diff options
author | Tudor Ambarus <tudor.ambarus@freescale.com> | 2014-10-30 12:55:07 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2014-11-06 10:15:03 -0500 |
commit | 5d0429a30f06845af78a696de59e3e8d21252846 (patch) | |
tree | 6142fabf98f93fba6854305a1b2d22a5678eaba8 /drivers/crypto | |
parent | f129430dd87dfe868845292e661b186fbfa89ce3 (diff) |
crypto: caam - add support for rfc4543(gcm(aes))
Add AES-GMAC as an IPSec ESP mechanism to provide
data origin authentication, but not confidentiality.
This method is referred as ENCR_NULL_AUTH_AES_GMAC.
Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/caam/caamalg.c | 458 |
1 files changed, 457 insertions, 1 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 36434d9eefad..48df0520ed46 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c | |||
@@ -83,13 +83,18 @@ | |||
83 | #define DESC_RFC4106_DEC_LEN (DESC_RFC4106_BASE + 14 * CAAM_CMD_SZ) | 83 | #define DESC_RFC4106_DEC_LEN (DESC_RFC4106_BASE + 14 * CAAM_CMD_SZ) |
84 | #define DESC_RFC4106_GIVENC_LEN (DESC_RFC4106_BASE + 21 * CAAM_CMD_SZ) | 84 | #define DESC_RFC4106_GIVENC_LEN (DESC_RFC4106_BASE + 21 * CAAM_CMD_SZ) |
85 | 85 | ||
86 | #define DESC_RFC4543_BASE (3 * CAAM_CMD_SZ) | ||
87 | #define DESC_RFC4543_ENC_LEN (DESC_RFC4543_BASE + 25 * CAAM_CMD_SZ) | ||
88 | #define DESC_RFC4543_DEC_LEN (DESC_RFC4543_BASE + 27 * CAAM_CMD_SZ) | ||
89 | #define DESC_RFC4543_GIVENC_LEN (DESC_RFC4543_BASE + 30 * CAAM_CMD_SZ) | ||
90 | |||
86 | #define DESC_ABLKCIPHER_BASE (3 * CAAM_CMD_SZ) | 91 | #define DESC_ABLKCIPHER_BASE (3 * CAAM_CMD_SZ) |
87 | #define DESC_ABLKCIPHER_ENC_LEN (DESC_ABLKCIPHER_BASE + \ | 92 | #define DESC_ABLKCIPHER_ENC_LEN (DESC_ABLKCIPHER_BASE + \ |
88 | 20 * CAAM_CMD_SZ) | 93 | 20 * CAAM_CMD_SZ) |
89 | #define DESC_ABLKCIPHER_DEC_LEN (DESC_ABLKCIPHER_BASE + \ | 94 | #define DESC_ABLKCIPHER_DEC_LEN (DESC_ABLKCIPHER_BASE + \ |
90 | 15 * CAAM_CMD_SZ) | 95 | 15 * CAAM_CMD_SZ) |
91 | 96 | ||
92 | #define DESC_MAX_USED_BYTES (DESC_AEAD_GIVENC_LEN + \ | 97 | #define DESC_MAX_USED_BYTES (DESC_RFC4543_GIVENC_LEN + \ |
93 | CAAM_MAX_KEY_SIZE) | 98 | CAAM_MAX_KEY_SIZE) |
94 | #define DESC_MAX_USED_LEN (DESC_MAX_USED_BYTES / CAAM_CMD_SZ) | 99 | #define DESC_MAX_USED_LEN (DESC_MAX_USED_BYTES / CAAM_CMD_SZ) |
95 | 100 | ||
@@ -1150,6 +1155,401 @@ static int rfc4106_setauthsize(struct crypto_aead *authenc, | |||
1150 | return 0; | 1155 | return 0; |
1151 | } | 1156 | } |
1152 | 1157 | ||
1158 | static int rfc4543_set_sh_desc(struct crypto_aead *aead) | ||
1159 | { | ||
1160 | struct aead_tfm *tfm = &aead->base.crt_aead; | ||
1161 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
1162 | struct device *jrdev = ctx->jrdev; | ||
1163 | bool keys_fit_inline = false; | ||
1164 | u32 *key_jump_cmd, *write_iv_cmd, *write_aad_cmd; | ||
1165 | u32 *read_move_cmd, *write_move_cmd; | ||
1166 | u32 *desc; | ||
1167 | u32 geniv; | ||
1168 | |||
1169 | if (!ctx->enckeylen || !ctx->authsize) | ||
1170 | return 0; | ||
1171 | |||
1172 | /* | ||
1173 | * RFC4543 encrypt shared descriptor | ||
1174 | * Job Descriptor and Shared Descriptor | ||
1175 | * must fit into the 64-word Descriptor h/w Buffer | ||
1176 | */ | ||
1177 | if (DESC_RFC4543_ENC_LEN + DESC_JOB_IO_LEN + | ||
1178 | ctx->enckeylen <= CAAM_DESC_BYTES_MAX) | ||
1179 | keys_fit_inline = true; | ||
1180 | |||
1181 | desc = ctx->sh_desc_enc; | ||
1182 | |||
1183 | init_sh_desc(desc, HDR_SHARE_SERIAL); | ||
1184 | |||
1185 | /* Skip key loading if it is loaded due to sharing */ | ||
1186 | key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | | ||
1187 | JUMP_COND_SHRD); | ||
1188 | if (keys_fit_inline) | ||
1189 | append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, | ||
1190 | ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); | ||
1191 | else | ||
1192 | append_key(desc, ctx->key_dma, ctx->enckeylen, | ||
1193 | CLASS_1 | KEY_DEST_CLASS_REG); | ||
1194 | set_jump_tgt_here(desc, key_jump_cmd); | ||
1195 | |||
1196 | /* Class 1 operation */ | ||
1197 | append_operation(desc, ctx->class1_alg_type | | ||
1198 | OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); | ||
1199 | |||
1200 | /* Load AES-GMAC ESP IV into Math1 register */ | ||
1201 | append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_WORD_DECO_MATH1 | | ||
1202 | LDST_CLASS_DECO | tfm->ivsize); | ||
1203 | |||
1204 | /* Wait the DMA transaction to finish */ | ||
1205 | append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | | ||
1206 | (1 << JUMP_OFFSET_SHIFT)); | ||
1207 | |||
1208 | /* Overwrite blank immediate AES-GMAC ESP IV data */ | ||
1209 | write_iv_cmd = append_move(desc, MOVE_SRC_MATH1 | MOVE_DEST_DESCBUF | | ||
1210 | (tfm->ivsize << MOVE_LEN_SHIFT)); | ||
1211 | |||
1212 | /* Overwrite blank immediate AAD data */ | ||
1213 | write_aad_cmd = append_move(desc, MOVE_SRC_MATH1 | MOVE_DEST_DESCBUF | | ||
1214 | (tfm->ivsize << MOVE_LEN_SHIFT)); | ||
1215 | |||
1216 | /* cryptlen = seqoutlen - authsize */ | ||
1217 | append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize); | ||
1218 | |||
1219 | /* assoclen = (seqinlen - ivsize) - cryptlen */ | ||
1220 | append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG3, CAAM_CMD_SZ); | ||
1221 | |||
1222 | /* Read Salt and AES-GMAC ESP IV */ | ||
1223 | append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE | | ||
1224 | FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | (4 + tfm->ivsize)); | ||
1225 | /* Append Salt */ | ||
1226 | append_data(desc, (void *)(ctx->key + ctx->enckeylen), 4); | ||
1227 | set_move_tgt_here(desc, write_iv_cmd); | ||
1228 | /* Blank commands. Will be overwritten by AES-GMAC ESP IV. */ | ||
1229 | append_cmd(desc, 0x00000000); | ||
1230 | append_cmd(desc, 0x00000000); | ||
1231 | /* End of blank commands */ | ||
1232 | |||
1233 | /* Read assoc data */ | ||
1234 | append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | | ||
1235 | FIFOLD_TYPE_AAD); | ||
1236 | |||
1237 | /* Will read cryptlen bytes */ | ||
1238 | append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ); | ||
1239 | |||
1240 | /* Will write cryptlen bytes */ | ||
1241 | append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); | ||
1242 | |||
1243 | /* | ||
1244 | * MOVE_LEN opcode is not available in all SEC HW revisions, | ||
1245 | * thus need to do some magic, i.e. self-patch the descriptor | ||
1246 | * buffer. | ||
1247 | */ | ||
1248 | read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 | | ||
1249 | (0x6 << MOVE_LEN_SHIFT)); | ||
1250 | write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF | | ||
1251 | (0x8 << MOVE_LEN_SHIFT)); | ||
1252 | |||
1253 | /* Authenticate AES-GMAC ESP IV */ | ||
1254 | append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE | | ||
1255 | FIFOLD_TYPE_AAD | tfm->ivsize); | ||
1256 | set_move_tgt_here(desc, write_aad_cmd); | ||
1257 | /* Blank commands. Will be overwritten by AES-GMAC ESP IV. */ | ||
1258 | append_cmd(desc, 0x00000000); | ||
1259 | append_cmd(desc, 0x00000000); | ||
1260 | /* End of blank commands */ | ||
1261 | |||
1262 | /* Read and write cryptlen bytes */ | ||
1263 | aead_append_src_dst(desc, FIFOLD_TYPE_AAD); | ||
1264 | |||
1265 | set_move_tgt_here(desc, read_move_cmd); | ||
1266 | set_move_tgt_here(desc, write_move_cmd); | ||
1267 | append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); | ||
1268 | /* Move payload data to OFIFO */ | ||
1269 | append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO); | ||
1270 | |||
1271 | /* Write ICV */ | ||
1272 | append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB | | ||
1273 | LDST_SRCDST_BYTE_CONTEXT); | ||
1274 | |||
1275 | ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc, | ||
1276 | desc_bytes(desc), | ||
1277 | DMA_TO_DEVICE); | ||
1278 | if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) { | ||
1279 | dev_err(jrdev, "unable to map shared descriptor\n"); | ||
1280 | return -ENOMEM; | ||
1281 | } | ||
1282 | #ifdef DEBUG | ||
1283 | print_hex_dump(KERN_ERR, "rfc4543 enc shdesc@"__stringify(__LINE__)": ", | ||
1284 | DUMP_PREFIX_ADDRESS, 16, 4, desc, | ||
1285 | desc_bytes(desc), 1); | ||
1286 | #endif | ||
1287 | |||
1288 | /* | ||
1289 | * Job Descriptor and Shared Descriptors | ||
1290 | * must all fit into the 64-word Descriptor h/w Buffer | ||
1291 | */ | ||
1292 | keys_fit_inline = false; | ||
1293 | if (DESC_RFC4543_DEC_LEN + DESC_JOB_IO_LEN + | ||
1294 | ctx->enckeylen <= CAAM_DESC_BYTES_MAX) | ||
1295 | keys_fit_inline = true; | ||
1296 | |||
1297 | desc = ctx->sh_desc_dec; | ||
1298 | |||
1299 | init_sh_desc(desc, HDR_SHARE_SERIAL); | ||
1300 | |||
1301 | /* Skip key loading if it is loaded due to sharing */ | ||
1302 | key_jump_cmd = append_jump(desc, JUMP_JSL | | ||
1303 | JUMP_TEST_ALL | JUMP_COND_SHRD); | ||
1304 | if (keys_fit_inline) | ||
1305 | append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, | ||
1306 | ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); | ||
1307 | else | ||
1308 | append_key(desc, ctx->key_dma, ctx->enckeylen, | ||
1309 | CLASS_1 | KEY_DEST_CLASS_REG); | ||
1310 | set_jump_tgt_here(desc, key_jump_cmd); | ||
1311 | |||
1312 | /* Class 1 operation */ | ||
1313 | append_operation(desc, ctx->class1_alg_type | | ||
1314 | OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON); | ||
1315 | |||
1316 | /* Load AES-GMAC ESP IV into Math1 register */ | ||
1317 | append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_WORD_DECO_MATH1 | | ||
1318 | LDST_CLASS_DECO | tfm->ivsize); | ||
1319 | |||
1320 | /* Wait the DMA transaction to finish */ | ||
1321 | append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | | ||
1322 | (1 << JUMP_OFFSET_SHIFT)); | ||
1323 | |||
1324 | /* assoclen + cryptlen = (seqinlen - ivsize) - icvsize */ | ||
1325 | append_math_sub_imm_u32(desc, REG3, SEQINLEN, IMM, ctx->authsize); | ||
1326 | |||
1327 | /* Overwrite blank immediate AES-GMAC ESP IV data */ | ||
1328 | write_iv_cmd = append_move(desc, MOVE_SRC_MATH1 | MOVE_DEST_DESCBUF | | ||
1329 | (tfm->ivsize << MOVE_LEN_SHIFT)); | ||
1330 | |||
1331 | /* Overwrite blank immediate AAD data */ | ||
1332 | write_aad_cmd = append_move(desc, MOVE_SRC_MATH1 | MOVE_DEST_DESCBUF | | ||
1333 | (tfm->ivsize << MOVE_LEN_SHIFT)); | ||
1334 | |||
1335 | /* assoclen = (assoclen + cryptlen) - cryptlen */ | ||
1336 | append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ); | ||
1337 | append_math_sub(desc, VARSEQINLEN, REG3, REG2, CAAM_CMD_SZ); | ||
1338 | |||
1339 | /* | ||
1340 | * MOVE_LEN opcode is not available in all SEC HW revisions, | ||
1341 | * thus need to do some magic, i.e. self-patch the descriptor | ||
1342 | * buffer. | ||
1343 | */ | ||
1344 | read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 | | ||
1345 | (0x6 << MOVE_LEN_SHIFT)); | ||
1346 | write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF | | ||
1347 | (0x8 << MOVE_LEN_SHIFT)); | ||
1348 | |||
1349 | /* Read Salt and AES-GMAC ESP IV */ | ||
1350 | append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE | | ||
1351 | FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | (4 + tfm->ivsize)); | ||
1352 | /* Append Salt */ | ||
1353 | append_data(desc, (void *)(ctx->key + ctx->enckeylen), 4); | ||
1354 | set_move_tgt_here(desc, write_iv_cmd); | ||
1355 | /* Blank commands. Will be overwritten by AES-GMAC ESP IV. */ | ||
1356 | append_cmd(desc, 0x00000000); | ||
1357 | append_cmd(desc, 0x00000000); | ||
1358 | /* End of blank commands */ | ||
1359 | |||
1360 | /* Read assoc data */ | ||
1361 | append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | | ||
1362 | FIFOLD_TYPE_AAD); | ||
1363 | |||
1364 | /* Will read cryptlen bytes */ | ||
1365 | append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ); | ||
1366 | |||
1367 | /* Will write cryptlen bytes */ | ||
1368 | append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ); | ||
1369 | |||
1370 | /* Authenticate AES-GMAC ESP IV */ | ||
1371 | append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE | | ||
1372 | FIFOLD_TYPE_AAD | tfm->ivsize); | ||
1373 | set_move_tgt_here(desc, write_aad_cmd); | ||
1374 | /* Blank commands. Will be overwritten by AES-GMAC ESP IV. */ | ||
1375 | append_cmd(desc, 0x00000000); | ||
1376 | append_cmd(desc, 0x00000000); | ||
1377 | /* End of blank commands */ | ||
1378 | |||
1379 | /* Store payload data */ | ||
1380 | append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF); | ||
1381 | |||
1382 | /* In-snoop cryptlen data */ | ||
1383 | append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF | | ||
1384 | FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1); | ||
1385 | |||
1386 | set_move_tgt_here(desc, read_move_cmd); | ||
1387 | set_move_tgt_here(desc, write_move_cmd); | ||
1388 | append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); | ||
1389 | /* Move payload data to OFIFO */ | ||
1390 | append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO); | ||
1391 | append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO); | ||
1392 | |||
1393 | /* Read ICV */ | ||
1394 | append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 | | ||
1395 | FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1); | ||
1396 | |||
1397 | ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc, | ||
1398 | desc_bytes(desc), | ||
1399 | DMA_TO_DEVICE); | ||
1400 | if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) { | ||
1401 | dev_err(jrdev, "unable to map shared descriptor\n"); | ||
1402 | return -ENOMEM; | ||
1403 | } | ||
1404 | #ifdef DEBUG | ||
1405 | print_hex_dump(KERN_ERR, "rfc4543 dec shdesc@"__stringify(__LINE__)": ", | ||
1406 | DUMP_PREFIX_ADDRESS, 16, 4, desc, | ||
1407 | desc_bytes(desc), 1); | ||
1408 | #endif | ||
1409 | |||
1410 | /* | ||
1411 | * Job Descriptor and Shared Descriptors | ||
1412 | * must all fit into the 64-word Descriptor h/w Buffer | ||
1413 | */ | ||
1414 | keys_fit_inline = false; | ||
1415 | if (DESC_RFC4543_GIVENC_LEN + DESC_JOB_IO_LEN + | ||
1416 | ctx->enckeylen <= CAAM_DESC_BYTES_MAX) | ||
1417 | keys_fit_inline = true; | ||
1418 | |||
1419 | /* rfc4543_givencrypt shared descriptor */ | ||
1420 | desc = ctx->sh_desc_givenc; | ||
1421 | |||
1422 | init_sh_desc(desc, HDR_SHARE_SERIAL); | ||
1423 | |||
1424 | /* Skip key loading if it is loaded due to sharing */ | ||
1425 | key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | | ||
1426 | JUMP_COND_SHRD); | ||
1427 | if (keys_fit_inline) | ||
1428 | append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, | ||
1429 | ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); | ||
1430 | else | ||
1431 | append_key(desc, ctx->key_dma, ctx->enckeylen, | ||
1432 | CLASS_1 | KEY_DEST_CLASS_REG); | ||
1433 | set_jump_tgt_here(desc, key_jump_cmd); | ||
1434 | |||
1435 | /* Generate IV */ | ||
1436 | geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO | | ||
1437 | NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 | | ||
1438 | NFIFOENTRY_PTYPE_RND | (tfm->ivsize << NFIFOENTRY_DLEN_SHIFT); | ||
1439 | append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB | | ||
1440 | LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM); | ||
1441 | append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); | ||
1442 | /* Move generated IV to Math1 register */ | ||
1443 | append_move(desc, MOVE_SRC_INFIFO | MOVE_DEST_MATH1 | | ||
1444 | (tfm->ivsize << MOVE_LEN_SHIFT)); | ||
1445 | append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO); | ||
1446 | |||
1447 | /* Overwrite blank immediate AES-GMAC IV data */ | ||
1448 | write_iv_cmd = append_move(desc, MOVE_SRC_MATH1 | MOVE_DEST_DESCBUF | | ||
1449 | (tfm->ivsize << MOVE_LEN_SHIFT)); | ||
1450 | |||
1451 | /* Overwrite blank immediate AAD data */ | ||
1452 | write_aad_cmd = append_move(desc, MOVE_SRC_MATH1 | MOVE_DEST_DESCBUF | | ||
1453 | (tfm->ivsize << MOVE_LEN_SHIFT)); | ||
1454 | |||
1455 | /* Copy generated IV to OFIFO */ | ||
1456 | append_move(desc, MOVE_SRC_MATH1 | MOVE_DEST_OUTFIFO | | ||
1457 | (tfm->ivsize << MOVE_LEN_SHIFT)); | ||
1458 | |||
1459 | /* Class 1 operation */ | ||
1460 | append_operation(desc, ctx->class1_alg_type | | ||
1461 | OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); | ||
1462 | |||
1463 | /* ivsize + cryptlen = seqoutlen - authsize */ | ||
1464 | append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize); | ||
1465 | |||
1466 | /* assoclen = seqinlen - (ivsize + cryptlen) */ | ||
1467 | append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG3, CAAM_CMD_SZ); | ||
1468 | |||
1469 | /* Will write ivsize + cryptlen */ | ||
1470 | append_math_add(desc, VARSEQOUTLEN, REG3, REG0, CAAM_CMD_SZ); | ||
1471 | |||
1472 | /* | ||
1473 | * MOVE_LEN opcode is not available in all SEC HW revisions, | ||
1474 | * thus need to do some magic, i.e. self-patch the descriptor | ||
1475 | * buffer. | ||
1476 | */ | ||
1477 | read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 | | ||
1478 | (0x6 << MOVE_LEN_SHIFT)); | ||
1479 | write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF | | ||
1480 | (0x8 << MOVE_LEN_SHIFT)); | ||
1481 | |||
1482 | /* Read Salt and AES-GMAC generated IV */ | ||
1483 | append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE | | ||
1484 | FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | (4 + tfm->ivsize)); | ||
1485 | /* Append Salt */ | ||
1486 | append_data(desc, (void *)(ctx->key + ctx->enckeylen), 4); | ||
1487 | set_move_tgt_here(desc, write_iv_cmd); | ||
1488 | /* Blank commands. Will be overwritten by AES-GMAC generated IV. */ | ||
1489 | append_cmd(desc, 0x00000000); | ||
1490 | append_cmd(desc, 0x00000000); | ||
1491 | /* End of blank commands */ | ||
1492 | |||
1493 | /* No need to reload iv */ | ||
1494 | append_seq_fifo_load(desc, tfm->ivsize, FIFOLD_CLASS_SKIP); | ||
1495 | |||
1496 | /* Read assoc data */ | ||
1497 | append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | | ||
1498 | FIFOLD_TYPE_AAD); | ||
1499 | |||
1500 | /* Will read cryptlen */ | ||
1501 | append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); | ||
1502 | |||
1503 | /* Authenticate AES-GMAC IV */ | ||
1504 | append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE | | ||
1505 | FIFOLD_TYPE_AAD | tfm->ivsize); | ||
1506 | set_move_tgt_here(desc, write_aad_cmd); | ||
1507 | /* Blank commands. Will be overwritten by AES-GMAC IV. */ | ||
1508 | append_cmd(desc, 0x00000000); | ||
1509 | append_cmd(desc, 0x00000000); | ||
1510 | /* End of blank commands */ | ||
1511 | |||
1512 | /* Read and write cryptlen bytes */ | ||
1513 | aead_append_src_dst(desc, FIFOLD_TYPE_AAD); | ||
1514 | |||
1515 | set_move_tgt_here(desc, read_move_cmd); | ||
1516 | set_move_tgt_here(desc, write_move_cmd); | ||
1517 | append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); | ||
1518 | /* Move payload data to OFIFO */ | ||
1519 | append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO); | ||
1520 | |||
1521 | /* Write ICV */ | ||
1522 | append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB | | ||
1523 | LDST_SRCDST_BYTE_CONTEXT); | ||
1524 | |||
1525 | ctx->sh_desc_givenc_dma = dma_map_single(jrdev, desc, | ||
1526 | desc_bytes(desc), | ||
1527 | DMA_TO_DEVICE); | ||
1528 | if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) { | ||
1529 | dev_err(jrdev, "unable to map shared descriptor\n"); | ||
1530 | return -ENOMEM; | ||
1531 | } | ||
1532 | #ifdef DEBUG | ||
1533 | print_hex_dump(KERN_ERR, | ||
1534 | "rfc4543 givenc shdesc@"__stringify(__LINE__)": ", | ||
1535 | DUMP_PREFIX_ADDRESS, 16, 4, desc, | ||
1536 | desc_bytes(desc), 1); | ||
1537 | #endif | ||
1538 | |||
1539 | return 0; | ||
1540 | } | ||
1541 | |||
1542 | static int rfc4543_setauthsize(struct crypto_aead *authenc, | ||
1543 | unsigned int authsize) | ||
1544 | { | ||
1545 | struct caam_ctx *ctx = crypto_aead_ctx(authenc); | ||
1546 | |||
1547 | ctx->authsize = authsize; | ||
1548 | rfc4543_set_sh_desc(authenc); | ||
1549 | |||
1550 | return 0; | ||
1551 | } | ||
1552 | |||
1153 | static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in, | 1553 | static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in, |
1154 | u32 authkeylen) | 1554 | u32 authkeylen) |
1155 | { | 1555 | { |
@@ -1292,6 +1692,45 @@ static int rfc4106_setkey(struct crypto_aead *aead, | |||
1292 | return ret; | 1692 | return ret; |
1293 | } | 1693 | } |
1294 | 1694 | ||
1695 | static int rfc4543_setkey(struct crypto_aead *aead, | ||
1696 | const u8 *key, unsigned int keylen) | ||
1697 | { | ||
1698 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
1699 | struct device *jrdev = ctx->jrdev; | ||
1700 | int ret = 0; | ||
1701 | |||
1702 | if (keylen < 4) | ||
1703 | return -EINVAL; | ||
1704 | |||
1705 | #ifdef DEBUG | ||
1706 | print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ", | ||
1707 | DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); | ||
1708 | #endif | ||
1709 | |||
1710 | memcpy(ctx->key, key, keylen); | ||
1711 | |||
1712 | /* | ||
1713 | * The last four bytes of the key material are used as the salt value | ||
1714 | * in the nonce. Update the AES key length. | ||
1715 | */ | ||
1716 | ctx->enckeylen = keylen - 4; | ||
1717 | |||
1718 | ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->enckeylen, | ||
1719 | DMA_TO_DEVICE); | ||
1720 | if (dma_mapping_error(jrdev, ctx->key_dma)) { | ||
1721 | dev_err(jrdev, "unable to map key i/o memory\n"); | ||
1722 | return -ENOMEM; | ||
1723 | } | ||
1724 | |||
1725 | ret = rfc4543_set_sh_desc(aead); | ||
1726 | if (ret) { | ||
1727 | dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen, | ||
1728 | DMA_TO_DEVICE); | ||
1729 | } | ||
1730 | |||
1731 | return ret; | ||
1732 | } | ||
1733 | |||
1295 | static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, | 1734 | static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, |
1296 | const u8 *key, unsigned int keylen) | 1735 | const u8 *key, unsigned int keylen) |
1297 | { | 1736 | { |
@@ -3011,6 +3450,23 @@ static struct caam_alg_template driver_algs[] = { | |||
3011 | }, | 3450 | }, |
3012 | .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, | 3451 | .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, |
3013 | }, | 3452 | }, |
3453 | { | ||
3454 | .name = "rfc4543(gcm(aes))", | ||
3455 | .driver_name = "rfc4543-gcm-aes-caam", | ||
3456 | .blocksize = 1, | ||
3457 | .type = CRYPTO_ALG_TYPE_AEAD, | ||
3458 | .template_aead = { | ||
3459 | .setkey = rfc4543_setkey, | ||
3460 | .setauthsize = rfc4543_setauthsize, | ||
3461 | .encrypt = aead_encrypt, | ||
3462 | .decrypt = aead_decrypt, | ||
3463 | .givencrypt = aead_givencrypt, | ||
3464 | .geniv = "<built-in>", | ||
3465 | .ivsize = 8, | ||
3466 | .maxauthsize = AES_BLOCK_SIZE, | ||
3467 | }, | ||
3468 | .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, | ||
3469 | }, | ||
3014 | /* Galois Counter Mode */ | 3470 | /* Galois Counter Mode */ |
3015 | { | 3471 | { |
3016 | .name = "gcm(aes)", | 3472 | .name = "gcm(aes)", |