|
30 | 30 |
|
31 | 31 | #include <wolfssl/wolfcrypt/ed448.h> |
32 | 32 | #include <wolfssl/wolfcrypt/types.h> |
| 33 | +#ifdef WOLF_CRYPTO_CB |
| 34 | + #include <wolfssl/wolfcrypt/cryptocb.h> |
| 35 | +#endif |
33 | 36 | #include <tests/api/api.h> |
34 | 37 | #include <tests/api/test_ed448.h> |
35 | 38 |
|
@@ -1369,3 +1372,123 @@ int test_wc_ed448_check_key_decisions(void) |
1369 | 1372 | return EXPECT_RESULT(); |
1370 | 1373 | } /* END test_wc_ed448_check_key_decisions */ |
1371 | 1374 |
|
| 1375 | +/* Test Ed448 sign/verify routed through a crypto callback (CryptoCb) device. */ |
| 1376 | +#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ED448) && \ |
| 1377 | + defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_VERIFY) && \ |
| 1378 | + !defined(WC_NO_RNG) |
| 1379 | +typedef struct ed448SpyCtx { |
| 1380 | + int signSeen; |
| 1381 | + int verifySeen; |
| 1382 | +} ed448SpyCtx; |
| 1383 | + |
| 1384 | +/* Spy device: services Ed448 sign/verify in software (devId cleared) and counts |
| 1385 | + * each; declines everything else so make_key runs in software. */ |
| 1386 | +static int ed448_test_crypto_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) |
| 1387 | +{ |
| 1388 | + ed448SpyCtx* spy = (ed448SpyCtx*)ctx; |
| 1389 | + int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); |
| 1390 | + |
| 1391 | + (void)devIdArg; |
| 1392 | + |
| 1393 | + if (info == NULL || spy == NULL) { |
| 1394 | + return BAD_FUNC_ARG; |
| 1395 | + } |
| 1396 | + |
| 1397 | + if (info->algo_type == WC_ALGO_TYPE_PK) { |
| 1398 | + #ifdef HAVE_ED448_SIGN |
| 1399 | + if (info->pk.type == WC_PK_TYPE_ED448) { |
| 1400 | + int save = info->pk.ed448sign.key->devId; |
| 1401 | + info->pk.ed448sign.key->devId = INVALID_DEVID; |
| 1402 | + ret = wc_ed448_sign_msg_ex( |
| 1403 | + info->pk.ed448sign.in, info->pk.ed448sign.inLen, |
| 1404 | + info->pk.ed448sign.out, info->pk.ed448sign.outLen, |
| 1405 | + info->pk.ed448sign.key, info->pk.ed448sign.type, |
| 1406 | + info->pk.ed448sign.context, info->pk.ed448sign.contextLen); |
| 1407 | + info->pk.ed448sign.key->devId = save; |
| 1408 | + spy->signSeen++; |
| 1409 | + } |
| 1410 | + #endif |
| 1411 | + #ifdef HAVE_ED448_VERIFY |
| 1412 | + if (info->pk.type == WC_PK_TYPE_ED448_VERIFY) { |
| 1413 | + int save = info->pk.ed448verify.key->devId; |
| 1414 | + info->pk.ed448verify.key->devId = INVALID_DEVID; |
| 1415 | + ret = wc_ed448_verify_msg_ex( |
| 1416 | + info->pk.ed448verify.sig, info->pk.ed448verify.sigLen, |
| 1417 | + info->pk.ed448verify.msg, info->pk.ed448verify.msgLen, |
| 1418 | + info->pk.ed448verify.res, info->pk.ed448verify.key, |
| 1419 | + info->pk.ed448verify.type, info->pk.ed448verify.context, |
| 1420 | + info->pk.ed448verify.contextLen); |
| 1421 | + info->pk.ed448verify.key->devId = save; |
| 1422 | + spy->verifySeen++; |
| 1423 | + } |
| 1424 | + #endif |
| 1425 | + } |
| 1426 | + |
| 1427 | + return ret; |
| 1428 | +} |
| 1429 | +#endif |
| 1430 | + |
| 1431 | +int test_wc_ed448_cryptocb(void) |
| 1432 | +{ |
| 1433 | + EXPECT_DECLS; |
| 1434 | +#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ED448) && \ |
| 1435 | + defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_VERIFY) && \ |
| 1436 | + !defined(WC_NO_RNG) |
| 1437 | + int devId = 4448; |
| 1438 | + ed448SpyCtx spy; |
| 1439 | + WC_RNG rng; |
| 1440 | + byte msg[32]; |
| 1441 | + word32 sigLen = ED448_SIG_SIZE; |
| 1442 | + int verify = 0; |
| 1443 | + WC_DECLARE_VAR(key, ed448_key, 1, HEAP_HINT); |
| 1444 | + WC_DECLARE_VAR(sig, byte, ED448_SIG_SIZE, HEAP_HINT); |
| 1445 | + |
| 1446 | + XMEMSET(&rng, 0, sizeof(rng)); |
| 1447 | + XMEMSET(&spy, 0, sizeof(spy)); |
| 1448 | + XMEMSET(msg, 0x5a, sizeof(msg)); |
| 1449 | + |
| 1450 | + WC_ALLOC_VAR(key, ed448_key, 1, HEAP_HINT); |
| 1451 | + WC_ALLOC_VAR(sig, byte, ED448_SIG_SIZE, HEAP_HINT); |
| 1452 | +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC |
| 1453 | + ExpectNotNull(key); |
| 1454 | + ExpectNotNull(sig); |
| 1455 | +#endif |
| 1456 | + |
| 1457 | + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, ed448_test_crypto_cb, &spy), |
| 1458 | + 0); |
| 1459 | + ExpectIntEQ(wc_InitRng(&rng), 0); |
| 1460 | + ExpectIntEQ(wc_ed448_init_ex(key, HEAP_HINT, devId), 0); |
| 1461 | + ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, key), 0); |
| 1462 | + |
| 1463 | + /* Sign routes through the device callback. */ |
| 1464 | + ExpectIntEQ(wc_ed448_sign_msg(msg, (word32)sizeof(msg), sig, &sigLen, key, |
| 1465 | + NULL, 0), 0); |
| 1466 | + ExpectIntGE(spy.signSeen, 1); |
| 1467 | + |
| 1468 | + /* Verify routes through the device callback. */ |
| 1469 | + ExpectIntEQ(wc_ed448_verify_msg(sig, sigLen, msg, (word32)sizeof(msg), |
| 1470 | + &verify, key, NULL, 0), 0); |
| 1471 | + ExpectIntGE(spy.verifySeen, 1); |
| 1472 | + ExpectIntEQ(verify, 1); |
| 1473 | + |
| 1474 | + /* Negative: corrupt the signature. Ed448 reports a bad signature as |
| 1475 | + * SIG_VERIFY_E, exercising the device verify error path (verify == 0). */ |
| 1476 | + if (WC_VAR_OK(sig)) { |
| 1477 | + sig[0] ^= 0xFF; |
| 1478 | + } |
| 1479 | + verify = 1; |
| 1480 | + ExpectIntEQ(wc_ed448_verify_msg(sig, sigLen, msg, (word32)sizeof(msg), |
| 1481 | + &verify, key, NULL, 0), |
| 1482 | + WC_NO_ERR_TRACE(SIG_VERIFY_E)); |
| 1483 | + ExpectIntGE(spy.verifySeen, 2); |
| 1484 | + ExpectIntEQ(verify, 0); |
| 1485 | + |
| 1486 | + wc_ed448_free(key); |
| 1487 | + DoExpectIntEQ(wc_FreeRng(&rng), 0); |
| 1488 | + wc_CryptoCb_UnRegisterDevice(devId); |
| 1489 | + |
| 1490 | + WC_FREE_VAR(sig, HEAP_HINT); |
| 1491 | + WC_FREE_VAR(key, HEAP_HINT); |
| 1492 | +#endif |
| 1493 | + return EXPECT_RESULT(); |
| 1494 | +} |
0 commit comments