diff options
| author | James Morris <jmorris@redhat.com> | 2004-03-21 06:36:22 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-03-21 06:36:22 -0800 |
| commit | 5654cd6cccf5d2a1eec0f8d60b5196fd454f523a (patch) | |
| tree | 24e4d4124df920be8916acb43a988468c15b2c5e | |
| parent | c81430b50f55670cd5bef96242021943832e4470 (diff) | |
[CRYPTO]: Add setkey operation for digests.
From Jouni Malinen <jkmaline@cc.hut.fi>
Added support for using keyed digest with an optional dit_setkey handler.
This does not change the behavior of the existing digest algorithms, but
allows new ones to add setkey handler that can be used to initialize the
algorithm with a key or seed. setkey is to be called after init, but before
any of the update call(s).
| -rw-r--r-- | crypto/digest.c | 10 | ||||
| -rw-r--r-- | crypto/tcrypt.c | 4 | ||||
| -rw-r--r-- | crypto/tcrypt.h | 2 | ||||
| -rw-r--r-- | include/linux/crypto.h | 13 |
4 files changed, 29 insertions, 0 deletions
diff --git a/crypto/digest.c b/crypto/digest.c index a62327d3c37b..30dabe203d30 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -42,6 +42,15 @@ static void final(struct crypto_tfm *tfm, u8 *out) tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); } +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) +{ + u32 flags; + if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) + return -ENOSYS; + return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), + key, keylen, &flags); +} + static void digest(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out) { @@ -72,6 +81,7 @@ int crypto_init_digest_ops(struct crypto_tfm *tfm) ops->dit_update = update; ops->dit_final = final; ops->dit_digest = digest; + ops->dit_setkey = setkey; return crypto_alloc_hmac_block(tfm); } diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 0208e531315f..0caf31954330 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -112,6 +112,10 @@ test_hash (char * algo, struct hash_testvec * template, unsigned int tcount) sg[0].length = hash_tv[i].psize; crypto_digest_init (tfm); + if (tfm->crt_u.digest.dit_setkey) { + crypto_digest_setkey (tfm, hash_tv[i].key, + hash_tv[i].ksize); + } crypto_digest_update (tfm, sg, 1); crypto_digest_final (tfm, result); diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h index 0880165b1400..f4a6f3dd5ec1 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h @@ -30,6 +30,8 @@ struct hash_testvec { char digest[MAX_DIGEST_SIZE]; unsigned char np; unsigned char tap[MAX_TAP]; + char key[128]; /* only used with keyed hash algorithms */ + unsigned char ksize; }; struct hmac_testvec { diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 2331966abe8f..0f0d8a9f5b53 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -76,6 +76,8 @@ struct digest_alg { void (*dia_init)(void *ctx); void (*dia_update)(void *ctx, const u8 *data, unsigned int len); void (*dia_final)(void *ctx, u8 *out); + int (*dia_setkey)(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags); }; struct compress_alg { @@ -157,6 +159,8 @@ struct digest_tfm { void (*dit_final)(struct crypto_tfm *tfm, u8 *out); void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out); + int (*dit_setkey)(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen); #ifdef CONFIG_CRYPTO_HMAC void *dit_hmac_block; #endif @@ -282,6 +286,15 @@ static inline void crypto_digest_digest(struct crypto_tfm *tfm, tfm->crt_digest.dit_digest(tfm, sg, nsg, out); } +static inline int crypto_digest_setkey(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + if (tfm->crt_digest.dit_setkey == NULL) + return -ENOSYS; + return tfm->crt_digest.dit_setkey(tfm, key, keylen); +} + static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { |
