diff options
author | David Phillips <david@sighup.nz> | 2017-05-28 21:13:54 +1200 |
---|---|---|
committer | David Phillips <david@sighup.nz> | 2017-05-28 21:15:06 +1200 |
commit | cd1702d70f5e5a38cfb215d0952dbfb45eb7b2a1 (patch) | |
tree | d9c040cb2c7afd05a04fe11965af929cb2a7d2e3 /key_update.c | |
parent | 89512e156e8eeb1637727591666e332baa7233bc (diff) | |
download | sand-leek-cd1702d70f5e5a38cfb215d0952dbfb45eb7b2a1.tar.xz |
Openssl-1.0 compat
Diffstat (limited to 'key_update.c')
-rw-r--r-- | key_update.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/key_update.c b/key_update.c new file mode 100644 index 0000000..c9b90cc --- /dev/null +++ b/key_update.c @@ -0,0 +1,115 @@ +#include <openssl/bn.h> +#include <openssl/rsa.h> + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +/* re-calculate the decryption key `d` for the given key + * the product of e and d must be congruent to 1, and since we are messing + * with e to generate our keys, we must re-calculate d */ +int +key_update_d(RSA *rsa_key) { + const BIGNUM *p = NULL; + const BIGNUM *q = NULL; + const BIGNUM *d = NULL; + const BIGNUM *e = NULL; + BIGNUM *gcd = BN_secure_new(); + BIGNUM *p1 = BN_secure_new(); + BIGNUM *q1 = BN_secure_new(); + BIGNUM *p1q1 = BN_secure_new(); + BIGNUM *lambda_n = BN_secure_new(); + BIGNUM *true_d = BN_secure_new(); + BIGNUM *true_dmp1 = BN_secure_new(); + BIGNUM *true_dmq1 = BN_secure_new(); + BIGNUM *true_iqmp = BN_secure_new(); + BN_CTX *bn_ctx = BN_CTX_secure_new(); + + if (!(bn_ctx && gcd && p1 && q1 && p1q1 && lambda_n && true_d && + true_dmp1 && true_dmq1 && true_iqmp)) { + perror("bignum or bignum context allocation"); + return 1; + } + + RSA_get0_key(rsa_key, NULL, &e, &d); + RSA_get0_factors(rsa_key, &p, &q); + + /* calculate p-1 and q-1 and their product */ + BN_sub(p1, p, BN_value_one()); + BN_sub(q1, q, BN_value_one()); + BN_mul(p1q1, p1, q1, bn_ctx); + + /* calculate LCM of p1,q1 with p1*q1/gcd(p1,q1) */ + BN_gcd(gcd, p1, q1, bn_ctx); + BN_div(lambda_n, NULL, p1q1, gcd, bn_ctx); + + BN_mod_inverse(true_d, e, lambda_n, bn_ctx); + BN_mod_inverse(true_iqmp, q, p, bn_ctx); + BN_mod(rsa_key->dmp, true_d, p1, bn_ctx); + BN_mod(rsa_key->dmq, true_d, q1, bn_ctx); + + /* cleanup BN structs not managed by RSA internal functions */ + BN_clear_free(gcd); + BN_clear_free(p1); + BN_clear_free(q1); + BN_clear_free(p1q1); + BN_clear_free(lambda_n); + BN_CTX_free(bn_ctx); + + if (!RSA_set0_key(rsa_key, NULL, NULL, true_d)) { + fprintf(stderr, "setting d failed\n"); + return 1; + } + if (!RSA_set0_crt_params(rsa_key, true_dmp1, true_dmq1, true_iqmp)) { + fprintf(stderr, "setting crt params failed\n"); + return 1; + } + return 0; +} + +#else + +/* re-calculate the decryption key `d` for the given key + * the product of e and d must be congruent to 1, and since we are messing + * with e to generate our keys, we must re-calculate d */ +int +key_update_d(RSA *rsa_key) { + BIGNUM *gcd = BN_new(); + BIGNUM *p1 = BN_new(); + BIGNUM *q1 = BN_new(); + BIGNUM *p1q1 = BN_new(); + BIGNUM *lambda_n = BN_new(); + BIGNUM *true_d = BN_new(); + BIGNUM *true_dmp1 = BN_new(); + BIGNUM *true_dmq1 = BN_new(); + BIGNUM *true_iqmp = BN_new(); + BN_CTX *bn_ctx = BN_CTX_new(); + + if (!(bn_ctx && gcd && p1 && q1 && p1q1 && lambda_n && true_d && + true_dmp1 && true_dmq1 && true_iqmp)) { + perror("bignum or bignum context allocation"); + return 1; + } + + /* calculate p-1 and q-1 and their product */ + BN_sub(p1, rsa_key->p, BN_value_one()); + BN_sub(q1, rsa_key->q, BN_value_one()); + BN_mul(p1q1, p1, q1, bn_ctx); + + /* calculate LCM of p1,q1 with p1*q1/gcd(p1,q1) */ + BN_gcd(gcd, p1, q1, bn_ctx); + BN_div(lambda_n, NULL, p1q1, gcd, bn_ctx); + + BN_mod_inverse(rsa_key->d, rsa_key->e, lambda_n, bn_ctx); + BN_mod_inverse(true_iqmp, rsa_key->q, rsa_key->p, bn_ctx); + BN_mod(rsa_key->dmp1, rsa_key->d, p1, bn_ctx); + BN_mod(rsa_key->dmq1, rsa_key->d, q1, bn_ctx); + + /* cleanup BN structs not managed by RSA internal functions */ + BN_clear_free(gcd); + BN_clear_free(p1); + BN_clear_free(q1); + BN_clear_free(p1q1); + BN_clear_free(lambda_n); + BN_CTX_free(bn_ctx); + + return 0; +} +#endif |