VirtualBox

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

Last change on this file since 75482 was 73705, checked in by vboxsync, 6 years ago

IPRT: Better fix for missing md4 failure; adding information status codes for indicating deprecated and compromised digests when used.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.9 KB
Line 
1/* $Id: digest-builtin.cpp 73705 2018-08-16 09:31:18Z vboxsync $ */
2/** @file
3 * IPRT - Crypto - Cryptographic Hash / Message Digest API, Built-in providers.
4 */
5
6/*
7 * Copyright (C) 2006-2017 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 NULL
522};
523
524/** SHA-512/224 descriptor. */
525static RTCRDIGESTDESC const g_rtCrDigestSha512t224Desc =
526{
527 "sha-512/224",
528 "2.16.840.1.101.3.4.2.5",
529 g_apszSha512t224Aliases,
530 RTDIGESTTYPE_SHA512T224,
531 RTSHA512T224_HASH_SIZE,
532 sizeof(RTSHA512T224CONTEXT),
533 0,
534 NULL,
535 NULL,
536 rtCrDigestSha512t224_Update,
537 rtCrDigestSha512t224_Final,
538 rtCrDigestSha512t224_Init,
539 NULL,
540 NULL,
541 NULL,
542 NULL,
543};
544#endif /* !IPRT_WITHOUT_SHA512T224 */
545
546
547#ifndef IPRT_WITHOUT_SHA512T256
548/*
549 * SHA-512/256
550 */
551
552/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
553static DECLCALLBACK(void) rtCrDigestSha512t256_Update(void *pvState, const void *pvData, size_t cbData)
554{
555 RTSha512t256Update((PRTSHA512T256CONTEXT)pvState, pvData, cbData);
556}
557
558/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
559static DECLCALLBACK(void) rtCrDigestSha512t256_Final(void *pvState, uint8_t *pbHash)
560{
561 RTSha512t256Final((PRTSHA512T256CONTEXT)pvState, pbHash);
562}
563
564/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
565static DECLCALLBACK(int) rtCrDigestSha512t256_Init(void *pvState, void *pvOpaque, bool fReInit)
566{
567 RT_NOREF_PV(pvOpaque); RT_NOREF_PV(fReInit);
568 AssertReturn(pvOpaque == NULL, VERR_INVALID_PARAMETER);
569 RTSha512t256Init((PRTSHA512T256CONTEXT)pvState);
570 return VINF_SUCCESS;
571}
572
573/** SHA-512/256 alias ODIs. */
574static const char * const g_apszSha512t256Aliases[] =
575{
576 NULL
577};
578
579/** SHA-512/256 descriptor. */
580static RTCRDIGESTDESC const g_rtCrDigestSha512t256Desc =
581{
582 "sha-512/256",
583 "2.16.840.1.101.3.4.2.6",
584 g_apszSha512t256Aliases,
585 RTDIGESTTYPE_SHA512T256,
586 RTSHA512T256_HASH_SIZE,
587 sizeof(RTSHA512T256CONTEXT),
588 0,
589 NULL,
590 NULL,
591 rtCrDigestSha512t256_Update,
592 rtCrDigestSha512t256_Final,
593 rtCrDigestSha512t256_Init,
594 NULL,
595 NULL,
596 NULL,
597 NULL,
598};
599#endif /* !IPRT_WITHOUT_SHA512T256 */
600
601
602/**
603 * Array of built in message digest vtables.
604 */
605static PCRTCRDIGESTDESC const g_apDigestOps[] =
606{
607#ifndef IPRT_WITHOUT_DIGEST_MD2
608 &g_rtCrDigestMd2Desc,
609#endif
610#ifndef IPRT_WITHOUT_DIGEST_MD4
611 &g_rtCrDigestMd4Desc,
612#endif
613#ifndef IPRT_WITHOUT_DIGEST_MD5
614 &g_rtCrDigestMd5Desc,
615#endif
616 &g_rtCrDigestSha1Desc,
617 &g_rtCrDigestSha256Desc,
618 &g_rtCrDigestSha512Desc,
619 &g_rtCrDigestSha224Desc,
620 &g_rtCrDigestSha384Desc,
621#ifndef IPRT_WITHOUT_SHA512T224
622 &g_rtCrDigestSha512t224Desc,
623#endif
624#ifndef IPRT_WITHOUT_SHA512T256
625 &g_rtCrDigestSha512t256Desc,
626#endif
627};
628
629
630#ifdef IPRT_WITH_OPENSSL
631/*
632 * OpenSSL EVP.
633 */
634
635# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
636/** @impl_interface_method{RTCRDIGESTDESC::pfnNew} */
637static DECLCALLBACK(void*) rtCrDigestOsslEvp_New(void)
638{
639 return EVP_MD_CTX_new();
640}
641
642static DECLCALLBACK(void) rtCrDigestOsslEvp_Free(void *pvState)
643{
644 EVP_MD_CTX_free((EVP_MD_CTX*)pvState);
645}
646
647# endif
648
649/** @impl_interface_method{RTCRDIGESTDESC::pfnUpdate} */
650static DECLCALLBACK(void) rtCrDigestOsslEvp_Update(void *pvState, const void *pvData, size_t cbData)
651{
652 EVP_DigestUpdate((EVP_MD_CTX *)pvState, pvData, cbData);
653}
654
655/** @impl_interface_method{RTCRDIGESTDESC::pfnFinal} */
656static DECLCALLBACK(void) rtCrDigestOsslEvp_Final(void *pvState, uint8_t *pbHash)
657{
658 unsigned int cbHash = EVP_MAX_MD_SIZE;
659 EVP_DigestFinal((EVP_MD_CTX *)pvState, (unsigned char *)pbHash, &cbHash);
660}
661
662/** @impl_interface_method{RTCRDIGESTDESC::pfnInit} */
663static DECLCALLBACK(int) rtCrDigestOsslEvp_Init(void *pvState, void *pvOpaque, bool fReInit)
664{
665 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
666 EVP_MD const *pEvpType = (EVP_MD const *)pvOpaque;
667
668 if (fReInit)
669 {
670 pEvpType = EVP_MD_CTX_md(pThis);
671# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
672 EVP_MD_CTX_reset(pThis);
673# else
674 EVP_MD_CTX_cleanup(pThis);
675# endif
676 }
677
678 AssertPtrReturn(pEvpType, VERR_INVALID_PARAMETER);
679# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
680 Assert(EVP_MD_block_size(pEvpType));
681# else
682 Assert(pEvpType->md_size);
683# endif
684 if (EVP_DigestInit(pThis, pEvpType))
685 return VINF_SUCCESS;
686 return VERR_CR_DIGEST_OSSL_DIGEST_INIT_ERROR;
687}
688
689
690/** @impl_interface_method{RTCRDIGESTDESC::pfn} */
691static DECLCALLBACK(void) rtCrDigestOsslEvp_Delete(void *pvState)
692{
693 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
694# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
695 EVP_MD_CTX_reset(pThis);
696# else
697 EVP_MD_CTX_cleanup(pThis);
698# endif
699}
700
701
702/** @impl_interface_method{RTCRDIGESTDESC::pfnClone} */
703static DECLCALLBACK(int) rtCrDigestOsslEvp_Clone(void *pvState, void const *pvSrcState)
704{
705 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
706 EVP_MD_CTX const *pSrc = (EVP_MD_CTX const *)pvSrcState;
707
708 if (EVP_MD_CTX_copy(pThis, pSrc))
709 return VINF_SUCCESS;
710 return VERR_CR_DIGEST_OSSL_DIGEST_CTX_COPY_ERROR;
711}
712
713
714/** @impl_interface_method{RTCRDIGESTDESC::pfnGetHashSize} */
715static DECLCALLBACK(uint32_t) rtCrDigestOsslEvp_GetHashSize(void *pvState)
716{
717 EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
718 return EVP_MD_size(EVP_MD_CTX_md(pThis));
719}
720
721
722/** @impl_interface_method{RTCRDIGESTDESC::pfnGetHashSize} */
723static DECLCALLBACK(RTDIGESTTYPE) rtCrDigestOsslEvp_GetDigestType(void *pvState)
724{
725 RT_NOREF_PV(pvState); //EVP_MD_CTX *pThis = (EVP_MD_CTX *)pvState;
726 /** @todo figure which digest algorithm it is! */
727 return RTDIGESTTYPE_UNKNOWN;
728}
729
730
731/** Descriptor for the OpenSSL EVP base message digest provider. */
732static RTCRDIGESTDESC const g_rtCrDigestOpenSslDesc =
733{
734 "OpenSSL EVP",
735 NULL,
736 NULL,
737 RTDIGESTTYPE_UNKNOWN,
738 EVP_MAX_MD_SIZE,
739# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
740 0,
741# else
742 sizeof(EVP_MD_CTX),
743# endif
744 0,
745# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
746 rtCrDigestOsslEvp_New,
747 rtCrDigestOsslEvp_Free,
748# else
749 NULL,
750 NULL,
751# endif
752 rtCrDigestOsslEvp_Update,
753 rtCrDigestOsslEvp_Final,
754 rtCrDigestOsslEvp_Init,
755 rtCrDigestOsslEvp_Delete,
756 rtCrDigestOsslEvp_Clone,
757 rtCrDigestOsslEvp_GetHashSize,
758 rtCrDigestOsslEvp_GetDigestType
759};
760
761#endif /* IPRT_WITH_OPENSSL */
762
763
764RTDECL(PCRTCRDIGESTDESC) RTCrDigestFindByObjIdString(const char *pszObjId, void **ppvOpaque)
765{
766 if (ppvOpaque)
767 *ppvOpaque = NULL;
768
769 /*
770 * Primary OIDs.
771 */
772 uint32_t i = RT_ELEMENTS(g_apDigestOps);
773 while (i-- > 0)
774 if (strcmp(g_apDigestOps[i]->pszObjId, pszObjId) == 0)
775 return g_apDigestOps[i];
776
777 /*
778 * Alias OIDs.
779 */
780 i = RT_ELEMENTS(g_apDigestOps);
781 while (i-- > 0)
782 {
783 const char * const *ppszAliases = g_apDigestOps[i]->papszObjIdAliases;
784 if (ppszAliases)
785 for (; *ppszAliases; ppszAliases++)
786 if (strcmp(*ppszAliases, pszObjId) == 0)
787 return g_apDigestOps[i];
788 }
789
790#ifdef IPRT_WITH_OPENSSL
791 /*
792 * Try EVP and see if it knows the algorithm.
793 */
794 if (ppvOpaque)
795 {
796 rtCrOpenSslInit();
797 int iAlgoNid = OBJ_txt2nid(pszObjId);
798 if (iAlgoNid != NID_undef)
799 {
800 const char *pszAlogSn = OBJ_nid2sn(iAlgoNid);
801 const EVP_MD *pEvpMdType = EVP_get_digestbyname(pszAlogSn);
802 if (pEvpMdType)
803 {
804 /*
805 * Return the OpenSSL provider descriptor and the EVP_MD address.
806 */
807# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
808 Assert(EVP_MD_block_size(pEvpMdType));
809# else
810 Assert(pEvpMdType->md_size);
811# endif
812 *ppvOpaque = (void *)pEvpMdType;
813 return &g_rtCrDigestOpenSslDesc;
814 }
815 }
816 }
817#endif
818 return NULL;
819}
820
821
822RTDECL(PCRTCRDIGESTDESC) RTCrDigestFindByObjId(PCRTASN1OBJID pObjId, void **ppvOpaque)
823{
824 return RTCrDigestFindByObjIdString(pObjId->szObjId, ppvOpaque);
825}
826
827
828RTDECL(int) RTCrDigestCreateByObjIdString(PRTCRDIGEST phDigest, const char *pszObjId)
829{
830 void *pvOpaque;
831 PCRTCRDIGESTDESC pDesc = RTCrDigestFindByObjIdString(pszObjId, &pvOpaque);
832 if (pDesc)
833 return RTCrDigestCreate(phDigest, pDesc, pvOpaque);
834 return VERR_NOT_FOUND;
835}
836
837
838RTDECL(int) RTCrDigestCreateByObjId(PRTCRDIGEST phDigest, PCRTASN1OBJID pObjId)
839{
840 void *pvOpaque;
841 PCRTCRDIGESTDESC pDesc = RTCrDigestFindByObjId(pObjId, &pvOpaque);
842 if (pDesc)
843 return RTCrDigestCreate(phDigest, pDesc, pvOpaque);
844 return VERR_NOT_FOUND;
845}
846
847
848RTDECL(PCRTCRDIGESTDESC) RTCrDigestFindByType(RTDIGESTTYPE enmDigestType)
849{
850 AssertReturn(enmDigestType > RTDIGESTTYPE_INVALID && enmDigestType <= RTDIGESTTYPE_END, NULL);
851
852 uint32_t i = RT_ELEMENTS(g_apDigestOps);
853 while (i-- > 0)
854 if (g_apDigestOps[i]->enmType == enmDigestType)
855 return g_apDigestOps[i];
856 return NULL;
857}
858
859
860RTDECL(int) RTCrDigestCreateByType(PRTCRDIGEST phDigest, RTDIGESTTYPE enmDigestType)
861{
862 PCRTCRDIGESTDESC pDesc = RTCrDigestFindByType(enmDigestType);
863 if (pDesc)
864 return RTCrDigestCreate(phDigest, pDesc, NULL);
865 return VERR_NOT_FOUND;
866}
867
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