summaryrefslogtreecommitdiffstats
path: root/crypto/testmgr.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2019-05-28 12:40:55 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2019-06-06 02:38:57 -0400
commitd8ea98aa3cd4646945a2a9b647c2502b1e2dcdec (patch)
treed2e24e3559521e8611f0df26c164b32047c320f3 /crypto/testmgr.c
parent6bd934de1e393466b319d29c4427598fda096c57 (diff)
crypto: testmgr - test the shash API
For hash algorithms implemented using the "shash" algorithm type, test both the ahash and shash APIs, not just the ahash API. Testing the ahash API already tests the shash API indirectly, which is normally good enough. However, there have been corner cases where there have been shash bugs that don't get exposed through the ahash API. So, update testmgr to test the shash API too. This would have detected the arm64 SHA-1 and SHA-2 bugs for which fixes were just sent out (https://patchwork.kernel.org/patch/10964843/ and https://patchwork.kernel.org/patch/10965089/): alg: shash: sha1-ce test failed (wrong result) on test vector 0, cfg="init+finup aligned buffer" alg: shash: sha224-ce test failed (wrong result) on test vector 0, cfg="init+finup aligned buffer" alg: shash: sha256-ce test failed (wrong result) on test vector 0, cfg="init+finup aligned buffer" This also would have detected the bugs fixed by commit 307508d10729 ("crypto: crct10dif-generic - fix use via crypto_shash_digest()") and commit dec3d0b1071a ("crypto: x86/crct10dif-pcl - fix use via crypto_shash_digest()"). Signed-off-by: Eric Biggers <ebiggers@google.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r--crypto/testmgr.c402
1 files changed, 335 insertions, 67 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index c9e67c2bd725..a347be142323 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1037,6 +1037,205 @@ static void crypto_reenable_simd_for_test(void)
1037} 1037}
1038#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 1038#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
1039 1039
1040static int build_hash_sglist(struct test_sglist *tsgl,
1041 const struct hash_testvec *vec,
1042 const struct testvec_config *cfg,
1043 unsigned int alignmask,
1044 const struct test_sg_division *divs[XBUFSIZE])
1045{
1046 struct kvec kv;
1047 struct iov_iter input;
1048
1049 kv.iov_base = (void *)vec->plaintext;
1050 kv.iov_len = vec->psize;
1051 iov_iter_kvec(&input, WRITE, &kv, 1, vec->psize);
1052 return build_test_sglist(tsgl, cfg->src_divs, alignmask, vec->psize,
1053 &input, divs);
1054}
1055
1056static int check_hash_result(const char *type,
1057 const u8 *result, unsigned int digestsize,
1058 const struct hash_testvec *vec,
1059 const char *vec_name,
1060 const char *driver,
1061 const struct testvec_config *cfg)
1062{
1063 if (memcmp(result, vec->digest, digestsize) != 0) {
1064 pr_err("alg: %s: %s test failed (wrong result) on test vector %s, cfg=\"%s\"\n",
1065 type, driver, vec_name, cfg->name);
1066 return -EINVAL;
1067 }
1068 if (!testmgr_is_poison(&result[digestsize], TESTMGR_POISON_LEN)) {
1069 pr_err("alg: %s: %s overran result buffer on test vector %s, cfg=\"%s\"\n",
1070 type, driver, vec_name, cfg->name);
1071 return -EOVERFLOW;
1072 }
1073 return 0;
1074}
1075
1076static inline int check_shash_op(const char *op, int err,
1077 const char *driver, const char *vec_name,
1078 const struct testvec_config *cfg)
1079{
1080 if (err)
1081 pr_err("alg: shash: %s %s() failed with err %d on test vector %s, cfg=\"%s\"\n",
1082 driver, op, err, vec_name, cfg->name);
1083 return err;
1084}
1085
1086static inline const void *sg_data(struct scatterlist *sg)
1087{
1088 return page_address(sg_page(sg)) + sg->offset;
1089}
1090
1091/* Test one hash test vector in one configuration, using the shash API */
1092static int test_shash_vec_cfg(const char *driver,
1093 const struct hash_testvec *vec,
1094 const char *vec_name,
1095 const struct testvec_config *cfg,
1096 struct shash_desc *desc,
1097 struct test_sglist *tsgl,
1098 u8 *hashstate)
1099{
1100 struct crypto_shash *tfm = desc->tfm;
1101 const unsigned int alignmask = crypto_shash_alignmask(tfm);
1102 const unsigned int digestsize = crypto_shash_digestsize(tfm);
1103 const unsigned int statesize = crypto_shash_statesize(tfm);
1104 const struct test_sg_division *divs[XBUFSIZE];
1105 unsigned int i;
1106 u8 result[HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN];
1107 int err;
1108
1109 /* Set the key, if specified */
1110 if (vec->ksize) {
1111 err = crypto_shash_setkey(tfm, vec->key, vec->ksize);
1112 if (err) {
1113 if (err == vec->setkey_error)
1114 return 0;
1115 pr_err("alg: shash: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n",
1116 driver, vec_name, vec->setkey_error, err,
1117 crypto_shash_get_flags(tfm));
1118 return err;
1119 }
1120 if (vec->setkey_error) {
1121 pr_err("alg: shash: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n",
1122 driver, vec_name, vec->setkey_error);
1123 return -EINVAL;
1124 }
1125 }
1126
1127 /* Build the scatterlist for the source data */
1128 err = build_hash_sglist(tsgl, vec, cfg, alignmask, divs);
1129 if (err) {
1130 pr_err("alg: shash: %s: error preparing scatterlist for test vector %s, cfg=\"%s\"\n",
1131 driver, vec_name, cfg->name);
1132 return err;
1133 }
1134
1135 /* Do the actual hashing */
1136
1137 testmgr_poison(desc->__ctx, crypto_shash_descsize(tfm));
1138 testmgr_poison(result, digestsize + TESTMGR_POISON_LEN);
1139
1140 if (cfg->finalization_type == FINALIZATION_TYPE_DIGEST ||
1141 vec->digest_error) {
1142 /* Just using digest() */
1143 if (tsgl->nents != 1)
1144 return 0;
1145 if (cfg->nosimd)
1146 crypto_disable_simd_for_test();
1147 err = crypto_shash_digest(desc, sg_data(&tsgl->sgl[0]),
1148 tsgl->sgl[0].length, result);
1149 if (cfg->nosimd)
1150 crypto_reenable_simd_for_test();
1151 if (err) {
1152 if (err == vec->digest_error)
1153 return 0;
1154 pr_err("alg: shash: %s digest() failed on test vector %s; expected_error=%d, actual_error=%d, cfg=\"%s\"\n",
1155 driver, vec_name, vec->digest_error, err,
1156 cfg->name);
1157 return err;
1158 }
1159 if (vec->digest_error) {
1160 pr_err("alg: shash: %s digest() unexpectedly succeeded on test vector %s; expected_error=%d, cfg=\"%s\"\n",
1161 driver, vec_name, vec->digest_error, cfg->name);
1162 return -EINVAL;
1163 }
1164 goto result_ready;
1165 }
1166
1167 /* Using init(), zero or more update(), then final() or finup() */
1168
1169 if (cfg->nosimd)
1170 crypto_disable_simd_for_test();
1171 err = crypto_shash_init(desc);
1172 if (cfg->nosimd)
1173 crypto_reenable_simd_for_test();
1174 err = check_shash_op("init", err, driver, vec_name, cfg);
1175 if (err)
1176 return err;
1177
1178 for (i = 0; i < tsgl->nents; i++) {
1179 if (i + 1 == tsgl->nents &&
1180 cfg->finalization_type == FINALIZATION_TYPE_FINUP) {
1181 if (divs[i]->nosimd)
1182 crypto_disable_simd_for_test();
1183 err = crypto_shash_finup(desc, sg_data(&tsgl->sgl[i]),
1184 tsgl->sgl[i].length, result);
1185 if (divs[i]->nosimd)
1186 crypto_reenable_simd_for_test();
1187 err = check_shash_op("finup", err, driver, vec_name,
1188 cfg);
1189 if (err)
1190 return err;
1191 goto result_ready;
1192 }
1193 if (divs[i]->nosimd)
1194 crypto_disable_simd_for_test();
1195 err = crypto_shash_update(desc, sg_data(&tsgl->sgl[i]),
1196 tsgl->sgl[i].length);
1197 if (divs[i]->nosimd)
1198 crypto_reenable_simd_for_test();
1199 err = check_shash_op("update", err, driver, vec_name, cfg);
1200 if (err)
1201 return err;
1202 if (divs[i]->flush_type == FLUSH_TYPE_REIMPORT) {
1203 /* Test ->export() and ->import() */
1204 testmgr_poison(hashstate + statesize,
1205 TESTMGR_POISON_LEN);
1206 err = crypto_shash_export(desc, hashstate);
1207 err = check_shash_op("export", err, driver, vec_name,
1208 cfg);
1209 if (err)
1210 return err;
1211 if (!testmgr_is_poison(hashstate + statesize,
1212 TESTMGR_POISON_LEN)) {
1213 pr_err("alg: shash: %s export() overran state buffer on test vector %s, cfg=\"%s\"\n",
1214 driver, vec_name, cfg->name);
1215 return -EOVERFLOW;
1216 }
1217 testmgr_poison(desc->__ctx, crypto_shash_descsize(tfm));
1218 err = crypto_shash_import(desc, hashstate);
1219 err = check_shash_op("import", err, driver, vec_name,
1220 cfg);
1221 if (err)
1222 return err;
1223 }
1224 }
1225
1226 if (cfg->nosimd)
1227 crypto_disable_simd_for_test();
1228 err = crypto_shash_final(desc, result);
1229 if (cfg->nosimd)
1230 crypto_reenable_simd_for_test();
1231 err = check_shash_op("final", err, driver, vec_name, cfg);
1232 if (err)
1233 return err;
1234result_ready:
1235 return check_hash_result("shash", result, digestsize, vec, vec_name,
1236 driver, cfg);
1237}
1238
1040static int do_ahash_op(int (*op)(struct ahash_request *req), 1239static int do_ahash_op(int (*op)(struct ahash_request *req),
1041 struct ahash_request *req, 1240 struct ahash_request *req,
1042 struct crypto_wait *wait, bool nosimd) 1241 struct crypto_wait *wait, bool nosimd)
@@ -1054,31 +1253,32 @@ static int do_ahash_op(int (*op)(struct ahash_request *req),
1054 return crypto_wait_req(err, wait); 1253 return crypto_wait_req(err, wait);
1055} 1254}
1056 1255
1057static int check_nonfinal_hash_op(const char *op, int err, 1256static int check_nonfinal_ahash_op(const char *op, int err,
1058 u8 *result, unsigned int digestsize, 1257 u8 *result, unsigned int digestsize,
1059 const char *driver, const char *vec_name, 1258 const char *driver, const char *vec_name,
1060 const struct testvec_config *cfg) 1259 const struct testvec_config *cfg)
1061{ 1260{
1062 if (err) { 1261 if (err) {
1063 pr_err("alg: hash: %s %s() failed with err %d on test vector %s, cfg=\"%s\"\n", 1262 pr_err("alg: ahash: %s %s() failed with err %d on test vector %s, cfg=\"%s\"\n",
1064 driver, op, err, vec_name, cfg->name); 1263 driver, op, err, vec_name, cfg->name);
1065 return err; 1264 return err;
1066 } 1265 }
1067 if (!testmgr_is_poison(result, digestsize)) { 1266 if (!testmgr_is_poison(result, digestsize)) {
1068 pr_err("alg: hash: %s %s() used result buffer on test vector %s, cfg=\"%s\"\n", 1267 pr_err("alg: ahash: %s %s() used result buffer on test vector %s, cfg=\"%s\"\n",
1069 driver, op, vec_name, cfg->name); 1268 driver, op, vec_name, cfg->name);
1070 return -EINVAL; 1269 return -EINVAL;
1071 } 1270 }
1072 return 0; 1271 return 0;
1073} 1272}
1074 1273
1075static int test_hash_vec_cfg(const char *driver, 1274/* Test one hash test vector in one configuration, using the ahash API */
1076 const struct hash_testvec *vec, 1275static int test_ahash_vec_cfg(const char *driver,
1077 const char *vec_name, 1276 const struct hash_testvec *vec,
1078 const struct testvec_config *cfg, 1277 const char *vec_name,
1079 struct ahash_request *req, 1278 const struct testvec_config *cfg,
1080 struct test_sglist *tsgl, 1279 struct ahash_request *req,
1081 u8 *hashstate) 1280 struct test_sglist *tsgl,
1281 u8 *hashstate)
1082{ 1282{
1083 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 1283 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
1084 const unsigned int alignmask = crypto_ahash_alignmask(tfm); 1284 const unsigned int alignmask = crypto_ahash_alignmask(tfm);
@@ -1087,8 +1287,6 @@ static int test_hash_vec_cfg(const char *driver,
1087 const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags; 1287 const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags;
1088 const struct test_sg_division *divs[XBUFSIZE]; 1288 const struct test_sg_division *divs[XBUFSIZE];
1089 DECLARE_CRYPTO_WAIT(wait); 1289 DECLARE_CRYPTO_WAIT(wait);
1090 struct kvec _input;
1091 struct iov_iter input;
1092 unsigned int i; 1290 unsigned int i;
1093 struct scatterlist *pending_sgl; 1291 struct scatterlist *pending_sgl;
1094 unsigned int pending_len; 1292 unsigned int pending_len;
@@ -1101,26 +1299,22 @@ static int test_hash_vec_cfg(const char *driver,
1101 if (err) { 1299 if (err) {
1102 if (err == vec->setkey_error) 1300 if (err == vec->setkey_error)
1103 return 0; 1301 return 0;
1104 pr_err("alg: hash: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n", 1302 pr_err("alg: ahash: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n",
1105 driver, vec_name, vec->setkey_error, err, 1303 driver, vec_name, vec->setkey_error, err,
1106 crypto_ahash_get_flags(tfm)); 1304 crypto_ahash_get_flags(tfm));
1107 return err; 1305 return err;
1108 } 1306 }
1109 if (vec->setkey_error) { 1307 if (vec->setkey_error) {
1110 pr_err("alg: hash: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n", 1308 pr_err("alg: ahash: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n",
1111 driver, vec_name, vec->setkey_error); 1309 driver, vec_name, vec->setkey_error);
1112 return -EINVAL; 1310 return -EINVAL;
1113 } 1311 }
1114 } 1312 }
1115 1313
1116 /* Build the scatterlist for the source data */ 1314 /* Build the scatterlist for the source data */
1117 _input.iov_base = (void *)vec->plaintext; 1315 err = build_hash_sglist(tsgl, vec, cfg, alignmask, divs);
1118 _input.iov_len = vec->psize;
1119 iov_iter_kvec(&input, WRITE, &_input, 1, vec->psize);
1120 err = build_test_sglist(tsgl, cfg->src_divs, alignmask, vec->psize,
1121 &input, divs);
1122 if (err) { 1316 if (err) {
1123 pr_err("alg: hash: %s: error preparing scatterlist for test vector %s, cfg=\"%s\"\n", 1317 pr_err("alg: ahash: %s: error preparing scatterlist for test vector %s, cfg=\"%s\"\n",
1124 driver, vec_name, cfg->name); 1318 driver, vec_name, cfg->name);
1125 return err; 1319 return err;
1126 } 1320 }
@@ -1140,13 +1334,13 @@ static int test_hash_vec_cfg(const char *driver,
1140 if (err) { 1334 if (err) {
1141 if (err == vec->digest_error) 1335 if (err == vec->digest_error)
1142 return 0; 1336 return 0;
1143 pr_err("alg: hash: %s digest() failed on test vector %s; expected_error=%d, actual_error=%d, cfg=\"%s\"\n", 1337 pr_err("alg: ahash: %s digest() failed on test vector %s; expected_error=%d, actual_error=%d, cfg=\"%s\"\n",
1144 driver, vec_name, vec->digest_error, err, 1338 driver, vec_name, vec->digest_error, err,
1145 cfg->name); 1339 cfg->name);
1146 return err; 1340 return err;
1147 } 1341 }
1148 if (vec->digest_error) { 1342 if (vec->digest_error) {
1149 pr_err("alg: hash: %s digest() unexpectedly succeeded on test vector %s; expected_error=%d, cfg=\"%s\"\n", 1343 pr_err("alg: ahash: %s digest() unexpectedly succeeded on test vector %s; expected_error=%d, cfg=\"%s\"\n",
1150 driver, vec_name, vec->digest_error, cfg->name); 1344 driver, vec_name, vec->digest_error, cfg->name);
1151 return -EINVAL; 1345 return -EINVAL;
1152 } 1346 }
@@ -1158,8 +1352,8 @@ static int test_hash_vec_cfg(const char *driver,
1158 ahash_request_set_callback(req, req_flags, crypto_req_done, &wait); 1352 ahash_request_set_callback(req, req_flags, crypto_req_done, &wait);
1159 ahash_request_set_crypt(req, NULL, result, 0); 1353 ahash_request_set_crypt(req, NULL, result, 0);
1160 err = do_ahash_op(crypto_ahash_init, req, &wait, cfg->nosimd); 1354 err = do_ahash_op(crypto_ahash_init, req, &wait, cfg->nosimd);
1161 err = check_nonfinal_hash_op("init", err, result, digestsize, 1355 err = check_nonfinal_ahash_op("init", err, result, digestsize,
1162 driver, vec_name, cfg); 1356 driver, vec_name, cfg);
1163 if (err) 1357 if (err)
1164 return err; 1358 return err;
1165 1359
@@ -1175,9 +1369,9 @@ static int test_hash_vec_cfg(const char *driver,
1175 pending_len); 1369 pending_len);
1176 err = do_ahash_op(crypto_ahash_update, req, &wait, 1370 err = do_ahash_op(crypto_ahash_update, req, &wait,
1177 divs[i]->nosimd); 1371 divs[i]->nosimd);
1178 err = check_nonfinal_hash_op("update", err, 1372 err = check_nonfinal_ahash_op("update", err,
1179 result, digestsize, 1373 result, digestsize,
1180 driver, vec_name, cfg); 1374 driver, vec_name, cfg);
1181 if (err) 1375 if (err)
1182 return err; 1376 return err;
1183 pending_sgl = NULL; 1377 pending_sgl = NULL;
@@ -1188,23 +1382,23 @@ static int test_hash_vec_cfg(const char *driver,
1188 testmgr_poison(hashstate + statesize, 1382 testmgr_poison(hashstate + statesize,
1189 TESTMGR_POISON_LEN); 1383 TESTMGR_POISON_LEN);
1190 err = crypto_ahash_export(req, hashstate); 1384 err = crypto_ahash_export(req, hashstate);
1191 err = check_nonfinal_hash_op("export", err, 1385 err = check_nonfinal_ahash_op("export", err,
1192 result, digestsize, 1386 result, digestsize,
1193 driver, vec_name, cfg); 1387 driver, vec_name, cfg);
1194 if (err) 1388 if (err)
1195 return err; 1389 return err;
1196 if (!testmgr_is_poison(hashstate + statesize, 1390 if (!testmgr_is_poison(hashstate + statesize,
1197 TESTMGR_POISON_LEN)) { 1391 TESTMGR_POISON_LEN)) {
1198 pr_err("alg: hash: %s export() overran state buffer on test vector %s, cfg=\"%s\"\n", 1392 pr_err("alg: ahash: %s export() overran state buffer on test vector %s, cfg=\"%s\"\n",
1199 driver, vec_name, cfg->name); 1393 driver, vec_name, cfg->name);
1200 return -EOVERFLOW; 1394 return -EOVERFLOW;
1201 } 1395 }
1202 1396
1203 testmgr_poison(req->__ctx, crypto_ahash_reqsize(tfm)); 1397 testmgr_poison(req->__ctx, crypto_ahash_reqsize(tfm));
1204 err = crypto_ahash_import(req, hashstate); 1398 err = crypto_ahash_import(req, hashstate);
1205 err = check_nonfinal_hash_op("import", err, 1399 err = check_nonfinal_ahash_op("import", err,
1206 result, digestsize, 1400 result, digestsize,
1207 driver, vec_name, cfg); 1401 driver, vec_name, cfg);
1208 if (err) 1402 if (err)
1209 return err; 1403 return err;
1210 } 1404 }
@@ -1218,13 +1412,13 @@ static int test_hash_vec_cfg(const char *driver,
1218 if (cfg->finalization_type == FINALIZATION_TYPE_FINAL) { 1412 if (cfg->finalization_type == FINALIZATION_TYPE_FINAL) {
1219 /* finish with update() and final() */ 1413 /* finish with update() and final() */
1220 err = do_ahash_op(crypto_ahash_update, req, &wait, cfg->nosimd); 1414 err = do_ahash_op(crypto_ahash_update, req, &wait, cfg->nosimd);
1221 err = check_nonfinal_hash_op("update", err, result, digestsize, 1415 err = check_nonfinal_ahash_op("update", err, result, digestsize,
1222 driver, vec_name, cfg); 1416 driver, vec_name, cfg);
1223 if (err) 1417 if (err)
1224 return err; 1418 return err;
1225 err = do_ahash_op(crypto_ahash_final, req, &wait, cfg->nosimd); 1419 err = do_ahash_op(crypto_ahash_final, req, &wait, cfg->nosimd);
1226 if (err) { 1420 if (err) {
1227 pr_err("alg: hash: %s final() failed with err %d on test vector %s, cfg=\"%s\"\n", 1421 pr_err("alg: ahash: %s final() failed with err %d on test vector %s, cfg=\"%s\"\n",
1228 driver, err, vec_name, cfg->name); 1422 driver, err, vec_name, cfg->name);
1229 return err; 1423 return err;
1230 } 1424 }
@@ -1232,31 +1426,49 @@ static int test_hash_vec_cfg(const char *driver,
1232 /* finish with finup() */ 1426 /* finish with finup() */
1233 err = do_ahash_op(crypto_ahash_finup, req, &wait, cfg->nosimd); 1427 err = do_ahash_op(crypto_ahash_finup, req, &wait, cfg->nosimd);
1234 if (err) { 1428 if (err) {
1235 pr_err("alg: hash: %s finup() failed with err %d on test vector %s, cfg=\"%s\"\n", 1429 pr_err("alg: ahash: %s finup() failed with err %d on test vector %s, cfg=\"%s\"\n",
1236 driver, err, vec_name, cfg->name); 1430 driver, err, vec_name, cfg->name);
1237 return err; 1431 return err;
1238 } 1432 }
1239 } 1433 }
1240 1434
1241result_ready: 1435result_ready:
1242 /* Check that the algorithm produced the correct digest */ 1436 return check_hash_result("ahash", result, digestsize, vec, vec_name,
1243 if (memcmp(result, vec->digest, digestsize) != 0) { 1437 driver, cfg);
1244 pr_err("alg: hash: %s test failed (wrong result) on test vector %s, cfg=\"%s\"\n", 1438}
1245 driver, vec_name, cfg->name); 1439
1246 return -EINVAL; 1440static int test_hash_vec_cfg(const char *driver,
1247 } 1441 const struct hash_testvec *vec,
1248 if (!testmgr_is_poison(&result[digestsize], TESTMGR_POISON_LEN)) { 1442 const char *vec_name,
1249 pr_err("alg: hash: %s overran result buffer on test vector %s, cfg=\"%s\"\n", 1443 const struct testvec_config *cfg,
1250 driver, vec_name, cfg->name); 1444 struct ahash_request *req,
1251 return -EOVERFLOW; 1445 struct shash_desc *desc,
1446 struct test_sglist *tsgl,
1447 u8 *hashstate)
1448{
1449 int err;
1450
1451 /*
1452 * For algorithms implemented as "shash", most bugs will be detected by
1453 * both the shash and ahash tests. Test the shash API first so that the
1454 * failures involve less indirection, so are easier to debug.
1455 */
1456
1457 if (desc) {
1458 err = test_shash_vec_cfg(driver, vec, vec_name, cfg, desc, tsgl,
1459 hashstate);
1460 if (err)
1461 return err;
1252 } 1462 }
1253 1463
1254 return 0; 1464 return test_ahash_vec_cfg(driver, vec, vec_name, cfg, req, tsgl,
1465 hashstate);
1255} 1466}
1256 1467
1257static int test_hash_vec(const char *driver, const struct hash_testvec *vec, 1468static int test_hash_vec(const char *driver, const struct hash_testvec *vec,
1258 unsigned int vec_num, struct ahash_request *req, 1469 unsigned int vec_num, struct ahash_request *req,
1259 struct test_sglist *tsgl, u8 *hashstate) 1470 struct shash_desc *desc, struct test_sglist *tsgl,
1471 u8 *hashstate)
1260{ 1472{
1261 char vec_name[16]; 1473 char vec_name[16];
1262 unsigned int i; 1474 unsigned int i;
@@ -1267,7 +1479,7 @@ static int test_hash_vec(const char *driver, const struct hash_testvec *vec,
1267 for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++) { 1479 for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++) {
1268 err = test_hash_vec_cfg(driver, vec, vec_name, 1480 err = test_hash_vec_cfg(driver, vec, vec_name,
1269 &default_hash_testvec_configs[i], 1481 &default_hash_testvec_configs[i],
1270 req, tsgl, hashstate); 1482 req, desc, tsgl, hashstate);
1271 if (err) 1483 if (err)
1272 return err; 1484 return err;
1273 } 1485 }
@@ -1281,7 +1493,7 @@ static int test_hash_vec(const char *driver, const struct hash_testvec *vec,
1281 generate_random_testvec_config(&cfg, cfgname, 1493 generate_random_testvec_config(&cfg, cfgname,
1282 sizeof(cfgname)); 1494 sizeof(cfgname));
1283 err = test_hash_vec_cfg(driver, vec, vec_name, &cfg, 1495 err = test_hash_vec_cfg(driver, vec, vec_name, &cfg,
1284 req, tsgl, hashstate); 1496 req, desc, tsgl, hashstate);
1285 if (err) 1497 if (err)
1286 return err; 1498 return err;
1287 } 1499 }
@@ -1343,6 +1555,7 @@ static int test_hash_vs_generic_impl(const char *driver,
1343 const char *generic_driver, 1555 const char *generic_driver,
1344 unsigned int maxkeysize, 1556 unsigned int maxkeysize,
1345 struct ahash_request *req, 1557 struct ahash_request *req,
1558 struct shash_desc *desc,
1346 struct test_sglist *tsgl, 1559 struct test_sglist *tsgl,
1347 u8 *hashstate) 1560 u8 *hashstate)
1348{ 1561{
@@ -1423,7 +1636,7 @@ static int test_hash_vs_generic_impl(const char *driver,
1423 generate_random_testvec_config(&cfg, cfgname, sizeof(cfgname)); 1636 generate_random_testvec_config(&cfg, cfgname, sizeof(cfgname));
1424 1637
1425 err = test_hash_vec_cfg(driver, &vec, vec_name, &cfg, 1638 err = test_hash_vec_cfg(driver, &vec, vec_name, &cfg,
1426 req, tsgl, hashstate); 1639 req, desc, tsgl, hashstate);
1427 if (err) 1640 if (err)
1428 goto out; 1641 goto out;
1429 cond_resched(); 1642 cond_resched();
@@ -1441,6 +1654,7 @@ static int test_hash_vs_generic_impl(const char *driver,
1441 const char *generic_driver, 1654 const char *generic_driver,
1442 unsigned int maxkeysize, 1655 unsigned int maxkeysize,
1443 struct ahash_request *req, 1656 struct ahash_request *req,
1657 struct shash_desc *desc,
1444 struct test_sglist *tsgl, 1658 struct test_sglist *tsgl,
1445 u8 *hashstate) 1659 u8 *hashstate)
1446{ 1660{
@@ -1448,26 +1662,67 @@ static int test_hash_vs_generic_impl(const char *driver,
1448} 1662}
1449#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 1663#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
1450 1664
1665static int alloc_shash(const char *driver, u32 type, u32 mask,
1666 struct crypto_shash **tfm_ret,
1667 struct shash_desc **desc_ret)
1668{
1669 struct crypto_shash *tfm;
1670 struct shash_desc *desc;
1671
1672 tfm = crypto_alloc_shash(driver, type, mask);
1673 if (IS_ERR(tfm)) {
1674 if (PTR_ERR(tfm) == -ENOENT) {
1675 /*
1676 * This algorithm is only available through the ahash
1677 * API, not the shash API, so skip the shash tests.
1678 */
1679 return 0;
1680 }
1681 pr_err("alg: hash: failed to allocate shash transform for %s: %ld\n",
1682 driver, PTR_ERR(tfm));
1683 return PTR_ERR(tfm);
1684 }
1685
1686 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
1687 if (!desc) {
1688 crypto_free_shash(tfm);
1689 return -ENOMEM;
1690 }
1691 desc->tfm = tfm;
1692
1693 *tfm_ret = tfm;
1694 *desc_ret = desc;
1695 return 0;
1696}
1697
1451static int __alg_test_hash(const struct hash_testvec *vecs, 1698static int __alg_test_hash(const struct hash_testvec *vecs,
1452 unsigned int num_vecs, const char *driver, 1699 unsigned int num_vecs, const char *driver,
1453 u32 type, u32 mask, 1700 u32 type, u32 mask,
1454 const char *generic_driver, unsigned int maxkeysize) 1701 const char *generic_driver, unsigned int maxkeysize)
1455{ 1702{
1456 struct crypto_ahash *tfm; 1703 struct crypto_ahash *atfm = NULL;
1457 struct ahash_request *req = NULL; 1704 struct ahash_request *req = NULL;
1705 struct crypto_shash *stfm = NULL;
1706 struct shash_desc *desc = NULL;
1458 struct test_sglist *tsgl = NULL; 1707 struct test_sglist *tsgl = NULL;
1459 u8 *hashstate = NULL; 1708 u8 *hashstate = NULL;
1709 unsigned int statesize;
1460 unsigned int i; 1710 unsigned int i;
1461 int err; 1711 int err;
1462 1712
1463 tfm = crypto_alloc_ahash(driver, type, mask); 1713 /*
1464 if (IS_ERR(tfm)) { 1714 * Always test the ahash API. This works regardless of whether the
1715 * algorithm is implemented as ahash or shash.
1716 */
1717
1718 atfm = crypto_alloc_ahash(driver, type, mask);
1719 if (IS_ERR(atfm)) {
1465 pr_err("alg: hash: failed to allocate transform for %s: %ld\n", 1720 pr_err("alg: hash: failed to allocate transform for %s: %ld\n",
1466 driver, PTR_ERR(tfm)); 1721 driver, PTR_ERR(atfm));
1467 return PTR_ERR(tfm); 1722 return PTR_ERR(atfm);
1468 } 1723 }
1469 1724
1470 req = ahash_request_alloc(tfm, GFP_KERNEL); 1725 req = ahash_request_alloc(atfm, GFP_KERNEL);
1471 if (!req) { 1726 if (!req) {
1472 pr_err("alg: hash: failed to allocate request for %s\n", 1727 pr_err("alg: hash: failed to allocate request for %s\n",
1473 driver); 1728 driver);
@@ -1475,6 +1730,14 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
1475 goto out; 1730 goto out;
1476 } 1731 }
1477 1732
1733 /*
1734 * If available also test the shash API, to cover corner cases that may
1735 * be missed by testing the ahash API only.
1736 */
1737 err = alloc_shash(driver, type, mask, &stfm, &desc);
1738 if (err)
1739 goto out;
1740
1478 tsgl = kmalloc(sizeof(*tsgl), GFP_KERNEL); 1741 tsgl = kmalloc(sizeof(*tsgl), GFP_KERNEL);
1479 if (!tsgl || init_test_sglist(tsgl) != 0) { 1742 if (!tsgl || init_test_sglist(tsgl) != 0) {
1480 pr_err("alg: hash: failed to allocate test buffers for %s\n", 1743 pr_err("alg: hash: failed to allocate test buffers for %s\n",
@@ -1485,8 +1748,10 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
1485 goto out; 1748 goto out;
1486 } 1749 }
1487 1750
1488 hashstate = kmalloc(crypto_ahash_statesize(tfm) + TESTMGR_POISON_LEN, 1751 statesize = crypto_ahash_statesize(atfm);
1489 GFP_KERNEL); 1752 if (stfm)
1753 statesize = max(statesize, crypto_shash_statesize(stfm));
1754 hashstate = kmalloc(statesize + TESTMGR_POISON_LEN, GFP_KERNEL);
1490 if (!hashstate) { 1755 if (!hashstate) {
1491 pr_err("alg: hash: failed to allocate hash state buffer for %s\n", 1756 pr_err("alg: hash: failed to allocate hash state buffer for %s\n",
1492 driver); 1757 driver);
@@ -1495,20 +1760,23 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
1495 } 1760 }
1496 1761
1497 for (i = 0; i < num_vecs; i++) { 1762 for (i = 0; i < num_vecs; i++) {
1498 err = test_hash_vec(driver, &vecs[i], i, req, tsgl, hashstate); 1763 err = test_hash_vec(driver, &vecs[i], i, req, desc, tsgl,
1764 hashstate);
1499 if (err) 1765 if (err)
1500 goto out; 1766 goto out;
1501 } 1767 }
1502 err = test_hash_vs_generic_impl(driver, generic_driver, maxkeysize, req, 1768 err = test_hash_vs_generic_impl(driver, generic_driver, maxkeysize, req,
1503 tsgl, hashstate); 1769 desc, tsgl, hashstate);
1504out: 1770out:
1505 kfree(hashstate); 1771 kfree(hashstate);
1506 if (tsgl) { 1772 if (tsgl) {
1507 destroy_test_sglist(tsgl); 1773 destroy_test_sglist(tsgl);
1508 kfree(tsgl); 1774 kfree(tsgl);
1509 } 1775 }
1776 kfree(desc);
1777 crypto_free_shash(stfm);
1510 ahash_request_free(req); 1778 ahash_request_free(req);
1511 crypto_free_ahash(tfm); 1779 crypto_free_ahash(atfm);
1512 return err; 1780 return err;
1513} 1781}
1514 1782