Skip to content

Commit 0620020

Browse files
siemen11nasahlpa
authored andcommitted
[pentest] Unroll 25519 point mult
We had x25519 point mult calling the pentest ecdh in order to simulate the point multiplication. Instead, call the cryptolibrary ecdh directly and write out the point multiplication. Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
1 parent edeafc9 commit 0620020

2 files changed

Lines changed: 141 additions & 25 deletions

File tree

sw/device/tests/penetrationtests/firmware/fi/cryptolib_fi_asym_impl.c

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,21 +1506,83 @@ status_t cryptolib_fi_x25519_ecdh_impl(
15061506
status_t cryptolib_fi_x25519_point_mul_impl(
15071507
cryptolib_fi_asym_x25519_point_mul_in_t uj_input,
15081508
cryptolib_fi_asym_x25519_point_mul_out_t *uj_output) {
1509-
// Point multiplication in X25519 is equivalent to ECDH
1510-
// where Bob's scalar is used as the base point.
1511-
cryptolib_fi_asym_x25519_ecdh_in_t ecdh_in;
1512-
memcpy(ecdh_in.private_key, uj_input.scalar_alice, X25519_CMD_BYTES);
1513-
memcpy(ecdh_in.public_x, uj_input.scalar_bob, X25519_CMD_BYTES);
1514-
memset(ecdh_in.public_y, 0, X25519_CMD_BYTES); // Ignored
1515-
ecdh_in.cfg = uj_input.cfg;
1516-
ecdh_in.trigger = uj_input.trigger;
1517-
1518-
cryptolib_fi_asym_x25519_ecdh_out_t ecdh_out;
1519-
HARDENED_TRY(cryptolib_fi_x25519_ecdh_impl(ecdh_in, &ecdh_out));
1520-
1521-
memcpy(uj_output->x, ecdh_out.shared_key, X25519_CMD_BYTES);
1522-
memset(uj_output->y, 0, X25519_CMD_BYTES);
1523-
uj_output->cfg = ecdh_out.cfg;
1509+
// Use the Ed25519 masked size since both use the exact same 256-bit curve
1510+
uint32_t private_keyblob[kPentestEd25519MaskedPrivateKeyWords * 2];
1511+
memset(private_keyblob, 0, sizeof(private_keyblob));
1512+
// Alice's scalar acts as the private key
1513+
memcpy(private_keyblob, uj_input.scalar_alice, X25519_CMD_BYTES);
1514+
1515+
otcrypto_blinded_key_t private_key = {
1516+
.config =
1517+
{
1518+
.version = kOtcryptoLibVersion1,
1519+
.key_mode = kOtcryptoKeyModeX25519,
1520+
.key_length = X25519_CMD_BYTES,
1521+
.hw_backed = kHardenedBoolFalse,
1522+
.exportable = kHardenedBoolTrue,
1523+
.security_level = kOtcryptoKeySecurityLevelLow,
1524+
},
1525+
.keyblob_length = sizeof(private_keyblob),
1526+
.keyblob = private_keyblob,
1527+
};
1528+
private_key.checksum = otcrypto_integrity_blinded_checksum(&private_key);
1529+
1530+
uint32_t public_key_buf[X25519_CMD_BYTES / sizeof(uint32_t)];
1531+
memset(public_key_buf, 0, sizeof(public_key_buf));
1532+
// Bob's scalar acts as the base point (public key X coordinate)
1533+
memcpy(public_key_buf, uj_input.scalar_bob, X25519_CMD_BYTES);
1534+
1535+
otcrypto_unblinded_key_t public_key = {
1536+
.key_mode = kOtcryptoKeyModeX25519,
1537+
.key_length = X25519_CMD_BYTES,
1538+
.key = public_key_buf,
1539+
};
1540+
public_key.checksum = otcrypto_integrity_unblinded_checksum(&public_key);
1541+
1542+
uint32_t shared_secretblob[16];
1543+
memset(shared_secretblob, 0, sizeof(shared_secretblob));
1544+
otcrypto_blinded_key_t shared_secret = {
1545+
.config =
1546+
{
1547+
.version = kOtcryptoLibVersion1,
1548+
.key_mode = kOtcryptoKeyModeAesCtr,
1549+
.key_length = X25519_CMD_BYTES,
1550+
.hw_backed = kHardenedBoolFalse,
1551+
.exportable = kHardenedBoolTrue,
1552+
.security_level = kOtcryptoKeySecurityLevelLow,
1553+
},
1554+
.keyblob_length = sizeof(shared_secretblob),
1555+
.keyblob = shared_secretblob,
1556+
};
1557+
1558+
// FI Trigger window
1559+
if (uj_input.trigger) {
1560+
pentest_set_trigger_high();
1561+
}
1562+
HARDENED_TRY(otcrypto_x25519(&private_key, &public_key, &shared_secret));
1563+
if (uj_input.trigger) {
1564+
pentest_set_trigger_low();
1565+
}
1566+
1567+
uint32_t ss_share0[8];
1568+
uint32_t ss_share1[8];
1569+
otcrypto_word32_buf_t ss_share0_buf =
1570+
OTCRYPTO_MAKE_BUF(otcrypto_word32_buf_t, ss_share0, 8);
1571+
otcrypto_word32_buf_t ss_share1_buf =
1572+
OTCRYPTO_MAKE_BUF(otcrypto_word32_buf_t, ss_share1, 8);
1573+
1574+
HARDENED_TRY(otcrypto_export_blinded_key(&shared_secret, &ss_share0_buf,
1575+
&ss_share1_buf));
1576+
1577+
uint32_t ss_unmasked[8];
1578+
HARDENED_TRY(hardened_add(ss_share0, ss_share1, 8, ss_unmasked));
1579+
1580+
// Map the unmasked secret back to the point multiplication output
1581+
uj_output->cfg = 0;
1582+
memset(uj_output->x, 0, X25519_CMD_BYTES);
1583+
memcpy(uj_output->x, ss_unmasked, X25519_CMD_BYTES);
1584+
memset(uj_output->y, 0,
1585+
X25519_CMD_BYTES); // Y coordinate is ignored in X25519
15241586
uj_output->magic = kOutputComplete;
15251587

15261588
return OK_STATUS();

sw/device/tests/penetrationtests/firmware/sca/cryptolib_sca_asym_impl.c

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -976,19 +976,73 @@ status_t cryptolib_sca_x25519_ecdh_impl(
976976
status_t cryptolib_sca_x25519_point_mul_impl(
977977
cryptolib_sca_asym_x25519_point_mul_in_t uj_input,
978978
cryptolib_sca_asym_x25519_point_mul_out_t *uj_output) {
979-
cryptolib_sca_asym_x25519_ecdh_in_t ecdh_in;
980-
memcpy(ecdh_in.private_key, uj_input.scalar_alice, X25519_CMD_BYTES);
981-
memcpy(ecdh_in.public_x, uj_input.scalar_bob, X25519_CMD_BYTES);
982-
memset(ecdh_in.public_y, 0, X25519_CMD_BYTES);
983-
ecdh_in.cfg = uj_input.cfg;
984-
ecdh_in.trigger = uj_input.trigger;
979+
uint32_t private_keyblob[kPentestEd25519MaskedPrivateKeyWords * 2];
980+
memset(private_keyblob, 0, sizeof(private_keyblob));
981+
// Alice's scalar acts as the private key
982+
memcpy(private_keyblob, uj_input.scalar_alice, X25519_CMD_BYTES);
983+
984+
otcrypto_blinded_key_t private_key = {
985+
.config =
986+
{
987+
.version = kOtcryptoLibVersion1,
988+
.key_mode = kOtcryptoKeyModeX25519,
989+
.key_length = X25519_CMD_BYTES,
990+
.hw_backed = kHardenedBoolFalse,
991+
.exportable = kHardenedBoolTrue,
992+
.security_level = kOtcryptoKeySecurityLevelHigh,
993+
},
994+
.keyblob_length = sizeof(private_keyblob),
995+
.keyblob = private_keyblob,
996+
};
997+
private_key.checksum = otcrypto_integrity_blinded_checksum(&private_key);
985998

986-
cryptolib_sca_asym_x25519_ecdh_out_t ecdh_out;
987-
HARDENED_TRY(cryptolib_sca_x25519_ecdh_impl(ecdh_in, &ecdh_out));
999+
uint32_t public_key_buf[X25519_CMD_BYTES / sizeof(uint32_t)];
1000+
// Bob's scalar acts as the base point (public key X coordinate)
1001+
memcpy(public_key_buf, uj_input.scalar_bob, X25519_CMD_BYTES);
9881002

989-
memcpy(uj_output->x, ecdh_out.shared_key, X25519_CMD_BYTES);
1003+
otcrypto_unblinded_key_t public_key = {
1004+
.key_mode = kOtcryptoKeyModeX25519,
1005+
.key_length = sizeof(public_key_buf),
1006+
.key = public_key_buf,
1007+
};
1008+
public_key.checksum = otcrypto_integrity_unblinded_checksum(&public_key);
1009+
1010+
uint32_t shared_secretblob[16];
1011+
memset(shared_secretblob, 0, sizeof(shared_secretblob));
1012+
otcrypto_blinded_key_t shared_secret = {
1013+
.config =
1014+
{
1015+
.version = kOtcryptoLibVersion1,
1016+
.key_mode = kOtcryptoKeyModeAesCtr,
1017+
.key_length = X25519_CMD_BYTES,
1018+
.hw_backed = kHardenedBoolFalse,
1019+
.exportable = kHardenedBoolTrue,
1020+
.security_level = kOtcryptoKeySecurityLevelHigh,
1021+
},
1022+
.keyblob_length = sizeof(shared_secretblob),
1023+
.keyblob = shared_secretblob,
1024+
};
1025+
1026+
pentest_set_trigger_high();
1027+
HARDENED_TRY(otcrypto_x25519(&private_key, &public_key, &shared_secret));
1028+
pentest_set_trigger_low();
1029+
1030+
uint32_t ss_share0[8];
1031+
uint32_t ss_share1[8];
1032+
otcrypto_word32_buf_t ss_share0_buf =
1033+
OTCRYPTO_MAKE_BUF(otcrypto_word32_buf_t, ss_share0, 8);
1034+
otcrypto_word32_buf_t ss_share1_buf =
1035+
OTCRYPTO_MAKE_BUF(otcrypto_word32_buf_t, ss_share1, 8);
1036+
1037+
HARDENED_TRY(otcrypto_export_blinded_key(&shared_secret, &ss_share0_buf,
1038+
&ss_share1_buf));
1039+
1040+
uint32_t ss_unmasked[8];
1041+
HARDENED_TRY(hardened_add(ss_share0, ss_share1, 8, ss_unmasked));
1042+
1043+
uj_output->cfg = 0;
1044+
memcpy(uj_output->x, ss_unmasked, X25519_CMD_BYTES);
9901045
memset(uj_output->y, 0, X25519_CMD_BYTES);
991-
uj_output->cfg = ecdh_out.cfg;
9921046

9931047
return OK_STATUS();
9941048
}

0 commit comments

Comments
 (0)