diff --git a/pkcs11/util_pkcs11.c b/pkcs11/util_pkcs11.c index 8d4d38c3..52296073 100644 --- a/pkcs11/util_pkcs11.c +++ b/pkcs11/util_pkcs11.c @@ -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) { @@ -4009,62 +4007,50 @@ 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; @@ -4072,7 +4058,7 @@ CK_RV parse_rsa_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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; @@ -4080,7 +4066,7 @@ CK_RV parse_rsa_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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; @@ -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, ¶m_ptr, ecparams_len) != NULL) { + if (d2i_ECPKParameters(&group, &ecparams, ecparams_len) != NULL) { curve = EC_GROUP_get_curve_name(group); } EC_GROUP_free(group); @@ -4221,28 +4212,28 @@ 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; @@ -4250,7 +4241,7 @@ CK_RV parse_ec_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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; @@ -4258,7 +4249,7 @@ CK_RV parse_ec_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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; @@ -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; } @@ -4344,10 +4323,10 @@ 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; @@ -4355,7 +4334,7 @@ CK_RV parse_hmac_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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; @@ -4363,7 +4342,7 @@ CK_RV parse_hmac_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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; @@ -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; @@ -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; } } @@ -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; @@ -5000,7 +4979,7 @@ 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; @@ -5008,7 +4987,7 @@ CK_RV parse_wrap_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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; @@ -5016,7 +4995,7 @@ CK_RV parse_wrap_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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; @@ -5024,7 +5003,7 @@ CK_RV parse_wrap_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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; @@ -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; diff --git a/pkcs11/yubihsm_pkcs11.c b/pkcs11/yubihsm_pkcs11.c index 3889ed46..fb93e540 100644 --- a/pkcs11/yubihsm_pkcs11.c +++ b/pkcs11/yubihsm_pkcs11.c @@ -31,6 +31,7 @@ #include "yubihsm_pkcs11.h" #include "../common/insecure_memzero.h" #include "../common/parsing.h" +#include "../common/util.h" #ifdef __WIN32 #include @@ -1398,7 +1399,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject) case CKA_EXTRACTABLE: if ((rv = set_template_attribute(&template.exportable, pTemplate[i].pValue)) != CKR_OK) { - DBG_ERR("CKA_EXTRACTABLE inconsistent in Template"); + DBG_ERR("CKA_EXTRACTABLE inconsistent in template"); goto c_co_out; } } @@ -1454,10 +1455,17 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject) } } + uint8_t p[512], q[512]; + + set_component(p, template.obj.rsa.p, template.objlen / 2); + set_component(q, template.obj.rsa.q, template.objlen / 2); + + BN_free(template.obj.rsa.p); + BN_free(template.obj.rsa.q); + rc = yh_util_import_rsa_key(session->slot->device_session, &template.id, template.label, 0xffff, &capabilities, - template.algorithm, template.obj.rsa.p, - template.obj.rsa.q); + template.algorithm, p, q); if (rc != YHR_SUCCESS) { DBG_ERR("Failed writing RSA key to device: %s", yh_strerror(rc)); rv = yrc_to_rv(rc); @@ -1488,9 +1496,14 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject) } } + uint8_t d[128]; + set_component(d, template.obj.ec.d, template.objlen); + + BN_free(template.obj.ec.d); + rc = yh_util_import_ec_key(session->slot->device_session, &template.id, template.label, 0xffff, &capabilities, - template.algorithm, template.obj.buf); + template.algorithm, d); if (rc != YHR_SUCCESS) { DBG_ERR("Failed writing EC key to device: %s", yh_strerror(rc)); rv = yrc_to_rv(rc); @@ -4983,7 +4996,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GenerateKey) case CKA_EXTRACTABLE: if ((rv = set_template_attribute(&template.exportable, pTemplate[i].pValue)) != CKR_OK) { - DBG_ERR("CKA_EXTRACTABLE inconsistent in Template"); + DBG_ERR("CKA_EXTRACTABLE inconsistent in template"); return rv; } } diff --git a/pkcs11/yubihsm_pkcs11.h b/pkcs11/yubihsm_pkcs11.h index 422d8620..d969f5e4 100644 --- a/pkcs11/yubihsm_pkcs11.h +++ b/pkcs11/yubihsm_pkcs11.h @@ -239,9 +239,12 @@ typedef struct { uint16_t objlen; union { struct { - uint8_t *p; - uint8_t *q; + BIGNUM *p; + BIGNUM *q; } rsa; + struct { + BIGNUM *d; + } ec; uint8_t *buf; } obj; } yubihsm_pkcs11_object_template; diff --git a/src/commands.c b/src/commands.c index 39a0afc4..59b9d8a2 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1055,7 +1055,7 @@ int yh_com_get_pubkey(yubihsm_context *ctx, Argument *argv, cmd_format in_fmt, } BIGNUM *e = BN_new(); BIGNUM *n = BN_bin2bn(response, response_len, NULL); - BN_hex2bn(&e, "10001"); + BN_set_word(e, 0x010001); if (RSA_set0_key(rsa, n, e, NULL) != 1) { fprintf(stderr, "Failed to set RSA key\n"); RSA_free(rsa);