📄 rsa.c
字号:
/* * Licensed Materials - Property of IBM * * trousers - An open source TCG Software Stack * * (C) Copyright International Business Machines Corp. 2004-2006 * *//* * rsa.c - openssl TSS crypto routines * * Kent Yoder <shpedoikal@gmail.com> * */#include <string.h>#include <openssl/evp.h>#include <openssl/err.h>#include <openssl/sha.h>#include <openssl/rsa.h>#include "trousers/tss.h"#include "trousers/trousers.h"#include "trousers_types.h"#include "spi_utils.h"#include "tsplog.h"#ifdef TSS_DEBUG#define DEBUG_print_openssl_errors() \ do { \ ERR_load_crypto_strings(); \ ERR_print_errors_fp(stderr); \ } while (0)#else#define DEBUG_print_openssl_errors()#endif/* * Hopefully this will make the code clearer since * OpenSSL returns 1 on success */#define EVP_SUCCESS 1/* XXX int set to unsigned int values */intTrspi_RSA_Encrypt(unsigned char *dataToEncrypt, /* in */ unsigned int dataToEncryptLen, /* in */ unsigned char *encryptedData, /* out */ unsigned int *encryptedDataLen, /* out */ unsigned char *publicKey, unsigned int keysize){ int rv; unsigned char exp[] = { 0x01, 0x00, 0x01 }; /* 65537 hex */ unsigned char oaepPad[] = "TCPA"; int oaepPadLen = 4; RSA *rsa = RSA_new(); BYTE encodedData[256]; int encodedDataLen; if (rsa == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } /* set the public key value in the OpenSSL object */ rsa->n = BN_bin2bn(publicKey, keysize, rsa->n); /* set the public exponent */ rsa->e = BN_bin2bn(exp, sizeof(exp), rsa->e); if (rsa->n == NULL || rsa->e == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } /* padding constraint for PKCS#1 OAEP padding */ if ((int)dataToEncryptLen >= (RSA_size(rsa) - ((2 * SHA_DIGEST_LENGTH) + 1))) { rv = TSPERR(TSS_E_INTERNAL_ERROR); goto err; } encodedDataLen = MIN(RSA_size(rsa), 256); /* perform our OAEP padding here with custom padding parameter */ rv = RSA_padding_add_PKCS1_OAEP(encodedData, encodedDataLen, dataToEncrypt, dataToEncryptLen, oaepPad, oaepPadLen); if (rv != EVP_SUCCESS) { rv = TSPERR(TSS_E_INTERNAL_ERROR); goto err; } /* call OpenSSL with no additional padding */ rv = RSA_public_encrypt(encodedDataLen, encodedData, encryptedData, rsa, RSA_NO_PADDING); if (rv == -1) { rv = TSPERR(TSS_E_INTERNAL_ERROR); goto err; } /* RSA_public_encrypt returns the size of the encrypted data */ *encryptedDataLen = rv; rv = TSS_SUCCESS; goto out;err: DEBUG_print_openssl_errors();out: if (rsa) RSA_free(rsa); return rv;}TSS_RESULTTrspi_Verify(UINT32 HashType, BYTE *pHash, UINT32 iHashLength, unsigned char *pModulus, int iKeyLength, BYTE *pSignature, UINT32 sig_len){ int rv, nid; unsigned char exp[] = { 0x01, 0x00, 0x01 }; /* The default public exponent for the TPM */ unsigned char buf[256]; RSA *rsa = RSA_new(); if (rsa == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } /* We assume we're verifying data from a TPM, so there are only * two options, SHA1 data and PKCSv1.5 encoded signature data. */ switch (HashType) { case TSS_HASH_SHA1: nid = NID_sha1; break; case TSS_HASH_OTHER: nid = NID_undef; break; default: rv = TSPERR(TSS_E_BAD_PARAMETER); goto out; break; } /* set the public key value in the OpenSSL object */ rsa->n = BN_bin2bn(pModulus, iKeyLength, rsa->n); /* set the public exponent */ rsa->e = BN_bin2bn(exp, sizeof(exp), rsa->e); if (rsa->n == NULL || rsa->e == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } /* if we don't know the structure of the data we're verifying, do a public decrypt * and compare manually. If we know we're looking for a SHA1 hash, allow OpenSSL * to do the work for us. */ if (nid == NID_undef) { rv = RSA_public_decrypt(sig_len, pSignature, buf, rsa, RSA_PKCS1_PADDING); if ((UINT32)rv != iHashLength) { rv = TSPERR(TSS_E_FAIL); goto out; } else if (memcmp(pHash, buf, iHashLength)) { rv = TSPERR(TSS_E_FAIL); goto out; } } else { if ((rv = RSA_verify(nid, pHash, iHashLength, pSignature, sig_len, rsa)) == 0) { rv = TSPERR(TSS_E_FAIL); goto out; } } rv = TSS_SUCCESS; goto out;err: DEBUG_print_openssl_errors();out: if (rsa) RSA_free(rsa); return rv;}intTrspi_RSA_Public_Encrypt(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlen, unsigned char *pubkey, unsigned int pubsize, unsigned int e, int padding){ int rv, e_size = 3; unsigned char exp[] = { 0x01, 0x00, 0x01 }; RSA *rsa = RSA_new(); if (rsa == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } switch (e) { case 0: /* fall through */ case 65537: break; case 17: exp[0] = 17; e_size = 1; break; case 3: exp[0] = 3; e_size = 1; break; default: rv = TSPERR(TSS_E_INTERNAL_ERROR); goto out; break; } switch (padding) { case TR_RSA_PKCS1_OAEP_PADDING: padding = RSA_PKCS1_OAEP_PADDING; break; case TR_RSA_PKCS1_PADDING: padding = RSA_PKCS1_PADDING; break; case TR_RSA_NO_PADDING: padding = RSA_NO_PADDING; break; default: rv = TSPERR(TSS_E_INTERNAL_ERROR); goto out; break; } /* set the public key value in the OpenSSL object */ rsa->n = BN_bin2bn(pubkey, pubsize, rsa->n); /* set the public exponent */ rsa->e = BN_bin2bn(exp, e_size, rsa->e); if (rsa->n == NULL || rsa->e == NULL) { rv = TSPERR(TSS_E_OUTOFMEMORY); goto err; } rv = RSA_public_encrypt(inlen, in, out, rsa, padding); if (rv == -1) { rv = TSPERR(TSS_E_INTERNAL_ERROR); goto err; } /* RSA_public_encrypt returns the size of the encrypted data */ *outlen = rv; rv = TSS_SUCCESS; goto out;err: DEBUG_print_openssl_errors();out: if (rsa) RSA_free(rsa); return rv;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -