TianoCore EDK2 master
Loading...
Searching...
No Matches
CryptAuthenticode.c
Go to the documentation of this file.
1
10#include "InternalCryptLib.h"
11#include <mbedtls/pkcs7.h>
12
13//
14// OID ASN.1 Value for SPC_INDIRECT_DATA_OBJID
15//
16GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mSpcIndirectOidValue[] = {
17 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x04
18};
19
40BOOLEAN
41EFIAPI
43 IN CONST UINT8 *AuthData,
44 IN UINTN DataSize,
45 IN CONST UINT8 *TrustedCert,
46 IN UINTN CertSize,
47 IN CONST UINT8 *ImageHash,
48 IN UINTN HashSize
49 )
50{
51 BOOLEAN Status;
52 CONST UINT8 *OrigAuthData;
53 UINT8 *SpcIndirectDataContent;
54 UINT8 Asn1Byte;
55 UINTN ContentSize;
56 CONST UINT8 *SpcIndirectDataOid;
57 UINT8 *Ptr;
58 UINT8 *End;
59 INT32 Len;
60 UINTN ObjLen;
61
62 OrigAuthData = AuthData;
63
64 //
65 // Check input parameters.
66 //
67 if ((AuthData == NULL) || (TrustedCert == NULL) || (ImageHash == NULL)) {
68 return FALSE;
69 }
70
71 if ((DataSize > INT_MAX) || (CertSize > INT_MAX) || (HashSize > INT_MAX)) {
72 return FALSE;
73 }
74
75 if (DataSize <= HashSize) {
76 return FALSE;
77 }
78
79 Ptr = (UINT8 *)(UINTN)AuthData;
80 Len = (UINT32)DataSize;
81 End = Ptr + Len;
82
83 // ContentInfo
84 if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
85 return FALSE;
86 }
87
88 // ContentType
89 if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
90 return FALSE;
91 }
92
93 Ptr += ObjLen;
94 // content
95 if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
96 return FALSE;
97 }
98
99 End = Ptr + ObjLen;
100 // signedData
101 if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
102 return FALSE;
103 }
104
105 // version
106 if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
107 return FALSE;
108 }
109
110 Ptr += ObjLen;
111 // digestAlgo
112 if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
113 return FALSE;
114 }
115
116 Ptr += ObjLen;
117
118 // encapContentInfo
119 if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
120 return FALSE;
121 }
122
123 End = Ptr + ObjLen;
124 // eContentType
125 if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
126 return FALSE;
127 }
128
129 Status = FALSE;
130
131 SpcIndirectDataOid = Ptr;
132 if ((ObjLen != sizeof (mSpcIndirectOidValue)) ||
133 (CompareMem (
134 SpcIndirectDataOid,
135 mSpcIndirectOidValue,
136 sizeof (mSpcIndirectOidValue)
137 ) != 0))
138 {
139 //
140 // Un-matched SPC_INDIRECT_DATA_OBJID.
141 //
142 goto _Exit;
143 }
144
145 Ptr += ObjLen;
146 // eContent
147 if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
148 return FALSE;
149 }
150
151 SpcIndirectDataContent = Ptr;
152
153 //
154 // Retrieve the SEQUENCE data size from ASN.1-encoded SpcIndirectDataContent.
155 //
156 Asn1Byte = *(SpcIndirectDataContent + 1);
157
158 if ((Asn1Byte & 0x80) == 0) {
159 //
160 // Short Form of Length Encoding (Length < 128)
161 //
162 ContentSize = (UINTN)(Asn1Byte & 0x7F);
163 //
164 // Skip the SEQUENCE Tag;
165 //
166 SpcIndirectDataContent += 2;
167 } else if ((Asn1Byte & 0x81) == 0x81) {
168 //
169 // Long Form of Length Encoding (128 <= Length < 255, Single Octet)
170 //
171 ContentSize = (UINTN)(*(UINT8 *)(SpcIndirectDataContent + 2));
172 //
173 // Skip the SEQUENCE Tag;
174 //
175 SpcIndirectDataContent += 3;
176 } else if ((Asn1Byte & 0x82) == 0x82) {
177 //
178 // Long Form of Length Encoding (Length > 255, Two Octet)
179 //
180 ContentSize = (UINTN)(*(UINT8 *)(SpcIndirectDataContent + 2));
181 ContentSize = (ContentSize << 8) + (UINTN)(*(UINT8 *)(SpcIndirectDataContent + 3));
182 //
183 // Skip the SEQUENCE Tag;
184 //
185 SpcIndirectDataContent += 4;
186 } else {
187 goto _Exit;
188 }
189
190 //
191 // Compare the original file hash value to the digest retrieve from SpcIndirectDataContent
192 // defined in Authenticode
193 // NOTE: Need to double-check HashLength here!
194 //
195 if (ContentSize < HashSize) {
196 return FALSE;
197 }
198
199 if (CompareMem (SpcIndirectDataContent + ContentSize - HashSize, ImageHash, HashSize) != 0) {
200 //
201 // Un-matched PE/COFF Hash Value
202 //
203 goto _Exit;
204 }
205
206 //
207 // Verifies the PKCS#7 Signed Data in PE/COFF Authenticode Signature
208 //
209 Status = (BOOLEAN)Pkcs7Verify (OrigAuthData, DataSize, TrustedCert, CertSize, SpcIndirectDataContent, ContentSize);
210
211_Exit:
212
213 return Status;
214}
UINT64 UINTN
BOOLEAN EFIAPI Pkcs7Verify(IN CONST UINT8 *P7Data, IN UINTN P7Length, IN CONST UINT8 *TrustedCert, IN UINTN CertLength, IN CONST UINT8 *InData, IN UINTN DataLength)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
BOOLEAN EFIAPI AuthenticodeVerify(IN CONST UINT8 *AuthData, IN UINTN DataSize, IN CONST UINT8 *TrustedCert, IN UINTN CertSize, IN CONST UINT8 *ImageHash, IN UINTN HashSize)