diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2012-11-18 19:22:31 +0100 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2012-11-18 19:22:31 +0100 |
commit | 168ee460c6b2137d347b87fa534ce720c40ba112 (patch) | |
tree | 8deb36197a38bffcc8fa280509904b9fd8cc650a /src | |
parent | c1c98f5f4a4a4305c44389dda3363c2026c886c1 (diff) | |
download | strongswan-168ee460c6b2137d347b87fa534ce720c40ba112.tar.bz2 strongswan-168ee460c6b2137d347b87fa534ce720c40ba112.tar.xz |
implemented generation of safe primes
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/credentials/builder.c | 1 | ||||
-rw-r--r-- | src/libstrongswan/credentials/builder.h | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c | 50 | ||||
-rw-r--r-- | src/pki/commands/gen.c | 27 |
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"}, } }); } |