summaryrefslogtreecommitdiffstats
path: root/crypto/ccm.c
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2017-02-11 14:25:21 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2017-02-15 00:23:45 -0500
commit5338ad7065c0a4cb55e949638b1fdba6b09dc5a2 (patch)
treecb27a7354999fe514c521ff01bdd34ef75cae95c /crypto/ccm.c
parent944c3d4dca34403e802287a1e7e9d02c06dce0d5 (diff)
crypto: ccm - honour alignmask of subordinate MAC cipher
The CCM driver was recently updated to defer the MAC part of the algorithm to a dedicated crypto transform, and a template for instantiating such transforms was added at the same time. However, this new cbcmac template fails to take the alignmask of the encapsulated cipher into account, which may result in buffer addresses being passed down that are not sufficiently aligned. So update the code to ensure that the digest buffer in the desc ctx appears at a sufficiently aligned offset, and tweak the code so that all calls to crypto_cipher_encrypt_one() operate on this buffer exclusively. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/ccm.c')
-rw-r--r--crypto/ccm.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/crypto/ccm.c b/crypto/ccm.c
index 52e307807ff6..24c26ab052ca 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -58,7 +58,6 @@ struct cbcmac_tfm_ctx {
58 58
59struct cbcmac_desc_ctx { 59struct cbcmac_desc_ctx {
60 unsigned int len; 60 unsigned int len;
61 u8 dg[];
62}; 61};
63 62
64static inline struct crypto_ccm_req_priv_ctx *crypto_ccm_reqctx( 63static inline struct crypto_ccm_req_priv_ctx *crypto_ccm_reqctx(
@@ -868,9 +867,10 @@ static int crypto_cbcmac_digest_init(struct shash_desc *pdesc)
868{ 867{
869 struct cbcmac_desc_ctx *ctx = shash_desc_ctx(pdesc); 868 struct cbcmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
870 int bs = crypto_shash_digestsize(pdesc->tfm); 869 int bs = crypto_shash_digestsize(pdesc->tfm);
870 u8 *dg = (u8 *)ctx + crypto_shash_descsize(pdesc->tfm) - bs;
871 871
872 ctx->len = 0; 872 ctx->len = 0;
873 memset(ctx->dg, 0, bs); 873 memset(dg, 0, bs);
874 874
875 return 0; 875 return 0;
876} 876}
@@ -883,17 +883,18 @@ static int crypto_cbcmac_digest_update(struct shash_desc *pdesc, const u8 *p,
883 struct cbcmac_desc_ctx *ctx = shash_desc_ctx(pdesc); 883 struct cbcmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
884 struct crypto_cipher *tfm = tctx->child; 884 struct crypto_cipher *tfm = tctx->child;
885 int bs = crypto_shash_digestsize(parent); 885 int bs = crypto_shash_digestsize(parent);
886 u8 *dg = (u8 *)ctx + crypto_shash_descsize(parent) - bs;
886 887
887 while (len > 0) { 888 while (len > 0) {
888 unsigned int l = min(len, bs - ctx->len); 889 unsigned int l = min(len, bs - ctx->len);
889 890
890 crypto_xor(ctx->dg + ctx->len, p, l); 891 crypto_xor(dg + ctx->len, p, l);
891 ctx->len +=l; 892 ctx->len +=l;
892 len -= l; 893 len -= l;
893 p += l; 894 p += l;
894 895
895 if (ctx->len == bs) { 896 if (ctx->len == bs) {
896 crypto_cipher_encrypt_one(tfm, ctx->dg, ctx->dg); 897 crypto_cipher_encrypt_one(tfm, dg, dg);
897 ctx->len = 0; 898 ctx->len = 0;
898 } 899 }
899 } 900 }
@@ -908,12 +909,12 @@ static int crypto_cbcmac_digest_final(struct shash_desc *pdesc, u8 *out)
908 struct cbcmac_desc_ctx *ctx = shash_desc_ctx(pdesc); 909 struct cbcmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
909 struct crypto_cipher *tfm = tctx->child; 910 struct crypto_cipher *tfm = tctx->child;
910 int bs = crypto_shash_digestsize(parent); 911 int bs = crypto_shash_digestsize(parent);
912 u8 *dg = (u8 *)ctx + crypto_shash_descsize(parent) - bs;
911 913
912 if (ctx->len) 914 if (ctx->len)
913 crypto_cipher_encrypt_one(tfm, out, ctx->dg); 915 crypto_cipher_encrypt_one(tfm, dg, dg);
914 else
915 memcpy(out, ctx->dg, bs);
916 916
917 memcpy(out, dg, bs);
917 return 0; 918 return 0;
918} 919}
919 920
@@ -969,7 +970,8 @@ static int cbcmac_create(struct crypto_template *tmpl, struct rtattr **tb)
969 inst->alg.base.cra_blocksize = 1; 970 inst->alg.base.cra_blocksize = 1;
970 971
971 inst->alg.digestsize = alg->cra_blocksize; 972 inst->alg.digestsize = alg->cra_blocksize;
972 inst->alg.descsize = sizeof(struct cbcmac_desc_ctx) + 973 inst->alg.descsize = ALIGN(sizeof(struct cbcmac_desc_ctx),
974 alg->cra_alignmask + 1) +
973 alg->cra_blocksize; 975 alg->cra_blocksize;
974 976
975 inst->alg.base.cra_ctxsize = sizeof(struct cbcmac_tfm_ctx); 977 inst->alg.base.cra_ctxsize = sizeof(struct cbcmac_tfm_ctx);