Skip to content

Commit

Permalink
Fix rsa and ec key size handling
Browse files Browse the repository at this point in the history
  • Loading branch information
qpernil committed Mar 3, 2024
1 parent 6f116bb commit d751f53
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 92 deletions.
149 changes: 64 additions & 85 deletions pkcs11/util_pkcs11.c
Original file line number Diff line number Diff line change
Expand Up @@ -1722,9 +1722,7 @@ static CK_RV load_public_key(yh_session *session, uint16_t id, EVP_PKEY *key) {
goto l_p_k_failure;
}

if (BN_hex2bn(&e, "10001") == 0) {
goto l_p_k_failure;
}
BN_set_word(e, 0x010001);

n = BN_bin2bn(data + 1, data_len, NULL);
if (n == NULL) {
Expand Down Expand Up @@ -4009,78 +4007,66 @@ CK_RV check_bool_attribute(void *value, bool check) {
return CKR_ATTRIBUTE_VALUE_INVALID;
}

static int BN_cmp_f5(BIGNUM *bn) {
BIGNUM *f5 = BN_new();
BN_set_word(f5, 0x010001);
int cmp = BN_cmp(bn, f5);
BN_free(f5);
return cmp;
}

CK_RV parse_rsa_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
yubihsm_pkcs11_object_template *template) {

uint8_t *e = NULL;
uint16_t primelen = 0;
BIGNUM *e = NULL;
CK_RV rv;
for (CK_ULONG i = 0; i < ulCount; i++) {
switch (pTemplate[i].type) {

case CKA_PRIME_1:
if (template->obj.rsa.p == NULL) {
template->obj.rsa.p = (CK_BYTE_PTR) pTemplate[i].pValue;
if (pTemplate[i].ulValueLen % 2 != 0) {
pTemplate[i].ulValueLen--;
template->obj.rsa.p++;
}
if (primelen == 0 || primelen == pTemplate[i].ulValueLen) {
primelen = pTemplate[i].ulValueLen;
} else {
DBG_ERR("CKA_PRIME_1 inconsistent in Template");
return CKR_TEMPLATE_INCONSISTENT;
}
template->obj.rsa.p = BN_bin2bn(pTemplate[i].pValue, pTemplate[i].ulValueLen, NULL);
} else {
DBG_ERR("CKA_PRIME_1 inconsistent in Template");
DBG_ERR("CKA_PRIME_1 inconsistent in template");
return CKR_TEMPLATE_INCONSISTENT;
}
break;

case CKA_PRIME_2:
if (template->obj.rsa.q == NULL) {
template->obj.rsa.q = (CK_BYTE_PTR) pTemplate[i].pValue;
if (pTemplate[i].ulValueLen % 2 != 0) {
pTemplate[i].ulValueLen--;
template->obj.rsa.q++;
}
if (primelen == 0 || primelen == pTemplate[i].ulValueLen) {
primelen = pTemplate[i].ulValueLen;
} else {
DBG_ERR("CKA_PRIME_2 inconsistent in Template");
return CKR_TEMPLATE_INCONSISTENT;
}
template->obj.rsa.q = BN_bin2bn(pTemplate[i].pValue, pTemplate[i].ulValueLen, NULL);
} else {
DBG_ERR("CKA_PRIME_2 inconsistent in Template");
DBG_ERR("CKA_PRIME_2 inconsistent in template");
return CKR_TEMPLATE_INCONSISTENT;
}
break;

case CKA_PUBLIC_EXPONENT:
if (e == NULL) {
e = (CK_BYTE_PTR) pTemplate[i].pValue;
if (pTemplate[i].ulValueLen != 3 ||
memcmp(e, "\x01\x00\x01", 3) != 0) {
DBG_ERR("CKA_PUBLIC_EXPONENT invalid in Template");
return CKR_ATTRIBUTE_VALUE_INVALID;
if(e == NULL) {
e = BN_bin2bn(pTemplate[i].pValue, pTemplate[i].ulValueLen, NULL);
if(e == NULL || BN_cmp_f5(e)) {
DBG_ERR("CKA_PUBLIC_EXPONENT invalid in template");
BN_free(e);
return CKR_ATTRIBUTE_VALUE_INVALID;;
}
BN_free(e);
} else {
DBG_ERR("CKA_PUBLIC_EXPONENT inconsistent in template");
return CKR_TEMPLATE_INCONSISTENT;
}
break;

case CKA_SIGN:
if ((rv = set_template_attribute(&template->sign,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_SIGN inconsistent in Template");
DBG_ERR("CKA_SIGN inconsistent in template");
return rv;
}
break;

case CKA_DECRYPT:
if ((rv = set_template_attribute(&template->decrypt,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_DECRYPT inconsistent in Template");
DBG_ERR("CKA_DECRYPT inconsistent in template");
return rv;
}
break;
Expand Down Expand Up @@ -4138,38 +4124,43 @@ CK_RV parse_rsa_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
return CKR_ATTRIBUTE_TYPE_INVALID;
}
}
if (e && template->obj.rsa.p && template->obj.rsa.q) {
template->objlen = primelen;
switch (primelen) {
if (template->obj.rsa.p && template->obj.rsa.q) {
if(BN_num_bytes(template->obj.rsa.p) != BN_num_bytes(template->obj.rsa.q)) {
DBG_ERR("Inconsistent prime sizes in template");
return CKR_ATTRIBUTE_VALUE_INVALID;
}
switch (BN_num_bytes(template->obj.rsa.p)) {
case 128:
template->algorithm = YH_ALGO_RSA_2048;
template->objlen = 256;
break;
case 192:
template->algorithm = YH_ALGO_RSA_3072;
template->objlen = 384;
break;
case 256:
template->algorithm = YH_ALGO_RSA_4096;
template->objlen = 512;
break;
default:
DBG_ERR("Invalid prime length in Template");
DBG_ERR("Invalid primes in template");
return CKR_ATTRIBUTE_VALUE_INVALID;
}
} else {
DBG_ERR("Iconsistent RSA Template");
DBG_ERR("Iconsistent RSA template");
return CKR_TEMPLATE_INCONSISTENT;
}
return CKR_OK;
}

static CK_RV parse_ecparams(uint8_t *ecparams, uint16_t ecparams_len,
static CK_RV parse_ecparams(const uint8_t *ecparams, uint16_t ecparams_len,
yh_algorithm *algorithm, uint16_t *key_len) {
EC_GROUP *group = EC_GROUP_new(EC_GFp_simple_method());
const uint8_t *param_ptr = ecparams;
int curve = 0;
if (group == NULL) {
return CKR_HOST_MEMORY;
}
if (d2i_ECPKParameters(&group, &param_ptr, ecparams_len) != NULL) {
if (d2i_ECPKParameters(&group, &ecparams, ecparams_len) != NULL) {
curve = EC_GROUP_get_curve_name(group);
}
EC_GROUP_free(group);
Expand Down Expand Up @@ -4221,44 +4212,44 @@ static CK_RV parse_ecparams(uint8_t *ecparams, uint16_t ecparams_len,
CK_RV parse_ec_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
yubihsm_pkcs11_object_template *template) {

uint8_t *ecparams = NULL;
uint16_t ecparams_len = 0;
CK_RV rv;
for (CK_ULONG i = 0; i < ulCount; i++) {
switch (pTemplate[i].type) {

case CKA_VALUE:
if (template->obj.buf == NULL) {
template->obj.buf = (CK_BYTE_PTR) pTemplate[i].pValue;
template->objlen = pTemplate[i].ulValueLen;
if (template->obj.ec.d == NULL) {
template->obj.ec.d = BN_bin2bn(pTemplate[i].pValue, pTemplate[i].ulValueLen, NULL);
} else {
DBG_ERR("CKA_VALUE inconsistent in Template");
DBG_ERR("CKA_VALUE inconsistent in template");
return CKR_TEMPLATE_INCONSISTENT;
}
break;

case CKA_EC_PARAMS:
if (ecparams == NULL) {
ecparams = (CK_BYTE_PTR) pTemplate[i].pValue;
ecparams_len = pTemplate[i].ulValueLen;
if (template->objlen == 0) {
rv = parse_ecparams(pTemplate[i].pValue, pTemplate[i].ulValueLen, &template->algorithm, &template->objlen);
if (rv != CKR_OK) {
DBG_ERR("Invalid EC parameters in template");
return rv;
}
} else {
DBG_ERR("CKA_EC_PARAMS inconsistent in Template");
DBG_ERR("CKA_EC_PARAMS inconsistent in template");
return CKR_TEMPLATE_INCONSISTENT;
}
break;

case CKA_SIGN:
if ((rv = set_template_attribute(&template->sign,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_SIGN inconsistent in Template");
DBG_ERR("CKA_SIGN inconsistent in template");
return rv;
}
break;

case CKA_DERIVE:
if ((rv = set_template_attribute(&template->derive,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_DERIVE inconsistent in Template");
DBG_ERR("CKA_DERIVE inconsistent in template");
return rv;
}
break;
Expand Down Expand Up @@ -4313,22 +4304,10 @@ CK_RV parse_ec_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
return CKR_ATTRIBUTE_TYPE_INVALID;
}
}
if (ecparams && template->obj.buf) {
uint16_t key_len;
rv = parse_ecparams(ecparams, ecparams_len, &template->algorithm, &key_len);
if (rv != CKR_OK) {
DBG_ERR("Invalid EC parameters in Template");
return rv;
}
if (key_len != template->objlen) {
DBG_ERR("Invalid EC parameter length in Template");
return CKR_ATTRIBUTE_VALUE_INVALID;
}
} else {
DBG_ERR("Inconsistent EC Template");
if (template->obj.ec.d == NULL || template->objlen == 0) {
DBG_ERR("Inconsistent EC template");
return CKR_TEMPLATE_INCONSISTENT;
}

return CKR_OK;
}

Expand All @@ -4344,26 +4323,26 @@ CK_RV parse_hmac_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
case CKA_VALUE:
if (generate == false && template->obj.buf == NULL) {
// TODO: consider hanshing the key here if it's longer than blocklen
template->obj.buf = (CK_BYTE_PTR) pTemplate[i].pValue;
template->obj.buf = pTemplate[i].pValue;
template->objlen = pTemplate[i].ulValueLen;
} else {
DBG_ERR("CKA_VALUE inconsistent in Template");
DBG_ERR("CKA_VALUE inconsistent in template");
return CKR_TEMPLATE_INCONSISTENT;
}
break;

case CKA_SIGN:
if ((rv = set_template_attribute(&template->sign,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_SIGN inconsistent in Template");
DBG_ERR("CKA_SIGN inconsistent in template");
return rv;
}
break;

case CKA_VERIFY:
if ((rv = set_template_attribute(&template->verify,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_VERIFY inconsistent in Template");
DBG_ERR("CKA_VERIFY inconsistent in template");
return rv;
}
break;
Expand All @@ -4383,7 +4362,7 @@ CK_RV parse_hmac_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
template->algorithm = YH_ALGO_HMAC_SHA512;
break;
default:
DBG_ERR("CKA_KEY_TYPE inconsistent in Template");
DBG_ERR("CKA_KEY_TYPE inconsistent in template");
return CKR_TEMPLATE_INCONSISTENT;
}
break;
Expand Down Expand Up @@ -4432,7 +4411,7 @@ CK_RV parse_hmac_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
if (template->algorithm && (generate == true || template->obj.buf)) {
return CKR_OK;
} else {
DBG_ERR("Inconsistent HMAC Template");
DBG_ERR("Inconsistent HMAC template");
return CKR_TEMPLATE_INCONSISTENT;
}
}
Expand Down Expand Up @@ -4974,10 +4953,10 @@ CK_RV parse_wrap_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,

case CKA_VALUE:
if (generate == false && template->obj.buf == NULL) {
template->obj.buf = (CK_BYTE_PTR) pTemplate[i].pValue;
template->obj.buf = pTemplate[i].pValue;
template->objlen = pTemplate[i].ulValueLen;
} else {
DBG_ERR("CKA_VALUE inconsistent in Template");
DBG_ERR("CKA_VALUE inconsistent in template");
return CKR_TEMPLATE_INCONSISTENT;
}
break;
Expand All @@ -5000,31 +4979,31 @@ CK_RV parse_wrap_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
case CKA_WRAP:
if ((rv = set_template_attribute(&template->wrap,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_WRAP inconsistent in Template");
DBG_ERR("CKA_WRAP inconsistent in template");
return rv;
}
break;

case CKA_UNWRAP:
if ((rv = set_template_attribute(&template->unwrap,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_UNWRAP inconsistent in Template");
DBG_ERR("CKA_UNWRAP inconsistent in template");
return rv;
}
break;

case CKA_ENCRYPT:
if ((rv = set_template_attribute(&template->encrypt,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_ENCRYPT inconsistent in Template");
DBG_ERR("CKA_ENCRYPT inconsistent in template");
return rv;
}
break;

case CKA_DECRYPT:
if ((rv = set_template_attribute(&template->decrypt,
pTemplate[i].pValue)) != CKR_OK) {
DBG_ERR("CKA_DECRYPT inconsistent in Template");
DBG_ERR("CKA_DECRYPT inconsistent in template");
return rv;
}
break;
Expand Down Expand Up @@ -5086,7 +5065,7 @@ CK_RV parse_aes_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,

case CKA_VALUE:
if (generate == false && template->obj.buf == NULL) {
template->obj.buf = (CK_BYTE_PTR) pTemplate[i].pValue;
template->obj.buf = pTemplate[i].pValue;
template->objlen = keylen = pTemplate[i].ulValueLen;
} else {
return CKR_TEMPLATE_INCONSISTENT;
Expand Down
Loading

0 comments on commit d751f53

Please sign in to comment.