Skip to content

Commit

Permalink
Add support for RSA3072 and RSA4096
Browse files Browse the repository at this point in the history
  • Loading branch information
aveenismail committed Jan 18, 2024
1 parent f857aa3 commit e65e968
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 72 deletions.
15 changes: 0 additions & 15 deletions common/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,18 +663,3 @@ int SSH_write_X509(FILE *fp, X509 *x) {
return ret;

}

bool is_rsa_key_algorithm(unsigned char algo) {
if(algo == YKPIV_ALGO_RSA1024 || algo == YKPIV_ALGO_RSA2048 ||
algo == YKPIV_ALGO_RSA3072 || algo == YKPIV_ALGO_RSA4096) {
return true;
}
return false;
}

bool is_ec_key_algorithm(unsigned char algo) {
if(algo == YKPIV_ALGO_ECCP256 || algo == YKPIV_ALGO_ECCP384) {
return true;
}
return false;
}
6 changes: 2 additions & 4 deletions lib/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,6 @@ ykpiv_rc ykpiv_util_generate_key(ykpiv_state *state, uint8_t slot, uint8_t algor
(state->ver.major < 5 || (ykpiv_util_devicemodel(state) == DEVTYPE_YK5 && state->ver.minor < 7))) {
DBG("RSA3072 and RSA4096 keys are only supported in YubiKey version 5.7.0 and above");
return YKPIV_NOT_SUPPORTED;

}
if (ykpiv_util_devicemodel(state) == DEVTYPE_YK4 && (algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048)) {
if ((state->ver.major == 4) && (state->ver.minor < 3 || ((state->ver.minor == 3) && (state->ver.patch < 5)))) {
Expand Down Expand Up @@ -872,8 +871,7 @@ ykpiv_rc ykpiv_util_generate_key(ykpiv_state *state, uint8_t slot, uint8_t algor
goto Cleanup;
}

if ((YKPIV_ALGO_RSA1024 == algorithm) || (YKPIV_ALGO_RSA2048 == algorithm) ||
(YKPIV_ALGO_RSA3072 == algorithm) || (YKPIV_ALGO_RSA4096 == algorithm)) {
if (YKPIV_IS_RSA(algorithm)) {
size_t len;
unsigned char *data_ptr = data + 2 + _ykpiv_get_length(data + 2, data + recv_len, &len);

Expand Down Expand Up @@ -936,7 +934,7 @@ ykpiv_rc ykpiv_util_generate_key(ykpiv_state *state, uint8_t slot, uint8_t algor
ptr_exp = NULL;
*exp_len = cb_exp;
}
else if ((YKPIV_ALGO_ECCP256 == algorithm) || (YKPIV_ALGO_ECCP384 == algorithm)) {
else if (YKPIV_IS_EC(algorithm)) {
unsigned char *data_ptr = data + 3;
size_t len;

Expand Down
3 changes: 1 addition & 2 deletions lib/ykpiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

#include <zlib.h>

#include "../common/util.h"
#include "internal.h"
#include "ykpiv.h"

Expand Down Expand Up @@ -1907,7 +1906,7 @@ ykpiv_rc ykpiv_import_private_key(ykpiv_state *state, const unsigned char key, u
touch_policy != YKPIV_TOUCHPOLICY_CACHED)
return YKPIV_GENERIC_ERROR;

if (is_rsa_key_algorithm(algorithm)) {
if (YKPIV_IS_RSA(algorithm)) {

if ((algorithm == YKPIV_ALGO_RSA3072 || algorithm == YKPIV_ALGO_RSA4096) &&
(state->ver.major < 5 || (ykpiv_util_devicemodel(state) == DEVTYPE_YK5 && state->ver.minor < 7))) {
Expand Down
130 changes: 79 additions & 51 deletions tool/yubico-piv-tool.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,24 @@ static bool sign_data(ykpiv_state *state, const unsigned char *in, size_t len, u

unsigned char signinput[1024] = {0};
if(YKPIV_IS_RSA(algorithm)) {
size_t padlen = algorithm == YKPIV_ALGO_RSA1024 ? 128 : 256;
size_t padlen = 0;
switch (algorithm) {
case YKPIV_ALGO_RSA1024:
padlen = 128;
break;
case YKPIV_ALGO_RSA2048:
padlen = 256;
break;
case YKPIV_ALGO_RSA3072:
padlen = 384;
break;
case YKPIV_ALGO_RSA4096:
padlen = 512;
break;
default:
fprintf(stderr, "Unknown RSA algorithm.\n");
return false;
}
if(RSA_padding_add_PKCS1_type_1(signinput, padlen, in, len) == 0) {
fprintf(stderr, "Failed adding padding.\n");
return false;
Expand Down Expand Up @@ -288,62 +305,71 @@ static bool generate_key(ykpiv_state *state, enum enum_slot slot,
goto generate_out;
}

if(key_format == key_format_arg_PEM) {
if (key_format == key_format_arg_PEM) {
public_key = EVP_PKEY_new();
if(algorithm == algorithm_arg_RSA1024 || algorithm == algorithm_arg_RSA2048) {
BIGNUM *bignum_n = NULL;
BIGNUM *bignum_e = NULL;
rsa = RSA_new();
bignum_n = BN_bin2bn(mod, mod_len, NULL);
if (bignum_n == NULL) {
fprintf(stderr, "Failed to parse public key modulus.\n");
goto generate_out;
}
bignum_e = BN_bin2bn(exp, exp_len, NULL);
if(bignum_e == NULL) {
fprintf(stderr, "Failed to parse public key exponent.\n");
goto generate_out;
}
switch (algorithm) {
case algorithm_arg_RSA1024:
case algorithm_arg_RSA2048:
case algorithm_arg_RSA3072:
case algorithm_arg_RSA4096: {
BIGNUM *bignum_n = NULL;
BIGNUM *bignum_e = NULL;
rsa = RSA_new();
bignum_n = BN_bin2bn(mod, mod_len, NULL);
if (bignum_n == NULL) {
fprintf(stderr, "Failed to parse public key modulus.\n");
goto generate_out;
}
bignum_e = BN_bin2bn(exp, exp_len, NULL);
if (bignum_e == NULL) {
fprintf(stderr, "Failed to parse public key exponent.\n");
goto generate_out;
}

if(RSA_set0_key(rsa, bignum_n, bignum_e, NULL) != 1) {
fprintf(stderr, "Failed to set RSA key\n");
goto generate_out;
}
if(EVP_PKEY_set1_RSA(public_key, rsa) != 1) {
fprintf(stderr, "Failed to set RSA public key\n");
goto generate_out;
if (RSA_set0_key(rsa, bignum_n, bignum_e, NULL) != 1) {
fprintf(stderr, "Failed to set RSA key\n");
goto generate_out;
}
if (EVP_PKEY_set1_RSA(public_key, rsa) != 1) {
fprintf(stderr, "Failed to set RSA public key\n");
goto generate_out;
}
}
} else if(algorithm == algorithm_arg_ECCP256 || algorithm == algorithm_arg_ECCP384) {
int nid;
break;
case algorithm_arg_ECCP256:
case algorithm_arg_ECCP384: {
int nid;

if(algorithm == algorithm_arg_ECCP256) {
nid = NID_X9_62_prime256v1;
} else {
nid = NID_secp384r1;
}
eckey = EC_KEY_new();
group = EC_GROUP_new_by_curve_name(nid);
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
if(EC_KEY_set_group(eckey, group) != 1) {
fprintf(stderr, "Failed to set EC group.\n");
goto generate_out;
}
ecpoint = EC_POINT_new(group);
if (algorithm == algorithm_arg_ECCP256) {
nid = NID_X9_62_prime256v1;
} else {
nid = NID_secp384r1;
}
eckey = EC_KEY_new();
group = EC_GROUP_new_by_curve_name(nid);
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
if (EC_KEY_set_group(eckey, group) != 1) {
fprintf(stderr, "Failed to set EC group.\n");
goto generate_out;
}
ecpoint = EC_POINT_new(group);

if(!EC_POINT_oct2point(group, ecpoint, point, point_len, NULL)) {
fprintf(stderr, "Failed to load public point.\n");
goto generate_out;
}
if(!EC_KEY_set_public_key(eckey, ecpoint)) {
fprintf(stderr, "Failed to set the public key.\n");
goto generate_out;
}
if(EVP_PKEY_set1_EC_KEY(public_key, eckey) != 1) {
fprintf(stderr, "Failed to set EC public key.\n");
goto generate_out;
if (!EC_POINT_oct2point(group, ecpoint, point, point_len, NULL)) {
fprintf(stderr, "Failed to load public point.\n");
goto generate_out;
}
if (!EC_KEY_set_public_key(eckey, ecpoint)) {
fprintf(stderr, "Failed to set the public key.\n");
goto generate_out;
}
if (EVP_PKEY_set1_EC_KEY(public_key, eckey) != 1) {
fprintf(stderr, "Failed to set EC public key.\n");
goto generate_out;
}
}
} else {
fprintf(stderr, "Wrong algorithm.\n");
break;
default:
fprintf(stderr, "Wrong algorithm.\n");
}
if(PEM_write_PUBKEY(output_file, public_key) == 1) {
ret = true;
Expand Down Expand Up @@ -1830,6 +1856,8 @@ static bool test_signature(ykpiv_state *state, enum enum_slot slot,
switch(algorithm) {
case YKPIV_ALGO_RSA1024:
case YKPIV_ALGO_RSA2048:
case YKPIV_ALGO_RSA3072:
case YKPIV_ALGO_RSA4096:
{
RSA *rsa = EVP_PKEY_get1_RSA(pubkey);
if(!rsa) {
Expand Down

0 comments on commit e65e968

Please sign in to comment.