1
2 /*
3 * Licensed Materials - Property of IBM
4 *
5 * trousers - An open source TCG Software Stack
6 *
7 * (C) Copyright International Business Machines Corp. 2007
8 *
9 */
10
11
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15
16 #include <openssl/asn1.h>
17 #include <openssl/asn1t.h>
18
19 #ifndef TSS_BUILD_ASN1_OPENSSL
20 #include <arpa/inet.h>
21 #endif
22
23 #include "trousers/tss.h"
24 #include "trousers/trousers.h"
25 #include "trousers_types.h"
26 #include "tsplog.h"
27
28 #define TSS_OPENSSL_ASN1_ERROR (0xffffffff)
29
30 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
31 #define OPENSSL_COMPAT_CONST const
32 #else
33 #define OPENSSL_COMPAT_CONST
34 #endif
35
36 #define OPENSSL_COMPAT_ASN1_SEQUENCE(tname) \
37 static const ASN1_TEMPLATE tname##_seq_tt[]
38
39 typedef struct tdTSS_BLOB {
40 ASN1_INTEGER * structVersion;
41 ASN1_INTEGER * blobType;
42 ASN1_INTEGER * blobLength;
43 ASN1_OCTET_STRING * blob;
44 } TSS_BLOB;
45
46 OPENSSL_COMPAT_ASN1_SEQUENCE(TSS_BLOB) = {
47 ASN1_SIMPLE(TSS_BLOB, structVersion, ASN1_INTEGER),
48 ASN1_SIMPLE(TSS_BLOB, blobType, ASN1_INTEGER),
49 ASN1_SIMPLE(TSS_BLOB, blobLength, ASN1_INTEGER),
50 ASN1_SIMPLE(TSS_BLOB, blob, ASN1_OCTET_STRING)
51 } ASN1_SEQUENCE_END(TSS_BLOB)
52 IMPLEMENT_ASN1_FUNCTIONS(TSS_BLOB)
53
54
55 TSS_RESULT
56 Tspi_EncodeDER_TssBlob(UINT32 rawBlobSize, /* in */
57 BYTE *rawBlob, /* in */
58 UINT32 blobType, /* in */
59 UINT32 *derBlobSize, /* in/out */
60 BYTE *derBlob) /* out */
61 {
62 #ifdef TSS_BUILD_ASN1_OPENSSL
63 TSS_BLOB *tssBlob = NULL;
64 #endif
65 BYTE *encBlob = NULL;
66 UINT32 encBlobLen;
67
68 if ((rawBlobSize == 0) || (rawBlob == NULL))
69 return TSPERR(TSS_E_BAD_PARAMETER);
70
71 if ((blobType < TSS_BLOB_TYPE_KEY) || (blobType > TSS_BLOB_TYPE_CMK_BYTE_STREAM))
72 return TSPERR(TSS_E_BAD_PARAMETER);
73
74 if ((*derBlobSize != 0) && (derBlob == NULL))
75 return TSPERR(TSS_E_BAD_PARAMETER);
76
77 /* The TSS working group has stated that the ASN1 encoding will be done in a
78 * specific way that generates an ASN1 encoding that is exactly 20 bytes
79 * larger than the blob being encoded.
80 *
81 * OpenSSL uses the smallest number of bytes possible to encode and object
82 * and as a result cannot be used to perform the encoding. The encoding
83 * must be done manually.
84 *
85 * The 20 byte fixed header will result in issues for objects greater than
86 * 2^16 in size since some fields are now limited to 16-bit lengths.
87 */
88
89 #ifdef TSS_BUILD_ASN1_OPENSSL
90 tssBlob = TSS_BLOB_new();
91 if (!tssBlob)
92 return TSPERR(TSS_E_OUTOFMEMORY);
93
94 if (ASN1_INTEGER_set(tssBlob->structVersion, TSS_BLOB_STRUCT_VERSION) == 0) {
95 TSS_BLOB_free(tssBlob);
96 return TSPERR(TSS_E_OUTOFMEMORY);
97 }
98
99 if (ASN1_INTEGER_set(tssBlob->blobType, blobType) == 0) {
100 TSS_BLOB_free(tssBlob);
101 return TSPERR(TSS_E_OUTOFMEMORY);
102 }
103
104 if (ASN1_INTEGER_set(tssBlob->blobLength, rawBlobSize) == 0) {
105 TSS_BLOB_free(tssBlob);
106 return TSPERR(TSS_E_OUTOFMEMORY);
107 }
108
109 if (ASN1_OCTET_STRING_set(tssBlob->blob, rawBlob, rawBlobSize) == 0) {
110 TSS_BLOB_free(tssBlob);
111 return TSPERR(TSS_E_OUTOFMEMORY);
112 }
113
114 encBlobLen = i2d_TSS_BLOB(tssBlob, &encBlob);
115 if (encBlobLen <= 0) {
116 TSS_BLOB_free(tssBlob);
117 return TSPERR(TSS_E_INTERNAL_ERROR);
118 }
119
120 if (*derBlobSize != 0) {
121 if (encBlobLen <= *derBlobSize) {
122 memcpy(derBlob, encBlob, encBlobLen);
123 }
124 else {
125 OPENSSL_free(encBlob);
126 TSS_BLOB_free(tssBlob);
127 return TSPERR(TSS_E_BAD_PARAMETER);
128 }
129 }
130
131 *derBlobSize = encBlobLen;
132
133 OPENSSL_free(encBlob);
134 TSS_BLOB_free(tssBlob);
135 #else
136 if ((rawBlobSize + 16) > UINT16_MAX)
137 return TSPERR(TSS_E_INTERNAL_ERROR);
138
139 encBlobLen = rawBlobSize + 20;
140
141 if (*derBlobSize != 0) {
142 if (encBlobLen <= *derBlobSize) {
143 UINT16 *pShort;
144 UINT32 *pLong;
145
146 encBlob = derBlob;
147 encBlob[0] = 0x30; /* Sequence tag */
148 encBlob[1] = 0x82; /* Length in the two octets that follow */
149 encBlob += 2;
150 pShort = (UINT16 *)encBlob;
151 *pShort = htons(rawBlobSize + 16);
152 encBlob += sizeof(UINT16);
153
154 encBlob[0] = 0x02; /* Integer tag */
155 encBlob[1] = 0x01; /* Length is one */
156 encBlob[2] = (BYTE)TSS_BLOB_STRUCT_VERSION;
157 encBlob += 3;
158
159 encBlob[0] = 0x02; /* Integer tag */
160 encBlob[1] = 0x01; /* Length is one */
161 encBlob[2] = (BYTE)blobType;
162 encBlob += 3;
163
164 encBlob[0] = 0x02; /* Integer tag */
165 encBlob[1] = 0x04; /* Length is four */
166 encBlob += 2;
167 pLong = (UINT32 *)encBlob;
168 *pLong = htonl(rawBlobSize);
169 encBlob += sizeof(UINT32);
170
171 encBlob[0] = 0x04; /* Octet string tag */
172 encBlob[1] = 0x82; /* Length in the two octets that follow */
173 encBlob += 2;
174 pShort = (UINT16 *)encBlob;
175 *pShort = htons(rawBlobSize);
176 encBlob += sizeof(UINT16);
177 memcpy(encBlob, rawBlob, rawBlobSize);
178 }
179 else
180 return TSPERR(TSS_E_BAD_PARAMETER);
181 }
182
183 *derBlobSize = encBlobLen;
184 #endif
185
186 return TSS_SUCCESS;
187 }
188
189 TSS_RESULT
Tspi_DecodeBER_TssBlob(UINT32 berBlobSize,BYTE * berBlob,UINT32 * blobType,UINT32 * rawBlobSize,BYTE * rawBlob)190 Tspi_DecodeBER_TssBlob(UINT32 berBlobSize, /* in */
191 BYTE *berBlob, /* in */
192 UINT32 *blobType, /* out */
193 UINT32 *rawBlobSize, /* in/out */
194 BYTE *rawBlob) /* out */
195 {
196 TSS_BLOB *tssBlob = NULL;
197 OPENSSL_COMPAT_CONST BYTE *encBlob = berBlob;
198
199 UINT32 encBlobLen = berBlobSize;
200 UINT32 decStructVersion, decBlobType, decBlobSize;
201
202 if ((berBlobSize == 0) || (berBlob == NULL))
203 return TSPERR(TSS_E_BAD_PARAMETER);
204
205 if ((*rawBlobSize != 0) && (rawBlob == NULL))
206 return TSPERR(TSS_E_BAD_PARAMETER);
207
208 tssBlob = d2i_TSS_BLOB(NULL, &encBlob, encBlobLen);
209 if (!tssBlob)
210 return TSPERR(TSS_E_INTERNAL_ERROR);
211
212 decStructVersion = ASN1_INTEGER_get(tssBlob->structVersion);
213 if (decStructVersion == TSS_OPENSSL_ASN1_ERROR) {
214 TSS_BLOB_free(tssBlob);
215 return TSPERR(TSS_E_INTERNAL_ERROR);
216 }
217 if (decStructVersion > TSS_BLOB_STRUCT_VERSION) {
218 TSS_BLOB_free(tssBlob);
219 return TSPERR(TSS_E_BAD_PARAMETER);
220 }
221
222 decBlobType = ASN1_INTEGER_get(tssBlob->blobType);
223 if (decBlobType == TSS_OPENSSL_ASN1_ERROR) {
224 TSS_BLOB_free(tssBlob);
225 return TSPERR(TSS_E_INTERNAL_ERROR);
226 }
227 if ((decBlobType < TSS_BLOB_TYPE_KEY) || (decBlobType > TSS_BLOB_TYPE_CMK_BYTE_STREAM)) {
228 TSS_BLOB_free(tssBlob);
229 return TSPERR(TSS_E_BAD_PARAMETER);
230 }
231
232 decBlobSize = ASN1_INTEGER_get(tssBlob->blobLength);
233 if (decBlobSize == TSS_OPENSSL_ASN1_ERROR) {
234 TSS_BLOB_free(tssBlob);
235 return TSPERR(TSS_E_INTERNAL_ERROR);
236 }
237
238 if (*rawBlobSize != 0) {
239 if (decBlobSize <= *rawBlobSize) {
240 memcpy(rawBlob, tssBlob->blob->data, decBlobSize);
241 }
242 else {
243 TSS_BLOB_free(tssBlob);
244 return TSPERR(TSS_E_BAD_PARAMETER);
245 }
246 }
247
248 *rawBlobSize = decBlobSize;
249 *blobType = decBlobType;
250
251 TSS_BLOB_free(tssBlob);
252
253 return TSS_SUCCESS;
254 }
255
256