@@ -157,6 +157,8 @@ static const char* GetPkTypeStr(int pk)
157157 case WC_PK_TYPE_EC_KEYGEN : return "ECC KeyGen" ;
158158 case WC_PK_TYPE_EC_GET_SIZE : return "ECC GetSize" ;
159159 case WC_PK_TYPE_EC_GET_SIG_SIZE : return "ECC GetSigSize" ;
160+ case WC_PK_TYPE_EC_MAKE_PUB : return "ECC MakePub" ;
161+ case WC_PK_TYPE_EC_CHECK_PUB_KEY : return "ECC CheckPubKey" ;
160162 }
161163 return NULL ;
162164}
@@ -882,6 +884,127 @@ int wc_CryptoCb_EccGetSigSize(const ecc_key* key, int* sigSize)
882884
883885 return wc_CryptoCb_TranslateErrorCode (ret );
884886}
887+
888+ int wc_CryptoCb_EccMakePub (ecc_key * key , ecc_point * pubOut )
889+ {
890+ int ret = WC_NO_ERR_TRACE (CRYPTOCB_UNAVAILABLE );
891+ CryptoCb * dev ;
892+
893+ if (key == NULL || pubOut == NULL || key -> dp == NULL )
894+ return ret ;
895+
896+ if (key -> dp -> size > MAX_ECC_BYTES )
897+ return ret ;
898+
899+ dev = wc_CryptoCb_FindDevice (key -> devId , WC_ALGO_TYPE_PK );
900+ if (dev && dev -> cb ) {
901+ wc_CryptoInfo cryptoInfo ;
902+ word32 curveSz = (word32 )key -> dp -> size ;
903+ word32 ptSz = 1 + 2 * curveSz ; /* X9.63 uncompressed length */
904+ word32 outSz = 1 + 2 * MAX_ECC_BYTES ; /* buffer size on input */
905+ WC_DECLARE_VAR (buf , byte , (1 + 2 * MAX_ECC_BYTES ), key -> heap );
906+ WC_ALLOC_VAR_EX (buf , byte , (1 + 2 * MAX_ECC_BYTES ), key -> heap ,
907+ DYNAMIC_TYPE_ECC_BUFFER , return MEMORY_E );
908+
909+ /* zero the result buffer so a handler that returns success without
910+ * writing output is rejected deterministically by the tag check */
911+ XMEMSET (buf , 0 , ptSz );
912+
913+ XMEMSET (& cryptoInfo , 0 , sizeof (cryptoInfo ));
914+ cryptoInfo .algo_type = WC_ALGO_TYPE_PK ;
915+ cryptoInfo .pk .type = WC_PK_TYPE_EC_MAKE_PUB ;
916+ cryptoInfo .pk .ecc_make_pub .key = key ;
917+ cryptoInfo .pk .ecc_make_pub .pubOut = buf ;
918+ cryptoInfo .pk .ecc_make_pub .pubOutSz = & outSz ;
919+
920+ ret = dev -> cb (dev -> devId , & cryptoInfo , dev -> ctx );
921+
922+ /* deserialize X9.63 uncompressed result into pubOut; reject a result
923+ * whose size is not exactly the curve's X9.63 length */
924+ if (ret == 0 ) {
925+ if (outSz != ptSz || buf [0 ] != ECC_POINT_UNCOMP ) {
926+ ret = BUFFER_E ;
927+ }
928+ else {
929+ int err = mp_read_unsigned_bin (pubOut -> x , buf + 1 , curveSz );
930+ if (err == MP_OKAY )
931+ err = mp_read_unsigned_bin (pubOut -> y , buf + 1 + curveSz ,
932+ curveSz );
933+ if (err == MP_OKAY )
934+ err = mp_set (pubOut -> z , 1 );
935+ if (err != MP_OKAY )
936+ ret = err ;
937+ }
938+ }
939+
940+ WC_FREE_VAR_EX (buf , key -> heap , DYNAMIC_TYPE_ECC_BUFFER );
941+ }
942+
943+ return wc_CryptoCb_TranslateErrorCode (ret );
944+ }
945+
946+ #ifdef HAVE_ECC_CHECK_KEY
947+ int wc_CryptoCb_EccCheckPubKey (ecc_key * key , int checkOrder , int checkPriv )
948+ {
949+ int ret = WC_NO_ERR_TRACE (CRYPTOCB_UNAVAILABLE );
950+ CryptoCb * dev ;
951+
952+ if (key == NULL || key -> dp == NULL )
953+ return ret ;
954+
955+ if (key -> dp -> size > MAX_ECC_BYTES )
956+ return ret ;
957+
958+ /* locate registered callback */
959+ dev = wc_CryptoCb_FindDevice (key -> devId , WC_ALGO_TYPE_PK );
960+ if (dev && dev -> cb ) {
961+ wc_CryptoInfo cryptoInfo ;
962+ word32 curveSz = (word32 )key -> dp -> size ;
963+ word32 ptSz = 1 + 2 * curveSz ;
964+ word32 xSz = curveSz ;
965+ word32 ySz = curveSz ;
966+ /* a key with no host-side public point is represented by
967+ * ECC_PRIVATEKEY_ONLY and crosses as pubKey = NULL / pubKeySz = 0.
968+ * If the key state says a public point exists, serialize it even when
969+ * the coordinates are invalid (e.g. 0,0) so the device can reject the
970+ * actual input instead of seeing "no public point". */
971+ int havePub = (key -> type != ECC_PRIVATEKEY_ONLY );
972+ WC_DECLARE_VAR (buf , byte , (1 + 2 * MAX_ECC_BYTES ), key -> heap );
973+
974+ ret = MP_OKAY ;
975+ if (havePub ) {
976+ WC_ALLOC_VAR_EX (buf , byte , (1 + 2 * MAX_ECC_BYTES ), key -> heap ,
977+ DYNAMIC_TYPE_ECC_BUFFER , return MEMORY_E );
978+ /* serialize key->pubkey to X9.63 uncompressed (0x04 || X || Y) */
979+ buf [0 ] = ECC_POINT_UNCOMP ;
980+ ret = wc_export_int (key -> pubkey .x , buf + 1 , & xSz , curveSz ,
981+ WC_TYPE_UNSIGNED_BIN );
982+ if (ret == MP_OKAY )
983+ ret = wc_export_int (key -> pubkey .y , buf + 1 + curveSz , & ySz ,
984+ curveSz , WC_TYPE_UNSIGNED_BIN );
985+ }
986+
987+ if (ret == MP_OKAY ) {
988+ XMEMSET (& cryptoInfo , 0 , sizeof (cryptoInfo ));
989+ cryptoInfo .algo_type = WC_ALGO_TYPE_PK ;
990+ cryptoInfo .pk .type = WC_PK_TYPE_EC_CHECK_PUB_KEY ;
991+ cryptoInfo .pk .ecc_check_pub .key = key ;
992+ cryptoInfo .pk .ecc_check_pub .pubKey = havePub ? buf : NULL ;
993+ cryptoInfo .pk .ecc_check_pub .pubKeySz = havePub ? ptSz : 0 ;
994+ cryptoInfo .pk .ecc_check_pub .checkOrder = checkOrder ;
995+ cryptoInfo .pk .ecc_check_pub .checkPriv = checkPriv ;
996+
997+ ret = dev -> cb (dev -> devId , & cryptoInfo , dev -> ctx );
998+ }
999+
1000+ if (havePub ) {
1001+ WC_FREE_VAR_EX (buf , key -> heap , DYNAMIC_TYPE_ECC_BUFFER );
1002+ }
1003+ }
1004+
1005+ return wc_CryptoCb_TranslateErrorCode (ret );
1006+ }
1007+ #endif /* HAVE_ECC_CHECK_KEY */
8851008#endif /* HAVE_ECC */
8861009
8871010#ifdef HAVE_CURVE25519
0 commit comments