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