Skip to content

Commit

Permalink
Merge pull request #7608 from ejohnstown/rsa-add
Browse files Browse the repository at this point in the history
Import Raw RSA Private Key
  • Loading branch information
dgarske authored Jun 3, 2024
2 parents 4140a05 + e8e6eae commit 43f4ba9
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 0 deletions.
99 changes: 99 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -19712,6 +19712,104 @@ static int test_wc_RsaPublicKeyDecodeRaw(void)
} /* END test_wc_RsaPublicKeyDecodeRaw */


/*
* Testing wc_RsaPrivateKeyDecodeRaw()
*/
static int test_wc_RsaPrivateKeyDecodeRaw(void)
{
EXPECT_DECLS;
#if !defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) \
&& !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
RsaKey key;
const byte n = 33;
const byte e = 3;
const byte d = 7;
const byte u = 2;
const byte p = 3;
const byte q = 11;
const byte dp = 1;
const byte dq = 7;

ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), NULL, 0,
NULL, 0, &key), 0);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
NULL, 0, &key), 0);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), NULL, 0,
&dq, sizeof(dq), &key), 0);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), 0);

/* Pass in bad args. */
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(NULL, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, 0,
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
NULL, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, 0, &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), NULL, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, 0, &u, sizeof(u),
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
NULL, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, 0, &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), NULL, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, sizeof(u),
&p, sizeof(p), &q, 0, &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, 0,
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), NULL, sizeof(u),
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
ExpectIntEQ(wc_RsaPrivateKeyDecodeRaw(&n, sizeof(n),
&e, sizeof(e), &d, sizeof(d), &u, 0,
&p, sizeof(p), &q, sizeof(q), &dp, sizeof(dp),
&dq, sizeof(dq), &key), BAD_FUNC_ARG);
#endif

DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
#endif
return EXPECT_RESULT();
} /* END test_wc_RsaPrivateKeyDecodeRaw */


#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
/* In FIPS builds, wc_MakeRsaKey() will return an error if it cannot find
* a probable prime in 5*(modLen/2) attempts. In non-FIPS builds, it keeps
Expand Down Expand Up @@ -72426,6 +72524,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wc_RsaPrivateKeyDecode),
TEST_DECL(test_wc_RsaPublicKeyDecode),
TEST_DECL(test_wc_RsaPublicKeyDecodeRaw),
TEST_DECL(test_wc_RsaPrivateKeyDecodeRaw),
TEST_DECL(test_wc_MakeRsaKey),
TEST_DECL(test_wc_CheckProbablePrime),
TEST_DECL(test_wc_RsaPSS_Verify),
Expand Down
101 changes: 101 additions & 0 deletions wolfcrypt/src/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -5148,4 +5148,105 @@ int wc_RsaSetNonBlockTime(RsaKey* key, word32 maxBlockUs, word32 cpuMHz)
#endif /* WC_RSA_NONBLOCK_TIME */
#endif /* WC_RSA_NONBLOCK */

#ifndef WOLFSSL_RSA_PUBLIC_ONLY

#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
/*
* Calculate y = d mod(x-1)
*/
static int CalcDX(mp_int* y, mp_int* x, mp_int* d)
{
mp_int m;
int err;

err = mp_init(&m);
if (err == MP_OKAY) {
err = mp_sub_d(x, 1, &m);
if (err == MP_OKAY)
err = mp_mod(d, &m, y);
mp_forcezero(&m);
}

return err;
}
#endif

int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz,
const byte* e, word32 eSz, const byte* d, word32 dSz,
const byte* u, word32 uSz, const byte* p, word32 pSz,
const byte* q, word32 qSz, const byte* dP, word32 dPSz,
const byte* dQ, word32 dQSz, RsaKey* key)
{
int err = MP_OKAY;

if (n == NULL || nSz == 0 || e == NULL || eSz == 0
|| d == NULL || dSz == 0 || p == NULL || pSz == 0
|| q == NULL || qSz == 0 || key == NULL) {
err = BAD_FUNC_ARG;
}

#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
if (err == MP_OKAY) {
if ((u == NULL || uSz == 0)
|| (dP != NULL && dPSz == 0)
|| (dQ != NULL && dQSz == 0)) {
err = BAD_FUNC_ARG;
}
}
#else
(void)u;
(void)uSz;
(void)dP;
(void)dPSz;
(void)dQ;
(void)dQSz;
#endif

if (err == MP_OKAY)
err = mp_read_unsigned_bin(&key->n, n, nSz);
if (err == MP_OKAY)
err = mp_read_unsigned_bin(&key->e, e, eSz);
if (err == MP_OKAY)
err = mp_read_unsigned_bin(&key->d, d, dSz);
if (err == MP_OKAY)
err = mp_read_unsigned_bin(&key->p, p, pSz);
if (err == MP_OKAY)
err = mp_read_unsigned_bin(&key->q, q, qSz);
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
if (err == MP_OKAY)
err = mp_read_unsigned_bin(&key->u, u, uSz);
if (err == MP_OKAY) {
if (dP != NULL)
err = mp_read_unsigned_bin(&key->dP, dP, dPSz);
else
err = CalcDX(&key->dP, &key->p, &key->d);
}
if (err == MP_OKAY) {
if (dQ != NULL)
err = mp_read_unsigned_bin(&key->dQ, dQ, dQSz);
else
err = CalcDX(&key->dQ, &key->q, &key->d);
}
#endif

if (err == MP_OKAY) {
key->type = RSA_PRIVATE;
}
else {
mp_clear(&key->n);
mp_clear(&key->e);
mp_clear(&key->d);
mp_clear(&key->p);
mp_clear(&key->q);
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
mp_clear(&key->u);
mp_clear(&key->dP);
mp_clear(&key->dQ);
#endif
}

return err;
}
#endif /* WOLFSSL_RSA_PUBLIC_ONLY */

#endif /* NO_RSA */
6 changes: 6 additions & 0 deletions wolfssl/wolfcrypt/rsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,12 @@ WOLFSSL_LOCAL int wc_hash2mgf(enum wc_HashType hType);
WOLFSSL_LOCAL int RsaFunctionCheckIn(const byte* in, word32 inLen, RsaKey* key,
int checkSmallCt);

WOLFSSL_API int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz,
const byte* e, word32 eSz, const byte* d, word32 dSz,
const byte* u, word32 uSz, const byte* p, word32 pSz,
const byte* q, word32 qSz, const byte* dP, word32 dPSz,
const byte* dQ, word32 dQSz, RsaKey* key);

#ifdef __cplusplus
} /* extern "C" */
#endif
Expand Down

0 comments on commit 43f4ba9

Please sign in to comment.