diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 7f6fb75ff..13edcc49e 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -359,6 +359,30 @@ int wc_CryptoCb_RsaCheckPrivKey(RsaKey* key, const byte* pubKey, return wc_CryptoCb_TranslateErrorCode(ret); } + +int wc_CryptoCb_RsaGetSize(const RsaKey* key, int* keySize) +{ + int ret = CRYPTOCB_UNAVAILABLE; + CryptoCb* dev; + + if (key == NULL) + return ret; + + /* locate registered callback */ + dev = wc_CryptoCb_FindDevice(key->devId, WC_ALGO_TYPE_PK); + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_RSA_GET_SIZE; + cryptoInfo.pk.rsa_get_size.key = key; + cryptoInfo.pk.rsa_get_size.keySize = keySize; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} #endif /* !NO_RSA */ #ifdef HAVE_ECC diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 61288aa4f..33fb3bc64 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -4307,7 +4307,9 @@ int wc_RsaEncryptSize(const RsaKey* key) #ifdef WOLF_CRYPTO_CB if (ret == 0 && key->devId != INVALID_DEVID) { - ret = 2048/8; /* hardware handles, use 2048-bit as default */ + if (wc_CryptoCb_RsaGetSize(key, &ret) == CRYPTOCB_UNAVAILABLE) { + ret = 2048/8; /* hardware handles, use 2048-bit as default */ + } } #endif diff --git a/wolfcrypt/src/wc_pkcs11.c b/wolfcrypt/src/wc_pkcs11.c index b2386f57b..6ae88d796 100644 --- a/wolfcrypt/src/wc_pkcs11.c +++ b/wolfcrypt/src/wc_pkcs11.c @@ -1724,6 +1724,42 @@ static int Pkcs11GetRsaPublicKey(RsaKey* key, Pkcs11Session* session, return ret; } +/** + * Get the RSA modulus size in bytes from the PKCS#11 object. + * + * @param [in] session Session object. + * @param [in] pubkey Public key object. + * @param [out] modSize Size of the modulus in bytes. + * @return WC_HW_E when a PKCS#11 library call fails. + * @return MEMORY_E when a memory allocation fails. + * @return 0 on success. + */ +static int Pkcs11GetRsaModulusSize(Pkcs11Session* session, + CK_OBJECT_HANDLE pubKey, int* modSize) +{ + int ret = 0; + CK_ATTRIBUTE tmpl[] = { + { CKA_MODULUS, NULL_PTR, 0 } + }; + CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl); + CK_RV rv; + + PKCS11_DUMP_TEMPLATE("Get RSA Modulus Length", tmpl, tmplCnt); + rv = session->func->C_GetAttributeValue(session->handle, pubKey, tmpl, + tmplCnt); + PKCS11_RV("C_GetAttributeValue", rv); + if (rv != CKR_OK) { + ret = WC_HW_E; + } + PKCS11_DUMP_TEMPLATE("RSA Modulus Length", tmpl, tmplCnt); + + if (ret == 0) { + *modSize = (int)tmpl[0].ulValueLen; + } + + return ret; +} + /** * Make a handle to a private RSA key. * @@ -2965,7 +3001,6 @@ static int wc_Pkcs11CheckPrivKey_Rsa(RsaKey* priv, * @param [in] info Cryptographic operation data. * @return WC_HW_E when a PKCS#11 library call fails. * @return MEMORY_E when a memory allocation fails. - * @return MEMORY_E when a memory allocation fails. * @return MP_CMP_E when the public parts are different. * @return 0 on success. */ @@ -2982,7 +3017,7 @@ static int Pkcs11RsaCheckPrivKey(Pkcs11Session* session, wc_CryptoInfo* info) CKK_RSA, session, priv->label, priv->labelLen); } - else if (info->pk.rsa.key->idLen > 0) { + else if (priv->idLen > 0) { ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_RSA, session, priv->id, priv->idLen); } @@ -3003,6 +3038,52 @@ static int Pkcs11RsaCheckPrivKey(Pkcs11Session* session, wc_CryptoInfo* info) return ret; } + +/** + * Get the size of the RSA key in bytes. + * + * @param [in] session Session object. + * @param [in] info Cryptographic operation data. + * @return WC_HW_E when a PKCS#11 library call fails. + * @return NOT_COMPILED_IN when no modulus, label or id. + * @return 0 on success. + */ +static int Pkcs11RsaGetSize(Pkcs11Session* session, wc_CryptoInfo* info) +{ + int ret = 0; + CK_OBJECT_HANDLE privateKey; + const RsaKey* priv = info->pk.rsa_get_size.key; + + if (!mp_iszero(&priv->n)) { + /* Use the key's modulus MP integer to determine size. */ + *info->pk.rsa_get_size.keySize = mp_unsigned_bin_size(&priv->n); + } + else { + /* Get the RSA private key object. */ + if (priv->labelLen > 0) { + ret = Pkcs11FindKeyByLabel(&privateKey, CKO_PRIVATE_KEY, + CKK_RSA, session, (char*)priv->label, + priv->labelLen); + } + else if (priv->idLen > 0) { + ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_RSA, + session, (unsigned char*)priv->id, + priv->idLen); + } + else { + /* Lookup is by modulus which is not present. */ + ret = NOT_COMPILED_IN; + } + + if (ret == 0) { + /* Lookup the modulus size in bytes. */ + ret = Pkcs11GetRsaModulusSize(session, privateKey, + info->pk.rsa_get_size.keySize); + } + } + + return ret; +} #endif #ifdef HAVE_ECC @@ -3710,6 +3791,13 @@ int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) Pkcs11CloseSession(token, &session); } break; + case WC_PK_TYPE_RSA_GET_SIZE: + ret = Pkcs11OpenSession(token, &session, readWrite); + if (ret == 0) { + ret = Pkcs11RsaGetSize(&session, info); + Pkcs11CloseSession(token, &session); + } + break; #endif #ifdef HAVE_ECC #ifndef NO_PKCS11_EC_KEYGEN diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index b5a592b18..c1b4307fe 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -107,6 +107,10 @@ typedef struct wc_CryptoInfo { const byte* pubKey; word32 pubKeySz; } rsa_check; + struct { + const RsaKey* key; + int* keySize; + } rsa_get_size; #endif #ifdef HAVE_ECC struct { @@ -391,6 +395,7 @@ WOLFSSL_LOCAL int wc_CryptoCb_MakeRsaKey(RsaKey* key, int size, long e, WOLFSSL_LOCAL int wc_CryptoCb_RsaCheckPrivKey(RsaKey* key, const byte* pubKey, word32 pubKeySz); +WOLFSSL_LOCAL int wc_CryptoCb_RsaGetSize(const RsaKey* key, int* keySize); #endif /* !NO_RSA */ #ifdef HAVE_ECC diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index b105028e3..83f868dec 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1141,7 +1141,8 @@ typedef struct w64wrapper { WC_PK_TYPE_ED25519_VERIFY = 14, WC_PK_TYPE_ED25519_KEYGEN = 15, WC_PK_TYPE_CURVE25519_KEYGEN = 16, - WC_PK_TYPE_MAX = WC_PK_TYPE_CURVE25519_KEYGEN + WC_PK_TYPE_RSA_GET_SIZE = 17, + WC_PK_TYPE_MAX = WC_PK_TYPE_RSA_GET_SIZE };