diff options
author | Andrew Manison <amanison@anselsystems.com> | 2010-06-01 23:45:07 +0000 |
---|---|---|
committer | Andrew Manison <amanison@anselsystems.com> | 2010-06-01 23:45:07 +0000 |
commit | 8e157a2055bf4e5f3ec2113b32080f3fcf2f7f34 (patch) | |
tree | d812f1188fa683eb40ad9ea1fe47f2ab657d5c34 | |
parent | 2c7f7f25f1476495e77fbf4528199e794aaff614 (diff) | |
download | alpine_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.patch | 821 |
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 | # | ||
7 | Index: 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 | |||