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. 2004-2006 8 * 9 */ 10 11 /* 12 * hash.c - openssl TSS crypto routines 13 * 14 * Kent Yoder <shpedoikal (at) gmail.com> 15 * 16 */ 17 18 #include <string.h> 19 20 #include <openssl/opensslv.h> 21 #include <openssl/rsa.h> // for some reason the MGF1 prototype is in here 22 #include <openssl/evp.h> 23 #include <openssl/hmac.h> 24 #include <openssl/err.h> 25 #include <openssl/sha.h> 26 27 #include "trousers/tss.h" 28 #include "trousers/trousers.h" 29 #include "trousers_types.h" 30 #include "spi_utils.h" 31 #include "tsplog.h" 32 33 #ifdef TSS_DEBUG 34 #define DEBUG_print_openssl_errors() \ 35 do { \ 36 ERR_load_crypto_strings(); \ 37 ERR_print_errors_fp(stderr); \ 38 } while (0) 39 #else 40 #define DEBUG_print_openssl_errors() 41 #endif 42 43 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL) 44 #define OpenSSL_MGF1(m,mlen,s,slen,md) PKCS1_MGF1(m,mlen,s,slen,md) 45 #else 46 int MGF1(unsigned char *, long, const unsigned char *, long); 47 #define OpenSSL_MGF1(m,mlen,s,slen,md) MGF1(m,mlen,s,slen) 48 #endif 49 50 /* 51 * Hopefully this will make the code clearer since 52 * OpenSSL returns 1 on success 53 */ 54 #define EVP_SUCCESS 1 55 56 TSS_RESULT 57 Trspi_Hash(UINT32 HashType, UINT32 BufSize, BYTE* Buf, BYTE* Digest) 58 { 59 EVP_MD_CTX *md_ctx; 60 unsigned int result_size; 61 int rv; 62 63 md_ctx = EVP_MD_CTX_create(); 64 65 switch (HashType) { 66 case TSS_HASH_SHA1: 67 rv = EVP_DigestInit(md_ctx, EVP_sha1()); 68 break; 69 default: 70 rv = TSPERR(TSS_E_BAD_PARAMETER); 71 goto out; 72 break; 73 } 74 75 if (rv != EVP_SUCCESS) { 76 rv = TSPERR(TSS_E_INTERNAL_ERROR); 77 goto err; 78 } 79 80 rv = EVP_DigestUpdate(md_ctx, Buf, BufSize); 81 if (rv != EVP_SUCCESS) { 82 rv = TSPERR(TSS_E_INTERNAL_ERROR); 83 goto err; 84 } 85 86 result_size = EVP_MD_CTX_size(md_ctx); 87 rv = EVP_DigestFinal(md_ctx, Digest, &result_size); 88 if (rv != EVP_SUCCESS) { 89 rv = TSPERR(TSS_E_INTERNAL_ERROR); 90 goto err; 91 } else 92 rv = TSS_SUCCESS; 93 94 goto out; 95 96 err: 97 DEBUG_print_openssl_errors(); 98 out: 99 EVP_MD_CTX_destroy(md_ctx); 100 return rv; 101 } 102 103 TSS_RESULT 104 Trspi_HashInit(Trspi_HashCtx *ctx, UINT32 HashType) 105 { 106 int rv; 107 EVP_MD *md; 108 109 switch (HashType) { 110 case TSS_HASH_SHA1: 111 md = (EVP_MD *)EVP_sha1(); 112 break; 113 default: 114 return TSPERR(TSS_E_BAD_PARAMETER); 115 break; 116 } 117 118 if ((ctx->ctx = EVP_MD_CTX_create()) == NULL) 119 return TSPERR(TSS_E_OUTOFMEMORY); 120 121 rv = EVP_DigestInit((EVP_MD_CTX *)ctx->ctx, (const EVP_MD *)md); 122 123 if (rv != EVP_SUCCESS) { 124 DEBUG_print_openssl_errors(); 125 return TSPERR(TSS_E_INTERNAL_ERROR); 126 } 127 128 return TSS_SUCCESS; 129 } 130 131 TSS_RESULT 132 Trspi_HashUpdate(Trspi_HashCtx *ctx, UINT32 size, BYTE *data) 133 { 134 int rv; 135 136 if (ctx == NULL || ctx->ctx == NULL) 137 return TSPERR(TSS_E_INTERNAL_ERROR); 138 139 if (data == NULL && size) 140 return TSPERR(TSS_E_BAD_PARAMETER); 141 142 if (!size) 143 return TSS_SUCCESS; 144 145 rv = EVP_DigestUpdate(ctx->ctx, data, size); 146 if (rv != EVP_SUCCESS) { 147 DEBUG_print_openssl_errors(); 148 free(ctx->ctx); 149 ctx->ctx = NULL; 150 return TSPERR(TSS_E_INTERNAL_ERROR); 151 } 152 153 return TSS_SUCCESS; 154 } 155 156 TSS_RESULT 157 Trspi_HashFinal(Trspi_HashCtx *ctx, BYTE *digest) 158 { 159 int rv; 160 UINT32 result_size; 161 162 if (ctx == NULL || ctx->ctx == NULL) 163 return TSPERR(TSS_E_INTERNAL_ERROR); 164 165 result_size = EVP_MD_CTX_size((EVP_MD_CTX *)ctx->ctx); 166 rv = EVP_DigestFinal(ctx->ctx, digest, &result_size); 167 if (rv != EVP_SUCCESS) 168 return TSPERR(TSS_E_INTERNAL_ERROR); 169 170 free(ctx->ctx); 171 ctx->ctx = NULL; 172 173 return TSS_SUCCESS; 174 } 175 176 UINT32 177 Trspi_HMAC(UINT32 HashType, UINT32 SecretSize, BYTE* Secret, UINT32 BufSize, BYTE* Buf, BYTE* hmacOut) 178 { 179 /*HMAC_CTX hmac_ctx;*/ 180 const EVP_MD *md; 181 unsigned int len; 182 int rv = TSS_SUCCESS; 183 184 switch (HashType) { 185 case TSS_HASH_SHA1: 186 md = EVP_sha1(); 187 break; 188 default: 189 rv = TSPERR(TSS_E_BAD_PARAMETER); 190 goto out; 191 break; 192 } 193 194 len = EVP_MD_size(md); 195 196 HMAC(md, Secret, SecretSize, Buf, BufSize, hmacOut, &len); 197 out: 198 return rv; 199 } 200 201 TSS_RESULT 202 Trspi_MGF1(UINT32 alg, UINT32 seedLen, BYTE *seed, UINT32 outLen, BYTE *out) 203 { 204 const EVP_MD *md; 205 long olen = outLen, slen = seedLen; 206 int rv = TSS_SUCCESS; 207 208 switch (alg) { 209 case TSS_HASH_SHA1: 210 md = EVP_sha1(); 211 break; 212 default: 213 rv = TSPERR(TSS_E_BAD_PARAMETER); 214 goto out; 215 break; 216 } 217 218 rv = OpenSSL_MGF1(out, olen, seed, slen, md); 219 out: 220 return rv; 221 } 222