2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
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
11 * Finite Field cryptography (FFC) is used for DSA and DH.
12 * This file contains methods for validation of FFC parameters.
13 * It calls the same functions as the generation as the code is very similar.
16 #include <openssl/err.h>
17 #include <openssl/bn.h>
18 #include <openssl/dsaerr.h>
19 #include <openssl/dherr.h>
20 #include "internal/ffc.h"
22 /* FIPS186-4 A.2.2 Unverifiable partial validation of Generator g */
23 int ossl_ffc_params_validate_unverifiable_g(BN_CTX
*ctx
, BN_MONT_CTX
*mont
,
24 const BIGNUM
*p
, const BIGNUM
*q
,
25 const BIGNUM
*g
, BIGNUM
*tmp
,
31 * Verify that 2 <= g <= (p - 1)
33 if (BN_cmp(g
, BN_value_one()) <= 0 || BN_cmp(g
, p
) >= 0) {
34 *ret
|= FFC_ERROR_NOT_SUITABLE_GENERATOR
;
43 if (!BN_mod_exp_mont(tmp
, g
, q
, p
, ctx
, mont
))
45 if (BN_cmp(tmp
, BN_value_one()) != 0) {
46 *ret
|= FFC_ERROR_NOT_SUITABLE_GENERATOR
;
52 int ossl_ffc_params_FIPS186_4_validate(OSSL_LIB_CTX
*libctx
,
53 const FFC_PARAMS
*params
, int type
,
54 int *res
, BN_GENCB
*cb
)
58 if (params
== NULL
|| params
->p
== NULL
|| params
->q
== NULL
)
59 return FFC_PARAM_RET_STATUS_FAILED
;
61 /* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */
62 L
= BN_num_bits(params
->p
);
63 N
= BN_num_bits(params
->q
);
64 return ossl_ffc_params_FIPS186_4_gen_verify(libctx
, (FFC_PARAMS
*)params
,
65 FFC_PARAM_MODE_VERIFY
, type
,
69 /* This may be used in FIPS mode to validate deprecated FIPS-186-2 Params */
70 int ossl_ffc_params_FIPS186_2_validate(OSSL_LIB_CTX
*libctx
,
71 const FFC_PARAMS
*params
, int type
,
72 int *res
, BN_GENCB
*cb
)
76 if (params
== NULL
|| params
->p
== NULL
|| params
->q
== NULL
) {
77 *res
= FFC_CHECK_INVALID_PQ
;
78 return FFC_PARAM_RET_STATUS_FAILED
;
81 /* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */
82 L
= BN_num_bits(params
->p
);
83 N
= BN_num_bits(params
->q
);
84 return ossl_ffc_params_FIPS186_2_gen_verify(libctx
, (FFC_PARAMS
*)params
,
85 FFC_PARAM_MODE_VERIFY
, type
,
90 * This does a simple check of L and N and partial g.
91 * It makes no attempt to do a full validation of p, q or g since these require
92 * extra parameters such as the digest and seed, which may not be available for
95 int ossl_ffc_params_simple_validate(OSSL_LIB_CTX
*libctx
, const FFC_PARAMS
*params
,
96 int paramstype
, int *res
)
100 FFC_PARAMS tmpparams
= {0};
108 if (!ossl_ffc_params_copy(&tmpparams
, params
))
111 tmpparams
.flags
= FFC_PARAM_FLAG_VALIDATE_G
;
112 tmpparams
.gindex
= FFC_UNVERIFIABLE_GINDEX
;
115 if (params
->flags
& FFC_PARAM_FLAG_VALIDATE_LEGACY
)
116 ret
= ossl_ffc_params_FIPS186_2_validate(libctx
, &tmpparams
, paramstype
,
120 ret
= ossl_ffc_params_FIPS186_4_validate(libctx
, &tmpparams
, paramstype
,
122 #ifndef OPENSSL_NO_DH
123 if (ret
== FFC_PARAM_RET_STATUS_FAILED
124 && (*res
& FFC_ERROR_NOT_SUITABLE_GENERATOR
) != 0) {
125 ERR_raise(ERR_LIB_DH
, DH_R_NOT_SUITABLE_GENERATOR
);
129 ossl_ffc_params_cleanup(&tmpparams
);
131 return ret
!= FFC_PARAM_RET_STATUS_FAILED
;
135 * If possible (or always in FIPS_MODULE) do full FIPS 186-4 validation.
136 * Otherwise do simple check but in addition also check the primality of the
139 int ossl_ffc_params_full_validate(OSSL_LIB_CTX
*libctx
, const FFC_PARAMS
*params
,
140 int paramstype
, int *res
)
151 return ossl_ffc_params_FIPS186_4_validate(libctx
, params
, paramstype
,
154 if (params
->seed
!= NULL
) {
155 return ossl_ffc_params_FIPS186_4_validate(libctx
, params
, paramstype
,
160 ret
= ossl_ffc_params_simple_validate(libctx
, params
, paramstype
, res
);
164 if ((ctx
= BN_CTX_new_ex(libctx
)) == NULL
)
166 if (BN_check_prime(params
->q
, ctx
, NULL
) != 1) {
167 # ifndef OPENSSL_NO_DSA
168 ERR_raise(ERR_LIB_DSA
, DSA_R_Q_NOT_PRIME
);
172 if (ret
&& BN_check_prime(params
->p
, ctx
, NULL
) != 1) {
173 # ifndef OPENSSL_NO_DSA
174 ERR_raise(ERR_LIB_DSA
, DSA_R_P_NOT_PRIME
);