Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion SymCryptProvider/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/inc/p_scossl_base.h.in
${CMAKE_CURRENT_SOURCE_DIR}/inc/p_scossl_base.h)

find_package(OpenSSL REQUIRED)
find_package(OpenSSL 3.5 REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIR})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: This bumps the minimum OpenSSL requirement from any version to 3.5 globally, making the entire provider unbuildable with OpenSSL 3.0-3.4. The SKEYMGMT dispatch registration in p_scossl_base.c already uses #ifdef OSSL_OP_SKEYMGMT guards — was making 3.5 the hard minimum intentional? If not, the new source files could be conditionally compiled and the find_package left as-is.


find_library(SYMCRYPT_LIBRARY symcrypt PATHS ${CMAKE_SOURCE_DIR})
Expand Down Expand Up @@ -52,6 +52,8 @@ set(SCOSSL_SOURCES
./src/mac/p_scossl_kmac.c
./src/signature/p_scossl_ecdsa_signature.c
./src/signature/p_scossl_rsa_signature.c
./src/skeymgmt/p_scossl_aes_skeymgmt.c
./src/skeymgmt/p_scossl_generic_skeymgmt.c
./src/p_scossl_bio.c
./src/p_scossl_ecc.c
./src/p_scossl_rand.c
Expand Down
23 changes: 20 additions & 3 deletions SymCryptProvider/src/ciphers/p_scossl_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "scossl_helpers.h"
#include "p_scossl_base.h"
#include "p_scossl_aes.h"
#include "p_scossl_skey.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -148,12 +149,26 @@ static SCOSSL_STATUS p_scossl_aes_generic_decrypt_init(_Inout_ SCOSSL_AES_CTX *c
return p_scossl_aes_generic_init_internal(ctx, FALSE, key, keylen, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_generic_skey_encrypt_init(_Inout_ SCOSSL_AES_CTX *ctx, _In_ SCOSSL_SKEY *skey,
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_generic_init_internal(ctx, TRUE, skey->pbKey, skey->cbKey, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_generic_skey_decrypt_init(_Inout_ SCOSSL_AES_CTX *ctx, _In_ SCOSSL_SKEY *skey,
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_generic_init_internal(ctx, FALSE, skey->pbKey, skey->cbKey, iv, ivlen, params);
}

#define SYMCRYPT_OPENSSL_MASK8_SELECT( _mask, _a, _b ) (SYMCRYPT_FORCE_READ8(&_mask) & _a) | (~(SYMCRYPT_FORCE_READ8(&_mask)) & _b)

// Verifies the TLS padding from the end of record, extracts the MAC from the end of
// the unpadded record, and saves the result to ctx->tlsMac.
//
// If ctx->tlsMacSize is 0 (in the case of encrypt-then-mac), no MAC is extracted,
// the unpadded record, and saves the result to ctx->tlsMac.
//
// If ctx->tlsMacSize is 0 (in the case of encrypt-then-mac), no MAC is extracted,
// but the padding is still verified and removed.
//
// The MAC will later be fetched through p_scossl_aes_generic_get_ctx_params
Expand Down Expand Up @@ -1028,6 +1043,8 @@ static SCOSSL_STATUS scossl_aes_cfb8_cipher(_Inout_ SCOSSL_AES_CTX *ctx,
{OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (void (*)(void))p_scossl_aes_generic_gettable_params}, \
{OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_aes_generic_gettable_ctx_params}, \
{OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_aes_generic_settable_ctx_params}, \
{OSSL_FUNC_CIPHER_ENCRYPT_SKEY_INIT, (void (*)(void))p_scossl_aes_generic_skey_encrypt_init}, \
{OSSL_FUNC_CIPHER_DECRYPT_SKEY_INIT, (void (*)(void))p_scossl_aes_generic_skey_decrypt_init}, \
{0, NULL}};

IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(128, SYMCRYPT_AES_BLOCK_SIZE, cbc, CBC, block, SYMCRYPT_AES_BLOCK_SIZE)
Expand Down
31 changes: 31 additions & 0 deletions SymCryptProvider/src/ciphers/p_scossl_aes_aead.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "scossl_aes_aead.h"
#include "p_scossl_aes.h"
#include "p_scossl_skey.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -115,6 +116,20 @@ static SCOSSL_STATUS p_scossl_aes_gcm_decrypt_init(_Inout_ SCOSSL_CIPHER_GCM_CTX
return p_scossl_aes_gcm_init_internal(ctx, 0, key, keylen, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_gcm_skey_encrypt_init(_Inout_ void *ctx, _In_ SCOSSL_SKEY *skey,
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_gcm_init_internal(ctx, 1, skey->pbKey, skey->cbKey, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_gcm_skey_decrypt_init(_Inout_ void *ctx, _In_ SCOSSL_SKEY *skey,
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_gcm_init_internal(ctx, 0, skey->pbKey, skey->cbKey, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_gcm_final(_Inout_ SCOSSL_CIPHER_GCM_CTX *ctx,
_Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, ossl_unused size_t outsize)
{
Expand Down Expand Up @@ -372,6 +387,20 @@ static SCOSSL_STATUS p_scossl_aes_ccm_decrypt_init(_Inout_ SCOSSL_CIPHER_CCM_CTX
return p_scossl_aes_ccm_init_internal(ctx, 0, key, keylen, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_ccm_skey_encrypt_init(_Inout_ void *ctx, _In_ SCOSSL_SKEY *skey,
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_ccm_init_internal(ctx, 1, skey->pbKey, skey->cbKey, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_ccm_skey_decrypt_init(_Inout_ void *ctx, _In_ SCOSSL_SKEY *skey,
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_ccm_init_internal(ctx, 0, skey->pbKey, skey->cbKey, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_ccm_final(_Inout_ SCOSSL_CIPHER_CCM_CTX *ctx,
_Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, ossl_unused size_t outsize)
{
Expand Down Expand Up @@ -579,6 +608,8 @@ static SCOSSL_STATUS p_scossl_aes_ccm_set_ctx_params(_Inout_ SCOSSL_CIPHER_CCM_C
{OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (void (*)(void))p_scossl_aes_generic_gettable_params}, \
{OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_aes_##lcmode##_gettable_ctx_params}, \
{OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_aes_##lcmode##_settable_ctx_params}, \
{OSSL_FUNC_CIPHER_ENCRYPT_SKEY_INIT, (void (*)(void))p_scossl_aes_##lcmode##_skey_encrypt_init}, \
{OSSL_FUNC_CIPHER_DECRYPT_SKEY_INIT, (void (*)(void))p_scossl_aes_##lcmode##_skey_decrypt_init}, \
{0, NULL}};

IMPLEMENT_SCOSSL_AES_AEAD_CIPHER(128, SCOSSL_GCM_DEFAULT_IV_LENGTH, gcm, GCM)
Expand Down
16 changes: 16 additions & 0 deletions SymCryptProvider/src/ciphers/p_scossl_aes_xts.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "scossl_helpers.h"
#include "p_scossl_aes.h"
#include "p_scossl_skey.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -120,6 +121,19 @@ static SCOSSL_STATUS p_scossl_aes_xts_decrypt_init(_Inout_ SCOSSL_AES_XTS_CTX *c
return p_scossl_aes_xts_init_internal(ctx, 0, key, keylen, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_xts_skey_encrypt_init(_Inout_ SCOSSL_AES_XTS_CTX *ctx, _In_ SCOSSL_SKEY *skey,
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_xts_init_internal((SCOSSL_AES_XTS_CTX *)ctx, 1, skey->pbKey, skey->cbKey, iv, ivlen, params);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Redundant cast — ctx is already declared as SCOSSL_AES_XTS_CTX *ctx in the function signature, so (SCOSSL_AES_XTS_CTX *)ctx is unnecessary.


static SCOSSL_STATUS p_scossl_aes_xts_skey_decrypt_init(_Inout_ SCOSSL_AES_XTS_CTX *ctx, _In_ SCOSSL_SKEY *skey,
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_xts_init_internal((SCOSSL_AES_XTS_CTX *)ctx, 0, skey->pbKey, skey->cbKey, iv, ivlen, params);
}

static SCOSSL_STATUS p_scossl_aes_xts_cipher(SCOSSL_AES_XTS_CTX *ctx,
_Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize,
Expand Down Expand Up @@ -274,6 +288,8 @@ static SCOSSL_STATUS p_scossl_aes_xts_set_ctx_params(_Inout_ SCOSSL_AES_XTS_CTX
{OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (void (*)(void))p_scossl_aes_generic_gettable_params}, \
{OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_aes_xts_gettable_ctx_params}, \
{OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_aes_xts_settable_ctx_params}, \
{OSSL_FUNC_CIPHER_ENCRYPT_SKEY_INIT, (void (*)(void))p_scossl_aes_xts_skey_encrypt_init}, \
{OSSL_FUNC_CIPHER_DECRYPT_SKEY_INIT, (void (*)(void))p_scossl_aes_xts_skey_decrypt_init}, \
{0, NULL}};

IMPLEMENT_SCOSSL_AES_XTS_CIPHER(128)
Expand Down
10 changes: 10 additions & 0 deletions SymCryptProvider/src/mac/p_scossl_cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "scossl_mac.h"
#include "p_scossl_base.h"
#include "p_scossl_skey.h"

#include <openssl/proverr.h>

Expand Down Expand Up @@ -44,6 +45,14 @@ static SCOSSL_STATUS p_scossl_cmac_init(_Inout_ SCOSSL_MAC_CTX *ctx,

}

static SCOSSL_STATUS p_scossl_cmac_init_skey(_Inout_ void *ctx,
_In_ SCOSSL_SKEY *skey,
_In_ const OSSL_PARAM params[])
{
return p_scossl_cmac_set_ctx_params(ctx, params) &&
scossl_mac_init(ctx, skey->pbKey, skey->cbKey);
}

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;
Expand Down Expand Up @@ -130,6 +139,7 @@ const OSSL_DISPATCH p_scossl_cmac_functions[] = {
{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_INIT_SKEY, (void (*)(void))p_scossl_cmac_init_skey},
{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},
Expand Down
15 changes: 15 additions & 0 deletions SymCryptProvider/src/p_scossl_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,17 @@ static const OSSL_ALGORITHM p_scossl_encoder[] = {
ENCODER_ENTRIES_ALL(SCOSSL_LN_MLKEM1024, mlkem1024)
ALG_TABLE_END};

// Symmetric key management
#ifdef OSSL_OP_SKEYMGMT
extern const OSSL_DISPATCH p_scossl_aes_skeymgmt_functions[];
extern const OSSL_DISPATCH p_scossl_generic_skeymgmt_functions[];

static const OSSL_ALGORITHM p_scossl_skeymgmt[] = {
ALG("AES", p_scossl_aes_skeymgmt_functions),
ALG("GENERIC-SECRET", p_scossl_generic_skeymgmt_functions),
ALG_TABLE_END};
#endif // OSSL_OP_SKEYMGMT

static SCOSSL_STATUS p_scossl_register_extended_algorithms()
{
return p_scossl_mlkem_register_algorithms();
Expand Down Expand Up @@ -609,6 +620,10 @@ static const OSSL_ALGORITHM *p_scossl_query_operation(ossl_unused void *provctx,
return p_scossl_decoder;
case OSSL_OP_ENCODER:
return p_scossl_encoder;
#ifdef OSSL_OP_SKEYMGMT
case OSSL_OP_SKEYMGMT:
return p_scossl_skeymgmt;
#endif
}

return NULL;
Expand Down
28 changes: 28 additions & 0 deletions SymCryptProvider/src/p_scossl_skey.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//

#pragma once

#include "scossl_helpers.h"

#ifdef __cplusplus
extern "C" {
#endif

#define SCOSSL_SKEY_TYPE_GENERIC 1
#define SCOSSL_SKEY_TYPE_AES 2

typedef struct
{
int type;

OSSL_LIB_CTX *libctx;

PBYTE pbKey;
SIZE_T cbKey;
} SCOSSL_SKEY;

#ifdef __cplusplus
}
#endif
91 changes: 91 additions & 0 deletions SymCryptProvider/src/skeymgmt/p_scossl_aes_skeymgmt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//

#include <openssl/proverr.h>

#include "p_scossl_generic_skeymgmt.h"

#ifdef __cplusplus
extern "C" {
#endif

static const OSSL_PARAM p_scossl_aes_skeymgmt_settable_param_types[] = {
OSSL_PARAM_octet_string(OSSL_SKEY_PARAM_RAW_BYTES, NULL, 0),
OSSL_PARAM_END};

static const OSSL_PARAM p_scossl_aes_skeygen_settable_param_types[] = {
OSSL_PARAM_size_t(OSSL_SKEY_PARAM_KEY_LENGTH, NULL),
OSSL_PARAM_END};

static SCOSSL_SKEY *p_scossl_aes_skeymgmt_import(_In_ SCOSSL_PROVCTX *provctx, int selection, _In_ const OSSL_PARAM params[])
{
SCOSSL_SKEY *skey = p_scossl_generic_skeymgmt_import(provctx, selection, params);

if (skey != NULL)
{
skey->type = SCOSSL_SKEY_TYPE_AES;

if (skey->cbKey != 16 && skey->cbKey != 24 && skey->cbKey != 32)
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: AES key length is validated after p_scossl_generic_skeymgmt_import has already allocated secure memory and copied the key material. For invalid lengths, the key is allocated, copied, then immediately freed. Consider validating the length from the OSSL_PARAM before calling the generic import to avoid the wasted OPENSSL_secure_malloc + memcpy. Same applies to p_scossl_aes_skeygen_generate below — SymCryptRandom is called for invalid lengths.

ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
p_scossl_generic_skeymgmt_free(skey);
skey = NULL;
}
}

return skey;
}

static SCOSSL_STATUS p_scossl_aes_skeymgmt_export(_In_ SCOSSL_SKEY *skey, int selection,
_In_ OSSL_CALLBACK *param_cb, _In_ void *cbarg)
{
if (skey->type != SCOSSL_SKEY_TYPE_AES)
{
return SCOSSL_FAILURE;
}

return p_scossl_generic_skeymgmt_export(skey, selection, param_cb, cbarg);
}

static SCOSSL_SKEY *p_scossl_aes_skeygen_generate(_In_ SCOSSL_PROVCTX *provctx, _In_ const OSSL_PARAM params[])
{
SCOSSL_SKEY *skey = p_scossl_generic_skeygen_generate(provctx, params);

if (skey != NULL)
{
skey->type = SCOSSL_SKEY_TYPE_AES;

if (skey->cbKey != 16 && skey->cbKey != 24 && skey->cbKey != 32)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
p_scossl_generic_skeymgmt_free(skey);
skey = NULL;
}
}

return skey;
}

static const OSSL_PARAM *p_scossl_aes_skeymgmt_imp_settable_params(ossl_unused void *provctx)
{
return p_scossl_aes_skeymgmt_settable_param_types;
}

static const OSSL_PARAM *p_scossl_aes_skeygen_settable_params(ossl_unused void *provctx)
{
return p_scossl_aes_skeygen_settable_param_types;
}

const OSSL_DISPATCH p_scossl_aes_skeymgmt_functions[] = {
{OSSL_FUNC_SKEYMGMT_FREE, (void (*)(void))p_scossl_generic_skeymgmt_free},
{OSSL_FUNC_SKEYMGMT_IMPORT, (void (*)(void))p_scossl_aes_skeymgmt_import},
{OSSL_FUNC_SKEYMGMT_EXPORT, (void (*)(void))p_scossl_aes_skeymgmt_export},
{OSSL_FUNC_SKEYMGMT_GENERATE, (void (*)(void))p_scossl_aes_skeygen_generate},
{OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS, (void (*)(void))p_scossl_aes_skeymgmt_imp_settable_params},
{OSSL_FUNC_SKEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))p_scossl_aes_skeygen_settable_params},
{0, NULL}};

#ifdef __cplusplus
}
#endif
Loading
Loading