summaryrefslogtreecommitdiffstats
path: root/main/openssl
diff options
context:
space:
mode:
Diffstat (limited to 'main/openssl')
-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 */
-