@@ -772,6 +772,55 @@ int test_wc_ecc_import_x963(void)
772772 return EXPECT_RESULT ();
773773} /* END wc_ecc_import_x963 */
774774
775+ /*
776+ * testing wc_ecc_import_x963() rejects an off-curve public point.
777+ *
778+ * Regression coverage for the invalid-curve attack: the legacy wrapper
779+ * wc_ecc_import_x963_ex must pass untrusted=1 to wc_ecc_import_x963_ex2
780+ * so that ECIES, PKCS#7 KARI, and EVP ECDH callers validate that the
781+ * imported point actually lies on the curve. Without that, an attacker
782+ * can feed a point from a weak twist and leak the victim's private
783+ * scalar modulo small primes (Biehl-Meyer-Mueller).
784+ */
785+ int test_wc_ecc_import_x963_off_curve (void )
786+ {
787+ EXPECT_DECLS ;
788+ #if defined(HAVE_ECC ) && defined(HAVE_ECC_KEY_IMPORT ) && \
789+ !defined(NO_ECC256 ) && !defined(NO_ECC_SECP )
790+ ecc_key pubKey ;
791+ /* Uncompressed X9.63 P-256 point: 0x04 || Gx || Gy with the last byte
792+ * of Gy flipped by 1. Gx/Gy are the NIST P-256 generator coordinates;
793+ * modifying a single bit of Gy produces a point that is not on the
794+ * curve, so wc_ecc_import_x963 must reject it. */
795+ static const byte offCurveX963 [] = {
796+ 0x04 ,
797+ 0x6B , 0x17 , 0xD1 , 0xF2 , 0xE1 , 0x2C , 0x42 , 0x47 ,
798+ 0xF8 , 0xBC , 0xE6 , 0xE5 , 0x63 , 0xA4 , 0x40 , 0xF2 ,
799+ 0x77 , 0x03 , 0x7D , 0x81 , 0x2D , 0xEB , 0x33 , 0xA0 ,
800+ 0xF4 , 0xA1 , 0x39 , 0x45 , 0xD8 , 0x98 , 0xC2 , 0x96 ,
801+ 0x4F , 0xE3 , 0x42 , 0xE2 , 0xFE , 0x1A , 0x7F , 0x9B ,
802+ 0x8E , 0xE7 , 0xEB , 0x4A , 0x7C , 0x0F , 0x9E , 0x16 ,
803+ 0x2B , 0xCE , 0x33 , 0x57 , 0x6B , 0x31 , 0x5E , 0xCE ,
804+ 0xCB , 0xB6 , 0x40 , 0x68 , 0x37 , 0xBF , 0x51 , 0xF4
805+ };
806+
807+ XMEMSET (& pubKey , 0 , sizeof (ecc_key ));
808+
809+ ExpectIntEQ (wc_ecc_init (& pubKey ), 0 );
810+
811+ /* Importing an off-curve point must fail. */
812+ ExpectIntNE (wc_ecc_import_x963 (offCurveX963 , (word32 )sizeof (offCurveX963 ),
813+ & pubKey ), 0 );
814+
815+ wc_ecc_free (& pubKey );
816+
817+ #ifdef FP_ECC
818+ wc_ecc_fp_free ();
819+ #endif
820+ #endif
821+ return EXPECT_RESULT ();
822+ } /* END test_wc_ecc_import_x963_off_curve */
823+
775824/*
776825 * testing wc_ecc_import_private_key()
777826 */
0 commit comments