* HMAC stubs

* Common hmac implementation

* Typedef aligned context type for readablity

* Provider HMAC

* Refactor engine hmac

* KMAC stubs

* Provider KMAC

* CMAC

* Make mac implementations more generic

* Route cmac to common mac implementation

* Clean up kmac

* Validate engine build

* Additional refactoring and cleanup

* Address PR comments

* Address PR comments

* Address PR comments and ad SHA3 HMAC

* zalloc in mac duplication

* PR comments
This commit is contained in:
Maxwell McKee 2023-12-14 10:26:53 -08:00 коммит произвёл GitHub
Родитель 0ecad51d38
Коммит c16e31d4e6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 1101 добавлений и 218 удалений

Просмотреть файл

@ -13,6 +13,7 @@ set(SCOSSL_SOURCES
./src/scossl_aes_aead.c
./src/scossl_ecc.c
./src/scossl_hkdf.c
./src/scossl_mac.c
./src/scossl_rsa.c
./src/scossl_sshkdf.c
./src/scossl_tls1prf.c

Просмотреть файл

@ -54,10 +54,10 @@ typedef _Return_type_success_(return >= 0) int SCOSSL_RETURNLENGTH; // For funct
// We need to be able to represent the offset into our allocation in a single byte
C_ASSERT( SYMCRYPT_ALIGN_VALUE < 256 );
#define SCOSSL_COMMON_ALIGNED_ALLOC(ptr, allocator, typename) \
#define SCOSSL_COMMON_ALIGNED_ALLOC_EX(ptr, allocator, typename, size) \
typename *ptr; \
{ \
PBYTE scossl_alloc = allocator(SCOSSL_ALIGNED_SIZEOF(typename)); \
PBYTE scossl_alloc = allocator(size + SYMCRYPT_ALIGN_VALUE); \
PBYTE scossl_aligned = NULL; \
if (scossl_alloc) \
{ \
@ -67,14 +67,20 @@ C_ASSERT( SYMCRYPT_ALIGN_VALUE < 256 );
ptr = (typename *) scossl_aligned; \
}
#define SCOSSL_COMMON_ALIGNED_FREE(ptr, deallocator, typename) \
#define SCOSSL_COMMON_ALIGNED_ALLOC(ptr, allocator, typename) \
SCOSSL_COMMON_ALIGNED_ALLOC_EX(ptr, allocator, typename, sizeof(typename))
#define SCOSSL_COMMON_ALIGNED_FREE_EX(ptr, deallocator, size) \
{ \
PBYTE scossl_aligned = (PBYTE) ptr; \
PBYTE scossl_alloc = scossl_aligned - *(scossl_aligned-1); \
deallocator(scossl_alloc, SCOSSL_ALIGNED_SIZEOF(typename)); \
deallocator(scossl_alloc, size + SYMCRYPT_ALIGN_VALUE); \
ptr = NULL; \
}
#define SCOSSL_COMMON_ALIGNED_FREE(ptr, deallocator, typename) \
SCOSSL_COMMON_ALIGNED_FREE_EX(ptr, deallocator, sizeof(typename))
void SCOSSL_set_trace_level(int trace_level, int ossl_ERR_level);
void SCOSSL_set_trace_log_filename(const char *filename);

Просмотреть файл

@ -0,0 +1,58 @@
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "scossl_helpers.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef VOID SCOSSL_MAC_EXPANDED_KEY, *PSCOSSL_MAC_EXPANDED_KEY;
typedef VOID SCOSSL_MAC_STATE, *PSCOSSL_MAC_STATE;
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_KEY_COPY) (PSCOSSL_MAC_EXPANDED_KEY pSrc, PSCOSSL_MAC_EXPANDED_KEY pDst);
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_STATE_COPY) (PSCOSSL_MAC_STATE pSrc, PSCOSSL_MAC_EXPANDED_KEY pExpandedKey, PSCOSSL_MAC_STATE pDst);
// Structure for holding additional constant MAC functions and
// properties needed by SCOSSL
typedef struct
{
PSYMCRYPT_MAC_KEY_COPY keyCopyFunc;
PSYMCRYPT_MAC_STATE_COPY stateCopyFunc;
SIZE_T blockSize;
} SCOSSL_MAC_EX;
typedef struct
{
PSCOSSL_MAC_EXPANDED_KEY expandedKey;
PSCOSSL_MAC_STATE macState;
PCSYMCRYPT_MAC pMac;
const SCOSSL_MAC_EX *pMacEx;
PBYTE pbKey;
SIZE_T cbKey;
// Provider specific fields
PVOID libctx;
// Purely informational
char* mdName;
} SCOSSL_MAC_CTX;
SCOSSL_MAC_CTX *scossl_mac_dupctx(_In_ SCOSSL_MAC_CTX *ctx);
void scossl_mac_freectx(_Inout_ SCOSSL_MAC_CTX *ctx);
SCOSSL_STATUS scossl_mac_set_hmac_md(_Inout_ SCOSSL_MAC_CTX *ctx, _In_ const EVP_MD *md);
SCOSSL_STATUS scossl_mac_set_cmac_cipher(_Inout_ SCOSSL_MAC_CTX *ctx, _In_ const EVP_CIPHER *cipher);
SCOSSL_STATUS scossl_mac_set_mac_key(_Inout_ SCOSSL_MAC_CTX *ctx,
_In_reads_bytes_(cbMacKey) PCBYTE pbMacKey, SIZE_T cbMacKey);
SCOSSL_STATUS scossl_mac_init(_Inout_ SCOSSL_MAC_CTX *ctx,
_In_reads_bytes_(cbKey) PCBYTE pbKey, SIZE_T cbKey);
SCOSSL_STATUS scossl_mac_update(_Inout_ SCOSSL_MAC_CTX *ctx,
_In_reads_bytes_(cbData) PCBYTE pbData, SIZE_T cbData);
SCOSSL_STATUS scossl_mac_final(_Inout_ SCOSSL_MAC_CTX *ctx,
_Out_writes_bytes_opt_(*cbResult) PBYTE pbResult, _Out_ SIZE_T *cbResult, SIZE_T outsize);
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -39,7 +39,7 @@ SCOSSL_STATUS scossl_aes_gcm_init_key(SCOSSL_CIPHER_GCM_CTX *ctx,
if (ivlen != SCOSSL_GCM_IV_LENGTH)
{
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_AES_GCM_CTRL, SCOSSL_ERR_R_NOT_IMPLEMENTED,
"SymCrypt for OpenSSL only supports %d byte IV for AES-GCM", SCOSSL_GCM_IV_LENGTH);
"SCOSSL only supports %d byte IV for AES-GCM", SCOSSL_GCM_IV_LENGTH);
return SCOSSL_FAILURE;
}
ctx->ivlen = ivlen;
@ -655,7 +655,7 @@ SCOSSL_STATUS scossl_aes_ccm_set_iv_len(SCOSSL_CIPHER_CCM_CTX *ctx, size_t ivlen
if (ivlen < SCOSSL_CCM_MIN_IV_LENGTH || ivlen > SCOSSL_CCM_MAX_IV_LENGTH)
{
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_AES_CCM_CTRL, ERR_R_PASSED_INVALID_ARGUMENT,
"SymCrypt for OpenSSL only supports [%d-%d] byte IVs for AES-CCM",
"SCOSSL only supports [%d-%d] byte IVs for AES-CCM",
SCOSSL_CCM_MIN_IV_LENGTH, SCOSSL_CCM_MAX_IV_LENGTH);
return SCOSSL_FAILURE;
}

Просмотреть файл

@ -0,0 +1,319 @@
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "scossl_mac.h"
#ifdef __cplusplus
extern "C" {
#endif
static const SCOSSL_MAC_EX SymCryptHmacSha1Ex = {
(PSYMCRYPT_MAC_KEY_COPY)SymCryptHmacSha1KeyCopy,
(PSYMCRYPT_MAC_STATE_COPY)SymCryptHmacSha1StateCopy,
SYMCRYPT_HMAC_SHA1_INPUT_BLOCK_SIZE
};
static const SCOSSL_MAC_EX SymCryptHmacSha256Ex = {
(PSYMCRYPT_MAC_KEY_COPY)SymCryptHmacSha256KeyCopy,
(PSYMCRYPT_MAC_STATE_COPY)SymCryptHmacSha256StateCopy,
SYMCRYPT_HMAC_SHA256_INPUT_BLOCK_SIZE
};
static const SCOSSL_MAC_EX SymCryptHmacSha384Ex = {
(PSYMCRYPT_MAC_KEY_COPY)SymCryptHmacSha384KeyCopy,
(PSYMCRYPT_MAC_STATE_COPY)SymCryptHmacSha384StateCopy,
SYMCRYPT_HMAC_SHA384_INPUT_BLOCK_SIZE
};
static const SCOSSL_MAC_EX SymCryptHmacSha512Ex = {
(PSYMCRYPT_MAC_KEY_COPY)SymCryptHmacSha512KeyCopy,
(PSYMCRYPT_MAC_STATE_COPY)SymCryptHmacSha512StateCopy,
SYMCRYPT_HMAC_SHA512_INPUT_BLOCK_SIZE
};
static const SCOSSL_MAC_EX SymCryptHmacSha3_256Ex = {
(PSYMCRYPT_MAC_KEY_COPY)SymCryptHmacSha3_256KeyCopy,
(PSYMCRYPT_MAC_STATE_COPY)SymCryptHmacSha3_256StateCopy,
SYMCRYPT_HMAC_SHA3_256_INPUT_BLOCK_SIZE
};
static const SCOSSL_MAC_EX SymCryptHmacSha3_384Ex = {
(PSYMCRYPT_MAC_KEY_COPY)SymCryptHmacSha3_384KeyCopy,
(PSYMCRYPT_MAC_STATE_COPY)SymCryptHmacSha3_384StateCopy,
SYMCRYPT_HMAC_SHA3_384_INPUT_BLOCK_SIZE
};
static const SCOSSL_MAC_EX SymCryptHmacSha3_512Ex = {
(PSYMCRYPT_MAC_KEY_COPY)SymCryptHmacSha3_512KeyCopy,
(PSYMCRYPT_MAC_STATE_COPY)SymCryptHmacSha3_512StateCopy,
SYMCRYPT_HMAC_SHA3_512_INPUT_BLOCK_SIZE
};
static const SCOSSL_MAC_EX SymCryptAesCmacEx = {
(PSYMCRYPT_MAC_KEY_COPY)SymCryptAesCmacKeyCopy,
(PSYMCRYPT_MAC_STATE_COPY)SymCryptAesCmacStateCopy,
SYMCRYPT_AES_CMAC_INPUT_BLOCK_SIZE
};
_Use_decl_annotations_
SCOSSL_MAC_CTX *scossl_mac_dupctx(SCOSSL_MAC_CTX *ctx)
{
SCOSSL_STATUS success = SCOSSL_FAILURE;
SCOSSL_MAC_CTX *copyCtx = NULL;
if ((copyCtx = OPENSSL_zalloc(sizeof(SCOSSL_MAC_CTX))) != NULL)
{
if (ctx->pbKey != NULL)
{
if ((copyCtx->pbKey = OPENSSL_malloc(ctx->cbKey)) == NULL)
{
goto cleanup;
}
memcpy(copyCtx->pbKey, ctx->pbKey, ctx->cbKey);
copyCtx->cbKey = ctx->cbKey;
}
copyCtx->pMac = ctx->pMac;
copyCtx->pMacEx = ctx->pMacEx;
if (ctx->pMacEx != NULL)
{
if (ctx->expandedKey != NULL)
{
SCOSSL_COMMON_ALIGNED_ALLOC_EX(expandedKey, OPENSSL_malloc, SCOSSL_MAC_EXPANDED_KEY, ctx->pMac->expandedKeySize);
if (expandedKey == NULL)
{
goto cleanup;
}
copyCtx->expandedKey = expandedKey;
ctx->pMacEx->keyCopyFunc(ctx->expandedKey, copyCtx->expandedKey);
}
if (ctx->macState != NULL)
{
SCOSSL_COMMON_ALIGNED_ALLOC_EX(macState, OPENSSL_malloc, SCOSSL_MAC_STATE, ctx->pMac->stateSize);
if (macState == NULL)
{
goto cleanup;
}
copyCtx->macState = macState;
ctx->pMacEx->stateCopyFunc(ctx->macState, ctx->expandedKey, copyCtx->macState);
}
}
copyCtx->mdName = OPENSSL_strdup(ctx->mdName);
copyCtx->libctx = ctx->libctx;
}
success = SCOSSL_SUCCESS;
cleanup:
if (!success)
{
scossl_mac_freectx(copyCtx);
copyCtx = NULL;
}
return copyCtx;
}
_Use_decl_annotations_
void scossl_mac_freectx(SCOSSL_MAC_CTX *ctx)
{
if (ctx == NULL)
return;
if (ctx->expandedKey != NULL)
{
SCOSSL_COMMON_ALIGNED_FREE_EX(ctx->expandedKey, OPENSSL_clear_free, ctx->pMac->expandedKeySize);
}
if (ctx->macState != NULL)
{
SCOSSL_COMMON_ALIGNED_FREE_EX(ctx->macState, OPENSSL_clear_free, ctx->pMac->stateSize);
}
OPENSSL_free(ctx->mdName);
OPENSSL_clear_free(ctx->pbKey, ctx->cbKey);
OPENSSL_free(ctx);
}
// HMAC
_Use_decl_annotations_
SCOSSL_STATUS scossl_mac_set_hmac_md(SCOSSL_MAC_CTX *ctx, const EVP_MD *md)
{
int type = EVP_MD_type(md);
if (ctx->macState != NULL)
{
SCOSSL_COMMON_ALIGNED_FREE_EX(ctx->macState, OPENSSL_clear_free, ctx->pMac->stateSize);
ctx->macState = NULL;
}
if (ctx->expandedKey != NULL)
{
SCOSSL_COMMON_ALIGNED_FREE_EX(ctx->expandedKey, OPENSSL_clear_free, ctx->pMac->expandedKeySize);
ctx->expandedKey = NULL;
}
switch (type)
{
case NID_sha1:
ctx->pMac = SymCryptHmacSha1Algorithm;
ctx->pMacEx = &SymCryptHmacSha1Ex;
break;
case NID_sha256:
ctx->pMac = SymCryptHmacSha256Algorithm;
ctx->pMacEx = &SymCryptHmacSha256Ex;
break;
case NID_sha384:
ctx->pMac = SymCryptHmacSha384Algorithm;
ctx->pMacEx = &SymCryptHmacSha384Ex;
break;
case NID_sha512:
ctx->pMac = SymCryptHmacSha512Algorithm;
ctx->pMacEx = &SymCryptHmacSha512Ex;
break;
case NID_sha3_256:
ctx->pMac = SymCryptHmacSha3_256Algorithm;
ctx->pMacEx = &SymCryptHmacSha3_256Ex;
break;
case NID_sha3_384:
ctx->pMac = SymCryptHmacSha3_384Algorithm;
ctx->pMacEx = &SymCryptHmacSha3_384Ex;
break;
case NID_sha3_512:
ctx->pMac = SymCryptHmacSha3_512Algorithm;
ctx->pMacEx = &SymCryptHmacSha3_512Ex;
break;
default:
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_GET_SYMCRYPT_HASH_ALGORITHM, SCOSSL_ERR_R_NOT_IMPLEMENTED,
"SCOSSL does not support hash algorithm for MAC %d", type);
return SCOSSL_FAILURE;
}
SCOSSL_COMMON_ALIGNED_ALLOC_EX(macState, OPENSSL_malloc, SCOSSL_MAC_STATE, ctx->pMac->stateSize);
ctx->macState = macState;
return ctx->macState != NULL;
}
// CMAC
_Use_decl_annotations_
SCOSSL_STATUS scossl_mac_set_cmac_cipher(SCOSSL_MAC_CTX *ctx, const EVP_CIPHER *cipher)
{
if (ctx->macState != NULL)
{
SCOSSL_COMMON_ALIGNED_FREE_EX(ctx->macState, OPENSSL_clear_free, ctx->pMac->stateSize);
ctx->macState = NULL;
}
if (ctx->expandedKey != NULL)
{
SCOSSL_COMMON_ALIGNED_FREE_EX(ctx->expandedKey, OPENSSL_clear_free, ctx->pMac->expandedKeySize);
ctx->expandedKey = NULL;
}
switch (EVP_CIPHER_nid(cipher))
{
case NID_aes_128_cbc:
ctx->cbKey = 16;
break;
case NID_aes_192_cbc:
ctx->cbKey = 24;
break;
case NID_aes_256_cbc:
ctx->cbKey = 32;
break;
default:
return SCOSSL_FAILURE;
}
ctx->pMac = SymCryptAesCmacAlgorithm;;
ctx->pMacEx = &SymCryptAesCmacEx;
SCOSSL_COMMON_ALIGNED_ALLOC_EX(macState, OPENSSL_malloc, SCOSSL_MAC_STATE, ctx->pMac->stateSize);
ctx->macState = macState;
return ctx->macState != NULL;
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_mac_set_mac_key(SCOSSL_MAC_CTX *ctx,
PCBYTE pbMacKey, SIZE_T cbMacKey)
{
PBYTE pbKey;
if (pbMacKey == NULL ||
(pbKey = OPENSSL_malloc(cbMacKey)) == NULL)
{
return SCOSSL_FAILURE;
}
OPENSSL_clear_free(ctx->pbKey, ctx->cbKey);
ctx->pbKey = pbKey;
ctx->cbKey = cbMacKey;
memcpy(ctx->pbKey, pbMacKey, cbMacKey);
return SCOSSL_SUCCESS;
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_mac_init(SCOSSL_MAC_CTX *ctx,
PCBYTE pbKey, SIZE_T cbKey)
{
if (pbKey != NULL)
{
if (ctx->expandedKey == NULL)
{
SCOSSL_COMMON_ALIGNED_ALLOC_EX(expandedKey, OPENSSL_malloc, SCOSSL_MAC_EXPANDED_KEY, ctx->pMac->expandedKeySize);
ctx->expandedKey = expandedKey;
}
if (ctx->expandedKey == NULL ||
ctx->pMac->expandKeyFunc(ctx->expandedKey, pbKey, cbKey) != SYMCRYPT_NO_ERROR)
{
return SCOSSL_FAILURE;
}
}
ctx->pMac->initFunc(ctx->macState, ctx->expandedKey);
return SCOSSL_SUCCESS;
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_mac_update(SCOSSL_MAC_CTX *ctx,
PCBYTE pbData, SIZE_T cbData)
{
ctx->pMac->appendFunc(ctx->macState, pbData, cbData);
return SCOSSL_SUCCESS;
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_mac_final(SCOSSL_MAC_CTX *ctx,
PBYTE pbResult, SIZE_T *cbResult, SIZE_T outsize)
{
if (pbResult != NULL)
{
if (outsize < ctx->pMac->resultSize)
{
return SCOSSL_FAILURE;
}
ctx->pMac->resultFunc(ctx->macState, pbResult);
}
*cbResult = ctx->pMac->resultSize;
return SCOSSL_SUCCESS;
}
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -2,7 +2,9 @@
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "scossl_mac.h"
#include "e_scossl_hmac.h"
#include <openssl/hmac.h>
#include <openssl/kdf.h>
@ -10,220 +12,89 @@
extern "C" {
#endif
typedef struct {
SYMCRYPT_MAC_EXPANDED_KEY expandedKey;
SYMCRYPT_MAC_STATE macState;
PCSYMCRYPT_MAC mac;
ASN1_OCTET_STRING key;
} SCOSSL_HMAC_PKEY_CTX;
static PCSYMCRYPT_MAC e_scossl_get_symcrypt_hmac_algorithm( _In_ const EVP_MD *evp_md )
_Use_decl_annotations_
SCOSSL_STATUS e_scossl_hmac_init(EVP_PKEY_CTX *ctx)
{
int type = EVP_MD_type(evp_md);
SCOSSL_MAC_CTX *e_scossl_hmac_context;
if (type == NID_sha1)
return SymCryptHmacSha1Algorithm;
if (type == NID_sha256)
return SymCryptHmacSha256Algorithm;
if (type == NID_sha384)
return SymCryptHmacSha384Algorithm;
if (type == NID_sha512)
return SymCryptHmacSha512Algorithm;
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_GET_SYMCRYPT_HASH_ALGORITHM, SCOSSL_ERR_R_NOT_IMPLEMENTED,
"SymCrypt engine does not support hash algorithm %d", type);
return NULL;
}
SCOSSL_STATUS e_scossl_hmac_init(_Inout_ EVP_PKEY_CTX *ctx)
{
PBYTE e_scossl_hmac_context_alloc;
if ((e_scossl_hmac_context_alloc = OPENSSL_zalloc(SCOSSL_ALIGNED_SIZEOF(SCOSSL_HMAC_PKEY_CTX))) == NULL) {
if ((e_scossl_hmac_context = OPENSSL_zalloc(sizeof(SCOSSL_MAC_CTX))) == NULL)
{
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HMAC_INIT, ERR_R_MALLOC_FAILURE,
"OPENSSL_zalloc returned NULL");
"OPENSSL_zalloc returned NULL");
return SCOSSL_FAILURE;
}
EVP_PKEY_CTX_set_data(ctx, e_scossl_hmac_context_alloc);
EVP_PKEY_CTX_set_data(ctx, e_scossl_hmac_context);
return SCOSSL_SUCCESS;
}
void e_scossl_hmac_cleanup(_Inout_ EVP_PKEY_CTX *ctx)
_Use_decl_annotations_
void e_scossl_hmac_cleanup(EVP_PKEY_CTX *ctx)
{
PBYTE e_scossl_hmac_context_alloc = EVP_PKEY_CTX_get_data(ctx);
SCOSSL_HMAC_PKEY_CTX *e_scossl_hmac_context = (SCOSSL_HMAC_PKEY_CTX *) SCOSSL_ALIGN_UP(e_scossl_hmac_context_alloc);
if (!e_scossl_hmac_context) {
return;
}
OPENSSL_clear_free(e_scossl_hmac_context->key.data, e_scossl_hmac_context->key.length);
OPENSSL_clear_free(e_scossl_hmac_context_alloc, SCOSSL_ALIGNED_SIZEOF(SCOSSL_HMAC_PKEY_CTX));
SCOSSL_MAC_CTX *e_scossl_hmac_context = EVP_PKEY_CTX_get_data(ctx);
scossl_mac_freectx(e_scossl_hmac_context);
EVP_PKEY_CTX_set_data(ctx, NULL);
}
SCOSSL_STATUS e_scossl_hmac_copy(_Out_ EVP_PKEY_CTX *dst, _In_ EVP_PKEY_CTX *src)
// The const modifier on src was added in OpenSSL 3, but is not expected
// in OpenSSL 1.1.1. Building the Engine for OpenSSL 1.1.1 will generate
// an incompatible pointer warning that can be safely ignored.
_Use_decl_annotations_
SCOSSL_STATUS e_scossl_hmac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
{
SCOSSL_STATUS ret = SCOSSL_SUCCESS;
SCOSSL_HMAC_PKEY_CTX *src_ctx, *dst_ctx;
ASN1_OCTET_STRING *pkey;
SCOSSL_MAC_CTX *src_ctx, *dst_ctx;
ret = e_scossl_hmac_init(dst);
if (ret != SCOSSL_SUCCESS) {
goto end;
if ((src_ctx = EVP_PKEY_CTX_get_data(src)) == NULL)
{
return SCOSSL_FAILURE;
}
src_ctx = (SCOSSL_HMAC_PKEY_CTX *) SCOSSL_ALIGN_UP(EVP_PKEY_CTX_get_data(src));
dst_ctx = (SCOSSL_HMAC_PKEY_CTX *) SCOSSL_ALIGN_UP(EVP_PKEY_CTX_get_data(dst));
if(!src_ctx || !dst_ctx) {
ret = SCOSSL_FAILURE;
goto cleanup;
if ((dst_ctx = scossl_mac_dupctx(src_ctx)) == NULL)
{
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HMAC_INIT, ERR_R_MALLOC_FAILURE,
"scossl_hmac_dupctx returned NULL");
return SCOSSL_FAILURE;
}
if(src_ctx->key.data) {
EVP_PKEY_CTX_set_data(dst, dst_ctx);
pkey = ASN1_OCTET_STRING_dup(&src_ctx->key);
if(!pkey) {
ret = SCOSSL_FAILURE;
goto cleanup;
}
dst_ctx->key = *pkey;
}
else {
dst_ctx->key.data = NULL;
dst_ctx->key.length = 0;
}
dst_ctx->mac = src_ctx->mac;
// Copy the expanded key and mac state
if(src_ctx->mac == SymCryptHmacSha1Algorithm) {
SymCryptHmacSha1KeyCopy(&src_ctx->expandedKey.sha1Key,
&dst_ctx->expandedKey.sha1Key);
SymCryptHmacSha1StateCopy( &src_ctx->macState.sha1State,
&dst_ctx->expandedKey.sha1Key,
&dst_ctx->macState.sha1State);
}
else if(src_ctx->mac == SymCryptHmacSha256Algorithm) {
SymCryptHmacSha256KeyCopy( &src_ctx->expandedKey.sha256Key,
&dst_ctx->expandedKey.sha256Key);
SymCryptHmacSha256StateCopy(&src_ctx->macState.sha256State,
&dst_ctx->expandedKey.sha256Key,
&dst_ctx->macState.sha256State);
}
else if(src_ctx->mac == SymCryptHmacSha384Algorithm) {
SymCryptHmacSha384KeyCopy( &src_ctx->expandedKey.sha384Key,
&dst_ctx->expandedKey.sha384Key);
SymCryptHmacSha384StateCopy(&src_ctx->macState.sha384State,
&dst_ctx->expandedKey.sha384Key,
&dst_ctx->macState.sha384State);
}
else if(src_ctx->mac == SymCryptHmacSha512Algorithm) {
SymCryptHmacSha512KeyCopy( &src_ctx->expandedKey.sha512Key,
&dst_ctx->expandedKey.sha512Key);
SymCryptHmacSha512StateCopy(&src_ctx->macState.sha512State,
&dst_ctx->expandedKey.sha512Key,
&dst_ctx->macState.sha512State);
}
cleanup:
if(ret != SCOSSL_SUCCESS) {
e_scossl_hmac_cleanup(dst);
}
end:
return ret;
return SCOSSL_SUCCESS;
}
_Use_decl_annotations_
SCOSSL_STATUS e_scossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
SCOSSL_STATUS ret = SCOSSL_SUCCESS;
SCOSSL_HMAC_PKEY_CTX *e_scossl_hmac_context = (SCOSSL_HMAC_PKEY_CTX *) SCOSSL_ALIGN_UP(EVP_PKEY_CTX_get_data(ctx));
EVP_PKEY *pkey;
ASN1_OCTET_STRING *key;
SCOSSL_STATUS ret = SCOSSL_SUCCESS;
SCOSSL_MAC_CTX *e_scossl_hmac_context = EVP_PKEY_CTX_get_data(ctx);
switch (type) {
switch (type)
{
case EVP_PKEY_CTRL_MD:
// Expecting p2 of type EVP_MD* specifying the hash function to be used in HMAC
if (p2 == NULL) {
ret = SCOSSL_FAILURE;
break;
}
e_scossl_hmac_context->mac = e_scossl_get_symcrypt_hmac_algorithm((const EVP_MD*)p2);
ret = scossl_mac_set_hmac_md(e_scossl_hmac_context, p2);
break;
case EVP_PKEY_CTRL_SET_MAC_KEY:
// p2 : pointer to the buffer containing the HMAC key, must not be NULL.
// p1 : length of the key in bytes. p1 = -1 indicates p2 is a null-terminated string.
if (p1 < -1 || !p2) {
ret = SCOSSL_FAILURE;
break;
}
if(e_scossl_hmac_context->key.data) {
OPENSSL_clear_free(e_scossl_hmac_context->key.data, e_scossl_hmac_context->key.length);
}
if(!ASN1_OCTET_STRING_set(&e_scossl_hmac_context->key, p2, p1)) {
ret = SCOSSL_FAILURE;
break;
}
ret = scossl_mac_set_mac_key(e_scossl_hmac_context, p2, p1);
break;
case EVP_PKEY_CTRL_DIGESTINIT:
pkey = EVP_PKEY_CTX_get0_pkey(ctx);
if(!pkey) {
if ((pkey = EVP_PKEY_CTX_get0_pkey(ctx)) == NULL ||
(key = EVP_PKEY_get0(pkey)) == NULL)
{
ret = SCOSSL_FAILURE;
break;
}
key = EVP_PKEY_get0(pkey);
if(!key) {
ret = SCOSSL_FAILURE;
break;
}
if(e_scossl_hmac_context->mac->expandKeyFunc(&e_scossl_hmac_context->expandedKey,
key->data,
key->length) != SYMCRYPT_NO_ERROR) {
ret = SCOSSL_FAILURE;
break;
}
e_scossl_hmac_context->mac->initFunc(&e_scossl_hmac_context->macState, &e_scossl_hmac_context->expandedKey);
ret = scossl_mac_init(e_scossl_hmac_context, key->data, key->length);
break;
default:
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HMAC_CTRL, SCOSSL_ERR_R_NOT_IMPLEMENTED,
"SymCrypt Engine does not support ctrl type (%d)", type);
@ -233,41 +104,40 @@ SCOSSL_STATUS e_scossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return ret;
}
_Use_decl_annotations_
SCOSSL_STATUS e_scossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
SCOSSL_STATUS ret = SCOSSL_SUCCESS;
SCOSSL_HMAC_PKEY_CTX *e_scossl_hmac_context = (SCOSSL_HMAC_PKEY_CTX *) SCOSSL_ALIGN_UP(EVP_PKEY_CTX_get_data(ctx));
SCOSSL_MAC_CTX *e_scossl_hmac_context = EVP_PKEY_CTX_get_data(ctx);
ASN1_OCTET_STRING *key;
if(!e_scossl_hmac_context->key.data) {
if (e_scossl_hmac_context->pbKey == NULL)
{
ret = SCOSSL_FAILURE;
goto end;
}
key = ASN1_OCTET_STRING_dup(&e_scossl_hmac_context->key);
if(!key) {
if ((key = ASN1_OCTET_STRING_new()) == NULL ||
!ASN1_OCTET_STRING_set(key, e_scossl_hmac_context->pbKey, e_scossl_hmac_context->cbKey))
{
ret = SCOSSL_FAILURE;
goto end;
}
EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, key);
end:
return ret;
}
_Use_decl_annotations_
SCOSSL_STATUS e_scossl_hmac_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
SCOSSL_HMAC_PKEY_CTX *e_scossl_hmac_context = (SCOSSL_HMAC_PKEY_CTX *) SCOSSL_ALIGN_UP(EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)));
e_scossl_hmac_context->mac->appendFunc(&e_scossl_hmac_context->macState, data, count);
return SCOSSL_SUCCESS;
return scossl_mac_update(EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)), data, count);
}
_Use_decl_annotations_
SCOSSL_STATUS e_scossl_hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mdctx)
{
EVP_MD_CTX_set_flags(mdctx, EVP_MD_CTX_FLAG_NO_INIT);
@ -277,36 +147,12 @@ SCOSSL_STATUS e_scossl_hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mdctx)
return SCOSSL_SUCCESS;
}
SCOSSL_STATUS e_scossl_hmac_signctx(_Inout_ EVP_PKEY_CTX *ctx, _Out_ unsigned char *sig, _Out_ size_t *siglen, _In_ EVP_MD_CTX *mdctx)
_Use_decl_annotations_
SCOSSL_STATUS e_scossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mdctx)
{
SCOSSL_STATUS ret = SCOSSL_SUCCESS;
SCOSSL_HMAC_PKEY_CTX *e_scossl_hmac_context = (SCOSSL_HMAC_PKEY_CTX *) SCOSSL_ALIGN_UP(EVP_PKEY_CTX_get_data(ctx));
if(!sig) {
*siglen = e_scossl_hmac_context->mac->resultSize;
goto end;
}
if(*siglen < e_scossl_hmac_context->mac->resultSize) {
ret = SCOSSL_FAILURE;
goto end;
}
e_scossl_hmac_context->mac->resultFunc(&e_scossl_hmac_context->macState, sig);
*siglen = e_scossl_hmac_context->mac->resultSize;
end:
return ret;
return scossl_mac_final(EVP_PKEY_CTX_get_data(ctx), sig, siglen, *siglen);
}
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -16,7 +16,7 @@ SCOSSL_STATUS e_scossl_hmac_init(_Inout_ EVP_PKEY_CTX *ctx);
void e_scossl_hmac_cleanup(_Inout_ EVP_PKEY_CTX *ctx);
// Makes a copy of internal context src
SCOSSL_STATUS e_scossl_hmac_copy(_Out_ EVP_PKEY_CTX *dst, _In_ EVP_PKEY_CTX *src);
SCOSSL_STATUS e_scossl_hmac_copy(_Out_ EVP_PKEY_CTX *dst, _In_ const EVP_PKEY_CTX *src);
// Sends a control operation to context ctx. type indicates which operation, and
// p1 and p2 are optional parameters depending on which type is used.
@ -24,7 +24,7 @@ SCOSSL_STATUS e_scossl_hmac_copy(_Out_ EVP_PKEY_CTX *dst, _In_ EVP_PKEY_CTX *src
SCOSSL_STATUS e_scossl_hmac_ctrl(_Inout_ EVP_PKEY_CTX *ctx, int type, int p1, _In_ void *p2);
// Initializes pkey with the HMAC key from the internal context.
SCOSSL_STATUS e_scossl_hmac_keygen(_Inout_ EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
SCOSSL_STATUS e_scossl_hmac_keygen(_In_ EVP_PKEY_CTX *ctx, _Inout_ EVP_PKEY *pkey);
// Performs initialization on the mdctx object, such as setting the message update function.
SCOSSL_STATUS e_scossl_hmac_signctx_init(_Inout_ EVP_PKEY_CTX *ctx, _In_ EVP_MD_CTX *mdctx);

Просмотреть файл

@ -27,6 +27,9 @@ set(SCOSSL_SOURCES
./src/keyexch/p_scossl_ecdh.c
./src/keymgmt/p_scossl_ecc_keymgmt.c
./src/keymgmt/p_scossl_rsa_keymgmt.c
./src/mac/p_scossl_cmac.c
./src/mac/p_scossl_hmac.c
./src/mac/p_scossl_kmac.c
./src/signature/p_scossl_ecdsa_signature.c
./src/signature/p_scossl_rsa_signature.c
./src/p_scossl_digests.c

Просмотреть файл

@ -0,0 +1,143 @@
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "scossl_mac.h"
#include "p_scossl_base.h"
#include <openssl/proverr.h>
#ifdef __cplusplus
extern "C" {
#endif
static const OSSL_PARAM p_scossl_cmac_ctx_gettable_param_types[] = {
OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL),
OSSL_PARAM_END};
static const OSSL_PARAM p_scossl_cmac_ctx_settable_param_types[] = {
OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
OSSL_PARAM_END};
static SCOSSL_STATUS p_scossl_cmac_set_ctx_params(_Inout_ SCOSSL_MAC_CTX *ctx, _In_ const OSSL_PARAM params[]);
static SCOSSL_MAC_CTX *p_scossl_cmac_newctx(_In_ SCOSSL_PROVCTX *provctx)
{
SCOSSL_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(SCOSSL_MAC_CTX));
if (ctx != NULL)
{
ctx->libctx = provctx->libctx;
}
return ctx;
}
static SCOSSL_STATUS p_scossl_cmac_init(_Inout_ SCOSSL_MAC_CTX *ctx,
_In_reads_bytes_opt_(keylen) unsigned char *key, size_t keylen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_cmac_set_ctx_params(ctx, params) &&
scossl_mac_init(ctx, key, keylen);
}
static const OSSL_PARAM *p_scossl_cmac_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
{
return p_scossl_cmac_ctx_gettable_param_types;
}
static const OSSL_PARAM *p_scossl_cmac_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
{
return p_scossl_cmac_ctx_settable_param_types;
}
static SCOSSL_STATUS p_scossl_cmac_get_ctx_params(_In_ SCOSSL_MAC_CTX *ctx, _Inout_ OSSL_PARAM params[])
{
OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL &&
!OSSL_PARAM_set_size_t(p, ctx->pMac == NULL ? 0 : ctx->pMac->resultSize))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_BLOCK_SIZE)) != NULL &&
!OSSL_PARAM_set_size_t(p, ctx->pMacEx == NULL ? 0 : ctx->pMacEx->blockSize))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
return SCOSSL_SUCCESS;
}
static SCOSSL_STATUS p_scossl_cmac_set_ctx_params(_Inout_ SCOSSL_MAC_CTX *ctx, _In_ const OSSL_PARAM params[])
{
const OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CIPHER)) != NULL)
{
SCOSSL_STATUS success;
const char *cipherName, *cipherProps;
EVP_CIPHER *cipher;
if (!OSSL_PARAM_get_utf8_string_ptr(p, &cipherName))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
cipherProps = NULL;
p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_PROPERTIES);
if ((p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &cipherProps)) ||
(cipher = EVP_CIPHER_fetch(ctx->libctx, cipherName, cipherProps)) == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
success = scossl_mac_set_cmac_cipher(ctx, cipher);
EVP_CIPHER_free(cipher);
if (!success)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
return SCOSSL_FAILURE;
}
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL)
{
PCBYTE pbMacKey;
SIZE_T cbMacKey;
if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pbMacKey, &cbMacKey) ||
!scossl_mac_init(ctx, pbMacKey, cbMacKey))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
}
return SCOSSL_SUCCESS;
}
const OSSL_DISPATCH p_scossl_cmac_functions[] = {
{OSSL_FUNC_MAC_NEWCTX, (void (*)(void))p_scossl_cmac_newctx},
{OSSL_FUNC_MAC_FREECTX, (void (*)(void))scossl_mac_freectx},
{OSSL_FUNC_MAC_DUPCTX, (void (*)(void))scossl_mac_dupctx},
{OSSL_FUNC_MAC_INIT, (void (*)(void))p_scossl_cmac_init},
{OSSL_FUNC_MAC_UPDATE, (void (*)(void))scossl_mac_update},
{OSSL_FUNC_MAC_FINAL, (void (*)(void))scossl_mac_final},
{OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_cmac_gettable_ctx_params},
{OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_cmac_settable_ctx_params},
{OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))p_scossl_cmac_get_ctx_params},
{OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))p_scossl_cmac_set_ctx_params},
{0, NULL}};
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -0,0 +1,162 @@
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "scossl_mac.h"
#include "p_scossl_base.h"
#include <openssl/proverr.h>
#ifdef __cplusplus
extern "C" {
#endif
static const OSSL_PARAM p_scossl_hmac_ctx_gettable_param_types[] = {
OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL),
OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_END};
static const OSSL_PARAM p_scossl_hmac_ctx_settable_param_types[] = {
OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
OSSL_PARAM_END};
static SCOSSL_STATUS p_scossl_hmac_set_ctx_params(_Inout_ SCOSSL_MAC_CTX *ctx, _In_ const OSSL_PARAM params[]);
static SCOSSL_MAC_CTX *p_scossl_hmac_newctx(_In_ SCOSSL_PROVCTX *provctx)
{
SCOSSL_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(SCOSSL_MAC_CTX));
if (ctx != NULL)
{
ctx->libctx = provctx->libctx;
}
return ctx;
}
static SCOSSL_STATUS p_scossl_hmac_init(_Inout_ SCOSSL_MAC_CTX *ctx,
_In_reads_bytes_opt_(keylen) unsigned char *key, size_t keylen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_hmac_set_ctx_params(ctx, params) &&
scossl_mac_init(ctx, key, keylen);
}
static const OSSL_PARAM *p_scossl_hmac_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
{
return p_scossl_hmac_ctx_gettable_param_types;
}
static const OSSL_PARAM *p_scossl_hmac_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
{
return p_scossl_hmac_ctx_settable_param_types;
}
static SCOSSL_STATUS p_scossl_hmac_get_ctx_params(_In_ SCOSSL_MAC_CTX *ctx, _Inout_ OSSL_PARAM params[])
{
OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL &&
!OSSL_PARAM_set_size_t(p, ctx->pMac == NULL ? 0 : ctx->pMac->resultSize))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_BLOCK_SIZE)) != NULL &&
!OSSL_PARAM_set_size_t(p, ctx->pMacEx == NULL ? 0 : ctx->pMacEx->blockSize))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_DIGEST)) != NULL &&
!OSSL_PARAM_set_utf8_string(p, ctx->mdName == NULL ? "" : ctx->mdName))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
return SCOSSL_SUCCESS;
}
static SCOSSL_STATUS p_scossl_hmac_set_ctx_params(_Inout_ SCOSSL_MAC_CTX *ctx, _In_ const OSSL_PARAM params[])
{
const OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_DIGEST)) != NULL)
{
SCOSSL_STATUS success;
const char *paramMdName, *mdProps;
char *mdName;
EVP_MD *md;
if (!OSSL_PARAM_get_utf8_string_ptr(p, &paramMdName))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
mdProps = NULL;
p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES);
if (p != NULL &&
!OSSL_PARAM_get_utf8_string_ptr(p, &mdProps))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
if ((md = EVP_MD_fetch(ctx->libctx, paramMdName, mdProps)) == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
return SCOSSL_FAILURE;
}
mdName = OPENSSL_strdup(EVP_MD_get0_name(md));
success = scossl_mac_set_hmac_md(ctx, md);
EVP_MD_free(md);
if (!success)
{
OPENSSL_free(mdName);
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
return SCOSSL_FAILURE;
}
OPENSSL_free(ctx->mdName);
ctx->mdName = mdName;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL)
{
PCBYTE pbMacKey;
SIZE_T cbMacKey;
if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pbMacKey, &cbMacKey) ||
!scossl_mac_init(ctx, pbMacKey, cbMacKey))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
}
return SCOSSL_SUCCESS;
}
const OSSL_DISPATCH p_scossl_hmac_functions[] = {
{OSSL_FUNC_MAC_NEWCTX, (void (*)(void))p_scossl_hmac_newctx},
{OSSL_FUNC_MAC_FREECTX, (void (*)(void))scossl_mac_freectx},
{OSSL_FUNC_MAC_DUPCTX, (void (*)(void))scossl_mac_dupctx},
{OSSL_FUNC_MAC_INIT, (void (*)(void))p_scossl_hmac_init},
{OSSL_FUNC_MAC_UPDATE, (void (*)(void))scossl_mac_update},
{OSSL_FUNC_MAC_FINAL, (void (*)(void))scossl_mac_final},
{OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_hmac_gettable_ctx_params},
{OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_hmac_settable_ctx_params},
{OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))p_scossl_hmac_get_ctx_params},
{OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))p_scossl_hmac_set_ctx_params},
{0, NULL}};
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -0,0 +1,339 @@
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "scossl_helpers.h"
#include <openssl/core_names.h>
#include <openssl/proverr.h>
#ifdef __cplusplus
extern "C" {
#endif
#define KMAC_MAX_OUTPUT_LEN (0xFFFFFF / 8)
#define KMAC_MAX_CUSTOM 512
typedef union
{
SYMCRYPT_KMAC128_EXPANDED_KEY kmac128Key;
SYMCRYPT_KMAC256_EXPANDED_KEY kmac256Key;
} SCOSSL_KMAC_EXPANDED_KEY;
typedef union
{
SYMCRYPT_KMAC128_STATE kmac128State;
SYMCRYPT_KMAC256_STATE kmac256State;
} SCOSSL_KMAC_STATE;
typedef SYMCRYPT_ERROR (SYMCRYPT_CALL * PSYMCRYPT_KMAC_EXPAND_KEY_EX)
(SCOSSL_KMAC_EXPANDED_KEY *pExpandedKey, PCBYTE pbKey, SIZE_T cbKey,
PCBYTE pbCustomizationString, SIZE_T cbCustomizationString);
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_KMAC_RESULT_EX) (SCOSSL_KMAC_STATE *pState, PVOID pbResult, SIZE_T cbResult);
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_KMAC_EXTRACT) (SCOSSL_KMAC_STATE *pState, PVOID pbOutput, SIZE_T cbOutput, BOOLEAN bWipe);
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_KMAC_KEY_COPY) (SCOSSL_KMAC_EXPANDED_KEY *pSrc, SCOSSL_KMAC_EXPANDED_KEY *pDst);
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_KMAC_STATE_COPY) (SCOSSL_KMAC_STATE *pSrc, SCOSSL_KMAC_STATE *pDst);
typedef struct
{
PSYMCRYPT_KMAC_EXPAND_KEY_EX expandKeyExFunc;
PSYMCRYPT_KMAC_RESULT_EX resultExFunc;
PSYMCRYPT_KMAC_EXTRACT extractFunc;
PSYMCRYPT_KMAC_KEY_COPY keyCopyFunc;
PSYMCRYPT_KMAC_STATE_COPY stateCopyFunc;
SIZE_T blockSize;
} SCOSSL_KMAC_EXTENSIONS;
const SCOSSL_KMAC_EXTENSIONS SymCryptKmac128AlgorithmEx = {
(PSYMCRYPT_KMAC_EXPAND_KEY_EX) SymCryptKmac128ExpandKeyEx,
(PSYMCRYPT_KMAC_RESULT_EX) SymCryptKmac128ResultEx,
(PSYMCRYPT_KMAC_EXTRACT) SymCryptKmac128Extract,
(PSYMCRYPT_KMAC_KEY_COPY) SymCryptKmac128KeyCopy,
(PSYMCRYPT_KMAC_STATE_COPY) SymCryptKmac128StateCopy,
SYMCRYPT_KMAC128_INPUT_BLOCK_SIZE
};
const SCOSSL_KMAC_EXTENSIONS SymCryptKmac256AlgorithmEx = {
(PSYMCRYPT_KMAC_EXPAND_KEY_EX) SymCryptKmac256ExpandKeyEx,
(PSYMCRYPT_KMAC_RESULT_EX) SymCryptKmac256ResultEx,
(PSYMCRYPT_KMAC_EXTRACT) SymCryptKmac256Extract,
(PSYMCRYPT_KMAC_KEY_COPY) SymCryptKmac256KeyCopy,
(PSYMCRYPT_KMAC_STATE_COPY) SymCryptKmac256StateCopy,
SYMCRYPT_KMAC256_INPUT_BLOCK_SIZE
};
typedef struct
{
SCOSSL_KMAC_EXPANDED_KEY expandedKey;
SCOSSL_KMAC_STATE macState;
PCSYMCRYPT_MAC pMac;
const SCOSSL_KMAC_EXTENSIONS *pMacEx;
int xofMode;
SIZE_T cbOutput;
BYTE customizationString[KMAC_MAX_CUSTOM];
SIZE_T cbCustomizationString;
} SCOSSL_KMAC_CTX;
static const OSSL_PARAM p_scossl_kmac_ctx_gettable_param_types[] = {
OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL),
OSSL_PARAM_END};
static const OSSL_PARAM p_scossl_kmac_ctx_settable_param_types[] = {
OSSL_PARAM_int(OSSL_MAC_PARAM_XOF, NULL),
OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, NULL, 0),
OSSL_PARAM_END};
static SCOSSL_STATUS p_scossl_kmac_set_ctx_params(_Inout_ SCOSSL_KMAC_CTX *ctx, _In_ const OSSL_PARAM params[]);
static SCOSSL_KMAC_CTX *p_scossl_kmac128_newctx(ossl_unused void *provctx)
{
SCOSSL_COMMON_ALIGNED_ALLOC(ctx, OPENSSL_zalloc, SCOSSL_KMAC_CTX);
if (ctx != NULL)
{
ctx->pMac = SymCryptKmac128Algorithm;
ctx->pMacEx = &SymCryptKmac128AlgorithmEx;
ctx->cbOutput = ctx->pMac->resultSize;
}
return ctx;
}
static SCOSSL_KMAC_CTX *p_scossl_kmac256_newctx(ossl_unused void *provctx)
{
SCOSSL_COMMON_ALIGNED_ALLOC(ctx, OPENSSL_zalloc, SCOSSL_KMAC_CTX);
if (ctx != NULL)
{
ctx->pMac = SymCryptKmac256Algorithm;
ctx->pMacEx = &SymCryptKmac256AlgorithmEx;
ctx->cbOutput = ctx->pMac->resultSize;
}
return ctx;
}
static void p_scossl_kmac_freectx(_Inout_ SCOSSL_KMAC_CTX *ctx)
{
if (ctx == NULL)
return;
SCOSSL_COMMON_ALIGNED_FREE(ctx, OPENSSL_clear_free, SCOSSL_KMAC_CTX);
}
static SCOSSL_KMAC_CTX *p_scossl_kmac_dupctx(_In_ SCOSSL_KMAC_CTX *ctx)
{
SCOSSL_COMMON_ALIGNED_ALLOC(copyCtx, OPENSSL_zalloc, SCOSSL_KMAC_CTX);
if (copyCtx == NULL)
{
return NULL;
}
copyCtx->pMac = ctx->pMac;
copyCtx->pMacEx = ctx->pMacEx;
ctx->pMacEx->keyCopyFunc(&ctx->expandedKey, &copyCtx->expandedKey);
ctx->pMacEx->stateCopyFunc(&ctx->macState, &copyCtx->macState);
if (ctx->cbCustomizationString > 0)
{
memcpy(copyCtx->customizationString, ctx->customizationString, ctx->cbCustomizationString);
copyCtx->cbCustomizationString = ctx->cbCustomizationString;
}
copyCtx->cbOutput = ctx->cbOutput;
copyCtx->xofMode = ctx->xofMode;
return ctx;
}
static SCOSSL_STATUS p_scossl_kmac_init(_Inout_ SCOSSL_KMAC_CTX *ctx,
_In_reads_bytes_opt_(keylen) unsigned char *key, size_t keylen,
_In_ const OSSL_PARAM params[])
{
if (!p_scossl_kmac_set_ctx_params(ctx, params))
{
return SCOSSL_FAILURE;
}
if (key != NULL &&
ctx->pMacEx->expandKeyExFunc(
&ctx->expandedKey,
key, keylen,
ctx->customizationString, ctx->cbCustomizationString) != SYMCRYPT_NO_ERROR)
{
return SCOSSL_FAILURE;
}
ctx->pMac->initFunc(&ctx->macState, &ctx->expandedKey);
return SCOSSL_SUCCESS;
}
static SCOSSL_STATUS p_scossl_kmac_update(_Inout_ SCOSSL_KMAC_CTX *ctx,
_In_reads_bytes_(inl) const unsigned char *in, size_t inl)
{
ctx->pMac->appendFunc(&ctx->macState, in, inl);
return SCOSSL_SUCCESS;
}
static SCOSSL_STATUS p_scossl_kmac_final(_Inout_ SCOSSL_KMAC_CTX *ctx,
_Out_writes_bytes_(*outl) char *out, _Out_ size_t *outl, size_t outsize)
{
if (out != NULL)
{
if (outsize < ctx->cbOutput)
{
return SCOSSL_FAILURE;
}
if (ctx->xofMode)
{
ctx->pMacEx->extractFunc(&ctx->macState, out, ctx->cbOutput, TRUE);
}
else
{
ctx->pMacEx->resultExFunc(&ctx->macState, out, ctx->cbOutput);
}
}
*outl = ctx->cbOutput;
return SCOSSL_SUCCESS;
}
static const OSSL_PARAM *p_scossl_kmac_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
{
return p_scossl_kmac_ctx_gettable_param_types;
}
static const OSSL_PARAM *p_scossl_kmac_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
{
return p_scossl_kmac_ctx_settable_param_types;
}
static SCOSSL_STATUS p_scossl_kmac_get_ctx_params(_In_ SCOSSL_KMAC_CTX *ctx, _Inout_ OSSL_PARAM params[])
{
OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL &&
!OSSL_PARAM_set_size_t(p, ctx->cbOutput))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_BLOCK_SIZE)) != NULL &&
(ctx->pMacEx == NULL || !OSSL_PARAM_set_size_t(p, ctx->pMacEx ->blockSize)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
return SCOSSL_SUCCESS;
}
static SCOSSL_STATUS p_scossl_kmac_set_ctx_params(_Inout_ SCOSSL_KMAC_CTX *ctx, _In_ const OSSL_PARAM params[])
{
const OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_XOF)) != NULL &&
!OSSL_PARAM_get_int(p, &ctx->xofMode))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL)
{
SIZE_T cbOutput = 0;
if (!OSSL_PARAM_get_size_t(p, &cbOutput))
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH);
return SCOSSL_FAILURE;
}
if (cbOutput > KMAC_MAX_OUTPUT_LEN)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
ctx->cbOutput = cbOutput;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM)) != NULL)
{
PCBYTE pbCustomizationString;
SIZE_T cbCustomizationString;
if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **) &pbCustomizationString, &cbCustomizationString))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
if (cbCustomizationString > KMAC_MAX_CUSTOM)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
return 0;
}
OPENSSL_cleanse(ctx->customizationString, ctx->cbCustomizationString);
memcpy(ctx->customizationString, pbCustomizationString, cbCustomizationString);
ctx->cbCustomizationString = cbCustomizationString;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL)
{
PCBYTE pbMacKey;
SIZE_T cbMacKey;
if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pbMacKey, &cbMacKey) ||
ctx->pMacEx->expandKeyExFunc(&ctx->expandedKey,
pbMacKey, cbMacKey,
ctx->customizationString, ctx->cbCustomizationString) != SYMCRYPT_NO_ERROR)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
ctx->pMac->initFunc(&ctx->macState, &ctx->expandedKey);
}
return SCOSSL_SUCCESS;
}
const OSSL_DISPATCH p_scossl_kmac128_functions[] = {
{OSSL_FUNC_MAC_NEWCTX, (void (*)(void))p_scossl_kmac128_newctx},
{OSSL_FUNC_MAC_FREECTX, (void (*)(void))p_scossl_kmac_freectx},
{OSSL_FUNC_MAC_DUPCTX, (void (*)(void))p_scossl_kmac_dupctx},
{OSSL_FUNC_MAC_INIT, (void (*)(void))p_scossl_kmac_init},
{OSSL_FUNC_MAC_UPDATE, (void (*)(void))p_scossl_kmac_update},
{OSSL_FUNC_MAC_FINAL, (void (*)(void))p_scossl_kmac_final},
{OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_kmac_gettable_ctx_params},
{OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_kmac_settable_ctx_params},
{OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))p_scossl_kmac_get_ctx_params},
{OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))p_scossl_kmac_set_ctx_params},
{0, NULL}};
const OSSL_DISPATCH p_scossl_kmac256_functions[] = {
{OSSL_FUNC_MAC_NEWCTX, (void (*)(void))p_scossl_kmac256_newctx},
{OSSL_FUNC_MAC_FREECTX, (void (*)(void))p_scossl_kmac_freectx},
{OSSL_FUNC_MAC_DUPCTX, (void (*)(void))p_scossl_kmac_dupctx},
{OSSL_FUNC_MAC_INIT, (void (*)(void))p_scossl_kmac_init},
{OSSL_FUNC_MAC_UPDATE, (void (*)(void))p_scossl_kmac_update},
{OSSL_FUNC_MAC_FINAL, (void (*)(void))p_scossl_kmac_final},
{OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_kmac_gettable_ctx_params},
{OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_kmac_settable_ctx_params},
{OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))p_scossl_kmac_get_ctx_params},
{OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))p_scossl_kmac_set_ctx_params},
{0, NULL}};
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -89,10 +89,16 @@ static const OSSL_ALGORITHM p_scossl_cipher[] = {
ALG_TABLE_END};
// MAC
extern const OSSL_DISPATCH p_scossl_cmac_functions[];
extern const OSSL_DISPATCH p_scossl_hmac_functions[];
extern const OSSL_DISPATCH p_scossl_kmac128_functions[];
extern const OSSL_DISPATCH p_scossl_kmac256_functions[];
static const OSSL_ALGORITHM p_scossl_mac[] = {
// ALG("HMAC", p_scossl_hmac_functions),
ALG("CMAC", p_scossl_cmac_functions),
ALG("HMAC", p_scossl_hmac_functions),
ALG("KMAC-128:KMAC128:2.16.840.1.101.3.4.2.19", p_scossl_kmac128_functions),
ALG("KMAC-256:KMAC256:2.16.840.1.101.3.4.2.20", p_scossl_kmac256_functions),
ALG_TABLE_END};
// KDF