Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ cd wolfPKCS11
make
make check
```
### Optional: AES-CCM Support

To have AES-CCM support in wolfPKCS11, simiply configure wolfSSL with the
addition of `--enable-aesccm`

### TPM support with wolfTPM

Expand Down
89 changes: 89 additions & 0 deletions src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,30 @@ CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession,
break;
}
#endif

#ifdef HAVE_AESCCM
case CKM_AES_CCM: {
CK_CCM_PARAMS* params;

if (type != CKK_AES)
return CKR_KEY_TYPE_INCONSISTENT;
if (pMechanism->pParameter == NULL)
return CKR_MECHANISM_PARAM_INVALID;
if (pMechanism->ulParameterLen != sizeof(CK_CCM_PARAMS))
return CKR_MECHANISM_PARAM_INVALID;

params = (CK_CCM_PARAMS*)pMechanism->pParameter;
ret = WP11_Session_SetCcmParams(session,
(int)params->ulDataLen,
params->pIv, (int)params->ulIvLen,
params->pAAD, (int)params->ulAADLen,
(int)params->ulMacLen);
if (ret != 0)
return CKR_MECHANISM_PARAM_INVALID;
init = WP11_INIT_AES_CCM_ENC;
break;
}
#endif
#endif
default:
(void)type;
Expand Down Expand Up @@ -1471,6 +1495,27 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
*pulEncryptedDataLen = encDataLen;
break;
#endif
#ifdef HAVE_AESCCM
case CKM_AES_CCM:
if (!WP11_Session_IsOpInitialized(session, WP11_INIT_AES_CCM_ENC))
return CKR_OPERATION_NOT_INITIALIZED;

encDataLen = (word32)ulDataLen +
WP11_AesCcm_GetMacLen(session);
if (pEncryptedData == NULL) {
*pulEncryptedDataLen = encDataLen;
return CKR_OK;
}
if (encDataLen > (word32)*pulEncryptedDataLen)
return CKR_BUFFER_TOO_SMALL;

ret = WP11_AesCcm_Encrypt(pData, (int)ulDataLen, pEncryptedData,
&encDataLen, obj, session);
if (ret < 0)
return CKR_FUNCTION_FAILED;
*pulEncryptedDataLen = encDataLen;
break;
#endif
#endif
default:
(void)ret;
Expand Down Expand Up @@ -1858,6 +1903,29 @@ CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession,
break;
}
#endif
#ifdef HAVE_AESCCM
case CKM_AES_CCM: {
CK_CCM_PARAMS* params;

if (type != CKK_AES)
return CKR_KEY_TYPE_INCONSISTENT;
if (pMechanism->pParameter == NULL)
return CKR_MECHANISM_PARAM_INVALID;
if (pMechanism->ulParameterLen != sizeof(CK_CCM_PARAMS))
return CKR_MECHANISM_PARAM_INVALID;

params = (CK_CCM_PARAMS*)pMechanism->pParameter;
ret = WP11_Session_SetCcmParams(session,
(int)params->ulDataLen,
params->pIv, (int)params->ulIvLen,
params->pAAD, (int)params->ulAADLen,
(int)params->ulMacLen);
if (ret != 0)
return CKR_MECHANISM_PARAM_INVALID;
init = WP11_INIT_AES_CCM_DEC;
break;
}
#endif
#endif
default:
(void)type;
Expand Down Expand Up @@ -2042,6 +2110,27 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
*pulDataLen = decDataLen;
break;
#endif
#ifdef HAVE_AESCCM
case CKM_AES_CCM:
if (!WP11_Session_IsOpInitialized(session, WP11_INIT_AES_CCM_DEC))
return CKR_OPERATION_NOT_INITIALIZED;

decDataLen = (word32)ulEncryptedDataLen -
WP11_AesCcm_GetMacLen(session);
if (pData == NULL) {
*pulDataLen = decDataLen;
return CKR_OK;
}
if (decDataLen > (word32)*pulDataLen)
return CKR_BUFFER_TOO_SMALL;

ret = WP11_AesCcm_Decrypt(pEncryptedData, (int)ulEncryptedDataLen,
pData, &decDataLen, obj, session);
if (ret < 0)
return CKR_FUNCTION_FAILED;
*pulDataLen = decDataLen;
break;
#endif
#endif
default:
(void)decDataLen;
Expand Down
214 changes: 213 additions & 1 deletion src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,18 @@ typedef struct WP11_GcmParams {
int encSz; /* Size of encrypted data in bytes */
} WP11_GcmParams;
#endif

#ifdef HAVE_AESCCM
typedef struct WP11_CcmParams {
int dataSz; /* Data size in bytes */
unsigned char iv[WP11_MAX_GCM_NONCE_SZ];
/* IV/nonce data */
int ivSz; /* IV/nonce size in bytes */
unsigned char* aad; /* Additional Authentication Data */
int aadSz; /* AAD size in bytes */
int macSz; /* Size of MAC data in bytes */
} WP11_CcmParams;
#endif
#endif

#ifndef NO_HMAC
Expand Down Expand Up @@ -292,6 +304,9 @@ struct WP11_Session {
#ifdef HAVE_AESGCM
WP11_GcmParams gcm; /* AES-GCM parameters */
#endif
#ifdef HAVE_AESCCM
WP11_CcmParams ccm; /* AES-CCM parameters */
#endif
#endif
#ifndef NO_HMAC
WP11_Hmac hmac; /* HMAC parameters */
Expand Down Expand Up @@ -620,6 +635,14 @@ static void wp11_Session_Final(WP11_Session* session)
}
}
#endif
#ifdef HAVE_AESCCM
if (session->mechanism == CKM_AES_CCM) {
if (session->params.ccm.aad != NULL) {
XFREE(session->params.ccm.aad, NULL, DYNAMIC_TYPE_TMP_BUFFER);
session->params.ccm.aad = NULL;
}
}
#endif
#endif
}

Expand Down Expand Up @@ -4584,7 +4607,7 @@ int WP11_Session_SetCbcParams(WP11_Session* session, unsigned char* iv,

#ifdef HAVE_AESGCM
/**
* Set the parameters to use for an AES-CBC operation.
* Set the parameters to use for an AES-GCM operation.
*
* @param session [in] Session object.
* @param iv [in] Initialization vector.
Expand Down Expand Up @@ -4626,6 +4649,55 @@ int WP11_Session_SetGcmParams(WP11_Session* session, unsigned char* iv,
return ret;
}
#endif /* HAVE_AESGCM */

#ifdef HAVE_AESCCM
/**
* Set the parameters to use for an AES-CCM operation.
*
* @param dataSz [in] Length of data in bytes.
* @param session [in] Session object.
* @param iv [in] Nonce.
* @param ivSz [in] Length of nonce in bytes.
* @param aad [in] Additional authentication data.
* @param aadSz [in] Length of additional authentication data.
* @param macSz [in] Length of the MAC in bytes.
* @return BAD_FUNC_ARG if the IV/nonce is too big.
* Other -ve value on failure.
* 0 on success.
*/
int WP11_Session_SetCcmParams(WP11_Session* session, int dataSz,
unsigned char* iv, int ivSz,
unsigned char* aad, int aadSz,
int macSz)
{
int ret = 0;
WP11_CcmParams* ccm = &session->params.ccm;

if (ivSz > WP11_MAX_GCM_NONCE_SZ)
ret = BAD_FUNC_ARG;

if (ret == 0) {
ccm->dataSz = dataSz;
XMEMSET(ccm, 0, sizeof(*ccm));
XMEMCPY(ccm->iv, iv, ivSz);
ccm->ivSz = ivSz;
if (aad != NULL) {
ccm->aad = (unsigned char*)XMALLOC(aadSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (ccm->aad == NULL) {
ret = MEMORY_E;
}
if (ret == 0) {
XMEMCPY(ccm->aad, aad, aadSz);
ccm->aadSz = aadSz;
}
}
ccm->macSz = macSz;
}

return ret;
}
#endif /* HAVE_AESGCM */
#endif /* !NO_AES */

/**
Expand Down Expand Up @@ -8302,6 +8374,146 @@ int WP11_AesGcm_DecryptFinal(unsigned char* dec, word32* decSz,
return ret;
}
#endif /* HAVE_AESGCM */

#ifdef HAVE_AESCCM
/**
* Return the number of data bytes from CCM parameters.
*
* @param session [in] Session object.
* @return Data byte length.
*/
int WP11_AesCcm_DataLen(WP11_Session* session)
{
WP11_CcmParams* ccm = &session->params.ccm;

return ccm->dataSz;
}

/**
* Return the MAC size from the CCM parameters.
*
* @param session [in] Session object.
* @return MAC byte length.
*/
int WP11_AesCcm_GetMacLen(WP11_Session* session)
{
WP11_CcmParams* ccm = &session->params.ccm;

return ccm->macSz;
}

/**
* Encrypt plain text with AES-CCM placing authentication tag on end.
* Output buffer must be large enough to hold all data.
*
* @param plain [in] Plain text.
* @param plainSz [in] Length of plain text in bytes.
* @param enc [in] Buffer to hold encrypted data.
* @param encSz [in,out] On in, length of buffer in bytes.
* On out, length of encrypted data including
* authentication tag in bytes.
* @param secret [in] Secret key object.
* @param session [in] Session object holding CCM parameters.
* @return -ve on encryption failure.
* 0 on success.
*/
int WP11_AesCcm_Encrypt(unsigned char* plain, word32 plainSz,
unsigned char* enc, word32* encSz, WP11_Object* secret,
WP11_Session* session)
{
int ret;
Aes aes;
WP11_Data* key;
WP11_CcmParams* ccm = &session->params.ccm;
word32 authTagSz = ccm->macSz;
unsigned char* authTag = enc + plainSz;

ret = wc_AesInit(&aes, NULL, session->devId);
if (ret == 0) {
if (secret->onToken)
WP11_Lock_LockRO(secret->lock);
key = &secret->data.symmKey;
ret = wc_AesCcmSetKey(&aes, key->data, key->len);
if (secret->onToken)
WP11_Lock_UnlockRO(secret->lock);

if (ret == 0)
ret = wc_AesCcmEncrypt(&aes, enc, plain, plainSz,
ccm->iv, ccm->ivSz,
authTag, authTagSz,
ccm->aad, ccm->aadSz);
if (ret == 0)
*encSz = plainSz + authTagSz;

if (ccm->aad != NULL) {
XFREE(ccm->aad, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ccm->aad = NULL;
ccm->aadSz = 0;
}

wc_AesFree(&aes);
}

return ret;
}

/**
* Decrypt data, including authentication tag, with AES-CCM
* Output buffer must be large enough to hold all decrypted data.
*
* @param enc [in] Encrypted data.
* @param encSz [in] Length of encrypted data in bytes.
* @param dec [in] Buffer to hold decrypted data.
* @param decSz [in,out] On in, length of buffer in bytes.
* On out, length of decrypted data in bytes.
* @param session [in] Session object holding Aes object.
* @return AES_CCM_AUTH_E when data does not authenticate.
* Other -ve on encryption failure.
* 0 on success.
*/
int WP11_AesCcm_Decrypt(unsigned char* enc, word32 encSz, unsigned char* dec,
word32* decSz, WP11_Object* secret,
WP11_Session* session)
{
int ret;
Aes aes;
WP11_Data* key;
WP11_CcmParams* ccm = &session->params.ccm;
word32 authTagSz = ccm->macSz;
unsigned char* authTag = enc + encSz - authTagSz;
encSz -= authTagSz;

ret = wc_AesInit(&aes, NULL, session->devId);
if (ret == 0) {
if (secret->onToken)
WP11_Lock_LockRO(secret->lock);
key = &secret->data.symmKey;
ret = wc_AesCcmSetKey(&aes, key->data, key->len);
if (secret->onToken)
WP11_Lock_UnlockRO(secret->lock);

if (ret == 0)
ret = wc_AesCcmDecrypt(&aes, dec, enc, encSz,
ccm->iv, ccm->ivSz,
authTag, authTagSz,
ccm->aad, ccm->aadSz);

if (ret == 0) {
*decSz = encSz;
}

if (ccm->aad != NULL) {
XFREE(ccm->aad, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ccm->aad = NULL;
ccm->aadSz = 0;
}

wc_AesFree(&aes);
}

return ret;
}
#endif /* HAVE_AESCCM */
#endif /* !NO_AES */

#ifndef NO_HMAC
Expand Down
Loading
Loading