1 /*############################################################################
2 # Copyright 2016-2017 Intel Corporation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 ############################################################################*/
16 /// Implementation of 1.1 issuer material file parsing utilities.
17 /*!
18 * \file
19 */
20 #include "epid/common/1.1/file_parser.h"
21 #include <string.h>
22
23 #include "epid/common/math/ecdsa.h"
24 #include "epid/common/src/file_parser-internal.h"
25 #include "epid/common/src/memory.h"
26
27 /// Intel(R) EPID 1.1 Group Public Key binary format
28 typedef struct Epid11GroupPubKeyCertificate {
29 EpidFileHeader header; ///< Intel(R) EPID binary file header
30 Epid11GroupId gid; ///< group ID
31 Epid11G1ElemStr h1; ///< an element in G1
32 Epid11G1ElemStr h2; ///< an element in G1
33 Epid11G2ElemStr w; ///< an element in G2
34 EcdsaSignature signature; ///< ECDSA Signature on SHA-256 of above values
35 } Epid11GroupPubKeyCertificate;
36
37 /// Parse a file with a revocation list of any type
Epid11ParseRlFile(void const * buf,size_t len,EpidCaCertificate const * cert,void * rl,size_t * rl_len,EpidFileType file_type)38 static EpidStatus Epid11ParseRlFile(void const* buf, size_t len,
39 EpidCaCertificate const* cert, void* rl,
40 size_t* rl_len, EpidFileType file_type) {
41 size_t min_rl_file_size = 0;
42 size_t empty_rl_size = 0;
43 size_t rl_entry_size = 0;
44 EpidStatus result = kEpidErr;
45 EpidFileHeader const* file_header = (EpidFileHeader*)buf;
46 void const* buf_rl =
47 (void const*)((unsigned char*)buf + sizeof(EpidFileHeader));
48 size_t buf_rl_len = 0;
49 EcdsaSignature const* signature = NULL;
50
51 if (!buf || !cert || !rl_len) return kEpidBadArgErr;
52
53 switch (file_type) {
54 case kPrivRlFile:
55 empty_rl_size = sizeof(Epid11PrivRl) - sizeof(((Epid11PrivRl*)0)->f[0]);
56 rl_entry_size = sizeof(((Epid11PrivRl*)0)->f[0]);
57 min_rl_file_size = sizeof(EpidFileHeader) + sizeof(Epid11PrivRl) -
58 sizeof(((Epid11PrivRl*)0)->f[0]) +
59 sizeof(EcdsaSignature);
60 break;
61 case kSigRlFile:
62 empty_rl_size = sizeof(Epid11SigRl) - sizeof(((Epid11SigRl*)0)->bk[0]);
63 rl_entry_size = sizeof(((Epid11SigRl*)0)->bk[0]);
64 min_rl_file_size = sizeof(EpidFileHeader) + sizeof(Epid11SigRl) -
65 sizeof(((Epid11SigRl*)0)->bk[0]) +
66 sizeof(EcdsaSignature);
67 break;
68 case kGroupRlFile:
69 empty_rl_size =
70 sizeof(Epid11GroupRl) - sizeof(((Epid11GroupRl*)0)->gid[0]);
71 rl_entry_size = sizeof(((Epid11GroupRl*)0)->gid[0]);
72 min_rl_file_size = sizeof(EpidFileHeader) + sizeof(Epid11GroupRl) -
73 sizeof(((Epid11GroupRl*)0)->gid[0]) +
74 sizeof(EcdsaSignature);
75 break;
76 default:
77 return kEpidErr;
78 }
79
80 if (min_rl_file_size > len) return kEpidBadArgErr;
81
82 // Verify that Intel(R) EPID file header in the buffer is correct
83 if (0 != memcmp(&file_header->epid_version, &kEpidVersionCode[kEpid1x],
84 sizeof(kEpidVersionCode[kEpid1x]))) {
85 return kEpidBadArgErr;
86 }
87 if (0 != memcmp(&file_header->file_type, &kEpidFileTypeCode[file_type],
88 sizeof(file_header->file_type))) {
89 return kEpidBadArgErr;
90 }
91
92 // Verify that CA certificate is correct
93 result = EpidVerifyCaCertificate(cert);
94 if (kEpidNoErr != result) return result;
95
96 // Verify that RL in file buffer contains of integer number of entries
97 buf_rl_len = len - sizeof(EpidFileHeader) - sizeof(EcdsaSignature);
98 if (0 != ((buf_rl_len - empty_rl_size) % rl_entry_size)) {
99 return kEpidBadArgErr;
100 }
101
102 signature =
103 (EcdsaSignature*)((unsigned char*)buf + len - sizeof(EcdsaSignature));
104 // Authenticate signature for buffer
105 result = EcdsaVerifyBuffer(buf, len - sizeof(EcdsaSignature),
106 (EcdsaPublicKey*)&cert->pubkey, signature);
107 if (kEpidSigValid != result) return result;
108
109 buf_rl_len = len - sizeof(EpidFileHeader) - sizeof(EcdsaSignature);
110
111 // If pointer to output buffer is NULL it should return required size of RL
112 if (!rl) {
113 *rl_len = buf_rl_len;
114 return kEpidNoErr;
115 }
116
117 if (*rl_len < buf_rl_len) return kEpidBadArgErr;
118 *rl_len = buf_rl_len;
119
120 // Copy revocation list from file buffer to output
121 // Memory copy is used to copy a revocation list of variable length
122 if (0 != memcpy_S(rl, *rl_len, buf_rl, buf_rl_len)) return kEpidBadArgErr;
123
124 return kEpidNoErr;
125 }
126
Epid11ParseGroupPubKeyFile(void const * buf,size_t len,EpidCaCertificate const * cert,Epid11GroupPubKey * pubkey)127 EpidStatus Epid11ParseGroupPubKeyFile(void const* buf, size_t len,
128 EpidCaCertificate const* cert,
129 Epid11GroupPubKey* pubkey) {
130 EpidStatus result = kEpidErr;
131 Epid11GroupPubKeyCertificate* buf_pubkey = (Epid11GroupPubKeyCertificate*)buf;
132
133 if (!buf || !cert || !pubkey) {
134 return kEpidBadArgErr;
135 }
136
137 if (len == 0 || len % sizeof(Epid11GroupPubKeyCertificate) != 0) {
138 return kEpidBadArgErr;
139 }
140
141 // Verify that Intel(R) EPID file header in the buffer is correct
142 if (0 != memcmp(&buf_pubkey->header.epid_version, &kEpidVersionCode[kEpid1x],
143 sizeof(buf_pubkey->header.epid_version))) {
144 return kEpidBadArgErr;
145 }
146 if (0 != memcmp(&buf_pubkey->header.file_type,
147 &kEpidFileTypeCode[kGroupPubKeyFile],
148 sizeof(buf_pubkey->header.file_type))) {
149 return kEpidBadArgErr;
150 }
151
152 // Verify that CA certificate is correct
153 result = EpidVerifyCaCertificate(cert);
154 if (kEpidNoErr != result) return result;
155
156 // Authenticate signature for buffer
157 result = EcdsaVerifyBuffer(
158 buf_pubkey, sizeof(Epid11GroupPubKeyCertificate) - sizeof(EcdsaSignature),
159 (EcdsaPublicKey*)&cert->pubkey, &buf_pubkey->signature);
160 if (kEpidSigValid != result) return result;
161
162 // Copy group public key from the buffer to output
163 pubkey->gid = buf_pubkey->gid;
164 pubkey->h1 = buf_pubkey->h1;
165 pubkey->h2 = buf_pubkey->h2;
166 pubkey->w = buf_pubkey->w;
167
168 return kEpidNoErr;
169 }
170
Epid11ParsePrivRlFile(void const * buf,size_t len,EpidCaCertificate const * cert,Epid11PrivRl * rl,size_t * rl_len)171 EpidStatus Epid11ParsePrivRlFile(void const* buf, size_t len,
172 EpidCaCertificate const* cert,
173 Epid11PrivRl* rl, size_t* rl_len) {
174 return Epid11ParseRlFile(buf, len, cert, rl, rl_len, kPrivRlFile);
175 }
176
Epid11ParseSigRlFile(void const * buf,size_t len,EpidCaCertificate const * cert,Epid11SigRl * rl,size_t * rl_len)177 EpidStatus Epid11ParseSigRlFile(void const* buf, size_t len,
178 EpidCaCertificate const* cert, Epid11SigRl* rl,
179 size_t* rl_len) {
180 return Epid11ParseRlFile(buf, len, cert, rl, rl_len, kSigRlFile);
181 }
182
Epid11ParseGroupRlFile(void const * buf,size_t len,EpidCaCertificate const * cert,Epid11GroupRl * rl,size_t * rl_len)183 EpidStatus Epid11ParseGroupRlFile(void const* buf, size_t len,
184 EpidCaCertificate const* cert,
185 Epid11GroupRl* rl, size_t* rl_len) {
186 return Epid11ParseRlFile(buf, len, cert, rl, rl_len, kGroupRlFile);
187 }
188