@@ -1074,6 +1074,27 @@ static int wp_rsa_match(const wp_Rsa* rsa1, const wp_Rsa* rsa2, int selection)
10741074 return ok ;
10751075}
10761076
1077+ #define VALIDATE_PRIMES_SIZE 133
1078+ static const mp_digit validate_primes [VALIDATE_PRIMES_SIZE ] = {
1079+ 0x0002 , 0x0003 , 0x0005 , 0x0007 , 0x000B , 0x000D , 0x0011 , 0x0013 ,
1080+ 0x0017 , 0x001D , 0x001F , 0x0025 , 0x0029 , 0x002B , 0x002F , 0x0035 ,
1081+ 0x003B , 0x003D , 0x0043 , 0x0047 , 0x0049 , 0x004F , 0x0053 , 0x0059 ,
1082+ 0x0061 , 0x0065 , 0x0067 , 0x006B , 0x006D , 0x0071 , 0x007F , 0x0083 ,
1083+ 0x0089 , 0x008B , 0x0095 , 0x0097 , 0x009D , 0x00A3 , 0x00A7 , 0x00AD ,
1084+ 0x00B3 , 0x00B5 , 0x00BF , 0x00C1 , 0x00C5 , 0x00C7 , 0x00D3 , 0x00DF ,
1085+ 0x00E3 , 0x00E5 , 0x00E9 , 0x00EF , 0x00F1 , 0x00FB , 0x0101 , 0x0107 ,
1086+ 0x010D , 0x010F , 0x0115 , 0x0119 , 0x011B , 0x0125 , 0x0133 , 0x0137 ,
1087+ 0x0139 , 0x013D , 0x014B , 0x0151 , 0x015B , 0x015D , 0x0161 , 0x0167 ,
1088+ 0x016F , 0x0175 , 0x017B , 0x017F , 0x0185 , 0x018D , 0x0191 , 0x0199 ,
1089+ 0x01A3 , 0x01A5 , 0x01AF , 0x01B1 , 0x01B7 , 0x01BB , 0x01C1 , 0x01C9 ,
1090+ 0x01CD , 0x01CF , 0x01D3 , 0x01DF , 0x01E7 , 0x01EB , 0x01F3 , 0x01F7 ,
1091+ 0x01FD , 0x0209 , 0x020B , 0x021D , 0x0223 , 0x022D , 0x0233 , 0x0239 ,
1092+ 0x023B , 0x0241 , 0x024B , 0x0251 , 0x0257 , 0x0259 , 0x025F , 0x0265 ,
1093+ 0x0269 , 0x026B , 0x0277 , 0x0281 , 0x0283 , 0x0287 , 0x028D , 0x0293 ,
1094+ 0x0295 , 0x02A1 , 0x02A5 , 0x02AB , 0x02B3 , 0x02BD , 0x02C5 , 0x02CF ,
1095+ 0x02D7 , 0x02DD , 0x02E3 , 0x02E7 , 0x02EF ,
1096+ };
1097+
10771098/**
10781099 * Validate the RSA key.
10791100 *
@@ -1106,22 +1127,72 @@ static int wp_rsa_validate(const wp_Rsa* rsa, int selection, int checkType)
11061127 else
11071128#endif
11081129 if (checkPriv ) {
1109- if (mp_isone ( & rsa -> key . d ) || mp_iszero ((mp_int * )& rsa -> key .d ) ||
1130+ if (mp_iszero ((mp_int * )& rsa -> key .d ) ||
11101131 (mp_cmp ((mp_int * )& rsa -> key .d , (mp_int * )& rsa -> key .n ) != MP_LT )) {
11111132 ok = 0 ;
11121133 }
11131134 }
11141135 else if (checkPub ) {
1115- if (mp_iseven (& rsa -> key .e ) || mp_iszero ((mp_int * )& rsa -> key .e ) ||
1116- mp_isone (& rsa -> key .e )) {
1136+ int prime ;
1137+ mp_int res ;
1138+
1139+ if (mp_iszero ((mp_int * )& rsa -> key .e ) || mp_iszero ((mp_int * )& rsa -> key .n ) ||
1140+ mp_isone ((mp_int * )& rsa -> key .e ) || mp_isone ((mp_int * )& rsa -> key .n ) ||
1141+ mp_iseven ((mp_int * )& rsa -> key .e ) || mp_iseven ((mp_int * )& rsa -> key .n )) {
1142+ ok = 0 ;
1143+ }
1144+
1145+ if (ok && mp_init (& res ) != MP_OKAY ) {
11171146 ok = 0 ;
11181147 }
1148+
1149+ if (ok ) {
1150+ for (prime = 0 ; prime < VALIDATE_PRIMES_SIZE ; prime ++ ) {
1151+ if (mp_set_int (& res , validate_primes [prime ]) != MP_OKAY ||
1152+ mp_mod ((mp_int * )& rsa -> key .n , & res , & res ) != MP_OKAY ||
1153+ mp_iszero (& res )) {
1154+ ok = 0 ;
1155+ break ;
1156+ }
1157+ }
1158+ }
1159+
1160+ mp_clear (& res );
11191161 }
11201162
11211163 WOLFPROV_LEAVE (WP_LOG_COMP_RSA , __FILE__ ":" WOLFPROV_STRINGIZE (__LINE__ ), ok );
11221164 return ok ;
11231165}
11241166
1167+ /**
1168+ * Copy an unsigned value from an OSSL param into a provided RSA key parameter.
1169+ *
1170+ * @param [out] mp RSA key parameter.
1171+ * @param [in] param Parameter to copy value from.
1172+ * @return 1 on success.
1173+ * @return 0 on failure.
1174+ */
1175+ static int wp_rsa_import_store_unsigned (mp_int * mp , const OSSL_PARAM * param )
1176+ {
1177+ int ok = 1 ;
1178+
1179+ if (param -> data == NULL ){
1180+ ok = 0 ;
1181+ }
1182+ else if (param -> data_type != OSSL_PARAM_UNSIGNED_INTEGER ){
1183+ /* Negative values are stored as NULL by OSSL, for now just set to 0
1184+ * since NULL can't be stored */
1185+ ok = mp_set (mp , 0 ) == MP_OKAY ;
1186+ }
1187+ else if (!wp_mp_read_unsigned_bin_le (mp , param -> data , param -> data_size )) {
1188+ WOLFPROV_MSG (WP_LOG_COMP_RSA ,
1189+ "Failed to read %s from parameters" , param -> key );
1190+ ok = 0 ;
1191+ }
1192+
1193+ return ok ;
1194+ }
1195+
11251196/**
11261197 * Import the key data into RSA key object from parameters.
11271198 *
@@ -1139,18 +1210,26 @@ static int wp_rsa_import_key_data(wp_Rsa* rsa, const OSSL_PARAM params[],
11391210 int cnt = 0 ;
11401211 mp_int * mp = NULL ;
11411212 const OSSL_PARAM * p = NULL ;
1213+ const OSSL_PARAM * n = NULL ;
1214+ const OSSL_PARAM * e = NULL ;
1215+ const OSSL_PARAM * d = NULL ;
11421216
11431217 WOLFPROV_ENTER (WP_LOG_COMP_RSA , "wp_rsa_import_key_data" );
11441218
11451219 /* N and E params are the only ones required by OSSL, so match that.
11461220 * See ossl_rsa_fromdata() and RSA_set0_key() in OpenSSL. */
1147- if (OSSL_PARAM_locate_const (params , OSSL_PKEY_PARAM_RSA_N ) == NULL ||
1148- OSSL_PARAM_locate_const (params , OSSL_PKEY_PARAM_RSA_E ) == NULL ) {
1221+ if ((n = OSSL_PARAM_locate_const (params , OSSL_PKEY_PARAM_RSA_N )) == NULL ||
1222+ n -> data == NULL ||
1223+ (e = OSSL_PARAM_locate_const (params , OSSL_PKEY_PARAM_RSA_E )) == NULL ||
1224+ e -> data == NULL ){
11491225 WOLFPROV_MSG (WP_LOG_COMP_RSA , "Param N or E is missing" );
11501226 ok = 0 ;
11511227 }
1228+ if (ok && priv ) {
1229+ d = OSSL_PARAM_locate_const (params , OSSL_PKEY_PARAM_RSA_D );
1230+ }
11521231
1153- if (ok ) {
1232+ if (ok && d != NULL ) {
11541233 cnt = wp_params_count (params );
11551234 rsa -> key .type = priv ? RSA_PRIVATE : RSA_PUBLIC ;
11561235
@@ -1160,7 +1239,7 @@ static int wp_rsa_import_key_data(wp_Rsa* rsa, const OSSL_PARAM params[],
11601239 index = -1 ;
11611240 for (j = 0 ; j < (int )ARRAY_SIZE (wp_rsa_param_key ); j ++ ) {
11621241 if (XSTRNCMP (p -> key , wp_rsa_param_key [j ], XSTRLEN (p -> key )) == 0 ) {
1163- index = j ;
1242+ index = j ;
11641243 break ;
11651244 }
11661245 }
@@ -1170,18 +1249,21 @@ static int wp_rsa_import_key_data(wp_Rsa* rsa, const OSSL_PARAM params[],
11701249 p -> key );
11711250 continue ;
11721251 }
1173-
11741252 /* Read the value into the rsa struct */
11751253 if (ok ) {
11761254 mp = (mp_int * )(((byte * )& rsa -> key ) + wp_rsa_offset [index ]);
1177- if (!wp_mp_read_unsigned_bin_le (mp , p -> data , p -> data_size )) {
1178- WOLFPROV_MSG (WP_LOG_COMP_RSA ,
1179- "Failed to read %s from parameters" , p -> key );
1180- ok = 0 ;
1181- }
1255+ ok = wp_rsa_import_store_unsigned (mp , p );
11821256 }
11831257 }
11841258 }
1259+ else if (ok && d == NULL ) {
1260+ mp = & rsa -> key .n ;
1261+ ok = wp_rsa_import_store_unsigned (mp , n );
1262+ if (ok ){
1263+ mp = & rsa -> key .e ;
1264+ ok = wp_rsa_import_store_unsigned (mp , e );
1265+ }
1266+ }
11851267
11861268 WOLFPROV_LEAVE (WP_LOG_COMP_RSA , __FILE__ ":" WOLFPROV_STRINGIZE (__LINE__ ), ok );
11871269 return ok ;
0 commit comments