diff options
Diffstat (limited to 'src/lib/libcrypto/dh/dh_pmeth.c')
| -rw-r--r-- | src/lib/libcrypto/dh/dh_pmeth.c | 113 |
1 files changed, 60 insertions, 53 deletions
diff --git a/src/lib/libcrypto/dh/dh_pmeth.c b/src/lib/libcrypto/dh/dh_pmeth.c index cb424ac149..fb441b563b 100644 --- a/src/lib/libcrypto/dh/dh_pmeth.c +++ b/src/lib/libcrypto/dh/dh_pmeth.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: dh_pmeth.c,v 1.6 2014/06/12 20:40:57 deraadt Exp $ */ | 1 | /* $OpenBSD: dh_pmeth.c,v 1.7 2014/07/09 13:26:47 miod Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2006. | 3 | * project 2006. |
| 4 | */ | 4 | */ |
| @@ -68,8 +68,7 @@ | |||
| 68 | 68 | ||
| 69 | /* DH pkey context structure */ | 69 | /* DH pkey context structure */ |
| 70 | 70 | ||
| 71 | typedef struct | 71 | typedef struct { |
| 72 | { | ||
| 73 | /* Parameter gen parameters */ | 72 | /* Parameter gen parameters */ |
| 74 | int prime_len; | 73 | int prime_len; |
| 75 | int generator; | 74 | int generator; |
| @@ -77,11 +76,13 @@ typedef struct | |||
| 77 | /* Keygen callback info */ | 76 | /* Keygen callback info */ |
| 78 | int gentmp[2]; | 77 | int gentmp[2]; |
| 79 | /* message digest */ | 78 | /* message digest */ |
| 80 | } DH_PKEY_CTX; | 79 | } DH_PKEY_CTX; |
| 81 | 80 | ||
| 82 | static int pkey_dh_init(EVP_PKEY_CTX *ctx) | 81 | static int |
| 83 | { | 82 | pkey_dh_init(EVP_PKEY_CTX *ctx) |
| 83 | { | ||
| 84 | DH_PKEY_CTX *dctx; | 84 | DH_PKEY_CTX *dctx; |
| 85 | |||
| 85 | dctx = malloc(sizeof(DH_PKEY_CTX)); | 86 | dctx = malloc(sizeof(DH_PKEY_CTX)); |
| 86 | if (!dctx) | 87 | if (!dctx) |
| 87 | return 0; | 88 | return 0; |
| @@ -94,11 +95,13 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx) | |||
| 94 | ctx->keygen_info_count = 2; | 95 | ctx->keygen_info_count = 2; |
| 95 | 96 | ||
| 96 | return 1; | 97 | return 1; |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 99 | static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | 100 | static int |
| 100 | { | 101 | pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) |
| 102 | { | ||
| 101 | DH_PKEY_CTX *dctx, *sctx; | 103 | DH_PKEY_CTX *dctx, *sctx; |
| 104 | |||
| 102 | if (!pkey_dh_init(dst)) | 105 | if (!pkey_dh_init(dst)) |
| 103 | return 0; | 106 | return 0; |
| 104 | sctx = src->data; | 107 | sctx = src->data; |
| @@ -107,43 +110,44 @@ static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | |||
| 107 | dctx->generator = sctx->generator; | 110 | dctx->generator = sctx->generator; |
| 108 | dctx->use_dsa = sctx->use_dsa; | 111 | dctx->use_dsa = sctx->use_dsa; |
| 109 | return 1; | 112 | return 1; |
| 110 | } | 113 | } |
| 111 | 114 | ||
| 112 | static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) | 115 | static void |
| 113 | { | 116 | pkey_dh_cleanup(EVP_PKEY_CTX *ctx) |
| 117 | { | ||
| 114 | DH_PKEY_CTX *dctx = ctx->data; | 118 | DH_PKEY_CTX *dctx = ctx->data; |
| 119 | |||
| 115 | free(dctx); | 120 | free(dctx); |
| 116 | } | 121 | } |
| 117 | 122 | ||
| 118 | static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | 123 | static int |
| 119 | { | 124 | pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) |
| 125 | { | ||
| 120 | DH_PKEY_CTX *dctx = ctx->data; | 126 | DH_PKEY_CTX *dctx = ctx->data; |
| 121 | switch (type) | 127 | |
| 122 | { | 128 | switch (type) { |
| 123 | case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: | 129 | case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: |
| 124 | if (p1 < 256) | 130 | if (p1 < 256) |
| 125 | return -2; | 131 | return -2; |
| 126 | dctx->prime_len = p1; | 132 | dctx->prime_len = p1; |
| 127 | return 1; | 133 | return 1; |
| 128 | 134 | ||
| 129 | case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: | 135 | case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: |
| 130 | dctx->generator = p1; | 136 | dctx->generator = p1; |
| 131 | return 1; | 137 | return 1; |
| 132 | 138 | ||
| 133 | case EVP_PKEY_CTRL_PEER_KEY: | 139 | case EVP_PKEY_CTRL_PEER_KEY: |
| 134 | /* Default behaviour is OK */ | 140 | /* Default behaviour is OK */ |
| 135 | return 1; | 141 | return 1; |
| 136 | 142 | ||
| 137 | default: | 143 | default: |
| 138 | return -2; | 144 | return -2; |
| 139 | |||
| 140 | } | ||
| 141 | } | 145 | } |
| 142 | 146 | } | |
| 143 | 147 | ||
| 144 | static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, | 148 | static int |
| 145 | const char *type, const char *value) | 149 | pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) |
| 146 | { | 150 | { |
| 147 | long lval; | 151 | long lval; |
| 148 | char *ep; | 152 | char *ep; |
| 149 | int len; | 153 | int len; |
| @@ -153,18 +157,19 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, | |||
| 153 | lval = strtol(value, &ep, 10); | 157 | lval = strtol(value, &ep, 10); |
| 154 | if (value[0] == '\0' || *ep != '\0') | 158 | if (value[0] == '\0' || *ep != '\0') |
| 155 | goto not_a_number; | 159 | goto not_a_number; |
| 156 | if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) || | 160 | if ((errno == ERANGE && |
| 161 | (lval == LONG_MAX || lval == LONG_MIN)) || | ||
| 157 | (lval > INT_MAX || lval < INT_MIN)) | 162 | (lval > INT_MAX || lval < INT_MIN)) |
| 158 | goto out_of_range; | 163 | goto out_of_range; |
| 159 | len = lval; | 164 | len = lval; |
| 160 | return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); | 165 | return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); |
| 161 | } | 166 | } else if (!strcmp(type, "dh_paramgen_generator")) { |
| 162 | if (!strcmp(type, "dh_paramgen_generator")) { | ||
| 163 | errno = 0; | 167 | errno = 0; |
| 164 | lval = strtol(value, &ep, 10); | 168 | lval = strtol(value, &ep, 10); |
| 165 | if (value[0] == '\0' || *ep != '\0') | 169 | if (value[0] == '\0' || *ep != '\0') |
| 166 | goto not_a_number; | 170 | goto not_a_number; |
| 167 | if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) || | 171 | if ((errno == ERANGE && |
| 172 | (lval == LONG_MAX || lval == LONG_MIN)) || | ||
| 168 | (lval > INT_MAX || lval < INT_MIN)) | 173 | (lval > INT_MAX || lval < INT_MIN)) |
| 169 | goto out_of_range; | 174 | goto out_of_range; |
| 170 | len = lval; | 175 | len = lval; |
| @@ -176,39 +181,40 @@ out_of_range: | |||
| 176 | return -2; | 181 | return -2; |
| 177 | } | 182 | } |
| 178 | 183 | ||
| 179 | static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | 184 | static int |
| 180 | { | 185 | pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) |
| 186 | { | ||
| 181 | DH *dh = NULL; | 187 | DH *dh = NULL; |
| 182 | DH_PKEY_CTX *dctx = ctx->data; | 188 | DH_PKEY_CTX *dctx = ctx->data; |
| 183 | BN_GENCB *pcb, cb; | 189 | BN_GENCB *pcb, cb; |
| 184 | int ret; | 190 | int ret; |
| 185 | if (ctx->pkey_gencb) | 191 | |
| 186 | { | 192 | if (ctx->pkey_gencb) { |
| 187 | pcb = &cb; | 193 | pcb = &cb; |
| 188 | evp_pkey_set_cb_translate(pcb, ctx); | 194 | evp_pkey_set_cb_translate(pcb, ctx); |
| 189 | } | 195 | } else |
| 190 | else | ||
| 191 | pcb = NULL; | 196 | pcb = NULL; |
| 192 | dh = DH_new(); | 197 | dh = DH_new(); |
| 193 | if (!dh) | 198 | if (!dh) |
| 194 | return 0; | 199 | return 0; |
| 195 | ret = DH_generate_parameters_ex(dh, | 200 | ret = DH_generate_parameters_ex(dh, dctx->prime_len, dctx->generator, |
| 196 | dctx->prime_len, dctx->generator, pcb); | 201 | pcb); |
| 197 | if (ret) | 202 | if (ret) |
| 198 | EVP_PKEY_assign_DH(pkey, dh); | 203 | EVP_PKEY_assign_DH(pkey, dh); |
| 199 | else | 204 | else |
| 200 | DH_free(dh); | 205 | DH_free(dh); |
| 201 | return ret; | 206 | return ret; |
| 202 | } | 207 | } |
| 203 | 208 | ||
| 204 | static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | 209 | static int |
| 205 | { | 210 | pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) |
| 211 | { | ||
| 206 | DH *dh = NULL; | 212 | DH *dh = NULL; |
| 207 | if (ctx->pkey == NULL) | 213 | |
| 208 | { | 214 | if (ctx->pkey == NULL) { |
| 209 | DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); | 215 | DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); |
| 210 | return 0; | 216 | return 0; |
| 211 | } | 217 | } |
| 212 | dh = DH_new(); | 218 | dh = DH_new(); |
| 213 | if (!dh) | 219 | if (!dh) |
| 214 | return 0; | 220 | return 0; |
| @@ -217,23 +223,24 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | |||
| 217 | if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) | 223 | if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) |
| 218 | return 0; | 224 | return 0; |
| 219 | return DH_generate_key(pkey->pkey.dh); | 225 | return DH_generate_key(pkey->pkey.dh); |
| 220 | } | 226 | } |
| 221 | 227 | ||
| 222 | static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) | 228 | static int |
| 223 | { | 229 | pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) |
| 230 | { | ||
| 224 | int ret; | 231 | int ret; |
| 225 | if (!ctx->pkey || !ctx->peerkey) | 232 | |
| 226 | { | 233 | if (!ctx->pkey || !ctx->peerkey) { |
| 227 | DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); | 234 | DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); |
| 228 | return 0; | 235 | return 0; |
| 229 | } | 236 | } |
| 230 | ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key, | 237 | ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key, |
| 231 | ctx->pkey->pkey.dh); | 238 | ctx->pkey->pkey.dh); |
| 232 | if (ret < 0) | 239 | if (ret < 0) |
| 233 | return ret; | 240 | return ret; |
| 234 | *keylen = ret; | 241 | *keylen = ret; |
| 235 | return 1; | 242 | return 1; |
| 236 | } | 243 | } |
| 237 | 244 | ||
| 238 | const EVP_PKEY_METHOD dh_pkey_meth = { | 245 | const EVP_PKEY_METHOD dh_pkey_meth = { |
| 239 | .pkey_id = EVP_PKEY_DH, | 246 | .pkey_id = EVP_PKEY_DH, |
