VirtualBox

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

Last change on this file since 64883 was 63867, checked in by vboxsync, 8 years ago

Runtime: OpenSSL 1.1 fix

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