1 /* 2 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* 11 * DH low level APIs are deprecated for public use, but still ok for 12 * internal use. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <stdio.h> 17 #include "internal/cryptlib.h" 18 #include <openssl/bn.h> 19 #include "dh_local.h" 20 #include "crypto/dh.h" 21 22 /*- 23 * Check that p and g are suitable enough 24 * 25 * p is odd 26 * 1 < g < p - 1 27 */ 28 int DH_check_params_ex(const DH *dh) 29 { 30 int errflags = 0; 31 32 if (!DH_check_params(dh, &errflags)) 33 return 0; 34 35 if ((errflags & DH_CHECK_P_NOT_PRIME) != 0) 36 ERR_raise(ERR_LIB_DH, DH_R_CHECK_P_NOT_PRIME); 37 if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0) 38 ERR_raise(ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR); 39 if ((errflags & DH_MODULUS_TOO_SMALL) != 0) 40 ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL); 41 if ((errflags & DH_MODULUS_TOO_LARGE) != 0) 42 ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); 43 44 return errflags == 0; 45 } 46 47 #ifdef FIPS_MODULE 48 int DH_check_params(const DH *dh, int *ret) 49 { 50 int nid; 51 52 *ret = 0; 53 /* 54 * SP800-56A R3 Section 5.5.2 Assurances of Domain Parameter Validity 55 * (1a) The domain parameters correspond to any approved safe prime group. 56 */ 57 nid = DH_get_nid((DH *)dh); 58 if (nid != NID_undef) 59 return 1; 60 /* 61 * OR 62 * (2b) FFC domain params conform to FIPS-186-4 explicit domain param 63 * validity tests. 64 */ 65 return ossl_ffc_params_FIPS186_4_validate(dh->libctx, &dh->params, 66 FFC_PARAM_TYPE_DH, ret, NULL); 67 } 68 #else 69 int DH_check_params(const DH *dh, int *ret) 70 { 71 int ok = 0; 72 BIGNUM *tmp = NULL; 73 BN_CTX *ctx = NULL; 74 75 *ret = 0; 76 ctx = BN_CTX_new_ex(dh->libctx); 77 if (ctx == NULL) 78 goto err; 79 BN_CTX_start(ctx); 80 tmp = BN_CTX_get(ctx); 81 if (tmp == NULL) 82 goto err; 83 84 if (!BN_is_odd(dh->params.p)) 85 *ret |= DH_CHECK_P_NOT_PRIME; 86 if (BN_is_negative(dh->params.g) 87 || BN_is_zero(dh->params.g) 88 || BN_is_one(dh->params.g)) 89 *ret |= DH_NOT_SUITABLE_GENERATOR; 90 if (BN_copy(tmp, dh->params.p) == NULL || !BN_sub_word(tmp, 1)) 91 goto err; 92 if (BN_cmp(dh->params.g, tmp) >= 0) 93 *ret |= DH_NOT_SUITABLE_GENERATOR; 94 if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) 95 *ret |= DH_MODULUS_TOO_SMALL; 96 if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) 97 *ret |= DH_MODULUS_TOO_LARGE; 98 99 ok = 1; 100 err: 101 BN_CTX_end(ctx); 102 BN_CTX_free(ctx); 103 return ok; 104 } 105 #endif /* FIPS_MODULE */ 106 107 /*- 108 * Check that p is a safe prime and 109 * g is a suitable generator. 110 */ 111 int DH_check_ex(const DH *dh) 112 { 113 int errflags = 0; 114 115 if (!DH_check(dh, &errflags)) 116 return 0; 117 118 if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0) 119 ERR_raise(ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR); 120 if ((errflags & DH_CHECK_Q_NOT_PRIME) != 0) 121 ERR_raise(ERR_LIB_DH, DH_R_CHECK_Q_NOT_PRIME); 122 if ((errflags & DH_CHECK_INVALID_Q_VALUE) != 0) 123 ERR_raise(ERR_LIB_DH, DH_R_CHECK_INVALID_Q_VALUE); 124 if ((errflags & DH_CHECK_INVALID_J_VALUE) != 0) 125 ERR_raise(ERR_LIB_DH, DH_R_CHECK_INVALID_J_VALUE); 126 if ((errflags & DH_UNABLE_TO_CHECK_GENERATOR) != 0) 127 ERR_raise(ERR_LIB_DH, DH_R_UNABLE_TO_CHECK_GENERATOR); 128 if ((errflags & DH_CHECK_P_NOT_PRIME) != 0) 129 ERR_raise(ERR_LIB_DH, DH_R_CHECK_P_NOT_PRIME); 130 if ((errflags & DH_CHECK_P_NOT_SAFE_PRIME) != 0) 131 ERR_raise(ERR_LIB_DH, DH_R_CHECK_P_NOT_SAFE_PRIME); 132 if ((errflags & DH_MODULUS_TOO_SMALL) != 0) 133 ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL); 134 if ((errflags & DH_MODULUS_TOO_LARGE) != 0) 135 ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); 136 137 return errflags == 0; 138 } 139 140 /* Note: according to documentation - this only checks the params */ 141 int DH_check(const DH *dh, int *ret) 142 { 143 #ifdef FIPS_MODULE 144 return DH_check_params(dh, ret); 145 #else 146 int ok = 0, r, q_good = 0; 147 BN_CTX *ctx = NULL; 148 BIGNUM *t1 = NULL, *t2 = NULL; 149 int nid = DH_get_nid((DH *)dh); 150 151 *ret = 0; 152 if (nid != NID_undef) 153 return 1; 154 155 /* Don't do any checks at all with an excessively large modulus */ 156 if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { 157 ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); 158 *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_P_NOT_PRIME; 159 return 0; 160 } 161 162 if (!DH_check_params(dh, ret)) 163 return 0; 164 165 ctx = BN_CTX_new_ex(dh->libctx); 166 if (ctx == NULL) 167 goto err; 168 BN_CTX_start(ctx); 169 t1 = BN_CTX_get(ctx); 170 t2 = BN_CTX_get(ctx); 171 if (t2 == NULL) 172 goto err; 173 174 if (dh->params.q != NULL) { 175 if (BN_ucmp(dh->params.p, dh->params.q) > 0) 176 q_good = 1; 177 else 178 *ret |= DH_CHECK_INVALID_Q_VALUE; 179 } 180 181 if (q_good) { 182 if (BN_cmp(dh->params.g, BN_value_one()) <= 0) 183 *ret |= DH_NOT_SUITABLE_GENERATOR; 184 else if (BN_cmp(dh->params.g, dh->params.p) >= 0) 185 *ret |= DH_NOT_SUITABLE_GENERATOR; 186 else { 187 /* Check g^q == 1 mod p */ 188 if (!BN_mod_exp(t1, dh->params.g, dh->params.q, dh->params.p, ctx)) 189 goto err; 190 if (!BN_is_one(t1)) 191 *ret |= DH_NOT_SUITABLE_GENERATOR; 192 } 193 r = BN_check_prime(dh->params.q, ctx, NULL); 194 if (r < 0) 195 goto err; 196 if (!r) 197 *ret |= DH_CHECK_Q_NOT_PRIME; 198 /* Check p == 1 mod q i.e. q divides p - 1 */ 199 if (!BN_div(t1, t2, dh->params.p, dh->params.q, ctx)) 200 goto err; 201 if (!BN_is_one(t2)) 202 *ret |= DH_CHECK_INVALID_Q_VALUE; 203 if (dh->params.j != NULL 204 && BN_cmp(dh->params.j, t1)) 205 *ret |= DH_CHECK_INVALID_J_VALUE; 206 } 207 208 r = BN_check_prime(dh->params.p, ctx, NULL); 209 if (r < 0) 210 goto err; 211 if (!r) 212 *ret |= DH_CHECK_P_NOT_PRIME; 213 else if (dh->params.q == NULL) { 214 if (!BN_rshift1(t1, dh->params.p)) 215 goto err; 216 r = BN_check_prime(t1, ctx, NULL); 217 if (r < 0) 218 goto err; 219 if (!r) 220 *ret |= DH_CHECK_P_NOT_SAFE_PRIME; 221 } 222 ok = 1; 223 err: 224 BN_CTX_end(ctx); 225 BN_CTX_free(ctx); 226 return ok; 227 #endif /* FIPS_MODULE */ 228 } 229 230 int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key) 231 { 232 int errflags = 0; 233 234 if (!DH_check_pub_key(dh, pub_key, &errflags)) 235 return 0; 236 237 if ((errflags & DH_CHECK_PUBKEY_TOO_SMALL) != 0) 238 ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_SMALL); 239 if ((errflags & DH_CHECK_PUBKEY_TOO_LARGE) != 0) 240 ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_LARGE); 241 if ((errflags & DH_CHECK_PUBKEY_INVALID) != 0) 242 ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID); 243 244 return errflags == 0; 245 } 246 247 /* 248 * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Full public key validation. 249 */ 250 int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) 251 { 252 return ossl_ffc_validate_public_key(&dh->params, pub_key, ret); 253 } 254 255 /* 256 * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Partial public key validation. 257 * To only be used with ephemeral FFC public keys generated using the approved 258 * safe-prime groups. 259 */ 260 int ossl_dh_check_pub_key_partial(const DH *dh, const BIGNUM *pub_key, int *ret) 261 { 262 return ossl_ffc_validate_public_key_partial(&dh->params, pub_key, ret) 263 && *ret == 0; 264 } 265 266 int ossl_dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret) 267 { 268 int ok = 0; 269 BIGNUM *two_powN = NULL, *upper; 270 271 *ret = 0; 272 two_powN = BN_new(); 273 if (two_powN == NULL) 274 return 0; 275 276 if (dh->params.q != NULL) { 277 upper = dh->params.q; 278 #ifndef FIPS_MODULE 279 } else if (dh->params.p != NULL) { 280 /* 281 * We do not have q so we just check the key is within some 282 * reasonable range, or the number of bits is equal to dh->length. 283 */ 284 int length = dh->length; 285 286 if (length == 0) { 287 length = BN_num_bits(dh->params.p) - 1; 288 if (BN_num_bits(priv_key) <= length 289 && BN_num_bits(priv_key) > 1) 290 ok = 1; 291 } else if (BN_num_bits(priv_key) == length) { 292 ok = 1; 293 } 294 goto end; 295 #endif 296 } else { 297 goto end; 298 } 299 300 /* Is it from an approved Safe prime group ?*/ 301 if (DH_get_nid((DH *)dh) != NID_undef && dh->length != 0) { 302 if (!BN_lshift(two_powN, BN_value_one(), dh->length)) 303 goto end; 304 if (BN_cmp(two_powN, dh->params.q) < 0) 305 upper = two_powN; 306 } 307 if (!ossl_ffc_validate_private_key(upper, priv_key, ret)) 308 goto end; 309 310 ok = 1; 311 end: 312 BN_free(two_powN); 313 return ok; 314 } 315 316 /* 317 * FFC pairwise check from SP800-56A R3. 318 * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency 319 */ 320 int ossl_dh_check_pairwise(const DH *dh) 321 { 322 int ret = 0; 323 BN_CTX *ctx = NULL; 324 BIGNUM *pub_key = NULL; 325 326 if (dh->params.p == NULL 327 || dh->params.g == NULL 328 || dh->priv_key == NULL 329 || dh->pub_key == NULL) 330 return 0; 331 332 ctx = BN_CTX_new_ex(dh->libctx); 333 if (ctx == NULL) 334 goto err; 335 pub_key = BN_new(); 336 if (pub_key == NULL) 337 goto err; 338 339 /* recalculate the public key = (g ^ priv) mod p */ 340 if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key)) 341 goto err; 342 /* check it matches the existing pubic_key */ 343 ret = BN_cmp(pub_key, dh->pub_key) == 0; 344 err: 345 BN_free(pub_key); 346 BN_CTX_free(ctx); 347 return ret; 348 } 349