VirtualBox

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

Last change on this file since 62538 was 62477, checked in by vboxsync, 9 years ago

(C) 2016

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