VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/crypto/digest-builtin.cpp

Last change on this file was 100442, checked in by vboxsync, 11 months ago

IPRT,OpenSSL: Support ECDSA for verficiation purposes when IPRT links with OpenSSL. This required quite a bit of cleanups, so not entirely no-risk. bugref:10479 ticketref:21621

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.2 KB
Line 
1/* $Id: digest-builtin.cpp 100442 2023-07-08 11:10:51Z vboxsync $ */
2/** @file
3 * IPRT - Crypto - Cryptographic Hash / Message Digest API, Built-in providers.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include "internal/iprt.h"
42#include <iprt/crypto/digest.h>
43
44#include <iprt/err.h>
45#include <iprt/mem.h>
46#include <iprt/string.h>
47#include <iprt/md2.h>
48#include <iprt/md4.h>
49#include <iprt/md5.h>
50#include <iprt/sha.h>
51#include <iprt/crypto/pkix.h>
52
53#ifdef IPRT_WITH_OPENSSL
54# include "internal/iprt-openssl.h"
55# include "internal/openssl-pre.h"
56# include <openssl/evp.h>
57# include "internal/openssl-post.h"
58#endif
59
60
61
62/*
63 * MD2
64 */
65#ifndef IPRT_WITHOUT_DIGEST_MD2
66
67/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
68static DECLCALLBACK(void) rtCrDigestMd2_Update(void *pvState, const void *pvData, size_t cbData)
69{
70 RTMd2Update((PRTMD2CONTEXT)pvState, pvData, cbData);
71}
72
73/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
74static DECLCALLBACK(void) rtCrDigestMd2_Final(void *pvState, uint8_t *pbHash)
75{
76 RTMd2Final((PRTMD2CONTEXT)pvState, pbHash);
77}
78
79/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
80static DECLCALLBACK(int) rtCrDigestMd2_Init(void *pvState, void *pvOpaque, bool fReInit)
81{
82 RT_NOREF_PV(fReInit); RT_NOREF_PV(pvOpaque);
83 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
84 RTMd2Init((PRTMD2CONTEXT)pvState);
85 return VINF_SUCCESS;
86}
87
88/** MD2 alias ODIs. */
89static const char * const g_apszMd2Aliases[] =
90{
91 RTCR_PKCS1_MD2_WITH_RSA_OID,
92 "1.3.14.3.2.24" /* OIW md2WithRSASignature */,
93 NULL
94};
95
96/** MD2 descriptor. */
97static RTCRDIGESTDESC const g_rtCrDigestMd2Desc =
98{
99 "md2",
100 "1.2.840.113549.2.2",
101 g_apszMd2Aliases,
102 RTDIGESTTYPE_MD2,
103 RTMD2_HASH_SIZE,
104 sizeof(RTMD2CONTEXT),
105 RTCRDIGESTDESC_F_DEPRECATED,
106 NULL,
107 NULL,
108 rtCrDigestMd2_Update,
109 rtCrDigestMd2_Final,
110 rtCrDigestMd2_Init,
111 NULL,
112 NULL,
113 NULL,
114 NULL,
115};
116#endif /* !IPRT_WITHOUT_DIGEST_MD2 */
117
118
119/*
120 * MD4
121 */
122#ifndef IPRT_WITHOUT_DIGEST_MD4
123
124/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
125static DECLCALLBACK(void) rtCrDigestMd4_Update(void *pvState, const void *pvData, size_t cbData)
126{
127 RTMd4Update((PRTMD4CONTEXT)pvState, pvData, cbData);
128}
129
130/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
131static DECLCALLBACK(void) rtCrDigestMd4_Final(void *pvState, uint8_t *pbHash)
132{
133 RTMd4Final((PRTMD4CONTEXT)pvState, pbHash);
134}
135
136/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
137static DECLCALLBACK(int) rtCrDigestMd4_Init(void *pvState, void *pvOpaque, bool fReInit)
138{
139 RT_NOREF_PV(fReInit); RT_NOREF_PV(pvOpaque);
140 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
141 RTMd4Init((PRTMD4CONTEXT)pvState);
142 return VINF_SUCCESS;
143}
144
145/** MD4 alias ODIs. */
146static const char * const g_apszMd4Aliases[] =
147{
148 RTCR_PKCS1_MD4_WITH_RSA_OID,
149 NULL
150};
151
152/** MD4 descriptor. */
153static RTCRDIGESTDESC const g_rtCrDigestMd4Desc =
154{
155 "md4",
156 "1.2.840.113549.2.4",
157 g_apszMd4Aliases,
158 RTDIGESTTYPE_MD4,
159 RTMD4_HASH_SIZE,
160 sizeof(RTMD4CONTEXT),
161 RTCRDIGESTDESC_F_DEPRECATED | RTCRDIGESTDESC_F_COMPROMISED | RTCRDIGESTDESC_F_SERVERELY_COMPROMISED,
162 NULL,
163 NULL,
164 rtCrDigestMd4_Update,
165 rtCrDigestMd4_Final,
166 rtCrDigestMd4_Init,
167 NULL,
168 NULL,
169 NULL,
170 NULL,
171};
172
173#endif /* !IPRT_WITHOUT_DIGEST_MD4 */
174
175
176/*
177 * MD5
178 */
179#ifndef IPRT_WITHOUT_DIGEST_MD5
180
181/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
182static DECLCALLBACK(void) rtCrDigestMd5_Update(void *pvState, const void *pvData, size_t cbData)
183{
184 RTMd5Update((PRTMD5CONTEXT)pvState, pvData, cbData);
185}
186
187/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
188static DECLCALLBACK(void) rtCrDigestMd5_Final(void *pvState, uint8_t *pbHash)
189{
190 RTMd5Final(pbHash, (PRTMD5CONTEXT)pvState);
191}
192
193/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
194static DECLCALLBACK(int) rtCrDigestMd5_Init(void *pvState, void *pvOpaque, bool fReInit)
195{
196 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
197 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
198 RTMd5Init((PRTMD5CONTEXT)pvState);
199 return VINF_SUCCESS;
200}
201
202/** MD5 alias ODIs. */
203static const char * const g_apszMd5Aliases[] =
204{
205 RTCR_PKCS1_MD5_WITH_RSA_OID,
206 "1.3.14.3.2.25" /* OIW md5WithRSASignature */,
207 NULL
208};
209
210/** MD5 descriptor. */
211static RTCRDIGESTDESC const g_rtCrDigestMd5Desc =
212{
213 "md5",
214 "1.2.840.113549.2.5",
215 g_apszMd5Aliases,
216 RTDIGESTTYPE_MD5,
217 RTMD5_HASH_SIZE,
218 sizeof(RTMD5CONTEXT),
219 RTCRDIGESTDESC_F_COMPROMISED,
220 NULL,
221 NULL,
222 rtCrDigestMd5_Update,
223 rtCrDigestMd5_Final,
224 rtCrDigestMd5_Init,
225 NULL,
226 NULL,
227 NULL,
228 NULL,
229};
230#endif /* !IPRT_WITHOUT_DIGEST_MD5 */
231
232
233/*
234 * SHA-1
235 */
236
237/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
238static DECLCALLBACK(void) rtCrDigestSha1_Update(void *pvState, const void *pvData, size_t cbData)
239{
240 RTSha1Update((PRTSHA1CONTEXT)pvState, pvData, cbData);
241}
242
243/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
244static DECLCALLBACK(void) rtCrDigestSha1_Final(void *pvState, uint8_t *pbHash)
245{
246 RTSha1Final((PRTSHA1CONTEXT)pvState, pbHash);
247}
248
249/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
250static DECLCALLBACK(int) rtCrDigestSha1_Init(void *pvState, void *pvOpaque, bool fReInit)
251{
252 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
253 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
254 RTSha1Init((PRTSHA1CONTEXT)pvState);
255 return VINF_SUCCESS;
256}
257
258/** SHA-1 alias ODIs. */
259static const char * const g_apszSha1Aliases[] =
260{
261 RTCR_PKCS1_SHA1_WITH_RSA_OID,
262 "1.3.14.3.2.29" /* OIW sha1WithRSASignature */,
263 RTCR_X962_ECDSA_WITH_SHA1_OID,
264 NULL
265};
266
267/** SHA-1 descriptor. */
268static RTCRDIGESTDESC const g_rtCrDigestSha1Desc =
269{
270 "sha-1",
271 "1.3.14.3.2.26",
272 g_apszSha1Aliases,
273 RTDIGESTTYPE_SHA1,
274 RTSHA1_HASH_SIZE,
275 sizeof(RTSHA1CONTEXT),
276 RTCRDIGESTDESC_F_DEPRECATED,
277 NULL,
278 NULL,
279 rtCrDigestSha1_Update,
280 rtCrDigestSha1_Final,
281 rtCrDigestSha1_Init,
282 NULL,
283 NULL,
284 NULL,
285 NULL,
286};
287
288
289/*
290 * SHA-256
291 */
292
293/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
294static DECLCALLBACK(void) rtCrDigestSha256_Update(void *pvState, const void *pvData, size_t cbData)
295{
296 RTSha256Update((PRTSHA256CONTEXT)pvState, pvData, cbData);
297}
298
299/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
300static DECLCALLBACK(void) rtCrDigestSha256_Final(void *pvState, uint8_t *pbHash)
301{
302 RTSha256Final((PRTSHA256CONTEXT)pvState, pbHash);
303}
304
305/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
306static DECLCALLBACK(int) rtCrDigestSha256_Init(void *pvState, void *pvOpaque, bool fReInit)
307{
308 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
309 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
310 RTSha256Init((PRTSHA256CONTEXT)pvState);
311 return VINF_SUCCESS;
312}
313
314/** SHA-256 alias ODIs. */
315static const char * const g_apszSha256Aliases[] =
316{
317 RTCR_PKCS1_SHA256_WITH_RSA_OID,
318 RTCR_X962_ECDSA_WITH_SHA256_OID,
319 NULL
320};
321
322/** SHA-256 descriptor. */
323static RTCRDIGESTDESC const g_rtCrDigestSha256Desc =
324{
325 "sha-256",
326 "2.16.840.1.101.3.4.2.1",
327 g_apszSha256Aliases,
328 RTDIGESTTYPE_SHA256,
329 RTSHA256_HASH_SIZE,
330 sizeof(RTSHA256CONTEXT),
331 0,
332 NULL,
333 NULL,
334 rtCrDigestSha256_Update,
335 rtCrDigestSha256_Final,
336 rtCrDigestSha256_Init,
337 NULL,
338 NULL,
339 NULL,
340 NULL,
341};
342
343
344/*
345 * SHA-512
346 */
347
348/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
349static DECLCALLBACK(void) rtCrDigestSha512_Update(void *pvState, const void *pvData, size_t cbData)
350{
351 RTSha512Update((PRTSHA512CONTEXT)pvState, pvData, cbData);
352}
353
354/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
355static DECLCALLBACK(void) rtCrDigestSha512_Final(void *pvState, uint8_t *pbHash)
356{
357 RTSha512Final((PRTSHA512CONTEXT)pvState, pbHash);
358}
359
360/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
361static DECLCALLBACK(int) rtCrDigestSha512_Init(void *pvState, void *pvOpaque, bool fReInit)
362{
363 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
364 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
365 RTSha512Init((PRTSHA512CONTEXT)pvState);
366 return VINF_SUCCESS;
367}
368
369/** SHA-512 alias ODIs. */
370static const char * const g_apszSha512Aliases[] =
371{
372 RTCR_PKCS1_SHA512_WITH_RSA_OID,
373 RTCR_X962_ECDSA_WITH_SHA512_OID,
374 NULL
375};
376
377/** SHA-512 descriptor. */
378static RTCRDIGESTDESC const g_rtCrDigestSha512Desc =
379{
380 "sha-512",
381 "2.16.840.1.101.3.4.2.3",
382 g_apszSha512Aliases,
383 RTDIGESTTYPE_SHA512,
384 RTSHA512_HASH_SIZE,
385 sizeof(RTSHA512CONTEXT),
386 0,
387 NULL,
388 NULL,
389 rtCrDigestSha512_Update,
390 rtCrDigestSha512_Final,
391 rtCrDigestSha512_Init,
392 NULL,
393 NULL,
394 NULL,
395 NULL,
396};
397
398
399/*
400 * SHA-224
401 */
402
403/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
404static DECLCALLBACK(void) rtCrDigestSha224_Update(void *pvState, const void *pvData, size_t cbData)
405{
406 RTSha224Update((PRTSHA224CONTEXT)pvState, pvData, cbData);
407}
408
409/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
410static DECLCALLBACK(void) rtCrDigestSha224_Final(void *pvState, uint8_t *pbHash)
411{
412 RTSha224Final((PRTSHA224CONTEXT)pvState, pbHash);
413}
414
415/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
416static DECLCALLBACK(int) rtCrDigestSha224_Init(void *pvState, void *pvOpaque, bool fReInit)
417{
418 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
419 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
420 RTSha224Init((PRTSHA224CONTEXT)pvState);
421 return VINF_SUCCESS;
422}
423
424/** SHA-224 alias ODIs. */
425static const char * const g_apszSha224Aliases[] =
426{
427 RTCR_PKCS1_SHA224_WITH_RSA_OID,
428 RTCR_X962_ECDSA_WITH_SHA224_OID,
429 NULL
430};
431
432/** SHA-224 descriptor. */
433static RTCRDIGESTDESC const g_rtCrDigestSha224Desc =
434{
435 "sha-224",
436 "2.16.840.1.101.3.4.2.4",
437 g_apszSha224Aliases,
438 RTDIGESTTYPE_SHA224,
439 RTSHA224_HASH_SIZE,
440 sizeof(RTSHA224CONTEXT),
441 0,
442 NULL,
443 NULL,
444 rtCrDigestSha224_Update,
445 rtCrDigestSha224_Final,
446 rtCrDigestSha224_Init,
447 NULL,
448 NULL,
449 NULL,
450 NULL,
451};
452
453
454/*
455 * SHA-384
456 */
457
458/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
459static DECLCALLBACK(void) rtCrDigestSha384_Update(void *pvState, const void *pvData, size_t cbData)
460{
461 RTSha384Update((PRTSHA384CONTEXT)pvState, pvData, cbData);
462}
463
464/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
465static DECLCALLBACK(void) rtCrDigestSha384_Final(void *pvState, uint8_t *pbHash)
466{
467 RTSha384Final((PRTSHA384CONTEXT)pvState, pbHash);
468}
469
470/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
471static DECLCALLBACK(int) rtCrDigestSha384_Init(void *pvState, void *pvOpaque, bool fReInit)
472{
473 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
474 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
475 RTSha384Init((PRTSHA384CONTEXT)pvState);
476 return VINF_SUCCESS;
477}
478
479/** SHA-384 alias ODIs. */
480static const char * const g_apszSha384Aliases[] =
481{
482 RTCR_PKCS1_SHA384_WITH_RSA_OID,
483 RTCR_X962_ECDSA_WITH_SHA384_OID,
484 NULL
485};
486
487/** SHA-384 descriptor. */
488static RTCRDIGESTDESC const g_rtCrDigestSha384Desc =
489{
490 "sha-384",
491 "2.16.840.1.101.3.4.2.2",
492 g_apszSha384Aliases,
493 RTDIGESTTYPE_SHA384,
494 RTSHA384_HASH_SIZE,
495 sizeof(RTSHA384CONTEXT),
496 0,
497 NULL,
498 NULL,
499 rtCrDigestSha384_Update,
500 rtCrDigestSha384_Final,
501 rtCrDigestSha384_Init,
502 NULL,
503 NULL,
504 NULL,
505 NULL,
506};
507
508
509#ifndef IPRT_WITHOUT_SHA512T224
510/*
511 * SHA-512/224
512 */
513
514/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
515static DECLCALLBACK(void) rtCrDigestSha512t224_Update(void *pvState, const void *pvData, size_t cbData)
516{
517 RTSha512t224Update((PRTSHA512T224CONTEXT)pvState, pvData, cbData);
518}
519
520/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
521static DECLCALLBACK(void) rtCrDigestSha512t224_Final(void *pvState, uint8_t *pbHash)
522{
523 RTSha512t224Final((PRTSHA512T224CONTEXT)pvState, pbHash);
524}
525
526/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
527static DECLCALLBACK(int) rtCrDigestSha512t224_Init(void *pvState, void *pvOpaque, bool fReInit)
528{
529 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
530 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
531 RTSha512t224Init((PRTSHA512T224CONTEXT)pvState);
532 return VINF_SUCCESS;
533}
534
535/** SHA-512/224 alias ODIs. */
536static const char * const g_apszSha512t224Aliases[] =
537{
538 RTCR_PKCS1_SHA512T224_WITH_RSA_OID,
539 NULL
540};
541
542/** SHA-512/224 descriptor. */
543static RTCRDIGESTDESC const g_rtCrDigestSha512t224Desc =
544{
545 "sha-512/224",
546 "2.16.840.1.101.3.4.2.5",
547 g_apszSha512t224Aliases,
548 RTDIGESTTYPE_SHA512T224,
549 RTSHA512T224_HASH_SIZE,
550 sizeof(RTSHA512T224CONTEXT),
551 0,
552 NULL,
553 NULL,
554 rtCrDigestSha512t224_Update,
555 rtCrDigestSha512t224_Final,
556 rtCrDigestSha512t224_Init,
557 NULL,
558 NULL,
559 NULL,
560 NULL,
561};
562#endif /* !IPRT_WITHOUT_SHA512T224 */
563
564
565#ifndef IPRT_WITHOUT_SHA512T256
566/*
567 * SHA-512/256
568 */
569
570/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
571static DECLCALLBACK(void) rtCrDigestSha512t256_Update(void *pvState, const void *pvData, size_t cbData)
572{
573 RTSha512t256Update((PRTSHA512T256CONTEXT)pvState, pvData, cbData);
574}
575
576/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
577static DECLCALLBACK(void) rtCrDigestSha512t256_Final(void *pvState, uint8_t *pbHash)
578{
579 RTSha512t256Final((PRTSHA512T256CONTEXT)pvState, pbHash);
580}
581
582/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
583static DECLCALLBACK(int) rtCrDigestSha512t256_Init(void *pvState, void *pvOpaque, bool fReInit)
584{
585 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
586 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
587 RTSha512t256Init((PRTSHA512T256CONTEXT)pvState);
588 return VINF_SUCCESS;
589}
590
591/** SHA-512/256 alias ODIs. */
592static const char * const g_apszSha512t256Aliases[] =
593{
594 RTCR_PKCS1_SHA512T256_WITH_RSA_OID,
595 NULL
596};
597
598/** SHA-512/256 descriptor. */
599static RTCRDIGESTDESC const g_rtCrDigestSha512t256Desc =
600{
601 "sha-512/256",
602 "2.16.840.1.101.3.4.2.6",
603 g_apszSha512t256Aliases,
604 RTDIGESTTYPE_SHA512T256,
605 RTSHA512T256_HASH_SIZE,
606 sizeof(RTSHA512T256CONTEXT),
607 0,
608 NULL,
609 NULL,
610 rtCrDigestSha512t256_Update,
611 rtCrDigestSha512t256_Final,
612 rtCrDigestSha512t256_Init,
613 NULL,
614 NULL,
615 NULL,
616 NULL,
617};
618#endif /* !IPRT_WITHOUT_SHA512T256 */
619
620#ifndef IPRT_WITHOUT_SHA3
621
622/*
623 * SHA3-224
624 */
625
626/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
627static DECLCALLBACK(void) rtCrDigestSha3t224_Update(void *pvState, const void *pvData, size_t cbData)
628{
629 int rc = RTSha3t224Update((PRTSHA3T224CONTEXT)pvState, pvData, cbData);
630 AssertRC(rc);
631}
632
633/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
634static DECLCALLBACK(void) rtCrDigestSha3t224_Final(void *pvState, uint8_t *pbHash)
635{
636 int rc = RTSha3t224Final((PRTSHA3T224CONTEXT)pvState, pbHash);
637 AssertRC(rc);
638}
639
640/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
641static DECLCALLBACK(int) rtCrDigestSha3t224_Init(void *pvState, void *pvOpaque, bool fReInit)
642{
643 RT_NOREF_PV(pvOpaque);
644 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
645 if (fReInit)
646 RTSha3t224Cleanup((PRTSHA3T224CONTEXT)pvState);
647 return RTSha3t224Init((PRTSHA3T224CONTEXT)pvState);
648}
649
650/** @impl_interface_method{RTCRDIGESTDESC::pfnDelete} */
651static DECLCALLBACK(void) rtCrDigestSha3t224_Delete(void *pvState)
652{
653 RTSha3t224Cleanup((PRTSHA3T224CONTEXT)pvState);
654}
655
656/** @impl_interface_method{RTCRDIGESTDESC::pfnDelete} */
657static DECLCALLBACK(int) rtCrDigestSha3t224_Clone(void *pvState, void const *pvSrcState)
658{
659 return RTSha3t224Clone((PRTSHA3T224CONTEXT)pvState, (PRTSHA3T224CONTEXT)pvSrcState);
660}
661
662/** SHA3-224 alias ODIs. */
663static const char * const g_apszSha3t224Aliases[] =
664{
665 "2.16.840.1.101.3.4.3.13",
666 RTCR_NIST_SHA3_224_WITH_ECDSA_OID,
667 NULL
668};
669
670/** SHA3-224 descriptor. */
671static RTCRDIGESTDESC const g_rtCrDigestSha3t224Desc =
672{
673 "sha3-224",
674 "2.16.840.1.101.3.4.2.7",
675 g_apszSha3t224Aliases,
676 RTDIGESTTYPE_SHA3_224,
677 RTSHA3_224_HASH_SIZE,
678 sizeof(RTSHA3T224CONTEXT),
679 0,
680 NULL,
681 NULL,
682 rtCrDigestSha3t224_Update,
683 rtCrDigestSha3t224_Final,
684 rtCrDigestSha3t224_Init,
685 rtCrDigestSha3t224_Delete,
686 rtCrDigestSha3t224_Clone,
687 NULL,
688 NULL,
689};
690
691
692/*
693 * SHA3-256
694 */
695
696/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
697static DECLCALLBACK(void) rtCrDigestSha3t256_Update(void *pvState, const void *pvData, size_t cbData)
698{
699 int rc = RTSha3t256Update((PRTSHA3T256CONTEXT)pvState, pvData, cbData);
700 AssertRC(rc);
701}
702
703/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
704static DECLCALLBACK(void) rtCrDigestSha3t256_Final(void *pvState, uint8_t *pbHash)
705{
706 int rc = RTSha3t256Final((PRTSHA3T256CONTEXT)pvState, pbHash);
707 AssertRC(rc);
708}
709
710/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
711static DECLCALLBACK(int) rtCrDigestSha3t256_Init(void *pvState, void *pvOpaque, bool fReInit)
712{
713 RT_NOREF_PV(pvOpaque);
714 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
715 if (fReInit)
716 RTSha3t256Cleanup((PRTSHA3T256CONTEXT)pvState);
717 return RTSha3t256Init((PRTSHA3T256CONTEXT)pvState);
718}
719
720/** @impl_interface_method{RTCRDIGESTDESC::pfnDelete} */
721static DECLCALLBACK(void) rtCrDigestSha3t256_Delete(void *pvState)
722{
723 RTSha3t256Cleanup((PRTSHA3T256CONTEXT)pvState);
724}
725
726/** @impl_interface_method{RTCRDIGESTDESC::pfnDelete} */
727static DECLCALLBACK(int) rtCrDigestSha3t256_Clone(void *pvState, void const *pvSrcState)
728{
729 return RTSha3t256Clone((PRTSHA3T256CONTEXT)pvState, (PRTSHA3T256CONTEXT)pvSrcState);
730}
731
732/** SHA3-256 alias ODIs. */
733static const char * const g_apszSha3t256Aliases[] =
734{
735 "2.16.840.1.101.3.4.3.14",
736 RTCR_NIST_SHA3_256_WITH_ECDSA_OID,
737 NULL
738};
739
740/** SHA3-256 descriptor. */
741static RTCRDIGESTDESC const g_rtCrDigestSha3t256Desc =
742{
743 "sha3-256",
744 "2.16.840.1.101.3.4.2.8",
745 g_apszSha3t256Aliases,
746 RTDIGESTTYPE_SHA3_256,
747 RTSHA3_256_HASH_SIZE,
748 sizeof(RTSHA3T256CONTEXT),
749 0,
750 NULL,
751 NULL,
752 rtCrDigestSha3t256_Update,
753 rtCrDigestSha3t256_Final,
754 rtCrDigestSha3t256_Init,
755 rtCrDigestSha3t256_Delete,
756 rtCrDigestSha3t256_Clone,
757 NULL,
758 NULL,
759};
760
761
762/*
763 * SHA3-384
764 */
765
766/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
767static DECLCALLBACK(void) rtCrDigestSha3t384_Update(void *pvState, const void *pvData, size_t cbData)
768{
769 int rc = RTSha3t384Update((PRTSHA3T384CONTEXT)pvState, pvData, cbData);
770 AssertRC(rc);
771}
772
773/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
774static DECLCALLBACK(void) rtCrDigestSha3t384_Final(void *pvState, uint8_t *pbHash)
775{
776 int rc = RTSha3t384Final((PRTSHA3T384CONTEXT)pvState, pbHash);
777 AssertRC(rc);
778}
779
780/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
781static DECLCALLBACK(int) rtCrDigestSha3t384_Init(void *pvState, void *pvOpaque, bool fReInit)
782{
783 RT_NOREF_PV(pvOpaque);
784 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
785 if (fReInit)
786 RTSha3t384Cleanup((PRTSHA3T384CONTEXT)pvState);
787 return RTSha3t384Init((PRTSHA3T384CONTEXT)pvState);
788}
789
790/** @impl_interface_method{RTCRDIGESTDESC::pfnDelete} */
791static DECLCALLBACK(void) rtCrDigestSha3t384_Delete(void *pvState)
792{
793 RTSha3t384Cleanup((PRTSHA3T384CONTEXT)pvState);
794}
795
796/** @impl_interface_method{RTCRDIGESTDESC::pfnDelete} */
797static DECLCALLBACK(int) rtCrDigestSha3t384_Clone(void *pvState, void const *pvSrcState)
798{
799 return RTSha3t384Clone((PRTSHA3T384CONTEXT)pvState, (PRTSHA3T384CONTEXT)pvSrcState);
800}
801
802/** SHA3-384 alias ODIs. */
803static const char * const g_apszSha3t384Aliases[] =
804{
805 "2.16.840.1.101.3.4.3.15",
806 RTCR_NIST_SHA3_384_WITH_ECDSA_OID,
807 NULL
808};
809
810/** SHA3-384 descriptor. */
811static RTCRDIGESTDESC const g_rtCrDigestSha3t384Desc =
812{
813 "sha3-384",
814 "2.16.840.1.101.3.4.2.9",
815 g_apszSha3t384Aliases,
816 RTDIGESTTYPE_SHA3_384,
817 RTSHA3_384_HASH_SIZE,
818 sizeof(RTSHA3T384CONTEXT),
819 0,
820 NULL,
821 NULL,
822 rtCrDigestSha3t384_Update,
823 rtCrDigestSha3t384_Final,
824 rtCrDigestSha3t384_Init,
825 rtCrDigestSha3t384_Delete,
826 rtCrDigestSha3t384_Clone,
827 NULL,
828 NULL,
829};
830
831
832/*
833 * SHA3-512
834 */
835
836/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
837static DECLCALLBACK(void) rtCrDigestSha3t512_Update(void *pvState, const void *pvData, size_t cbData)
838{
839 int rc = RTSha3t512Update((PRTSHA3T512CONTEXT)pvState, pvData, cbData);
840 AssertRC(rc);
841}
842
843/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
844static DECLCALLBACK(void) rtCrDigestSha3t512_Final(void *pvState, uint8_t *pbHash)
845{
846 int rc = RTSha3t512Final((PRTSHA3T512CONTEXT)pvState, pbHash);
847 AssertRC(rc);
848}
849
850/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
851static DECLCALLBACK(int) rtCrDigestSha3t512_Init(void *pvState, void *pvOpaque, bool fReInit)
852{
853 RT_NOREF_PV(pvOpaque);
854 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
855 if (fReInit)
856 RTSha3t512Cleanup((PRTSHA3T512CONTEXT)pvState);
857 return RTSha3t512Init((PRTSHA3T512CONTEXT)pvState);
858}
859
860/** @impl_interface_method{RTCRDIGESTDESC::pfnDelete} */
861static DECLCALLBACK(void) rtCrDigestSha3t512_Delete(void *pvState)
862{
863 RTSha3t512Cleanup((PRTSHA3T512CONTEXT)pvState);
864}
865
866/** @impl_interface_method{RTCRDIGESTDESC::pfnDelete} */
867static DECLCALLBACK(int) rtCrDigestSha3t512_Clone(void *pvState, void const *pvSrcState)
868{
869 return RTSha3t512Clone((PRTSHA3T512CONTEXT)pvState, (PRTSHA3T512CONTEXT)pvSrcState);
870}
871
872/** SHA3-512 alias ODIs. */
873static const char * const g_apszSha3t512Aliases[] =
874{
875 "2.16.840.1.101.3.4.3.16",
876 RTCR_NIST_SHA3_512_WITH_ECDSA_OID,
877 NULL
878};
879
880/** SHA3-512 descriptor. */
881static RTCRDIGESTDESC const g_rtCrDigestSha3t512Desc =
882{
883 "sha3-512",
884 "2.16.840.1.101.3.4.2.10",
885 g_apszSha3t512Aliases,
886 RTDIGESTTYPE_SHA3_512,
887 RTSHA3_512_HASH_SIZE,
888 sizeof(RTSHA3T512CONTEXT),
889 0,
890 NULL,
891 NULL,
892 rtCrDigestSha3t512_Update,
893 rtCrDigestSha3t512_Final,
894 rtCrDigestSha3t512_Init,
895 rtCrDigestSha3t512_Delete,
896 rtCrDigestSha3t512_Clone,
897 NULL,
898 NULL,
899};
900
901#endif /* !IPRT_WITHOUT_SHA3 */
902
903
904/**
905 * Array of built in message digest vtables.
906 */
907static PCRTCRDIGESTDESC const g_apDigestOps[] =
908{
909#ifndef IPRT_WITHOUT_DIGEST_MD2
910 &g_rtCrDigestMd2Desc,
911#endif
912#ifndef IPRT_WITHOUT_DIGEST_MD4
913 &g_rtCrDigestMd4Desc,
914#endif
915#ifndef IPRT_WITHOUT_DIGEST_MD5
916 &g_rtCrDigestMd5Desc,
917#endif
918 &g_rtCrDigestSha1Desc,
919 &g_rtCrDigestSha256Desc,
920 &g_rtCrDigestSha512Desc,
921 &g_rtCrDigestSha224Desc,
922 &g_rtCrDigestSha384Desc,
923#ifndef IPRT_WITHOUT_SHA512T224
924 &g_rtCrDigestSha512t224Desc,
925#endif
926#ifndef IPRT_WITHOUT_SHA512T256
927 &g_rtCrDigestSha512t256Desc,
928#endif
929#ifndef IPRT_WITHOUT_SHA3
930 &g_rtCrDigestSha3t224Desc,
931 &g_rtCrDigestSha3t256Desc,
932 &g_rtCrDigestSha3t384Desc,
933 &g_rtCrDigestSha3t512Desc,
934#endif
935};
936
937
938#ifdef IPRT_WITH_OPENSSL
939/*
940 * OpenSSL EVP.
941 */
942
943# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
944/** @impl_interface_method{RTCRDIGESTDESC::pfnNew} */
945static DECLCALLBACK(void*) rtCrDigestOsslEvp_New(void)
946{
947 return EVP_MD_CTX_new();
948}
949
950static DECLCALLBACK(void) rtCrDigestOsslEvp_Free(void *pvState)
951{
952 EVP_MD_CTX_free((EVP_MD_CTX*)pvState);
953}
954
955# endif
956
957/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
958static DECLCALLBACK(void) rtCrDigestOsslEvp_Update(void *pvState, const void *pvData, size_t cbData)
959{
960 EVP_DigestUpdate((EVP_MD_CTX *)pvState, pvData, cbData);
961}
962
963/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
964static DECLCALLBACK(void) rtCrDigestOsslEvp_Final(void *pvState, uint8_t *pbHash)
965{
966 unsigned int cbHash = EVP_MAX_MD_SIZE;
967 EVP_DigestFinal((EVP_MD_CTX *)pvState, (unsigned char *)pbHash, &cbHash);
968}
969
970/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
971static DECLCALLBACK(int) rtCrDigestOsslEvp_Init(void *pvState, void *pvOpaque, bool fReInit)
972{
973 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
974 EVP_MD const *pEvpType = (EVP_MD const *)pvOpaque;
975
976 if (fReInit)
977 {
978 pEvpType = EVP_MD_CTX_md(pThis);
979# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
980 EVP_MD_CTX_reset(pThis);
981# else
982 EVP_MD_CTX_cleanup(pThis);
983# endif
984 }
985
986 AssertPtrReturn(pEvpType, VERR_INVALID_PARAMETER);
987# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
988 Assert(EVP_MD_block_size(pEvpType));
989# else
990 Assert(pEvpType->md_size);
991# endif
992 if (EVP_DigestInit(pThis, pEvpType))
993 return VINF_SUCCESS;
994 return VERR_CR_DIGEST_OSSL_DIGEST_INIT_ERROR;
995}
996
997
998/** @impl_interface_method{RTCRDIGESTDESC::pfn} */
999static DECLCALLBACK(void) rtCrDigestOsslEvp_Delete(void *pvState)
1000{
1001 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
1002# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
1003 EVP_MD_CTX_reset(pThis);
1004# else
1005 EVP_MD_CTX_cleanup(pThis);
1006# endif
1007}
1008
1009
1010/** @impl_interface_method{RTCRDIGESTDESC::pfnClone} */
1011static DECLCALLBACK(int) rtCrDigestOsslEvp_Clone(void *pvState, void const *pvSrcState)
1012{
1013 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
1014 EVP_MD_CTX const *pSrc = (EVP_MD_CTX const *)pvSrcState;
1015
1016 if (EVP_MD_CTX_copy(pThis, pSrc))
1017 return VINF_SUCCESS;
1018 return VERR_CR_DIGEST_OSSL_DIGEST_CTX_COPY_ERROR;
1019}
1020
1021
1022/** @impl_interface_method{RTCRDIGESTDESC::pfnGetHashSize} */
1023static DECLCALLBACK(uint32_t) rtCrDigestOsslEvp_GetHashSize(void *pvState)
1024{
1025 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
1026 return EVP_MD_size(EVP_MD_CTX_md(pThis));
1027}
1028
1029
1030/** @impl_interface_method{RTCRDIGESTDESC::pfnGetHashSize} */
1031static DECLCALLBACK(RTDIGESTTYPE) rtCrDigestOsslEvp_GetDigestType(void *pvState)
1032{
1033 RT_NOREF_PV(pvState); //EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
1034 /** @todo figure which digest algorithm it is! */
1035 return RTDIGESTTYPE_UNKNOWN;
1036}
1037
1038
1039/** Descriptor for the OpenSSL EVP base message digest provider. */
1040static RTCRDIGESTDESC const g_rtCrDigestOpenSslDesc =
1041{
1042 "OpenSSL EVP",
1043 NULL,
1044 NULL,
1045 RTDIGESTTYPE_UNKNOWN,
1046 EVP_MAX_MD_SIZE,
1047# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
1048 0,
1049# else
1050 sizeof(EVP_MD_CTX),
1051# endif
1052 0,
1053# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
1054 rtCrDigestOsslEvp_New,
1055 rtCrDigestOsslEvp_Free,
1056# else
1057 NULL,
1058 NULL,
1059# endif
1060 rtCrDigestOsslEvp_Update,
1061 rtCrDigestOsslEvp_Final,
1062 rtCrDigestOsslEvp_Init,
1063 rtCrDigestOsslEvp_Delete,
1064 rtCrDigestOsslEvp_Clone,
1065 rtCrDigestOsslEvp_GetHashSize,
1066 rtCrDigestOsslEvp_GetDigestType
1067};
1068
1069#endif /* IPRT_WITH_OPENSSL */
1070
1071
1072RTDECL(PCRTCRDIGESTDESC) RTCrDigestFindByObjIdString(const char *pszObjId, void **ppvOpaque)
1073{
1074 if (ppvOpaque)
1075 *ppvOpaque = NULL;
1076
1077 /*
1078 * Primary OIDs.
1079 */
1080 uint32_t i = RT_ELEMENTS(g_apDigestOps);
1081 while (i-- > 0)
1082 if (strcmp(g_apDigestOps[i]->pszObjId, pszObjId) == 0)
1083 return g_apDigestOps[i];
1084
1085 /*
1086 * Alias OIDs.
1087 */
1088 i = RT_ELEMENTS(g_apDigestOps);
1089 while (i-- > 0)
1090 {
1091 const char * const *ppszAliases = g_apDigestOps[i]->papszObjIdAliases;
1092 if (ppszAliases)
1093 for (; *ppszAliases; ppszAliases++)
1094 if (strcmp(*ppszAliases, pszObjId) == 0)
1095 return g_apDigestOps[i];
1096 }
1097
1098#ifdef IPRT_WITH_OPENSSL
1099 /*
1100 * Try EVP and see if it knows the algorithm.
1101 */
1102 if (ppvOpaque)
1103 {
1104 rtCrOpenSslInit();
1105 int iAlgoNid = OBJ_txt2nid(pszObjId);
1106 if (iAlgoNid != NID_undef)
1107 {
1108 const char *pszAlogSn = OBJ_nid2sn(iAlgoNid);
1109 const EVP_MD *pEvpMdType = EVP_get_digestbyname(pszAlogSn);
1110 if (pEvpMdType)
1111 {
1112 /*
1113 * Return the OpenSSL provider descriptor and the EVP_MD address.
1114 */
1115# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
1116 Assert(EVP_MD_block_size(pEvpMdType));
1117# else
1118 Assert(pEvpMdType->md_size);
1119# endif
1120 *ppvOpaque = (void *)pEvpMdType;
1121 return &g_rtCrDigestOpenSslDesc;
1122 }
1123 }
1124 }
1125#endif
1126 return NULL;
1127}
1128
1129
1130RTDECL(PCRTCRDIGESTDESC) RTCrDigestFindByObjId(PCRTASN1OBJID pObjId, void **ppvOpaque)
1131{
1132 return RTCrDigestFindByObjIdString(pObjId->szObjId, ppvOpaque);
1133}
1134
1135
1136RTDECL(int) RTCrDigestCreateByObjIdString(PRTCRDIGEST phDigest, const char *pszObjId)
1137{
1138 void *pvOpaque;
1139 PCRTCRDIGESTDESC pDesc = RTCrDigestFindByObjIdString(pszObjId, &pvOpaque);
1140 if (pDesc)
1141 return RTCrDigestCreate(phDigest, pDesc, pvOpaque);
1142 return VERR_NOT_FOUND;
1143}
1144
1145
1146RTDECL(int) RTCrDigestCreateByObjId(PRTCRDIGEST phDigest, PCRTASN1OBJID pObjId)
1147{
1148 void *pvOpaque;
1149 PCRTCRDIGESTDESC pDesc = RTCrDigestFindByObjId(pObjId, &pvOpaque);
1150 if (pDesc)
1151 return RTCrDigestCreate(phDigest, pDesc, pvOpaque);
1152 return VERR_NOT_FOUND;
1153}
1154
1155
1156RTDECL(PCRTCRDIGESTDESC) RTCrDigestFindByType(RTDIGESTTYPE enmDigestType)
1157{
1158 AssertReturn(enmDigestType > RTDIGESTTYPE_INVALID && enmDigestType <= RTDIGESTTYPE_END, NULL);
1159
1160 uint32_t i = RT_ELEMENTS(g_apDigestOps);
1161 while (i-- > 0)
1162 if (g_apDigestOps[i]->enmType == enmDigestType)
1163 return g_apDigestOps[i];
1164 return NULL;
1165}
1166
1167
1168RTDECL(int) RTCrDigestCreateByType(PRTCRDIGEST phDigest, RTDIGESTTYPE enmDigestType)
1169{
1170 PCRTCRDIGESTDESC pDesc = RTCrDigestFindByType(enmDigestType);
1171 if (pDesc)
1172 return RTCrDigestCreate(phDigest, pDesc, NULL);
1173 return VERR_NOT_FOUND;
1174}
1175
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use