Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/wolfprovider/wp_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ int wp_params_get_uint(const OSSL_PARAM* params, const char* key,
int wp_params_set_mp(OSSL_PARAM params[], const char* key, mp_int* mp);
int wp_params_set_octet_string_be(OSSL_PARAM params[], const char* key,
unsigned char* data, size_t len);

int wp_params_count(const OSSL_PARAM *p);
#endif /* WP_PARAMS_H */

6 changes: 5 additions & 1 deletion scripts/utils-wolfssl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ install_wolfssl() {
CONF_ARGS="-prefix=${WOLFSSL_INSTALL_DIR}"

if [ "$WOLFPROV_DEBUG" = "1" ]; then
CONF_ARGS+=" --enable-debug --enable-debug-trace-errcodes=backtrace --enable-keylog-export"
CONF_ARGS+=" --enable-debug --enable-keylog-export"
if [[ "$OSTYPE" != "darwin"* ]]; then
# macOS doesn't support backtrace
CONF_ARGS+=" --enable-debug-trace-errcodes=backtrace"
fi
WOLFSSL_CONFIG_CFLAGS+=" -DWOLFSSL_LOGGINGENABLED_DEFAULT=1"
fi
if [ -n "$WOLFSSL_FIPS_BUNDLE" ]; then
Expand Down
15 changes: 15 additions & 0 deletions src/wp_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -645,3 +645,18 @@ int wp_params_set_octet_string_be(OSSL_PARAM params[], const char* key,
return ok;
}

/**
* Count the number of parameters in the array, not including the end marker.
*
* @param [in] params Array of parameters.
* @return number of parameters in the array.
*/
int wp_params_count(const OSSL_PARAM *p)
{
int cnt = 0;
while ((p != NULL) && (p->key != NULL)) {
cnt++;
p++;
}
return cnt;
}
73 changes: 43 additions & 30 deletions src/wp_rsa_kmgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, NULL, 0)
#define OFFSETOF(type, field) ((size_t)&(((type *)0)->field))
#endif

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif

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

static int wp_params_count(const OSSL_PARAM *p)
{
int cnt = 0;
while ((p != NULL) && (p->key != NULL)) {
cnt++;
p++;
}
return cnt;
}

/**
* Import the key data into RSA key object from parameters.
*
Expand All @@ -1087,28 +1080,48 @@ static int wp_rsa_import_key_data(wp_Rsa* rsa, const OSSL_PARAM params[],
int priv)
{
int ok = 1;
int i;
int cnt;

if (priv && (wp_params_count(params) > 2)) {
cnt = WP_RSA_PARAM_NUMS_CNT;
rsa->key.type = RSA_PRIVATE;
}
else {
cnt = WP_RSA_PARAM_PUB_NUMS_CNT;
rsa->key.type = RSA_PUBLIC;
int i, j, index = -1;
int cnt = 0;
mp_int* mp = NULL;
const OSSL_PARAM* p = NULL;

/* N and E params are the only ones required by OSSL, so match that.
* See ossl_rsa_fromdata() and RSA_set0_key() in OpenSSL. */
if (OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N) == NULL ||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E) == NULL) {
WOLFPROV_MSG(WP_LOG_PK, "Param N or E is missing");
ok = 0;
}

for (i = 0; ok && (i < cnt); i++) {
const OSSL_PARAM* p = OSSL_PARAM_locate_const(params,
wp_rsa_param_key[i]);
if (p == NULL) {
ok = 0;
}
if (ok) {
mp_int* mp = (mp_int*)(((byte*)&rsa->key) + wp_rsa_offset[i]);
if (!wp_mp_read_unsigned_bin_le(mp, p->data, p->data_size)) {
ok = 0;
if (ok) {
cnt = wp_params_count(params);
rsa->key.type = priv ? RSA_PRIVATE : RSA_PUBLIC;

for (i = 0; i < cnt; i++) {
/* Use the table to look up the offset in the rsa struct */
p = &params[i];
index = -1;
for (j = 0; j < (int)ARRAY_SIZE(wp_rsa_param_key); j++) {
if (XSTRNCMP(p->key, wp_rsa_param_key[j], p->data_size) == 0) {
index = j;
break;
}
}
if (index < 0) {
/* Follow OSSL implementation and ignore irrelevant fields. */
WOLFPROV_MSG(WP_LOG_PK, "Unexpected param %s, skipping.",
p->key);
continue;
}

/* Read the value into the rsa struct */
if (ok) {
mp = (mp_int*)(((byte*)&rsa->key) + wp_rsa_offset[index]);
if (!wp_mp_read_unsigned_bin_le(mp, p->data, p->data_size)) {
WOLFPROV_MSG(WP_LOG_PK,
"Failed to read %s from parameters", p->key);
ok = 0;
}
}
}
}
Expand Down
154 changes: 154 additions & 0 deletions test/test_rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@

#ifdef WP_HAVE_RSA

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif

static const unsigned char rsa_key_der_256[] =
{
0x30, 0x81, 0xC1, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86,
Expand Down Expand Up @@ -1004,4 +1008,154 @@ int test_rsa_load_cert(void* data)
OSSL_STORE_close(ctx);
return err;
}

int test_rsa_fromdata(void* data)
{
(void)data;
int err = 0;
EVP_PKEY_CTX *ctx_wolf = NULL;
EVP_PKEY_CTX *ctx_ossl = NULL;

PRINT_MSG("Testing EVP_PKEY_fromdata");

ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, "RSA", NULL);
ctx_ossl = EVP_PKEY_CTX_new_from_name(osslLibCtx, "RSA", NULL);
if (ctx_wolf == NULL || ctx_ossl == NULL) {
err = 1;
}

if (err == 0) {
/* EVP_PKEY_fromdata_init returns 1 on success */
err |= EVP_PKEY_fromdata_init(ctx_wolf) != 1;
err |= EVP_PKEY_fromdata_init(ctx_ossl) != 1;
}

if (err == 0) {
EVP_PKEY *pkey_wolf = NULL;
EVP_PKEY *pkey_ossl = NULL;

/* Permutations of the selection field to test */
static const int selections[] = {
EVP_PKEY_KEYPAIR,
EVP_PKEY_PUBLIC_KEY,
EVP_PKEY_PRIVATE_KEY,
};

/* Parameter data fields */
unsigned long rsa_n = 0xbc747fc5;
unsigned long rsa_e = 0x10001;
unsigned long rsa_d = 0x7b133399;
const char *foo = "some string";
size_t foo_l = strlen(foo);
const char bar[] = "some other string";

/* Permutations of the params field to test */
OSSL_PARAM params_none[] = {
OSSL_PARAM_END
};
OSSL_PARAM params_n[] = {
OSSL_PARAM_ulong("n", &rsa_n),
OSSL_PARAM_END
};
OSSL_PARAM params_e[] = {
OSSL_PARAM_ulong("e", &rsa_e),
OSSL_PARAM_END
};
OSSL_PARAM params_d[] = {
OSSL_PARAM_ulong("d", &rsa_d),
OSSL_PARAM_END
};
OSSL_PARAM params_ne[] = {
OSSL_PARAM_ulong("n", &rsa_n),
OSSL_PARAM_ulong("e", &rsa_e),
OSSL_PARAM_END
};
OSSL_PARAM params_nd[] = {
OSSL_PARAM_ulong("n", &rsa_n),
OSSL_PARAM_ulong("d", &rsa_d),
OSSL_PARAM_END
};
OSSL_PARAM params_ed[] = {
OSSL_PARAM_ulong("e", &rsa_e),
OSSL_PARAM_ulong("d", &rsa_d),
OSSL_PARAM_END
};
OSSL_PARAM params_ned[] = {
OSSL_PARAM_ulong("n", &rsa_n),
OSSL_PARAM_ulong("e", &rsa_e),
OSSL_PARAM_ulong("d", &rsa_d),
OSSL_PARAM_END
};
OSSL_PARAM params_extra_ulong[] = {
OSSL_PARAM_ulong("n", &rsa_n),
OSSL_PARAM_ulong("e", &rsa_e),
OSSL_PARAM_ulong("d", &rsa_d),
OSSL_PARAM_ulong("asdf", &rsa_d),
OSSL_PARAM_END
};
OSSL_PARAM params_extra_str[] = {
OSSL_PARAM_ulong("n", &rsa_n),
OSSL_PARAM_ulong("e", &rsa_e),
OSSL_PARAM_ulong("d", &rsa_d),
{ "foo", OSSL_PARAM_UTF8_PTR, &foo, foo_l, 0 },
{ "bar", OSSL_PARAM_UTF8_STRING, (void *)&bar, sizeof(bar) - 1, 0 },
OSSL_PARAM_END
};
OSSL_PARAM* params_table[] = {
params_none,
params_n,
params_e,
params_d,
params_ne,
params_nd,
params_ed,
params_ned,
params_extra_ulong,
params_extra_str,
};

for (unsigned i = 0; i < ARRAY_SIZE(selections); i++) {
for (unsigned j = 0; j < ARRAY_SIZE(params_table); j++) {
int status_wolf = EVP_PKEY_fromdata(ctx_wolf, &pkey_wolf,
selections[i], &params_table[j][0]);
int status_ossl = EVP_PKEY_fromdata(ctx_ossl, &pkey_ossl,
selections[i], &params_table[j][0]);

if (status_wolf != status_ossl) {
PRINT_MSG("EVP_PKEY_fromdata (wolf=%d) and (ossl=%d) status "
"mismatch for selection %d (0x%08X) and params %d",
status_wolf, status_ossl, i, selections[i], j);
err = 1;
}
else if (status_wolf == 1) {
PRINT_MSG("EVP_PKEY_fromdata (wolf) succeeded for "
"selection %d (0x%08X) and params %d",
i, selections[i], j);

if (EVP_PKEY_cmp(pkey_wolf, pkey_ossl) != 1) {
PRINT_MSG("EVP_PKEY_cmp failed for selection %d "
"(0x%08X)", i, selections[i]);
err = 1;
}
if (EVP_PKEY_cmp_parameters(pkey_wolf, pkey_ossl) != 1) {
PRINT_MSG("EVP_PKEY_cmp_parameters failed for "
"selection %d (0x%08X)", i, selections[i]);
err = 1;
}
}

EVP_PKEY_free(pkey_wolf);
EVP_PKEY_free(pkey_ossl);
pkey_wolf = NULL;
pkey_ossl = NULL;
}
}
}

EVP_PKEY_CTX_free(ctx_wolf);
EVP_PKEY_CTX_free(ctx_ossl);

return err;
}

#endif /* WP_HAVE_RSA */
1 change: 1 addition & 0 deletions test/unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ TEST_CASE test_case[] = {
TEST_DECL(test_rsa_get_params, NULL),
TEST_DECL(test_rsa_load_key, NULL),
TEST_DECL(test_rsa_load_cert, NULL),
TEST_DECL(test_rsa_fromdata, NULL),
#endif /* WP_HAVE_RSA */
#ifdef WP_HAVE_EC_P192
#ifdef WP_HAVE_ECKEYGEN
Expand Down
5 changes: 3 additions & 2 deletions test/unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@
#define PRINT_MSG(str)
#define PRINT_ERR_MSG(str)
#else
#define PRINT_MSG(str) printf("MSG: %s\n", str)
#define PRINT_ERR_MSG(str) printf("ERR: %s\n", str)
#define PRINT_MSG(str, ...) printf("MSG: " str "\n", ##__VA_ARGS__)
#define PRINT_ERR_MSG(str, ...) printf("ERR: " str "\n", ##__VA_ARGS__)
#endif
#ifdef WOLFPROV_DEBUG
void print_buffer(const char *desc, const unsigned char *buffer, size_t len);
Expand Down Expand Up @@ -243,6 +243,7 @@ int test_rsa_get_params(void *data);

int test_rsa_load_key(void* data);
int test_rsa_load_cert(void* data);
int test_rsa_fromdata(void* data);
#endif /* WP_HAVE_RSA */

#ifdef WP_HAVE_DH
Expand Down