summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2010-06-04 18:57:47 +0300
committerTimo Teräs <timo.teras@iki.fi>2010-06-04 19:12:22 +0300
commitc6da72282a062d468fa30abd504c8a22d248ab91 (patch)
tree027886e1aeac1d2f727dd589cf1b218291c96fc7
parenta15391804137e41d409891eaafd125481b118ed9 (diff)
downloadaports-c6da72282a062d468fa30abd504c8a22d248ab91.tar.bz2
aports-c6da72282a062d468fa30abd504c8a22d248ab91.tar.xz
main/openssl: update padlock sha patches
New version of padlock sha patches that do not use the seg.fault handler trick. It requires application to properly use oneshot mode context flag, or the high level full operation methods to take use of VIA C7 SHA acceleration. VIA Nano support is included in this patch and supports the partial transforms, so it gets accelerated always. Fixes #215.
-rw-r--r--main/openssl/0001-crypto-hmac-support-EVP_MD_CTX_FLAG_ONESHOT-and-set-.patch80
-rw-r--r--main/openssl/0002-apps-speed-fix-digest-speed-measurement-and-add-hmac.patch373
-rw-r--r--main/openssl/0003-engine-padlock-implement-sha1-sha224-sha256-accelera.patch703
-rw-r--r--main/openssl/APKBUILD10
-rw-r--r--main/openssl/openssl-0.9.8k-padlock-sha.patch821
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 */
-