VirtualBox

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

Last change on this file since 85126 was 85121, checked in by vboxsync, 5 years ago

iprt/cdefs.h: Refactored the typedef use of DECLCALLBACK as well as DECLCALLBACKMEMBER to wrap the whole expression, similar to the DECLR?CALLBACKMEMBER macros. This allows adding a throw() at the end when compiling with the VC++ compiler to indicate that the callbacks won't throw anything, so we can stop supressing the C5039 warning about passing functions that can potential throw C++ exceptions to extern C code that can't necessarily cope with such (unwind,++). Introduced a few _EX variations that allows specifying different/no calling convention too, as that's handy when dynamically resolving host APIs. Fixed numerous places missing DECLCALLBACK and such. Left two angry @todos regarding use of CreateThread. bugref:9794

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.1 KB
Line 
1/* $Id: digest-builtin.cpp 85121 2020-07-08 19:33:26Z vboxsync $ */
2/** @file
3 * IPRT - Crypto - Cryptographic Hash / Message Digest API, Built-in providers.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include "internal/iprt.h"
32#include <iprt/crypto/digest.h>
33
34#include <iprt/err.h>
35#include <iprt/mem.h>
36#include <iprt/string.h>
37#include <iprt/md2.h>
38#include <iprt/md4.h>
39#include <iprt/md5.h>
40#include <iprt/sha.h>
41#include <iprt/crypto/pkix.h>
42
43#ifdef IPRT_WITH_OPENSSL
44# include "internal/iprt-openssl.h"
45# include "internal/openssl-pre.h"
46# include <openssl/evp.h>
47# include "internal/openssl-post.h"
48#endif
49
50
51
52/*
53 * MD2
54 */
55#ifndef IPRT_WITHOUT_DIGEST_MD2
56
57/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
58static DECLCALLBACK(void) rtCrDigestMd2_Update(void *pvState, const void *pvData, size_t cbData)
59{
60 RTMd2Update((PRTMD2CONTEXT)pvState, pvData, cbData);
61}
62
63/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
64static DECLCALLBACK(void) rtCrDigestMd2_Final(void *pvState, uint8_t *pbHash)
65{
66 RTMd2Final((PRTMD2CONTEXT)pvState, pbHash);
67}
68
69/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
70static DECLCALLBACK(int) rtCrDigestMd2_Init(void *pvState, void *pvOpaque, bool fReInit)
71{
72 RT_NOREF_PV(fReInit); RT_NOREF_PV(pvOpaque);
73 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
74 RTMd2Init((PRTMD2CONTEXT)pvState);
75 return VINF_SUCCESS;
76}
77
78/** MD2 alias ODIs. */
79static const char * const g_apszMd2Aliases[] =
80{
81 RTCR_PKCS1_MD2_WITH_RSA_OID,
82 "1.3.14.3.2.24" /* OIW md2WithRSASignature */,
83 NULL
84};
85
86/** MD2 descriptor. */
87static RTCRDIGESTDESC const g_rtCrDigestMd2Desc =
88{
89 "md2",
90 "1.2.840.113549.2.2",
91 g_apszMd2Aliases,
92 RTDIGESTTYPE_MD2,
93 RTMD2_HASH_SIZE,
94 sizeof(RTMD2CONTEXT),
95 RTCRDIGESTDESC_F_DEPRECATED,
96 NULL,
97 NULL,
98 rtCrDigestMd2_Update,
99 rtCrDigestMd2_Final,
100 rtCrDigestMd2_Init,
101 NULL,
102 NULL,
103 NULL,
104 NULL,
105};
106#endif /* !IPRT_WITHOUT_DIGEST_MD2 */
107
108
109/*
110 * MD4
111 */
112#ifndef IPRT_WITHOUT_DIGEST_MD4
113
114/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
115static DECLCALLBACK(void) rtCrDigestMd4_Update(void *pvState, const void *pvData, size_t cbData)
116{
117 RTMd4Update((PRTMD4CONTEXT)pvState, pvData, cbData);
118}
119
120/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
121static DECLCALLBACK(void) rtCrDigestMd4_Final(void *pvState, uint8_t *pbHash)
122{
123 RTMd4Final((PRTMD4CONTEXT)pvState, pbHash);
124}
125
126/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
127static DECLCALLBACK(int) rtCrDigestMd4_Init(void *pvState, void *pvOpaque, bool fReInit)
128{
129 RT_NOREF_PV(fReInit); RT_NOREF_PV(pvOpaque);
130 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
131 RTMd4Init((PRTMD4CONTEXT)pvState);
132 return VINF_SUCCESS;
133}
134
135/** MD4 alias ODIs. */
136static const char * const g_apszMd4Aliases[] =
137{
138 RTCR_PKCS1_MD4_WITH_RSA_OID,
139 NULL
140};
141
142/** MD4 descriptor. */
143static RTCRDIGESTDESC const g_rtCrDigestMd4Desc =
144{
145 "md4",
146 "1.2.840.113549.2.4",
147 g_apszMd4Aliases,
148 RTDIGESTTYPE_MD4,
149 RTMD4_HASH_SIZE,
150 sizeof(RTMD4CONTEXT),
151 RTCRDIGESTDESC_F_DEPRECATED | RTCRDIGESTDESC_F_COMPROMISED | RTCRDIGESTDESC_F_SERVERELY_COMPROMISED,
152 NULL,
153 NULL,
154 rtCrDigestMd4_Update,
155 rtCrDigestMd4_Final,
156 rtCrDigestMd4_Init,
157 NULL,
158 NULL,
159 NULL,
160 NULL,
161};
162
163#endif /* !IPRT_WITHOUT_DIGEST_MD4 */
164
165
166/*
167 * MD5
168 */
169#ifndef IPRT_WITHOUT_DIGEST_MD5
170
171/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
172static DECLCALLBACK(void) rtCrDigestMd5_Update(void *pvState, const void *pvData, size_t cbData)
173{
174 RTMd5Update((PRTMD5CONTEXT)pvState, pvData, cbData);
175}
176
177/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
178static DECLCALLBACK(void) rtCrDigestMd5_Final(void *pvState, uint8_t *pbHash)
179{
180 RTMd5Final(pbHash, (PRTMD5CONTEXT)pvState);
181}
182
183/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
184static DECLCALLBACK(int) rtCrDigestMd5_Init(void *pvState, void *pvOpaque, bool fReInit)
185{
186 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
187 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
188 RTMd5Init((PRTMD5CONTEXT)pvState);
189 return VINF_SUCCESS;
190}
191
192/** MD5 alias ODIs. */
193static const char * const g_apszMd5Aliases[] =
194{
195 RTCR_PKCS1_MD5_WITH_RSA_OID,
196 "1.3.14.3.2.25" /* OIW md5WithRSASignature */,
197 NULL
198};
199
200/** MD5 descriptor. */
201static RTCRDIGESTDESC const g_rtCrDigestMd5Desc =
202{
203 "md5",
204 "1.2.840.113549.2.5",
205 g_apszMd5Aliases,
206 RTDIGESTTYPE_MD5,
207 RTMD5_HASH_SIZE,
208 sizeof(RTMD5CONTEXT),
209 RTCRDIGESTDESC_F_COMPROMISED,
210 NULL,
211 NULL,
212 rtCrDigestMd5_Update,
213 rtCrDigestMd5_Final,
214 rtCrDigestMd5_Init,
215 NULL,
216 NULL,
217 NULL,
218 NULL,
219};
220#endif /* !IPRT_WITHOUT_DIGEST_MD5 */
221
222
223/*
224 * SHA-1
225 */
226
227/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
228static DECLCALLBACK(void) rtCrDigestSha1_Update(void *pvState, const void *pvData, size_t cbData)
229{
230 RTSha1Update((PRTSHA1CONTEXT)pvState, pvData, cbData);
231}
232
233/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
234static DECLCALLBACK(void) rtCrDigestSha1_Final(void *pvState, uint8_t *pbHash)
235{
236 RTSha1Final((PRTSHA1CONTEXT)pvState, pbHash);
237}
238
239/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
240static DECLCALLBACK(int) rtCrDigestSha1_Init(void *pvState, void *pvOpaque, bool fReInit)
241{
242 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
243 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
244 RTSha1Init((PRTSHA1CONTEXT)pvState);
245 return VINF_SUCCESS;
246}
247
248/** SHA-1 alias ODIs. */
249static const char * const g_apszSha1Aliases[] =
250{
251 RTCR_PKCS1_SHA1_WITH_RSA_OID,
252 "1.3.14.3.2.29" /* OIW sha1WithRSASignature */,
253 NULL
254};
255
256/** SHA-1 descriptor. */
257static RTCRDIGESTDESC const g_rtCrDigestSha1Desc =
258{
259 "sha-1",
260 "1.3.14.3.2.26",
261 g_apszSha1Aliases,
262 RTDIGESTTYPE_SHA1,
263 RTSHA1_HASH_SIZE,
264 sizeof(RTSHA1CONTEXT),
265 RTCRDIGESTDESC_F_DEPRECATED,
266 NULL,
267 NULL,
268 rtCrDigestSha1_Update,
269 rtCrDigestSha1_Final,
270 rtCrDigestSha1_Init,
271 NULL,
272 NULL,
273 NULL,
274 NULL,
275};
276
277
278/*
279 * SHA-256
280 */
281
282/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
283static DECLCALLBACK(void) rtCrDigestSha256_Update(void *pvState, const void *pvData, size_t cbData)
284{
285 RTSha256Update((PRTSHA256CONTEXT)pvState, pvData, cbData);
286}
287
288/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
289static DECLCALLBACK(void) rtCrDigestSha256_Final(void *pvState, uint8_t *pbHash)
290{
291 RTSha256Final((PRTSHA256CONTEXT)pvState, pbHash);
292}
293
294/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
295static DECLCALLBACK(int) rtCrDigestSha256_Init(void *pvState, void *pvOpaque, bool fReInit)
296{
297 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
298 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
299 RTSha256Init((PRTSHA256CONTEXT)pvState);
300 return VINF_SUCCESS;
301}
302
303/** SHA-256 alias ODIs. */
304static const char * const g_apszSha256Aliases[] =
305{
306 RTCR_PKCS1_SHA256_WITH_RSA_OID,
307 NULL
308};
309
310/** SHA-256 descriptor. */
311static RTCRDIGESTDESC const g_rtCrDigestSha256Desc =
312{
313 "sha-256",
314 "2.16.840.1.101.3.4.2.1",
315 g_apszSha256Aliases,
316 RTDIGESTTYPE_SHA256,
317 RTSHA256_HASH_SIZE,
318 sizeof(RTSHA256CONTEXT),
319 0,
320 NULL,
321 NULL,
322 rtCrDigestSha256_Update,
323 rtCrDigestSha256_Final,
324 rtCrDigestSha256_Init,
325 NULL,
326 NULL,
327 NULL,
328 NULL,
329};
330
331
332/*
333 * SHA-512
334 */
335
336/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
337static DECLCALLBACK(void) rtCrDigestSha512_Update(void *pvState, const void *pvData, size_t cbData)
338{
339 RTSha512Update((PRTSHA512CONTEXT)pvState, pvData, cbData);
340}
341
342/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
343static DECLCALLBACK(void) rtCrDigestSha512_Final(void *pvState, uint8_t *pbHash)
344{
345 RTSha512Final((PRTSHA512CONTEXT)pvState, pbHash);
346}
347
348/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
349static DECLCALLBACK(int) rtCrDigestSha512_Init(void *pvState, void *pvOpaque, bool fReInit)
350{
351 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
352 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
353 RTSha512Init((PRTSHA512CONTEXT)pvState);
354 return VINF_SUCCESS;
355}
356
357/** SHA-512 alias ODIs. */
358static const char * const g_apszSha512Aliases[] =
359{
360 RTCR_PKCS1_SHA512_WITH_RSA_OID,
361 NULL
362};
363
364/** SHA-512 descriptor. */
365static RTCRDIGESTDESC const g_rtCrDigestSha512Desc =
366{
367 "sha-512",
368 "2.16.840.1.101.3.4.2.3",
369 g_apszSha512Aliases,
370 RTDIGESTTYPE_SHA512,
371 RTSHA512_HASH_SIZE,
372 sizeof(RTSHA512CONTEXT),
373 0,
374 NULL,
375 NULL,
376 rtCrDigestSha512_Update,
377 rtCrDigestSha512_Final,
378 rtCrDigestSha512_Init,
379 NULL,
380 NULL,
381 NULL,
382 NULL,
383};
384
385
386/*
387 * SHA-224
388 */
389
390/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
391static DECLCALLBACK(void) rtCrDigestSha224_Update(void *pvState, const void *pvData, size_t cbData)
392{
393 RTSha224Update((PRTSHA224CONTEXT)pvState, pvData, cbData);
394}
395
396/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
397static DECLCALLBACK(void) rtCrDigestSha224_Final(void *pvState, uint8_t *pbHash)
398{
399 RTSha224Final((PRTSHA224CONTEXT)pvState, pbHash);
400}
401
402/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
403static DECLCALLBACK(int) rtCrDigestSha224_Init(void *pvState, void *pvOpaque, bool fReInit)
404{
405 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
406 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
407 RTSha224Init((PRTSHA224CONTEXT)pvState);
408 return VINF_SUCCESS;
409}
410
411/** SHA-224 alias ODIs. */
412static const char * const g_apszSha224Aliases[] =
413{
414 RTCR_PKCS1_SHA224_WITH_RSA_OID,
415 NULL
416};
417
418/** SHA-224 descriptor. */
419static RTCRDIGESTDESC const g_rtCrDigestSha224Desc =
420{
421 "sha-224",
422 "2.16.840.1.101.3.4.2.4",
423 g_apszSha224Aliases,
424 RTDIGESTTYPE_SHA224,
425 RTSHA224_HASH_SIZE,
426 sizeof(RTSHA224CONTEXT),
427 0,
428 NULL,
429 NULL,
430 rtCrDigestSha224_Update,
431 rtCrDigestSha224_Final,
432 rtCrDigestSha224_Init,
433 NULL,
434 NULL,
435 NULL,
436 NULL,
437};
438
439
440/*
441 * SHA-384
442 */
443
444/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
445static DECLCALLBACK(void) rtCrDigestSha384_Update(void *pvState, const void *pvData, size_t cbData)
446{
447 RTSha384Update((PRTSHA384CONTEXT)pvState, pvData, cbData);
448}
449
450/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
451static DECLCALLBACK(void) rtCrDigestSha384_Final(void *pvState, uint8_t *pbHash)
452{
453 RTSha384Final((PRTSHA384CONTEXT)pvState, pbHash);
454}
455
456/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
457static DECLCALLBACK(int) rtCrDigestSha384_Init(void *pvState, void *pvOpaque, bool fReInit)
458{
459 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
460 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
461 RTSha384Init((PRTSHA384CONTEXT)pvState);
462 return VINF_SUCCESS;
463}
464
465/** SHA-384 alias ODIs. */
466static const char * const g_apszSha384Aliases[] =
467{
468 RTCR_PKCS1_SHA384_WITH_RSA_OID,
469 NULL
470};
471
472/** SHA-384 descriptor. */
473static RTCRDIGESTDESC const g_rtCrDigestSha384Desc =
474{
475 "sha-384",
476 "2.16.840.1.101.3.4.2.2",
477 g_apszSha384Aliases,
478 RTDIGESTTYPE_SHA384,
479 RTSHA384_HASH_SIZE,
480 sizeof(RTSHA384CONTEXT),
481 0,
482 NULL,
483 NULL,
484 rtCrDigestSha384_Update,
485 rtCrDigestSha384_Final,
486 rtCrDigestSha384_Init,
487 NULL,
488 NULL,
489 NULL,
490 NULL,
491};
492
493
494#ifndef IPRT_WITHOUT_SHA512T224
495/*
496 * SHA-512/224
497 */
498
499/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
500static DECLCALLBACK(void) rtCrDigestSha512t224_Update(void *pvState, const void *pvData, size_t cbData)
501{
502 RTSha512t224Update((PRTSHA512T224CONTEXT)pvState, pvData, cbData);
503}
504
505/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
506static DECLCALLBACK(void) rtCrDigestSha512t224_Final(void *pvState, uint8_t *pbHash)
507{
508 RTSha512t224Final((PRTSHA512T224CONTEXT)pvState, pbHash);
509}
510
511/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
512static DECLCALLBACK(int) rtCrDigestSha512t224_Init(void *pvState, void *pvOpaque, bool fReInit)
513{
514 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
515 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
516 RTSha512t224Init((PRTSHA512T224CONTEXT)pvState);
517 return VINF_SUCCESS;
518}
519
520/** SHA-512/224 alias ODIs. */
521static const char * const g_apszSha512t224Aliases[] =
522{
523 RTCR_PKCS1_SHA512T224_WITH_RSA_OID,
524 NULL
525};
526
527/** SHA-512/224 descriptor. */
528static RTCRDIGESTDESC const g_rtCrDigestSha512t224Desc =
529{
530 "sha-512/224",
531 "2.16.840.1.101.3.4.2.5",
532 g_apszSha512t224Aliases,
533 RTDIGESTTYPE_SHA512T224,
534 RTSHA512T224_HASH_SIZE,
535 sizeof(RTSHA512T224CONTEXT),
536 0,
537 NULL,
538 NULL,
539 rtCrDigestSha512t224_Update,
540 rtCrDigestSha512t224_Final,
541 rtCrDigestSha512t224_Init,
542 NULL,
543 NULL,
544 NULL,
545 NULL,
546};
547#endif /* !IPRT_WITHOUT_SHA512T224 */
548
549
550#ifndef IPRT_WITHOUT_SHA512T256
551/*
552 * SHA-512/256
553 */
554
555/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
556static DECLCALLBACK(void) rtCrDigestSha512t256_Update(void *pvState, const void *pvData, size_t cbData)
557{
558 RTSha512t256Update((PRTSHA512T256CONTEXT)pvState, pvData, cbData);
559}
560
561/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
562static DECLCALLBACK(void) rtCrDigestSha512t256_Final(void *pvState, uint8_t *pbHash)
563{
564 RTSha512t256Final((PRTSHA512T256CONTEXT)pvState, pbHash);
565}
566
567/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
568static DECLCALLBACK(int) rtCrDigestSha512t256_Init(void *pvState, void *pvOpaque, bool fReInit)
569{
570 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
571 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
572 RTSha512t256Init((PRTSHA512T256CONTEXT)pvState);
573 return VINF_SUCCESS;
574}
575
576/** SHA-512/256 alias ODIs. */
577static const char * const g_apszSha512t256Aliases[] =
578{
579 RTCR_PKCS1_SHA512T256_WITH_RSA_OID,
580 NULL
581};
582
583/** SHA-512/256 descriptor. */
584static RTCRDIGESTDESC const g_rtCrDigestSha512t256Desc =
585{
586 "sha-512/256",
587 "2.16.840.1.101.3.4.2.6",
588 g_apszSha512t256Aliases,
589 RTDIGESTTYPE_SHA512T256,
590 RTSHA512T256_HASH_SIZE,
591 sizeof(RTSHA512T256CONTEXT),
592 0,
593 NULL,
594 NULL,
595 rtCrDigestSha512t256_Update,
596 rtCrDigestSha512t256_Final,
597 rtCrDigestSha512t256_Init,
598 NULL,
599 NULL,
600 NULL,
601 NULL,
602};
603#endif /* !IPRT_WITHOUT_SHA512T256 */
604
605
606/**
607 * Array of built in message digest vtables.
608 */
609static PCRTCRDIGESTDESC const g_apDigestOps[] =
610{
611#ifndef IPRT_WITHOUT_DIGEST_MD2
612 &g_rtCrDigestMd2Desc,
613#endif
614#ifndef IPRT_WITHOUT_DIGEST_MD4
615 &g_rtCrDigestMd4Desc,
616#endif
617#ifndef IPRT_WITHOUT_DIGEST_MD5
618 &g_rtCrDigestMd5Desc,
619#endif
620 &g_rtCrDigestSha1Desc,
621 &g_rtCrDigestSha256Desc,
622 &g_rtCrDigestSha512Desc,
623 &g_rtCrDigestSha224Desc,
624 &g_rtCrDigestSha384Desc,
625#ifndef IPRT_WITHOUT_SHA512T224
626 &g_rtCrDigestSha512t224Desc,
627#endif
628#ifndef IPRT_WITHOUT_SHA512T256
629 &g_rtCrDigestSha512t256Desc,
630#endif
631};
632
633
634#ifdef IPRT_WITH_OPENSSL
635/*
636 * OpenSSL EVP.
637 */
638
639# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
640/** @impl_interface_method{RTCRDIGESTDESC::pfnNew} */
641static DECLCALLBACK(void*) rtCrDigestOsslEvp_New(void)
642{
643 return EVP_MD_CTX_new();
644}
645
646static DECLCALLBACK(void) rtCrDigestOsslEvp_Free(void *pvState)
647{
648 EVP_MD_CTX_free((EVP_MD_CTX*)pvState);
649}
650
651# endif
652
653/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
654static DECLCALLBACK(void) rtCrDigestOsslEvp_Update(void *pvState, const void *pvData, size_t cbData)
655{
656 EVP_DigestUpdate((EVP_MD_CTX *)pvState, pvData, cbData);
657}
658
659/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
660static DECLCALLBACK(void) rtCrDigestOsslEvp_Final(void *pvState, uint8_t *pbHash)
661{
662 unsigned int cbHash = EVP_MAX_MD_SIZE;
663 EVP_DigestFinal((EVP_MD_CTX *)pvState, (unsigned char *)pbHash, &cbHash);
664}
665
666/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
667static DECLCALLBACK(int) rtCrDigestOsslEvp_Init(void *pvState, void *pvOpaque, bool fReInit)
668{
669 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
670 EVP_MD const *pEvpType = (EVP_MD const *)pvOpaque;
671
672 if (fReInit)
673 {
674 pEvpType = EVP_MD_CTX_md(pThis);
675# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
676 EVP_MD_CTX_reset(pThis);
677# else
678 EVP_MD_CTX_cleanup(pThis);
679# endif
680 }
681
682 AssertPtrReturn(pEvpType, VERR_INVALID_PARAMETER);
683# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
684 Assert(EVP_MD_block_size(pEvpType));
685# else
686 Assert(pEvpType->md_size);
687# endif
688 if (EVP_DigestInit(pThis, pEvpType))
689 return VINF_SUCCESS;
690 return VERR_CR_DIGEST_OSSL_DIGEST_INIT_ERROR;
691}
692
693
694/** @impl_interface_method{RTCRDIGESTDESC::pfn} */
695static DECLCALLBACK(void) rtCrDigestOsslEvp_Delete(void *pvState)
696{
697 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
698# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
699 EVP_MD_CTX_reset(pThis);
700# else
701 EVP_MD_CTX_cleanup(pThis);
702# endif
703}
704
705
706/** @impl_interface_method{RTCRDIGESTDESC::pfnClone} */
707static DECLCALLBACK(int) rtCrDigestOsslEvp_Clone(void *pvState, void const *pvSrcState)
708{
709 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
710 EVP_MD_CTX const *pSrc = (EVP_MD_CTX const *)pvSrcState;
711
712 if (EVP_MD_CTX_copy(pThis, pSrc))
713 return VINF_SUCCESS;
714 return VERR_CR_DIGEST_OSSL_DIGEST_CTX_COPY_ERROR;
715}
716
717
718/** @impl_interface_method{RTCRDIGESTDESC::pfnGetHashSize} */
719static DECLCALLBACK(uint32_t) rtCrDigestOsslEvp_GetHashSize(void *pvState)
720{
721 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
722 return EVP_MD_size(EVP_MD_CTX_md(pThis));
723}
724
725
726/** @impl_interface_method{RTCRDIGESTDESC::pfnGetHashSize} */
727static DECLCALLBACK(RTDIGESTTYPE) rtCrDigestOsslEvp_GetDigestType(void *pvState)
728{
729 RT_NOREF_PV(pvState); //EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
730 /** @todo figure which digest algorithm it is! */
731 return RTDIGESTTYPE_UNKNOWN;
732}
733
734
735/** Descriptor for the OpenSSL EVP base message digest provider. */
736static RTCRDIGESTDESC const g_rtCrDigestOpenSslDesc =
737{
738 "OpenSSL EVP",
739 NULL,
740 NULL,
741 RTDIGESTTYPE_UNKNOWN,
742 EVP_MAX_MD_SIZE,
743# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
744 0,
745# else
746 sizeof(EVP_MD_CTX),
747# endif
748 0,
749# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
750 rtCrDigestOsslEvp_New,
751 rtCrDigestOsslEvp_Free,
752# else
753 NULL,
754 NULL,
755# endif
756 rtCrDigestOsslEvp_Update,
757 rtCrDigestOsslEvp_Final,
758 rtCrDigestOsslEvp_Init,
759 rtCrDigestOsslEvp_Delete,
760 rtCrDigestOsslEvp_Clone,
761 rtCrDigestOsslEvp_GetHashSize,
762 rtCrDigestOsslEvp_GetDigestType
763};
764
765#endif /* IPRT_WITH_OPENSSL */
766
767
768RTDECL(PCRTCRDIGESTDESC) RTCrDigestFindByObjIdString(const char *pszObjId, void **ppvOpaque)
769{
770 if (ppvOpaque)
771 *ppvOpaque = NULL;
772
773 /*
774 * Primary OIDs.
775 */
776 uint32_t i = RT_ELEMENTS(g_apDigestOps);
777 while (i-- > 0)
778 if (strcmp(g_apDigestOps[i]->pszObjId, pszObjId) == 0)
779 return g_apDigestOps[i];
780
781 /*
782 * Alias OIDs.
783 */
784 i = RT_ELEMENTS(g_apDigestOps);
785 while (i-- > 0)
786 {
787 const char * const *ppszAliases = g_apDigestOps[i]->papszObjIdAliases;
788 if (ppszAliases)
789 for (; *ppszAliases; ppszAliases++)
790 if (strcmp(*ppszAliases, pszObjId) == 0)
791 return g_apDigestOps[i];
792 }
793
794#ifdef IPRT_WITH_OPENSSL
795 /*
796 * Try EVP and see if it knows the algorithm.
797 */
798 if (ppvOpaque)
799 {
800 rtCrOpenSslInit();
801 int iAlgoNid = OBJ_txt2nid(pszObjId);
802 if (iAlgoNid != NID_undef)
803 {
804 const char *pszAlogSn = OBJ_nid2sn(iAlgoNid);
805 const EVP_MD *pEvpMdType = EVP_get_digestbyname(pszAlogSn);
806 if (pEvpMdType)
807 {
808 /*
809 * Return the OpenSSL provider descriptor and the EVP_MD address.
810 */
811# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
812 Assert(EVP_MD_block_size(pEvpMdType));
813# else
814 Assert(pEvpMdType->md_size);
815# endif
816 *ppvOpaque = (void *)pEvpMdType;
817 return &g_rtCrDigestOpenSslDesc;
818 }
819 }
820 }
821#endif
822 return NULL;
823}
824
825
826RTDECL(PCRTCRDIGESTDESC) RTCrDigestFindByObjId(PCRTASN1OBJID pObjId, void **ppvOpaque)
827{
828 return RTCrDigestFindByObjIdString(pObjId->szObjId, ppvOpaque);
829}
830
831
832RTDECL(int) RTCrDigestCreateByObjIdString(PRTCRDIGEST phDigest, const char *pszObjId)
833{
834 void *pvOpaque;
835 PCRTCRDIGESTDESC pDesc = RTCrDigestFindByObjIdString(pszObjId, &pvOpaque);
836 if (pDesc)
837 return RTCrDigestCreate(phDigest, pDesc, pvOpaque);
838 return VERR_NOT_FOUND;
839}
840
841
842RTDECL(int) RTCrDigestCreateByObjId(PRTCRDIGEST phDigest, PCRTASN1OBJID pObjId)
843{
844 void *pvOpaque;
845 PCRTCRDIGESTDESC pDesc = RTCrDigestFindByObjId(pObjId, &pvOpaque);
846 if (pDesc)
847 return RTCrDigestCreate(phDigest, pDesc, pvOpaque);
848 return VERR_NOT_FOUND;
849}
850
851
852RTDECL(PCRTCRDIGESTDESC) RTCrDigestFindByType(RTDIGESTTYPE enmDigestType)
853{
854 AssertReturn(enmDigestType > RTDIGESTTYPE_INVALID && enmDigestType <= RTDIGESTTYPE_END, NULL);
855
856 uint32_t i = RT_ELEMENTS(g_apDigestOps);
857 while (i-- > 0)
858 if (g_apDigestOps[i]->enmType == enmDigestType)
859 return g_apDigestOps[i];
860 return NULL;
861}
862
863
864RTDECL(int) RTCrDigestCreateByType(PRTCRDIGEST phDigest, RTDIGESTTYPE enmDigestType)
865{
866 PCRTCRDIGESTDESC pDesc = RTCrDigestFindByType(enmDigestType);
867 if (pDesc)
868 return RTCrDigestCreate(phDigest, pDesc, NULL);
869 return VERR_NOT_FOUND;
870}
871
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette