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 /* Don't do any checks at all with an excessively large modulus */ 253 if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { 254 ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); 255 *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_PUBKEY_INVALID; 256 return 0; 257 } 258 259 if (dh->params.q != NULL && BN_ucmp(dh->params.p, dh->params.q) < 0) { 260 *ret |= DH_CHECK_INVALID_Q_VALUE | DH_CHECK_PUBKEY_INVALID; 261 return 1; 262 } 263 264 return ossl_ffc_validate_public_key(&dh->params, pub_key, ret); 265 } 266 267 /* 268 * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Partial public key validation. 269 * To only be used with ephemeral FFC public keys generated using the approved 270 * safe-prime groups. 271 */ 272 int ossl_dh_check_pub_key_partial(const DH *dh, const BIGNUM *pub_key, int *ret) 273 { 274 return ossl_ffc_validate_public_key_partial(&dh->params, pub_key, ret) 275 && *ret == 0; 276 } 277 278 int ossl_dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret) 279 { 280 int ok = 0; 281 BIGNUM *two_powN = NULL, *upper; 282 283 *ret = 0; 284 two_powN = BN_new(); 285 if (two_powN == NULL) 286 return 0; 287 288 if (dh->params.q != NULL) { 289 upper = dh->params.q; 290 #ifndef FIPS_MODULE 291 } else if (dh->params.p != NULL) { 292 /* 293 * We do not have q so we just check the key is within some 294 * reasonable range, or the number of bits is equal to dh->length. 295 */ 296 int length = dh->length; 297 298 if (length == 0) { 299 length = BN_num_bits(dh->params.p) - 1; 300 if (BN_num_bits(priv_key) <= length 301 && BN_num_bits(priv_key) > 1) 302 ok = 1; 303 } else if (BN_num_bits(priv_key) == length) { 304 ok = 1; 305 } 306 goto end; 307 #endif 308 } else { 309 goto end; 310 } 311 312 /* Is it from an approved Safe prime group ?*/ 313 if (DH_get_nid((DH *)dh) != NID_undef && dh->length != 0) { 314 if (!BN_lshift(two_powN, BN_value_one(), dh->length)) 315 goto end; 316 if (BN_cmp(two_powN, dh->params.q) < 0) 317 upper = two_powN; 318 } 319 if (!ossl_ffc_validate_private_key(upper, priv_key, ret)) 320 goto end; 321 322 ok = 1; 323 end: 324 BN_free(two_powN); 325 return ok; 326 } 327 328 /* 329 * FFC pairwise check from SP800-56A R3. 330 * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency 331 */ 332 int ossl_dh_check_pairwise(const DH *dh) 333 { 334 int ret = 0; 335 BN_CTX *ctx = NULL; 336 BIGNUM *pub_key = NULL; 337 338 if (dh->params.p == NULL 339 || dh->params.g == NULL 340 || dh->priv_key == NULL 341 || dh->pub_key == NULL) 342 return 0; 343 344 ctx = BN_CTX_new_ex(dh->libctx); 345 if (ctx == NULL) 346 goto err; 347 pub_key = BN_new(); 348 if (pub_key == NULL) 349 goto err; 350 351 /* recalculate the public key = (g ^ priv) mod p */ 352 if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key)) 353 goto err; 354 /* check it matches the existing pubic_key */ 355 ret = BN_cmp(pub_key, dh->pub_key) == 0; 356 err: 357 BN_free(pub_key); 358 BN_CTX_free(ctx); 359 return ret; 360 } 361