implemented generation of safe primes
This commit is contained in:
@@ -64,6 +64,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
|
|||||||
"BUILD_RSA_EXP1",
|
"BUILD_RSA_EXP1",
|
||||||
"BUILD_RSA_EXP2",
|
"BUILD_RSA_EXP2",
|
||||||
"BUILD_RSA_COEFF",
|
"BUILD_RSA_COEFF",
|
||||||
|
"BUILD_SAFE_PRIMES",
|
||||||
"BUILD_END",
|
"BUILD_END",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,8 @@ enum builder_part_t {
|
|||||||
BUILD_RSA_EXP2,
|
BUILD_RSA_EXP2,
|
||||||
/** coefficient (coeff) of a RSA key, chunk_t */
|
/** coefficient (coeff) of a RSA key, chunk_t */
|
||||||
BUILD_RSA_COEFF,
|
BUILD_RSA_COEFF,
|
||||||
|
/** generate (p) and (q) as safe primes */
|
||||||
|
BUILD_SAFE_PRIMES,
|
||||||
/** end of variable argument builder list */
|
/** end of variable argument builder list */
|
||||||
BUILD_END,
|
BUILD_END,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -132,10 +132,10 @@ static void mpz_clear_sensitive(mpz_t z)
|
|||||||
/**
|
/**
|
||||||
* Create a mpz prime of at least prime_size
|
* Create a mpz prime of at least prime_size
|
||||||
*/
|
*/
|
||||||
static status_t compute_prime(private_gmp_rsa_private_key_t *this,
|
static status_t compute_prime(size_t prime_size, bool safe, mpz_t *prime)
|
||||||
size_t prime_size, mpz_t *prime)
|
|
||||||
{
|
{
|
||||||
rng_t *rng;
|
rng_t *rng;
|
||||||
|
mpz_t q;
|
||||||
chunk_t random_bytes;
|
chunk_t random_bytes;
|
||||||
|
|
||||||
rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
|
rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
|
||||||
@@ -147,6 +147,8 @@ static status_t compute_prime(private_gmp_rsa_private_key_t *this,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mpz_init(*prime);
|
mpz_init(*prime);
|
||||||
|
mpz_init(q);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!rng->allocate_bytes(rng, prime_size, &random_bytes))
|
if (!rng->allocate_bytes(rng, prime_size, &random_bytes))
|
||||||
@@ -155,17 +157,36 @@ static status_t compute_prime(private_gmp_rsa_private_key_t *this,
|
|||||||
rng->destroy(rng);
|
rng->destroy(rng);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
/* make sure the two most significant bits are set */
|
|
||||||
random_bytes.ptr[0] = random_bytes.ptr[0] | 0xC0;
|
|
||||||
|
|
||||||
mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
|
/* make sure the two most significant bits are set */
|
||||||
mpz_nextprime (*prime, *prime);
|
if (safe)
|
||||||
|
{
|
||||||
|
random_bytes.ptr[0] &= 0x7F;
|
||||||
|
random_bytes.ptr[0] |= 0x60;
|
||||||
|
mpz_import(q, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
mpz_nextprime (q, q);
|
||||||
|
mpz_mul_ui(*prime, q, 2);
|
||||||
|
mpz_add_ui(*prime, *prime, 1);
|
||||||
|
}
|
||||||
|
while (mpz_probab_prime_p(*prime, 10) == 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
random_bytes.ptr[0] |= 0xC0;
|
||||||
|
mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
|
||||||
|
mpz_nextprime (*prime, *prime);
|
||||||
|
}
|
||||||
chunk_clear(&random_bytes);
|
chunk_clear(&random_bytes);
|
||||||
}
|
}
|
||||||
/* check if it isn't too large */
|
|
||||||
|
/* check if the prime isn't too large */
|
||||||
while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size);
|
while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size);
|
||||||
|
|
||||||
rng->destroy(rng);
|
rng->destroy(rng);
|
||||||
|
mpz_clear(q);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -600,6 +621,7 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args)
|
|||||||
mpz_t p, q, n, e, d, exp1, exp2, coeff, m, q1, t;
|
mpz_t p, q, n, e, d, exp1, exp2, coeff, m, q1, t;
|
||||||
private_gmp_rsa_private_key_t *this;
|
private_gmp_rsa_private_key_t *this;
|
||||||
u_int key_size = 0;
|
u_int key_size = 0;
|
||||||
|
bool safe_prime = FALSE;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
@@ -608,6 +630,9 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args)
|
|||||||
case BUILD_KEY_SIZE:
|
case BUILD_KEY_SIZE:
|
||||||
key_size = va_arg(args, u_int);
|
key_size = va_arg(args, u_int);
|
||||||
continue;
|
continue;
|
||||||
|
case BUILD_SAFE_PRIMES:
|
||||||
|
safe_prime = TRUE;
|
||||||
|
continue;
|
||||||
case BUILD_END:
|
case BUILD_END:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -620,19 +645,16 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
this = gmp_rsa_private_key_create_empty();
|
|
||||||
key_size = key_size / BITS_PER_BYTE;
|
key_size = key_size / BITS_PER_BYTE;
|
||||||
|
|
||||||
/* Get values of primes p and q */
|
/* Get values of primes p and q */
|
||||||
if (compute_prime(this, key_size/2, &p) != SUCCESS)
|
if (compute_prime(key_size/2, safe_prime, &p) != SUCCESS)
|
||||||
{
|
{
|
||||||
free(this);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (compute_prime(this, key_size/2, &q) != SUCCESS)
|
if (compute_prime(key_size/2, safe_prime, &q) != SUCCESS)
|
||||||
{
|
{
|
||||||
mpz_clear(p);
|
mpz_clear(p);
|
||||||
free(this);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -651,7 +673,7 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args)
|
|||||||
|
|
||||||
mpz_mul(n, p, q); /* n = p*q */
|
mpz_mul(n, p, q); /* n = p*q */
|
||||||
mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */
|
mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */
|
||||||
mpz_init_set(m, p); /* m = p */
|
mpz_init_set(m, p); /* m = p */
|
||||||
mpz_sub_ui(m, m, 1); /* m = m -1 */
|
mpz_sub_ui(m, m, 1); /* m = m -1 */
|
||||||
mpz_init_set(q1, q); /* q1 = q */
|
mpz_init_set(q1, q); /* q1 = q */
|
||||||
mpz_sub_ui(q1, q1, 1); /* q1 = q1 -1 */
|
mpz_sub_ui(q1, q1, 1); /* q1 = q1 -1 */
|
||||||
@@ -680,6 +702,8 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args)
|
|||||||
mpz_clear_sensitive(m);
|
mpz_clear_sensitive(m);
|
||||||
mpz_clear_sensitive(t);
|
mpz_clear_sensitive(t);
|
||||||
|
|
||||||
|
this = gmp_rsa_private_key_create_empty();
|
||||||
|
|
||||||
/* apply values */
|
/* apply values */
|
||||||
*(this->p) = *p;
|
*(this->p) = *p;
|
||||||
*(this->q) = *q;
|
*(this->q) = *q;
|
||||||
|
|||||||
+20
-7
@@ -25,6 +25,7 @@ static int gen()
|
|||||||
u_int size = 0;
|
u_int size = 0;
|
||||||
private_key_t *key;
|
private_key_t *key;
|
||||||
chunk_t encoding;
|
chunk_t encoding;
|
||||||
|
bool safe_primes = FALSE;
|
||||||
char *arg;
|
char *arg;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
@@ -60,6 +61,9 @@ static int gen()
|
|||||||
return command_usage("invalid key size");
|
return command_usage("invalid key size");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
case 'p':
|
||||||
|
safe_primes = TRUE;
|
||||||
|
continue;
|
||||||
case EOF:
|
case EOF:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -82,8 +86,16 @@ static int gen()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
|
if (type == KEY_RSA && safe_primes)
|
||||||
BUILD_KEY_SIZE, size, BUILD_END);
|
{
|
||||||
|
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
|
||||||
|
BUILD_KEY_SIZE, size, BUILD_SAFE_PRIMES, BUILD_END);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
|
||||||
|
BUILD_KEY_SIZE, size, BUILD_END);
|
||||||
|
}
|
||||||
if (!key)
|
if (!key)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "private key generation failed\n");
|
fprintf(stderr, "private key generation failed\n");
|
||||||
@@ -113,12 +125,13 @@ static void __attribute__ ((constructor))reg()
|
|||||||
{
|
{
|
||||||
command_register((command_t) {
|
command_register((command_t) {
|
||||||
gen, 'g', "gen", "generate a new private key",
|
gen, 'g', "gen", "generate a new private key",
|
||||||
{"[--type rsa|ecdsa] [--size bits] [--outform der|pem|pgp]"},
|
{"[--type rsa|ecdsa] [--size bits] [--safe-primes] [--outform der|pem|pgp]"},
|
||||||
{
|
{
|
||||||
{"help", 'h', 0, "show usage information"},
|
{"help", 'h', 0, "show usage information"},
|
||||||
{"type", 't', 1, "type of key, default: rsa"},
|
{"type", 't', 1, "type of key, default: rsa"},
|
||||||
{"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"},
|
{"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"},
|
||||||
{"outform", 'f', 1, "encoding of generated private key"},
|
{"safe-primes", 'p', 0, "generate rsa safe primes"},
|
||||||
|
{"outform", 'f', 1, "encoding of generated private key"},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user