VirtualBox

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

Last change on this file since 84379 was 84251, checked in by vboxsync, 5 years ago

IPRT/crypto: Adding functions for checking whether a key or certificate can handle a given digest (size wise). Also, added OIDs, padding variants and stuff for sha512-224WithRSAEncryption and sha512-256WithRSAEncryption (RFC-8017). Note that OpenSSL does not implement these yet. [missed a couple sha512t* usages] bugref:9699

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

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