diff --git a/wolfcrypt/src/wc_pkcs11.c b/wolfcrypt/src/wc_pkcs11.c index 91a1dedd8..d07f5b6c1 100644 --- a/wolfcrypt/src/wc_pkcs11.c +++ b/wolfcrypt/src/wc_pkcs11.c @@ -45,8 +45,27 @@ #define MAX_EC_PARAM_LEN 16 +#if defined(NO_PKCS11_RSA) && !defined(NO_RSA) + #define NO_RSA +#endif +#if defined(NO_PKCS11_ECC) && defined(HAVE_ECC) + #undef HAVE_ECC +#endif +#if defined(NO_PKCS11_AES) && !defined(NO_AES) + #define NO_AES +#endif +#if defined(NO_PKCS11_AESGCM) && defined(HAVE_AESGCM) + #undef HAVE_AESGCM +#endif +#if defined(NO_PKCS11_AESCBC) && defined(HAVE_AES_CBC) + #undef HAVE_AES_CBC +#endif +#if defined(NO_PKCS11_RNG) && !defined(WC_NO_RNG) + #define WC_NO_RNG +#endif -#ifdef HAVE_ECC + +#if defined(HAVE_ECC) && !defined(NO_PKCS11_ECDH) static CK_BBOOL ckFalse = CK_FALSE; #endif #if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \ @@ -329,7 +348,7 @@ void wc_Pkcs11Token_Close(Pkcs11Token* token) } -#if !defined(NO_AES) && defined(HAVE_AESGCM) +#if !defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC)) static int Pkcs11CreateSecretKey(CK_OBJECT_HANDLE* key, Pkcs11Session* session, CK_KEY_TYPE keyType, unsigned char* data, int len, unsigned char* id, int idLen) @@ -553,6 +572,25 @@ int wc_Pkcs11StoreKey(Pkcs11Token* token, int type, int clear, void* key) break; } #endif + #if !defined(NO_AES) && defined(HAVE_AES_CBC) + case PKCS11_KEY_TYPE_AES_CBC: { + Aes* aes = (Aes*)key; + + ret = Pkcs11MechAvail(&session, CKM_AES_CBC); + if (ret == 0) { + ret = Pkcs11CreateSecretKey(&privKey, &session, CKK_AES, + (unsigned char *)aes->devKey, + aes->keylen, + (unsigned char *)aes->id, + aes->idLen); + } + if (ret == 0 && clear) { + XMEMSET(aes->devKey, 0, aes->keylen); + XMEMSET(aes->key, 0, aes->keylen); + } + break; + } + #endif #ifndef NO_RSA case PKCS11_KEY_TYPE_RSA: { RsaKey* rsaKey = (RsaKey*)key; @@ -576,12 +614,14 @@ int wc_Pkcs11StoreKey(Pkcs11Token* token, int type, int clear, void* key) ecc_key* eccKey = (ecc_key*)key; int ret2 = NOT_COMPILED_IN; + #ifndef NO_PKCS11_ECDH /* Try ECDH mechanism first. */ ret = Pkcs11MechAvail(&session, CKM_ECDH1_DERIVE); if (ret == 0) { ret = Pkcs11CreateEccPrivateKey(&privKey, &session, eccKey, CKA_DERIVE); } + #endif if (ret == 0 || ret == NOT_COMPILED_IN) { /* Try ECDSA mechanism next. */ ret2 = Pkcs11MechAvail(&session, CKM_ECDSA); @@ -1178,6 +1218,7 @@ static int Pkcs11CreateEccPublicKey(CK_OBJECT_HANDLE* publicKey, return ret; } +#ifndef NO_PKCS11_EC_KEYGEN /** * Gets the public key data from the PKCS#11 object and puts into the ECC key. * @@ -1315,8 +1356,9 @@ static int Pkcs11EcKeyGen(Pkcs11Session* session, wc_CryptoInfo* info) return ret; } +#endif - +#ifndef NO_PKCS11_ECDH /** * Extracts the secret key data from the PKCS#11 object. * @@ -1455,7 +1497,7 @@ static int Pkcs11ECDH(Pkcs11Session* session, wc_CryptoInfo* info) return ret; } - +#endif /** * Encode, in place, the ECDSA signature. @@ -1941,6 +1983,141 @@ static int Pkcs11AesGcmDecrypt(Pkcs11Session* session, wc_CryptoInfo* info) } #endif +#if !defined(NO_AES) && defined(HAVE_AES_CBC) +/** + * Performs the AES-CBC encryption operation. + * + * @param session [in] Session object. + * @param info [in] Cryptographic operation data. + * @return WC_HW_E when a PKCS#11 library call fails. + * MEMORY_E when a memory allocation fails. + * 0 on success. + */ +static int Pkcs11AesCbcEncrypt(Pkcs11Session* session, wc_CryptoInfo* info) +{ + int ret = 0; + CK_RV rv; + Aes* aes = info->cipher.aescbc.aes; + CK_MECHANISM_INFO mechInfo; + CK_OBJECT_HANDLE key = NULL_PTR; + CK_MECHANISM mech; + CK_ULONG outLen; + + /* Check operation is supported. */ + rv = session->func->C_GetMechanismInfo(session->slotId, CKM_AES_CBC, + &mechInfo); + if (rv != CKR_OK || (mechInfo.flags & CKF_ENCRYPT) == 0) + ret = NOT_COMPILED_IN; + + if (ret == 0) { + WOLFSSL_MSG("PKCS#11: AES-CBC Encryption Operation"); + } + + /* Create a private key object or find by id. */ + if (ret == 0 && aes->idLen == 0) { + ret = Pkcs11CreateSecretKey(&key, session, CKK_AES, + (unsigned char *)aes->devKey, aes->keylen, + NULL, 0); + + } + else if (ret == 0) { + ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session, aes->id, + aes->idLen); + } + + if (ret == 0) { + mech.mechanism = CKM_AES_CBC; + mech.ulParameterLen = AES_BLOCK_SIZE; + mech.pParameter = (CK_BYTE_PTR)info->cipher.aescbc.aes->reg; + + rv = session->func->C_EncryptInit(session->handle, &mech, key); + if (rv != CKR_OK) + ret = WC_HW_E; + } + if (ret == 0) { + outLen = info->cipher.aescbc.sz; + rv = session->func->C_Encrypt(session->handle, + (CK_BYTE_PTR)info->cipher.aescbc.in, + info->cipher.aescbc.sz, + info->cipher.aescbc.out, + &outLen); + if (rv != CKR_OK) + ret = WC_HW_E; + } + + if (aes->idLen == 0 && key != NULL_PTR) + session->func->C_DestroyObject(session->handle, key); + + return ret; +} + +/** + * Performs the AES-CBC decryption operation. + * + * @param session [in] Session object. + * @param info [in] Cryptographic operation data. + * @return WC_HW_E when a PKCS#11 library call fails. + * MEMORY_E when a memory allocation fails. + * 0 on success. + */ +static int Pkcs11AesCbcDecrypt(Pkcs11Session* session, wc_CryptoInfo* info) +{ + int ret = 0; + CK_RV rv; + Aes* aes = info->cipher.aescbc.aes; + CK_MECHANISM_INFO mechInfo; + CK_OBJECT_HANDLE key = NULL_PTR; + CK_MECHANISM mech; + CK_ULONG outLen; + + /* Check operation is supported. */ + rv = session->func->C_GetMechanismInfo(session->slotId, CKM_AES_CBC, + &mechInfo); + if (rv != CKR_OK || (mechInfo.flags & CKF_DECRYPT) == 0) + ret = NOT_COMPILED_IN; + + if (ret == 0) { + WOLFSSL_MSG("PKCS#11: AES-CBC Decryption Operation"); + } + + /* Create a private key object or find by id. */ + if (ret == 0 && aes->idLen == 0) { + ret = Pkcs11CreateSecretKey(&key, session, CKK_AES, + (unsigned char *)aes->devKey, aes->keylen, + NULL, 0); + } + else if (ret == 0) { + ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session, aes->id, + aes->idLen); + } + + if (ret == 0) { + mech.mechanism = CKM_AES_CBC; + mech.ulParameterLen = AES_BLOCK_SIZE; + mech.pParameter = (CK_BYTE_PTR)info->cipher.aescbc.aes->reg; + + rv = session->func->C_DecryptInit(session->handle, &mech, key); + if (rv != CKR_OK) + ret = WC_HW_E; + } + if (ret == 0) { + outLen = info->cipher.aescbc.sz; + rv = session->func->C_DecryptUpdate(session->handle, + (CK_BYTE_PTR)info->cipher.aescbc.in, + info->cipher.aescbc.sz, + info->cipher.aescbc.out, + &outLen); + if (rv != CKR_OK) + ret = WC_HW_E; + } + + if (aes->idLen == 0 && key != NULL_PTR) + session->func->C_DestroyObject(session->handle, key); + + return ret; +} +#endif + #ifndef WC_NO_RNG #ifndef HAVE_HASHDRBG /** @@ -2020,12 +2197,16 @@ int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) #endif #endif #ifdef HAVE_ECC + #ifndef NO_PKCS11_EC_KEYGEN case WC_PK_TYPE_EC_KEYGEN: ret = Pkcs11EcKeyGen(&session, info); break; + #endif + #ifndef NO_PKCS11_ECDH case WC_PK_TYPE_ECDH: ret = Pkcs11ECDH(&session, info); break; + #endif case WC_PK_TYPE_ECDSA_SIGN: ret = Pkcs11ECDSA_Sign(&session, info); break; @@ -2040,13 +2221,23 @@ int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) } else if (info->algo_type == WC_ALGO_TYPE_CIPHER) { switch (info->cipher.type) { - #if !defined(NO_AES) && defined(HAVE_AESGCM) + #ifndef NO_AES + #ifdef HAVE_AESGCM case WC_CIPHER_AES_GCM: if (info->cipher.enc) ret = Pkcs11AesGcmEncrypt(&session, info); else ret = Pkcs11AesGcmDecrypt(&session, info); break; + #endif + #ifdef HAVE_AES_CBC + case WC_CIPHER_AES_CBC: + if (info->cipher.enc) + ret = Pkcs11AesCbcEncrypt(&session, info); + else + ret = Pkcs11AesCbcDecrypt(&session, info); + break; + #endif #endif } } diff --git a/wolfssl/wolfcrypt/pkcs11.h b/wolfssl/wolfcrypt/pkcs11.h index 8d139449b..bef0b7b21 100644 --- a/wolfssl/wolfcrypt/pkcs11.h +++ b/wolfssl/wolfcrypt/pkcs11.h @@ -141,6 +141,7 @@ extern "C" { #define CKM_ECDH1_DERIVE 0x00001050UL #define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL #define CKM_AES_KEY_GEN 0x00001080UL +#define CKM_AES_CBC 0x00001082UL #define CKM_AES_GCM 0x00001087UL #define CKR_OK 0x00000000UL diff --git a/wolfssl/wolfcrypt/wc_pkcs11.h b/wolfssl/wolfcrypt/wc_pkcs11.h index 39357dc3b..7f6695438 100644 --- a/wolfssl/wolfcrypt/wc_pkcs11.h +++ b/wolfssl/wolfcrypt/wc_pkcs11.h @@ -60,6 +60,7 @@ typedef struct Pkcs11Session { /* Types of keys that can be stored. */ enum Pkcs11KeyType { PKCS11_KEY_TYPE_AES_GCM, + PKCS11_KEY_TYPE_AES_CBC, PKCS11_KEY_TYPE_RSA, PKCS11_KEY_TYPE_EC, };