diff options
Diffstat (limited to 'main/openssl')
5 files changed, 1163 insertions, 824 deletions
diff --git a/main/openssl/0001-crypto-hmac-support-EVP_MD_CTX_FLAG_ONESHOT-and-set-.patch b/main/openssl/0001-crypto-hmac-support-EVP_MD_CTX_FLAG_ONESHOT-and-set-.patch new file mode 100644 index 000000000..6033afc4e --- /dev/null +++ b/main/openssl/0001-crypto-hmac-support-EVP_MD_CTX_FLAG_ONESHOT-and-set-.patch @@ -0,0 +1,80 @@ +From 8290b2ced17ee3d0e52345180ef4fc6d79bc0751 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> +Date: Fri, 4 Jun 2010 09:48:39 +0300 +Subject: [PATCH 1/3] crypto/hmac: support EVP_MD_CTX_FLAG_ONESHOT and set it properly + +Some engines (namely VIA C7 Padlock) work only if EVP_MD_CTX_FLAG_ONESHOT +is set before final update. This is because some crypto accelerators cannot +perform non-finalizing transform of the digest. + +The usage of EVP_MD_CTX_FLAG_ONESHOT is used semantically slightly +differently here. It is set before the final EVP_DigestUpdate call, not +necessarily before EVP_DigestInit call. This will not cause any problems +though. +--- + crypto/hmac/hmac.c | 14 +++++++++++--- + 1 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c +index cbc1c76..a75a35d 100644 +--- a/crypto/hmac/hmac.c ++++ b/crypto/hmac/hmac.c +@@ -68,6 +68,7 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + { + int i,j,reset=0; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; ++ unsigned long flags; + + if (md != NULL) + { +@@ -84,6 +85,7 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + OPENSSL_assert(j <= (int)sizeof(ctx->key)); + if (j < len) + { ++ M_EVP_MD_CTX_set_flags(&ctx->md_ctx, EVP_MD_CTX_FLAG_ONESHOT); + EVP_DigestInit_ex(&ctx->md_ctx,md, impl); + EVP_DigestUpdate(&ctx->md_ctx,key,len); + EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key, +@@ -104,13 +106,18 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + { + for (i=0; i<HMAC_MAX_MD_CBLOCK; i++) + pad[i]=0x36^ctx->key[i]; ++ flags = M_EVP_MD_CTX_test_flags(&ctx->i_ctx, EVP_MD_CTX_FLAG_ONESHOT); ++ M_EVP_MD_CTX_clear_flags(&ctx->i_ctx, EVP_MD_CTX_FLAG_ONESHOT); + EVP_DigestInit_ex(&ctx->i_ctx,md, impl); + EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md)); ++ M_EVP_MD_CTX_set_flags(&ctx->i_ctx, flags); + + for (i=0; i<HMAC_MAX_MD_CBLOCK; i++) + pad[i]=0x5c^ctx->key[i]; ++ M_EVP_MD_CTX_clear_flags(&ctx->o_ctx, EVP_MD_CTX_FLAG_ONESHOT); + EVP_DigestInit_ex(&ctx->o_ctx,md, impl); + EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md)); ++ M_EVP_MD_CTX_set_flags(&ctx->o_ctx, EVP_MD_CTX_FLAG_ONESHOT); + } + EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx); + } +@@ -166,7 +173,8 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + + if (md == NULL) md=m; + HMAC_CTX_init(&c); +- HMAC_Init(&c,key,key_len,evp_md); ++ HMAC_CTX_set_flags(&c, EVP_MD_CTX_FLAG_ONESHOT); ++ HMAC_Init_ex(&c,key,key_len,evp_md,NULL); + HMAC_Update(&c,d,n); + HMAC_Final(&c,md,md_len); + HMAC_CTX_cleanup(&c); +@@ -176,8 +184,8 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) + { + EVP_MD_CTX_set_flags(&ctx->i_ctx, flags); +- EVP_MD_CTX_set_flags(&ctx->o_ctx, flags); +- EVP_MD_CTX_set_flags(&ctx->md_ctx, flags); ++ EVP_MD_CTX_set_flags(&ctx->o_ctx, flags & ~EVP_MD_CTX_FLAG_ONESHOT); ++ EVP_MD_CTX_set_flags(&ctx->md_ctx, flags & ~EVP_MD_CTX_FLAG_ONESHOT); + } + + #endif +-- +1.7.0.4 + diff --git a/main/openssl/0002-apps-speed-fix-digest-speed-measurement-and-add-hmac.patch b/main/openssl/0002-apps-speed-fix-digest-speed-measurement-and-add-hmac.patch new file mode 100644 index 000000000..112e883d7 --- /dev/null +++ b/main/openssl/0002-apps-speed-fix-digest-speed-measurement-and-add-hmac.patch @@ -0,0 +1,373 @@ +From 711ae63d2c715a34b15262b4dd4a48b09f02a400 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> +Date: Thu, 3 Jun 2010 09:02:13 +0300 +Subject: [PATCH 2/3] apps/speed: fix digest speed measurement and add hmac-sha1 test + +Merge the common code of testing digest speed, and make it reuse +existing context. Context creation can be heavy operation, and it's +speed depends on if engine is used or not. As we are measuring the +digest speed, the context creation overhead should not be included +like hmac tests do. + +This also adds test for hmac-sha1 speed. +--- + apps/speed.c | 232 ++++++++++++++++++++++------------------------------------ + 1 files changed, 87 insertions(+), 145 deletions(-) + +diff --git a/apps/speed.c b/apps/speed.c +index 393a7ba..6e375c6 100644 +--- a/apps/speed.c ++++ b/apps/speed.c +@@ -285,7 +285,7 @@ static void print_result(int alg,int run_no,int count,double time_used); + static int do_multi(int multi); + #endif + +-#define ALGOR_NUM 28 ++#define ALGOR_NUM 29 + #define SIZE_NUM 5 + #define RSA_NUM 4 + #define DSA_NUM 3 +@@ -300,9 +300,11 @@ static const char *names[ALGOR_NUM]={ + "aes-128 cbc","aes-192 cbc","aes-256 cbc", + "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc", + "evp","sha256","sha512", +- "aes-128 ige","aes-192 ige","aes-256 ige"}; ++ "aes-128 ige","aes-192 ige","aes-256 ige", "hmac(sha1)" }; + static double results[ALGOR_NUM][SIZE_NUM]; + static int lengths[SIZE_NUM]={16,64,256,1024,8*1024}; ++static unsigned char *buf=NULL,*buf2=NULL; ++static long c[ALGOR_NUM][SIZE_NUM]; + #ifndef OPENSSL_NO_RSA + static double rsa_results[RSA_NUM][2]; + #endif +@@ -478,6 +480,66 @@ static double Time_F(int s) + } + #endif /* if defined(OPENSSL_SYS_NETWARE) */ + ++#ifndef SIGALRM ++#define COND(d) (count < (d)) ++#else ++#define COND(c) (run) ++#endif /* SIGALRM */ ++ ++static void Test_Digest(int digest, const EVP_MD *type) ++{ ++ unsigned char md[EVP_MAX_MD_SIZE]; ++ int j, count; ++ double d=0.0; ++ EVP_MD_CTX ctx; ++ ++ EVP_MD_CTX_init(&ctx); ++ EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT); ++ ++ for (j=0; j<SIZE_NUM; j++) ++ { ++ print_message(names[digest],c[digest][j],lengths[j]); ++ Time_F(START); ++ for (count=0,run=1; COND(c[digest][j]); count++) ++ { ++ EVP_DigestInit_ex(&ctx, type, NULL); ++ EVP_DigestUpdate(&ctx, buf, (unsigned long)lengths[j]); ++ EVP_DigestFinal_ex(&ctx, md, NULL); ++ } ++ d=Time_F(STOP); ++ print_result(digest,j,count,d); ++ } ++ ++ EVP_MD_CTX_cleanup(&ctx); ++} ++ ++static void Test_HMAC(int digest, const EVP_MD *type) ++{ ++ unsigned char md[EVP_MAX_MD_SIZE]; ++ HMAC_CTX hctx; ++ int j, count; ++ double d=0.0; ++ ++ HMAC_CTX_init(&hctx); ++ HMAC_CTX_set_flags(&hctx, EVP_MD_CTX_FLAG_ONESHOT); ++ HMAC_Init_ex(&hctx,(unsigned char *)"This is a key...", ++ 16,type, NULL); ++ ++ for (j=0; j<SIZE_NUM; j++) ++ { ++ print_message(names[digest],c[digest][j],lengths[j]); ++ Time_F(START); ++ for (count=0,run=1; COND(c[digest][j]); count++) ++ { ++ HMAC_Init_ex(&hctx,NULL,0,NULL,NULL); ++ HMAC_Update(&hctx,buf,lengths[j]); ++ HMAC_Final(&hctx,md,NULL); ++ } ++ d=Time_F(STOP); ++ print_result(digest,j,count,d); ++ } ++ HMAC_CTX_cleanup(&hctx); ++} + + #ifndef OPENSSL_NO_ECDH + static const int KDF1_SHA1_len = 20; +@@ -503,7 +565,6 @@ int MAIN(int argc, char **argv) + #ifndef OPENSSL_NO_ENGINE + ENGINE *e = NULL; + #endif +- unsigned char *buf=NULL,*buf2=NULL; + int mret=1; + long count=0,save_count=0; + int i,j,k; +@@ -514,31 +575,6 @@ int MAIN(int argc, char **argv) + unsigned rsa_num; + #endif + unsigned char md[EVP_MAX_MD_SIZE]; +-#ifndef OPENSSL_NO_MD2 +- unsigned char md2[MD2_DIGEST_LENGTH]; +-#endif +-#ifndef OPENSSL_NO_MDC2 +- unsigned char mdc2[MDC2_DIGEST_LENGTH]; +-#endif +-#ifndef OPENSSL_NO_MD4 +- unsigned char md4[MD4_DIGEST_LENGTH]; +-#endif +-#ifndef OPENSSL_NO_MD5 +- unsigned char md5[MD5_DIGEST_LENGTH]; +- unsigned char hmac[MD5_DIGEST_LENGTH]; +-#endif +-#ifndef OPENSSL_NO_SHA +- unsigned char sha[SHA_DIGEST_LENGTH]; +-#ifndef OPENSSL_NO_SHA256 +- unsigned char sha256[SHA256_DIGEST_LENGTH]; +-#endif +-#ifndef OPENSSL_NO_SHA512 +- unsigned char sha512[SHA512_DIGEST_LENGTH]; +-#endif +-#endif +-#ifndef OPENSSL_NO_RIPEMD +- unsigned char rmd160[RIPEMD160_DIGEST_LENGTH]; +-#endif + #ifndef OPENSSL_NO_RC4 + RC4_KEY rc4_ks; + #endif +@@ -635,8 +671,8 @@ int MAIN(int argc, char **argv) + #define D_IGE_128_AES 25 + #define D_IGE_192_AES 26 + #define D_IGE_256_AES 27 ++#define D_HMAC_SHA1 28 + double d=0.0; +- long c[ALGOR_NUM][SIZE_NUM]; + #define R_DSA_512 0 + #define R_DSA_1024 1 + #define R_DSA_2048 2 +@@ -945,6 +981,8 @@ int MAIN(int argc, char **argv) + doit[D_SHA256]=1, + doit[D_SHA512]=1; + else ++ if (strcmp(*argv,"hmac-sha1") == 0) doit[D_HMAC_SHA1]=1; ++ else + #ifndef OPENSSL_NO_SHA256 + if (strcmp(*argv,"sha256") == 0) doit[D_SHA256]=1; + else +@@ -1158,6 +1196,9 @@ int MAIN(int argc, char **argv) + #endif + #ifndef OPENSSL_NO_SHA1 + BIO_printf(bio_err,"sha1 "); ++#ifndef OPENSSL_NO_HMAC ++ BIO_printf(bio_err,"hmac-sha1 "); ++#endif + #endif + #ifndef OPENSSL_NO_SHA256 + BIO_printf(bio_err,"sha256 "); +@@ -1420,6 +1461,7 @@ int MAIN(int argc, char **argv) + c[D_IGE_128_AES][0]=count; + c[D_IGE_192_AES][0]=count; + c[D_IGE_256_AES][0]=count; ++ c[D_HMAC_SHA1][0]=count; + + for (i=1; i<SIZE_NUM; i++) + { +@@ -1432,6 +1474,7 @@ int MAIN(int argc, char **argv) + c[D_RMD160][i]=c[D_RMD160][0]*4*lengths[0]/lengths[i]; + c[D_SHA256][i]=c[D_SHA256][0]*4*lengths[0]/lengths[i]; + c[D_SHA512][i]=c[D_SHA512][0]*4*lengths[0]/lengths[i]; ++ c[D_HMAC_SHA1][i]=c[D_HMAC_SHA1][0]*4*lengths[0]/lengths[i]; + } + for (i=1; i<SIZE_NUM; i++) + { +@@ -1606,160 +1649,59 @@ int MAIN(int argc, char **argv) + } + #endif + +-#define COND(d) (count < (d)) +-#define COUNT(d) (d) + #else + /* not worth fixing */ + # error "You cannot disable DES on systems without SIGALRM." + #endif /* OPENSSL_NO_DES */ +-#else +-#define COND(c) (run) +-#define COUNT(d) (count) ++#else /* SIGALRM */ + signal(SIGALRM,sig_done); +-#endif /* SIGALRM */ ++#endif + + #ifndef OPENSSL_NO_MD2 + if (doit[D_MD2]) +- { +- for (j=0; j<SIZE_NUM; j++) +- { +- print_message(names[D_MD2],c[D_MD2][j],lengths[j]); +- Time_F(START); +- for (count=0,run=1; COND(c[D_MD2][j]); count++) +- EVP_Digest(buf,(unsigned long)lengths[j],&(md2[0]),NULL,EVP_md2(),NULL); +- d=Time_F(STOP); +- print_result(D_MD2,j,count,d); +- } +- } ++ Test_Digest(D_MD2, EVP_md2()); + #endif + #ifndef OPENSSL_NO_MDC2 + if (doit[D_MDC2]) +- { +- for (j=0; j<SIZE_NUM; j++) +- { +- print_message(names[D_MDC2],c[D_MDC2][j],lengths[j]); +- Time_F(START); +- for (count=0,run=1; COND(c[D_MDC2][j]); count++) +- EVP_Digest(buf,(unsigned long)lengths[j],&(mdc2[0]),NULL,EVP_mdc2(),NULL); +- d=Time_F(STOP); +- print_result(D_MDC2,j,count,d); +- } +- } ++ Test_Digest(D_MDC2, EVP_mdc2()); + #endif + + #ifndef OPENSSL_NO_MD4 + if (doit[D_MD4]) +- { +- for (j=0; j<SIZE_NUM; j++) +- { +- print_message(names[D_MD4],c[D_MD4][j],lengths[j]); +- Time_F(START); +- for (count=0,run=1; COND(c[D_MD4][j]); count++) +- EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md4[0]),NULL,EVP_md4(),NULL); +- d=Time_F(STOP); +- print_result(D_MD4,j,count,d); +- } +- } ++ Test_Digest(D_MD4, EVP_md4()); + #endif + + #ifndef OPENSSL_NO_MD5 + if (doit[D_MD5]) +- { +- for (j=0; j<SIZE_NUM; j++) +- { +- print_message(names[D_MD5],c[D_MD5][j],lengths[j]); +- Time_F(START); +- for (count=0,run=1; COND(c[D_MD5][j]); count++) +- EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md5[0]),NULL,EVP_get_digestbyname("md5"),NULL); +- d=Time_F(STOP); +- print_result(D_MD5,j,count,d); +- } +- } ++ Test_Digest(D_MD5, EVP_md5()); + #endif + + #if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_HMAC) + if (doit[D_HMAC]) +- { +- HMAC_CTX hctx; +- +- HMAC_CTX_init(&hctx); +- HMAC_Init_ex(&hctx,(unsigned char *)"This is a key...", +- 16,EVP_md5(), NULL); +- +- for (j=0; j<SIZE_NUM; j++) +- { +- print_message(names[D_HMAC],c[D_HMAC][j],lengths[j]); +- Time_F(START); +- for (count=0,run=1; COND(c[D_HMAC][j]); count++) +- { +- HMAC_Init_ex(&hctx,NULL,0,NULL,NULL); +- HMAC_Update(&hctx,buf,lengths[j]); +- HMAC_Final(&hctx,&(hmac[0]),NULL); +- } +- d=Time_F(STOP); +- print_result(D_HMAC,j,count,d); +- } +- HMAC_CTX_cleanup(&hctx); +- } ++ Test_HMAC(D_HMAC, EVP_md5()); ++#endif ++#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_HMAC) ++ if (doit[D_HMAC_SHA1]) ++ Test_HMAC(D_HMAC_SHA1, EVP_sha1()); + #endif + #ifndef OPENSSL_NO_SHA + if (doit[D_SHA1]) +- { +- for (j=0; j<SIZE_NUM; j++) +- { +- print_message(names[D_SHA1],c[D_SHA1][j],lengths[j]); +- Time_F(START); +- for (count=0,run=1; COND(c[D_SHA1][j]); count++) +- EVP_Digest(buf,(unsigned long)lengths[j],&(sha[0]),NULL,EVP_sha1(),NULL); +- d=Time_F(STOP); +- print_result(D_SHA1,j,count,d); +- } +- } ++ Test_Digest(D_SHA1, EVP_sha1()); + + #ifndef OPENSSL_NO_SHA256 + if (doit[D_SHA256]) +- { +- for (j=0; j<SIZE_NUM; j++) +- { +- print_message(names[D_SHA256],c[D_SHA256][j],lengths[j]); +- Time_F(START); +- for (count=0,run=1; COND(c[D_SHA256][j]); count++) +- SHA256(buf,lengths[j],sha256); +- d=Time_F(STOP); +- print_result(D_SHA256,j,count,d); +- } +- } ++ Test_Digest(D_SHA256, EVP_sha256()); + #endif + + #ifndef OPENSSL_NO_SHA512 + if (doit[D_SHA512]) +- { +- for (j=0; j<SIZE_NUM; j++) +- { +- print_message(names[D_SHA512],c[D_SHA512][j],lengths[j]); +- Time_F(START); +- for (count=0,run=1; COND(c[D_SHA512][j]); count++) +- SHA512(buf,lengths[j],sha512); +- d=Time_F(STOP); +- print_result(D_SHA512,j,count,d); +- } +- } ++ Test_Digest(D_SHA512, EVP_sha512()); + #endif + + #endif + #ifndef OPENSSL_NO_RIPEMD + if (doit[D_RMD160]) +- { +- for (j=0; j<SIZE_NUM; j++) +- { +- print_message(names[D_RMD160],c[D_RMD160][j],lengths[j]); +- Time_F(START); +- for (count=0,run=1; COND(c[D_RMD160][j]); count++) +- EVP_Digest(buf,(unsigned long)lengths[j],&(rmd160[0]),NULL,EVP_ripemd160(),NULL); +- d=Time_F(STOP); +- print_result(D_RMD160,j,count,d); +- } +- } ++ Test_Digest(D_RMD160, EVP_ripemd160()); + #endif + #ifndef OPENSSL_NO_RC4 + if (doit[D_RC4]) +-- +1.7.0.4 + diff --git a/main/openssl/0003-engine-padlock-implement-sha1-sha224-sha256-accelera.patch b/main/openssl/0003-engine-padlock-implement-sha1-sha224-sha256-accelera.patch new file mode 100644 index 000000000..993c9b178 --- /dev/null +++ b/main/openssl/0003-engine-padlock-implement-sha1-sha224-sha256-accelera.patch @@ -0,0 +1,703 @@ +From 9fe6001d9b7a35a12a6a282677c79fd56eeaf99c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> +Date: Fri, 4 Jun 2010 10:00:15 +0300 +Subject: [PATCH 3/3] engine/padlock: implement sha1/sha224/sha256 acceleration + +Limited support for VIA C7 that works only when EVP_MD_CTX_FLAG_ONESHOT +is used appropriately (as done by EVP_Digest, and my previous HMAC patch). + +Full support for VIA Nano including partial transformation. + +Benchmarks from VIA Nano 1.6GHz, done with including the previous HMAC and +apps/speed patches done. From single run, error margin of about 100-200k. + +No padlock + +type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes +sha1 20057.60k 51514.05k 99721.39k 130167.81k 142811.14k +sha256 7757.72k 16907.18k 28937.05k 35181.23k 37568.51k +hmac(sha1) 8582.53k 27644.69k 70402.30k 114602.67k 140167.85k + +With the patch + +sha1 37713.77k 114562.71k 259637.33k 379907.41k 438818.13k +sha256 34262.86k 103233.75k 232476.07k 338386.60k 389860.01k +hmac(sha1) 8424.70k 31475.11k 104036.10k 245559.30k 406667.26k +--- + crypto/engine/eng_padlock.c | 597 +++++++++++++++++++++++++++++++++++++++--- + 1 files changed, 554 insertions(+), 43 deletions(-) + +diff --git a/crypto/engine/eng_padlock.c b/crypto/engine/eng_padlock.c +index 743558a..28ec0f7 100644 +--- a/crypto/engine/eng_padlock.c ++++ b/crypto/engine/eng_padlock.c +@@ -3,6 +3,9 @@ + * Written by Michal Ludvig <michal@logix.cz> + * http://www.logix.cz/michal + * ++ * SHA support by Timo Teras <timo.teras@iki.fi>. Portions based on ++ * code originally written by Michal Ludvig. ++ * + * Big thanks to Andy Polyakov for a help with optimization, + * assembler fixes, port to MS Windows and a lot of other + * valuable work on this engine! +@@ -74,12 +77,23 @@ + #ifndef OPENSSL_NO_AES + #include <openssl/aes.h> + #endif ++#ifndef OPENSSL_NO_SHA ++#include <openssl/sha.h> ++#endif + #include <openssl/rand.h> + #include <openssl/err.h> + + #ifndef OPENSSL_NO_HW + #ifndef OPENSSL_NO_HW_PADLOCK + ++/* PadLock RNG is disabled by default */ ++#define PADLOCK_NO_RNG 1 ++ ++/* No ASM routines for SHA in MSC yet */ ++#ifdef _MSC_VER ++#define OPENSSL_NO_SHA ++#endif ++ + /* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */ + #if (OPENSSL_VERSION_NUMBER >= 0x00908000L) + # ifndef OPENSSL_NO_DYNAMIC_ENGINE +@@ -138,58 +152,40 @@ static int padlock_available(void); + static int padlock_init(ENGINE *e); + + /* RNG Stuff */ ++#ifndef PADLOCK_NO_RNG + static RAND_METHOD padlock_rand; +- +-/* Cipher Stuff */ +-#ifndef OPENSSL_NO_AES +-static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + #endif + + /* Engine names */ + static const char *padlock_id = "padlock"; + static char padlock_name[100]; + +-/* Available features */ +-static int padlock_use_ace = 0; /* Advanced Cryptography Engine */ +-static int padlock_use_rng = 0; /* Random Number Generator */ +-#ifndef OPENSSL_NO_AES +-static int padlock_aes_align_required = 1; +-#endif +- +-/* ===== Engine "management" functions ===== */ ++static int padlock_bind_helper(ENGINE *e); + +-/* Prepare the ENGINE structure for registration */ +-static int +-padlock_bind_helper(ENGINE *e) +-{ +- /* Check available features */ +- padlock_available(); +- +-#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */ +- padlock_use_rng=0; +-#endif +- +- /* Generate a nice engine name with available features */ +- BIO_snprintf(padlock_name, sizeof(padlock_name), +- "VIA PadLock (%s, %s)", +- padlock_use_rng ? "RNG" : "no-RNG", +- padlock_use_ace ? "ACE" : "no-ACE"); ++ /* Available features */ ++enum padlock_flags { ++ PADLOCK_RNG = 0x01, ++ PADLOCK_ACE = 0x02, ++ PADLOCK_ACE2 = 0x04, ++ PADLOCK_PHE = 0x08, ++ PADLOCK_PMM = 0x10, ++ PADLOCK_NANO = 0x20, ++}; ++enum padlock_flags padlock_flags; + +- /* Register everything or return with an error */ +- if (!ENGINE_set_id(e, padlock_id) || +- !ENGINE_set_name(e, padlock_name) || ++#define PADLOCK_HAVE_RNG (padlock_flags & PADLOCK_RNG) ++#define PADLOCK_HAVE_ACE (padlock_flags & (PADLOCK_ACE|PADLOCK_ACE2)) ++#define PADLOCK_HAVE_ACE1 (padlock_flags & PADLOCK_ACE) ++#define PADLOCK_HAVE_ACE2 (padlock_flags & PADLOCK_ACE2) ++#define PADLOCK_HAVE_PHE (padlock_flags & PADLOCK_PHE) ++#define PADLOCK_HAVE_PMM (padlock_flags & PADLOCK_PMM) ++#define PADLOCK_HAVE_NANO (padlock_flags & PADLOCK_NANO) + +- !ENGINE_set_init_function(e, padlock_init) || + #ifndef OPENSSL_NO_AES +- (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) || ++static int padlock_aes_align_required = 1; + #endif +- (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) { +- return 0; +- } + +- /* Everything looks good */ +- return 1; +-} ++/* ===== Engine "management" functions ===== */ + + /* Constructor */ + static ENGINE * +@@ -213,7 +209,7 @@ ENGINE_padlock(void) + static int + padlock_init(ENGINE *e) + { +- return (padlock_use_rng || padlock_use_ace); ++ return padlock_flags; + } + + /* This stuff is needed if this ENGINE is being compiled into a self-contained +@@ -365,10 +361,20 @@ padlock_available(void) + : "+a"(eax), "=d"(edx) : : "ecx"); + + /* Fill up some flags */ +- padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6)); +- padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2)); ++ padlock_flags |= ((edx & (0x3<<3)) ? PADLOCK_RNG : 0); ++ padlock_flags |= ((edx & (0x3<<7)) ? PADLOCK_ACE : 0); ++ padlock_flags |= ((edx & (0x3<<9)) ? PADLOCK_ACE2 : 0); ++ padlock_flags |= ((edx & (0x3<<11)) ? PADLOCK_PHE : 0); ++ padlock_flags |= ((edx & (0x3<<13)) ? PADLOCK_PMM : 0); ++ ++ /* Check for VIA Nano CPU */ ++ eax = 0x00000001; ++ asm volatile ("pushl %%ebx; cpuid; popl %%ebx" ++ : "+a"(eax) : : "ecx", "edx"); ++ if ((eax | 0x000F) == 0x06FF) ++ padlock_flags |= PADLOCK_NANO; + +- return padlock_use_ace + padlock_use_rng; ++ return padlock_flags; + } + + #ifndef OPENSSL_NO_AES +@@ -1157,6 +1163,454 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, + + #endif /* OPENSSL_NO_AES */ + ++#ifndef OPENSSL_NO_SHA ++ ++static inline void ++padlock_copy_bswap(void *dst, void *src, size_t count) ++{ ++ uint32_t *udst = dst, *usrc = src; ++ unsigned int reg; ++ int i = 0; ++ ++ for (i = 0; i < count; i++) { ++ reg = usrc[i]; ++ asm volatile("bswapl %0" : "+&r"(reg)); ++ udst[i] = reg; ++ } ++} ++ ++#define PADLOCK_SHA_ALIGN(dd) (uint32_t*)(((uintptr_t)(dd) + 15) & ~15) ++#define PADLOCK_SHA_HWCTX (128+16) ++ ++static void ++padlock_sha1(void *hwctx, const void *buf, uint32_t total, uint32_t now) ++{ ++ uint32_t pos = total - now; ++ ++ asm volatile ("xsha1" ++ : "+S"(buf), "+D"(hwctx), "+a"(pos), "+c"(total) ++ : : "memory"); ++} ++ ++static void ++padlock_sha1_partial(void *hwctx, const void *buf, uint32_t blocks) ++{ ++ asm volatile ("xsha1" ++ : "+S"(buf), "+D"(hwctx), "+c"(blocks) ++ : "a"(-1) : "memory"); ++} ++ ++static int padlock_sha1_init(EVP_MD_CTX *ctx) ++{ ++ return SHA1_Init(ctx->md_data); ++} ++ ++static int padlock_sha1_update(EVP_MD_CTX *ctx, const void *data, ++ size_t len) ++{ ++ unsigned char hwctx[PADLOCK_SHA_HWCTX]; ++ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx); ++ SHA_CTX *c = ctx->md_data; ++ uint_fast64_t total; ++ const unsigned char *p = data; ++ unsigned int l = 0; ++ ++ /* Calculate total length (Nl,Nh) is length in bits */ ++ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3); ++ total += len; ++ ++ if ((ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) && ++ (total <= 0xfffffffe)) { ++ if (c->num != 0) { ++ l = (len < SHA_CBLOCK) ? len : SHA_CBLOCK; ++ if (!SHA1_Update(c, data, l)) ++ return 0; ++ p += l; ++ if (c->num != 0) { ++ p = (unsigned char *) c->data; ++ len = c->num; ++ l = 0; ++ } ++ } ++ memcpy(aligned, &c->h0, 5 * sizeof(SHA_LONG)); ++ padlock_sha1(aligned, p, total, len - l); ++ memcpy(&c->h0, aligned, 5 * sizeof(SHA_LONG)); ++ c->num = -1; ++ return 1; ++ } ++ ++ return SHA1_Update(c, data, len); ++} ++ ++static int padlock_nano_sha1_update(EVP_MD_CTX *ctx, const void *data, ++ size_t len) ++{ ++ unsigned char hwctx[PADLOCK_SHA_HWCTX]; ++ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx); ++ SHA_CTX *c = ctx->md_data; ++ uint_fast64_t total; ++ unsigned char *p; ++ unsigned int n; ++ ++ /* Calculate total length (Nl,Nh) is length in bits */ ++ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3); ++ total += len; ++ c->Nh = total >> 29; ++ c->Nl = (total << 3) & 0xffffffffUL; ++ ++ memcpy(aligned, &c->h0, 5 * sizeof(SHA_LONG)); ++ ++ /* Check partial data */ ++ n = c->num; ++ if (n) { ++ p = (unsigned char *) c->data; ++ if (len >= SHA_CBLOCK || len+n >= SHA_CBLOCK) { ++ memcpy(p+n, data, SHA_CBLOCK-n); ++ padlock_sha1_partial(aligned, p, 1); ++ n = SHA_CBLOCK - n; ++ data += n; ++ len -= n; ++ c->num = 0; ++ memset(p, 0, SHA_CBLOCK); ++ } else { ++ memcpy(p+n, data, len); ++ c->num += (unsigned int)len; ++ return 1; ++ } ++ } ++ ++ /* Can we finalize straight away? */ ++ if ((ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) && ++ (total <= 0xfffffffe)) { ++ padlock_sha1(aligned, data, total, len); ++ memcpy(&c->h0, aligned, 5 * sizeof(SHA_LONG)); ++ c->num = -1; ++ return 1; ++ } ++ ++ /* Use nonfinalizing update */ ++ n = len / SHA_CBLOCK; ++ if (n != 0) { ++ padlock_sha1_partial(aligned, data, n); ++ data += n * SHA_CBLOCK; ++ len -= n * SHA_CBLOCK; ++ } ++ memcpy(&c->h0, aligned, 5 * sizeof(SHA_LONG)); ++ ++ /* Buffer remaining bytes */ ++ if (len) { ++ memcpy(c->data, data, len); ++ c->num = len; ++ } ++ ++ return 1; ++} ++ ++static int padlock_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) ++{ ++ SHA_CTX *c = ctx->md_data; ++ uint_fast64_t total; ++ ++ if (c->num == -1) { ++ padlock_copy_bswap(md, &c->h0, 5); ++ c->num = 0; ++ return 1; ++ } ++ ++ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3); ++ if (total <= 0xfffffffe) { ++ unsigned char hwctx[PADLOCK_SHA_HWCTX]; ++ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx); ++ ++ memcpy(aligned, &c->h0, 5 * sizeof(SHA_LONG)); ++ padlock_sha1(aligned, c->data, total, c->num); ++ padlock_copy_bswap(md, aligned, 5); ++ c->num = 0; ++ return 1; ++ } ++ ++ return SHA1_Final(md, c); ++} ++ ++static EVP_MD padlock_sha1_md = { ++ NID_sha1, ++ NID_sha1WithRSAEncryption, ++ SHA_DIGEST_LENGTH, ++ 0, ++ padlock_sha1_init, ++ padlock_sha1_update, ++ padlock_sha1_final, ++ NULL, ++ NULL, ++ EVP_PKEY_RSA_method, ++ SHA_CBLOCK, ++ sizeof(SHA_CTX), ++}; ++ ++static EVP_MD padlock_dss1_md = { ++ NID_dsa, ++ NID_dsaWithSHA1, ++ SHA_DIGEST_LENGTH, ++ 0, ++ padlock_sha1_init, ++ padlock_sha1_update, ++ padlock_sha1_final, ++ NULL, ++ NULL, ++ EVP_PKEY_DSA_method, ++ SHA_CBLOCK, ++ sizeof(SHA_CTX), ++}; ++ ++ ++#if !defined(OPENSSL_NO_SHA256) ++ ++static void ++padlock_sha256(void *hwctx, const void *buf, uint32_t total, uint32_t now) ++{ ++ uint32_t pos = total - now; ++ ++ asm volatile ("xsha256" ++ : "+S"(buf), "+D"(hwctx), "+a"(pos), "+c"(total) ++ : : "memory"); ++} ++ ++static void ++padlock_sha256_partial(void *hwctx, const void *buf, uint32_t blocks) ++{ ++ asm volatile ("xsha256" ++ : "+S"(buf), "+D"(hwctx), "+c"(blocks) ++ : "a"(-1) : "memory"); ++} ++ ++static int padlock_sha256_update(EVP_MD_CTX *ctx, const void *data, ++ size_t len) ++{ ++ unsigned char hwctx[PADLOCK_SHA_HWCTX]; ++ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx); ++ SHA256_CTX *c = ctx->md_data; ++ uint_fast64_t total; ++ const unsigned char *p = data; ++ unsigned int l = 0; ++ ++ /* Calculate total length (Nl,Nh) is length in bits */ ++ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3); ++ total += len; ++ ++ if ((ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) && ++ (total <= 0xfffffffe)) { ++ if (c->num != 0) { ++ l = (len < SHA256_CBLOCK) ? len : SHA256_CBLOCK; ++ if (!SHA256_Update(c, data, l)) ++ return 0; ++ p += l; ++ if (c->num != 0) { ++ p = (unsigned char *) c->data; ++ len = c->num; ++ l = 0; ++ } ++ } ++ memcpy(aligned, c->h, sizeof(c->h)); ++ padlock_sha256(aligned, p, total, len - l); ++ memcpy(c->h, aligned, sizeof(c->h)); ++ c->num = -1; ++ return 1; ++ } ++ ++ return SHA256_Update(c, data, len); ++} ++ ++static int padlock_nano_sha256_update(EVP_MD_CTX *ctx, const void *data, ++ size_t len) ++{ ++ unsigned char hwctx[PADLOCK_SHA_HWCTX]; ++ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx); ++ SHA256_CTX *c = ctx->md_data; ++ uint_fast64_t total; ++ unsigned char *p; ++ unsigned int n; ++ ++ /* Calculate total length (Nl,Nh) is length in bits */ ++ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3); ++ total += len; ++ c->Nh = total >> 29; ++ c->Nl = (total << 3) & 0xffffffffUL; ++ ++ memcpy(aligned, c->h, sizeof(c->h)); ++ ++ /* Check partial data */ ++ n = c->num; ++ if (n) { ++ p = (unsigned char *) c->data; ++ if (len >= SHA256_CBLOCK || len+n >= SHA256_CBLOCK) { ++ memcpy(p+n, data, SHA256_CBLOCK-n); ++ padlock_sha256_partial(aligned, p, 1); ++ n = SHA256_CBLOCK - n; ++ data += n; ++ len -= n; ++ c->num = 0; ++ memset(p, 0, SHA256_CBLOCK); ++ } else { ++ memcpy(p+n, data, len); ++ c->num += (unsigned int)len; ++ return 1; ++ } ++ } ++ ++ /* Can we finalize straight away? */ ++ if ((ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) && ++ (total <= 0xfffffffe)) { ++ padlock_sha256(aligned, data, total, len); ++ memcpy(c->h, aligned, sizeof(c->h)); ++ c->num = -1; ++ return 1; ++ } ++ ++ /* Use nonfinalizing update */ ++ n = len / SHA256_CBLOCK; ++ if (n != 0) { ++ padlock_sha256_partial(aligned, data, n); ++ data += n * SHA256_CBLOCK; ++ len -= n * SHA256_CBLOCK; ++ } ++ memcpy(c->h, aligned, sizeof(c->h)); ++ ++ /* Buffer remaining bytes */ ++ if (len) { ++ memcpy(c->data, data, len); ++ c->num = len; ++ } ++ ++ return 1; ++} ++ ++static int padlock_sha256_final(EVP_MD_CTX *ctx, unsigned char *md) ++{ ++ SHA256_CTX *c = ctx->md_data; ++ uint_fast64_t total; ++ ++ if (c->num == -1) { ++ padlock_copy_bswap(md, c->h, sizeof(c->h)/sizeof(c->h[0])); ++ c->num = 0; ++ return 1; ++ } ++ ++ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3); ++ if (total <= 0xfffffffe) { ++ unsigned char hwctx[PADLOCK_SHA_HWCTX]; ++ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx); ++ ++ memcpy(aligned, c->h, sizeof(c->h)); ++ padlock_sha256(aligned, c->data, total, c->num); ++ padlock_copy_bswap(md, aligned, sizeof(c->h)/sizeof(c->h[0])); ++ c->num = 0; ++ return 1; ++ } ++ ++ return SHA256_Final(md, c); ++} ++ ++#if !defined(OPENSSL_NO_SHA224) ++ ++static int padlock_sha224_init(EVP_MD_CTX *ctx) ++{ ++ return SHA224_Init(ctx->md_data); ++} ++ ++static EVP_MD padlock_sha224_md = { ++ NID_sha224, ++ NID_sha224WithRSAEncryption, ++ SHA224_DIGEST_LENGTH, ++ 0, ++ padlock_sha224_init, ++ padlock_sha256_update, ++ padlock_sha256_final, ++ NULL, ++ NULL, ++ EVP_PKEY_RSA_method, ++ SHA_CBLOCK, ++ sizeof(SHA256_CTX), ++}; ++#endif /* !OPENSSL_NO_SHA224 */ ++ ++static int padlock_sha256_init(EVP_MD_CTX *ctx) ++{ ++ return SHA256_Init(ctx->md_data); ++} ++ ++static EVP_MD padlock_sha256_md = { ++ NID_sha256, ++ NID_sha256WithRSAEncryption, ++ SHA256_DIGEST_LENGTH, ++ 0, ++ padlock_sha256_init, ++ padlock_sha256_update, ++ padlock_sha256_final, ++ NULL, ++ NULL, ++ EVP_PKEY_RSA_method, ++ SHA_CBLOCK, ++ sizeof(SHA256_CTX), ++}; ++#endif /* !OPENSSL_NO_SHA256 */ ++ ++static int padlock_digest_nids[] = { ++#if !defined(OPENSSL_NO_SHA) ++ NID_sha1, ++ NID_dsa, ++#endif ++#if !defined(OPENSSL_NO_SHA256) ++#if !defined(OPENSSL_NO_SHA224) ++ NID_sha224, ++#endif ++ NID_sha256, ++#endif ++}; ++ ++static int padlock_digest_nids_num = sizeof(padlock_digest_nids)/sizeof(padlock_digest_nids[0]); ++ ++static int ++padlock_digests (ENGINE *e, const EVP_MD **digest, const int **nids, int nid) ++{ ++ /* No specific digest => return a list of supported nids ... */ ++ if (!digest) { ++ *nids = padlock_digest_nids; ++ return padlock_digest_nids_num; ++ } ++ ++ /* ... or the requested "digest" otherwise */ ++ switch (nid) { ++#if !defined(OPENSSL_NO_SHA) ++ case NID_sha1: ++ *digest = &padlock_sha1_md; ++ break; ++ case NID_dsa: ++ *digest = &padlock_dss1_md; ++ break; ++#endif ++#if !defined(OPENSSL_NO_SHA256) ++#if !defined(OPENSSL_NO_SHA224) ++ case NID_sha224: ++ *digest = &padlock_sha224_md; ++ break; ++#endif /* OPENSSL_NO_SHA224 */ ++ case NID_sha256: ++ *digest = &padlock_sha256_md; ++ break; ++#endif /* OPENSSL_NO_SHA256 */ ++ default: ++ /* Sorry, we don't support this NID */ ++ *digest = NULL; ++ return 0; ++ } ++ ++ return 1; ++} ++ ++#endif /* OPENSSL_NO_SHA */ ++ ++#ifndef PADLOCK_NO_RNG ++ + /* ===== Random Number Generator ===== */ + /* + * This code is not engaged. The reason is that it does not comply +@@ -1213,7 +1667,64 @@ static RAND_METHOD padlock_rand = { + padlock_rand_status, /* rand status */ + }; + ++#endif /* PADLOCK_NO_RNG */ ++ + #endif /* COMPILE_HW_PADLOCK */ + ++ ++/* Prepare the ENGINE structure for registration */ ++static int ++padlock_bind_helper(ENGINE *e) ++{ ++ /* Check available features */ ++ padlock_available(); ++ ++ /* Generate a nice engine name with available features */ ++ BIO_snprintf(padlock_name, sizeof(padlock_name), ++ "VIA PadLock: %s%s%s%s%s%s", ++ padlock_flags ? "" : "not supported", ++ PADLOCK_HAVE_RNG ? "RNG " : "", ++ PADLOCK_HAVE_ACE ? (PADLOCK_HAVE_ACE2 ? "ACE2 " : "ACE ") : "", ++ PADLOCK_HAVE_PHE ? "PHE " : "", ++ PADLOCK_HAVE_PMM ? "PMM " : "", ++ PADLOCK_HAVE_NANO ? "NANO " : "" ++ ); ++ ++#ifndef OPENSSL_NO_SHA ++ /* Use Nano SHA acceleration? */ ++ if (PADLOCK_HAVE_NANO) { ++ padlock_sha1_md.update = padlock_nano_sha1_update; ++ padlock_dss1_md.update = padlock_nano_sha1_update; ++#if !defined(OPENSSL_NO_SHA256) ++#if !defined(OPENSSL_NO_SHA224) ++ padlock_sha224_md.update = padlock_nano_sha256_update; ++#endif ++ padlock_sha256_md.update = padlock_nano_sha256_update; ++#endif ++ } ++#endif ++ ++ /* Register everything or return with an error */ ++ if (!ENGINE_set_id(e, padlock_id) || ++ !ENGINE_set_name(e, padlock_name) || ++ ++ !ENGINE_set_init_function(e, padlock_init) ++#ifndef OPENSSL_NO_AES ++ || (PADLOCK_HAVE_ACE && !ENGINE_set_ciphers (e, padlock_ciphers)) ++#endif ++#ifndef OPENSSL_NO_SHA ++ || (PADLOCK_HAVE_PHE && !ENGINE_set_digests (e, padlock_digests)) ++#endif ++#ifndef PADLOCK_NO_RNG ++ || (PADLOCK_HAVE_RNG && !ENGINE_set_RAND (e, &padlock_rand)) ++#endif ++ ) { ++ return 0; ++ } ++ ++ /* Everything looks good */ ++ return 1; ++} ++ + #endif /* !OPENSSL_NO_HW_PADLOCK */ + #endif /* !OPENSSL_NO_HW */ +-- +1.7.0.4 + diff --git a/main/openssl/APKBUILD b/main/openssl/APKBUILD index 62cd44998..8b886e99e 100644 --- a/main/openssl/APKBUILD +++ b/main/openssl/APKBUILD @@ -1,7 +1,7 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=openssl pkgver=0.9.8o -pkgrel=0 +pkgrel=1 pkgdesc="Toolkit for SSL v2/v3 and TLS v1" url=http://openssl.org depends= @@ -13,7 +13,9 @@ subpackages="$pkgname-dev $pkgname-doc libcrypto" source="http://www.openssl.org/source/${pkgname}-${pkgver}.tar.gz openssl-0.9.8o-fix-manpages.patch openssl-bb-basename.patch - openssl-0.9.8k-padlock-sha.patch + 0001-crypto-hmac-support-EVP_MD_CTX_FLAG_ONESHOT-and-set-.patch + 0002-apps-speed-fix-digest-speed-measurement-and-add-hmac.patch + 0003-engine-padlock-implement-sha1-sha224-sha256-accelera.patch " _builddir="$srcdir"/$pkgname-$pkgver @@ -51,4 +53,6 @@ libcrypto() { md5sums="63ddc5116488985e820075e65fbe6aa4 openssl-0.9.8o.tar.gz 19615785a671129bae790478f073da2c openssl-0.9.8o-fix-manpages.patch c6a9857a5dbd30cead0404aa7dd73977 openssl-bb-basename.patch -86b7f1bf50e1f3ba407ec62001a51a0d openssl-0.9.8k-padlock-sha.patch" +2f370b846d8f27ac45dd6e5341366e16 0001-crypto-hmac-support-EVP_MD_CTX_FLAG_ONESHOT-and-set-.patch +234de7f31d2e9c826616dd7a23598e86 0002-apps-speed-fix-digest-speed-measurement-and-add-hmac.patch +e262418b20a05c2af12d464ac194ea21 0003-engine-padlock-implement-sha1-sha224-sha256-accelera.patch" diff --git a/main/openssl/openssl-0.9.8k-padlock-sha.patch b/main/openssl/openssl-0.9.8k-padlock-sha.patch deleted file mode 100644 index b2e7e954d..000000000 --- a/main/openssl/openssl-0.9.8k-padlock-sha.patch +++ /dev/null @@ -1,821 +0,0 @@ -# -# OpenSSL patch to support VIA C7 hash engine -# Written by: Timo Teras <timo.teras@iki.fi> -# based on patch by: Michal Ludvig <michal@logix.cz> -# http://www.logix.cz/michal/devel/padlock -# -Index: openssl-0.9.8k/crypto/engine/eng_padlock.c -=================================================================== ---- openssl-0.9.8k.orig/crypto/engine/eng_padlock.c 2009-07-27 16:18:20.000000000 +0300 -+++ openssl-0.9.8k/crypto/engine/eng_padlock.c 2009-07-30 22:02:54.000000000 +0300 -@@ -1,10 +1,13 @@ --/* -+/* - * Support for VIA PadLock Advanced Cryptography Engine (ACE) - * Written by Michal Ludvig <michal@logix.cz> - * http://www.logix.cz/michal - * -- * Big thanks to Andy Polyakov for a help with optimization, -- * assembler fixes, port to MS Windows and a lot of other -+ * SHA support by Timo Teras <timo.teras@iki.fi> based on code -+ * originally by Michal Ludvig. -+ * -+ * Big thanks to Andy Polyakov for a help with optimization, -+ * assembler fixes, port to MS Windows and a lot of other - * valuable work on this engine! - */ - -@@ -66,6 +69,13 @@ - #include <stdio.h> - #include <string.h> - -+#include <signal.h> -+#include <stdint.h> -+#include <unistd.h> -+#include <sys/mman.h> -+#include <sys/ucontext.h> -+#include <arpa/inet.h> -+ - #include <openssl/opensslconf.h> - #include <openssl/crypto.h> - #include <openssl/dso.h> -@@ -74,12 +84,23 @@ - #ifndef OPENSSL_NO_AES - #include <openssl/aes.h> - #endif -+#ifndef OPENSSL_NO_SHA -+#include <openssl/sha.h> -+#endif - #include <openssl/rand.h> - #include <openssl/err.h> - - #ifndef OPENSSL_NO_HW - #ifndef OPENSSL_NO_HW_PADLOCK - -+/* PadLock RNG is disabled by default */ -+#define PADLOCK_NO_RNG 1 -+ -+/* No ASM routines for SHA in MSC yet */ -+#ifdef _MSC_VER -+#define OPENSSL_NO_SHA -+#endif -+ - /* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */ - #if (OPENSSL_VERSION_NUMBER >= 0x00908000L) - # ifndef OPENSSL_NO_DYNAMIC_ENGINE -@@ -96,7 +117,7 @@ - /* VIA PadLock AES is available *ONLY* on some x86 CPUs. - Not only that it doesn't exist elsewhere, but it - even can't be compiled on other platforms! -- -+ - In addition, because of the heavy use of inline assembler, - compiler choice is limited to GCC and Microsoft C. */ - #undef COMPILE_HW_PADLOCK -@@ -138,20 +159,42 @@ - static int padlock_init(ENGINE *e); - - /* RNG Stuff */ -+#ifndef PADLOCK_NO_RNG - static RAND_METHOD padlock_rand; -+#endif - - /* Cipher Stuff */ - #ifndef OPENSSL_NO_AES - static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); - #endif - -+/* Digest Stuff */ -+#ifndef OPENSSL_NO_SHA -+static int padlock_digests(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); -+static volatile void *padlock_cached_sha_buffer = NULL; -+#endif -+ - /* Engine names */ - static const char *padlock_id = "padlock"; - static char padlock_name[100]; - - /* Available features */ --static int padlock_use_ace = 0; /* Advanced Cryptography Engine */ --static int padlock_use_rng = 0; /* Random Number Generator */ -+enum padlock_flags { -+ PADLOCK_RNG = 0x01, -+ PADLOCK_ACE = 0x02, -+ PADLOCK_ACE2 = 0x04, -+ PADLOCK_PHE = 0x08, -+ PADLOCK_PMM = 0x10 -+}; -+enum padlock_flags padlock_flags; -+ -+#define PADLOCK_HAVE_RNG (padlock_flags & PADLOCK_RNG) -+#define PADLOCK_HAVE_ACE (padlock_flags & (PADLOCK_ACE|PADLOCK_ACE2)) -+#define PADLOCK_HAVE_ACE1 (padlock_flags & PADLOCK_ACE) -+#define PADLOCK_HAVE_ACE2 (padlock_flags & PADLOCK_ACE2) -+#define PADLOCK_HAVE_PHE (padlock_flags & PADLOCK_PHE) -+#define PADLOCK_HAVE_PMM (padlock_flags & PADLOCK_PMM) -+ - #ifndef OPENSSL_NO_AES - static int padlock_aes_align_required = 1; - #endif -@@ -165,25 +208,30 @@ - /* Check available features */ - padlock_available(); - --#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */ -- padlock_use_rng=0; --#endif -- - /* Generate a nice engine name with available features */ - BIO_snprintf(padlock_name, sizeof(padlock_name), -- "VIA PadLock (%s, %s)", -- padlock_use_rng ? "RNG" : "no-RNG", -- padlock_use_ace ? "ACE" : "no-ACE"); -+ "VIA PadLock: %s%s%s%s%s", -+ padlock_flags ? "" : "not supported", -+ PADLOCK_HAVE_RNG ? "RNG " : "", -+ PADLOCK_HAVE_ACE ? (PADLOCK_HAVE_ACE2 ? "ACE2 " : "ACE ") : "", -+ PADLOCK_HAVE_PHE ? "PHE " : "", -+ PADLOCK_HAVE_PMM ? "PMM " : ""); - -- /* Register everything or return with an error */ -+ /* Register everything or return with an error */ - if (!ENGINE_set_id(e, padlock_id) || - !ENGINE_set_name(e, padlock_name) || - -- !ENGINE_set_init_function(e, padlock_init) || -+ !ENGINE_set_init_function(e, padlock_init) - #ifndef OPENSSL_NO_AES -- (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) || -+ || (PADLOCK_HAVE_ACE && !ENGINE_set_ciphers (e, padlock_ciphers)) - #endif -- (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) { -+#ifndef OPENSSL_NO_SHA -+ || (PADLOCK_HAVE_PHE && !ENGINE_set_digests (e, padlock_digests)) -+#endif -+#ifndef PADLOCK_NO_RNG -+ || (PADLOCK_HAVE_RNG && !ENGINE_set_RAND (e, &padlock_rand)) -+#endif -+ ) { - return 0; - } - -@@ -213,7 +261,7 @@ - static int - padlock_init(ENGINE *e) - { -- return (padlock_use_rng || padlock_use_ace); -+ return (padlock_flags); - } - - /* This stuff is needed if this ENGINE is being compiled into a self-contained -@@ -247,7 +295,7 @@ - #define AES_KEY_SIZE_192 24 - #define AES_KEY_SIZE_256 32 - --/* Here we store the status information relevant to the -+/* Here we store the status information relevant to the - current context. */ - /* BIG FAT WARNING: - * Inline assembler in PADLOCK_XCRYPT_ASM() -@@ -306,7 +354,7 @@ - { - int result = -1; - -- /* We're checking if the bit #21 of EFLAGS -+ /* We're checking if the bit #21 of EFLAGS - can be toggled. If yes = CPUID is available. */ - asm volatile ( - "pushf\n" -@@ -322,7 +370,7 @@ - "xorl %%eax, %%ecx\n" - "movl %%ecx, %0\n" - : "=r" (result) : : "eax", "ecx"); -- -+ - return (result == 0); - } - -@@ -365,10 +413,22 @@ - : "+a"(eax), "=d"(edx) : : "ecx"); - - /* Fill up some flags */ -- padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6)); -- padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2)); -+ padlock_flags |= ((edx & (0x3<<3)) ? PADLOCK_RNG : 0); -+ padlock_flags |= ((edx & (0x3<<7)) ? PADLOCK_ACE : 0); -+ padlock_flags |= ((edx & (0x3<<9)) ? PADLOCK_ACE2 : 0); -+ padlock_flags |= ((edx & (0x3<<11)) ? PADLOCK_PHE : 0); -+ padlock_flags |= ((edx & (0x3<<13)) ? PADLOCK_PMM : 0); - -- return padlock_use_ace + padlock_use_rng; -+ return padlock_flags; -+} -+ -+static inline void -+padlock_htonl_block(uint32_t *data, size_t count) -+{ -+ while (count--) { -+ asm volatile ("bswapl %0" : "+r"(*data)); -+ data++; -+ } - } - - #ifndef OPENSSL_NO_AES -@@ -377,17 +437,14 @@ - padlock_bswapl(AES_KEY *ks) - { - size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]); -- unsigned int *key = ks->rd_key; -+ uint32_t *key = (uint32_t*) ks->rd_key; - -- while (i--) { -- asm volatile ("bswapl %0" : "+r"(*key)); -- key++; -- } -+ padlock_htonl_block(key, i); - } - #endif - - /* Force key reload from memory to the CPU microcode. -- Loading EFLAGS from the stack clears EFLAGS[30] -+ Loading EFLAGS from the stack clears EFLAGS[30] - which does the trick. */ - static inline void - padlock_reload_key(void) -@@ -423,7 +480,7 @@ - } - - /* Template for padlock_xcrypt_* modes */ --/* BIG FAT WARNING: -+/* BIG FAT WARNING: - * The offsets used with 'leal' instructions - * describe items of the 'padlock_cipher_data' - * structure. -@@ -475,7 +532,7 @@ - * In case you wonder 'rep xcrypt*' instructions above are *not* - * affected by the Direction Flag and pointers advance toward - * larger addresses unconditionally. -- */ -+ */ - static inline unsigned char * - padlock_memcpy(void *dst,const void *src,size_t n) - { -@@ -501,7 +558,7 @@ - _asm _emit 0x0f _asm _emit 0xa7 \ - _asm _emit code - --/* BIG FAT WARNING: -+/* BIG FAT WARNING: - * The offsets used with 'lea' instructions - * describe items of the 'padlock_cipher_data' - * structure. -@@ -840,7 +897,7 @@ - return 1; - } - --/* -+/* - * Simplified version of padlock_aes_cipher() used when - * 1) both input and output buffers are at aligned addresses. - * or when -@@ -895,7 +952,7 @@ - # error "insane PADLOCK_CHUNK..." - #endif - --/* Re-align the arguments to 16-Bytes boundaries and run the -+/* Re-align the arguments to 16-Bytes boundaries and run the - encryption function itself. This function is not AES-specific. */ - static int - padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, -@@ -1157,6 +1214,514 @@ - - #endif /* OPENSSL_NO_AES */ - -+#ifndef OPENSSL_NO_SHA -+ -+#define DIGEST_DATA(ctx) ((struct padlock_digest_data *)(ctx->md_data)) -+#define PADLOCK_SHA_ALIGN(dd) (uint32_t*)(((uintptr_t)(dd) + 15) & ~15) -+#define PADLOCK_SHA_PAGES 14 -+#define PADLOCK_SHA_BUFFER (512 - sizeof(size_t) - 4*sizeof(void*)) -+#define PADLOCK_SHA_INITVECTOR_SIZE (8 * sizeof(uint32_t)) -+ -+struct padlock_digest_data { -+ union { -+ unsigned char smallbuffer[PADLOCK_SHA_BUFFER]; -+ struct { -+ unsigned char padlockctx[128+16]; -+ unsigned char *buffer; -+ size_t mmap_size; -+ uint64_t total; -+ }; -+ }; -+ void *initvector; -+ size_t used; -+ void (*hash)(void *padlockctx, const void *buf, size_t len); -+ int (*update)(EVP_MD_CTX *ctx, const void *buffer, size_t len); -+ int (*final)(EVP_MD_CTX *ctx, unsigned char *buffer); -+}; -+ -+static inline void * -+padlock_atomic_xchg(volatile void **mem, void *fixed) -+{ -+ /* No lock prefix due the xchg asserts it anyway, and the -+ * funny unsigned long* cast is required to workaround some gcc -+ * problems if compiling in PIC mode */ -+ asm volatile ( -+ "xchg %0, %1" -+ : "=r"(fixed) -+ : "m"(*(unsigned long*)mem), "0"(fixed) -+ : "memory"); -+ return fixed; -+} -+ -+static void -+padlock_do_sha1(void *padlockctx, const void *buf, size_t len) -+{ -+ asm volatile ( -+ "xsha1" -+ : "+S"(buf), "+D"(padlockctx) -+ : "c"(len), "a"(0)); -+} -+ -+static void -+padlock_do_sha256(void *padlockctx, const void *buf, size_t len) -+{ -+ asm volatile ( -+ "xsha256" -+ : "+S"(buf), "+D"(padlockctx) -+ : "c"(len), "a"(0)); -+} -+ -+static void -+handle_sigsegv(int sig, siginfo_t *info, void *uctxp) -+{ -+ ucontext_t *uctx = uctxp; -+ uctx->uc_mcontext.gregs[14] += 4; -+} -+ -+static void -+padlock_sha_nonfinalizing(struct padlock_digest_data *data) -+{ -+ struct sigaction act, oldact; -+ size_t bofs = 0; -+ -+ if (data->used != data->mmap_size) { -+ bofs = data->mmap_size - data->used; -+ memmove(&data->buffer[bofs], data->buffer, data->used); -+ } -+ -+ memset(&act, 0, sizeof(act)); -+ act.sa_sigaction = handle_sigsegv; -+ act.sa_flags = SA_SIGINFO; -+ sigaction(SIGSEGV, &act, &oldact); -+ data->hash(PADLOCK_SHA_ALIGN(data->padlockctx), -+ &data->buffer[bofs], data->used + 64); -+ sigaction(SIGSEGV, &oldact, NULL); -+} -+ -+static void -+padlock_free_buffer(void *buf) -+{ -+ buf = padlock_atomic_xchg(&padlock_cached_sha_buffer, buf); -+ if (buf != NULL) { -+ munmap(buf, (PADLOCK_SHA_PAGES + 1) * getpagesize()); -+ } -+} -+ -+static void * -+padlock_allocate_buffer(size_t *maxsize) -+{ -+ void *buf; -+ size_t size, page; -+ -+ page = getpagesize(); -+ buf = padlock_atomic_xchg(&padlock_cached_sha_buffer, NULL); -+ if (buf != NULL) -+ goto ret; -+ -+ size = (PADLOCK_SHA_PAGES + 1) * page; -+ buf = mmap(0, size, PROT_READ | PROT_WRITE, -+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); -+ if (buf == NULL) -+ return NULL; -+ -+ /* Try locking the pages to avoid swapping, but don't fail if -+ * we are over quota. */ -+ mlock(buf, size); -+ -+ if (mprotect(buf + PADLOCK_SHA_PAGES * page, page, PROT_NONE) < 0) { -+ munmap(buf, size); -+ return NULL; -+ } -+ -+ret: -+ *maxsize = PADLOCK_SHA_PAGES * page - 64; -+ -+ return buf; -+} -+ -+static int -+padlock_multi_update(EVP_MD_CTX *ctx, const void *data, size_t len) -+{ -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ size_t chunk_size; -+ -+ if (ddata->buffer == NULL) -+ ddata->buffer = padlock_allocate_buffer(&ddata->mmap_size); -+ -+ while (len) { -+ if (ddata->used + len < ddata->mmap_size) { -+ memcpy(&ddata->buffer[ddata->used], data, len); -+ ddata->used += len; -+ ddata->total += len; -+ return 1; -+ } -+ -+ chunk_size = ddata->mmap_size - ddata->used; -+ memcpy(&ddata->buffer[ddata->used], data, chunk_size); -+ -+ data += chunk_size; -+ len -= chunk_size; -+ ddata->used = ddata->mmap_size; -+ ddata->total += chunk_size; -+ padlock_sha_nonfinalizing(ddata); -+ ddata->used = 0; -+ } -+ -+ return 1; -+} -+ -+static int -+padlock_oneshot_final(EVP_MD_CTX *ctx, unsigned char *md) -+{ -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ size_t size = EVP_MD_CTX_size(ctx); -+ -+ memcpy(md, PADLOCK_SHA_ALIGN(ddata->padlockctx), size); -+ return 1; -+} -+ -+static int -+padlock_copy_final(EVP_MD_CTX *ctx, unsigned char *md) -+{ -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ char padlockctx[128+16]; -+ void *aligned = PADLOCK_SHA_ALIGN(padlockctx); -+ size_t size = EVP_MD_CTX_size(ctx); -+ -+ memcpy(aligned, ddata->initvector, PADLOCK_SHA_INITVECTOR_SIZE); -+ ddata->hash(aligned, ddata->smallbuffer, ddata->used); -+ padlock_htonl_block(aligned, size / sizeof(uint32_t)); -+ memcpy(md, aligned, size); -+ -+ return 1; -+} -+ -+static int -+padlock_multi_final(EVP_MD_CTX *ctx, unsigned char *md) -+{ -+ static const char padding[64] = { 0x80, }; -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ size_t mdsize = EVP_MD_CTX_size(ctx); -+ void *aligned = PADLOCK_SHA_ALIGN(ddata->padlockctx); -+ -+ if (ddata->used == ddata->total) { -+ /* Sweet, everything fits in one buffer. */ -+ ddata->hash(aligned, ddata->buffer, ddata->used); -+ } else { -+ /* Hardware already hashed some buffers. -+ * Do finalizing manually */ -+ union { -+ uint64_t u64; -+ uint32_t u32[2]; -+ } bits_le, bits; -+ size_t lastblocklen, padlen; -+ -+ /* BigEndianise the length. */ -+ bits_le.u64 = ddata->total * 8; -+ bits.u32[1] = htonl(bits_le.u32[0]); -+ bits.u32[0] = htonl(bits_le.u32[1]); -+ -+ /* Append padding, leave space for length. */ -+ lastblocklen = ddata->total & 63; -+ padlen = (lastblocklen < 56) ? (56 - lastblocklen) : ((64+56) - lastblocklen); -+ padlock_multi_update(ctx, padding, padlen); -+ -+ /* Length in BigEndian64 */ -+ padlock_multi_update(ctx, (const char *) &bits, sizeof(bits)); -+ -+ /* And finally calculate it */ -+ padlock_sha_nonfinalizing(ddata); -+ } -+ padlock_htonl_block(aligned, mdsize / sizeof(uint32_t)); -+ memcpy(md, aligned, mdsize); -+ -+ return 1; -+} -+ -+static int -+padlock_copy_update(EVP_MD_CTX *ctx, const void *data, size_t len) -+{ -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ -+ if (ddata->used + len > sizeof(ddata->smallbuffer)) { -+ ddata->update = padlock_multi_update; -+ ddata->final = padlock_multi_final; -+ -+ if (ddata->used != 0) { -+ void *buffer; -+ size_t mmap_size; -+ -+ buffer = padlock_allocate_buffer(&mmap_size); -+ memcpy(buffer, ddata->smallbuffer, ddata->used); -+ ddata->buffer = buffer; -+ ddata->total = ddata->used; -+ ddata->mmap_size = mmap_size; -+ } else { -+ ddata->buffer = NULL; -+ ddata->total = 0; -+ } -+ -+ memcpy(PADLOCK_SHA_ALIGN(ddata->padlockctx), ddata->initvector, -+ PADLOCK_SHA_INITVECTOR_SIZE); -+ -+ return padlock_multi_update(ctx, data, len); -+ } -+ -+ memcpy(&ddata->smallbuffer[ddata->used], data, len); -+ ddata->used += len; -+ -+ return 1; -+} -+ -+static int -+padlock_oneshot_update(EVP_MD_CTX *ctx, const void *data, size_t len) -+{ -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ void *aligned = PADLOCK_SHA_ALIGN(ddata->padlockctx); -+ size_t mdsize = EVP_MD_CTX_size(ctx); -+ -+ /* Oneshot update is only possible if context flags indicate so */ -+ if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { -+ ddata->update = padlock_copy_update; -+ ddata->final = padlock_copy_final; -+ return padlock_copy_update(ctx, data, len); -+ } -+ -+ memcpy(aligned, ddata->initvector, PADLOCK_SHA_INITVECTOR_SIZE); -+ ddata->hash(aligned, data, len); -+ padlock_htonl_block(aligned, mdsize / sizeof(uint32_t)); -+ ddata->used += len; -+ -+ return 1; -+} -+ -+static int -+padlock_sha_init(struct padlock_digest_data *ddata) -+{ -+ ddata->used = 0; -+ ddata->update = padlock_oneshot_update; -+ ddata->final = padlock_oneshot_final; -+ -+ return 1; -+} -+ -+static int -+padlock_sha1_init(EVP_MD_CTX *ctx) -+{ -+ static uint32_t sha1_initvector[8] = { -+ 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, -+ 0xC3D2E1F0 -+ }; -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ -+ ddata->hash = padlock_do_sha1; -+ ddata->initvector = sha1_initvector; -+ return padlock_sha_init(ddata); -+} -+ -+static int -+padlock_sha224_init(EVP_MD_CTX *ctx) -+{ -+ static uint32_t sha224_initvector[] = { -+ 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, -+ 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4, -+ }; -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ -+ ddata->hash = padlock_do_sha256; -+ ddata->initvector = sha224_initvector; -+ return padlock_sha_init(ddata); -+} -+ -+static int -+padlock_sha256_init(EVP_MD_CTX *ctx) -+{ -+ static uint32_t sha256_initvector[] = { -+ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, -+ 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 -+ }; -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ -+ ddata->hash = padlock_do_sha256; -+ ddata->initvector = sha256_initvector; -+ return padlock_sha_init(ddata); -+} -+ -+static int -+padlock_sha_update(EVP_MD_CTX *ctx, const void *data, size_t length) -+{ -+ return DIGEST_DATA(ctx)->update(ctx, data, length); -+} -+ -+static int -+padlock_sha_final(EVP_MD_CTX *ctx, unsigned char *md) -+{ -+ return DIGEST_DATA(ctx)->final(ctx, md); -+} -+ -+static int -+padlock_sha_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) -+{ -+ struct padlock_digest_data *dfrom = DIGEST_DATA(from); -+ struct padlock_digest_data *dto = DIGEST_DATA(to); -+ -+ /* When we get here, dto is already a memcpied from dfrom, -+ * it's ok for all other cases except when data is on a separate -+ * mmapped area. It would be nice if we had a flag, if this is -+ * a "finalization copy", so we could do finalizing SHA here and -+ * store the result to *to precalculated. But there's no such -+ * flag as to is reset on copy. */ -+ -+ if (dfrom->update != padlock_copy_update) { -+ /* Recopy the context, as they might have different alignment */ -+ memcpy(PADLOCK_SHA_ALIGN(dto->padlockctx), -+ PADLOCK_SHA_ALIGN(dfrom->padlockctx), -+ PADLOCK_SHA_INITVECTOR_SIZE); -+ } -+ -+ if (dfrom->update == padlock_multi_update) { -+ /* Update total, and copy the buffer */ -+ dto->total = dfrom->total - dfrom->used; -+ dto->buffer = NULL; -+ dto->used = 0; -+ dto->mmap_size = 0; -+ if (dfrom->used != 0) -+ padlock_sha_update(to, dfrom->buffer, dfrom->used); -+ } -+ -+ return 1; -+} -+ -+static int -+padlock_sha_cleanup(EVP_MD_CTX *ctx) -+{ -+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx); -+ -+ if (ddata->update == padlock_multi_update && ddata->buffer != NULL) -+ padlock_free_buffer(ddata->buffer); -+ -+ return 1; -+} -+ -+static const EVP_MD padlock_sha1_md = { -+ NID_sha1, -+ NID_sha1WithRSAEncryption, -+ SHA_DIGEST_LENGTH, -+ 0, -+ padlock_sha1_init, -+ padlock_sha_update, -+ padlock_sha_final, -+ padlock_sha_copy, -+ padlock_sha_cleanup, -+ EVP_PKEY_RSA_method, -+ SHA_CBLOCK, -+ sizeof(struct padlock_digest_data), -+}; -+ -+static const EVP_MD padlock_dss1_md = { -+ NID_dsa, -+ NID_dsaWithSHA1, -+ SHA_DIGEST_LENGTH, -+ 0, -+ padlock_sha1_init, -+ padlock_sha_update, -+ padlock_sha_final, -+ padlock_sha_copy, -+ padlock_sha_cleanup, -+ EVP_PKEY_DSA_method, -+ SHA_CBLOCK, -+ sizeof(struct padlock_digest_data), -+}; -+ -+static const EVP_MD padlock_sha224_md = { -+ NID_sha224, -+ NID_sha224WithRSAEncryption, -+ SHA224_DIGEST_LENGTH, -+ 0, -+ padlock_sha224_init, -+ padlock_sha_update, -+ padlock_sha_final, -+ padlock_sha_copy, -+ padlock_sha_cleanup, -+ EVP_PKEY_RSA_method, -+ SHA_CBLOCK, -+ sizeof(struct padlock_digest_data), -+}; -+ -+static const EVP_MD padlock_sha256_md = { -+ NID_sha256, -+ NID_sha256WithRSAEncryption, -+ SHA256_DIGEST_LENGTH, -+ 0, -+ padlock_sha256_init, -+ padlock_sha_update, -+ padlock_sha_final, -+ padlock_sha_copy, -+ padlock_sha_cleanup, -+ EVP_PKEY_RSA_method, -+ SHA_CBLOCK, -+ sizeof(struct padlock_digest_data), -+}; -+ -+static int padlock_digest_nids[] = { -+#if !defined(OPENSSL_NO_SHA) -+ NID_sha1, -+ NID_dsa, -+#endif -+#if !defined(OPENSSL_NO_SHA256) -+#if !defined(OPENSSL_NO_SHA224) -+ NID_sha224, -+#endif -+ NID_sha256, -+#endif -+}; -+ -+static int padlock_digest_nids_num = sizeof(padlock_digest_nids)/sizeof(padlock_digest_nids[0]); -+ -+static int -+padlock_digests (ENGINE *e, const EVP_MD **digest, const int **nids, int nid) -+{ -+ /* No specific digest => return a list of supported nids ... */ -+ if (!digest) { -+ *nids = padlock_digest_nids; -+ return padlock_digest_nids_num; -+ } -+ -+ /* ... or the requested "digest" otherwise */ -+ switch (nid) { -+#if !defined(OPENSSL_NO_SHA) -+ case NID_sha1: -+ *digest = &padlock_sha1_md; -+ break; -+ case NID_dsa: -+ *digest = &padlock_dss1_md; -+ break; -+#endif -+ -+#if !defined(OPENSSL_NO_SHA256) -+#if !defined(OPENSSL_NO_SHA224) -+ case NID_sha224: -+ *digest = &padlock_sha224_md; -+ break; -+#endif /* OPENSSL_NO_SHA224 */ -+ -+ case NID_sha256: -+ *digest = &padlock_sha256_md; -+ break; -+#endif /* OPENSSL_NO_SHA256 */ -+ -+ default: -+ /* Sorry, we don't support this NID */ -+ *digest = NULL; -+ return 0; -+ } -+ -+ return 1; -+} -+ -+#endif /* OPENSSL_NO_SHA */ -+ -+#ifndef PADLOCK_NO_RNG - /* ===== Random Number Generator ===== */ - /* - * This code is not engaged. The reason is that it does not comply -@@ -1164,7 +1729,7 @@ - * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it - * provide meaningful error control... - */ --/* Wrapper that provides an interface between the API and -+/* Wrapper that provides an interface between the API and - the raw PadLock RNG */ - static int - padlock_rand_bytes(unsigned char *output, int count) -@@ -1212,6 +1777,7 @@ - padlock_rand_bytes, /* pseudorand */ - padlock_rand_status, /* rand status */ - }; -+#endif /* PADLOCK_NO_RNG */ - - #endif /* COMPILE_HW_PADLOCK */ - |