From e86aae00edad2931727a88bebc728bb293b7fe27 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 11 Feb 2019 10:25:53 +1000 Subject: [PATCH] Change to allow setting of devId for private key --- src/internal.c | 84 ++++++--------------- src/ssl.c | 12 ++- wolfcrypt/src/ecc.c | 8 ++ wolfcrypt/src/wc_pkcs11.c | 152 ++++++++++++++++++++------------------ wolfssl/internal.h | 2 + wolfssl/ssl.h | 4 +- 6 files changed, 126 insertions(+), 136 deletions(-) diff --git a/src/internal.c b/src/internal.c index 38f078121..cbe49380d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4413,10 +4413,11 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #ifdef WOLFSSL_TLS13 ssl->buffers.certChainCnt = ctx->certChainCnt; #endif - ssl->buffers.key = ctx->privateKey; - ssl->buffers.keyType = ctx->privateKeyType; - ssl->buffers.keyId = ctx->privateKeyId; - ssl->buffers.keySz = ctx->privateKeySz; + ssl->buffers.key = ctx->privateKey; + ssl->buffers.keyType = ctx->privateKeyType; + ssl->buffers.keyId = ctx->privateKeyId; + ssl->buffers.keySz = ctx->privateKeySz; + ssl->buffers.keyDevId = ctx->privateKeyDevId; #endif #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ !defined(NO_ED25519_CLIENT_AUTH) @@ -16929,7 +16930,11 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } #ifdef HAVE_PKCS11 - if (ssl->devId != INVALID_DEVID && ssl->buffers.keyId) { + if (ssl->buffers.keyDevId != INVALID_DEVID && ssl->buffers.keyId) { + if (ssl->buffers.keyType == rsa_sa_algo) + ssl->hsType = DYNAMIC_TYPE_RSA; + else if (ssl->buffers.keyType == ecc_dsa_sa_algo) + ssl->hsType = DYNAMIC_TYPE_ECC; ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); if (ret != 0) { goto exit_dpk; @@ -16938,7 +16943,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) if (ssl->buffers.keyType == rsa_sa_algo) { ret = wc_InitRsaKey_Id((RsaKey*)ssl->hsKey, ssl->buffers.key->buffer, ssl->buffers.key->length, - ssl->heap, ssl->devId); + ssl->heap, ssl->buffers.keyDevId); if (ret == 0) { if (ssl->buffers.keySz < ssl->options.minRsaKeySz) { WOLFSSL_MSG("RSA key size too small"); @@ -16951,7 +16956,8 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } else if (ssl->buffers.keyType == ecc_dsa_sa_algo) { ret = wc_ecc_init_id((ecc_key*)ssl->hsKey, ssl->buffers.key->buffer, - ssl->buffers.key->length, ssl->heap, ssl->devId); + ssl->buffers.key->length, ssl->heap, + ssl->buffers.keyDevId); if (ret == 0) { if (ssl->buffers.keySz < ssl->options.minEccKeySz) { WOLFSSL_MSG("ECC key size too small"); @@ -22053,19 +22059,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, { word16 keySz; - ssl->hsType = DYNAMIC_TYPE_RSA; - if (ssl->buffers.keyType == 0) - ssl->buffers.keyType = rsa_sa_algo; + ssl->buffers.keyType = rsa_sa_algo; ret = DecodePrivateKey(ssl, &keySz); if (ret != 0) { - ERROR_OUT(keySz, exit_sske); + goto exit_sske; } args->tmpSigSz = (word32)keySz; - if (keySz < ssl->options.minRsaKeySz) { - WOLFSSL_MSG("RSA signature key size too small"); - ERROR_OUT(RSA_KEY_SIZE_E, exit_sske); - } break; } #endif /* !NO_RSA */ @@ -22074,21 +22074,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, { word16 keySz; - ssl->hsType = DYNAMIC_TYPE_ECC; - if (ssl->buffers.keyType == 0) - ssl->buffers.keyType = ecc_dsa_sa_algo; + ssl->buffers.keyType = ecc_dsa_sa_algo; ret = DecodePrivateKey(ssl, &keySz); if (ret != 0) { - ERROR_OUT(keySz, exit_sske); + goto exit_sske; } /* worst case estimate */ args->tmpSigSz = keySz; - - /* check the minimum ECC key size */ - if (keySz < ssl->options.minEccKeySz) { - WOLFSSL_MSG("ECC key size too small"); - ERROR_OUT(ECC_KEY_SIZE_E, exit_sske); - } break; } #endif @@ -22097,23 +22089,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, { word16 keySz; - ssl->hsType = DYNAMIC_TYPE_ED25519; - if (ssl->buffers.keyType == 0) - ssl->buffers.keyType = ed25519_sa_algo; + ssl->buffers.keyType = ed25519_sa_algo; ret = DecodePrivateKey(ssl, &keySz); if (ret != 0) { - ERROR_OUT(keySz, exit_sske); + goto exit_sske; } /* worst case estimate */ args->tmpSigSz = ED25519_SIG_SIZE; - - /* check the minimum ECC key size */ - if (ED25519_KEY_SIZE < - ssl->options.minEccKeySz) { - WOLFSSL_MSG("Ed25519 key size too small"); - ERROR_OUT(ECC_KEY_SIZE_E, exit_sske); - } break; } #endif /* HAVE_ED25519 */ @@ -22333,12 +22316,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } else { - ssl->hsType = DYNAMIC_TYPE_RSA; if (ssl->buffers.keyType == 0) ssl->buffers.keyType = rsa_sa_algo; ret = DecodePrivateKey(ssl, &keySz); if (ret != 0) { - ERROR_OUT(keySz, exit_sske); + goto exit_sske; } } @@ -22349,11 +22331,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, args->tmpSigSz = (word32)keySz; args->length += args->tmpSigSz; - if (keySz < ssl->options.minRsaKeySz) { - WOLFSSL_MSG("RSA key size too small"); - ERROR_OUT(RSA_KEY_SIZE_E, exit_sske); - } - if (IsAtLeastTLSv1_2(ssl)) { args->length += HASH_SIG_SIZE; } @@ -25018,19 +24995,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, { word16 keySz; - ssl->hsType = DYNAMIC_TYPE_RSA; - if (ssl->buffers.keyType == 0) - ssl->buffers.keyType = rsa_sa_algo; + ssl->buffers.keyType = rsa_sa_algo; ret = DecodePrivateKey(ssl, &keySz); if (ret != 0) { - ERROR_OUT(keySz, exit_dcke); + goto exit_dcke; } args->length = (word32)keySz; - - if (keySz < ssl->options.minRsaKeySz) { - WOLFSSL_MSG("Peer RSA key is too small"); - ERROR_OUT(RSA_KEY_SIZE_E, exit_dcke); - } ssl->arrays->preMasterSz = SECRET_LEN; if (ssl->options.tls) { @@ -25167,16 +25137,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->ecdhCurveOID != ECC_X25519_OID) { word16 keySz; - ssl->hsType = DYNAMIC_TYPE_ECC; - if (ssl->buffers.keyType == 0) - ssl->buffers.keyType = rsa_sa_algo; + ssl->buffers.keyType = ecc_dsa_sa_algo; ret = DecodePrivateKey(ssl, &keySz); if (ret != 0) { - ERROR_OUT(keySz, exit_dcke); - } - if (keySz < ssl->options.minEccKeySz) { - WOLFSSL_MSG("ECC key too small"); - ERROR_OUT(ECC_KEY_SIZE_E, exit_dcke); + goto exit_dcke; } private_key = (ecc_key*)ssl->hsKey; } diff --git a/src/ssl.c b/src/ssl.c index 64de96b14..9c655791d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11158,7 +11158,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifdef HAVE_PKCS11 int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id, - long sz, long keySz) + long sz, int devId, long keySz) { int ret = WOLFSSL_FAILURE; @@ -11167,6 +11167,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl) XMEMCPY(ctx->privateKey->buffer, id, sz); ctx->privateKeyId = 1; ctx->privateKeySz = keySz; + if (devId != INVALID_DEVID) + ctx->privateKeyDevId = devId; + else + ctx->privateKeyDevId = ctx->devId; ret = WOLFSSL_SUCCESS; } @@ -11311,7 +11315,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifdef HAVE_PKCS11 int wolfSSL_use_PrivateKey_id(WOLFSSL* ssl, const unsigned char* id, - long sz, long keySz) + long sz, int devId, long keySz) { int ret = WOLFSSL_FAILURE; @@ -11321,6 +11325,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ssl->buffers.weOwnKey = 1; ssl->buffers.keyId = 1; ssl->buffers.keySz = keySz; + if (devId != INVALID_DEVID) + ssl->buffers.keyId = devId; + else + ssl->buffers.keyId = ssl->devId; ret = WOLFSSL_SUCCESS; } diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 81ccd2f10..ed8a7ddde 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4351,6 +4351,10 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, key->state = ECC_STATE_SIGN_DO; if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){ + #if !defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_SMALL_STACK) + XFREE(s, key->heap, DYNAMIC_TYPE_ECC); + XFREE(r, key->heap, DYNAMIC_TYPE_ECC); + #endif break; } @@ -4361,6 +4365,10 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); #endif if (err < 0) { + #if !defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_SMALL_STACK) + XFREE(s, key->heap, DYNAMIC_TYPE_ECC); + XFREE(r, key->heap, DYNAMIC_TYPE_ECC); + #endif break; } diff --git a/wolfcrypt/src/wc_pkcs11.c b/wolfcrypt/src/wc_pkcs11.c index 26c807059..9bd43eda3 100644 --- a/wolfcrypt/src/wc_pkcs11.c +++ b/wolfcrypt/src/wc_pkcs11.c @@ -660,78 +660,6 @@ static int Pkcs11FindKeyById(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass, #endif #ifndef NO_RSA -/** - * Exponentiate the input with the public part of the RSA key. - * Used in public encrypt and decrypt. - * - * @param session [in] Session object. - * @param info [in] Cryptographic operation data. - * @return WC_HW_E when a PKCS#11 library call fails. - * 0 on success. - */ -static int Pkcs11RsaPublic(Pkcs11Session* session, wc_CryptoInfo* info) -{ - int ret = 0; - CK_RV rv; - CK_MECHANISM mech; - CK_ULONG outLen; - CK_OBJECT_HANDLE publicKey = NULL_PTR; - CK_ATTRIBUTE keyTemplate[] = { - { CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) }, - { CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) }, - { CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) }, - { CKA_MODULUS, NULL, 0 }, - { CKA_PUBLIC_EXPONENT, NULL, 0 } - }; - CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate); - - WOLFSSL_MSG("PKCS#11: RSA Public Key Operation"); - - if (ret == 0 && info->pk.rsa.outLen == NULL) { - ret = BAD_FUNC_ARG; - } - - if (ret == 0) { - /* Set the modulus and public exponent data. */ - keyTemplate[3].pValue = info->pk.rsa.key->n.raw.buf; - keyTemplate[3].ulValueLen = info->pk.rsa.key->n.raw.len; - keyTemplate[4].pValue = info->pk.rsa.key->e.raw.buf; - keyTemplate[4].ulValueLen = info->pk.rsa.key->e.raw.len; - - /* Create an object containing public key data for device to use. */ - rv = session->func->C_CreateObject(session->handle, keyTemplate, - keyTmplCnt, &publicKey); - if (rv != CKR_OK) - ret = WC_HW_E; - } - - if (ret == 0) { - /* Raw RSA encrypt/decrypt operation. */ - mech.mechanism = CKM_RSA_X_509; - mech.ulParameterLen = 0; - mech.pParameter = NULL; - - rv = session->func->C_EncryptInit(session->handle, &mech, publicKey); - if (rv != CKR_OK) - ret = WC_HW_E; - } - if (ret == 0) { - outLen = (CK_ULONG)*info->pk.rsa.outLen; - rv = session->func->C_Encrypt(session->handle, - (CK_BYTE_PTR)info->pk.rsa.in, info->pk.rsa.inLen, - info->pk.rsa.out, &outLen); - if (rv != CKR_OK) - ret = WC_HW_E; - } - if (ret == 0) - *info->pk.rsa.outLen = (word32)outLen; - - if (publicKey != NULL_PTR) - session->func->C_DestroyObject(session->handle, publicKey); - - return ret; -} - /** * Find the PKCS#11 object containing the RSA public or private key data with * the modulus specified. @@ -774,6 +702,86 @@ static int Pkcs11FindRsaKey(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass, return ret; } +/** + * Exponentiate the input with the public part of the RSA key. + * Used in public encrypt and decrypt. + * + * @param session [in] Session object. + * @param info [in] Cryptographic operation data. + * @return WC_HW_E when a PKCS#11 library call fails. + * 0 on success. + */ +static int Pkcs11RsaPublic(Pkcs11Session* session, wc_CryptoInfo* info) +{ + int ret = 0; + CK_RV rv; + CK_MECHANISM mech; + CK_ULONG outLen; + CK_OBJECT_HANDLE publicKey = NULL_PTR; + int sessionKey = 0; + CK_ATTRIBUTE keyTemplate[] = { + { CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) }, + { CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) }, + { CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) }, + { CKA_MODULUS, NULL, 0 }, + { CKA_PUBLIC_EXPONENT, NULL, 0 } + }; + CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate); + + WOLFSSL_MSG("PKCS#11: RSA Public Key Operation"); + + if (ret == 0 && info->pk.rsa.outLen == NULL) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + if ((sessionKey = !mp_iszero(&info->pk.rsa.key->e))) { + /* Set the modulus and public exponent data. */ + keyTemplate[3].pValue = info->pk.rsa.key->n.raw.buf; + keyTemplate[3].ulValueLen = info->pk.rsa.key->n.raw.len; + keyTemplate[4].pValue = info->pk.rsa.key->e.raw.buf; + keyTemplate[4].ulValueLen = info->pk.rsa.key->e.raw.len; + + /* Create an object containing public key data for device to use. */ + rv = session->func->C_CreateObject(session->handle, keyTemplate, + keyTmplCnt, &publicKey); + if (rv != CKR_OK) + ret = WC_HW_E; + } + else { + ret = Pkcs11FindKeyById(&publicKey, CKO_PUBLIC_KEY, CKK_RSA, + session, info->pk.rsa.key->id, + info->pk.rsa.key->idLen); + } + } + + if (ret == 0) { + /* Raw RSA encrypt/decrypt operation. */ + mech.mechanism = CKM_RSA_X_509; + mech.ulParameterLen = 0; + mech.pParameter = NULL; + + rv = session->func->C_EncryptInit(session->handle, &mech, publicKey); + if (rv != CKR_OK) + ret = WC_HW_E; + } + if (ret == 0) { + outLen = (CK_ULONG)*info->pk.rsa.outLen; + rv = session->func->C_Encrypt(session->handle, + (CK_BYTE_PTR)info->pk.rsa.in, info->pk.rsa.inLen, + info->pk.rsa.out, &outLen); + if (rv != CKR_OK) + ret = WC_HW_E; + } + if (ret == 0) + *info->pk.rsa.outLen = (word32)outLen; + + if (sessionKey) + session->func->C_DestroyObject(session->handle, publicKey); + + return ret; +} + /** * Exponentiate the input with the private part of the RSA key. * Used in private encrypt and decrypt. diff --git a/wolfssl/internal.h b/wolfssl/internal.h index de6dc19a2..5ecfe638b 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2500,6 +2500,7 @@ struct WOLFSSL_CTX { byte privateKeyType:7; byte privateKeyId:1; int privateKeySz; + int privateKeyDevId; WOLFSSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */ #endif #ifdef KEEP_OUR_CERT @@ -3082,6 +3083,7 @@ typedef struct Buffers { byte keyType:7; /* Type of key: RSA, ECC, Ed25519 */ byte keyId:1; /* Key data is an id not data */ int keySz; /* Size of RSA key */ + int keyDevId; /* Device Id for key */ DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */ /* chain after self, in DER, with leading size for each cert */ #ifdef WOLFSSL_TLS13 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index aa83d3e65..44bc2367b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1734,7 +1734,7 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len, WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX*, const unsigned char*, long, int); WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX*, - const unsigned char*, long, long); + const unsigned char*, long, int, long); WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX*, const unsigned char*, long, int); WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX*, @@ -1748,7 +1748,7 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len, WOLFSSL_API int wolfSSL_use_PrivateKey_buffer(WOLFSSL*, const unsigned char*, long, int); WOLFSSL_API int wolfSSL_use_PrivateKey_id(WOLFSSL*, const unsigned char*, - long, long); + long, int, long); WOLFSSL_API int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL*, const unsigned char*, long, int); WOLFSSL_API int wolfSSL_use_certificate_chain_buffer(WOLFSSL*,