@@ -1506,21 +1506,83 @@ status_t cryptolib_fi_x25519_ecdh_impl(
15061506status_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 ();
0 commit comments