aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Manison <amanison@anselsystems.com>2010-06-01 23:45:07 +0000
committerAndrew Manison <amanison@anselsystems.com>2010-06-01 23:45:07 +0000
commit8e157a2055bf4e5f3ec2113b32080f3fcf2f7f34 (patch)
treed812f1188fa683eb40ad9ea1fe47f2ab657d5c34
parent2c7f7f25f1476495e77fbf4528199e794aaff614 (diff)
downloadalpine_aports-8e157a2055bf4e5f3ec2113b32080f3fcf2f7f34.tar.bz2
alpine_aports-8e157a2055bf4e5f3ec2113b32080f3fcf2f7f34.tar.xz
alpine_aports-8e157a2055bf4e5f3ec2113b32080f3fcf2f7f34.zip
Deleted old patch file.
-rw-r--r--main/openssl/openssl-0.9.8k-padlock-sha.patch821
1 files changed, 0 insertions, 821 deletions
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