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@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
Trspi_Hash(UINT32 HashType,UINT32 BufSize,BYTE * Buf,BYTE * Digest)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
Trspi_HashInit(Trspi_HashCtx * ctx,UINT32 HashType)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
Trspi_HashUpdate(Trspi_HashCtx * ctx,UINT32 size,BYTE * data)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
Trspi_HashFinal(Trspi_HashCtx * ctx,BYTE * digest)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
Trspi_HMAC(UINT32 HashType,UINT32 SecretSize,BYTE * Secret,UINT32 BufSize,BYTE * Buf,BYTE * hmacOut)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
Trspi_MGF1(UINT32 alg,UINT32 seedLen,BYTE * seed,UINT32 outLen,BYTE * out)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