Skip to content

Commit b401bb5

Browse files
committed
Add test cases for EVP_PKEY_fromdata, fix incompatibility in wp_rsa_import_key_data().
1 parent b896f5b commit b401bb5

File tree

7 files changed

+222
-34
lines changed

7 files changed

+222
-34
lines changed

include/wolfprovider/wp_params.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,6 @@ int wp_params_get_uint(const OSSL_PARAM* params, const char* key,
7373
int wp_params_set_mp(OSSL_PARAM params[], const char* key, mp_int* mp);
7474
int wp_params_set_octet_string_be(OSSL_PARAM params[], const char* key,
7575
unsigned char* data, size_t len);
76-
76+
int wp_params_count(const OSSL_PARAM *p);
7777
#endif /* WP_PARAMS_H */
7878

scripts/utils-wolfssl.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ install_wolfssl() {
8181
CONF_ARGS="-prefix=${WOLFSSL_INSTALL_DIR}"
8282

8383
if [ "$WOLFPROV_DEBUG" = "1" ]; then
84-
CONF_ARGS+=" --enable-debug --enable-debug-trace-errcodes=backtrace --enable-keylog-export"
84+
CONF_ARGS+=" --enable-debug --enable-keylog-export"
85+
if [[ "$OSTYPE" != "darwin"* ]]; then
86+
# macOS doesn't support backtrace
87+
CONF_ARGS+=" --enable-debug-trace-errcodes=backtrace"
88+
fi
8589
WOLFSSL_CONFIG_CFLAGS+=" -DWOLFSSL_LOGGINGENABLED_DEFAULT=1"
8690
fi
8791
if [ -n "$WOLFSSL_FIPS_BUNDLE" ]; then

src/wp_params.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,3 +645,18 @@ int wp_params_set_octet_string_be(OSSL_PARAM params[], const char* key,
645645
return ok;
646646
}
647647

648+
/**
649+
* Count the number of parameters in the array, not including the end marker.
650+
*
651+
* @param [in] params Array of parameters.
652+
* @return number of parameters in the array.
653+
*/
654+
int wp_params_count(const OSSL_PARAM *p)
655+
{
656+
int cnt = 0;
657+
while ((p != NULL) && (p->key != NULL)) {
658+
cnt++;
659+
p++;
660+
}
661+
return cnt;
662+
}

src/wp_rsa_kmgmt.c

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, NULL, 0)
7777
#define OFFSETOF(type, field) ((size_t)&(((type *)0)->field))
7878
#endif
7979

80+
#ifndef ARRAY_SIZE
81+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
82+
#endif
8083

8184
/** SHA-256 Algorithm ID DER encoding in PSS parameters. */
8285
static const byte sha256AlgId[] = {
@@ -1064,16 +1067,6 @@ static int wp_rsa_validate(const wp_Rsa* rsa, int selection, int checkType)
10641067
return ok;
10651068
}
10661069

1067-
static int wp_params_count(const OSSL_PARAM *p)
1068-
{
1069-
int cnt = 0;
1070-
while ((p != NULL) && (p->key != NULL)) {
1071-
cnt++;
1072-
p++;
1073-
}
1074-
return cnt;
1075-
}
1076-
10771070
/**
10781071
* Import the key data into RSA key object from parameters.
10791072
*
@@ -1087,28 +1080,48 @@ static int wp_rsa_import_key_data(wp_Rsa* rsa, const OSSL_PARAM params[],
10871080
int priv)
10881081
{
10891082
int ok = 1;
1090-
int i;
1091-
int cnt;
1092-
1093-
if (priv && (wp_params_count(params) > 2)) {
1094-
cnt = WP_RSA_PARAM_NUMS_CNT;
1095-
rsa->key.type = RSA_PRIVATE;
1096-
}
1097-
else {
1098-
cnt = WP_RSA_PARAM_PUB_NUMS_CNT;
1099-
rsa->key.type = RSA_PUBLIC;
1083+
int i, j, index = -1;
1084+
int cnt = 0;
1085+
mp_int* mp = NULL;
1086+
const OSSL_PARAM* p = NULL;
1087+
1088+
/* N and E params are the only ones required by OSSL, so match that.
1089+
* See ossl_rsa_fromdata() and RSA_set0_key() in OpenSSL. */
1090+
if (OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N) == NULL ||
1091+
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E) == NULL) {
1092+
WOLFPROV_MSG(WP_LOG_PK, "Param N or E is missing");
1093+
ok = 0;
11001094
}
11011095

1102-
for (i = 0; ok && (i < cnt); i++) {
1103-
const OSSL_PARAM* p = OSSL_PARAM_locate_const(params,
1104-
wp_rsa_param_key[i]);
1105-
if (p == NULL) {
1106-
ok = 0;
1107-
}
1108-
if (ok) {
1109-
mp_int* mp = (mp_int*)(((byte*)&rsa->key) + wp_rsa_offset[i]);
1110-
if (!wp_mp_read_unsigned_bin_le(mp, p->data, p->data_size)) {
1111-
ok = 0;
1096+
if (ok) {
1097+
cnt = wp_params_count(params);
1098+
rsa->key.type = priv ? RSA_PRIVATE : RSA_PUBLIC;
1099+
1100+
for (i = 0; i < cnt; i++) {
1101+
/* Use the table to look up the offset in the rsa struct */
1102+
p = &params[i];
1103+
index = -1;
1104+
for (j = 0; j < (int)ARRAY_SIZE(wp_rsa_param_key); j++) {
1105+
if (XSTRNCMP(p->key, wp_rsa_param_key[j], p->data_size) == 0) {
1106+
index = j;
1107+
break;
1108+
}
1109+
}
1110+
if (index < 0) {
1111+
/* Follow OSSL implementation and ignore irrelevant fields. */
1112+
WOLFPROV_MSG(WP_LOG_PK, "Unexpected param %s, skipping.",
1113+
p->key);
1114+
continue;
1115+
}
1116+
1117+
/* Read the value into the rsa struct */
1118+
if (ok) {
1119+
mp = (mp_int*)(((byte*)&rsa->key) + wp_rsa_offset[index]);
1120+
if (!wp_mp_read_unsigned_bin_le(mp, p->data, p->data_size)) {
1121+
WOLFPROV_MSG(WP_LOG_PK,
1122+
"Failed to read %s from parameters", p->key);
1123+
ok = 0;
1124+
}
11121125
}
11131126
}
11141127
}

test/test_rsa.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626

2727
#ifdef WP_HAVE_RSA
2828

29+
#ifndef ARRAY_SIZE
30+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
31+
#endif
32+
2933
static const unsigned char rsa_key_der_256[] =
3034
{
3135
0x30, 0x81, 0xC1, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86,
@@ -1004,4 +1008,154 @@ int test_rsa_load_cert(void* data)
10041008
OSSL_STORE_close(ctx);
10051009
return err;
10061010
}
1011+
1012+
int test_rsa_fromdata(void* data)
1013+
{
1014+
(void)data;
1015+
int err = 0;
1016+
EVP_PKEY_CTX *ctx_wolf = NULL;
1017+
EVP_PKEY_CTX *ctx_ossl = NULL;
1018+
1019+
PRINT_MSG("Testing EVP_PKEY_fromdata");
1020+
1021+
ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, "RSA", NULL);
1022+
ctx_ossl = EVP_PKEY_CTX_new_from_name(osslLibCtx, "RSA", NULL);
1023+
if (ctx_wolf == NULL || ctx_ossl == NULL) {
1024+
err = 1;
1025+
}
1026+
1027+
if (err == 0) {
1028+
/* EVP_PKEY_fromdata_init returns 1 on success */
1029+
err |= EVP_PKEY_fromdata_init(ctx_wolf) != 1;
1030+
err |= EVP_PKEY_fromdata_init(ctx_ossl) != 1;
1031+
}
1032+
1033+
if (err == 0) {
1034+
EVP_PKEY *pkey_wolf = NULL;
1035+
EVP_PKEY *pkey_ossl = NULL;
1036+
1037+
/* Permutations of the selection field to test */
1038+
static const int selections[] = {
1039+
EVP_PKEY_KEYPAIR,
1040+
EVP_PKEY_PUBLIC_KEY,
1041+
EVP_PKEY_PRIVATE_KEY,
1042+
};
1043+
1044+
/* Parameter data fields */
1045+
unsigned long rsa_n = 0xbc747fc5;
1046+
unsigned long rsa_e = 0x10001;
1047+
unsigned long rsa_d = 0x7b133399;
1048+
const char *foo = "some string";
1049+
size_t foo_l = strlen(foo);
1050+
const char bar[] = "some other string";
1051+
1052+
/* Permutations of the params field to test */
1053+
OSSL_PARAM params_none[] = {
1054+
OSSL_PARAM_END
1055+
};
1056+
OSSL_PARAM params_n[] = {
1057+
OSSL_PARAM_ulong("n", &rsa_n),
1058+
OSSL_PARAM_END
1059+
};
1060+
OSSL_PARAM params_e[] = {
1061+
OSSL_PARAM_ulong("e", &rsa_e),
1062+
OSSL_PARAM_END
1063+
};
1064+
OSSL_PARAM params_d[] = {
1065+
OSSL_PARAM_ulong("d", &rsa_d),
1066+
OSSL_PARAM_END
1067+
};
1068+
OSSL_PARAM params_ne[] = {
1069+
OSSL_PARAM_ulong("n", &rsa_n),
1070+
OSSL_PARAM_ulong("e", &rsa_e),
1071+
OSSL_PARAM_END
1072+
};
1073+
OSSL_PARAM params_nd[] = {
1074+
OSSL_PARAM_ulong("n", &rsa_n),
1075+
OSSL_PARAM_ulong("d", &rsa_d),
1076+
OSSL_PARAM_END
1077+
};
1078+
OSSL_PARAM params_ed[] = {
1079+
OSSL_PARAM_ulong("e", &rsa_e),
1080+
OSSL_PARAM_ulong("d", &rsa_d),
1081+
OSSL_PARAM_END
1082+
};
1083+
OSSL_PARAM params_ned[] = {
1084+
OSSL_PARAM_ulong("n", &rsa_n),
1085+
OSSL_PARAM_ulong("e", &rsa_e),
1086+
OSSL_PARAM_ulong("d", &rsa_d),
1087+
OSSL_PARAM_END
1088+
};
1089+
OSSL_PARAM params_extra_ulong[] = {
1090+
OSSL_PARAM_ulong("n", &rsa_n),
1091+
OSSL_PARAM_ulong("e", &rsa_e),
1092+
OSSL_PARAM_ulong("d", &rsa_d),
1093+
OSSL_PARAM_ulong("asdf", &rsa_d),
1094+
OSSL_PARAM_END
1095+
};
1096+
OSSL_PARAM params_extra_str[] = {
1097+
OSSL_PARAM_ulong("n", &rsa_n),
1098+
OSSL_PARAM_ulong("e", &rsa_e),
1099+
OSSL_PARAM_ulong("d", &rsa_d),
1100+
{ "foo", OSSL_PARAM_UTF8_PTR, &foo, foo_l, 0 },
1101+
{ "bar", OSSL_PARAM_UTF8_STRING, (void *)&bar, sizeof(bar) - 1, 0 },
1102+
OSSL_PARAM_END
1103+
};
1104+
OSSL_PARAM* params_table[] = {
1105+
params_none,
1106+
params_n,
1107+
params_e,
1108+
params_d,
1109+
params_ne,
1110+
params_nd,
1111+
params_ed,
1112+
params_ned,
1113+
params_extra_ulong,
1114+
params_extra_str,
1115+
};
1116+
1117+
for (unsigned i = 0; i < ARRAY_SIZE(selections); i++) {
1118+
for (unsigned j = 0; j < ARRAY_SIZE(params_table); j++) {
1119+
int status_wolf = EVP_PKEY_fromdata(ctx_wolf, &pkey_wolf,
1120+
selections[i], &params_table[j][0]);
1121+
int status_ossl = EVP_PKEY_fromdata(ctx_ossl, &pkey_ossl,
1122+
selections[i], &params_table[j][0]);
1123+
1124+
if (status_wolf != status_ossl) {
1125+
PRINT_MSG("EVP_PKEY_fromdata (wolf=%d) and (ossl=%d) status "
1126+
"mismatch for selection %d (0x%08X) and params %d",
1127+
status_wolf, status_ossl, i, selections[i], j);
1128+
err = 1;
1129+
}
1130+
else if (status_wolf == 1) {
1131+
PRINT_MSG("EVP_PKEY_fromdata (wolf) succeeded for "
1132+
"selection %d (0x%08X) and params %d",
1133+
i, selections[i], j);
1134+
1135+
if (EVP_PKEY_cmp(pkey_wolf, pkey_ossl) != 1) {
1136+
PRINT_MSG("EVP_PKEY_cmp failed for selection %d "
1137+
"(0x%08X)", i, selections[i]);
1138+
err = 1;
1139+
}
1140+
if (EVP_PKEY_cmp_parameters(pkey_wolf, pkey_ossl) != 1) {
1141+
PRINT_MSG("EVP_PKEY_cmp_parameters failed for "
1142+
"selection %d (0x%08X)", i, selections[i]);
1143+
err = 1;
1144+
}
1145+
}
1146+
1147+
EVP_PKEY_free(pkey_wolf);
1148+
EVP_PKEY_free(pkey_ossl);
1149+
pkey_wolf = NULL;
1150+
pkey_ossl = NULL;
1151+
}
1152+
}
1153+
}
1154+
1155+
EVP_PKEY_CTX_free(ctx_wolf);
1156+
EVP_PKEY_CTX_free(ctx_ossl);
1157+
1158+
return err;
1159+
}
1160+
10071161
#endif /* WP_HAVE_RSA */

test/unit.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ TEST_CASE test_case[] = {
164164
TEST_DECL(test_rsa_get_params, NULL),
165165
TEST_DECL(test_rsa_load_key, NULL),
166166
TEST_DECL(test_rsa_load_cert, NULL),
167+
TEST_DECL(test_rsa_fromdata, NULL),
167168
#endif /* WP_HAVE_RSA */
168169
#ifdef WP_HAVE_EC_P192
169170
#ifdef WP_HAVE_ECKEYGEN

test/unit.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
#define PRINT_MSG(str)
4848
#define PRINT_ERR_MSG(str)
4949
#else
50-
#define PRINT_MSG(str) printf("MSG: %s\n", str)
51-
#define PRINT_ERR_MSG(str) printf("ERR: %s\n", str)
50+
#define PRINT_MSG(str, ...) printf("MSG: " str "\n", ##__VA_ARGS__)
51+
#define PRINT_ERR_MSG(str, ...) printf("ERR: " str "\n", ##__VA_ARGS__)
5252
#endif
5353
#ifdef WOLFPROV_DEBUG
5454
void print_buffer(const char *desc, const unsigned char *buffer, size_t len);
@@ -243,6 +243,7 @@ int test_rsa_get_params(void *data);
243243

244244
int test_rsa_load_key(void* data);
245245
int test_rsa_load_cert(void* data);
246+
int test_rsa_fromdata(void* data);
246247
#endif /* WP_HAVE_RSA */
247248

248249
#ifdef WP_HAVE_DH

0 commit comments

Comments
 (0)