aboutsummaryrefslogtreecommitdiff
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)
downloadalpine_aports-c6da72282a062d468fa30abd504c8a22d248ab91.tar.bz2
alpine_aports-c6da72282a062d468fa30abd504c8a22d248ab91.tar.xz
alpine_aports-c6da72282a062d468fa30abd504c8a22d248ab91.zip
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 0000000000..6033afc4ed
--- /dev/null
+++ b/main/openssl/0001-crypto-hmac-support-EVP_MD_CTX_FLAG_ONESHOT-and-set-.patch
@@ -0,0 +1,80 @@
1From 8290b2ced17ee3d0e52345180ef4fc6d79bc0751 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
3Date: Fri, 4 Jun 2010 09:48:39 +0300
4Subject: [PATCH 1/3] crypto/hmac: support EVP_MD_CTX_FLAG_ONESHOT and set it properly
5
6Some engines (namely VIA C7 Padlock) work only if EVP_MD_CTX_FLAG_ONESHOT
7is set before final update. This is because some crypto accelerators cannot
8perform non-finalizing transform of the digest.
9
10The usage of EVP_MD_CTX_FLAG_ONESHOT is used semantically slightly
11differently here. It is set before the final EVP_DigestUpdate call, not
12necessarily before EVP_DigestInit call. This will not cause any problems
13though.
14---
15 crypto/hmac/hmac.c | 14 +++++++++++---
16 1 files changed, 11 insertions(+), 3 deletions(-)
17
18diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c
19index cbc1c76..a75a35d 100644
20--- a/crypto/hmac/hmac.c
21+++ b/crypto/hmac/hmac.c
22@@ -68,6 +68,7 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
23 {
24 int i,j,reset=0;
25 unsigned char pad[HMAC_MAX_MD_CBLOCK];
26+ unsigned long flags;
27
28 if (md != NULL)
29 {
30@@ -84,6 +85,7 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
31 OPENSSL_assert(j <= (int)sizeof(ctx->key));
32 if (j < len)
33 {
34+ M_EVP_MD_CTX_set_flags(&ctx->md_ctx, EVP_MD_CTX_FLAG_ONESHOT);
35 EVP_DigestInit_ex(&ctx->md_ctx,md, impl);
36 EVP_DigestUpdate(&ctx->md_ctx,key,len);
37 EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key,
38@@ -104,13 +106,18 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
39 {
40 for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
41 pad[i]=0x36^ctx->key[i];
42+ flags = M_EVP_MD_CTX_test_flags(&ctx->i_ctx, EVP_MD_CTX_FLAG_ONESHOT);
43+ M_EVP_MD_CTX_clear_flags(&ctx->i_ctx, EVP_MD_CTX_FLAG_ONESHOT);
44 EVP_DigestInit_ex(&ctx->i_ctx,md, impl);
45 EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md));
46+ M_EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
47
48 for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
49 pad[i]=0x5c^ctx->key[i];
50+ M_EVP_MD_CTX_clear_flags(&ctx->o_ctx, EVP_MD_CTX_FLAG_ONESHOT);
51 EVP_DigestInit_ex(&ctx->o_ctx,md, impl);
52 EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md));
53+ M_EVP_MD_CTX_set_flags(&ctx->o_ctx, EVP_MD_CTX_FLAG_ONESHOT);
54 }
55 EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx);
56 }
57@@ -166,7 +173,8 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
58
59 if (md == NULL) md=m;
60 HMAC_CTX_init(&c);
61- HMAC_Init(&c,key,key_len,evp_md);
62+ HMAC_CTX_set_flags(&c, EVP_MD_CTX_FLAG_ONESHOT);
63+ HMAC_Init_ex(&c,key,key_len,evp_md,NULL);
64 HMAC_Update(&c,d,n);
65 HMAC_Final(&c,md,md_len);
66 HMAC_CTX_cleanup(&c);
67@@ -176,8 +184,8 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
68 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
69 {
70 EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
71- EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
72- EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
73+ EVP_MD_CTX_set_flags(&ctx->o_ctx, flags & ~EVP_MD_CTX_FLAG_ONESHOT);
74+ EVP_MD_CTX_set_flags(&ctx->md_ctx, flags & ~EVP_MD_CTX_FLAG_ONESHOT);
75 }
76
77 #endif
78--
791.7.0.4
80
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 0000000000..112e883d7f
--- /dev/null
+++ b/main/openssl/0002-apps-speed-fix-digest-speed-measurement-and-add-hmac.patch
@@ -0,0 +1,373 @@
1From 711ae63d2c715a34b15262b4dd4a48b09f02a400 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
3Date: Thu, 3 Jun 2010 09:02:13 +0300
4Subject: [PATCH 2/3] apps/speed: fix digest speed measurement and add hmac-sha1 test
5
6Merge the common code of testing digest speed, and make it reuse
7existing context. Context creation can be heavy operation, and it's
8speed depends on if engine is used or not. As we are measuring the
9digest speed, the context creation overhead should not be included
10like hmac tests do.
11
12This also adds test for hmac-sha1 speed.
13---
14 apps/speed.c | 232 ++++++++++++++++++++++------------------------------------
15 1 files changed, 87 insertions(+), 145 deletions(-)
16
17diff --git a/apps/speed.c b/apps/speed.c
18index 393a7ba..6e375c6 100644
19--- a/apps/speed.c
20+++ b/apps/speed.c
21@@ -285,7 +285,7 @@ static void print_result(int alg,int run_no,int count,double time_used);
22 static int do_multi(int multi);
23 #endif
24
25-#define ALGOR_NUM 28
26+#define ALGOR_NUM 29
27 #define SIZE_NUM 5
28 #define RSA_NUM 4
29 #define DSA_NUM 3
30@@ -300,9 +300,11 @@ static const char *names[ALGOR_NUM]={
31 "aes-128 cbc","aes-192 cbc","aes-256 cbc",
32 "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc",
33 "evp","sha256","sha512",
34- "aes-128 ige","aes-192 ige","aes-256 ige"};
35+ "aes-128 ige","aes-192 ige","aes-256 ige", "hmac(sha1)" };
36 static double results[ALGOR_NUM][SIZE_NUM];
37 static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
38+static unsigned char *buf=NULL,*buf2=NULL;
39+static long c[ALGOR_NUM][SIZE_NUM];
40 #ifndef OPENSSL_NO_RSA
41 static double rsa_results[RSA_NUM][2];
42 #endif
43@@ -478,6 +480,66 @@ static double Time_F(int s)
44 }
45 #endif /* if defined(OPENSSL_SYS_NETWARE) */
46
47+#ifndef SIGALRM
48+#define COND(d) (count < (d))
49+#else
50+#define COND(c) (run)
51+#endif /* SIGALRM */
52+
53+static void Test_Digest(int digest, const EVP_MD *type)
54+{
55+ unsigned char md[EVP_MAX_MD_SIZE];
56+ int j, count;
57+ double d=0.0;
58+ EVP_MD_CTX ctx;
59+
60+ EVP_MD_CTX_init(&ctx);
61+ EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
62+
63+ for (j=0; j<SIZE_NUM; j++)
64+ {
65+ print_message(names[digest],c[digest][j],lengths[j]);
66+ Time_F(START);
67+ for (count=0,run=1; COND(c[digest][j]); count++)
68+ {
69+ EVP_DigestInit_ex(&ctx, type, NULL);
70+ EVP_DigestUpdate(&ctx, buf, (unsigned long)lengths[j]);
71+ EVP_DigestFinal_ex(&ctx, md, NULL);
72+ }
73+ d=Time_F(STOP);
74+ print_result(digest,j,count,d);
75+ }
76+
77+ EVP_MD_CTX_cleanup(&ctx);
78+}
79+
80+static void Test_HMAC(int digest, const EVP_MD *type)
81+{
82+ unsigned char md[EVP_MAX_MD_SIZE];
83+ HMAC_CTX hctx;
84+ int j, count;
85+ double d=0.0;
86+
87+ HMAC_CTX_init(&hctx);
88+ HMAC_CTX_set_flags(&hctx, EVP_MD_CTX_FLAG_ONESHOT);
89+ HMAC_Init_ex(&hctx,(unsigned char *)"This is a key...",
90+ 16,type, NULL);
91+
92+ for (j=0; j<SIZE_NUM; j++)
93+ {
94+ print_message(names[digest],c[digest][j],lengths[j]);
95+ Time_F(START);
96+ for (count=0,run=1; COND(c[digest][j]); count++)
97+ {
98+ HMAC_Init_ex(&hctx,NULL,0,NULL,NULL);
99+ HMAC_Update(&hctx,buf,lengths[j]);
100+ HMAC_Final(&hctx,md,NULL);
101+ }
102+ d=Time_F(STOP);
103+ print_result(digest,j,count,d);
104+ }
105+ HMAC_CTX_cleanup(&hctx);
106+}
107
108 #ifndef OPENSSL_NO_ECDH
109 static const int KDF1_SHA1_len = 20;
110@@ -503,7 +565,6 @@ int MAIN(int argc, char **argv)
111 #ifndef OPENSSL_NO_ENGINE
112 ENGINE *e = NULL;
113 #endif
114- unsigned char *buf=NULL,*buf2=NULL;
115 int mret=1;
116 long count=0,save_count=0;
117 int i,j,k;
118@@ -514,31 +575,6 @@ int MAIN(int argc, char **argv)
119 unsigned rsa_num;
120 #endif
121 unsigned char md[EVP_MAX_MD_SIZE];
122-#ifndef OPENSSL_NO_MD2
123- unsigned char md2[MD2_DIGEST_LENGTH];
124-#endif
125-#ifndef OPENSSL_NO_MDC2
126- unsigned char mdc2[MDC2_DIGEST_LENGTH];
127-#endif
128-#ifndef OPENSSL_NO_MD4
129- unsigned char md4[MD4_DIGEST_LENGTH];
130-#endif
131-#ifndef OPENSSL_NO_MD5
132- unsigned char md5[MD5_DIGEST_LENGTH];
133- unsigned char hmac[MD5_DIGEST_LENGTH];
134-#endif
135-#ifndef OPENSSL_NO_SHA
136- unsigned char sha[SHA_DIGEST_LENGTH];
137-#ifndef OPENSSL_NO_SHA256
138- unsigned char sha256[SHA256_DIGEST_LENGTH];
139-#endif
140-#ifndef OPENSSL_NO_SHA512
141- unsigned char sha512[SHA512_DIGEST_LENGTH];
142-#endif
143-#endif
144-#ifndef OPENSSL_NO_RIPEMD
145- unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
146-#endif
147 #ifndef OPENSSL_NO_RC4
148 RC4_KEY rc4_ks;
149 #endif
150@@ -635,8 +671,8 @@ int MAIN(int argc, char **argv)
151 #define D_IGE_128_AES 25
152 #define D_IGE_192_AES 26
153 #define D_IGE_256_AES 27
154+#define D_HMAC_SHA1 28
155 double d=0.0;
156- long c[ALGOR_NUM][SIZE_NUM];
157 #define R_DSA_512 0
158 #define R_DSA_1024 1
159 #define R_DSA_2048 2
160@@ -945,6 +981,8 @@ int MAIN(int argc, char **argv)
161 doit[D_SHA256]=1,
162 doit[D_SHA512]=1;
163 else
164+ if (strcmp(*argv,"hmac-sha1") == 0) doit[D_HMAC_SHA1]=1;
165+ else
166 #ifndef OPENSSL_NO_SHA256
167 if (strcmp(*argv,"sha256") == 0) doit[D_SHA256]=1;
168 else
169@@ -1158,6 +1196,9 @@ int MAIN(int argc, char **argv)
170 #endif
171 #ifndef OPENSSL_NO_SHA1
172 BIO_printf(bio_err,"sha1 ");
173+#ifndef OPENSSL_NO_HMAC
174+ BIO_printf(bio_err,"hmac-sha1 ");
175+#endif
176 #endif
177 #ifndef OPENSSL_NO_SHA256
178 BIO_printf(bio_err,"sha256 ");
179@@ -1420,6 +1461,7 @@ int MAIN(int argc, char **argv)
180 c[D_IGE_128_AES][0]=count;
181 c[D_IGE_192_AES][0]=count;
182 c[D_IGE_256_AES][0]=count;
183+ c[D_HMAC_SHA1][0]=count;
184
185 for (i=1; i<SIZE_NUM; i++)
186 {
187@@ -1432,6 +1474,7 @@ int MAIN(int argc, char **argv)
188 c[D_RMD160][i]=c[D_RMD160][0]*4*lengths[0]/lengths[i];
189 c[D_SHA256][i]=c[D_SHA256][0]*4*lengths[0]/lengths[i];
190 c[D_SHA512][i]=c[D_SHA512][0]*4*lengths[0]/lengths[i];
191+ c[D_HMAC_SHA1][i]=c[D_HMAC_SHA1][0]*4*lengths[0]/lengths[i];
192 }
193 for (i=1; i<SIZE_NUM; i++)
194 {
195@@ -1606,160 +1649,59 @@ int MAIN(int argc, char **argv)
196 }
197 #endif
198
199-#define COND(d) (count < (d))
200-#define COUNT(d) (d)
201 #else
202 /* not worth fixing */
203 # error "You cannot disable DES on systems without SIGALRM."
204 #endif /* OPENSSL_NO_DES */
205-#else
206-#define COND(c) (run)
207-#define COUNT(d) (count)
208+#else /* SIGALRM */
209 signal(SIGALRM,sig_done);
210-#endif /* SIGALRM */
211+#endif
212
213 #ifndef OPENSSL_NO_MD2
214 if (doit[D_MD2])
215- {
216- for (j=0; j<SIZE_NUM; j++)
217- {
218- print_message(names[D_MD2],c[D_MD2][j],lengths[j]);
219- Time_F(START);
220- for (count=0,run=1; COND(c[D_MD2][j]); count++)
221- EVP_Digest(buf,(unsigned long)lengths[j],&(md2[0]),NULL,EVP_md2(),NULL);
222- d=Time_F(STOP);
223- print_result(D_MD2,j,count,d);
224- }
225- }
226+ Test_Digest(D_MD2, EVP_md2());
227 #endif
228 #ifndef OPENSSL_NO_MDC2
229 if (doit[D_MDC2])
230- {
231- for (j=0; j<SIZE_NUM; j++)
232- {
233- print_message(names[D_MDC2],c[D_MDC2][j],lengths[j]);
234- Time_F(START);
235- for (count=0,run=1; COND(c[D_MDC2][j]); count++)
236- EVP_Digest(buf,(unsigned long)lengths[j],&(mdc2[0]),NULL,EVP_mdc2(),NULL);
237- d=Time_F(STOP);
238- print_result(D_MDC2,j,count,d);
239- }
240- }
241+ Test_Digest(D_MDC2, EVP_mdc2());
242 #endif
243
244 #ifndef OPENSSL_NO_MD4
245 if (doit[D_MD4])
246- {
247- for (j=0; j<SIZE_NUM; j++)
248- {
249- print_message(names[D_MD4],c[D_MD4][j],lengths[j]);
250- Time_F(START);
251- for (count=0,run=1; COND(c[D_MD4][j]); count++)
252- EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md4[0]),NULL,EVP_md4(),NULL);
253- d=Time_F(STOP);
254- print_result(D_MD4,j,count,d);
255- }
256- }
257+ Test_Digest(D_MD4, EVP_md4());
258 #endif
259
260 #ifndef OPENSSL_NO_MD5
261 if (doit[D_MD5])
262- {
263- for (j=0; j<SIZE_NUM; j++)
264- {
265- print_message(names[D_MD5],c[D_MD5][j],lengths[j]);
266- Time_F(START);
267- for (count=0,run=1; COND(c[D_MD5][j]); count++)
268- EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md5[0]),NULL,EVP_get_digestbyname("md5"),NULL);
269- d=Time_F(STOP);
270- print_result(D_MD5,j,count,d);
271- }
272- }
273+ Test_Digest(D_MD5, EVP_md5());
274 #endif
275
276 #if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_HMAC)
277 if (doit[D_HMAC])
278- {
279- HMAC_CTX hctx;
280-
281- HMAC_CTX_init(&hctx);
282- HMAC_Init_ex(&hctx,(unsigned char *)"This is a key...",
283- 16,EVP_md5(), NULL);
284-
285- for (j=0; j<SIZE_NUM; j++)
286- {
287- print_message(names[D_HMAC],c[D_HMAC][j],lengths[j]);
288- Time_F(START);
289- for (count=0,run=1; COND(c[D_HMAC][j]); count++)
290- {
291- HMAC_Init_ex(&hctx,NULL,0,NULL,NULL);
292- HMAC_Update(&hctx,buf,lengths[j]);
293- HMAC_Final(&hctx,&(hmac[0]),NULL);
294- }
295- d=Time_F(STOP);
296- print_result(D_HMAC,j,count,d);
297- }
298- HMAC_CTX_cleanup(&hctx);
299- }
300+ Test_HMAC(D_HMAC, EVP_md5());
301+#endif
302+#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_HMAC)
303+ if (doit[D_HMAC_SHA1])
304+ Test_HMAC(D_HMAC_SHA1, EVP_sha1());
305 #endif
306 #ifndef OPENSSL_NO_SHA
307 if (doit[D_SHA1])
308- {
309- for (j=0; j<SIZE_NUM; j++)
310- {
311- print_message(names[D_SHA1],c[D_SHA1][j],lengths[j]);
312- Time_F(START);
313- for (count=0,run=1; COND(c[D_SHA1][j]); count++)
314- EVP_Digest(buf,(unsigned long)lengths[j],&(sha[0]),NULL,EVP_sha1(),NULL);
315- d=Time_F(STOP);
316- print_result(D_SHA1,j,count,d);
317- }
318- }
319+ Test_Digest(D_SHA1, EVP_sha1());
320
321 #ifndef OPENSSL_NO_SHA256
322 if (doit[D_SHA256])
323- {
324- for (j=0; j<SIZE_NUM; j++)
325- {
326- print_message(names[D_SHA256],c[D_SHA256][j],lengths[j]);
327- Time_F(START);
328- for (count=0,run=1; COND(c[D_SHA256][j]); count++)
329- SHA256(buf,lengths[j],sha256);
330- d=Time_F(STOP);
331- print_result(D_SHA256,j,count,d);
332- }
333- }
334+ Test_Digest(D_SHA256, EVP_sha256());
335 #endif
336
337 #ifndef OPENSSL_NO_SHA512
338 if (doit[D_SHA512])
339- {
340- for (j=0; j<SIZE_NUM; j++)
341- {
342- print_message(names[D_SHA512],c[D_SHA512][j],lengths[j]);
343- Time_F(START);
344- for (count=0,run=1; COND(c[D_SHA512][j]); count++)
345- SHA512(buf,lengths[j],sha512);
346- d=Time_F(STOP);
347- print_result(D_SHA512,j,count,d);
348- }
349- }
350+ Test_Digest(D_SHA512, EVP_sha512());
351 #endif
352
353 #endif
354 #ifndef OPENSSL_NO_RIPEMD
355 if (doit[D_RMD160])
356- {
357- for (j=0; j<SIZE_NUM; j++)
358- {
359- print_message(names[D_RMD160],c[D_RMD160][j],lengths[j]);
360- Time_F(START);
361- for (count=0,run=1; COND(c[D_RMD160][j]); count++)
362- EVP_Digest(buf,(unsigned long)lengths[j],&(rmd160[0]),NULL,EVP_ripemd160(),NULL);
363- d=Time_F(STOP);
364- print_result(D_RMD160,j,count,d);
365- }
366- }
367+ Test_Digest(D_RMD160, EVP_ripemd160());
368 #endif
369 #ifndef OPENSSL_NO_RC4
370 if (doit[D_RC4])
371--
3721.7.0.4
373
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 0000000000..993c9b1780
--- /dev/null
+++ b/main/openssl/0003-engine-padlock-implement-sha1-sha224-sha256-accelera.patch
@@ -0,0 +1,703 @@
1From 9fe6001d9b7a35a12a6a282677c79fd56eeaf99c Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
3Date: Fri, 4 Jun 2010 10:00:15 +0300
4Subject: [PATCH 3/3] engine/padlock: implement sha1/sha224/sha256 acceleration
5
6Limited support for VIA C7 that works only when EVP_MD_CTX_FLAG_ONESHOT
7is used appropriately (as done by EVP_Digest, and my previous HMAC patch).
8
9Full support for VIA Nano including partial transformation.
10
11Benchmarks from VIA Nano 1.6GHz, done with including the previous HMAC and
12apps/speed patches done. From single run, error margin of about 100-200k.
13
14No padlock
15
16type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
17sha1 20057.60k 51514.05k 99721.39k 130167.81k 142811.14k
18sha256 7757.72k 16907.18k 28937.05k 35181.23k 37568.51k
19hmac(sha1) 8582.53k 27644.69k 70402.30k 114602.67k 140167.85k
20
21With the patch
22
23sha1 37713.77k 114562.71k 259637.33k 379907.41k 438818.13k
24sha256 34262.86k 103233.75k 232476.07k 338386.60k 389860.01k
25hmac(sha1) 8424.70k 31475.11k 104036.10k 245559.30k 406667.26k
26---
27 crypto/engine/eng_padlock.c | 597 +++++++++++++++++++++++++++++++++++++++---
28 1 files changed, 554 insertions(+), 43 deletions(-)
29
30diff --git a/crypto/engine/eng_padlock.c b/crypto/engine/eng_padlock.c
31index 743558a..28ec0f7 100644
32--- a/crypto/engine/eng_padlock.c
33+++ b/crypto/engine/eng_padlock.c
34@@ -3,6 +3,9 @@
35 * Written by Michal Ludvig <michal@logix.cz>
36 * http://www.logix.cz/michal
37 *
38+ * SHA support by Timo Teras <timo.teras@iki.fi>. Portions based on
39+ * code originally written by Michal Ludvig.
40+ *
41 * Big thanks to Andy Polyakov for a help with optimization,
42 * assembler fixes, port to MS Windows and a lot of other
43 * valuable work on this engine!
44@@ -74,12 +77,23 @@
45 #ifndef OPENSSL_NO_AES
46 #include <openssl/aes.h>
47 #endif
48+#ifndef OPENSSL_NO_SHA
49+#include <openssl/sha.h>
50+#endif
51 #include <openssl/rand.h>
52 #include <openssl/err.h>
53
54 #ifndef OPENSSL_NO_HW
55 #ifndef OPENSSL_NO_HW_PADLOCK
56
57+/* PadLock RNG is disabled by default */
58+#define PADLOCK_NO_RNG 1
59+
60+/* No ASM routines for SHA in MSC yet */
61+#ifdef _MSC_VER
62+#define OPENSSL_NO_SHA
63+#endif
64+
65 /* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
66 #if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
67 # ifndef OPENSSL_NO_DYNAMIC_ENGINE
68@@ -138,58 +152,40 @@ static int padlock_available(void);
69 static int padlock_init(ENGINE *e);
70
71 /* RNG Stuff */
72+#ifndef PADLOCK_NO_RNG
73 static RAND_METHOD padlock_rand;
74-
75-/* Cipher Stuff */
76-#ifndef OPENSSL_NO_AES
77-static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
78 #endif
79
80 /* Engine names */
81 static const char *padlock_id = "padlock";
82 static char padlock_name[100];
83
84-/* Available features */
85-static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
86-static int padlock_use_rng = 0; /* Random Number Generator */
87-#ifndef OPENSSL_NO_AES
88-static int padlock_aes_align_required = 1;
89-#endif
90-
91-/* ===== Engine "management" functions ===== */
92+static int padlock_bind_helper(ENGINE *e);
93
94-/* Prepare the ENGINE structure for registration */
95-static int
96-padlock_bind_helper(ENGINE *e)
97-{
98- /* Check available features */
99- padlock_available();
100-
101-#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
102- padlock_use_rng=0;
103-#endif
104-
105- /* Generate a nice engine name with available features */
106- BIO_snprintf(padlock_name, sizeof(padlock_name),
107- "VIA PadLock (%s, %s)",
108- padlock_use_rng ? "RNG" : "no-RNG",
109- padlock_use_ace ? "ACE" : "no-ACE");
110+ /* Available features */
111+enum padlock_flags {
112+ PADLOCK_RNG = 0x01,
113+ PADLOCK_ACE = 0x02,
114+ PADLOCK_ACE2 = 0x04,
115+ PADLOCK_PHE = 0x08,
116+ PADLOCK_PMM = 0x10,
117+ PADLOCK_NANO = 0x20,
118+};
119+enum padlock_flags padlock_flags;
120
121- /* Register everything or return with an error */
122- if (!ENGINE_set_id(e, padlock_id) ||
123- !ENGINE_set_name(e, padlock_name) ||
124+#define PADLOCK_HAVE_RNG (padlock_flags & PADLOCK_RNG)
125+#define PADLOCK_HAVE_ACE (padlock_flags & (PADLOCK_ACE|PADLOCK_ACE2))
126+#define PADLOCK_HAVE_ACE1 (padlock_flags & PADLOCK_ACE)
127+#define PADLOCK_HAVE_ACE2 (padlock_flags & PADLOCK_ACE2)
128+#define PADLOCK_HAVE_PHE (padlock_flags & PADLOCK_PHE)
129+#define PADLOCK_HAVE_PMM (padlock_flags & PADLOCK_PMM)
130+#define PADLOCK_HAVE_NANO (padlock_flags & PADLOCK_NANO)
131
132- !ENGINE_set_init_function(e, padlock_init) ||
133 #ifndef OPENSSL_NO_AES
134- (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
135+static int padlock_aes_align_required = 1;
136 #endif
137- (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
138- return 0;
139- }
140
141- /* Everything looks good */
142- return 1;
143-}
144+/* ===== Engine "management" functions ===== */
145
146 /* Constructor */
147 static ENGINE *
148@@ -213,7 +209,7 @@ ENGINE_padlock(void)
149 static int
150 padlock_init(ENGINE *e)
151 {
152- return (padlock_use_rng || padlock_use_ace);
153+ return padlock_flags;
154 }
155
156 /* This stuff is needed if this ENGINE is being compiled into a self-contained
157@@ -365,10 +361,20 @@ padlock_available(void)
158 : "+a"(eax), "=d"(edx) : : "ecx");
159
160 /* Fill up some flags */
161- padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
162- padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
163+ padlock_flags |= ((edx & (0x3<<3)) ? PADLOCK_RNG : 0);
164+ padlock_flags |= ((edx & (0x3<<7)) ? PADLOCK_ACE : 0);
165+ padlock_flags |= ((edx & (0x3<<9)) ? PADLOCK_ACE2 : 0);
166+ padlock_flags |= ((edx & (0x3<<11)) ? PADLOCK_PHE : 0);
167+ padlock_flags |= ((edx & (0x3<<13)) ? PADLOCK_PMM : 0);
168+
169+ /* Check for VIA Nano CPU */
170+ eax = 0x00000001;
171+ asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
172+ : "+a"(eax) : : "ecx", "edx");
173+ if ((eax | 0x000F) == 0x06FF)
174+ padlock_flags |= PADLOCK_NANO;
175
176- return padlock_use_ace + padlock_use_rng;
177+ return padlock_flags;
178 }
179
180 #ifndef OPENSSL_NO_AES
181@@ -1157,6 +1163,454 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
182
183 #endif /* OPENSSL_NO_AES */
184
185+#ifndef OPENSSL_NO_SHA
186+
187+static inline void
188+padlock_copy_bswap(void *dst, void *src, size_t count)
189+{
190+ uint32_t *udst = dst, *usrc = src;
191+ unsigned int reg;
192+ int i = 0;
193+
194+ for (i = 0; i < count; i++) {
195+ reg = usrc[i];
196+ asm volatile("bswapl %0" : "+&r"(reg));
197+ udst[i] = reg;
198+ }
199+}
200+
201+#define PADLOCK_SHA_ALIGN(dd) (uint32_t*)(((uintptr_t)(dd) + 15) & ~15)
202+#define PADLOCK_SHA_HWCTX (128+16)
203+
204+static void
205+padlock_sha1(void *hwctx, const void *buf, uint32_t total, uint32_t now)
206+{
207+ uint32_t pos = total - now;
208+
209+ asm volatile ("xsha1"
210+ : "+S"(buf), "+D"(hwctx), "+a"(pos), "+c"(total)
211+ : : "memory");
212+}
213+
214+static void
215+padlock_sha1_partial(void *hwctx, const void *buf, uint32_t blocks)
216+{
217+ asm volatile ("xsha1"
218+ : "+S"(buf), "+D"(hwctx), "+c"(blocks)
219+ : "a"(-1) : "memory");
220+}
221+
222+static int padlock_sha1_init(EVP_MD_CTX *ctx)
223+{
224+ return SHA1_Init(ctx->md_data);
225+}
226+
227+static int padlock_sha1_update(EVP_MD_CTX *ctx, const void *data,
228+ size_t len)
229+{
230+ unsigned char hwctx[PADLOCK_SHA_HWCTX];
231+ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx);
232+ SHA_CTX *c = ctx->md_data;
233+ uint_fast64_t total;
234+ const unsigned char *p = data;
235+ unsigned int l = 0;
236+
237+ /* Calculate total length (Nl,Nh) is length in bits */
238+ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3);
239+ total += len;
240+
241+ if ((ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) &&
242+ (total <= 0xfffffffe)) {
243+ if (c->num != 0) {
244+ l = (len < SHA_CBLOCK) ? len : SHA_CBLOCK;
245+ if (!SHA1_Update(c, data, l))
246+ return 0;
247+ p += l;
248+ if (c->num != 0) {
249+ p = (unsigned char *) c->data;
250+ len = c->num;
251+ l = 0;
252+ }
253+ }
254+ memcpy(aligned, &c->h0, 5 * sizeof(SHA_LONG));
255+ padlock_sha1(aligned, p, total, len - l);
256+ memcpy(&c->h0, aligned, 5 * sizeof(SHA_LONG));
257+ c->num = -1;
258+ return 1;
259+ }
260+
261+ return SHA1_Update(c, data, len);
262+}
263+
264+static int padlock_nano_sha1_update(EVP_MD_CTX *ctx, const void *data,
265+ size_t len)
266+{
267+ unsigned char hwctx[PADLOCK_SHA_HWCTX];
268+ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx);
269+ SHA_CTX *c = ctx->md_data;
270+ uint_fast64_t total;
271+ unsigned char *p;
272+ unsigned int n;
273+
274+ /* Calculate total length (Nl,Nh) is length in bits */
275+ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3);
276+ total += len;
277+ c->Nh = total >> 29;
278+ c->Nl = (total << 3) & 0xffffffffUL;
279+
280+ memcpy(aligned, &c->h0, 5 * sizeof(SHA_LONG));
281+
282+ /* Check partial data */
283+ n = c->num;
284+ if (n) {
285+ p = (unsigned char *) c->data;
286+ if (len >= SHA_CBLOCK || len+n >= SHA_CBLOCK) {
287+ memcpy(p+n, data, SHA_CBLOCK-n);
288+ padlock_sha1_partial(aligned, p, 1);
289+ n = SHA_CBLOCK - n;
290+ data += n;
291+ len -= n;
292+ c->num = 0;
293+ memset(p, 0, SHA_CBLOCK);
294+ } else {
295+ memcpy(p+n, data, len);
296+ c->num += (unsigned int)len;
297+ return 1;
298+ }
299+ }
300+
301+ /* Can we finalize straight away? */
302+ if ((ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) &&
303+ (total <= 0xfffffffe)) {
304+ padlock_sha1(aligned, data, total, len);
305+ memcpy(&c->h0, aligned, 5 * sizeof(SHA_LONG));
306+ c->num = -1;
307+ return 1;
308+ }
309+
310+ /* Use nonfinalizing update */
311+ n = len / SHA_CBLOCK;
312+ if (n != 0) {
313+ padlock_sha1_partial(aligned, data, n);
314+ data += n * SHA_CBLOCK;
315+ len -= n * SHA_CBLOCK;
316+ }
317+ memcpy(&c->h0, aligned, 5 * sizeof(SHA_LONG));
318+
319+ /* Buffer remaining bytes */
320+ if (len) {
321+ memcpy(c->data, data, len);
322+ c->num = len;
323+ }
324+
325+ return 1;
326+}
327+
328+static int padlock_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
329+{
330+ SHA_CTX *c = ctx->md_data;
331+ uint_fast64_t total;
332+
333+ if (c->num == -1) {
334+ padlock_copy_bswap(md, &c->h0, 5);
335+ c->num = 0;
336+ return 1;
337+ }
338+
339+ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3);
340+ if (total <= 0xfffffffe) {
341+ unsigned char hwctx[PADLOCK_SHA_HWCTX];
342+ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx);
343+
344+ memcpy(aligned, &c->h0, 5 * sizeof(SHA_LONG));
345+ padlock_sha1(aligned, c->data, total, c->num);
346+ padlock_copy_bswap(md, aligned, 5);
347+ c->num = 0;
348+ return 1;
349+ }
350+
351+ return SHA1_Final(md, c);
352+}
353+
354+static EVP_MD padlock_sha1_md = {
355+ NID_sha1,
356+ NID_sha1WithRSAEncryption,
357+ SHA_DIGEST_LENGTH,
358+ 0,
359+ padlock_sha1_init,
360+ padlock_sha1_update,
361+ padlock_sha1_final,
362+ NULL,
363+ NULL,
364+ EVP_PKEY_RSA_method,
365+ SHA_CBLOCK,
366+ sizeof(SHA_CTX),
367+};
368+
369+static EVP_MD padlock_dss1_md = {
370+ NID_dsa,
371+ NID_dsaWithSHA1,
372+ SHA_DIGEST_LENGTH,
373+ 0,
374+ padlock_sha1_init,
375+ padlock_sha1_update,
376+ padlock_sha1_final,
377+ NULL,
378+ NULL,
379+ EVP_PKEY_DSA_method,
380+ SHA_CBLOCK,
381+ sizeof(SHA_CTX),
382+};
383+
384+
385+#if !defined(OPENSSL_NO_SHA256)
386+
387+static void
388+padlock_sha256(void *hwctx, const void *buf, uint32_t total, uint32_t now)
389+{
390+ uint32_t pos = total - now;
391+
392+ asm volatile ("xsha256"
393+ : "+S"(buf), "+D"(hwctx), "+a"(pos), "+c"(total)
394+ : : "memory");
395+}
396+
397+static void
398+padlock_sha256_partial(void *hwctx, const void *buf, uint32_t blocks)
399+{
400+ asm volatile ("xsha256"
401+ : "+S"(buf), "+D"(hwctx), "+c"(blocks)
402+ : "a"(-1) : "memory");
403+}
404+
405+static int padlock_sha256_update(EVP_MD_CTX *ctx, const void *data,
406+ size_t len)
407+{
408+ unsigned char hwctx[PADLOCK_SHA_HWCTX];
409+ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx);
410+ SHA256_CTX *c = ctx->md_data;
411+ uint_fast64_t total;
412+ const unsigned char *p = data;
413+ unsigned int l = 0;
414+
415+ /* Calculate total length (Nl,Nh) is length in bits */
416+ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3);
417+ total += len;
418+
419+ if ((ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) &&
420+ (total <= 0xfffffffe)) {
421+ if (c->num != 0) {
422+ l = (len < SHA256_CBLOCK) ? len : SHA256_CBLOCK;
423+ if (!SHA256_Update(c, data, l))
424+ return 0;
425+ p += l;
426+ if (c->num != 0) {
427+ p = (unsigned char *) c->data;
428+ len = c->num;
429+ l = 0;
430+ }
431+ }
432+ memcpy(aligned, c->h, sizeof(c->h));
433+ padlock_sha256(aligned, p, total, len - l);
434+ memcpy(c->h, aligned, sizeof(c->h));
435+ c->num = -1;
436+ return 1;
437+ }
438+
439+ return SHA256_Update(c, data, len);
440+}
441+
442+static int padlock_nano_sha256_update(EVP_MD_CTX *ctx, const void *data,
443+ size_t len)
444+{
445+ unsigned char hwctx[PADLOCK_SHA_HWCTX];
446+ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx);
447+ SHA256_CTX *c = ctx->md_data;
448+ uint_fast64_t total;
449+ unsigned char *p;
450+ unsigned int n;
451+
452+ /* Calculate total length (Nl,Nh) is length in bits */
453+ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3);
454+ total += len;
455+ c->Nh = total >> 29;
456+ c->Nl = (total << 3) & 0xffffffffUL;
457+
458+ memcpy(aligned, c->h, sizeof(c->h));
459+
460+ /* Check partial data */
461+ n = c->num;
462+ if (n) {
463+ p = (unsigned char *) c->data;
464+ if (len >= SHA256_CBLOCK || len+n >= SHA256_CBLOCK) {
465+ memcpy(p+n, data, SHA256_CBLOCK-n);
466+ padlock_sha256_partial(aligned, p, 1);
467+ n = SHA256_CBLOCK - n;
468+ data += n;
469+ len -= n;
470+ c->num = 0;
471+ memset(p, 0, SHA256_CBLOCK);
472+ } else {
473+ memcpy(p+n, data, len);
474+ c->num += (unsigned int)len;
475+ return 1;
476+ }
477+ }
478+
479+ /* Can we finalize straight away? */
480+ if ((ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) &&
481+ (total <= 0xfffffffe)) {
482+ padlock_sha256(aligned, data, total, len);
483+ memcpy(c->h, aligned, sizeof(c->h));
484+ c->num = -1;
485+ return 1;
486+ }
487+
488+ /* Use nonfinalizing update */
489+ n = len / SHA256_CBLOCK;
490+ if (n != 0) {
491+ padlock_sha256_partial(aligned, data, n);
492+ data += n * SHA256_CBLOCK;
493+ len -= n * SHA256_CBLOCK;
494+ }
495+ memcpy(c->h, aligned, sizeof(c->h));
496+
497+ /* Buffer remaining bytes */
498+ if (len) {
499+ memcpy(c->data, data, len);
500+ c->num = len;
501+ }
502+
503+ return 1;
504+}
505+
506+static int padlock_sha256_final(EVP_MD_CTX *ctx, unsigned char *md)
507+{
508+ SHA256_CTX *c = ctx->md_data;
509+ uint_fast64_t total;
510+
511+ if (c->num == -1) {
512+ padlock_copy_bswap(md, c->h, sizeof(c->h)/sizeof(c->h[0]));
513+ c->num = 0;
514+ return 1;
515+ }
516+
517+ total = (((uint_fast64_t) c->Nh) << 29) + (c->Nl >> 3);
518+ if (total <= 0xfffffffe) {
519+ unsigned char hwctx[PADLOCK_SHA_HWCTX];
520+ uint32_t *aligned = PADLOCK_SHA_ALIGN(hwctx);
521+
522+ memcpy(aligned, c->h, sizeof(c->h));
523+ padlock_sha256(aligned, c->data, total, c->num);
524+ padlock_copy_bswap(md, aligned, sizeof(c->h)/sizeof(c->h[0]));
525+ c->num = 0;
526+ return 1;
527+ }
528+
529+ return SHA256_Final(md, c);
530+}
531+
532+#if !defined(OPENSSL_NO_SHA224)
533+
534+static int padlock_sha224_init(EVP_MD_CTX *ctx)
535+{
536+ return SHA224_Init(ctx->md_data);
537+}
538+
539+static EVP_MD padlock_sha224_md = {
540+ NID_sha224,
541+ NID_sha224WithRSAEncryption,
542+ SHA224_DIGEST_LENGTH,
543+ 0,
544+ padlock_sha224_init,
545+ padlock_sha256_update,
546+ padlock_sha256_final,
547+ NULL,
548+ NULL,
549+ EVP_PKEY_RSA_method,
550+ SHA_CBLOCK,
551+ sizeof(SHA256_CTX),
552+};
553+#endif /* !OPENSSL_NO_SHA224 */
554+
555+static int padlock_sha256_init(EVP_MD_CTX *ctx)
556+{
557+ return SHA256_Init(ctx->md_data);
558+}
559+
560+static EVP_MD padlock_sha256_md = {
561+ NID_sha256,
562+ NID_sha256WithRSAEncryption,
563+ SHA256_DIGEST_LENGTH,
564+ 0,
565+ padlock_sha256_init,
566+ padlock_sha256_update,
567+ padlock_sha256_final,
568+ NULL,
569+ NULL,
570+ EVP_PKEY_RSA_method,
571+ SHA_CBLOCK,
572+ sizeof(SHA256_CTX),
573+};
574+#endif /* !OPENSSL_NO_SHA256 */
575+
576+static int padlock_digest_nids[] = {
577+#if !defined(OPENSSL_NO_SHA)
578+ NID_sha1,
579+ NID_dsa,
580+#endif
581+#if !defined(OPENSSL_NO_SHA256)
582+#if !defined(OPENSSL_NO_SHA224)
583+ NID_sha224,
584+#endif
585+ NID_sha256,
586+#endif
587+};
588+
589+static int padlock_digest_nids_num = sizeof(padlock_digest_nids)/sizeof(padlock_digest_nids[0]);
590+
591+static int
592+padlock_digests (ENGINE *e, const EVP_MD **digest, const int **nids, int nid)
593+{
594+ /* No specific digest => return a list of supported nids ... */
595+ if (!digest) {
596+ *nids = padlock_digest_nids;
597+ return padlock_digest_nids_num;
598+ }
599+
600+ /* ... or the requested "digest" otherwise */
601+ switch (nid) {
602+#if !defined(OPENSSL_NO_SHA)
603+ case NID_sha1:
604+ *digest = &padlock_sha1_md;
605+ break;
606+ case NID_dsa:
607+ *digest = &padlock_dss1_md;
608+ break;
609+#endif
610+#if !defined(OPENSSL_NO_SHA256)
611+#if !defined(OPENSSL_NO_SHA224)
612+ case NID_sha224:
613+ *digest = &padlock_sha224_md;
614+ break;
615+#endif /* OPENSSL_NO_SHA224 */
616+ case NID_sha256:
617+ *digest = &padlock_sha256_md;
618+ break;
619+#endif /* OPENSSL_NO_SHA256 */
620+ default:
621+ /* Sorry, we don't support this NID */
622+ *digest = NULL;
623+ return 0;
624+ }
625+
626+ return 1;
627+}
628+
629+#endif /* OPENSSL_NO_SHA */
630+
631+#ifndef PADLOCK_NO_RNG
632+
633 /* ===== Random Number Generator ===== */
634 /*
635 * This code is not engaged. The reason is that it does not comply
636@@ -1213,7 +1667,64 @@ static RAND_METHOD padlock_rand = {
637 padlock_rand_status, /* rand status */
638 };
639
640+#endif /* PADLOCK_NO_RNG */
641+
642 #endif /* COMPILE_HW_PADLOCK */
643
644+
645+/* Prepare the ENGINE structure for registration */
646+static int
647+padlock_bind_helper(ENGINE *e)
648+{
649+ /* Check available features */
650+ padlock_available();
651+
652+ /* Generate a nice engine name with available features */
653+ BIO_snprintf(padlock_name, sizeof(padlock_name),
654+ "VIA PadLock: %s%s%s%s%s%s",
655+ padlock_flags ? "" : "not supported",
656+ PADLOCK_HAVE_RNG ? "RNG " : "",
657+ PADLOCK_HAVE_ACE ? (PADLOCK_HAVE_ACE2 ? "ACE2 " : "ACE ") : "",
658+ PADLOCK_HAVE_PHE ? "PHE " : "",
659+ PADLOCK_HAVE_PMM ? "PMM " : "",
660+ PADLOCK_HAVE_NANO ? "NANO " : ""
661+ );
662+
663+#ifndef OPENSSL_NO_SHA
664+ /* Use Nano SHA acceleration? */
665+ if (PADLOCK_HAVE_NANO) {
666+ padlock_sha1_md.update = padlock_nano_sha1_update;
667+ padlock_dss1_md.update = padlock_nano_sha1_update;
668+#if !defined(OPENSSL_NO_SHA256)
669+#if !defined(OPENSSL_NO_SHA224)
670+ padlock_sha224_md.update = padlock_nano_sha256_update;
671+#endif
672+ padlock_sha256_md.update = padlock_nano_sha256_update;
673+#endif
674+ }
675+#endif
676+
677+ /* Register everything or return with an error */
678+ if (!ENGINE_set_id(e, padlock_id) ||
679+ !ENGINE_set_name(e, padlock_name) ||
680+
681+ !ENGINE_set_init_function(e, padlock_init)
682+#ifndef OPENSSL_NO_AES
683+ || (PADLOCK_HAVE_ACE && !ENGINE_set_ciphers (e, padlock_ciphers))
684+#endif
685+#ifndef OPENSSL_NO_SHA
686+ || (PADLOCK_HAVE_PHE && !ENGINE_set_digests (e, padlock_digests))
687+#endif
688+#ifndef PADLOCK_NO_RNG
689+ || (PADLOCK_HAVE_RNG && !ENGINE_set_RAND (e, &padlock_rand))
690+#endif
691+ ) {
692+ return 0;
693+ }
694+
695+ /* Everything looks good */
696+ return 1;
697+}
698+
699 #endif /* !OPENSSL_NO_HW_PADLOCK */
700 #endif /* !OPENSSL_NO_HW */
701--
7021.7.0.4
703
diff --git a/main/openssl/APKBUILD b/main/openssl/APKBUILD
index 62cd44998f..8b886e99ea 100644
--- a/main/openssl/APKBUILD
+++ b/main/openssl/APKBUILD
@@ -1,7 +1,7 @@
1# Maintainer: Natanael Copa <ncopa@alpinelinux.org> 1# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
2pkgname=openssl 2pkgname=openssl
3pkgver=0.9.8o 3pkgver=0.9.8o
4pkgrel=0 4pkgrel=1
5pkgdesc="Toolkit for SSL v2/v3 and TLS v1" 5pkgdesc="Toolkit for SSL v2/v3 and TLS v1"
6url=http://openssl.org 6url=http://openssl.org
7depends= 7depends=
@@ -13,7 +13,9 @@ subpackages="$pkgname-dev $pkgname-doc libcrypto"
13source="http://www.openssl.org/source/${pkgname}-${pkgver}.tar.gz 13source="http://www.openssl.org/source/${pkgname}-${pkgver}.tar.gz
14 openssl-0.9.8o-fix-manpages.patch 14 openssl-0.9.8o-fix-manpages.patch
15 openssl-bb-basename.patch 15 openssl-bb-basename.patch
16 openssl-0.9.8k-padlock-sha.patch 16 0001-crypto-hmac-support-EVP_MD_CTX_FLAG_ONESHOT-and-set-.patch
17 0002-apps-speed-fix-digest-speed-measurement-and-add-hmac.patch
18 0003-engine-padlock-implement-sha1-sha224-sha256-accelera.patch
17 " 19 "
18 20
19_builddir="$srcdir"/$pkgname-$pkgver 21_builddir="$srcdir"/$pkgname-$pkgver
@@ -51,4 +53,6 @@ libcrypto() {
51md5sums="63ddc5116488985e820075e65fbe6aa4 openssl-0.9.8o.tar.gz 53md5sums="63ddc5116488985e820075e65fbe6aa4 openssl-0.9.8o.tar.gz
5219615785a671129bae790478f073da2c openssl-0.9.8o-fix-manpages.patch 5419615785a671129bae790478f073da2c openssl-0.9.8o-fix-manpages.patch
53c6a9857a5dbd30cead0404aa7dd73977 openssl-bb-basename.patch 55c6a9857a5dbd30cead0404aa7dd73977 openssl-bb-basename.patch
5486b7f1bf50e1f3ba407ec62001a51a0d openssl-0.9.8k-padlock-sha.patch" 562f370b846d8f27ac45dd6e5341366e16 0001-crypto-hmac-support-EVP_MD_CTX_FLAG_ONESHOT-and-set-.patch
57234de7f31d2e9c826616dd7a23598e86 0002-apps-speed-fix-digest-speed-measurement-and-add-hmac.patch
58e262418b20a05c2af12d464ac194ea21 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 b2e7e954d6..0000000000
--- a/main/openssl/openssl-0.9.8k-padlock-sha.patch
+++ /dev/null
@@ -1,821 +0,0 @@
1#
2# OpenSSL patch to support VIA C7 hash engine
3# Written by: Timo Teras <timo.teras@iki.fi>
4# based on patch by: Michal Ludvig <michal@logix.cz>
5# http://www.logix.cz/michal/devel/padlock
6#
7Index: openssl-0.9.8k/crypto/engine/eng_padlock.c
8===================================================================
9--- openssl-0.9.8k.orig/crypto/engine/eng_padlock.c 2009-07-27 16:18:20.000000000 +0300
10+++ openssl-0.9.8k/crypto/engine/eng_padlock.c 2009-07-30 22:02:54.000000000 +0300
11@@ -1,10 +1,13 @@
12-/*
13+/*
14 * Support for VIA PadLock Advanced Cryptography Engine (ACE)
15 * Written by Michal Ludvig <michal@logix.cz>
16 * http://www.logix.cz/michal
17 *
18- * Big thanks to Andy Polyakov for a help with optimization,
19- * assembler fixes, port to MS Windows and a lot of other
20+ * SHA support by Timo Teras <timo.teras@iki.fi> based on code
21+ * originally by Michal Ludvig.
22+ *
23+ * Big thanks to Andy Polyakov for a help with optimization,
24+ * assembler fixes, port to MS Windows and a lot of other
25 * valuable work on this engine!
26 */
27
28@@ -66,6 +69,13 @@
29 #include <stdio.h>
30 #include <string.h>
31
32+#include <signal.h>
33+#include <stdint.h>
34+#include <unistd.h>
35+#include <sys/mman.h>
36+#include <sys/ucontext.h>
37+#include <arpa/inet.h>
38+
39 #include <openssl/opensslconf.h>
40 #include <openssl/crypto.h>
41 #include <openssl/dso.h>
42@@ -74,12 +84,23 @@
43 #ifndef OPENSSL_NO_AES
44 #include <openssl/aes.h>
45 #endif
46+#ifndef OPENSSL_NO_SHA
47+#include <openssl/sha.h>
48+#endif
49 #include <openssl/rand.h>
50 #include <openssl/err.h>
51
52 #ifndef OPENSSL_NO_HW
53 #ifndef OPENSSL_NO_HW_PADLOCK
54
55+/* PadLock RNG is disabled by default */
56+#define PADLOCK_NO_RNG 1
57+
58+/* No ASM routines for SHA in MSC yet */
59+#ifdef _MSC_VER
60+#define OPENSSL_NO_SHA
61+#endif
62+
63 /* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
64 #if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
65 # ifndef OPENSSL_NO_DYNAMIC_ENGINE
66@@ -96,7 +117,7 @@
67 /* VIA PadLock AES is available *ONLY* on some x86 CPUs.
68 Not only that it doesn't exist elsewhere, but it
69 even can't be compiled on other platforms!
70-
71+
72 In addition, because of the heavy use of inline assembler,
73 compiler choice is limited to GCC and Microsoft C. */
74 #undef COMPILE_HW_PADLOCK
75@@ -138,20 +159,42 @@
76 static int padlock_init(ENGINE *e);
77
78 /* RNG Stuff */
79+#ifndef PADLOCK_NO_RNG
80 static RAND_METHOD padlock_rand;
81+#endif
82
83 /* Cipher Stuff */
84 #ifndef OPENSSL_NO_AES
85 static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
86 #endif
87
88+/* Digest Stuff */
89+#ifndef OPENSSL_NO_SHA
90+static int padlock_digests(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
91+static volatile void *padlock_cached_sha_buffer = NULL;
92+#endif
93+
94 /* Engine names */
95 static const char *padlock_id = "padlock";
96 static char padlock_name[100];
97
98 /* Available features */
99-static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
100-static int padlock_use_rng = 0; /* Random Number Generator */
101+enum padlock_flags {
102+ PADLOCK_RNG = 0x01,
103+ PADLOCK_ACE = 0x02,
104+ PADLOCK_ACE2 = 0x04,
105+ PADLOCK_PHE = 0x08,
106+ PADLOCK_PMM = 0x10
107+};
108+enum padlock_flags padlock_flags;
109+
110+#define PADLOCK_HAVE_RNG (padlock_flags & PADLOCK_RNG)
111+#define PADLOCK_HAVE_ACE (padlock_flags & (PADLOCK_ACE|PADLOCK_ACE2))
112+#define PADLOCK_HAVE_ACE1 (padlock_flags & PADLOCK_ACE)
113+#define PADLOCK_HAVE_ACE2 (padlock_flags & PADLOCK_ACE2)
114+#define PADLOCK_HAVE_PHE (padlock_flags & PADLOCK_PHE)
115+#define PADLOCK_HAVE_PMM (padlock_flags & PADLOCK_PMM)
116+
117 #ifndef OPENSSL_NO_AES
118 static int padlock_aes_align_required = 1;
119 #endif
120@@ -165,25 +208,30 @@
121 /* Check available features */
122 padlock_available();
123
124-#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
125- padlock_use_rng=0;
126-#endif
127-
128 /* Generate a nice engine name with available features */
129 BIO_snprintf(padlock_name, sizeof(padlock_name),
130- "VIA PadLock (%s, %s)",
131- padlock_use_rng ? "RNG" : "no-RNG",
132- padlock_use_ace ? "ACE" : "no-ACE");
133+ "VIA PadLock: %s%s%s%s%s",
134+ padlock_flags ? "" : "not supported",
135+ PADLOCK_HAVE_RNG ? "RNG " : "",
136+ PADLOCK_HAVE_ACE ? (PADLOCK_HAVE_ACE2 ? "ACE2 " : "ACE ") : "",
137+ PADLOCK_HAVE_PHE ? "PHE " : "",
138+ PADLOCK_HAVE_PMM ? "PMM " : "");
139
140- /* Register everything or return with an error */
141+ /* Register everything or return with an error */
142 if (!ENGINE_set_id(e, padlock_id) ||
143 !ENGINE_set_name(e, padlock_name) ||
144
145- !ENGINE_set_init_function(e, padlock_init) ||
146+ !ENGINE_set_init_function(e, padlock_init)
147 #ifndef OPENSSL_NO_AES
148- (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
149+ || (PADLOCK_HAVE_ACE && !ENGINE_set_ciphers (e, padlock_ciphers))
150 #endif
151- (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
152+#ifndef OPENSSL_NO_SHA
153+ || (PADLOCK_HAVE_PHE && !ENGINE_set_digests (e, padlock_digests))
154+#endif
155+#ifndef PADLOCK_NO_RNG
156+ || (PADLOCK_HAVE_RNG && !ENGINE_set_RAND (e, &padlock_rand))
157+#endif
158+ ) {
159 return 0;
160 }
161
162@@ -213,7 +261,7 @@
163 static int
164 padlock_init(ENGINE *e)
165 {
166- return (padlock_use_rng || padlock_use_ace);
167+ return (padlock_flags);
168 }
169
170 /* This stuff is needed if this ENGINE is being compiled into a self-contained
171@@ -247,7 +295,7 @@
172 #define AES_KEY_SIZE_192 24
173 #define AES_KEY_SIZE_256 32
174
175-/* Here we store the status information relevant to the
176+/* Here we store the status information relevant to the
177 current context. */
178 /* BIG FAT WARNING:
179 * Inline assembler in PADLOCK_XCRYPT_ASM()
180@@ -306,7 +354,7 @@
181 {
182 int result = -1;
183
184- /* We're checking if the bit #21 of EFLAGS
185+ /* We're checking if the bit #21 of EFLAGS
186 can be toggled. If yes = CPUID is available. */
187 asm volatile (
188 "pushf\n"
189@@ -322,7 +370,7 @@
190 "xorl %%eax, %%ecx\n"
191 "movl %%ecx, %0\n"
192 : "=r" (result) : : "eax", "ecx");
193-
194+
195 return (result == 0);
196 }
197
198@@ -365,10 +413,22 @@
199 : "+a"(eax), "=d"(edx) : : "ecx");
200
201 /* Fill up some flags */
202- padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
203- padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
204+ padlock_flags |= ((edx & (0x3<<3)) ? PADLOCK_RNG : 0);
205+ padlock_flags |= ((edx & (0x3<<7)) ? PADLOCK_ACE : 0);
206+ padlock_flags |= ((edx & (0x3<<9)) ? PADLOCK_ACE2 : 0);
207+ padlock_flags |= ((edx & (0x3<<11)) ? PADLOCK_PHE : 0);
208+ padlock_flags |= ((edx & (0x3<<13)) ? PADLOCK_PMM : 0);
209
210- return padlock_use_ace + padlock_use_rng;
211+ return padlock_flags;
212+}
213+
214+static inline void
215+padlock_htonl_block(uint32_t *data, size_t count)
216+{
217+ while (count--) {
218+ asm volatile ("bswapl %0" : "+r"(*data));
219+ data++;
220+ }
221 }
222
223 #ifndef OPENSSL_NO_AES
224@@ -377,17 +437,14 @@
225 padlock_bswapl(AES_KEY *ks)
226 {
227 size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
228- unsigned int *key = ks->rd_key;
229+ uint32_t *key = (uint32_t*) ks->rd_key;
230
231- while (i--) {
232- asm volatile ("bswapl %0" : "+r"(*key));
233- key++;
234- }
235+ padlock_htonl_block(key, i);
236 }
237 #endif
238
239 /* Force key reload from memory to the CPU microcode.
240- Loading EFLAGS from the stack clears EFLAGS[30]
241+ Loading EFLAGS from the stack clears EFLAGS[30]
242 which does the trick. */
243 static inline void
244 padlock_reload_key(void)
245@@ -423,7 +480,7 @@
246 }
247
248 /* Template for padlock_xcrypt_* modes */
249-/* BIG FAT WARNING:
250+/* BIG FAT WARNING:
251 * The offsets used with 'leal' instructions
252 * describe items of the 'padlock_cipher_data'
253 * structure.
254@@ -475,7 +532,7 @@
255 * In case you wonder 'rep xcrypt*' instructions above are *not*
256 * affected by the Direction Flag and pointers advance toward
257 * larger addresses unconditionally.
258- */
259+ */
260 static inline unsigned char *
261 padlock_memcpy(void *dst,const void *src,size_t n)
262 {
263@@ -501,7 +558,7 @@
264 _asm _emit 0x0f _asm _emit 0xa7 \
265 _asm _emit code
266
267-/* BIG FAT WARNING:
268+/* BIG FAT WARNING:
269 * The offsets used with 'lea' instructions
270 * describe items of the 'padlock_cipher_data'
271 * structure.
272@@ -840,7 +897,7 @@
273 return 1;
274 }
275
276-/*
277+/*
278 * Simplified version of padlock_aes_cipher() used when
279 * 1) both input and output buffers are at aligned addresses.
280 * or when
281@@ -895,7 +952,7 @@
282 # error "insane PADLOCK_CHUNK..."
283 #endif
284
285-/* Re-align the arguments to 16-Bytes boundaries and run the
286+/* Re-align the arguments to 16-Bytes boundaries and run the
287 encryption function itself. This function is not AES-specific. */
288 static int
289 padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
290@@ -1157,6 +1214,514 @@
291
292 #endif /* OPENSSL_NO_AES */
293
294+#ifndef OPENSSL_NO_SHA
295+
296+#define DIGEST_DATA(ctx) ((struct padlock_digest_data *)(ctx->md_data))
297+#define PADLOCK_SHA_ALIGN(dd) (uint32_t*)(((uintptr_t)(dd) + 15) & ~15)
298+#define PADLOCK_SHA_PAGES 14
299+#define PADLOCK_SHA_BUFFER (512 - sizeof(size_t) - 4*sizeof(void*))
300+#define PADLOCK_SHA_INITVECTOR_SIZE (8 * sizeof(uint32_t))
301+
302+struct padlock_digest_data {
303+ union {
304+ unsigned char smallbuffer[PADLOCK_SHA_BUFFER];
305+ struct {
306+ unsigned char padlockctx[128+16];
307+ unsigned char *buffer;
308+ size_t mmap_size;
309+ uint64_t total;
310+ };
311+ };
312+ void *initvector;
313+ size_t used;
314+ void (*hash)(void *padlockctx, const void *buf, size_t len);
315+ int (*update)(EVP_MD_CTX *ctx, const void *buffer, size_t len);
316+ int (*final)(EVP_MD_CTX *ctx, unsigned char *buffer);
317+};
318+
319+static inline void *
320+padlock_atomic_xchg(volatile void **mem, void *fixed)
321+{
322+ /* No lock prefix due the xchg asserts it anyway, and the
323+ * funny unsigned long* cast is required to workaround some gcc
324+ * problems if compiling in PIC mode */
325+ asm volatile (
326+ "xchg %0, %1"
327+ : "=r"(fixed)
328+ : "m"(*(unsigned long*)mem), "0"(fixed)
329+ : "memory");
330+ return fixed;
331+}
332+
333+static void
334+padlock_do_sha1(void *padlockctx, const void *buf, size_t len)
335+{
336+ asm volatile (
337+ "xsha1"
338+ : "+S"(buf), "+D"(padlockctx)
339+ : "c"(len), "a"(0));
340+}
341+
342+static void
343+padlock_do_sha256(void *padlockctx, const void *buf, size_t len)
344+{
345+ asm volatile (
346+ "xsha256"
347+ : "+S"(buf), "+D"(padlockctx)
348+ : "c"(len), "a"(0));
349+}
350+
351+static void
352+handle_sigsegv(int sig, siginfo_t *info, void *uctxp)
353+{
354+ ucontext_t *uctx = uctxp;
355+ uctx->uc_mcontext.gregs[14] += 4;
356+}
357+
358+static void
359+padlock_sha_nonfinalizing(struct padlock_digest_data *data)
360+{
361+ struct sigaction act, oldact;
362+ size_t bofs = 0;
363+
364+ if (data->used != data->mmap_size) {
365+ bofs = data->mmap_size - data->used;
366+ memmove(&data->buffer[bofs], data->buffer, data->used);
367+ }
368+
369+ memset(&act, 0, sizeof(act));
370+ act.sa_sigaction = handle_sigsegv;
371+ act.sa_flags = SA_SIGINFO;
372+ sigaction(SIGSEGV, &act, &oldact);
373+ data->hash(PADLOCK_SHA_ALIGN(data->padlockctx),
374+ &data->buffer[bofs], data->used + 64);
375+ sigaction(SIGSEGV, &oldact, NULL);
376+}
377+
378+static void
379+padlock_free_buffer(void *buf)
380+{
381+ buf = padlock_atomic_xchg(&padlock_cached_sha_buffer, buf);
382+ if (buf != NULL) {
383+ munmap(buf, (PADLOCK_SHA_PAGES + 1) * getpagesize());
384+ }
385+}
386+
387+static void *
388+padlock_allocate_buffer(size_t *maxsize)
389+{
390+ void *buf;
391+ size_t size, page;
392+
393+ page = getpagesize();
394+ buf = padlock_atomic_xchg(&padlock_cached_sha_buffer, NULL);
395+ if (buf != NULL)
396+ goto ret;
397+
398+ size = (PADLOCK_SHA_PAGES + 1) * page;
399+ buf = mmap(0, size, PROT_READ | PROT_WRITE,
400+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
401+ if (buf == NULL)
402+ return NULL;
403+
404+ /* Try locking the pages to avoid swapping, but don't fail if
405+ * we are over quota. */
406+ mlock(buf, size);
407+
408+ if (mprotect(buf + PADLOCK_SHA_PAGES * page, page, PROT_NONE) < 0) {
409+ munmap(buf, size);
410+ return NULL;
411+ }
412+
413+ret:
414+ *maxsize = PADLOCK_SHA_PAGES * page - 64;
415+
416+ return buf;
417+}
418+
419+static int
420+padlock_multi_update(EVP_MD_CTX *ctx, const void *data, size_t len)
421+{
422+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
423+ size_t chunk_size;
424+
425+ if (ddata->buffer == NULL)
426+ ddata->buffer = padlock_allocate_buffer(&ddata->mmap_size);
427+
428+ while (len) {
429+ if (ddata->used + len < ddata->mmap_size) {
430+ memcpy(&ddata->buffer[ddata->used], data, len);
431+ ddata->used += len;
432+ ddata->total += len;
433+ return 1;
434+ }
435+
436+ chunk_size = ddata->mmap_size - ddata->used;
437+ memcpy(&ddata->buffer[ddata->used], data, chunk_size);
438+
439+ data += chunk_size;
440+ len -= chunk_size;
441+ ddata->used = ddata->mmap_size;
442+ ddata->total += chunk_size;
443+ padlock_sha_nonfinalizing(ddata);
444+ ddata->used = 0;
445+ }
446+
447+ return 1;
448+}
449+
450+static int
451+padlock_oneshot_final(EVP_MD_CTX *ctx, unsigned char *md)
452+{
453+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
454+ size_t size = EVP_MD_CTX_size(ctx);
455+
456+ memcpy(md, PADLOCK_SHA_ALIGN(ddata->padlockctx), size);
457+ return 1;
458+}
459+
460+static int
461+padlock_copy_final(EVP_MD_CTX *ctx, unsigned char *md)
462+{
463+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
464+ char padlockctx[128+16];
465+ void *aligned = PADLOCK_SHA_ALIGN(padlockctx);
466+ size_t size = EVP_MD_CTX_size(ctx);
467+
468+ memcpy(aligned, ddata->initvector, PADLOCK_SHA_INITVECTOR_SIZE);
469+ ddata->hash(aligned, ddata->smallbuffer, ddata->used);
470+ padlock_htonl_block(aligned, size / sizeof(uint32_t));
471+ memcpy(md, aligned, size);
472+
473+ return 1;
474+}
475+
476+static int
477+padlock_multi_final(EVP_MD_CTX *ctx, unsigned char *md)
478+{
479+ static const char padding[64] = { 0x80, };
480+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
481+ size_t mdsize = EVP_MD_CTX_size(ctx);
482+ void *aligned = PADLOCK_SHA_ALIGN(ddata->padlockctx);
483+
484+ if (ddata->used == ddata->total) {
485+ /* Sweet, everything fits in one buffer. */
486+ ddata->hash(aligned, ddata->buffer, ddata->used);
487+ } else {
488+ /* Hardware already hashed some buffers.
489+ * Do finalizing manually */
490+ union {
491+ uint64_t u64;
492+ uint32_t u32[2];
493+ } bits_le, bits;
494+ size_t lastblocklen, padlen;
495+
496+ /* BigEndianise the length. */
497+ bits_le.u64 = ddata->total * 8;
498+ bits.u32[1] = htonl(bits_le.u32[0]);
499+ bits.u32[0] = htonl(bits_le.u32[1]);
500+
501+ /* Append padding, leave space for length. */
502+ lastblocklen = ddata->total & 63;
503+ padlen = (lastblocklen < 56) ? (56 - lastblocklen) : ((64+56) - lastblocklen);
504+ padlock_multi_update(ctx, padding, padlen);
505+
506+ /* Length in BigEndian64 */
507+ padlock_multi_update(ctx, (const char *) &bits, sizeof(bits));
508+
509+ /* And finally calculate it */
510+ padlock_sha_nonfinalizing(ddata);
511+ }
512+ padlock_htonl_block(aligned, mdsize / sizeof(uint32_t));
513+ memcpy(md, aligned, mdsize);
514+
515+ return 1;
516+}
517+
518+static int
519+padlock_copy_update(EVP_MD_CTX *ctx, const void *data, size_t len)
520+{
521+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
522+
523+ if (ddata->used + len > sizeof(ddata->smallbuffer)) {
524+ ddata->update = padlock_multi_update;
525+ ddata->final = padlock_multi_final;
526+
527+ if (ddata->used != 0) {
528+ void *buffer;
529+ size_t mmap_size;
530+
531+ buffer = padlock_allocate_buffer(&mmap_size);
532+ memcpy(buffer, ddata->smallbuffer, ddata->used);
533+ ddata->buffer = buffer;
534+ ddata->total = ddata->used;
535+ ddata->mmap_size = mmap_size;
536+ } else {
537+ ddata->buffer = NULL;
538+ ddata->total = 0;
539+ }
540+
541+ memcpy(PADLOCK_SHA_ALIGN(ddata->padlockctx), ddata->initvector,
542+ PADLOCK_SHA_INITVECTOR_SIZE);
543+
544+ return padlock_multi_update(ctx, data, len);
545+ }
546+
547+ memcpy(&ddata->smallbuffer[ddata->used], data, len);
548+ ddata->used += len;
549+
550+ return 1;
551+}
552+
553+static int
554+padlock_oneshot_update(EVP_MD_CTX *ctx, const void *data, size_t len)
555+{
556+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
557+ void *aligned = PADLOCK_SHA_ALIGN(ddata->padlockctx);
558+ size_t mdsize = EVP_MD_CTX_size(ctx);
559+
560+ /* Oneshot update is only possible if context flags indicate so */
561+ if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
562+ ddata->update = padlock_copy_update;
563+ ddata->final = padlock_copy_final;
564+ return padlock_copy_update(ctx, data, len);
565+ }
566+
567+ memcpy(aligned, ddata->initvector, PADLOCK_SHA_INITVECTOR_SIZE);
568+ ddata->hash(aligned, data, len);
569+ padlock_htonl_block(aligned, mdsize / sizeof(uint32_t));
570+ ddata->used += len;
571+
572+ return 1;
573+}
574+
575+static int
576+padlock_sha_init(struct padlock_digest_data *ddata)
577+{
578+ ddata->used = 0;
579+ ddata->update = padlock_oneshot_update;
580+ ddata->final = padlock_oneshot_final;
581+
582+ return 1;
583+}
584+
585+static int
586+padlock_sha1_init(EVP_MD_CTX *ctx)
587+{
588+ static uint32_t sha1_initvector[8] = {
589+ 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476,
590+ 0xC3D2E1F0
591+ };
592+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
593+
594+ ddata->hash = padlock_do_sha1;
595+ ddata->initvector = sha1_initvector;
596+ return padlock_sha_init(ddata);
597+}
598+
599+static int
600+padlock_sha224_init(EVP_MD_CTX *ctx)
601+{
602+ static uint32_t sha224_initvector[] = {
603+ 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939,
604+ 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4,
605+ };
606+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
607+
608+ ddata->hash = padlock_do_sha256;
609+ ddata->initvector = sha224_initvector;
610+ return padlock_sha_init(ddata);
611+}
612+
613+static int
614+padlock_sha256_init(EVP_MD_CTX *ctx)
615+{
616+ static uint32_t sha256_initvector[] = {
617+ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
618+ 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
619+ };
620+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
621+
622+ ddata->hash = padlock_do_sha256;
623+ ddata->initvector = sha256_initvector;
624+ return padlock_sha_init(ddata);
625+}
626+
627+static int
628+padlock_sha_update(EVP_MD_CTX *ctx, const void *data, size_t length)
629+{
630+ return DIGEST_DATA(ctx)->update(ctx, data, length);
631+}
632+
633+static int
634+padlock_sha_final(EVP_MD_CTX *ctx, unsigned char *md)
635+{
636+ return DIGEST_DATA(ctx)->final(ctx, md);
637+}
638+
639+static int
640+padlock_sha_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
641+{
642+ struct padlock_digest_data *dfrom = DIGEST_DATA(from);
643+ struct padlock_digest_data *dto = DIGEST_DATA(to);
644+
645+ /* When we get here, dto is already a memcpied from dfrom,
646+ * it's ok for all other cases except when data is on a separate
647+ * mmapped area. It would be nice if we had a flag, if this is
648+ * a "finalization copy", so we could do finalizing SHA here and
649+ * store the result to *to precalculated. But there's no such
650+ * flag as to is reset on copy. */
651+
652+ if (dfrom->update != padlock_copy_update) {
653+ /* Recopy the context, as they might have different alignment */
654+ memcpy(PADLOCK_SHA_ALIGN(dto->padlockctx),
655+ PADLOCK_SHA_ALIGN(dfrom->padlockctx),
656+ PADLOCK_SHA_INITVECTOR_SIZE);
657+ }
658+
659+ if (dfrom->update == padlock_multi_update) {
660+ /* Update total, and copy the buffer */
661+ dto->total = dfrom->total - dfrom->used;
662+ dto->buffer = NULL;
663+ dto->used = 0;
664+ dto->mmap_size = 0;
665+ if (dfrom->used != 0)
666+ padlock_sha_update(to, dfrom->buffer, dfrom->used);
667+ }
668+
669+ return 1;
670+}
671+
672+static int
673+padlock_sha_cleanup(EVP_MD_CTX *ctx)
674+{
675+ struct padlock_digest_data *ddata = DIGEST_DATA(ctx);
676+
677+ if (ddata->update == padlock_multi_update && ddata->buffer != NULL)
678+ padlock_free_buffer(ddata->buffer);
679+
680+ return 1;
681+}
682+
683+static const EVP_MD padlock_sha1_md = {
684+ NID_sha1,
685+ NID_sha1WithRSAEncryption,
686+ SHA_DIGEST_LENGTH,
687+ 0,
688+ padlock_sha1_init,
689+ padlock_sha_update,
690+ padlock_sha_final,
691+ padlock_sha_copy,
692+ padlock_sha_cleanup,
693+ EVP_PKEY_RSA_method,
694+ SHA_CBLOCK,
695+ sizeof(struct padlock_digest_data),
696+};
697+
698+static const EVP_MD padlock_dss1_md = {
699+ NID_dsa,
700+ NID_dsaWithSHA1,
701+ SHA_DIGEST_LENGTH,
702+ 0,
703+ padlock_sha1_init,
704+ padlock_sha_update,
705+ padlock_sha_final,
706+ padlock_sha_copy,
707+ padlock_sha_cleanup,
708+ EVP_PKEY_DSA_method,
709+ SHA_CBLOCK,
710+ sizeof(struct padlock_digest_data),
711+};
712+
713+static const EVP_MD padlock_sha224_md = {
714+ NID_sha224,
715+ NID_sha224WithRSAEncryption,
716+ SHA224_DIGEST_LENGTH,
717+ 0,
718+ padlock_sha224_init,
719+ padlock_sha_update,
720+ padlock_sha_final,
721+ padlock_sha_copy,
722+ padlock_sha_cleanup,
723+ EVP_PKEY_RSA_method,
724+ SHA_CBLOCK,
725+ sizeof(struct padlock_digest_data),
726+};
727+
728+static const EVP_MD padlock_sha256_md = {
729+ NID_sha256,
730+ NID_sha256WithRSAEncryption,
731+ SHA256_DIGEST_LENGTH,
732+ 0,
733+ padlock_sha256_init,
734+ padlock_sha_update,
735+ padlock_sha_final,
736+ padlock_sha_copy,
737+ padlock_sha_cleanup,
738+ EVP_PKEY_RSA_method,
739+ SHA_CBLOCK,
740+ sizeof(struct padlock_digest_data),
741+};
742+
743+static int padlock_digest_nids[] = {
744+#if !defined(OPENSSL_NO_SHA)
745+ NID_sha1,
746+ NID_dsa,
747+#endif
748+#if !defined(OPENSSL_NO_SHA256)
749+#if !defined(OPENSSL_NO_SHA224)
750+ NID_sha224,
751+#endif
752+ NID_sha256,
753+#endif
754+};
755+
756+static int padlock_digest_nids_num = sizeof(padlock_digest_nids)/sizeof(padlock_digest_nids[0]);
757+
758+static int
759+padlock_digests (ENGINE *e, const EVP_MD **digest, const int **nids, int nid)
760+{
761+ /* No specific digest => return a list of supported nids ... */
762+ if (!digest) {
763+ *nids = padlock_digest_nids;
764+ return padlock_digest_nids_num;
765+ }
766+
767+ /* ... or the requested "digest" otherwise */
768+ switch (nid) {
769+#if !defined(OPENSSL_NO_SHA)
770+ case NID_sha1:
771+ *digest = &padlock_sha1_md;
772+ break;
773+ case NID_dsa:
774+ *digest = &padlock_dss1_md;
775+ break;
776+#endif
777+
778+#if !defined(OPENSSL_NO_SHA256)
779+#if !defined(OPENSSL_NO_SHA224)
780+ case NID_sha224:
781+ *digest = &padlock_sha224_md;
782+ break;
783+#endif /* OPENSSL_NO_SHA224 */
784+
785+ case NID_sha256:
786+ *digest = &padlock_sha256_md;
787+ break;
788+#endif /* OPENSSL_NO_SHA256 */
789+
790+ default:
791+ /* Sorry, we don't support this NID */
792+ *digest = NULL;
793+ return 0;
794+ }
795+
796+ return 1;
797+}
798+
799+#endif /* OPENSSL_NO_SHA */
800+
801+#ifndef PADLOCK_NO_RNG
802 /* ===== Random Number Generator ===== */
803 /*
804 * This code is not engaged. The reason is that it does not comply
805@@ -1164,7 +1729,7 @@
806 * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
807 * provide meaningful error control...
808 */
809-/* Wrapper that provides an interface between the API and
810+/* Wrapper that provides an interface between the API and
811 the raw PadLock RNG */
812 static int
813 padlock_rand_bytes(unsigned char *output, int count)
814@@ -1212,6 +1777,7 @@
815 padlock_rand_bytes, /* pseudorand */
816 padlock_rand_status, /* rand status */
817 };
818+#endif /* PADLOCK_NO_RNG */
819
820 #endif /* COMPILE_HW_PADLOCK */
821