start adding secp384r1
This commit is contained in:
+1
-1
@@ -41,7 +41,7 @@ text "
|
||||
9c is for Digital Signature (PIN always checked)
|
||||
9d is for Key Management
|
||||
9e is for Card Authentication (PIN never checked)\n"
|
||||
option "algorithm" A "What algorithm to use" values="RSA1024","RSA2048","ECCP256" enum optional default="RSA2048"
|
||||
option "algorithm" A "What algorithm to use" values="RSA1024","RSA2048","ECCP256","ECCP384" enum optional default="RSA2048"
|
||||
option "hash" H "Hash to use for signatures" values="SHA1","SHA256","SHA512" enum optional default="SHA256"
|
||||
option "new-key" n "New authentication key to use" string optional
|
||||
option "pin-retries" - "Number of retries before the pin code is blocked" int optional dependon="puk-retries"
|
||||
|
||||
@@ -80,6 +80,8 @@ unsigned char get_algorithm(EVP_PKEY *key) {
|
||||
int curve = EC_GROUP_get_curve_name(group);
|
||||
if(curve == NID_X9_62_prime256v1) {
|
||||
return YKPIV_ALGO_ECCP256;
|
||||
} else if(curve == NID_secp384r1) {
|
||||
return YKPIV_ALGO_ECCP384;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown EC curve %d\n", curve);
|
||||
return 0;
|
||||
|
||||
+37
-12
@@ -138,6 +138,9 @@ static bool generate_key(ykpiv_state *state, const char *slot,
|
||||
case algorithm_arg_ECCP256:
|
||||
in_data[4] = YKPIV_ALGO_ECCP256;
|
||||
break;
|
||||
case algorithm_arg_ECCP384:
|
||||
in_data[4] = YKPIV_ALGO_ECCP384;
|
||||
break;
|
||||
case algorithm__NULL:
|
||||
default:
|
||||
fprintf(stderr, "Unexepcted algorithm.\n");
|
||||
@@ -189,24 +192,34 @@ static bool generate_key(ykpiv_state *state, const char *slot,
|
||||
rsa->n = bignum_n;
|
||||
rsa->e = bignum_e;
|
||||
EVP_PKEY_set1_RSA(public_key, rsa);
|
||||
} else if(algorithm == algorithm_arg_ECCP256) {
|
||||
} else if(algorithm == algorithm_arg_ECCP256 || algorithm == algorithm_arg_ECCP384) {
|
||||
EC_GROUP *group;
|
||||
unsigned char *data_ptr = data + 3;
|
||||
int nid;
|
||||
size_t len;
|
||||
|
||||
if(algorithm == algorithm_arg_ECCP256) {
|
||||
nid = NID_X9_62_prime256v1;
|
||||
len = 65;
|
||||
} else {
|
||||
nid = NID_secp384r1;
|
||||
len = 97;
|
||||
}
|
||||
|
||||
eckey = EC_KEY_new();
|
||||
group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
|
||||
EC_GROUP_set_asn1_flag(group, NID_X9_62_prime256v1);
|
||||
group = EC_GROUP_new_by_curve_name(nid);
|
||||
EC_GROUP_set_asn1_flag(group, nid);
|
||||
EC_KEY_set_group(eckey, group);
|
||||
point = EC_POINT_new(group);
|
||||
if(*data_ptr++ != 0x86) {
|
||||
fprintf(stderr, "Failed to parse public key structure.\n");
|
||||
goto generate_out;
|
||||
}
|
||||
if(*data_ptr++ != 65) { /* the curve point should always be 65 bytes */
|
||||
if(*data_ptr++ != len) { /* the curve point should always be 65 bytes */
|
||||
fprintf(stderr, "Unexpected length.\n");
|
||||
goto generate_out;
|
||||
}
|
||||
if(!EC_POINT_oct2point(group, point, data_ptr, 65, NULL)) {
|
||||
if(!EC_POINT_oct2point(group, point, data_ptr, len, NULL)) {
|
||||
fprintf(stderr, "Failed to load public point.\n");
|
||||
goto generate_out;
|
||||
}
|
||||
@@ -674,6 +687,7 @@ static bool request_certificate(ykpiv_state *state, enum enum_key_format key_for
|
||||
}
|
||||
break;
|
||||
case YKPIV_ALGO_ECCP256:
|
||||
case YKPIV_ALGO_ECCP384:
|
||||
signinput = digest + oid_len;
|
||||
len = digest_len;
|
||||
switch(hash) {
|
||||
@@ -866,6 +880,7 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo
|
||||
}
|
||||
break;
|
||||
case YKPIV_ALGO_ECCP256:
|
||||
case YKPIV_ALGO_ECCP384:
|
||||
signinput = digest + oid_len;
|
||||
len = md_len;
|
||||
switch(hash) {
|
||||
@@ -1577,20 +1592,30 @@ static bool test_decipher(ykpiv_state *state, enum enum_slot slot,
|
||||
} else {
|
||||
fprintf(stderr, "Failed unwrapping PKCS1 envelope.\n");
|
||||
}
|
||||
} else {
|
||||
unsigned char secret[32];
|
||||
unsigned char secret2[32];
|
||||
unsigned char public_key[65];
|
||||
} else if(algorithm == YKPIV_ALGO_ECCP256 || algorithm == YKPIV_ALGO_ECCP384) {
|
||||
unsigned char secret[48];
|
||||
unsigned char secret2[48];
|
||||
unsigned char public_key[97];
|
||||
unsigned char *ptr = public_key;
|
||||
size_t len = sizeof(secret);
|
||||
EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pubkey);
|
||||
int nid;
|
||||
size_t key_len;
|
||||
|
||||
tmpkey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
||||
if(algorithm == YKPIV_ALGO_ECCP256) {
|
||||
nid = NID_X9_62_prime256v1;
|
||||
key_len = 32;
|
||||
} else {
|
||||
nid = NID_secp384r1;
|
||||
key_len = 48;
|
||||
}
|
||||
|
||||
tmpkey = EC_KEY_new_by_curve_name(nid);
|
||||
EC_KEY_generate_key(tmpkey);
|
||||
ECDH_compute_key(secret, len, EC_KEY_get0_public_key(ec), tmpkey, NULL);
|
||||
|
||||
i2o_ECPublicKey(tmpkey, &ptr);
|
||||
if(ykpiv_decipher_data(state, public_key, sizeof(public_key), secret2, &len, algorithm, key) != YKPIV_OK) {
|
||||
if(ykpiv_decipher_data(state, public_key, (key_len * 2) + 1, secret2, &len, algorithm, key) != YKPIV_OK) {
|
||||
fprintf(stderr, "Failed ECDH exchange!\n");
|
||||
goto decipher_out;
|
||||
}
|
||||
@@ -1600,7 +1625,7 @@ static bool test_decipher(ykpiv_state *state, enum enum_slot slot,
|
||||
fprintf(stderr, "ECDH card generated: ");
|
||||
dump_hex(secret2, len, stderr, true);
|
||||
}
|
||||
if(memcmp(secret, secret2, 32) == 0) {
|
||||
if(memcmp(secret, secret2, key_len) == 0) {
|
||||
fprintf(stderr, "Successfully performed ECDH exchange with card.\n");
|
||||
ret = true;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user