aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2012-11-18 19:22:31 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2012-11-18 19:22:31 +0100
commit168ee460c6b2137d347b87fa534ce720c40ba112 (patch)
tree8deb36197a38bffcc8fa280509904b9fd8cc650a /src
parentc1c98f5f4a4a4305c44389dda3363c2026c886c1 (diff)
downloadstrongswan-168ee460c6b2137d347b87fa534ce720c40ba112.tar.bz2
strongswan-168ee460c6b2137d347b87fa534ce720c40ba112.tar.xz
implemented generation of safe primes
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/credentials/builder.c1
-rw-r--r--src/libstrongswan/credentials/builder.h2
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c50
-rw-r--r--src/pki/commands/gen.c27
4 files changed, 60 insertions, 20 deletions
diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c
index d3157c80e..be5f8b79b 100644
--- a/src/libstrongswan/credentials/builder.c
+++ b/src/libstrongswan/credentials/builder.c
@@ -64,6 +64,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
"BUILD_RSA_EXP1",
"BUILD_RSA_EXP2",
"BUILD_RSA_COEFF",
+ "BUILD_SAFE_PRIMES",
"BUILD_END",
);
diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h
index 41250ccae..6f2444a7b 100644
--- a/src/libstrongswan/credentials/builder.h
+++ b/src/libstrongswan/credentials/builder.h
@@ -139,6 +139,8 @@ enum builder_part_t {
BUILD_RSA_EXP2,
/** coefficient (coeff) of a RSA key, chunk_t */
BUILD_RSA_COEFF,
+ /** generate (p) and (q) as safe primes */
+ BUILD_SAFE_PRIMES,
/** end of variable argument builder list */
BUILD_END,
};
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
index 6ecf4ec52..e86028721 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
@@ -132,10 +132,10 @@ static void mpz_clear_sensitive(mpz_t z)
/**
* Create a mpz prime of at least prime_size
*/
-static status_t compute_prime(private_gmp_rsa_private_key_t *this,
- size_t prime_size, mpz_t *prime)
+static status_t compute_prime(size_t prime_size, bool safe, mpz_t *prime)
{
rng_t *rng;
+ mpz_t q;
chunk_t random_bytes;
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(q);
+
do
{
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);
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);
- mpz_nextprime (*prime, *prime);
+ /* make sure the two most significant bits are set */
+ 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);
}
- /* check if it isn't too large */
+
+ /* check if the prime isn't too large */
while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size);
rng->destroy(rng);
+ mpz_clear(q);
+
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;
private_gmp_rsa_private_key_t *this;
u_int key_size = 0;
+ bool safe_prime = FALSE;
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:
key_size = va_arg(args, u_int);
continue;
+ case BUILD_SAFE_PRIMES:
+ safe_prime = TRUE;
+ continue;
case BUILD_END:
break;
default:
@@ -620,19 +645,16 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args)
return NULL;
}
- this = gmp_rsa_private_key_create_empty();
key_size = key_size / BITS_PER_BYTE;
/* 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;
}
- if (compute_prime(this, key_size/2, &q) != SUCCESS)
+ if (compute_prime(key_size/2, safe_prime, &q) != SUCCESS)
{
mpz_clear(p);
- free(this);
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_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_init_set(q1, q); /* q1 = q */
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(t);
+ this = gmp_rsa_private_key_create_empty();
+
/* apply values */
*(this->p) = *p;
*(this->q) = *q;
diff --git a/src/pki/commands/gen.c b/src/pki/commands/gen.c
index 33d9cf35d..d6c4c2e10 100644
--- a/src/pki/commands/gen.c
+++ b/src/pki/commands/gen.c
@@ -25,6 +25,7 @@ static int gen()
u_int size = 0;
private_key_t *key;
chunk_t encoding;
+ bool safe_primes = FALSE;
char *arg;
while (TRUE)
@@ -60,6 +61,9 @@ static int gen()
return command_usage("invalid key size");
}
continue;
+ case 'p':
+ safe_primes = TRUE;
+ continue;
case EOF:
break;
default:
@@ -82,8 +86,16 @@ static int gen()
break;
}
}
- key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
- BUILD_KEY_SIZE, size, BUILD_END);
+ if (type == KEY_RSA && safe_primes)
+ {
+ 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)
{
fprintf(stderr, "private key generation failed\n");
@@ -113,12 +125,13 @@ static void __attribute__ ((constructor))reg()
{
command_register((command_t) {
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"},
- {"type", 't', 1, "type of key, default: rsa"},
- {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"},
- {"outform", 'f', 1, "encoding of generated private key"},
+ {"help", 'h', 0, "show usage information"},
+ {"type", 't', 1, "type of key, default: rsa"},
+ {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"},
+ {"safe-primes", 'p', 0, "generate rsa safe primes"},
+ {"outform", 'f', 1, "encoding of generated private key"},
}
});
}