Commit 3957f2b3 authored by James Morris's avatar James Morris Committed by Sridhar Samudrala

[CRYPTO]: in/out scatterlist support for ciphers.

- Merge scatterwalk patch from Adam J. Richter <adam@yggdrasil.com>
  API change: cipher methods now take in/out scatterlists and nbytes 
  params.
- Merge gss_krb5_crypto update from Adam J. Richter <adam@yggdrasil.com>
- Add KM_SOFTIRQn (instead of KM_CRYPTO_IN etc).
- Add asm/kmap_types.h to crypto/internal.h
- Update cipher.c credits.
- Update cipher.c documentation.
parent 8f5e762b
This diff is collapsed.
......@@ -28,10 +28,10 @@ static void update(struct crypto_tfm *tfm,
unsigned int i;
for (i = 0; i < nsg; i++) {
char *p = crypto_kmap(sg[i].page) + sg[i].offset;
char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx,
p, sg[i].length);
crypto_kunmap(p);
crypto_kunmap(p, 0);
crypto_yield(tfm);
}
}
......@@ -49,10 +49,10 @@ static void digest(struct crypto_tfm *tfm,
tfm->crt_digest.dit_init(tfm);
for (i = 0; i < nsg; i++) {
char *p = crypto_kmap(sg[i].page) + sg[i].offset;
char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx,
p, sg[i].length);
crypto_kunmap(p);
crypto_kunmap(p, 0);
crypto_yield(tfm);
}
crypto_digest_final(tfm, out);
......
......@@ -16,17 +16,29 @@
#include <linux/init.h>
#include <asm/hardirq.h>
#include <asm/softirq.h>
#include <asm/kmap_types.h>
static inline void *crypto_kmap(struct page *page)
static enum km_type km_types[] = {
KM_USER0,
KM_USER1,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
};
static inline enum km_type crypto_kmap_type(int out)
{
return km_types[(in_softirq() ? 2 : 0) + out];
}
static inline void *crypto_kmap(struct page *page, int out)
{
return kmap_atomic(page, in_softirq() ?
KM_CRYPTO_SOFTIRQ : KM_CRYPTO_USER);
return kmap_atomic(page, crypto_kmap_type(out));
}
static inline void crypto_kunmap(void *vaddr)
static inline void crypto_kunmap(void *vaddr, int out)
{
kunmap_atomic(vaddr, in_softirq() ?
KM_CRYPTO_SOFTIRQ : KM_CRYPTO_USER);
kunmap_atomic(vaddr, crypto_kmap_type(out));
}
static inline void crypto_yield(struct crypto_tfm *tfm)
......
......@@ -703,7 +703,7 @@ test_des(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = len;
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, len);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -746,7 +746,7 @@ test_des(void)
sg[1].offset = ((long) p & ~PAGE_MASK);
sg[1].length = 8;
ret = crypto_cipher_encrypt(tfm, sg, 2);
ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -814,7 +814,7 @@ test_des(void)
sg[2].offset = ((long) p & ~PAGE_MASK);
sg[2].length = 8;
ret = crypto_cipher_encrypt(tfm, sg, 3);
ret = crypto_cipher_encrypt(tfm, sg, sg, 32);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
......@@ -890,7 +890,7 @@ test_des(void)
sg[3].offset = ((long) p & ~PAGE_MASK);
sg[3].length = 18;
ret = crypto_cipher_encrypt(tfm, sg, 4);
ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
......@@ -979,7 +979,7 @@ test_des(void)
sg[4].offset = ((long) p & ~PAGE_MASK);
sg[4].length = 8;
ret = crypto_cipher_encrypt(tfm, sg, 5);
ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
......@@ -1078,7 +1078,7 @@ test_des(void)
sg[7].offset = ((long) p & ~PAGE_MASK);
sg[7].length = 1;
ret = crypto_cipher_encrypt(tfm, sg, 8);
ret = crypto_cipher_encrypt(tfm, sg, sg, 8);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1120,7 +1120,7 @@ test_des(void)
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = len;
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("des_decrypt() failed flags=%x\n",
tfm->crt_flags);
......@@ -1163,7 +1163,7 @@ test_des(void)
sg[1].offset = ((long) p & ~PAGE_MASK);
sg[1].length = 8;
ret = crypto_cipher_decrypt(tfm, sg, 2);
ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1220,7 +1220,7 @@ test_des(void)
sg[2].offset = ((long) p & ~PAGE_MASK);
sg[2].length = 1;
ret = crypto_cipher_decrypt(tfm, sg, 3);
ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
......@@ -1290,7 +1290,7 @@ test_des(void)
crypto_cipher_set_iv(tfm, des_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, len);
if (ret) {
printk("des_cbc_encrypt() failed flags=%x\n",
tfm->crt_flags);
......@@ -1349,7 +1349,7 @@ test_des(void)
crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, 2);
ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
if (ret) {
printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1398,7 +1398,7 @@ test_des(void)
crypto_cipher_set_iv(tfm, des_tv[i].iv,
crypto_tfm_alg_blocksize(tfm));
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, len);
if (ret) {
printk("des_cbc_decrypt() failed flags=%x\n",
tfm->crt_flags);
......@@ -1450,7 +1450,7 @@ test_des(void)
crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_decrypt(tfm, sg, 2);
ret = crypto_cipher_decrypt(tfm, sg, sg, 8);
if (ret) {
printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1518,7 +1518,7 @@ test_des3_ede(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = len;
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, len);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1561,7 +1561,7 @@ test_des3_ede(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = len;
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, len);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1624,7 +1624,7 @@ test_blowfish(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = bf_tv[i].plen;
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1666,7 +1666,7 @@ test_blowfish(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = bf_tv[i].plen;
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1719,7 +1719,7 @@ test_blowfish(void)
crypto_cipher_set_iv(tfm, bf_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("blowfish_cbc_encrypt() failed flags=%x\n",
tfm->crt_flags);
......@@ -1764,7 +1764,7 @@ test_blowfish(void)
crypto_cipher_set_iv(tfm, bf_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("blowfish_cbc_decrypt() failed flags=%x\n",
tfm->crt_flags);
......@@ -1829,7 +1829,7 @@ test_twofish(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = tf_tv[i].plen;
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1871,7 +1871,7 @@ test_twofish(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = tf_tv[i].plen;
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -1924,7 +1924,7 @@ test_twofish(void)
crypto_cipher_set_iv(tfm, tf_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("blowfish_cbc_encrypt() failed flags=%x\n",
tfm->crt_flags);
......@@ -1970,7 +1970,7 @@ test_twofish(void)
crypto_cipher_set_iv(tfm, tf_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("blowfish_cbc_decrypt() failed flags=%x\n",
tfm->crt_flags);
......@@ -2030,7 +2030,7 @@ test_serpent(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = sizeof(serp_tv[i].plaintext);
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -2070,7 +2070,7 @@ test_serpent(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = sizeof(serp_tv[i].plaintext);
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -2133,7 +2133,7 @@ test_aes(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = aes_tv[i].plen;
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......@@ -2175,7 +2175,7 @@ test_aes(void)
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = aes_tv[i].plen;
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
......
......@@ -23,8 +23,8 @@ D(7) KM_PTE0,
D(8) KM_PTE1,
D(9) KM_IRQ0,
D(10) KM_IRQ1,
D(11) KM_CRYPTO_USER,
D(12) KM_CRYPTO_SOFTIRQ,
D(11) KM_SOFTIRQ0,
D(12) KM_SOFTIRQ1,
D(13) KM_TYPE_NR
};
......
......@@ -22,8 +22,8 @@ D(8) KM_PTE1,
D(9) KM_PTE2,
D(10) KM_IRQ0,
D(11) KM_IRQ1,
D(12) KM_CRYPTO_USER,
D(13) KM_CRYPTO_SOFTIRQ,
D(12) KM_SOFTIRQ0,
D(13) KM_SOFTIRQ1,
D(14) KM_TYPE_NR
};
......
......@@ -21,8 +21,8 @@ D(7) KM_PTE0,
D(8) KM_PTE1,
D(9) KM_IRQ0,
D(10) KM_IRQ1,
D(11) KM_CRYPTO_USER,
D(12) KM_CRYPTO_SOFTIRQ,
D(11) KM_SOFTIRQ0,
D(12) KM_SOFTIRQ1,
D(13) KM_TYPE_NR
};
......
......@@ -14,8 +14,8 @@ enum km_type {
KM_PTE1,
KM_IRQ0,
KM_IRQ1,
KM_CRYPTO_USER,
KM_CRYPTO_SOFTIRQ,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_TYPE_NR
};
......
......@@ -14,8 +14,8 @@ enum km_type {
KM_PTE1,
KM_IRQ0,
KM_IRQ1,
KM_CRYPTO_USER,
KM_CRYPTO_SOFTIRQ,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_TYPE_NR
};
......
......@@ -14,8 +14,8 @@ enum km_type {
KM_PTE1,
KM_IRQ0,
KM_IRQ1,
KM_CRYPTO_USER,
KM_CRYPTO_SOFTIRQ,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_TYPE_NR
};
......
......@@ -13,8 +13,8 @@ enum km_type {
KM_PTE1,
KM_IRQ0,
KM_IRQ1,
KM_CRYPTO_USER,
KM_CRYPTO_SOFTIRQ,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_TYPE_NR
};
......
......@@ -17,8 +17,8 @@ enum km_type {
KM_PTE1,
KM_IRQ0,
KM_IRQ1,
KM_CRYPTO_USER,
KM_CRYPTO_SOFTIRQ,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_TYPE_NR
};
......
......@@ -11,8 +11,8 @@ enum km_type {
KM_BIO_DST_IRQ,
KM_IRQ0,
KM_IRQ1,
KM_CRYPTO_USER,
KM_CRYPTO_SOFTIRQ,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_TYPE_NR
};
......
......@@ -131,9 +131,13 @@ struct cipher_tfm {
int (*cit_setkey)(struct crypto_tfm *tfm,
const u8 *key, unsigned int keylen);
int (*cit_encrypt)(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg);
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes);
int (*cit_decrypt)(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg);
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes);
void (*cit_xor_block)(u8 *dst, const u8 *src);
};
......@@ -274,19 +278,21 @@ static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
}
static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
struct scatterlist *sg,
unsigned int nsg)
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
return tfm->crt_cipher.cit_encrypt(tfm, sg, nsg);
return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
}
static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
struct scatterlist *sg,
unsigned int nsg)
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
return tfm->crt_cipher.cit_decrypt(tfm, sg, nsg);
return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
}
static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
......
......@@ -423,7 +423,7 @@ int esp_output(struct sk_buff *skb)
goto error;
}
skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
crypto_cipher_encrypt(tfm, sg, nfrags);
crypto_cipher_encrypt(tfm, sg, sg, clen);
if (unlikely(sg != sgbuf))
kfree(sg);
} while (0);
......@@ -520,7 +520,7 @@ int esp_input(struct xfrm_state *x, struct sk_buff *skb)
goto out;
}
skb_to_sgvec(skb, sg, 8+esp->conf.ivlen, elen);
crypto_cipher_decrypt(esp->conf.tfm, sg, nfrags);
crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
if (unlikely(sg != sgbuf))
kfree(sg);
......
......@@ -78,7 +78,7 @@ krb5_encrypt(
sg[0].offset = ((long)out & ~PAGE_MASK);
sg[0].length = length;
ret = crypto_cipher_encrypt(tfm, sg, 1);
ret = crypto_cipher_encrypt(tfm, sg, sg, length);
out:
dprintk("gss_k5encrypt returns %d\n",ret);
......@@ -117,7 +117,7 @@ krb5_decrypt(
sg[0].offset = ((long)out & ~PAGE_MASK);
sg[0].length = length;
ret = crypto_cipher_decrypt(tfm, sg, 1);
ret = crypto_cipher_decrypt(tfm, sg, sg, length);
out:
dprintk("gss_k5decrypt returns %d\n",ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment