Provider KDF (#65)
* Stub KDF functions * HKDF implementation * Provider SSH KDF * Fix engine publiuc header property * Provider TLS1-PRF * Cleanup * OpenSSL 1.1.1 engine build compatability * Use common hash fetching for RSA * Address PR comments * Correct MAC related error logging * PR comments * PR comments * Minor cleanup
This commit is contained in:
Родитель
8ee9ee42c9
Коммит
7abafd80a9
|
@ -12,7 +12,10 @@ set(SCOSSL_SOURCES
|
|||
./src/scossl_helpers.c
|
||||
./src/scossl_aes_aead.c
|
||||
./src/scossl_ecc.c
|
||||
./src/scossl_hkdf.c
|
||||
./src/scossl_rsa.c
|
||||
./src/scossl_sshkdf.c
|
||||
./src/scossl_tls1prf.c
|
||||
)
|
||||
|
||||
add_library(scossl_common STATIC ${SCOSSL_SOURCES})
|
||||
|
|
|
@ -239,6 +239,15 @@ void _scossl_log_SYMCRYPT_ERROR(
|
|||
#define SCOSSL_LOG_SYMCRYPT_ERROR(func_code, reason_code, description, scError) \
|
||||
_scossl_log_SYMCRYPT_ERROR(SCOSSL_LOG_LEVEL_ERROR, func_code, reason_code, __FILE__, __LINE__, description, scError)
|
||||
|
||||
//
|
||||
// Common helper functions
|
||||
//
|
||||
|
||||
// Functions for converting OpenSSL types to their SymCrypt equivalent
|
||||
BOOL scossl_is_md_supported(int mdnid);
|
||||
PCSYMCRYPT_MAC scossl_get_symcrypt_hmac_algorithm(int mdnid);
|
||||
PCSYMCRYPT_HASH scossl_get_symcrypt_hash_algorithm(int mdnid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_helpers.h"
|
||||
|
||||
#include <openssl/kdf.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HKDF_MAXBUF 1024
|
||||
|
||||
// These macros were renamed in OpenSSL 3. Common implementation
|
||||
// uses the new names. This mapping from new to old names is
|
||||
// needed until OpenSSL 1.1.1 builds are no longer needed.
|
||||
#ifndef EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND
|
||||
#define EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND
|
||||
#endif
|
||||
|
||||
#ifndef EVP_KDF_HKDF_MODE_EXTRACT_ONLY
|
||||
#define EVP_KDF_HKDF_MODE_EXTRACT_ONLY EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY
|
||||
#endif
|
||||
|
||||
#ifndef EVP_KDF_HKDF_MODE_EXPAND_ONLY
|
||||
#define EVP_KDF_HKDF_MODE_EXPAND_ONLY EVP_PKEY_HKDEF_MODE_EXPAND_ONLY
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int mode;
|
||||
EVP_MD *md;
|
||||
PBYTE pbSalt;
|
||||
SIZE_T cbSalt;
|
||||
PBYTE pbKey;
|
||||
SIZE_T cbKey;
|
||||
BYTE info[HKDF_MAXBUF];
|
||||
SIZE_T cbInfo;
|
||||
} SCOSSL_HKDF_CTX;
|
||||
|
||||
SCOSSL_HKDF_CTX *scossl_hkdf_newctx();
|
||||
SCOSSL_HKDF_CTX *scossl_hkdf_dupctx(_In_ SCOSSL_HKDF_CTX *ctx);
|
||||
void scossl_hkdf_freectx(_Inout_ SCOSSL_HKDF_CTX *ctx);
|
||||
|
||||
SCOSSL_STATUS scossl_hkdf_reset(_Inout_ SCOSSL_HKDF_CTX *ctx);
|
||||
|
||||
SCOSSL_STATUS scossl_hkdf_append_info(_Inout_ SCOSSL_HKDF_CTX *ctx,
|
||||
_In_reads_bytes_(cbInfo) PCBYTE pbInfo, SIZE_T cbInfo);
|
||||
|
||||
SCOSSL_STATUS scossl_hkdf_derive(_In_ SCOSSL_HKDF_CTX *ctx,
|
||||
_Out_writes_bytes_(keylen) PBYTE key, SIZE_T keylen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_helpers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SSH_KDF_MAX_DIGEST_SIZE (512 / 8)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PCSYMCRYPT_HASH pHash;
|
||||
PBYTE pbKey;
|
||||
SIZE_T cbKey;
|
||||
BYTE hashValue[SSH_KDF_MAX_DIGEST_SIZE];
|
||||
SIZE_T cbHashValue;
|
||||
BYTE sessionId[SSH_KDF_MAX_DIGEST_SIZE];
|
||||
SIZE_T cbSessionId;
|
||||
BYTE label;
|
||||
} SCOSSL_SSHKDF_CTX;
|
||||
|
||||
SCOSSL_SSHKDF_CTX *scossl_sshkdf_newctx();
|
||||
SCOSSL_SSHKDF_CTX *scossl_sshkdf_dupctx(_In_ SCOSSL_SSHKDF_CTX *ctx);
|
||||
void scossl_sshkdf_freectx(_Inout_ SCOSSL_SSHKDF_CTX *ctx);
|
||||
|
||||
SCOSSL_STATUS scossl_sshkdf_reset(_Inout_ SCOSSL_SSHKDF_CTX *ctx);
|
||||
|
||||
SCOSSL_STATUS scossl_sshkdf_derive(_In_ SCOSSL_SSHKDF_CTX *ctx,
|
||||
_Out_writes_bytes_(keylen) PBYTE key, SIZE_T keylen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_helpers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TLS1_PRF_MAXBUF 1024
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL isTlsPrf1_1;
|
||||
PCSYMCRYPT_MAC pHmac;
|
||||
PBYTE pbSecret;
|
||||
SIZE_T cbSecret;
|
||||
BYTE seed[TLS1_PRF_MAXBUF];
|
||||
SIZE_T cbSeed;
|
||||
} SCOSSL_TLS1_PRF_CTX;
|
||||
|
||||
SCOSSL_TLS1_PRF_CTX *scossl_tls1prf_newctx();
|
||||
SCOSSL_TLS1_PRF_CTX *scossl_tls1prf_dupctx(_In_ SCOSSL_TLS1_PRF_CTX *ctx);
|
||||
void scossl_tls1prf_freectx(_Inout_ SCOSSL_TLS1_PRF_CTX *ctx);
|
||||
SCOSSL_STATUS scossl_tls1prf_reset(_Inout_ SCOSSL_TLS1_PRF_CTX *ctx);
|
||||
|
||||
SCOSSL_STATUS scossl_tls1prf_append_seed(_Inout_ SCOSSL_TLS1_PRF_CTX *ctx,
|
||||
_In_reads_bytes_(cbSeed) PCBYTE pbSeed, SIZE_T cbSeed);
|
||||
|
||||
SCOSSL_STATUS scossl_tls1prf_derive(_In_ SCOSSL_TLS1_PRF_CTX *ctx,
|
||||
_Out_writes_bytes_(keylen) PBYTE key, SIZE_T keylen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -67,7 +67,7 @@ static ERR_STRING_DATA SCOSSL_ERR_function_strings[] = {
|
|||
{ERR_PACK(0, SCOSSL_ERR_F_GET_DH_CONTEXT_EX, 0), "scossl_get_dh_context_ex"},
|
||||
{ERR_PACK(0, SCOSSL_ERR_F_GET_ECC_CONTEXT_EX, 0), "scossl_get_ecc_context_ex"},
|
||||
{ERR_PACK(0, SCOSSL_ERR_F_GET_SYMCRYPT_HASH_ALGORITHM, 0), "scossl_get_symcrypt_hash_algorithm"},
|
||||
{ERR_PACK(0, SCOSSL_ERR_F_GET_SYMCRYPT_MAC_ALGORITHM, 0), "scossl_get_symcrypt_mac_algorithm"},
|
||||
{ERR_PACK(0, SCOSSL_ERR_F_GET_SYMCRYPT_MAC_ALGORITHM, 0), "scossl_get_symcrypt_hmac_algorithm"},
|
||||
{ERR_PACK(0, SCOSSL_ERR_F_HKDF_CTRL, 0), "scossl_hkdf_ctrl"},
|
||||
{ERR_PACK(0, SCOSSL_ERR_F_HKDF_DERIVE, 0), "scossl_hkdf_derive"},
|
||||
{ERR_PACK(0, SCOSSL_ERR_F_HKDF_INIT, 0), "scossl_hkdf_init"},
|
||||
|
@ -394,6 +394,74 @@ void _scossl_log_SYMCRYPT_ERROR(
|
|||
_scossl_log(trace_level, func_code, reason_code, file, line, "%s - %s (0x%x)", description, scErrorString, scError);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
BOOL scossl_is_md_supported(int mdnid)
|
||||
{
|
||||
switch (mdnid)
|
||||
{
|
||||
case NID_sha1:
|
||||
case NID_sha256:
|
||||
case NID_sha384:
|
||||
case NID_sha512:
|
||||
case NID_sha3_256:
|
||||
case NID_sha3_384:
|
||||
case NID_sha3_512:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
PCSYMCRYPT_MAC scossl_get_symcrypt_hmac_algorithm(int mdnid)
|
||||
{
|
||||
switch(mdnid)
|
||||
{
|
||||
case NID_sha1:
|
||||
return SymCryptHmacSha1Algorithm;
|
||||
case NID_sha256:
|
||||
return SymCryptHmacSha256Algorithm;
|
||||
case NID_sha384:
|
||||
return SymCryptHmacSha384Algorithm;
|
||||
case NID_sha512:
|
||||
return SymCryptHmacSha512Algorithm;
|
||||
case NID_sha3_256:
|
||||
return SymCryptHmacSha3_256Algorithm;
|
||||
case NID_sha3_384:
|
||||
return SymCryptHmacSha3_384Algorithm;
|
||||
case NID_sha3_512:
|
||||
return SymCryptHmacSha3_512Algorithm;
|
||||
}
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_GET_SYMCRYPT_MAC_ALGORITHM, SCOSSL_ERR_R_NOT_IMPLEMENTED,
|
||||
"SymCrypt-OpenSSL does not support hmac algorithm %d", mdnid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
PCSYMCRYPT_HASH scossl_get_symcrypt_hash_algorithm(int mdnid)
|
||||
{
|
||||
switch (mdnid)
|
||||
{
|
||||
case NID_sha1:
|
||||
return SymCryptSha1Algorithm;
|
||||
case NID_sha256:
|
||||
return SymCryptSha256Algorithm;
|
||||
case NID_sha384:
|
||||
return SymCryptSha384Algorithm;
|
||||
case NID_sha512:
|
||||
return SymCryptSha512Algorithm;
|
||||
case NID_sha3_256:
|
||||
return SymCryptSha3_256Algorithm;
|
||||
case NID_sha3_384:
|
||||
return SymCryptSha3_384Algorithm;
|
||||
case NID_sha3_512:
|
||||
return SymCryptSha3_512Algorithm;
|
||||
}
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_GET_SYMCRYPT_HASH_ALGORITHM, SCOSSL_ERR_R_NOT_IMPLEMENTED,
|
||||
"SymCrypt-OpenSSL does not support hash algorithm %d", mdnid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_hkdf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SCOSSL_HKDF_CTX *scossl_hkdf_newctx()
|
||||
{
|
||||
return OPENSSL_zalloc(sizeof(SCOSSL_HKDF_CTX));
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_HKDF_CTX *scossl_hkdf_dupctx(SCOSSL_HKDF_CTX *ctx)
|
||||
{
|
||||
SCOSSL_HKDF_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_HKDF_CTX));
|
||||
if (copyCtx != NULL)
|
||||
{
|
||||
if (ctx->pbSalt == NULL)
|
||||
{
|
||||
copyCtx->pbSalt = NULL;
|
||||
}
|
||||
else if ((copyCtx->pbSalt = OPENSSL_memdup(ctx->pbSalt, ctx->cbSalt)) == NULL)
|
||||
{
|
||||
scossl_hkdf_freectx(copyCtx);
|
||||
return NULL;
|
||||
}
|
||||
copyCtx->cbSalt = ctx->cbSalt;
|
||||
|
||||
if (ctx->pbKey == NULL)
|
||||
{
|
||||
copyCtx->pbKey = NULL;
|
||||
}
|
||||
else if ((copyCtx->pbKey = OPENSSL_memdup(ctx->pbKey, ctx->cbKey)) == NULL)
|
||||
{
|
||||
scossl_hkdf_freectx(copyCtx);
|
||||
return NULL;
|
||||
}
|
||||
copyCtx->cbKey = ctx->cbKey;
|
||||
|
||||
copyCtx->md = ctx->md;
|
||||
copyCtx->mode = ctx->mode;
|
||||
copyCtx->cbInfo = ctx->cbInfo;
|
||||
memcpy(copyCtx->info, ctx->info, ctx->cbInfo);
|
||||
}
|
||||
|
||||
return copyCtx;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
void scossl_hkdf_freectx(SCOSSL_HKDF_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
OPENSSL_clear_free(ctx->pbSalt, ctx->cbSalt);
|
||||
OPENSSL_clear_free(ctx->pbKey, ctx->cbKey);
|
||||
OPENSSL_cleanse(ctx->info, ctx->cbInfo);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS scossl_hkdf_reset(SCOSSL_HKDF_CTX *ctx)
|
||||
{
|
||||
OPENSSL_clear_free(ctx->pbSalt, ctx->cbSalt);
|
||||
OPENSSL_clear_free(ctx->pbKey, ctx->cbKey);
|
||||
OPENSSL_cleanse(ctx, sizeof(*ctx));
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS scossl_hkdf_append_info(SCOSSL_HKDF_CTX *ctx,
|
||||
PCBYTE pbInfo, SIZE_T cbInfo)
|
||||
{
|
||||
if (cbInfo > HKDF_MAXBUF - ctx->cbInfo)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(ctx->info + ctx->cbInfo, pbInfo, cbInfo);
|
||||
ctx->cbInfo += cbInfo;
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS scossl_hkdf_derive(SCOSSL_HKDF_CTX *ctx,
|
||||
PBYTE key, SIZE_T keylen)
|
||||
{
|
||||
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
|
||||
PCSYMCRYPT_MAC symcryptHmacAlg = NULL;
|
||||
SYMCRYPT_HKDF_EXPANDED_KEY scExpandedKey;
|
||||
|
||||
if (ctx->md == NULL)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Digest");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (ctx->pbKey == NULL)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Key");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
symcryptHmacAlg = scossl_get_symcrypt_hmac_algorithm(EVP_MD_type(ctx->md));
|
||||
if (symcryptHmacAlg == NULL)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
switch (ctx->mode)
|
||||
{
|
||||
case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
|
||||
scError = SymCryptHkdf(
|
||||
symcryptHmacAlg,
|
||||
ctx->pbKey, ctx->cbKey,
|
||||
ctx->pbSalt, ctx->cbSalt,
|
||||
ctx->info, ctx->cbInfo,
|
||||
key, keylen);
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
break;
|
||||
case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
|
||||
scError = SymCryptHkdfExtractPrk(
|
||||
symcryptHmacAlg,
|
||||
ctx->pbKey, ctx->cbKey,
|
||||
ctx->pbSalt, ctx->cbSalt,
|
||||
key, keylen);
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
break;
|
||||
case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
|
||||
scError = SymCryptHkdfPrkExpandKey(
|
||||
&scExpandedKey,
|
||||
symcryptHmacAlg,
|
||||
ctx->pbKey, ctx->cbKey);
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
scError = SymCryptHkdfDerive(
|
||||
&scExpandedKey,
|
||||
ctx->info, ctx->cbInfo,
|
||||
key, keylen);
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Invalid Mode: %d", ctx->mode);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -64,30 +64,6 @@ static const SCOSSL_RSA_PKCS1_PARAMS *scossl_get_rsa_pkcs1_params(int mdnid)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static PCSYMCRYPT_HASH scossl_get_symcrypt_hash_algorithm(int mdnid)
|
||||
{
|
||||
switch (mdnid)
|
||||
{
|
||||
case NID_md5:
|
||||
return SymCryptMd5Algorithm;
|
||||
case NID_sha1:
|
||||
return SymCryptSha1Algorithm;
|
||||
case NID_sha256:
|
||||
return SymCryptSha256Algorithm;
|
||||
case NID_sha384:
|
||||
return SymCryptSha384Algorithm;
|
||||
case NID_sha512:
|
||||
return SymCryptSha512Algorithm;
|
||||
case NID_sha3_256:
|
||||
return SymCryptSha3_256Algorithm;
|
||||
case NID_sha3_384:
|
||||
return SymCryptSha3_384Algorithm;
|
||||
case NID_sha3_512:
|
||||
return SymCryptSha3_512Algorithm;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SIZE_T scossl_get_expected_hash_length(int mdnid)
|
||||
{
|
||||
switch (mdnid)
|
||||
|
@ -196,15 +172,15 @@ SCOSSL_STATUS scossl_rsa_pkcs1_sign(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid,
|
|||
{
|
||||
case NID_md5_sha1:
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSA_SIGN, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm MD5+SHA1 which is not FIPS compliant");
|
||||
"Using Hmac algorithm MD5+SHA1 which is not FIPS compliant");
|
||||
break;
|
||||
case NID_md5:
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSA_SIGN, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm MD5 which is not FIPS compliant");
|
||||
"Using Hmac algorithm MD5 which is not FIPS compliant");
|
||||
break;
|
||||
case NID_sha1:
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSA_SIGN, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm SHA1 which is not FIPS compliant");
|
||||
"Using Hmac algorithm SHA1 which is not FIPS compliant");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -258,15 +234,15 @@ SCOSSL_STATUS scossl_rsa_pkcs1_verify(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid,
|
|||
{
|
||||
case NID_md5_sha1:
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSA_VERIFY, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm MD5+SHA1 which is not FIPS compliant");
|
||||
"Using Hmac algorithm MD5+SHA1 which is not FIPS compliant");
|
||||
break;
|
||||
case NID_md5:
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSA_VERIFY, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm MD5 which is not FIPS compliant");
|
||||
"Using Hmac algorithm MD5 which is not FIPS compliant");
|
||||
break;
|
||||
case NID_sha1:
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSA_VERIFY, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm SHA1 which is not FIPS compliant");
|
||||
"Using Hmac algorithm SHA1 which is not FIPS compliant");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -363,12 +339,12 @@ SCOSSL_STATUS scossl_rsapss_sign(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cbSa
|
|||
if (mdnid == NID_md5)
|
||||
{
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSAPSS_SIGN, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm MD5 which is not FIPS compliant");
|
||||
"Using Hmac algorithm MD5 which is not FIPS compliant");
|
||||
}
|
||||
else if (mdnid == NID_sha1)
|
||||
{
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSAPSS_SIGN, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm SHA1 which is not FIPS compliant");
|
||||
"Using Hmac algorithm SHA1 which is not FIPS compliant");
|
||||
}
|
||||
|
||||
if (cbHashValue != expectedHashLength)
|
||||
|
@ -458,12 +434,12 @@ SCOSSL_STATUS scossl_rsapss_verify(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cb
|
|||
if (mdnid == NID_md5)
|
||||
{
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSAPSS_VERIFY, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm MD5 which is not FIPS compliant");
|
||||
"Using Hmac algorithm MD5 which is not FIPS compliant");
|
||||
}
|
||||
else if (mdnid == NID_sha1)
|
||||
{
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSAPSS_VERIFY, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm SHA1 which is not FIPS compliant");
|
||||
"Using Hmac algorithm SHA1 which is not FIPS compliant");
|
||||
}
|
||||
|
||||
scError = SymCryptRsaPssVerify(
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_sshkdf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_SSHKDF_CTX *scossl_sshkdf_newctx()
|
||||
{
|
||||
return OPENSSL_zalloc(sizeof(SCOSSL_SSHKDF_CTX));
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_SSHKDF_CTX *scossl_sshkdf_dupctx(SCOSSL_SSHKDF_CTX *ctx)
|
||||
{
|
||||
SCOSSL_SSHKDF_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_SSHKDF_CTX));
|
||||
|
||||
if (copyCtx != NULL)
|
||||
{
|
||||
*copyCtx = *ctx;
|
||||
copyCtx->pbKey = NULL;
|
||||
|
||||
if (ctx->pbKey != NULL &&
|
||||
(copyCtx->pbKey = OPENSSL_memdup(ctx->pbKey, ctx->cbKey)) == NULL)
|
||||
{
|
||||
scossl_sshkdf_freectx(copyCtx);
|
||||
copyCtx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return copyCtx;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
void scossl_sshkdf_freectx(SCOSSL_SSHKDF_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
OPENSSL_clear_free(ctx->pbKey, ctx->cbKey);
|
||||
OPENSSL_cleanse(ctx->hashValue, sizeof(ctx->hashValue));
|
||||
OPENSSL_cleanse(ctx->sessionId, sizeof(ctx->sessionId));
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS scossl_sshkdf_reset(SCOSSL_SSHKDF_CTX *ctx)
|
||||
{
|
||||
OPENSSL_clear_free(ctx->pbKey, ctx->cbKey);
|
||||
OPENSSL_cleanse(ctx, sizeof(*ctx));
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS scossl_sshkdf_derive(SCOSSL_SSHKDF_CTX *ctx,
|
||||
PBYTE key, SIZE_T keylen)
|
||||
{
|
||||
SYMCRYPT_ERROR scError;
|
||||
|
||||
if (!ctx->pHash ||
|
||||
ctx->cbHashValue == 0)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_SSHKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Digest");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (!ctx->pbKey)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_SSHKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Key");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (ctx->cbSessionId == 0)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_SSHKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Session ID");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (ctx->label == 0)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_SSHKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Label");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
scError = SymCryptSshKdf(
|
||||
ctx->pHash,
|
||||
ctx->pbKey, ctx->cbKey,
|
||||
ctx->hashValue, ctx->cbHashValue,
|
||||
ctx->label,
|
||||
ctx->sessionId, ctx->cbSessionId,
|
||||
key, keylen);
|
||||
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,130 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_tls1prf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SCOSSL_TLS1_PRF_CTX *scossl_tls1prf_newctx()
|
||||
{
|
||||
return OPENSSL_zalloc(sizeof(SCOSSL_TLS1_PRF_CTX));
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_TLS1_PRF_CTX *scossl_tls1prf_dupctx(SCOSSL_TLS1_PRF_CTX *ctx)
|
||||
{
|
||||
SCOSSL_TLS1_PRF_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_TLS1_PRF_CTX));
|
||||
if (copyCtx != NULL)
|
||||
{
|
||||
if (ctx->pbSecret == NULL)
|
||||
{
|
||||
copyCtx->pbSecret = NULL;
|
||||
}
|
||||
else if ((copyCtx->pbSecret = OPENSSL_memdup(ctx->pbSecret, ctx->cbSecret)) == NULL)
|
||||
{
|
||||
scossl_tls1prf_freectx(copyCtx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
copyCtx->isTlsPrf1_1 = ctx->isTlsPrf1_1;
|
||||
copyCtx->pHmac = ctx->pHmac;
|
||||
copyCtx->cbSecret = ctx->cbSecret;
|
||||
copyCtx->cbSeed = ctx->cbSeed;
|
||||
memcpy(copyCtx->seed, ctx->seed, ctx->cbSeed);
|
||||
}
|
||||
|
||||
return copyCtx;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
void scossl_tls1prf_freectx(SCOSSL_TLS1_PRF_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
OPENSSL_clear_free(ctx->pbSecret, ctx->cbSecret);
|
||||
OPENSSL_cleanse(ctx->seed, ctx->cbSeed);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS scossl_tls1prf_reset(SCOSSL_TLS1_PRF_CTX *ctx)
|
||||
{
|
||||
OPENSSL_clear_free(ctx->pbSecret, ctx->cbSecret);
|
||||
OPENSSL_cleanse(ctx, sizeof(*ctx));
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS scossl_tls1prf_append_seed(SCOSSL_TLS1_PRF_CTX *ctx,
|
||||
PCBYTE pbSeed, SIZE_T cbSeed)
|
||||
{
|
||||
if (cbSeed > TLS1_PRF_MAXBUF - ctx->cbSeed )
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(ctx->seed + ctx->cbSeed, pbSeed, cbSeed);
|
||||
ctx->cbSeed += cbSeed;
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS scossl_tls1prf_derive(SCOSSL_TLS1_PRF_CTX *ctx,
|
||||
PBYTE key, SIZE_T keylen)
|
||||
{
|
||||
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
|
||||
|
||||
if (ctx->pbSecret == NULL)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_TLS1PRF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Secret");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (ctx->isTlsPrf1_1)
|
||||
{
|
||||
// Special case to use TlsPrf1_1 to handle md5_sha1
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_TLS1PRF_DERIVE, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Hmac algorithm MD5+SHA1 which is not FIPS compliant");
|
||||
|
||||
scError = SymCryptTlsPrf1_1(
|
||||
ctx->pbSecret, ctx->cbSecret,
|
||||
NULL, 0,
|
||||
ctx->seed, ctx->cbSeed,
|
||||
key, keylen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctx->pHmac == NULL)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_TLS1PRF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Digest");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
scError = SymCryptTlsPrf1_2(
|
||||
ctx->pHmac,
|
||||
ctx->pbSecret, ctx->cbSecret,
|
||||
NULL, 0,
|
||||
ctx->seed, ctx->cbSeed,
|
||||
key, keylen);
|
||||
}
|
||||
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
SCOSSL_LOG_SYMCRYPT_ERROR(SCOSSL_ERR_F_TLS1PRF_DERIVE, SCOSSL_ERR_R_SYMCRYPT_FAILURE,
|
||||
"SymCryptTlsPrf1_x failed", scError);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -39,7 +39,7 @@ endif()
|
|||
add_library(scossl_dynamic SHARED ${SCOSSL_SOURCES})
|
||||
add_dependencies(scossl_dynamic scossl_common)
|
||||
|
||||
set_target_properties(scossl_dynamic PROPERTIES PUBLIC_HEADER ../inc/scossl.h)
|
||||
set_target_properties(scossl_dynamic PROPERTIES PUBLIC_HEADER ../inc/e_scossl.h)
|
||||
# target_link_libraries(scossl_dynamic ${OPENSSL_CRYPTO_LIBRARY})
|
||||
target_include_directories(scossl_dynamic PUBLIC ../inc)
|
||||
target_include_directories(scossl_dynamic PRIVATE ../src)
|
||||
|
|
|
@ -2,31 +2,20 @@
|
|||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_hkdf.h"
|
||||
#include "e_scossl_hkdf.h"
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/kdf.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HKDF_MAXBUF 1024
|
||||
typedef struct {
|
||||
int mode;
|
||||
const EVP_MD *md;
|
||||
unsigned char *salt;
|
||||
size_t salt_len;
|
||||
unsigned char *key;
|
||||
size_t key_len;
|
||||
unsigned char info[HKDF_MAXBUF];
|
||||
size_t info_len;
|
||||
} SCOSSL_HKDF_PKEY_CTX;
|
||||
|
||||
|
||||
SCOSSL_STATUS e_scossl_hkdf_init(_Inout_ EVP_PKEY_CTX *ctx)
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS e_scossl_hkdf_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
SCOSSL_HKDF_PKEY_CTX *e_scossl_hkdf_context;
|
||||
if ((e_scossl_hkdf_context = OPENSSL_zalloc(sizeof(*e_scossl_hkdf_context))) == NULL) {
|
||||
SCOSSL_HKDF_CTX *e_scossl_hkdf_context;
|
||||
if ((e_scossl_hkdf_context = scossl_hkdf_newctx()) == NULL) {
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_INIT, ERR_R_MALLOC_FAILURE,
|
||||
"OPENSSL_zalloc returned NULL");
|
||||
return SCOSSL_FAILURE;
|
||||
|
@ -35,24 +24,23 @@ SCOSSL_STATUS e_scossl_hkdf_init(_Inout_ EVP_PKEY_CTX *ctx)
|
|||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
void e_scossl_hkdf_cleanup(_Inout_ EVP_PKEY_CTX *ctx)
|
||||
_Use_decl_annotations_
|
||||
void e_scossl_hkdf_cleanup(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
SCOSSL_HKDF_PKEY_CTX *e_scossl_hkdf_context = NULL;
|
||||
SCOSSL_HKDF_CTX *e_scossl_hkdf_context = NULL;
|
||||
|
||||
e_scossl_hkdf_context = (SCOSSL_HKDF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
if (e_scossl_hkdf_context == NULL) {
|
||||
e_scossl_hkdf_context = (SCOSSL_HKDF_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
if (e_scossl_hkdf_context == NULL)
|
||||
return;
|
||||
}
|
||||
OPENSSL_clear_free(e_scossl_hkdf_context->salt, e_scossl_hkdf_context->salt_len);
|
||||
OPENSSL_clear_free(e_scossl_hkdf_context->key, e_scossl_hkdf_context->key_len);
|
||||
OPENSSL_cleanse(e_scossl_hkdf_context->info, e_scossl_hkdf_context->info_len);
|
||||
OPENSSL_free(e_scossl_hkdf_context);
|
||||
|
||||
scossl_hkdf_freectx(e_scossl_hkdf_context);
|
||||
EVP_PKEY_CTX_set_data(ctx, NULL);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS e_scossl_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
SCOSSL_HKDF_PKEY_CTX *e_scossl_hkdf_context = (SCOSSL_HKDF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
SCOSSL_HKDF_CTX *e_scossl_hkdf_context = (SCOSSL_HKDF_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
switch (type) {
|
||||
case EVP_PKEY_CTRL_HKDF_MD:
|
||||
if (p2 == NULL)
|
||||
|
@ -67,31 +55,27 @@ SCOSSL_STATUS e_scossl_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
|||
return SCOSSL_SUCCESS;
|
||||
if (p1 < 0)
|
||||
return SCOSSL_FAILURE;
|
||||
if (e_scossl_hkdf_context->salt != NULL)
|
||||
OPENSSL_clear_free(e_scossl_hkdf_context->salt, e_scossl_hkdf_context->salt_len);
|
||||
e_scossl_hkdf_context->salt = OPENSSL_memdup(p2, p1);
|
||||
if (e_scossl_hkdf_context->salt == NULL)
|
||||
if (e_scossl_hkdf_context->pbSalt != NULL)
|
||||
OPENSSL_clear_free(e_scossl_hkdf_context->pbSalt, e_scossl_hkdf_context->cbSalt);
|
||||
e_scossl_hkdf_context->pbSalt = OPENSSL_memdup(p2, p1);
|
||||
if (e_scossl_hkdf_context->pbSalt == NULL)
|
||||
return SCOSSL_FAILURE;
|
||||
e_scossl_hkdf_context->salt_len = p1;
|
||||
e_scossl_hkdf_context->cbSalt = p1;
|
||||
return SCOSSL_SUCCESS;
|
||||
case EVP_PKEY_CTRL_HKDF_KEY:
|
||||
if (p1 < 0)
|
||||
return SCOSSL_FAILURE;
|
||||
if (e_scossl_hkdf_context->key != NULL)
|
||||
OPENSSL_clear_free(e_scossl_hkdf_context->key, e_scossl_hkdf_context->key_len);
|
||||
e_scossl_hkdf_context->key = OPENSSL_memdup(p2, p1);
|
||||
if (e_scossl_hkdf_context->key == NULL)
|
||||
if (e_scossl_hkdf_context->pbKey != NULL)
|
||||
OPENSSL_clear_free(e_scossl_hkdf_context->pbKey, e_scossl_hkdf_context->cbKey);
|
||||
e_scossl_hkdf_context->pbKey = OPENSSL_memdup(p2, p1);
|
||||
if (e_scossl_hkdf_context->pbKey == NULL)
|
||||
return SCOSSL_FAILURE;
|
||||
e_scossl_hkdf_context->key_len = p1;
|
||||
e_scossl_hkdf_context->cbKey = p1;
|
||||
return SCOSSL_SUCCESS;
|
||||
case EVP_PKEY_CTRL_HKDF_INFO:
|
||||
if (p1 == 0 || p2 == NULL)
|
||||
return SCOSSL_SUCCESS;
|
||||
if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - e_scossl_hkdf_context->info_len))
|
||||
return SCOSSL_FAILURE;
|
||||
memcpy(e_scossl_hkdf_context->info + e_scossl_hkdf_context->info_len, p2, p1);
|
||||
e_scossl_hkdf_context->info_len += p1;
|
||||
return SCOSSL_SUCCESS;
|
||||
return scossl_hkdf_append_info(e_scossl_hkdf_context, p2, p1);
|
||||
default:
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_CTRL, SCOSSL_ERR_R_NOT_IMPLEMENTED,
|
||||
"SymCrypt Engine does not support ctrl type (%d)", type);
|
||||
|
@ -99,16 +83,16 @@ SCOSSL_STATUS e_scossl_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
|||
}
|
||||
}
|
||||
|
||||
SCOSSL_STATUS e_scossl_hkdf_derive_init(_Inout_ EVP_PKEY_CTX *ctx)
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS e_scossl_hkdf_derive_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
SCOSSL_HKDF_PKEY_CTX *e_scossl_hkdf_context = (SCOSSL_HKDF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
OPENSSL_clear_free(e_scossl_hkdf_context->key, e_scossl_hkdf_context->key_len);
|
||||
OPENSSL_clear_free(e_scossl_hkdf_context->salt, e_scossl_hkdf_context->salt_len);
|
||||
OPENSSL_cleanse(e_scossl_hkdf_context->info, e_scossl_hkdf_context->info_len);
|
||||
memset(e_scossl_hkdf_context, 0, sizeof(*e_scossl_hkdf_context));
|
||||
return SCOSSL_SUCCESS;
|
||||
SCOSSL_HKDF_CTX *e_scossl_hkdf_context = (SCOSSL_HKDF_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
return scossl_hkdf_reset(e_scossl_hkdf_context);
|
||||
}
|
||||
|
||||
//
|
||||
// Default OpenSSL fallback functions
|
||||
//
|
||||
static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
|
||||
const unsigned char *salt, size_t salt_len,
|
||||
const unsigned char *key, size_t key_len,
|
||||
|
@ -206,140 +190,64 @@ static unsigned char *HKDF(const EVP_MD *evp_md,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static PCSYMCRYPT_MAC e_scossl_get_symcrypt_mac_algorithm( _In_ const EVP_MD *evp_md )
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS e_scossl_hkdf_derive(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *key, size_t *keylen)
|
||||
{
|
||||
int type = EVP_MD_type(evp_md);
|
||||
SCOSSL_HKDF_CTX *e_scossl_hkdf_context = (SCOSSL_HKDF_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
|
||||
if (type == NID_sha1)
|
||||
return SymCryptHmacSha1Algorithm;
|
||||
if (type == NID_sha256)
|
||||
return SymCryptHmacSha256Algorithm;
|
||||
if (type == NID_sha384)
|
||||
return SymCryptHmacSha384Algorithm;
|
||||
if (type == NID_sha512)
|
||||
return SymCryptHmacSha512Algorithm;
|
||||
// if (type == NID_AES_CMC)
|
||||
// return SymCryptAesCmacAlgorithm;
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_GET_SYMCRYPT_MAC_ALGORITHM, SCOSSL_ERR_R_NOT_IMPLEMENTED,
|
||||
"SymCrypt engine does not support Mac algorithm %d", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SCOSSL_STATUS e_scossl_hkdf_derive(_Inout_ EVP_PKEY_CTX *ctx, _Out_writes_opt_(*keylen) unsigned char *key,
|
||||
_Inout_ size_t *keylen)
|
||||
{
|
||||
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
|
||||
SCOSSL_HKDF_PKEY_CTX *e_scossl_hkdf_context = (SCOSSL_HKDF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
PCSYMCRYPT_MAC e_scossl_mac_algo = NULL;
|
||||
SYMCRYPT_HKDF_EXPANDED_KEY scExpandedKey;
|
||||
|
||||
if (e_scossl_hkdf_context->md == NULL) {
|
||||
if (e_scossl_hkdf_context->md == NULL)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Digest");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
e_scossl_mac_algo = e_scossl_get_symcrypt_mac_algorithm(e_scossl_hkdf_context->md);
|
||||
if (e_scossl_hkdf_context->key == NULL) {
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Key");
|
||||
"Missing Digest");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
switch (e_scossl_hkdf_context->mode) {
|
||||
case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND:
|
||||
if( e_scossl_mac_algo != NULL )
|
||||
{
|
||||
scError = SymCryptHkdf(
|
||||
e_scossl_mac_algo,
|
||||
e_scossl_hkdf_context->key, e_scossl_hkdf_context->key_len,
|
||||
e_scossl_hkdf_context->salt, e_scossl_hkdf_context->salt_len,
|
||||
e_scossl_hkdf_context->info, e_scossl_hkdf_context->info_len,
|
||||
key, *keylen);
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_HKDF_DERIVE, SCOSSL_ERR_R_OPENSSL_FALLBACK,
|
||||
"SymCrypt engine does not support Mac algorithm %d - falling back to OpenSSL", EVP_MD_type(e_scossl_hkdf_context->md));
|
||||
if (e_scossl_hkdf_context->pbKey == NULL)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Key");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
return HKDF(
|
||||
e_scossl_hkdf_context->md,
|
||||
e_scossl_hkdf_context->salt, e_scossl_hkdf_context->salt_len,
|
||||
e_scossl_hkdf_context->key, e_scossl_hkdf_context->key_len,
|
||||
e_scossl_hkdf_context->info, e_scossl_hkdf_context->info_len,
|
||||
key, *keylen) != NULL;
|
||||
}
|
||||
return SCOSSL_SUCCESS;
|
||||
case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY:
|
||||
if (key == NULL) {
|
||||
if (scossl_is_md_supported(EVP_MD_type(e_scossl_hkdf_context->md)))
|
||||
{
|
||||
if (e_scossl_hkdf_context->mode == EVP_KDF_HKDF_MODE_EXTRACT_ONLY && key == NULL)
|
||||
{
|
||||
*keylen = EVP_MD_size(e_scossl_hkdf_context->md);
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
if( e_scossl_mac_algo != NULL )
|
||||
{
|
||||
scError = SymCryptHkdfExtractPrk(
|
||||
e_scossl_mac_algo,
|
||||
e_scossl_hkdf_context->key, e_scossl_hkdf_context->key_len,
|
||||
e_scossl_hkdf_context->salt, e_scossl_hkdf_context->salt_len,
|
||||
key, *keylen );
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_HKDF_DERIVE, SCOSSL_ERR_R_OPENSSL_FALLBACK,
|
||||
"SymCrypt engine does not support Mac algorithm %d - falling back to OpenSSL", EVP_MD_type(e_scossl_hkdf_context->md));
|
||||
|
||||
return HKDF_Extract(
|
||||
e_scossl_hkdf_context->md,
|
||||
e_scossl_hkdf_context->salt, e_scossl_hkdf_context->salt_len,
|
||||
e_scossl_hkdf_context->key, e_scossl_hkdf_context->key_len,
|
||||
key, keylen) != NULL;
|
||||
}
|
||||
return SCOSSL_SUCCESS;
|
||||
case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY:
|
||||
if( e_scossl_mac_algo != NULL )
|
||||
{
|
||||
scError = SymCryptHkdfPrkExpandKey(
|
||||
&scExpandedKey,
|
||||
e_scossl_mac_algo,
|
||||
e_scossl_hkdf_context->key, e_scossl_hkdf_context->key_len );
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
scError = SymCryptHkdfDerive(
|
||||
&scExpandedKey,
|
||||
e_scossl_hkdf_context->info, e_scossl_hkdf_context->info_len,
|
||||
key,
|
||||
*keylen);
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_HKDF_DERIVE, SCOSSL_ERR_R_OPENSSL_FALLBACK,
|
||||
"SymCrypt engine does not support Mac algorithm %d - falling back to OpenSSL", EVP_MD_type(e_scossl_hkdf_context->md));
|
||||
|
||||
return HKDF_Expand(
|
||||
e_scossl_hkdf_context->md,
|
||||
e_scossl_hkdf_context->key, e_scossl_hkdf_context->key_len,
|
||||
e_scossl_hkdf_context->info, e_scossl_hkdf_context->info_len,
|
||||
key, *keylen) != NULL;
|
||||
}
|
||||
return SCOSSL_SUCCESS;
|
||||
default:
|
||||
return SCOSSL_FAILURE;
|
||||
return scossl_hkdf_derive(e_scossl_hkdf_context, key, *keylen);
|
||||
}
|
||||
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_HKDF_DERIVE, SCOSSL_ERR_R_OPENSSL_FALLBACK,
|
||||
"SymCrypt engine does not support Hmac algorithm %d - falling back to OpenSSL", EVP_MD_type(e_scossl_hkdf_context->md));
|
||||
|
||||
switch (e_scossl_hkdf_context->mode)
|
||||
{
|
||||
case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
|
||||
return HKDF(
|
||||
e_scossl_hkdf_context->md,
|
||||
e_scossl_hkdf_context->pbSalt, e_scossl_hkdf_context->cbSalt,
|
||||
e_scossl_hkdf_context->pbKey, e_scossl_hkdf_context->cbKey,
|
||||
e_scossl_hkdf_context->info, e_scossl_hkdf_context->cbInfo,
|
||||
key, *keylen) != NULL;
|
||||
case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
|
||||
return HKDF_Extract(
|
||||
e_scossl_hkdf_context->md,
|
||||
e_scossl_hkdf_context->pbSalt, e_scossl_hkdf_context->cbSalt,
|
||||
e_scossl_hkdf_context->pbKey, e_scossl_hkdf_context->cbKey,
|
||||
key, keylen) != NULL;
|
||||
case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
|
||||
return HKDF_Expand(
|
||||
e_scossl_hkdf_context->md,
|
||||
e_scossl_hkdf_context->pbKey, e_scossl_hkdf_context->cbKey,
|
||||
e_scossl_hkdf_context->info, e_scossl_hkdf_context->cbInfo,
|
||||
key, *keylen) != NULL;
|
||||
}
|
||||
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -28,8 +28,8 @@ SCOSSL_STATUS e_scossl_hkdf_derive_init(_Inout_ EVP_PKEY_CTX *ctx);
|
|||
// is written to the keylen parameter. If key is not NULL, then keylen should contain the length of
|
||||
// the key buffer, the shared secret is written to key and the amount of data written to keylen.
|
||||
// Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE or a negative value for failure.
|
||||
SCOSSL_STATUS e_scossl_hkdf_derive(_Inout_ EVP_PKEY_CTX *ctx, _Out_writes_opt_(*keylen) unsigned char *key,
|
||||
_Inout_ size_t *keylen);
|
||||
SCOSSL_STATUS e_scossl_hkdf_derive(_Inout_ EVP_PKEY_CTX *ctx,
|
||||
_Out_writes_opt_(*keylen) unsigned char *key, _Inout_ size_t *keylen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ SCOSSL_STATUS e_scossl_sshkdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
|||
case EVP_KDF_CTRL_SET_MD:
|
||||
md = va_arg(args, EVP_MD*);
|
||||
|
||||
impl->pHash = e_scossl_get_symcrypt_hash_algorithm(md);
|
||||
impl->pHash = e_scossl_get_symcrypt_hash_algorithm(EVP_MD_type(md));
|
||||
|
||||
if(!impl->pHash) {
|
||||
ret = SCOSSL_FAILURE;
|
||||
|
|
|
@ -2,168 +2,97 @@
|
|||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_tls1prf.h"
|
||||
#include "e_scossl_tls1prf.h"
|
||||
|
||||
#include <openssl/kdf.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TLS1_PRF_MAXBUF 1024
|
||||
|
||||
/* TLS KDF pkey context structure */
|
||||
typedef struct {
|
||||
/* Digest to use for PRF */
|
||||
const EVP_MD *md;
|
||||
/* Secret value to use for PRF */
|
||||
unsigned char *secret;
|
||||
size_t secret_length;
|
||||
/* Buffer of concatenated seed data */
|
||||
unsigned char seed[TLS1_PRF_MAXBUF];
|
||||
size_t seed_length;
|
||||
} SCOSSL_TLS1_PRF_PKEY_CTX;
|
||||
|
||||
SCOSSL_STATUS e_scossl_tls1prf_init(_Inout_ EVP_PKEY_CTX *ctx)
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS e_scossl_tls1prf_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
SCOSSL_TLS1_PRF_PKEY_CTX *key_context = NULL;
|
||||
if ((key_context = OPENSSL_zalloc(sizeof(*key_context))) == NULL) {
|
||||
SCOSSL_TLS1_PRF_CTX *key_context = NULL;
|
||||
if ((key_context = scossl_tls1prf_newctx()) == NULL)
|
||||
{
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_TLS1PRF_INIT, ERR_R_MALLOC_FAILURE,
|
||||
"OPENSSL_zalloc return NULL");
|
||||
"OPENSSL_zalloc return NULL");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
EVP_PKEY_CTX_set_data(ctx, key_context);
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
void e_scossl_tls1prf_cleanup(_Inout_ EVP_PKEY_CTX *ctx)
|
||||
_Use_decl_annotations_
|
||||
void e_scossl_tls1prf_cleanup(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
SCOSSL_TLS1_PRF_PKEY_CTX *key_context = (SCOSSL_TLS1_PRF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
if (key_context == NULL) {
|
||||
SCOSSL_TLS1_PRF_CTX *key_context = (SCOSSL_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
if (key_context == NULL)
|
||||
return;
|
||||
}
|
||||
OPENSSL_clear_free(key_context->secret, key_context->secret_length);
|
||||
OPENSSL_cleanse(key_context->seed, key_context->seed_length);
|
||||
OPENSSL_free(key_context);
|
||||
|
||||
scossl_tls1prf_freectx(key_context);
|
||||
|
||||
EVP_PKEY_CTX_set_data(ctx, NULL);
|
||||
}
|
||||
|
||||
SCOSSL_STATUS e_scossl_tls1prf_ctrl(_Inout_ EVP_PKEY_CTX *ctx, int type, int p1, _In_ void *p2)
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS e_scossl_tls1prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
SCOSSL_TLS1_PRF_PKEY_CTX *key_context = (SCOSSL_TLS1_PRF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
SCOSSL_TLS1_PRF_CTX *key_context = (SCOSSL_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
PCSYMCRYPT_MAC symcryptHmacAlg = NULL;
|
||||
BOOL isTlsPrf1_1 = TRUE;
|
||||
|
||||
switch (type) {
|
||||
switch (type)
|
||||
{
|
||||
case EVP_PKEY_CTRL_TLS_MD:
|
||||
key_context->md = p2;
|
||||
// Special case to always allow md5_sha1 for tls1.1 PRF compat
|
||||
if (EVP_MD_type(p2) != NID_md5_sha1)
|
||||
{
|
||||
if ((symcryptHmacAlg = scossl_get_symcrypt_hmac_algorithm(EVP_MD_type(p2))) == NULL)
|
||||
return SCOSSL_FAILURE;
|
||||
isTlsPrf1_1 = FALSE;
|
||||
}
|
||||
key_context->pHmac = symcryptHmacAlg;
|
||||
key_context->isTlsPrf1_1 = isTlsPrf1_1;
|
||||
return SCOSSL_SUCCESS;
|
||||
|
||||
case EVP_PKEY_CTRL_TLS_SECRET:
|
||||
if (p1 < 0)
|
||||
return SCOSSL_FAILURE;
|
||||
if (key_context->secret != NULL)
|
||||
OPENSSL_clear_free(key_context->secret, key_context->secret_length);
|
||||
OPENSSL_cleanse(key_context->seed, key_context->seed_length);
|
||||
key_context->seed_length = 0;
|
||||
key_context->secret = OPENSSL_memdup(p2, p1);
|
||||
if (key_context->secret == NULL)
|
||||
if (key_context->pbSecret != NULL)
|
||||
OPENSSL_clear_free(key_context->pbSecret, key_context->cbSecret);
|
||||
OPENSSL_cleanse(key_context->seed, key_context->cbSeed);
|
||||
key_context->cbSeed = 0;
|
||||
key_context->pbSecret = OPENSSL_memdup(p2, p1);
|
||||
if (key_context->pbSecret == NULL)
|
||||
return SCOSSL_FAILURE;
|
||||
key_context->secret_length = p1;
|
||||
key_context->cbSecret = p1;
|
||||
return SCOSSL_SUCCESS;
|
||||
case EVP_PKEY_CTRL_TLS_SEED:
|
||||
if (p1 == 0 || p2 == NULL)
|
||||
return SCOSSL_SUCCESS;
|
||||
if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - key_context->seed_length))
|
||||
return SCOSSL_FAILURE;
|
||||
memcpy(key_context->seed + key_context->seed_length, p2, p1);
|
||||
key_context->seed_length += p1;
|
||||
return SCOSSL_SUCCESS;
|
||||
return scossl_tls1prf_append_seed(key_context, p2, p1);
|
||||
default:
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_TLS1PRF_CTRL, SCOSSL_ERR_R_NOT_IMPLEMENTED,
|
||||
"SymCrypt Engine does not support ctrl type (%d)", type);
|
||||
"SymCrypt Engine does not support ctrl type (%d)", type);
|
||||
return SCOSSL_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
SCOSSL_STATUS e_scossl_tls1prf_derive_init(_Inout_ EVP_PKEY_CTX *ctx)
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS e_scossl_tls1prf_derive_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
SCOSSL_TLS1_PRF_PKEY_CTX *key_context = (SCOSSL_TLS1_PRF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
OPENSSL_clear_free(key_context->secret, key_context->secret_length);
|
||||
OPENSSL_cleanse(key_context->seed, key_context->seed_length);
|
||||
memset(key_context, 0, sizeof(*key_context));
|
||||
return SCOSSL_SUCCESS;
|
||||
SCOSSL_TLS1_PRF_CTX *key_context = (SCOSSL_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
return scossl_tls1prf_reset(key_context);
|
||||
}
|
||||
|
||||
static PCSYMCRYPT_MAC e_scossl_get_symcrypt_mac_algorithm(const EVP_MD *evp_md)
|
||||
_Use_decl_annotations_
|
||||
SCOSSL_STATUS e_scossl_tls1prf_derive(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *key, size_t *keylen)
|
||||
{
|
||||
int type = EVP_MD_type(evp_md);
|
||||
|
||||
if (type == NID_sha1)
|
||||
return SymCryptHmacSha1Algorithm;
|
||||
if (type == NID_sha256)
|
||||
return SymCryptHmacSha256Algorithm;
|
||||
if (type == NID_sha384)
|
||||
return SymCryptHmacSha384Algorithm;
|
||||
if (type == NID_sha512)
|
||||
return SymCryptHmacSha512Algorithm;
|
||||
// if (type == NID_AES_CMC)
|
||||
// return SymCryptAesCmacAlgorithm;
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_GET_SYMCRYPT_MAC_ALGORITHM, SCOSSL_ERR_R_NOT_IMPLEMENTED,
|
||||
"SymCrypt engine does not support Mac algorithm %d", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SCOSSL_STATUS e_scossl_tls1prf_derive(_Inout_ EVP_PKEY_CTX *ctx, _Out_writes_opt_(*keylen) unsigned char *key,
|
||||
_Inout_ size_t *keylen)
|
||||
{
|
||||
SCOSSL_TLS1_PRF_PKEY_CTX *key_context = (SCOSSL_TLS1_PRF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
PCSYMCRYPT_MAC e_scossl_mac_algo = NULL;
|
||||
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
|
||||
|
||||
if (key_context->md == NULL) {
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_TLS1PRF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Digest");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (key_context->secret == NULL) {
|
||||
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_TLS1PRF_DERIVE, ERR_R_INTERNAL_ERROR,
|
||||
"Missing Secret");
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if( EVP_MD_type(key_context->md) == NID_md5_sha1 )
|
||||
{
|
||||
// Special case to use TlsPrf1_1 to handle md5_sha1
|
||||
SCOSSL_LOG_INFO(SCOSSL_ERR_F_TLS1PRF_DERIVE, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM,
|
||||
"Using Mac algorithm MD5+SHA1 which is not FIPS compliant");
|
||||
scError = SymCryptTlsPrf1_1(
|
||||
key_context->secret, key_context->secret_length,
|
||||
NULL, 0,
|
||||
key_context->seed, key_context->seed_length,
|
||||
key, *keylen);
|
||||
}
|
||||
else
|
||||
{
|
||||
e_scossl_mac_algo = e_scossl_get_symcrypt_mac_algorithm(key_context->md);
|
||||
if( e_scossl_mac_algo == NULL )
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
scError = SymCryptTlsPrf1_2(
|
||||
e_scossl_mac_algo,
|
||||
key_context->secret, key_context->secret_length,
|
||||
NULL, 0,
|
||||
key_context->seed, key_context->seed_length,
|
||||
key, *keylen);
|
||||
}
|
||||
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
SCOSSL_LOG_SYMCRYPT_ERROR(SCOSSL_ERR_F_TLS1PRF_DERIVE, SCOSSL_ERR_R_SYMCRYPT_FAILURE,
|
||||
"SymCryptTlsPrf1_x failed", scError);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
return SCOSSL_SUCCESS;
|
||||
SCOSSL_TLS1_PRF_CTX *key_context = (SCOSSL_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx);
|
||||
return scossl_tls1prf_derive(key_context, key, *keylen);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -24,12 +24,12 @@ SCOSSL_STATUS e_scossl_tls1prf_ctrl(_Inout_ EVP_PKEY_CTX *ctx, int type, int p1,
|
|||
// Returns SCOSSL_SUCCESS on success or SCOSSL_FAILURE on error.
|
||||
SCOSSL_STATUS e_scossl_tls1prf_derive_init(_Inout_ EVP_PKEY_CTX *ctx);
|
||||
|
||||
// Derives a shared secret using ctx. If key is NULL then the maximum size of the output buffer
|
||||
// is written to the keylen parameter. If key is not NULL, then keylen should contain the length of
|
||||
// the key buffer, the shared secret is written to key and the amount of data written to keylen.
|
||||
// Derives a shared secret using ctx.
|
||||
// NOTE: The documentation states that if the key is NULL, then keylen will be set to the maximum size of
|
||||
// the output buffer. This is not true for TLS1-PRF, and the keylen is always expected.
|
||||
// Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error.
|
||||
SCOSSL_STATUS e_scossl_tls1prf_derive(_Inout_ EVP_PKEY_CTX *ctx, _Out_writes_opt_(*keylen) unsigned char *key,
|
||||
_Inout_ size_t *keylen);
|
||||
SCOSSL_STATUS e_scossl_tls1prf_derive(_Inout_ EVP_PKEY_CTX *ctx,
|
||||
_Out_writes_bytes_(*keylen) unsigned char *key, _In_ size_t *keylen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ endif()
|
|||
add_library(scossl_static STATIC ${SCOSSL_SOURCES})
|
||||
add_dependencies(scossl_static scossl_common)
|
||||
|
||||
set_target_properties(scossl_static PROPERTIES PUBLIC_HEADER ../inc/scossl.h)
|
||||
set_target_properties(scossl_static PROPERTIES PUBLIC_HEADER ../inc/e_scossl.h)
|
||||
# target_link_libraries(scossl_static ${OPENSSL_CRYPTO_LIBRARY})
|
||||
target_include_directories(scossl_static PUBLIC ../inc)
|
||||
target_include_directories(scossl_static PRIVATE ../src)
|
||||
|
|
|
@ -21,6 +21,9 @@ set(SCOSSL_SOURCES
|
|||
./src/ciphers/p_scossl_aes.c
|
||||
./src/ciphers/p_scossl_aes_aead.c
|
||||
# ./src/ciphers/p_scossl_aes_xts.c
|
||||
./src/kdf/p_scossl_hkdf.c
|
||||
./src/kdf/p_scossl_sshkdf.c
|
||||
./src/kdf/p_scossl_tls1prf.c
|
||||
./src/keyexch/p_scossl_ecdh.c
|
||||
./src/keymgmt/p_scossl_ecc_keymgmt.c
|
||||
./src/keymgmt/p_scossl_rsa_keymgmt.c
|
||||
|
|
|
@ -0,0 +1,354 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_hkdf.h"
|
||||
#include "p_scossl_base.h"
|
||||
|
||||
#include <openssl/proverr.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Needed for fetching md
|
||||
OSSL_LIB_CTX *libctx;
|
||||
|
||||
SCOSSL_HKDF_CTX *hkdfCtx;
|
||||
} SCOSSL_PROV_HKDF_CTX;
|
||||
|
||||
#define HKDF_MODE_EXTRACT_AND_EXPAND "EXTRACT_AND_EXPAND"
|
||||
#define HKDF_MODE_EXTRACT_ONLY "EXTRACT_ONLY"
|
||||
#define HKDF_MODE_EXPAND_ONLY "EXPAND_ONLY"
|
||||
|
||||
static const OSSL_PARAM p_scossl_hkdf_gettable_ctx_param_types[] = {
|
||||
OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0),
|
||||
OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
|
||||
OSSL_PARAM_END};
|
||||
|
||||
static const OSSL_PARAM p_scossl_hkdf_settable_ctx_param_types[] = {
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0),
|
||||
OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
|
||||
OSSL_PARAM_END};
|
||||
|
||||
static SCOSSL_STATUS p_scossl_hkdf_set_ctx_params(_Inout_ SCOSSL_PROV_HKDF_CTX *ctx, const _In_ OSSL_PARAM params[]);
|
||||
|
||||
static SCOSSL_PROV_HKDF_CTX *p_scossl_hkdf_newctx(_In_ SCOSSL_PROVCTX *provctx)
|
||||
{
|
||||
SCOSSL_PROV_HKDF_CTX *ctx = OPENSSL_malloc(sizeof(SCOSSL_PROV_HKDF_CTX));
|
||||
if (ctx != NULL)
|
||||
{
|
||||
if ((ctx->hkdfCtx = scossl_hkdf_newctx()) == NULL)
|
||||
{
|
||||
OPENSSL_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->libctx = provctx->libctx;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void p_scossl_hkdf_freectx(_Inout_ SCOSSL_PROV_HKDF_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
{
|
||||
EVP_MD_free(ctx->hkdfCtx->md);
|
||||
scossl_hkdf_freectx(ctx->hkdfCtx);
|
||||
}
|
||||
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
static SCOSSL_PROV_HKDF_CTX *p_scossl_hkdf_dupctx(_In_ SCOSSL_PROV_HKDF_CTX *ctx)
|
||||
{
|
||||
SCOSSL_PROV_HKDF_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_PROV_HKDF_CTX));
|
||||
if (copyCtx != NULL)
|
||||
{
|
||||
if ((copyCtx->hkdfCtx = scossl_hkdf_dupctx(ctx->hkdfCtx)) == NULL ||
|
||||
(ctx->hkdfCtx->md != NULL && !EVP_MD_up_ref(ctx->hkdfCtx->md)))
|
||||
{
|
||||
scossl_hkdf_freectx(copyCtx->hkdfCtx);
|
||||
OPENSSL_free(copyCtx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
copyCtx->libctx = ctx->libctx;
|
||||
}
|
||||
|
||||
return copyCtx;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_hkdf_reset(_Inout_ SCOSSL_PROV_HKDF_CTX *ctx)
|
||||
{
|
||||
EVP_MD_free(ctx->hkdfCtx->md);
|
||||
return scossl_hkdf_reset(ctx->hkdfCtx);
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_hkdf_derive(_In_ SCOSSL_PROV_HKDF_CTX *ctx,
|
||||
_Out_writes_bytes_(keylen) unsigned char *key, size_t keylen,
|
||||
_In_ const OSSL_PARAM params[])
|
||||
{
|
||||
return p_scossl_hkdf_set_ctx_params(ctx, params) &&
|
||||
scossl_hkdf_derive(ctx->hkdfCtx, key, keylen);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *p_scossl_hkdf_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
|
||||
{
|
||||
return p_scossl_hkdf_gettable_ctx_param_types;
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *p_scossl_hkdf_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
|
||||
{
|
||||
return p_scossl_hkdf_settable_ctx_param_types;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_hkdf_get_ctx_params(_In_ SCOSSL_PROV_HKDF_CTX *ctx, _Inout_ OSSL_PARAM params[])
|
||||
{
|
||||
OSSL_PARAM *p;
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
|
||||
{
|
||||
SIZE_T cbResult;
|
||||
if (ctx->hkdfCtx->mode == EVP_KDF_HKDF_MODE_EXTRACT_ONLY)
|
||||
{
|
||||
if (ctx->hkdfCtx->md == NULL)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
cbResult = EVP_MD_get_size(ctx->hkdfCtx->md);
|
||||
}
|
||||
else
|
||||
{
|
||||
cbResult = SIZE_MAX;
|
||||
}
|
||||
|
||||
if (!OSSL_PARAM_set_size_t(p, cbResult))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_MODE)) != NULL)
|
||||
{
|
||||
if (p->data_type == OSSL_PARAM_UTF8_STRING)
|
||||
{
|
||||
const char *mode = NULL;
|
||||
switch (ctx->hkdfCtx->mode)
|
||||
{
|
||||
case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
|
||||
mode = HKDF_MODE_EXTRACT_AND_EXPAND;
|
||||
break;
|
||||
case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
|
||||
mode = HKDF_MODE_EXTRACT_ONLY;
|
||||
break;
|
||||
case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
|
||||
mode = HKDF_MODE_EXPAND_ONLY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode == NULL ||
|
||||
!OSSL_PARAM_set_utf8_string(p, mode))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
else if (!OSSL_PARAM_set_int(p, ctx->hkdfCtx->mode))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_DIGEST)) != NULL &&
|
||||
!OSSL_PARAM_set_utf8_string(p, ctx->hkdfCtx->md == NULL ? "" : EVP_MD_get0_name(ctx->hkdfCtx->md)))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SALT)) != NULL &&
|
||||
!OSSL_PARAM_set_octet_string(p, ctx->hkdfCtx->pbSalt, ctx->hkdfCtx->cbSalt))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_KEY)) != NULL &&
|
||||
!OSSL_PARAM_set_octet_string(p, ctx->hkdfCtx->pbKey, ctx->hkdfCtx->cbKey))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_INFO)) != NULL &&
|
||||
!OSSL_PARAM_set_octet_string(p, ctx->hkdfCtx->info, ctx->hkdfCtx->cbInfo))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_hkdf_set_ctx_params(_Inout_ SCOSSL_PROV_HKDF_CTX *ctx, const _In_ OSSL_PARAM params[])
|
||||
{
|
||||
PCBYTE pbInfo;
|
||||
SIZE_T cbInfo;
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL)
|
||||
{
|
||||
int mode = -1;
|
||||
if (p->data_type == OSSL_PARAM_UTF8_STRING)
|
||||
{
|
||||
if (OPENSSL_strcasecmp(p->data, HKDF_MODE_EXTRACT_AND_EXPAND) == 0)
|
||||
{
|
||||
mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND;
|
||||
}
|
||||
else if (OPENSSL_strcasecmp(p->data, HKDF_MODE_EXTRACT_ONLY) == 0)
|
||||
{
|
||||
mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;
|
||||
}
|
||||
else if (OPENSSL_strcasecmp(p->data, HKDF_MODE_EXPAND_ONLY) == 0)
|
||||
{
|
||||
mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;
|
||||
}
|
||||
}
|
||||
else if (!OSSL_PARAM_get_int(p, &mode))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (mode < EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND || mode > EVP_KDF_HKDF_MODE_EXPAND_ONLY)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
ctx->hkdfCtx->mode = mode;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL)
|
||||
{
|
||||
const OSSL_PARAM *param_propq;
|
||||
const char *mdName, *mdProps;
|
||||
EVP_MD *md;
|
||||
|
||||
if (!OSSL_PARAM_get_utf8_string_ptr(p, &mdName))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
mdProps = NULL;
|
||||
param_propq = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES);
|
||||
if (param_propq != NULL &&
|
||||
!OSSL_PARAM_get_utf8_string_ptr(p, &mdProps))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
md = EVP_MD_fetch(ctx->libctx, mdName, mdProps);
|
||||
|
||||
if (md == NULL ||
|
||||
!scossl_is_md_supported(EVP_MD_type(md)))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
EVP_MD_free(ctx->hkdfCtx->md);
|
||||
ctx->hkdfCtx->md = md;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL)
|
||||
{
|
||||
PBYTE pbSalt = NULL;
|
||||
SIZE_T cbSalt = 0;
|
||||
|
||||
if (p->data_size > 0 &&
|
||||
!OSSL_PARAM_get_octet_string(p, (void **)&pbSalt, 0, &cbSalt))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
OPENSSL_clear_free(ctx->hkdfCtx->pbSalt, ctx->hkdfCtx->cbSalt);
|
||||
ctx->hkdfCtx->pbSalt = pbSalt;
|
||||
ctx->hkdfCtx->cbSalt = cbSalt;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
|
||||
{
|
||||
PBYTE pbKey = NULL;
|
||||
SIZE_T cbKey = 0;
|
||||
|
||||
if (p->data_size > 0 &&
|
||||
!OSSL_PARAM_get_octet_string(p, (void **)&pbKey, 0, &cbKey))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
OPENSSL_clear_free(ctx->hkdfCtx->pbKey, ctx->hkdfCtx->cbKey);
|
||||
ctx->hkdfCtx->pbKey = pbKey;
|
||||
ctx->hkdfCtx->cbKey = cbKey;
|
||||
}
|
||||
|
||||
// Parameters may contain multiple info params that must all be processed
|
||||
for (p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO);
|
||||
p != NULL;
|
||||
p = OSSL_PARAM_locate_const(p + 1, OSSL_KDF_PARAM_INFO))
|
||||
{
|
||||
if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pbInfo, &cbInfo))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (!scossl_hkdf_append_info(ctx->hkdfCtx, pbInfo, cbInfo))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
const OSSL_DISPATCH p_scossl_hkdf_kdf_functions[] = {
|
||||
{OSSL_FUNC_KDF_NEWCTX, (void (*)(void))p_scossl_hkdf_newctx},
|
||||
{OSSL_FUNC_KDF_FREECTX, (void (*)(void))p_scossl_hkdf_freectx},
|
||||
{OSSL_FUNC_KDF_DUPCTX, (void (*)(void))p_scossl_hkdf_dupctx},
|
||||
{OSSL_FUNC_KDF_RESET, (void (*)(void))p_scossl_hkdf_reset},
|
||||
{OSSL_FUNC_KDF_DERIVE, (void (*)(void))p_scossl_hkdf_derive},
|
||||
{OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_hkdf_gettable_ctx_params},
|
||||
{OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_hkdf_settable_ctx_params},
|
||||
{OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))p_scossl_hkdf_get_ctx_params},
|
||||
{OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))p_scossl_hkdf_set_ctx_params},
|
||||
{0, NULL}};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,320 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "scossl_sshkdf.h"
|
||||
#include "p_scossl_base.h"
|
||||
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/proverr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
// Needed for fetching md
|
||||
OSSL_LIB_CTX *libctx;
|
||||
|
||||
// Purely informational
|
||||
char* mdName;
|
||||
|
||||
SCOSSL_SSHKDF_CTX *sshkdfCtx;
|
||||
} SCOSSL_PROV_SSHKDF_CTX;
|
||||
|
||||
static const OSSL_PARAM p_scossl_sshkdf_gettable_ctx_param_types[] = {
|
||||
OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_XCGHASH, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, NULL, 0),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE, NULL, 0),
|
||||
OSSL_PARAM_END};
|
||||
|
||||
static const OSSL_PARAM p_scossl_sshkdf_settable_ctx_param_types[] = {
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_XCGHASH, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, NULL, 0),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE, NULL, 0),
|
||||
OSSL_PARAM_END};
|
||||
|
||||
SCOSSL_STATUS p_scossl_sshkdf_set_ctx_params(_Inout_ SCOSSL_PROV_SSHKDF_CTX *ctx, _In_ const OSSL_PARAM params[]);
|
||||
|
||||
SCOSSL_PROV_SSHKDF_CTX *p_scossl_sshkdf_newctx(_In_ SCOSSL_PROVCTX *provctx)
|
||||
{
|
||||
SCOSSL_PROV_SSHKDF_CTX *ctx = OPENSSL_malloc(sizeof(SCOSSL_PROV_SSHKDF_CTX));
|
||||
if (ctx != NULL)
|
||||
{
|
||||
if ((ctx->sshkdfCtx = scossl_sshkdf_newctx()) == NULL)
|
||||
{
|
||||
OPENSSL_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->mdName = NULL;
|
||||
ctx->libctx = provctx->libctx;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void p_scossl_sshkdf_freectx(_Inout_ SCOSSL_PROV_SSHKDF_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
{
|
||||
OPENSSL_free(ctx->mdName);
|
||||
scossl_sshkdf_freectx(ctx->sshkdfCtx);
|
||||
}
|
||||
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
SCOSSL_PROV_SSHKDF_CTX *p_scossl_sshkdf_dupctx(_In_ SCOSSL_PROV_SSHKDF_CTX *ctx)
|
||||
{
|
||||
SCOSSL_PROV_SSHKDF_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_PROV_SSHKDF_CTX));
|
||||
if (copyCtx != NULL)
|
||||
{
|
||||
if ((copyCtx->sshkdfCtx = scossl_sshkdf_dupctx(ctx->sshkdfCtx)) == NULL)
|
||||
{
|
||||
OPENSSL_free(copyCtx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
copyCtx->libctx = ctx->libctx;
|
||||
copyCtx->mdName = OPENSSL_strdup(ctx->mdName);
|
||||
}
|
||||
|
||||
return copyCtx;
|
||||
}
|
||||
|
||||
SCOSSL_STATUS p_scossl_sshkdf_reset(_Inout_ SCOSSL_PROV_SSHKDF_CTX *ctx)
|
||||
{
|
||||
OPENSSL_free(ctx->mdName);
|
||||
ctx->mdName = NULL;
|
||||
return scossl_sshkdf_reset(ctx->sshkdfCtx);
|
||||
}
|
||||
|
||||
SCOSSL_STATUS p_scossl_sshkdf_derive(_In_ SCOSSL_PROV_SSHKDF_CTX *ctx,
|
||||
_Out_writes_bytes_(keylen) unsigned char *key, size_t keylen,
|
||||
_In_ const OSSL_PARAM params[])
|
||||
{
|
||||
return p_scossl_sshkdf_set_ctx_params(ctx, params) &&
|
||||
scossl_sshkdf_derive(ctx->sshkdfCtx, key, keylen);
|
||||
}
|
||||
|
||||
const OSSL_PARAM *p_scossl_sshkdf_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
|
||||
{
|
||||
return p_scossl_sshkdf_gettable_ctx_param_types;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *p_scossl_sshkdf_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
|
||||
{
|
||||
return p_scossl_sshkdf_settable_ctx_param_types;
|
||||
}
|
||||
|
||||
SCOSSL_STATUS p_scossl_sshkdf_get_ctx_params(_In_ SCOSSL_PROV_SSHKDF_CTX *ctx, _Inout_ OSSL_PARAM params[])
|
||||
{
|
||||
OSSL_PARAM *p;
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL &&
|
||||
!OSSL_PARAM_set_size_t(p, SIZE_MAX))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_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;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_KEY)) != NULL &&
|
||||
!OSSL_PARAM_set_octet_string(p, ctx->sshkdfCtx->pbKey, ctx->sshkdfCtx->cbKey))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SSHKDF_XCGHASH)) != NULL &&
|
||||
!OSSL_PARAM_set_octet_string(p, ctx->sshkdfCtx->hashValue, ctx->sshkdfCtx->cbHashValue))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SSHKDF_SESSION_ID)) != NULL &&
|
||||
!OSSL_PARAM_set_octet_string(p, ctx->sshkdfCtx->sessionId, ctx->sshkdfCtx->cbSessionId))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SSHKDF_TYPE)) != NULL)
|
||||
{
|
||||
char *pData = p->data;
|
||||
|
||||
if (p->data_type != OSSL_PARAM_UTF8_STRING ||
|
||||
p->data_size < 1)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
pData[0] = ctx->sshkdfCtx->label;
|
||||
p->return_size = 1;
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
SCOSSL_STATUS p_scossl_sshkdf_set_ctx_params(_Inout_ SCOSSL_PROV_SSHKDF_CTX *ctx, _In_ const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL)
|
||||
{
|
||||
PCSYMCRYPT_HASH symcryptHashAlg = NULL;
|
||||
const char *paramMdName, *mdProps;
|
||||
char *mdName;
|
||||
EVP_MD *md;
|
||||
|
||||
if (!OSSL_PARAM_get_utf8_string_ptr(p, ¶mMdName))
|
||||
{
|
||||
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));
|
||||
symcryptHashAlg = scossl_get_symcrypt_hash_algorithm(EVP_MD_type(md));
|
||||
EVP_MD_free(md);
|
||||
|
||||
if (symcryptHashAlg == NULL)
|
||||
{
|
||||
OPENSSL_free(mdName);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
OPENSSL_free(ctx->mdName);
|
||||
ctx->mdName = mdName;
|
||||
ctx->sshkdfCtx->pHash = symcryptHashAlg;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
|
||||
{
|
||||
PBYTE pbKey = NULL;
|
||||
SIZE_T cbKey = 0;
|
||||
|
||||
if (p->data_size > 0 &&
|
||||
!OSSL_PARAM_get_octet_string(p, (void **)&pbKey, 0, &cbKey))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
OPENSSL_clear_free(ctx->sshkdfCtx->pbKey, ctx->sshkdfCtx->cbKey);
|
||||
ctx->sshkdfCtx->pbKey = pbKey;
|
||||
ctx->sshkdfCtx->cbKey = cbKey;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_XCGHASH)) != NULL)
|
||||
{
|
||||
PCBYTE pbHashValue;
|
||||
SIZE_T cbHashValue;
|
||||
if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pbHashValue, &cbHashValue))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (cbHashValue > SSH_KDF_MAX_DIGEST_SIZE)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(ctx->sshkdfCtx->hashValue, pbHashValue, cbHashValue);
|
||||
ctx->sshkdfCtx->cbHashValue = cbHashValue;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_SESSION_ID)) != NULL)
|
||||
{
|
||||
PCBYTE pbSessionId;
|
||||
SIZE_T cbSessionId;
|
||||
if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pbSessionId, &cbSessionId))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (cbSessionId > SSH_KDF_MAX_DIGEST_SIZE)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(ctx->sshkdfCtx->sessionId, pbSessionId, cbSessionId);
|
||||
ctx->sshkdfCtx->cbSessionId = cbSessionId;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_TYPE)) != NULL)
|
||||
{
|
||||
const char *type;
|
||||
if (p->data_size != 1)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (!OSSL_PARAM_get_utf8_string_ptr(p, &type))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (type[0] < EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV ||
|
||||
type[0] > EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_SRV_TO_CLI)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_VALUE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->sshkdfCtx->label = type[0];
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
const OSSL_DISPATCH p_scossl_sshkdf_kdf_functions[] = {
|
||||
{OSSL_FUNC_KDF_NEWCTX, (void (*)(void))p_scossl_sshkdf_newctx},
|
||||
{OSSL_FUNC_KDF_FREECTX, (void (*)(void))p_scossl_sshkdf_freectx},
|
||||
{OSSL_FUNC_KDF_DUPCTX, (void (*)(void))p_scossl_sshkdf_dupctx},
|
||||
{OSSL_FUNC_KDF_RESET, (void (*)(void))p_scossl_sshkdf_reset},
|
||||
{OSSL_FUNC_KDF_DERIVE, (void (*)(void))p_scossl_sshkdf_derive},
|
||||
{OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_sshkdf_gettable_ctx_params},
|
||||
{OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_sshkdf_settable_ctx_params},
|
||||
{OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))p_scossl_sshkdf_get_ctx_params},
|
||||
{OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))p_scossl_sshkdf_set_ctx_params},
|
||||
{0, NULL}};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,257 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include <openssl/proverr.h>
|
||||
|
||||
#include "scossl_tls1prf.h"
|
||||
#include "p_scossl_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
// Needed for fetching md
|
||||
OSSL_LIB_CTX *libctx;
|
||||
|
||||
// Purely informational
|
||||
char *mdName;
|
||||
|
||||
SCOSSL_TLS1_PRF_CTX *tls1prfCtx;
|
||||
} SCOSSL_PROV_TLS1_PRF_CTX;
|
||||
|
||||
static const OSSL_PARAM p_scossl_tls1prf_gettable_ctx_param_types[] = {
|
||||
OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SEED, NULL, 0),
|
||||
OSSL_PARAM_END};
|
||||
|
||||
static const OSSL_PARAM p_scossl_tls1prf_settable_ctx_param_types[] = {
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
|
||||
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SEED, NULL, 0),
|
||||
OSSL_PARAM_END};
|
||||
|
||||
SCOSSL_STATUS p_scossl_tls1prf_set_ctx_params(_Inout_ SCOSSL_PROV_TLS1_PRF_CTX *ctx, _In_ const OSSL_PARAM params[]);
|
||||
|
||||
SCOSSL_PROV_TLS1_PRF_CTX *p_scossl_tls1prf_newctx(_In_ SCOSSL_PROVCTX *provctx)
|
||||
{
|
||||
SCOSSL_PROV_TLS1_PRF_CTX *ctx = OPENSSL_malloc(sizeof(SCOSSL_PROV_TLS1_PRF_CTX));
|
||||
if (ctx != NULL)
|
||||
{
|
||||
if ((ctx->tls1prfCtx = scossl_tls1prf_newctx()) == NULL)
|
||||
{
|
||||
OPENSSL_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->mdName = NULL;
|
||||
ctx->libctx = provctx->libctx;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void p_scossl_tls1prf_freectx(_Inout_ SCOSSL_PROV_TLS1_PRF_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
{
|
||||
scossl_tls1prf_freectx(ctx->tls1prfCtx);
|
||||
}
|
||||
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
SCOSSL_PROV_TLS1_PRF_CTX *p_scossl_tls1prf_dupctx(_In_ SCOSSL_PROV_TLS1_PRF_CTX *ctx)
|
||||
{
|
||||
SCOSSL_PROV_TLS1_PRF_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_PROV_TLS1_PRF_CTX));
|
||||
if (copyCtx != NULL)
|
||||
{
|
||||
if ((copyCtx->tls1prfCtx = scossl_tls1prf_dupctx(ctx->tls1prfCtx)) == NULL)
|
||||
{
|
||||
OPENSSL_free(copyCtx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
copyCtx->mdName = OPENSSL_strdup(ctx->mdName);
|
||||
copyCtx->libctx = ctx->libctx;
|
||||
}
|
||||
|
||||
return copyCtx;
|
||||
}
|
||||
|
||||
SCOSSL_STATUS p_scossl_tls1prf_reset(_Inout_ SCOSSL_PROV_TLS1_PRF_CTX *ctx)
|
||||
{
|
||||
OPENSSL_free(ctx->mdName);
|
||||
ctx->mdName = NULL;
|
||||
return scossl_tls1prf_reset(ctx->tls1prfCtx);
|
||||
}
|
||||
|
||||
SCOSSL_STATUS p_scossl_tls1prf_derive(_In_ SCOSSL_PROV_TLS1_PRF_CTX *ctx,
|
||||
_Out_writes_bytes_(keylen) unsigned char *key, size_t keylen,
|
||||
_In_ const OSSL_PARAM params[])
|
||||
{
|
||||
return p_scossl_tls1prf_set_ctx_params(ctx, params) &&
|
||||
scossl_tls1prf_derive(ctx->tls1prfCtx, key, keylen);
|
||||
}
|
||||
|
||||
const OSSL_PARAM *p_scossl_tls1prf_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
|
||||
{
|
||||
return p_scossl_tls1prf_gettable_ctx_param_types;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *p_scossl_tls1prf_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx)
|
||||
{
|
||||
return p_scossl_tls1prf_settable_ctx_param_types;
|
||||
}
|
||||
|
||||
SCOSSL_STATUS p_scossl_tls1prf_get_ctx_params(_In_ SCOSSL_PROV_TLS1_PRF_CTX *ctx, _Inout_ OSSL_PARAM params[])
|
||||
{
|
||||
OSSL_PARAM *p;
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL &&
|
||||
!OSSL_PARAM_set_size_t(p, SIZE_MAX))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_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;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SECRET)) != NULL &&
|
||||
!OSSL_PARAM_set_octet_string(p, ctx->tls1prfCtx->pbSecret, ctx->tls1prfCtx->cbSecret))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SEED)) != NULL &&
|
||||
!OSSL_PARAM_set_octet_string(p, ctx->tls1prfCtx->seed, ctx->tls1prfCtx->cbSeed))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
SCOSSL_STATUS p_scossl_tls1prf_set_ctx_params(_Inout_ SCOSSL_PROV_TLS1_PRF_CTX *ctx, _In_ const OSSL_PARAM params[])
|
||||
{
|
||||
PCBYTE pbSeed;
|
||||
SIZE_T cbSeed;
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL)
|
||||
{
|
||||
PCSYMCRYPT_MAC symcryptHmacAlg = NULL;
|
||||
BOOL isTlsPrf1_1 = FALSE;
|
||||
const char *paramMdName, *mdProps;
|
||||
char *mdName;
|
||||
EVP_MD *md;
|
||||
|
||||
if (!OSSL_PARAM_get_utf8_string_ptr(p, ¶mMdName))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
// Special case to always allow md5_sha1 for tls1.1 PRF compat
|
||||
if (OPENSSL_strcasecmp(paramMdName, SN_md5_sha1) != 0)
|
||||
{
|
||||
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));
|
||||
symcryptHmacAlg = scossl_get_symcrypt_hmac_algorithm(EVP_MD_type(md));
|
||||
EVP_MD_free(md);
|
||||
|
||||
if (symcryptHmacAlg == NULL)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mdName = OPENSSL_strdup(SN_md5_sha1);
|
||||
isTlsPrf1_1 = TRUE;
|
||||
}
|
||||
|
||||
OPENSSL_free(ctx->mdName);
|
||||
ctx->mdName = mdName;
|
||||
ctx->tls1prfCtx->pHmac = symcryptHmacAlg;
|
||||
ctx->tls1prfCtx->isTlsPrf1_1 = isTlsPrf1_1;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL)
|
||||
{
|
||||
PBYTE pbSecret = NULL;
|
||||
SIZE_T cbSecret = 0;
|
||||
|
||||
if (p->data_size > 0 &&
|
||||
!OSSL_PARAM_get_octet_string(p, (void **)&pbSecret, 0, &cbSecret))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
OPENSSL_clear_free(ctx->tls1prfCtx->pbSecret, ctx->tls1prfCtx->cbSecret);
|
||||
ctx->tls1prfCtx->pbSecret = pbSecret;
|
||||
ctx->tls1prfCtx->cbSecret = cbSecret;
|
||||
}
|
||||
|
||||
// Parameters may contain multiple seed params that must all be processed
|
||||
for (p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED);
|
||||
p != NULL;
|
||||
p = OSSL_PARAM_locate_const(p + 1, OSSL_KDF_PARAM_SEED))
|
||||
{
|
||||
if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pbSeed, &cbSeed))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (!scossl_tls1prf_append_seed(ctx->tls1prfCtx, pbSeed, cbSeed))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
const OSSL_DISPATCH p_scossl_tls1prf_kdf_functions[] = {
|
||||
{OSSL_FUNC_KDF_NEWCTX, (void (*)(void))p_scossl_tls1prf_newctx},
|
||||
{OSSL_FUNC_KDF_FREECTX, (void (*)(void))p_scossl_tls1prf_freectx},
|
||||
{OSSL_FUNC_KDF_DUPCTX, (void (*)(void))p_scossl_tls1prf_dupctx},
|
||||
{OSSL_FUNC_KDF_RESET, (void (*)(void))p_scossl_tls1prf_reset},
|
||||
{OSSL_FUNC_KDF_DERIVE, (void (*)(void))p_scossl_tls1prf_derive},
|
||||
{OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_tls1prf_gettable_ctx_params},
|
||||
{OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_tls1prf_settable_ctx_params},
|
||||
{OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))p_scossl_tls1prf_get_ctx_params},
|
||||
{OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))p_scossl_tls1prf_set_ctx_params},
|
||||
{0, NULL}};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -106,9 +106,9 @@ extern const OSSL_DISPATCH p_scossl_hkdf_kdf_functions[];
|
|||
extern const OSSL_DISPATCH p_scossl_tls1prf_kdf_functions[];
|
||||
|
||||
static const OSSL_ALGORITHM p_scossl_kdf[] = {
|
||||
// ALG("SSHKDF", p_scossl_sshkdf_kdf_functions),
|
||||
// ALG("HKDF", p_scossl_hkdf_kdf_functions),
|
||||
// ALG("TLS1-PRF", p_scossl_tls1prf_kdf_functions),
|
||||
ALG("SSHKDF", p_scossl_sshkdf_kdf_functions),
|
||||
ALG("HKDF", p_scossl_hkdf_kdf_functions),
|
||||
ALG("TLS1-PRF", p_scossl_tls1prf_kdf_functions),
|
||||
ALG_TABLE_END};
|
||||
|
||||
// Rand
|
||||
|
@ -252,8 +252,6 @@ SCOSSL_STATUS OSSL_provider_init(_In_ const OSSL_CORE_HANDLE *handle,
|
|||
SCOSSL_PROVCTX *p_ctx = NULL;
|
||||
OSSL_FUNC_core_get_libctx_fn *core_get_libctx = NULL;
|
||||
|
||||
*out = p_scossl_base_dispatch;
|
||||
|
||||
if (!scossl_prov_initialized)
|
||||
{
|
||||
SYMCRYPT_MODULE_INIT();
|
||||
|
@ -289,23 +287,12 @@ SCOSSL_STATUS OSSL_provider_init(_In_ const OSSL_CORE_HANDLE *handle,
|
|||
}
|
||||
}
|
||||
|
||||
p_ctx = OPENSSL_malloc(sizeof(SCOSSL_PROVCTX));
|
||||
if (p_ctx != NULL)
|
||||
{
|
||||
p_ctx->handle = handle;
|
||||
*provctx = p_ctx;
|
||||
}
|
||||
|
||||
*out = p_scossl_base_dispatch;
|
||||
|
||||
if (!scossl_prov_initialized)
|
||||
{
|
||||
SYMCRYPT_MODULE_INIT();
|
||||
scossl_prov_initialized = 1;
|
||||
}
|
||||
|
||||
scossl_setup_logging();
|
||||
|
||||
if (core_get_libctx == NULL)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
|
@ -322,6 +309,8 @@ SCOSSL_STATUS OSSL_provider_init(_In_ const OSSL_CORE_HANDLE *handle,
|
|||
p_ctx->libctx = (OSSL_LIB_CTX *)core_get_libctx(handle);
|
||||
*provctx = p_ctx;
|
||||
|
||||
*out = p_scossl_base_dispatch;
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include "scossl_helpers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Prototype definition, subject to change
|
||||
#define IMPLEMENT_SCOSSL_KDF_FUNCTIONS(alg) \
|
||||
const OSSL_DISPATCH p_scossl_##alg##_kdf_functions = { \
|
||||
{OSSL_FUNC_KDF_NEWCTX, (void (*)(void))p_scossl_##alg##_kdf_new}, \
|
||||
{OSSL_FUNC_KDF_DUPCTX, (void (*)(void))p_scossl_##alg##_kdf_dup}, \
|
||||
{OSSL_FUNC_KDF_FREECTX, (void (*)(void))p_scossl_##alg##_kdf_free}, \
|
||||
{OSSL_FUNC_KDF_RESET, (void (*)(void))p_scossl_##alg##_kdf_reset}, \
|
||||
{OSSL_FUNC_KDF_DERIVE, (void (*)(void))p_scossl_##alg##_kdf_derive}, \
|
||||
{OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_##alg##_kdf_settable_ctx_params}, \
|
||||
{OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))p_scossl_##alg##_kdf_set_ctx_params}, \
|
||||
{OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_##alg##_kdf_gettable_ctx_params}, \
|
||||
{OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))p_scossl_##alg##_kdf_get_ctx_params}, \
|
||||
{0, NULL}};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче