Commit 612893c0 authored by James Morris's avatar James Morris

[CRYPTO]: Algorithm lookup API change plus bug fixes.

- API change: implemented simplest version of algorithm lookup
by name (feedback from Rusty Russell and Herbert Valerio Riedel).
- Now need to add the following line to to /etc/modules.conf for
dynamic module loading:
    alias des3_ede des
parent d02509cd
...@@ -36,7 +36,7 @@ static inline void crypto_alg_put(struct crypto_alg *alg) ...@@ -36,7 +36,7 @@ static inline void crypto_alg_put(struct crypto_alg *alg)
__MOD_DEC_USE_COUNT(alg->cra_module); __MOD_DEC_USE_COUNT(alg->cra_module);
} }
struct crypto_alg *crypto_alg_lookup(u32 algid) struct crypto_alg *crypto_alg_lookup(char *name)
{ {
struct list_head *p; struct list_head *p;
struct crypto_alg *alg = NULL; struct crypto_alg *alg = NULL;
...@@ -44,10 +44,13 @@ struct crypto_alg *crypto_alg_lookup(u32 algid) ...@@ -44,10 +44,13 @@ struct crypto_alg *crypto_alg_lookup(u32 algid)
down_read(&crypto_alg_sem); down_read(&crypto_alg_sem);
list_for_each(p, &crypto_alg_list) { list_for_each(p, &crypto_alg_list) {
if ((((struct crypto_alg *)p)->cra_id struct crypto_alg *q =
& CRYPTO_ALG_MASK) == algid) { list_entry(p, struct crypto_alg, cra_list);
if (crypto_alg_get((struct crypto_alg *)p))
alg = (struct crypto_alg *)p; if (!(strcmp(q->cra_name, name))) {
if (crypto_alg_get(q))
alg = q;
break; break;
} }
} }
...@@ -56,18 +59,43 @@ struct crypto_alg *crypto_alg_lookup(u32 algid) ...@@ -56,18 +59,43 @@ struct crypto_alg *crypto_alg_lookup(u32 algid)
return alg; return alg;
} }
static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
{
tfm->crt_flags = 0;
if (flags & CRYPTO_TFM_REQ_ATOMIC)
tfm->crt_flags |= CRYPTO_TFM_REQ_ATOMIC;
switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER:
return crypto_init_cipher_flags(tfm, flags);
case CRYPTO_ALG_TYPE_DIGEST:
return crypto_init_digest_flags(tfm, flags);
case CRYPTO_ALG_TYPE_COMP:
return crypto_init_compress_flags(tfm, flags);
default:
BUG();
}
return -EINVAL;
}
static void crypto_init_ops(struct crypto_tfm *tfm) static void crypto_init_ops(struct crypto_tfm *tfm)
{ {
switch (crypto_tfm_type(tfm) & CRYPTO_TYPE_MASK) { switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_TYPE_CIPHER: case CRYPTO_ALG_TYPE_CIPHER:
crypto_init_cipher_ops(tfm); crypto_init_cipher_ops(tfm);
break; break;
case CRYPTO_TYPE_DIGEST: case CRYPTO_ALG_TYPE_DIGEST:
crypto_init_digest_ops(tfm); crypto_init_digest_ops(tfm);
break; break;
case CRYPTO_TYPE_COMP: case CRYPTO_ALG_TYPE_COMP:
crypto_init_compress_ops(tfm); crypto_init_compress_ops(tfm);
break; break;
...@@ -77,16 +105,16 @@ static void crypto_init_ops(struct crypto_tfm *tfm) ...@@ -77,16 +105,16 @@ static void crypto_init_ops(struct crypto_tfm *tfm)
} }
} }
struct crypto_tfm *crypto_alloc_tfm(u32 id) struct crypto_tfm *crypto_alloc_tfm(char *name, u32 flags)
{ {
struct crypto_tfm *tfm = NULL; struct crypto_tfm *tfm = NULL;
struct crypto_alg *alg; struct crypto_alg *alg;
alg = crypto_alg_lookup(id & CRYPTO_ALG_MASK); alg = crypto_alg_lookup(name);
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
if (alg == NULL) { if (alg == NULL) {
crypto_alg_autoload(id & CRYPTO_ALG_MASK); crypto_alg_autoload(name);
alg = crypto_alg_lookup(id & CRYPTO_ALG_MASK); alg = crypto_alg_lookup(name);
} }
#endif #endif
if (alg == NULL) if (alg == NULL)
...@@ -102,17 +130,11 @@ struct crypto_tfm *crypto_alloc_tfm(u32 id) ...@@ -102,17 +130,11 @@ struct crypto_tfm *crypto_alloc_tfm(u32 id)
goto out_free_tfm; goto out_free_tfm;
} }
if ((alg->cra_id & CRYPTO_TYPE_MASK) == CRYPTO_TYPE_CIPHER) {
if (alg->cra_cipher.cia_ivsize) {
tfm->crt_cipher.cit_iv =
kmalloc(alg->cra_cipher.cia_ivsize, GFP_KERNEL);
if (tfm->crt_cipher.cit_iv == NULL)
goto out_free_ctx;
}
tfm->crt_cipher.cit_mode = id & CRYPTO_MODE_MASK;
}
tfm->__crt_alg = alg; tfm->__crt_alg = alg;
if (crypto_init_flags(tfm, flags))
goto out_free_ctx;
crypto_init_ops(tfm); crypto_init_ops(tfm);
goto out; goto out;
...@@ -134,8 +156,8 @@ void crypto_free_tfm(struct crypto_tfm *tfm) ...@@ -134,8 +156,8 @@ void crypto_free_tfm(struct crypto_tfm *tfm)
if (tfm->__crt_alg->cra_ctxsize) if (tfm->__crt_alg->cra_ctxsize)
kfree(tfm->crt_ctx); kfree(tfm->crt_ctx);
if (crypto_tfm_type(tfm) == CRYPTO_TYPE_CIPHER) if (crypto_tfm_alg_type(tfm) == CRYPTO_ALG_TYPE_CIPHER)
if (tfm->__crt_alg->cra_cipher.cia_ivsize) if (tfm->crt_cipher.cit_iv)
kfree(tfm->crt_cipher.cit_iv); kfree(tfm->crt_cipher.cit_iv);
crypto_alg_put(tfm->__crt_alg); crypto_alg_put(tfm->__crt_alg);
...@@ -150,9 +172,10 @@ int crypto_register_alg(struct crypto_alg *alg) ...@@ -150,9 +172,10 @@ int crypto_register_alg(struct crypto_alg *alg)
down_write(&crypto_alg_sem); down_write(&crypto_alg_sem);
list_for_each(p, &crypto_alg_list) { list_for_each(p, &crypto_alg_list) {
struct crypto_alg *q = (struct crypto_alg *)p; struct crypto_alg *q =
list_entry(p, struct crypto_alg, cra_list);
if (q->cra_id == alg->cra_id) { if (!(strcmp(q->cra_name, alg->cra_name))) {
ret = -EEXIST; ret = -EEXIST;
goto out; goto out;
} }
...@@ -172,7 +195,7 @@ int crypto_unregister_alg(struct crypto_alg *alg) ...@@ -172,7 +195,7 @@ int crypto_unregister_alg(struct crypto_alg *alg)
down_write(&crypto_alg_sem); down_write(&crypto_alg_sem);
list_for_each(p, &crypto_alg_list) { list_for_each(p, &crypto_alg_list) {
if (alg == (struct crypto_alg *)p) { if (alg == (void *)p) {
list_del(p); list_del(p);
ret = 0; ret = 0;
goto out; goto out;
...@@ -215,16 +238,17 @@ static int c_show(struct seq_file *m, void *p) ...@@ -215,16 +238,17 @@ static int c_show(struct seq_file *m, void *p)
struct crypto_alg *alg = (struct crypto_alg *)p; struct crypto_alg *alg = (struct crypto_alg *)p;
seq_printf(m, "name : %s\n", alg->cra_name); seq_printf(m, "name : %s\n", alg->cra_name);
seq_printf(m, "id : 0x%08x\n", alg->cra_id); seq_printf(m, "module : %s\n", alg->cra_module ?
alg->cra_module->name : "[static]");
seq_printf(m, "blocksize : %Zd\n", alg->cra_blocksize); seq_printf(m, "blocksize : %Zd\n", alg->cra_blocksize);
switch (alg->cra_id & CRYPTO_TYPE_MASK) { switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
case CRYPTO_TYPE_CIPHER: case CRYPTO_ALG_TYPE_CIPHER:
seq_printf(m, "keysize : %Zd\n", alg->cra_cipher.cia_keysize); seq_printf(m, "keysize : %Zd\n", alg->cra_cipher.cia_keysize);
seq_printf(m, "ivsize : %Zd\n", alg->cra_cipher.cia_ivsize); seq_printf(m, "ivsize : %Zd\n", alg->cra_cipher.cia_ivsize);
break; break;
case CRYPTO_TYPE_DIGEST: case CRYPTO_ALG_TYPE_DIGEST:
seq_printf(m, "digestsize : %Zd\n", seq_printf(m, "digestsize : %Zd\n",
alg->cra_digest.dia_digestsize); alg->cra_digest.dia_digestsize);
break; break;
......
...@@ -15,31 +15,17 @@ ...@@ -15,31 +15,17 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/module.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/crypto.h> #include <linux/crypto.h>
#include "internal.h" #include "internal.h"
static struct { /*
u32 algid; * A far more intelligent version of this is planned. For now, just
char *name; * try an exact match on the name of the algorithm.
} alg_modmap[] = { */
{ CRYPTO_ALG_DES, "des" }, void crypto_alg_autoload(char *name)
{ CRYPTO_ALG_DES3_EDE, "des" },
{ CRYPTO_ALG_MD4, "md4" },
{ CRYPTO_ALG_MD5, "md5" },
{ CRYPTO_ALG_SHA1, "sha1" },
};
#define ALG_MAX_MODMAP 5
void crypto_alg_autoload(u32 algid)
{ {
int i; request_module(name);
for (i = 0; i < ALG_MAX_MODMAP ; i++) {
if ((alg_modmap[i].algid & CRYPTO_ALG_MASK) == algid) {
request_module(alg_modmap[i].name);
break;
}
}
return; return;
} }
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
#include <linux/crypto.h> #include <linux/crypto.h>
...@@ -50,7 +52,7 @@ static int copy_chunks(struct crypto_tfm *tfm, u8 *buf, ...@@ -50,7 +52,7 @@ static int copy_chunks(struct crypto_tfm *tfm, u8 *buf,
int rlen, int *last, int in) int rlen, int *last, int in)
{ {
int i, copied, coff, j, aligned; int i, copied, coff, j, aligned;
size_t bsize = crypto_tfm_blocksize(tfm); size_t bsize = crypto_tfm_alg_blocksize(tfm);
for (i = sgidx, j = copied = 0, aligned = 0 ; copied < bsize; i++) { for (i = sgidx, j = copied = 0, aligned = 0 ; copied < bsize; i++) {
int len = sg[i].length; int len = sg[i].length;
...@@ -115,11 +117,11 @@ static int crypt(struct crypto_tfm *tfm, struct scatterlist *sg, ...@@ -115,11 +117,11 @@ static int crypt(struct crypto_tfm *tfm, struct scatterlist *sg,
size_t nsg, cryptfn_t crfn, procfn_t prfn, int enc) size_t nsg, cryptfn_t crfn, procfn_t prfn, int enc)
{ {
int i, coff; int i, coff;
size_t bsize = crypto_tfm_blocksize(tfm); size_t bsize = crypto_tfm_alg_blocksize(tfm);
u8 tmp[CRYPTO_MAX_BLOCK_SIZE]; u8 tmp[CRYPTO_MAX_BLOCK_SIZE];
if (sglen(sg, nsg) % bsize) { if (sglen(sg, nsg) % bsize) {
tfm->crt_flags |= CRYPTO_BAD_BLOCK_LEN; tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
return -EINVAL; return -EINVAL;
} }
...@@ -168,15 +170,15 @@ static void cbc_process(struct crypto_tfm *tfm, ...@@ -168,15 +170,15 @@ static void cbc_process(struct crypto_tfm *tfm,
xor_64(tfm->crt_cipher.cit_iv, block); xor_64(tfm->crt_cipher.cit_iv, block);
fn(tfm->crt_ctx, block, tfm->crt_cipher.cit_iv); fn(tfm->crt_ctx, block, tfm->crt_cipher.cit_iv);
memcpy(tfm->crt_cipher.cit_iv, block, memcpy(tfm->crt_cipher.cit_iv, block,
crypto_tfm_blocksize(tfm)); crypto_tfm_alg_blocksize(tfm));
} else { } else {
u8 buf[CRYPTO_MAX_BLOCK_SIZE]; u8 buf[CRYPTO_MAX_BLOCK_SIZE];
fn(tfm->crt_ctx, buf, block); fn(tfm->crt_ctx, buf, block);
xor_64(buf, tfm->crt_cipher.cit_iv); xor_64(buf, tfm->crt_cipher.cit_iv);
memcpy(tfm->crt_cipher.cit_iv, block, memcpy(tfm->crt_cipher.cit_iv, block,
crypto_tfm_blocksize(tfm)); crypto_tfm_alg_blocksize(tfm));
memcpy(block, buf, crypto_tfm_blocksize(tfm)); memcpy(block, buf, crypto_tfm_alg_blocksize(tfm));
} }
} }
...@@ -225,6 +227,27 @@ static int nocrypt(struct crypto_tfm *tfm, struct scatterlist *sg, size_t nsg) ...@@ -225,6 +227,27 @@ static int nocrypt(struct crypto_tfm *tfm, struct scatterlist *sg, size_t nsg)
return -ENOSYS; return -ENOSYS;
} }
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
{
struct crypto_alg *alg = tfm->__crt_alg;
u32 mode = flags & CRYPTO_TFM_MODE_MASK;
tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
if (alg->cra_cipher.cia_ivsize && mode != CRYPTO_TFM_MODE_ECB) {
tfm->crt_cipher.cit_iv =
kmalloc(alg->cra_cipher.cia_ivsize, GFP_KERNEL);
if (tfm->crt_cipher.cit_iv == NULL)
return -ENOMEM;
} else
tfm->crt_cipher.cit_iv = NULL;
if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
return 0;
}
void crypto_init_cipher_ops(struct crypto_tfm *tfm) void crypto_init_cipher_ops(struct crypto_tfm *tfm)
{ {
struct cipher_tfm *ops = &tfm->crt_cipher; struct cipher_tfm *ops = &tfm->crt_cipher;
...@@ -232,22 +255,22 @@ void crypto_init_cipher_ops(struct crypto_tfm *tfm) ...@@ -232,22 +255,22 @@ void crypto_init_cipher_ops(struct crypto_tfm *tfm)
ops->cit_setkey = setkey; ops->cit_setkey = setkey;
switch (tfm->crt_cipher.cit_mode) { switch (tfm->crt_cipher.cit_mode) {
case CRYPTO_MODE_ECB: case CRYPTO_TFM_MODE_ECB:
ops->cit_encrypt = ecb_encrypt; ops->cit_encrypt = ecb_encrypt;
ops->cit_decrypt = ecb_decrypt; ops->cit_decrypt = ecb_decrypt;
break; break;
case CRYPTO_MODE_CBC: case CRYPTO_TFM_MODE_CBC:
ops->cit_encrypt = cbc_encrypt; ops->cit_encrypt = cbc_encrypt;
ops->cit_decrypt = cbc_decrypt; ops->cit_decrypt = cbc_decrypt;
break; break;
case CRYPTO_MODE_CFB: case CRYPTO_TFM_MODE_CFB:
ops->cit_encrypt = nocrypt; ops->cit_encrypt = nocrypt;
ops->cit_decrypt = nocrypt; ops->cit_decrypt = nocrypt;
break; break;
case CRYPTO_MODE_CTR: case CRYPTO_TFM_MODE_CTR:
ops->cit_encrypt = nocrypt; ops->cit_encrypt = nocrypt;
ops->cit_decrypt = nocrypt; ops->cit_decrypt = nocrypt;
break; break;
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/crypto.h> #include <linux/crypto.h>
...@@ -32,6 +34,11 @@ static void crypto_decompress(struct crypto_tfm *tfm) ...@@ -32,6 +34,11 @@ static void crypto_decompress(struct crypto_tfm *tfm)
return; return;
} }
int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
{
return crypto_cipher_flags(flags) ? -EINVAL : 0;
}
void crypto_init_compress_ops(struct crypto_tfm *tfm) void crypto_init_compress_ops(struct crypto_tfm *tfm)
{ {
struct compress_tfm *ops = &tfm->crt_compress; struct compress_tfm *ops = &tfm->crt_compress;
......
...@@ -1036,7 +1036,7 @@ static int setkey(u32 *expkey, const u8 *key, size_t keylen, int *flags) ...@@ -1036,7 +1036,7 @@ static int setkey(u32 *expkey, const u8 *key, size_t keylen, int *flags)
u8 bits0[56], bits1[56]; u8 bits0[56], bits1[56];
if (keylen != DES_KEY_SIZE) { if (keylen != DES_KEY_SIZE) {
*flags |= CRYPTO_BAD_KEY_LEN; *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL; return -EINVAL;
} }
...@@ -1050,7 +1050,7 @@ static int setkey(u32 *expkey, const u8 *key, size_t keylen, int *flags) ...@@ -1050,7 +1050,7 @@ static int setkey(u32 *expkey, const u8 *key, size_t keylen, int *flags)
n |= parity[key[7]]; n |= parity[key[7]];
w = 0x88888888L; w = 0x88888888L;
if ((*flags & CRYPTO_WEAK_KEY_CHECK) if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
&& !((n - (w >> 3)) & w)) { /* 1 in 10^10 keys passes this test */ && !((n - (w >> 3)) & w)) { /* 1 in 10^10 keys passes this test */
if (n < 0x41415151) { if (n < 0x41415151) {
if (n < 0x31312121) { if (n < 0x31312121) {
...@@ -1108,7 +1108,7 @@ static int setkey(u32 *expkey, const u8 *key, size_t keylen, int *flags) ...@@ -1108,7 +1108,7 @@ static int setkey(u32 *expkey, const u8 *key, size_t keylen, int *flags)
goto not_weak; goto not_weak;
weak: weak:
*flags |= CRYPTO_WEAK_KEY; *flags |= CRYPTO_TFM_RES_WEAK_KEY;
return -EINVAL; return -EINVAL;
} }
...@@ -1211,7 +1211,7 @@ static int des3_ede_setkey(void *ctx, const u8 *key, size_t keylen, int *flags) ...@@ -1211,7 +1211,7 @@ static int des3_ede_setkey(void *ctx, const u8 *key, size_t keylen, int *flags)
struct des3_ede_ctx *dctx = ctx; struct des3_ede_ctx *dctx = ctx;
if (keylen != DES3_EDE_KEY_SIZE) { if (keylen != DES3_EDE_KEY_SIZE) {
*flags |= CRYPTO_BAD_KEY_LEN; *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL; return -EINVAL;
} }
...@@ -1219,7 +1219,7 @@ static int des3_ede_setkey(void *ctx, const u8 *key, size_t keylen, int *flags) ...@@ -1219,7 +1219,7 @@ static int des3_ede_setkey(void *ctx, const u8 *key, size_t keylen, int *flags)
memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
DES_KEY_SIZE))) { DES_KEY_SIZE))) {
*flags |= CRYPTO_BAD_KEY_SCHED; *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
return -EINVAL; return -EINVAL;
} }
...@@ -1255,8 +1255,8 @@ static void des3_ede_decrypt(void *ctx, u8 *dst, u8 *src) ...@@ -1255,8 +1255,8 @@ static void des3_ede_decrypt(void *ctx, u8 *dst, u8 *src)
} }
static struct crypto_alg des_alg = { static struct crypto_alg des_alg = {
.cra_id = CRYPTO_ALG_DES,
.cra_name = "des", .cra_name = "des",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = DES_BLOCK_SIZE, .cra_blocksize = DES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct des_ctx), .cra_ctxsize = sizeof(struct des_ctx),
.cra_module = THIS_MODULE, .cra_module = THIS_MODULE,
...@@ -1269,8 +1269,8 @@ static struct crypto_alg des_alg = { ...@@ -1269,8 +1269,8 @@ static struct crypto_alg des_alg = {
}; };
static struct crypto_alg des3_ede_alg = { static struct crypto_alg des3_ede_alg = {
.cra_id = CRYPTO_ALG_DES3_EDE,
.cra_name = "des3_ede", .cra_name = "des3_ede",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct des3_ede_ctx), .cra_ctxsize = sizeof(struct des3_ede_ctx),
.cra_module = THIS_MODULE, .cra_module = THIS_MODULE,
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
...@@ -71,15 +72,15 @@ static void hmac(struct crypto_tfm *tfm, u8 *key, size_t keylen, ...@@ -71,15 +72,15 @@ static void hmac(struct crypto_tfm *tfm, u8 *key, size_t keylen,
{ {
int i; int i;
struct scatterlist tmp; struct scatterlist tmp;
char ipad[crypto_tfm_blocksize(tfm) + 1]; char ipad[crypto_tfm_alg_blocksize(tfm) + 1];
char opad[crypto_tfm_blocksize(tfm) + 1]; char opad[crypto_tfm_alg_blocksize(tfm) + 1];
if (keylen > crypto_tfm_blocksize(tfm)) { if (keylen > crypto_tfm_alg_blocksize(tfm)) {
tmp.page = virt_to_page(key); tmp.page = virt_to_page(key);
tmp.offset = ((long)key & ~PAGE_MASK); tmp.offset = ((long)key & ~PAGE_MASK);
tmp.length = keylen; tmp.length = keylen;
crypto_digest_digest(tfm, &tmp, 1, key); crypto_digest_digest(tfm, &tmp, 1, key);
keylen = crypto_tfm_digestsize(tfm); keylen = crypto_tfm_alg_digestsize(tfm);
} }
memset(ipad, 0, sizeof(ipad)); memset(ipad, 0, sizeof(ipad));
...@@ -87,14 +88,14 @@ static void hmac(struct crypto_tfm *tfm, u8 *key, size_t keylen, ...@@ -87,14 +88,14 @@ static void hmac(struct crypto_tfm *tfm, u8 *key, size_t keylen,
memcpy(ipad, key, keylen); memcpy(ipad, key, keylen);
memcpy(opad, key, keylen); memcpy(opad, key, keylen);
for (i = 0; i < crypto_tfm_blocksize(tfm); i++) { for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++) {
ipad[i] ^= 0x36; ipad[i] ^= 0x36;
opad[i] ^= 0x5c; opad[i] ^= 0x5c;
} }
tmp.page = virt_to_page(ipad); tmp.page = virt_to_page(ipad);
tmp.offset = ((long)ipad & ~PAGE_MASK); tmp.offset = ((long)ipad & ~PAGE_MASK);
tmp.length = crypto_tfm_blocksize(tfm); tmp.length = crypto_tfm_alg_blocksize(tfm);
crypto_digest_init(tfm); crypto_digest_init(tfm);
crypto_digest_update(tfm, &tmp, 1); crypto_digest_update(tfm, &tmp, 1);
...@@ -103,20 +104,25 @@ static void hmac(struct crypto_tfm *tfm, u8 *key, size_t keylen, ...@@ -103,20 +104,25 @@ static void hmac(struct crypto_tfm *tfm, u8 *key, size_t keylen,
tmp.page = virt_to_page(opad); tmp.page = virt_to_page(opad);
tmp.offset = ((long)opad & ~PAGE_MASK); tmp.offset = ((long)opad & ~PAGE_MASK);
tmp.length = crypto_tfm_blocksize(tfm); tmp.length = crypto_tfm_alg_blocksize(tfm);
crypto_digest_init(tfm); crypto_digest_init(tfm);
crypto_digest_update(tfm, &tmp, 1); crypto_digest_update(tfm, &tmp, 1);
tmp.page = virt_to_page(out); tmp.page = virt_to_page(out);
tmp.offset = ((long)out & ~PAGE_MASK); tmp.offset = ((long)out & ~PAGE_MASK);
tmp.length = crypto_tfm_digestsize(tfm); tmp.length = crypto_tfm_alg_digestsize(tfm);
crypto_digest_update(tfm, &tmp, 1); crypto_digest_update(tfm, &tmp, 1);
crypto_digest_final(tfm, out); crypto_digest_final(tfm, out);
return; return;
} }
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
{
return crypto_cipher_flags(flags) ? -EINVAL : 0;
}
void crypto_init_digest_ops(struct crypto_tfm *tfm) void crypto_init_digest_ops(struct crypto_tfm *tfm)
{ {
struct digest_tfm *ops = &tfm->crt_digest; struct digest_tfm *ops = &tfm->crt_digest;
......
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
static inline void *crypto_kmap(struct crypto_tfm *tfm, struct page *page) static inline void *crypto_kmap(struct crypto_tfm *tfm, struct page *page)
{ {
if (tfm->crt_flags & CRYPTO_ATOMIC) { if (tfm->crt_flags & CRYPTO_TFM_REQ_ATOMIC) {
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM /* XXX: remove this after the api change */
local_bh_disable(); local_bh_disable();
#endif #endif
return kmap_atomic(page, KM_CRYPTO_SOFTIRQ); return kmap_atomic(page, KM_CRYPTO_SOFTIRQ);
...@@ -30,9 +30,9 @@ static inline void *crypto_kmap(struct crypto_tfm *tfm, struct page *page) ...@@ -30,9 +30,9 @@ static inline void *crypto_kmap(struct crypto_tfm *tfm, struct page *page)
static inline void crypto_kunmap(struct crypto_tfm *tfm, void *vaddr) static inline void crypto_kunmap(struct crypto_tfm *tfm, void *vaddr)
{ {
if (tfm->crt_flags & CRYPTO_ATOMIC) { if (tfm->crt_flags & CRYPTO_TFM_REQ_ATOMIC) {
kunmap_atomic(vaddr, KM_CRYPTO_SOFTIRQ); kunmap_atomic(vaddr, KM_CRYPTO_SOFTIRQ);
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM /* XXX: remove this after the api change */
local_bh_enable(); local_bh_enable();
#endif #endif
} else } else
...@@ -41,14 +41,23 @@ static inline void crypto_kunmap(struct crypto_tfm *tfm, void *vaddr) ...@@ -41,14 +41,23 @@ static inline void crypto_kunmap(struct crypto_tfm *tfm, void *vaddr)
static inline void crypto_yield(struct crypto_tfm *tfm) static inline void crypto_yield(struct crypto_tfm *tfm)
{ {
if (!(tfm->crt_flags & CRYPTO_ATOMIC)) if (!(tfm->crt_flags & CRYPTO_TFM_REQ_ATOMIC))
cond_resched(); cond_resched();
} }
static inline int crypto_cipher_flags(u32 flags)
{
return flags & (CRYPTO_TFM_MODE_MASK|CRYPTO_TFM_REQ_WEAK_KEY);
}
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
void crypto_alg_autoload(u32 algid); void crypto_alg_autoload(char *name);
#endif #endif
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
void crypto_init_digest_ops(struct crypto_tfm *tfm); void crypto_init_digest_ops(struct crypto_tfm *tfm);
void crypto_init_cipher_ops(struct crypto_tfm *tfm); void crypto_init_cipher_ops(struct crypto_tfm *tfm);
void crypto_init_compress_ops(struct crypto_tfm *tfm); void crypto_init_compress_ops(struct crypto_tfm *tfm);
......
...@@ -221,8 +221,8 @@ static void md4_final(void *ctx, u8 *out) ...@@ -221,8 +221,8 @@ static void md4_final(void *ctx, u8 *out)
} }
static struct crypto_alg alg = { static struct crypto_alg alg = {
.cra_id = CRYPTO_ALG_MD4,
.cra_name = "md4", .cra_name = "md4",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = MD4_HMAC_BLOCK_SIZE, .cra_blocksize = MD4_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct md4_ctx), .cra_ctxsize = sizeof(struct md4_ctx),
.cra_module = THIS_MODULE, .cra_module = THIS_MODULE,
......
...@@ -214,8 +214,8 @@ static void md5_final(void *ctx, u8 *out) ...@@ -214,8 +214,8 @@ static void md5_final(void *ctx, u8 *out)
} }
static struct crypto_alg alg = { static struct crypto_alg alg = {
.cra_id = CRYPTO_ALG_MD5,
.cra_name = "md5", .cra_name = "md5",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = MD5_HMAC_BLOCK_SIZE, .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct md5_ctx), .cra_ctxsize = sizeof(struct md5_ctx),
.cra_module = THIS_MODULE, .cra_module = THIS_MODULE,
......
...@@ -178,8 +178,8 @@ static void sha1_final(void* ctx, u8 *out) ...@@ -178,8 +178,8 @@ static void sha1_final(void* ctx, u8 *out)
} }
static struct crypto_alg alg = { static struct crypto_alg alg = {
.cra_id = CRYPTO_ALG_SHA1,
.cra_name = "sha1", .cra_name = "sha1",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = SHA1_HMAC_BLOCK_SIZE, .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct sha1_ctx), .cra_ctxsize = sizeof(struct sha1_ctx),
.cra_module = THIS_MODULE, .cra_module = THIS_MODULE,
......
...@@ -76,9 +76,9 @@ static void test_md5(void) ...@@ -76,9 +76,9 @@ static void test_md5(void)
memcpy(tvmem, md5_tv_template, tsize); memcpy(tvmem, md5_tv_template, tsize);
md5_tv = (void *)tvmem; md5_tv = (void *)tvmem;
tfm = crypto_alloc_tfm(CRYPTO_ALG_MD5); tfm = crypto_alloc_tfm("md5", 0);
if (tfm == NULL) { if (tfm == NULL) {
printk("failed to load transform for CRYPTO_ALG_MD5\n"); printk("failed to load transform for md5\n");
return; return;
} }
...@@ -95,8 +95,8 @@ static void test_md5(void) ...@@ -95,8 +95,8 @@ static void test_md5(void)
crypto_digest_update(tfm, sg, 1); crypto_digest_update(tfm, sg, 1);
crypto_digest_final(tfm, result); crypto_digest_final(tfm, result);
hexdump(result, crypto_tfm_digestsize(tfm)); hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n", memcmp(result, md5_tv[i].digest, crypto_tfm_digestsize(tfm)) ? "fail" : "pass"); printk("%s\n", memcmp(result, md5_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
} }
printk("\ntesting md5 across pages\n"); printk("\ntesting md5 across pages\n");
...@@ -118,9 +118,9 @@ static void test_md5(void) ...@@ -118,9 +118,9 @@ static void test_md5(void)
memset(result, 0, sizeof(result)); memset(result, 0, sizeof(result));
crypto_digest_digest(tfm, sg, 2, result); crypto_digest_digest(tfm, sg, 2, result);
hexdump(result, crypto_tfm_digestsize(tfm)); hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n", memcmp(result, md5_tv[4].digest, crypto_tfm_digestsize(tfm)) ? "fail" : "pass"); printk("%s\n", memcmp(result, md5_tv[4].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
printk("\ntesting hmac_md5\n"); printk("\ntesting hmac_md5\n");
...@@ -144,8 +144,8 @@ static void test_md5(void) ...@@ -144,8 +144,8 @@ static void test_md5(void)
crypto_digest_hmac(tfm, hmac_md5_tv[i].key, strlen(hmac_md5_tv[i].key),sg , 1, result); crypto_digest_hmac(tfm, hmac_md5_tv[i].key, strlen(hmac_md5_tv[i].key),sg , 1, result);
hexdump(result, crypto_tfm_digestsize(tfm)); hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n", memcmp(result, hmac_md5_tv[i].digest, crypto_tfm_digestsize(tfm)) ? "fail" : "pass"); printk("%s\n", memcmp(result, hmac_md5_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
} }
printk("\ntesting hmac_md5 across pages\n"); printk("\ntesting hmac_md5 across pages\n");
...@@ -167,9 +167,9 @@ static void test_md5(void) ...@@ -167,9 +167,9 @@ static void test_md5(void)
memset(result, 0, sizeof(result)); memset(result, 0, sizeof(result));
crypto_digest_hmac(tfm, hmac_md5_tv[1].key, strlen(hmac_md5_tv[1].key), sg, 2, result); crypto_digest_hmac(tfm, hmac_md5_tv[1].key, strlen(hmac_md5_tv[1].key), sg, 2, result);
hexdump(result, crypto_tfm_digestsize(tfm)); hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n", memcmp(result, hmac_md5_tv[1].digest, crypto_tfm_digestsize(tfm)) ? "fail" : "pass"); printk("%s\n", memcmp(result, hmac_md5_tv[1].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
crypto_free_tfm(tfm); crypto_free_tfm(tfm);
} }
...@@ -195,9 +195,9 @@ static void test_md4(void) ...@@ -195,9 +195,9 @@ static void test_md4(void)
memcpy(tvmem, md4_tv_template, tsize); memcpy(tvmem, md4_tv_template, tsize);
md4_tv = (void *)tvmem; md4_tv = (void *)tvmem;
tfm = crypto_alloc_tfm(CRYPTO_ALG_MD4); tfm = crypto_alloc_tfm("md4", 0);
if (tfm == NULL) { if (tfm == NULL) {
printk("failed to load transform for CRYPTO_ALG_MD4\n"); printk("failed to load transform for md4\n");
return; return;
} }
...@@ -212,8 +212,8 @@ static void test_md4(void) ...@@ -212,8 +212,8 @@ static void test_md4(void)
crypto_digest_digest(tfm, sg, 1, result); crypto_digest_digest(tfm, sg, 1, result);
hexdump(result, crypto_tfm_digestsize(tfm)); hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n", memcmp(result, md4_tv[i].digest, crypto_tfm_digestsize(tfm)) ? "fail" : "pass"); printk("%s\n", memcmp(result, md4_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
} }
crypto_free_tfm(tfm); crypto_free_tfm(tfm);
...@@ -241,9 +241,9 @@ static void test_sha1(void) ...@@ -241,9 +241,9 @@ static void test_sha1(void)
memcpy(tvmem, sha1_tv_template, tsize); memcpy(tvmem, sha1_tv_template, tsize);
sha1_tv = (void *)tvmem; sha1_tv = (void *)tvmem;
tfm = crypto_alloc_tfm(CRYPTO_ALG_SHA1); tfm = crypto_alloc_tfm("sha1", 0);
if (tfm == NULL) { if (tfm == NULL) {
printk("failed to load transform for CRYPTO_ALG_SHA1\n"); printk("failed to load transform for sha1\n");
return; return;
} }
...@@ -260,8 +260,8 @@ static void test_sha1(void) ...@@ -260,8 +260,8 @@ static void test_sha1(void)
crypto_digest_update(tfm, sg, 1); crypto_digest_update(tfm, sg, 1);
crypto_digest_final(tfm, result); crypto_digest_final(tfm, result);
hexdump(result, crypto_tfm_digestsize(tfm)); hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n", memcmp(result, sha1_tv[i].digest, crypto_tfm_digestsize(tfm)) ? "fail" : "pass"); printk("%s\n", memcmp(result, sha1_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
} }
printk("\ntesting sha1 across pages\n"); printk("\ntesting sha1 across pages\n");
...@@ -283,8 +283,8 @@ static void test_sha1(void) ...@@ -283,8 +283,8 @@ static void test_sha1(void)
memset(result, 0, sizeof(result)); memset(result, 0, sizeof(result));
crypto_digest_digest(tfm, sg, 2, result); crypto_digest_digest(tfm, sg, 2, result);
hexdump(result, crypto_tfm_digestsize(tfm)); hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n", memcmp(result, sha1_tv[1].digest, crypto_tfm_digestsize(tfm)) ? "fail" : "pass"); printk("%s\n", memcmp(result, sha1_tv[1].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
printk("\ntesting hmac_sha1\n"); printk("\ntesting hmac_sha1\n");
...@@ -309,7 +309,7 @@ static void test_sha1(void) ...@@ -309,7 +309,7 @@ static void test_sha1(void)
crypto_digest_hmac(tfm, hmac_sha1_tv[i].key, strlen(hmac_sha1_tv[i].key),sg , 1, result); crypto_digest_hmac(tfm, hmac_sha1_tv[i].key, strlen(hmac_sha1_tv[i].key),sg , 1, result);
hexdump(result, sizeof(result)); hexdump(result, sizeof(result));
printk("%s\n", memcmp(result, hmac_sha1_tv[i].digest, crypto_tfm_digestsize(tfm)) ? "fail" : "pass"); printk("%s\n", memcmp(result, hmac_sha1_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
} }
printk("\ntesting hmac_sha1 across pages\n"); printk("\ntesting hmac_sha1 across pages\n");
...@@ -332,9 +332,9 @@ static void test_sha1(void) ...@@ -332,9 +332,9 @@ static void test_sha1(void)
memset(result, 0, sizeof(result)); memset(result, 0, sizeof(result));
crypto_digest_hmac(tfm, hmac_sha1_tv[1].key, strlen(hmac_sha1_tv[1].key), sg, 2, result); crypto_digest_hmac(tfm, hmac_sha1_tv[1].key, strlen(hmac_sha1_tv[1].key), sg, 2, result);
hexdump(result, crypto_tfm_digestsize(tfm)); hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n", memcmp(result, hmac_sha1_tv[1].digest, crypto_tfm_digestsize(tfm)) ? "fail" : "pass"); printk("%s\n", memcmp(result, hmac_sha1_tv[1].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
crypto_free_tfm(tfm); crypto_free_tfm(tfm);
} }
...@@ -360,9 +360,9 @@ void test_des(void) ...@@ -360,9 +360,9 @@ void test_des(void)
memcpy(tvmem, des_enc_tv_template, tsize); memcpy(tvmem, des_enc_tv_template, tsize);
des_tv = (void *)tvmem; des_tv = (void *)tvmem;
tfm = crypto_alloc_tfm(CRYPTO_ALG_DES_ECB); tfm = crypto_alloc_tfm("des", 0);
if (tfm == NULL) { if (tfm == NULL) {
printk("failed to load transform for CRYPTO_ALG_DES_ECB\n"); printk("failed to load transform for des (default ecb)\n");
return; return;
} }
...@@ -370,8 +370,8 @@ void test_des(void) ...@@ -370,8 +370,8 @@ void test_des(void)
printk("test %d:\n", i + 1); printk("test %d:\n", i + 1);
key = des_tv[i].key; key = des_tv[i].key;
tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
tfm->crt_flags = CRYPTO_WEAK_KEY_CHECK;
ret = crypto_cipher_setkey(tfm, key, 8); ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) { if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags); printk("setkey() failed flags=%x\n", tfm->crt_flags);
...@@ -700,7 +700,7 @@ void test_des(void) ...@@ -700,7 +700,7 @@ void test_des(void)
*/ */
i = 7; i = 7;
key = des_tv[i].key; key = des_tv[i].key;
tfm->crt_flags = CRYPTO_ATOMIC; tfm->crt_flags = CRYPTO_TFM_REQ_ATOMIC;
ret = crypto_cipher_setkey(tfm, key, 8); ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) { if (ret) {
...@@ -761,7 +761,6 @@ void test_des(void) ...@@ -761,7 +761,6 @@ void test_des(void)
sg[7].length = 1; sg[7].length = 1;
ret = crypto_cipher_encrypt(tfm, sg, 8); ret = crypto_cipher_encrypt(tfm, sg, 8);
if (ret) { if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags); printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out; goto out;
...@@ -926,9 +925,9 @@ void test_des(void) ...@@ -926,9 +925,9 @@ void test_des(void)
crypto_free_tfm(tfm); crypto_free_tfm(tfm);
tfm = crypto_alloc_tfm(CRYPTO_ALG_DES_CBC); tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC);
if (tfm == NULL) { if (tfm == NULL) {
printk("failed to load transform for CRYPTO_ALG_DES_CBC\n"); printk("failed to load transform for des cbc\n");
return; return;
} }
...@@ -945,7 +944,7 @@ void test_des(void) ...@@ -945,7 +944,7 @@ void test_des(void)
for (i = 0; i < DES_CBC_ENC_TEST_VECTORS; i++) { for (i = 0; i < DES_CBC_ENC_TEST_VECTORS; i++) {
printk("test %d:\n", i + 1); printk("test %d:\n", i + 1);
tfm->crt_flags = CRYPTO_ATOMIC; tfm->crt_flags |= CRYPTO_TFM_REQ_ATOMIC;
key = des_tv[i].key; key = des_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, 8); ret = crypto_cipher_setkey(tfm, key, 8);
...@@ -961,7 +960,7 @@ void test_des(void) ...@@ -961,7 +960,7 @@ void test_des(void)
sg[0].offset = ((long)p & ~PAGE_MASK); sg[0].offset = ((long)p & ~PAGE_MASK);
sg[0].length = len; sg[0].length = len;
crypto_cipher_copy_iv(tfm, des_tv[i].iv, crypto_tfm_ivsize(tfm)); crypto_cipher_copy_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, 1); ret = crypto_cipher_encrypt(tfm, sg, 1);
if (ret) { if (ret) {
...@@ -987,7 +986,7 @@ void test_des(void) ...@@ -987,7 +986,7 @@ void test_des(void)
printk("\ntesting des cbc encryption chunking scenario F\n"); printk("\ntesting des cbc encryption chunking scenario F\n");
i = 4; i = 4;
tfm = crypto_alloc_tfm(CRYPTO_ALG_DES_CBC); tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC);
if (tfm == NULL) { if (tfm == NULL) {
printk("failed to load transform for CRYPTO_ALG_DES_CCB\n"); printk("failed to load transform for CRYPTO_ALG_DES_CCB\n");
return; return;
...@@ -1018,7 +1017,7 @@ void test_des(void) ...@@ -1018,7 +1017,7 @@ void test_des(void)
sg[1].offset = ((long)p & ~PAGE_MASK); sg[1].offset = ((long)p & ~PAGE_MASK);
sg[1].length = 11; sg[1].length = 11;
crypto_cipher_copy_iv(tfm, des_tv[i].iv, crypto_tfm_ivsize(tfm)); crypto_cipher_copy_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, 2); ret = crypto_cipher_encrypt(tfm, sg, 2);
if (ret) { if (ret) {
...@@ -1066,7 +1065,7 @@ void test_des(void) ...@@ -1066,7 +1065,7 @@ void test_des(void)
sg[0].offset = ((long)p & ~PAGE_MASK); sg[0].offset = ((long)p & ~PAGE_MASK);
sg[0].length = len; sg[0].length = len;
crypto_cipher_copy_iv(tfm, des_tv[i].iv, crypto_tfm_blocksize(tfm)); crypto_cipher_copy_iv(tfm, des_tv[i].iv, crypto_tfm_alg_blocksize(tfm));
ret = crypto_cipher_decrypt(tfm, sg, 1); ret = crypto_cipher_decrypt(tfm, sg, 1);
if (ret) { if (ret) {
...@@ -1116,7 +1115,7 @@ void test_des(void) ...@@ -1116,7 +1115,7 @@ void test_des(void)
sg[1].offset = ((long)p & ~PAGE_MASK); sg[1].offset = ((long)p & ~PAGE_MASK);
sg[1].length = 4; sg[1].length = 4;
crypto_cipher_copy_iv(tfm, des_tv[i].iv, crypto_tfm_ivsize(tfm)); crypto_cipher_copy_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_decrypt(tfm, sg, 2); ret = crypto_cipher_decrypt(tfm, sg, 2);
if (ret) { if (ret) {
...@@ -1161,9 +1160,9 @@ void test_des3_ede(void) ...@@ -1161,9 +1160,9 @@ void test_des3_ede(void)
memcpy(tvmem, des3_ede_enc_tv_template, tsize); memcpy(tvmem, des3_ede_enc_tv_template, tsize);
des_tv = (void *)tvmem; des_tv = (void *)tvmem;
tfm = crypto_alloc_tfm(CRYPTO_ALG_DES3_EDE_ECB); tfm = crypto_alloc_tfm("des3_ede", CRYPTO_TFM_MODE_ECB);
if (tfm == NULL) { if (tfm == NULL) {
printk("failed to load transform for CRYPTO_ALG_DES3_EDE_ECB\n"); printk("failed to load transform for 3des ecb\n");
return; return;
} }
...@@ -1171,8 +1170,6 @@ void test_des3_ede(void) ...@@ -1171,8 +1170,6 @@ void test_des3_ede(void)
printk("test %d:\n", i + 1); printk("test %d:\n", i + 1);
key = des_tv[i].key; key = des_tv[i].key;
tfm->crt_flags = CRYPTO_WEAK_KEY_CHECK;
ret = crypto_cipher_setkey(tfm, key, 24); ret = crypto_cipher_setkey(tfm, key, 24);
if (ret) { if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags); printk("setkey() failed flags=%x\n", tfm->crt_flags);
...@@ -1214,8 +1211,6 @@ void test_des3_ede(void) ...@@ -1214,8 +1211,6 @@ void test_des3_ede(void)
printk("test %d:\n", i + 1); printk("test %d:\n", i + 1);
key = des_tv[i].key; key = des_tv[i].key;
tfm->crt_flags = CRYPTO_WEAK_KEY_CHECK;
ret = crypto_cipher_setkey(tfm, key, 24); ret = crypto_cipher_setkey(tfm, key, 24);
if (ret) { if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags); printk("setkey() failed flags=%x\n", tfm->crt_flags);
......
...@@ -16,56 +16,50 @@ ...@@ -16,56 +16,50 @@
#ifndef _LINUX_CRYPTO_H #ifndef _LINUX_CRYPTO_H
#define _LINUX_CRYPTO_H #define _LINUX_CRYPTO_H
/*
* Crypto context flags.
*/
#define CRYPTO_WEAK_KEY_CHECK 0x0001
#define CRYPTO_WEAK_KEY 0x0008
#define CRYPTO_BAD_KEY_LEN 0x0010
#define CRYPTO_BAD_KEY_SCHED 0x0020
#define CRYPTO_BAD_BLOCK_LEN 0x0040
#define CRYPTO_ATOMIC 0x1000
/* /*
* Algorithm identifiers. These may be expanded later to 64 bits * Algorithm masks and types.
* and include vendor id info, so we can have multiple versions
* (e.g. asm, various hardware versions etc).
*
* Todo: sadb translation.
*/ */
#define CRYPTO_TYPE_MASK 0xf0000000 #define CRYPTO_ALG_TYPE_MASK 0x000000ff
#define CRYPTO_MODE_MASK 0x0ff00000 #define CRYPTO_ALG_TYPE_CIPHER 0x00000001
#define CRYPTO_ALG_MASK 0x000fffff #define CRYPTO_ALG_TYPE_DIGEST 0x00000002
#define CRYPTO_ALG_TYPE_COMP 0x00000004
#define CRYPTO_TYPE_CIPHER 0x10000000
#define CRYPTO_TYPE_DIGEST 0x20000000
#define CRYPTO_TYPE_COMP 0x40000000
#define CRYPTO_MODE_ECB 0x00100000 /*
#define CRYPTO_MODE_CBC 0x00200000 * Transform masks and values (for crt_flags).
#define CRYPTO_MODE_CFB 0x00400000 */
#define CRYPTO_MODE_CTR 0x00800000 #define CRYPTO_TFM_MODE_MASK 0x000000ff
#define CRYPTO_TFM_REQ_MASK 0x000fff00
#define CRYPTO_TFM_RES_MASK 0xfff00000
#define CRYPTO_ALG_NULL 0x00000001 #define CRYPTO_TFM_MODE_ECB 0x00000001
#define CRYPTO_TFM_MODE_CBC 0x00000002
#define CRYPTO_TFM_MODE_CFB 0x00000004
#define CRYPTO_TFM_MODE_CTR 0x00000008
#define CRYPTO_ALG_DES (0x00000002|CRYPTO_TYPE_CIPHER) #define CRYPTO_TFM_REQ_ATOMIC 0x00000100
#define CRYPTO_ALG_DES_ECB (CRYPTO_ALG_DES|CRYPTO_MODE_ECB) #define CRYPTO_TFM_REQ_WEAK_KEY 0x00000200
#define CRYPTO_ALG_DES_CBC (CRYPTO_ALG_DES|CRYPTO_MODE_CBC)
#define CRYPTO_ALG_DES3_EDE (0x00000003|CRYPTO_TYPE_CIPHER) #define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
#define CRYPTO_ALG_DES3_EDE_ECB (CRYPTO_ALG_DES3_EDE|CRYPTO_MODE_ECB) #define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
#define CRYPTO_ALG_DES3_EDE_CBC (CRYPTO_ALG_DES3_EDE|CRYPTO_MODE_CBC) #define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000
#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000
#define CRYPTO_ALG_MD4 (0x00000f00|CRYPTO_TYPE_DIGEST)
#define CRYPTO_ALG_MD5 (0x00000f01|CRYPTO_TYPE_DIGEST)
#define CRYPTO_ALG_SHA1 (0x00000f02|CRYPTO_TYPE_DIGEST)
#define CRYPTO_UNSPEC 0 /*
#define CRYPTO_MAX_ALG_NAME 64 * Miscellaneous stuff.
#define CRYPTO_MAX_BLOCK_SIZE 16 */
#define CRYPTO_UNSPEC 0
#define CRYPTO_MAX_ALG_NAME 64
#define CRYPTO_MAX_BLOCK_SIZE 16
struct scatterlist; struct scatterlist;
/*
* Algorithms: modular crypto algorithm implementations, managed
* via crypto_register_alg() and crypto_unregister_alg().
*/
struct cipher_alg { struct cipher_alg {
size_t cia_keysize; size_t cia_keysize;
size_t cia_ivsize; size_t cia_ivsize;
...@@ -92,7 +86,7 @@ struct compress_alg { ...@@ -92,7 +86,7 @@ struct compress_alg {
struct crypto_alg { struct crypto_alg {
struct list_head cra_list; struct list_head cra_list;
u32 cra_id; int cra_flags;
size_t cra_blocksize; size_t cra_blocksize;
size_t cra_ctxsize; size_t cra_ctxsize;
char cra_name[CRYPTO_MAX_ALG_NAME]; char cra_name[CRYPTO_MAX_ALG_NAME];
...@@ -112,11 +106,13 @@ struct crypto_alg { ...@@ -112,11 +106,13 @@ struct crypto_alg {
int crypto_register_alg(struct crypto_alg *alg); int crypto_register_alg(struct crypto_alg *alg);
int crypto_unregister_alg(struct crypto_alg *alg); int crypto_unregister_alg(struct crypto_alg *alg);
struct crypto_tfm;
/* /*
* Transformations: user-instantiated algorithms. * Transforms: user-instantiated objects which encapsulate algorithms
* and core processing logic. Managed via crypto_alloc_tfm() and
* crypto_free_tfm(), as well as the various helpers below.
*/ */
struct crypto_tfm;
struct cipher_tfm { struct cipher_tfm {
void *cit_iv; void *cit_iv;
u32 cit_mode; u32 cit_mode;
...@@ -161,17 +157,61 @@ struct crypto_tfm { ...@@ -161,17 +157,61 @@ struct crypto_tfm {
struct crypto_alg *__crt_alg; struct crypto_alg *__crt_alg;
}; };
/*
* Transform user interface.
*/
/* /*
* Finds specified algorithm, allocates and returns a transform for it. * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
* Will try an load a module based on the name if not present * If that fails and the kernel supports dynamically loadable modules, it
* in the kernel. Increments its algorithm refcount. * will then attempt to load a module of the same name or alias. A refcount
* is grabbed on the algorithm which is then associated with the new transform.
*/ */
struct crypto_tfm *crypto_alloc_tfm(u32 id); struct crypto_tfm *crypto_alloc_tfm(char *alg_name, u32 tfm_flags);
void crypto_free_tfm(struct crypto_tfm *tfm);
/* /*
* Frees the transform and decrements its algorithm's recount. * Transform helpers which query the underlying algorithm.
*/ */
void crypto_free_tfm(struct crypto_tfm *tfm); static inline char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_name;
}
static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
{
struct crypto_alg *alg = tfm->__crt_alg;
if (alg->cra_module)
return alg->cra_module->name;
else
return NULL;
}
static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
}
static inline size_t crypto_tfm_alg_keysize(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_cipher.cia_keysize;
}
static inline size_t crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_cipher.cia_ivsize;
}
static inline size_t crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_blocksize;
}
static inline size_t crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_digest.dia_digestsize;
}
/* /*
* API wrappers. * API wrappers.
...@@ -241,47 +281,4 @@ static inline void crypto_comp_decompress(struct crypto_tfm *tfm) ...@@ -241,47 +281,4 @@ static inline void crypto_comp_decompress(struct crypto_tfm *tfm)
tfm->crt_compress.cot_decompress(tfm); tfm->crt_compress.cot_decompress(tfm);
} }
/*
* Transform helpers which allow the underlying algorithm to be queried.
*/
static inline int crypto_tfm_id(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_id;
}
static inline int crypto_tfm_alg(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_id & CRYPTO_ALG_MASK;
}
static inline char *crypto_tfm_name(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_name;
}
static inline u32 crypto_tfm_type(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_id & CRYPTO_TYPE_MASK;
}
static inline size_t crypto_tfm_keysize(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_cipher.cia_keysize;
}
static inline size_t crypto_tfm_ivsize(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_cipher.cia_ivsize;
}
static inline size_t crypto_tfm_blocksize(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_blocksize;
}
static inline size_t crypto_tfm_digestsize(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_digest.dia_digestsize;
}
#endif /* _LINUX_CRYPTO_H */ #endif /* _LINUX_CRYPTO_H */
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