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 39typedef struct tdTSS_BLOB { 40 ASN1_INTEGER * structVersion; 41 ASN1_INTEGER * blobType; 42 ASN1_INTEGER * blobLength; 43 ASN1_OCTET_STRING * blob; 44} TSS_BLOB; 45 46OPENSSL_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) 52IMPLEMENT_ASN1_FUNCTIONS(TSS_BLOB) 53 54 55TSS_RESULT 56Tspi_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 189TSS_RESULT 190Tspi_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