1 |
From 97ac06e5a8e3a8699279c06eeb64c8e958bad7bd Mon Sep 17 00:00:00 2001 |
2 |
From: Clemens Lang <cllang@redhat.com> |
3 |
Date: Fri, 15 Jul 2022 17:45:40 +0200 |
4 |
Subject: [PATCH] FIPS: Use digest_sign & digest_verify in self test |
5 |
|
6 |
In review for FIPS 140-3, the lack of a self-test for the digest_sign |
7 |
and digest_verify provider functions was highlighted as a problem. NIST |
8 |
no longer provides ACVP tests for the RSA SigVer primitive (see |
9 |
https://github.com/usnistgov/ACVP/issues/1347). Because FIPS 140-3 |
10 |
recommends the use of functions that compute the digest and signature |
11 |
within the module, we have been advised in our module review that the |
12 |
self tests should also use the combined digest and signature APIs, i.e. |
13 |
the digest_sign and digest_verify provider functions. |
14 |
|
15 |
Modify the signature self-test to use these instead by switching to |
16 |
EVP_DigestSign and EVP_DigestVerify. This requires adding more ifdefs to |
17 |
crypto/evp/m_sigver.c to make these functions usable in the FIPS module. |
18 |
|
19 |
Signed-off-by: Clemens Lang <cllang@redhat.com> |
20 |
--- |
21 |
crypto/evp/m_sigver.c | 43 +++++++++++++++++++++++++++------ |
22 |
providers/fips/self_test_kats.c | 37 +++++++++++++++------------- |
23 |
2 files changed, 56 insertions(+), 24 deletions(-) |
24 |
|
25 |
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c |
26 |
index db1a1d7bc3..c94c3c53bd 100644 |
27 |
--- a/crypto/evp/m_sigver.c |
28 |
+++ b/crypto/evp/m_sigver.c |
29 |
@@ -88,6 +88,7 @@ static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen) |
30 |
ERR_raise(ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED); |
31 |
return 0; |
32 |
} |
33 |
+#endif /* !defined(FIPS_MODULE) */ |
34 |
|
35 |
/* |
36 |
* If we get the "NULL" md then the name comes back as "UNDEF". We want to use |
37 |
@@ -130,8 +131,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
38 |
reinit = 0; |
39 |
if (e == NULL) |
40 |
ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props); |
41 |
+#ifndef FIPS_MODULE |
42 |
else |
43 |
ctx->pctx = EVP_PKEY_CTX_new(pkey, e); |
44 |
+#endif /* !defined(FIPS_MODULE) */ |
45 |
} |
46 |
if (ctx->pctx == NULL) |
47 |
return 0; |
48 |
@@ -139,8 +142,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
49 |
locpctx = ctx->pctx; |
50 |
ERR_set_mark(); |
51 |
|
52 |
+#ifndef FIPS_MODULE |
53 |
if (evp_pkey_ctx_is_legacy(locpctx)) |
54 |
goto legacy; |
55 |
+#endif /* !defined(FIPS_MODULE) */ |
56 |
|
57 |
/* do not reinitialize if pkey is set or operation is different */ |
58 |
if (reinit |
59 |
@@ -225,8 +230,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
60 |
signature = |
61 |
evp_signature_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, |
62 |
supported_sig, locpctx->propquery); |
63 |
+#ifndef FIPS_MODULE |
64 |
if (signature == NULL) |
65 |
goto legacy; |
66 |
+#endif /* !defined(FIPS_MODULE) */ |
67 |
break; |
68 |
} |
69 |
if (signature == NULL) |
70 |
@@ -310,6 +317,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
71 |
ctx->fetched_digest = EVP_MD_fetch(locpctx->libctx, mdname, props); |
72 |
if (ctx->fetched_digest != NULL) { |
73 |
ctx->digest = ctx->reqdigest = ctx->fetched_digest; |
74 |
+#ifndef FIPS_MODULE |
75 |
} else { |
76 |
/* legacy engine support : remove the mark when this is deleted */ |
77 |
ctx->reqdigest = ctx->digest = EVP_get_digestbyname(mdname); |
78 |
@@ -318,11 +326,13 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
79 |
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
80 |
goto err; |
81 |
} |
82 |
+#endif /* !defined(FIPS_MODULE) */ |
83 |
} |
84 |
(void)ERR_pop_to_mark(); |
85 |
} |
86 |
} |
87 |
|
88 |
+#ifndef FIPS_MODULE |
89 |
if (ctx->reqdigest != NULL |
90 |
&& !EVP_PKEY_is_a(locpctx->pkey, SN_hmac) |
91 |
&& !EVP_PKEY_is_a(locpctx->pkey, SN_tls1_prf) |
92 |
@@ -334,6 +344,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
93 |
goto err; |
94 |
} |
95 |
} |
96 |
+#endif /* !defined(FIPS_MODULE) */ |
97 |
|
98 |
if (ver) { |
99 |
if (signature->digest_verify_init == NULL) { |
100 |
@@ -366,6 +377,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
101 |
EVP_KEYMGMT_free(tmp_keymgmt); |
102 |
return 0; |
103 |
|
104 |
+#ifndef FIPS_MODULE |
105 |
legacy: |
106 |
/* |
107 |
* If we don't have the full support we need with provided methods, |
108 |
@@ -437,6 +449,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
109 |
ctx->pctx->flag_call_digest_custom = 1; |
110 |
|
111 |
ret = 1; |
112 |
+#endif /* !defined(FIPS_MODULE) */ |
113 |
|
114 |
end: |
115 |
#ifndef FIPS_MODULE |
116 |
@@ -479,7 +492,6 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
117 |
return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1, |
118 |
NULL); |
119 |
} |
120 |
-#endif /* FIPS_MDOE */ |
121 |
|
122 |
int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) |
123 |
{ |
124 |
@@ -541,23 +553,29 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) |
125 |
return EVP_DigestUpdate(ctx, data, dsize); |
126 |
} |
127 |
|
128 |
-#ifndef FIPS_MODULE |
129 |
int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, |
130 |
size_t *siglen) |
131 |
{ |
132 |
- int sctx = 0, r = 0; |
133 |
- EVP_PKEY_CTX *dctx, *pctx = ctx->pctx; |
134 |
+ int r = 0; |
135 |
+#ifndef FIPS_MODULE |
136 |
+ int sctx = 0; |
137 |
+ EVP_PKEY_CTX *dctx; |
138 |
+#endif /* !defined(FIPS_MODULE) */ |
139 |
+ EVP_PKEY_CTX *pctx = ctx->pctx; |
140 |
|
141 |
+#ifndef FIPS_MODULE |
142 |
if (pctx == NULL |
143 |
|| pctx->operation != EVP_PKEY_OP_SIGNCTX |
144 |
|| pctx->op.sig.algctx == NULL |
145 |
|| pctx->op.sig.signature == NULL) |
146 |
goto legacy; |
147 |
+#endif /* !defined(FIPS_MODULE) */ |
148 |
|
149 |
if (sigret == NULL || (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) |
150 |
return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx, |
151 |
sigret, siglen, |
152 |
sigret == NULL ? 0 : *siglen); |
153 |
+#ifndef FIPS_MODULE |
154 |
dctx = EVP_PKEY_CTX_dup(pctx); |
155 |
if (dctx == NULL) |
156 |
return 0; |
157 |
@@ -566,8 +584,10 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, |
158 |
sigret, siglen, |
159 |
*siglen); |
160 |
EVP_PKEY_CTX_free(dctx); |
161 |
+#endif /* defined(FIPS_MODULE) */ |
162 |
return r; |
163 |
|
164 |
+#ifndef FIPS_MODULE |
165 |
legacy: |
166 |
if (pctx == NULL || pctx->pmeth == NULL) { |
167 |
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
168 |
@@ -639,6 +659,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, |
169 |
} |
170 |
} |
171 |
return 1; |
172 |
+#endif /* !defined(FIPS_MODULE) */ |
173 |
} |
174 |
|
175 |
int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, |
176 |
@@ -669,21 +690,27 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, |
177 |
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, |
178 |
size_t siglen) |
179 |
{ |
180 |
- unsigned char md[EVP_MAX_MD_SIZE]; |
181 |
int r = 0; |
182 |
+#ifndef FIPS_MODULE |
183 |
+ unsigned char md[EVP_MAX_MD_SIZE]; |
184 |
unsigned int mdlen = 0; |
185 |
int vctx = 0; |
186 |
- EVP_PKEY_CTX *dctx, *pctx = ctx->pctx; |
187 |
+ EVP_PKEY_CTX *dctx; |
188 |
+#endif /* !defined(FIPS_MODULE) */ |
189 |
+ EVP_PKEY_CTX *pctx = ctx->pctx; |
190 |
|
191 |
+#ifndef FIPS_MODULE |
192 |
if (pctx == NULL |
193 |
|| pctx->operation != EVP_PKEY_OP_VERIFYCTX |
194 |
|| pctx->op.sig.algctx == NULL |
195 |
|| pctx->op.sig.signature == NULL) |
196 |
goto legacy; |
197 |
+#endif /* !defined(FIPS_MODULE) */ |
198 |
|
199 |
if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) |
200 |
return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx, |
201 |
sig, siglen); |
202 |
+#ifndef FIPS_MODULE |
203 |
dctx = EVP_PKEY_CTX_dup(pctx); |
204 |
if (dctx == NULL) |
205 |
return 0; |
206 |
@@ -691,8 +718,10 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, |
207 |
r = dctx->op.sig.signature->digest_verify_final(dctx->op.sig.algctx, |
208 |
sig, siglen); |
209 |
EVP_PKEY_CTX_free(dctx); |
210 |
+#endif /* !defined(FIPS_MODULE) */ |
211 |
return r; |
212 |
|
213 |
+#ifndef FIPS_MODULE |
214 |
legacy: |
215 |
if (pctx == NULL || pctx->pmeth == NULL) { |
216 |
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
217 |
@@ -732,6 +761,7 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, |
218 |
if (vctx || !r) |
219 |
return r; |
220 |
return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen); |
221 |
+#endif /* !defined(FIPS_MODULE) */ |
222 |
} |
223 |
|
224 |
int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, |
225 |
@@ -757,4 +787,3 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, |
226 |
return -1; |
227 |
return EVP_DigestVerifyFinal(ctx, sigret, siglen); |
228 |
} |
229 |
-#endif /* FIPS_MODULE */ |
230 |
diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c |
231 |
index b6d5e8e134..77eec075e6 100644 |
232 |
--- a/providers/fips/self_test_kats.c |
233 |
+++ b/providers/fips/self_test_kats.c |
234 |
@@ -444,11 +444,14 @@ static int self_test_sign(const ST_KAT_SIGN *t, |
235 |
int ret = 0; |
236 |
OSSL_PARAM *params = NULL, *params_sig = NULL; |
237 |
OSSL_PARAM_BLD *bld = NULL; |
238 |
+ EVP_MD *md = NULL; |
239 |
+ EVP_MD_CTX *ctx = NULL; |
240 |
EVP_PKEY_CTX *sctx = NULL, *kctx = NULL; |
241 |
EVP_PKEY *pkey = NULL; |
242 |
- unsigned char sig[256]; |
243 |
BN_CTX *bnctx = NULL; |
244 |
BIGNUM *K = NULL; |
245 |
+ const char *msg = "Hello World!"; |
246 |
+ unsigned char sig[256]; |
247 |
size_t siglen = sizeof(sig); |
248 |
static const unsigned char dgst[] = { |
249 |
0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, |
250 |
@@ -488,23 +491,26 @@ static int self_test_sign(const ST_KAT_SIGN *t, |
251 |
|| EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) |
252 |
goto err; |
253 |
|
254 |
- /* Create a EVP_PKEY_CTX to use for the signing operation */ |
255 |
- sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL); |
256 |
- if (sctx == NULL |
257 |
- || EVP_PKEY_sign_init(sctx) <= 0) |
258 |
- goto err; |
259 |
- |
260 |
- /* set signature parameters */ |
261 |
- if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_SIGNATURE_PARAM_DIGEST, |
262 |
- t->mdalgorithm, |
263 |
- strlen(t->mdalgorithm) + 1)) |
264 |
- goto err; |
265 |
+ /* Create a EVP_MD_CTX to use for the signature operation, assign signature |
266 |
+ * parameters and sign */ |
267 |
params_sig = OSSL_PARAM_BLD_to_param(bld); |
268 |
- if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) |
269 |
+ md = EVP_MD_fetch(libctx, "SHA256", NULL); |
270 |
+ ctx = EVP_MD_CTX_new(); |
271 |
+ if (md == NULL || ctx == NULL) |
272 |
+ goto err; |
273 |
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE | EVP_MD_CTX_FLAG_ONESHOT); |
274 |
+ if (EVP_DigestSignInit(ctx, &sctx, md, NULL, pkey) <= 0 |
275 |
+ || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0 |
276 |
+ || EVP_DigestSign(ctx, sig, &siglen, (const unsigned char *)msg, strlen(msg)) <= 0 |
277 |
+ || EVP_MD_CTX_reset(ctx) <= 0) |
278 |
goto err; |
279 |
|
280 |
- if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0 |
281 |
- || EVP_PKEY_verify_init(sctx) <= 0 |
282 |
+ /* sctx is not freed automatically inside the FIPS module */ |
283 |
+ EVP_PKEY_CTX_free(sctx); |
284 |
+ sctx = NULL; |
285 |
+ |
286 |
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE | EVP_MD_CTX_FLAG_ONESHOT); |
287 |
+ if (EVP_DigestVerifyInit(ctx, &sctx, md, NULL, pkey) <= 0 |
288 |
|| EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) |
289 |
goto err; |
290 |
|
291 |
@@ -509,14 +510,17 @@ static int self_test_sign(const ST_KAT_SIGN *t, |
292 |
goto err; |
293 |
|
294 |
OSSL_SELF_TEST_oncorrupt_byte(st, sig); |
295 |
- if (EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0) |
296 |
+ if (EVP_DigestVerify(ctx, sig, siglen, (const unsigned char *)msg, strlen(msg)) <= 0) |
297 |
goto err; |
298 |
ret = 1; |
299 |
err: |
300 |
BN_CTX_free(bnctx); |
301 |
EVP_PKEY_free(pkey); |
302 |
- EVP_PKEY_CTX_free(kctx); |
303 |
+ EVP_MD_free(md); |
304 |
+ EVP_MD_CTX_free(ctx); |
305 |
+ /* sctx is not freed automatically inside the FIPS module */ |
306 |
EVP_PKEY_CTX_free(sctx); |
307 |
+ EVP_PKEY_CTX_free(kctx); |
308 |
OSSL_PARAM_free(params); |
309 |
OSSL_PARAM_free(params_sig); |
310 |
OSSL_PARAM_BLD_free(bld); |
311 |
-- |
312 |
2.37.1 |
313 |
|