TianoCore EDK2 master
Loading...
Searching...
No Matches
CryptPkcs7Sign.c
Go to the documentation of this file.
1
13#include "CryptPkcs7Internal.h"
14#include <mbedtls/ecdh.h>
15
19#define MAX_SIGNATURE_SIZE 1024
20
21GLOBAL_REMOVE_IF_UNREFERENCED UINT8 MbedtlsOidDigestAlgSha256[] = MBEDTLS_OID_DIGEST_ALG_SHA256;
22GLOBAL_REMOVE_IF_UNREFERENCED UINT8 MbedtlsOidPkcs1Rsa[] = MBEDTLS_OID_PKCS1_RSA;
23
35INT32
37 UINT8 **Ptr,
38 UINT8 *Start,
39 mbedtls_md_type_t DigestType
40 )
41{
42 UINT8 *OidPtr;
43 UINTN OidLen;
44 INT32 Ret;
45
46 Ret = mbedtls_oid_get_oid_by_md (DigestType, (CONST CHAR8 **)&OidPtr, &OidLen);
47 if (Ret == 0) {
48 return mbedtls_asn1_write_oid (Ptr, (CONST UINT8 *)Start, (CONST CHAR8 *)OidPtr, OidLen);
49 }
50
51 return 0;
52}
53
67INT32
69 UINT8 **Ptr,
70 UINT8 *Start,
71 mbedtls_md_type_t *DigestTypes,
72 INTN Count
73 )
74{
75 INTN Idx;
76 INT32 Len;
77 INT32 Ret;
78
79 Len = 0;
80 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_null (Ptr, Start));
81
82 for (Idx = 0; Idx < Count; Idx++) {
83 EDKII_ASN1_CHK_ADD (
84 Len,
85 MbedTlsPkcs7WriteDigestAlgorithm (Ptr, Start, DigestTypes[Idx])
86 );
87 }
88
89 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, (UINTN)Len));
90
91 EDKII_ASN1_CHK_ADD (
92 Len,
93 mbedtls_asn1_write_tag (
94 Ptr,
95 Start,
96 (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)
97 )
98 );
99
100 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, (UINTN)Len));
101
102 EDKII_ASN1_CHK_ADD (
103 Len,
104 mbedtls_asn1_write_tag (
105 Ptr,
106 Start,
107 (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)
108 )
109 );
110
111 return Len;
112}
113
128STATIC
129INT32
131 UINT8 **Ptr,
132 UINT8 *Start,
133 UINT8 *Content,
134 INTN ContentLen
135 )
136{
137 INT32 Ret;
138 INT32 Len;
139
140 Len = 0;
141 if (Content != NULL) {
142 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_octet_string (Ptr, Start, Content, ContentLen));
143 }
144
145 EDKII_ASN1_CHK_ADD (
146 Len,
147 mbedtls_asn1_write_oid (
148 Ptr,
149 Start,
150 MBEDTLS_OID_PKCS7_DATA,
151 sizeof (MBEDTLS_OID_PKCS7_DATA) - 1
152 )
153 );
154
155 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
156
157 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
158
159 return Len;
160}
161
176STATIC
177INT32
179 UINT8 **Ptr,
180 UINT8 *Start,
181 mbedtls_x509_crt *Cert,
182 mbedtls_x509_crt *OtherCerts
183 )
184{
185 INT32 Ret;
186 INT32 Len;
187 mbedtls_x509_crt *TmpCert;
188
189 Len = 0;
190
192 TmpCert = OtherCerts;
193 while (TmpCert != NULL) {
194 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, TmpCert->raw.p, TmpCert->raw.len));
195 TmpCert = TmpCert->next;
196 }
197
199 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, Cert->raw.p, Cert->raw.len));
200
202 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
203 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC));
204 return Len;
205}
206
218STATIC
219INT32
221 UINT8 **Ptr,
222 UINT8 *Start,
223 UINT8 *SerialRaw,
224 INTN SerialRawLen
225 )
226{
227 INT32 Ret;
228 UINT8 *Pt;
229 INT32 Len;
230
231 Len = 0;
232 Pt = SerialRaw + SerialRawLen;
233 while (Pt > SerialRaw) {
234 *--(*Ptr) = *--Pt;
235 Len++;
236 }
237
238 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
239 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_INTEGER));
240
241 return Len;
242}
243
257STATIC
258INT32
260 UINT8 **Ptr,
261 UINT8 *Start,
262 UINT8 *Serial,
263 INTN SerialLen,
264 UINT8 *IssuerRaw,
265 INTN IssuerRawLen
266 )
267{
268 INT32 Ret;
269 INT32 Len;
270
271 Len = 0;
272 EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteInt (Ptr, Start, Serial, SerialLen));
273
274 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, IssuerRaw, IssuerRawLen));
275
276 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
277 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
278
279 return Len;
280}
281
301STATIC
302INT32
304 UINT8 **Ptr,
305 UINT8 *Start,
306 MbedtlsPkcs7SignerInfo *SignerInfo
307 )
308{
309 INT32 Ret;
310 INT32 Len;
311
312 Len = 0;
313
314 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_octet_string (Ptr, Start, SignerInfo->Sig.p, SignerInfo->Sig.len));
315
316 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_algorithm_identifier (Ptr, Start, (CONST CHAR8 *)SignerInfo->SigAlgIdentifier.p, SignerInfo->SigAlgIdentifier.len, 0));
317
318 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_algorithm_identifier (Ptr, Start, (CONST CHAR8 *)SignerInfo->AlgIdentifier.p, SignerInfo->AlgIdentifier.len, 0));
319
320 EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteIssuerAndSerialNumber (Ptr, Start, SignerInfo->Serial.p, SignerInfo->Serial.len, SignerInfo->IssuerRaw.p, SignerInfo->IssuerRaw.len));
321
322 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_int (Ptr, Start, SignerInfo->Version));
323
324 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
325 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
326
327 return Len;
328}
329
340STATIC
341INT32
343 UINT8 **Ptr,
344 UINT8 *Start,
345 MbedtlsPkcs7SignerInfo *SignersSet
346 )
347{
348 MbedtlsPkcs7SignerInfo *SignerInfo;
349 INT32 Ret;
350 INT32 Len;
351
352 SignerInfo = SignersSet;
353 Len = 0;
354
355 while (SignerInfo != NULL) {
356 EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteSignerInfo (Ptr, Start, SignerInfo));
357 // move to next
358 SignerInfo = SignerInfo->Next;
359 }
360
361 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
362 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET));
363
364 return Len;
365}
366
392STATIC
393INT32
395 UINT8 **Ptr,
396 UINT8 *Start,
397 MbedtlsPkcs7 *Pkcs7
398 )
399{
400 INT32 Ret;
401 INT32 Len;
402 mbedtls_md_type_t DigestAlg[1];
403
404 DigestAlg[0] = MBEDTLS_MD_SHA256;
405 Len = 0;
406
407 EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteSignersInfoSet (Ptr, Start, &(Pkcs7->SignedData.SignerInfos)));
408
409 EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteCertificates (Ptr, Start, &(Pkcs7->SignedData.Certificates), Pkcs7->SignedData.Certificates.next));
410
411 EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteContentInfo (Ptr, Start, NULL, 0));
412
413 EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteDigestAlgorithmSet (Ptr, Start, DigestAlg, 1));
414
415 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_int (Ptr, Start, Pkcs7->SignedData.Version));
416
417 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
418 EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
419
420 return Len;
421}
422
450BOOLEAN
451EFIAPI
453 IN CONST UINT8 *PrivateKey,
454 IN UINTN PrivateKeySize,
455 IN CONST UINT8 *KeyPassword,
456 IN UINT8 *InData,
457 IN UINTN InDataSize,
458 IN UINT8 *SignCert,
459 IN UINT8 *OtherCerts OPTIONAL,
460 OUT UINT8 **SignedData,
461 OUT UINTN *SignedDataSize
462 )
463{
464 BOOLEAN Status;
465 INT32 Ret;
466 mbedtls_pk_context Pkey;
467 UINT8 HashValue[SHA256_DIGEST_SIZE];
468 UINT8 Signature[MAX_SIGNATURE_SIZE];
469 UINTN SignatureLen;
470 UINT8 *NewPrivateKey;
471 mbedtls_x509_crt *Crt;
472
473 MbedtlsPkcs7 Pkcs7;
474 MbedtlsPkcs7SignerInfo SignerInfo;
475 UINT8 *Buffer;
476 INTN BufferSize;
477 UINT8 *Ptr;
478 INT32 Len;
479
480 //
481 // Check input parameters.
482 //
483 if ((PrivateKey == NULL) || (KeyPassword == NULL) || (InData == NULL) ||
484 (SignCert == NULL) || (SignedData == NULL) || (SignedDataSize == NULL) || (InDataSize > INT_MAX))
485 {
486 return FALSE;
487 }
488
489 Buffer = NULL;
490 BufferSize = 4096;
491
492 SignatureLen = MAX_SIGNATURE_SIZE;
493 Crt = (mbedtls_x509_crt *)SignCert;
494
495 NewPrivateKey = NULL;
496 if (PrivateKey[PrivateKeySize - 1] != 0) {
497 NewPrivateKey = AllocateZeroPool (PrivateKeySize + 1);
498 if (NewPrivateKey == NULL) {
499 return FALSE;
500 }
501
502 CopyMem (NewPrivateKey, PrivateKey, PrivateKeySize);
503 NewPrivateKey[PrivateKeySize] = 0;
504 PrivateKeySize++;
505 } else {
506 NewPrivateKey = AllocateZeroPool (PrivateKeySize);
507 if (NewPrivateKey == NULL) {
508 return FALSE;
509 }
510
511 CopyMem (NewPrivateKey, PrivateKey, PrivateKeySize);
512 }
513
514 mbedtls_pk_init (&Pkey);
515 Ret = mbedtls_pk_parse_key (
516 &Pkey,
517 NewPrivateKey,
518 PrivateKeySize,
519 KeyPassword,
520 KeyPassword == NULL ? 0 : AsciiStrLen ((CONST CHAR8 *)KeyPassword),
521 NULL,
522 NULL
523 );
524 if (Ret != 0) {
525 Status = FALSE;
526 goto Cleanup;
527 }
528
530 ZeroMem (HashValue, SHA256_DIGEST_SIZE);
531 Status = Sha256HashAll (InData, InDataSize, HashValue);
532 if (!Status) {
533 goto Cleanup;
534 }
535
537 ZeroMem (Signature, MAX_SIGNATURE_SIZE);
538 Ret = mbedtls_pk_sign (
539 &Pkey,
540 MBEDTLS_MD_SHA256,
541 HashValue,
543 Signature,
545 &SignatureLen,
547 NULL
548 );
549 if (Ret != 0) {
550 Status = FALSE;
551 goto Cleanup;
552 }
553
554 ZeroMem (&Pkcs7, sizeof (MbedtlsPkcs7));
555 Pkcs7.SignedData.Version = 1;
556
557 Crt->next = (mbedtls_x509_crt *)OtherCerts;
558 Pkcs7.SignedData.Certificates = *Crt;
559
560 SignerInfo.Next = NULL;
561 SignerInfo.Sig.p = Signature;
562 SignerInfo.Sig.len = SignatureLen;
563 SignerInfo.Version = 1;
564 SignerInfo.AlgIdentifier.p = MbedtlsOidDigestAlgSha256;
565 SignerInfo.AlgIdentifier.len = sizeof (MBEDTLS_OID_DIGEST_ALG_SHA256) - 1;
566 if (mbedtls_pk_get_type (&Pkey) == MBEDTLS_PK_RSA) {
567 SignerInfo.SigAlgIdentifier.p = MbedtlsOidPkcs1Rsa;
568 SignerInfo.SigAlgIdentifier.len = sizeof (MBEDTLS_OID_PKCS1_RSA) - 1;
569 } else {
570 Ret = mbedtls_oid_get_oid_by_sig_alg (MBEDTLS_PK_ECDSA, MBEDTLS_MD_SHA256, (CONST CHAR8 **)&SignerInfo.SigAlgIdentifier.p, &SignerInfo.SigAlgIdentifier.len);
571 if (Ret != 0) {
572 Status = FALSE;
573 goto Cleanup;
574 }
575 }
576
577 SignerInfo.Serial = ((mbedtls_x509_crt *)SignCert)->serial;
578 SignerInfo.IssuerRaw = ((mbedtls_x509_crt *)SignCert)->issuer_raw;
579 Pkcs7.SignedData.SignerInfos = SignerInfo;
580
581 Buffer = AllocateZeroPool (BufferSize);
582 if (Buffer == NULL) {
583 Status = FALSE;
584 goto Cleanup;
585 }
586
587 Ptr = Buffer + BufferSize;
588 Len = MbedTlsPkcs7WriteDer (&Ptr, Buffer, &Pkcs7);
589
591 while (Len == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) {
592 BufferSize = BufferSize * 2;
593 Ptr = Buffer + BufferSize;
594 FreePool (Buffer);
595 Buffer = AllocateZeroPool (BufferSize);
596 if (Buffer == NULL) {
597 Status = FALSE;
598 goto Cleanup;
599 }
600
601 Ptr = Buffer + BufferSize;
602 Len = MbedTlsPkcs7WriteDer (&Ptr, Buffer, &Pkcs7);
603 }
604
605 if (Len <= 0) {
606 Status = FALSE;
607 goto Cleanup;
608 }
609
610 *SignedData = AllocateZeroPool (Len);
611 if (*SignedData == NULL) {
612 Status = FALSE;
613 goto Cleanup;
614 }
615
616 *SignedDataSize = Len;
617 CopyMem (*SignedData, Ptr, Len);
618 Status = TRUE;
619
620Cleanup:
621 if (&Pkey != NULL) {
622 mbedtls_pk_free (&Pkey);
623 }
624
625 if (NewPrivateKey != NULL) {
626 memset (NewPrivateKey, 0, PrivateKeySize);
627 FreePool (NewPrivateKey);
628 }
629
630 if (Buffer != NULL) {
631 memset (Buffer, 0, BufferSize);
632 FreePool (Buffer);
633 }
634
635 return Status;
636}
UINT64 UINTN
INT64 INTN
#define SHA256_DIGEST_SIZE
Definition: BaseCryptLib.h:44
BOOLEAN EFIAPI Sha256HashAll(IN CONST VOID *Data, IN UINTN DataSize, OUT UINT8 *HashValue)
Definition: CryptSha256.c:199
INT32 MbedtlsRand(VOID *RngState, UINT8 *Output, UINTN Len)
Definition: CryptRand.c:103
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
BOOLEAN EFIAPI Pkcs7Sign(IN CONST UINT8 *PrivateKey, IN UINTN PrivateKeySize, IN CONST UINT8 *KeyPassword, IN UINT8 *InData, IN UINTN InDataSize, IN UINT8 *SignCert, IN UINT8 *OtherCerts OPTIONAL, OUT UINT8 **SignedData, OUT UINTN *SignedDataSize)
STATIC INT32 MbedTlsPkcs7WriteDer(UINT8 **Ptr, UINT8 *Start, MbedtlsPkcs7 *Pkcs7)
STATIC INT32 MbedTlsPkcs7WriteInt(UINT8 **Ptr, UINT8 *Start, UINT8 *SerialRaw, INTN SerialRawLen)
STATIC INT32 MbedTlsPkcs7WriteDigestAlgorithmSet(UINT8 **Ptr, UINT8 *Start, mbedtls_md_type_t *DigestTypes, INTN Count)
STATIC INT32 MbedTlsPkcs7WriteSignerInfo(UINT8 **Ptr, UINT8 *Start, MbedtlsPkcs7SignerInfo *SignerInfo)
#define MAX_SIGNATURE_SIZE
STATIC INT32 MbedTlsPkcs7WriteCertificates(UINT8 **Ptr, UINT8 *Start, mbedtls_x509_crt *Cert, mbedtls_x509_crt *OtherCerts)
STATIC INT32 MbedTlsPkcs7WriteIssuerAndSerialNumber(UINT8 **Ptr, UINT8 *Start, UINT8 *Serial, INTN SerialLen, UINT8 *IssuerRaw, INTN IssuerRawLen)
STATIC INT32 MbedTlsPkcs7WriteContentInfo(UINT8 **Ptr, UINT8 *Start, UINT8 *Content, INTN ContentLen)
STATIC INT32 MbedTlsPkcs7WriteDigestAlgorithm(UINT8 **Ptr, UINT8 *Start, mbedtls_md_type_t DigestType)
STATIC INT32 MbedTlsPkcs7WriteSignersInfoSet(UINT8 **Ptr, UINT8 *Start, MbedtlsPkcs7SignerInfo *SignersSet)