CK_RV PKCS11_Encryption_OpenSSL::DecryptUpdate(Cryptoki_Session_Context* pSessionCtx, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { OPENSSL_HEADER(); OpenSSLEncryptData *pDec; if(pSessionCtx == NULL || pSessionCtx->DecryptionCtx == NULL) return CKR_SESSION_CLOSED; pDec = (OpenSSLEncryptData*)pSessionCtx->DecryptionCtx; if(pDec->IsSymmetric) { int outLen = *pulPartLen; OPENSSL_CHECKRESULT(EVP_DecryptUpdate((EVP_CIPHER_CTX*)pDec->Key->ctx, pPart, &outLen, pEncryptedPart, ulEncryptedPartLen)); *pulPartLen = outLen; } else { size_t outLen = *pulPartLen; OPENSSL_CHECKRESULT(EVP_PKEY_decrypt((EVP_PKEY_CTX*)pDec->Key->ctx, pPart, &outLen, pEncryptedPart, ulEncryptedPartLen)); *pulPartLen = outLen; } OPENSSL_CLEANUP(); if(retVal != CKR_OK) { TINYCLR_SSL_FREE(pDec); pSessionCtx->DecryptionCtx = NULL; } OPENSSL_RETURN(); }
CK_RV PKCS11_Encryption_OpenSSL::InitHelper(Cryptoki_Session_Context* pSessionCtx, CK_MECHANISM_PTR pEncryptMech, CK_OBJECT_HANDLE hKey, BOOL isEncrypt) { OPENSSL_HEADER(); OpenSSLEncryptData* pEnc; const EVP_CIPHER* pCipher; int padding = 0; if( pSessionCtx == NULL) return CKR_SESSION_CLOSED; if( isEncrypt && pSessionCtx->EncryptionCtx != NULL) return CKR_SESSION_PARALLEL_NOT_SUPPORTED; if(!isEncrypt && pSessionCtx->DecryptionCtx != NULL) return CKR_SESSION_PARALLEL_NOT_SUPPORTED; pEnc = (OpenSSLEncryptData*)TINYCLR_SSL_MALLOC(sizeof(*pEnc)); if(pEnc == NULL) return CKR_DEVICE_MEMORY; TINYCLR_SSL_MEMSET(pEnc, 0, sizeof(*pEnc)); pEnc->Key = PKCS11_Keys_OpenSSL::GetKeyFromHandle(pSessionCtx, hKey, !isEncrypt); pEnc->IsSymmetric = TRUE; switch(pEncryptMech->mechanism) { case CKM_AES_CBC: case CKM_AES_CBC_PAD: switch(pEnc->Key->size) { case 128: pCipher = EVP_aes_128_cbc(); break; case 192: pCipher = EVP_aes_192_cbc(); break; case 256: pCipher = EVP_aes_256_cbc(); break; default: OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID); } if(pEncryptMech->mechanism == CKM_AES_CBC_PAD) { padding = 1; } break; case CKM_AES_ECB: case CKM_AES_ECB_PAD: switch(pEnc->Key->size) { case 128: pCipher = EVP_aes_128_ecb(); break; case 192: pCipher = EVP_aes_192_ecb(); break; case 256: pCipher = EVP_aes_256_ecb(); break; default: OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID); } if(pEncryptMech->mechanism == CKM_AES_ECB_PAD) { padding = 1; } break; case CKM_DES3_CBC: pCipher = EVP_des_ede3_cbc(); break; case CKM_DES3_CBC_PAD: pCipher = EVP_des_ede3_cbc(); padding = 1; break; case CKM_RSA_PKCS: pEnc->IsSymmetric= FALSE; padding = RSA_PKCS1_PADDING; break; default: OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID); } if(pEnc->IsSymmetric) { if(pEncryptMech->ulParameterLen > 0 && pEncryptMech->ulParameterLen > 0) { memcpy(pEnc->IV, pEncryptMech->pParameter, pEncryptMech->ulParameterLen); } pEnc->Key->ctx = &pEnc->SymmetricCtx; if(isEncrypt) { OPENSSL_CHECKRESULT(EVP_EncryptInit(&pEnc->SymmetricCtx, pCipher, (const UINT8*)pEnc->Key->key, pEnc->IV)); } else { OPENSSL_CHECKRESULT(EVP_DecryptInit(&pEnc->SymmetricCtx, pCipher, (const UINT8*)pEnc->Key->key, pEnc->IV)); } OPENSSL_CHECKRESULT(EVP_CIPHER_CTX_set_padding(&pEnc->SymmetricCtx, padding)); } else { pEnc->Key->ctx = EVP_PKEY_CTX_new((EVP_PKEY*)pEnc->Key->key, NULL); if(isEncrypt) { OPENSSL_CHECKRESULT(EVP_PKEY_encrypt_init ((EVP_PKEY_CTX*)pEnc->Key->ctx )); OPENSSL_CHECKRESULT(EVP_PKEY_CTX_set_rsa_padding((EVP_PKEY_CTX*)pEnc->Key->ctx, padding)); } else { OPENSSL_CHECKRESULT(EVP_PKEY_decrypt_init ((EVP_PKEY_CTX*)pEnc->Key->ctx )); OPENSSL_CHECKRESULT(EVP_PKEY_CTX_set_rsa_padding((EVP_PKEY_CTX*)pEnc->Key->ctx, padding)); } } if(isEncrypt) pSessionCtx->EncryptionCtx = pEnc; else pSessionCtx->DecryptionCtx = pEnc; OPENSSL_CLEANUP(); if(retVal != CKR_OK && pEnc != NULL) { TINYCLR_SSL_FREE(pEnc); } OPENSSL_RETURN(); }
CK_RV PKCS11_Objects_OpenSSL::SetAttributeValue(Cryptoki_Session_Context* pSessionCtx, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { OBJECT_DATA* pObj = PKCS11_Objects_OpenSSL::GetObjectFromHandle(pSessionCtx, hObject); if(pObj == NULL) return CKR_OBJECT_HANDLE_INVALID; if(pObj->Type == CertificateType) { CERT_DATA* pCertData = (CERT_DATA*)pObj->Data; X509* pCert = pCertData->cert; CHAR group[20] = {0}; CHAR fileName[20] = {0}; INT32 len = 0; BOOL fSave = FALSE; BOOL fDelete = FALSE; for(int i=0; i<(int)ulCount; i++) { switch(pTemplate[i].type) { case CKA_PERSIST: fSave = SwapEndianIfBEc32(*(INT32*)pTemplate[i].pValue) != 0; fDelete = !fSave; break; case CKA_LABEL: len = pTemplate[i].ulValueLen; if(len >= ARRAYSIZE(group)) { len = ARRAYSIZE(group) - 1; } TINYCLR_SSL_MEMCPY(group, pTemplate[i].pValue, len); group[len] = 0; break; case CKA_OBJECT_ID: len = pTemplate[i].ulValueLen; if(len >= ARRAYSIZE(fileName)) { len = ARRAYSIZE(fileName) - 1; } TINYCLR_SSL_MEMCPY(fileName, pTemplate[i].pValue, len); fileName[len] = 0; break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } } if(fDelete) { hal_strcpy_s(fileName, ARRAYSIZE(pObj->FileName), pObj->FileName); pObj->GroupName[0] = 0; if(g_OpenSSL_Token.Storage != NULL && g_OpenSSL_Token.Storage->Delete != NULL) { if(!g_OpenSSL_Token.Storage->Delete(fileName, group)) return CKR_FUNCTION_FAILED; } else { return CKR_FUNCTION_NOT_SUPPORTED; } } else if(fSave) { hal_strcpy_s(pObj->GroupName, ARRAYSIZE(pObj->GroupName), group ); hal_strcpy_s(pObj->FileName , ARRAYSIZE(pObj->FileName ), fileName); if(g_OpenSSL_Token.Storage != NULL && g_OpenSSL_Token.Storage->Create != NULL) { BOOL res; UINT8* pData, *pTmp; INT32 len = i2d_X509( pCert, NULL ); if(len <= 0) return CKR_FUNCTION_FAILED; pData = (UINT8*)TINYCLR_SSL_MALLOC(len); if(pData == NULL) return CKR_DEVICE_MEMORY; pTmp = pData; i2d_X509(pCert, &pTmp); // TODO: Save private key as well res = g_OpenSSL_Token.Storage->Create( fileName, group, CertificateType, pData, len ); TINYCLR_SSL_FREE(pData); if(!res) return CKR_FUNCTION_FAILED; } else { return CKR_FUNCTION_NOT_SUPPORTED; } } else { return CKR_ATTRIBUTE_TYPE_INVALID; } } return CKR_OK; }
CK_RV PKCS11_Objects_OpenSSL::FindObjects(Cryptoki_Session_Context* pSessionCtx, CK_OBJECT_HANDLE_PTR phObjects, CK_ULONG ulMaxCount, CK_ULONG_PTR pulObjectCount) { FIND_OBJECT_DATA *pData = (FIND_OBJECT_DATA*)pSessionCtx->FindObjectsCtx; UINT32 cntObj = 0; *pulObjectCount = 0; if(pData == NULL) return CKR_FUNCTION_FAILED; if(ulMaxCount == 0) return CKR_ARGUMENTS_BAD; { FileEnumCtx ctx; CHAR fileName[20]; if(g_OpenSSL_Token.Storage == NULL || g_OpenSSL_Token.Storage->GetFileEnum == NULL) { return CKR_FUNCTION_NOT_SUPPORTED; } if(!g_OpenSSL_Token.Storage->GetFileEnum(pData->GroupName, pData->ObjectType, ctx)) return CKR_FUNCTION_FAILED; while(g_OpenSSL_Token.Storage->GetNextFile(ctx, fileName, ARRAYSIZE(fileName))) { UINT32 dataLen = 0; if(g_OpenSSL_Token.Storage->Read(fileName, pData->GroupName, pData->ObjectType, NULL, dataLen)) { UINT8* pObj = (UINT8*)TINYCLR_SSL_MALLOC(dataLen); if(pObj) { g_OpenSSL_Token.Storage->Read(fileName, pData->GroupName, pData->ObjectType, pObj, dataLen); switch(pData->ObjectType) { case CertificateType: { OBJECT_DATA *pObject = NULL; const UINT8* pTmp = pObj; CK_OBJECT_HANDLE hObjTmp, *pObjHandle; X509* x509 = d2i_X509(NULL, &pTmp, dataLen); if(x509 == NULL) { TINYCLR_SSL_FREE(pObj); return CKR_FUNCTION_FAILED; } if(phObjects == NULL) { pObjHandle = &hObjTmp; } else { pObjHandle = &phObjects[cntObj]; } if(CKR_OK != LoadX509Cert(pSessionCtx, x509, &pObject, NULL, pObjHandle)) { X509_free(x509); TINYCLR_SSL_FREE(pObj); //return CKR_FUNCTION_FAILED; g_OpenSSL_Token.Storage->Delete( fileName, pData->GroupName ); continue; } hal_strcpy_s(pObject->GroupName, ARRAYSIZE(pObject->GroupName), pData->GroupName); hal_strcpy_s(pObject->FileName , ARRAYSIZE(pObject->FileName ), fileName ); cntObj++; TINYCLR_SSL_FREE(pObj); if(cntObj >= ulMaxCount) { *pulObjectCount = cntObj; return CKR_OK; } } break; case KeyType: { // TODO: TINYCLR_SSL_FREE(pObj); } break; default: // TODO: TINYCLR_SSL_FREE(pObj); break; } } } } } *pulObjectCount = cntObj; return CKR_OK; }
CK_RV PKCS11_Digest_OpenSSL::DigestInit(Cryptoki_Session_Context* pSessionCtx, CK_MECHANISM_PTR pMechanism) { OPENSSL_HEADER(); OpenSSLDigestData* pDigData; const EVP_MD* pDigest; CK_OBJECT_HANDLE hKey = CK_OBJECT_HANDLE_INVALID; bool isHMAC = false; if(pSessionCtx == NULL) return CKR_SESSION_CLOSED; if(pSessionCtx->DigestCtx != NULL) return CKR_SESSION_PARALLEL_NOT_SUPPORTED; // another digest is in progress pDigData = (OpenSSLDigestData*)TINYCLR_SSL_MALLOC(sizeof(*pDigData)); if(pDigData == NULL) return CKR_DEVICE_MEMORY; TINYCLR_SSL_MEMSET(pDigData, 0, sizeof(*pDigData)); EVP_MD_CTX_init(&pDigData->CurrentCtx); switch(pMechanism->mechanism) { case CKM_SHA_1: pDigest = EVP_sha1(); break; case CKM_SHA224: pDigest = EVP_sha224(); break; case CKM_SHA256: pDigest = EVP_sha256(); break; case CKM_SHA384: pDigest = EVP_sha384(); break; case CKM_SHA512: pDigest = EVP_sha512(); break; case CKM_MD5: pDigest = EVP_md5(); break; case CKM_RIPEMD160: pDigest = EVP_ripemd160(); break; case CKM_MD5_HMAC: pDigest = EVP_md5(); isHMAC = true; break; case CKM_SHA_1_HMAC: pDigest = EVP_sha1(); isHMAC = true; break; case CKM_SHA256_HMAC: pDigest = EVP_sha256(); isHMAC = true; break; case CKM_SHA384_HMAC: pDigest = EVP_sha384(); isHMAC = true; break; case CKM_SHA512_HMAC: pDigest = EVP_sha512(); isHMAC = true; break; case CKM_RIPEMD160_HMAC: pDigest = EVP_ripemd160(); isHMAC = true; break; default: OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID); } if(isHMAC) { if(pMechanism->pParameter != NULL && pMechanism->ulParameterLen == sizeof(CK_OBJECT_HANDLE)) { hKey = SwapEndianIfBEc32(*(CK_OBJECT_HANDLE*)pMechanism->pParameter); } else { OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_PARAM_INVALID); } pDigData->HmacKey = PKCS11_Keys_OpenSSL::GetKeyFromHandle(pSessionCtx, hKey, TRUE); if(pDigData->HmacKey==NULL) OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_PARAM_INVALID); pDigData->HmacCtx.md = pDigest; OPENSSL_CHECKRESULT(HMAC_Init(&pDigData->HmacCtx, pDigData->HmacKey->key, pDigData->HmacKey->size/8, pDigData->HmacCtx.md)); } else { OPENSSL_CHECKRESULT(EVP_DigestInit_ex(&pDigData->CurrentCtx, pDigest, NULL)); } pSessionCtx->DigestCtx = pDigData; OPENSSL_CLEANUP(); if(retVal != CKR_OK && pDigData != NULL) { TINYCLR_SSL_FREE(pDigData); } OPENSSL_RETURN(); }