• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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