aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/gcm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-02 17:53:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-02 17:53:12 -0400
commit797994f81a8b2bdca2eecffa415c1e7a89a4f961 (patch)
tree1383dc469c26ad37fdf960f682d9a48c782935c5 /crypto/gcm.c
parentc8d8566952fda026966784a62f324c8352f77430 (diff)
parent3862de1f6c442d53bd828d39f86d07d933a70605 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto update from Herbert Xu: - XTS mode optimisation for twofish/cast6/camellia/aes on x86 - AVX2/x86_64 implementation for blowfish/twofish/serpent/camellia - SSSE3/AVX/AVX2 optimisations for sha256/sha512 - Added driver for SAHARA2 crypto accelerator - Fix for GMAC when used in non-IPsec secnarios - Added generic CMAC implementation (including IPsec glue) - IP update for crypto/atmel - Support for more than one device in hwrng/timeriomem - Added Broadcom BCM2835 RNG driver - Misc fixes * git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (59 commits) crypto: caam - fix job ring cleanup code crypto: camellia - add AVX2/AES-NI/x86_64 assembler implementation of camellia cipher crypto: serpent - add AVX2/x86_64 assembler implementation of serpent cipher crypto: twofish - add AVX2/x86_64 assembler implementation of twofish cipher crypto: blowfish - add AVX2/x86_64 implementation of blowfish cipher crypto: tcrypt - add async cipher speed tests for blowfish crypto: testmgr - extend camellia test-vectors for camellia-aesni/avx2 crypto: aesni_intel - fix Kconfig problem with CRYPTO_GLUE_HELPER_X86 crypto: aesni_intel - add more optimized XTS mode for x86-64 crypto: x86/camellia-aesni-avx - add more optimized XTS code crypto: cast6-avx: use new optimized XTS code crypto: x86/twofish-avx - use optimized XTS code crypto: x86 - add more optimized XTS-mode for serpent-avx xfrm: add rfc4494 AES-CMAC-96 support crypto: add CMAC support to CryptoAPI crypto: testmgr - add empty test vectors for null ciphers crypto: testmgr - add AES GMAC test vectors crypto: gcm - fix rfc4543 to handle async crypto correctly crypto: gcm - make GMAC work when dst and src are different hwrng: timeriomem - added devicetree hooks ...
Diffstat (limited to 'crypto/gcm.c')
-rw-r--r--crypto/gcm.c116
1 files changed, 97 insertions, 19 deletions
diff --git a/crypto/gcm.c b/crypto/gcm.c
index 13ccbda34ff9..43e1fb05ea54 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -37,8 +37,14 @@ struct crypto_rfc4106_ctx {
37 u8 nonce[4]; 37 u8 nonce[4];
38}; 38};
39 39
40struct crypto_rfc4543_instance_ctx {
41 struct crypto_aead_spawn aead;
42 struct crypto_skcipher_spawn null;
43};
44
40struct crypto_rfc4543_ctx { 45struct crypto_rfc4543_ctx {
41 struct crypto_aead *child; 46 struct crypto_aead *child;
47 struct crypto_blkcipher *null;
42 u8 nonce[4]; 48 u8 nonce[4];
43}; 49};
44 50
@@ -1094,21 +1100,36 @@ static int crypto_rfc4543_setauthsize(struct crypto_aead *parent,
1094 return crypto_aead_setauthsize(ctx->child, authsize); 1100 return crypto_aead_setauthsize(ctx->child, authsize);
1095} 1101}
1096 1102
1103static void crypto_rfc4543_done(struct crypto_async_request *areq, int err)
1104{
1105 struct aead_request *req = areq->data;
1106 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1107 struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req);
1108
1109 if (!err) {
1110 scatterwalk_map_and_copy(rctx->auth_tag, req->dst,
1111 req->cryptlen,
1112 crypto_aead_authsize(aead), 1);
1113 }
1114
1115 aead_request_complete(req, err);
1116}
1117
1097static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, 1118static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
1098 int enc) 1119 bool enc)
1099{ 1120{
1100 struct crypto_aead *aead = crypto_aead_reqtfm(req); 1121 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1101 struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead); 1122 struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead);
1102 struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req); 1123 struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req);
1103 struct aead_request *subreq = &rctx->subreq; 1124 struct aead_request *subreq = &rctx->subreq;
1104 struct scatterlist *dst = req->dst; 1125 struct scatterlist *src = req->src;
1105 struct scatterlist *cipher = rctx->cipher; 1126 struct scatterlist *cipher = rctx->cipher;
1106 struct scatterlist *payload = rctx->payload; 1127 struct scatterlist *payload = rctx->payload;
1107 struct scatterlist *assoc = rctx->assoc; 1128 struct scatterlist *assoc = rctx->assoc;
1108 unsigned int authsize = crypto_aead_authsize(aead); 1129 unsigned int authsize = crypto_aead_authsize(aead);
1109 unsigned int assoclen = req->assoclen; 1130 unsigned int assoclen = req->assoclen;
1110 struct page *dstp; 1131 struct page *srcp;
1111 u8 *vdst; 1132 u8 *vsrc;
1112 u8 *iv = PTR_ALIGN((u8 *)(rctx + 1) + crypto_aead_reqsize(ctx->child), 1133 u8 *iv = PTR_ALIGN((u8 *)(rctx + 1) + crypto_aead_reqsize(ctx->child),
1113 crypto_aead_alignmask(ctx->child) + 1); 1134 crypto_aead_alignmask(ctx->child) + 1);
1114 1135
@@ -1119,19 +1140,19 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
1119 if (enc) 1140 if (enc)
1120 memset(rctx->auth_tag, 0, authsize); 1141 memset(rctx->auth_tag, 0, authsize);
1121 else 1142 else
1122 scatterwalk_map_and_copy(rctx->auth_tag, dst, 1143 scatterwalk_map_and_copy(rctx->auth_tag, src,
1123 req->cryptlen - authsize, 1144 req->cryptlen - authsize,
1124 authsize, 0); 1145 authsize, 0);
1125 1146
1126 sg_init_one(cipher, rctx->auth_tag, authsize); 1147 sg_init_one(cipher, rctx->auth_tag, authsize);
1127 1148
1128 /* construct the aad */ 1149 /* construct the aad */
1129 dstp = sg_page(dst); 1150 srcp = sg_page(src);
1130 vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset; 1151 vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset;
1131 1152
1132 sg_init_table(payload, 2); 1153 sg_init_table(payload, 2);
1133 sg_set_buf(payload, req->iv, 8); 1154 sg_set_buf(payload, req->iv, 8);
1134 scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2); 1155 scatterwalk_crypto_chain(payload, src, vsrc == req->iv + 8, 2);
1135 assoclen += 8 + req->cryptlen - (enc ? 0 : authsize); 1156 assoclen += 8 + req->cryptlen - (enc ? 0 : authsize);
1136 1157
1137 if (req->assoc->length == req->assoclen) { 1158 if (req->assoc->length == req->assoclen) {
@@ -1150,14 +1171,27 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
1150 scatterwalk_crypto_chain(assoc, payload, 0, 2); 1171 scatterwalk_crypto_chain(assoc, payload, 0, 2);
1151 1172
1152 aead_request_set_tfm(subreq, ctx->child); 1173 aead_request_set_tfm(subreq, ctx->child);
1153 aead_request_set_callback(subreq, req->base.flags, req->base.complete, 1174 aead_request_set_callback(subreq, req->base.flags, crypto_rfc4543_done,
1154 req->base.data); 1175 req);
1155 aead_request_set_crypt(subreq, cipher, cipher, enc ? 0 : authsize, iv); 1176 aead_request_set_crypt(subreq, cipher, cipher, enc ? 0 : authsize, iv);
1156 aead_request_set_assoc(subreq, assoc, assoclen); 1177 aead_request_set_assoc(subreq, assoc, assoclen);
1157 1178
1158 return subreq; 1179 return subreq;
1159} 1180}
1160 1181
1182static int crypto_rfc4543_copy_src_to_dst(struct aead_request *req, bool enc)
1183{
1184 struct crypto_aead *aead = crypto_aead_reqtfm(req);
1185 struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead);
1186 unsigned int authsize = crypto_aead_authsize(aead);
1187 unsigned int nbytes = req->cryptlen - (enc ? 0 : authsize);
1188 struct blkcipher_desc desc = {
1189 .tfm = ctx->null,
1190 };
1191
1192 return crypto_blkcipher_encrypt(&desc, req->dst, req->src, nbytes);
1193}
1194
1161static int crypto_rfc4543_encrypt(struct aead_request *req) 1195static int crypto_rfc4543_encrypt(struct aead_request *req)
1162{ 1196{
1163 struct crypto_aead *aead = crypto_aead_reqtfm(req); 1197 struct crypto_aead *aead = crypto_aead_reqtfm(req);
@@ -1165,7 +1199,13 @@ static int crypto_rfc4543_encrypt(struct aead_request *req)
1165 struct aead_request *subreq; 1199 struct aead_request *subreq;
1166 int err; 1200 int err;
1167 1201
1168 subreq = crypto_rfc4543_crypt(req, 1); 1202 if (req->src != req->dst) {
1203 err = crypto_rfc4543_copy_src_to_dst(req, true);
1204 if (err)
1205 return err;
1206 }
1207
1208 subreq = crypto_rfc4543_crypt(req, true);
1169 err = crypto_aead_encrypt(subreq); 1209 err = crypto_aead_encrypt(subreq);
1170 if (err) 1210 if (err)
1171 return err; 1211 return err;
@@ -1178,7 +1218,15 @@ static int crypto_rfc4543_encrypt(struct aead_request *req)
1178 1218
1179static int crypto_rfc4543_decrypt(struct aead_request *req) 1219static int crypto_rfc4543_decrypt(struct aead_request *req)
1180{ 1220{
1181 req = crypto_rfc4543_crypt(req, 0); 1221 int err;
1222
1223 if (req->src != req->dst) {
1224 err = crypto_rfc4543_copy_src_to_dst(req, false);
1225 if (err)
1226 return err;
1227 }
1228
1229 req = crypto_rfc4543_crypt(req, false);
1182 1230
1183 return crypto_aead_decrypt(req); 1231 return crypto_aead_decrypt(req);
1184} 1232}
@@ -1186,16 +1234,25 @@ static int crypto_rfc4543_decrypt(struct aead_request *req)
1186static int crypto_rfc4543_init_tfm(struct crypto_tfm *tfm) 1234static int crypto_rfc4543_init_tfm(struct crypto_tfm *tfm)
1187{ 1235{
1188 struct crypto_instance *inst = (void *)tfm->__crt_alg; 1236 struct crypto_instance *inst = (void *)tfm->__crt_alg;
1189 struct crypto_aead_spawn *spawn = crypto_instance_ctx(inst); 1237 struct crypto_rfc4543_instance_ctx *ictx = crypto_instance_ctx(inst);
1238 struct crypto_aead_spawn *spawn = &ictx->aead;
1190 struct crypto_rfc4543_ctx *ctx = crypto_tfm_ctx(tfm); 1239 struct crypto_rfc4543_ctx *ctx = crypto_tfm_ctx(tfm);
1191 struct crypto_aead *aead; 1240 struct crypto_aead *aead;
1241 struct crypto_blkcipher *null;
1192 unsigned long align; 1242 unsigned long align;
1243 int err = 0;
1193 1244
1194 aead = crypto_spawn_aead(spawn); 1245 aead = crypto_spawn_aead(spawn);
1195 if (IS_ERR(aead)) 1246 if (IS_ERR(aead))
1196 return PTR_ERR(aead); 1247 return PTR_ERR(aead);
1197 1248
1249 null = crypto_spawn_blkcipher(&ictx->null.base);
1250 err = PTR_ERR(null);
1251 if (IS_ERR(null))
1252 goto err_free_aead;
1253
1198 ctx->child = aead; 1254 ctx->child = aead;
1255 ctx->null = null;
1199 1256
1200 align = crypto_aead_alignmask(aead); 1257 align = crypto_aead_alignmask(aead);
1201 align &= ~(crypto_tfm_ctx_alignment() - 1); 1258 align &= ~(crypto_tfm_ctx_alignment() - 1);
@@ -1205,6 +1262,10 @@ static int crypto_rfc4543_init_tfm(struct crypto_tfm *tfm)
1205 align + 16; 1262 align + 16;
1206 1263
1207 return 0; 1264 return 0;
1265
1266err_free_aead:
1267 crypto_free_aead(aead);
1268 return err;
1208} 1269}
1209 1270
1210static void crypto_rfc4543_exit_tfm(struct crypto_tfm *tfm) 1271static void crypto_rfc4543_exit_tfm(struct crypto_tfm *tfm)
@@ -1212,6 +1273,7 @@ static void crypto_rfc4543_exit_tfm(struct crypto_tfm *tfm)
1212 struct crypto_rfc4543_ctx *ctx = crypto_tfm_ctx(tfm); 1273 struct crypto_rfc4543_ctx *ctx = crypto_tfm_ctx(tfm);
1213 1274
1214 crypto_free_aead(ctx->child); 1275 crypto_free_aead(ctx->child);
1276 crypto_free_blkcipher(ctx->null);
1215} 1277}
1216 1278
1217static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb) 1279static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb)
@@ -1220,6 +1282,7 @@ static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb)
1220 struct crypto_instance *inst; 1282 struct crypto_instance *inst;
1221 struct crypto_aead_spawn *spawn; 1283 struct crypto_aead_spawn *spawn;
1222 struct crypto_alg *alg; 1284 struct crypto_alg *alg;
1285 struct crypto_rfc4543_instance_ctx *ctx;
1223 const char *ccm_name; 1286 const char *ccm_name;
1224 int err; 1287 int err;
1225 1288
@@ -1234,11 +1297,12 @@ static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb)
1234 if (IS_ERR(ccm_name)) 1297 if (IS_ERR(ccm_name))
1235 return ERR_CAST(ccm_name); 1298 return ERR_CAST(ccm_name);
1236 1299
1237 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 1300 inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
1238 if (!inst) 1301 if (!inst)
1239 return ERR_PTR(-ENOMEM); 1302 return ERR_PTR(-ENOMEM);
1240 1303
1241 spawn = crypto_instance_ctx(inst); 1304 ctx = crypto_instance_ctx(inst);
1305 spawn = &ctx->aead;
1242 crypto_set_aead_spawn(spawn, inst); 1306 crypto_set_aead_spawn(spawn, inst);
1243 err = crypto_grab_aead(spawn, ccm_name, 0, 1307 err = crypto_grab_aead(spawn, ccm_name, 0,
1244 crypto_requires_sync(algt->type, algt->mask)); 1308 crypto_requires_sync(algt->type, algt->mask));
@@ -1247,15 +1311,23 @@ static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb)
1247 1311
1248 alg = crypto_aead_spawn_alg(spawn); 1312 alg = crypto_aead_spawn_alg(spawn);
1249 1313
1314 crypto_set_skcipher_spawn(&ctx->null, inst);
1315 err = crypto_grab_skcipher(&ctx->null, "ecb(cipher_null)", 0,
1316 CRYPTO_ALG_ASYNC);
1317 if (err)
1318 goto out_drop_alg;
1319
1320 crypto_skcipher_spawn_alg(&ctx->null);
1321
1250 err = -EINVAL; 1322 err = -EINVAL;
1251 1323
1252 /* We only support 16-byte blocks. */ 1324 /* We only support 16-byte blocks. */
1253 if (alg->cra_aead.ivsize != 16) 1325 if (alg->cra_aead.ivsize != 16)
1254 goto out_drop_alg; 1326 goto out_drop_ecbnull;
1255 1327
1256 /* Not a stream cipher? */ 1328 /* Not a stream cipher? */
1257 if (alg->cra_blocksize != 1) 1329 if (alg->cra_blocksize != 1)
1258 goto out_drop_alg; 1330 goto out_drop_ecbnull;
1259 1331
1260 err = -ENAMETOOLONG; 1332 err = -ENAMETOOLONG;
1261 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, 1333 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
@@ -1263,7 +1335,7 @@ static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb)
1263 snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, 1335 snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
1264 "rfc4543(%s)", alg->cra_driver_name) >= 1336 "rfc4543(%s)", alg->cra_driver_name) >=
1265 CRYPTO_MAX_ALG_NAME) 1337 CRYPTO_MAX_ALG_NAME)
1266 goto out_drop_alg; 1338 goto out_drop_ecbnull;
1267 1339
1268 inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD; 1340 inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
1269 inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC; 1341 inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC;
@@ -1290,6 +1362,8 @@ static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb)
1290out: 1362out:
1291 return inst; 1363 return inst;
1292 1364
1365out_drop_ecbnull:
1366 crypto_drop_skcipher(&ctx->null);
1293out_drop_alg: 1367out_drop_alg:
1294 crypto_drop_aead(spawn); 1368 crypto_drop_aead(spawn);
1295out_free_inst: 1369out_free_inst:
@@ -1300,7 +1374,11 @@ out_free_inst:
1300 1374
1301static void crypto_rfc4543_free(struct crypto_instance *inst) 1375static void crypto_rfc4543_free(struct crypto_instance *inst)
1302{ 1376{
1303 crypto_drop_spawn(crypto_instance_ctx(inst)); 1377 struct crypto_rfc4543_instance_ctx *ctx = crypto_instance_ctx(inst);
1378
1379 crypto_drop_aead(&ctx->aead);
1380 crypto_drop_skcipher(&ctx->null);
1381
1304 kfree(inst); 1382 kfree(inst);
1305} 1383}
1306 1384