Home | History | Annotate | Line # | Download | only in openssl
      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