Properly support restricted PSS keys (#75)

* Properly support restricted PSS keys

* PR comments
This commit is contained in:
Maxwell McKee 2024-03-05 16:01:02 -08:00 коммит произвёл GitHub
Родитель 571dfb06bb
Коммит c2cb7fdc5b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
11 изменённых файлов: 527 добавлений и 173 удалений

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

@ -8,12 +8,6 @@
extern "C" {
#endif
typedef struct
{
int initialized;
PSYMCRYPT_RSAKEY key;
} SCOSSL_RSA_KEY_CTX;
typedef struct
{
BIGNUM *p;
@ -31,29 +25,26 @@ typedef struct
SCOSSL_RSA_PRIVATE_EXPORT_PARAMS *privateParams;
} SCOSSL_RSA_EXPORT_PARAMS;
SCOSSL_RSA_KEY_CTX *scossl_rsa_new_key_ctx();
void scossl_rsa_free_key_ctx(_In_ SCOSSL_RSA_KEY_CTX *keyCtx);
SCOSSL_STATUS scossl_rsa_pkcs1_sign(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid,
SCOSSL_STATUS scossl_rsa_pkcs1_sign(_In_ PSYMCRYPT_RSAKEY key, int mdnid,
_In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue,
_Out_writes_bytes_(*pcbSignature) PBYTE pbSignature, _Out_ SIZE_T* pcbSignature);
SCOSSL_STATUS scossl_rsa_pkcs1_verify(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid,
SCOSSL_STATUS scossl_rsa_pkcs1_verify(_In_ PSYMCRYPT_RSAKEY key, int mdnid,
_In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue,
_In_reads_bytes_(pcbSignature) PCBYTE pbSignature, SIZE_T pcbSignature);
SCOSSL_STATUS scossl_rsapss_sign(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cbSalt,
SCOSSL_STATUS scossl_rsapss_sign(_In_ PSYMCRYPT_RSAKEY key, int mdnid, int cbSalt,
_In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue,
_Out_writes_bytes_(*pcbSignature) PBYTE pbSignature, _Out_ SIZE_T* pcbSignature);
SCOSSL_STATUS scossl_rsapss_verify(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, _In_ int mdnid, int cbSalt,
SCOSSL_STATUS scossl_rsapss_verify(_In_ PSYMCRYPT_RSAKEY key, int mdnid, int cbSalt,
_In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue,
_In_reads_bytes_(pcbSignature) PCBYTE pbSignature, SIZE_T pcbSignature);
SCOSSL_STATUS scossl_rsa_encrypt(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
SCOSSL_STATUS scossl_rsa_encrypt(_In_ PSYMCRYPT_RSAKEY key, UINT padding,
int mdnid, _In_reads_bytes_opt_(cbLabel) PCBYTE pbLabel, SIZE_T cbLabel,
_In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc,
_Out_writes_bytes_(*pcbDst) PBYTE pbDst, _Out_ INT32 *pcbDst, SIZE_T cbDst);
SCOSSL_STATUS scossl_rsa_decrypt(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
SCOSSL_STATUS scossl_rsa_decrypt(_In_ PSYMCRYPT_RSAKEY key, UINT padding,
int mdnid, _In_reads_bytes_opt_(cbLabel) PCBYTE pbLabel, SIZE_T cbLabel,
_In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc,
_Out_writes_bytes_(*pcbDst) PBYTE pbDst, _Out_ INT32 *pcbDst, SIZE_T cbDst);

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

@ -87,30 +87,12 @@ static SIZE_T scossl_get_expected_hash_length(int mdnid)
return -1;
}
SCOSSL_RSA_KEY_CTX *scossl_rsa_new_key_ctx()
{
return OPENSSL_zalloc(sizeof(SCOSSL_RSA_KEY_CTX));
}
_Use_decl_annotations_
void scossl_rsa_free_key_ctx(SCOSSL_RSA_KEY_CTX *keyCtx)
{
if (keyCtx == NULL)
return;
if (keyCtx->key != NULL)
{
SymCryptRsakeyFree(keyCtx->key);
}
OPENSSL_free(keyCtx);
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_rsa_pkcs1_sign(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid,
SCOSSL_STATUS scossl_rsa_pkcs1_sign(PSYMCRYPT_RSAKEY key, int mdnid,
PCBYTE pbHashValue, SIZE_T cbHashValue,
PBYTE pbSignature, SIZE_T *pcbSignature)
{
UINT32 cbModulus = SymCryptRsakeySizeofModulus(keyCtx->key);
UINT32 cbModulus = SymCryptRsakeySizeofModulus(key);
SCOSSL_STATUS ret = SCOSSL_FAILURE;
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
const SCOSSL_RSA_PKCS1_PARAMS *pkcs1Params;
@ -151,7 +133,7 @@ SCOSSL_STATUS scossl_rsa_pkcs1_sign(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid,
}
scError = SymCryptRsaPkcs1Sign(
keyCtx->key,
key,
pbHashValue,
cbHashValue,
pkcs1Params->pHashOIDs,
@ -176,7 +158,7 @@ cleanup:
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_rsa_pkcs1_verify(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid,
SCOSSL_STATUS scossl_rsa_pkcs1_verify(PSYMCRYPT_RSAKEY key, int mdnid,
PCBYTE pbHashValue, SIZE_T cbHashValue,
PCBYTE pbSignature, SIZE_T pcbSignature)
{
@ -213,7 +195,7 @@ SCOSSL_STATUS scossl_rsa_pkcs1_verify(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid,
}
scError = SymCryptRsaPkcs1Verify(
keyCtx->key,
key,
pbHashValue,
cbHashValue,
pbSignature,
@ -238,7 +220,7 @@ cleanup:
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_rsapss_sign(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cbSalt,
SCOSSL_STATUS scossl_rsapss_sign(PSYMCRYPT_RSAKEY key, int mdnid, int cbSalt,
PCBYTE pbHashValue, SIZE_T cbHashValue,
PBYTE pbSignature, SIZE_T *pcbSignature)
{
@ -256,7 +238,7 @@ SCOSSL_STATUS scossl_rsapss_sign(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cbSa
goto cleanup;
}
cbSaltMax = ((SymCryptRsakeyModulusBits(keyCtx->key) + 6) / 8) - cbHashValue - 2; // ceil((ModulusBits - 1) / 8) - cbDigest - 2
cbSaltMax = ((SymCryptRsakeyModulusBits(key) + 6) / 8) - cbHashValue - 2; // ceil((ModulusBits - 1) / 8) - cbDigest - 2
switch (cbSalt)
{
case RSA_PSS_SALTLEN_DIGEST:
@ -280,7 +262,7 @@ SCOSSL_STATUS scossl_rsapss_sign(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cbSa
return SCOSSL_UNSUPPORTED;
}
cbResult = SymCryptRsakeySizeofModulus(keyCtx->key);
cbResult = SymCryptRsakeySizeofModulus(key);
if (pcbSignature == NULL)
{
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_RSAPSS_SIGN, ERR_R_PASSED_NULL_PARAMETER,
@ -314,7 +296,7 @@ SCOSSL_STATUS scossl_rsapss_sign(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cbSa
}
scError = SymCryptRsaPssSign(
keyCtx->key,
key,
pbHashValue,
cbHashValue,
scosslHashAlgo,
@ -338,7 +320,7 @@ cleanup:
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_rsapss_verify(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cbSalt,
SCOSSL_STATUS scossl_rsapss_verify(PSYMCRYPT_RSAKEY key, int mdnid, int cbSalt,
PCBYTE pbHashValue, SIZE_T cbHashValue,
PCBYTE pbSignature, SIZE_T pcbSignature)
{
@ -361,7 +343,7 @@ SCOSSL_STATUS scossl_rsapss_verify(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cb
goto cleanup;
}
cbSaltMax = ((SymCryptRsakeyModulusBits(keyCtx->key) + 6) / 8) - cbHashValue - 2; // ceil((ModulusBits - 1) / 8) - cbDigest - 2
cbSaltMax = ((SymCryptRsakeyModulusBits(key) + 6) / 8) - cbHashValue - 2; // ceil((ModulusBits - 1) / 8) - cbDigest - 2
switch (cbSalt)
{
case RSA_PSS_SALTLEN_DIGEST:
@ -404,7 +386,7 @@ SCOSSL_STATUS scossl_rsapss_verify(SCOSSL_RSA_KEY_CTX *keyCtx, int mdnid, int cb
}
scError = SymCryptRsaPssVerify(
keyCtx->key,
key,
pbHashValue,
cbHashValue,
pbSignature,
@ -429,14 +411,14 @@ cleanup:
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_rsa_encrypt(SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
SCOSSL_STATUS scossl_rsa_encrypt(PSYMCRYPT_RSAKEY key, UINT padding,
int mdnid, PCBYTE pbLabel, SIZE_T cbLabel, // OAEP-only parameters
PCBYTE pbSrc, SIZE_T cbSrc,
PBYTE pbDst, INT32 *pcbDst, SIZE_T cbDst)
{
SCOSSL_STATUS ret = SCOSSL_FAILURE;
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
UINT32 cbModulus = SymCryptRsakeySizeofModulus(keyCtx->key);
UINT32 cbModulus = SymCryptRsakeySizeofModulus(key);
SIZE_T cbResult = -1;
if (pbDst == NULL)
@ -464,7 +446,7 @@ SCOSSL_STATUS scossl_rsa_encrypt(SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
goto cleanup;
}
scError = SymCryptRsaPkcs1Encrypt(
keyCtx->key,
key,
pbSrc,
cbSrc,
0,
@ -494,7 +476,7 @@ SCOSSL_STATUS scossl_rsa_encrypt(SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
}
scError = SymCryptRsaOaepEncrypt(
keyCtx->key,
key,
pbSrc,
cbSrc,
scosslHashAlgo,
@ -518,7 +500,7 @@ SCOSSL_STATUS scossl_rsa_encrypt(SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
goto cleanup;
}
scError = SymCryptRsaRawEncrypt(
keyCtx->key,
key,
pbSrc,
cbSrc,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
@ -547,7 +529,7 @@ cleanup:
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_rsa_decrypt(SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
SCOSSL_STATUS scossl_rsa_decrypt(PSYMCRYPT_RSAKEY key, UINT padding,
int mdnid, PCBYTE pbLabel, SIZE_T cbLabel, // OAEP-only parameters
PCBYTE pbSrc, SIZE_T cbSrc,
PBYTE pbDst, INT32 *pcbDst, SIZE_T cbDst)
@ -559,7 +541,7 @@ SCOSSL_STATUS scossl_rsa_decrypt(SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
UINT64 err = 0;
SIZE_T cbResult = -1;
cbModulus = SymCryptRsakeySizeofModulus(keyCtx->key);
cbModulus = SymCryptRsakeySizeofModulus(key);
if (pbDst == NULL)
{
@ -584,7 +566,7 @@ SCOSSL_STATUS scossl_rsa_decrypt(SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
{
case RSA_PKCS1_PADDING:
scError = SymCryptRsaPkcs1Decrypt(
keyCtx->key,
key,
pbSrc,
cbSrc,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
@ -618,7 +600,7 @@ SCOSSL_STATUS scossl_rsa_decrypt(SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
}
scError = SymCryptRsaOaepDecrypt(
keyCtx->key,
key,
pbSrc,
cbSrc,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
@ -638,7 +620,7 @@ SCOSSL_STATUS scossl_rsa_decrypt(SCOSSL_RSA_KEY_CTX *keyCtx, UINT padding,
break;
case RSA_NO_PADDING:
scError = SymCryptRsaRawDecrypt(
keyCtx->key,
key,
pbSrc,
cbSrc,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,

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

@ -31,7 +31,7 @@ SCOSSL_RETURNLENGTH e_scossl_rsa_pub_enc(int flen, _In_reads_bytes_(flen) const
int ret = -1;
const RSA_METHOD *ossl_rsa_meth = NULL;
PFN_RSA_meth_pub_enc pfn_rsa_meth_pub_enc = NULL;
SCOSSL_RSA_KEY_CTX *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
SCOSSL_RSA_KEY_CONTEXT *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
if( keyCtx == NULL )
{
@ -57,7 +57,7 @@ SCOSSL_RETURNLENGTH e_scossl_rsa_pub_enc(int flen, _In_reads_bytes_(flen) const
case RSA_PKCS1_PADDING:
case RSA_PKCS1_OAEP_PADDING:
case RSA_NO_PADDING:
scossl_rsa_encrypt(keyCtx, padding, NID_sha1, NULL, 0, from, flen, to, &ret, -1);
scossl_rsa_encrypt(keyCtx->key, padding, NID_sha1, NULL, 0, from, flen, to, &ret, -1);
break;
default:
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSA_PUB_ENC, SCOSSL_ERR_R_OPENSSL_FALLBACK,
@ -81,7 +81,7 @@ SCOSSL_RETURNLENGTH e_scossl_rsa_priv_dec(int flen, _In_reads_bytes_(flen) const
int ret = -1;
const RSA_METHOD *ossl_rsa_meth = NULL;
PFN_RSA_meth_priv_dec pfn_rsa_meth_priv_dec = NULL;
SCOSSL_RSA_KEY_CTX *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
SCOSSL_RSA_KEY_CONTEXT *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
if( keyCtx == NULL )
{
@ -107,7 +107,7 @@ SCOSSL_RETURNLENGTH e_scossl_rsa_priv_dec(int flen, _In_reads_bytes_(flen) const
case RSA_PKCS1_PADDING:
case RSA_PKCS1_OAEP_PADDING:
case RSA_NO_PADDING:
scossl_rsa_decrypt(keyCtx, padding, NID_sha1, NULL, 0, from, flen, to, &ret, -1);
scossl_rsa_decrypt(keyCtx->key, padding, NID_sha1, NULL, 0, from, flen, to, &ret, -1);
break;
default:
SCOSSL_LOG_INFO(SCOSSL_ERR_F_RSA_PRIV_DEC, SCOSSL_ERR_R_OPENSSL_FALLBACK,
@ -162,7 +162,7 @@ SCOSSL_STATUS e_scossl_rsa_sign(int type, _In_reads_bytes_(m_length) const unsig
_Out_writes_bytes_(siglen) unsigned char* sigret, _Out_ unsigned int* siglen,
_In_ const RSA* rsa)
{
SCOSSL_RSA_KEY_CTX *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
SCOSSL_RSA_KEY_CONTEXT *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
if( keyCtx == NULL )
{
@ -178,7 +178,7 @@ SCOSSL_STATUS e_scossl_rsa_sign(int type, _In_reads_bytes_(m_length) const unsig
}
}
return scossl_rsa_pkcs1_sign(keyCtx, type, m, m_length, sigret, (SIZE_T*)siglen);
return scossl_rsa_pkcs1_sign(keyCtx->key, type, m, m_length, sigret, (SIZE_T*)siglen);
}
SCOSSL_STATUS e_scossl_rsa_verify(int dtype, _In_reads_bytes_(m_length) const unsigned char* m,
@ -186,7 +186,7 @@ SCOSSL_STATUS e_scossl_rsa_verify(int dtype, _In_reads_bytes_(m_length) const un
_In_reads_bytes_(siglen) const unsigned char* sigbuf,
unsigned int siglen, _In_ const RSA* rsa)
{
SCOSSL_RSA_KEY_CTX *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
SCOSSL_RSA_KEY_CONTEXT *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
if( keyCtx == NULL )
{
@ -202,7 +202,7 @@ SCOSSL_STATUS e_scossl_rsa_verify(int dtype, _In_reads_bytes_(m_length) const un
}
}
return scossl_rsa_pkcs1_verify(keyCtx, dtype, m, m_length, sigbuf, siglen);
return scossl_rsa_pkcs1_verify(keyCtx->key, dtype, m, m_length, sigbuf, siglen);
}
SCOSSL_STATUS e_scossl_rsa_keygen(_Out_ RSA* rsa, int bits, _In_ BIGNUM* e,
@ -212,7 +212,7 @@ SCOSSL_STATUS e_scossl_rsa_keygen(_Out_ RSA* rsa, int bits, _In_ BIGNUM* e,
SYMCRYPT_RSA_PARAMS SymcryptRsaParam;
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
int ret = SCOSSL_FAILURE;
SCOSSL_RSA_KEY_CTX *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
SCOSSL_RSA_KEY_CONTEXT *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
SCOSSL_RSA_EXPORT_PARAMS *rsaParams = NULL;
if( keyCtx == NULL )
@ -284,7 +284,7 @@ cleanup:
return ret;
}
SCOSSL_STATUS e_scossl_initialize_rsa_key(_In_ const RSA* rsa, _Out_ SCOSSL_RSA_KEY_CTX *keyCtx)
SCOSSL_STATUS e_scossl_initialize_rsa_key(_In_ const RSA* rsa, _Out_ SCOSSL_RSA_KEY_CONTEXT *keyCtx)
{
int ret = SCOSSL_FAILURE;
UINT64 pubExp64;
@ -477,7 +477,7 @@ SCOSSL_STATUS e_scossl_rsa_bn_mod_exp(_Out_ BIGNUM* r, _In_ const BIGNUM* a, _In
SCOSSL_STATUS e_scossl_rsa_init(_Inout_ RSA *rsa)
{
SCOSSL_RSA_KEY_CTX *keyCtx = OPENSSL_zalloc(sizeof(*keyCtx));
SCOSSL_RSA_KEY_CONTEXT *keyCtx = OPENSSL_zalloc(sizeof(*keyCtx));
if( !keyCtx )
{
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_RSA_INIT, ERR_R_MALLOC_FAILURE,
@ -496,7 +496,7 @@ SCOSSL_STATUS e_scossl_rsa_init(_Inout_ RSA *rsa)
return SCOSSL_SUCCESS;
}
void e_scossl_rsa_free_key_context(_In_ SCOSSL_RSA_KEY_CTX *keyCtx)
void e_scossl_rsa_free_key_context(_In_ SCOSSL_RSA_KEY_CONTEXT *keyCtx)
{
if( keyCtx->key )
{
@ -509,7 +509,7 @@ void e_scossl_rsa_free_key_context(_In_ SCOSSL_RSA_KEY_CTX *keyCtx)
SCOSSL_STATUS e_scossl_rsa_finish(_Inout_ RSA *rsa)
{
SCOSSL_RSA_KEY_CTX *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
SCOSSL_RSA_KEY_CONTEXT *keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx);
if( keyCtx )
{
if( keyCtx->initialized == 1 )

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

@ -89,12 +89,17 @@ SCOSSL_STATUS e_scossl_rsa_init(_Inout_ RSA *rsa);
// Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error
SCOSSL_STATUS e_scossl_rsa_finish(_Inout_ RSA *rsa);
typedef struct _SCOSSL_RSA_KEY_CONTEXT {
int initialized;
PSYMCRYPT_RSAKEY key;
} SCOSSL_RSA_KEY_CONTEXT;
// Initializes keyCtx from key rsa.
// Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error
SCOSSL_STATUS e_scossl_initialize_rsa_key(_In_ const RSA* rsa, _Out_ SCOSSL_RSA_KEY_CTX *keyCtx);
SCOSSL_STATUS e_scossl_initialize_rsa_key(_In_ const RSA* rsa, _Out_ SCOSSL_RSA_KEY_CONTEXT *keyCtx);
// Frees data and key of keyCtx
void e_scossl_rsa_free_key_context(_In_ SCOSSL_RSA_KEY_CTX *keyCtx);
void e_scossl_rsa_free_key_context(_In_ SCOSSL_RSA_KEY_CONTEXT *keyCtx);
#ifdef __cplusplus
}

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

@ -15,7 +15,7 @@ SCOSSL_STATUS e_scossl_rsapss_sign(_Inout_ EVP_PKEY_CTX *ctx, _Out_writes_opt_(*
{
EVP_PKEY* pkey = NULL;
const RSA* rsa = NULL;
SCOSSL_RSA_KEY_CTX *keyCtx = NULL;
SCOSSL_RSA_KEY_CONTEXT *keyCtx = NULL;
const EVP_MD *messageDigest;
const EVP_MD *mgf1Digest;
int type = 0;
@ -72,7 +72,7 @@ SCOSSL_STATUS e_scossl_rsapss_sign(_Inout_ EVP_PKEY_CTX *ctx, _Out_writes_opt_(*
}
}
return scossl_rsapss_sign(keyCtx, type, cbSalt, tbs, tbslen, sig, (SIZE_T*)siglen);
return scossl_rsapss_sign(keyCtx->key, type, cbSalt, tbs, tbslen, sig, (SIZE_T*)siglen);
}
SCOSSL_STATUS e_scossl_rsapss_verify(_Inout_ EVP_PKEY_CTX *ctx, _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen,
@ -80,7 +80,7 @@ SCOSSL_STATUS e_scossl_rsapss_verify(_Inout_ EVP_PKEY_CTX *ctx, _In_reads_bytes_
{
EVP_PKEY* pkey = NULL;
const RSA* rsa = NULL;
SCOSSL_RSA_KEY_CTX *keyCtx = NULL;
SCOSSL_RSA_KEY_CONTEXT *keyCtx = NULL;
const EVP_MD *messageDigest;
const EVP_MD *mgf1Digest;
int type = 0;
@ -142,7 +142,7 @@ SCOSSL_STATUS e_scossl_rsapss_verify(_Inout_ EVP_PKEY_CTX *ctx, _In_reads_bytes_
return SCOSSL_FAILURE;
}
return scossl_rsapss_verify(keyCtx, type, cbSalt, tbs, tbslen, sig, siglen);
return scossl_rsapss_verify(keyCtx->key, type, cbSalt, tbs, tbslen, sig, siglen);
}

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

@ -19,7 +19,7 @@ typedef struct
{
OSSL_LIB_CTX *libctx;
SCOSSL_RSA_KEY_CTX *keyCtx;
SCOSSL_PROV_RSA_KEY_CTX *keyCtx;
UINT padding;
// OAEP Parameters
@ -53,9 +53,9 @@ static OSSL_ITEM p_scossl_rsa_cipher_padding_modes[] = {
{RSA_PKCS1_OAEP_PADDING, OSSL_PKEY_RSA_PAD_MODE_OAEP},
{0, NULL}};
SCOSSL_STATUS p_scossl_rsa_cipher_set_ctx_params(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx, _In_ const OSSL_PARAM params[]);
static SCOSSL_STATUS p_scossl_rsa_cipher_set_ctx_params(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx, _In_ const OSSL_PARAM params[]);
SCOSSL_RSA_CIPHER_CTX *p_scossl_rsa_cipher_newctx(_In_ SCOSSL_PROVCTX *provctx)
static SCOSSL_RSA_CIPHER_CTX *p_scossl_rsa_cipher_newctx(_In_ SCOSSL_PROVCTX *provctx)
{
SCOSSL_RSA_CIPHER_CTX *ctx = OPENSSL_zalloc(sizeof(SCOSSL_RSA_CIPHER_CTX));
if (ctx != NULL)
@ -66,7 +66,7 @@ SCOSSL_RSA_CIPHER_CTX *p_scossl_rsa_cipher_newctx(_In_ SCOSSL_PROVCTX *provctx)
return ctx;
}
void p_scossl_rsa_cipher_freectx(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx)
static void p_scossl_rsa_cipher_freectx(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx)
{
if (ctx != NULL)
{
@ -75,19 +75,13 @@ void p_scossl_rsa_cipher_freectx(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx)
OPENSSL_free(ctx);
}
SCOSSL_RSA_CIPHER_CTX *p_scossl_rsa_cipher_dupctx(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx)
static SCOSSL_RSA_CIPHER_CTX *p_scossl_rsa_cipher_dupctx(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx)
{
SCOSSL_RSA_CIPHER_CTX* copyCtx = OPENSSL_malloc(sizeof(SCOSSL_RSA_CIPHER_CTX));
if (copyCtx != NULL)
{
memcpy(copyCtx, ctx, sizeof(SCOSSL_RSA_CIPHER_CTX));
}
return copyCtx;
return OPENSSL_memdup(ctx, sizeof(SCOSSL_RSA_CIPHER_CTX));
}
SCOSSL_STATUS p_scossl_rsa_cipher_init(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx, _In_ SCOSSL_RSA_KEY_CTX *keyCtx,
_In_ const OSSL_PARAM params[])
static SCOSSL_STATUS p_scossl_rsa_cipher_init(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx,
_In_ const OSSL_PARAM params[])
{
ctx->keyCtx = keyCtx;
ctx->padding = RSA_PKCS1_PADDING;
@ -95,14 +89,20 @@ SCOSSL_STATUS p_scossl_rsa_cipher_init(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx, _In_
return p_scossl_rsa_cipher_set_ctx_params(ctx, params);
}
SCOSSL_STATUS p_scossl_rsa_cipher_encrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx,
_Out_writes_bytes_(*outlen) unsigned char *out, _Out_ size_t *outlen, size_t outsize,
_In_reads_bytes_(inlen) const unsigned char *in, size_t inlen)
static SCOSSL_STATUS p_scossl_rsa_cipher_encrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx,
_Out_writes_bytes_(*outlen) unsigned char *out, _Out_ size_t *outlen, size_t outsize,
_In_reads_bytes_(inlen) const unsigned char *in, size_t inlen)
{
int mdnid = 0;
INT32 cbResult;
SCOSSL_STATUS ret;
if (ctx->keyCtx == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
return SCOSSL_FAILURE;
}
// Default to SHA1 for OAEP. Update md in context so this is
// reflected in getparam
if (ctx->padding == RSA_PKCS1_OAEP_PADDING)
@ -120,7 +120,7 @@ SCOSSL_STATUS p_scossl_rsa_cipher_encrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx,
mdnid = ctx->oaepMdInfo->id;
}
ret = scossl_rsa_encrypt(ctx->keyCtx, ctx->padding,
ret = scossl_rsa_encrypt(ctx->keyCtx->key, ctx->padding,
mdnid, ctx->pbLabel, ctx->cbLabel,
in, inlen,
out, &cbResult, outsize);
@ -129,14 +129,20 @@ SCOSSL_STATUS p_scossl_rsa_cipher_encrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx,
return ret;
}
SCOSSL_STATUS p_scossl_rsa_cipher_decrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx,
_Out_writes_bytes_(*outlen) unsigned char *out, _Out_ size_t *outlen, size_t outsize,
_In_reads_bytes_(inlen) const unsigned char *in, size_t inlen)
static SCOSSL_STATUS p_scossl_rsa_cipher_decrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx,
_Out_writes_bytes_(*outlen) unsigned char *out, _Out_ size_t *outlen, size_t outsize,
_In_reads_bytes_(inlen) const unsigned char *in, size_t inlen)
{
int mdnid = 0;
INT32 cbResult;
SCOSSL_STATUS ret;
if (ctx->keyCtx == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
return SCOSSL_FAILURE;
}
// Default to SHA1 for OAEP. Update md in context so this is
// reflected in getparam
if (ctx->padding == RSA_PKCS1_OAEP_PADDING)
@ -154,7 +160,7 @@ SCOSSL_STATUS p_scossl_rsa_cipher_decrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx,
mdnid = ctx->oaepMdInfo->id;
}
ret = scossl_rsa_decrypt(ctx->keyCtx, ctx->padding,
ret = scossl_rsa_decrypt(ctx->keyCtx->key, ctx->padding,
mdnid, ctx->pbLabel, ctx->cbLabel,
in, inlen,
out, &cbResult, outsize);
@ -163,7 +169,7 @@ SCOSSL_STATUS p_scossl_rsa_cipher_decrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx,
return ret;
}
SCOSSL_STATUS p_scossl_rsa_cipher_get_ctx_params(_In_ SCOSSL_RSA_CIPHER_CTX *ctx, _Out_ OSSL_PARAM params[])
static SCOSSL_STATUS p_scossl_rsa_cipher_get_ctx_params(_In_ SCOSSL_RSA_CIPHER_CTX *ctx, _Out_ OSSL_PARAM params[])
{
OSSL_PARAM *p;
@ -217,12 +223,12 @@ SCOSSL_STATUS p_scossl_rsa_cipher_get_ctx_params(_In_ SCOSSL_RSA_CIPHER_CTX *ctx
return SCOSSL_SUCCESS;
}
const OSSL_PARAM *p_scossl_rsa_cipher_gettable_ctx_params(ossl_unused void *provctx)
static const OSSL_PARAM *p_scossl_rsa_cipher_gettable_ctx_params(ossl_unused void *provctx)
{
return p_scossl_rsa_cipher_gettable_ctx_param_types;
}
SCOSSL_STATUS p_scossl_rsa_cipher_set_ctx_params(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx, _In_ const OSSL_PARAM params[])
static SCOSSL_STATUS p_scossl_rsa_cipher_set_ctx_params(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx, _In_ const OSSL_PARAM params[])
{
const OSSL_PARAM *p;
const OSSL_PARAM *param_propq;

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

@ -6,6 +6,7 @@
#include <openssl/proverr.h>
#include "p_scossl_base.h"
#include "p_scossl_rsa.h"
#include "scossl_rsa.h"
#ifdef __cplusplus
@ -14,12 +15,18 @@ extern "C" {
typedef struct
{
OSSL_LIB_CTX *libctx;
// May be set for PSS
SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions;
UINT32 nBitsOfModulus;
UINT64 pubExp64;
UINT32 nPubExp;
UINT padding;
} SCOSSL_RSA_KEYGEN_CTX;
#define SCOSSL_DEFAULT_RSA_BITS 2048
#define SCOSSL_RSA_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)
#define SCOSSL_RSA_KEYMGMT_PARAMS \
OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, NULL, 0), \
@ -40,6 +47,15 @@ static const OSSL_PARAM p_scossl_rsa_keygen_settable_param_types[] = {
OSSL_PARAM_uint64(OSSL_PKEY_PARAM_RSA_E, NULL),
OSSL_PARAM_END};
static const OSSL_PARAM p_scossl_rsapss_keygen_settable_param_types[] = {
OSSL_PARAM_uint32(OSSL_PKEY_PARAM_RSA_BITS, NULL),
OSSL_PARAM_uint64(OSSL_PKEY_PARAM_RSA_E, NULL),
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_DIGEST, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_DIGEST_PROPS, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_MGF1_DIGEST, NULL, 0),
OSSL_PARAM_int(OSSL_PKEY_PARAM_RSA_PSS_SALTLEN, NULL),
OSSL_PARAM_END};
static const OSSL_PARAM p_scossl_rsa_keymgmt_gettable_param_types[] = {
OSSL_PARAM_uint32(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
OSSL_PARAM_uint32(OSSL_PKEY_PARAM_BITS, NULL),
@ -60,9 +76,38 @@ static const OSSL_PARAM p_scossl_rsa_keymgmt_impexp_param_types[] = {
// first, then passes that reference to keymgmt_import. Since
// the size of the SYMPCRYPT_RSAKEY depends on parameters that aren't
// known until import, no key is actually allocated here.
static SCOSSL_RSA_KEY_CTX *p_scossl_rsa_keymgmt_new_ctx(ossl_unused void *provctx)
static SCOSSL_PROV_RSA_KEY_CTX *p_scossl_rsa_keymgmt_new_ctx(ossl_unused void *provctx)
{
return scossl_rsa_new_key_ctx();
SCOSSL_PROV_RSA_KEY_CTX *keyCtx = OPENSSL_zalloc(sizeof(SCOSSL_PROV_RSA_KEY_CTX));
if (keyCtx != NULL)
{
keyCtx->padding = RSA_PKCS1_PADDING;
}
return keyCtx;
}
static SCOSSL_PROV_RSA_KEY_CTX *p_scossl_rsapss_keymgmt_new_ctx(_In_ SCOSSL_PROVCTX *provctx)
{
SCOSSL_PROV_RSA_KEY_CTX *keyCtx = OPENSSL_zalloc(sizeof(SCOSSL_PROV_RSA_KEY_CTX));
if (keyCtx != NULL)
{
keyCtx->libctx = provctx->libctx;
keyCtx->padding = RSA_PKCS1_PSS_PADDING;
}
return keyCtx;
}
void p_scossl_rsa_keymgmt_free_ctx(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx)
{
if (keyCtx == NULL)
return;
if (keyCtx->key != NULL)
{
SymCryptRsakeyFree(keyCtx->key);
}
OPENSSL_free(keyCtx->pssRestrictions);
OPENSSL_free(keyCtx);
}
// We need to export, then import the key to copy with optional private key.
@ -172,26 +217,36 @@ cleanup:
return ret;
}
static SCOSSL_RSA_KEY_CTX *p_scossl_rsa_keymgmt_dup_ctx(_In_ const SCOSSL_RSA_KEY_CTX *keyCtx, int selection)
static SCOSSL_PROV_RSA_KEY_CTX *p_scossl_rsa_keymgmt_dup_ctx(_In_ const SCOSSL_PROV_RSA_KEY_CTX *keyCtx, int selection)
{
SCOSSL_RSA_KEY_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_RSA_KEY_CTX));
SCOSSL_PROV_RSA_KEY_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_PROV_RSA_KEY_CTX));
if (copyCtx == NULL)
{
return NULL;
}
copyCtx->initialized = keyCtx->initialized;
copyCtx->padding = keyCtx->padding;
if (keyCtx->initialized && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
{
if (!p_scossl_rsa_keymgmt_dup_keydata((PCSYMCRYPT_RSAKEY) keyCtx->key, &copyCtx->key,
(selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0))
{
scossl_rsa_free_key_ctx(copyCtx);
p_scossl_rsa_keymgmt_free_ctx(copyCtx);
copyCtx = NULL;
}
}
if (keyCtx->padding == RSA_PKCS1_PSS_PADDING &&
keyCtx->pssRestrictions != NULL &&
(copyCtx->pssRestrictions = OPENSSL_memdup(keyCtx->pssRestrictions, sizeof(SCOSSL_RSA_PSS_RESTRICTIONS))) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
p_scossl_rsa_keymgmt_free_ctx(copyCtx);
copyCtx = NULL;
}
return copyCtx;
}
@ -231,6 +286,12 @@ static SCOSSL_STATUS p_scossl_rsa_keygen_set_params(_Inout_ SCOSSL_RSA_KEYGEN_CT
genCtx->nPubExp = 1;
}
if (genCtx->padding == RSA_PKCS1_PSS_PADDING &&
!p_scossl_rsa_pss_restrictions_from_params(genCtx->libctx, params, &genCtx->pssRestrictions))
{
return SCOSSL_FAILURE;
}
return SCOSSL_SUCCESS;
}
@ -240,13 +301,23 @@ static const OSSL_PARAM *p_scossl_rsa_keygen_settable_params(ossl_unused void *g
return p_scossl_rsa_keygen_settable_param_types;
}
static const OSSL_PARAM *p_scossl_rsapss_keygen_settable_params(ossl_unused void *genCtx,
ossl_unused void *provctx)
{
return p_scossl_rsapss_keygen_settable_param_types;
}
static void p_scossl_rsa_keygen_cleanup(_Inout_ SCOSSL_RSA_KEYGEN_CTX *genCtx)
{
if (genCtx == NULL)
return;
OPENSSL_free(genCtx->pssRestrictions);
OPENSSL_clear_free(genCtx, sizeof(SCOSSL_RSA_KEYGEN_CTX));
}
static SCOSSL_RSA_KEYGEN_CTX *p_scossl_rsa_keygen_init(ossl_unused void *provctx, int selection,
_In_ const OSSL_PARAM params[])
static SCOSSL_RSA_KEYGEN_CTX *p_scossl_rsa_keygen_init_common(_In_ SCOSSL_PROVCTX *provctx, int selection,
_In_ const OSSL_PARAM params[], UINT padding)
{
// Sanity check
if (!(selection & OSSL_KEYMGMT_SELECT_KEYPAIR))
@ -263,6 +334,9 @@ static SCOSSL_RSA_KEYGEN_CTX *p_scossl_rsa_keygen_init(ossl_unused void *provctx
genCtx->nBitsOfModulus = SCOSSL_DEFAULT_RSA_BITS;
genCtx->nPubExp = 0;
genCtx->libctx = provctx->libctx;
genCtx->padding = padding;
genCtx->pssRestrictions = NULL;
if (!p_scossl_rsa_keygen_set_params(genCtx, params))
{
@ -273,14 +347,26 @@ static SCOSSL_RSA_KEYGEN_CTX *p_scossl_rsa_keygen_init(ossl_unused void *provctx
return genCtx;
}
static SCOSSL_RSA_KEY_CTX *p_scossl_rsa_keygen(_In_ SCOSSL_RSA_KEYGEN_CTX *genCtx, ossl_unused OSSL_CALLBACK *cb, ossl_unused void *cbarg)
static SCOSSL_RSA_KEYGEN_CTX *p_scossl_rsa_keygen_init(_In_ SCOSSL_PROVCTX *provctx, int selection,
_In_ const OSSL_PARAM params[])
{
return p_scossl_rsa_keygen_init_common(provctx, selection, params, RSA_PKCS1_PADDING);
}
static SCOSSL_RSA_KEYGEN_CTX *p_scossl_rsapss_keygen_init(_In_ SCOSSL_PROVCTX *provctx, int selection,
_In_ const OSSL_PARAM params[])
{
return p_scossl_rsa_keygen_init_common(provctx, selection, params, RSA_PKCS1_PSS_PADDING);;
}
static SCOSSL_PROV_RSA_KEY_CTX *p_scossl_rsa_keygen(_In_ SCOSSL_RSA_KEYGEN_CTX *genCtx, ossl_unused OSSL_CALLBACK *cb, ossl_unused void *cbarg)
{
SYMCRYPT_RSA_PARAMS symcryptRsaParam;
SCOSSL_RSA_KEY_CTX *keyCtx;
SCOSSL_PROV_RSA_KEY_CTX *keyCtx;
SYMCRYPT_ERROR scError;
PUINT64 pPubExp64;
keyCtx = scossl_rsa_new_key_ctx();
keyCtx = OPENSSL_malloc(sizeof(SCOSSL_PROV_RSA_KEY_CTX));
if (keyCtx == NULL)
{
goto cleanup;
@ -306,7 +392,10 @@ static SCOSSL_RSA_KEY_CTX *p_scossl_rsa_keygen(_In_ SCOSSL_RSA_KEYGEN_CTX *genCt
goto cleanup;
}
keyCtx->initialized = 1;
keyCtx->initialized = TRUE;
keyCtx->padding = genCtx->padding;
keyCtx->pssRestrictions = genCtx->pssRestrictions;
genCtx->pssRestrictions = NULL;
cleanup:
if (keyCtx != NULL && !keyCtx->initialized)
@ -442,7 +531,7 @@ static UINT16 p_scossl_rsa_get_security_bits(_In_ PSYMCRYPT_RSAKEY keydata)
return ret;
}
static SCOSSL_STATUS p_scossl_rsa_keymgmt_get_params(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, _Inout_ OSSL_PARAM params[])
static SCOSSL_STATUS p_scossl_rsa_keymgmt_get_params(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, _Inout_ OSSL_PARAM params[])
{
SCOSSL_STATUS ret = SCOSSL_FAILURE;
@ -628,7 +717,7 @@ static const OSSL_PARAM *p_scossl_rsa_keymgmt_gettable_params(ossl_unused void *
return p_scossl_rsa_keymgmt_gettable_param_types;
}
static BOOL p_scossl_rsa_keymgmt_has(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, int selection)
static BOOL p_scossl_rsa_keymgmt_has(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, int selection)
{
BOOL ret = TRUE;
if (keyCtx->key == NULL)
@ -642,7 +731,7 @@ static BOOL p_scossl_rsa_keymgmt_has(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, int select
return ret;
}
static BOOL p_scossl_rsa_keymgmt_match(_In_ SCOSSL_RSA_KEY_CTX *keyCtx1, _In_ SCOSSL_RSA_KEY_CTX *keyCtx2,
static BOOL p_scossl_rsa_keymgmt_match(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx1, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx2,
int selection)
{
BOOL ret = FALSE;
@ -751,7 +840,7 @@ static const OSSL_PARAM *p_scossl_rsa_keymgmt_impexp_types(int selection){
NULL;
}
static SCOSSL_STATUS p_scossl_rsa_keymgmt_import(_Inout_ SCOSSL_RSA_KEY_CTX *keyCtx, int selection, _In_ const OSSL_PARAM params[])
static SCOSSL_STATUS p_scossl_rsa_keymgmt_import(_Inout_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, int selection, _In_ const OSSL_PARAM params[])
{
BOOL include_private = (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0;
const OSSL_PARAM *p;
@ -766,8 +855,8 @@ static SCOSSL_STATUS p_scossl_rsa_keymgmt_import(_Inout_ SCOSSL_RSA_KEY_CTX *key
SYMCRYPT_RSA_PARAMS symcryptRsaParam;
BIGNUM *bn;
if (keyCtx == NULL &&
((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0))
if (keyCtx == NULL ||
(selection & SCOSSL_RSA_POSSIBLE_SELECTIONS) == 0)
{
return SCOSSL_FAILURE;
}
@ -881,7 +970,14 @@ static SCOSSL_STATUS p_scossl_rsa_keymgmt_import(_Inout_ SCOSSL_RSA_KEY_CTX *key
}
}
keyCtx->initialized = 1;
if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0 &&
keyCtx->padding == RSA_PKCS1_PSS_PADDING &&
!p_scossl_rsa_pss_restrictions_from_params(keyCtx->libctx, params, &keyCtx->pssRestrictions))
{
goto cleanup;
}
keyCtx->initialized = TRUE;
ret = SCOSSL_SUCCESS;
@ -893,7 +989,7 @@ cleanup:
return ret;
}
static SCOSSL_STATUS p_scossl_rsa_keymgmt_export(_In_ SCOSSL_RSA_KEY_CTX *keyCtx, int selection,
static SCOSSL_STATUS p_scossl_rsa_keymgmt_export(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, int selection,
_In_ OSSL_CALLBACK *param_cb, _In_ void *cbarg)
{
BOOL includePrivate = (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0;
@ -903,7 +999,7 @@ static SCOSSL_STATUS p_scossl_rsa_keymgmt_export(_In_ SCOSSL_RSA_KEY_CTX *keyCtx
OSSL_PARAM *params = NULL;
if (keyCtx == NULL ||
!(selection & OSSL_KEYMGMT_SELECT_KEYPAIR))
(selection & SCOSSL_RSA_POSSIBLE_SELECTIONS) == 0)
{
return ret;
}
@ -930,13 +1026,26 @@ static SCOSSL_STATUS p_scossl_rsa_keymgmt_export(_In_ SCOSSL_RSA_KEY_CTX *keyCtx
!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT1, rsaParams->privateParams->dmp1) ||
!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT2, rsaParams->privateParams->dmq1) ||
!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, rsaParams->privateParams->iqmp) ||
!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, rsaParams->privateParams->d))) ||
((params = OSSL_PARAM_BLD_to_param(bld)) == NULL))
!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, rsaParams->privateParams->d))))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0 &&
keyCtx->padding == RSA_PKCS1_PSS_PADDING &&
keyCtx->pssRestrictions != NULL &&
!p_scossl_rsa_pss_restrictions_to_params(keyCtx->pssRestrictions, bld))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if ((params = OSSL_PARAM_BLD_to_param(bld)) == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
ret = param_cb(params, cbarg);
cleanup:
@ -947,10 +1056,15 @@ cleanup:
return ret;
}
static const char *p_scossl_rsa_query_operation_name(ossl_unused int operation_id)
{
return "RSA";
}
const OSSL_DISPATCH p_scossl_rsa_keymgmt_functions[] = {
{OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))p_scossl_rsa_keymgmt_new_ctx},
{OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))p_scossl_rsa_keymgmt_dup_ctx},
{OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))scossl_rsa_free_key_ctx},
{OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))p_scossl_rsa_keymgmt_free_ctx},
{OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))p_scossl_rsa_keygen_set_params},
{OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))p_scossl_rsa_keygen_settable_params},
{OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))p_scossl_rsa_keygen_cleanup},
@ -966,6 +1080,26 @@ const OSSL_DISPATCH p_scossl_rsa_keymgmt_functions[] = {
{OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))p_scossl_rsa_keymgmt_export},
{0, NULL}};
const OSSL_DISPATCH p_scossl_rsapss_keymgmt_functions[] = {
{OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))p_scossl_rsapss_keymgmt_new_ctx},
{OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))p_scossl_rsa_keymgmt_dup_ctx},
{OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))p_scossl_rsa_keymgmt_free_ctx},
{OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))p_scossl_rsa_keygen_set_params},
{OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))p_scossl_rsapss_keygen_settable_params},
{OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))p_scossl_rsa_keygen_cleanup},
{OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))p_scossl_rsapss_keygen_init},
{OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))p_scossl_rsa_keygen},
{OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))p_scossl_rsa_keymgmt_get_params},
{OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))p_scossl_rsa_keymgmt_gettable_params},
{OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))p_scossl_rsa_keymgmt_has},
{OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))p_scossl_rsa_keymgmt_match},
{OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))p_scossl_rsa_keymgmt_impexp_types},
{OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))p_scossl_rsa_keymgmt_impexp_types},
{OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))p_scossl_rsa_keymgmt_import},
{OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))p_scossl_rsa_keymgmt_export},
{OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))p_scossl_rsa_query_operation_name},
{0, NULL}};
#ifdef __cplusplus
}
#endif

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

@ -216,12 +216,14 @@ static const OSSL_ALGORITHM p_scossl_rand[] = {
// Key management
extern const OSSL_DISPATCH p_scossl_dh_keymgmt_functions[];
extern const OSSL_DISPATCH p_scossl_rsa_keymgmt_functions[];
extern const OSSL_DISPATCH p_scossl_rsapss_keymgmt_functions[];
extern const OSSL_DISPATCH p_scossl_ecc_keymgmt_functions[];
extern const OSSL_DISPATCH p_scossl_x25519_keymgmt_functions[];
static const OSSL_ALGORITHM p_scossl_keymgmt[] = {
ALG("DH:dhKeyAgreement:1.2.840.113549.1.3.1", p_scossl_dh_keymgmt_functions),
ALG("RSA:rsaEncryption:1.2.840.113549.1.1.1:", p_scossl_rsa_keymgmt_functions),
ALG("RSA-PSS:RSASSA-PSS:1.2.840.113549.1.1.10", p_scossl_rsapss_keymgmt_functions),
ALG("EC:id-ecPublicKey:1.2.840.10045.2.1", p_scossl_ecc_keymgmt_functions),
ALG("X25519:1.3.101.110", p_scossl_x25519_keymgmt_functions),
ALG_TABLE_END};
@ -230,15 +232,11 @@ static const OSSL_ALGORITHM p_scossl_keymgmt[] = {
extern const OSSL_DISPATCH p_scossl_dh_functions[];
extern const OSSL_DISPATCH p_scossl_ecdh_functions[];
extern const OSSL_DISPATCH p_scossl_x25519_functions[];
extern const OSSL_DISPATCH p_scossl_hkdf_keyexch_functions[];
extern const OSSL_DISPATCH p_scossl_tls1prf_keyexch_functions[];
static const OSSL_ALGORITHM p_scossl_keyexch[] = {
ALG("DH:dhKeyAgreement:1.2.840.113549.1.3.1", p_scossl_dh_functions),
ALG("ECDH", p_scossl_ecdh_functions),
ALG("X25519:1.3.101.110", p_scossl_ecdh_functions),
// ALG("HKDF", p_scossl_hkdf_keyexch_functions),
// ALG("TLS1-PRF", p_scossl_tls1prf_keyexch_functions),
ALG_TABLE_END};
// Signature
@ -388,21 +386,21 @@ SCOSSL_STATUS OSSL_provider_init(_In_ const OSSL_CORE_HANDLE *handle,
{
switch(in->function_id)
{
case OSSL_FUNC_CRYPTO_MALLOC:
c_CRYPTO_malloc = OSSL_FUNC_CRYPTO_malloc(in);
break;
case OSSL_FUNC_CRYPTO_ZALLOC:
c_CRYPTO_zalloc = OSSL_FUNC_CRYPTO_zalloc(in);
break;
case OSSL_FUNC_CRYPTO_FREE:
c_CRYPTO_free = OSSL_FUNC_CRYPTO_free(in);
break;
case OSSL_FUNC_CRYPTO_CLEAR_FREE:
c_CRYPTO_clear_free = OSSL_FUNC_CRYPTO_clear_free(in);
break;
case OSSL_FUNC_CORE_GET_LIBCTX:
core_get_libctx = OSSL_FUNC_core_get_libctx(in);
break;
case OSSL_FUNC_CRYPTO_MALLOC:
c_CRYPTO_malloc = OSSL_FUNC_CRYPTO_malloc(in);
break;
case OSSL_FUNC_CRYPTO_ZALLOC:
c_CRYPTO_zalloc = OSSL_FUNC_CRYPTO_zalloc(in);
break;
case OSSL_FUNC_CRYPTO_FREE:
c_CRYPTO_free = OSSL_FUNC_CRYPTO_free(in);
break;
case OSSL_FUNC_CRYPTO_CLEAR_FREE:
c_CRYPTO_clear_free = OSSL_FUNC_CRYPTO_clear_free(in);
break;
case OSSL_FUNC_CORE_GET_LIBCTX:
core_get_libctx = OSSL_FUNC_core_get_libctx(in);
break;
}
}

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

@ -8,11 +8,16 @@
#include <openssl/core_names.h>
#include <openssl/evp.h>
#include <openssl/param_build.h>
#include <openssl/proverr.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SCOSSL_PROV_RSA_PSS_DEFAULT_MD (0) // Index of the default MD in p_scossl_rsa_supported_mds (SHA1)
#define SCOSSL_PROV_RSA_PSS_DEFAULT_SALTLEN_MIN (20)
static const OSSL_ITEM p_scossl_rsa_supported_mds[] = {
{NID_sha1, OSSL_DIGEST_NAME_SHA1}, // Default
{NID_sha256, OSSL_DIGEST_NAME_SHA2_256},
@ -53,6 +58,117 @@ const OSSL_ITEM *p_scossl_rsa_get_supported_md(OSSL_LIB_CTX *libctx,
return mdInfo;
}
static const OSSL_ITEM *p_scossl_rsa_pss_param_to_mdinfo(_In_ OSSL_LIB_CTX *libctx,
_In_ const OSSL_PARAM *p, _In_ const char *mdProps)
{
const OSSL_ITEM *mdInfo;
const char *mdName;
if (!OSSL_PARAM_get_utf8_string_ptr(p, &mdName))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return NULL;
}
mdInfo = p_scossl_rsa_get_supported_md(libctx, mdName, mdProps, NULL);
if (mdInfo == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
return NULL;
}
return mdInfo;
}
_Use_decl_annotations_
SCOSSL_STATUS p_scossl_rsa_pss_restrictions_from_params(OSSL_LIB_CTX *libctx, const OSSL_PARAM params[],
SCOSSL_RSA_PSS_RESTRICTIONS **pPssRestrictions)
{
const char *mdProps = NULL;
SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions;
SCOSSL_STATUS ret = SCOSSL_FAILURE;
const OSSL_PARAM *paramSaltlenMin = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN);
const OSSL_PARAM *paramPropq = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST_PROPS);
const OSSL_PARAM *paramMd = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST);
const OSSL_PARAM *paramMgf1md = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_MGF1_DIGEST);
if (paramSaltlenMin == NULL &&
paramPropq == NULL &&
paramMd == NULL &&
paramMgf1md == NULL)
{
return SCOSSL_SUCCESS;
}
if (*pPssRestrictions == NULL)
{
if ((pssRestrictions = OPENSSL_malloc(sizeof(SCOSSL_RSA_PSS_RESTRICTIONS))) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
goto cleanup;
}
// Set defaults based on RFC 8017, A.2.3. This is the same behavior
// as the default provider.
pssRestrictions->mdInfo = &p_scossl_rsa_supported_mds[SCOSSL_PROV_RSA_PSS_DEFAULT_MD];
pssRestrictions->mgf1MdInfo = &p_scossl_rsa_supported_mds[SCOSSL_PROV_RSA_PSS_DEFAULT_MD];
pssRestrictions->cbSaltMin = SCOSSL_PROV_RSA_PSS_DEFAULT_SALTLEN_MIN;
*pPssRestrictions = pssRestrictions;
}
else
{
pssRestrictions = *pPssRestrictions;
}
if (paramSaltlenMin != NULL &&
!OSSL_PARAM_get_int(paramSaltlenMin, &pssRestrictions->cbSaltMin))
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
goto cleanup;
}
if (paramPropq != NULL &&
!OSSL_PARAM_get_utf8_string_ptr(paramPropq, &mdProps))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
goto cleanup;
}
if (paramMd != NULL &&
(pssRestrictions->mdInfo = p_scossl_rsa_pss_param_to_mdinfo(libctx, paramMd, mdProps)) == NULL)
{
goto cleanup;
}
if (paramMgf1md != NULL &&
(pssRestrictions->mgf1MdInfo = p_scossl_rsa_pss_param_to_mdinfo(libctx, paramMgf1md, mdProps)) == NULL)
{
goto cleanup;
}
ret = SCOSSL_SUCCESS;
cleanup:
if (!ret)
{
OPENSSL_free(pssRestrictions);
*pPssRestrictions = NULL;
}
return ret;
}
_Use_decl_annotations_
SCOSSL_STATUS p_scossl_rsa_pss_restrictions_to_params(const SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions,
OSSL_PARAM_BLD *bld)
{
return OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_RSA_DIGEST, pssRestrictions->mdInfo->ptr, 0) &&
OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_RSA_MGF1_DIGEST, pssRestrictions->mgf1MdInfo->ptr, 0) &&
OSSL_PARAM_BLD_push_int(bld, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN, pssRestrictions->cbSaltMin);
}
#ifdef __cplusplus
}
#endif

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

@ -8,10 +8,32 @@
extern "C" {
#endif
typedef struct
{
const OSSL_ITEM *mdInfo;
const OSSL_ITEM *mgf1MdInfo;
int cbSaltMin;
} SCOSSL_RSA_PSS_RESTRICTIONS;
typedef struct
{
OSSL_LIB_CTX *libctx;
BOOL initialized;
PSYMCRYPT_RSAKEY key;
UINT padding;
SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions;
} SCOSSL_PROV_RSA_KEY_CTX;
const OSSL_ITEM *p_scossl_rsa_get_supported_md(_In_ OSSL_LIB_CTX *libctx,
_In_ const char *mdname, _In_ const char *propq,
_Out_opt_ EVP_MD **md);
SCOSSL_STATUS p_scossl_rsa_pss_restrictions_from_params(_In_ OSSL_LIB_CTX *libctx, _In_ const OSSL_PARAM params[],
_Out_ SCOSSL_RSA_PSS_RESTRICTIONS **pPssRestrictions);
SCOSSL_STATUS p_scossl_rsa_pss_restrictions_to_params(_In_ const SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions,
_Inout_ OSSL_PARAM_BLD *bld);
#ifdef __cplusplus
}
#endif

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

@ -17,9 +17,9 @@ extern "C" {
typedef struct
{
SCOSSL_RSA_KEY_CTX *keyCtx;
SCOSSL_PROV_RSA_KEY_CTX *keyCtx;
UINT padding;
UINT operation;
int operation;
// Needed for fetching md
OSSL_LIB_CTX *libctx;
@ -31,8 +31,10 @@ typedef struct
BOOL allowMdUpdates;
// PSS params
BOOL pssRestricted;
const OSSL_ITEM *mgf1MdInfo; // Informational, must match md if set
int cbSalt;
int cbSaltMin;
} SCOSSL_RSA_SIGN_CTX;
#define SCOSSL_RSA_SIGNATURE_GETTABLE_PARAMS \
@ -95,6 +97,7 @@ static SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_newctx(_In_ SCOSSL_PROVCTX *provctx, _I
ctx->libctx = provctx->libctx;
ctx->allowMdUpdates = TRUE;
ctx->padding = RSA_PKCS1_PADDING;
ctx->cbSaltMin = -1;
}
return ctx;
@ -102,6 +105,9 @@ static SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_newctx(_In_ SCOSSL_PROVCTX *provctx, _I
static void p_scossl_rsa_freectx(SCOSSL_RSA_SIGN_CTX *ctx)
{
if (ctx == NULL)
return;
EVP_MD_CTX_free(ctx->mdctx);
EVP_MD_free(ctx->md);
OPENSSL_free(ctx->propq);
@ -122,9 +128,10 @@ static SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_dupctx(_In_ SCOSSL_RSA_SIGN_CTX *ctx)
copyCtx = NULL;
}
copyCtx->libctx = ctx->libctx;
copyCtx->padding = ctx->padding;
copyCtx->keyCtx = ctx->keyCtx;
copyCtx->padding = ctx->padding;
copyCtx->operation = ctx->operation;
copyCtx->libctx = ctx->libctx;
copyCtx->md = ctx->md;
copyCtx->cbSalt = ctx->cbSalt;
copyCtx->mdInfo = ctx->mdInfo;
@ -134,7 +141,7 @@ static SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_dupctx(_In_ SCOSSL_RSA_SIGN_CTX *ctx)
return copyCtx;
}
static SCOSSL_STATUS p_scossl_rsa_signverify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_RSA_KEY_CTX *keyCtx,
static SCOSSL_STATUS p_scossl_rsa_signverify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx,
_In_ const OSSL_PARAM params[], int operation)
{
if (ctx == NULL ||
@ -153,19 +160,48 @@ static SCOSSL_STATUS p_scossl_rsa_signverify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *c
ctx->operation = operation;
if (keyCtx != NULL)
{
if (keyCtx->pssRestrictions != NULL)
{
EVP_MD *md = NULL;
// ScOSSL does not support distinct MD and MGF1 MD
if (keyCtx->pssRestrictions->mdInfo != keyCtx->pssRestrictions->mgf1MdInfo ||
(md = EVP_MD_fetch(ctx->libctx, keyCtx->pssRestrictions->mdInfo->ptr, NULL)) == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
return SCOSSL_FAILURE;
}
int cbSaltMax = ((SymCryptRsakeyModulusBits(keyCtx->key) + 6) / 8) - EVP_MD_get_size(md) - 2; // ceil((ModulusBits - 1) / 8) - cbDigest - 2)
if (keyCtx->pssRestrictions->cbSaltMin < 0 ||
keyCtx->pssRestrictions->cbSaltMin > cbSaltMax)
{
EVP_MD_free(md);
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
return SCOSSL_FAILURE;
}
ctx->md = md;
ctx->mdInfo = keyCtx->pssRestrictions->mdInfo;
ctx->mgf1MdInfo = keyCtx->pssRestrictions->mgf1MdInfo;
ctx->cbSalt = keyCtx->pssRestrictions->cbSaltMin;
ctx->cbSaltMin = keyCtx->pssRestrictions->cbSaltMin;
ctx->pssRestricted = TRUE;
}
ctx->keyCtx = keyCtx;
ctx->padding = keyCtx->padding;
}
return p_scossl_rsa_set_ctx_params(ctx, params);
}
static SCOSSL_STATUS p_scossl_rsa_sign_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_RSA_KEY_CTX *keyCtx,
static SCOSSL_STATUS p_scossl_rsa_sign_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx,
_In_ const OSSL_PARAM params[])
{
return p_scossl_rsa_signverify_init(ctx, keyCtx, params, EVP_PKEY_OP_SIGN);
}
static SCOSSL_STATUS p_scossl_rsa_verify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_RSA_KEY_CTX *keyCtx,
static SCOSSL_STATUS p_scossl_rsa_verify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx,
_In_ const OSSL_PARAM params[])
{
return p_scossl_rsa_signverify_init(ctx, keyCtx, params, EVP_PKEY_OP_VERIFY);
@ -190,9 +226,9 @@ static SCOSSL_STATUS p_scossl_rsa_sign(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
switch (ctx->padding)
{
case RSA_PKCS1_PADDING:
return scossl_rsa_pkcs1_sign(ctx->keyCtx, ctx->mdInfo->id, tbs, tbslen, sig, siglen);
return scossl_rsa_pkcs1_sign(ctx->keyCtx->key, ctx->mdInfo->id, tbs, tbslen, sig, siglen);
case RSA_PKCS1_PSS_PADDING:
return scossl_rsapss_sign(ctx->keyCtx, ctx->mdInfo->id, ctx->cbSalt, tbs, tbslen, sig, siglen);
return scossl_rsapss_sign(ctx->keyCtx->key, ctx->mdInfo->id, ctx->cbSalt, tbs, tbslen, sig, siglen);
default:
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE);
}
@ -213,9 +249,9 @@ static SCOSSL_STATUS p_scossl_rsa_verify(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
switch (ctx->padding)
{
case RSA_PKCS1_PADDING:
return scossl_rsa_pkcs1_verify(ctx->keyCtx, ctx->mdInfo->id, tbs, tbslen, sig, siglen);
return scossl_rsa_pkcs1_verify(ctx->keyCtx->key, ctx->mdInfo->id, tbs, tbslen, sig, siglen);
case RSA_PKCS1_PSS_PADDING:
return scossl_rsapss_verify(ctx->keyCtx, ctx->mdInfo->id, ctx->cbSalt, tbs, tbslen, sig, siglen);
return scossl_rsapss_verify(ctx->keyCtx->key, ctx->mdInfo->id, ctx->cbSalt, tbs, tbslen, sig, siglen);
default:
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE);
}
@ -224,17 +260,23 @@ static SCOSSL_STATUS p_scossl_rsa_verify(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
}
static SCOSSL_STATUS p_scossl_rsa_digest_signverify_init(_In_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ const char *mdname,
_In_ SCOSSL_RSA_KEY_CTX *keyCtx, _In_ const OSSL_PARAM params[], int operation)
_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, _In_ const OSSL_PARAM params[], int operation)
{
if (!p_scossl_rsa_signverify_init(ctx, keyCtx, params, operation))
{
return SCOSSL_FAILURE;
}
// Different digest specified than what was previously set by paramters.
if (mdname != NULL &&
(mdname[0] == '\0' || !EVP_MD_is_a(ctx->md, mdname)))
{
// Different digest specified than what was previously set by paramters.
if (ctx->pssRestricted)
{
ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
return SCOSSL_FAILURE;
}
EVP_MD *md;
const OSSL_ITEM *mdInfo = p_scossl_rsa_get_supported_md(ctx->libctx, mdname, NULL, &md);
@ -271,13 +313,13 @@ static SCOSSL_STATUS p_scossl_rsa_digest_signverify_init(_In_ SCOSSL_RSA_SIGN_CT
}
static SCOSSL_STATUS p_scossl_rsa_digest_sign_init(_In_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ const char *mdname,
_In_ SCOSSL_RSA_KEY_CTX *keyCtx, _In_ const OSSL_PARAM params[])
_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, _In_ const OSSL_PARAM params[])
{
return p_scossl_rsa_digest_signverify_init(ctx, mdname, keyCtx, params, EVP_PKEY_OP_SIGN);
}
static SCOSSL_STATUS p_scossl_rsa_digest_verify_init(_In_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ const char *mdname,
_In_ SCOSSL_RSA_KEY_CTX *keyCtx, _In_ const OSSL_PARAM params[])
_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, _In_ const OSSL_PARAM params[])
{
return p_scossl_rsa_digest_signverify_init(ctx, mdname, keyCtx, params, EVP_PKEY_OP_VERIFY);
}
@ -372,8 +414,22 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct
return SCOSSL_FAILURE;
}
ctx->md = md;
ctx->mdInfo = mdInfo;
if (ctx->pssRestricted)
{
// MD already set. Only need to check whether this matches
EVP_MD_free(md);
if (mdInfo->id != ctx->mdInfo->id)
{
ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
return SCOSSL_FAILURE;
}
}
else
{
EVP_MD_free(ctx->md);
ctx->md = md;
ctx->mdInfo = mdInfo;
}
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PAD_MODE)) != NULL)
@ -412,7 +468,8 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct
padding = p_scossl_rsa_sign_padding_modes[i].id;
if (padding == 0)
if (padding == 0 ||
(ctx->pssRestricted && padding != RSA_PKCS1_PSS_PADDING))
{
ERR_raise(ERR_LIB_PROV, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
return SCOSSL_FAILURE;
@ -433,12 +490,12 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct
return SCOSSL_FAILURE;
}
int saltlen;
int cbSalt;
// Padding mode may be passed as legacy NID or string
switch (p->data_type)
{
case OSSL_PARAM_INTEGER:
if (!OSSL_PARAM_get_int(p, &saltlen))
if (!OSSL_PARAM_get_int(p, &cbSalt))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
@ -447,29 +504,29 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct
case OSSL_PARAM_UTF8_STRING:
if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST) == 0)
{
saltlen = RSA_PSS_SALTLEN_DIGEST;
cbSalt = RSA_PSS_SALTLEN_DIGEST;
}
else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0)
{
// Sign: Maximized salt length
// Verify: Autorecovered salt length
saltlen = RSA_PSS_SALTLEN_AUTO;
cbSalt = RSA_PSS_SALTLEN_AUTO;
}
else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_MAX) == 0)
{
saltlen = RSA_PSS_SALTLEN_MAX;
cbSalt = RSA_PSS_SALTLEN_MAX;
}
#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX
else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0)
{
// Sign: Smaller of digest length or maximized salt length
// Verify: Autorecovered salt length
saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
cbSalt = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
}
#endif
else
{
saltlen = atoi(p->data);
cbSalt = atoi(p->data);
}
break;
default:
@ -477,16 +534,46 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct
return SCOSSL_FAILURE;
}
#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX
if (saltlen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX)
if (cbSalt < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX)
#else
if (saltlen < RSA_PSS_SALTLEN_MAX)
if (cbSalt < RSA_PSS_SALTLEN_MAX)
#endif
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
return SCOSSL_FAILURE;
}
ctx->cbSalt = saltlen;
if (ctx->pssRestricted)
{
switch (cbSalt)
{
case RSA_PSS_SALTLEN_AUTO:
#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX
case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX:
#endif
if (ctx->operation == EVP_PKEY_OP_VERIFY)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
return SCOSSL_FAILURE;
}
break;
case RSA_PSS_SALTLEN_DIGEST:
if (EVP_MD_get_size(ctx->md) < ctx->cbSaltMin)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
return SCOSSL_FAILURE;
}
break;
default:
if (cbSalt >= 0 && cbSalt < ctx->cbSaltMin)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
return SCOSSL_FAILURE;
}
}
}
ctx->cbSalt = cbSalt;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_MGF1_DIGEST)) != NULL)
@ -525,10 +612,23 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct
return SCOSSL_FAILURE;
}
EVP_MD_free(ctx->md);
ctx->md = md;
ctx->mgf1MdInfo = mgf1MdInfo;
ctx->mdInfo = mgf1MdInfo;
if (ctx->pssRestricted)
{
// MD already set. Only need to check whether this matches
EVP_MD_free(md);
if (mgf1MdInfo->id != ctx->mgf1MdInfo->id)
{
ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
return SCOSSL_FAILURE;
}
}
else
{
EVP_MD_free(ctx->md);
ctx->md = md;
ctx->mgf1MdInfo = mgf1MdInfo;
ctx->mdInfo = mgf1MdInfo;
}
}
return SCOSSL_SUCCESS;