diff options
Diffstat (limited to 'src/lib/libcrypto/dh/dh_key.c')
| -rw-r--r-- | src/lib/libcrypto/dh/dh_key.c | 131 |
1 files changed, 106 insertions, 25 deletions
diff --git a/src/lib/libcrypto/dh/dh_key.c b/src/lib/libcrypto/dh/dh_key.c index 7576772bcd..1a0efca2c4 100644 --- a/src/lib/libcrypto/dh/dh_key.c +++ b/src/lib/libcrypto/dh/dh_key.c | |||
| @@ -58,32 +58,63 @@ | |||
| 58 | 58 | ||
| 59 | #include <stdio.h> | 59 | #include <stdio.h> |
| 60 | #include "cryptlib.h" | 60 | #include "cryptlib.h" |
| 61 | #include "bn.h" | 61 | #include <openssl/bn.h> |
| 62 | #include "rand.h" | 62 | #include <openssl/rand.h> |
| 63 | #include "dh.h" | 63 | #include <openssl/dh.h> |
| 64 | #include <openssl/engine.h> | ||
| 64 | 65 | ||
| 65 | int DH_generate_key(dh) | 66 | static int generate_key(DH *dh); |
| 66 | DH *dh; | 67 | static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); |
| 68 | static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, | ||
| 69 | const BIGNUM *a, const BIGNUM *p, | ||
| 70 | const BIGNUM *m, BN_CTX *ctx, | ||
| 71 | BN_MONT_CTX *m_ctx); | ||
| 72 | static int dh_init(DH *dh); | ||
| 73 | static int dh_finish(DH *dh); | ||
| 74 | |||
| 75 | int DH_generate_key(DH *dh) | ||
| 76 | { | ||
| 77 | return dh->meth->generate_key(dh); | ||
| 78 | } | ||
| 79 | |||
| 80 | int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | ||
| 81 | { | ||
| 82 | return dh->meth->compute_key(key, pub_key, dh); | ||
| 83 | } | ||
| 84 | |||
| 85 | static DH_METHOD dh_ossl = { | ||
| 86 | "OpenSSL DH Method", | ||
| 87 | generate_key, | ||
| 88 | compute_key, | ||
| 89 | dh_bn_mod_exp, | ||
| 90 | dh_init, | ||
| 91 | dh_finish, | ||
| 92 | 0, | ||
| 93 | NULL | ||
| 94 | }; | ||
| 95 | |||
| 96 | const DH_METHOD *DH_OpenSSL(void) | ||
| 97 | { | ||
| 98 | return &dh_ossl; | ||
| 99 | } | ||
| 100 | |||
| 101 | static int generate_key(DH *dh) | ||
| 67 | { | 102 | { |
| 68 | int ok=0; | 103 | int ok=0; |
| 69 | unsigned int i; | 104 | int generate_new_key=0; |
| 70 | BN_CTX *ctx=NULL; | 105 | unsigned l; |
| 106 | BN_CTX *ctx; | ||
| 107 | BN_MONT_CTX *mont; | ||
| 71 | BIGNUM *pub_key=NULL,*priv_key=NULL; | 108 | BIGNUM *pub_key=NULL,*priv_key=NULL; |
| 72 | 109 | ||
| 73 | ctx=BN_CTX_new(); | 110 | ctx = BN_CTX_new(); |
| 74 | if (ctx == NULL) goto err; | 111 | if (ctx == NULL) goto err; |
| 75 | 112 | ||
| 76 | if (dh->priv_key == NULL) | 113 | if (dh->priv_key == NULL) |
| 77 | { | 114 | { |
| 78 | i=dh->length; | ||
| 79 | if (i == 0) | ||
| 80 | { | ||
| 81 | /* Make the number p-1 bits long */ | ||
| 82 | i=BN_num_bits(dh->p)-1; | ||
| 83 | } | ||
| 84 | priv_key=BN_new(); | 115 | priv_key=BN_new(); |
| 85 | if (priv_key == NULL) goto err; | 116 | if (priv_key == NULL) goto err; |
| 86 | if (!BN_rand(priv_key,i,0,0)) goto err; | 117 | generate_new_key=1; |
| 87 | } | 118 | } |
| 88 | else | 119 | else |
| 89 | priv_key=dh->priv_key; | 120 | priv_key=dh->priv_key; |
| @@ -96,7 +127,21 @@ DH *dh; | |||
| 96 | else | 127 | else |
| 97 | pub_key=dh->pub_key; | 128 | pub_key=dh->pub_key; |
| 98 | 129 | ||
| 99 | if (!BN_mod_exp(pub_key,dh->g,priv_key,dh->p,ctx)) goto err; | 130 | if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P)) |
| 131 | { | ||
| 132 | if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) | ||
| 133 | if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p, | ||
| 134 | dh->p,ctx)) goto err; | ||
| 135 | } | ||
| 136 | mont=(BN_MONT_CTX *)dh->method_mont_p; | ||
| 137 | |||
| 138 | if (generate_new_key) | ||
| 139 | { | ||
| 140 | l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */ | ||
| 141 | if (!BN_rand(priv_key, l, 0, 0)) goto err; | ||
| 142 | } | ||
| 143 | if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, priv_key,dh->p,ctx,mont)) | ||
| 144 | goto err; | ||
| 100 | 145 | ||
| 101 | dh->pub_key=pub_key; | 146 | dh->pub_key=pub_key; |
| 102 | dh->priv_key=priv_key; | 147 | dh->priv_key=priv_key; |
| @@ -107,29 +152,36 @@ err: | |||
| 107 | 152 | ||
| 108 | if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); | 153 | if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); |
| 109 | if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); | 154 | if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); |
| 110 | if (ctx != NULL) BN_CTX_free(ctx); | 155 | BN_CTX_free(ctx); |
| 111 | return(ok); | 156 | return(ok); |
| 112 | } | 157 | } |
| 113 | 158 | ||
| 114 | int DH_compute_key(key,pub_key,dh) | 159 | static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) |
| 115 | unsigned char *key; | ||
| 116 | BIGNUM *pub_key; | ||
| 117 | DH *dh; | ||
| 118 | { | 160 | { |
| 119 | BN_CTX *ctx; | 161 | BN_CTX *ctx; |
| 162 | BN_MONT_CTX *mont; | ||
| 120 | BIGNUM *tmp; | 163 | BIGNUM *tmp; |
| 121 | int ret= -1; | 164 | int ret= -1; |
| 122 | 165 | ||
| 123 | ctx=BN_CTX_new(); | 166 | ctx = BN_CTX_new(); |
| 124 | if (ctx == NULL) goto err; | 167 | if (ctx == NULL) goto err; |
| 125 | tmp=ctx->bn[ctx->tos++]; | 168 | BN_CTX_start(ctx); |
| 169 | tmp = BN_CTX_get(ctx); | ||
| 126 | 170 | ||
| 127 | if (dh->priv_key == NULL) | 171 | if (dh->priv_key == NULL) |
| 128 | { | 172 | { |
| 129 | DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE); | 173 | DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE); |
| 130 | goto err; | 174 | goto err; |
| 131 | } | 175 | } |
| 132 | if (!BN_mod_exp(tmp,pub_key,dh->priv_key,dh->p,ctx)) | 176 | if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P)) |
| 177 | { | ||
| 178 | if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) | ||
| 179 | if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p, | ||
| 180 | dh->p,ctx)) goto err; | ||
| 181 | } | ||
| 182 | |||
| 183 | mont=(BN_MONT_CTX *)dh->method_mont_p; | ||
| 184 | if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont)) | ||
| 133 | { | 185 | { |
| 134 | DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB); | 186 | DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB); |
| 135 | goto err; | 187 | goto err; |
| @@ -137,6 +189,35 @@ DH *dh; | |||
| 137 | 189 | ||
| 138 | ret=BN_bn2bin(tmp,key); | 190 | ret=BN_bn2bin(tmp,key); |
| 139 | err: | 191 | err: |
| 140 | if (ctx != NULL) BN_CTX_free(ctx); | 192 | BN_CTX_end(ctx); |
| 193 | BN_CTX_free(ctx); | ||
| 141 | return(ret); | 194 | return(ret); |
| 142 | } | 195 | } |
| 196 | |||
| 197 | static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, | ||
| 198 | const BIGNUM *a, const BIGNUM *p, | ||
| 199 | const BIGNUM *m, BN_CTX *ctx, | ||
| 200 | BN_MONT_CTX *m_ctx) | ||
| 201 | { | ||
| 202 | if (a->top == 1) | ||
| 203 | { | ||
| 204 | BN_ULONG A = a->d[0]; | ||
| 205 | return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx); | ||
| 206 | } | ||
| 207 | else | ||
| 208 | return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx); | ||
| 209 | } | ||
| 210 | |||
| 211 | |||
| 212 | static int dh_init(DH *dh) | ||
| 213 | { | ||
| 214 | dh->flags |= DH_FLAG_CACHE_MONT_P; | ||
| 215 | return(1); | ||
| 216 | } | ||
| 217 | |||
| 218 | static int dh_finish(DH *dh) | ||
| 219 | { | ||
| 220 | if(dh->method_mont_p) | ||
| 221 | BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p); | ||
| 222 | return(1); | ||
| 223 | } | ||
