diff options
author | djm <> | 2010-10-01 22:54:21 +0000 |
---|---|---|
committer | djm <> | 2010-10-01 22:54:21 +0000 |
commit | 2ea67f4aa254b09ded62e6e14fc893bbe6381579 (patch) | |
tree | bb3923b81f2ce34b1ad62684afdf1a94d904c185 | |
parent | 6ddfb710ab14b10183ff3a6a32f643554c80065e (diff) | |
parent | 829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2 (diff) | |
download | openbsd-2ea67f4aa254b09ded62e6e14fc893bbe6381579.tar.gz openbsd-2ea67f4aa254b09ded62e6e14fc893bbe6381579.tar.bz2 openbsd-2ea67f4aa254b09ded62e6e14fc893bbe6381579.zip |
This commit was generated by cvs2git to track changes on a CVS vendor
branch.
189 files changed, 34138 insertions, 4739 deletions
diff --git a/src/lib/libcrypto/aes/aes_ige.c b/src/lib/libcrypto/aes/aes_ige.c index 45d7096181..c161351e65 100644 --- a/src/lib/libcrypto/aes/aes_ige.c +++ b/src/lib/libcrypto/aes/aes_ige.c | |||
@@ -77,11 +77,11 @@ typedef struct { | |||
77 | /* N.B. The IV for this mode is _twice_ the block size */ | 77 | /* N.B. The IV for this mode is _twice_ the block size */ |
78 | 78 | ||
79 | void AES_ige_encrypt(const unsigned char *in, unsigned char *out, | 79 | void AES_ige_encrypt(const unsigned char *in, unsigned char *out, |
80 | const unsigned long length, const AES_KEY *key, | 80 | size_t length, const AES_KEY *key, |
81 | unsigned char *ivec, const int enc) | 81 | unsigned char *ivec, const int enc) |
82 | { | 82 | { |
83 | unsigned long n; | 83 | size_t n; |
84 | unsigned long len; | 84 | size_t len = length; |
85 | 85 | ||
86 | OPENSSL_assert(in && out && key && ivec); | 86 | OPENSSL_assert(in && out && key && ivec); |
87 | OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); | 87 | OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); |
@@ -211,12 +211,12 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, | |||
211 | /* N.B. The IV for this mode is _four times_ the block size */ | 211 | /* N.B. The IV for this mode is _four times_ the block size */ |
212 | 212 | ||
213 | void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, | 213 | void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, |
214 | const unsigned long length, const AES_KEY *key, | 214 | size_t length, const AES_KEY *key, |
215 | const AES_KEY *key2, const unsigned char *ivec, | 215 | const AES_KEY *key2, const unsigned char *ivec, |
216 | const int enc) | 216 | const int enc) |
217 | { | 217 | { |
218 | unsigned long n; | 218 | size_t n; |
219 | unsigned long len = length; | 219 | size_t len = length; |
220 | unsigned char tmp[AES_BLOCK_SIZE]; | 220 | unsigned char tmp[AES_BLOCK_SIZE]; |
221 | unsigned char tmp2[AES_BLOCK_SIZE]; | 221 | unsigned char tmp2[AES_BLOCK_SIZE]; |
222 | unsigned char tmp3[AES_BLOCK_SIZE]; | 222 | unsigned char tmp3[AES_BLOCK_SIZE]; |
diff --git a/src/lib/libcrypto/aes/asm/aes-armv4.pl b/src/lib/libcrypto/aes/asm/aes-armv4.pl index 15742c1ec5..690244111a 100644 --- a/src/lib/libcrypto/aes/asm/aes-armv4.pl +++ b/src/lib/libcrypto/aes/asm/aes-armv4.pl | |||
@@ -1024,6 +1024,7 @@ _armv4_AES_decrypt: | |||
1024 | mov pc,lr @ return | 1024 | mov pc,lr @ return |
1025 | .size _armv4_AES_decrypt,.-_armv4_AES_decrypt | 1025 | .size _armv4_AES_decrypt,.-_armv4_AES_decrypt |
1026 | .asciz "AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>" | 1026 | .asciz "AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>" |
1027 | .align 2 | ||
1027 | ___ | 1028 | ___ |
1028 | 1029 | ||
1029 | $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 | 1030 | $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 |
diff --git a/src/lib/libcrypto/aes/asm/aes-ppc.pl b/src/lib/libcrypto/aes/asm/aes-ppc.pl index ce427655ef..f82c5e1814 100644 --- a/src/lib/libcrypto/aes/asm/aes-ppc.pl +++ b/src/lib/libcrypto/aes/asm/aes-ppc.pl | |||
@@ -16,6 +16,19 @@ | |||
16 | # at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact - | 16 | # at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact - |
17 | # at 1/3 of ppc_AES_decrypt. | 17 | # at 1/3 of ppc_AES_decrypt. |
18 | 18 | ||
19 | # February 2010 | ||
20 | # | ||
21 | # Rescheduling instructions to favour Power6 pipeline gives 10% | ||
22 | # performance improvement on the platfrom in question (and marginal | ||
23 | # improvement even on others). It should be noted that Power6 fails | ||
24 | # to process byte in 18 cycles, only in 23, because it fails to issue | ||
25 | # 4 load instructions in two cycles, only in 3. As result non-compact | ||
26 | # block subroutines are 25% slower than one would expect. Compact | ||
27 | # functions scale better, because they have pure computational part, | ||
28 | # which scales perfectly with clock frequency. To be specific | ||
29 | # ppc_AES_encrypt_compact operates at 42 cycles per byte, while | ||
30 | # ppc_AES_decrypt_compact - at 55 (in 64-bit build). | ||
31 | |||
19 | $flavour = shift; | 32 | $flavour = shift; |
20 | 33 | ||
21 | if ($flavour =~ /64/) { | 34 | if ($flavour =~ /64/) { |
@@ -376,7 +389,7 @@ $code.=<<___; | |||
376 | addi $sp,$sp,$FRAME | 389 | addi $sp,$sp,$FRAME |
377 | blr | 390 | blr |
378 | 391 | ||
379 | .align 4 | 392 | .align 5 |
380 | Lppc_AES_encrypt: | 393 | Lppc_AES_encrypt: |
381 | lwz $acc00,240($key) | 394 | lwz $acc00,240($key) |
382 | lwz $t0,0($key) | 395 | lwz $t0,0($key) |
@@ -397,46 +410,46 @@ Lppc_AES_encrypt: | |||
397 | Lenc_loop: | 410 | Lenc_loop: |
398 | rlwinm $acc00,$s0,`32-24+3`,21,28 | 411 | rlwinm $acc00,$s0,`32-24+3`,21,28 |
399 | rlwinm $acc01,$s1,`32-24+3`,21,28 | 412 | rlwinm $acc01,$s1,`32-24+3`,21,28 |
400 | lwz $t0,0($key) | ||
401 | lwz $t1,4($key) | ||
402 | rlwinm $acc02,$s2,`32-24+3`,21,28 | 413 | rlwinm $acc02,$s2,`32-24+3`,21,28 |
403 | rlwinm $acc03,$s3,`32-24+3`,21,28 | 414 | rlwinm $acc03,$s3,`32-24+3`,21,28 |
404 | lwz $t2,8($key) | 415 | lwz $t0,0($key) |
405 | lwz $t3,12($key) | 416 | lwz $t1,4($key) |
406 | rlwinm $acc04,$s1,`32-16+3`,21,28 | 417 | rlwinm $acc04,$s1,`32-16+3`,21,28 |
407 | rlwinm $acc05,$s2,`32-16+3`,21,28 | 418 | rlwinm $acc05,$s2,`32-16+3`,21,28 |
408 | lwzx $acc00,$Tbl0,$acc00 | 419 | lwz $t2,8($key) |
409 | lwzx $acc01,$Tbl0,$acc01 | 420 | lwz $t3,12($key) |
410 | rlwinm $acc06,$s3,`32-16+3`,21,28 | 421 | rlwinm $acc06,$s3,`32-16+3`,21,28 |
411 | rlwinm $acc07,$s0,`32-16+3`,21,28 | 422 | rlwinm $acc07,$s0,`32-16+3`,21,28 |
412 | lwzx $acc02,$Tbl0,$acc02 | 423 | lwzx $acc00,$Tbl0,$acc00 |
413 | lwzx $acc03,$Tbl0,$acc03 | 424 | lwzx $acc01,$Tbl0,$acc01 |
414 | rlwinm $acc08,$s2,`32-8+3`,21,28 | 425 | rlwinm $acc08,$s2,`32-8+3`,21,28 |
415 | rlwinm $acc09,$s3,`32-8+3`,21,28 | 426 | rlwinm $acc09,$s3,`32-8+3`,21,28 |
416 | lwzx $acc04,$Tbl1,$acc04 | 427 | lwzx $acc02,$Tbl0,$acc02 |
417 | lwzx $acc05,$Tbl1,$acc05 | 428 | lwzx $acc03,$Tbl0,$acc03 |
418 | rlwinm $acc10,$s0,`32-8+3`,21,28 | 429 | rlwinm $acc10,$s0,`32-8+3`,21,28 |
419 | rlwinm $acc11,$s1,`32-8+3`,21,28 | 430 | rlwinm $acc11,$s1,`32-8+3`,21,28 |
420 | lwzx $acc06,$Tbl1,$acc06 | 431 | lwzx $acc04,$Tbl1,$acc04 |
421 | lwzx $acc07,$Tbl1,$acc07 | 432 | lwzx $acc05,$Tbl1,$acc05 |
422 | rlwinm $acc12,$s3,`0+3`,21,28 | 433 | rlwinm $acc12,$s3,`0+3`,21,28 |
423 | rlwinm $acc13,$s0,`0+3`,21,28 | 434 | rlwinm $acc13,$s0,`0+3`,21,28 |
424 | lwzx $acc08,$Tbl2,$acc08 | 435 | lwzx $acc06,$Tbl1,$acc06 |
425 | lwzx $acc09,$Tbl2,$acc09 | 436 | lwzx $acc07,$Tbl1,$acc07 |
426 | rlwinm $acc14,$s1,`0+3`,21,28 | 437 | rlwinm $acc14,$s1,`0+3`,21,28 |
427 | rlwinm $acc15,$s2,`0+3`,21,28 | 438 | rlwinm $acc15,$s2,`0+3`,21,28 |
428 | lwzx $acc10,$Tbl2,$acc10 | 439 | lwzx $acc08,$Tbl2,$acc08 |
429 | lwzx $acc11,$Tbl2,$acc11 | 440 | lwzx $acc09,$Tbl2,$acc09 |
430 | xor $t0,$t0,$acc00 | 441 | xor $t0,$t0,$acc00 |
431 | xor $t1,$t1,$acc01 | 442 | xor $t1,$t1,$acc01 |
432 | lwzx $acc12,$Tbl3,$acc12 | 443 | lwzx $acc10,$Tbl2,$acc10 |
433 | lwzx $acc13,$Tbl3,$acc13 | 444 | lwzx $acc11,$Tbl2,$acc11 |
434 | xor $t2,$t2,$acc02 | 445 | xor $t2,$t2,$acc02 |
435 | xor $t3,$t3,$acc03 | 446 | xor $t3,$t3,$acc03 |
436 | lwzx $acc14,$Tbl3,$acc14 | 447 | lwzx $acc12,$Tbl3,$acc12 |
437 | lwzx $acc15,$Tbl3,$acc15 | 448 | lwzx $acc13,$Tbl3,$acc13 |
438 | xor $t0,$t0,$acc04 | 449 | xor $t0,$t0,$acc04 |
439 | xor $t1,$t1,$acc05 | 450 | xor $t1,$t1,$acc05 |
451 | lwzx $acc14,$Tbl3,$acc14 | ||
452 | lwzx $acc15,$Tbl3,$acc15 | ||
440 | xor $t2,$t2,$acc06 | 453 | xor $t2,$t2,$acc06 |
441 | xor $t3,$t3,$acc07 | 454 | xor $t3,$t3,$acc07 |
442 | xor $t0,$t0,$acc08 | 455 | xor $t0,$t0,$acc08 |
@@ -452,60 +465,60 @@ Lenc_loop: | |||
452 | 465 | ||
453 | addi $Tbl2,$Tbl0,2048 | 466 | addi $Tbl2,$Tbl0,2048 |
454 | nop | 467 | nop |
455 | lwz $acc08,`2048+0`($Tbl0) ! prefetch Te4 | ||
456 | lwz $acc09,`2048+32`($Tbl0) | ||
457 | lwz $acc10,`2048+64`($Tbl0) | ||
458 | lwz $acc11,`2048+96`($Tbl0) | ||
459 | lwz $acc08,`2048+128`($Tbl0) | ||
460 | lwz $acc09,`2048+160`($Tbl0) | ||
461 | lwz $acc10,`2048+192`($Tbl0) | ||
462 | lwz $acc11,`2048+224`($Tbl0) | ||
463 | rlwinm $acc00,$s0,`32-24`,24,31 | ||
464 | rlwinm $acc01,$s1,`32-24`,24,31 | ||
465 | lwz $t0,0($key) | 468 | lwz $t0,0($key) |
466 | lwz $t1,4($key) | 469 | lwz $t1,4($key) |
467 | rlwinm $acc02,$s2,`32-24`,24,31 | 470 | rlwinm $acc00,$s0,`32-24`,24,31 |
468 | rlwinm $acc03,$s3,`32-24`,24,31 | 471 | rlwinm $acc01,$s1,`32-24`,24,31 |
469 | lwz $t2,8($key) | 472 | lwz $t2,8($key) |
470 | lwz $t3,12($key) | 473 | lwz $t3,12($key) |
474 | rlwinm $acc02,$s2,`32-24`,24,31 | ||
475 | rlwinm $acc03,$s3,`32-24`,24,31 | ||
476 | lwz $acc08,`2048+0`($Tbl0) ! prefetch Te4 | ||
477 | lwz $acc09,`2048+32`($Tbl0) | ||
471 | rlwinm $acc04,$s1,`32-16`,24,31 | 478 | rlwinm $acc04,$s1,`32-16`,24,31 |
472 | rlwinm $acc05,$s2,`32-16`,24,31 | 479 | rlwinm $acc05,$s2,`32-16`,24,31 |
473 | lbzx $acc00,$Tbl2,$acc00 | 480 | lwz $acc10,`2048+64`($Tbl0) |
474 | lbzx $acc01,$Tbl2,$acc01 | 481 | lwz $acc11,`2048+96`($Tbl0) |
475 | rlwinm $acc06,$s3,`32-16`,24,31 | 482 | rlwinm $acc06,$s3,`32-16`,24,31 |
476 | rlwinm $acc07,$s0,`32-16`,24,31 | 483 | rlwinm $acc07,$s0,`32-16`,24,31 |
477 | lbzx $acc02,$Tbl2,$acc02 | 484 | lwz $acc12,`2048+128`($Tbl0) |
478 | lbzx $acc03,$Tbl2,$acc03 | 485 | lwz $acc13,`2048+160`($Tbl0) |
479 | rlwinm $acc08,$s2,`32-8`,24,31 | 486 | rlwinm $acc08,$s2,`32-8`,24,31 |
480 | rlwinm $acc09,$s3,`32-8`,24,31 | 487 | rlwinm $acc09,$s3,`32-8`,24,31 |
481 | lbzx $acc04,$Tbl2,$acc04 | 488 | lwz $acc14,`2048+192`($Tbl0) |
482 | lbzx $acc05,$Tbl2,$acc05 | 489 | lwz $acc15,`2048+224`($Tbl0) |
483 | rlwinm $acc10,$s0,`32-8`,24,31 | 490 | rlwinm $acc10,$s0,`32-8`,24,31 |
484 | rlwinm $acc11,$s1,`32-8`,24,31 | 491 | rlwinm $acc11,$s1,`32-8`,24,31 |
485 | lbzx $acc06,$Tbl2,$acc06 | 492 | lbzx $acc00,$Tbl2,$acc00 |
486 | lbzx $acc07,$Tbl2,$acc07 | 493 | lbzx $acc01,$Tbl2,$acc01 |
487 | rlwinm $acc12,$s3,`0`,24,31 | 494 | rlwinm $acc12,$s3,`0`,24,31 |
488 | rlwinm $acc13,$s0,`0`,24,31 | 495 | rlwinm $acc13,$s0,`0`,24,31 |
489 | lbzx $acc08,$Tbl2,$acc08 | 496 | lbzx $acc02,$Tbl2,$acc02 |
490 | lbzx $acc09,$Tbl2,$acc09 | 497 | lbzx $acc03,$Tbl2,$acc03 |
491 | rlwinm $acc14,$s1,`0`,24,31 | 498 | rlwinm $acc14,$s1,`0`,24,31 |
492 | rlwinm $acc15,$s2,`0`,24,31 | 499 | rlwinm $acc15,$s2,`0`,24,31 |
493 | lbzx $acc10,$Tbl2,$acc10 | 500 | lbzx $acc04,$Tbl2,$acc04 |
494 | lbzx $acc11,$Tbl2,$acc11 | 501 | lbzx $acc05,$Tbl2,$acc05 |
495 | rlwinm $s0,$acc00,24,0,7 | 502 | rlwinm $s0,$acc00,24,0,7 |
496 | rlwinm $s1,$acc01,24,0,7 | 503 | rlwinm $s1,$acc01,24,0,7 |
497 | lbzx $acc12,$Tbl2,$acc12 | 504 | lbzx $acc06,$Tbl2,$acc06 |
498 | lbzx $acc13,$Tbl2,$acc13 | 505 | lbzx $acc07,$Tbl2,$acc07 |
499 | rlwinm $s2,$acc02,24,0,7 | 506 | rlwinm $s2,$acc02,24,0,7 |
500 | rlwinm $s3,$acc03,24,0,7 | 507 | rlwinm $s3,$acc03,24,0,7 |
501 | lbzx $acc14,$Tbl2,$acc14 | 508 | lbzx $acc08,$Tbl2,$acc08 |
502 | lbzx $acc15,$Tbl2,$acc15 | 509 | lbzx $acc09,$Tbl2,$acc09 |
503 | rlwimi $s0,$acc04,16,8,15 | 510 | rlwimi $s0,$acc04,16,8,15 |
504 | rlwimi $s1,$acc05,16,8,15 | 511 | rlwimi $s1,$acc05,16,8,15 |
512 | lbzx $acc10,$Tbl2,$acc10 | ||
513 | lbzx $acc11,$Tbl2,$acc11 | ||
505 | rlwimi $s2,$acc06,16,8,15 | 514 | rlwimi $s2,$acc06,16,8,15 |
506 | rlwimi $s3,$acc07,16,8,15 | 515 | rlwimi $s3,$acc07,16,8,15 |
516 | lbzx $acc12,$Tbl2,$acc12 | ||
517 | lbzx $acc13,$Tbl2,$acc13 | ||
507 | rlwimi $s0,$acc08,8,16,23 | 518 | rlwimi $s0,$acc08,8,16,23 |
508 | rlwimi $s1,$acc09,8,16,23 | 519 | rlwimi $s1,$acc09,8,16,23 |
520 | lbzx $acc14,$Tbl2,$acc14 | ||
521 | lbzx $acc15,$Tbl2,$acc15 | ||
509 | rlwimi $s2,$acc10,8,16,23 | 522 | rlwimi $s2,$acc10,8,16,23 |
510 | rlwimi $s3,$acc11,8,16,23 | 523 | rlwimi $s3,$acc11,8,16,23 |
511 | or $s0,$s0,$acc12 | 524 | or $s0,$s0,$acc12 |
@@ -542,40 +555,40 @@ Lenc_compact_loop: | |||
542 | rlwinm $acc01,$s1,`32-24`,24,31 | 555 | rlwinm $acc01,$s1,`32-24`,24,31 |
543 | rlwinm $acc02,$s2,`32-24`,24,31 | 556 | rlwinm $acc02,$s2,`32-24`,24,31 |
544 | rlwinm $acc03,$s3,`32-24`,24,31 | 557 | rlwinm $acc03,$s3,`32-24`,24,31 |
545 | lbzx $acc00,$Tbl1,$acc00 | ||
546 | lbzx $acc01,$Tbl1,$acc01 | ||
547 | rlwinm $acc04,$s1,`32-16`,24,31 | 558 | rlwinm $acc04,$s1,`32-16`,24,31 |
548 | rlwinm $acc05,$s2,`32-16`,24,31 | 559 | rlwinm $acc05,$s2,`32-16`,24,31 |
549 | lbzx $acc02,$Tbl1,$acc02 | ||
550 | lbzx $acc03,$Tbl1,$acc03 | ||
551 | rlwinm $acc06,$s3,`32-16`,24,31 | 560 | rlwinm $acc06,$s3,`32-16`,24,31 |
552 | rlwinm $acc07,$s0,`32-16`,24,31 | 561 | rlwinm $acc07,$s0,`32-16`,24,31 |
553 | lbzx $acc04,$Tbl1,$acc04 | 562 | lbzx $acc00,$Tbl1,$acc00 |
554 | lbzx $acc05,$Tbl1,$acc05 | 563 | lbzx $acc01,$Tbl1,$acc01 |
555 | rlwinm $acc08,$s2,`32-8`,24,31 | 564 | rlwinm $acc08,$s2,`32-8`,24,31 |
556 | rlwinm $acc09,$s3,`32-8`,24,31 | 565 | rlwinm $acc09,$s3,`32-8`,24,31 |
557 | lbzx $acc06,$Tbl1,$acc06 | 566 | lbzx $acc02,$Tbl1,$acc02 |
558 | lbzx $acc07,$Tbl1,$acc07 | 567 | lbzx $acc03,$Tbl1,$acc03 |
559 | rlwinm $acc10,$s0,`32-8`,24,31 | 568 | rlwinm $acc10,$s0,`32-8`,24,31 |
560 | rlwinm $acc11,$s1,`32-8`,24,31 | 569 | rlwinm $acc11,$s1,`32-8`,24,31 |
561 | lbzx $acc08,$Tbl1,$acc08 | 570 | lbzx $acc04,$Tbl1,$acc04 |
562 | lbzx $acc09,$Tbl1,$acc09 | 571 | lbzx $acc05,$Tbl1,$acc05 |
563 | rlwinm $acc12,$s3,`0`,24,31 | 572 | rlwinm $acc12,$s3,`0`,24,31 |
564 | rlwinm $acc13,$s0,`0`,24,31 | 573 | rlwinm $acc13,$s0,`0`,24,31 |
565 | lbzx $acc10,$Tbl1,$acc10 | 574 | lbzx $acc06,$Tbl1,$acc06 |
566 | lbzx $acc11,$Tbl1,$acc11 | 575 | lbzx $acc07,$Tbl1,$acc07 |
567 | rlwinm $acc14,$s1,`0`,24,31 | 576 | rlwinm $acc14,$s1,`0`,24,31 |
568 | rlwinm $acc15,$s2,`0`,24,31 | 577 | rlwinm $acc15,$s2,`0`,24,31 |
569 | lbzx $acc12,$Tbl1,$acc12 | 578 | lbzx $acc08,$Tbl1,$acc08 |
570 | lbzx $acc13,$Tbl1,$acc13 | 579 | lbzx $acc09,$Tbl1,$acc09 |
571 | rlwinm $s0,$acc00,24,0,7 | 580 | rlwinm $s0,$acc00,24,0,7 |
572 | rlwinm $s1,$acc01,24,0,7 | 581 | rlwinm $s1,$acc01,24,0,7 |
573 | lbzx $acc14,$Tbl1,$acc14 | 582 | lbzx $acc10,$Tbl1,$acc10 |
574 | lbzx $acc15,$Tbl1,$acc15 | 583 | lbzx $acc11,$Tbl1,$acc11 |
575 | rlwinm $s2,$acc02,24,0,7 | 584 | rlwinm $s2,$acc02,24,0,7 |
576 | rlwinm $s3,$acc03,24,0,7 | 585 | rlwinm $s3,$acc03,24,0,7 |
586 | lbzx $acc12,$Tbl1,$acc12 | ||
587 | lbzx $acc13,$Tbl1,$acc13 | ||
577 | rlwimi $s0,$acc04,16,8,15 | 588 | rlwimi $s0,$acc04,16,8,15 |
578 | rlwimi $s1,$acc05,16,8,15 | 589 | rlwimi $s1,$acc05,16,8,15 |
590 | lbzx $acc14,$Tbl1,$acc14 | ||
591 | lbzx $acc15,$Tbl1,$acc15 | ||
579 | rlwimi $s2,$acc06,16,8,15 | 592 | rlwimi $s2,$acc06,16,8,15 |
580 | rlwimi $s3,$acc07,16,8,15 | 593 | rlwimi $s3,$acc07,16,8,15 |
581 | rlwimi $s0,$acc08,8,16,23 | 594 | rlwimi $s0,$acc08,8,16,23 |
@@ -725,7 +738,7 @@ Lenc_compact_done: | |||
725 | addi $sp,$sp,$FRAME | 738 | addi $sp,$sp,$FRAME |
726 | blr | 739 | blr |
727 | 740 | ||
728 | .align 4 | 741 | .align 5 |
729 | Lppc_AES_decrypt: | 742 | Lppc_AES_decrypt: |
730 | lwz $acc00,240($key) | 743 | lwz $acc00,240($key) |
731 | lwz $t0,0($key) | 744 | lwz $t0,0($key) |
@@ -746,46 +759,46 @@ Lppc_AES_decrypt: | |||
746 | Ldec_loop: | 759 | Ldec_loop: |
747 | rlwinm $acc00,$s0,`32-24+3`,21,28 | 760 | rlwinm $acc00,$s0,`32-24+3`,21,28 |
748 | rlwinm $acc01,$s1,`32-24+3`,21,28 | 761 | rlwinm $acc01,$s1,`32-24+3`,21,28 |
749 | lwz $t0,0($key) | ||
750 | lwz $t1,4($key) | ||
751 | rlwinm $acc02,$s2,`32-24+3`,21,28 | 762 | rlwinm $acc02,$s2,`32-24+3`,21,28 |
752 | rlwinm $acc03,$s3,`32-24+3`,21,28 | 763 | rlwinm $acc03,$s3,`32-24+3`,21,28 |
753 | lwz $t2,8($key) | 764 | lwz $t0,0($key) |
754 | lwz $t3,12($key) | 765 | lwz $t1,4($key) |
755 | rlwinm $acc04,$s3,`32-16+3`,21,28 | 766 | rlwinm $acc04,$s3,`32-16+3`,21,28 |
756 | rlwinm $acc05,$s0,`32-16+3`,21,28 | 767 | rlwinm $acc05,$s0,`32-16+3`,21,28 |
757 | lwzx $acc00,$Tbl0,$acc00 | 768 | lwz $t2,8($key) |
758 | lwzx $acc01,$Tbl0,$acc01 | 769 | lwz $t3,12($key) |
759 | rlwinm $acc06,$s1,`32-16+3`,21,28 | 770 | rlwinm $acc06,$s1,`32-16+3`,21,28 |
760 | rlwinm $acc07,$s2,`32-16+3`,21,28 | 771 | rlwinm $acc07,$s2,`32-16+3`,21,28 |
761 | lwzx $acc02,$Tbl0,$acc02 | 772 | lwzx $acc00,$Tbl0,$acc00 |
762 | lwzx $acc03,$Tbl0,$acc03 | 773 | lwzx $acc01,$Tbl0,$acc01 |
763 | rlwinm $acc08,$s2,`32-8+3`,21,28 | 774 | rlwinm $acc08,$s2,`32-8+3`,21,28 |
764 | rlwinm $acc09,$s3,`32-8+3`,21,28 | 775 | rlwinm $acc09,$s3,`32-8+3`,21,28 |
765 | lwzx $acc04,$Tbl1,$acc04 | 776 | lwzx $acc02,$Tbl0,$acc02 |
766 | lwzx $acc05,$Tbl1,$acc05 | 777 | lwzx $acc03,$Tbl0,$acc03 |
767 | rlwinm $acc10,$s0,`32-8+3`,21,28 | 778 | rlwinm $acc10,$s0,`32-8+3`,21,28 |
768 | rlwinm $acc11,$s1,`32-8+3`,21,28 | 779 | rlwinm $acc11,$s1,`32-8+3`,21,28 |
769 | lwzx $acc06,$Tbl1,$acc06 | 780 | lwzx $acc04,$Tbl1,$acc04 |
770 | lwzx $acc07,$Tbl1,$acc07 | 781 | lwzx $acc05,$Tbl1,$acc05 |
771 | rlwinm $acc12,$s1,`0+3`,21,28 | 782 | rlwinm $acc12,$s1,`0+3`,21,28 |
772 | rlwinm $acc13,$s2,`0+3`,21,28 | 783 | rlwinm $acc13,$s2,`0+3`,21,28 |
773 | lwzx $acc08,$Tbl2,$acc08 | 784 | lwzx $acc06,$Tbl1,$acc06 |
774 | lwzx $acc09,$Tbl2,$acc09 | 785 | lwzx $acc07,$Tbl1,$acc07 |
775 | rlwinm $acc14,$s3,`0+3`,21,28 | 786 | rlwinm $acc14,$s3,`0+3`,21,28 |
776 | rlwinm $acc15,$s0,`0+3`,21,28 | 787 | rlwinm $acc15,$s0,`0+3`,21,28 |
777 | lwzx $acc10,$Tbl2,$acc10 | 788 | lwzx $acc08,$Tbl2,$acc08 |
778 | lwzx $acc11,$Tbl2,$acc11 | 789 | lwzx $acc09,$Tbl2,$acc09 |
779 | xor $t0,$t0,$acc00 | 790 | xor $t0,$t0,$acc00 |
780 | xor $t1,$t1,$acc01 | 791 | xor $t1,$t1,$acc01 |
781 | lwzx $acc12,$Tbl3,$acc12 | 792 | lwzx $acc10,$Tbl2,$acc10 |
782 | lwzx $acc13,$Tbl3,$acc13 | 793 | lwzx $acc11,$Tbl2,$acc11 |
783 | xor $t2,$t2,$acc02 | 794 | xor $t2,$t2,$acc02 |
784 | xor $t3,$t3,$acc03 | 795 | xor $t3,$t3,$acc03 |
785 | lwzx $acc14,$Tbl3,$acc14 | 796 | lwzx $acc12,$Tbl3,$acc12 |
786 | lwzx $acc15,$Tbl3,$acc15 | 797 | lwzx $acc13,$Tbl3,$acc13 |
787 | xor $t0,$t0,$acc04 | 798 | xor $t0,$t0,$acc04 |
788 | xor $t1,$t1,$acc05 | 799 | xor $t1,$t1,$acc05 |
800 | lwzx $acc14,$Tbl3,$acc14 | ||
801 | lwzx $acc15,$Tbl3,$acc15 | ||
789 | xor $t2,$t2,$acc06 | 802 | xor $t2,$t2,$acc06 |
790 | xor $t3,$t3,$acc07 | 803 | xor $t3,$t3,$acc07 |
791 | xor $t0,$t0,$acc08 | 804 | xor $t0,$t0,$acc08 |
@@ -801,56 +814,56 @@ Ldec_loop: | |||
801 | 814 | ||
802 | addi $Tbl2,$Tbl0,2048 | 815 | addi $Tbl2,$Tbl0,2048 |
803 | nop | 816 | nop |
804 | lwz $acc08,`2048+0`($Tbl0) ! prefetch Td4 | ||
805 | lwz $acc09,`2048+32`($Tbl0) | ||
806 | lwz $acc10,`2048+64`($Tbl0) | ||
807 | lwz $acc11,`2048+96`($Tbl0) | ||
808 | lwz $acc08,`2048+128`($Tbl0) | ||
809 | lwz $acc09,`2048+160`($Tbl0) | ||
810 | lwz $acc10,`2048+192`($Tbl0) | ||
811 | lwz $acc11,`2048+224`($Tbl0) | ||
812 | rlwinm $acc00,$s0,`32-24`,24,31 | ||
813 | rlwinm $acc01,$s1,`32-24`,24,31 | ||
814 | lwz $t0,0($key) | 817 | lwz $t0,0($key) |
815 | lwz $t1,4($key) | 818 | lwz $t1,4($key) |
816 | rlwinm $acc02,$s2,`32-24`,24,31 | 819 | rlwinm $acc00,$s0,`32-24`,24,31 |
817 | rlwinm $acc03,$s3,`32-24`,24,31 | 820 | rlwinm $acc01,$s1,`32-24`,24,31 |
818 | lwz $t2,8($key) | 821 | lwz $t2,8($key) |
819 | lwz $t3,12($key) | 822 | lwz $t3,12($key) |
823 | rlwinm $acc02,$s2,`32-24`,24,31 | ||
824 | rlwinm $acc03,$s3,`32-24`,24,31 | ||
825 | lwz $acc08,`2048+0`($Tbl0) ! prefetch Td4 | ||
826 | lwz $acc09,`2048+32`($Tbl0) | ||
820 | rlwinm $acc04,$s3,`32-16`,24,31 | 827 | rlwinm $acc04,$s3,`32-16`,24,31 |
821 | rlwinm $acc05,$s0,`32-16`,24,31 | 828 | rlwinm $acc05,$s0,`32-16`,24,31 |
829 | lwz $acc10,`2048+64`($Tbl0) | ||
830 | lwz $acc11,`2048+96`($Tbl0) | ||
822 | lbzx $acc00,$Tbl2,$acc00 | 831 | lbzx $acc00,$Tbl2,$acc00 |
823 | lbzx $acc01,$Tbl2,$acc01 | 832 | lbzx $acc01,$Tbl2,$acc01 |
833 | lwz $acc12,`2048+128`($Tbl0) | ||
834 | lwz $acc13,`2048+160`($Tbl0) | ||
824 | rlwinm $acc06,$s1,`32-16`,24,31 | 835 | rlwinm $acc06,$s1,`32-16`,24,31 |
825 | rlwinm $acc07,$s2,`32-16`,24,31 | 836 | rlwinm $acc07,$s2,`32-16`,24,31 |
826 | lbzx $acc02,$Tbl2,$acc02 | 837 | lwz $acc14,`2048+192`($Tbl0) |
827 | lbzx $acc03,$Tbl2,$acc03 | 838 | lwz $acc15,`2048+224`($Tbl0) |
828 | rlwinm $acc08,$s2,`32-8`,24,31 | 839 | rlwinm $acc08,$s2,`32-8`,24,31 |
829 | rlwinm $acc09,$s3,`32-8`,24,31 | 840 | rlwinm $acc09,$s3,`32-8`,24,31 |
830 | lbzx $acc04,$Tbl2,$acc04 | 841 | lbzx $acc02,$Tbl2,$acc02 |
831 | lbzx $acc05,$Tbl2,$acc05 | 842 | lbzx $acc03,$Tbl2,$acc03 |
832 | rlwinm $acc10,$s0,`32-8`,24,31 | 843 | rlwinm $acc10,$s0,`32-8`,24,31 |
833 | rlwinm $acc11,$s1,`32-8`,24,31 | 844 | rlwinm $acc11,$s1,`32-8`,24,31 |
834 | lbzx $acc06,$Tbl2,$acc06 | 845 | lbzx $acc04,$Tbl2,$acc04 |
835 | lbzx $acc07,$Tbl2,$acc07 | 846 | lbzx $acc05,$Tbl2,$acc05 |
836 | rlwinm $acc12,$s1,`0`,24,31 | 847 | rlwinm $acc12,$s1,`0`,24,31 |
837 | rlwinm $acc13,$s2,`0`,24,31 | 848 | rlwinm $acc13,$s2,`0`,24,31 |
838 | lbzx $acc08,$Tbl2,$acc08 | 849 | lbzx $acc06,$Tbl2,$acc06 |
839 | lbzx $acc09,$Tbl2,$acc09 | 850 | lbzx $acc07,$Tbl2,$acc07 |
840 | rlwinm $acc14,$s3,`0`,24,31 | 851 | rlwinm $acc14,$s3,`0`,24,31 |
841 | rlwinm $acc15,$s0,`0`,24,31 | 852 | rlwinm $acc15,$s0,`0`,24,31 |
842 | lbzx $acc10,$Tbl2,$acc10 | 853 | lbzx $acc08,$Tbl2,$acc08 |
843 | lbzx $acc11,$Tbl2,$acc11 | 854 | lbzx $acc09,$Tbl2,$acc09 |
844 | rlwinm $s0,$acc00,24,0,7 | 855 | rlwinm $s0,$acc00,24,0,7 |
845 | rlwinm $s1,$acc01,24,0,7 | 856 | rlwinm $s1,$acc01,24,0,7 |
846 | lbzx $acc12,$Tbl2,$acc12 | 857 | lbzx $acc10,$Tbl2,$acc10 |
847 | lbzx $acc13,$Tbl2,$acc13 | 858 | lbzx $acc11,$Tbl2,$acc11 |
848 | rlwinm $s2,$acc02,24,0,7 | 859 | rlwinm $s2,$acc02,24,0,7 |
849 | rlwinm $s3,$acc03,24,0,7 | 860 | rlwinm $s3,$acc03,24,0,7 |
850 | lbzx $acc14,$Tbl2,$acc14 | 861 | lbzx $acc12,$Tbl2,$acc12 |
851 | lbzx $acc15,$Tbl2,$acc15 | 862 | lbzx $acc13,$Tbl2,$acc13 |
852 | rlwimi $s0,$acc04,16,8,15 | 863 | rlwimi $s0,$acc04,16,8,15 |
853 | rlwimi $s1,$acc05,16,8,15 | 864 | rlwimi $s1,$acc05,16,8,15 |
865 | lbzx $acc14,$Tbl2,$acc14 | ||
866 | lbzx $acc15,$Tbl2,$acc15 | ||
854 | rlwimi $s2,$acc06,16,8,15 | 867 | rlwimi $s2,$acc06,16,8,15 |
855 | rlwimi $s3,$acc07,16,8,15 | 868 | rlwimi $s3,$acc07,16,8,15 |
856 | rlwimi $s0,$acc08,8,16,23 | 869 | rlwimi $s0,$acc08,8,16,23 |
@@ -897,40 +910,40 @@ Ldec_compact_loop: | |||
897 | rlwinm $acc01,$s1,`32-24`,24,31 | 910 | rlwinm $acc01,$s1,`32-24`,24,31 |
898 | rlwinm $acc02,$s2,`32-24`,24,31 | 911 | rlwinm $acc02,$s2,`32-24`,24,31 |
899 | rlwinm $acc03,$s3,`32-24`,24,31 | 912 | rlwinm $acc03,$s3,`32-24`,24,31 |
900 | lbzx $acc00,$Tbl1,$acc00 | ||
901 | lbzx $acc01,$Tbl1,$acc01 | ||
902 | rlwinm $acc04,$s3,`32-16`,24,31 | 913 | rlwinm $acc04,$s3,`32-16`,24,31 |
903 | rlwinm $acc05,$s0,`32-16`,24,31 | 914 | rlwinm $acc05,$s0,`32-16`,24,31 |
904 | lbzx $acc02,$Tbl1,$acc02 | ||
905 | lbzx $acc03,$Tbl1,$acc03 | ||
906 | rlwinm $acc06,$s1,`32-16`,24,31 | 915 | rlwinm $acc06,$s1,`32-16`,24,31 |
907 | rlwinm $acc07,$s2,`32-16`,24,31 | 916 | rlwinm $acc07,$s2,`32-16`,24,31 |
908 | lbzx $acc04,$Tbl1,$acc04 | 917 | lbzx $acc00,$Tbl1,$acc00 |
909 | lbzx $acc05,$Tbl1,$acc05 | 918 | lbzx $acc01,$Tbl1,$acc01 |
910 | rlwinm $acc08,$s2,`32-8`,24,31 | 919 | rlwinm $acc08,$s2,`32-8`,24,31 |
911 | rlwinm $acc09,$s3,`32-8`,24,31 | 920 | rlwinm $acc09,$s3,`32-8`,24,31 |
912 | lbzx $acc06,$Tbl1,$acc06 | 921 | lbzx $acc02,$Tbl1,$acc02 |
913 | lbzx $acc07,$Tbl1,$acc07 | 922 | lbzx $acc03,$Tbl1,$acc03 |
914 | rlwinm $acc10,$s0,`32-8`,24,31 | 923 | rlwinm $acc10,$s0,`32-8`,24,31 |
915 | rlwinm $acc11,$s1,`32-8`,24,31 | 924 | rlwinm $acc11,$s1,`32-8`,24,31 |
916 | lbzx $acc08,$Tbl1,$acc08 | 925 | lbzx $acc04,$Tbl1,$acc04 |
917 | lbzx $acc09,$Tbl1,$acc09 | 926 | lbzx $acc05,$Tbl1,$acc05 |
918 | rlwinm $acc12,$s1,`0`,24,31 | 927 | rlwinm $acc12,$s1,`0`,24,31 |
919 | rlwinm $acc13,$s2,`0`,24,31 | 928 | rlwinm $acc13,$s2,`0`,24,31 |
920 | lbzx $acc10,$Tbl1,$acc10 | 929 | lbzx $acc06,$Tbl1,$acc06 |
921 | lbzx $acc11,$Tbl1,$acc11 | 930 | lbzx $acc07,$Tbl1,$acc07 |
922 | rlwinm $acc14,$s3,`0`,24,31 | 931 | rlwinm $acc14,$s3,`0`,24,31 |
923 | rlwinm $acc15,$s0,`0`,24,31 | 932 | rlwinm $acc15,$s0,`0`,24,31 |
924 | lbzx $acc12,$Tbl1,$acc12 | 933 | lbzx $acc08,$Tbl1,$acc08 |
925 | lbzx $acc13,$Tbl1,$acc13 | 934 | lbzx $acc09,$Tbl1,$acc09 |
926 | rlwinm $s0,$acc00,24,0,7 | 935 | rlwinm $s0,$acc00,24,0,7 |
927 | rlwinm $s1,$acc01,24,0,7 | 936 | rlwinm $s1,$acc01,24,0,7 |
928 | lbzx $acc14,$Tbl1,$acc14 | 937 | lbzx $acc10,$Tbl1,$acc10 |
929 | lbzx $acc15,$Tbl1,$acc15 | 938 | lbzx $acc11,$Tbl1,$acc11 |
930 | rlwinm $s2,$acc02,24,0,7 | 939 | rlwinm $s2,$acc02,24,0,7 |
931 | rlwinm $s3,$acc03,24,0,7 | 940 | rlwinm $s3,$acc03,24,0,7 |
941 | lbzx $acc12,$Tbl1,$acc12 | ||
942 | lbzx $acc13,$Tbl1,$acc13 | ||
932 | rlwimi $s0,$acc04,16,8,15 | 943 | rlwimi $s0,$acc04,16,8,15 |
933 | rlwimi $s1,$acc05,16,8,15 | 944 | rlwimi $s1,$acc05,16,8,15 |
945 | lbzx $acc14,$Tbl1,$acc14 | ||
946 | lbzx $acc15,$Tbl1,$acc15 | ||
934 | rlwimi $s2,$acc06,16,8,15 | 947 | rlwimi $s2,$acc06,16,8,15 |
935 | rlwimi $s3,$acc07,16,8,15 | 948 | rlwimi $s3,$acc07,16,8,15 |
936 | rlwimi $s0,$acc08,8,16,23 | 949 | rlwimi $s0,$acc08,8,16,23 |
diff --git a/src/lib/libcrypto/aes/asm/aes-s390x.pl b/src/lib/libcrypto/aes/asm/aes-s390x.pl index 4b27afd92f..7e01889298 100644 --- a/src/lib/libcrypto/aes/asm/aes-s390x.pl +++ b/src/lib/libcrypto/aes/asm/aes-s390x.pl | |||
@@ -765,6 +765,11 @@ $code.=<<___ if (!$softonly); | |||
765 | srl %r5,6 | 765 | srl %r5,6 |
766 | ar %r5,%r0 | 766 | ar %r5,%r0 |
767 | 767 | ||
768 | larl %r1,OPENSSL_s390xcap_P | ||
769 | lg %r0,0(%r1) | ||
770 | tmhl %r0,0x4000 # check for message-security assist | ||
771 | jz .Lekey_internal | ||
772 | |||
768 | lghi %r0,0 # query capability vector | 773 | lghi %r0,0 # query capability vector |
769 | la %r1,16($sp) | 774 | la %r1,16($sp) |
770 | .long 0xb92f0042 # kmc %r4,%r2 | 775 | .long 0xb92f0042 # kmc %r4,%r2 |
@@ -1323,6 +1328,7 @@ $code.=<<___; | |||
1323 | 4: ex $len,0($s1) | 1328 | 4: ex $len,0($s1) |
1324 | j .Lcbc_dec_exit | 1329 | j .Lcbc_dec_exit |
1325 | .size AES_cbc_encrypt,.-AES_cbc_encrypt | 1330 | .size AES_cbc_encrypt,.-AES_cbc_encrypt |
1331 | .comm OPENSSL_s390xcap_P,8,8 | ||
1326 | ___ | 1332 | ___ |
1327 | } | 1333 | } |
1328 | $code.=<<___; | 1334 | $code.=<<___; |
diff --git a/src/lib/libcrypto/aes/asm/aes-x86_64.pl b/src/lib/libcrypto/aes/asm/aes-x86_64.pl index f616f1751f..a545e892ae 100755 --- a/src/lib/libcrypto/aes/asm/aes-x86_64.pl +++ b/src/lib/libcrypto/aes/asm/aes-x86_64.pl | |||
@@ -2,11 +2,12 @@ | |||
2 | # | 2 | # |
3 | # ==================================================================== | 3 | # ==================================================================== |
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | 4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL |
5 | # project. Rights for redistribution and usage in source and binary | 5 | # project. The module is, however, dual licensed under OpenSSL and |
6 | # forms are granted according to the OpenSSL license. | 6 | # CRYPTOGAMS licenses depending on where you obtain it. For further |
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
7 | # ==================================================================== | 8 | # ==================================================================== |
8 | # | 9 | # |
9 | # Version 1.2. | 10 | # Version 2.1. |
10 | # | 11 | # |
11 | # aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on | 12 | # aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on |
12 | # Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version | 13 | # Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version |
@@ -17,17 +18,29 @@ | |||
17 | # | 18 | # |
18 | # Performance in number of cycles per processed byte for 128-bit key: | 19 | # Performance in number of cycles per processed byte for 128-bit key: |
19 | # | 20 | # |
20 | # ECB CBC encrypt | 21 | # ECB encrypt ECB decrypt CBC large chunk |
21 | # AMD64 13.7 13.0(*) | 22 | # AMD64 33 41 13.0 |
22 | # EM64T 20.2 18.6(*) | 23 | # EM64T 38 59 18.6(*) |
24 | # Core 2 30 43 14.5(*) | ||
23 | # | 25 | # |
24 | # (*) CBC benchmarks are better than ECB thanks to custom ABI used | 26 | # (*) with hyper-threading off |
25 | # by the private block encryption function. | 27 | |
28 | $flavour = shift; | ||
29 | $output = shift; | ||
30 | if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } | ||
31 | |||
32 | $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); | ||
33 | |||
34 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | ||
35 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | ||
36 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | ||
37 | die "can't locate x86_64-xlate.pl"; | ||
38 | |||
39 | open STDOUT,"| $^X $xlate $flavour $output"; | ||
26 | 40 | ||
27 | $verticalspin=1; # unlike 32-bit version $verticalspin performs | 41 | $verticalspin=1; # unlike 32-bit version $verticalspin performs |
28 | # ~15% better on both AMD and Intel cores | 42 | # ~15% better on both AMD and Intel cores |
29 | $output=shift; | 43 | $speed_limit=512; # see aes-586.pl for details |
30 | open STDOUT,"| $^X ../perlasm/x86_64-xlate.pl $output"; | ||
31 | 44 | ||
32 | $code=".text\n"; | 45 | $code=".text\n"; |
33 | 46 | ||
@@ -35,9 +48,9 @@ $s0="%eax"; | |||
35 | $s1="%ebx"; | 48 | $s1="%ebx"; |
36 | $s2="%ecx"; | 49 | $s2="%ecx"; |
37 | $s3="%edx"; | 50 | $s3="%edx"; |
38 | $acc0="%esi"; | 51 | $acc0="%esi"; $mask80="%rsi"; |
39 | $acc1="%edi"; | 52 | $acc1="%edi"; $maskfe="%rdi"; |
40 | $acc2="%ebp"; | 53 | $acc2="%ebp"; $mask1b="%rbp"; |
41 | $inp="%r8"; | 54 | $inp="%r8"; |
42 | $out="%r9"; | 55 | $out="%r9"; |
43 | $t0="%r10d"; | 56 | $t0="%r10d"; |
@@ -51,6 +64,8 @@ sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; } | |||
51 | sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/; | 64 | sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/; |
52 | $r =~ s/%[er]([sd]i)/%\1l/; | 65 | $r =~ s/%[er]([sd]i)/%\1l/; |
53 | $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; } | 66 | $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; } |
67 | sub LO() { my $r=shift; $r =~ s/%r([a-z]+)/%e\1/; | ||
68 | $r =~ s/%r([0-9]+)/%r\1d/; $r; } | ||
54 | sub _data_word() | 69 | sub _data_word() |
55 | { my $i; | 70 | { my $i; |
56 | while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; } | 71 | while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; } |
@@ -138,22 +153,17 @@ $code.=<<___; | |||
138 | movzb `&lo("$s0")`,$acc0 | 153 | movzb `&lo("$s0")`,$acc0 |
139 | movzb `&lo("$s1")`,$acc1 | 154 | movzb `&lo("$s1")`,$acc1 |
140 | movzb `&lo("$s2")`,$acc2 | 155 | movzb `&lo("$s2")`,$acc2 |
141 | mov 2($sbox,$acc0,8),$t0 | 156 | movzb 2($sbox,$acc0,8),$t0 |
142 | mov 2($sbox,$acc1,8),$t1 | 157 | movzb 2($sbox,$acc1,8),$t1 |
143 | mov 2($sbox,$acc2,8),$t2 | 158 | movzb 2($sbox,$acc2,8),$t2 |
144 | |||
145 | and \$0x000000ff,$t0 | ||
146 | and \$0x000000ff,$t1 | ||
147 | and \$0x000000ff,$t2 | ||
148 | 159 | ||
149 | movzb `&lo("$s3")`,$acc0 | 160 | movzb `&lo("$s3")`,$acc0 |
150 | movzb `&hi("$s1")`,$acc1 | 161 | movzb `&hi("$s1")`,$acc1 |
151 | movzb `&hi("$s2")`,$acc2 | 162 | movzb `&hi("$s2")`,$acc2 |
152 | mov 2($sbox,$acc0,8),$t3 | 163 | movzb 2($sbox,$acc0,8),$t3 |
153 | mov 0($sbox,$acc1,8),$acc1 #$t0 | 164 | mov 0($sbox,$acc1,8),$acc1 #$t0 |
154 | mov 0($sbox,$acc2,8),$acc2 #$t1 | 165 | mov 0($sbox,$acc2,8),$acc2 #$t1 |
155 | 166 | ||
156 | and \$0x000000ff,$t3 | ||
157 | and \$0x0000ff00,$acc1 | 167 | and \$0x0000ff00,$acc1 |
158 | and \$0x0000ff00,$acc2 | 168 | and \$0x0000ff00,$acc2 |
159 | 169 | ||
@@ -345,6 +355,234 @@ $code.=<<___; | |||
345 | .size _x86_64_AES_encrypt,.-_x86_64_AES_encrypt | 355 | .size _x86_64_AES_encrypt,.-_x86_64_AES_encrypt |
346 | ___ | 356 | ___ |
347 | 357 | ||
358 | # it's possible to implement this by shifting tN by 8, filling least | ||
359 | # significant byte with byte load and finally bswap-ing at the end, | ||
360 | # but such partial register load kills Core 2... | ||
361 | sub enccompactvert() | ||
362 | { my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d"); | ||
363 | |||
364 | $code.=<<___; | ||
365 | movzb `&lo("$s0")`,$t0 | ||
366 | movzb `&lo("$s1")`,$t1 | ||
367 | movzb `&lo("$s2")`,$t2 | ||
368 | movzb ($sbox,$t0,1),$t0 | ||
369 | movzb ($sbox,$t1,1),$t1 | ||
370 | movzb ($sbox,$t2,1),$t2 | ||
371 | |||
372 | movzb `&lo("$s3")`,$t3 | ||
373 | movzb `&hi("$s1")`,$acc0 | ||
374 | movzb `&hi("$s2")`,$acc1 | ||
375 | movzb ($sbox,$t3,1),$t3 | ||
376 | movzb ($sbox,$acc0,1),$t4 #$t0 | ||
377 | movzb ($sbox,$acc1,1),$t5 #$t1 | ||
378 | |||
379 | movzb `&hi("$s3")`,$acc2 | ||
380 | movzb `&hi("$s0")`,$acc0 | ||
381 | shr \$16,$s2 | ||
382 | movzb ($sbox,$acc2,1),$acc2 #$t2 | ||
383 | movzb ($sbox,$acc0,1),$acc0 #$t3 | ||
384 | shr \$16,$s3 | ||
385 | |||
386 | movzb `&lo("$s2")`,$acc1 | ||
387 | shl \$8,$t4 | ||
388 | shl \$8,$t5 | ||
389 | movzb ($sbox,$acc1,1),$acc1 #$t0 | ||
390 | xor $t4,$t0 | ||
391 | xor $t5,$t1 | ||
392 | |||
393 | movzb `&lo("$s3")`,$t4 | ||
394 | shr \$16,$s0 | ||
395 | shr \$16,$s1 | ||
396 | movzb `&lo("$s0")`,$t5 | ||
397 | shl \$8,$acc2 | ||
398 | shl \$8,$acc0 | ||
399 | movzb ($sbox,$t4,1),$t4 #$t1 | ||
400 | movzb ($sbox,$t5,1),$t5 #$t2 | ||
401 | xor $acc2,$t2 | ||
402 | xor $acc0,$t3 | ||
403 | |||
404 | movzb `&lo("$s1")`,$acc2 | ||
405 | movzb `&hi("$s3")`,$acc0 | ||
406 | shl \$16,$acc1 | ||
407 | movzb ($sbox,$acc2,1),$acc2 #$t3 | ||
408 | movzb ($sbox,$acc0,1),$acc0 #$t0 | ||
409 | xor $acc1,$t0 | ||
410 | |||
411 | movzb `&hi("$s0")`,$acc1 | ||
412 | shr \$8,$s2 | ||
413 | shr \$8,$s1 | ||
414 | movzb ($sbox,$acc1,1),$acc1 #$t1 | ||
415 | movzb ($sbox,$s2,1),$s3 #$t3 | ||
416 | movzb ($sbox,$s1,1),$s2 #$t2 | ||
417 | shl \$16,$t4 | ||
418 | shl \$16,$t5 | ||
419 | shl \$16,$acc2 | ||
420 | xor $t4,$t1 | ||
421 | xor $t5,$t2 | ||
422 | xor $acc2,$t3 | ||
423 | |||
424 | shl \$24,$acc0 | ||
425 | shl \$24,$acc1 | ||
426 | shl \$24,$s3 | ||
427 | xor $acc0,$t0 | ||
428 | shl \$24,$s2 | ||
429 | xor $acc1,$t1 | ||
430 | mov $t0,$s0 | ||
431 | mov $t1,$s1 | ||
432 | xor $t2,$s2 | ||
433 | xor $t3,$s3 | ||
434 | ___ | ||
435 | } | ||
436 | |||
437 | sub enctransform_ref() | ||
438 | { my $sn = shift; | ||
439 | my ($acc,$r2,$tmp)=("%r8d","%r9d","%r13d"); | ||
440 | |||
441 | $code.=<<___; | ||
442 | mov $sn,$acc | ||
443 | and \$0x80808080,$acc | ||
444 | mov $acc,$tmp | ||
445 | shr \$7,$tmp | ||
446 | lea ($sn,$sn),$r2 | ||
447 | sub $tmp,$acc | ||
448 | and \$0xfefefefe,$r2 | ||
449 | and \$0x1b1b1b1b,$acc | ||
450 | mov $sn,$tmp | ||
451 | xor $acc,$r2 | ||
452 | |||
453 | xor $r2,$sn | ||
454 | rol \$24,$sn | ||
455 | xor $r2,$sn | ||
456 | ror \$16,$tmp | ||
457 | xor $tmp,$sn | ||
458 | ror \$8,$tmp | ||
459 | xor $tmp,$sn | ||
460 | ___ | ||
461 | } | ||
462 | |||
463 | # unlike decrypt case it does not pay off to parallelize enctransform | ||
464 | sub enctransform() | ||
465 | { my ($t3,$r20,$r21)=($acc2,"%r8d","%r9d"); | ||
466 | |||
467 | $code.=<<___; | ||
468 | mov $s0,$acc0 | ||
469 | mov $s1,$acc1 | ||
470 | and \$0x80808080,$acc0 | ||
471 | and \$0x80808080,$acc1 | ||
472 | mov $acc0,$t0 | ||
473 | mov $acc1,$t1 | ||
474 | shr \$7,$t0 | ||
475 | lea ($s0,$s0),$r20 | ||
476 | shr \$7,$t1 | ||
477 | lea ($s1,$s1),$r21 | ||
478 | sub $t0,$acc0 | ||
479 | sub $t1,$acc1 | ||
480 | and \$0xfefefefe,$r20 | ||
481 | and \$0xfefefefe,$r21 | ||
482 | and \$0x1b1b1b1b,$acc0 | ||
483 | and \$0x1b1b1b1b,$acc1 | ||
484 | mov $s0,$t0 | ||
485 | mov $s1,$t1 | ||
486 | xor $acc0,$r20 | ||
487 | xor $acc1,$r21 | ||
488 | |||
489 | xor $r20,$s0 | ||
490 | xor $r21,$s1 | ||
491 | mov $s2,$acc0 | ||
492 | mov $s3,$acc1 | ||
493 | rol \$24,$s0 | ||
494 | rol \$24,$s1 | ||
495 | and \$0x80808080,$acc0 | ||
496 | and \$0x80808080,$acc1 | ||
497 | xor $r20,$s0 | ||
498 | xor $r21,$s1 | ||
499 | mov $acc0,$t2 | ||
500 | mov $acc1,$t3 | ||
501 | ror \$16,$t0 | ||
502 | ror \$16,$t1 | ||
503 | shr \$7,$t2 | ||
504 | lea ($s2,$s2),$r20 | ||
505 | xor $t0,$s0 | ||
506 | xor $t1,$s1 | ||
507 | shr \$7,$t3 | ||
508 | lea ($s3,$s3),$r21 | ||
509 | ror \$8,$t0 | ||
510 | ror \$8,$t1 | ||
511 | sub $t2,$acc0 | ||
512 | sub $t3,$acc1 | ||
513 | xor $t0,$s0 | ||
514 | xor $t1,$s1 | ||
515 | |||
516 | and \$0xfefefefe,$r20 | ||
517 | and \$0xfefefefe,$r21 | ||
518 | and \$0x1b1b1b1b,$acc0 | ||
519 | and \$0x1b1b1b1b,$acc1 | ||
520 | mov $s2,$t2 | ||
521 | mov $s3,$t3 | ||
522 | xor $acc0,$r20 | ||
523 | xor $acc1,$r21 | ||
524 | |||
525 | xor $r20,$s2 | ||
526 | xor $r21,$s3 | ||
527 | rol \$24,$s2 | ||
528 | rol \$24,$s3 | ||
529 | xor $r20,$s2 | ||
530 | xor $r21,$s3 | ||
531 | mov 0($sbox),$acc0 # prefetch Te4 | ||
532 | ror \$16,$t2 | ||
533 | ror \$16,$t3 | ||
534 | mov 64($sbox),$acc1 | ||
535 | xor $t2,$s2 | ||
536 | xor $t3,$s3 | ||
537 | mov 128($sbox),$r20 | ||
538 | ror \$8,$t2 | ||
539 | ror \$8,$t3 | ||
540 | mov 192($sbox),$r21 | ||
541 | xor $t2,$s2 | ||
542 | xor $t3,$s3 | ||
543 | ___ | ||
544 | } | ||
545 | |||
546 | $code.=<<___; | ||
547 | .type _x86_64_AES_encrypt_compact,\@abi-omnipotent | ||
548 | .align 16 | ||
549 | _x86_64_AES_encrypt_compact: | ||
550 | lea 128($sbox),$inp # size optimization | ||
551 | mov 0-128($inp),$acc1 # prefetch Te4 | ||
552 | mov 32-128($inp),$acc2 | ||
553 | mov 64-128($inp),$t0 | ||
554 | mov 96-128($inp),$t1 | ||
555 | mov 128-128($inp),$acc1 | ||
556 | mov 160-128($inp),$acc2 | ||
557 | mov 192-128($inp),$t0 | ||
558 | mov 224-128($inp),$t1 | ||
559 | jmp .Lenc_loop_compact | ||
560 | .align 16 | ||
561 | .Lenc_loop_compact: | ||
562 | xor 0($key),$s0 # xor with key | ||
563 | xor 4($key),$s1 | ||
564 | xor 8($key),$s2 | ||
565 | xor 12($key),$s3 | ||
566 | lea 16($key),$key | ||
567 | ___ | ||
568 | &enccompactvert(); | ||
569 | $code.=<<___; | ||
570 | cmp 16(%rsp),$key | ||
571 | je .Lenc_compact_done | ||
572 | ___ | ||
573 | &enctransform(); | ||
574 | $code.=<<___; | ||
575 | jmp .Lenc_loop_compact | ||
576 | .align 16 | ||
577 | .Lenc_compact_done: | ||
578 | xor 0($key),$s0 | ||
579 | xor 4($key),$s1 | ||
580 | xor 8($key),$s2 | ||
581 | xor 12($key),$s3 | ||
582 | .byte 0xf3,0xc3 # rep ret | ||
583 | .size _x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact | ||
584 | ___ | ||
585 | |||
348 | # void AES_encrypt (const void *inp,void *out,const AES_KEY *key); | 586 | # void AES_encrypt (const void *inp,void *out,const AES_KEY *key); |
349 | $code.=<<___; | 587 | $code.=<<___; |
350 | .globl AES_encrypt | 588 | .globl AES_encrypt |
@@ -358,31 +596,57 @@ AES_encrypt: | |||
358 | push %r14 | 596 | push %r14 |
359 | push %r15 | 597 | push %r15 |
360 | 598 | ||
361 | mov %rdx,$key | 599 | # allocate frame "above" key schedule |
362 | mov %rdi,$inp | 600 | mov %rsp,%r10 |
363 | mov %rsi,$out | 601 | lea -63(%rdx),%rcx # %rdx is key argument |
364 | 602 | and \$-64,%rsp | |
365 | .picmeup $sbox | 603 | sub %rsp,%rcx |
366 | lea AES_Te-.($sbox),$sbox | 604 | neg %rcx |
367 | 605 | and \$0x3c0,%rcx | |
368 | mov 0($inp),$s0 | 606 | sub %rcx,%rsp |
369 | mov 4($inp),$s1 | 607 | sub \$32,%rsp |
370 | mov 8($inp),$s2 | ||
371 | mov 12($inp),$s3 | ||
372 | 608 | ||
373 | call _x86_64_AES_encrypt | 609 | mov %rsi,16(%rsp) # save out |
610 | mov %r10,24(%rsp) # save real stack pointer | ||
611 | .Lenc_prologue: | ||
374 | 612 | ||
375 | mov $s0,0($out) | 613 | mov %rdx,$key |
614 | mov 240($key),$rnds # load rounds | ||
615 | |||
616 | mov 0(%rdi),$s0 # load input vector | ||
617 | mov 4(%rdi),$s1 | ||
618 | mov 8(%rdi),$s2 | ||
619 | mov 12(%rdi),$s3 | ||
620 | |||
621 | shl \$4,$rnds | ||
622 | lea ($key,$rnds),%rbp | ||
623 | mov $key,(%rsp) # key schedule | ||
624 | mov %rbp,8(%rsp) # end of key schedule | ||
625 | |||
626 | # pick Te4 copy which can't "overlap" with stack frame or key schedule | ||
627 | lea .LAES_Te+2048(%rip),$sbox | ||
628 | lea 768(%rsp),%rbp | ||
629 | sub $sbox,%rbp | ||
630 | and \$0x300,%rbp | ||
631 | lea ($sbox,%rbp),$sbox | ||
632 | |||
633 | call _x86_64_AES_encrypt_compact | ||
634 | |||
635 | mov 16(%rsp),$out # restore out | ||
636 | mov 24(%rsp),%rsi # restore saved stack pointer | ||
637 | mov $s0,0($out) # write output vector | ||
376 | mov $s1,4($out) | 638 | mov $s1,4($out) |
377 | mov $s2,8($out) | 639 | mov $s2,8($out) |
378 | mov $s3,12($out) | 640 | mov $s3,12($out) |
379 | 641 | ||
380 | pop %r15 | 642 | mov (%rsi),%r15 |
381 | pop %r14 | 643 | mov 8(%rsi),%r14 |
382 | pop %r13 | 644 | mov 16(%rsi),%r13 |
383 | pop %r12 | 645 | mov 24(%rsi),%r12 |
384 | pop %rbp | 646 | mov 32(%rsi),%rbp |
385 | pop %rbx | 647 | mov 40(%rsi),%rbx |
648 | lea 48(%rsi),%rsp | ||
649 | .Lenc_epilogue: | ||
386 | ret | 650 | ret |
387 | .size AES_encrypt,.-AES_encrypt | 651 | .size AES_encrypt,.-AES_encrypt |
388 | ___ | 652 | ___ |
@@ -453,19 +717,20 @@ sub declastvert() | |||
453 | { my $t3="%r8d"; # zaps $inp! | 717 | { my $t3="%r8d"; # zaps $inp! |
454 | 718 | ||
455 | $code.=<<___; | 719 | $code.=<<___; |
720 | lea 2048($sbox),$sbox # size optimization | ||
456 | movzb `&lo("$s0")`,$acc0 | 721 | movzb `&lo("$s0")`,$acc0 |
457 | movzb `&lo("$s1")`,$acc1 | 722 | movzb `&lo("$s1")`,$acc1 |
458 | movzb `&lo("$s2")`,$acc2 | 723 | movzb `&lo("$s2")`,$acc2 |
459 | movzb 2048($sbox,$acc0,1),$t0 | 724 | movzb ($sbox,$acc0,1),$t0 |
460 | movzb 2048($sbox,$acc1,1),$t1 | 725 | movzb ($sbox,$acc1,1),$t1 |
461 | movzb 2048($sbox,$acc2,1),$t2 | 726 | movzb ($sbox,$acc2,1),$t2 |
462 | 727 | ||
463 | movzb `&lo("$s3")`,$acc0 | 728 | movzb `&lo("$s3")`,$acc0 |
464 | movzb `&hi("$s3")`,$acc1 | 729 | movzb `&hi("$s3")`,$acc1 |
465 | movzb `&hi("$s0")`,$acc2 | 730 | movzb `&hi("$s0")`,$acc2 |
466 | movzb 2048($sbox,$acc0,1),$t3 | 731 | movzb ($sbox,$acc0,1),$t3 |
467 | movzb 2048($sbox,$acc1,1),$acc1 #$t0 | 732 | movzb ($sbox,$acc1,1),$acc1 #$t0 |
468 | movzb 2048($sbox,$acc2,1),$acc2 #$t1 | 733 | movzb ($sbox,$acc2,1),$acc2 #$t1 |
469 | 734 | ||
470 | shl \$8,$acc1 | 735 | shl \$8,$acc1 |
471 | shl \$8,$acc2 | 736 | shl \$8,$acc2 |
@@ -477,8 +742,8 @@ $code.=<<___; | |||
477 | movzb `&hi("$s1")`,$acc0 | 742 | movzb `&hi("$s1")`,$acc0 |
478 | movzb `&hi("$s2")`,$acc1 | 743 | movzb `&hi("$s2")`,$acc1 |
479 | shr \$16,$s0 | 744 | shr \$16,$s0 |
480 | movzb 2048($sbox,$acc0,1),$acc0 #$t2 | 745 | movzb ($sbox,$acc0,1),$acc0 #$t2 |
481 | movzb 2048($sbox,$acc1,1),$acc1 #$t3 | 746 | movzb ($sbox,$acc1,1),$acc1 #$t3 |
482 | 747 | ||
483 | shl \$8,$acc0 | 748 | shl \$8,$acc0 |
484 | shl \$8,$acc1 | 749 | shl \$8,$acc1 |
@@ -490,9 +755,9 @@ $code.=<<___; | |||
490 | movzb `&lo("$s2")`,$acc0 | 755 | movzb `&lo("$s2")`,$acc0 |
491 | movzb `&lo("$s3")`,$acc1 | 756 | movzb `&lo("$s3")`,$acc1 |
492 | movzb `&lo("$s0")`,$acc2 | 757 | movzb `&lo("$s0")`,$acc2 |
493 | movzb 2048($sbox,$acc0,1),$acc0 #$t0 | 758 | movzb ($sbox,$acc0,1),$acc0 #$t0 |
494 | movzb 2048($sbox,$acc1,1),$acc1 #$t1 | 759 | movzb ($sbox,$acc1,1),$acc1 #$t1 |
495 | movzb 2048($sbox,$acc2,1),$acc2 #$t2 | 760 | movzb ($sbox,$acc2,1),$acc2 #$t2 |
496 | 761 | ||
497 | shl \$16,$acc0 | 762 | shl \$16,$acc0 |
498 | shl \$16,$acc1 | 763 | shl \$16,$acc1 |
@@ -505,9 +770,9 @@ $code.=<<___; | |||
505 | movzb `&lo("$s1")`,$acc0 | 770 | movzb `&lo("$s1")`,$acc0 |
506 | movzb `&hi("$s1")`,$acc1 | 771 | movzb `&hi("$s1")`,$acc1 |
507 | movzb `&hi("$s2")`,$acc2 | 772 | movzb `&hi("$s2")`,$acc2 |
508 | movzb 2048($sbox,$acc0,1),$acc0 #$t3 | 773 | movzb ($sbox,$acc0,1),$acc0 #$t3 |
509 | movzb 2048($sbox,$acc1,1),$acc1 #$t0 | 774 | movzb ($sbox,$acc1,1),$acc1 #$t0 |
510 | movzb 2048($sbox,$acc2,1),$acc2 #$t1 | 775 | movzb ($sbox,$acc2,1),$acc2 #$t1 |
511 | 776 | ||
512 | shl \$16,$acc0 | 777 | shl \$16,$acc0 |
513 | shl \$24,$acc1 | 778 | shl \$24,$acc1 |
@@ -520,8 +785,8 @@ $code.=<<___; | |||
520 | movzb `&hi("$s3")`,$acc0 | 785 | movzb `&hi("$s3")`,$acc0 |
521 | movzb `&hi("$s0")`,$acc1 | 786 | movzb `&hi("$s0")`,$acc1 |
522 | mov 16+12($key),$s3 | 787 | mov 16+12($key),$s3 |
523 | movzb 2048($sbox,$acc0,1),$acc0 #$t2 | 788 | movzb ($sbox,$acc0,1),$acc0 #$t2 |
524 | movzb 2048($sbox,$acc1,1),$acc1 #$t3 | 789 | movzb ($sbox,$acc1,1),$acc1 #$t3 |
525 | mov 16+0($key),$s0 | 790 | mov 16+0($key),$s0 |
526 | 791 | ||
527 | shl \$24,$acc0 | 792 | shl \$24,$acc0 |
@@ -532,6 +797,7 @@ $code.=<<___; | |||
532 | 797 | ||
533 | mov 16+4($key),$s1 | 798 | mov 16+4($key),$s1 |
534 | mov 16+8($key),$s2 | 799 | mov 16+8($key),$s2 |
800 | lea -2048($sbox),$sbox | ||
535 | xor $t0,$s0 | 801 | xor $t0,$s0 |
536 | xor $t1,$s1 | 802 | xor $t1,$s1 |
537 | xor $t2,$s2 | 803 | xor $t2,$s2 |
@@ -659,6 +925,260 @@ $code.=<<___; | |||
659 | .size _x86_64_AES_decrypt,.-_x86_64_AES_decrypt | 925 | .size _x86_64_AES_decrypt,.-_x86_64_AES_decrypt |
660 | ___ | 926 | ___ |
661 | 927 | ||
928 | sub deccompactvert() | ||
929 | { my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d"); | ||
930 | |||
931 | $code.=<<___; | ||
932 | movzb `&lo("$s0")`,$t0 | ||
933 | movzb `&lo("$s1")`,$t1 | ||
934 | movzb `&lo("$s2")`,$t2 | ||
935 | movzb ($sbox,$t0,1),$t0 | ||
936 | movzb ($sbox,$t1,1),$t1 | ||
937 | movzb ($sbox,$t2,1),$t2 | ||
938 | |||
939 | movzb `&lo("$s3")`,$t3 | ||
940 | movzb `&hi("$s3")`,$acc0 | ||
941 | movzb `&hi("$s0")`,$acc1 | ||
942 | movzb ($sbox,$t3,1),$t3 | ||
943 | movzb ($sbox,$acc0,1),$t4 #$t0 | ||
944 | movzb ($sbox,$acc1,1),$t5 #$t1 | ||
945 | |||
946 | movzb `&hi("$s1")`,$acc2 | ||
947 | movzb `&hi("$s2")`,$acc0 | ||
948 | shr \$16,$s2 | ||
949 | movzb ($sbox,$acc2,1),$acc2 #$t2 | ||
950 | movzb ($sbox,$acc0,1),$acc0 #$t3 | ||
951 | shr \$16,$s3 | ||
952 | |||
953 | movzb `&lo("$s2")`,$acc1 | ||
954 | shl \$8,$t4 | ||
955 | shl \$8,$t5 | ||
956 | movzb ($sbox,$acc1,1),$acc1 #$t0 | ||
957 | xor $t4,$t0 | ||
958 | xor $t5,$t1 | ||
959 | |||
960 | movzb `&lo("$s3")`,$t4 | ||
961 | shr \$16,$s0 | ||
962 | shr \$16,$s1 | ||
963 | movzb `&lo("$s0")`,$t5 | ||
964 | shl \$8,$acc2 | ||
965 | shl \$8,$acc0 | ||
966 | movzb ($sbox,$t4,1),$t4 #$t1 | ||
967 | movzb ($sbox,$t5,1),$t5 #$t2 | ||
968 | xor $acc2,$t2 | ||
969 | xor $acc0,$t3 | ||
970 | |||
971 | movzb `&lo("$s1")`,$acc2 | ||
972 | movzb `&hi("$s1")`,$acc0 | ||
973 | shl \$16,$acc1 | ||
974 | movzb ($sbox,$acc2,1),$acc2 #$t3 | ||
975 | movzb ($sbox,$acc0,1),$acc0 #$t0 | ||
976 | xor $acc1,$t0 | ||
977 | |||
978 | movzb `&hi("$s2")`,$acc1 | ||
979 | shl \$16,$t4 | ||
980 | shl \$16,$t5 | ||
981 | movzb ($sbox,$acc1,1),$s1 #$t1 | ||
982 | xor $t4,$t1 | ||
983 | xor $t5,$t2 | ||
984 | |||
985 | movzb `&hi("$s3")`,$acc1 | ||
986 | shr \$8,$s0 | ||
987 | shl \$16,$acc2 | ||
988 | movzb ($sbox,$acc1,1),$s2 #$t2 | ||
989 | movzb ($sbox,$s0,1),$s3 #$t3 | ||
990 | xor $acc2,$t3 | ||
991 | |||
992 | shl \$24,$acc0 | ||
993 | shl \$24,$s1 | ||
994 | shl \$24,$s2 | ||
995 | xor $acc0,$t0 | ||
996 | shl \$24,$s3 | ||
997 | xor $t1,$s1 | ||
998 | mov $t0,$s0 | ||
999 | xor $t2,$s2 | ||
1000 | xor $t3,$s3 | ||
1001 | ___ | ||
1002 | } | ||
1003 | |||
1004 | # parallelized version! input is pair of 64-bit values: %rax=s1.s0 | ||
1005 | # and %rcx=s3.s2, output is four 32-bit values in %eax=s0, %ebx=s1, | ||
1006 | # %ecx=s2 and %edx=s3. | ||
1007 | sub dectransform() | ||
1008 | { my ($tp10,$tp20,$tp40,$tp80,$acc0)=("%rax","%r8", "%r9", "%r10","%rbx"); | ||
1009 | my ($tp18,$tp28,$tp48,$tp88,$acc8)=("%rcx","%r11","%r12","%r13","%rdx"); | ||
1010 | my $prefetch = shift; | ||
1011 | |||
1012 | $code.=<<___; | ||
1013 | mov $tp10,$acc0 | ||
1014 | mov $tp18,$acc8 | ||
1015 | and $mask80,$acc0 | ||
1016 | and $mask80,$acc8 | ||
1017 | mov $acc0,$tp40 | ||
1018 | mov $acc8,$tp48 | ||
1019 | shr \$7,$tp40 | ||
1020 | lea ($tp10,$tp10),$tp20 | ||
1021 | shr \$7,$tp48 | ||
1022 | lea ($tp18,$tp18),$tp28 | ||
1023 | sub $tp40,$acc0 | ||
1024 | sub $tp48,$acc8 | ||
1025 | and $maskfe,$tp20 | ||
1026 | and $maskfe,$tp28 | ||
1027 | and $mask1b,$acc0 | ||
1028 | and $mask1b,$acc8 | ||
1029 | xor $tp20,$acc0 | ||
1030 | xor $tp28,$acc8 | ||
1031 | mov $acc0,$tp20 | ||
1032 | mov $acc8,$tp28 | ||
1033 | |||
1034 | and $mask80,$acc0 | ||
1035 | and $mask80,$acc8 | ||
1036 | mov $acc0,$tp80 | ||
1037 | mov $acc8,$tp88 | ||
1038 | shr \$7,$tp80 | ||
1039 | lea ($tp20,$tp20),$tp40 | ||
1040 | shr \$7,$tp88 | ||
1041 | lea ($tp28,$tp28),$tp48 | ||
1042 | sub $tp80,$acc0 | ||
1043 | sub $tp88,$acc8 | ||
1044 | and $maskfe,$tp40 | ||
1045 | and $maskfe,$tp48 | ||
1046 | and $mask1b,$acc0 | ||
1047 | and $mask1b,$acc8 | ||
1048 | xor $tp40,$acc0 | ||
1049 | xor $tp48,$acc8 | ||
1050 | mov $acc0,$tp40 | ||
1051 | mov $acc8,$tp48 | ||
1052 | |||
1053 | and $mask80,$acc0 | ||
1054 | and $mask80,$acc8 | ||
1055 | mov $acc0,$tp80 | ||
1056 | mov $acc8,$tp88 | ||
1057 | shr \$7,$tp80 | ||
1058 | xor $tp10,$tp20 # tp2^=tp1 | ||
1059 | shr \$7,$tp88 | ||
1060 | xor $tp18,$tp28 # tp2^=tp1 | ||
1061 | sub $tp80,$acc0 | ||
1062 | sub $tp88,$acc8 | ||
1063 | lea ($tp40,$tp40),$tp80 | ||
1064 | lea ($tp48,$tp48),$tp88 | ||
1065 | xor $tp10,$tp40 # tp4^=tp1 | ||
1066 | xor $tp18,$tp48 # tp4^=tp1 | ||
1067 | and $maskfe,$tp80 | ||
1068 | and $maskfe,$tp88 | ||
1069 | and $mask1b,$acc0 | ||
1070 | and $mask1b,$acc8 | ||
1071 | xor $acc0,$tp80 | ||
1072 | xor $acc8,$tp88 | ||
1073 | |||
1074 | xor $tp80,$tp10 # tp1^=tp8 | ||
1075 | xor $tp88,$tp18 # tp1^=tp8 | ||
1076 | xor $tp80,$tp20 # tp2^tp1^=tp8 | ||
1077 | xor $tp88,$tp28 # tp2^tp1^=tp8 | ||
1078 | mov $tp10,$acc0 | ||
1079 | mov $tp18,$acc8 | ||
1080 | xor $tp80,$tp40 # tp4^tp1^=tp8 | ||
1081 | xor $tp88,$tp48 # tp4^tp1^=tp8 | ||
1082 | shr \$32,$acc0 | ||
1083 | shr \$32,$acc8 | ||
1084 | xor $tp20,$tp80 # tp8^=tp8^tp2^tp1=tp2^tp1 | ||
1085 | xor $tp28,$tp88 # tp8^=tp8^tp2^tp1=tp2^tp1 | ||
1086 | rol \$8,`&LO("$tp10")` # ROTATE(tp1^tp8,8) | ||
1087 | rol \$8,`&LO("$tp18")` # ROTATE(tp1^tp8,8) | ||
1088 | xor $tp40,$tp80 # tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2 | ||
1089 | xor $tp48,$tp88 # tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2 | ||
1090 | |||
1091 | rol \$8,`&LO("$acc0")` # ROTATE(tp1^tp8,8) | ||
1092 | rol \$8,`&LO("$acc8")` # ROTATE(tp1^tp8,8) | ||
1093 | xor `&LO("$tp80")`,`&LO("$tp10")` | ||
1094 | xor `&LO("$tp88")`,`&LO("$tp18")` | ||
1095 | shr \$32,$tp80 | ||
1096 | shr \$32,$tp88 | ||
1097 | xor `&LO("$tp80")`,`&LO("$acc0")` | ||
1098 | xor `&LO("$tp88")`,`&LO("$acc8")` | ||
1099 | |||
1100 | mov $tp20,$tp80 | ||
1101 | mov $tp28,$tp88 | ||
1102 | shr \$32,$tp80 | ||
1103 | shr \$32,$tp88 | ||
1104 | rol \$24,`&LO("$tp20")` # ROTATE(tp2^tp1^tp8,24) | ||
1105 | rol \$24,`&LO("$tp28")` # ROTATE(tp2^tp1^tp8,24) | ||
1106 | rol \$24,`&LO("$tp80")` # ROTATE(tp2^tp1^tp8,24) | ||
1107 | rol \$24,`&LO("$tp88")` # ROTATE(tp2^tp1^tp8,24) | ||
1108 | xor `&LO("$tp20")`,`&LO("$tp10")` | ||
1109 | xor `&LO("$tp28")`,`&LO("$tp18")` | ||
1110 | mov $tp40,$tp20 | ||
1111 | mov $tp48,$tp28 | ||
1112 | xor `&LO("$tp80")`,`&LO("$acc0")` | ||
1113 | xor `&LO("$tp88")`,`&LO("$acc8")` | ||
1114 | |||
1115 | `"mov 0($sbox),$mask80" if ($prefetch)` | ||
1116 | shr \$32,$tp20 | ||
1117 | shr \$32,$tp28 | ||
1118 | `"mov 64($sbox),$maskfe" if ($prefetch)` | ||
1119 | rol \$16,`&LO("$tp40")` # ROTATE(tp4^tp1^tp8,16) | ||
1120 | rol \$16,`&LO("$tp48")` # ROTATE(tp4^tp1^tp8,16) | ||
1121 | `"mov 128($sbox),$mask1b" if ($prefetch)` | ||
1122 | rol \$16,`&LO("$tp20")` # ROTATE(tp4^tp1^tp8,16) | ||
1123 | rol \$16,`&LO("$tp28")` # ROTATE(tp4^tp1^tp8,16) | ||
1124 | `"mov 192($sbox),$tp80" if ($prefetch)` | ||
1125 | xor `&LO("$tp40")`,`&LO("$tp10")` | ||
1126 | xor `&LO("$tp48")`,`&LO("$tp18")` | ||
1127 | `"mov 256($sbox),$tp88" if ($prefetch)` | ||
1128 | xor `&LO("$tp20")`,`&LO("$acc0")` | ||
1129 | xor `&LO("$tp28")`,`&LO("$acc8")` | ||
1130 | ___ | ||
1131 | } | ||
1132 | |||
1133 | $code.=<<___; | ||
1134 | .type _x86_64_AES_decrypt_compact,\@abi-omnipotent | ||
1135 | .align 16 | ||
1136 | _x86_64_AES_decrypt_compact: | ||
1137 | lea 128($sbox),$inp # size optimization | ||
1138 | mov 0-128($inp),$acc1 # prefetch Td4 | ||
1139 | mov 32-128($inp),$acc2 | ||
1140 | mov 64-128($inp),$t0 | ||
1141 | mov 96-128($inp),$t1 | ||
1142 | mov 128-128($inp),$acc1 | ||
1143 | mov 160-128($inp),$acc2 | ||
1144 | mov 192-128($inp),$t0 | ||
1145 | mov 224-128($inp),$t1 | ||
1146 | jmp .Ldec_loop_compact | ||
1147 | |||
1148 | .align 16 | ||
1149 | .Ldec_loop_compact: | ||
1150 | xor 0($key),$s0 # xor with key | ||
1151 | xor 4($key),$s1 | ||
1152 | xor 8($key),$s2 | ||
1153 | xor 12($key),$s3 | ||
1154 | lea 16($key),$key | ||
1155 | ___ | ||
1156 | &deccompactvert(); | ||
1157 | $code.=<<___; | ||
1158 | cmp 16(%rsp),$key | ||
1159 | je .Ldec_compact_done | ||
1160 | |||
1161 | mov 256+0($sbox),$mask80 | ||
1162 | shl \$32,%rbx | ||
1163 | shl \$32,%rdx | ||
1164 | mov 256+8($sbox),$maskfe | ||
1165 | or %rbx,%rax | ||
1166 | or %rdx,%rcx | ||
1167 | mov 256+16($sbox),$mask1b | ||
1168 | ___ | ||
1169 | &dectransform(1); | ||
1170 | $code.=<<___; | ||
1171 | jmp .Ldec_loop_compact | ||
1172 | .align 16 | ||
1173 | .Ldec_compact_done: | ||
1174 | xor 0($key),$s0 | ||
1175 | xor 4($key),$s1 | ||
1176 | xor 8($key),$s2 | ||
1177 | xor 12($key),$s3 | ||
1178 | .byte 0xf3,0xc3 # rep ret | ||
1179 | .size _x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact | ||
1180 | ___ | ||
1181 | |||
662 | # void AES_decrypt (const void *inp,void *out,const AES_KEY *key); | 1182 | # void AES_decrypt (const void *inp,void *out,const AES_KEY *key); |
663 | $code.=<<___; | 1183 | $code.=<<___; |
664 | .globl AES_decrypt | 1184 | .globl AES_decrypt |
@@ -672,43 +1192,59 @@ AES_decrypt: | |||
672 | push %r14 | 1192 | push %r14 |
673 | push %r15 | 1193 | push %r15 |
674 | 1194 | ||
675 | mov %rdx,$key | 1195 | # allocate frame "above" key schedule |
676 | mov %rdi,$inp | 1196 | mov %rsp,%r10 |
677 | mov %rsi,$out | 1197 | lea -63(%rdx),%rcx # %rdx is key argument |
1198 | and \$-64,%rsp | ||
1199 | sub %rsp,%rcx | ||
1200 | neg %rcx | ||
1201 | and \$0x3c0,%rcx | ||
1202 | sub %rcx,%rsp | ||
1203 | sub \$32,%rsp | ||
1204 | |||
1205 | mov %rsi,16(%rsp) # save out | ||
1206 | mov %r10,24(%rsp) # save real stack pointer | ||
1207 | .Ldec_prologue: | ||
678 | 1208 | ||
679 | .picmeup $sbox | 1209 | mov %rdx,$key |
680 | lea AES_Td-.($sbox),$sbox | 1210 | mov 240($key),$rnds # load rounds |
681 | 1211 | ||
682 | # prefetch Td4 | 1212 | mov 0(%rdi),$s0 # load input vector |
683 | lea 2048+128($sbox),$sbox; | 1213 | mov 4(%rdi),$s1 |
684 | mov 0-128($sbox),$s0 | 1214 | mov 8(%rdi),$s2 |
685 | mov 32-128($sbox),$s1 | 1215 | mov 12(%rdi),$s3 |
686 | mov 64-128($sbox),$s2 | 1216 | |
687 | mov 96-128($sbox),$s3 | 1217 | shl \$4,$rnds |
688 | mov 128-128($sbox),$s0 | 1218 | lea ($key,$rnds),%rbp |
689 | mov 160-128($sbox),$s1 | 1219 | mov $key,(%rsp) # key schedule |
690 | mov 192-128($sbox),$s2 | 1220 | mov %rbp,8(%rsp) # end of key schedule |
691 | mov 224-128($sbox),$s3 | 1221 | |
692 | lea -2048-128($sbox),$sbox; | 1222 | # pick Td4 copy which can't "overlap" with stack frame or key schedule |
693 | 1223 | lea .LAES_Td+2048(%rip),$sbox | |
694 | mov 0($inp),$s0 | 1224 | lea 768(%rsp),%rbp |
695 | mov 4($inp),$s1 | 1225 | sub $sbox,%rbp |
696 | mov 8($inp),$s2 | 1226 | and \$0x300,%rbp |
697 | mov 12($inp),$s3 | 1227 | lea ($sbox,%rbp),$sbox |
698 | 1228 | shr \$3,%rbp # recall "magic" constants! | |
699 | call _x86_64_AES_decrypt | 1229 | add %rbp,$sbox |
700 | 1230 | ||
701 | mov $s0,0($out) | 1231 | call _x86_64_AES_decrypt_compact |
1232 | |||
1233 | mov 16(%rsp),$out # restore out | ||
1234 | mov 24(%rsp),%rsi # restore saved stack pointer | ||
1235 | mov $s0,0($out) # write output vector | ||
702 | mov $s1,4($out) | 1236 | mov $s1,4($out) |
703 | mov $s2,8($out) | 1237 | mov $s2,8($out) |
704 | mov $s3,12($out) | 1238 | mov $s3,12($out) |
705 | 1239 | ||
706 | pop %r15 | 1240 | mov (%rsi),%r15 |
707 | pop %r14 | 1241 | mov 8(%rsi),%r14 |
708 | pop %r13 | 1242 | mov 16(%rsi),%r13 |
709 | pop %r12 | 1243 | mov 24(%rsi),%r12 |
710 | pop %rbp | 1244 | mov 32(%rsi),%rbp |
711 | pop %rbx | 1245 | mov 40(%rsi),%rbx |
1246 | lea 48(%rsi),%rsp | ||
1247 | .Ldec_epilogue: | ||
712 | ret | 1248 | ret |
713 | .size AES_decrypt,.-AES_decrypt | 1249 | .size AES_decrypt,.-AES_decrypt |
714 | ___ | 1250 | ___ |
@@ -718,27 +1254,26 @@ sub enckey() | |||
718 | { | 1254 | { |
719 | $code.=<<___; | 1255 | $code.=<<___; |
720 | movz %dl,%esi # rk[i]>>0 | 1256 | movz %dl,%esi # rk[i]>>0 |
721 | mov 2(%rbp,%rsi,8),%ebx | 1257 | movzb -128(%rbp,%rsi),%ebx |
722 | movz %dh,%esi # rk[i]>>8 | 1258 | movz %dh,%esi # rk[i]>>8 |
723 | and \$0xFF000000,%ebx | 1259 | shl \$24,%ebx |
724 | xor %ebx,%eax | 1260 | xor %ebx,%eax |
725 | 1261 | ||
726 | mov 2(%rbp,%rsi,8),%ebx | 1262 | movzb -128(%rbp,%rsi),%ebx |
727 | shr \$16,%edx | 1263 | shr \$16,%edx |
728 | and \$0x000000FF,%ebx | ||
729 | movz %dl,%esi # rk[i]>>16 | 1264 | movz %dl,%esi # rk[i]>>16 |
730 | xor %ebx,%eax | 1265 | xor %ebx,%eax |
731 | 1266 | ||
732 | mov 0(%rbp,%rsi,8),%ebx | 1267 | movzb -128(%rbp,%rsi),%ebx |
733 | movz %dh,%esi # rk[i]>>24 | 1268 | movz %dh,%esi # rk[i]>>24 |
734 | and \$0x0000FF00,%ebx | 1269 | shl \$8,%ebx |
735 | xor %ebx,%eax | 1270 | xor %ebx,%eax |
736 | 1271 | ||
737 | mov 0(%rbp,%rsi,8),%ebx | 1272 | movzb -128(%rbp,%rsi),%ebx |
738 | and \$0x00FF0000,%ebx | 1273 | shl \$16,%ebx |
739 | xor %ebx,%eax | 1274 | xor %ebx,%eax |
740 | 1275 | ||
741 | xor 2048(%rbp,%rcx,4),%eax # rcon | 1276 | xor 1024-128(%rbp,%rcx,4),%eax # rcon |
742 | ___ | 1277 | ___ |
743 | } | 1278 | } |
744 | 1279 | ||
@@ -751,7 +1286,29 @@ $code.=<<___; | |||
751 | AES_set_encrypt_key: | 1286 | AES_set_encrypt_key: |
752 | push %rbx | 1287 | push %rbx |
753 | push %rbp | 1288 | push %rbp |
1289 | push %r12 # redundant, but allows to share | ||
1290 | push %r13 # exception handler... | ||
1291 | push %r14 | ||
1292 | push %r15 | ||
1293 | sub \$8,%rsp | ||
1294 | .Lenc_key_prologue: | ||
1295 | |||
1296 | call _x86_64_AES_set_encrypt_key | ||
1297 | |||
1298 | mov 8(%rsp),%r15 | ||
1299 | mov 16(%rsp),%r14 | ||
1300 | mov 24(%rsp),%r13 | ||
1301 | mov 32(%rsp),%r12 | ||
1302 | mov 40(%rsp),%rbp | ||
1303 | mov 48(%rsp),%rbx | ||
1304 | add \$56,%rsp | ||
1305 | .Lenc_key_epilogue: | ||
1306 | ret | ||
1307 | .size AES_set_encrypt_key,.-AES_set_encrypt_key | ||
754 | 1308 | ||
1309 | .type _x86_64_AES_set_encrypt_key,\@abi-omnipotent | ||
1310 | .align 16 | ||
1311 | _x86_64_AES_set_encrypt_key: | ||
755 | mov %esi,%ecx # %ecx=bits | 1312 | mov %esi,%ecx # %ecx=bits |
756 | mov %rdi,%rsi # %rsi=userKey | 1313 | mov %rdi,%rsi # %rsi=userKey |
757 | mov %rdx,%rdi # %rdi=key | 1314 | mov %rdx,%rdi # %rdi=key |
@@ -761,8 +1318,18 @@ AES_set_encrypt_key: | |||
761 | test \$-1,%rdi | 1318 | test \$-1,%rdi |
762 | jz .Lbadpointer | 1319 | jz .Lbadpointer |
763 | 1320 | ||
764 | .picmeup %rbp | 1321 | lea .LAES_Te(%rip),%rbp |
765 | lea AES_Te-.(%rbp),%rbp | 1322 | lea 2048+128(%rbp),%rbp |
1323 | |||
1324 | # prefetch Te4 | ||
1325 | mov 0-128(%rbp),%eax | ||
1326 | mov 32-128(%rbp),%ebx | ||
1327 | mov 64-128(%rbp),%r8d | ||
1328 | mov 96-128(%rbp),%edx | ||
1329 | mov 128-128(%rbp),%eax | ||
1330 | mov 160-128(%rbp),%ebx | ||
1331 | mov 192-128(%rbp),%r8d | ||
1332 | mov 224-128(%rbp),%edx | ||
766 | 1333 | ||
767 | cmp \$128,%ecx | 1334 | cmp \$128,%ecx |
768 | je .L10rounds | 1335 | je .L10rounds |
@@ -774,15 +1341,12 @@ AES_set_encrypt_key: | |||
774 | jmp .Lexit | 1341 | jmp .Lexit |
775 | 1342 | ||
776 | .L10rounds: | 1343 | .L10rounds: |
777 | mov 0(%rsi),%eax # copy first 4 dwords | 1344 | mov 0(%rsi),%rax # copy first 4 dwords |
778 | mov 4(%rsi),%ebx | 1345 | mov 8(%rsi),%rdx |
779 | mov 8(%rsi),%ecx | 1346 | mov %rax,0(%rdi) |
780 | mov 12(%rsi),%edx | 1347 | mov %rdx,8(%rdi) |
781 | mov %eax,0(%rdi) | ||
782 | mov %ebx,4(%rdi) | ||
783 | mov %ecx,8(%rdi) | ||
784 | mov %edx,12(%rdi) | ||
785 | 1348 | ||
1349 | shr \$32,%rdx | ||
786 | xor %ecx,%ecx | 1350 | xor %ecx,%ecx |
787 | jmp .L10shortcut | 1351 | jmp .L10shortcut |
788 | .align 4 | 1352 | .align 4 |
@@ -810,19 +1374,14 @@ $code.=<<___; | |||
810 | jmp .Lexit | 1374 | jmp .Lexit |
811 | 1375 | ||
812 | .L12rounds: | 1376 | .L12rounds: |
813 | mov 0(%rsi),%eax # copy first 6 dwords | 1377 | mov 0(%rsi),%rax # copy first 6 dwords |
814 | mov 4(%rsi),%ebx | 1378 | mov 8(%rsi),%rbx |
815 | mov 8(%rsi),%ecx | 1379 | mov 16(%rsi),%rdx |
816 | mov 12(%rsi),%edx | 1380 | mov %rax,0(%rdi) |
817 | mov %eax,0(%rdi) | 1381 | mov %rbx,8(%rdi) |
818 | mov %ebx,4(%rdi) | 1382 | mov %rdx,16(%rdi) |
819 | mov %ecx,8(%rdi) | 1383 | |
820 | mov %edx,12(%rdi) | 1384 | shr \$32,%rdx |
821 | mov 16(%rsi),%ecx | ||
822 | mov 20(%rsi),%edx | ||
823 | mov %ecx,16(%rdi) | ||
824 | mov %edx,20(%rdi) | ||
825 | |||
826 | xor %ecx,%ecx | 1385 | xor %ecx,%ecx |
827 | jmp .L12shortcut | 1386 | jmp .L12shortcut |
828 | .align 4 | 1387 | .align 4 |
@@ -858,30 +1417,23 @@ $code.=<<___; | |||
858 | jmp .Lexit | 1417 | jmp .Lexit |
859 | 1418 | ||
860 | .L14rounds: | 1419 | .L14rounds: |
861 | mov 0(%rsi),%eax # copy first 8 dwords | 1420 | mov 0(%rsi),%rax # copy first 8 dwords |
862 | mov 4(%rsi),%ebx | 1421 | mov 8(%rsi),%rbx |
863 | mov 8(%rsi),%ecx | 1422 | mov 16(%rsi),%rcx |
864 | mov 12(%rsi),%edx | 1423 | mov 24(%rsi),%rdx |
865 | mov %eax,0(%rdi) | 1424 | mov %rax,0(%rdi) |
866 | mov %ebx,4(%rdi) | 1425 | mov %rbx,8(%rdi) |
867 | mov %ecx,8(%rdi) | 1426 | mov %rcx,16(%rdi) |
868 | mov %edx,12(%rdi) | 1427 | mov %rdx,24(%rdi) |
869 | mov 16(%rsi),%eax | 1428 | |
870 | mov 20(%rsi),%ebx | 1429 | shr \$32,%rdx |
871 | mov 24(%rsi),%ecx | ||
872 | mov 28(%rsi),%edx | ||
873 | mov %eax,16(%rdi) | ||
874 | mov %ebx,20(%rdi) | ||
875 | mov %ecx,24(%rdi) | ||
876 | mov %edx,28(%rdi) | ||
877 | |||
878 | xor %ecx,%ecx | 1430 | xor %ecx,%ecx |
879 | jmp .L14shortcut | 1431 | jmp .L14shortcut |
880 | .align 4 | 1432 | .align 4 |
881 | .L14loop: | 1433 | .L14loop: |
1434 | mov 0(%rdi),%eax # rk[0] | ||
882 | mov 28(%rdi),%edx # rk[4] | 1435 | mov 28(%rdi),%edx # rk[4] |
883 | .L14shortcut: | 1436 | .L14shortcut: |
884 | mov 0(%rdi),%eax # rk[0] | ||
885 | ___ | 1437 | ___ |
886 | &enckey (); | 1438 | &enckey (); |
887 | $code.=<<___; | 1439 | $code.=<<___; |
@@ -900,24 +1452,23 @@ $code.=<<___; | |||
900 | mov %eax,%edx | 1452 | mov %eax,%edx |
901 | mov 16(%rdi),%eax # rk[4] | 1453 | mov 16(%rdi),%eax # rk[4] |
902 | movz %dl,%esi # rk[11]>>0 | 1454 | movz %dl,%esi # rk[11]>>0 |
903 | mov 2(%rbp,%rsi,8),%ebx | 1455 | movzb -128(%rbp,%rsi),%ebx |
904 | movz %dh,%esi # rk[11]>>8 | 1456 | movz %dh,%esi # rk[11]>>8 |
905 | and \$0x000000FF,%ebx | ||
906 | xor %ebx,%eax | 1457 | xor %ebx,%eax |
907 | 1458 | ||
908 | mov 0(%rbp,%rsi,8),%ebx | 1459 | movzb -128(%rbp,%rsi),%ebx |
909 | shr \$16,%edx | 1460 | shr \$16,%edx |
910 | and \$0x0000FF00,%ebx | 1461 | shl \$8,%ebx |
911 | movz %dl,%esi # rk[11]>>16 | 1462 | movz %dl,%esi # rk[11]>>16 |
912 | xor %ebx,%eax | 1463 | xor %ebx,%eax |
913 | 1464 | ||
914 | mov 0(%rbp,%rsi,8),%ebx | 1465 | movzb -128(%rbp,%rsi),%ebx |
915 | movz %dh,%esi # rk[11]>>24 | 1466 | movz %dh,%esi # rk[11]>>24 |
916 | and \$0x00FF0000,%ebx | 1467 | shl \$16,%ebx |
917 | xor %ebx,%eax | 1468 | xor %ebx,%eax |
918 | 1469 | ||
919 | mov 2(%rbp,%rsi,8),%ebx | 1470 | movzb -128(%rbp,%rsi),%ebx |
920 | and \$0xFF000000,%ebx | 1471 | shl \$24,%ebx |
921 | xor %ebx,%eax | 1472 | xor %ebx,%eax |
922 | 1473 | ||
923 | mov %eax,48(%rdi) # rk[12] | 1474 | mov %eax,48(%rdi) # rk[12] |
@@ -938,31 +1489,61 @@ $code.=<<___; | |||
938 | .Lbadpointer: | 1489 | .Lbadpointer: |
939 | mov \$-1,%rax | 1490 | mov \$-1,%rax |
940 | .Lexit: | 1491 | .Lexit: |
941 | pop %rbp | 1492 | .byte 0xf3,0xc3 # rep ret |
942 | pop %rbx | 1493 | .size _x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key |
943 | ret | ||
944 | .size AES_set_encrypt_key,.-AES_set_encrypt_key | ||
945 | ___ | 1494 | ___ |
946 | 1495 | ||
947 | sub deckey() | 1496 | sub deckey_ref() |
948 | { my ($i,$ptr,$te,$td) = @_; | 1497 | { my ($i,$ptr,$te,$td) = @_; |
1498 | my ($tp1,$tp2,$tp4,$tp8,$acc)=("%eax","%ebx","%edi","%edx","%r8d"); | ||
949 | $code.=<<___; | 1499 | $code.=<<___; |
950 | mov $i($ptr),%eax | 1500 | mov $i($ptr),$tp1 |
951 | mov %eax,%edx | 1501 | mov $tp1,$acc |
952 | movz %ah,%ebx | 1502 | and \$0x80808080,$acc |
953 | shr \$16,%edx | 1503 | mov $acc,$tp4 |
954 | and \$0xFF,%eax | 1504 | shr \$7,$tp4 |
955 | movzb 2($te,%rax,8),%rax | 1505 | lea 0($tp1,$tp1),$tp2 |
956 | movzb 2($te,%rbx,8),%rbx | 1506 | sub $tp4,$acc |
957 | mov 0($td,%rax,8),%eax | 1507 | and \$0xfefefefe,$tp2 |
958 | xor 3($td,%rbx,8),%eax | 1508 | and \$0x1b1b1b1b,$acc |
959 | movzb %dh,%ebx | 1509 | xor $tp2,$acc |
960 | and \$0xFF,%edx | 1510 | mov $acc,$tp2 |
961 | movzb 2($te,%rdx,8),%rdx | 1511 | |
962 | movzb 2($te,%rbx,8),%rbx | 1512 | and \$0x80808080,$acc |
963 | xor 2($td,%rdx,8),%eax | 1513 | mov $acc,$tp8 |
964 | xor 1($td,%rbx,8),%eax | 1514 | shr \$7,$tp8 |
965 | mov %eax,$i($ptr) | 1515 | lea 0($tp2,$tp2),$tp4 |
1516 | sub $tp8,$acc | ||
1517 | and \$0xfefefefe,$tp4 | ||
1518 | and \$0x1b1b1b1b,$acc | ||
1519 | xor $tp1,$tp2 # tp2^tp1 | ||
1520 | xor $tp4,$acc | ||
1521 | mov $acc,$tp4 | ||
1522 | |||
1523 | and \$0x80808080,$acc | ||
1524 | mov $acc,$tp8 | ||
1525 | shr \$7,$tp8 | ||
1526 | sub $tp8,$acc | ||
1527 | lea 0($tp4,$tp4),$tp8 | ||
1528 | xor $tp1,$tp4 # tp4^tp1 | ||
1529 | and \$0xfefefefe,$tp8 | ||
1530 | and \$0x1b1b1b1b,$acc | ||
1531 | xor $acc,$tp8 | ||
1532 | |||
1533 | xor $tp8,$tp1 # tp1^tp8 | ||
1534 | rol \$8,$tp1 # ROTATE(tp1^tp8,8) | ||
1535 | xor $tp8,$tp2 # tp2^tp1^tp8 | ||
1536 | xor $tp8,$tp4 # tp4^tp1^tp8 | ||
1537 | xor $tp2,$tp8 | ||
1538 | xor $tp4,$tp8 # tp8^(tp8^tp4^tp1)^(tp8^tp2^tp1)=tp8^tp4^tp2 | ||
1539 | |||
1540 | xor $tp8,$tp1 | ||
1541 | rol \$24,$tp2 # ROTATE(tp2^tp1^tp8,24) | ||
1542 | xor $tp2,$tp1 | ||
1543 | rol \$16,$tp4 # ROTATE(tp4^tp1^tp8,16) | ||
1544 | xor $tp4,$tp1 | ||
1545 | |||
1546 | mov $tp1,$i($ptr) | ||
966 | ___ | 1547 | ___ |
967 | } | 1548 | } |
968 | 1549 | ||
@@ -973,19 +1554,23 @@ $code.=<<___; | |||
973 | .type AES_set_decrypt_key,\@function,3 | 1554 | .type AES_set_decrypt_key,\@function,3 |
974 | .align 16 | 1555 | .align 16 |
975 | AES_set_decrypt_key: | 1556 | AES_set_decrypt_key: |
976 | push %rdx | 1557 | push %rbx |
977 | call AES_set_encrypt_key | 1558 | push %rbp |
978 | cmp \$0,%eax | 1559 | push %r12 |
979 | je .Lproceed | 1560 | push %r13 |
980 | lea 24(%rsp),%rsp | 1561 | push %r14 |
981 | ret | 1562 | push %r15 |
982 | .Lproceed: | 1563 | push %rdx # save key schedule |
1564 | .Ldec_key_prologue: | ||
1565 | |||
1566 | call _x86_64_AES_set_encrypt_key | ||
983 | mov (%rsp),%r8 # restore key schedule | 1567 | mov (%rsp),%r8 # restore key schedule |
984 | mov %rbx,(%rsp) | 1568 | cmp \$0,%eax |
1569 | jne .Labort | ||
985 | 1570 | ||
986 | mov 240(%r8),%ecx # pull number of rounds | 1571 | mov 240(%r8),%r14d # pull number of rounds |
987 | xor %rdi,%rdi | 1572 | xor %rdi,%rdi |
988 | lea (%rdi,%rcx,4),%rcx | 1573 | lea (%rdi,%r14d,4),%rcx |
989 | mov %r8,%rsi | 1574 | mov %r8,%rsi |
990 | lea (%r8,%rcx,4),%rdi # pointer to last chunk | 1575 | lea (%r8,%rcx,4),%rdi # pointer to last chunk |
991 | .align 4 | 1576 | .align 4 |
@@ -1003,27 +1588,39 @@ AES_set_decrypt_key: | |||
1003 | cmp %rsi,%rdi | 1588 | cmp %rsi,%rdi |
1004 | jne .Linvert | 1589 | jne .Linvert |
1005 | 1590 | ||
1006 | .picmeup %r9 | 1591 | lea .LAES_Te+2048+1024(%rip),%rax # rcon |
1007 | lea AES_Td-.(%r9),%rdi | ||
1008 | lea AES_Te-AES_Td(%rdi),%r9 | ||
1009 | 1592 | ||
1010 | mov %r8,%rsi | 1593 | mov 40(%rax),$mask80 |
1011 | mov 240(%r8),%ecx # pull number of rounds | 1594 | mov 48(%rax),$maskfe |
1012 | sub \$1,%ecx | 1595 | mov 56(%rax),$mask1b |
1596 | |||
1597 | mov %r8,$key | ||
1598 | sub \$1,%r14d | ||
1013 | .align 4 | 1599 | .align 4 |
1014 | .Lpermute: | 1600 | .Lpermute: |
1015 | lea 16(%rsi),%rsi | 1601 | lea 16($key),$key |
1602 | mov 0($key),%rax | ||
1603 | mov 8($key),%rcx | ||
1016 | ___ | 1604 | ___ |
1017 | &deckey (0,"%rsi","%r9","%rdi"); | 1605 | &dectransform (); |
1018 | &deckey (4,"%rsi","%r9","%rdi"); | ||
1019 | &deckey (8,"%rsi","%r9","%rdi"); | ||
1020 | &deckey (12,"%rsi","%r9","%rdi"); | ||
1021 | $code.=<<___; | 1606 | $code.=<<___; |
1022 | sub \$1,%ecx | 1607 | mov %eax,0($key) |
1608 | mov %ebx,4($key) | ||
1609 | mov %ecx,8($key) | ||
1610 | mov %edx,12($key) | ||
1611 | sub \$1,%r14d | ||
1023 | jnz .Lpermute | 1612 | jnz .Lpermute |
1024 | 1613 | ||
1025 | xor %rax,%rax | 1614 | xor %rax,%rax |
1026 | pop %rbx | 1615 | .Labort: |
1616 | mov 8(%rsp),%r15 | ||
1617 | mov 16(%rsp),%r14 | ||
1618 | mov 24(%rsp),%r13 | ||
1619 | mov 32(%rsp),%r12 | ||
1620 | mov 40(%rsp),%rbp | ||
1621 | mov 48(%rsp),%rbx | ||
1622 | add \$56,%rsp | ||
1623 | .Ldec_key_epilogue: | ||
1027 | ret | 1624 | ret |
1028 | .size AES_set_decrypt_key,.-AES_set_decrypt_key | 1625 | .size AES_set_decrypt_key,.-AES_set_decrypt_key |
1029 | ___ | 1626 | ___ |
@@ -1034,47 +1631,59 @@ ___ | |||
1034 | { | 1631 | { |
1035 | # stack frame layout | 1632 | # stack frame layout |
1036 | # -8(%rsp) return address | 1633 | # -8(%rsp) return address |
1037 | my $_rsp="0(%rsp)"; # saved %rsp | 1634 | my $keyp="0(%rsp)"; # one to pass as $key |
1038 | my $_len="8(%rsp)"; # copy of 3rd parameter, length | 1635 | my $keyend="8(%rsp)"; # &(keyp->rd_key[4*keyp->rounds]) |
1039 | my $_key="16(%rsp)"; # copy of 4th parameter, key | 1636 | my $_rsp="16(%rsp)"; # saved %rsp |
1040 | my $_ivp="24(%rsp)"; # copy of 5th parameter, ivp | 1637 | my $_inp="24(%rsp)"; # copy of 1st parameter, inp |
1041 | my $keyp="32(%rsp)"; # one to pass as $key | 1638 | my $_out="32(%rsp)"; # copy of 2nd parameter, out |
1042 | my $ivec="40(%rsp)"; # ivec[16] | 1639 | my $_len="40(%rsp)"; # copy of 3rd parameter, length |
1043 | my $aes_key="56(%rsp)"; # copy of aes_key | 1640 | my $_key="48(%rsp)"; # copy of 4th parameter, key |
1044 | my $mark="56+240(%rsp)"; # copy of aes_key->rounds | 1641 | my $_ivp="56(%rsp)"; # copy of 5th parameter, ivp |
1642 | my $ivec="64(%rsp)"; # ivec[16] | ||
1643 | my $aes_key="80(%rsp)"; # copy of aes_key | ||
1644 | my $mark="80+240(%rsp)"; # copy of aes_key->rounds | ||
1045 | 1645 | ||
1046 | $code.=<<___; | 1646 | $code.=<<___; |
1047 | .globl AES_cbc_encrypt | 1647 | .globl AES_cbc_encrypt |
1048 | .type AES_cbc_encrypt,\@function,6 | 1648 | .type AES_cbc_encrypt,\@function,6 |
1049 | .align 16 | 1649 | .align 16 |
1650 | .extern OPENSSL_ia32cap_P | ||
1050 | AES_cbc_encrypt: | 1651 | AES_cbc_encrypt: |
1051 | cmp \$0,%rdx # check length | 1652 | cmp \$0,%rdx # check length |
1052 | je .Lcbc_just_ret | 1653 | je .Lcbc_epilogue |
1654 | pushfq | ||
1053 | push %rbx | 1655 | push %rbx |
1054 | push %rbp | 1656 | push %rbp |
1055 | push %r12 | 1657 | push %r12 |
1056 | push %r13 | 1658 | push %r13 |
1057 | push %r14 | 1659 | push %r14 |
1058 | push %r15 | 1660 | push %r15 |
1059 | pushfq | 1661 | .Lcbc_prologue: |
1662 | |||
1060 | cld | 1663 | cld |
1061 | mov %r9d,%r9d # clear upper half of enc | 1664 | mov %r9d,%r9d # clear upper half of enc |
1062 | 1665 | ||
1063 | .picmeup $sbox | 1666 | lea .LAES_Te(%rip),$sbox |
1064 | .Lcbc_pic_point: | ||
1065 | |||
1066 | cmp \$0,%r9 | 1667 | cmp \$0,%r9 |
1067 | je .LDECRYPT | 1668 | jne .Lcbc_picked_te |
1068 | 1669 | lea .LAES_Td(%rip),$sbox | |
1069 | lea AES_Te-.Lcbc_pic_point($sbox),$sbox | 1670 | .Lcbc_picked_te: |
1671 | |||
1672 | mov OPENSSL_ia32cap_P(%rip),%r10d | ||
1673 | cmp \$$speed_limit,%rdx | ||
1674 | jb .Lcbc_slow_prologue | ||
1675 | test \$15,%rdx | ||
1676 | jnz .Lcbc_slow_prologue | ||
1677 | bt \$28,%r10d | ||
1678 | jc .Lcbc_slow_prologue | ||
1070 | 1679 | ||
1071 | # allocate aligned stack frame... | 1680 | # allocate aligned stack frame... |
1072 | lea -64-248(%rsp),$key | 1681 | lea -88-248(%rsp),$key |
1073 | and \$-64,$key | 1682 | and \$-64,$key |
1074 | 1683 | ||
1075 | # ... and make it doesn't alias with AES_Te modulo 4096 | 1684 | # ... and make sure it doesn't alias with AES_T[ed] modulo 4096 |
1076 | mov $sbox,%r10 | 1685 | mov $sbox,%r10 |
1077 | lea 2048($sbox),%r11 | 1686 | lea 2304($sbox),%r11 |
1078 | mov $key,%r12 | 1687 | mov $key,%r12 |
1079 | and \$0xFFF,%r10 # s = $sbox&0xfff | 1688 | and \$0xFFF,%r10 # s = $sbox&0xfff |
1080 | and \$0xFFF,%r11 # e = ($sbox+2048)&0xfff | 1689 | and \$0xFFF,%r11 # e = ($sbox+2048)&0xfff |
@@ -1094,22 +1703,27 @@ AES_cbc_encrypt: | |||
1094 | .Lcbc_te_ok: | 1703 | .Lcbc_te_ok: |
1095 | 1704 | ||
1096 | xchg %rsp,$key | 1705 | xchg %rsp,$key |
1097 | add \$8,%rsp # reserve for return address! | 1706 | #add \$8,%rsp # reserve for return address! |
1098 | mov $key,$_rsp # save %rsp | 1707 | mov $key,$_rsp # save %rsp |
1708 | .Lcbc_fast_body: | ||
1709 | mov %rdi,$_inp # save copy of inp | ||
1710 | mov %rsi,$_out # save copy of out | ||
1099 | mov %rdx,$_len # save copy of len | 1711 | mov %rdx,$_len # save copy of len |
1100 | mov %rcx,$_key # save copy of key | 1712 | mov %rcx,$_key # save copy of key |
1101 | mov %r8,$_ivp # save copy of ivp | 1713 | mov %r8,$_ivp # save copy of ivp |
1102 | movl \$0,$mark # copy of aes_key->rounds = 0; | 1714 | movl \$0,$mark # copy of aes_key->rounds = 0; |
1103 | mov %r8,%rbp # rearrange input arguments | 1715 | mov %r8,%rbp # rearrange input arguments |
1716 | mov %r9,%rbx | ||
1104 | mov %rsi,$out | 1717 | mov %rsi,$out |
1105 | mov %rdi,$inp | 1718 | mov %rdi,$inp |
1106 | mov %rcx,$key | 1719 | mov %rcx,$key |
1107 | 1720 | ||
1721 | mov 240($key),%eax # key->rounds | ||
1108 | # do we copy key schedule to stack? | 1722 | # do we copy key schedule to stack? |
1109 | mov $key,%r10 | 1723 | mov $key,%r10 |
1110 | sub $sbox,%r10 | 1724 | sub $sbox,%r10 |
1111 | and \$0xfff,%r10 | 1725 | and \$0xfff,%r10 |
1112 | cmp \$2048,%r10 | 1726 | cmp \$2304,%r10 |
1113 | jb .Lcbc_do_ecopy | 1727 | jb .Lcbc_do_ecopy |
1114 | cmp \$4096-248,%r10 | 1728 | cmp \$4096-248,%r10 |
1115 | jb .Lcbc_skip_ecopy | 1729 | jb .Lcbc_skip_ecopy |
@@ -1120,12 +1734,11 @@ AES_cbc_encrypt: | |||
1120 | lea $aes_key,$key | 1734 | lea $aes_key,$key |
1121 | mov \$240/8,%ecx | 1735 | mov \$240/8,%ecx |
1122 | .long 0x90A548F3 # rep movsq | 1736 | .long 0x90A548F3 # rep movsq |
1123 | mov (%rsi),%eax # copy aes_key->rounds | 1737 | mov %eax,(%rdi) # copy aes_key->rounds |
1124 | mov %eax,(%rdi) | ||
1125 | .Lcbc_skip_ecopy: | 1738 | .Lcbc_skip_ecopy: |
1126 | mov $key,$keyp # save key pointer | 1739 | mov $key,$keyp # save key pointer |
1127 | 1740 | ||
1128 | mov \$16,%ecx | 1741 | mov \$18,%ecx |
1129 | .align 4 | 1742 | .align 4 |
1130 | .Lcbc_prefetch_te: | 1743 | .Lcbc_prefetch_te: |
1131 | mov 0($sbox),%r10 | 1744 | mov 0($sbox),%r10 |
@@ -1135,184 +1748,77 @@ AES_cbc_encrypt: | |||
1135 | lea 128($sbox),$sbox | 1748 | lea 128($sbox),$sbox |
1136 | sub \$1,%ecx | 1749 | sub \$1,%ecx |
1137 | jnz .Lcbc_prefetch_te | 1750 | jnz .Lcbc_prefetch_te |
1138 | sub \$2048,$sbox | 1751 | lea -2304($sbox),$sbox |
1139 | 1752 | ||
1140 | test \$-16,%rdx # check upon length | 1753 | cmp \$0,%rbx |
1141 | mov %rdx,%r10 | 1754 | je .LFAST_DECRYPT |
1755 | |||
1756 | #----------------------------- ENCRYPT -----------------------------# | ||
1142 | mov 0(%rbp),$s0 # load iv | 1757 | mov 0(%rbp),$s0 # load iv |
1143 | mov 4(%rbp),$s1 | 1758 | mov 4(%rbp),$s1 |
1144 | mov 8(%rbp),$s2 | 1759 | mov 8(%rbp),$s2 |
1145 | mov 12(%rbp),$s3 | 1760 | mov 12(%rbp),$s3 |
1146 | jz .Lcbc_enc_tail # short input... | ||
1147 | 1761 | ||
1148 | .align 4 | 1762 | .align 4 |
1149 | .Lcbc_enc_loop: | 1763 | .Lcbc_fast_enc_loop: |
1150 | xor 0($inp),$s0 | 1764 | xor 0($inp),$s0 |
1151 | xor 4($inp),$s1 | 1765 | xor 4($inp),$s1 |
1152 | xor 8($inp),$s2 | 1766 | xor 8($inp),$s2 |
1153 | xor 12($inp),$s3 | 1767 | xor 12($inp),$s3 |
1154 | mov $inp,$ivec # if ($verticalspin) save inp | ||
1155 | |||
1156 | mov $keyp,$key # restore key | 1768 | mov $keyp,$key # restore key |
1769 | mov $inp,$_inp # if ($verticalspin) save inp | ||
1770 | |||
1157 | call _x86_64_AES_encrypt | 1771 | call _x86_64_AES_encrypt |
1158 | 1772 | ||
1159 | mov $ivec,$inp # if ($verticalspin) restore inp | 1773 | mov $_inp,$inp # if ($verticalspin) restore inp |
1774 | mov $_len,%r10 | ||
1160 | mov $s0,0($out) | 1775 | mov $s0,0($out) |
1161 | mov $s1,4($out) | 1776 | mov $s1,4($out) |
1162 | mov $s2,8($out) | 1777 | mov $s2,8($out) |
1163 | mov $s3,12($out) | 1778 | mov $s3,12($out) |
1164 | 1779 | ||
1165 | mov $_len,%r10 | ||
1166 | lea 16($inp),$inp | 1780 | lea 16($inp),$inp |
1167 | lea 16($out),$out | 1781 | lea 16($out),$out |
1168 | sub \$16,%r10 | 1782 | sub \$16,%r10 |
1169 | test \$-16,%r10 | 1783 | test \$-16,%r10 |
1170 | mov %r10,$_len | 1784 | mov %r10,$_len |
1171 | jnz .Lcbc_enc_loop | 1785 | jnz .Lcbc_fast_enc_loop |
1172 | test \$15,%r10 | ||
1173 | jnz .Lcbc_enc_tail | ||
1174 | mov $_ivp,%rbp # restore ivp | 1786 | mov $_ivp,%rbp # restore ivp |
1175 | mov $s0,0(%rbp) # save ivec | 1787 | mov $s0,0(%rbp) # save ivec |
1176 | mov $s1,4(%rbp) | 1788 | mov $s1,4(%rbp) |
1177 | mov $s2,8(%rbp) | 1789 | mov $s2,8(%rbp) |
1178 | mov $s3,12(%rbp) | 1790 | mov $s3,12(%rbp) |
1179 | 1791 | ||
1180 | .align 4 | 1792 | jmp .Lcbc_fast_cleanup |
1181 | .Lcbc_cleanup: | 1793 | |
1182 | cmpl \$0,$mark # was the key schedule copied? | ||
1183 | lea $aes_key,%rdi | ||
1184 | mov $_rsp,%rsp | ||
1185 | je .Lcbc_exit | ||
1186 | mov \$240/8,%ecx | ||
1187 | xor %rax,%rax | ||
1188 | .long 0x90AB48F3 # rep stosq | ||
1189 | .Lcbc_exit: | ||
1190 | popfq | ||
1191 | pop %r15 | ||
1192 | pop %r14 | ||
1193 | pop %r13 | ||
1194 | pop %r12 | ||
1195 | pop %rbp | ||
1196 | pop %rbx | ||
1197 | .Lcbc_just_ret: | ||
1198 | ret | ||
1199 | .align 4 | ||
1200 | .Lcbc_enc_tail: | ||
1201 | mov %rax,%r11 | ||
1202 | mov %rcx,%r12 | ||
1203 | mov %r10,%rcx | ||
1204 | mov $inp,%rsi | ||
1205 | mov $out,%rdi | ||
1206 | .long 0xF689A4F3 # rep movsb | ||
1207 | mov \$16,%rcx # zero tail | ||
1208 | sub %r10,%rcx | ||
1209 | xor %rax,%rax | ||
1210 | .long 0xF689AAF3 # rep stosb | ||
1211 | mov $out,$inp # this is not a mistake! | ||
1212 | movq \$16,$_len # len=16 | ||
1213 | mov %r11,%rax | ||
1214 | mov %r12,%rcx | ||
1215 | jmp .Lcbc_enc_loop # one more spin... | ||
1216 | #----------------------------- DECRYPT -----------------------------# | 1794 | #----------------------------- DECRYPT -----------------------------# |
1217 | .align 16 | 1795 | .align 16 |
1218 | .LDECRYPT: | 1796 | .LFAST_DECRYPT: |
1219 | lea AES_Td-.Lcbc_pic_point($sbox),$sbox | ||
1220 | |||
1221 | # allocate aligned stack frame... | ||
1222 | lea -64-248(%rsp),$key | ||
1223 | and \$-64,$key | ||
1224 | |||
1225 | # ... and make it doesn't alias with AES_Td modulo 4096 | ||
1226 | mov $sbox,%r10 | ||
1227 | lea 2304($sbox),%r11 | ||
1228 | mov $key,%r12 | ||
1229 | and \$0xFFF,%r10 # s = $sbox&0xfff | ||
1230 | and \$0xFFF,%r11 # e = ($sbox+2048+256)&0xfff | ||
1231 | and \$0xFFF,%r12 # p = %rsp&0xfff | ||
1232 | |||
1233 | cmp %r11,%r12 # if (p=>e) %rsp =- (p-e); | ||
1234 | jb .Lcbc_td_break_out | ||
1235 | sub %r11,%r12 | ||
1236 | sub %r12,$key | ||
1237 | jmp .Lcbc_td_ok | ||
1238 | .Lcbc_td_break_out: # else %rsp -= (p-s)&0xfff + framesz | ||
1239 | sub %r10,%r12 | ||
1240 | and \$0xFFF,%r12 | ||
1241 | add \$320,%r12 | ||
1242 | sub %r12,$key | ||
1243 | .align 4 | ||
1244 | .Lcbc_td_ok: | ||
1245 | |||
1246 | xchg %rsp,$key | ||
1247 | add \$8,%rsp # reserve for return address! | ||
1248 | mov $key,$_rsp # save %rsp | ||
1249 | mov %rdx,$_len # save copy of len | ||
1250 | mov %rcx,$_key # save copy of key | ||
1251 | mov %r8,$_ivp # save copy of ivp | ||
1252 | movl \$0,$mark # copy of aes_key->rounds = 0; | ||
1253 | mov %r8,%rbp # rearrange input arguments | ||
1254 | mov %rsi,$out | ||
1255 | mov %rdi,$inp | ||
1256 | mov %rcx,$key | ||
1257 | |||
1258 | # do we copy key schedule to stack? | ||
1259 | mov $key,%r10 | ||
1260 | sub $sbox,%r10 | ||
1261 | and \$0xfff,%r10 | ||
1262 | cmp \$2304,%r10 | ||
1263 | jb .Lcbc_do_dcopy | ||
1264 | cmp \$4096-248,%r10 | ||
1265 | jb .Lcbc_skip_dcopy | ||
1266 | .align 4 | ||
1267 | .Lcbc_do_dcopy: | ||
1268 | mov $key,%rsi | ||
1269 | lea $aes_key,%rdi | ||
1270 | lea $aes_key,$key | ||
1271 | mov \$240/8,%ecx | ||
1272 | .long 0x90A548F3 # rep movsq | ||
1273 | mov (%rsi),%eax # copy aes_key->rounds | ||
1274 | mov %eax,(%rdi) | ||
1275 | .Lcbc_skip_dcopy: | ||
1276 | mov $key,$keyp # save key pointer | ||
1277 | |||
1278 | mov \$18,%ecx | ||
1279 | .align 4 | ||
1280 | .Lcbc_prefetch_td: | ||
1281 | mov 0($sbox),%r10 | ||
1282 | mov 32($sbox),%r11 | ||
1283 | mov 64($sbox),%r12 | ||
1284 | mov 96($sbox),%r13 | ||
1285 | lea 128($sbox),$sbox | ||
1286 | sub \$1,%ecx | ||
1287 | jnz .Lcbc_prefetch_td | ||
1288 | sub \$2304,$sbox | ||
1289 | |||
1290 | cmp $inp,$out | 1797 | cmp $inp,$out |
1291 | je .Lcbc_dec_in_place | 1798 | je .Lcbc_fast_dec_in_place |
1292 | 1799 | ||
1293 | mov %rbp,$ivec | 1800 | mov %rbp,$ivec |
1294 | .align 4 | 1801 | .align 4 |
1295 | .Lcbc_dec_loop: | 1802 | .Lcbc_fast_dec_loop: |
1296 | mov 0($inp),$s0 # read input | 1803 | mov 0($inp),$s0 # read input |
1297 | mov 4($inp),$s1 | 1804 | mov 4($inp),$s1 |
1298 | mov 8($inp),$s2 | 1805 | mov 8($inp),$s2 |
1299 | mov 12($inp),$s3 | 1806 | mov 12($inp),$s3 |
1300 | mov $inp,8+$ivec # if ($verticalspin) save inp | ||
1301 | |||
1302 | mov $keyp,$key # restore key | 1807 | mov $keyp,$key # restore key |
1808 | mov $inp,$_inp # if ($verticalspin) save inp | ||
1809 | |||
1303 | call _x86_64_AES_decrypt | 1810 | call _x86_64_AES_decrypt |
1304 | 1811 | ||
1305 | mov $ivec,%rbp # load ivp | 1812 | mov $ivec,%rbp # load ivp |
1306 | mov 8+$ivec,$inp # if ($verticalspin) restore inp | 1813 | mov $_inp,$inp # if ($verticalspin) restore inp |
1814 | mov $_len,%r10 # load len | ||
1307 | xor 0(%rbp),$s0 # xor iv | 1815 | xor 0(%rbp),$s0 # xor iv |
1308 | xor 4(%rbp),$s1 | 1816 | xor 4(%rbp),$s1 |
1309 | xor 8(%rbp),$s2 | 1817 | xor 8(%rbp),$s2 |
1310 | xor 12(%rbp),$s3 | 1818 | xor 12(%rbp),$s3 |
1311 | mov $inp,%rbp # current input, next iv | 1819 | mov $inp,%rbp # current input, next iv |
1312 | 1820 | ||
1313 | mov $_len,%r10 # load len | ||
1314 | sub \$16,%r10 | 1821 | sub \$16,%r10 |
1315 | jc .Lcbc_dec_partial | ||
1316 | mov %r10,$_len # update len | 1822 | mov %r10,$_len # update len |
1317 | mov %rbp,$ivec # update ivp | 1823 | mov %rbp,$ivec # update ivp |
1318 | 1824 | ||
@@ -1323,81 +1829,281 @@ AES_cbc_encrypt: | |||
1323 | 1829 | ||
1324 | lea 16($inp),$inp | 1830 | lea 16($inp),$inp |
1325 | lea 16($out),$out | 1831 | lea 16($out),$out |
1326 | jnz .Lcbc_dec_loop | 1832 | jnz .Lcbc_fast_dec_loop |
1327 | .Lcbc_dec_end: | ||
1328 | mov $_ivp,%r12 # load user ivp | 1833 | mov $_ivp,%r12 # load user ivp |
1329 | mov 0(%rbp),%r10 # load iv | 1834 | mov 0(%rbp),%r10 # load iv |
1330 | mov 8(%rbp),%r11 | 1835 | mov 8(%rbp),%r11 |
1331 | mov %r10,0(%r12) # copy back to user | 1836 | mov %r10,0(%r12) # copy back to user |
1332 | mov %r11,8(%r12) | 1837 | mov %r11,8(%r12) |
1333 | jmp .Lcbc_cleanup | 1838 | jmp .Lcbc_fast_cleanup |
1334 | |||
1335 | .align 4 | ||
1336 | .Lcbc_dec_partial: | ||
1337 | mov $s0,0+$ivec # dump output to stack | ||
1338 | mov $s1,4+$ivec | ||
1339 | mov $s2,8+$ivec | ||
1340 | mov $s3,12+$ivec | ||
1341 | mov $out,%rdi | ||
1342 | lea $ivec,%rsi | ||
1343 | mov \$16,%rcx | ||
1344 | add %r10,%rcx # number of bytes to copy | ||
1345 | .long 0xF689A4F3 # rep movsb | ||
1346 | jmp .Lcbc_dec_end | ||
1347 | 1839 | ||
1348 | .align 16 | 1840 | .align 16 |
1349 | .Lcbc_dec_in_place: | 1841 | .Lcbc_fast_dec_in_place: |
1842 | mov 0(%rbp),%r10 # copy iv to stack | ||
1843 | mov 8(%rbp),%r11 | ||
1844 | mov %r10,0+$ivec | ||
1845 | mov %r11,8+$ivec | ||
1846 | .align 4 | ||
1847 | .Lcbc_fast_dec_in_place_loop: | ||
1350 | mov 0($inp),$s0 # load input | 1848 | mov 0($inp),$s0 # load input |
1351 | mov 4($inp),$s1 | 1849 | mov 4($inp),$s1 |
1352 | mov 8($inp),$s2 | 1850 | mov 8($inp),$s2 |
1353 | mov 12($inp),$s3 | 1851 | mov 12($inp),$s3 |
1852 | mov $keyp,$key # restore key | ||
1853 | mov $inp,$_inp # if ($verticalspin) save inp | ||
1354 | 1854 | ||
1355 | mov $inp,$ivec # if ($verticalspin) save inp | ||
1356 | mov $keyp,$key | ||
1357 | call _x86_64_AES_decrypt | 1855 | call _x86_64_AES_decrypt |
1358 | 1856 | ||
1359 | mov $ivec,$inp # if ($verticalspin) restore inp | 1857 | mov $_inp,$inp # if ($verticalspin) restore inp |
1360 | mov $_ivp,%rbp | 1858 | mov $_len,%r10 |
1361 | xor 0(%rbp),$s0 | 1859 | xor 0+$ivec,$s0 |
1362 | xor 4(%rbp),$s1 | 1860 | xor 4+$ivec,$s1 |
1363 | xor 8(%rbp),$s2 | 1861 | xor 8+$ivec,$s2 |
1364 | xor 12(%rbp),$s3 | 1862 | xor 12+$ivec,$s3 |
1863 | |||
1864 | mov 0($inp),%r11 # load input | ||
1865 | mov 8($inp),%r12 | ||
1866 | sub \$16,%r10 | ||
1867 | jz .Lcbc_fast_dec_in_place_done | ||
1365 | 1868 | ||
1366 | mov 0($inp),%r10 # copy input to iv | 1869 | mov %r11,0+$ivec # copy input to iv |
1367 | mov 8($inp),%r11 | 1870 | mov %r12,8+$ivec |
1368 | mov %r10,0(%rbp) | ||
1369 | mov %r11,8(%rbp) | ||
1370 | 1871 | ||
1371 | mov $s0,0($out) # save output [zaps input] | 1872 | mov $s0,0($out) # save output [zaps input] |
1372 | mov $s1,4($out) | 1873 | mov $s1,4($out) |
1373 | mov $s2,8($out) | 1874 | mov $s2,8($out) |
1374 | mov $s3,12($out) | 1875 | mov $s3,12($out) |
1375 | 1876 | ||
1376 | mov $_len,%rcx | ||
1377 | lea 16($inp),$inp | 1877 | lea 16($inp),$inp |
1378 | lea 16($out),$out | 1878 | lea 16($out),$out |
1379 | sub \$16,%rcx | 1879 | mov %r10,$_len |
1380 | jc .Lcbc_dec_in_place_partial | 1880 | jmp .Lcbc_fast_dec_in_place_loop |
1381 | mov %rcx,$_len | 1881 | .Lcbc_fast_dec_in_place_done: |
1382 | jnz .Lcbc_dec_in_place | 1882 | mov $_ivp,%rdi |
1383 | jmp .Lcbc_cleanup | 1883 | mov %r11,0(%rdi) # copy iv back to user |
1884 | mov %r12,8(%rdi) | ||
1885 | |||
1886 | mov $s0,0($out) # save output [zaps input] | ||
1887 | mov $s1,4($out) | ||
1888 | mov $s2,8($out) | ||
1889 | mov $s3,12($out) | ||
1384 | 1890 | ||
1385 | .align 4 | 1891 | .align 4 |
1386 | .Lcbc_dec_in_place_partial: | 1892 | .Lcbc_fast_cleanup: |
1387 | # one can argue if this is actually required | 1893 | cmpl \$0,$mark # was the key schedule copied? |
1388 | lea ($out,%rcx),%rdi | 1894 | lea $aes_key,%rdi |
1389 | lea (%rbp,%rcx),%rsi | 1895 | je .Lcbc_exit |
1390 | neg %rcx | 1896 | mov \$240/8,%ecx |
1391 | .long 0xF689A4F3 # rep movsb # restore tail | 1897 | xor %rax,%rax |
1392 | jmp .Lcbc_cleanup | 1898 | .long 0x90AB48F3 # rep stosq |
1899 | |||
1900 | jmp .Lcbc_exit | ||
1901 | |||
1902 | #--------------------------- SLOW ROUTINE ---------------------------# | ||
1903 | .align 16 | ||
1904 | .Lcbc_slow_prologue: | ||
1905 | # allocate aligned stack frame... | ||
1906 | lea -88(%rsp),%rbp | ||
1907 | and \$-64,%rbp | ||
1908 | # ... just "above" key schedule | ||
1909 | lea -88-63(%rcx),%r10 | ||
1910 | sub %rbp,%r10 | ||
1911 | neg %r10 | ||
1912 | and \$0x3c0,%r10 | ||
1913 | sub %r10,%rbp | ||
1914 | |||
1915 | xchg %rsp,%rbp | ||
1916 | #add \$8,%rsp # reserve for return address! | ||
1917 | mov %rbp,$_rsp # save %rsp | ||
1918 | .Lcbc_slow_body: | ||
1919 | #mov %rdi,$_inp # save copy of inp | ||
1920 | #mov %rsi,$_out # save copy of out | ||
1921 | #mov %rdx,$_len # save copy of len | ||
1922 | #mov %rcx,$_key # save copy of key | ||
1923 | mov %r8,$_ivp # save copy of ivp | ||
1924 | mov %r8,%rbp # rearrange input arguments | ||
1925 | mov %r9,%rbx | ||
1926 | mov %rsi,$out | ||
1927 | mov %rdi,$inp | ||
1928 | mov %rcx,$key | ||
1929 | mov %rdx,%r10 | ||
1930 | |||
1931 | mov 240($key),%eax | ||
1932 | mov $key,$keyp # save key pointer | ||
1933 | shl \$4,%eax | ||
1934 | lea ($key,%rax),%rax | ||
1935 | mov %rax,$keyend | ||
1936 | |||
1937 | # pick Te4 copy which can't "overlap" with stack frame or key scdedule | ||
1938 | lea 2048($sbox),$sbox | ||
1939 | lea 768-8(%rsp),%rax | ||
1940 | sub $sbox,%rax | ||
1941 | and \$0x300,%rax | ||
1942 | lea ($sbox,%rax),$sbox | ||
1943 | |||
1944 | cmp \$0,%rbx | ||
1945 | je .LSLOW_DECRYPT | ||
1946 | |||
1947 | #--------------------------- SLOW ENCRYPT ---------------------------# | ||
1948 | test \$-16,%r10 # check upon length | ||
1949 | mov 0(%rbp),$s0 # load iv | ||
1950 | mov 4(%rbp),$s1 | ||
1951 | mov 8(%rbp),$s2 | ||
1952 | mov 12(%rbp),$s3 | ||
1953 | jz .Lcbc_slow_enc_tail # short input... | ||
1954 | |||
1955 | .align 4 | ||
1956 | .Lcbc_slow_enc_loop: | ||
1957 | xor 0($inp),$s0 | ||
1958 | xor 4($inp),$s1 | ||
1959 | xor 8($inp),$s2 | ||
1960 | xor 12($inp),$s3 | ||
1961 | mov $keyp,$key # restore key | ||
1962 | mov $inp,$_inp # save inp | ||
1963 | mov $out,$_out # save out | ||
1964 | mov %r10,$_len # save len | ||
1965 | |||
1966 | call _x86_64_AES_encrypt_compact | ||
1967 | |||
1968 | mov $_inp,$inp # restore inp | ||
1969 | mov $_out,$out # restore out | ||
1970 | mov $_len,%r10 # restore len | ||
1971 | mov $s0,0($out) | ||
1972 | mov $s1,4($out) | ||
1973 | mov $s2,8($out) | ||
1974 | mov $s3,12($out) | ||
1975 | |||
1976 | lea 16($inp),$inp | ||
1977 | lea 16($out),$out | ||
1978 | sub \$16,%r10 | ||
1979 | test \$-16,%r10 | ||
1980 | jnz .Lcbc_slow_enc_loop | ||
1981 | test \$15,%r10 | ||
1982 | jnz .Lcbc_slow_enc_tail | ||
1983 | mov $_ivp,%rbp # restore ivp | ||
1984 | mov $s0,0(%rbp) # save ivec | ||
1985 | mov $s1,4(%rbp) | ||
1986 | mov $s2,8(%rbp) | ||
1987 | mov $s3,12(%rbp) | ||
1988 | |||
1989 | jmp .Lcbc_exit | ||
1990 | |||
1991 | .align 4 | ||
1992 | .Lcbc_slow_enc_tail: | ||
1993 | mov %rax,%r11 | ||
1994 | mov %rcx,%r12 | ||
1995 | mov %r10,%rcx | ||
1996 | mov $inp,%rsi | ||
1997 | mov $out,%rdi | ||
1998 | .long 0x9066A4F3 # rep movsb | ||
1999 | mov \$16,%rcx # zero tail | ||
2000 | sub %r10,%rcx | ||
2001 | xor %rax,%rax | ||
2002 | .long 0x9066AAF3 # rep stosb | ||
2003 | mov $out,$inp # this is not a mistake! | ||
2004 | mov \$16,%r10 # len=16 | ||
2005 | mov %r11,%rax | ||
2006 | mov %r12,%rcx | ||
2007 | jmp .Lcbc_slow_enc_loop # one more spin... | ||
2008 | #--------------------------- SLOW DECRYPT ---------------------------# | ||
2009 | .align 16 | ||
2010 | .LSLOW_DECRYPT: | ||
2011 | shr \$3,%rax | ||
2012 | add %rax,$sbox # recall "magic" constants! | ||
2013 | |||
2014 | mov 0(%rbp),%r11 # copy iv to stack | ||
2015 | mov 8(%rbp),%r12 | ||
2016 | mov %r11,0+$ivec | ||
2017 | mov %r12,8+$ivec | ||
2018 | |||
2019 | .align 4 | ||
2020 | .Lcbc_slow_dec_loop: | ||
2021 | mov 0($inp),$s0 # load input | ||
2022 | mov 4($inp),$s1 | ||
2023 | mov 8($inp),$s2 | ||
2024 | mov 12($inp),$s3 | ||
2025 | mov $keyp,$key # restore key | ||
2026 | mov $inp,$_inp # save inp | ||
2027 | mov $out,$_out # save out | ||
2028 | mov %r10,$_len # save len | ||
2029 | |||
2030 | call _x86_64_AES_decrypt_compact | ||
2031 | |||
2032 | mov $_inp,$inp # restore inp | ||
2033 | mov $_out,$out # restore out | ||
2034 | mov $_len,%r10 | ||
2035 | xor 0+$ivec,$s0 | ||
2036 | xor 4+$ivec,$s1 | ||
2037 | xor 8+$ivec,$s2 | ||
2038 | xor 12+$ivec,$s3 | ||
2039 | |||
2040 | mov 0($inp),%r11 # load input | ||
2041 | mov 8($inp),%r12 | ||
2042 | sub \$16,%r10 | ||
2043 | jc .Lcbc_slow_dec_partial | ||
2044 | jz .Lcbc_slow_dec_done | ||
2045 | |||
2046 | mov %r11,0+$ivec # copy input to iv | ||
2047 | mov %r12,8+$ivec | ||
2048 | |||
2049 | mov $s0,0($out) # save output [can zap input] | ||
2050 | mov $s1,4($out) | ||
2051 | mov $s2,8($out) | ||
2052 | mov $s3,12($out) | ||
2053 | |||
2054 | lea 16($inp),$inp | ||
2055 | lea 16($out),$out | ||
2056 | jmp .Lcbc_slow_dec_loop | ||
2057 | .Lcbc_slow_dec_done: | ||
2058 | mov $_ivp,%rdi | ||
2059 | mov %r11,0(%rdi) # copy iv back to user | ||
2060 | mov %r12,8(%rdi) | ||
2061 | |||
2062 | mov $s0,0($out) # save output [can zap input] | ||
2063 | mov $s1,4($out) | ||
2064 | mov $s2,8($out) | ||
2065 | mov $s3,12($out) | ||
2066 | |||
2067 | jmp .Lcbc_exit | ||
2068 | |||
2069 | .align 4 | ||
2070 | .Lcbc_slow_dec_partial: | ||
2071 | mov $_ivp,%rdi | ||
2072 | mov %r11,0(%rdi) # copy iv back to user | ||
2073 | mov %r12,8(%rdi) | ||
2074 | |||
2075 | mov $s0,0+$ivec # save output to stack | ||
2076 | mov $s1,4+$ivec | ||
2077 | mov $s2,8+$ivec | ||
2078 | mov $s3,12+$ivec | ||
2079 | |||
2080 | mov $out,%rdi | ||
2081 | lea $ivec,%rsi | ||
2082 | lea 16(%r10),%rcx | ||
2083 | .long 0x9066A4F3 # rep movsb | ||
2084 | jmp .Lcbc_exit | ||
2085 | |||
2086 | .align 16 | ||
2087 | .Lcbc_exit: | ||
2088 | mov $_rsp,%rsi | ||
2089 | mov (%rsi),%r15 | ||
2090 | mov 8(%rsi),%r14 | ||
2091 | mov 16(%rsi),%r13 | ||
2092 | mov 24(%rsi),%r12 | ||
2093 | mov 32(%rsi),%rbp | ||
2094 | mov 40(%rsi),%rbx | ||
2095 | lea 48(%rsi),%rsp | ||
2096 | .Lcbc_popfq: | ||
2097 | popfq | ||
2098 | .Lcbc_epilogue: | ||
2099 | ret | ||
1393 | .size AES_cbc_encrypt,.-AES_cbc_encrypt | 2100 | .size AES_cbc_encrypt,.-AES_cbc_encrypt |
1394 | ___ | 2101 | ___ |
1395 | } | 2102 | } |
1396 | 2103 | ||
1397 | $code.=<<___; | 2104 | $code.=<<___; |
1398 | .globl AES_Te | ||
1399 | .align 64 | 2105 | .align 64 |
1400 | AES_Te: | 2106 | .LAES_Te: |
1401 | ___ | 2107 | ___ |
1402 | &_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6); | 2108 | &_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6); |
1403 | &_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591); | 2109 | &_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591); |
@@ -1463,16 +2169,149 @@ ___ | |||
1463 | &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0); | 2169 | &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0); |
1464 | &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e); | 2170 | &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e); |
1465 | &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c); | 2171 | &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c); |
2172 | |||
2173 | #Te4 # four copies of Te4 to choose from to avoid L1 aliasing | ||
2174 | &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); | ||
2175 | &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); | ||
2176 | &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); | ||
2177 | &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); | ||
2178 | &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); | ||
2179 | &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); | ||
2180 | &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); | ||
2181 | &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); | ||
2182 | &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); | ||
2183 | &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); | ||
2184 | &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); | ||
2185 | &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); | ||
2186 | &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); | ||
2187 | &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); | ||
2188 | &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); | ||
2189 | &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); | ||
2190 | &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); | ||
2191 | &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); | ||
2192 | &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); | ||
2193 | &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); | ||
2194 | &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); | ||
2195 | &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); | ||
2196 | &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); | ||
2197 | &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); | ||
2198 | &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); | ||
2199 | &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); | ||
2200 | &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); | ||
2201 | &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); | ||
2202 | &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); | ||
2203 | &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); | ||
2204 | &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); | ||
2205 | &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); | ||
2206 | |||
2207 | &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); | ||
2208 | &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); | ||
2209 | &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); | ||
2210 | &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); | ||
2211 | &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); | ||
2212 | &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); | ||
2213 | &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); | ||
2214 | &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); | ||
2215 | &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); | ||
2216 | &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); | ||
2217 | &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); | ||
2218 | &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); | ||
2219 | &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); | ||
2220 | &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); | ||
2221 | &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); | ||
2222 | &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); | ||
2223 | &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); | ||
2224 | &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); | ||
2225 | &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); | ||
2226 | &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); | ||
2227 | &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); | ||
2228 | &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); | ||
2229 | &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); | ||
2230 | &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); | ||
2231 | &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); | ||
2232 | &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); | ||
2233 | &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); | ||
2234 | &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); | ||
2235 | &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); | ||
2236 | &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); | ||
2237 | &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); | ||
2238 | &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); | ||
2239 | |||
2240 | &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); | ||
2241 | &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); | ||
2242 | &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); | ||
2243 | &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); | ||
2244 | &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); | ||
2245 | &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); | ||
2246 | &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); | ||
2247 | &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); | ||
2248 | &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); | ||
2249 | &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); | ||
2250 | &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); | ||
2251 | &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); | ||
2252 | &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); | ||
2253 | &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); | ||
2254 | &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); | ||
2255 | &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); | ||
2256 | &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); | ||
2257 | &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); | ||
2258 | &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); | ||
2259 | &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); | ||
2260 | &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); | ||
2261 | &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); | ||
2262 | &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); | ||
2263 | &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); | ||
2264 | &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); | ||
2265 | &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); | ||
2266 | &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); | ||
2267 | &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); | ||
2268 | &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); | ||
2269 | &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); | ||
2270 | &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); | ||
2271 | &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); | ||
2272 | |||
2273 | &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); | ||
2274 | &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); | ||
2275 | &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); | ||
2276 | &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); | ||
2277 | &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); | ||
2278 | &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); | ||
2279 | &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); | ||
2280 | &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); | ||
2281 | &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); | ||
2282 | &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); | ||
2283 | &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); | ||
2284 | &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); | ||
2285 | &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); | ||
2286 | &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); | ||
2287 | &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); | ||
2288 | &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); | ||
2289 | &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); | ||
2290 | &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); | ||
2291 | &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); | ||
2292 | &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); | ||
2293 | &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); | ||
2294 | &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); | ||
2295 | &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); | ||
2296 | &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); | ||
2297 | &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); | ||
2298 | &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); | ||
2299 | &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); | ||
2300 | &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); | ||
2301 | &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); | ||
2302 | &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); | ||
2303 | &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); | ||
2304 | &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); | ||
1466 | #rcon: | 2305 | #rcon: |
1467 | $code.=<<___; | 2306 | $code.=<<___; |
1468 | .long 0x00000001, 0x00000002, 0x00000004, 0x00000008 | 2307 | .long 0x00000001, 0x00000002, 0x00000004, 0x00000008 |
1469 | .long 0x00000010, 0x00000020, 0x00000040, 0x00000080 | 2308 | .long 0x00000010, 0x00000020, 0x00000040, 0x00000080 |
1470 | .long 0x0000001b, 0x00000036, 0, 0, 0, 0, 0, 0 | 2309 | .long 0x0000001b, 0x00000036, 0x80808080, 0x80808080 |
2310 | .long 0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b | ||
1471 | ___ | 2311 | ___ |
1472 | $code.=<<___; | 2312 | $code.=<<___; |
1473 | .globl AES_Td | ||
1474 | .align 64 | 2313 | .align 64 |
1475 | AES_Td: | 2314 | .LAES_Td: |
1476 | ___ | 2315 | ___ |
1477 | &_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a); | 2316 | &_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a); |
1478 | &_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b); | 2317 | &_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b); |
@@ -1538,7 +2377,116 @@ ___ | |||
1538 | &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff); | 2377 | &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff); |
1539 | &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664); | 2378 | &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664); |
1540 | &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0); | 2379 | &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0); |
1541 | #Td4: | 2380 | |
2381 | #Td4: # four copies of Td4 to choose from to avoid L1 aliasing | ||
2382 | &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); | ||
2383 | &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); | ||
2384 | &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); | ||
2385 | &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); | ||
2386 | &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); | ||
2387 | &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); | ||
2388 | &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); | ||
2389 | &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); | ||
2390 | &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); | ||
2391 | &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); | ||
2392 | &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); | ||
2393 | &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); | ||
2394 | &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); | ||
2395 | &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); | ||
2396 | &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); | ||
2397 | &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); | ||
2398 | &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); | ||
2399 | &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); | ||
2400 | &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); | ||
2401 | &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); | ||
2402 | &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); | ||
2403 | &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); | ||
2404 | &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); | ||
2405 | &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); | ||
2406 | &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); | ||
2407 | &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); | ||
2408 | &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); | ||
2409 | &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); | ||
2410 | &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); | ||
2411 | &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); | ||
2412 | &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); | ||
2413 | &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); | ||
2414 | $code.=<<___; | ||
2415 | .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe | ||
2416 | .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 | ||
2417 | ___ | ||
2418 | &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); | ||
2419 | &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); | ||
2420 | &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); | ||
2421 | &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); | ||
2422 | &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); | ||
2423 | &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); | ||
2424 | &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); | ||
2425 | &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); | ||
2426 | &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); | ||
2427 | &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); | ||
2428 | &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); | ||
2429 | &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); | ||
2430 | &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); | ||
2431 | &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); | ||
2432 | &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); | ||
2433 | &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); | ||
2434 | &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); | ||
2435 | &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); | ||
2436 | &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); | ||
2437 | &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); | ||
2438 | &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); | ||
2439 | &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); | ||
2440 | &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); | ||
2441 | &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); | ||
2442 | &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); | ||
2443 | &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); | ||
2444 | &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); | ||
2445 | &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); | ||
2446 | &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); | ||
2447 | &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); | ||
2448 | &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); | ||
2449 | &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); | ||
2450 | $code.=<<___; | ||
2451 | .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe | ||
2452 | .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 | ||
2453 | ___ | ||
2454 | &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); | ||
2455 | &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); | ||
2456 | &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); | ||
2457 | &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); | ||
2458 | &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); | ||
2459 | &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); | ||
2460 | &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); | ||
2461 | &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); | ||
2462 | &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); | ||
2463 | &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); | ||
2464 | &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); | ||
2465 | &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); | ||
2466 | &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); | ||
2467 | &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); | ||
2468 | &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); | ||
2469 | &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); | ||
2470 | &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); | ||
2471 | &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); | ||
2472 | &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); | ||
2473 | &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); | ||
2474 | &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); | ||
2475 | &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); | ||
2476 | &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); | ||
2477 | &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); | ||
2478 | &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); | ||
2479 | &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); | ||
2480 | &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); | ||
2481 | &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); | ||
2482 | &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); | ||
2483 | &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); | ||
2484 | &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); | ||
2485 | &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); | ||
2486 | $code.=<<___; | ||
2487 | .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe | ||
2488 | .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 | ||
2489 | ___ | ||
1542 | &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); | 2490 | &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); |
1543 | &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); | 2491 | &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); |
1544 | &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); | 2492 | &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); |
@@ -1571,6 +2519,288 @@ ___ | |||
1571 | &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); | 2519 | &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); |
1572 | &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); | 2520 | &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); |
1573 | &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); | 2521 | &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); |
2522 | $code.=<<___; | ||
2523 | .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe | ||
2524 | .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 | ||
2525 | .asciz "AES for x86_64, CRYPTOGAMS by <appro\@openssl.org>" | ||
2526 | .align 64 | ||
2527 | ___ | ||
2528 | |||
2529 | # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, | ||
2530 | # CONTEXT *context,DISPATCHER_CONTEXT *disp) | ||
2531 | if ($win64) { | ||
2532 | $rec="%rcx"; | ||
2533 | $frame="%rdx"; | ||
2534 | $context="%r8"; | ||
2535 | $disp="%r9"; | ||
2536 | |||
2537 | $code.=<<___; | ||
2538 | .extern __imp_RtlVirtualUnwind | ||
2539 | .type block_se_handler,\@abi-omnipotent | ||
2540 | .align 16 | ||
2541 | block_se_handler: | ||
2542 | push %rsi | ||
2543 | push %rdi | ||
2544 | push %rbx | ||
2545 | push %rbp | ||
2546 | push %r12 | ||
2547 | push %r13 | ||
2548 | push %r14 | ||
2549 | push %r15 | ||
2550 | pushfq | ||
2551 | sub \$64,%rsp | ||
2552 | |||
2553 | mov 120($context),%rax # pull context->Rax | ||
2554 | mov 248($context),%rbx # pull context->Rip | ||
2555 | |||
2556 | mov 8($disp),%rsi # disp->ImageBase | ||
2557 | mov 56($disp),%r11 # disp->HandlerData | ||
2558 | |||
2559 | mov 0(%r11),%r10d # HandlerData[0] | ||
2560 | lea (%rsi,%r10),%r10 # prologue label | ||
2561 | cmp %r10,%rbx # context->Rip<prologue label | ||
2562 | jb .Lin_block_prologue | ||
2563 | |||
2564 | mov 152($context),%rax # pull context->Rsp | ||
2565 | |||
2566 | mov 4(%r11),%r10d # HandlerData[1] | ||
2567 | lea (%rsi,%r10),%r10 # epilogue label | ||
2568 | cmp %r10,%rbx # context->Rip>=epilogue label | ||
2569 | jae .Lin_block_prologue | ||
2570 | |||
2571 | mov 24(%rax),%rax # pull saved real stack pointer | ||
2572 | lea 48(%rax),%rax # adjust... | ||
2573 | |||
2574 | mov -8(%rax),%rbx | ||
2575 | mov -16(%rax),%rbp | ||
2576 | mov -24(%rax),%r12 | ||
2577 | mov -32(%rax),%r13 | ||
2578 | mov -40(%rax),%r14 | ||
2579 | mov -48(%rax),%r15 | ||
2580 | mov %rbx,144($context) # restore context->Rbx | ||
2581 | mov %rbp,160($context) # restore context->Rbp | ||
2582 | mov %r12,216($context) # restore context->R12 | ||
2583 | mov %r13,224($context) # restore context->R13 | ||
2584 | mov %r14,232($context) # restore context->R14 | ||
2585 | mov %r15,240($context) # restore context->R15 | ||
2586 | |||
2587 | .Lin_block_prologue: | ||
2588 | mov 8(%rax),%rdi | ||
2589 | mov 16(%rax),%rsi | ||
2590 | mov %rax,152($context) # restore context->Rsp | ||
2591 | mov %rsi,168($context) # restore context->Rsi | ||
2592 | mov %rdi,176($context) # restore context->Rdi | ||
2593 | |||
2594 | jmp .Lcommon_seh_exit | ||
2595 | .size block_se_handler,.-block_se_handler | ||
2596 | |||
2597 | .type key_se_handler,\@abi-omnipotent | ||
2598 | .align 16 | ||
2599 | key_se_handler: | ||
2600 | push %rsi | ||
2601 | push %rdi | ||
2602 | push %rbx | ||
2603 | push %rbp | ||
2604 | push %r12 | ||
2605 | push %r13 | ||
2606 | push %r14 | ||
2607 | push %r15 | ||
2608 | pushfq | ||
2609 | sub \$64,%rsp | ||
2610 | |||
2611 | mov 120($context),%rax # pull context->Rax | ||
2612 | mov 248($context),%rbx # pull context->Rip | ||
2613 | |||
2614 | mov 8($disp),%rsi # disp->ImageBase | ||
2615 | mov 56($disp),%r11 # disp->HandlerData | ||
2616 | |||
2617 | mov 0(%r11),%r10d # HandlerData[0] | ||
2618 | lea (%rsi,%r10),%r10 # prologue label | ||
2619 | cmp %r10,%rbx # context->Rip<prologue label | ||
2620 | jb .Lin_key_prologue | ||
2621 | |||
2622 | mov 152($context),%rax # pull context->Rsp | ||
2623 | |||
2624 | mov 4(%r11),%r10d # HandlerData[1] | ||
2625 | lea (%rsi,%r10),%r10 # epilogue label | ||
2626 | cmp %r10,%rbx # context->Rip>=epilogue label | ||
2627 | jae .Lin_key_prologue | ||
2628 | |||
2629 | lea 56(%rax),%rax | ||
2630 | |||
2631 | mov -8(%rax),%rbx | ||
2632 | mov -16(%rax),%rbp | ||
2633 | mov -24(%rax),%r12 | ||
2634 | mov -32(%rax),%r13 | ||
2635 | mov -40(%rax),%r14 | ||
2636 | mov -48(%rax),%r15 | ||
2637 | mov %rbx,144($context) # restore context->Rbx | ||
2638 | mov %rbp,160($context) # restore context->Rbp | ||
2639 | mov %r12,216($context) # restore context->R12 | ||
2640 | mov %r13,224($context) # restore context->R13 | ||
2641 | mov %r14,232($context) # restore context->R14 | ||
2642 | mov %r15,240($context) # restore context->R15 | ||
2643 | |||
2644 | .Lin_key_prologue: | ||
2645 | mov 8(%rax),%rdi | ||
2646 | mov 16(%rax),%rsi | ||
2647 | mov %rax,152($context) # restore context->Rsp | ||
2648 | mov %rsi,168($context) # restore context->Rsi | ||
2649 | mov %rdi,176($context) # restore context->Rdi | ||
2650 | |||
2651 | jmp .Lcommon_seh_exit | ||
2652 | .size key_se_handler,.-key_se_handler | ||
2653 | |||
2654 | .type cbc_se_handler,\@abi-omnipotent | ||
2655 | .align 16 | ||
2656 | cbc_se_handler: | ||
2657 | push %rsi | ||
2658 | push %rdi | ||
2659 | push %rbx | ||
2660 | push %rbp | ||
2661 | push %r12 | ||
2662 | push %r13 | ||
2663 | push %r14 | ||
2664 | push %r15 | ||
2665 | pushfq | ||
2666 | sub \$64,%rsp | ||
2667 | |||
2668 | mov 120($context),%rax # pull context->Rax | ||
2669 | mov 248($context),%rbx # pull context->Rip | ||
2670 | |||
2671 | lea .Lcbc_prologue(%rip),%r10 | ||
2672 | cmp %r10,%rbx # context->Rip<.Lcbc_prologue | ||
2673 | jb .Lin_cbc_prologue | ||
2674 | |||
2675 | lea .Lcbc_fast_body(%rip),%r10 | ||
2676 | cmp %r10,%rbx # context->Rip<.Lcbc_fast_body | ||
2677 | jb .Lin_cbc_frame_setup | ||
2678 | |||
2679 | lea .Lcbc_slow_prologue(%rip),%r10 | ||
2680 | cmp %r10,%rbx # context->Rip<.Lcbc_slow_prologue | ||
2681 | jb .Lin_cbc_body | ||
2682 | |||
2683 | lea .Lcbc_slow_body(%rip),%r10 | ||
2684 | cmp %r10,%rbx # context->Rip<.Lcbc_slow_body | ||
2685 | jb .Lin_cbc_frame_setup | ||
2686 | |||
2687 | .Lin_cbc_body: | ||
2688 | mov 152($context),%rax # pull context->Rsp | ||
2689 | |||
2690 | lea .Lcbc_epilogue(%rip),%r10 | ||
2691 | cmp %r10,%rbx # context->Rip>=.Lcbc_epilogue | ||
2692 | jae .Lin_cbc_prologue | ||
2693 | |||
2694 | lea 8(%rax),%rax | ||
2695 | |||
2696 | lea .Lcbc_popfq(%rip),%r10 | ||
2697 | cmp %r10,%rbx # context->Rip>=.Lcbc_popfq | ||
2698 | jae .Lin_cbc_prologue | ||
2699 | |||
2700 | mov `16-8`(%rax),%rax # biased $_rsp | ||
2701 | lea 56(%rax),%rax | ||
2702 | |||
2703 | .Lin_cbc_frame_setup: | ||
2704 | mov -16(%rax),%rbx | ||
2705 | mov -24(%rax),%rbp | ||
2706 | mov -32(%rax),%r12 | ||
2707 | mov -40(%rax),%r13 | ||
2708 | mov -48(%rax),%r14 | ||
2709 | mov -56(%rax),%r15 | ||
2710 | mov %rbx,144($context) # restore context->Rbx | ||
2711 | mov %rbp,160($context) # restore context->Rbp | ||
2712 | mov %r12,216($context) # restore context->R12 | ||
2713 | mov %r13,224($context) # restore context->R13 | ||
2714 | mov %r14,232($context) # restore context->R14 | ||
2715 | mov %r15,240($context) # restore context->R15 | ||
2716 | |||
2717 | .Lin_cbc_prologue: | ||
2718 | mov 8(%rax),%rdi | ||
2719 | mov 16(%rax),%rsi | ||
2720 | mov %rax,152($context) # restore context->Rsp | ||
2721 | mov %rsi,168($context) # restore context->Rsi | ||
2722 | mov %rdi,176($context) # restore context->Rdi | ||
2723 | |||
2724 | .Lcommon_seh_exit: | ||
2725 | |||
2726 | mov 40($disp),%rdi # disp->ContextRecord | ||
2727 | mov $context,%rsi # context | ||
2728 | mov \$`1232/8`,%ecx # sizeof(CONTEXT) | ||
2729 | .long 0xa548f3fc # cld; rep movsq | ||
2730 | |||
2731 | mov $disp,%rsi | ||
2732 | xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER | ||
2733 | mov 8(%rsi),%rdx # arg2, disp->ImageBase | ||
2734 | mov 0(%rsi),%r8 # arg3, disp->ControlPc | ||
2735 | mov 16(%rsi),%r9 # arg4, disp->FunctionEntry | ||
2736 | mov 40(%rsi),%r10 # disp->ContextRecord | ||
2737 | lea 56(%rsi),%r11 # &disp->HandlerData | ||
2738 | lea 24(%rsi),%r12 # &disp->EstablisherFrame | ||
2739 | mov %r10,32(%rsp) # arg5 | ||
2740 | mov %r11,40(%rsp) # arg6 | ||
2741 | mov %r12,48(%rsp) # arg7 | ||
2742 | mov %rcx,56(%rsp) # arg8, (NULL) | ||
2743 | call *__imp_RtlVirtualUnwind(%rip) | ||
2744 | |||
2745 | mov \$1,%eax # ExceptionContinueSearch | ||
2746 | add \$64,%rsp | ||
2747 | popfq | ||
2748 | pop %r15 | ||
2749 | pop %r14 | ||
2750 | pop %r13 | ||
2751 | pop %r12 | ||
2752 | pop %rbp | ||
2753 | pop %rbx | ||
2754 | pop %rdi | ||
2755 | pop %rsi | ||
2756 | ret | ||
2757 | .size cbc_se_handler,.-cbc_se_handler | ||
2758 | |||
2759 | .section .pdata | ||
2760 | .align 4 | ||
2761 | .rva .LSEH_begin_AES_encrypt | ||
2762 | .rva .LSEH_end_AES_encrypt | ||
2763 | .rva .LSEH_info_AES_encrypt | ||
2764 | |||
2765 | .rva .LSEH_begin_AES_decrypt | ||
2766 | .rva .LSEH_end_AES_decrypt | ||
2767 | .rva .LSEH_info_AES_decrypt | ||
2768 | |||
2769 | .rva .LSEH_begin_AES_set_encrypt_key | ||
2770 | .rva .LSEH_end_AES_set_encrypt_key | ||
2771 | .rva .LSEH_info_AES_set_encrypt_key | ||
2772 | |||
2773 | .rva .LSEH_begin_AES_set_decrypt_key | ||
2774 | .rva .LSEH_end_AES_set_decrypt_key | ||
2775 | .rva .LSEH_info_AES_set_decrypt_key | ||
2776 | |||
2777 | .rva .LSEH_begin_AES_cbc_encrypt | ||
2778 | .rva .LSEH_end_AES_cbc_encrypt | ||
2779 | .rva .LSEH_info_AES_cbc_encrypt | ||
2780 | |||
2781 | .section .xdata | ||
2782 | .align 8 | ||
2783 | .LSEH_info_AES_encrypt: | ||
2784 | .byte 9,0,0,0 | ||
2785 | .rva block_se_handler | ||
2786 | .rva .Lenc_prologue,.Lenc_epilogue # HandlerData[] | ||
2787 | .LSEH_info_AES_decrypt: | ||
2788 | .byte 9,0,0,0 | ||
2789 | .rva block_se_handler | ||
2790 | .rva .Ldec_prologue,.Ldec_epilogue # HandlerData[] | ||
2791 | .LSEH_info_AES_set_encrypt_key: | ||
2792 | .byte 9,0,0,0 | ||
2793 | .rva key_se_handler | ||
2794 | .rva .Lenc_key_prologue,.Lenc_key_epilogue # HandlerData[] | ||
2795 | .LSEH_info_AES_set_decrypt_key: | ||
2796 | .byte 9,0,0,0 | ||
2797 | .rva key_se_handler | ||
2798 | .rva .Ldec_key_prologue,.Ldec_key_epilogue # HandlerData[] | ||
2799 | .LSEH_info_AES_cbc_encrypt: | ||
2800 | .byte 9,0,0,0 | ||
2801 | .rva cbc_se_handler | ||
2802 | ___ | ||
2803 | } | ||
1574 | 2804 | ||
1575 | $code =~ s/\`([^\`]*)\`/eval($1)/gem; | 2805 | $code =~ s/\`([^\`]*)\`/eval($1)/gem; |
1576 | 2806 | ||
diff --git a/src/lib/libcrypto/asn1/ameth_lib.c b/src/lib/libcrypto/asn1/ameth_lib.c index 18957c669e..9a8b6cc222 100644 --- a/src/lib/libcrypto/asn1/ameth_lib.c +++ b/src/lib/libcrypto/asn1/ameth_lib.c | |||
@@ -301,6 +301,8 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags, | |||
301 | if (!ameth->info) | 301 | if (!ameth->info) |
302 | goto err; | 302 | goto err; |
303 | } | 303 | } |
304 | else | ||
305 | ameth->info = NULL; | ||
304 | 306 | ||
305 | if (pem_str) | 307 | if (pem_str) |
306 | { | 308 | { |
@@ -308,6 +310,8 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags, | |||
308 | if (!ameth->pem_str) | 310 | if (!ameth->pem_str) |
309 | goto err; | 311 | goto err; |
310 | } | 312 | } |
313 | else | ||
314 | ameth->pem_str = NULL; | ||
311 | 315 | ||
312 | ameth->pub_decode = 0; | 316 | ameth->pub_decode = 0; |
313 | ameth->pub_encode = 0; | 317 | ameth->pub_encode = 0; |
diff --git a/src/lib/libcrypto/asn1/asn1_gen.c b/src/lib/libcrypto/asn1/asn1_gen.c index 2da38292c8..4fc241908f 100644 --- a/src/lib/libcrypto/asn1/asn1_gen.c +++ b/src/lib/libcrypto/asn1/asn1_gen.c | |||
@@ -227,6 +227,8 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) | |||
227 | /* Allocate buffer for new encoding */ | 227 | /* Allocate buffer for new encoding */ |
228 | 228 | ||
229 | new_der = OPENSSL_malloc(len); | 229 | new_der = OPENSSL_malloc(len); |
230 | if (!new_der) | ||
231 | goto err; | ||
230 | 232 | ||
231 | /* Generate tagged encoding */ | 233 | /* Generate tagged encoding */ |
232 | 234 | ||
@@ -245,8 +247,14 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) | |||
245 | /* If IMPLICIT, output tag */ | 247 | /* If IMPLICIT, output tag */ |
246 | 248 | ||
247 | if (asn1_tags.imp_tag != -1) | 249 | if (asn1_tags.imp_tag != -1) |
250 | { | ||
251 | if (asn1_tags.imp_class == V_ASN1_UNIVERSAL | ||
252 | && (asn1_tags.imp_tag == V_ASN1_SEQUENCE | ||
253 | || asn1_tags.imp_tag == V_ASN1_SET) ) | ||
254 | hdr_constructed = V_ASN1_CONSTRUCTED; | ||
248 | ASN1_put_object(&p, hdr_constructed, hdr_len, | 255 | ASN1_put_object(&p, hdr_constructed, hdr_len, |
249 | asn1_tags.imp_tag, asn1_tags.imp_class); | 256 | asn1_tags.imp_tag, asn1_tags.imp_class); |
257 | } | ||
250 | 258 | ||
251 | /* Copy across original encoding */ | 259 | /* Copy across original encoding */ |
252 | memcpy(p, cpy_start, cpy_len); | 260 | memcpy(p, cpy_start, cpy_len); |
@@ -439,13 +447,15 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) | |||
439 | 447 | ||
440 | static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) | 448 | static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) |
441 | { | 449 | { |
442 | ASN1_TYPE *ret = NULL, *typ = NULL; | 450 | ASN1_TYPE *ret = NULL; |
443 | STACK_OF(ASN1_TYPE) *sk = NULL; | 451 | STACK_OF(ASN1_TYPE) *sk = NULL; |
444 | STACK_OF(CONF_VALUE) *sect = NULL; | 452 | STACK_OF(CONF_VALUE) *sect = NULL; |
445 | unsigned char *der = NULL, *p; | 453 | unsigned char *der = NULL; |
446 | int derlen; | 454 | int derlen; |
447 | int i, is_set; | 455 | int i; |
448 | sk = sk_ASN1_TYPE_new_null(); | 456 | sk = sk_ASN1_TYPE_new_null(); |
457 | if (!sk) | ||
458 | goto bad; | ||
449 | if (section) | 459 | if (section) |
450 | { | 460 | { |
451 | if (!cnf) | 461 | if (!cnf) |
@@ -455,28 +465,23 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) | |||
455 | goto bad; | 465 | goto bad; |
456 | for (i = 0; i < sk_CONF_VALUE_num(sect); i++) | 466 | for (i = 0; i < sk_CONF_VALUE_num(sect); i++) |
457 | { | 467 | { |
458 | typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); | 468 | ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); |
459 | if (!typ) | 469 | if (!typ) |
460 | goto bad; | 470 | goto bad; |
461 | sk_ASN1_TYPE_push(sk, typ); | 471 | if (!sk_ASN1_TYPE_push(sk, typ)) |
462 | typ = NULL; | 472 | goto bad; |
463 | } | 473 | } |
464 | } | 474 | } |
465 | 475 | ||
466 | /* Now we has a STACK of the components, convert to the correct form */ | 476 | /* Now we has a STACK of the components, convert to the correct form */ |
467 | 477 | ||
468 | if (utype == V_ASN1_SET) | 478 | if (utype == V_ASN1_SET) |
469 | is_set = 1; | 479 | derlen = i2d_ASN1_SET_ANY(sk, &der); |
470 | else | 480 | else |
471 | is_set = 0; | 481 | derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); |
472 | |||
473 | 482 | ||
474 | derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype, | 483 | if (derlen < 0) |
475 | V_ASN1_UNIVERSAL, is_set); | 484 | goto bad; |
476 | der = OPENSSL_malloc(derlen); | ||
477 | p = der; | ||
478 | i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype, | ||
479 | V_ASN1_UNIVERSAL, is_set); | ||
480 | 485 | ||
481 | if (!(ret = ASN1_TYPE_new())) | 486 | if (!(ret = ASN1_TYPE_new())) |
482 | goto bad; | 487 | goto bad; |
@@ -498,8 +503,6 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) | |||
498 | 503 | ||
499 | if (sk) | 504 | if (sk) |
500 | sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); | 505 | sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); |
501 | if (typ) | ||
502 | ASN1_TYPE_free(typ); | ||
503 | if (sect) | 506 | if (sect) |
504 | X509V3_section_free(cnf, sect); | 507 | X509V3_section_free(cnf, sect); |
505 | 508 | ||
@@ -549,7 +552,7 @@ static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_cons | |||
549 | static int asn1_str2tag(const char *tagstr, int len) | 552 | static int asn1_str2tag(const char *tagstr, int len) |
550 | { | 553 | { |
551 | unsigned int i; | 554 | unsigned int i; |
552 | static struct tag_name_st *tntmp, tnst [] = { | 555 | static const struct tag_name_st *tntmp, tnst [] = { |
553 | ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), | 556 | ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), |
554 | ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), | 557 | ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), |
555 | ASN1_GEN_STR("NULL", V_ASN1_NULL), | 558 | ASN1_GEN_STR("NULL", V_ASN1_NULL), |
@@ -584,6 +587,8 @@ static int asn1_str2tag(const char *tagstr, int len) | |||
584 | ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), | 587 | ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), |
585 | ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), | 588 | ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), |
586 | ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), | 589 | ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), |
590 | ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), | ||
591 | ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), | ||
587 | 592 | ||
588 | /* Special cases */ | 593 | /* Special cases */ |
589 | ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), | 594 | ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), |
@@ -729,6 +734,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) | |||
729 | case V_ASN1_VISIBLESTRING: | 734 | case V_ASN1_VISIBLESTRING: |
730 | case V_ASN1_UNIVERSALSTRING: | 735 | case V_ASN1_UNIVERSALSTRING: |
731 | case V_ASN1_GENERALSTRING: | 736 | case V_ASN1_GENERALSTRING: |
737 | case V_ASN1_NUMERICSTRING: | ||
732 | 738 | ||
733 | if (format == ASN1_GEN_FORMAT_ASCII) | 739 | if (format == ASN1_GEN_FORMAT_ASCII) |
734 | format = MBSTRING_ASC; | 740 | format = MBSTRING_ASC; |
diff --git a/src/lib/libcrypto/bn/asm/alpha-mont.pl b/src/lib/libcrypto/bn/asm/alpha-mont.pl index 7a2cc3173b..f7e0ca1646 100644 --- a/src/lib/libcrypto/bn/asm/alpha-mont.pl +++ b/src/lib/libcrypto/bn/asm/alpha-mont.pl | |||
@@ -53,15 +53,15 @@ $code=<<___; | |||
53 | .align 5 | 53 | .align 5 |
54 | .ent bn_mul_mont | 54 | .ent bn_mul_mont |
55 | bn_mul_mont: | 55 | bn_mul_mont: |
56 | lda sp,-40(sp) | 56 | lda sp,-48(sp) |
57 | stq ra,0(sp) | 57 | stq ra,0(sp) |
58 | stq s3,8(sp) | 58 | stq s3,8(sp) |
59 | stq s4,16(sp) | 59 | stq s4,16(sp) |
60 | stq s5,24(sp) | 60 | stq s5,24(sp) |
61 | stq fp,32(sp) | 61 | stq fp,32(sp) |
62 | mov sp,fp | 62 | mov sp,fp |
63 | .mask 0x0400f000,-40 | 63 | .mask 0x0400f000,-48 |
64 | .frame fp,40,ra | 64 | .frame fp,48,ra |
65 | .prologue 0 | 65 | .prologue 0 |
66 | 66 | ||
67 | .align 4 | 67 | .align 4 |
@@ -306,7 +306,7 @@ bn_mul_mont: | |||
306 | ldq s4,16(sp) | 306 | ldq s4,16(sp) |
307 | ldq s5,24(sp) | 307 | ldq s5,24(sp) |
308 | ldq fp,32(sp) | 308 | ldq fp,32(sp) |
309 | lda sp,40(sp) | 309 | lda sp,48(sp) |
310 | ret (ra) | 310 | ret (ra) |
311 | .end bn_mul_mont | 311 | .end bn_mul_mont |
312 | .rdata | 312 | .rdata |
diff --git a/src/lib/libcrypto/bn/asm/armv4-mont.pl b/src/lib/libcrypto/bn/asm/armv4-mont.pl index 05d5dc1a48..14e0d2d1dd 100644 --- a/src/lib/libcrypto/bn/asm/armv4-mont.pl +++ b/src/lib/libcrypto/bn/asm/armv4-mont.pl | |||
@@ -193,6 +193,7 @@ bn_mul_mont: | |||
193 | bx lr @ interoperable with Thumb ISA:-) | 193 | bx lr @ interoperable with Thumb ISA:-) |
194 | .size bn_mul_mont,.-bn_mul_mont | 194 | .size bn_mul_mont,.-bn_mul_mont |
195 | .asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>" | 195 | .asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>" |
196 | .align 2 | ||
196 | ___ | 197 | ___ |
197 | 198 | ||
198 | $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 | 199 | $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 |
diff --git a/src/lib/libcrypto/bn/asm/ppc.pl b/src/lib/libcrypto/bn/asm/ppc.pl index 08e0053473..37c65d3511 100644 --- a/src/lib/libcrypto/bn/asm/ppc.pl +++ b/src/lib/libcrypto/bn/asm/ppc.pl | |||
@@ -100,9 +100,9 @@ | |||
100 | # me a note at schari@us.ibm.com | 100 | # me a note at schari@us.ibm.com |
101 | # | 101 | # |
102 | 102 | ||
103 | $opf = shift; | 103 | $flavour = shift; |
104 | 104 | ||
105 | if ($opf =~ /32\.s/) { | 105 | if ($flavour =~ /32/) { |
106 | $BITS= 32; | 106 | $BITS= 32; |
107 | $BNSZ= $BITS/8; | 107 | $BNSZ= $BITS/8; |
108 | $ISA= "\"ppc\""; | 108 | $ISA= "\"ppc\""; |
@@ -125,7 +125,7 @@ if ($opf =~ /32\.s/) { | |||
125 | $INSR= "insrwi"; # insert right | 125 | $INSR= "insrwi"; # insert right |
126 | $ROTL= "rotlwi"; # rotate left by immediate | 126 | $ROTL= "rotlwi"; # rotate left by immediate |
127 | $TR= "tw"; # conditional trap | 127 | $TR= "tw"; # conditional trap |
128 | } elsif ($opf =~ /64\.s/) { | 128 | } elsif ($flavour =~ /64/) { |
129 | $BITS= 64; | 129 | $BITS= 64; |
130 | $BNSZ= $BITS/8; | 130 | $BNSZ= $BITS/8; |
131 | $ISA= "\"ppc64\""; | 131 | $ISA= "\"ppc64\""; |
@@ -149,93 +149,16 @@ if ($opf =~ /32\.s/) { | |||
149 | $INSR= "insrdi"; # insert right | 149 | $INSR= "insrdi"; # insert right |
150 | $ROTL= "rotldi"; # rotate left by immediate | 150 | $ROTL= "rotldi"; # rotate left by immediate |
151 | $TR= "td"; # conditional trap | 151 | $TR= "td"; # conditional trap |
152 | } else { die "nonsense $opf"; } | 152 | } else { die "nonsense $flavour"; } |
153 | 153 | ||
154 | ( defined shift || open STDOUT,">$opf" ) || die "can't open $opf: $!"; | 154 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; |
155 | ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or | ||
156 | ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or | ||
157 | die "can't locate ppc-xlate.pl"; | ||
155 | 158 | ||
156 | # function entry points from the AIX code | 159 | open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; |
157 | # | ||
158 | # There are other, more elegant, ways to handle this. We (IBM) chose | ||
159 | # this approach as it plays well with scripts we run to 'namespace' | ||
160 | # OpenSSL .i.e. we add a prefix to all the public symbols so we can | ||
161 | # co-exist in the same process with other implementations of OpenSSL. | ||
162 | # 'cleverer' ways of doing these substitutions tend to hide data we | ||
163 | # need to be obvious. | ||
164 | # | ||
165 | my @items = ("bn_sqr_comba4", | ||
166 | "bn_sqr_comba8", | ||
167 | "bn_mul_comba4", | ||
168 | "bn_mul_comba8", | ||
169 | "bn_sub_words", | ||
170 | "bn_add_words", | ||
171 | "bn_div_words", | ||
172 | "bn_sqr_words", | ||
173 | "bn_mul_words", | ||
174 | "bn_mul_add_words"); | ||
175 | 160 | ||
176 | if ($opf =~ /linux/) { do_linux(); } | 161 | $data=<<EOF; |
177 | elsif ($opf =~ /aix/) { do_aix(); } | ||
178 | elsif ($opf =~ /osx/) { do_osx(); } | ||
179 | else { do_bsd(); } | ||
180 | |||
181 | sub do_linux { | ||
182 | $d=&data(); | ||
183 | |||
184 | if ($BITS==64) { | ||
185 | foreach $t (@items) { | ||
186 | $d =~ s/\.$t:/\ | ||
187 | \t.section\t".opd","aw"\ | ||
188 | \t.align\t3\ | ||
189 | \t.globl\t$t\ | ||
190 | $t:\ | ||
191 | \t.quad\t.$t,.TOC.\@tocbase,0\ | ||
192 | \t.size\t$t,24\ | ||
193 | \t.previous\n\ | ||
194 | \t.type\t.$t,\@function\ | ||
195 | \t.globl\t.$t\ | ||
196 | .$t:/g; | ||
197 | } | ||
198 | } | ||
199 | else { | ||
200 | foreach $t (@items) { | ||
201 | $d=~s/\.$t/$t/g; | ||
202 | } | ||
203 | } | ||
204 | # hide internal labels to avoid pollution of name table... | ||
205 | $d=~s/Lppcasm_/.Lppcasm_/gm; | ||
206 | print $d; | ||
207 | } | ||
208 | |||
209 | sub do_aix { | ||
210 | # AIX assembler is smart enough to please the linker without | ||
211 | # making us do something special... | ||
212 | print &data(); | ||
213 | } | ||
214 | |||
215 | # MacOSX 32 bit | ||
216 | sub do_osx { | ||
217 | $d=&data(); | ||
218 | # Change the bn symbol prefix from '.' to '_' | ||
219 | foreach $t (@items) { | ||
220 | $d=~s/\.$t/_$t/g; | ||
221 | } | ||
222 | # Change .machine to something OS X asm will accept | ||
223 | $d=~s/\.machine.*/.text/g; | ||
224 | $d=~s/\#/;/g; # change comment from '#' to ';' | ||
225 | print $d; | ||
226 | } | ||
227 | |||
228 | # BSD (Untested) | ||
229 | sub do_bsd { | ||
230 | $d=&data(); | ||
231 | foreach $t (@items) { | ||
232 | $d=~s/\.$t/_$t/g; | ||
233 | } | ||
234 | print $d; | ||
235 | } | ||
236 | |||
237 | sub data { | ||
238 | local($data)=<<EOF; | ||
239 | #-------------------------------------------------------------------- | 162 | #-------------------------------------------------------------------- |
240 | # | 163 | # |
241 | # | 164 | # |
@@ -297,33 +220,20 @@ sub data { | |||
297 | # | 220 | # |
298 | # Defines to be used in the assembly code. | 221 | # Defines to be used in the assembly code. |
299 | # | 222 | # |
300 | .set r0,0 # we use it as storage for value of 0 | 223 | #.set r0,0 # we use it as storage for value of 0 |
301 | .set SP,1 # preserved | 224 | #.set SP,1 # preserved |
302 | .set RTOC,2 # preserved | 225 | #.set RTOC,2 # preserved |
303 | .set r3,3 # 1st argument/return value | 226 | #.set r3,3 # 1st argument/return value |
304 | .set r4,4 # 2nd argument/volatile register | 227 | #.set r4,4 # 2nd argument/volatile register |
305 | .set r5,5 # 3rd argument/volatile register | 228 | #.set r5,5 # 3rd argument/volatile register |
306 | .set r6,6 # ... | 229 | #.set r6,6 # ... |
307 | .set r7,7 | 230 | #.set r7,7 |
308 | .set r8,8 | 231 | #.set r8,8 |
309 | .set r9,9 | 232 | #.set r9,9 |
310 | .set r10,10 | 233 | #.set r10,10 |
311 | .set r11,11 | 234 | #.set r11,11 |
312 | .set r12,12 | 235 | #.set r12,12 |
313 | .set r13,13 # not used, nor any other "below" it... | 236 | #.set r13,13 # not used, nor any other "below" it... |
314 | |||
315 | .set BO_IF_NOT,4 | ||
316 | .set BO_IF,12 | ||
317 | .set BO_dCTR_NZERO,16 | ||
318 | .set BO_dCTR_ZERO,18 | ||
319 | .set BO_ALWAYS,20 | ||
320 | .set CR0_LT,0; | ||
321 | .set CR0_GT,1; | ||
322 | .set CR0_EQ,2 | ||
323 | .set CR1_FX,4; | ||
324 | .set CR1_FEX,5; | ||
325 | .set CR1_VX,6 | ||
326 | .set LR,8 | ||
327 | 237 | ||
328 | # Declare function names to be global | 238 | # Declare function names to be global |
329 | # NOTE: For gcc these names MUST be changed to remove | 239 | # NOTE: For gcc these names MUST be changed to remove |
@@ -344,7 +254,7 @@ sub data { | |||
344 | 254 | ||
345 | # .text section | 255 | # .text section |
346 | 256 | ||
347 | .machine $ISA | 257 | .machine "any" |
348 | 258 | ||
349 | # | 259 | # |
350 | # NOTE: The following label name should be changed to | 260 | # NOTE: The following label name should be changed to |
@@ -478,7 +388,7 @@ sub data { | |||
478 | 388 | ||
479 | $ST r9,`6*$BNSZ`(r3) #r[6]=c1 | 389 | $ST r9,`6*$BNSZ`(r3) #r[6]=c1 |
480 | $ST r10,`7*$BNSZ`(r3) #r[7]=c2 | 390 | $ST r10,`7*$BNSZ`(r3) #r[7]=c2 |
481 | bclr BO_ALWAYS,CR0_LT | 391 | blr |
482 | .long 0x00000000 | 392 | .long 0x00000000 |
483 | 393 | ||
484 | # | 394 | # |
@@ -903,7 +813,7 @@ sub data { | |||
903 | $ST r9, `15*$BNSZ`(r3) #r[15]=c1; | 813 | $ST r9, `15*$BNSZ`(r3) #r[15]=c1; |
904 | 814 | ||
905 | 815 | ||
906 | bclr BO_ALWAYS,CR0_LT | 816 | blr |
907 | 817 | ||
908 | .long 0x00000000 | 818 | .long 0x00000000 |
909 | 819 | ||
@@ -1055,7 +965,7 @@ sub data { | |||
1055 | 965 | ||
1056 | $ST r10,`6*$BNSZ`(r3) #r[6]=c1 | 966 | $ST r10,`6*$BNSZ`(r3) #r[6]=c1 |
1057 | $ST r11,`7*$BNSZ`(r3) #r[7]=c2 | 967 | $ST r11,`7*$BNSZ`(r3) #r[7]=c2 |
1058 | bclr BO_ALWAYS,CR0_LT | 968 | blr |
1059 | .long 0x00000000 | 969 | .long 0x00000000 |
1060 | 970 | ||
1061 | # | 971 | # |
@@ -1591,7 +1501,7 @@ sub data { | |||
1591 | adde r10,r10,r9 | 1501 | adde r10,r10,r9 |
1592 | $ST r12,`14*$BNSZ`(r3) #r[14]=c3; | 1502 | $ST r12,`14*$BNSZ`(r3) #r[14]=c3; |
1593 | $ST r10,`15*$BNSZ`(r3) #r[15]=c1; | 1503 | $ST r10,`15*$BNSZ`(r3) #r[15]=c1; |
1594 | bclr BO_ALWAYS,CR0_LT | 1504 | blr |
1595 | .long 0x00000000 | 1505 | .long 0x00000000 |
1596 | 1506 | ||
1597 | # | 1507 | # |
@@ -1623,7 +1533,7 @@ sub data { | |||
1623 | subfc. r7,r0,r6 # If r6 is 0 then result is 0. | 1533 | subfc. r7,r0,r6 # If r6 is 0 then result is 0. |
1624 | # if r6 > 0 then result !=0 | 1534 | # if r6 > 0 then result !=0 |
1625 | # In either case carry bit is set. | 1535 | # In either case carry bit is set. |
1626 | bc BO_IF,CR0_EQ,Lppcasm_sub_adios | 1536 | beq Lppcasm_sub_adios |
1627 | addi r4,r4,-$BNSZ | 1537 | addi r4,r4,-$BNSZ |
1628 | addi r3,r3,-$BNSZ | 1538 | addi r3,r3,-$BNSZ |
1629 | addi r5,r5,-$BNSZ | 1539 | addi r5,r5,-$BNSZ |
@@ -1635,11 +1545,11 @@ Lppcasm_sub_mainloop: | |||
1635 | # if carry = 1 this is r7-r8. Else it | 1545 | # if carry = 1 this is r7-r8. Else it |
1636 | # is r7-r8 -1 as we need. | 1546 | # is r7-r8 -1 as we need. |
1637 | $STU r6,$BNSZ(r3) | 1547 | $STU r6,$BNSZ(r3) |
1638 | bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_sub_mainloop | 1548 | bdnz- Lppcasm_sub_mainloop |
1639 | Lppcasm_sub_adios: | 1549 | Lppcasm_sub_adios: |
1640 | subfze r3,r0 # if carry bit is set then r3 = 0 else -1 | 1550 | subfze r3,r0 # if carry bit is set then r3 = 0 else -1 |
1641 | andi. r3,r3,1 # keep only last bit. | 1551 | andi. r3,r3,1 # keep only last bit. |
1642 | bclr BO_ALWAYS,CR0_LT | 1552 | blr |
1643 | .long 0x00000000 | 1553 | .long 0x00000000 |
1644 | 1554 | ||
1645 | 1555 | ||
@@ -1670,7 +1580,7 @@ Lppcasm_sub_adios: | |||
1670 | # check for r6 = 0. Is this needed? | 1580 | # check for r6 = 0. Is this needed? |
1671 | # | 1581 | # |
1672 | addic. r6,r6,0 #test r6 and clear carry bit. | 1582 | addic. r6,r6,0 #test r6 and clear carry bit. |
1673 | bc BO_IF,CR0_EQ,Lppcasm_add_adios | 1583 | beq Lppcasm_add_adios |
1674 | addi r4,r4,-$BNSZ | 1584 | addi r4,r4,-$BNSZ |
1675 | addi r3,r3,-$BNSZ | 1585 | addi r3,r3,-$BNSZ |
1676 | addi r5,r5,-$BNSZ | 1586 | addi r5,r5,-$BNSZ |
@@ -1680,10 +1590,10 @@ Lppcasm_add_mainloop: | |||
1680 | $LDU r8,$BNSZ(r5) | 1590 | $LDU r8,$BNSZ(r5) |
1681 | adde r8,r7,r8 | 1591 | adde r8,r7,r8 |
1682 | $STU r8,$BNSZ(r3) | 1592 | $STU r8,$BNSZ(r3) |
1683 | bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_add_mainloop | 1593 | bdnz- Lppcasm_add_mainloop |
1684 | Lppcasm_add_adios: | 1594 | Lppcasm_add_adios: |
1685 | addze r3,r0 #return carry bit. | 1595 | addze r3,r0 #return carry bit. |
1686 | bclr BO_ALWAYS,CR0_LT | 1596 | blr |
1687 | .long 0x00000000 | 1597 | .long 0x00000000 |
1688 | 1598 | ||
1689 | # | 1599 | # |
@@ -1707,24 +1617,24 @@ Lppcasm_add_adios: | |||
1707 | # r5 = d | 1617 | # r5 = d |
1708 | 1618 | ||
1709 | $UCMPI 0,r5,0 # compare r5 and 0 | 1619 | $UCMPI 0,r5,0 # compare r5 and 0 |
1710 | bc BO_IF_NOT,CR0_EQ,Lppcasm_div1 # proceed if d!=0 | 1620 | bne Lppcasm_div1 # proceed if d!=0 |
1711 | li r3,-1 # d=0 return -1 | 1621 | li r3,-1 # d=0 return -1 |
1712 | bclr BO_ALWAYS,CR0_LT | 1622 | blr |
1713 | Lppcasm_div1: | 1623 | Lppcasm_div1: |
1714 | xor r0,r0,r0 #r0=0 | 1624 | xor r0,r0,r0 #r0=0 |
1715 | li r8,$BITS | 1625 | li r8,$BITS |
1716 | $CNTLZ. r7,r5 #r7 = num leading 0s in d. | 1626 | $CNTLZ. r7,r5 #r7 = num leading 0s in d. |
1717 | bc BO_IF,CR0_EQ,Lppcasm_div2 #proceed if no leading zeros | 1627 | beq Lppcasm_div2 #proceed if no leading zeros |
1718 | subf r8,r7,r8 #r8 = BN_num_bits_word(d) | 1628 | subf r8,r7,r8 #r8 = BN_num_bits_word(d) |
1719 | $SHR. r9,r3,r8 #are there any bits above r8'th? | 1629 | $SHR. r9,r3,r8 #are there any bits above r8'th? |
1720 | $TR 16,r9,r0 #if there're, signal to dump core... | 1630 | $TR 16,r9,r0 #if there're, signal to dump core... |
1721 | Lppcasm_div2: | 1631 | Lppcasm_div2: |
1722 | $UCMP 0,r3,r5 #h>=d? | 1632 | $UCMP 0,r3,r5 #h>=d? |
1723 | bc BO_IF,CR0_LT,Lppcasm_div3 #goto Lppcasm_div3 if not | 1633 | blt Lppcasm_div3 #goto Lppcasm_div3 if not |
1724 | subf r3,r5,r3 #h-=d ; | 1634 | subf r3,r5,r3 #h-=d ; |
1725 | Lppcasm_div3: #r7 = BN_BITS2-i. so r7=i | 1635 | Lppcasm_div3: #r7 = BN_BITS2-i. so r7=i |
1726 | cmpi 0,0,r7,0 # is (i == 0)? | 1636 | cmpi 0,0,r7,0 # is (i == 0)? |
1727 | bc BO_IF,CR0_EQ,Lppcasm_div4 | 1637 | beq Lppcasm_div4 |
1728 | $SHL r3,r3,r7 # h = (h<< i) | 1638 | $SHL r3,r3,r7 # h = (h<< i) |
1729 | $SHR r8,r4,r8 # r8 = (l >> BN_BITS2 -i) | 1639 | $SHR r8,r4,r8 # r8 = (l >> BN_BITS2 -i) |
1730 | $SHL r5,r5,r7 # d<<=i | 1640 | $SHL r5,r5,r7 # d<<=i |
@@ -1741,7 +1651,7 @@ Lppcasm_divouterloop: | |||
1741 | $SHRI r11,r4,`$BITS/2` #r11= (l&BN_MASK2h)>>BN_BITS4 | 1651 | $SHRI r11,r4,`$BITS/2` #r11= (l&BN_MASK2h)>>BN_BITS4 |
1742 | # compute here for innerloop. | 1652 | # compute here for innerloop. |
1743 | $UCMP 0,r8,r9 # is (h>>BN_BITS4)==dh | 1653 | $UCMP 0,r8,r9 # is (h>>BN_BITS4)==dh |
1744 | bc BO_IF_NOT,CR0_EQ,Lppcasm_div5 # goto Lppcasm_div5 if not | 1654 | bne Lppcasm_div5 # goto Lppcasm_div5 if not |
1745 | 1655 | ||
1746 | li r8,-1 | 1656 | li r8,-1 |
1747 | $CLRU r8,r8,`$BITS/2` #q = BN_MASK2l | 1657 | $CLRU r8,r8,`$BITS/2` #q = BN_MASK2l |
@@ -1762,9 +1672,9 @@ Lppcasm_divinnerloop: | |||
1762 | # the following 2 instructions do that | 1672 | # the following 2 instructions do that |
1763 | $SHLI r7,r10,`$BITS/2` # r7 = (t<<BN_BITS4) | 1673 | $SHLI r7,r10,`$BITS/2` # r7 = (t<<BN_BITS4) |
1764 | or r7,r7,r11 # r7|=((l&BN_MASK2h)>>BN_BITS4) | 1674 | or r7,r7,r11 # r7|=((l&BN_MASK2h)>>BN_BITS4) |
1765 | $UCMP 1,r6,r7 # compare (tl <= r7) | 1675 | $UCMP cr1,r6,r7 # compare (tl <= r7) |
1766 | bc BO_IF_NOT,CR0_EQ,Lppcasm_divinnerexit | 1676 | bne Lppcasm_divinnerexit |
1767 | bc BO_IF_NOT,CR1_FEX,Lppcasm_divinnerexit | 1677 | ble cr1,Lppcasm_divinnerexit |
1768 | addi r8,r8,-1 #q-- | 1678 | addi r8,r8,-1 #q-- |
1769 | subf r12,r9,r12 #th -=dh | 1679 | subf r12,r9,r12 #th -=dh |
1770 | $CLRU r10,r5,`$BITS/2` #r10=dl. t is no longer needed in loop. | 1680 | $CLRU r10,r5,`$BITS/2` #r10=dl. t is no longer needed in loop. |
@@ -1773,14 +1683,14 @@ Lppcasm_divinnerloop: | |||
1773 | Lppcasm_divinnerexit: | 1683 | Lppcasm_divinnerexit: |
1774 | $SHRI r10,r6,`$BITS/2` #t=(tl>>BN_BITS4) | 1684 | $SHRI r10,r6,`$BITS/2` #t=(tl>>BN_BITS4) |
1775 | $SHLI r11,r6,`$BITS/2` #tl=(tl<<BN_BITS4)&BN_MASK2h; | 1685 | $SHLI r11,r6,`$BITS/2` #tl=(tl<<BN_BITS4)&BN_MASK2h; |
1776 | $UCMP 1,r4,r11 # compare l and tl | 1686 | $UCMP cr1,r4,r11 # compare l and tl |
1777 | add r12,r12,r10 # th+=t | 1687 | add r12,r12,r10 # th+=t |
1778 | bc BO_IF_NOT,CR1_FX,Lppcasm_div7 # if (l>=tl) goto Lppcasm_div7 | 1688 | bge cr1,Lppcasm_div7 # if (l>=tl) goto Lppcasm_div7 |
1779 | addi r12,r12,1 # th++ | 1689 | addi r12,r12,1 # th++ |
1780 | Lppcasm_div7: | 1690 | Lppcasm_div7: |
1781 | subf r11,r11,r4 #r11=l-tl | 1691 | subf r11,r11,r4 #r11=l-tl |
1782 | $UCMP 1,r3,r12 #compare h and th | 1692 | $UCMP cr1,r3,r12 #compare h and th |
1783 | bc BO_IF_NOT,CR1_FX,Lppcasm_div8 #if (h>=th) goto Lppcasm_div8 | 1693 | bge cr1,Lppcasm_div8 #if (h>=th) goto Lppcasm_div8 |
1784 | addi r8,r8,-1 # q-- | 1694 | addi r8,r8,-1 # q-- |
1785 | add r3,r5,r3 # h+=d | 1695 | add r3,r5,r3 # h+=d |
1786 | Lppcasm_div8: | 1696 | Lppcasm_div8: |
@@ -1791,12 +1701,12 @@ Lppcasm_div8: | |||
1791 | # the following 2 instructions will do this. | 1701 | # the following 2 instructions will do this. |
1792 | $INSR r11,r12,`$BITS/2`,`$BITS/2` # r11 is the value we want rotated $BITS/2. | 1702 | $INSR r11,r12,`$BITS/2`,`$BITS/2` # r11 is the value we want rotated $BITS/2. |
1793 | $ROTL r3,r11,`$BITS/2` # rotate by $BITS/2 and store in r3 | 1703 | $ROTL r3,r11,`$BITS/2` # rotate by $BITS/2 and store in r3 |
1794 | bc BO_dCTR_ZERO,CR0_EQ,Lppcasm_div9#if (count==0) break ; | 1704 | bdz Lppcasm_div9 #if (count==0) break ; |
1795 | $SHLI r0,r8,`$BITS/2` #ret =q<<BN_BITS4 | 1705 | $SHLI r0,r8,`$BITS/2` #ret =q<<BN_BITS4 |
1796 | b Lppcasm_divouterloop | 1706 | b Lppcasm_divouterloop |
1797 | Lppcasm_div9: | 1707 | Lppcasm_div9: |
1798 | or r3,r8,r0 | 1708 | or r3,r8,r0 |
1799 | bclr BO_ALWAYS,CR0_LT | 1709 | blr |
1800 | .long 0x00000000 | 1710 | .long 0x00000000 |
1801 | 1711 | ||
1802 | # | 1712 | # |
@@ -1822,7 +1732,7 @@ Lppcasm_div9: | |||
1822 | # No unrolling done here. Not performance critical. | 1732 | # No unrolling done here. Not performance critical. |
1823 | 1733 | ||
1824 | addic. r5,r5,0 #test r5. | 1734 | addic. r5,r5,0 #test r5. |
1825 | bc BO_IF,CR0_EQ,Lppcasm_sqr_adios | 1735 | beq Lppcasm_sqr_adios |
1826 | addi r4,r4,-$BNSZ | 1736 | addi r4,r4,-$BNSZ |
1827 | addi r3,r3,-$BNSZ | 1737 | addi r3,r3,-$BNSZ |
1828 | mtctr r5 | 1738 | mtctr r5 |
@@ -1833,9 +1743,9 @@ Lppcasm_sqr_mainloop: | |||
1833 | $UMULH r8,r6,r6 | 1743 | $UMULH r8,r6,r6 |
1834 | $STU r7,$BNSZ(r3) | 1744 | $STU r7,$BNSZ(r3) |
1835 | $STU r8,$BNSZ(r3) | 1745 | $STU r8,$BNSZ(r3) |
1836 | bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_sqr_mainloop | 1746 | bdnz- Lppcasm_sqr_mainloop |
1837 | Lppcasm_sqr_adios: | 1747 | Lppcasm_sqr_adios: |
1838 | bclr BO_ALWAYS,CR0_LT | 1748 | blr |
1839 | .long 0x00000000 | 1749 | .long 0x00000000 |
1840 | 1750 | ||
1841 | 1751 | ||
@@ -1858,7 +1768,7 @@ Lppcasm_sqr_adios: | |||
1858 | xor r0,r0,r0 | 1768 | xor r0,r0,r0 |
1859 | xor r12,r12,r12 # used for carry | 1769 | xor r12,r12,r12 # used for carry |
1860 | rlwinm. r7,r5,30,2,31 # num >> 2 | 1770 | rlwinm. r7,r5,30,2,31 # num >> 2 |
1861 | bc BO_IF,CR0_EQ,Lppcasm_mw_REM | 1771 | beq Lppcasm_mw_REM |
1862 | mtctr r7 | 1772 | mtctr r7 |
1863 | Lppcasm_mw_LOOP: | 1773 | Lppcasm_mw_LOOP: |
1864 | #mul(rp[0],ap[0],w,c1); | 1774 | #mul(rp[0],ap[0],w,c1); |
@@ -1896,11 +1806,11 @@ Lppcasm_mw_LOOP: | |||
1896 | 1806 | ||
1897 | addi r3,r3,`4*$BNSZ` | 1807 | addi r3,r3,`4*$BNSZ` |
1898 | addi r4,r4,`4*$BNSZ` | 1808 | addi r4,r4,`4*$BNSZ` |
1899 | bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_mw_LOOP | 1809 | bdnz- Lppcasm_mw_LOOP |
1900 | 1810 | ||
1901 | Lppcasm_mw_REM: | 1811 | Lppcasm_mw_REM: |
1902 | andi. r5,r5,0x3 | 1812 | andi. r5,r5,0x3 |
1903 | bc BO_IF,CR0_EQ,Lppcasm_mw_OVER | 1813 | beq Lppcasm_mw_OVER |
1904 | #mul(rp[0],ap[0],w,c1); | 1814 | #mul(rp[0],ap[0],w,c1); |
1905 | $LD r8,`0*$BNSZ`(r4) | 1815 | $LD r8,`0*$BNSZ`(r4) |
1906 | $UMULL r9,r6,r8 | 1816 | $UMULL r9,r6,r8 |
@@ -1912,7 +1822,7 @@ Lppcasm_mw_REM: | |||
1912 | 1822 | ||
1913 | addi r5,r5,-1 | 1823 | addi r5,r5,-1 |
1914 | cmpli 0,0,r5,0 | 1824 | cmpli 0,0,r5,0 |
1915 | bc BO_IF,CR0_EQ,Lppcasm_mw_OVER | 1825 | beq Lppcasm_mw_OVER |
1916 | 1826 | ||
1917 | 1827 | ||
1918 | #mul(rp[1],ap[1],w,c1); | 1828 | #mul(rp[1],ap[1],w,c1); |
@@ -1926,7 +1836,7 @@ Lppcasm_mw_REM: | |||
1926 | 1836 | ||
1927 | addi r5,r5,-1 | 1837 | addi r5,r5,-1 |
1928 | cmpli 0,0,r5,0 | 1838 | cmpli 0,0,r5,0 |
1929 | bc BO_IF,CR0_EQ,Lppcasm_mw_OVER | 1839 | beq Lppcasm_mw_OVER |
1930 | 1840 | ||
1931 | #mul_add(rp[2],ap[2],w,c1); | 1841 | #mul_add(rp[2],ap[2],w,c1); |
1932 | $LD r8,`2*$BNSZ`(r4) | 1842 | $LD r8,`2*$BNSZ`(r4) |
@@ -1939,7 +1849,7 @@ Lppcasm_mw_REM: | |||
1939 | 1849 | ||
1940 | Lppcasm_mw_OVER: | 1850 | Lppcasm_mw_OVER: |
1941 | addi r3,r12,0 | 1851 | addi r3,r12,0 |
1942 | bclr BO_ALWAYS,CR0_LT | 1852 | blr |
1943 | .long 0x00000000 | 1853 | .long 0x00000000 |
1944 | 1854 | ||
1945 | # | 1855 | # |
@@ -1964,7 +1874,7 @@ Lppcasm_mw_OVER: | |||
1964 | xor r0,r0,r0 #r0 = 0 | 1874 | xor r0,r0,r0 #r0 = 0 |
1965 | xor r12,r12,r12 #r12 = 0 . used for carry | 1875 | xor r12,r12,r12 #r12 = 0 . used for carry |
1966 | rlwinm. r7,r5,30,2,31 # num >> 2 | 1876 | rlwinm. r7,r5,30,2,31 # num >> 2 |
1967 | bc BO_IF,CR0_EQ,Lppcasm_maw_leftover # if (num < 4) go LPPCASM_maw_leftover | 1877 | beq Lppcasm_maw_leftover # if (num < 4) go LPPCASM_maw_leftover |
1968 | mtctr r7 | 1878 | mtctr r7 |
1969 | Lppcasm_maw_mainloop: | 1879 | Lppcasm_maw_mainloop: |
1970 | #mul_add(rp[0],ap[0],w,c1); | 1880 | #mul_add(rp[0],ap[0],w,c1); |
@@ -2017,11 +1927,11 @@ Lppcasm_maw_mainloop: | |||
2017 | $ST r11,`3*$BNSZ`(r3) | 1927 | $ST r11,`3*$BNSZ`(r3) |
2018 | addi r3,r3,`4*$BNSZ` | 1928 | addi r3,r3,`4*$BNSZ` |
2019 | addi r4,r4,`4*$BNSZ` | 1929 | addi r4,r4,`4*$BNSZ` |
2020 | bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_maw_mainloop | 1930 | bdnz- Lppcasm_maw_mainloop |
2021 | 1931 | ||
2022 | Lppcasm_maw_leftover: | 1932 | Lppcasm_maw_leftover: |
2023 | andi. r5,r5,0x3 | 1933 | andi. r5,r5,0x3 |
2024 | bc BO_IF,CR0_EQ,Lppcasm_maw_adios | 1934 | beq Lppcasm_maw_adios |
2025 | addi r3,r3,-$BNSZ | 1935 | addi r3,r3,-$BNSZ |
2026 | addi r4,r4,-$BNSZ | 1936 | addi r4,r4,-$BNSZ |
2027 | #mul_add(rp[0],ap[0],w,c1); | 1937 | #mul_add(rp[0],ap[0],w,c1); |
@@ -2036,7 +1946,7 @@ Lppcasm_maw_leftover: | |||
2036 | addze r12,r10 | 1946 | addze r12,r10 |
2037 | $ST r9,0(r3) | 1947 | $ST r9,0(r3) |
2038 | 1948 | ||
2039 | bc BO_dCTR_ZERO,CR0_EQ,Lppcasm_maw_adios | 1949 | bdz Lppcasm_maw_adios |
2040 | #mul_add(rp[1],ap[1],w,c1); | 1950 | #mul_add(rp[1],ap[1],w,c1); |
2041 | $LDU r8,$BNSZ(r4) | 1951 | $LDU r8,$BNSZ(r4) |
2042 | $UMULL r9,r6,r8 | 1952 | $UMULL r9,r6,r8 |
@@ -2048,7 +1958,7 @@ Lppcasm_maw_leftover: | |||
2048 | addze r12,r10 | 1958 | addze r12,r10 |
2049 | $ST r9,0(r3) | 1959 | $ST r9,0(r3) |
2050 | 1960 | ||
2051 | bc BO_dCTR_ZERO,CR0_EQ,Lppcasm_maw_adios | 1961 | bdz Lppcasm_maw_adios |
2052 | #mul_add(rp[2],ap[2],w,c1); | 1962 | #mul_add(rp[2],ap[2],w,c1); |
2053 | $LDU r8,$BNSZ(r4) | 1963 | $LDU r8,$BNSZ(r4) |
2054 | $UMULL r9,r6,r8 | 1964 | $UMULL r9,r6,r8 |
@@ -2062,17 +1972,10 @@ Lppcasm_maw_leftover: | |||
2062 | 1972 | ||
2063 | Lppcasm_maw_adios: | 1973 | Lppcasm_maw_adios: |
2064 | addi r3,r12,0 | 1974 | addi r3,r12,0 |
2065 | bclr BO_ALWAYS,CR0_LT | 1975 | blr |
2066 | .long 0x00000000 | 1976 | .long 0x00000000 |
2067 | .align 4 | 1977 | .align 4 |
2068 | EOF | 1978 | EOF |
2069 | $data =~ s/\`([^\`]*)\`/eval $1/gem; | 1979 | $data =~ s/\`([^\`]*)\`/eval $1/gem; |
2070 | 1980 | print $data; | |
2071 | # if some assembler chokes on some simplified mnemonic, | 1981 | close STDOUT; |
2072 | # this is the spot to fix it up, e.g.: | ||
2073 | # GNU as doesn't seem to accept cmplw, 32-bit unsigned compare | ||
2074 | $data =~ s/^(\s*)cmplw(\s+)([^,]+),(.*)/$1cmpl$2$3,0,$4/gm; | ||
2075 | # assembler X doesn't accept li, load immediate value | ||
2076 | #$data =~ s/^(\s*)li(\s+)([^,]+),(.*)/$1addi$2$3,0,$4/gm; | ||
2077 | return($data); | ||
2078 | } | ||
diff --git a/src/lib/libcrypto/bn/asm/x86_64-gcc.c b/src/lib/libcrypto/bn/asm/x86_64-gcc.c index f13f52dd85..acb0b40118 100644 --- a/src/lib/libcrypto/bn/asm/x86_64-gcc.c +++ b/src/lib/libcrypto/bn/asm/x86_64-gcc.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #ifdef __SUNPRO_C | 1 | #include "../bn_lcl.h" |
2 | #if !(defined(__GNUC__) && __GNUC__>=2) | ||
2 | # include "../bn_asm.c" /* kind of dirty hack for Sun Studio */ | 3 | # include "../bn_asm.c" /* kind of dirty hack for Sun Studio */ |
3 | #else | 4 | #else |
4 | /* | 5 | /* |
@@ -54,7 +55,15 @@ | |||
54 | * machine. | 55 | * machine. |
55 | */ | 56 | */ |
56 | 57 | ||
58 | #ifdef _WIN64 | ||
59 | #define BN_ULONG unsigned long long | ||
60 | #else | ||
57 | #define BN_ULONG unsigned long | 61 | #define BN_ULONG unsigned long |
62 | #endif | ||
63 | |||
64 | #undef mul | ||
65 | #undef mul_add | ||
66 | #undef sqr | ||
58 | 67 | ||
59 | /* | 68 | /* |
60 | * "m"(a), "+m"(r) is the way to favor DirectPath µ-code; | 69 | * "m"(a), "+m"(r) is the way to favor DirectPath µ-code; |
@@ -97,7 +106,7 @@ | |||
97 | : "a"(a) \ | 106 | : "a"(a) \ |
98 | : "cc"); | 107 | : "cc"); |
99 | 108 | ||
100 | BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | 109 | BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) |
101 | { | 110 | { |
102 | BN_ULONG c1=0; | 111 | BN_ULONG c1=0; |
103 | 112 | ||
@@ -121,7 +130,7 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | |||
121 | return(c1); | 130 | return(c1); |
122 | } | 131 | } |
123 | 132 | ||
124 | BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | 133 | BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) |
125 | { | 134 | { |
126 | BN_ULONG c1=0; | 135 | BN_ULONG c1=0; |
127 | 136 | ||
@@ -144,7 +153,7 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | |||
144 | return(c1); | 153 | return(c1); |
145 | } | 154 | } |
146 | 155 | ||
147 | void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n) | 156 | void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) |
148 | { | 157 | { |
149 | if (n <= 0) return; | 158 | if (n <= 0) return; |
150 | 159 | ||
@@ -175,14 +184,14 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) | |||
175 | return ret; | 184 | return ret; |
176 | } | 185 | } |
177 | 186 | ||
178 | BN_ULONG bn_add_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n) | 187 | BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n) |
179 | { BN_ULONG ret=0,i=0; | 188 | { BN_ULONG ret=0,i=0; |
180 | 189 | ||
181 | if (n <= 0) return 0; | 190 | if (n <= 0) return 0; |
182 | 191 | ||
183 | asm ( | 192 | asm ( |
184 | " subq %2,%2 \n" | 193 | " subq %2,%2 \n" |
185 | ".align 16 \n" | 194 | ".p2align 4 \n" |
186 | "1: movq (%4,%2,8),%0 \n" | 195 | "1: movq (%4,%2,8),%0 \n" |
187 | " adcq (%5,%2,8),%0 \n" | 196 | " adcq (%5,%2,8),%0 \n" |
188 | " movq %0,(%3,%2,8) \n" | 197 | " movq %0,(%3,%2,8) \n" |
@@ -198,14 +207,14 @@ BN_ULONG bn_add_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n) | |||
198 | } | 207 | } |
199 | 208 | ||
200 | #ifndef SIMICS | 209 | #ifndef SIMICS |
201 | BN_ULONG bn_sub_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n) | 210 | BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n) |
202 | { BN_ULONG ret=0,i=0; | 211 | { BN_ULONG ret=0,i=0; |
203 | 212 | ||
204 | if (n <= 0) return 0; | 213 | if (n <= 0) return 0; |
205 | 214 | ||
206 | asm ( | 215 | asm ( |
207 | " subq %2,%2 \n" | 216 | " subq %2,%2 \n" |
208 | ".align 16 \n" | 217 | ".p2align 4 \n" |
209 | "1: movq (%4,%2,8),%0 \n" | 218 | "1: movq (%4,%2,8),%0 \n" |
210 | " sbbq (%5,%2,8),%0 \n" | 219 | " sbbq (%5,%2,8),%0 \n" |
211 | " movq %0,(%3,%2,8) \n" | 220 | " movq %0,(%3,%2,8) \n" |
@@ -485,7 +494,7 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | |||
485 | r[7]=c2; | 494 | r[7]=c2; |
486 | } | 495 | } |
487 | 496 | ||
488 | void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) | 497 | void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) |
489 | { | 498 | { |
490 | BN_ULONG t1,t2; | 499 | BN_ULONG t1,t2; |
491 | BN_ULONG c1,c2,c3; | 500 | BN_ULONG c1,c2,c3; |
@@ -561,7 +570,7 @@ void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) | |||
561 | r[15]=c1; | 570 | r[15]=c1; |
562 | } | 571 | } |
563 | 572 | ||
564 | void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) | 573 | void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) |
565 | { | 574 | { |
566 | BN_ULONG t1,t2; | 575 | BN_ULONG t1,t2; |
567 | BN_ULONG c1,c2,c3; | 576 | BN_ULONG c1,c2,c3; |
diff --git a/src/lib/libcrypto/bn/asm/x86_64-mont.pl b/src/lib/libcrypto/bn/asm/x86_64-mont.pl index c43b69592a..3b7a6f243f 100755 --- a/src/lib/libcrypto/bn/asm/x86_64-mont.pl +++ b/src/lib/libcrypto/bn/asm/x86_64-mont.pl | |||
@@ -15,14 +15,18 @@ | |||
15 | # respectful 50%. It remains to be seen if loop unrolling and | 15 | # respectful 50%. It remains to be seen if loop unrolling and |
16 | # dedicated squaring routine can provide further improvement... | 16 | # dedicated squaring routine can provide further improvement... |
17 | 17 | ||
18 | $output=shift; | 18 | $flavour = shift; |
19 | $output = shift; | ||
20 | if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } | ||
21 | |||
22 | $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); | ||
19 | 23 | ||
20 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | 24 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; |
21 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | 25 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or |
22 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | 26 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or |
23 | die "can't locate x86_64-xlate.pl"; | 27 | die "can't locate x86_64-xlate.pl"; |
24 | 28 | ||
25 | open STDOUT,"| $^X $xlate $output"; | 29 | open STDOUT,"| $^X $xlate $flavour $output"; |
26 | 30 | ||
27 | # int bn_mul_mont( | 31 | # int bn_mul_mont( |
28 | $rp="%rdi"; # BN_ULONG *rp, | 32 | $rp="%rdi"; # BN_ULONG *rp, |
@@ -55,13 +59,14 @@ bn_mul_mont: | |||
55 | push %r15 | 59 | push %r15 |
56 | 60 | ||
57 | mov ${num}d,${num}d | 61 | mov ${num}d,${num}d |
58 | lea 2($num),%rax | 62 | lea 2($num),%r10 |
59 | mov %rsp,%rbp | 63 | mov %rsp,%r11 |
60 | neg %rax | 64 | neg %r10 |
61 | lea (%rsp,%rax,8),%rsp # tp=alloca(8*(num+2)) | 65 | lea (%rsp,%r10,8),%rsp # tp=alloca(8*(num+2)) |
62 | and \$-1024,%rsp # minimize TLB usage | 66 | and \$-1024,%rsp # minimize TLB usage |
63 | 67 | ||
64 | mov %rbp,8(%rsp,$num,8) # tp[num+1]=%rsp | 68 | mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp |
69 | .Lprologue: | ||
65 | mov %rdx,$bp # $bp reassigned, remember? | 70 | mov %rdx,$bp # $bp reassigned, remember? |
66 | 71 | ||
67 | mov ($n0),$n0 # pull n0[0] value | 72 | mov ($n0),$n0 # pull n0[0] value |
@@ -197,18 +202,129 @@ bn_mul_mont: | |||
197 | dec $j | 202 | dec $j |
198 | jge .Lcopy | 203 | jge .Lcopy |
199 | 204 | ||
200 | mov 8(%rsp,$num,8),%rsp # restore %rsp | 205 | mov 8(%rsp,$num,8),%rsi # restore %rsp |
201 | mov \$1,%rax | 206 | mov \$1,%rax |
207 | mov (%rsi),%r15 | ||
208 | mov 8(%rsi),%r14 | ||
209 | mov 16(%rsi),%r13 | ||
210 | mov 24(%rsi),%r12 | ||
211 | mov 32(%rsi),%rbp | ||
212 | mov 40(%rsi),%rbx | ||
213 | lea 48(%rsi),%rsp | ||
214 | .Lepilogue: | ||
215 | ret | ||
216 | .size bn_mul_mont,.-bn_mul_mont | ||
217 | .asciz "Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>" | ||
218 | .align 16 | ||
219 | ___ | ||
220 | |||
221 | # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, | ||
222 | # CONTEXT *context,DISPATCHER_CONTEXT *disp) | ||
223 | if ($win64) { | ||
224 | $rec="%rcx"; | ||
225 | $frame="%rdx"; | ||
226 | $context="%r8"; | ||
227 | $disp="%r9"; | ||
228 | |||
229 | $code.=<<___; | ||
230 | .extern __imp_RtlVirtualUnwind | ||
231 | .type se_handler,\@abi-omnipotent | ||
232 | .align 16 | ||
233 | se_handler: | ||
234 | push %rsi | ||
235 | push %rdi | ||
236 | push %rbx | ||
237 | push %rbp | ||
238 | push %r12 | ||
239 | push %r13 | ||
240 | push %r14 | ||
241 | push %r15 | ||
242 | pushfq | ||
243 | sub \$64,%rsp | ||
244 | |||
245 | mov 120($context),%rax # pull context->Rax | ||
246 | mov 248($context),%rbx # pull context->Rip | ||
247 | |||
248 | lea .Lprologue(%rip),%r10 | ||
249 | cmp %r10,%rbx # context->Rip<.Lprologue | ||
250 | jb .Lin_prologue | ||
251 | |||
252 | mov 152($context),%rax # pull context->Rsp | ||
253 | |||
254 | lea .Lepilogue(%rip),%r10 | ||
255 | cmp %r10,%rbx # context->Rip>=.Lepilogue | ||
256 | jae .Lin_prologue | ||
257 | |||
258 | mov 192($context),%r10 # pull $num | ||
259 | mov 8(%rax,%r10,8),%rax # pull saved stack pointer | ||
260 | lea 48(%rax),%rax | ||
261 | |||
262 | mov -8(%rax),%rbx | ||
263 | mov -16(%rax),%rbp | ||
264 | mov -24(%rax),%r12 | ||
265 | mov -32(%rax),%r13 | ||
266 | mov -40(%rax),%r14 | ||
267 | mov -48(%rax),%r15 | ||
268 | mov %rbx,144($context) # restore context->Rbx | ||
269 | mov %rbp,160($context) # restore context->Rbp | ||
270 | mov %r12,216($context) # restore context->R12 | ||
271 | mov %r13,224($context) # restore context->R13 | ||
272 | mov %r14,232($context) # restore context->R14 | ||
273 | mov %r15,240($context) # restore context->R15 | ||
274 | |||
275 | .Lin_prologue: | ||
276 | mov 8(%rax),%rdi | ||
277 | mov 16(%rax),%rsi | ||
278 | mov %rax,152($context) # restore context->Rsp | ||
279 | mov %rsi,168($context) # restore context->Rsi | ||
280 | mov %rdi,176($context) # restore context->Rdi | ||
281 | |||
282 | mov 40($disp),%rdi # disp->ContextRecord | ||
283 | mov $context,%rsi # context | ||
284 | mov \$154,%ecx # sizeof(CONTEXT) | ||
285 | .long 0xa548f3fc # cld; rep movsq | ||
286 | |||
287 | mov $disp,%rsi | ||
288 | xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER | ||
289 | mov 8(%rsi),%rdx # arg2, disp->ImageBase | ||
290 | mov 0(%rsi),%r8 # arg3, disp->ControlPc | ||
291 | mov 16(%rsi),%r9 # arg4, disp->FunctionEntry | ||
292 | mov 40(%rsi),%r10 # disp->ContextRecord | ||
293 | lea 56(%rsi),%r11 # &disp->HandlerData | ||
294 | lea 24(%rsi),%r12 # &disp->EstablisherFrame | ||
295 | mov %r10,32(%rsp) # arg5 | ||
296 | mov %r11,40(%rsp) # arg6 | ||
297 | mov %r12,48(%rsp) # arg7 | ||
298 | mov %rcx,56(%rsp) # arg8, (NULL) | ||
299 | call *__imp_RtlVirtualUnwind(%rip) | ||
300 | |||
301 | mov \$1,%eax # ExceptionContinueSearch | ||
302 | add \$64,%rsp | ||
303 | popfq | ||
202 | pop %r15 | 304 | pop %r15 |
203 | pop %r14 | 305 | pop %r14 |
204 | pop %r13 | 306 | pop %r13 |
205 | pop %r12 | 307 | pop %r12 |
206 | pop %rbp | 308 | pop %rbp |
207 | pop %rbx | 309 | pop %rbx |
310 | pop %rdi | ||
311 | pop %rsi | ||
208 | ret | 312 | ret |
209 | .size bn_mul_mont,.-bn_mul_mont | 313 | .size se_handler,.-se_handler |
210 | .asciz "Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>" | 314 | |
315 | .section .pdata | ||
316 | .align 4 | ||
317 | .rva .LSEH_begin_bn_mul_mont | ||
318 | .rva .LSEH_end_bn_mul_mont | ||
319 | .rva .LSEH_info_bn_mul_mont | ||
320 | |||
321 | .section .xdata | ||
322 | .align 8 | ||
323 | .LSEH_info_bn_mul_mont: | ||
324 | .byte 9,0,0,0 | ||
325 | .rva se_handler | ||
211 | ___ | 326 | ___ |
327 | } | ||
212 | 328 | ||
213 | print $code; | 329 | print $code; |
214 | close STDOUT; | 330 | close STDOUT; |
diff --git a/src/lib/libcrypto/camellia/asm/cmll-x86.pl b/src/lib/libcrypto/camellia/asm/cmll-x86.pl index 0812815bfb..027302ac86 100644 --- a/src/lib/libcrypto/camellia/asm/cmll-x86.pl +++ b/src/lib/libcrypto/camellia/asm/cmll-x86.pl | |||
@@ -1133,6 +1133,6 @@ my ($s0,$s1,$s2,$s3) = @T; | |||
1133 | &function_end("Camellia_cbc_encrypt"); | 1133 | &function_end("Camellia_cbc_encrypt"); |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | &asciz("Camellia for x86 by <appro@openssl.org>"); | 1136 | &asciz("Camellia for x86 by <appro\@openssl.org>"); |
1137 | 1137 | ||
1138 | &asm_finish(); | 1138 | &asm_finish(); |
diff --git a/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl b/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl index c683646ca7..76955e4726 100644 --- a/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl +++ b/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl | |||
@@ -656,7 +656,7 @@ Camellia_cbc_encrypt: | |||
656 | mov %rsi,$out # out argument | 656 | mov %rsi,$out # out argument |
657 | mov %r8,%rbx # ivp argument | 657 | mov %r8,%rbx # ivp argument |
658 | mov %rcx,$key # key argument | 658 | mov %rcx,$key # key argument |
659 | mov 272(%rcx),$keyend # grandRounds | 659 | mov 272(%rcx),${keyend}d # grandRounds |
660 | 660 | ||
661 | mov %r8,$_ivp | 661 | mov %r8,$_ivp |
662 | mov %rbp,$_rsp | 662 | mov %rbp,$_rsp |
@@ -859,7 +859,7 @@ Camellia_cbc_encrypt: | |||
859 | ret | 859 | ret |
860 | .size Camellia_cbc_encrypt,.-Camellia_cbc_encrypt | 860 | .size Camellia_cbc_encrypt,.-Camellia_cbc_encrypt |
861 | 861 | ||
862 | .asciz "Camellia for x86_64 by <appro@openssl.org>" | 862 | .asciz "Camellia for x86_64 by <appro\@openssl.org>" |
863 | ___ | 863 | ___ |
864 | } | 864 | } |
865 | 865 | ||
diff --git a/src/lib/libcrypto/camellia/camellia.c b/src/lib/libcrypto/camellia/camellia.c index 491c26b39e..75fc8991c0 100644 --- a/src/lib/libcrypto/camellia/camellia.c +++ b/src/lib/libcrypto/camellia/camellia.c | |||
@@ -68,1557 +68,515 @@ | |||
68 | /* Algorithm Specification | 68 | /* Algorithm Specification |
69 | http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html | 69 | http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html |
70 | */ | 70 | */ |
71 | 71 | ||
72 | 72 | /* | |
73 | #include <string.h> | 73 | * This release balances code size and performance. In particular key |
74 | #include <stdlib.h> | 74 | * schedule setup is fully unrolled, because doing so *significantly* |
75 | * reduces amount of instructions per setup round and code increase is | ||
76 | * justifiable. In block functions on the other hand only inner loops | ||
77 | * are unrolled, as full unroll gives only nominal performance boost, | ||
78 | * while code size grows 4 or 7 times. Also, unlike previous versions | ||
79 | * this one "encourages" compiler to keep intermediate variables in | ||
80 | * registers, which should give better "all round" results, in other | ||
81 | * words reasonable performance even with not so modern compilers. | ||
82 | */ | ||
75 | 83 | ||
76 | #include "camellia.h" | 84 | #include "camellia.h" |
77 | #include "cmll_locl.h" | 85 | #include "cmll_locl.h" |
86 | #include <string.h> | ||
87 | #include <stdlib.h> | ||
78 | 88 | ||
79 | /* key constants */ | 89 | /* 32-bit rotations */ |
80 | #define CAMELLIA_SIGMA1L (0xA09E667FL) | 90 | #if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) |
81 | #define CAMELLIA_SIGMA1R (0x3BCC908BL) | 91 | # if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) |
82 | #define CAMELLIA_SIGMA2L (0xB67AE858L) | 92 | # define RightRotate(x, s) _lrotr(x, s) |
83 | #define CAMELLIA_SIGMA2R (0x4CAA73B2L) | 93 | # define LeftRotate(x, s) _lrotl(x, s) |
84 | #define CAMELLIA_SIGMA3L (0xC6EF372FL) | 94 | # if _MSC_VER >= 1400 |
85 | #define CAMELLIA_SIGMA3R (0xE94F82BEL) | 95 | # define SWAP(x) _byteswap_ulong(x) |
86 | #define CAMELLIA_SIGMA4L (0x54FF53A5L) | 96 | # else |
87 | #define CAMELLIA_SIGMA4R (0xF1D36F1CL) | 97 | # define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) |
88 | #define CAMELLIA_SIGMA5L (0x10E527FAL) | 98 | # endif |
89 | #define CAMELLIA_SIGMA5R (0xDE682D1DL) | 99 | # define GETU32(p) SWAP(*((u32 *)(p))) |
90 | #define CAMELLIA_SIGMA6L (0xB05688C2L) | 100 | # define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v))) |
91 | #define CAMELLIA_SIGMA6R (0xB3E6C1FDL) | 101 | # elif defined(__GNUC__) && __GNUC__>=2 |
92 | 102 | # if defined(__i386) || defined(__x86_64) | |
103 | # define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) | ||
104 | # define LeftRotate(x,s) ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) | ||
105 | # if defined(B_ENDIAN) /* stratus.com does it */ | ||
106 | # define GETU32(p) (*(u32 *)(p)) | ||
107 | # define PUTU32(p,v) (*(u32 *)(p)=(v)) | ||
108 | # else | ||
109 | # define GETU32(p) ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; }) | ||
110 | # define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; }) | ||
111 | # endif | ||
112 | # elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ | ||
113 | defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) | ||
114 | # define LeftRotate(x,s) ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; }) | ||
115 | # define RightRotate(x,s) LeftRotate(x,(32-s)) | ||
116 | # elif defined(__s390x__) | ||
117 | # define LeftRotate(x,s) ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; }) | ||
118 | # define RightRotate(x,s) LeftRotate(x,(32-s)) | ||
119 | # define GETU32(p) (*(u32 *)(p)) | ||
120 | # define PUTU32(p,v) (*(u32 *)(p)=(v)) | ||
121 | # endif | ||
122 | # endif | ||
123 | #endif | ||
124 | |||
125 | #if !defined(RightRotate) && !defined(LeftRotate) | ||
126 | # define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) ) | ||
127 | # define LeftRotate(x, s) ( ((x) << (s)) + ((x) >> (32 - s)) ) | ||
128 | #endif | ||
129 | |||
130 | #if !defined(GETU32) && !defined(PUTU32) | ||
131 | # define GETU32(p) (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] << 8) ^ ((u32)(p)[3])) | ||
132 | # define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >> 8), (p)[3] = (u8)(v)) | ||
133 | #endif | ||
134 | |||
135 | /* S-box data */ | ||
136 | #define SBOX1_1110 Camellia_SBOX[0] | ||
137 | #define SBOX4_4404 Camellia_SBOX[1] | ||
138 | #define SBOX2_0222 Camellia_SBOX[2] | ||
139 | #define SBOX3_3033 Camellia_SBOX[3] | ||
140 | static const u32 Camellia_SBOX[][256] = { | ||
141 | { 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, | ||
142 | 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, | ||
143 | 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, | ||
144 | 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, | ||
145 | 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, | ||
146 | 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, | ||
147 | 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, | ||
148 | 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, | ||
149 | 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, | ||
150 | 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, | ||
151 | 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, | ||
152 | 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, | ||
153 | 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, | ||
154 | 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, | ||
155 | 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, | ||
156 | 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, | ||
157 | 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, | ||
158 | 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, | ||
159 | 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, | ||
160 | 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, | ||
161 | 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, | ||
162 | 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, | ||
163 | 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, | ||
164 | 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, | ||
165 | 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, | ||
166 | 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, | ||
167 | 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, | ||
168 | 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, | ||
169 | 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, | ||
170 | 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, | ||
171 | 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, | ||
172 | 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, | ||
173 | 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, | ||
174 | 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, | ||
175 | 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, | ||
176 | 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, | ||
177 | 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, | ||
178 | 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, | ||
179 | 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, | ||
180 | 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, | ||
181 | 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, | ||
182 | 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, | ||
183 | 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 }, | ||
184 | { 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, | ||
185 | 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, | ||
186 | 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, | ||
187 | 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, | ||
188 | 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, | ||
189 | 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, | ||
190 | 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, | ||
191 | 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, | ||
192 | 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, | ||
193 | 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, | ||
194 | 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, | ||
195 | 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, | ||
196 | 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, | ||
197 | 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, | ||
198 | 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, | ||
199 | 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, | ||
200 | 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, | ||
201 | 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, | ||
202 | 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, | ||
203 | 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, | ||
204 | 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, | ||
205 | 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, | ||
206 | 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, | ||
207 | 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, | ||
208 | 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, | ||
209 | 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, | ||
210 | 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, | ||
211 | 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, | ||
212 | 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, | ||
213 | 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, | ||
214 | 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, | ||
215 | 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, | ||
216 | 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, | ||
217 | 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, | ||
218 | 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, | ||
219 | 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, | ||
220 | 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, | ||
221 | 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, | ||
222 | 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, | ||
223 | 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, | ||
224 | 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, | ||
225 | 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, | ||
226 | 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e }, | ||
227 | { 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, | ||
228 | 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, | ||
229 | 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, | ||
230 | 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, | ||
231 | 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, | ||
232 | 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, | ||
233 | 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, | ||
234 | 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, | ||
235 | 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, | ||
236 | 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, | ||
237 | 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, | ||
238 | 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, | ||
239 | 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, | ||
240 | 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, | ||
241 | 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, | ||
242 | 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, | ||
243 | 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, | ||
244 | 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, | ||
245 | 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, | ||
246 | 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, | ||
247 | 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, | ||
248 | 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, | ||
249 | 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, | ||
250 | 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, | ||
251 | 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, | ||
252 | 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, | ||
253 | 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, | ||
254 | 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, | ||
255 | 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, | ||
256 | 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, | ||
257 | 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, | ||
258 | 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, | ||
259 | 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, | ||
260 | 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, | ||
261 | 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, | ||
262 | 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, | ||
263 | 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, | ||
264 | 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, | ||
265 | 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, | ||
266 | 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, | ||
267 | 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, | ||
268 | 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, | ||
269 | 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d }, | ||
270 | { 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, | ||
271 | 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, | ||
272 | 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, | ||
273 | 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, | ||
274 | 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, | ||
275 | 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, | ||
276 | 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, | ||
277 | 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, | ||
278 | 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, | ||
279 | 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, | ||
280 | 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, | ||
281 | 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, | ||
282 | 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, | ||
283 | 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, | ||
284 | 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, | ||
285 | 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, | ||
286 | 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, | ||
287 | 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, | ||
288 | 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, | ||
289 | 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, | ||
290 | 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, | ||
291 | 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, | ||
292 | 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, | ||
293 | 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, | ||
294 | 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, | ||
295 | 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, | ||
296 | 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, | ||
297 | 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, | ||
298 | 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, | ||
299 | 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, | ||
300 | 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, | ||
301 | 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, | ||
302 | 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, | ||
303 | 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, | ||
304 | 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, | ||
305 | 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, | ||
306 | 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, | ||
307 | 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, | ||
308 | 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, | ||
309 | 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, | ||
310 | 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, | ||
311 | 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, | ||
312 | 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f } | ||
313 | }; | ||
314 | |||
315 | /* Key generation constants */ | ||
316 | static const u32 SIGMA[] = { | ||
317 | 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, | ||
318 | 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd | ||
319 | }; | ||
320 | |||
321 | /* The phi algorithm given in C.2.7 of the Camellia spec document. */ | ||
93 | /* | 322 | /* |
94 | * macros | 323 | * This version does not attempt to minimize amount of temporary |
324 | * variables, but instead explicitly exposes algorithm's parallelism. | ||
325 | * It is therefore most appropriate for platforms with not less than | ||
326 | * ~16 registers. For platforms with less registers [well, x86 to be | ||
327 | * specific] assembler version should be/is provided anyway... | ||
95 | */ | 328 | */ |
96 | 329 | #define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\ | |
97 | /* e is pointer of subkey */ | 330 | register u32 _t0,_t1,_t2,_t3;\ |
98 | #define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2]) | 331 | \ |
99 | #define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1]) | 332 | _t0 = _s0 ^ (_key)[0];\ |
100 | 333 | _t3 = SBOX4_4404[_t0&0xff];\ | |
101 | /* rotation right shift 1byte */ | 334 | _t1 = _s1 ^ (_key)[1];\ |
102 | #define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) | 335 | _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\ |
103 | /* rotation left shift 1bit */ | 336 | _t2 = SBOX1_1110[_t1&0xff];\ |
104 | #define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) | 337 | _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\ |
105 | /* rotation left shift 1byte */ | 338 | _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\ |
106 | #define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24)) | 339 | _t3 ^= SBOX1_1110[(_t0 >> 24)];\ |
107 | 340 | _t2 ^= _t3;\ | |
108 | #define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ | 341 | _t3 = RightRotate(_t3,8);\ |
109 | do \ | 342 | _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\ |
110 | { \ | 343 | _s3 ^= _t3;\ |
111 | w0 = ll; \ | 344 | _t2 ^= SBOX2_0222[(_t1 >> 24)];\ |
112 | ll = (ll << bits) + (lr >> (32 - bits)); \ | 345 | _s2 ^= _t2; \ |
113 | lr = (lr << bits) + (rl >> (32 - bits)); \ | 346 | _s3 ^= _t2;\ |
114 | rl = (rl << bits) + (rr >> (32 - bits)); \ | 347 | } while(0) |
115 | rr = (rr << bits) + (w0 >> (32 - bits)); \ | ||
116 | } while(0) | ||
117 | |||
118 | #define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \ | ||
119 | do \ | ||
120 | { \ | ||
121 | w0 = ll; \ | ||
122 | w1 = lr; \ | ||
123 | ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \ | ||
124 | lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \ | ||
125 | rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \ | ||
126 | rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \ | ||
127 | } while(0) | ||
128 | |||
129 | #define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)]) | ||
130 | #define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)]) | ||
131 | #define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)]) | ||
132 | #define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)]) | ||
133 | |||
134 | #define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ | ||
135 | do \ | ||
136 | { \ | ||
137 | il = xl ^ kl; \ | ||
138 | ir = xr ^ kr; \ | ||
139 | t0 = il >> 16; \ | ||
140 | t1 = ir >> 16; \ | ||
141 | yl = CAMELLIA_SP1110(ir & 0xff) \ | ||
142 | ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ | ||
143 | ^ CAMELLIA_SP3033(t1 & 0xff) \ | ||
144 | ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ | ||
145 | yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ | ||
146 | ^ CAMELLIA_SP0222(t0 & 0xff) \ | ||
147 | ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ | ||
148 | ^ CAMELLIA_SP4404(il & 0xff); \ | ||
149 | yl ^= yr; \ | ||
150 | yr = CAMELLIA_RR8(yr); \ | ||
151 | yr ^= yl; \ | ||
152 | } while(0) | ||
153 | |||
154 | 348 | ||
155 | /* | 349 | /* |
156 | * for speed up | 350 | * Note that n has to be less than 32. Rotations for larger amount |
157 | * | 351 | * of bits are achieved by "rotating" order of s-elements and |
352 | * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32). | ||
158 | */ | 353 | */ |
159 | #define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \ | 354 | #define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\ |
160 | do \ | 355 | u32 _t0=_s0>>(32-_n);\ |
161 | { \ | 356 | _s0 = (_s0<<_n) | (_s1>>(32-_n));\ |
162 | t0 = kll; \ | 357 | _s1 = (_s1<<_n) | (_s2>>(32-_n));\ |
163 | t0 &= ll; \ | 358 | _s2 = (_s2<<_n) | (_s3>>(32-_n));\ |
164 | lr ^= CAMELLIA_RL1(t0); \ | 359 | _s3 = (_s3<<_n) | _t0;\ |
165 | t1 = klr; \ | 360 | } while (0) |
166 | t1 |= lr; \ | 361 | |
167 | ll ^= t1; \ | 362 | int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k) |
168 | \ | ||
169 | t2 = krr; \ | ||
170 | t2 |= rr; \ | ||
171 | rl ^= t2; \ | ||
172 | t3 = krl; \ | ||
173 | t3 &= rl; \ | ||
174 | rr ^= CAMELLIA_RL1(t3); \ | ||
175 | } while(0) | ||
176 | |||
177 | #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ | ||
178 | do \ | ||
179 | { \ | ||
180 | il = xl; \ | ||
181 | ir = xr; \ | ||
182 | t0 = il >> 16; \ | ||
183 | t1 = ir >> 16; \ | ||
184 | ir = CAMELLIA_SP1110(ir & 0xff) \ | ||
185 | ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ | ||
186 | ^ CAMELLIA_SP3033(t1 & 0xff) \ | ||
187 | ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ | ||
188 | il = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ | ||
189 | ^ CAMELLIA_SP0222(t0 & 0xff) \ | ||
190 | ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ | ||
191 | ^ CAMELLIA_SP4404(il & 0xff); \ | ||
192 | il ^= kl; \ | ||
193 | ir ^= kr; \ | ||
194 | ir ^= il; \ | ||
195 | il = CAMELLIA_RR8(il); \ | ||
196 | il ^= ir; \ | ||
197 | yl ^= ir; \ | ||
198 | yr ^= il; \ | ||
199 | } while(0) | ||
200 | |||
201 | static const u32 camellia_sp1110[256] = | ||
202 | { | ||
203 | 0x70707000,0x82828200,0x2c2c2c00,0xececec00, | ||
204 | 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500, | ||
205 | 0xe4e4e400,0x85858500,0x57575700,0x35353500, | ||
206 | 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100, | ||
207 | 0x23232300,0xefefef00,0x6b6b6b00,0x93939300, | ||
208 | 0x45454500,0x19191900,0xa5a5a500,0x21212100, | ||
209 | 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00, | ||
210 | 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00, | ||
211 | 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00, | ||
212 | 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00, | ||
213 | 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00, | ||
214 | 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00, | ||
215 | 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00, | ||
216 | 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00, | ||
217 | 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600, | ||
218 | 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00, | ||
219 | 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600, | ||
220 | 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00, | ||
221 | 0x74747400,0x12121200,0x2b2b2b00,0x20202000, | ||
222 | 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900, | ||
223 | 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200, | ||
224 | 0x34343400,0x7e7e7e00,0x76767600,0x05050500, | ||
225 | 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100, | ||
226 | 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700, | ||
227 | 0x14141400,0x58585800,0x3a3a3a00,0x61616100, | ||
228 | 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00, | ||
229 | 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600, | ||
230 | 0x53535300,0x18181800,0xf2f2f200,0x22222200, | ||
231 | 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200, | ||
232 | 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100, | ||
233 | 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800, | ||
234 | 0x60606000,0xfcfcfc00,0x69696900,0x50505000, | ||
235 | 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00, | ||
236 | 0xa1a1a100,0x89898900,0x62626200,0x97979700, | ||
237 | 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500, | ||
238 | 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200, | ||
239 | 0x10101000,0xc4c4c400,0x00000000,0x48484800, | ||
240 | 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00, | ||
241 | 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00, | ||
242 | 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400, | ||
243 | 0x87878700,0x5c5c5c00,0x83838300,0x02020200, | ||
244 | 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300, | ||
245 | 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300, | ||
246 | 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200, | ||
247 | 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600, | ||
248 | 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00, | ||
249 | 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00, | ||
250 | 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00, | ||
251 | 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00, | ||
252 | 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00, | ||
253 | 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600, | ||
254 | 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900, | ||
255 | 0x78787800,0x98989800,0x06060600,0x6a6a6a00, | ||
256 | 0xe7e7e700,0x46464600,0x71717100,0xbababa00, | ||
257 | 0xd4d4d400,0x25252500,0xababab00,0x42424200, | ||
258 | 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00, | ||
259 | 0x72727200,0x07070700,0xb9b9b900,0x55555500, | ||
260 | 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00, | ||
261 | 0x36363600,0x49494900,0x2a2a2a00,0x68686800, | ||
262 | 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400, | ||
263 | 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00, | ||
264 | 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100, | ||
265 | 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400, | ||
266 | 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00, | ||
267 | }; | ||
268 | |||
269 | static const u32 camellia_sp0222[256] = | ||
270 | { | 363 | { |
271 | 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9, | 364 | register u32 s0,s1,s2,s3; |
272 | 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb, | 365 | |
273 | 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a, | 366 | k[0] = s0 = GETU32(rawKey); |
274 | 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282, | 367 | k[1] = s1 = GETU32(rawKey+4); |
275 | 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727, | 368 | k[2] = s2 = GETU32(rawKey+8); |
276 | 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242, | 369 | k[3] = s3 = GETU32(rawKey+12); |
277 | 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c, | 370 | |
278 | 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b, | 371 | if (keyBitLength != 128) |
279 | 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f, | 372 | { |
280 | 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d, | 373 | k[8] = s0 = GETU32(rawKey+16); |
281 | 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe, | 374 | k[9] = s1 = GETU32(rawKey+20); |
282 | 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434, | 375 | if (keyBitLength == 192) |
283 | 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595, | 376 | { |
284 | 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a, | 377 | k[10] = s2 = ~s0; |
285 | 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad, | 378 | k[11] = s3 = ~s1; |
286 | 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a, | 379 | } |
287 | 0x00171717,0x001a1a1a,0x00353535,0x00cccccc, | 380 | else |
288 | 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a, | 381 | { |
289 | 0x00e8e8e8,0x00242424,0x00565656,0x00404040, | 382 | k[10] = s2 = GETU32(rawKey+24); |
290 | 0x00e1e1e1,0x00636363,0x00090909,0x00333333, | 383 | k[11] = s3 = GETU32(rawKey+28); |
291 | 0x00bfbfbf,0x00989898,0x00979797,0x00858585, | 384 | } |
292 | 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a, | 385 | s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; |
293 | 0x00dadada,0x006f6f6f,0x00535353,0x00626262, | 386 | } |
294 | 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf, | 387 | |
295 | 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2, | 388 | /* Use the Feistel routine to scramble the key material */ |
296 | 0x00bdbdbd,0x00363636,0x00222222,0x00383838, | 389 | Camellia_Feistel(s0,s1,s2,s3,SIGMA+0); |
297 | 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c, | 390 | Camellia_Feistel(s2,s3,s0,s1,SIGMA+2); |
298 | 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444, | 391 | |
299 | 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565, | 392 | s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; |
300 | 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323, | 393 | Camellia_Feistel(s0,s1,s2,s3,SIGMA+4); |
301 | 0x00484848,0x00101010,0x00d1d1d1,0x00515151, | 394 | Camellia_Feistel(s2,s3,s0,s1,SIGMA+6); |
302 | 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0, | 395 | |
303 | 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa, | 396 | /* Fill the keyTable. Requires many block rotations. */ |
304 | 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f, | 397 | if (keyBitLength == 128) |
305 | 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b, | 398 | { |
306 | 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5, | 399 | k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3; |
307 | 0x00202020,0x00898989,0x00000000,0x00909090, | 400 | RotLeft128(s0,s1,s2,s3,15); /* KA <<< 15 */ |
308 | 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7, | 401 | k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; |
309 | 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5, | 402 | RotLeft128(s0,s1,s2,s3,15); /* KA <<< 30 */ |
310 | 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929, | 403 | k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; |
311 | 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404, | 404 | RotLeft128(s0,s1,s2,s3,15); /* KA <<< 45 */ |
312 | 0x009b9b9b,0x00949494,0x00212121,0x00666666, | 405 | k[24] = s0, k[25] = s1; |
313 | 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7, | 406 | RotLeft128(s0,s1,s2,s3,15); /* KA <<< 60 */ |
314 | 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5, | 407 | k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; |
315 | 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c, | 408 | RotLeft128(s1,s2,s3,s0,2); /* KA <<< 94 */ |
316 | 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676, | 409 | k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0; |
317 | 0x00030303,0x002d2d2d,0x00dedede,0x00969696, | 410 | RotLeft128(s1,s2,s3,s0,17); /* KA <<<111 */ |
318 | 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c, | 411 | k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; |
319 | 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919, | 412 | |
320 | 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d, | 413 | s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3]; |
321 | 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d, | 414 | RotLeft128(s0,s1,s2,s3,15); /* KL <<< 15 */ |
322 | 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2, | 415 | k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3; |
323 | 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4, | 416 | RotLeft128(s0,s1,s2,s3,30); /* KL <<< 45 */ |
324 | 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575, | 417 | k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; |
325 | 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484, | 418 | RotLeft128(s0,s1,s2,s3,15); /* KL <<< 60 */ |
326 | 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5, | 419 | k[26] = s2, k[27] = s3; |
327 | 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa, | 420 | RotLeft128(s0,s1,s2,s3,17); /* KL <<< 77 */ |
328 | 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414, | 421 | k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3; |
329 | 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0, | 422 | RotLeft128(s0,s1,s2,s3,17); /* KL <<< 94 */ |
330 | 0x00787878,0x00707070,0x00e3e3e3,0x00494949, | 423 | k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; |
331 | 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6, | 424 | RotLeft128(s0,s1,s2,s3,17); /* KL <<<111 */ |
332 | 0x00777777,0x00939393,0x00868686,0x00838383, | 425 | k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3; |
333 | 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9, | 426 | |
334 | 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d, | 427 | return 3; /* grand rounds */ |
335 | }; | 428 | } |
336 | 429 | else | |
337 | static const u32 camellia_sp3033[256] = | 430 | { |
338 | { | 431 | k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; |
339 | 0x38003838,0x41004141,0x16001616,0x76007676, | 432 | s0 ^= k[8], s1 ^= k[9], s2 ^=k[10], s3 ^=k[11]; |
340 | 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2, | 433 | Camellia_Feistel(s0,s1,s2,s3,(SIGMA+8)); |
341 | 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a, | 434 | Camellia_Feistel(s2,s3,s0,s1,(SIGMA+10)); |
342 | 0x75007575,0x06000606,0x57005757,0xa000a0a0, | 435 | |
343 | 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9, | 436 | k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3; |
344 | 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090, | 437 | RotLeft128(s0,s1,s2,s3,30); /* KB <<< 30 */ |
345 | 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727, | 438 | k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; |
346 | 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede, | 439 | RotLeft128(s0,s1,s2,s3,30); /* KB <<< 60 */ |
347 | 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7, | 440 | k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3; |
348 | 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767, | 441 | RotLeft128(s1,s2,s3,s0,19); /* KB <<<111 */ |
349 | 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf, | 442 | k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0; |
350 | 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d, | 443 | |
351 | 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565, | 444 | s0 = k[ 8], s1 = k[ 9], s2 = k[10], s3 = k[11]; |
352 | 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e, | 445 | RotLeft128(s0,s1,s2,s3,15); /* KR <<< 15 */ |
353 | 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b, | 446 | k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3; |
354 | 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6, | 447 | RotLeft128(s0,s1,s2,s3,15); /* KR <<< 30 */ |
355 | 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333, | 448 | k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; |
356 | 0xfd00fdfd,0x66006666,0x58005858,0x96009696, | 449 | RotLeft128(s0,s1,s2,s3,30); /* KR <<< 60 */ |
357 | 0x3a003a3a,0x09000909,0x95009595,0x10001010, | 450 | k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; |
358 | 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc, | 451 | RotLeft128(s1,s2,s3,s0,2); /* KR <<< 94 */ |
359 | 0xef00efef,0x26002626,0xe500e5e5,0x61006161, | 452 | k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0; |
360 | 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282, | 453 | |
361 | 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898, | 454 | s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15]; |
362 | 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb, | 455 | RotLeft128(s0,s1,s2,s3,15); /* KA <<< 15 */ |
363 | 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0, | 456 | k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; |
364 | 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e, | 457 | RotLeft128(s0,s1,s2,s3,30); /* KA <<< 45 */ |
365 | 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b, | 458 | k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; |
366 | 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111, | 459 | /* KA <<< 77 */ |
367 | 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959, | 460 | k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; |
368 | 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8, | 461 | RotLeft128(s1,s2,s3,s0,17); /* KA <<< 94 */ |
369 | 0x12001212,0x04000404,0x74007474,0x54005454, | 462 | k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0; |
370 | 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828, | 463 | |
371 | 0x55005555,0x68006868,0x50005050,0xbe00bebe, | 464 | s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3]; |
372 | 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb, | 465 | RotLeft128(s1,s2,s3,s0,13); /* KL <<< 45 */ |
373 | 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca, | 466 | k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0; |
374 | 0x70007070,0xff00ffff,0x32003232,0x69006969, | 467 | RotLeft128(s1,s2,s3,s0,15); /* KL <<< 60 */ |
375 | 0x08000808,0x62006262,0x00000000,0x24002424, | 468 | k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0; |
376 | 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded, | 469 | RotLeft128(s1,s2,s3,s0,17); /* KL <<< 77 */ |
377 | 0x45004545,0x81008181,0x73007373,0x6d006d6d, | 470 | k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0; |
378 | 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a, | 471 | RotLeft128(s2,s3,s0,s1,2); /* KL <<<111 */ |
379 | 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101, | 472 | k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1; |
380 | 0xe600e6e6,0x25002525,0x48004848,0x99009999, | 473 | |
381 | 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9, | 474 | return 4; /* grand rounds */ |
382 | 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171, | 475 | } |
383 | 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313, | 476 | /* |
384 | 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d, | 477 | * It is possible to perform certain precalculations, which |
385 | 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5, | 478 | * would spare few cycles in block procedure. It's not done, |
386 | 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717, | 479 | * because it upsets the performance balance between key |
387 | 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646, | 480 | * setup and block procedures, negatively affecting overall |
388 | 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747, | 481 | * throughput in applications operating on short messages |
389 | 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b, | 482 | * and volatile keys. |
390 | 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac, | 483 | */ |
391 | 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535, | ||
392 | 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d, | ||
393 | 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121, | ||
394 | 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d, | ||
395 | 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa, | ||
396 | 0x7c007c7c,0x77007777,0x56005656,0x05000505, | ||
397 | 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434, | ||
398 | 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252, | ||
399 | 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd, | ||
400 | 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0, | ||
401 | 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a, | ||
402 | 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f, | ||
403 | }; | ||
404 | |||
405 | static const u32 camellia_sp4404[256] = | ||
406 | { | ||
407 | 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0, | ||
408 | 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae, | ||
409 | 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5, | ||
410 | 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092, | ||
411 | 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f, | ||
412 | 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b, | ||
413 | 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d, | ||
414 | 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c, | ||
415 | 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0, | ||
416 | 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084, | ||
417 | 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076, | ||
418 | 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004, | ||
419 | 0x14140014,0x3a3a003a,0xdede00de,0x11110011, | ||
420 | 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2, | ||
421 | 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a, | ||
422 | 0x24240024,0xe8e800e8,0x60600060,0x69690069, | ||
423 | 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062, | ||
424 | 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064, | ||
425 | 0x10100010,0x00000000,0xa3a300a3,0x75750075, | ||
426 | 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd, | ||
427 | 0x87870087,0x83830083,0xcdcd00cd,0x90900090, | ||
428 | 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf, | ||
429 | 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6, | ||
430 | 0x81810081,0x6f6f006f,0x13130013,0x63630063, | ||
431 | 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc, | ||
432 | 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4, | ||
433 | 0x78780078,0x06060006,0xe7e700e7,0x71710071, | ||
434 | 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d, | ||
435 | 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac, | ||
436 | 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1, | ||
437 | 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043, | ||
438 | 0x15150015,0xadad00ad,0x77770077,0x80800080, | ||
439 | 0x82820082,0xecec00ec,0x27270027,0xe5e500e5, | ||
440 | 0x85850085,0x35350035,0x0c0c000c,0x41410041, | ||
441 | 0xefef00ef,0x93930093,0x19190019,0x21210021, | ||
442 | 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd, | ||
443 | 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce, | ||
444 | 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a, | ||
445 | 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d, | ||
446 | 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d, | ||
447 | 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d, | ||
448 | 0x12120012,0x20200020,0xb1b100b1,0x99990099, | ||
449 | 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005, | ||
450 | 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7, | ||
451 | 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c, | ||
452 | 0x0f0f000f,0x16160016,0x18180018,0x22220022, | ||
453 | 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091, | ||
454 | 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050, | ||
455 | 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097, | ||
456 | 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2, | ||
457 | 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db, | ||
458 | 0x03030003,0xdada00da,0x3f3f003f,0x94940094, | ||
459 | 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033, | ||
460 | 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2, | ||
461 | 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b, | ||
462 | 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e, | ||
463 | 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e, | ||
464 | 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059, | ||
465 | 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba, | ||
466 | 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa, | ||
467 | 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a, | ||
468 | 0x49490049,0x68680068,0x38380038,0xa4a400a4, | ||
469 | 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1, | ||
470 | 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e, | ||
471 | }; | ||
472 | |||
473 | /** | ||
474 | * Stuff related to the Camellia key schedule | ||
475 | */ | ||
476 | #define subl(x) subL[(x)] | ||
477 | #define subr(x) subR[(x)] | ||
478 | |||
479 | void camellia_setup128(const u8 *key, u32 *subkey) | ||
480 | { | ||
481 | u32 kll, klr, krl, krr; | ||
482 | u32 il, ir, t0, t1, w0, w1; | ||
483 | u32 kw4l, kw4r, dw, tl, tr; | ||
484 | u32 subL[26]; | ||
485 | u32 subR[26]; | ||
486 | |||
487 | /** | ||
488 | * k == kll || klr || krl || krr (|| is concatination) | ||
489 | */ | ||
490 | kll = GETU32(key ); | ||
491 | klr = GETU32(key + 4); | ||
492 | krl = GETU32(key + 8); | ||
493 | krr = GETU32(key + 12); | ||
494 | /** | ||
495 | * generate KL dependent subkeys | ||
496 | */ | ||
497 | /* kw1 */ | ||
498 | subl(0) = kll; subr(0) = klr; | ||
499 | /* kw2 */ | ||
500 | subl(1) = krl; subr(1) = krr; | ||
501 | /* rotation left shift 15bit */ | ||
502 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
503 | /* k3 */ | ||
504 | subl(4) = kll; subr(4) = klr; | ||
505 | /* k4 */ | ||
506 | subl(5) = krl; subr(5) = krr; | ||
507 | /* rotation left shift 15+30bit */ | ||
508 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); | ||
509 | /* k7 */ | ||
510 | subl(10) = kll; subr(10) = klr; | ||
511 | /* k8 */ | ||
512 | subl(11) = krl; subr(11) = krr; | ||
513 | /* rotation left shift 15+30+15bit */ | ||
514 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
515 | /* k10 */ | ||
516 | subl(13) = krl; subr(13) = krr; | ||
517 | /* rotation left shift 15+30+15+17 bit */ | ||
518 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | ||
519 | /* kl3 */ | ||
520 | subl(16) = kll; subr(16) = klr; | ||
521 | /* kl4 */ | ||
522 | subl(17) = krl; subr(17) = krr; | ||
523 | /* rotation left shift 15+30+15+17+17 bit */ | ||
524 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | ||
525 | /* k13 */ | ||
526 | subl(18) = kll; subr(18) = klr; | ||
527 | /* k14 */ | ||
528 | subl(19) = krl; subr(19) = krr; | ||
529 | /* rotation left shift 15+30+15+17+17+17 bit */ | ||
530 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | ||
531 | /* k17 */ | ||
532 | subl(22) = kll; subr(22) = klr; | ||
533 | /* k18 */ | ||
534 | subl(23) = krl; subr(23) = krr; | ||
535 | |||
536 | /* generate KA */ | ||
537 | kll = subl(0); klr = subr(0); | ||
538 | krl = subl(1); krr = subr(1); | ||
539 | CAMELLIA_F(kll, klr, | ||
540 | CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, | ||
541 | w0, w1, il, ir, t0, t1); | ||
542 | krl ^= w0; krr ^= w1; | ||
543 | CAMELLIA_F(krl, krr, | ||
544 | CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, | ||
545 | kll, klr, il, ir, t0, t1); | ||
546 | /* current status == (kll, klr, w0, w1) */ | ||
547 | CAMELLIA_F(kll, klr, | ||
548 | CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, | ||
549 | krl, krr, il, ir, t0, t1); | ||
550 | krl ^= w0; krr ^= w1; | ||
551 | CAMELLIA_F(krl, krr, | ||
552 | CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, | ||
553 | w0, w1, il, ir, t0, t1); | ||
554 | kll ^= w0; klr ^= w1; | ||
555 | |||
556 | /* generate KA dependent subkeys */ | ||
557 | /* k1, k2 */ | ||
558 | subl(2) = kll; subr(2) = klr; | ||
559 | subl(3) = krl; subr(3) = krr; | ||
560 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
561 | /* k5,k6 */ | ||
562 | subl(6) = kll; subr(6) = klr; | ||
563 | subl(7) = krl; subr(7) = krr; | ||
564 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
565 | /* kl1, kl2 */ | ||
566 | subl(8) = kll; subr(8) = klr; | ||
567 | subl(9) = krl; subr(9) = krr; | ||
568 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
569 | /* k9 */ | ||
570 | subl(12) = kll; subr(12) = klr; | ||
571 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
572 | /* k11, k12 */ | ||
573 | subl(14) = kll; subr(14) = klr; | ||
574 | subl(15) = krl; subr(15) = krr; | ||
575 | CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); | ||
576 | /* k15, k16 */ | ||
577 | subl(20) = kll; subr(20) = klr; | ||
578 | subl(21) = krl; subr(21) = krr; | ||
579 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | ||
580 | /* kw3, kw4 */ | ||
581 | subl(24) = kll; subr(24) = klr; | ||
582 | subl(25) = krl; subr(25) = krr; | ||
583 | |||
584 | |||
585 | /* absorb kw2 to other subkeys */ | ||
586 | /* round 2 */ | ||
587 | subl(3) ^= subl(1); subr(3) ^= subr(1); | ||
588 | /* round 4 */ | ||
589 | subl(5) ^= subl(1); subr(5) ^= subr(1); | ||
590 | /* round 6 */ | ||
591 | subl(7) ^= subl(1); subr(7) ^= subr(1); | ||
592 | subl(1) ^= subr(1) & ~subr(9); | ||
593 | dw = subl(1) & subl(9), | ||
594 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ | ||
595 | /* round 8 */ | ||
596 | subl(11) ^= subl(1); subr(11) ^= subr(1); | ||
597 | /* round 10 */ | ||
598 | subl(13) ^= subl(1); subr(13) ^= subr(1); | ||
599 | /* round 12 */ | ||
600 | subl(15) ^= subl(1); subr(15) ^= subr(1); | ||
601 | subl(1) ^= subr(1) & ~subr(17); | ||
602 | dw = subl(1) & subl(17), | ||
603 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ | ||
604 | /* round 14 */ | ||
605 | subl(19) ^= subl(1); subr(19) ^= subr(1); | ||
606 | /* round 16 */ | ||
607 | subl(21) ^= subl(1); subr(21) ^= subr(1); | ||
608 | /* round 18 */ | ||
609 | subl(23) ^= subl(1); subr(23) ^= subr(1); | ||
610 | /* kw3 */ | ||
611 | subl(24) ^= subl(1); subr(24) ^= subr(1); | ||
612 | |||
613 | /* absorb kw4 to other subkeys */ | ||
614 | kw4l = subl(25); kw4r = subr(25); | ||
615 | /* round 17 */ | ||
616 | subl(22) ^= kw4l; subr(22) ^= kw4r; | ||
617 | /* round 15 */ | ||
618 | subl(20) ^= kw4l; subr(20) ^= kw4r; | ||
619 | /* round 13 */ | ||
620 | subl(18) ^= kw4l; subr(18) ^= kw4r; | ||
621 | kw4l ^= kw4r & ~subr(16); | ||
622 | dw = kw4l & subl(16), | ||
623 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ | ||
624 | /* round 11 */ | ||
625 | subl(14) ^= kw4l; subr(14) ^= kw4r; | ||
626 | /* round 9 */ | ||
627 | subl(12) ^= kw4l; subr(12) ^= kw4r; | ||
628 | /* round 7 */ | ||
629 | subl(10) ^= kw4l; subr(10) ^= kw4r; | ||
630 | kw4l ^= kw4r & ~subr(8); | ||
631 | dw = kw4l & subl(8), | ||
632 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ | ||
633 | /* round 5 */ | ||
634 | subl(6) ^= kw4l; subr(6) ^= kw4r; | ||
635 | /* round 3 */ | ||
636 | subl(4) ^= kw4l; subr(4) ^= kw4r; | ||
637 | /* round 1 */ | ||
638 | subl(2) ^= kw4l; subr(2) ^= kw4r; | ||
639 | /* kw1 */ | ||
640 | subl(0) ^= kw4l; subr(0) ^= kw4r; | ||
641 | |||
642 | |||
643 | /* key XOR is end of F-function */ | ||
644 | CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */ | ||
645 | CamelliaSubkeyR(0) = subr(0) ^ subr(2); | ||
646 | CamelliaSubkeyL(2) = subl(3); /* round 1 */ | ||
647 | CamelliaSubkeyR(2) = subr(3); | ||
648 | CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */ | ||
649 | CamelliaSubkeyR(3) = subr(2) ^ subr(4); | ||
650 | CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */ | ||
651 | CamelliaSubkeyR(4) = subr(3) ^ subr(5); | ||
652 | CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */ | ||
653 | CamelliaSubkeyR(5) = subr(4) ^ subr(6); | ||
654 | CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */ | ||
655 | CamelliaSubkeyR(6) = subr(5) ^ subr(7); | ||
656 | tl = subl(10) ^ (subr(10) & ~subr(8)); | ||
657 | dw = tl & subl(8), /* FL(kl1) */ | ||
658 | tr = subr(10) ^ CAMELLIA_RL1(dw); | ||
659 | CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */ | ||
660 | CamelliaSubkeyR(7) = subr(6) ^ tr; | ||
661 | CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */ | ||
662 | CamelliaSubkeyR(8) = subr(8); | ||
663 | CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */ | ||
664 | CamelliaSubkeyR(9) = subr(9); | ||
665 | tl = subl(7) ^ (subr(7) & ~subr(9)); | ||
666 | dw = tl & subl(9), /* FLinv(kl2) */ | ||
667 | tr = subr(7) ^ CAMELLIA_RL1(dw); | ||
668 | CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */ | ||
669 | CamelliaSubkeyR(10) = tr ^ subr(11); | ||
670 | CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */ | ||
671 | CamelliaSubkeyR(11) = subr(10) ^ subr(12); | ||
672 | CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */ | ||
673 | CamelliaSubkeyR(12) = subr(11) ^ subr(13); | ||
674 | CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */ | ||
675 | CamelliaSubkeyR(13) = subr(12) ^ subr(14); | ||
676 | CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */ | ||
677 | CamelliaSubkeyR(14) = subr(13) ^ subr(15); | ||
678 | tl = subl(18) ^ (subr(18) & ~subr(16)); | ||
679 | dw = tl & subl(16), /* FL(kl3) */ | ||
680 | tr = subr(18) ^ CAMELLIA_RL1(dw); | ||
681 | CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */ | ||
682 | CamelliaSubkeyR(15) = subr(14) ^ tr; | ||
683 | CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */ | ||
684 | CamelliaSubkeyR(16) = subr(16); | ||
685 | CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */ | ||
686 | CamelliaSubkeyR(17) = subr(17); | ||
687 | tl = subl(15) ^ (subr(15) & ~subr(17)); | ||
688 | dw = tl & subl(17), /* FLinv(kl4) */ | ||
689 | tr = subr(15) ^ CAMELLIA_RL1(dw); | ||
690 | CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */ | ||
691 | CamelliaSubkeyR(18) = tr ^ subr(19); | ||
692 | CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */ | ||
693 | CamelliaSubkeyR(19) = subr(18) ^ subr(20); | ||
694 | CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */ | ||
695 | CamelliaSubkeyR(20) = subr(19) ^ subr(21); | ||
696 | CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */ | ||
697 | CamelliaSubkeyR(21) = subr(20) ^ subr(22); | ||
698 | CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */ | ||
699 | CamelliaSubkeyR(22) = subr(21) ^ subr(23); | ||
700 | CamelliaSubkeyL(23) = subl(22); /* round 18 */ | ||
701 | CamelliaSubkeyR(23) = subr(22); | ||
702 | CamelliaSubkeyL(24) = subl(24) ^ subl(23); /* kw3 */ | ||
703 | CamelliaSubkeyR(24) = subr(24) ^ subr(23); | ||
704 | |||
705 | /* apply the inverse of the last half of P-function */ | ||
706 | dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), | ||
707 | dw = CAMELLIA_RL8(dw);/* round 1 */ | ||
708 | CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, | ||
709 | CamelliaSubkeyL(2) = dw; | ||
710 | dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), | ||
711 | dw = CAMELLIA_RL8(dw);/* round 2 */ | ||
712 | CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, | ||
713 | CamelliaSubkeyL(3) = dw; | ||
714 | dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), | ||
715 | dw = CAMELLIA_RL8(dw);/* round 3 */ | ||
716 | CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, | ||
717 | CamelliaSubkeyL(4) = dw; | ||
718 | dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), | ||
719 | dw = CAMELLIA_RL8(dw);/* round 4 */ | ||
720 | CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, | ||
721 | CamelliaSubkeyL(5) = dw; | ||
722 | dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), | ||
723 | dw = CAMELLIA_RL8(dw);/* round 5 */ | ||
724 | CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, | ||
725 | CamelliaSubkeyL(6) = dw; | ||
726 | dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), | ||
727 | dw = CAMELLIA_RL8(dw);/* round 6 */ | ||
728 | CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, | ||
729 | CamelliaSubkeyL(7) = dw; | ||
730 | dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), | ||
731 | dw = CAMELLIA_RL8(dw);/* round 7 */ | ||
732 | CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, | ||
733 | CamelliaSubkeyL(10) = dw; | ||
734 | dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), | ||
735 | dw = CAMELLIA_RL8(dw);/* round 8 */ | ||
736 | CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, | ||
737 | CamelliaSubkeyL(11) = dw; | ||
738 | dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), | ||
739 | dw = CAMELLIA_RL8(dw);/* round 9 */ | ||
740 | CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, | ||
741 | CamelliaSubkeyL(12) = dw; | ||
742 | dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), | ||
743 | dw = CAMELLIA_RL8(dw);/* round 10 */ | ||
744 | CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, | ||
745 | CamelliaSubkeyL(13) = dw; | ||
746 | dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), | ||
747 | dw = CAMELLIA_RL8(dw);/* round 11 */ | ||
748 | CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, | ||
749 | CamelliaSubkeyL(14) = dw; | ||
750 | dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), | ||
751 | dw = CAMELLIA_RL8(dw);/* round 12 */ | ||
752 | CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, | ||
753 | CamelliaSubkeyL(15) = dw; | ||
754 | dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), | ||
755 | dw = CAMELLIA_RL8(dw);/* round 13 */ | ||
756 | CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, | ||
757 | CamelliaSubkeyL(18) = dw; | ||
758 | dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), | ||
759 | dw = CAMELLIA_RL8(dw);/* round 14 */ | ||
760 | CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, | ||
761 | CamelliaSubkeyL(19) = dw; | ||
762 | dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), | ||
763 | dw = CAMELLIA_RL8(dw);/* round 15 */ | ||
764 | CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, | ||
765 | CamelliaSubkeyL(20) = dw; | ||
766 | dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), | ||
767 | dw = CAMELLIA_RL8(dw);/* round 16 */ | ||
768 | CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, | ||
769 | CamelliaSubkeyL(21) = dw; | ||
770 | dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), | ||
771 | dw = CAMELLIA_RL8(dw);/* round 17 */ | ||
772 | CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, | ||
773 | CamelliaSubkeyL(22) = dw; | ||
774 | dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), | ||
775 | dw = CAMELLIA_RL8(dw);/* round 18 */ | ||
776 | CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, | ||
777 | CamelliaSubkeyL(23) = dw; | ||
778 | |||
779 | return; | ||
780 | } | 484 | } |
781 | 485 | ||
782 | void camellia_setup256(const u8 *key, u32 *subkey) | 486 | void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], |
487 | const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) | ||
783 | { | 488 | { |
784 | u32 kll,klr,krl,krr; /* left half of key */ | 489 | register u32 s0,s1,s2,s3; |
785 | u32 krll,krlr,krrl,krrr; /* right half of key */ | 490 | const u32 *k = keyTable,*kend = keyTable+grandRounds*16; |
786 | u32 il, ir, t0, t1, w0, w1; /* temporary variables */ | 491 | |
787 | u32 kw4l, kw4r, dw, tl, tr; | 492 | s0 = GETU32(plaintext) ^ k[0]; |
788 | u32 subL[34]; | 493 | s1 = GETU32(plaintext+4) ^ k[1]; |
789 | u32 subR[34]; | 494 | s2 = GETU32(plaintext+8) ^ k[2]; |
790 | 495 | s3 = GETU32(plaintext+12) ^ k[3]; | |
791 | /** | 496 | k += 4; |
792 | * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) | 497 | |
793 | * (|| is concatination) | 498 | while (1) |
794 | */ | 499 | { |
795 | 500 | /* Camellia makes 6 Feistel rounds */ | |
796 | kll = GETU32(key ); | 501 | Camellia_Feistel(s0,s1,s2,s3,k+0); |
797 | klr = GETU32(key + 4); | 502 | Camellia_Feistel(s2,s3,s0,s1,k+2); |
798 | krl = GETU32(key + 8); | 503 | Camellia_Feistel(s0,s1,s2,s3,k+4); |
799 | krr = GETU32(key + 12); | 504 | Camellia_Feistel(s2,s3,s0,s1,k+6); |
800 | krll = GETU32(key + 16); | 505 | Camellia_Feistel(s0,s1,s2,s3,k+8); |
801 | krlr = GETU32(key + 20); | 506 | Camellia_Feistel(s2,s3,s0,s1,k+10); |
802 | krrl = GETU32(key + 24); | 507 | k += 12; |
803 | krrr = GETU32(key + 28); | 508 | |
804 | 509 | if (k == kend) break; | |
805 | /* generate KL dependent subkeys */ | 510 | |
806 | /* kw1 */ | 511 | /* This is the same function as the diffusion function D |
807 | subl(0) = kll; subr(0) = klr; | 512 | * of the accompanying documentation. See section 3.2 |
808 | /* kw2 */ | 513 | * for properties of the FLlayer function. */ |
809 | subl(1) = krl; subr(1) = krr; | 514 | s1 ^= LeftRotate(s0 & k[0], 1); |
810 | CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45); | 515 | s2 ^= s3 | k[3]; |
811 | /* k9 */ | 516 | s0 ^= s1 | k[1]; |
812 | subl(12) = kll; subr(12) = klr; | 517 | s3 ^= LeftRotate(s2 & k[2], 1); |
813 | /* k10 */ | 518 | k += 4; |
814 | subl(13) = krl; subr(13) = krr; | 519 | } |
815 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | 520 | |
816 | /* kl3 */ | 521 | s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; |
817 | subl(16) = kll; subr(16) = klr; | 522 | |
818 | /* kl4 */ | 523 | PUTU32(ciphertext, s2); |
819 | subl(17) = krl; subr(17) = krr; | 524 | PUTU32(ciphertext+4, s3); |
820 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | 525 | PUTU32(ciphertext+8, s0); |
821 | /* k17 */ | 526 | PUTU32(ciphertext+12,s1); |
822 | subl(22) = kll; subr(22) = klr; | ||
823 | /* k18 */ | ||
824 | subl(23) = krl; subr(23) = krr; | ||
825 | CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); | ||
826 | /* k23 */ | ||
827 | subl(30) = kll; subr(30) = klr; | ||
828 | /* k24 */ | ||
829 | subl(31) = krl; subr(31) = krr; | ||
830 | |||
831 | /* generate KR dependent subkeys */ | ||
832 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); | ||
833 | /* k3 */ | ||
834 | subl(4) = krll; subr(4) = krlr; | ||
835 | /* k4 */ | ||
836 | subl(5) = krrl; subr(5) = krrr; | ||
837 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); | ||
838 | /* kl1 */ | ||
839 | subl(8) = krll; subr(8) = krlr; | ||
840 | /* kl2 */ | ||
841 | subl(9) = krrl; subr(9) = krrr; | ||
842 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); | ||
843 | /* k13 */ | ||
844 | subl(18) = krll; subr(18) = krlr; | ||
845 | /* k14 */ | ||
846 | subl(19) = krrl; subr(19) = krrr; | ||
847 | CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); | ||
848 | /* k19 */ | ||
849 | subl(26) = krll; subr(26) = krlr; | ||
850 | /* k20 */ | ||
851 | subl(27) = krrl; subr(27) = krrr; | ||
852 | CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); | ||
853 | |||
854 | /* generate KA */ | ||
855 | kll = subl(0) ^ krll; klr = subr(0) ^ krlr; | ||
856 | krl = subl(1) ^ krrl; krr = subr(1) ^ krrr; | ||
857 | CAMELLIA_F(kll, klr, | ||
858 | CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, | ||
859 | w0, w1, il, ir, t0, t1); | ||
860 | krl ^= w0; krr ^= w1; | ||
861 | CAMELLIA_F(krl, krr, | ||
862 | CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, | ||
863 | kll, klr, il, ir, t0, t1); | ||
864 | kll ^= krll; klr ^= krlr; | ||
865 | CAMELLIA_F(kll, klr, | ||
866 | CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, | ||
867 | krl, krr, il, ir, t0, t1); | ||
868 | krl ^= w0 ^ krrl; krr ^= w1 ^ krrr; | ||
869 | CAMELLIA_F(krl, krr, | ||
870 | CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, | ||
871 | w0, w1, il, ir, t0, t1); | ||
872 | kll ^= w0; klr ^= w1; | ||
873 | |||
874 | /* generate KB */ | ||
875 | krll ^= kll; krlr ^= klr; | ||
876 | krrl ^= krl; krrr ^= krr; | ||
877 | CAMELLIA_F(krll, krlr, | ||
878 | CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R, | ||
879 | w0, w1, il, ir, t0, t1); | ||
880 | krrl ^= w0; krrr ^= w1; | ||
881 | CAMELLIA_F(krrl, krrr, | ||
882 | CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R, | ||
883 | w0, w1, il, ir, t0, t1); | ||
884 | krll ^= w0; krlr ^= w1; | ||
885 | |||
886 | /* generate KA dependent subkeys */ | ||
887 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
888 | /* k5 */ | ||
889 | subl(6) = kll; subr(6) = klr; | ||
890 | /* k6 */ | ||
891 | subl(7) = krl; subr(7) = krr; | ||
892 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); | ||
893 | /* k11 */ | ||
894 | subl(14) = kll; subr(14) = klr; | ||
895 | /* k12 */ | ||
896 | subl(15) = krl; subr(15) = krr; | ||
897 | /* rotation left shift 32bit */ | ||
898 | /* kl5 */ | ||
899 | subl(24) = klr; subr(24) = krl; | ||
900 | /* kl6 */ | ||
901 | subl(25) = krr; subr(25) = kll; | ||
902 | /* rotation left shift 49 from k11,k12 -> k21,k22 */ | ||
903 | CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49); | ||
904 | /* k21 */ | ||
905 | subl(28) = kll; subr(28) = klr; | ||
906 | /* k22 */ | ||
907 | subl(29) = krl; subr(29) = krr; | ||
908 | |||
909 | /* generate KB dependent subkeys */ | ||
910 | /* k1 */ | ||
911 | subl(2) = krll; subr(2) = krlr; | ||
912 | /* k2 */ | ||
913 | subl(3) = krrl; subr(3) = krrr; | ||
914 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); | ||
915 | /* k7 */ | ||
916 | subl(10) = krll; subr(10) = krlr; | ||
917 | /* k8 */ | ||
918 | subl(11) = krrl; subr(11) = krrr; | ||
919 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); | ||
920 | /* k15 */ | ||
921 | subl(20) = krll; subr(20) = krlr; | ||
922 | /* k16 */ | ||
923 | subl(21) = krrl; subr(21) = krrr; | ||
924 | CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51); | ||
925 | /* kw3 */ | ||
926 | subl(32) = krll; subr(32) = krlr; | ||
927 | /* kw4 */ | ||
928 | subl(33) = krrl; subr(33) = krrr; | ||
929 | |||
930 | /* absorb kw2 to other subkeys */ | ||
931 | /* round 2 */ | ||
932 | subl(3) ^= subl(1); subr(3) ^= subr(1); | ||
933 | /* round 4 */ | ||
934 | subl(5) ^= subl(1); subr(5) ^= subr(1); | ||
935 | /* round 6 */ | ||
936 | subl(7) ^= subl(1); subr(7) ^= subr(1); | ||
937 | subl(1) ^= subr(1) & ~subr(9); | ||
938 | dw = subl(1) & subl(9), | ||
939 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ | ||
940 | /* round 8 */ | ||
941 | subl(11) ^= subl(1); subr(11) ^= subr(1); | ||
942 | /* round 10 */ | ||
943 | subl(13) ^= subl(1); subr(13) ^= subr(1); | ||
944 | /* round 12 */ | ||
945 | subl(15) ^= subl(1); subr(15) ^= subr(1); | ||
946 | subl(1) ^= subr(1) & ~subr(17); | ||
947 | dw = subl(1) & subl(17), | ||
948 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ | ||
949 | /* round 14 */ | ||
950 | subl(19) ^= subl(1); subr(19) ^= subr(1); | ||
951 | /* round 16 */ | ||
952 | subl(21) ^= subl(1); subr(21) ^= subr(1); | ||
953 | /* round 18 */ | ||
954 | subl(23) ^= subl(1); subr(23) ^= subr(1); | ||
955 | subl(1) ^= subr(1) & ~subr(25); | ||
956 | dw = subl(1) & subl(25), | ||
957 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl6) */ | ||
958 | /* round 20 */ | ||
959 | subl(27) ^= subl(1); subr(27) ^= subr(1); | ||
960 | /* round 22 */ | ||
961 | subl(29) ^= subl(1); subr(29) ^= subr(1); | ||
962 | /* round 24 */ | ||
963 | subl(31) ^= subl(1); subr(31) ^= subr(1); | ||
964 | /* kw3 */ | ||
965 | subl(32) ^= subl(1); subr(32) ^= subr(1); | ||
966 | |||
967 | |||
968 | /* absorb kw4 to other subkeys */ | ||
969 | kw4l = subl(33); kw4r = subr(33); | ||
970 | /* round 23 */ | ||
971 | subl(30) ^= kw4l; subr(30) ^= kw4r; | ||
972 | /* round 21 */ | ||
973 | subl(28) ^= kw4l; subr(28) ^= kw4r; | ||
974 | /* round 19 */ | ||
975 | subl(26) ^= kw4l; subr(26) ^= kw4r; | ||
976 | kw4l ^= kw4r & ~subr(24); | ||
977 | dw = kw4l & subl(24), | ||
978 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl5) */ | ||
979 | /* round 17 */ | ||
980 | subl(22) ^= kw4l; subr(22) ^= kw4r; | ||
981 | /* round 15 */ | ||
982 | subl(20) ^= kw4l; subr(20) ^= kw4r; | ||
983 | /* round 13 */ | ||
984 | subl(18) ^= kw4l; subr(18) ^= kw4r; | ||
985 | kw4l ^= kw4r & ~subr(16); | ||
986 | dw = kw4l & subl(16), | ||
987 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ | ||
988 | /* round 11 */ | ||
989 | subl(14) ^= kw4l; subr(14) ^= kw4r; | ||
990 | /* round 9 */ | ||
991 | subl(12) ^= kw4l; subr(12) ^= kw4r; | ||
992 | /* round 7 */ | ||
993 | subl(10) ^= kw4l; subr(10) ^= kw4r; | ||
994 | kw4l ^= kw4r & ~subr(8); | ||
995 | dw = kw4l & subl(8), | ||
996 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ | ||
997 | /* round 5 */ | ||
998 | subl(6) ^= kw4l; subr(6) ^= kw4r; | ||
999 | /* round 3 */ | ||
1000 | subl(4) ^= kw4l; subr(4) ^= kw4r; | ||
1001 | /* round 1 */ | ||
1002 | subl(2) ^= kw4l; subr(2) ^= kw4r; | ||
1003 | /* kw1 */ | ||
1004 | subl(0) ^= kw4l; subr(0) ^= kw4r; | ||
1005 | |||
1006 | /* key XOR is end of F-function */ | ||
1007 | CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */ | ||
1008 | CamelliaSubkeyR(0) = subr(0) ^ subr(2); | ||
1009 | CamelliaSubkeyL(2) = subl(3); /* round 1 */ | ||
1010 | CamelliaSubkeyR(2) = subr(3); | ||
1011 | CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */ | ||
1012 | CamelliaSubkeyR(3) = subr(2) ^ subr(4); | ||
1013 | CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */ | ||
1014 | CamelliaSubkeyR(4) = subr(3) ^ subr(5); | ||
1015 | CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */ | ||
1016 | CamelliaSubkeyR(5) = subr(4) ^ subr(6); | ||
1017 | CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */ | ||
1018 | CamelliaSubkeyR(6) = subr(5) ^ subr(7); | ||
1019 | tl = subl(10) ^ (subr(10) & ~subr(8)); | ||
1020 | dw = tl & subl(8), /* FL(kl1) */ | ||
1021 | tr = subr(10) ^ CAMELLIA_RL1(dw); | ||
1022 | CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */ | ||
1023 | CamelliaSubkeyR(7) = subr(6) ^ tr; | ||
1024 | CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */ | ||
1025 | CamelliaSubkeyR(8) = subr(8); | ||
1026 | CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */ | ||
1027 | CamelliaSubkeyR(9) = subr(9); | ||
1028 | tl = subl(7) ^ (subr(7) & ~subr(9)); | ||
1029 | dw = tl & subl(9), /* FLinv(kl2) */ | ||
1030 | tr = subr(7) ^ CAMELLIA_RL1(dw); | ||
1031 | CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */ | ||
1032 | CamelliaSubkeyR(10) = tr ^ subr(11); | ||
1033 | CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */ | ||
1034 | CamelliaSubkeyR(11) = subr(10) ^ subr(12); | ||
1035 | CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */ | ||
1036 | CamelliaSubkeyR(12) = subr(11) ^ subr(13); | ||
1037 | CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */ | ||
1038 | CamelliaSubkeyR(13) = subr(12) ^ subr(14); | ||
1039 | CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */ | ||
1040 | CamelliaSubkeyR(14) = subr(13) ^ subr(15); | ||
1041 | tl = subl(18) ^ (subr(18) & ~subr(16)); | ||
1042 | dw = tl & subl(16), /* FL(kl3) */ | ||
1043 | tr = subr(18) ^ CAMELLIA_RL1(dw); | ||
1044 | CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */ | ||
1045 | CamelliaSubkeyR(15) = subr(14) ^ tr; | ||
1046 | CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */ | ||
1047 | CamelliaSubkeyR(16) = subr(16); | ||
1048 | CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */ | ||
1049 | CamelliaSubkeyR(17) = subr(17); | ||
1050 | tl = subl(15) ^ (subr(15) & ~subr(17)); | ||
1051 | dw = tl & subl(17), /* FLinv(kl4) */ | ||
1052 | tr = subr(15) ^ CAMELLIA_RL1(dw); | ||
1053 | CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */ | ||
1054 | CamelliaSubkeyR(18) = tr ^ subr(19); | ||
1055 | CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */ | ||
1056 | CamelliaSubkeyR(19) = subr(18) ^ subr(20); | ||
1057 | CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */ | ||
1058 | CamelliaSubkeyR(20) = subr(19) ^ subr(21); | ||
1059 | CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */ | ||
1060 | CamelliaSubkeyR(21) = subr(20) ^ subr(22); | ||
1061 | CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */ | ||
1062 | CamelliaSubkeyR(22) = subr(21) ^ subr(23); | ||
1063 | tl = subl(26) ^ (subr(26) | ||
1064 | & ~subr(24)); | ||
1065 | dw = tl & subl(24), /* FL(kl5) */ | ||
1066 | tr = subr(26) ^ CAMELLIA_RL1(dw); | ||
1067 | CamelliaSubkeyL(23) = subl(22) ^ tl; /* round 18 */ | ||
1068 | CamelliaSubkeyR(23) = subr(22) ^ tr; | ||
1069 | CamelliaSubkeyL(24) = subl(24); /* FL(kl5) */ | ||
1070 | CamelliaSubkeyR(24) = subr(24); | ||
1071 | CamelliaSubkeyL(25) = subl(25); /* FLinv(kl6) */ | ||
1072 | CamelliaSubkeyR(25) = subr(25); | ||
1073 | tl = subl(23) ^ (subr(23) & | ||
1074 | ~subr(25)); | ||
1075 | dw = tl & subl(25), /* FLinv(kl6) */ | ||
1076 | tr = subr(23) ^ CAMELLIA_RL1(dw); | ||
1077 | CamelliaSubkeyL(26) = tl ^ subl(27); /* round 19 */ | ||
1078 | CamelliaSubkeyR(26) = tr ^ subr(27); | ||
1079 | CamelliaSubkeyL(27) = subl(26) ^ subl(28); /* round 20 */ | ||
1080 | CamelliaSubkeyR(27) = subr(26) ^ subr(28); | ||
1081 | CamelliaSubkeyL(28) = subl(27) ^ subl(29); /* round 21 */ | ||
1082 | CamelliaSubkeyR(28) = subr(27) ^ subr(29); | ||
1083 | CamelliaSubkeyL(29) = subl(28) ^ subl(30); /* round 22 */ | ||
1084 | CamelliaSubkeyR(29) = subr(28) ^ subr(30); | ||
1085 | CamelliaSubkeyL(30) = subl(29) ^ subl(31); /* round 23 */ | ||
1086 | CamelliaSubkeyR(30) = subr(29) ^ subr(31); | ||
1087 | CamelliaSubkeyL(31) = subl(30); /* round 24 */ | ||
1088 | CamelliaSubkeyR(31) = subr(30); | ||
1089 | CamelliaSubkeyL(32) = subl(32) ^ subl(31); /* kw3 */ | ||
1090 | CamelliaSubkeyR(32) = subr(32) ^ subr(31); | ||
1091 | |||
1092 | /* apply the inverse of the last half of P-function */ | ||
1093 | dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), | ||
1094 | dw = CAMELLIA_RL8(dw);/* round 1 */ | ||
1095 | CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, | ||
1096 | CamelliaSubkeyL(2) = dw; | ||
1097 | dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), | ||
1098 | dw = CAMELLIA_RL8(dw);/* round 2 */ | ||
1099 | CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, | ||
1100 | CamelliaSubkeyL(3) = dw; | ||
1101 | dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), | ||
1102 | dw = CAMELLIA_RL8(dw);/* round 3 */ | ||
1103 | CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, | ||
1104 | CamelliaSubkeyL(4) = dw; | ||
1105 | dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), | ||
1106 | dw = CAMELLIA_RL8(dw);/* round 4 */ | ||
1107 | CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, | ||
1108 | CamelliaSubkeyL(5) = dw; | ||
1109 | dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), | ||
1110 | dw = CAMELLIA_RL8(dw);/* round 5 */ | ||
1111 | CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, | ||
1112 | CamelliaSubkeyL(6) = dw; | ||
1113 | dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), | ||
1114 | dw = CAMELLIA_RL8(dw);/* round 6 */ | ||
1115 | CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, | ||
1116 | CamelliaSubkeyL(7) = dw; | ||
1117 | dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), | ||
1118 | dw = CAMELLIA_RL8(dw);/* round 7 */ | ||
1119 | CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, | ||
1120 | CamelliaSubkeyL(10) = dw; | ||
1121 | dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), | ||
1122 | dw = CAMELLIA_RL8(dw);/* round 8 */ | ||
1123 | CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, | ||
1124 | CamelliaSubkeyL(11) = dw; | ||
1125 | dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), | ||
1126 | dw = CAMELLIA_RL8(dw);/* round 9 */ | ||
1127 | CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, | ||
1128 | CamelliaSubkeyL(12) = dw; | ||
1129 | dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), | ||
1130 | dw = CAMELLIA_RL8(dw);/* round 10 */ | ||
1131 | CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, | ||
1132 | CamelliaSubkeyL(13) = dw; | ||
1133 | dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), | ||
1134 | dw = CAMELLIA_RL8(dw);/* round 11 */ | ||
1135 | CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, | ||
1136 | CamelliaSubkeyL(14) = dw; | ||
1137 | dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), | ||
1138 | dw = CAMELLIA_RL8(dw);/* round 12 */ | ||
1139 | CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, | ||
1140 | CamelliaSubkeyL(15) = dw; | ||
1141 | dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), | ||
1142 | dw = CAMELLIA_RL8(dw);/* round 13 */ | ||
1143 | CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, | ||
1144 | CamelliaSubkeyL(18) = dw; | ||
1145 | dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), | ||
1146 | dw = CAMELLIA_RL8(dw);/* round 14 */ | ||
1147 | CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, | ||
1148 | CamelliaSubkeyL(19) = dw; | ||
1149 | dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), | ||
1150 | dw = CAMELLIA_RL8(dw);/* round 15 */ | ||
1151 | CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, | ||
1152 | CamelliaSubkeyL(20) = dw; | ||
1153 | dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), | ||
1154 | dw = CAMELLIA_RL8(dw);/* round 16 */ | ||
1155 | CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, | ||
1156 | CamelliaSubkeyL(21) = dw; | ||
1157 | dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), | ||
1158 | dw = CAMELLIA_RL8(dw);/* round 17 */ | ||
1159 | CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, | ||
1160 | CamelliaSubkeyL(22) = dw; | ||
1161 | dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), | ||
1162 | dw = CAMELLIA_RL8(dw);/* round 18 */ | ||
1163 | CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, | ||
1164 | CamelliaSubkeyL(23) = dw; | ||
1165 | dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), | ||
1166 | dw = CAMELLIA_RL8(dw);/* round 19 */ | ||
1167 | CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, | ||
1168 | CamelliaSubkeyL(26) = dw; | ||
1169 | dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), | ||
1170 | dw = CAMELLIA_RL8(dw);/* round 20 */ | ||
1171 | CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, | ||
1172 | CamelliaSubkeyL(27) = dw; | ||
1173 | dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), | ||
1174 | dw = CAMELLIA_RL8(dw);/* round 21 */ | ||
1175 | CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, | ||
1176 | CamelliaSubkeyL(28) = dw; | ||
1177 | dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), | ||
1178 | dw = CAMELLIA_RL8(dw);/* round 22 */ | ||
1179 | CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, | ||
1180 | CamelliaSubkeyL(29) = dw; | ||
1181 | dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), | ||
1182 | dw = CAMELLIA_RL8(dw);/* round 23 */ | ||
1183 | CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, | ||
1184 | CamelliaSubkeyL(30) = dw; | ||
1185 | dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), | ||
1186 | dw = CAMELLIA_RL8(dw);/* round 24 */ | ||
1187 | CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw, | ||
1188 | CamelliaSubkeyL(31) = dw; | ||
1189 | |||
1190 | |||
1191 | return; | ||
1192 | } | 527 | } |
1193 | 528 | void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], | |
1194 | void camellia_setup192(const u8 *key, u32 *subkey) | 529 | const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) |
1195 | { | ||
1196 | u8 kk[32]; | ||
1197 | u32 krll, krlr, krrl,krrr; | ||
1198 | |||
1199 | memcpy(kk, key, 24); | ||
1200 | memcpy((u8 *)&krll, key+16,4); | ||
1201 | memcpy((u8 *)&krlr, key+20,4); | ||
1202 | krrl = ~krll; | ||
1203 | krrr = ~krlr; | ||
1204 | memcpy(kk+24, (u8 *)&krrl, 4); | ||
1205 | memcpy(kk+28, (u8 *)&krrr, 4); | ||
1206 | camellia_setup256(kk, subkey); | ||
1207 | return; | ||
1208 | } | ||
1209 | |||
1210 | |||
1211 | /** | ||
1212 | * Stuff related to camellia encryption/decryption | ||
1213 | */ | ||
1214 | void camellia_encrypt128(const u32 *subkey, u32 *io) | ||
1215 | { | ||
1216 | u32 il, ir, t0, t1; | ||
1217 | |||
1218 | /* pre whitening but absorb kw2*/ | ||
1219 | io[0] ^= CamelliaSubkeyL(0); | ||
1220 | io[1] ^= CamelliaSubkeyR(0); | ||
1221 | /* main iteration */ | ||
1222 | |||
1223 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1224 | CamelliaSubkeyL(2),CamelliaSubkeyR(2), | ||
1225 | io[2],io[3],il,ir,t0,t1); | ||
1226 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1227 | CamelliaSubkeyL(3),CamelliaSubkeyR(3), | ||
1228 | io[0],io[1],il,ir,t0,t1); | ||
1229 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1230 | CamelliaSubkeyL(4),CamelliaSubkeyR(4), | ||
1231 | io[2],io[3],il,ir,t0,t1); | ||
1232 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1233 | CamelliaSubkeyL(5),CamelliaSubkeyR(5), | ||
1234 | io[0],io[1],il,ir,t0,t1); | ||
1235 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1236 | CamelliaSubkeyL(6),CamelliaSubkeyR(6), | ||
1237 | io[2],io[3],il,ir,t0,t1); | ||
1238 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1239 | CamelliaSubkeyL(7),CamelliaSubkeyR(7), | ||
1240 | io[0],io[1],il,ir,t0,t1); | ||
1241 | |||
1242 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1243 | CamelliaSubkeyL(8),CamelliaSubkeyR(8), | ||
1244 | CamelliaSubkeyL(9),CamelliaSubkeyR(9), | ||
1245 | t0,t1,il,ir); | ||
1246 | |||
1247 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1248 | CamelliaSubkeyL(10),CamelliaSubkeyR(10), | ||
1249 | io[2],io[3],il,ir,t0,t1); | ||
1250 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1251 | CamelliaSubkeyL(11),CamelliaSubkeyR(11), | ||
1252 | io[0],io[1],il,ir,t0,t1); | ||
1253 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1254 | CamelliaSubkeyL(12),CamelliaSubkeyR(12), | ||
1255 | io[2],io[3],il,ir,t0,t1); | ||
1256 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1257 | CamelliaSubkeyL(13),CamelliaSubkeyR(13), | ||
1258 | io[0],io[1],il,ir,t0,t1); | ||
1259 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1260 | CamelliaSubkeyL(14),CamelliaSubkeyR(14), | ||
1261 | io[2],io[3],il,ir,t0,t1); | ||
1262 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1263 | CamelliaSubkeyL(15),CamelliaSubkeyR(15), | ||
1264 | io[0],io[1],il,ir,t0,t1); | ||
1265 | |||
1266 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1267 | CamelliaSubkeyL(16),CamelliaSubkeyR(16), | ||
1268 | CamelliaSubkeyL(17),CamelliaSubkeyR(17), | ||
1269 | t0,t1,il,ir); | ||
1270 | |||
1271 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1272 | CamelliaSubkeyL(18),CamelliaSubkeyR(18), | ||
1273 | io[2],io[3],il,ir,t0,t1); | ||
1274 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1275 | CamelliaSubkeyL(19),CamelliaSubkeyR(19), | ||
1276 | io[0],io[1],il,ir,t0,t1); | ||
1277 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1278 | CamelliaSubkeyL(20),CamelliaSubkeyR(20), | ||
1279 | io[2],io[3],il,ir,t0,t1); | ||
1280 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1281 | CamelliaSubkeyL(21),CamelliaSubkeyR(21), | ||
1282 | io[0],io[1],il,ir,t0,t1); | ||
1283 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1284 | CamelliaSubkeyL(22),CamelliaSubkeyR(22), | ||
1285 | io[2],io[3],il,ir,t0,t1); | ||
1286 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1287 | CamelliaSubkeyL(23),CamelliaSubkeyR(23), | ||
1288 | io[0],io[1],il,ir,t0,t1); | ||
1289 | |||
1290 | /* post whitening but kw4 */ | ||
1291 | io[2] ^= CamelliaSubkeyL(24); | ||
1292 | io[3] ^= CamelliaSubkeyR(24); | ||
1293 | |||
1294 | t0 = io[0]; | ||
1295 | t1 = io[1]; | ||
1296 | io[0] = io[2]; | ||
1297 | io[1] = io[3]; | ||
1298 | io[2] = t0; | ||
1299 | io[3] = t1; | ||
1300 | |||
1301 | return; | ||
1302 | } | ||
1303 | |||
1304 | void camellia_decrypt128(const u32 *subkey, u32 *io) | ||
1305 | { | 530 | { |
1306 | u32 il,ir,t0,t1; /* temporary valiables */ | 531 | Camellia_EncryptBlock_Rounds(keyBitLength==128?3:4, |
1307 | 532 | plaintext,keyTable,ciphertext); | |
1308 | /* pre whitening but absorb kw2*/ | ||
1309 | io[0] ^= CamelliaSubkeyL(24); | ||
1310 | io[1] ^= CamelliaSubkeyR(24); | ||
1311 | |||
1312 | /* main iteration */ | ||
1313 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1314 | CamelliaSubkeyL(23),CamelliaSubkeyR(23), | ||
1315 | io[2],io[3],il,ir,t0,t1); | ||
1316 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1317 | CamelliaSubkeyL(22),CamelliaSubkeyR(22), | ||
1318 | io[0],io[1],il,ir,t0,t1); | ||
1319 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1320 | CamelliaSubkeyL(21),CamelliaSubkeyR(21), | ||
1321 | io[2],io[3],il,ir,t0,t1); | ||
1322 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1323 | CamelliaSubkeyL(20),CamelliaSubkeyR(20), | ||
1324 | io[0],io[1],il,ir,t0,t1); | ||
1325 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1326 | CamelliaSubkeyL(19),CamelliaSubkeyR(19), | ||
1327 | io[2],io[3],il,ir,t0,t1); | ||
1328 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1329 | CamelliaSubkeyL(18),CamelliaSubkeyR(18), | ||
1330 | io[0],io[1],il,ir,t0,t1); | ||
1331 | |||
1332 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1333 | CamelliaSubkeyL(17),CamelliaSubkeyR(17), | ||
1334 | CamelliaSubkeyL(16),CamelliaSubkeyR(16), | ||
1335 | t0,t1,il,ir); | ||
1336 | |||
1337 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1338 | CamelliaSubkeyL(15),CamelliaSubkeyR(15), | ||
1339 | io[2],io[3],il,ir,t0,t1); | ||
1340 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1341 | CamelliaSubkeyL(14),CamelliaSubkeyR(14), | ||
1342 | io[0],io[1],il,ir,t0,t1); | ||
1343 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1344 | CamelliaSubkeyL(13),CamelliaSubkeyR(13), | ||
1345 | io[2],io[3],il,ir,t0,t1); | ||
1346 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1347 | CamelliaSubkeyL(12),CamelliaSubkeyR(12), | ||
1348 | io[0],io[1],il,ir,t0,t1); | ||
1349 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1350 | CamelliaSubkeyL(11),CamelliaSubkeyR(11), | ||
1351 | io[2],io[3],il,ir,t0,t1); | ||
1352 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1353 | CamelliaSubkeyL(10),CamelliaSubkeyR(10), | ||
1354 | io[0],io[1],il,ir,t0,t1); | ||
1355 | |||
1356 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1357 | CamelliaSubkeyL(9),CamelliaSubkeyR(9), | ||
1358 | CamelliaSubkeyL(8),CamelliaSubkeyR(8), | ||
1359 | t0,t1,il,ir); | ||
1360 | |||
1361 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1362 | CamelliaSubkeyL(7),CamelliaSubkeyR(7), | ||
1363 | io[2],io[3],il,ir,t0,t1); | ||
1364 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1365 | CamelliaSubkeyL(6),CamelliaSubkeyR(6), | ||
1366 | io[0],io[1],il,ir,t0,t1); | ||
1367 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1368 | CamelliaSubkeyL(5),CamelliaSubkeyR(5), | ||
1369 | io[2],io[3],il,ir,t0,t1); | ||
1370 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1371 | CamelliaSubkeyL(4),CamelliaSubkeyR(4), | ||
1372 | io[0],io[1],il,ir,t0,t1); | ||
1373 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1374 | CamelliaSubkeyL(3),CamelliaSubkeyR(3), | ||
1375 | io[2],io[3],il,ir,t0,t1); | ||
1376 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1377 | CamelliaSubkeyL(2),CamelliaSubkeyR(2), | ||
1378 | io[0],io[1],il,ir,t0,t1); | ||
1379 | |||
1380 | /* post whitening but kw4 */ | ||
1381 | io[2] ^= CamelliaSubkeyL(0); | ||
1382 | io[3] ^= CamelliaSubkeyR(0); | ||
1383 | |||
1384 | t0 = io[0]; | ||
1385 | t1 = io[1]; | ||
1386 | io[0] = io[2]; | ||
1387 | io[1] = io[3]; | ||
1388 | io[2] = t0; | ||
1389 | io[3] = t1; | ||
1390 | |||
1391 | return; | ||
1392 | } | 533 | } |
1393 | 534 | ||
1394 | /** | 535 | void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], |
1395 | * stuff for 192 and 256bit encryption/decryption | 536 | const KEY_TABLE_TYPE keyTable, u8 plaintext[]) |
1396 | */ | ||
1397 | void camellia_encrypt256(const u32 *subkey, u32 *io) | ||
1398 | { | 537 | { |
1399 | u32 il,ir,t0,t1; /* temporary valiables */ | 538 | u32 s0,s1,s2,s3; |
1400 | 539 | const u32 *k = keyTable+grandRounds*16,*kend = keyTable+4; | |
1401 | /* pre whitening but absorb kw2*/ | 540 | |
1402 | io[0] ^= CamelliaSubkeyL(0); | 541 | s0 = GETU32(ciphertext) ^ k[0]; |
1403 | io[1] ^= CamelliaSubkeyR(0); | 542 | s1 = GETU32(ciphertext+4) ^ k[1]; |
1404 | 543 | s2 = GETU32(ciphertext+8) ^ k[2]; | |
1405 | /* main iteration */ | 544 | s3 = GETU32(ciphertext+12) ^ k[3]; |
1406 | CAMELLIA_ROUNDSM(io[0],io[1], | 545 | |
1407 | CamelliaSubkeyL(2),CamelliaSubkeyR(2), | 546 | while (1) |
1408 | io[2],io[3],il,ir,t0,t1); | 547 | { |
1409 | CAMELLIA_ROUNDSM(io[2],io[3], | 548 | /* Camellia makes 6 Feistel rounds */ |
1410 | CamelliaSubkeyL(3),CamelliaSubkeyR(3), | 549 | k -= 12; |
1411 | io[0],io[1],il,ir,t0,t1); | 550 | Camellia_Feistel(s0,s1,s2,s3,k+10); |
1412 | CAMELLIA_ROUNDSM(io[0],io[1], | 551 | Camellia_Feistel(s2,s3,s0,s1,k+8); |
1413 | CamelliaSubkeyL(4),CamelliaSubkeyR(4), | 552 | Camellia_Feistel(s0,s1,s2,s3,k+6); |
1414 | io[2],io[3],il,ir,t0,t1); | 553 | Camellia_Feistel(s2,s3,s0,s1,k+4); |
1415 | CAMELLIA_ROUNDSM(io[2],io[3], | 554 | Camellia_Feistel(s0,s1,s2,s3,k+2); |
1416 | CamelliaSubkeyL(5),CamelliaSubkeyR(5), | 555 | Camellia_Feistel(s2,s3,s0,s1,k+0); |
1417 | io[0],io[1],il,ir,t0,t1); | 556 | |
1418 | CAMELLIA_ROUNDSM(io[0],io[1], | 557 | if (k == kend) break; |
1419 | CamelliaSubkeyL(6),CamelliaSubkeyR(6), | 558 | |
1420 | io[2],io[3],il,ir,t0,t1); | 559 | /* This is the same function as the diffusion function D |
1421 | CAMELLIA_ROUNDSM(io[2],io[3], | 560 | * of the accompanying documentation. See section 3.2 |
1422 | CamelliaSubkeyL(7),CamelliaSubkeyR(7), | 561 | * for properties of the FLlayer function. */ |
1423 | io[0],io[1],il,ir,t0,t1); | 562 | k -= 4; |
1424 | 563 | s1 ^= LeftRotate(s0 & k[2], 1); | |
1425 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | 564 | s2 ^= s3 | k[1]; |
1426 | CamelliaSubkeyL(8),CamelliaSubkeyR(8), | 565 | s0 ^= s1 | k[3]; |
1427 | CamelliaSubkeyL(9),CamelliaSubkeyR(9), | 566 | s3 ^= LeftRotate(s2 & k[0], 1); |
1428 | t0,t1,il,ir); | 567 | } |
1429 | 568 | ||
1430 | CAMELLIA_ROUNDSM(io[0],io[1], | 569 | k -= 4; |
1431 | CamelliaSubkeyL(10),CamelliaSubkeyR(10), | 570 | s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; |
1432 | io[2],io[3],il,ir,t0,t1); | 571 | |
1433 | CAMELLIA_ROUNDSM(io[2],io[3], | 572 | PUTU32(plaintext, s2); |
1434 | CamelliaSubkeyL(11),CamelliaSubkeyR(11), | 573 | PUTU32(plaintext+4, s3); |
1435 | io[0],io[1],il,ir,t0,t1); | 574 | PUTU32(plaintext+8, s0); |
1436 | CAMELLIA_ROUNDSM(io[0],io[1], | 575 | PUTU32(plaintext+12,s1); |
1437 | CamelliaSubkeyL(12),CamelliaSubkeyR(12), | ||
1438 | io[2],io[3],il,ir,t0,t1); | ||
1439 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1440 | CamelliaSubkeyL(13),CamelliaSubkeyR(13), | ||
1441 | io[0],io[1],il,ir,t0,t1); | ||
1442 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1443 | CamelliaSubkeyL(14),CamelliaSubkeyR(14), | ||
1444 | io[2],io[3],il,ir,t0,t1); | ||
1445 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1446 | CamelliaSubkeyL(15),CamelliaSubkeyR(15), | ||
1447 | io[0],io[1],il,ir,t0,t1); | ||
1448 | |||
1449 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1450 | CamelliaSubkeyL(16),CamelliaSubkeyR(16), | ||
1451 | CamelliaSubkeyL(17),CamelliaSubkeyR(17), | ||
1452 | t0,t1,il,ir); | ||
1453 | |||
1454 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1455 | CamelliaSubkeyL(18),CamelliaSubkeyR(18), | ||
1456 | io[2],io[3],il,ir,t0,t1); | ||
1457 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1458 | CamelliaSubkeyL(19),CamelliaSubkeyR(19), | ||
1459 | io[0],io[1],il,ir,t0,t1); | ||
1460 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1461 | CamelliaSubkeyL(20),CamelliaSubkeyR(20), | ||
1462 | io[2],io[3],il,ir,t0,t1); | ||
1463 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1464 | CamelliaSubkeyL(21),CamelliaSubkeyR(21), | ||
1465 | io[0],io[1],il,ir,t0,t1); | ||
1466 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1467 | CamelliaSubkeyL(22),CamelliaSubkeyR(22), | ||
1468 | io[2],io[3],il,ir,t0,t1); | ||
1469 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1470 | CamelliaSubkeyL(23),CamelliaSubkeyR(23), | ||
1471 | io[0],io[1],il,ir,t0,t1); | ||
1472 | |||
1473 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1474 | CamelliaSubkeyL(24),CamelliaSubkeyR(24), | ||
1475 | CamelliaSubkeyL(25),CamelliaSubkeyR(25), | ||
1476 | t0,t1,il,ir); | ||
1477 | |||
1478 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1479 | CamelliaSubkeyL(26),CamelliaSubkeyR(26), | ||
1480 | io[2],io[3],il,ir,t0,t1); | ||
1481 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1482 | CamelliaSubkeyL(27),CamelliaSubkeyR(27), | ||
1483 | io[0],io[1],il,ir,t0,t1); | ||
1484 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1485 | CamelliaSubkeyL(28),CamelliaSubkeyR(28), | ||
1486 | io[2],io[3],il,ir,t0,t1); | ||
1487 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1488 | CamelliaSubkeyL(29),CamelliaSubkeyR(29), | ||
1489 | io[0],io[1],il,ir,t0,t1); | ||
1490 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1491 | CamelliaSubkeyL(30),CamelliaSubkeyR(30), | ||
1492 | io[2],io[3],il,ir,t0,t1); | ||
1493 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1494 | CamelliaSubkeyL(31),CamelliaSubkeyR(31), | ||
1495 | io[0],io[1],il,ir,t0,t1); | ||
1496 | |||
1497 | /* post whitening but kw4 */ | ||
1498 | io[2] ^= CamelliaSubkeyL(32); | ||
1499 | io[3] ^= CamelliaSubkeyR(32); | ||
1500 | |||
1501 | t0 = io[0]; | ||
1502 | t1 = io[1]; | ||
1503 | io[0] = io[2]; | ||
1504 | io[1] = io[3]; | ||
1505 | io[2] = t0; | ||
1506 | io[3] = t1; | ||
1507 | |||
1508 | return; | ||
1509 | } | 576 | } |
1510 | 577 | void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], | |
1511 | void camellia_decrypt256(const u32 *subkey, u32 *io) | 578 | const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) |
1512 | { | 579 | { |
1513 | u32 il,ir,t0,t1; /* temporary valiables */ | 580 | Camellia_DecryptBlock_Rounds(keyBitLength==128?3:4, |
1514 | 581 | plaintext,keyTable,ciphertext); | |
1515 | /* pre whitening but absorb kw2*/ | ||
1516 | io[0] ^= CamelliaSubkeyL(32); | ||
1517 | io[1] ^= CamelliaSubkeyR(32); | ||
1518 | |||
1519 | /* main iteration */ | ||
1520 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1521 | CamelliaSubkeyL(31),CamelliaSubkeyR(31), | ||
1522 | io[2],io[3],il,ir,t0,t1); | ||
1523 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1524 | CamelliaSubkeyL(30),CamelliaSubkeyR(30), | ||
1525 | io[0],io[1],il,ir,t0,t1); | ||
1526 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1527 | CamelliaSubkeyL(29),CamelliaSubkeyR(29), | ||
1528 | io[2],io[3],il,ir,t0,t1); | ||
1529 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1530 | CamelliaSubkeyL(28),CamelliaSubkeyR(28), | ||
1531 | io[0],io[1],il,ir,t0,t1); | ||
1532 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1533 | CamelliaSubkeyL(27),CamelliaSubkeyR(27), | ||
1534 | io[2],io[3],il,ir,t0,t1); | ||
1535 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1536 | CamelliaSubkeyL(26),CamelliaSubkeyR(26), | ||
1537 | io[0],io[1],il,ir,t0,t1); | ||
1538 | |||
1539 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1540 | CamelliaSubkeyL(25),CamelliaSubkeyR(25), | ||
1541 | CamelliaSubkeyL(24),CamelliaSubkeyR(24), | ||
1542 | t0,t1,il,ir); | ||
1543 | |||
1544 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1545 | CamelliaSubkeyL(23),CamelliaSubkeyR(23), | ||
1546 | io[2],io[3],il,ir,t0,t1); | ||
1547 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1548 | CamelliaSubkeyL(22),CamelliaSubkeyR(22), | ||
1549 | io[0],io[1],il,ir,t0,t1); | ||
1550 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1551 | CamelliaSubkeyL(21),CamelliaSubkeyR(21), | ||
1552 | io[2],io[3],il,ir,t0,t1); | ||
1553 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1554 | CamelliaSubkeyL(20),CamelliaSubkeyR(20), | ||
1555 | io[0],io[1],il,ir,t0,t1); | ||
1556 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1557 | CamelliaSubkeyL(19),CamelliaSubkeyR(19), | ||
1558 | io[2],io[3],il,ir,t0,t1); | ||
1559 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1560 | CamelliaSubkeyL(18),CamelliaSubkeyR(18), | ||
1561 | io[0],io[1],il,ir,t0,t1); | ||
1562 | |||
1563 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1564 | CamelliaSubkeyL(17),CamelliaSubkeyR(17), | ||
1565 | CamelliaSubkeyL(16),CamelliaSubkeyR(16), | ||
1566 | t0,t1,il,ir); | ||
1567 | |||
1568 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1569 | CamelliaSubkeyL(15),CamelliaSubkeyR(15), | ||
1570 | io[2],io[3],il,ir,t0,t1); | ||
1571 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1572 | CamelliaSubkeyL(14),CamelliaSubkeyR(14), | ||
1573 | io[0],io[1],il,ir,t0,t1); | ||
1574 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1575 | CamelliaSubkeyL(13),CamelliaSubkeyR(13), | ||
1576 | io[2],io[3],il,ir,t0,t1); | ||
1577 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1578 | CamelliaSubkeyL(12),CamelliaSubkeyR(12), | ||
1579 | io[0],io[1],il,ir,t0,t1); | ||
1580 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1581 | CamelliaSubkeyL(11),CamelliaSubkeyR(11), | ||
1582 | io[2],io[3],il,ir,t0,t1); | ||
1583 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1584 | CamelliaSubkeyL(10),CamelliaSubkeyR(10), | ||
1585 | io[0],io[1],il,ir,t0,t1); | ||
1586 | |||
1587 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1588 | CamelliaSubkeyL(9),CamelliaSubkeyR(9), | ||
1589 | CamelliaSubkeyL(8),CamelliaSubkeyR(8), | ||
1590 | t0,t1,il,ir); | ||
1591 | |||
1592 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1593 | CamelliaSubkeyL(7),CamelliaSubkeyR(7), | ||
1594 | io[2],io[3],il,ir,t0,t1); | ||
1595 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1596 | CamelliaSubkeyL(6),CamelliaSubkeyR(6), | ||
1597 | io[0],io[1],il,ir,t0,t1); | ||
1598 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1599 | CamelliaSubkeyL(5),CamelliaSubkeyR(5), | ||
1600 | io[2],io[3],il,ir,t0,t1); | ||
1601 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1602 | CamelliaSubkeyL(4),CamelliaSubkeyR(4), | ||
1603 | io[0],io[1],il,ir,t0,t1); | ||
1604 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1605 | CamelliaSubkeyL(3),CamelliaSubkeyR(3), | ||
1606 | io[2],io[3],il,ir,t0,t1); | ||
1607 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1608 | CamelliaSubkeyL(2),CamelliaSubkeyR(2), | ||
1609 | io[0],io[1],il,ir,t0,t1); | ||
1610 | |||
1611 | /* post whitening but kw4 */ | ||
1612 | io[2] ^= CamelliaSubkeyL(0); | ||
1613 | io[3] ^= CamelliaSubkeyR(0); | ||
1614 | |||
1615 | t0 = io[0]; | ||
1616 | t1 = io[1]; | ||
1617 | io[0] = io[2]; | ||
1618 | io[1] = io[3]; | ||
1619 | io[2] = t0; | ||
1620 | io[3] = t1; | ||
1621 | |||
1622 | return; | ||
1623 | } | 582 | } |
1624 | |||
diff --git a/src/lib/libcrypto/camellia/camellia.h b/src/lib/libcrypto/camellia/camellia.h index b8a8b6e10b..cf0457dd97 100644 --- a/src/lib/libcrypto/camellia/camellia.h +++ b/src/lib/libcrypto/camellia/camellia.h | |||
@@ -58,6 +58,8 @@ | |||
58 | #error CAMELLIA is disabled. | 58 | #error CAMELLIA is disabled. |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #include <stddef.h> | ||
62 | |||
61 | #define CAMELLIA_ENCRYPT 1 | 63 | #define CAMELLIA_ENCRYPT 1 |
62 | #define CAMELLIA_DECRYPT 0 | 64 | #define CAMELLIA_DECRYPT 0 |
63 | 65 | ||
@@ -74,24 +76,18 @@ extern "C" { | |||
74 | #define CAMELLIA_TABLE_BYTE_LEN 272 | 76 | #define CAMELLIA_TABLE_BYTE_LEN 272 |
75 | #define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) | 77 | #define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) |
76 | 78 | ||
77 | /* to match with WORD */ | 79 | typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */ |
78 | typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; | ||
79 | 80 | ||
80 | struct camellia_key_st | 81 | struct camellia_key_st |
81 | { | 82 | { |
82 | KEY_TABLE_TYPE rd_key; | 83 | union { |
83 | int bitLength; | 84 | double d; /* ensures 64-bit align */ |
84 | void (*enc)(const unsigned int *subkey, unsigned int *io); | 85 | KEY_TABLE_TYPE rd_key; |
85 | void (*dec)(const unsigned int *subkey, unsigned int *io); | 86 | } u; |
87 | int grand_rounds; | ||
86 | }; | 88 | }; |
87 | |||
88 | typedef struct camellia_key_st CAMELLIA_KEY; | 89 | typedef struct camellia_key_st CAMELLIA_KEY; |
89 | 90 | ||
90 | #ifdef OPENSSL_FIPS | ||
91 | int private_Camellia_set_key(const unsigned char *userKey, const int bits, | ||
92 | CAMELLIA_KEY *key); | ||
93 | #endif | ||
94 | |||
95 | int Camellia_set_key(const unsigned char *userKey, const int bits, | 91 | int Camellia_set_key(const unsigned char *userKey, const int bits, |
96 | CAMELLIA_KEY *key); | 92 | CAMELLIA_KEY *key); |
97 | 93 | ||
@@ -103,25 +99,22 @@ void Camellia_decrypt(const unsigned char *in, unsigned char *out, | |||
103 | void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, | 99 | void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, |
104 | const CAMELLIA_KEY *key, const int enc); | 100 | const CAMELLIA_KEY *key, const int enc); |
105 | void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, | 101 | void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, |
106 | const unsigned long length, const CAMELLIA_KEY *key, | 102 | size_t length, const CAMELLIA_KEY *key, |
107 | unsigned char *ivec, const int enc); | 103 | unsigned char *ivec, const int enc); |
108 | void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, | 104 | void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, |
109 | const unsigned long length, const CAMELLIA_KEY *key, | 105 | size_t length, const CAMELLIA_KEY *key, |
110 | unsigned char *ivec, int *num, const int enc); | 106 | unsigned char *ivec, int *num, const int enc); |
111 | void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, | 107 | void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, |
112 | const unsigned long length, const CAMELLIA_KEY *key, | 108 | size_t length, const CAMELLIA_KEY *key, |
113 | unsigned char *ivec, int *num, const int enc); | 109 | unsigned char *ivec, int *num, const int enc); |
114 | void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, | 110 | void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, |
115 | const unsigned long length, const CAMELLIA_KEY *key, | 111 | size_t length, const CAMELLIA_KEY *key, |
116 | unsigned char *ivec, int *num, const int enc); | 112 | unsigned char *ivec, int *num, const int enc); |
117 | void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, | ||
118 | const int nbits,const CAMELLIA_KEY *key, | ||
119 | unsigned char *ivec,const int enc); | ||
120 | void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, | 113 | void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, |
121 | const unsigned long length, const CAMELLIA_KEY *key, | 114 | size_t length, const CAMELLIA_KEY *key, |
122 | unsigned char *ivec, int *num); | 115 | unsigned char *ivec, int *num); |
123 | void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, | 116 | void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, |
124 | const unsigned long length, const CAMELLIA_KEY *key, | 117 | size_t length, const CAMELLIA_KEY *key, |
125 | unsigned char ivec[CAMELLIA_BLOCK_SIZE], | 118 | unsigned char ivec[CAMELLIA_BLOCK_SIZE], |
126 | unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], | 119 | unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], |
127 | unsigned int *num); | 120 | unsigned int *num); |
@@ -131,4 +124,3 @@ void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, | |||
131 | #endif | 124 | #endif |
132 | 125 | ||
133 | #endif /* !HEADER_Camellia_H */ | 126 | #endif /* !HEADER_Camellia_H */ |
134 | |||
diff --git a/src/lib/libcrypto/camellia/cmll_cbc.c b/src/lib/libcrypto/camellia/cmll_cbc.c index 4141a7b59b..4c8d455ade 100644 --- a/src/lib/libcrypto/camellia/cmll_cbc.c +++ b/src/lib/libcrypto/camellia/cmll_cbc.c | |||
@@ -49,225 +49,16 @@ | |||
49 | * | 49 | * |
50 | */ | 50 | */ |
51 | 51 | ||
52 | #ifndef CAMELLIA_DEBUG | ||
53 | # ifndef NDEBUG | ||
54 | # define NDEBUG | ||
55 | # endif | ||
56 | #endif | ||
57 | #include <assert.h> | ||
58 | #include <stdio.h> | ||
59 | #include <string.h> | ||
60 | |||
61 | #include <openssl/camellia.h> | 52 | #include <openssl/camellia.h> |
62 | #include "cmll_locl.h" | 53 | #include <openssl/modes.h> |
63 | 54 | ||
64 | void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, | 55 | void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, |
65 | const unsigned long length, const CAMELLIA_KEY *key, | 56 | size_t len, const CAMELLIA_KEY *key, |
66 | unsigned char *ivec, const int enc) { | 57 | unsigned char *ivec, const int enc) |
67 | 58 | { | |
68 | unsigned long n; | ||
69 | unsigned long len = length; | ||
70 | const unsigned char *iv = ivec; | ||
71 | union { u32 t32[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; | ||
72 | u8 t8 [CAMELLIA_BLOCK_SIZE]; } tmp; | ||
73 | const union { long one; char little; } camellia_endian = {1}; | ||
74 | |||
75 | |||
76 | assert(in && out && key && ivec); | ||
77 | assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc)); | ||
78 | 59 | ||
79 | if(((size_t)in|(size_t)out|(size_t)ivec) % sizeof(u32) == 0) | 60 | if (enc) |
80 | { | 61 | CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)Camellia_encrypt); |
81 | if (CAMELLIA_ENCRYPT == enc) | 62 | else |
82 | { | 63 | CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)Camellia_decrypt); |
83 | while (len >= CAMELLIA_BLOCK_SIZE) | 64 | } |
84 | { | ||
85 | XOR4WORD2((u32 *)out, | ||
86 | (u32 *)in, (u32 *)iv); | ||
87 | if (camellia_endian.little) | ||
88 | SWAP4WORD((u32 *)out); | ||
89 | key->enc(key->rd_key, (u32 *)out); | ||
90 | if (camellia_endian.little) | ||
91 | SWAP4WORD((u32 *)out); | ||
92 | iv = out; | ||
93 | len -= CAMELLIA_BLOCK_SIZE; | ||
94 | in += CAMELLIA_BLOCK_SIZE; | ||
95 | out += CAMELLIA_BLOCK_SIZE; | ||
96 | } | ||
97 | if (len) | ||
98 | { | ||
99 | for(n=0; n < len; ++n) | ||
100 | out[n] = in[n] ^ iv[n]; | ||
101 | for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
102 | out[n] = iv[n]; | ||
103 | if (camellia_endian.little) | ||
104 | SWAP4WORD((u32 *)out); | ||
105 | key->enc(key->rd_key, (u32 *)out); | ||
106 | if (camellia_endian.little) | ||
107 | SWAP4WORD((u32 *)out); | ||
108 | iv = out; | ||
109 | } | ||
110 | memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); | ||
111 | } | ||
112 | else if (in != out) | ||
113 | { | ||
114 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
115 | { | ||
116 | memcpy(out,in,CAMELLIA_BLOCK_SIZE); | ||
117 | if (camellia_endian.little) | ||
118 | SWAP4WORD((u32 *)out); | ||
119 | key->dec(key->rd_key,(u32 *)out); | ||
120 | if (camellia_endian.little) | ||
121 | SWAP4WORD((u32 *)out); | ||
122 | XOR4WORD((u32 *)out, (u32 *)iv); | ||
123 | iv = in; | ||
124 | len -= CAMELLIA_BLOCK_SIZE; | ||
125 | in += CAMELLIA_BLOCK_SIZE; | ||
126 | out += CAMELLIA_BLOCK_SIZE; | ||
127 | } | ||
128 | if (len) | ||
129 | { | ||
130 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
131 | if (camellia_endian.little) | ||
132 | SWAP4WORD(tmp.t32); | ||
133 | key->dec(key->rd_key, tmp.t32); | ||
134 | if (camellia_endian.little) | ||
135 | SWAP4WORD(tmp.t32); | ||
136 | for(n=0; n < len; ++n) | ||
137 | out[n] = tmp.t8[n] ^ iv[n]; | ||
138 | iv = in; | ||
139 | } | ||
140 | memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); | ||
141 | } | ||
142 | else /* in == out */ | ||
143 | { | ||
144 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
145 | { | ||
146 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
147 | if (camellia_endian.little) | ||
148 | SWAP4WORD((u32 *)out); | ||
149 | key->dec(key->rd_key, (u32 *)out); | ||
150 | if (camellia_endian.little) | ||
151 | SWAP4WORD((u32 *)out); | ||
152 | XOR4WORD((u32 *)out, (u32 *)ivec); | ||
153 | memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
154 | len -= CAMELLIA_BLOCK_SIZE; | ||
155 | in += CAMELLIA_BLOCK_SIZE; | ||
156 | out += CAMELLIA_BLOCK_SIZE; | ||
157 | } | ||
158 | if (len) | ||
159 | { | ||
160 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
161 | if (camellia_endian.little) | ||
162 | SWAP4WORD((u32 *)out); | ||
163 | key->dec(key->rd_key,(u32 *)out); | ||
164 | if (camellia_endian.little) | ||
165 | SWAP4WORD((u32 *)out); | ||
166 | for(n=0; n < len; ++n) | ||
167 | out[n] ^= ivec[n]; | ||
168 | for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
169 | out[n] = tmp.t8[n]; | ||
170 | memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | else /* no aligned */ | ||
175 | { | ||
176 | if (CAMELLIA_ENCRYPT == enc) | ||
177 | { | ||
178 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
179 | { | ||
180 | for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
181 | tmp.t8[n] = in[n] ^ iv[n]; | ||
182 | if (camellia_endian.little) | ||
183 | SWAP4WORD(tmp.t32); | ||
184 | key->enc(key->rd_key, tmp.t32); | ||
185 | if (camellia_endian.little) | ||
186 | SWAP4WORD(tmp.t32); | ||
187 | memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
188 | iv = out; | ||
189 | len -= CAMELLIA_BLOCK_SIZE; | ||
190 | in += CAMELLIA_BLOCK_SIZE; | ||
191 | out += CAMELLIA_BLOCK_SIZE; | ||
192 | } | ||
193 | if (len) | ||
194 | { | ||
195 | for(n=0; n < len; ++n) | ||
196 | tmp.t8[n] = in[n] ^ iv[n]; | ||
197 | for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
198 | tmp.t8[n] = iv[n]; | ||
199 | if (camellia_endian.little) | ||
200 | SWAP4WORD(tmp.t32); | ||
201 | key->enc(key->rd_key, tmp.t32); | ||
202 | if (camellia_endian.little) | ||
203 | SWAP4WORD(tmp.t32); | ||
204 | memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
205 | iv = out; | ||
206 | } | ||
207 | memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); | ||
208 | } | ||
209 | else if (in != out) | ||
210 | { | ||
211 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
212 | { | ||
213 | memcpy(tmp.t8,in,CAMELLIA_BLOCK_SIZE); | ||
214 | if (camellia_endian.little) | ||
215 | SWAP4WORD(tmp.t32); | ||
216 | key->dec(key->rd_key,tmp.t32); | ||
217 | if (camellia_endian.little) | ||
218 | SWAP4WORD(tmp.t32); | ||
219 | for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
220 | out[n] = tmp.t8[n] ^ iv[n]; | ||
221 | iv = in; | ||
222 | len -= CAMELLIA_BLOCK_SIZE; | ||
223 | in += CAMELLIA_BLOCK_SIZE; | ||
224 | out += CAMELLIA_BLOCK_SIZE; | ||
225 | } | ||
226 | if (len) | ||
227 | { | ||
228 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
229 | if (camellia_endian.little) | ||
230 | SWAP4WORD(tmp.t32); | ||
231 | key->dec(key->rd_key, tmp.t32); | ||
232 | if (camellia_endian.little) | ||
233 | SWAP4WORD(tmp.t32); | ||
234 | for(n=0; n < len; ++n) | ||
235 | out[n] = tmp.t8[n] ^ iv[n]; | ||
236 | iv = in; | ||
237 | } | ||
238 | memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
243 | { | ||
244 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
245 | if (camellia_endian.little) | ||
246 | SWAP4WORD(tmp.t32); | ||
247 | key->dec(key->rd_key, tmp.t32); | ||
248 | if (camellia_endian.little) | ||
249 | SWAP4WORD(tmp.t32); | ||
250 | for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
251 | tmp.t8[n] ^= ivec[n]; | ||
252 | memcpy(ivec, in, CAMELLIA_BLOCK_SIZE); | ||
253 | memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
254 | len -= CAMELLIA_BLOCK_SIZE; | ||
255 | in += CAMELLIA_BLOCK_SIZE; | ||
256 | out += CAMELLIA_BLOCK_SIZE; | ||
257 | } | ||
258 | if (len) | ||
259 | { | ||
260 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
261 | if (camellia_endian.little) | ||
262 | SWAP4WORD(tmp.t32); | ||
263 | key->dec(key->rd_key,tmp.t32); | ||
264 | if (camellia_endian.little) | ||
265 | SWAP4WORD(tmp.t32); | ||
266 | for(n=0; n < len; ++n) | ||
267 | tmp.t8[n] ^= ivec[n]; | ||
268 | memcpy(ivec, in, CAMELLIA_BLOCK_SIZE); | ||
269 | memcpy(out,tmp.t8,len); | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | } | ||
diff --git a/src/lib/libcrypto/camellia/cmll_cfb.c b/src/lib/libcrypto/camellia/cmll_cfb.c index af0f9f49ad..3d81b51d3f 100644 --- a/src/lib/libcrypto/camellia/cmll_cfb.c +++ b/src/lib/libcrypto/camellia/cmll_cfb.c | |||
@@ -105,17 +105,8 @@ | |||
105 | * [including the GNU Public Licence.] | 105 | * [including the GNU Public Licence.] |
106 | */ | 106 | */ |
107 | 107 | ||
108 | #ifndef CAMELLIA_DEBUG | ||
109 | # ifndef NDEBUG | ||
110 | # define NDEBUG | ||
111 | # endif | ||
112 | #endif | ||
113 | #include <assert.h> | ||
114 | #include <string.h> | ||
115 | |||
116 | #include <openssl/camellia.h> | 108 | #include <openssl/camellia.h> |
117 | #include "cmll_locl.h" | 109 | #include <openssl/modes.h> |
118 | #include "e_os.h" | ||
119 | 110 | ||
120 | 111 | ||
121 | /* The input and output encrypted as though 128bit cfb mode is being | 112 | /* The input and output encrypted as though 128bit cfb mode is being |
@@ -124,112 +115,25 @@ | |||
124 | */ | 115 | */ |
125 | 116 | ||
126 | void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, | 117 | void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, |
127 | const unsigned long length, const CAMELLIA_KEY *key, | 118 | size_t length, const CAMELLIA_KEY *key, |
128 | unsigned char *ivec, int *num, const int enc) | 119 | unsigned char *ivec, int *num, const int enc) |
129 | { | 120 | { |
130 | 121 | ||
131 | unsigned int n; | 122 | CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt); |
132 | unsigned long l = length; | ||
133 | unsigned char c; | ||
134 | |||
135 | assert(in && out && key && ivec && num); | ||
136 | |||
137 | n = *num; | ||
138 | |||
139 | if (enc) | ||
140 | { | ||
141 | while (l--) | ||
142 | { | ||
143 | if (n == 0) | ||
144 | { | ||
145 | Camellia_encrypt(ivec, ivec, key); | ||
146 | } | ||
147 | ivec[n] = *(out++) = *(in++) ^ ivec[n]; | ||
148 | n = (n+1) % CAMELLIA_BLOCK_SIZE; | ||
149 | } | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | while (l--) | ||
154 | { | ||
155 | if (n == 0) | ||
156 | { | ||
157 | Camellia_encrypt(ivec, ivec, key); | ||
158 | } | ||
159 | c = *(in); | ||
160 | *(out++) = *(in++) ^ ivec[n]; | ||
161 | ivec[n] = c; | ||
162 | n = (n+1) % CAMELLIA_BLOCK_SIZE; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | *num=n; | ||
167 | } | ||
168 | |||
169 | /* This expects a single block of size nbits for both in and out. Note that | ||
170 | it corrupts any extra bits in the last byte of out */ | ||
171 | void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, | ||
172 | const int nbits,const CAMELLIA_KEY *key, | ||
173 | unsigned char *ivec,const int enc) | ||
174 | { | ||
175 | int n,rem,num; | ||
176 | unsigned char ovec[CAMELLIA_BLOCK_SIZE*2]; | ||
177 | |||
178 | if (nbits<=0 || nbits>128) return; | ||
179 | |||
180 | /* fill in the first half of the new IV with the current IV */ | ||
181 | memcpy(ovec,ivec,CAMELLIA_BLOCK_SIZE); | ||
182 | /* construct the new IV */ | ||
183 | Camellia_encrypt(ivec,ivec,key); | ||
184 | num = (nbits+7)/8; | ||
185 | if (enc) /* encrypt the input */ | ||
186 | for(n=0 ; n < num ; ++n) | ||
187 | out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n] ^ ivec[n]); | ||
188 | else /* decrypt the input */ | ||
189 | for(n=0 ; n < num ; ++n) | ||
190 | out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n]) ^ ivec[n]; | ||
191 | /* shift ovec left... */ | ||
192 | rem = nbits%8; | ||
193 | num = nbits/8; | ||
194 | if(rem==0) | ||
195 | memcpy(ivec,ovec+num,CAMELLIA_BLOCK_SIZE); | ||
196 | else | ||
197 | for(n=0 ; n < CAMELLIA_BLOCK_SIZE ; ++n) | ||
198 | ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem); | ||
199 | |||
200 | /* it is not necessary to cleanse ovec, since the IV is not secret */ | ||
201 | } | 123 | } |
202 | 124 | ||
203 | /* N.B. This expects the input to be packed, MS bit first */ | 125 | /* N.B. This expects the input to be packed, MS bit first */ |
204 | void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, | 126 | void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, |
205 | const unsigned long length, const CAMELLIA_KEY *key, | 127 | size_t length, const CAMELLIA_KEY *key, |
206 | unsigned char *ivec, int *num, const int enc) | 128 | unsigned char *ivec, int *num, const int enc) |
207 | { | 129 | { |
208 | unsigned int n; | 130 | CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt); |
209 | unsigned char c[1],d[1]; | ||
210 | |||
211 | assert(in && out && key && ivec && num); | ||
212 | assert(*num == 0); | ||
213 | |||
214 | memset(out,0,(length+7)/8); | ||
215 | for(n=0 ; n < length ; ++n) | ||
216 | { | ||
217 | c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; | ||
218 | Camellia_cfbr_encrypt_block(c,d,1,key,ivec,enc); | ||
219 | out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8)); | ||
220 | } | ||
221 | } | 131 | } |
222 | 132 | ||
223 | void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, | 133 | void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, |
224 | const unsigned long length, const CAMELLIA_KEY *key, | 134 | size_t length, const CAMELLIA_KEY *key, |
225 | unsigned char *ivec, int *num, const int enc) | 135 | unsigned char *ivec, int *num, const int enc) |
226 | { | 136 | { |
227 | unsigned int n; | 137 | CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt); |
228 | |||
229 | assert(in && out && key && ivec && num); | ||
230 | assert(*num == 0); | ||
231 | |||
232 | for(n=0 ; n < length ; ++n) | ||
233 | Camellia_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc); | ||
234 | } | 138 | } |
235 | 139 | ||
diff --git a/src/lib/libcrypto/camellia/cmll_ctr.c b/src/lib/libcrypto/camellia/cmll_ctr.c index cc21b70890..014e621a34 100644 --- a/src/lib/libcrypto/camellia/cmll_ctr.c +++ b/src/lib/libcrypto/camellia/cmll_ctr.c | |||
@@ -49,95 +49,16 @@ | |||
49 | * | 49 | * |
50 | */ | 50 | */ |
51 | 51 | ||
52 | #ifndef CAMELLIA_DEBUG | ||
53 | # ifndef NDEBUG | ||
54 | # define NDEBUG | ||
55 | # endif | ||
56 | #endif | ||
57 | #include <assert.h> | ||
58 | |||
59 | #include <openssl/camellia.h> | 52 | #include <openssl/camellia.h> |
60 | #include "cmll_locl.h" | 53 | #include <openssl/modes.h> |
61 | |||
62 | /* NOTE: the IV/counter CTR mode is big-endian. The rest of the Camellia code | ||
63 | * is endian-neutral. */ | ||
64 | /* increment counter (128-bit int) by 1 */ | ||
65 | static void Camellia_ctr128_inc(unsigned char *counter) | ||
66 | { | ||
67 | unsigned long c; | ||
68 | |||
69 | /* Grab bottom dword of counter and increment */ | ||
70 | c = GETU32(counter + 12); | ||
71 | c++; c &= 0xFFFFFFFF; | ||
72 | PUTU32(counter + 12, c); | ||
73 | |||
74 | /* if no overflow, we're done */ | ||
75 | if (c) | ||
76 | return; | ||
77 | |||
78 | /* Grab 1st dword of counter and increment */ | ||
79 | c = GETU32(counter + 8); | ||
80 | c++; c &= 0xFFFFFFFF; | ||
81 | PUTU32(counter + 8, c); | ||
82 | |||
83 | /* if no overflow, we're done */ | ||
84 | if (c) | ||
85 | return; | ||
86 | |||
87 | /* Grab 2nd dword of counter and increment */ | ||
88 | c = GETU32(counter + 4); | ||
89 | c++; c &= 0xFFFFFFFF; | ||
90 | PUTU32(counter + 4, c); | ||
91 | |||
92 | /* if no overflow, we're done */ | ||
93 | if (c) | ||
94 | return; | ||
95 | 54 | ||
96 | /* Grab top dword of counter and increment */ | ||
97 | c = GETU32(counter + 0); | ||
98 | c++; c &= 0xFFFFFFFF; | ||
99 | PUTU32(counter + 0, c); | ||
100 | } | ||
101 | |||
102 | /* The input encrypted as though 128bit counter mode is being | ||
103 | * used. The extra state information to record how much of the | ||
104 | * 128bit block we have used is contained in *num, and the | ||
105 | * encrypted counter is kept in ecount_buf. Both *num and | ||
106 | * ecount_buf must be initialised with zeros before the first | ||
107 | * call to Camellia_ctr128_encrypt(). | ||
108 | * | ||
109 | * This algorithm assumes that the counter is in the x lower bits | ||
110 | * of the IV (ivec), and that the application has full control over | ||
111 | * overflow and the rest of the IV. This implementation takes NO | ||
112 | * responsability for checking that the counter doesn't overflow | ||
113 | * into the rest of the IV when incremented. | ||
114 | */ | ||
115 | void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, | 55 | void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, |
116 | const unsigned long length, const CAMELLIA_KEY *key, | 56 | size_t length, const CAMELLIA_KEY *key, |
117 | unsigned char ivec[CAMELLIA_BLOCK_SIZE], | 57 | unsigned char ivec[CAMELLIA_BLOCK_SIZE], |
118 | unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], | 58 | unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], |
119 | unsigned int *num) | 59 | unsigned int *num) |
120 | { | 60 | { |
121 | 61 | ||
122 | unsigned int n; | 62 | CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)Camellia_encrypt); |
123 | unsigned long l=length; | ||
124 | |||
125 | assert(in && out && key && counter && num); | ||
126 | assert(*num < CAMELLIA_BLOCK_SIZE); | ||
127 | |||
128 | n = *num; | ||
129 | |||
130 | while (l--) | ||
131 | { | ||
132 | if (n == 0) | ||
133 | { | ||
134 | Camellia_encrypt(ivec, ecount_buf, key); | ||
135 | Camellia_ctr128_inc(ivec); | ||
136 | } | ||
137 | *(out++) = *(in++) ^ ecount_buf[n]; | ||
138 | n = (n+1) % CAMELLIA_BLOCK_SIZE; | ||
139 | } | ||
140 | |||
141 | *num=n; | ||
142 | } | 63 | } |
143 | 64 | ||
diff --git a/src/lib/libcrypto/camellia/cmll_locl.h b/src/lib/libcrypto/camellia/cmll_locl.h index 2ac2e95435..4a4d880d16 100644 --- a/src/lib/libcrypto/camellia/cmll_locl.h +++ b/src/lib/libcrypto/camellia/cmll_locl.h | |||
@@ -68,98 +68,16 @@ | |||
68 | #ifndef HEADER_CAMELLIA_LOCL_H | 68 | #ifndef HEADER_CAMELLIA_LOCL_H |
69 | #define HEADER_CAMELLIA_LOCL_H | 69 | #define HEADER_CAMELLIA_LOCL_H |
70 | 70 | ||
71 | #include "openssl/e_os2.h" | 71 | typedef unsigned int u32; |
72 | #include <stdio.h> | ||
73 | #include <stdlib.h> | ||
74 | #include <string.h> | ||
75 | |||
76 | typedef unsigned char u8; | 72 | typedef unsigned char u8; |
77 | typedef unsigned int u32; | ||
78 | |||
79 | #ifdef __cplusplus | ||
80 | extern "C" { | ||
81 | #endif | ||
82 | |||
83 | #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) | ||
84 | # define SWAP(x) ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00 ) | ||
85 | # define GETU32(p) SWAP(*((u32 *)(p))) | ||
86 | # define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } | ||
87 | # define CAMELLIA_SWAP4(x) (x = ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) ) | ||
88 | |||
89 | #else /* not windows */ | ||
90 | # define GETU32(pt) (((u32)(pt)[0] << 24) \ | ||
91 | ^ ((u32)(pt)[1] << 16) \ | ||
92 | ^ ((u32)(pt)[2] << 8) \ | ||
93 | ^ ((u32)(pt)[3])) | ||
94 | |||
95 | # define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); \ | ||
96 | (ct)[1] = (u8)((st) >> 16); \ | ||
97 | (ct)[2] = (u8)((st) >> 8); \ | ||
98 | (ct)[3] = (u8)(st); } | ||
99 | |||
100 | #if (defined (__GNUC__) && (defined(__x86_64__) || defined(__x86_64))) | ||
101 | #define CAMELLIA_SWAP4(x) \ | ||
102 | do{\ | ||
103 | asm("bswap %1" : "+r" (x));\ | ||
104 | }while(0) | ||
105 | #else | ||
106 | #define CAMELLIA_SWAP4(x) \ | ||
107 | do{\ | ||
108 | x = ((u32)x << 16) + ((u32)x >> 16);\ | ||
109 | x = (((u32)x & 0xff00ff) << 8) + (((u32)x >> 8) & 0xff00ff);\ | ||
110 | } while(0) | ||
111 | #endif | ||
112 | #endif | ||
113 | |||
114 | #define COPY4WORD(dst, src) \ | ||
115 | do \ | ||
116 | { \ | ||
117 | (dst)[0]=(src)[0]; \ | ||
118 | (dst)[1]=(src)[1]; \ | ||
119 | (dst)[2]=(src)[2]; \ | ||
120 | (dst)[3]=(src)[3]; \ | ||
121 | }while(0) | ||
122 | |||
123 | #define SWAP4WORD(word) \ | ||
124 | do \ | ||
125 | { \ | ||
126 | CAMELLIA_SWAP4((word)[0]); \ | ||
127 | CAMELLIA_SWAP4((word)[1]); \ | ||
128 | CAMELLIA_SWAP4((word)[2]); \ | ||
129 | CAMELLIA_SWAP4((word)[3]); \ | ||
130 | }while(0) | ||
131 | |||
132 | #define XOR4WORD(a, b)/* a = a ^ b */ \ | ||
133 | do \ | ||
134 | { \ | ||
135 | (a)[0]^=(b)[0]; \ | ||
136 | (a)[1]^=(b)[1]; \ | ||
137 | (a)[2]^=(b)[2]; \ | ||
138 | (a)[3]^=(b)[3]; \ | ||
139 | }while(0) | ||
140 | |||
141 | #define XOR4WORD2(a, b, c)/* a = b ^ c */ \ | ||
142 | do \ | ||
143 | { \ | ||
144 | (a)[0]=(b)[0]^(c)[0]; \ | ||
145 | (a)[1]=(b)[1]^(c)[1]; \ | ||
146 | (a)[2]=(b)[2]^(c)[2]; \ | ||
147 | (a)[3]=(b)[3]^(c)[3]; \ | ||
148 | }while(0) | ||
149 | |||
150 | |||
151 | void camellia_setup128(const u8 *key, u32 *subkey); | ||
152 | void camellia_setup192(const u8 *key, u32 *subkey); | ||
153 | void camellia_setup256(const u8 *key, u32 *subkey); | ||
154 | |||
155 | void camellia_encrypt128(const u32 *subkey, u32 *io); | ||
156 | void camellia_decrypt128(const u32 *subkey, u32 *io); | ||
157 | void camellia_encrypt256(const u32 *subkey, u32 *io); | ||
158 | void camellia_decrypt256(const u32 *subkey, u32 *io); | ||
159 | |||
160 | #ifdef __cplusplus | ||
161 | } | ||
162 | #endif | ||
163 | 73 | ||
74 | int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE keyTable); | ||
75 | void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], | ||
76 | const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); | ||
77 | void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], | ||
78 | const KEY_TABLE_TYPE keyTable, u8 plaintext[]); | ||
79 | void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], | ||
80 | const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); | ||
81 | void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], | ||
82 | const KEY_TABLE_TYPE keyTable, u8 plaintext[]); | ||
164 | #endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ | 83 | #endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ |
165 | |||
diff --git a/src/lib/libcrypto/camellia/cmll_misc.c b/src/lib/libcrypto/camellia/cmll_misc.c index 2cd7aba9bb..f44689124b 100644 --- a/src/lib/libcrypto/camellia/cmll_misc.c +++ b/src/lib/libcrypto/camellia/cmll_misc.c | |||
@@ -52,78 +52,28 @@ | |||
52 | #include <openssl/opensslv.h> | 52 | #include <openssl/opensslv.h> |
53 | #include <openssl/camellia.h> | 53 | #include <openssl/camellia.h> |
54 | #include "cmll_locl.h" | 54 | #include "cmll_locl.h" |
55 | #include <openssl/crypto.h> | ||
56 | #ifdef OPENSSL_FIPS | ||
57 | #include <openssl/fips.h> | ||
58 | #endif | ||
59 | 55 | ||
60 | const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT; | 56 | const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT; |
61 | 57 | ||
62 | int Camellia_set_key(const unsigned char *userKey, const int bits, | 58 | int Camellia_set_key(const unsigned char *userKey, const int bits, |
63 | CAMELLIA_KEY *key) | 59 | CAMELLIA_KEY *key) |
64 | #ifdef OPENSSL_FIPS | ||
65 | { | 60 | { |
66 | if (FIPS_mode()) | 61 | if(!userKey || !key) |
67 | FIPS_BAD_ABORT(CAMELLIA) | ||
68 | return private_Camellia_set_key(userKey, bits, key); | ||
69 | } | ||
70 | int private_Camellia_set_key(const unsigned char *userKey, const int bits, | ||
71 | CAMELLIA_KEY *key) | ||
72 | #endif | ||
73 | { | ||
74 | if (!userKey || !key) | ||
75 | { | ||
76 | return -1; | 62 | return -1; |
77 | } | 63 | if(bits != 128 && bits != 192 && bits != 256) |
78 | |||
79 | switch(bits) | ||
80 | { | ||
81 | case 128: | ||
82 | camellia_setup128(userKey, (unsigned int *)key->rd_key); | ||
83 | key->enc = camellia_encrypt128; | ||
84 | key->dec = camellia_decrypt128; | ||
85 | break; | ||
86 | case 192: | ||
87 | camellia_setup192(userKey, (unsigned int *)key->rd_key); | ||
88 | key->enc = camellia_encrypt256; | ||
89 | key->dec = camellia_decrypt256; | ||
90 | break; | ||
91 | case 256: | ||
92 | camellia_setup256(userKey, (unsigned int *)key->rd_key); | ||
93 | key->enc = camellia_encrypt256; | ||
94 | key->dec = camellia_decrypt256; | ||
95 | break; | ||
96 | default: | ||
97 | return -2; | 64 | return -2; |
98 | } | 65 | key->grand_rounds = Camellia_Ekeygen(bits , userKey, key->u.rd_key); |
99 | |||
100 | key->bitLength = bits; | ||
101 | return 0; | 66 | return 0; |
102 | } | 67 | } |
103 | 68 | ||
104 | void Camellia_encrypt(const unsigned char *in, unsigned char *out, | 69 | void Camellia_encrypt(const unsigned char *in, unsigned char *out, |
105 | const CAMELLIA_KEY *key) | 70 | const CAMELLIA_KEY *key) |
106 | { | 71 | { |
107 | u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; | 72 | Camellia_EncryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out); |
108 | const union { long one; char little; } camellia_endian = {1}; | ||
109 | |||
110 | memcpy(tmp, in, CAMELLIA_BLOCK_SIZE); | ||
111 | if (camellia_endian.little) SWAP4WORD(tmp); | ||
112 | key->enc(key->rd_key, tmp); | ||
113 | if (camellia_endian.little) SWAP4WORD(tmp); | ||
114 | memcpy(out, tmp, CAMELLIA_BLOCK_SIZE); | ||
115 | } | 73 | } |
116 | 74 | ||
117 | void Camellia_decrypt(const unsigned char *in, unsigned char *out, | 75 | void Camellia_decrypt(const unsigned char *in, unsigned char *out, |
118 | const CAMELLIA_KEY *key) | 76 | const CAMELLIA_KEY *key) |
119 | { | 77 | { |
120 | u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; | 78 | Camellia_DecryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out); |
121 | const union { long one; char little; } camellia_endian = {1}; | ||
122 | |||
123 | memcpy(tmp, in, CAMELLIA_BLOCK_SIZE); | ||
124 | if (camellia_endian.little) SWAP4WORD(tmp); | ||
125 | key->dec(key->rd_key, tmp); | ||
126 | if (camellia_endian.little) SWAP4WORD(tmp); | ||
127 | memcpy(out, tmp, CAMELLIA_BLOCK_SIZE); | ||
128 | } | 79 | } |
129 | |||
diff --git a/src/lib/libcrypto/camellia/cmll_ofb.c b/src/lib/libcrypto/camellia/cmll_ofb.c index d89cf9f3b3..a482befc74 100644 --- a/src/lib/libcrypto/camellia/cmll_ofb.c +++ b/src/lib/libcrypto/camellia/cmll_ofb.c | |||
@@ -105,37 +105,15 @@ | |||
105 | * [including the GNU Public Licence.] | 105 | * [including the GNU Public Licence.] |
106 | */ | 106 | */ |
107 | 107 | ||
108 | #ifndef CAMELLIA_DEBUG | ||
109 | # ifndef NDEBUG | ||
110 | # define NDEBUG | ||
111 | # endif | ||
112 | #endif | ||
113 | #include <assert.h> | ||
114 | #include <openssl/camellia.h> | 108 | #include <openssl/camellia.h> |
115 | #include "cmll_locl.h" | 109 | #include <openssl/modes.h> |
116 | 110 | ||
117 | /* The input and output encrypted as though 128bit ofb mode is being | 111 | /* The input and output encrypted as though 128bit ofb mode is being |
118 | * used. The extra state information to record how much of the | 112 | * used. The extra state information to record how much of the |
119 | * 128bit block we have used is contained in *num; | 113 | * 128bit block we have used is contained in *num; |
120 | */ | 114 | */ |
121 | void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, | 115 | void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, |
122 | const unsigned long length, const CAMELLIA_KEY *key, | 116 | size_t length, const CAMELLIA_KEY *key, |
123 | unsigned char *ivec, int *num) { | 117 | unsigned char *ivec, int *num) { |
124 | 118 | CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)Camellia_encrypt); | |
125 | unsigned int n; | ||
126 | unsigned long l=length; | ||
127 | |||
128 | assert(in && out && key && ivec && num); | ||
129 | |||
130 | n = *num; | ||
131 | |||
132 | while (l--) { | ||
133 | if (n == 0) { | ||
134 | Camellia_encrypt(ivec, ivec, key); | ||
135 | } | ||
136 | *(out++) = *(in++) ^ ivec[n]; | ||
137 | n = (n+1) % CAMELLIA_BLOCK_SIZE; | ||
138 | } | ||
139 | |||
140 | *num=n; | ||
141 | } | 119 | } |
diff --git a/src/lib/libcrypto/cms/cms.h b/src/lib/libcrypto/cms/cms.h index 25f88745f2..09c45d0412 100644 --- a/src/lib/libcrypto/cms/cms.h +++ b/src/lib/libcrypto/cms/cms.h | |||
@@ -76,8 +76,9 @@ typedef struct CMS_Receipt_st CMS_Receipt; | |||
76 | 76 | ||
77 | DECLARE_STACK_OF(CMS_SignerInfo) | 77 | DECLARE_STACK_OF(CMS_SignerInfo) |
78 | DECLARE_STACK_OF(GENERAL_NAMES) | 78 | DECLARE_STACK_OF(GENERAL_NAMES) |
79 | DECLARE_ASN1_FUNCTIONS_const(CMS_ContentInfo) | 79 | DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) |
80 | DECLARE_ASN1_FUNCTIONS_const(CMS_ReceiptRequest) | 80 | DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) |
81 | DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) | ||
81 | 82 | ||
82 | #define CMS_SIGNERINFO_ISSUER_SERIAL 0 | 83 | #define CMS_SIGNERINFO_ISSUER_SERIAL 0 |
83 | #define CMS_SIGNERINFO_KEYIDENTIFIER 1 | 84 | #define CMS_SIGNERINFO_KEYIDENTIFIER 1 |
@@ -124,9 +125,13 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached); | |||
124 | DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) | 125 | DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) |
125 | #endif | 126 | #endif |
126 | 127 | ||
128 | int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); | ||
127 | CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); | 129 | CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); |
128 | int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); | 130 | int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); |
129 | 131 | ||
132 | BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); | ||
133 | int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); | ||
134 | int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); | ||
130 | CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); | 135 | CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); |
131 | int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); | 136 | int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); |
132 | 137 | ||
@@ -230,6 +235,7 @@ STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); | |||
230 | 235 | ||
231 | CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); | 236 | CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); |
232 | int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); | 237 | int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); |
238 | int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); | ||
233 | STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); | 239 | STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); |
234 | 240 | ||
235 | int CMS_SignedData_init(CMS_ContentInfo *cms); | 241 | int CMS_SignedData_init(CMS_ContentInfo *cms); |
diff --git a/src/lib/libcrypto/cms/cms_asn1.c b/src/lib/libcrypto/cms/cms_asn1.c index 7664921861..fcba4dcbcc 100644 --- a/src/lib/libcrypto/cms/cms_asn1.c +++ b/src/lib/libcrypto/cms/cms_asn1.c | |||
@@ -87,7 +87,8 @@ ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = { | |||
87 | } ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo) | 87 | } ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo) |
88 | 88 | ||
89 | /* Minor tweak to operation: free up signer key, cert */ | 89 | /* Minor tweak to operation: free up signer key, cert */ |
90 | static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) | 90 | static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, |
91 | void *exarg) | ||
91 | { | 92 | { |
92 | if(operation == ASN1_OP_FREE_POST) | 93 | if(operation == ASN1_OP_FREE_POST) |
93 | { | 94 | { |
@@ -130,8 +131,8 @@ ASN1_NDEF_SEQUENCE(CMS_SignedData) = { | |||
130 | } ASN1_NDEF_SEQUENCE_END(CMS_SignedData) | 131 | } ASN1_NDEF_SEQUENCE_END(CMS_SignedData) |
131 | 132 | ||
132 | ASN1_SEQUENCE(CMS_OriginatorInfo) = { | 133 | ASN1_SEQUENCE(CMS_OriginatorInfo) = { |
133 | ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0), | 134 | ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0), |
134 | ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1) | 135 | ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1) |
135 | } ASN1_SEQUENCE_END(CMS_OriginatorInfo) | 136 | } ASN1_SEQUENCE_END(CMS_OriginatorInfo) |
136 | 137 | ||
137 | ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { | 138 | ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { |
@@ -213,7 +214,8 @@ ASN1_SEQUENCE(CMS_OtherRecipientInfo) = { | |||
213 | } ASN1_SEQUENCE_END(CMS_OtherRecipientInfo) | 214 | } ASN1_SEQUENCE_END(CMS_OtherRecipientInfo) |
214 | 215 | ||
215 | /* Free up RecipientInfo additional data */ | 216 | /* Free up RecipientInfo additional data */ |
216 | static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) | 217 | static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, |
218 | void *exarg) | ||
217 | { | 219 | { |
218 | if(operation == ASN1_OP_FREE_PRE) | 220 | if(operation == ASN1_OP_FREE_PRE) |
219 | { | 221 | { |
@@ -300,10 +302,42 @@ ASN1_ADB(CMS_ContentInfo) = { | |||
300 | ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), | 302 | ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), |
301 | } ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); | 303 | } ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); |
302 | 304 | ||
303 | ASN1_NDEF_SEQUENCE(CMS_ContentInfo) = { | 305 | /* CMS streaming support */ |
306 | static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, | ||
307 | void *exarg) | ||
308 | { | ||
309 | ASN1_STREAM_ARG *sarg = exarg; | ||
310 | CMS_ContentInfo *cms = NULL; | ||
311 | if (pval) | ||
312 | cms = (CMS_ContentInfo *)*pval; | ||
313 | else | ||
314 | return 1; | ||
315 | switch(operation) | ||
316 | { | ||
317 | |||
318 | case ASN1_OP_STREAM_PRE: | ||
319 | if (CMS_stream(&sarg->boundary, cms) <= 0) | ||
320 | return 0; | ||
321 | case ASN1_OP_DETACHED_PRE: | ||
322 | sarg->ndef_bio = CMS_dataInit(cms, sarg->out); | ||
323 | if (!sarg->ndef_bio) | ||
324 | return 0; | ||
325 | break; | ||
326 | |||
327 | case ASN1_OP_STREAM_POST: | ||
328 | case ASN1_OP_DETACHED_POST: | ||
329 | if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0) | ||
330 | return 0; | ||
331 | break; | ||
332 | |||
333 | } | ||
334 | return 1; | ||
335 | } | ||
336 | |||
337 | ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = { | ||
304 | ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT), | 338 | ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT), |
305 | ASN1_ADB_OBJECT(CMS_ContentInfo) | 339 | ASN1_ADB_OBJECT(CMS_ContentInfo) |
306 | } ASN1_NDEF_SEQUENCE_END(CMS_ContentInfo) | 340 | } ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo) |
307 | 341 | ||
308 | /* Specials for signed attributes */ | 342 | /* Specials for signed attributes */ |
309 | 343 | ||
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c index d499ae85b4..b3237d4b94 100644 --- a/src/lib/libcrypto/cms/cms_env.c +++ b/src/lib/libcrypto/cms/cms_env.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #include <openssl/rand.h> | 60 | #include <openssl/rand.h> |
61 | #include <openssl/aes.h> | 61 | #include <openssl/aes.h> |
62 | #include "cms_lcl.h" | 62 | #include "cms_lcl.h" |
63 | #include "asn1_locl.h" | ||
63 | 64 | ||
64 | /* CMS EnvelopedData Utilities */ | 65 | /* CMS EnvelopedData Utilities */ |
65 | 66 | ||
@@ -151,7 +152,7 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, | |||
151 | CMS_KeyTransRecipientInfo *ktri; | 152 | CMS_KeyTransRecipientInfo *ktri; |
152 | CMS_EnvelopedData *env; | 153 | CMS_EnvelopedData *env; |
153 | EVP_PKEY *pk = NULL; | 154 | EVP_PKEY *pk = NULL; |
154 | int type; | 155 | int i, type; |
155 | env = cms_get0_enveloped(cms); | 156 | env = cms_get0_enveloped(cms); |
156 | if (!env) | 157 | if (!env) |
157 | goto err; | 158 | goto err; |
@@ -200,21 +201,22 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, | |||
200 | if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) | 201 | if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) |
201 | goto err; | 202 | goto err; |
202 | 203 | ||
203 | /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, | 204 | if (pk->ameth && pk->ameth->pkey_ctrl) |
204 | * hard code algorithm parameters. | ||
205 | */ | ||
206 | |||
207 | if (pk->type == EVP_PKEY_RSA) | ||
208 | { | ||
209 | X509_ALGOR_set0(ktri->keyEncryptionAlgorithm, | ||
210 | OBJ_nid2obj(NID_rsaEncryption), | ||
211 | V_ASN1_NULL, 0); | ||
212 | } | ||
213 | else | ||
214 | { | 205 | { |
215 | CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, | 206 | i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE, |
207 | 0, ri); | ||
208 | if (i == -2) | ||
209 | { | ||
210 | CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, | ||
216 | CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); | 211 | CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); |
217 | goto err; | 212 | goto err; |
213 | } | ||
214 | if (i <= 0) | ||
215 | { | ||
216 | CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, | ||
217 | CMS_R_CTRL_FAILURE); | ||
218 | goto err; | ||
219 | } | ||
218 | } | 220 | } |
219 | 221 | ||
220 | if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) | 222 | if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) |
@@ -301,8 +303,9 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, | |||
301 | { | 303 | { |
302 | CMS_KeyTransRecipientInfo *ktri; | 304 | CMS_KeyTransRecipientInfo *ktri; |
303 | CMS_EncryptedContentInfo *ec; | 305 | CMS_EncryptedContentInfo *ec; |
306 | EVP_PKEY_CTX *pctx = NULL; | ||
304 | unsigned char *ek = NULL; | 307 | unsigned char *ek = NULL; |
305 | int eklen; | 308 | size_t eklen; |
306 | 309 | ||
307 | int ret = 0; | 310 | int ret = 0; |
308 | 311 | ||
@@ -315,7 +318,22 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, | |||
315 | ktri = ri->d.ktri; | 318 | ktri = ri->d.ktri; |
316 | ec = cms->d.envelopedData->encryptedContentInfo; | 319 | ec = cms->d.envelopedData->encryptedContentInfo; |
317 | 320 | ||
318 | eklen = EVP_PKEY_size(ktri->pkey); | 321 | pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); |
322 | if (!pctx) | ||
323 | return 0; | ||
324 | |||
325 | if (EVP_PKEY_encrypt_init(pctx) <= 0) | ||
326 | goto err; | ||
327 | |||
328 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, | ||
329 | EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) | ||
330 | { | ||
331 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); | ||
332 | goto err; | ||
333 | } | ||
334 | |||
335 | if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) | ||
336 | goto err; | ||
319 | 337 | ||
320 | ek = OPENSSL_malloc(eklen); | 338 | ek = OPENSSL_malloc(eklen); |
321 | 339 | ||
@@ -326,9 +344,7 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, | |||
326 | goto err; | 344 | goto err; |
327 | } | 345 | } |
328 | 346 | ||
329 | eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey); | 347 | if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) |
330 | |||
331 | if (eklen <= 0) | ||
332 | goto err; | 348 | goto err; |
333 | 349 | ||
334 | ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); | 350 | ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); |
@@ -337,6 +353,8 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, | |||
337 | ret = 1; | 353 | ret = 1; |
338 | 354 | ||
339 | err: | 355 | err: |
356 | if (pctx) | ||
357 | EVP_PKEY_CTX_free(pctx); | ||
340 | if (ek) | 358 | if (ek) |
341 | OPENSSL_free(ek); | 359 | OPENSSL_free(ek); |
342 | return ret; | 360 | return ret; |
@@ -349,8 +367,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, | |||
349 | CMS_RecipientInfo *ri) | 367 | CMS_RecipientInfo *ri) |
350 | { | 368 | { |
351 | CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; | 369 | CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; |
370 | EVP_PKEY_CTX *pctx = NULL; | ||
352 | unsigned char *ek = NULL; | 371 | unsigned char *ek = NULL; |
353 | int eklen; | 372 | size_t eklen; |
354 | int ret = 0; | 373 | int ret = 0; |
355 | 374 | ||
356 | if (ktri->pkey == NULL) | 375 | if (ktri->pkey == NULL) |
@@ -360,7 +379,24 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, | |||
360 | return 0; | 379 | return 0; |
361 | } | 380 | } |
362 | 381 | ||
363 | eklen = EVP_PKEY_size(ktri->pkey); | 382 | pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); |
383 | if (!pctx) | ||
384 | return 0; | ||
385 | |||
386 | if (EVP_PKEY_decrypt_init(pctx) <= 0) | ||
387 | goto err; | ||
388 | |||
389 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, | ||
390 | EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) | ||
391 | { | ||
392 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); | ||
393 | goto err; | ||
394 | } | ||
395 | |||
396 | if (EVP_PKEY_decrypt(pctx, NULL, &eklen, | ||
397 | ktri->encryptedKey->data, | ||
398 | ktri->encryptedKey->length) <= 0) | ||
399 | goto err; | ||
364 | 400 | ||
365 | ek = OPENSSL_malloc(eklen); | 401 | ek = OPENSSL_malloc(eklen); |
366 | 402 | ||
@@ -371,10 +407,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, | |||
371 | goto err; | 407 | goto err; |
372 | } | 408 | } |
373 | 409 | ||
374 | eklen = EVP_PKEY_decrypt(ek, | 410 | if (EVP_PKEY_decrypt(pctx, ek, &eklen, |
375 | ktri->encryptedKey->data, | 411 | ktri->encryptedKey->data, |
376 | ktri->encryptedKey->length, ktri->pkey); | 412 | ktri->encryptedKey->length) <= 0) |
377 | if (eklen <= 0) | ||
378 | { | 413 | { |
379 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); | 414 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); |
380 | goto err; | 415 | goto err; |
@@ -386,6 +421,8 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, | |||
386 | cms->d.envelopedData->encryptedContentInfo->keylen = eklen; | 421 | cms->d.envelopedData->encryptedContentInfo->keylen = eklen; |
387 | 422 | ||
388 | err: | 423 | err: |
424 | if (pctx) | ||
425 | EVP_PKEY_CTX_free(pctx); | ||
389 | if (!ret && ek) | 426 | if (!ret && ek) |
390 | OPENSSL_free(ek); | 427 | OPENSSL_free(ek); |
391 | 428 | ||
diff --git a/src/lib/libcrypto/cms/cms_err.c b/src/lib/libcrypto/cms/cms_err.c index 52fa53954f..ff7b0309e5 100644 --- a/src/lib/libcrypto/cms/cms_err.c +++ b/src/lib/libcrypto/cms/cms_err.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* crypto/cms/cms_err.c */ | 1 | /* crypto/cms/cms_err.c */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions | 6 | * modification, are permitted provided that the following conditions |
@@ -133,7 +133,7 @@ static ERR_STRING_DATA CMS_str_functs[]= | |||
133 | {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), "CMS_SIGNERINFO_VERIFY_CERT"}, | 133 | {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), "CMS_SIGNERINFO_VERIFY_CERT"}, |
134 | {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), "CMS_SignerInfo_verify_content"}, | 134 | {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), "CMS_SignerInfo_verify_content"}, |
135 | {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"}, | 135 | {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"}, |
136 | {ERR_FUNC(CMS_F_CMS_STREAM), "CMS_STREAM"}, | 136 | {ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"}, |
137 | {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"}, | 137 | {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"}, |
138 | {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"}, | 138 | {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"}, |
139 | {0,NULL} | 139 | {0,NULL} |
diff --git a/src/lib/libcrypto/cms/cms_ess.c b/src/lib/libcrypto/cms/cms_ess.c index ed34ff3228..90c0b82fb5 100644 --- a/src/lib/libcrypto/cms/cms_ess.c +++ b/src/lib/libcrypto/cms/cms_ess.c | |||
@@ -63,7 +63,7 @@ | |||
63 | DECLARE_ASN1_ITEM(CMS_ReceiptRequest) | 63 | DECLARE_ASN1_ITEM(CMS_ReceiptRequest) |
64 | DECLARE_ASN1_ITEM(CMS_Receipt) | 64 | DECLARE_ASN1_ITEM(CMS_Receipt) |
65 | 65 | ||
66 | IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ReceiptRequest) | 66 | IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) |
67 | 67 | ||
68 | /* ESS services: for now just Signed Receipt related */ | 68 | /* ESS services: for now just Signed Receipt related */ |
69 | 69 | ||
@@ -344,7 +344,7 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) | |||
344 | 344 | ||
345 | /* Get original receipt request details */ | 345 | /* Get original receipt request details */ |
346 | 346 | ||
347 | if (!CMS_get1_ReceiptRequest(osi, &rr)) | 347 | if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) |
348 | { | 348 | { |
349 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); | 349 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); |
350 | goto err; | 350 | goto err; |
@@ -385,7 +385,7 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) | |||
385 | 385 | ||
386 | /* Get original receipt request details */ | 386 | /* Get original receipt request details */ |
387 | 387 | ||
388 | if (!CMS_get1_ReceiptRequest(si, &rr)) | 388 | if (CMS_get1_ReceiptRequest(si, &rr) <= 0) |
389 | { | 389 | { |
390 | CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); | 390 | CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); |
391 | goto err; | 391 | goto err; |
diff --git a/src/lib/libcrypto/cms/cms_io.c b/src/lib/libcrypto/cms/cms_io.c index 30f5ddfe6d..1cb0264cc5 100644 --- a/src/lib/libcrypto/cms/cms_io.c +++ b/src/lib/libcrypto/cms/cms_io.c | |||
@@ -58,6 +58,25 @@ | |||
58 | #include "cms.h" | 58 | #include "cms.h" |
59 | #include "cms_lcl.h" | 59 | #include "cms_lcl.h" |
60 | 60 | ||
61 | int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) | ||
62 | { | ||
63 | ASN1_OCTET_STRING **pos; | ||
64 | pos = CMS_get0_content(cms); | ||
65 | if (!pos) | ||
66 | return 0; | ||
67 | if (!*pos) | ||
68 | *pos = ASN1_OCTET_STRING_new(); | ||
69 | if (*pos) | ||
70 | { | ||
71 | (*pos)->flags |= ASN1_STRING_FLAG_NDEF; | ||
72 | (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; | ||
73 | *boundary = &(*pos)->data; | ||
74 | return 1; | ||
75 | } | ||
76 | CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
61 | CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) | 80 | CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) |
62 | { | 81 | { |
63 | return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); | 82 | return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); |
@@ -70,52 +89,26 @@ int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) | |||
70 | 89 | ||
71 | IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) | 90 | IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) |
72 | 91 | ||
73 | /* Callback for int_smime_write_ASN1 */ | 92 | BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) |
74 | |||
75 | static int cms_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, | ||
76 | const ASN1_ITEM *it) | ||
77 | { | 93 | { |
78 | CMS_ContentInfo *cms = (CMS_ContentInfo *)val; | 94 | return BIO_new_NDEF(out, (ASN1_VALUE *)cms, |
79 | BIO *tmpbio, *cmsbio; | 95 | ASN1_ITEM_rptr(CMS_ContentInfo)); |
80 | int r = 0; | 96 | } |
81 | |||
82 | if (!(flags & SMIME_DETACHED)) | ||
83 | { | ||
84 | SMIME_crlf_copy(data, out, flags); | ||
85 | return 1; | ||
86 | } | ||
87 | |||
88 | /* Let CMS code prepend any needed BIOs */ | ||
89 | |||
90 | cmsbio = CMS_dataInit(cms, out); | ||
91 | |||
92 | if (!cmsbio) | ||
93 | return 0; | ||
94 | |||
95 | /* Copy data across, passing through filter BIOs for processing */ | ||
96 | SMIME_crlf_copy(data, cmsbio, flags); | ||
97 | |||
98 | /* Finalize structure */ | ||
99 | if (CMS_dataFinal(cms, cmsbio) <= 0) | ||
100 | goto err; | ||
101 | |||
102 | r = 1; | ||
103 | |||
104 | err: | ||
105 | |||
106 | /* Now remove any digests prepended to the BIO */ | ||
107 | |||
108 | while (cmsbio != out) | ||
109 | { | ||
110 | tmpbio = BIO_pop(cmsbio); | ||
111 | BIO_free(cmsbio); | ||
112 | cmsbio = tmpbio; | ||
113 | } | ||
114 | 97 | ||
115 | return 1; | 98 | /* CMS wrappers round generalised stream and MIME routines */ |
116 | 99 | ||
100 | int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) | ||
101 | { | ||
102 | return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags, | ||
103 | ASN1_ITEM_rptr(CMS_ContentInfo)); | ||
117 | } | 104 | } |
118 | 105 | ||
106 | int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) | ||
107 | { | ||
108 | return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) cms, in, flags, | ||
109 | "CMS", | ||
110 | ASN1_ITEM_rptr(CMS_ContentInfo)); | ||
111 | } | ||
119 | 112 | ||
120 | int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) | 113 | int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) |
121 | { | 114 | { |
@@ -127,9 +120,8 @@ int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) | |||
127 | else | 120 | else |
128 | mdalgs = NULL; | 121 | mdalgs = NULL; |
129 | 122 | ||
130 | return int_smime_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, | 123 | return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, |
131 | ctype_nid, econt_nid, mdalgs, | 124 | ctype_nid, econt_nid, mdalgs, |
132 | cms_output_data, | ||
133 | ASN1_ITEM_rptr(CMS_ContentInfo)); | 125 | ASN1_ITEM_rptr(CMS_ContentInfo)); |
134 | } | 126 | } |
135 | 127 | ||
@@ -138,3 +130,4 @@ CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont) | |||
138 | return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, | 130 | return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, |
139 | ASN1_ITEM_rptr(CMS_ContentInfo)); | 131 | ASN1_ITEM_rptr(CMS_ContentInfo)); |
140 | } | 132 | } |
133 | |||
diff --git a/src/lib/libcrypto/cms/cms_lcl.h b/src/lib/libcrypto/cms/cms_lcl.h index 7d60fac67e..c8ecfa724a 100644 --- a/src/lib/libcrypto/cms/cms_lcl.h +++ b/src/lib/libcrypto/cms/cms_lcl.h | |||
@@ -406,6 +406,7 @@ struct CMS_Receipt_st | |||
406 | ASN1_OCTET_STRING *originatorSignatureValue; | 406 | ASN1_OCTET_STRING *originatorSignatureValue; |
407 | }; | 407 | }; |
408 | 408 | ||
409 | DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) | ||
409 | DECLARE_ASN1_ITEM(CMS_SignerInfo) | 410 | DECLARE_ASN1_ITEM(CMS_SignerInfo) |
410 | DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) | 411 | DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) |
411 | DECLARE_ASN1_ITEM(CMS_Attributes_Sign) | 412 | DECLARE_ASN1_ITEM(CMS_Attributes_Sign) |
diff --git a/src/lib/libcrypto/cms/cms_lib.c b/src/lib/libcrypto/cms/cms_lib.c index 8e6c1d29a5..d00fe0f87b 100644 --- a/src/lib/libcrypto/cms/cms_lib.c +++ b/src/lib/libcrypto/cms/cms_lib.c | |||
@@ -60,7 +60,8 @@ | |||
60 | #include "cms.h" | 60 | #include "cms.h" |
61 | #include "cms_lcl.h" | 61 | #include "cms_lcl.h" |
62 | 62 | ||
63 | IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ContentInfo) | 63 | IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo) |
64 | IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) | ||
64 | 65 | ||
65 | DECLARE_ASN1_ITEM(CMS_CertificateChoices) | 66 | DECLARE_ASN1_ITEM(CMS_CertificateChoices) |
66 | DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) | 67 | DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) |
@@ -346,20 +347,10 @@ void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) | |||
346 | { | 347 | { |
347 | int param_type; | 348 | int param_type; |
348 | 349 | ||
349 | switch (EVP_MD_type(md)) | 350 | if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) |
350 | { | ||
351 | case NID_sha1: | ||
352 | case NID_sha224: | ||
353 | case NID_sha256: | ||
354 | case NID_sha384: | ||
355 | case NID_sha512: | ||
356 | param_type = V_ASN1_UNDEF; | 351 | param_type = V_ASN1_UNDEF; |
357 | break; | 352 | else |
358 | |||
359 | default: | ||
360 | param_type = V_ASN1_NULL; | 353 | param_type = V_ASN1_NULL; |
361 | break; | ||
362 | } | ||
363 | 354 | ||
364 | X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); | 355 | X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); |
365 | 356 | ||
@@ -415,7 +406,11 @@ int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, | |||
415 | return 0; | 406 | return 0; |
416 | } | 407 | } |
417 | BIO_get_md_ctx(chain, &mtmp); | 408 | BIO_get_md_ctx(chain, &mtmp); |
418 | if (EVP_MD_CTX_type(mtmp) == nid) | 409 | if (EVP_MD_CTX_type(mtmp) == nid |
410 | /* Workaround for broken implementations that use signature | ||
411 | * algorithm OID instead of digest. | ||
412 | */ | ||
413 | || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) | ||
419 | { | 414 | { |
420 | EVP_MD_CTX_copy_ex(mctx, mtmp); | 415 | EVP_MD_CTX_copy_ex(mctx, mtmp); |
421 | return 1; | 416 | return 1; |
@@ -557,6 +552,15 @@ int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) | |||
557 | return 1; | 552 | return 1; |
558 | } | 553 | } |
559 | 554 | ||
555 | int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) | ||
556 | { | ||
557 | int r; | ||
558 | r = CMS_add0_crl(cms, crl); | ||
559 | if (r > 0) | ||
560 | CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); | ||
561 | return r; | ||
562 | } | ||
563 | |||
560 | STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) | 564 | STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) |
561 | { | 565 | { |
562 | STACK_OF(X509) *certs = NULL; | 566 | STACK_OF(X509) *certs = NULL; |
diff --git a/src/lib/libcrypto/cms/cms_sd.c b/src/lib/libcrypto/cms/cms_sd.c index cdac3b870d..e3192b9c57 100644 --- a/src/lib/libcrypto/cms/cms_sd.c +++ b/src/lib/libcrypto/cms/cms_sd.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <openssl/err.h> | 58 | #include <openssl/err.h> |
59 | #include <openssl/cms.h> | 59 | #include <openssl/cms.h> |
60 | #include "cms_lcl.h" | 60 | #include "cms_lcl.h" |
61 | #include "asn1_locl.h" | ||
61 | 62 | ||
62 | /* CMS SignedData Utilities */ | 63 | /* CMS SignedData Utilities */ |
63 | 64 | ||
@@ -218,10 +219,9 @@ int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) | |||
218 | if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, | 219 | if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, |
219 | X509_get_issuer_name(cert))) | 220 | X509_get_issuer_name(cert))) |
220 | goto merr; | 221 | goto merr; |
221 | ASN1_STRING_free(sid->d.issuerAndSerialNumber->serialNumber); | 222 | if (!ASN1_STRING_copy( |
222 | sid->d.issuerAndSerialNumber->serialNumber = | 223 | sid->d.issuerAndSerialNumber->serialNumber, |
223 | ASN1_STRING_dup(X509_get_serialNumber(cert)); | 224 | X509_get_serialNumber(cert))) |
224 | if(!sid->d.issuerAndSerialNumber->serialNumber) | ||
225 | goto merr; | 225 | goto merr; |
226 | break; | 226 | break; |
227 | 227 | ||
@@ -341,16 +341,22 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, | |||
341 | if (!cms_set1_SignerIdentifier(si->sid, signer, type)) | 341 | if (!cms_set1_SignerIdentifier(si->sid, signer, type)) |
342 | goto err; | 342 | goto err; |
343 | 343 | ||
344 | /* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */ | ||
345 | if (md == NULL) | 344 | if (md == NULL) |
346 | md = EVP_sha1(); | 345 | { |
347 | 346 | int def_nid; | |
348 | /* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */ | 347 | if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) |
348 | goto err; | ||
349 | md = EVP_get_digestbynid(def_nid); | ||
350 | if (md == NULL) | ||
351 | { | ||
352 | CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); | ||
353 | goto err; | ||
354 | } | ||
355 | } | ||
349 | 356 | ||
350 | if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1)) | 357 | if (!md) |
351 | { | 358 | { |
352 | CMSerr(CMS_F_CMS_ADD1_SIGNER, | 359 | CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); |
353 | CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); | ||
354 | goto err; | 360 | goto err; |
355 | } | 361 | } |
356 | 362 | ||
@@ -379,37 +385,21 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, | |||
379 | } | 385 | } |
380 | } | 386 | } |
381 | 387 | ||
382 | /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, | 388 | if (pk->ameth && pk->ameth->pkey_ctrl) |
383 | * hard code algorithm parameters. | ||
384 | */ | ||
385 | |||
386 | switch (pk->type) | ||
387 | { | 389 | { |
388 | 390 | i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN, | |
389 | case EVP_PKEY_RSA: | 391 | 0, si); |
390 | X509_ALGOR_set0(si->signatureAlgorithm, | 392 | if (i == -2) |
391 | OBJ_nid2obj(NID_rsaEncryption), | 393 | { |
392 | V_ASN1_NULL, 0); | 394 | CMSerr(CMS_F_CMS_ADD1_SIGNER, |
393 | break; | ||
394 | |||
395 | case EVP_PKEY_DSA: | ||
396 | X509_ALGOR_set0(si->signatureAlgorithm, | ||
397 | OBJ_nid2obj(NID_dsaWithSHA1), | ||
398 | V_ASN1_UNDEF, 0); | ||
399 | break; | ||
400 | |||
401 | |||
402 | case EVP_PKEY_EC: | ||
403 | X509_ALGOR_set0(si->signatureAlgorithm, | ||
404 | OBJ_nid2obj(NID_ecdsa_with_SHA1), | ||
405 | V_ASN1_UNDEF, 0); | ||
406 | break; | ||
407 | |||
408 | default: | ||
409 | CMSerr(CMS_F_CMS_ADD1_SIGNER, | ||
410 | CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); | 395 | CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); |
411 | goto err; | 396 | goto err; |
412 | 397 | } | |
398 | if (i <= 0) | ||
399 | { | ||
400 | CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE); | ||
401 | goto err; | ||
402 | } | ||
413 | } | 403 | } |
414 | 404 | ||
415 | if (!(flags & CMS_NOATTR)) | 405 | if (!(flags & CMS_NOATTR)) |
@@ -626,25 +616,6 @@ void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, | |||
626 | *psig = si->signatureAlgorithm; | 616 | *psig = si->signatureAlgorithm; |
627 | } | 617 | } |
628 | 618 | ||
629 | /* In OpenSSL 0.9.8 we have the link between digest types and public | ||
630 | * key types so we need to fixup the digest type if the public key | ||
631 | * type is not appropriate. | ||
632 | */ | ||
633 | |||
634 | static void cms_fixup_mctx(EVP_MD_CTX *mctx, EVP_PKEY *pkey) | ||
635 | { | ||
636 | if (EVP_MD_CTX_type(mctx) != NID_sha1) | ||
637 | return; | ||
638 | #ifndef OPENSSL_NO_DSA | ||
639 | if (pkey->type == EVP_PKEY_DSA) | ||
640 | mctx->digest = EVP_dss1(); | ||
641 | #endif | ||
642 | #ifndef OPENSSL_NO_ECDSA | ||
643 | if (pkey->type == EVP_PKEY_EC) | ||
644 | mctx->digest = EVP_ecdsa(); | ||
645 | #endif | ||
646 | } | ||
647 | |||
648 | static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, | 619 | static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, |
649 | CMS_SignerInfo *si, BIO *chain) | 620 | CMS_SignerInfo *si, BIO *chain) |
650 | { | 621 | { |
@@ -693,7 +664,6 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, | |||
693 | ERR_R_MALLOC_FAILURE); | 664 | ERR_R_MALLOC_FAILURE); |
694 | goto err; | 665 | goto err; |
695 | } | 666 | } |
696 | cms_fixup_mctx(&mctx, si->pkey); | ||
697 | if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) | 667 | if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) |
698 | { | 668 | { |
699 | CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, | 669 | CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, |
@@ -731,9 +701,10 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) | |||
731 | int CMS_SignerInfo_sign(CMS_SignerInfo *si) | 701 | int CMS_SignerInfo_sign(CMS_SignerInfo *si) |
732 | { | 702 | { |
733 | EVP_MD_CTX mctx; | 703 | EVP_MD_CTX mctx; |
704 | EVP_PKEY_CTX *pctx; | ||
734 | unsigned char *abuf = NULL; | 705 | unsigned char *abuf = NULL; |
735 | int alen; | 706 | int alen; |
736 | unsigned int siglen; | 707 | size_t siglen; |
737 | const EVP_MD *md = NULL; | 708 | const EVP_MD *md = NULL; |
738 | 709 | ||
739 | md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); | 710 | md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); |
@@ -748,40 +719,38 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) | |||
748 | goto err; | 719 | goto err; |
749 | } | 720 | } |
750 | 721 | ||
751 | if (EVP_SignInit_ex(&mctx, md, NULL) <= 0) | 722 | if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) |
752 | goto err; | 723 | goto err; |
753 | 724 | ||
754 | #if 0 | ||
755 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, | 725 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, |
756 | EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) | 726 | EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) |
757 | { | 727 | { |
758 | CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); | 728 | CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); |
759 | goto err; | 729 | goto err; |
760 | } | 730 | } |
761 | #endif | ||
762 | 731 | ||
763 | alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, | 732 | alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, |
764 | ASN1_ITEM_rptr(CMS_Attributes_Sign)); | 733 | ASN1_ITEM_rptr(CMS_Attributes_Sign)); |
765 | if(!abuf) | 734 | if(!abuf) |
766 | goto err; | 735 | goto err; |
767 | if (EVP_SignUpdate(&mctx, abuf, alen) <= 0) | 736 | if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) |
737 | goto err; | ||
738 | if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) | ||
768 | goto err; | 739 | goto err; |
769 | siglen = EVP_PKEY_size(si->pkey); | ||
770 | OPENSSL_free(abuf); | 740 | OPENSSL_free(abuf); |
771 | abuf = OPENSSL_malloc(siglen); | 741 | abuf = OPENSSL_malloc(siglen); |
772 | if(!abuf) | 742 | if(!abuf) |
773 | goto err; | 743 | goto err; |
774 | cms_fixup_mctx(&mctx, si->pkey); | 744 | if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) |
775 | if (EVP_SignFinal(&mctx, abuf, &siglen, si->pkey) <= 0) | ||
776 | goto err; | 745 | goto err; |
777 | #if 0 | 746 | |
778 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, | 747 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, |
779 | EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) | 748 | EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) |
780 | { | 749 | { |
781 | CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); | 750 | CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); |
782 | goto err; | 751 | goto err; |
783 | } | 752 | } |
784 | #endif | 753 | |
785 | EVP_MD_CTX_cleanup(&mctx); | 754 | EVP_MD_CTX_cleanup(&mctx); |
786 | 755 | ||
787 | ASN1_STRING_set0(si->signature, abuf, siglen); | 756 | ASN1_STRING_set0(si->signature, abuf, siglen); |
@@ -799,6 +768,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) | |||
799 | int CMS_SignerInfo_verify(CMS_SignerInfo *si) | 768 | int CMS_SignerInfo_verify(CMS_SignerInfo *si) |
800 | { | 769 | { |
801 | EVP_MD_CTX mctx; | 770 | EVP_MD_CTX mctx; |
771 | EVP_PKEY_CTX *pctx; | ||
802 | unsigned char *abuf = NULL; | 772 | unsigned char *abuf = NULL; |
803 | int alen, r = -1; | 773 | int alen, r = -1; |
804 | const EVP_MD *md = NULL; | 774 | const EVP_MD *md = NULL; |
@@ -813,23 +783,22 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) | |||
813 | if (md == NULL) | 783 | if (md == NULL) |
814 | return -1; | 784 | return -1; |
815 | EVP_MD_CTX_init(&mctx); | 785 | EVP_MD_CTX_init(&mctx); |
816 | if (EVP_VerifyInit_ex(&mctx, md, NULL) <= 0) | 786 | if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) |
817 | goto err; | 787 | goto err; |
818 | 788 | ||
819 | alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, | 789 | alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, |
820 | ASN1_ITEM_rptr(CMS_Attributes_Verify)); | 790 | ASN1_ITEM_rptr(CMS_Attributes_Verify)); |
821 | if(!abuf) | 791 | if(!abuf) |
822 | goto err; | 792 | goto err; |
823 | r = EVP_VerifyUpdate(&mctx, abuf, alen); | 793 | r = EVP_DigestVerifyUpdate(&mctx, abuf, alen); |
824 | OPENSSL_free(abuf); | 794 | OPENSSL_free(abuf); |
825 | if (r <= 0) | 795 | if (r <= 0) |
826 | { | 796 | { |
827 | r = -1; | 797 | r = -1; |
828 | goto err; | 798 | goto err; |
829 | } | 799 | } |
830 | cms_fixup_mctx(&mctx, si->pkey); | 800 | r = EVP_DigestVerifyFinal(&mctx, |
831 | r = EVP_VerifyFinal(&mctx, | 801 | si->signature->data, si->signature->length); |
832 | si->signature->data, si->signature->length, si->pkey); | ||
833 | if (r <= 0) | 802 | if (r <= 0) |
834 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); | 803 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); |
835 | err: | 804 | err: |
@@ -922,7 +891,6 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) | |||
922 | } | 891 | } |
923 | else | 892 | else |
924 | { | 893 | { |
925 | cms_fixup_mctx(&mctx, si->pkey); | ||
926 | r = EVP_VerifyFinal(&mctx, si->signature->data, | 894 | r = EVP_VerifyFinal(&mctx, si->signature->data, |
927 | si->signature->length, si->pkey); | 895 | si->signature->length, si->pkey); |
928 | if (r <= 0) | 896 | if (r <= 0) |
@@ -991,17 +959,19 @@ static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) | |||
991 | return CMS_add_simple_smimecap(sk, nid, arg); | 959 | return CMS_add_simple_smimecap(sk, nid, arg); |
992 | return 1; | 960 | return 1; |
993 | } | 961 | } |
994 | #if 0 | 962 | |
995 | static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) | 963 | static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) |
996 | { | 964 | { |
997 | if (EVP_get_digestbynid(nid)) | 965 | if (EVP_get_digestbynid(nid)) |
998 | return CMS_add_simple_smimecap(sk, nid, arg); | 966 | return CMS_add_simple_smimecap(sk, nid, arg); |
999 | return 1; | 967 | return 1; |
1000 | } | 968 | } |
1001 | #endif | 969 | |
1002 | int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) | 970 | int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) |
1003 | { | 971 | { |
1004 | if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) | 972 | if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) |
973 | || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) | ||
974 | || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) | ||
1005 | || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) | 975 | || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) |
1006 | || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) | 976 | || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) |
1007 | || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) | 977 | || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) |
diff --git a/src/lib/libcrypto/des/asm/des_enc.m4 b/src/lib/libcrypto/des/asm/des_enc.m4 index f59333a030..3280595478 100644 --- a/src/lib/libcrypto/des/asm/des_enc.m4 +++ b/src/lib/libcrypto/des/asm/des_enc.m4 | |||
@@ -1954,9 +1954,11 @@ DES_ede3_cbc_encrypt: | |||
1954 | .word LOOPS ! 280 | 1954 | .word LOOPS ! 280 |
1955 | .word 0x0000FC00 ! 284 | 1955 | .word 0x0000FC00 ! 284 |
1956 | 1956 | ||
1957 | .type .PIC.DES_SPtrans,#object | 1957 | .global DES_SPtrans |
1958 | .size .PIC.DES_SPtrans,2048 | 1958 | .type DES_SPtrans,#object |
1959 | .size DES_SPtrans,2048 | ||
1959 | .align 64 | 1960 | .align 64 |
1961 | DES_SPtrans: | ||
1960 | .PIC.DES_SPtrans: | 1962 | .PIC.DES_SPtrans: |
1961 | ! nibble 0 | 1963 | ! nibble 0 |
1962 | .word 0x02080800, 0x00080000, 0x02000002, 0x02080802 | 1964 | .word 0x02080800, 0x00080000, 0x02000002, 0x02080802 |
diff --git a/src/lib/libcrypto/dh/dh_ameth.c b/src/lib/libcrypto/dh/dh_ameth.c new file mode 100644 index 0000000000..377caf96c9 --- /dev/null +++ b/src/lib/libcrypto/dh/dh_ameth.c | |||
@@ -0,0 +1,500 @@ | |||
1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
2 | * project 2006. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <stdio.h> | ||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/x509.h> | ||
61 | #include <openssl/asn1.h> | ||
62 | #include <openssl/dh.h> | ||
63 | #include <openssl/bn.h> | ||
64 | #include "asn1_locl.h" | ||
65 | |||
66 | static void int_dh_free(EVP_PKEY *pkey) | ||
67 | { | ||
68 | DH_free(pkey->pkey.dh); | ||
69 | } | ||
70 | |||
71 | static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) | ||
72 | { | ||
73 | const unsigned char *p, *pm; | ||
74 | int pklen, pmlen; | ||
75 | int ptype; | ||
76 | void *pval; | ||
77 | ASN1_STRING *pstr; | ||
78 | X509_ALGOR *palg; | ||
79 | ASN1_INTEGER *public_key = NULL; | ||
80 | |||
81 | DH *dh = NULL; | ||
82 | |||
83 | if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) | ||
84 | return 0; | ||
85 | X509_ALGOR_get0(NULL, &ptype, &pval, palg); | ||
86 | |||
87 | if (ptype != V_ASN1_SEQUENCE) | ||
88 | { | ||
89 | DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR); | ||
90 | goto err; | ||
91 | } | ||
92 | |||
93 | pstr = pval; | ||
94 | pm = pstr->data; | ||
95 | pmlen = pstr->length; | ||
96 | |||
97 | if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) | ||
98 | { | ||
99 | DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); | ||
100 | goto err; | ||
101 | } | ||
102 | |||
103 | if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) | ||
104 | { | ||
105 | DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); | ||
106 | goto err; | ||
107 | } | ||
108 | |||
109 | /* We have parameters now set public key */ | ||
110 | if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) | ||
111 | { | ||
112 | DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR); | ||
113 | goto err; | ||
114 | } | ||
115 | |||
116 | ASN1_INTEGER_free(public_key); | ||
117 | EVP_PKEY_assign_DH(pkey, dh); | ||
118 | return 1; | ||
119 | |||
120 | err: | ||
121 | if (public_key) | ||
122 | ASN1_INTEGER_free(public_key); | ||
123 | if (dh) | ||
124 | DH_free(dh); | ||
125 | return 0; | ||
126 | |||
127 | } | ||
128 | |||
129 | static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) | ||
130 | { | ||
131 | DH *dh; | ||
132 | void *pval = NULL; | ||
133 | int ptype; | ||
134 | unsigned char *penc = NULL; | ||
135 | int penclen; | ||
136 | ASN1_STRING *str; | ||
137 | ASN1_INTEGER *pub_key = NULL; | ||
138 | |||
139 | dh=pkey->pkey.dh; | ||
140 | |||
141 | str = ASN1_STRING_new(); | ||
142 | str->length = i2d_DHparams(dh, &str->data); | ||
143 | if (str->length <= 0) | ||
144 | { | ||
145 | DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); | ||
146 | goto err; | ||
147 | } | ||
148 | pval = str; | ||
149 | ptype = V_ASN1_SEQUENCE; | ||
150 | |||
151 | pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL); | ||
152 | if (!pub_key) | ||
153 | goto err; | ||
154 | |||
155 | penclen = i2d_ASN1_INTEGER(pub_key, &penc); | ||
156 | |||
157 | ASN1_INTEGER_free(pub_key); | ||
158 | |||
159 | if (penclen <= 0) | ||
160 | { | ||
161 | DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); | ||
162 | goto err; | ||
163 | } | ||
164 | |||
165 | if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH), | ||
166 | ptype, pval, penc, penclen)) | ||
167 | return 1; | ||
168 | |||
169 | err: | ||
170 | if (penc) | ||
171 | OPENSSL_free(penc); | ||
172 | if (pval) | ||
173 | ASN1_STRING_free(pval); | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | |||
179 | /* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in | ||
180 | * that the AlgorithmIdentifier contains the paramaters, the private key | ||
181 | * is explcitly included and the pubkey must be recalculated. | ||
182 | */ | ||
183 | |||
184 | static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) | ||
185 | { | ||
186 | const unsigned char *p, *pm; | ||
187 | int pklen, pmlen; | ||
188 | int ptype; | ||
189 | void *pval; | ||
190 | ASN1_STRING *pstr; | ||
191 | X509_ALGOR *palg; | ||
192 | ASN1_INTEGER *privkey = NULL; | ||
193 | |||
194 | DH *dh = NULL; | ||
195 | |||
196 | if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) | ||
197 | return 0; | ||
198 | |||
199 | X509_ALGOR_get0(NULL, &ptype, &pval, palg); | ||
200 | |||
201 | if (ptype != V_ASN1_SEQUENCE) | ||
202 | goto decerr; | ||
203 | |||
204 | if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen))) | ||
205 | goto decerr; | ||
206 | |||
207 | |||
208 | pstr = pval; | ||
209 | pm = pstr->data; | ||
210 | pmlen = pstr->length; | ||
211 | if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) | ||
212 | goto decerr; | ||
213 | /* We have parameters now set private key */ | ||
214 | if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) | ||
215 | { | ||
216 | DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR); | ||
217 | goto dherr; | ||
218 | } | ||
219 | /* Calculate public key */ | ||
220 | if (!DH_generate_key(dh)) | ||
221 | goto dherr; | ||
222 | |||
223 | EVP_PKEY_assign_DH(pkey, dh); | ||
224 | |||
225 | ASN1_INTEGER_free(privkey); | ||
226 | |||
227 | return 1; | ||
228 | |||
229 | decerr: | ||
230 | DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR); | ||
231 | dherr: | ||
232 | DH_free(dh); | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) | ||
237 | { | ||
238 | ASN1_STRING *params = NULL; | ||
239 | ASN1_INTEGER *prkey = NULL; | ||
240 | unsigned char *dp = NULL; | ||
241 | int dplen; | ||
242 | |||
243 | params = ASN1_STRING_new(); | ||
244 | |||
245 | if (!params) | ||
246 | { | ||
247 | DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); | ||
248 | goto err; | ||
249 | } | ||
250 | |||
251 | params->length = i2d_DHparams(pkey->pkey.dh, ¶ms->data); | ||
252 | if (params->length <= 0) | ||
253 | { | ||
254 | DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); | ||
255 | goto err; | ||
256 | } | ||
257 | params->type = V_ASN1_SEQUENCE; | ||
258 | |||
259 | /* Get private key into integer */ | ||
260 | prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL); | ||
261 | |||
262 | if (!prkey) | ||
263 | { | ||
264 | DHerr(DH_F_DH_PRIV_ENCODE,DH_R_BN_ERROR); | ||
265 | goto err; | ||
266 | } | ||
267 | |||
268 | dplen = i2d_ASN1_INTEGER(prkey, &dp); | ||
269 | |||
270 | ASN1_INTEGER_free(prkey); | ||
271 | |||
272 | if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0, | ||
273 | V_ASN1_SEQUENCE, params, dp, dplen)) | ||
274 | goto err; | ||
275 | |||
276 | return 1; | ||
277 | |||
278 | err: | ||
279 | if (dp != NULL) | ||
280 | OPENSSL_free(dp); | ||
281 | if (params != NULL) | ||
282 | ASN1_STRING_free(params); | ||
283 | if (prkey != NULL) | ||
284 | ASN1_INTEGER_free(prkey); | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | |||
289 | static void update_buflen(const BIGNUM *b, size_t *pbuflen) | ||
290 | { | ||
291 | size_t i; | ||
292 | if (!b) | ||
293 | return; | ||
294 | if (*pbuflen < (i = (size_t)BN_num_bytes(b))) | ||
295 | *pbuflen = i; | ||
296 | } | ||
297 | |||
298 | static int dh_param_decode(EVP_PKEY *pkey, | ||
299 | const unsigned char **pder, int derlen) | ||
300 | { | ||
301 | DH *dh; | ||
302 | if (!(dh = d2i_DHparams(NULL, pder, derlen))) | ||
303 | { | ||
304 | DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); | ||
305 | return 0; | ||
306 | } | ||
307 | EVP_PKEY_assign_DH(pkey, dh); | ||
308 | return 1; | ||
309 | } | ||
310 | |||
311 | static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder) | ||
312 | { | ||
313 | return i2d_DHparams(pkey->pkey.dh, pder); | ||
314 | } | ||
315 | |||
316 | static int do_dh_print(BIO *bp, const DH *x, int indent, | ||
317 | ASN1_PCTX *ctx, int ptype) | ||
318 | { | ||
319 | unsigned char *m=NULL; | ||
320 | int reason=ERR_R_BUF_LIB,ret=0; | ||
321 | size_t buf_len=0; | ||
322 | |||
323 | const char *ktype = NULL; | ||
324 | |||
325 | BIGNUM *priv_key, *pub_key; | ||
326 | |||
327 | if (ptype == 2) | ||
328 | priv_key = x->priv_key; | ||
329 | else | ||
330 | priv_key = NULL; | ||
331 | |||
332 | if (ptype > 0) | ||
333 | pub_key = x->pub_key; | ||
334 | else | ||
335 | pub_key = NULL; | ||
336 | |||
337 | update_buflen(x->p, &buf_len); | ||
338 | |||
339 | if (buf_len == 0) | ||
340 | { | ||
341 | reason = ERR_R_PASSED_NULL_PARAMETER; | ||
342 | goto err; | ||
343 | } | ||
344 | |||
345 | update_buflen(x->g, &buf_len); | ||
346 | update_buflen(pub_key, &buf_len); | ||
347 | update_buflen(priv_key, &buf_len); | ||
348 | |||
349 | if (ptype == 2) | ||
350 | ktype = "PKCS#3 DH Private-Key"; | ||
351 | else if (ptype == 1) | ||
352 | ktype = "PKCS#3 DH Public-Key"; | ||
353 | else | ||
354 | ktype = "PKCS#3 DH Parameters"; | ||
355 | |||
356 | m= OPENSSL_malloc(buf_len+10); | ||
357 | if (m == NULL) | ||
358 | { | ||
359 | reason=ERR_R_MALLOC_FAILURE; | ||
360 | goto err; | ||
361 | } | ||
362 | |||
363 | BIO_indent(bp, indent, 128); | ||
364 | if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) | ||
365 | goto err; | ||
366 | indent += 4; | ||
367 | |||
368 | if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err; | ||
369 | if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err; | ||
370 | |||
371 | if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err; | ||
372 | if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err; | ||
373 | if (x->length != 0) | ||
374 | { | ||
375 | BIO_indent(bp, indent, 128); | ||
376 | if (BIO_printf(bp,"recommended-private-length: %d bits\n", | ||
377 | (int)x->length) <= 0) goto err; | ||
378 | } | ||
379 | |||
380 | |||
381 | ret=1; | ||
382 | if (0) | ||
383 | { | ||
384 | err: | ||
385 | DHerr(DH_F_DO_DH_PRINT,reason); | ||
386 | } | ||
387 | if (m != NULL) OPENSSL_free(m); | ||
388 | return(ret); | ||
389 | } | ||
390 | |||
391 | static int int_dh_size(const EVP_PKEY *pkey) | ||
392 | { | ||
393 | return(DH_size(pkey->pkey.dh)); | ||
394 | } | ||
395 | |||
396 | static int dh_bits(const EVP_PKEY *pkey) | ||
397 | { | ||
398 | return BN_num_bits(pkey->pkey.dh->p); | ||
399 | } | ||
400 | |||
401 | static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) | ||
402 | { | ||
403 | if ( BN_cmp(a->pkey.dh->p,b->pkey.dh->p) || | ||
404 | BN_cmp(a->pkey.dh->g,b->pkey.dh->g)) | ||
405 | return 0; | ||
406 | else | ||
407 | return 1; | ||
408 | } | ||
409 | |||
410 | static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) | ||
411 | { | ||
412 | BIGNUM *a; | ||
413 | |||
414 | if ((a=BN_dup(from->pkey.dh->p)) == NULL) | ||
415 | return 0; | ||
416 | if (to->pkey.dh->p != NULL) | ||
417 | BN_free(to->pkey.dh->p); | ||
418 | to->pkey.dh->p=a; | ||
419 | |||
420 | if ((a=BN_dup(from->pkey.dh->g)) == NULL) | ||
421 | return 0; | ||
422 | if (to->pkey.dh->g != NULL) | ||
423 | BN_free(to->pkey.dh->g); | ||
424 | to->pkey.dh->g=a; | ||
425 | |||
426 | return 1; | ||
427 | } | ||
428 | |||
429 | static int dh_missing_parameters(const EVP_PKEY *a) | ||
430 | { | ||
431 | if (!a->pkey.dh->p || !a->pkey.dh->g) | ||
432 | return 1; | ||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) | ||
437 | { | ||
438 | if (dh_cmp_parameters(a, b) == 0) | ||
439 | return 0; | ||
440 | if (BN_cmp(b->pkey.dh->pub_key,a->pkey.dh->pub_key) != 0) | ||
441 | return 0; | ||
442 | else | ||
443 | return 1; | ||
444 | } | ||
445 | |||
446 | static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
447 | ASN1_PCTX *ctx) | ||
448 | { | ||
449 | return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0); | ||
450 | } | ||
451 | |||
452 | static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
453 | ASN1_PCTX *ctx) | ||
454 | { | ||
455 | return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1); | ||
456 | } | ||
457 | |||
458 | static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
459 | ASN1_PCTX *ctx) | ||
460 | { | ||
461 | return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2); | ||
462 | } | ||
463 | |||
464 | int DHparams_print(BIO *bp, const DH *x) | ||
465 | { | ||
466 | return do_dh_print(bp, x, 4, NULL, 0); | ||
467 | } | ||
468 | |||
469 | const EVP_PKEY_ASN1_METHOD dh_asn1_meth = | ||
470 | { | ||
471 | EVP_PKEY_DH, | ||
472 | EVP_PKEY_DH, | ||
473 | 0, | ||
474 | |||
475 | "DH", | ||
476 | "OpenSSL PKCS#3 DH method", | ||
477 | |||
478 | dh_pub_decode, | ||
479 | dh_pub_encode, | ||
480 | dh_pub_cmp, | ||
481 | dh_public_print, | ||
482 | |||
483 | dh_priv_decode, | ||
484 | dh_priv_encode, | ||
485 | dh_private_print, | ||
486 | |||
487 | int_dh_size, | ||
488 | dh_bits, | ||
489 | |||
490 | dh_param_decode, | ||
491 | dh_param_encode, | ||
492 | dh_missing_parameters, | ||
493 | dh_copy_parameters, | ||
494 | dh_cmp_parameters, | ||
495 | dh_param_print, | ||
496 | |||
497 | int_dh_free, | ||
498 | 0 | ||
499 | }; | ||
500 | |||
diff --git a/src/lib/libcrypto/dh/dh_pmeth.c b/src/lib/libcrypto/dh/dh_pmeth.c new file mode 100644 index 0000000000..5ae72b7d4c --- /dev/null +++ b/src/lib/libcrypto/dh/dh_pmeth.c | |||
@@ -0,0 +1,254 @@ | |||
1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
2 | * project 2006. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <stdio.h> | ||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/asn1t.h> | ||
61 | #include <openssl/x509.h> | ||
62 | #include <openssl/evp.h> | ||
63 | #include <openssl/dh.h> | ||
64 | #include <openssl/bn.h> | ||
65 | #include "evp_locl.h" | ||
66 | |||
67 | /* DH pkey context structure */ | ||
68 | |||
69 | typedef struct | ||
70 | { | ||
71 | /* Parameter gen parameters */ | ||
72 | int prime_len; | ||
73 | int generator; | ||
74 | int use_dsa; | ||
75 | /* Keygen callback info */ | ||
76 | int gentmp[2]; | ||
77 | /* message digest */ | ||
78 | } DH_PKEY_CTX; | ||
79 | |||
80 | static int pkey_dh_init(EVP_PKEY_CTX *ctx) | ||
81 | { | ||
82 | DH_PKEY_CTX *dctx; | ||
83 | dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX)); | ||
84 | if (!dctx) | ||
85 | return 0; | ||
86 | dctx->prime_len = 1024; | ||
87 | dctx->generator = 2; | ||
88 | dctx->use_dsa = 0; | ||
89 | |||
90 | ctx->data = dctx; | ||
91 | ctx->keygen_info = dctx->gentmp; | ||
92 | ctx->keygen_info_count = 2; | ||
93 | |||
94 | return 1; | ||
95 | } | ||
96 | |||
97 | static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | ||
98 | { | ||
99 | DH_PKEY_CTX *dctx, *sctx; | ||
100 | if (!pkey_dh_init(dst)) | ||
101 | return 0; | ||
102 | sctx = src->data; | ||
103 | dctx = dst->data; | ||
104 | dctx->prime_len = sctx->prime_len; | ||
105 | dctx->generator = sctx->generator; | ||
106 | dctx->use_dsa = sctx->use_dsa; | ||
107 | return 1; | ||
108 | } | ||
109 | |||
110 | static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) | ||
111 | { | ||
112 | DH_PKEY_CTX *dctx = ctx->data; | ||
113 | if (dctx) | ||
114 | OPENSSL_free(dctx); | ||
115 | } | ||
116 | |||
117 | static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | ||
118 | { | ||
119 | DH_PKEY_CTX *dctx = ctx->data; | ||
120 | switch (type) | ||
121 | { | ||
122 | case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: | ||
123 | if (p1 < 256) | ||
124 | return -2; | ||
125 | dctx->prime_len = p1; | ||
126 | return 1; | ||
127 | |||
128 | case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: | ||
129 | dctx->generator = p1; | ||
130 | return 1; | ||
131 | |||
132 | case EVP_PKEY_CTRL_PEER_KEY: | ||
133 | /* Default behaviour is OK */ | ||
134 | return 1; | ||
135 | |||
136 | default: | ||
137 | return -2; | ||
138 | |||
139 | } | ||
140 | } | ||
141 | |||
142 | |||
143 | static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, | ||
144 | const char *type, const char *value) | ||
145 | { | ||
146 | if (!strcmp(type, "dh_paramgen_prime_len")) | ||
147 | { | ||
148 | int len; | ||
149 | len = atoi(value); | ||
150 | return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); | ||
151 | } | ||
152 | if (!strcmp(type, "dh_paramgen_generator")) | ||
153 | { | ||
154 | int len; | ||
155 | len = atoi(value); | ||
156 | return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len); | ||
157 | } | ||
158 | return -2; | ||
159 | } | ||
160 | |||
161 | static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
162 | { | ||
163 | DH *dh = NULL; | ||
164 | DH_PKEY_CTX *dctx = ctx->data; | ||
165 | BN_GENCB *pcb, cb; | ||
166 | int ret; | ||
167 | if (ctx->pkey_gencb) | ||
168 | { | ||
169 | pcb = &cb; | ||
170 | evp_pkey_set_cb_translate(pcb, ctx); | ||
171 | } | ||
172 | else | ||
173 | pcb = NULL; | ||
174 | dh = DH_new(); | ||
175 | if (!dh) | ||
176 | return 0; | ||
177 | ret = DH_generate_parameters_ex(dh, | ||
178 | dctx->prime_len, dctx->generator, pcb); | ||
179 | if (ret) | ||
180 | EVP_PKEY_assign_DH(pkey, dh); | ||
181 | else | ||
182 | DH_free(dh); | ||
183 | return ret; | ||
184 | } | ||
185 | |||
186 | static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
187 | { | ||
188 | DH *dh = NULL; | ||
189 | if (ctx->pkey == NULL) | ||
190 | { | ||
191 | DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); | ||
192 | return 0; | ||
193 | } | ||
194 | dh = DH_new(); | ||
195 | if (!dh) | ||
196 | return 0; | ||
197 | EVP_PKEY_assign_DH(pkey, dh); | ||
198 | /* Note: if error return, pkey is freed by parent routine */ | ||
199 | if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) | ||
200 | return 0; | ||
201 | return DH_generate_key(pkey->pkey.dh); | ||
202 | } | ||
203 | |||
204 | static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) | ||
205 | { | ||
206 | int ret; | ||
207 | if (!ctx->pkey || !ctx->peerkey) | ||
208 | { | ||
209 | DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); | ||
210 | return 0; | ||
211 | } | ||
212 | ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key, | ||
213 | ctx->pkey->pkey.dh); | ||
214 | if (ret < 0) | ||
215 | return ret; | ||
216 | *keylen = ret; | ||
217 | return 1; | ||
218 | } | ||
219 | |||
220 | const EVP_PKEY_METHOD dh_pkey_meth = | ||
221 | { | ||
222 | EVP_PKEY_DH, | ||
223 | EVP_PKEY_FLAG_AUTOARGLEN, | ||
224 | pkey_dh_init, | ||
225 | pkey_dh_copy, | ||
226 | pkey_dh_cleanup, | ||
227 | |||
228 | 0, | ||
229 | pkey_dh_paramgen, | ||
230 | |||
231 | 0, | ||
232 | pkey_dh_keygen, | ||
233 | |||
234 | 0, | ||
235 | 0, | ||
236 | |||
237 | 0, | ||
238 | 0, | ||
239 | |||
240 | 0,0, | ||
241 | |||
242 | 0,0,0,0, | ||
243 | |||
244 | 0,0, | ||
245 | |||
246 | 0,0, | ||
247 | |||
248 | 0, | ||
249 | pkey_dh_derive, | ||
250 | |||
251 | pkey_dh_ctrl, | ||
252 | pkey_dh_ctrl_str | ||
253 | |||
254 | }; | ||
diff --git a/src/lib/libcrypto/dh/dh_prn.c b/src/lib/libcrypto/dh/dh_prn.c new file mode 100644 index 0000000000..ae58c2ac87 --- /dev/null +++ b/src/lib/libcrypto/dh/dh_prn.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* crypto/asn1/t_pkey.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/evp.h> | ||
62 | #include <openssl/dh.h> | ||
63 | |||
64 | #ifndef OPENSSL_NO_FP_API | ||
65 | int DHparams_print_fp(FILE *fp, const DH *x) | ||
66 | { | ||
67 | BIO *b; | ||
68 | int ret; | ||
69 | |||
70 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
71 | { | ||
72 | DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB); | ||
73 | return(0); | ||
74 | } | ||
75 | BIO_set_fp(b,fp,BIO_NOCLOSE); | ||
76 | ret=DHparams_print(b, x); | ||
77 | BIO_free(b); | ||
78 | return(ret); | ||
79 | } | ||
80 | #endif | ||
diff --git a/src/lib/libcrypto/doc/EVP_DigestSignInit.pod b/src/lib/libcrypto/doc/EVP_DigestSignInit.pod new file mode 100644 index 0000000000..37d960e3b2 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_DigestSignInit.pod | |||
@@ -0,0 +1,87 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal - EVP signing functions | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, | ||
12 | const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); | ||
13 | int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); | ||
14 | int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | The EVP signature routines are a high level interface to digital signatures. | ||
19 | |||
20 | EVP_DigestSignInit() sets up signing context B<ctx> to use digest B<type> from | ||
21 | ENGINE B<impl> and private key B<pkey>. B<ctx> must be initialized with | ||
22 | EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the | ||
23 | EVP_PKEY_CTX of the signing operation will be written to B<*pctx>: this can | ||
24 | be used to set alternative signing options. | ||
25 | |||
26 | EVP_DigestSignUpdate() hashes B<cnt> bytes of data at B<d> into the | ||
27 | signature context B<ctx>. This function can be called several times on the | ||
28 | same B<ctx> to include additional data. This function is currently implemented | ||
29 | usig a macro. | ||
30 | |||
31 | EVP_DigestSignFinal() signs the data in B<ctx> places the signature in B<sig>. | ||
32 | If B<sig> is B<NULL> then the maximum size of the output buffer is written to | ||
33 | the B<siglen> parameter. If B<sig> is not B<NULL> then before the call the | ||
34 | B<siglen> parameter should contain the length of the B<sig> buffer, if the | ||
35 | call is successful the signature is written to B<sig> and the amount of data | ||
36 | written to B<siglen>. | ||
37 | |||
38 | =head1 RETURN VALUES | ||
39 | |||
40 | EVP_DigestSignInit() EVP_DigestSignUpdate() and EVP_DigestSignaFinal() return | ||
41 | 1 for success and 0 or a negative value for failure. In particular a return | ||
42 | value of -2 indicates the operation is not supported by the public key | ||
43 | algorithm. | ||
44 | |||
45 | The error codes can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>. | ||
46 | |||
47 | =head1 NOTES | ||
48 | |||
49 | The B<EVP> interface to digital signatures should almost always be used in | ||
50 | preference to the low level interfaces. This is because the code then becomes | ||
51 | transparent to the algorithm used and much more flexible. | ||
52 | |||
53 | In previous versions of OpenSSL there was a link between message digest types | ||
54 | and public key algorithms. This meant that "clone" digests such as EVP_dss1() | ||
55 | needed to be used to sign using SHA1 and DSA. This is no longer necessary and | ||
56 | the use of clone digest is now discouraged. | ||
57 | |||
58 | For some key types and parameters the random number generator must be seeded | ||
59 | or the operation will fail. | ||
60 | |||
61 | The call to EVP_DigestSignFinal() internally finalizes a copy of the digest | ||
62 | context. This means that calls to EVP_DigestSignUpdate() and | ||
63 | EVP_DigestSignFinal() can be called later to digest and sign additional data. | ||
64 | |||
65 | Since only a copy of the digest context is ever finalized the context must | ||
66 | be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak | ||
67 | will occur. | ||
68 | |||
69 | The use of EVP_PKEY_size() with these functions is discouraged because some | ||
70 | signature operations may have a signature length which depends on the | ||
71 | parameters set. As a result EVP_PKEY_size() would have to return a value | ||
72 | which indicates the maximum possible signature for any set of parameters. | ||
73 | |||
74 | =head1 SEE ALSO | ||
75 | |||
76 | L<EVP_DigestVerifyInit(3)|EVP_DigestVerifyInit(3)>, | ||
77 | L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>, | ||
78 | L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, | ||
79 | L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>, | ||
80 | L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)> | ||
81 | |||
82 | =head1 HISTORY | ||
83 | |||
84 | EVP_DigestSignInit(), EVP_DigestSignUpdate() and EVP_DigestSignFinal() | ||
85 | were first added to OpenSSL 1.0.0. | ||
86 | |||
87 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_DigestVerifyInit.pod b/src/lib/libcrypto/doc/EVP_DigestVerifyInit.pod new file mode 100644 index 0000000000..f224488978 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_DigestVerifyInit.pod | |||
@@ -0,0 +1,82 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal - EVP signature verification functions | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, | ||
12 | const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); | ||
13 | int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); | ||
14 | int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | The EVP signature routines are a high level interface to digital signatures. | ||
19 | |||
20 | EVP_DigestVerifyInit() sets up verification context B<ctx> to use digest | ||
21 | B<type> from ENGINE B<impl> and public key B<pkey>. B<ctx> must be initialized | ||
22 | with EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the | ||
23 | EVP_PKEY_CTX of the verification operation will be written to B<*pctx>: this | ||
24 | can be used to set alternative verification options. | ||
25 | |||
26 | EVP_DigestVerifyUpdate() hashes B<cnt> bytes of data at B<d> into the | ||
27 | verification context B<ctx>. This function can be called several times on the | ||
28 | same B<ctx> to include additional data. This function is currently implemented | ||
29 | using a macro. | ||
30 | |||
31 | EVP_DigestVerifyFinal() verifies the data in B<ctx> against the signature in | ||
32 | B<sig> of length B<siglen>. | ||
33 | |||
34 | =head1 RETURN VALUES | ||
35 | |||
36 | EVP_DigestVerifyInit() and EVP_DigestVerifyUpdate() return 1 for success and 0 | ||
37 | or a negative value for failure. In particular a return value of -2 indicates | ||
38 | the operation is not supported by the public key algorithm. | ||
39 | |||
40 | Unlike other functions the return value 0 from EVP_DigestVerifyFinal() only | ||
41 | indicates that the signature did not not verify successfully (that is tbs did | ||
42 | not match the original data or the signature was of invalid form) it is not an | ||
43 | indication of a more serious error. | ||
44 | |||
45 | The error codes can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>. | ||
46 | |||
47 | =head1 NOTES | ||
48 | |||
49 | The B<EVP> interface to digital signatures should almost always be used in | ||
50 | preference to the low level interfaces. This is because the code then becomes | ||
51 | transparent to the algorithm used and much more flexible. | ||
52 | |||
53 | In previous versions of OpenSSL there was a link between message digest types | ||
54 | and public key algorithms. This meant that "clone" digests such as EVP_dss1() | ||
55 | needed to be used to sign using SHA1 and DSA. This is no longer necessary and | ||
56 | the use of clone digest is now discouraged. | ||
57 | |||
58 | For some key types and parameters the random number generator must be seeded | ||
59 | or the operation will fail. | ||
60 | |||
61 | The call to EVP_DigestVerifyFinal() internally finalizes a copy of the digest | ||
62 | context. This means that calls to EVP_VerifyUpdate() and EVP_VerifyFinal() can | ||
63 | be called later to digest and verify additional data. | ||
64 | |||
65 | Since only a copy of the digest context is ever finalized the context must | ||
66 | be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak | ||
67 | will occur. | ||
68 | |||
69 | =head1 SEE ALSO | ||
70 | |||
71 | L<EVP_DigestSignInit(3)|EVP_DigestSignInit(3)>, | ||
72 | L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>, | ||
73 | L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, | ||
74 | L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>, | ||
75 | L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)> | ||
76 | |||
77 | =head1 HISTORY | ||
78 | |||
79 | EVP_DigestVerifyInit(), EVP_DigestVerifyUpdate() and EVP_DigestVerifyFinal() | ||
80 | were first added to OpenSSL 1.0.0. | ||
81 | |||
82 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod b/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod new file mode 100644 index 0000000000..f2f455990f --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod | |||
@@ -0,0 +1,128 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_ctrl, EVP_PKEY_ctrl_str - algorithm specific control operations | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, | ||
12 | int cmd, int p1, void *p2); | ||
13 | int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, | ||
14 | const char *value); | ||
15 | |||
16 | int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); | ||
17 | |||
18 | #include <openssl/rsa.h> | ||
19 | |||
20 | int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); | ||
21 | |||
22 | int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad); | ||
23 | int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len); | ||
24 | int EVP_PKEY_CTX_set_rsa_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits); | ||
25 | int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); | ||
26 | |||
27 | #include <openssl/dsa.h> | ||
28 | int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits); | ||
29 | |||
30 | #include <openssl/dh.h> | ||
31 | int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int len); | ||
32 | int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen); | ||
33 | |||
34 | #include <openssl/ec.h> | ||
35 | int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid); | ||
36 | |||
37 | =head1 DESCRIPTION | ||
38 | |||
39 | The function EVP_PKEY_CTX_ctrl() sends a control operation to the context | ||
40 | B<ctx>. The key type used must match B<keytype> if it is not -1. The parameter | ||
41 | B<optype> is a mask indicating which operations the control can be applied to. | ||
42 | The control command is indicated in B<cmd> and any additional arguments in | ||
43 | B<p1> and B<p2>. | ||
44 | |||
45 | Applications will not normally call EVP_PKEY_CTX_ctrl() directly but will | ||
46 | instead call one of the algorithm specific macros below. | ||
47 | |||
48 | The function EVP_PKEY_ctrl_str() allows an application to send an algorithm | ||
49 | specific control operation to a context B<ctx> in string form. This is | ||
50 | intended to be used for options specified on the command line or in text | ||
51 | files. The commands supported are documented in the openssl utility | ||
52 | command line pages for the option B<-pkeyopt> which is supported by the | ||
53 | B<pkeyutl>, B<genpkey> and B<req> commands. | ||
54 | |||
55 | All the remaining "functions" are implemented as macros. | ||
56 | |||
57 | The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used | ||
58 | in a signature. It can be used with any public key algorithm supporting | ||
59 | signature operations. | ||
60 | |||
61 | The macro EVP_PKEY_CTX_set_rsa_padding() sets the RSA padding mode for B<ctx>. | ||
62 | The B<pad> parameter can take the value RSA_PKCS1_PADDING for PKCS#1 padding, | ||
63 | RSA_SSLV23_PADDING for SSLv23 padding, RSA_NO_PADDING for no padding, | ||
64 | RSA_PKCS1_OAEP_PADDING for OAEP padding (encrypt and decrypt only), | ||
65 | RSA_X931_PADDING for X9.31 padding (signature operations only) and | ||
66 | RSA_PKCS1_PSS_PADDING (sign and verify only). | ||
67 | |||
68 | Two RSA padding modes behave differently if EVP_PKEY_CTX_set_signature_md() | ||
69 | is used. If this macro is called for PKCS#1 padding the plaintext buffer is | ||
70 | an actual digest value and is encapsulated in a DigestInfo structure according | ||
71 | to PKCS#1 when signing and this structure is expected (and stripped off) when | ||
72 | verifying. If this control is not used with RSA and PKCS#1 padding then the | ||
73 | supplied data is used directly and not encapsulated. In the case of X9.31 | ||
74 | padding for RSA the algorithm identifier byte is added or checked and removed | ||
75 | if this control is called. If it is not called then the first byte of the plaintext buffer is expected to be the algorithm identifier byte. | ||
76 | |||
77 | The EVP_PKEY_CTX_set_rsa_pss_saltlen() macro sets the RSA PSS salt length to | ||
78 | B<len> as its name implies it is only supported for PSS padding. Two special | ||
79 | values are supported: -1 sets the salt length to the digest length. When | ||
80 | signing -2 sets the salt length to the maximum permissible value. When | ||
81 | verifying -2 causes the salt length to be automatically determined based on the | ||
82 | B<PSS> block structure. If this macro is not called a salt length value of -2 | ||
83 | is used by default. | ||
84 | |||
85 | The EVP_PKEY_CTX_set_rsa_rsa_keygen_bits() macro sets the RSA key length for | ||
86 | RSA key genration to B<bits>. If not specified 1024 bits is used. | ||
87 | |||
88 | The EVP_PKEY_CTX_set_rsa_keygen_pubexp() macro sets the public exponent value | ||
89 | for RSA key generation to B<pubexp> currently it should be an odd integer. The | ||
90 | B<pubexp> pointer is used internally by this function so it should not be | ||
91 | modified or free after the call. If this macro is not called then 65537 is used. | ||
92 | |||
93 | The macro EVP_PKEY_CTX_set_dsa_paramgen_bits() sets the number of bits used | ||
94 | for DSA parameter generation to B<bits>. If not specified 1024 is used. | ||
95 | |||
96 | The macro EVP_PKEY_CTX_set_dh_paramgen_prime_len() sets the length of the DH | ||
97 | prime parameter B<p> for DH parameter generation. If this macro is not called | ||
98 | then 1024 is used. | ||
99 | |||
100 | The EVP_PKEY_CTX_set_dh_paramgen_generator() macro sets DH generator to B<gen> | ||
101 | for DH parameter generation. If not specified 2 is used. | ||
102 | |||
103 | The EVP_PKEY_CTX_set_ec_paramgen_curve_nid() sets the EC curve for EC parameter | ||
104 | generation to B<nid>. For EC parameter generation this macro must be called | ||
105 | or an error occurs because there is no default curve. | ||
106 | |||
107 | =head1 RETURN VALUES | ||
108 | |||
109 | EVP_PKEY_CTX_ctrl() and its macros return a positive value for success and 0 | ||
110 | or a negative value for failure. In particular a return value of -2 | ||
111 | indicates the operation is not supported by the public key algorithm. | ||
112 | |||
113 | =head1 SEE ALSO | ||
114 | |||
115 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
116 | L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>, | ||
117 | L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>, | ||
118 | L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>, | ||
119 | L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>, | ||
120 | L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>, | ||
121 | L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> | ||
122 | L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> | ||
123 | |||
124 | =head1 HISTORY | ||
125 | |||
126 | These functions were first added to OpenSSL 1.0.0. | ||
127 | |||
128 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_CTX_new.pod b/src/lib/libcrypto/doc/EVP_PKEY_CTX_new.pod new file mode 100644 index 0000000000..a9af867580 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_CTX_new.pod | |||
@@ -0,0 +1,52 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free - public key algorithm context functions. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); | ||
12 | EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); | ||
13 | EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); | ||
14 | void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | The EVP_PKEY_CTX_new() function allocates public key algorithm context using | ||
19 | the algorithm specified in B<pkey> and ENGINE B<e>. | ||
20 | |||
21 | The EVP_PKEY_CTX_new_id() function allocates public key algorithm context | ||
22 | using the algorithm specified by B<id> and ENGINE B<e>. It is normally used | ||
23 | when no B<EVP_PKEY> structure is associated with the operations, for example | ||
24 | during parameter generation of key genration for some algorithms. | ||
25 | |||
26 | EVP_PKEY_CTX_dup() duplicates the context B<ctx>. | ||
27 | |||
28 | EVP_PKEY_CTX_free() frees up the context B<ctx>. | ||
29 | |||
30 | =head1 NOTES | ||
31 | |||
32 | The B<EVP_PKEY_CTX> structure is an opaque public key algorithm context used | ||
33 | by the OpenSSL high level public key API. Contexts B<MUST NOT> be shared between | ||
34 | threads: that is it is not permissible to use the same context simultaneously | ||
35 | in two threads. | ||
36 | |||
37 | =head1 RETURN VALUES | ||
38 | |||
39 | EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id(), EVP_PKEY_CTX_dup() returns either | ||
40 | the newly allocated B<EVP_PKEY_CTX> structure of B<NULL> if an error occurred. | ||
41 | |||
42 | EVP_PKEY_CTX_free() does not return a value. | ||
43 | |||
44 | =head1 SEE ALSO | ||
45 | |||
46 | L<EVP_PKEY_new(3)|EVP_PKEY_new(3)> | ||
47 | |||
48 | =head1 HISTORY | ||
49 | |||
50 | These functions were first added to OpenSSL 1.0.0. | ||
51 | |||
52 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_cmp.pod b/src/lib/libcrypto/doc/EVP_PKEY_cmp.pod new file mode 100644 index 0000000000..4f8185e36c --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_cmp.pod | |||
@@ -0,0 +1,61 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_copy_parameters, EVP_PKEY_missing_parameters, EVP_PKEY_cmp_parameters, EVP_PKEY_cmp - public key parameter and comparison functions | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); | ||
12 | int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); | ||
13 | |||
14 | int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); | ||
15 | int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | The function EVP_PKEY_missing_parameters() returns 1 if the public key | ||
20 | parameters of B<pkey> are missing and 0 if they are present or the algorithm | ||
21 | doesn't use parameters. | ||
22 | |||
23 | The function EVP_PKEY_copy_parameters() copies the parameters from key | ||
24 | B<from> to key B<to>. | ||
25 | |||
26 | The funcion EVP_PKEY_cmp_parameters() compares the parameters of keys | ||
27 | B<a> and B<b>. | ||
28 | |||
29 | The funcion EVP_PKEY_cmp() compares the public key components and paramters | ||
30 | (if present) of keys B<a> and B<b>. | ||
31 | |||
32 | =head1 NOTES | ||
33 | |||
34 | The main purpose of the functions EVP_PKEY_missing_parameters() and | ||
35 | EVP_PKEY_copy_parameters() is to handle public keys in certificates where the | ||
36 | parameters are sometimes omitted from a public key if they are inherited from | ||
37 | the CA that signed it. | ||
38 | |||
39 | Since OpenSSL private keys contain public key components too the function | ||
40 | EVP_PKEY_cmp() can also be used to determine if a private key matches | ||
41 | a public key. | ||
42 | |||
43 | =head1 RETURN VALUES | ||
44 | |||
45 | The function EVP_PKEY_missing_parameters() returns 1 if the public key | ||
46 | parameters of B<pkey> are missing and 0 if they are present or the algorithm | ||
47 | doesn't use parameters. | ||
48 | |||
49 | These functions EVP_PKEY_copy_parameters() returns 1 for success and 0 for | ||
50 | failure. | ||
51 | |||
52 | The function EVP_PKEY_cmp_parameters() and EVP_PKEY_cmp() return 1 if the | ||
53 | keys match, 0 if they don't match, -1 if the key types are different and | ||
54 | -2 if the operation is not supported. | ||
55 | |||
56 | =head1 SEE ALSO | ||
57 | |||
58 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
59 | L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> | ||
60 | |||
61 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod b/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod new file mode 100644 index 0000000000..42b2a8c44e --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod | |||
@@ -0,0 +1,93 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_decrypt_init, EVP_PKEY_decrypt - decrypt using a public key algorithm | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); | ||
12 | int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, | ||
13 | unsigned char *out, size_t *outlen, | ||
14 | const unsigned char *in, size_t inlen); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | The EVP_PKEY_decrypt_init() function initializes a public key algorithm | ||
19 | context using key B<pkey> for a decryption operation. | ||
20 | |||
21 | The EVP_PKEY_decrypt() function performs a public key decryption operation | ||
22 | using B<ctx>. The data to be decrypted is specified using the B<in> and | ||
23 | B<inlen> parameters. If B<out> is B<NULL> then the maximum size of the output | ||
24 | buffer is written to the B<outlen> parameter. If B<out> is not B<NULL> then | ||
25 | before the call the B<outlen> parameter should contain the length of the | ||
26 | B<out> buffer, if the call is successful the decrypted data is written to | ||
27 | B<out> and the amount of data written to B<outlen>. | ||
28 | |||
29 | =head1 NOTES | ||
30 | |||
31 | After the call to EVP_PKEY_decrypt_init() algorithm specific control | ||
32 | operations can be performed to set any appropriate parameters for the | ||
33 | operation. | ||
34 | |||
35 | The function EVP_PKEY_decrypt() can be called more than once on the same | ||
36 | context if several operations are performed using the same parameters. | ||
37 | |||
38 | =head1 RETURN VALUES | ||
39 | |||
40 | EVP_PKEY_decrypt_init() and EVP_PKEY_decrypt() return 1 for success and 0 | ||
41 | or a negative value for failure. In particular a return value of -2 | ||
42 | indicates the operation is not supported by the public key algorithm. | ||
43 | |||
44 | =head1 EXAMPLE | ||
45 | |||
46 | Decrypt data using OAEP (for RSA keys): | ||
47 | |||
48 | #include <openssl/evp.h> | ||
49 | #include <openssl/rsa.h> | ||
50 | |||
51 | EVP_PKEY_CTX *ctx; | ||
52 | unsigned char *out, *in; | ||
53 | size_t outlen, inlen; | ||
54 | EVP_PKEY *key; | ||
55 | /* NB: assumes key in, inlen are already set up | ||
56 | * and that key is an RSA private key | ||
57 | */ | ||
58 | ctx = EVP_PKEY_CTX_new(key); | ||
59 | if (!ctx) | ||
60 | /* Error occurred */ | ||
61 | if (EVP_PKEY_decrypt_init(ctx) <= 0) | ||
62 | /* Error */ | ||
63 | if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0) | ||
64 | /* Error */ | ||
65 | |||
66 | /* Determine buffer length */ | ||
67 | if (EVP_PKEY_decrypt(ctx, NULL, &outlen, in, inlen) <= 0) | ||
68 | /* Error */ | ||
69 | |||
70 | out = OPENSSL_malloc(outlen); | ||
71 | |||
72 | if (!out) | ||
73 | /* malloc failure */ | ||
74 | |||
75 | if (EVP_PKEY_decrypt(ctx, out, &outlen, in, inlen) <= 0) | ||
76 | /* Error */ | ||
77 | |||
78 | /* Decrypted data is outlen bytes written to buffer out */ | ||
79 | |||
80 | =head1 SEE ALSO | ||
81 | |||
82 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
83 | L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>, | ||
84 | L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>, | ||
85 | L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>, | ||
86 | L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>, | ||
87 | L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> | ||
88 | |||
89 | =head1 HISTORY | ||
90 | |||
91 | These functions were first added to OpenSSL 1.0.0. | ||
92 | |||
93 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_derive.pod b/src/lib/libcrypto/doc/EVP_PKEY_derive.pod new file mode 100644 index 0000000000..d9d6d76c72 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_derive.pod | |||
@@ -0,0 +1,93 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_derive_init, EVP_PKEY_derive_set_peer, EVP_PKEY_derive - derive public key algorithm shared secret. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); | ||
12 | int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); | ||
13 | int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | The EVP_PKEY_derive_init() function initializes a public key algorithm | ||
18 | context using key B<pkey> for shared secret derivation. | ||
19 | |||
20 | The EVP_PKEY_derive_set_peer() function sets the peer key: this will normally | ||
21 | be a public key. | ||
22 | |||
23 | The EVP_PKEY_derive() derives a shared secret using B<ctx>. | ||
24 | If B<key> is B<NULL> then the maximum size of the output buffer is written to | ||
25 | the B<keylen> parameter. If B<key> is not B<NULL> then before the call the | ||
26 | B<keylen> parameter should contain the length of the B<key> buffer, if the call | ||
27 | is successful the shared secret is written to B<key> and the amount of data | ||
28 | written to B<keylen>. | ||
29 | |||
30 | =head1 NOTES | ||
31 | |||
32 | After the call to EVP_PKEY_derive_init() algorithm specific control | ||
33 | operations can be performed to set any appropriate parameters for the | ||
34 | operation. | ||
35 | |||
36 | The function EVP_PKEY_derive() can be called more than once on the same | ||
37 | context if several operations are performed using the same parameters. | ||
38 | |||
39 | =head1 RETURN VALUES | ||
40 | |||
41 | EVP_PKEY_derive_init() and EVP_PKEY_derive() return 1 for success and 0 | ||
42 | or a negative value for failure. In particular a return value of -2 | ||
43 | indicates the operation is not supported by the public key algorithm. | ||
44 | |||
45 | =head1 EXAMPLE | ||
46 | |||
47 | Derive shared secret (for example DH or EC keys): | ||
48 | |||
49 | #include <openssl/evp.h> | ||
50 | #include <openssl/rsa.h> | ||
51 | |||
52 | EVP_PKEY_CTX *ctx; | ||
53 | unsigned char *skey; | ||
54 | size_t skeylen; | ||
55 | EVP_PKEY *pkey, *peerkey; | ||
56 | /* NB: assumes pkey, peerkey have been already set up */ | ||
57 | |||
58 | ctx = EVP_PKEY_CTX_new(pkey); | ||
59 | if (!ctx) | ||
60 | /* Error occurred */ | ||
61 | if (EVP_PKEY_derive_init(ctx) <= 0) | ||
62 | /* Error */ | ||
63 | if (EVP_PKEY_derive_set_peer(ctx, peerkey) <= 0) | ||
64 | /* Error */ | ||
65 | |||
66 | /* Determine buffer length */ | ||
67 | if (EVP_PKEY_derive(ctx, NULL, &skeylen) <= 0) | ||
68 | /* Error */ | ||
69 | |||
70 | skey = OPENSSL_malloc(skeylen); | ||
71 | |||
72 | if (!skey) | ||
73 | /* malloc failure */ | ||
74 | |||
75 | if (EVP_PKEY_derive(ctx, skey, &skeylen) <= 0) | ||
76 | /* Error */ | ||
77 | |||
78 | /* Shared secret is skey bytes written to buffer skey */ | ||
79 | |||
80 | =head1 SEE ALSO | ||
81 | |||
82 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
83 | L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>, | ||
84 | L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>, | ||
85 | L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>, | ||
86 | L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>, | ||
87 | L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>, | ||
88 | |||
89 | =head1 HISTORY | ||
90 | |||
91 | These functions were first added to OpenSSL 1.0.0. | ||
92 | |||
93 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod b/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod new file mode 100644 index 0000000000..91c9c5d0a5 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod | |||
@@ -0,0 +1,93 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_encrypt_init, EVP_PKEY_encrypt - encrypt using a public key algorithm | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); | ||
12 | int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, | ||
13 | unsigned char *out, size_t *outlen, | ||
14 | const unsigned char *in, size_t inlen); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | The EVP_PKEY_encrypt_init() function initializes a public key algorithm | ||
19 | context using key B<pkey> for an encryption operation. | ||
20 | |||
21 | The EVP_PKEY_encrypt() function performs a public key encryption operation | ||
22 | using B<ctx>. The data to be encrypted is specified using the B<in> and | ||
23 | B<inlen> parameters. If B<out> is B<NULL> then the maximum size of the output | ||
24 | buffer is written to the B<outlen> parameter. If B<out> is not B<NULL> then | ||
25 | before the call the B<outlen> parameter should contain the length of the | ||
26 | B<out> buffer, if the call is successful the encrypted data is written to | ||
27 | B<out> and the amount of data written to B<outlen>. | ||
28 | |||
29 | =head1 NOTES | ||
30 | |||
31 | After the call to EVP_PKEY_encrypt_init() algorithm specific control | ||
32 | operations can be performed to set any appropriate parameters for the | ||
33 | operation. | ||
34 | |||
35 | The function EVP_PKEY_encrypt() can be called more than once on the same | ||
36 | context if several operations are performed using the same parameters. | ||
37 | |||
38 | =head1 RETURN VALUES | ||
39 | |||
40 | EVP_PKEY_encrypt_init() and EVP_PKEY_encrypt() return 1 for success and 0 | ||
41 | or a negative value for failure. In particular a return value of -2 | ||
42 | indicates the operation is not supported by the public key algorithm. | ||
43 | |||
44 | =head1 EXAMPLE | ||
45 | |||
46 | Encrypt data using OAEP (for RSA keys): | ||
47 | |||
48 | #include <openssl/evp.h> | ||
49 | #include <openssl/rsa.h> | ||
50 | |||
51 | EVP_PKEY_CTX *ctx; | ||
52 | unsigned char *out, *in; | ||
53 | size_t outlen, inlen; | ||
54 | EVP_PKEY *key; | ||
55 | /* NB: assumes key in, inlen are already set up | ||
56 | * and that key is an RSA public key | ||
57 | */ | ||
58 | ctx = EVP_PKEY_CTX_new(key); | ||
59 | if (!ctx) | ||
60 | /* Error occurred */ | ||
61 | if (EVP_PKEY_encrypt_init(ctx) <= 0) | ||
62 | /* Error */ | ||
63 | if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0) | ||
64 | /* Error */ | ||
65 | |||
66 | /* Determine buffer length */ | ||
67 | if (EVP_PKEY_encrypt(ctx, NULL, &outlen, in, inlen) <= 0) | ||
68 | /* Error */ | ||
69 | |||
70 | out = OPENSSL_malloc(outlen); | ||
71 | |||
72 | if (!out) | ||
73 | /* malloc failure */ | ||
74 | |||
75 | if (EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen) <= 0) | ||
76 | /* Error */ | ||
77 | |||
78 | /* Encrypted data is outlen bytes written to buffer out */ | ||
79 | |||
80 | =head1 SEE ALSO | ||
81 | |||
82 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
83 | L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>, | ||
84 | L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>, | ||
85 | L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>, | ||
86 | L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>, | ||
87 | L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> | ||
88 | |||
89 | =head1 HISTORY | ||
90 | |||
91 | These functions were first added to OpenSSL 1.0.0. | ||
92 | |||
93 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod b/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod new file mode 100644 index 0000000000..1a9c7954c5 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod | |||
@@ -0,0 +1,41 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_get_default_digest_nid - get default signature digest | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); | ||
11 | |||
12 | =head1 DESCRIPTION | ||
13 | |||
14 | The EVP_PKEY_get_default_digest_nid() function sets B<pnid> to the default | ||
15 | message digest NID for the public key signature operations associated with key | ||
16 | B<pkey>. | ||
17 | |||
18 | =head1 NOTES | ||
19 | |||
20 | For all current standard OpenSSL public key algorithms SHA1 is returned. | ||
21 | |||
22 | =head1 RETURN VALUES | ||
23 | |||
24 | The EVP_PKEY_get_default_digest_nid() function returns 1 if the message digest | ||
25 | is advisory (that is other digests can be used) and 2 if it is mandatory (other | ||
26 | digests can not be used). It returns 0 or a negative value for failure. In | ||
27 | particular a return value of -2 indicates the operation is not supported by the | ||
28 | public key algorithm. | ||
29 | |||
30 | =head1 SEE ALSO | ||
31 | |||
32 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
33 | L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>, | ||
34 | L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>, | ||
35 | L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>, | ||
36 | |||
37 | =head1 HISTORY | ||
38 | |||
39 | This function was first added to OpenSSL 1.0.0. | ||
40 | |||
41 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod b/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod new file mode 100644 index 0000000000..37c6fe9503 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod | |||
@@ -0,0 +1,161 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_keygen_init, EVP_PKEY_keygen, EVP_PKEY_paramgen_init, EVP_PKEY_paramgen, EVP_PKEY_CTX_set_cb, EVP_PKEY_CTX_get_cb, EVP_PKEY_CTX_get_keygen_info, EVP_PKEVP_PKEY_CTX_set_app_data, EVP_PKEY_CTX_get_app_data - key and parameter generation functions | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); | ||
12 | int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); | ||
13 | int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); | ||
14 | int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); | ||
15 | |||
16 | typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); | ||
17 | |||
18 | void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); | ||
19 | EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); | ||
20 | |||
21 | int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); | ||
22 | |||
23 | void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); | ||
24 | void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); | ||
25 | |||
26 | =head1 DESCRIPTION | ||
27 | |||
28 | The EVP_PKEY_keygen_init() function initializes a public key algorithm | ||
29 | context using key B<pkey> for a key genration operation. | ||
30 | |||
31 | The EVP_PKEY_keygen() function performs a key generation operation, the | ||
32 | generated key is written to B<ppkey>. | ||
33 | |||
34 | The functions EVP_PKEY_paramgen_init() and EVP_PKEY_paramgen() are similar | ||
35 | except parameters are generated. | ||
36 | |||
37 | The function EVP_PKEY_set_cb() sets the key or parameter generation callback | ||
38 | to B<cb>. The function EVP_PKEY_CTX_get_cb() returns the key or parameter | ||
39 | generation callback. | ||
40 | |||
41 | The function EVP_PKEY_CTX_get_keygen_info() returns parameters associated | ||
42 | with the generation operation. If B<idx> is -1 the total number of | ||
43 | parameters available is returned. Any non negative value returns the value of | ||
44 | that parameter. EVP_PKEY_CTX_gen_keygen_info() with a non-negative value for | ||
45 | B<idx> should only be called within the generation callback. | ||
46 | |||
47 | If the callback returns 0 then the key genration operation is aborted and an | ||
48 | error occurs. This might occur during a time consuming operation where | ||
49 | a user clicks on a "cancel" button. | ||
50 | |||
51 | The functions EVP_PKEY_CTX_set_app_data() and EVP_PKEY_CTX_get_app_data() set | ||
52 | and retrieve an opaque pointer. This can be used to set some application | ||
53 | defined value which can be retrieved in the callback: for example a handle | ||
54 | which is used to update a "progress dialog". | ||
55 | |||
56 | =head1 NOTES | ||
57 | |||
58 | After the call to EVP_PKEY_keygen_init() or EVP_PKEY_paramgen_init() algorithm | ||
59 | specific control operations can be performed to set any appropriate parameters | ||
60 | for the operation. | ||
61 | |||
62 | The functions EVP_PKEY_keygen() and EVP_PKEY_paramgen() can be called more than | ||
63 | once on the same context if several operations are performed using the same | ||
64 | parameters. | ||
65 | |||
66 | The meaning of the parameters passed to the callback will depend on the | ||
67 | algorithm and the specifiic implementation of the algorithm. Some might not | ||
68 | give any useful information at all during key or parameter generation. Others | ||
69 | might not even call the callback. | ||
70 | |||
71 | The operation performed by key or parameter generation depends on the algorithm | ||
72 | used. In some cases (e.g. EC with a supplied named curve) the "generation" | ||
73 | option merely sets the appropriate fields in an EVP_PKEY structure. | ||
74 | |||
75 | In OpenSSL an EVP_PKEY structure containing a private key also contains the | ||
76 | public key components and parameters (if any). An OpenSSL private key is | ||
77 | equivalent to what some libraries call a "key pair". A private key can be used | ||
78 | in functions which require the use of a public key or parameters. | ||
79 | |||
80 | =head1 RETURN VALUES | ||
81 | |||
82 | EVP_PKEY_keygen_init(), EVP_PKEY_paramgen_init(), EVP_PKEY_keygen() and | ||
83 | EVP_PKEY_paramgen() return 1 for success and 0 or a negative value for failure. | ||
84 | In particular a return value of -2 indicates the operation is not supported by | ||
85 | the public key algorithm. | ||
86 | |||
87 | =head1 EXAMPLES | ||
88 | |||
89 | Generate a 2048 bit RSA key: | ||
90 | |||
91 | #include <openssl/evp.h> | ||
92 | #include <openssl/rsa.h> | ||
93 | |||
94 | EVP_PKEY_CTX *ctx; | ||
95 | EVP_PKEY *pkey = NULL; | ||
96 | ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); | ||
97 | if (!ctx) | ||
98 | /* Error occurred */ | ||
99 | if (EVP_PKEY_keygen_init(ctx) <= 0) | ||
100 | /* Error */ | ||
101 | if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) | ||
102 | /* Error */ | ||
103 | |||
104 | /* Generate key */ | ||
105 | if (EVP_PKEY_keygen(ctx, &pkey) <= 0) | ||
106 | /* Error */ | ||
107 | |||
108 | Generate a key from a set of parameters: | ||
109 | |||
110 | #include <openssl/evp.h> | ||
111 | #include <openssl/rsa.h> | ||
112 | |||
113 | EVP_PKEY_CTX *ctx; | ||
114 | EVP_PKEY *pkey = NULL, *param; | ||
115 | /* Assumed param is set up already */ | ||
116 | ctx = EVP_PKEY_CTX_new(param); | ||
117 | if (!ctx) | ||
118 | /* Error occurred */ | ||
119 | if (EVP_PKEY_keygen_init(ctx) <= 0) | ||
120 | /* Error */ | ||
121 | |||
122 | /* Generate key */ | ||
123 | if (EVP_PKEY_keygen(ctx, &pkey) <= 0) | ||
124 | /* Error */ | ||
125 | |||
126 | Example of generation callback for OpenSSL public key implementations: | ||
127 | |||
128 | /* Application data is a BIO to output status to */ | ||
129 | |||
130 | EVP_PKEY_CTX_set_app_data(ctx, status_bio); | ||
131 | |||
132 | static int genpkey_cb(EVP_PKEY_CTX *ctx) | ||
133 | { | ||
134 | char c='*'; | ||
135 | BIO *b = EVP_PKEY_CTX_get_app_data(ctx); | ||
136 | int p; | ||
137 | p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); | ||
138 | if (p == 0) c='.'; | ||
139 | if (p == 1) c='+'; | ||
140 | if (p == 2) c='*'; | ||
141 | if (p == 3) c='\n'; | ||
142 | BIO_write(b,&c,1); | ||
143 | (void)BIO_flush(b); | ||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | =head1 SEE ALSO | ||
148 | |||
149 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
150 | L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>, | ||
151 | L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>, | ||
152 | L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>, | ||
153 | L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>, | ||
154 | L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>, | ||
155 | L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> | ||
156 | |||
157 | =head1 HISTORY | ||
158 | |||
159 | These functions were first added to OpenSSL 1.0.0. | ||
160 | |||
161 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_print_private.pod b/src/lib/libcrypto/doc/EVP_PKEY_print_private.pod new file mode 100644 index 0000000000..ce9d70d7a7 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_print_private.pod | |||
@@ -0,0 +1,53 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_print_public, EVP_PKEY_print_private, EVP_PKEY_print_params - public key algorithm printing routines. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, | ||
12 | int indent, ASN1_PCTX *pctx); | ||
13 | int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, | ||
14 | int indent, ASN1_PCTX *pctx); | ||
15 | int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, | ||
16 | int indent, ASN1_PCTX *pctx); | ||
17 | |||
18 | =head1 DESCRIPTION | ||
19 | |||
20 | The functions EVP_PKEY_print_public(), EVP_PKEY_print_private() and | ||
21 | EVP_PKEY_print_params() print out the public, private or parameter components | ||
22 | of key B<pkey> respectively. The key is sent to BIO B<out> in human readable | ||
23 | form. The parameter B<indent> indicated how far the printout should be indented. | ||
24 | |||
25 | The B<pctx> parameter allows the print output to be finely tuned by using | ||
26 | ASN1 printing options. If B<pctx> is set to NULL then default values will | ||
27 | be used. | ||
28 | |||
29 | =head1 NOTES | ||
30 | |||
31 | Currently no public key algorithms include any options in the B<pctx> parameter | ||
32 | parameter. | ||
33 | |||
34 | If the key does not include all the components indicated by the function then | ||
35 | only those contained in the key will be printed. For example passing a public | ||
36 | key to EVP_PKEY_print_private() will only print the public components. | ||
37 | |||
38 | =head1 RETURN VALUES | ||
39 | |||
40 | These functions all return 1 for success and 0 or a negative value for failure. | ||
41 | In particular a return value of -2 indicates the operation is not supported by | ||
42 | the public key algorithm. | ||
43 | |||
44 | =head1 SEE ALSO | ||
45 | |||
46 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
47 | L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> | ||
48 | |||
49 | =head1 HISTORY | ||
50 | |||
51 | These functions were first added to OpenSSL 1.0.0. | ||
52 | |||
53 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_sign.pod b/src/lib/libcrypto/doc/EVP_PKEY_sign.pod new file mode 100644 index 0000000000..2fb52c3486 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_sign.pod | |||
@@ -0,0 +1,96 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_sign_init, EVP_PKEY_sign - sign using a public key algorithm | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); | ||
12 | int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, | ||
13 | unsigned char *sig, size_t *siglen, | ||
14 | const unsigned char *tbs, size_t tbslen); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | The EVP_PKEY_sign_init() function initializes a public key algorithm | ||
19 | context using key B<pkey> for a signing operation. | ||
20 | |||
21 | The EVP_PKEY_sign() function performs a public key signing operation | ||
22 | using B<ctx>. The data to be signed is specified using the B<tbs> and | ||
23 | B<tbslen> parameters. If B<sig> is B<NULL> then the maximum size of the output | ||
24 | buffer is written to the B<siglen> parameter. If B<sig> is not B<NULL> then | ||
25 | before the call the B<siglen> parameter should contain the length of the | ||
26 | B<sig> buffer, if the call is successful the signature is written to | ||
27 | B<sig> and the amount of data written to B<siglen>. | ||
28 | |||
29 | =head1 NOTES | ||
30 | |||
31 | After the call to EVP_PKEY_sign_init() algorithm specific control | ||
32 | operations can be performed to set any appropriate parameters for the | ||
33 | operation. | ||
34 | |||
35 | The function EVP_PKEY_sign() can be called more than once on the same | ||
36 | context if several operations are performed using the same parameters. | ||
37 | |||
38 | =head1 RETURN VALUES | ||
39 | |||
40 | EVP_PKEY_sign_init() and EVP_PKEY_sign() return 1 for success and 0 | ||
41 | or a negative value for failure. In particular a return value of -2 | ||
42 | indicates the operation is not supported by the public key algorithm. | ||
43 | |||
44 | =head1 EXAMPLE | ||
45 | |||
46 | Sign data using RSA with PKCS#1 padding and SHA256 digest: | ||
47 | |||
48 | #include <openssl/evp.h> | ||
49 | #include <openssl/rsa.h> | ||
50 | |||
51 | EVP_PKEY_CTX *ctx; | ||
52 | unsigned char *md, *sig; | ||
53 | size_t mdlen, siglen; | ||
54 | EVP_PKEY *signing_key; | ||
55 | /* NB: assumes signing_key, md and mdlen are already set up | ||
56 | * and that signing_key is an RSA private key | ||
57 | */ | ||
58 | ctx = EVP_PKEY_CTX_new(signing_key); | ||
59 | if (!ctx) | ||
60 | /* Error occurred */ | ||
61 | if (EVP_PKEY_sign_init(ctx) <= 0) | ||
62 | /* Error */ | ||
63 | if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) | ||
64 | /* Error */ | ||
65 | if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) | ||
66 | /* Error */ | ||
67 | |||
68 | /* Determine buffer length */ | ||
69 | if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0) | ||
70 | /* Error */ | ||
71 | |||
72 | sig = OPENSSL_malloc(siglen); | ||
73 | |||
74 | if (!sig) | ||
75 | /* malloc failure */ | ||
76 | |||
77 | if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0) | ||
78 | /* Error */ | ||
79 | |||
80 | /* Signature is siglen bytes written to buffer sig */ | ||
81 | |||
82 | |||
83 | =head1 SEE ALSO | ||
84 | |||
85 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
86 | L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>, | ||
87 | L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>, | ||
88 | L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>, | ||
89 | L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>, | ||
90 | L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> | ||
91 | |||
92 | =head1 HISTORY | ||
93 | |||
94 | These functions were first added to OpenSSL 1.0.0. | ||
95 | |||
96 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_verify.pod b/src/lib/libcrypto/doc/EVP_PKEY_verify.pod new file mode 100644 index 0000000000..10633da3f2 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_verify.pod | |||
@@ -0,0 +1,91 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_PKEY_verify_init, EVP_PKEY_verify - signature verification using a public key algorithm | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); | ||
12 | int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, | ||
13 | const unsigned char *sig, size_t siglen, | ||
14 | const unsigned char *tbs, size_t tbslen); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | The EVP_PKEY_verify_init() function initializes a public key algorithm | ||
19 | context using key B<pkey> for a signature verification operation. | ||
20 | |||
21 | The EVP_PKEY_verify() function performs a public key verification operation | ||
22 | using B<ctx>. The signature is specified using the B<sig> and | ||
23 | B<siglen> parameters. The verified data (i.e. the data believed originally | ||
24 | signed) is specified using the B<tbs> and B<tbslen> parameters. | ||
25 | |||
26 | =head1 NOTES | ||
27 | |||
28 | After the call to EVP_PKEY_verify_init() algorithm specific control | ||
29 | operations can be performed to set any appropriate parameters for the | ||
30 | operation. | ||
31 | |||
32 | The function EVP_PKEY_verify() can be called more than once on the same | ||
33 | context if several operations are performed using the same parameters. | ||
34 | |||
35 | =head1 RETURN VALUES | ||
36 | |||
37 | EVP_PKEY_verify_init() and EVP_PKEY_verify() return 1 if the verification was | ||
38 | successful and 0 if it failed. Unlike other functions the return value 0 from | ||
39 | EVP_PKEY_verify() only indicates that the signature did not not verify | ||
40 | successfully (that is tbs did not match the original data or the signature was | ||
41 | of invalid form) it is not an indication of a more serious error. | ||
42 | |||
43 | A negative value indicates an error other that signature verification failure. | ||
44 | In particular a return value of -2 indicates the operation is not supported by | ||
45 | the public key algorithm. | ||
46 | |||
47 | =head1 EXAMPLE | ||
48 | |||
49 | Verify signature using PKCS#1 and SHA256 digest: | ||
50 | |||
51 | #include <openssl/evp.h> | ||
52 | #include <openssl/rsa.h> | ||
53 | |||
54 | EVP_PKEY_CTX *ctx; | ||
55 | unsigned char *md, *sig; | ||
56 | size_t mdlen, siglen; | ||
57 | EVP_PKEY *verify_key; | ||
58 | /* NB: assumes verify_key, sig, siglen md and mdlen are already set up | ||
59 | * and that verify_key is an RSA public key | ||
60 | */ | ||
61 | ctx = EVP_PKEY_CTX_new(verify_key); | ||
62 | if (!ctx) | ||
63 | /* Error occurred */ | ||
64 | if (EVP_PKEY_verify_init(ctx) <= 0) | ||
65 | /* Error */ | ||
66 | if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) | ||
67 | /* Error */ | ||
68 | if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) | ||
69 | /* Error */ | ||
70 | |||
71 | /* Perform operation */ | ||
72 | ret = EVP_PKEY_verify(ctx, md, mdlen, sig, siglen); | ||
73 | |||
74 | /* ret == 1 indicates success, 0 verify failure and < 0 for some | ||
75 | * other error. | ||
76 | */ | ||
77 | |||
78 | =head1 SEE ALSO | ||
79 | |||
80 | L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, | ||
81 | L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>, | ||
82 | L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>, | ||
83 | L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>, | ||
84 | L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>, | ||
85 | L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> | ||
86 | |||
87 | =head1 HISTORY | ||
88 | |||
89 | These functions were first added to OpenSSL 1.0.0. | ||
90 | |||
91 | =cut | ||
diff --git a/src/lib/libcrypto/doc/OBJ_nid2obj.pod b/src/lib/libcrypto/doc/OBJ_nid2obj.pod index 7dcc07923f..1e45dd40f6 100644 --- a/src/lib/libcrypto/doc/OBJ_nid2obj.pod +++ b/src/lib/libcrypto/doc/OBJ_nid2obj.pod | |||
@@ -8,6 +8,8 @@ functions | |||
8 | 8 | ||
9 | =head1 SYNOPSIS | 9 | =head1 SYNOPSIS |
10 | 10 | ||
11 | #include <openssl/objects.h> | ||
12 | |||
11 | ASN1_OBJECT * OBJ_nid2obj(int n); | 13 | ASN1_OBJECT * OBJ_nid2obj(int n); |
12 | const char * OBJ_nid2ln(int n); | 14 | const char * OBJ_nid2ln(int n); |
13 | const char * OBJ_nid2sn(int n); | 15 | const char * OBJ_nid2sn(int n); |
diff --git a/src/lib/libcrypto/doc/PEM_write_bio_CMS_stream.pod b/src/lib/libcrypto/doc/PEM_write_bio_CMS_stream.pod new file mode 100644 index 0000000000..e070c45c2e --- /dev/null +++ b/src/lib/libcrypto/doc/PEM_write_bio_CMS_stream.pod | |||
@@ -0,0 +1,41 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | PEM_write_bio_CMS_stream - output CMS_ContentInfo structure in PEM format. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/cms.h> | ||
10 | #include <openssl/pem.h> | ||
11 | |||
12 | int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags); | ||
13 | |||
14 | =head1 DESCRIPTION | ||
15 | |||
16 | PEM_write_bio_CMS_stream() outputs a CMS_ContentInfo structure in PEM format. | ||
17 | |||
18 | It is otherwise identical to the function SMIME_write_CMS(). | ||
19 | |||
20 | =head1 NOTES | ||
21 | |||
22 | This function is effectively a version of the PEM_write_bio_CMS() supporting | ||
23 | streaming. | ||
24 | |||
25 | =head1 RETURN VALUES | ||
26 | |||
27 | PEM_write_bio_CMS_stream() returns 1 for success or 0 for failure. | ||
28 | |||
29 | =head1 SEE ALSO | ||
30 | |||
31 | L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>, | ||
32 | L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)> | ||
33 | L<CMS_decrypt(3)|CMS_decrypt(3)>, | ||
34 | L<SMIME_write_CMS(3)|SMIME_write_CMS(3)>, | ||
35 | L<i2d_CMS_bio_stream(3)|i2d_CMS_bio_stream(3)> | ||
36 | |||
37 | =head1 HISTORY | ||
38 | |||
39 | PEM_write_bio_CMS_stream() was added to OpenSSL 1.0.0 | ||
40 | |||
41 | =cut | ||
diff --git a/src/lib/libcrypto/doc/PEM_write_bio_PKCS7_stream.pod b/src/lib/libcrypto/doc/PEM_write_bio_PKCS7_stream.pod new file mode 100644 index 0000000000..16fc9b6845 --- /dev/null +++ b/src/lib/libcrypto/doc/PEM_write_bio_PKCS7_stream.pod | |||
@@ -0,0 +1,41 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | PEM_write_bio_PKCS7_stream - output PKCS7 structure in PEM format. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/pkcs7.h> | ||
10 | #include <openssl/pem.h> | ||
11 | |||
12 | int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *data, int flags); | ||
13 | |||
14 | =head1 DESCRIPTION | ||
15 | |||
16 | PEM_write_bio_PKCS7_stream() outputs a PKCS7 structure in PEM format. | ||
17 | |||
18 | It is otherwise identical to the function SMIME_write_PKCS7(). | ||
19 | |||
20 | =head1 NOTES | ||
21 | |||
22 | This function is effectively a version of the PEM_write_bio_PKCS7() supporting | ||
23 | streaming. | ||
24 | |||
25 | =head1 RETURN VALUES | ||
26 | |||
27 | PEM_write_bio_PKCS7_stream() returns 1 for success or 0 for failure. | ||
28 | |||
29 | =head1 SEE ALSO | ||
30 | |||
31 | L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>, | ||
32 | L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)> | ||
33 | L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>, | ||
34 | L<SMIME_write_PKCS7(3)|SMIME_write_PKCS7(3)>, | ||
35 | L<i2d_PKCS7_bio_stream(3)|i2d_PKCS7_bio_stream(3)> | ||
36 | |||
37 | =head1 HISTORY | ||
38 | |||
39 | PEM_write_bio_PKCS7_stream() was added to OpenSSL 1.0.0 | ||
40 | |||
41 | =cut | ||
diff --git a/src/lib/libcrypto/doc/PKCS12_parse.pod b/src/lib/libcrypto/doc/PKCS12_parse.pod index 51344f883a..c54cf2ad61 100644 --- a/src/lib/libcrypto/doc/PKCS12_parse.pod +++ b/src/lib/libcrypto/doc/PKCS12_parse.pod | |||
@@ -20,24 +20,31 @@ certificate to B<*cert> and any additional certificates to B<*ca>. | |||
20 | 20 | ||
21 | =head1 NOTES | 21 | =head1 NOTES |
22 | 22 | ||
23 | The parameters B<pkey> and B<cert> cannot be B<NULL>. B<ca> can be <NULL> | 23 | The parameters B<pkey> and B<cert> cannot be B<NULL>. B<ca> can be <NULL> in |
24 | in which case additional certificates will be discarded. B<*ca> can also | 24 | which case additional certificates will be discarded. B<*ca> can also be a |
25 | be a valid STACK in which case additional certificates are appended to | 25 | valid STACK in which case additional certificates are appended to B<*ca>. If |
26 | B<*ca>. If B<*ca> is B<NULL> a new STACK will be allocated. | 26 | B<*ca> is B<NULL> a new STACK will be allocated. |
27 | 27 | ||
28 | The B<friendlyName> and B<localKeyID> attributes (if present) on each certificate | 28 | The B<friendlyName> and B<localKeyID> attributes (if present) on each |
29 | will be stored in the B<alias> and B<keyid> attributes of the B<X509> structure. | 29 | certificate will be stored in the B<alias> and B<keyid> attributes of the |
30 | B<X509> structure. | ||
31 | |||
32 | =head1 RETURN VALUES | ||
33 | |||
34 | PKCS12_parse() returns 1 for success and zero if an error occurred. | ||
35 | |||
36 | The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)> | ||
30 | 37 | ||
31 | =head1 BUGS | 38 | =head1 BUGS |
32 | 39 | ||
33 | Only a single private key and corresponding certificate is returned by this function. | 40 | Only a single private key and corresponding certificate is returned by this |
34 | More complex PKCS#12 files with multiple private keys will only return the first | 41 | function. More complex PKCS#12 files with multiple private keys will only |
35 | match. | 42 | return the first match. |
36 | 43 | ||
37 | Only B<friendlyName> and B<localKeyID> attributes are currently stored in certificates. | 44 | Only B<friendlyName> and B<localKeyID> attributes are currently stored in |
38 | Other attributes are discarded. | 45 | certificates. Other attributes are discarded. |
39 | 46 | ||
40 | Attributes currently cannot be store in the private key B<EVP_PKEY> structure. | 47 | Attributes currently cannot be stored in the private key B<EVP_PKEY> structure. |
41 | 48 | ||
42 | =head1 SEE ALSO | 49 | =head1 SEE ALSO |
43 | 50 | ||
diff --git a/src/lib/libcrypto/doc/PKCS7_decrypt.pod b/src/lib/libcrypto/doc/PKCS7_decrypt.pod index b0ca067b89..325699d0b6 100644 --- a/src/lib/libcrypto/doc/PKCS7_decrypt.pod +++ b/src/lib/libcrypto/doc/PKCS7_decrypt.pod | |||
@@ -6,7 +6,9 @@ PKCS7_decrypt - decrypt content from a PKCS#7 envelopedData structure | |||
6 | 6 | ||
7 | =head1 SYNOPSIS | 7 | =head1 SYNOPSIS |
8 | 8 | ||
9 | int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); | 9 | #include <openssl/pkcs7.h> |
10 | |||
11 | int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); | ||
10 | 12 | ||
11 | =head1 DESCRIPTION | 13 | =head1 DESCRIPTION |
12 | 14 | ||
diff --git a/src/lib/libcrypto/doc/PKCS7_encrypt.pod b/src/lib/libcrypto/doc/PKCS7_encrypt.pod index 1a507b22a2..2cd925a7e0 100644 --- a/src/lib/libcrypto/doc/PKCS7_encrypt.pod +++ b/src/lib/libcrypto/doc/PKCS7_encrypt.pod | |||
@@ -6,7 +6,9 @@ PKCS7_encrypt - create a PKCS#7 envelopedData structure | |||
6 | 6 | ||
7 | =head1 SYNOPSIS | 7 | =head1 SYNOPSIS |
8 | 8 | ||
9 | PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags); | 9 | #include <openssl/pkcs7.h> |
10 | |||
11 | PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags); | ||
10 | 12 | ||
11 | =head1 DESCRIPTION | 13 | =head1 DESCRIPTION |
12 | 14 | ||
@@ -16,43 +18,55 @@ B<cipher> is the symmetric cipher to use. B<flags> is an optional set of flags. | |||
16 | 18 | ||
17 | =head1 NOTES | 19 | =head1 NOTES |
18 | 20 | ||
19 | Only RSA keys are supported in PKCS#7 and envelopedData so the recipient certificates | 21 | Only RSA keys are supported in PKCS#7 and envelopedData so the recipient |
20 | supplied to this function must all contain RSA public keys, though they do not have to | 22 | certificates supplied to this function must all contain RSA public keys, though |
21 | be signed using the RSA algorithm. | 23 | they do not have to be signed using the RSA algorithm. |
22 | 24 | ||
23 | EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use because | 25 | EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use |
24 | most clients will support it. | 26 | because most clients will support it. |
25 | 27 | ||
26 | Some old "export grade" clients may only support weak encryption using 40 or 64 bit | 28 | Some old "export grade" clients may only support weak encryption using 40 or 64 |
27 | RC2. These can be used by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc() respectively. | 29 | bit RC2. These can be used by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc() |
30 | respectively. | ||
28 | 31 | ||
29 | The algorithm passed in the B<cipher> parameter must support ASN1 encoding of its | 32 | The algorithm passed in the B<cipher> parameter must support ASN1 encoding of |
30 | parameters. | 33 | its parameters. |
31 | 34 | ||
32 | Many browsers implement a "sign and encrypt" option which is simply an S/MIME | 35 | Many browsers implement a "sign and encrypt" option which is simply an S/MIME |
33 | envelopedData containing an S/MIME signed message. This can be readily produced | 36 | envelopedData containing an S/MIME signed message. This can be readily produced |
34 | by storing the S/MIME signed message in a memory BIO and passing it to | 37 | by storing the S/MIME signed message in a memory BIO and passing it to |
35 | PKCS7_encrypt(). | 38 | PKCS7_encrypt(). |
36 | 39 | ||
37 | The following flags can be passed in the B<flags> parameter. | 40 | The following flags can be passed in the B<flags> parameter. |
38 | 41 | ||
39 | If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are prepended | 42 | If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are |
40 | to the data. | 43 | prepended to the data. |
41 | 44 | ||
42 | Normally the supplied content is translated into MIME canonical format (as required | 45 | Normally the supplied content is translated into MIME canonical format (as |
43 | by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation occurs. This | 46 | required by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation |
44 | option should be used if the supplied data is in binary format otherwise the translation | 47 | occurs. This option should be used if the supplied data is in binary format |
45 | will corrupt it. If B<PKCS7_BINARY> is set then B<PKCS7_TEXT> is ignored. | 48 | otherwise the translation will corrupt it. If B<PKCS7_BINARY> is set then |
49 | B<PKCS7_TEXT> is ignored. | ||
46 | 50 | ||
47 | =head1 RETURN VALUES | 51 | If the B<PKCS7_STREAM> flag is set a partial B<PKCS7> structure is output |
52 | suitable for streaming I/O: no data is read from the BIO B<in>. | ||
48 | 53 | ||
49 | PKCS7_encrypt() returns either a valid PKCS7 structure or NULL if an error occurred. | 54 | =head1 NOTES |
50 | The error can be obtained from ERR_get_error(3). | ||
51 | 55 | ||
52 | =head1 BUGS | 56 | If the flag B<PKCS7_STREAM> is set the returned B<PKCS7> structure is B<not> |
57 | complete and outputting its contents via a function that does not | ||
58 | properly finalize the B<PKCS7> structure will give unpredictable | ||
59 | results. | ||
53 | 60 | ||
54 | The lack of single pass processing and need to hold all data in memory as | 61 | Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(), |
55 | mentioned in PKCS7_sign() also applies to PKCS7_verify(). | 62 | PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization |
63 | can be performed by obtaining the streaming ASN1 B<BIO> directly using | ||
64 | BIO_new_PKCS7(). | ||
65 | |||
66 | =head1 RETURN VALUES | ||
67 | |||
68 | PKCS7_encrypt() returns either a PKCS7 structure or NULL if an error occurred. | ||
69 | The error can be obtained from ERR_get_error(3). | ||
56 | 70 | ||
57 | =head1 SEE ALSO | 71 | =head1 SEE ALSO |
58 | 72 | ||
@@ -61,5 +75,6 @@ L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_decrypt(3)|PKCS7_decrypt(3)> | |||
61 | =head1 HISTORY | 75 | =head1 HISTORY |
62 | 76 | ||
63 | PKCS7_decrypt() was added to OpenSSL 0.9.5 | 77 | PKCS7_decrypt() was added to OpenSSL 0.9.5 |
78 | The B<PKCS7_STREAM> flag was first supported in OpenSSL 1.0.0. | ||
64 | 79 | ||
65 | =cut | 80 | =cut |
diff --git a/src/lib/libcrypto/doc/PKCS7_sign.pod b/src/lib/libcrypto/doc/PKCS7_sign.pod index ffd0c734b0..64a35144f8 100644 --- a/src/lib/libcrypto/doc/PKCS7_sign.pod +++ b/src/lib/libcrypto/doc/PKCS7_sign.pod | |||
@@ -6,14 +6,16 @@ PKCS7_sign - create a PKCS#7 signedData structure | |||
6 | 6 | ||
7 | =head1 SYNOPSIS | 7 | =head1 SYNOPSIS |
8 | 8 | ||
9 | PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags); | 9 | #include <openssl/pkcs7.h> |
10 | |||
11 | PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags); | ||
10 | 12 | ||
11 | =head1 DESCRIPTION | 13 | =head1 DESCRIPTION |
12 | 14 | ||
13 | PKCS7_sign() creates and returns a PKCS#7 signedData structure. B<signcert> | 15 | PKCS7_sign() creates and returns a PKCS#7 signedData structure. B<signcert> is |
14 | is the certificate to sign with, B<pkey> is the corresponsding private key. | 16 | the certificate to sign with, B<pkey> is the corresponsding private key. |
15 | B<certs> is an optional additional set of certificates to include in the | 17 | B<certs> is an optional additional set of certificates to include in the PKCS#7 |
16 | PKCS#7 structure (for example any intermediate CAs in the chain). | 18 | structure (for example any intermediate CAs in the chain). |
17 | 19 | ||
18 | The data to be signed is read from BIO B<data>. | 20 | The data to be signed is read from BIO B<data>. |
19 | 21 | ||
@@ -21,72 +23,83 @@ B<flags> is an optional set of flags. | |||
21 | 23 | ||
22 | =head1 NOTES | 24 | =head1 NOTES |
23 | 25 | ||
24 | Any of the following flags (ored together) can be passed in the B<flags> parameter. | 26 | Any of the following flags (ored together) can be passed in the B<flags> |
27 | parameter. | ||
25 | 28 | ||
26 | Many S/MIME clients expect the signed content to include valid MIME headers. If | 29 | Many S/MIME clients expect the signed content to include valid MIME headers. If |
27 | the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are prepended | 30 | the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are prepended |
28 | to the data. | 31 | to the data. |
29 | 32 | ||
30 | If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the | 33 | If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the |
31 | PKCS7 structure, the signer's certificate must still be supplied in the B<signcert> | 34 | PKCS7 structure, the signer's certificate must still be supplied in the |
32 | parameter though. This can reduce the size of the signature if the signers certificate | 35 | B<signcert> parameter though. This can reduce the size of the signature if the |
33 | can be obtained by other means: for example a previously signed message. | 36 | signers certificate can be obtained by other means: for example a previously |
34 | 37 | signed message. | |
35 | The data being signed is included in the PKCS7 structure, unless B<PKCS7_DETACHED> | 38 | |
36 | is set in which case it is omitted. This is used for PKCS7 detached signatures | 39 | The data being signed is included in the PKCS7 structure, unless |
37 | which are used in S/MIME plaintext signed messages for example. | 40 | B<PKCS7_DETACHED> is set in which case it is omitted. This is used for PKCS7 |
41 | detached signatures which are used in S/MIME plaintext signed messages for | ||
42 | example. | ||
43 | |||
44 | Normally the supplied content is translated into MIME canonical format (as | ||
45 | required by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation | ||
46 | occurs. This option should be used if the supplied data is in binary format | ||
47 | otherwise the translation will corrupt it. | ||
48 | |||
49 | The signedData structure includes several PKCS#7 autenticatedAttributes | ||
50 | including the signing time, the PKCS#7 content type and the supported list of | ||
51 | ciphers in an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no | ||
52 | authenticatedAttributes will be used. If B<PKCS7_NOSMIMECAP> is set then just | ||
53 | the SMIMECapabilities are omitted. | ||
38 | 54 | ||
39 | Normally the supplied content is translated into MIME canonical format (as required | 55 | If present the SMIMECapabilities attribute indicates support for the following |
40 | by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation occurs. This | 56 | algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of |
41 | option should be used if the supplied data is in binary format otherwise the translation | 57 | these algorithms is disabled then it will not be included. |
42 | will corrupt it. | ||
43 | 58 | ||
44 | The signedData structure includes several PKCS#7 autenticatedAttributes including | 59 | If the flags B<PKCS7_STREAM> is set then the returned B<PKCS7> structure is |
45 | the signing time, the PKCS#7 content type and the supported list of ciphers in | 60 | just initialized ready to perform the signing operation. The signing is however |
46 | an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no authenticatedAttributes | 61 | B<not> performed and the data to be signed is not read from the B<data> |
47 | will be used. If B<PKCS7_NOSMIMECAP> is set then just the SMIMECapabilities are | 62 | parameter. Signing is deferred until after the data has been written. In this |
48 | omitted. | 63 | way data can be signed in a single pass. |
49 | 64 | ||
50 | If present the SMIMECapabilities attribute indicates support for the following | 65 | If the B<PKCS7_PARTIAL> flag is set a partial B<PKCS7> structure is output to |
51 | algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any | 66 | which additional signers and capabilities can be added before finalization. |
52 | of these algorithms is disabled then it will not be included. | ||
53 | 67 | ||
54 | If the flags B<PKCS7_PARTSIGN> is set then the returned B<PKCS7> structure | ||
55 | is just initialized ready to perform the signing operation. The signing | ||
56 | is however B<not> performed and the data to be signed is not read from | ||
57 | the B<data> parameter. Signing is deferred until after the data has been | ||
58 | written. In this way data can be signed in a single pass. Currently the | ||
59 | flag B<PKCS7_DETACHED> B<must> also be set. | ||
60 | 68 | ||
61 | =head1 NOTES | 69 | =head1 NOTES |
62 | 70 | ||
63 | Currently the flag B<PKCS7_PARTSIGN> is only supported for detached | 71 | If the flag B<PKCS7_STREAM> is set the returned B<PKCS7> structure is B<not> |
64 | data. If this flag is set the returned B<PKCS7> structure is B<not> | 72 | complete and outputting its contents via a function that does not properly |
65 | complete and outputting its contents via a function that does not | 73 | finalize the B<PKCS7> structure will give unpredictable results. |
66 | properly finalize the B<PKCS7> structure will give unpredictable | ||
67 | results. | ||
68 | 74 | ||
69 | At present only the SMIME_write_PKCS7() function properly finalizes the | 75 | Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(), |
70 | structure. | 76 | PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization |
77 | can be performed by obtaining the streaming ASN1 B<BIO> directly using | ||
78 | BIO_new_PKCS7(). | ||
71 | 79 | ||
72 | =head1 BUGS | 80 | If a signer is specified it will use the default digest for the signing |
81 | algorithm. This is B<SHA1> for both RSA and DSA keys. | ||
82 | |||
83 | In OpenSSL 1.0.0 the B<certs>, B<signcert> and B<pkey> parameters can all be | ||
84 | B<NULL> if the B<PKCS7_PARTIAL> flag is set. One or more signers can be added | ||
85 | using the function B<PKCS7_sign_add_signer()>. B<PKCS7_final()> must also be | ||
86 | called to finalize the structure if streaming is not enabled. Alternative | ||
87 | signing digests can also be specified using this method. | ||
73 | 88 | ||
74 | PKCS7_sign() is somewhat limited. It does not support multiple signers, some | 89 | In OpenSSL 1.0.0 if B<signcert> and B<pkey> are NULL then a certificates only |
75 | advanced attributes such as counter signatures are not supported. | 90 | PKCS#7 structure is output. |
76 | 91 | ||
77 | The SHA1 digest algorithm is currently always used. | 92 | In versions of OpenSSL before 1.0.0 the B<signcert> and B<pkey> parameters must |
93 | B<NOT> be NULL. | ||
78 | 94 | ||
79 | When the signed data is not detached it will be stored in memory within the | 95 | =head1 BUGS |
80 | B<PKCS7> structure. This effectively limits the size of messages which can be | ||
81 | signed due to memory restraints. There should be a way to sign data without | ||
82 | having to hold it all in memory, this would however require fairly major | ||
83 | revisions of the OpenSSL ASN1 code. | ||
84 | 96 | ||
97 | Some advanced attributes such as counter signatures are not supported. | ||
85 | 98 | ||
86 | =head1 RETURN VALUES | 99 | =head1 RETURN VALUES |
87 | 100 | ||
88 | PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error occurred. | 101 | PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error |
89 | The error can be obtained from ERR_get_error(3). | 102 | occurred. The error can be obtained from ERR_get_error(3). |
90 | 103 | ||
91 | =head1 SEE ALSO | 104 | =head1 SEE ALSO |
92 | 105 | ||
@@ -96,6 +109,8 @@ L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_verify(3)|PKCS7_verify(3)> | |||
96 | 109 | ||
97 | PKCS7_sign() was added to OpenSSL 0.9.5 | 110 | PKCS7_sign() was added to OpenSSL 0.9.5 |
98 | 111 | ||
99 | The B<PKCS7_PARTSIGN> flag was added in OpenSSL 0.9.8 | 112 | The B<PKCS7_PARTIAL> flag was added in OpenSSL 1.0.0 |
113 | |||
114 | The B<PKCS7_STREAM> flag was added in OpenSSL 1.0.0 | ||
100 | 115 | ||
101 | =cut | 116 | =cut |
diff --git a/src/lib/libcrypto/doc/PKCS7_sign_add_signer.pod b/src/lib/libcrypto/doc/PKCS7_sign_add_signer.pod new file mode 100644 index 0000000000..ebec4d57de --- /dev/null +++ b/src/lib/libcrypto/doc/PKCS7_sign_add_signer.pod | |||
@@ -0,0 +1,87 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | PKCS7_sign_add_signer - add a signer PKCS7 signed data structure. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/pkcs7.h> | ||
10 | |||
11 | PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, int flags); | ||
12 | |||
13 | |||
14 | =head1 DESCRIPTION | ||
15 | |||
16 | PKCS7_sign_add_signer() adds a signer with certificate B<signcert> and private | ||
17 | key B<pkey> using message digest B<md> to a PKCS7 signed data structure | ||
18 | B<p7>. | ||
19 | |||
20 | The PKCS7 structure should be obtained from an initial call to PKCS7_sign() | ||
21 | with the flag B<PKCS7_PARTIAL> set or in the case or re-signing a valid PKCS7 | ||
22 | signed data structure. | ||
23 | |||
24 | If the B<md> parameter is B<NULL> then the default digest for the public | ||
25 | key algorithm will be used. | ||
26 | |||
27 | Unless the B<PKCS7_REUSE_DIGEST> flag is set the returned PKCS7 structure | ||
28 | is not complete and must be finalized either by streaming (if applicable) or | ||
29 | a call to PKCS7_final(). | ||
30 | |||
31 | |||
32 | =head1 NOTES | ||
33 | |||
34 | The main purpose of this function is to provide finer control over a PKCS#7 | ||
35 | signed data structure where the simpler PKCS7_sign() function defaults are | ||
36 | not appropriate. For example if multiple signers or non default digest | ||
37 | algorithms are needed. | ||
38 | |||
39 | Any of the following flags (ored together) can be passed in the B<flags> | ||
40 | parameter. | ||
41 | |||
42 | If B<PKCS7_REUSE_DIGEST> is set then an attempt is made to copy the content | ||
43 | digest value from the PKCS7 struture: to add a signer to an existing structure. | ||
44 | An error occurs if a matching digest value cannot be found to copy. The | ||
45 | returned PKCS7 structure will be valid and finalized when this flag is set. | ||
46 | |||
47 | If B<PKCS7_PARTIAL> is set in addition to B<PKCS7_REUSE_DIGEST> then the | ||
48 | B<PKCS7_SIGNER_INO> structure will not be finalized so additional attributes | ||
49 | can be added. In this case an explicit call to PKCS7_SIGNER_INFO_sign() is | ||
50 | needed to finalize it. | ||
51 | |||
52 | If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the | ||
53 | PKCS7 structure, the signer's certificate must still be supplied in the | ||
54 | B<signcert> parameter though. This can reduce the size of the signature if the | ||
55 | signers certificate can be obtained by other means: for example a previously | ||
56 | signed message. | ||
57 | |||
58 | The signedData structure includes several PKCS#7 autenticatedAttributes | ||
59 | including the signing time, the PKCS#7 content type and the supported list of | ||
60 | ciphers in an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no | ||
61 | authenticatedAttributes will be used. If B<PKCS7_NOSMIMECAP> is set then just | ||
62 | the SMIMECapabilities are omitted. | ||
63 | |||
64 | If present the SMIMECapabilities attribute indicates support for the following | ||
65 | algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of | ||
66 | these algorithms is disabled then it will not be included. | ||
67 | |||
68 | |||
69 | PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO | ||
70 | structure just added, this can be used to set additional attributes | ||
71 | before it is finalized. | ||
72 | |||
73 | =head1 RETURN VALUES | ||
74 | |||
75 | PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO | ||
76 | structure just added or NULL if an error occurs. | ||
77 | |||
78 | =head1 SEE ALSO | ||
79 | |||
80 | L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>, | ||
81 | L<PKCS7_final(3)|PKCS7_final(3)>, | ||
82 | |||
83 | =head1 HISTORY | ||
84 | |||
85 | PPKCS7_sign_add_signer() was added to OpenSSL 1.0.0 | ||
86 | |||
87 | =cut | ||
diff --git a/src/lib/libcrypto/doc/PKCS7_verify.pod b/src/lib/libcrypto/doc/PKCS7_verify.pod index 3490b5dc82..7c10a4cc3c 100644 --- a/src/lib/libcrypto/doc/PKCS7_verify.pod +++ b/src/lib/libcrypto/doc/PKCS7_verify.pod | |||
@@ -6,9 +6,11 @@ PKCS7_verify - verify a PKCS#7 signedData structure | |||
6 | 6 | ||
7 | =head1 SYNOPSIS | 7 | =head1 SYNOPSIS |
8 | 8 | ||
9 | int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags); | 9 | #include <openssl/pkcs7.h> |
10 | 10 | ||
11 | STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); | 11 | int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags); |
12 | |||
13 | STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); | ||
12 | 14 | ||
13 | =head1 DESCRIPTION | 15 | =head1 DESCRIPTION |
14 | 16 | ||
diff --git a/src/lib/libcrypto/doc/SMIME_read_CMS.pod b/src/lib/libcrypto/doc/SMIME_read_CMS.pod new file mode 100644 index 0000000000..acc5524c14 --- /dev/null +++ b/src/lib/libcrypto/doc/SMIME_read_CMS.pod | |||
@@ -0,0 +1,70 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | SMIME_read_CMS - parse S/MIME message. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/cms.h> | ||
10 | |||
11 | CMS_ContentInfo *SMIME_read_CMS(BIO *in, BIO **bcont); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | SMIME_read_CMS() parses a message in S/MIME format. | ||
16 | |||
17 | B<in> is a BIO to read the message from. | ||
18 | |||
19 | If cleartext signing is used then the content is saved in a memory bio which is | ||
20 | written to B<*bcont>, otherwise B<*bcont> is set to NULL. | ||
21 | |||
22 | The parsed CMS_ContentInfo structure is returned or NULL if an | ||
23 | error occurred. | ||
24 | |||
25 | =head1 NOTES | ||
26 | |||
27 | If B<*bcont> is not NULL then the message is clear text signed. B<*bcont> can | ||
28 | then be passed to CMS_verify() with the B<CMS_DETACHED> flag set. | ||
29 | |||
30 | Otherwise the type of the returned structure can be determined | ||
31 | using CMS_get0_type(). | ||
32 | |||
33 | To support future functionality if B<bcont> is not NULL B<*bcont> should be | ||
34 | initialized to NULL. For example: | ||
35 | |||
36 | BIO *cont = NULL; | ||
37 | CMS_ContentInfo *cms; | ||
38 | |||
39 | cms = SMIME_read_CMS(in, &cont); | ||
40 | |||
41 | =head1 BUGS | ||
42 | |||
43 | The MIME parser used by SMIME_read_CMS() is somewhat primitive. While it will | ||
44 | handle most S/MIME messages more complex compound formats may not work. | ||
45 | |||
46 | The parser assumes that the CMS_ContentInfo structure is always base64 encoded | ||
47 | and will not handle the case where it is in binary format or uses quoted | ||
48 | printable format. | ||
49 | |||
50 | The use of a memory BIO to hold the signed content limits the size of message | ||
51 | which can be processed due to memory restraints: a streaming single pass option | ||
52 | should be available. | ||
53 | |||
54 | =head1 RETURN VALUES | ||
55 | |||
56 | SMIME_read_CMS() returns a valid B<CMS_ContentInfo> structure or B<NULL> | ||
57 | if an error occurred. The error can be obtained from ERR_get_error(3). | ||
58 | |||
59 | =head1 SEE ALSO | ||
60 | |||
61 | L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_type(3)|CMS_type(3)> | ||
62 | L<SMIME_read_CMS(3)|SMIME_read_CMS(3)>, L<CMS_sign(3)|CMS_sign(3)>, | ||
63 | L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)> | ||
64 | L<CMS_decrypt(3)|CMS_decrypt(3)> | ||
65 | |||
66 | =head1 HISTORY | ||
67 | |||
68 | SMIME_read_CMS() was added to OpenSSL 0.9.8 | ||
69 | |||
70 | =cut | ||
diff --git a/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod b/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod index ffafa37887..9d46715941 100644 --- a/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod +++ b/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod | |||
@@ -6,7 +6,9 @@ SMIME_read_PKCS7 - parse S/MIME message. | |||
6 | 6 | ||
7 | =head1 SYNOPSIS | 7 | =head1 SYNOPSIS |
8 | 8 | ||
9 | PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont); | 9 | #include <openssl/pkcs7.h> |
10 | |||
11 | PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont); | ||
10 | 12 | ||
11 | =head1 DESCRIPTION | 13 | =head1 DESCRIPTION |
12 | 14 | ||
diff --git a/src/lib/libcrypto/doc/SMIME_write_CMS.pod b/src/lib/libcrypto/doc/SMIME_write_CMS.pod new file mode 100644 index 0000000000..04bedfb429 --- /dev/null +++ b/src/lib/libcrypto/doc/SMIME_write_CMS.pod | |||
@@ -0,0 +1,64 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | SMIME_write_CMS - convert CMS structure to S/MIME format. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/cms.h> | ||
10 | |||
11 | int SMIME_write_CMS(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | SMIME_write_CMS() adds the appropriate MIME headers to a CMS | ||
16 | structure to produce an S/MIME message. | ||
17 | |||
18 | B<out> is the BIO to write the data to. B<cms> is the appropriate | ||
19 | B<CMS_ContentInfo> structure. If streaming is enabled then the content must be | ||
20 | supplied in the B<data> argument. B<flags> is an optional set of flags. | ||
21 | |||
22 | =head1 NOTES | ||
23 | |||
24 | The following flags can be passed in the B<flags> parameter. | ||
25 | |||
26 | If B<CMS_DETACHED> is set then cleartext signing will be used, this option only | ||
27 | makes sense for SignedData where B<CMS_DETACHED> is also set when CMS_sign() is | ||
28 | called. | ||
29 | |||
30 | If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are added to | ||
31 | the content, this only makes sense if B<CMS_DETACHED> is also set. | ||
32 | |||
33 | If the B<CMS_STREAM> flag is set streaming is performed. This flag should only | ||
34 | be set if B<CMS_STREAM> was also set in the previous call to a CMS_ContentInfo | ||
35 | creation function. | ||
36 | |||
37 | If cleartext signing is being used and B<CMS_STREAM> not set then the data must | ||
38 | be read twice: once to compute the signature in CMS_sign() and once to output | ||
39 | the S/MIME message. | ||
40 | |||
41 | If streaming is performed the content is output in BER format using indefinite | ||
42 | length constructed encoding except in the case of signed data with detached | ||
43 | content where the content is absent and DER format is used. | ||
44 | |||
45 | =head1 BUGS | ||
46 | |||
47 | SMIME_write_CMS() always base64 encodes CMS structures, there should be an | ||
48 | option to disable this. | ||
49 | |||
50 | =head1 RETURN VALUES | ||
51 | |||
52 | SMIME_write_CMS() returns 1 for success or 0 for failure. | ||
53 | |||
54 | =head1 SEE ALSO | ||
55 | |||
56 | L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>, | ||
57 | L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)> | ||
58 | L<CMS_decrypt(3)|CMS_decrypt(3)> | ||
59 | |||
60 | =head1 HISTORY | ||
61 | |||
62 | SMIME_write_CMS() was added to OpenSSL 0.9.8 | ||
63 | |||
64 | =cut | ||
diff --git a/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod b/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod index 61945b3887..ca6bd02763 100644 --- a/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod +++ b/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod | |||
@@ -6,17 +6,18 @@ SMIME_write_PKCS7 - convert PKCS#7 structure to S/MIME format. | |||
6 | 6 | ||
7 | =head1 SYNOPSIS | 7 | =head1 SYNOPSIS |
8 | 8 | ||
9 | int SMIME_write_PKCS7(BIO *out, PKCS7 *p7, BIO *data, int flags); | 9 | #include <openssl/pkcs7.h> |
10 | |||
11 | int SMIME_write_PKCS7(BIO *out, PKCS7 *p7, BIO *data, int flags); | ||
10 | 12 | ||
11 | =head1 DESCRIPTION | 13 | =head1 DESCRIPTION |
12 | 14 | ||
13 | SMIME_write_PKCS7() adds the appropriate MIME headers to a PKCS#7 | 15 | SMIME_write_PKCS7() adds the appropriate MIME headers to a PKCS#7 |
14 | structure to produce an S/MIME message. | 16 | structure to produce an S/MIME message. |
15 | 17 | ||
16 | B<out> is the BIO to write the data to. B<p7> is the appropriate | 18 | B<out> is the BIO to write the data to. B<p7> is the appropriate B<PKCS7> |
17 | B<PKCS7> structure. If cleartext signing (B<multipart/signed>) is | 19 | structure. If streaming is enabled then the content must be supplied in the |
18 | being used then the signed data must be supplied in the B<data> | 20 | B<data> argument. B<flags> is an optional set of flags. |
19 | argument. B<flags> is an optional set of flags. | ||
20 | 21 | ||
21 | =head1 NOTES | 22 | =head1 NOTES |
22 | 23 | ||
@@ -30,15 +31,18 @@ If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> | |||
30 | are added to the content, this only makes sense if B<PKCS7_DETACHED> | 31 | are added to the content, this only makes sense if B<PKCS7_DETACHED> |
31 | is also set. | 32 | is also set. |
32 | 33 | ||
33 | If the B<PKCS7_PARTSIGN> flag is set the signed data is finalized | 34 | If the B<PKCS7_STREAM> flag is set streaming is performed. This flag should |
34 | and output along with the content. This flag should only be set | 35 | only be set if B<PKCS7_STREAM> was also set in the previous call to |
35 | if B<PKCS7_DETACHED> is also set and the previous call to PKCS7_sign() | 36 | PKCS7_sign() or B<PKCS7_encrypt()>. |
36 | also set these flags. | ||
37 | 37 | ||
38 | If cleartext signing is being used and B<PKCS7_PARTSIGN> not set then | 38 | If cleartext signing is being used and B<PKCS7_STREAM> not set then |
39 | the data must be read twice: once to compute the signature in PKCS7_sign() | 39 | the data must be read twice: once to compute the signature in PKCS7_sign() |
40 | and once to output the S/MIME message. | 40 | and once to output the S/MIME message. |
41 | 41 | ||
42 | If streaming is performed the content is output in BER format using indefinite | ||
43 | length constructuted encoding except in the case of signed data with detached | ||
44 | content where the content is absent and DER format is used. | ||
45 | |||
42 | =head1 BUGS | 46 | =head1 BUGS |
43 | 47 | ||
44 | SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there | 48 | SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there |
diff --git a/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod b/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod index 11b35f6fd3..41902c0d45 100644 --- a/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod +++ b/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod | |||
@@ -9,15 +9,17 @@ X509_NAME_ENTRY_create_by_OBJ - X509_NAME_ENTRY utility functions | |||
9 | 9 | ||
10 | =head1 SYNOPSIS | 10 | =head1 SYNOPSIS |
11 | 11 | ||
12 | ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); | 12 | #include <openssl/x509.h> |
13 | ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); | ||
14 | 13 | ||
15 | int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); | 14 | ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); |
16 | int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, const unsigned char *bytes, int len); | 15 | ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); |
17 | 16 | ||
18 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, const char *field, int type, const unsigned char *bytes, int len); | 17 | int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); |
19 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,unsigned char *bytes, int len); | 18 | int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, const unsigned char *bytes, int len); |
20 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len); | 19 | |
20 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, const char *field, int type, const unsigned char *bytes, int len); | ||
21 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,unsigned char *bytes, int len); | ||
22 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len); | ||
21 | 23 | ||
22 | =head1 DESCRIPTION | 24 | =head1 DESCRIPTION |
23 | 25 | ||
diff --git a/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod b/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod index e2ab4b0d2b..1afd008cb3 100644 --- a/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod +++ b/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod | |||
@@ -7,15 +7,17 @@ X509_NAME_add_entry, X509_NAME_delete_entry - X509_NAME modification functions | |||
7 | 7 | ||
8 | =head1 SYNOPSIS | 8 | =head1 SYNOPSIS |
9 | 9 | ||
10 | int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, const unsigned char *bytes, int len, int loc, int set); | 10 | #include <openssl/x509.h> |
11 | 11 | ||
12 | int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, unsigned char *bytes, int len, int loc, int set); | 12 | int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, const unsigned char *bytes, int len, int loc, int set); |
13 | 13 | ||
14 | int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set); | 14 | int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, unsigned char *bytes, int len, int loc, int set); |
15 | 15 | ||
16 | int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, int loc, int set); | 16 | int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set); |
17 | 17 | ||
18 | X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); | 18 | int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, int loc, int set); |
19 | |||
20 | X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); | ||
19 | 21 | ||
20 | =head1 DESCRIPTION | 22 | =head1 DESCRIPTION |
21 | 23 | ||
diff --git a/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod b/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod index 333323d734..3b1f9ff43b 100644 --- a/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod +++ b/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod | |||
@@ -8,14 +8,16 @@ X509_NAME lookup and enumeration functions | |||
8 | 8 | ||
9 | =head1 SYNOPSIS | 9 | =head1 SYNOPSIS |
10 | 10 | ||
11 | int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); | 11 | #include <openssl/x509.h> |
12 | int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, int lastpos); | ||
13 | 12 | ||
14 | int X509_NAME_entry_count(X509_NAME *name); | 13 | int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); |
15 | X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); | 14 | int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, int lastpos); |
16 | 15 | ||
17 | int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf,int len); | 16 | int X509_NAME_entry_count(X509_NAME *name); |
18 | int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,int len); | 17 | X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); |
18 | |||
19 | int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf,int len); | ||
20 | int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,int len); | ||
19 | 21 | ||
20 | =head1 DESCRIPTION | 22 | =head1 DESCRIPTION |
21 | 23 | ||
diff --git a/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod b/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod new file mode 100644 index 0000000000..a883f6c097 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod | |||
@@ -0,0 +1,303 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | X509_STORE_CTX_get_error, X509_STORE_CTX_set_error, X509_STORE_CTX_get_error_depth, X509_STORE_CTX_get_current_cert, X509_STORE_CTX_get1_chain, X509_verify_cert_error_string - get or set certificate verification status information | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/x509.h> | ||
10 | #include <openssl/x509_vfy.h> | ||
11 | |||
12 | int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); | ||
13 | void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); | ||
14 | int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); | ||
15 | X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); | ||
16 | |||
17 | STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); | ||
18 | |||
19 | const char *X509_verify_cert_error_string(long n); | ||
20 | |||
21 | =head1 DESCRIPTION | ||
22 | |||
23 | These functions are typically called after X509_verify_cert() has indicated | ||
24 | an error or in a verification callback to determine the nature of an error. | ||
25 | |||
26 | X509_STORE_CTX_get_error() returns the error code of B<ctx>, see | ||
27 | the B<ERROR CODES> section for a full description of all error codes. | ||
28 | |||
29 | X509_STORE_CTX_set_error() sets the error code of B<ctx> to B<s>. For example | ||
30 | it might be used in a verification callback to set an error based on additional | ||
31 | checks. | ||
32 | |||
33 | X509_STORE_CTX_get_error_depth() returns the B<depth> of the error. This is a | ||
34 | non-negative integer representing where in the certificate chain the error | ||
35 | occurred. If it is zero it occured in the end entity certificate, one if | ||
36 | it is the certificate which signed the end entity certificate and so on. | ||
37 | |||
38 | X509_STORE_CTX_get_current_cert() returns the certificate in B<ctx> which | ||
39 | caused the error or B<NULL> if no certificate is relevant. | ||
40 | |||
41 | X509_STORE_CTX_get1_chain() returns a complete validate chain if a previous | ||
42 | call to X509_verify_cert() is successful. If the call to X509_verify_cert() | ||
43 | is B<not> successful the returned chain may be incomplete or invalid. The | ||
44 | returned chain persists after the B<ctx> structure is freed, when it is | ||
45 | no longer needed it should be free up using: | ||
46 | |||
47 | sk_X509_pop_free(chain, X509_free); | ||
48 | |||
49 | X509_verify_cert_error_string() returns a human readable error string for | ||
50 | verification error B<n>. | ||
51 | |||
52 | =head1 RETURN VALUES | ||
53 | |||
54 | X509_STORE_CTX_get_error() returns B<X509_V_OK> or an error code. | ||
55 | |||
56 | X509_STORE_CTX_get_error_depth() returns a non-negative error depth. | ||
57 | |||
58 | X509_STORE_CTX_get_current_cert() returns the cerificate which caused the | ||
59 | error or B<NULL> if no certificate is relevant to the error. | ||
60 | |||
61 | X509_verify_cert_error_string() returns a human readable error string for | ||
62 | verification error B<n>. | ||
63 | |||
64 | =head1 ERROR CODES | ||
65 | |||
66 | A list of error codes and messages is shown below. Some of the | ||
67 | error codes are defined but currently never returned: these are described as | ||
68 | "unused". | ||
69 | |||
70 | =over 4 | ||
71 | |||
72 | =item B<X509_V_OK: ok> | ||
73 | |||
74 | the operation was successful. | ||
75 | |||
76 | =item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate> | ||
77 | |||
78 | the issuer certificate could not be found: this occurs if the issuer certificate | ||
79 | of an untrusted certificate cannot be found. | ||
80 | |||
81 | =item B<X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL> | ||
82 | |||
83 | the CRL of a certificate could not be found. | ||
84 | |||
85 | =item B<X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature> | ||
86 | |||
87 | the certificate signature could not be decrypted. This means that the actual | ||
88 | signature value could not be determined rather than it not matching the | ||
89 | expected value, this is only meaningful for RSA keys. | ||
90 | |||
91 | =item B<X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature> | ||
92 | |||
93 | the CRL signature could not be decrypted: this means that the actual signature | ||
94 | value could not be determined rather than it not matching the expected value. | ||
95 | Unused. | ||
96 | |||
97 | =item B<X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode issuer public key> | ||
98 | |||
99 | the public key in the certificate SubjectPublicKeyInfo could not be read. | ||
100 | |||
101 | =item B<X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure> | ||
102 | |||
103 | the signature of the certificate is invalid. | ||
104 | |||
105 | =item B<X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure> | ||
106 | |||
107 | the signature of the certificate is invalid. | ||
108 | |||
109 | =item B<X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid> | ||
110 | |||
111 | the certificate is not yet valid: the notBefore date is after the current time. | ||
112 | |||
113 | =item B<X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired> | ||
114 | |||
115 | the certificate has expired: that is the notAfter date is before the current time. | ||
116 | |||
117 | =item B<X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid> | ||
118 | |||
119 | the CRL is not yet valid. | ||
120 | |||
121 | =item B<X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired> | ||
122 | |||
123 | the CRL has expired. | ||
124 | |||
125 | =item B<X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field> | ||
126 | |||
127 | the certificate notBefore field contains an invalid time. | ||
128 | |||
129 | =item B<X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in certificate's notAfter field> | ||
130 | |||
131 | the certificate notAfter field contains an invalid time. | ||
132 | |||
133 | =item B<X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field> | ||
134 | |||
135 | the CRL lastUpdate field contains an invalid time. | ||
136 | |||
137 | =item B<X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field> | ||
138 | |||
139 | the CRL nextUpdate field contains an invalid time. | ||
140 | |||
141 | =item B<X509_V_ERR_OUT_OF_MEM: out of memory> | ||
142 | |||
143 | an error occurred trying to allocate memory. This should never happen. | ||
144 | |||
145 | =item B<X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate> | ||
146 | |||
147 | the passed certificate is self signed and the same certificate cannot be found | ||
148 | in the list of trusted certificates. | ||
149 | |||
150 | =item B<X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in certificate chain> | ||
151 | |||
152 | the certificate chain could be built up using the untrusted certificates but | ||
153 | the root could not be found locally. | ||
154 | |||
155 | =item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate> | ||
156 | |||
157 | the issuer certificate of a locally looked up certificate could not be found. | ||
158 | This normally means the list of trusted certificates is not complete. | ||
159 | |||
160 | =item B<X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate> | ||
161 | |||
162 | no signatures could be verified because the chain contains only one certificate | ||
163 | and it is not self signed. | ||
164 | |||
165 | =item B<X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long> | ||
166 | |||
167 | the certificate chain length is greater than the supplied maximum depth. Unused. | ||
168 | |||
169 | =item B<X509_V_ERR_CERT_REVOKED: certificate revoked> | ||
170 | |||
171 | the certificate has been revoked. | ||
172 | |||
173 | =item B<X509_V_ERR_INVALID_CA: invalid CA certificate> | ||
174 | |||
175 | a CA certificate is invalid. Either it is not a CA or its extensions are not | ||
176 | consistent with the supplied purpose. | ||
177 | |||
178 | =item B<X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded> | ||
179 | |||
180 | the basicConstraints pathlength parameter has been exceeded. | ||
181 | |||
182 | =item B<X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose> | ||
183 | |||
184 | the supplied certificate cannot be used for the specified purpose. | ||
185 | |||
186 | =item B<X509_V_ERR_CERT_UNTRUSTED: certificate not trusted> | ||
187 | |||
188 | the root CA is not marked as trusted for the specified purpose. | ||
189 | |||
190 | =item B<X509_V_ERR_CERT_REJECTED: certificate rejected> | ||
191 | |||
192 | the root CA is marked to reject the specified purpose. | ||
193 | |||
194 | =item B<X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch> | ||
195 | |||
196 | the current candidate issuer certificate was rejected because its subject name | ||
197 | did not match the issuer name of the current certificate. This is only set | ||
198 | if issuer check debugging is enabled it is used for status notification and | ||
199 | is B<not> in itself an error. | ||
200 | |||
201 | =item B<X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier mismatch> | ||
202 | |||
203 | the current candidate issuer certificate was rejected because its subject key | ||
204 | identifier was present and did not match the authority key identifier current | ||
205 | certificate. This is only set if issuer check debugging is enabled it is used | ||
206 | for status notification and is B<not> in itself an error. | ||
207 | |||
208 | =item B<X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial number mismatch> | ||
209 | |||
210 | the current candidate issuer certificate was rejected because its issuer name | ||
211 | and serial number was present and did not match the authority key identifier of | ||
212 | the current certificate. This is only set if issuer check debugging is enabled | ||
213 | it is used for status notification and is B<not> in itself an error. | ||
214 | |||
215 | =item B<X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include certificate signing> | ||
216 | |||
217 | the current candidate issuer certificate was rejected because its keyUsage | ||
218 | extension does not permit certificate signing. This is only set if issuer check | ||
219 | debugging is enabled it is used for status notification and is B<not> in itself | ||
220 | an error. | ||
221 | |||
222 | =item B<X509_V_ERR_INVALID_EXTENSION: invalid or inconsistent certificate extension> | ||
223 | |||
224 | A certificate extension had an invalid value (for example an incorrect | ||
225 | encoding) or some value inconsistent with other extensions. | ||
226 | |||
227 | |||
228 | =item B<X509_V_ERR_INVALID_POLICY_EXTENSION: invalid or inconsistent certificate policy extension> | ||
229 | |||
230 | A certificate policies extension had an invalid value (for example an incorrect | ||
231 | encoding) or some value inconsistent with other extensions. This error only | ||
232 | occurs if policy processing is enabled. | ||
233 | |||
234 | =item B<X509_V_ERR_NO_EXPLICIT_POLICY: no explicit policy> | ||
235 | |||
236 | The verification flags were set to require and explicit policy but none was | ||
237 | present. | ||
238 | |||
239 | =item B<X509_V_ERR_DIFFERENT_CRL_SCOPE: Different CRL scope> | ||
240 | |||
241 | The only CRLs that could be found did not match the scope of the certificate. | ||
242 | |||
243 | =item B<X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: Unsupported extension feature> | ||
244 | |||
245 | Some feature of a certificate extension is not supported. Unused. | ||
246 | |||
247 | =item B<X509_V_ERR_PERMITTED_VIOLATION: permitted subtree violation> | ||
248 | |||
249 | A name constraint violation occured in the permitted subtrees. | ||
250 | |||
251 | =item B<X509_V_ERR_EXCLUDED_VIOLATION: excluded subtree violation> | ||
252 | |||
253 | A name constraint violation occured in the excluded subtrees. | ||
254 | |||
255 | =item B<X509_V_ERR_SUBTREE_MINMAX: name constraints minimum and maximum not supported> | ||
256 | |||
257 | A certificate name constraints extension included a minimum or maximum field: | ||
258 | this is not supported. | ||
259 | |||
260 | =item B<X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: unsupported name constraint type> | ||
261 | |||
262 | An unsupported name constraint type was encountered. OpenSSL currently only | ||
263 | supports directory name, DNS name, email and URI types. | ||
264 | |||
265 | =item B<X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: unsupported or invalid name constraint syntax> | ||
266 | |||
267 | The format of the name constraint is not recognised: for example an email | ||
268 | address format of a form not mentioned in RFC3280. This could be caused by | ||
269 | a garbage extension or some new feature not currently supported. | ||
270 | |||
271 | =item B<X509_V_ERR_CRL_PATH_VALIDATION_ERROR: CRL path validation error> | ||
272 | |||
273 | An error occured when attempting to verify the CRL path. This error can only | ||
274 | happen if extended CRL checking is enabled. | ||
275 | |||
276 | =item B<X509_V_ERR_APPLICATION_VERIFICATION: application verification failure> | ||
277 | |||
278 | an application specific error. This will never be returned unless explicitly | ||
279 | set by an application. | ||
280 | |||
281 | =head1 NOTES | ||
282 | |||
283 | The above functions should be used instead of directly referencing the fields | ||
284 | in the B<X509_VERIFY_CTX> structure. | ||
285 | |||
286 | In versions of OpenSSL before 1.0 the current certificate returned by | ||
287 | X509_STORE_CTX_get_current_cert() was never B<NULL>. Applications should | ||
288 | check the return value before printing out any debugging information relating | ||
289 | to the current certificate. | ||
290 | |||
291 | If an unrecognised error code is passed to X509_verify_cert_error_string() the | ||
292 | numerical value of the unknown code is returned in a static buffer. This is not | ||
293 | thread safe but will never happen unless an invalid code is passed. | ||
294 | |||
295 | =head1 SEE ALSO | ||
296 | |||
297 | L<X509_verify_cert(3)|X509_verify_cert(3)> | ||
298 | |||
299 | =head1 HISTORY | ||
300 | |||
301 | TBA | ||
302 | |||
303 | =cut | ||
diff --git a/src/lib/libcrypto/doc/X509_STORE_CTX_get_ex_new_index.pod b/src/lib/libcrypto/doc/X509_STORE_CTX_get_ex_new_index.pod new file mode 100644 index 0000000000..8d6b9dda47 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_STORE_CTX_get_ex_new_index.pod | |||
@@ -0,0 +1,41 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | X509_STORE_CTX_get_ex_new_index, X509_STORE_CTX_set_ex_data, X509_STORE_CTX_get_ex_data - add application specific data to X509_STORE_CTX structures | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/x509_vfy.h> | ||
10 | |||
11 | int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, | ||
12 | CRYPTO_EX_new *new_func, | ||
13 | CRYPTO_EX_dup *dup_func, | ||
14 | CRYPTO_EX_free *free_func); | ||
15 | |||
16 | int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *d, int idx, void *arg); | ||
17 | |||
18 | char *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *d, int idx); | ||
19 | |||
20 | =head1 DESCRIPTION | ||
21 | |||
22 | These functions handle application specific data in X509_STORE_CTX structures. | ||
23 | Their usage is identical to that of RSA_get_ex_new_index(), RSA_set_ex_data() | ||
24 | and RSA_get_ex_data() as described in L<RSA_get_ex_new_index(3)>. | ||
25 | |||
26 | =head1 NOTES | ||
27 | |||
28 | This mechanism is used internally by the B<ssl> library to store the B<SSL> | ||
29 | structure associated with a verification operation in an B<X509_STORE_CTX> | ||
30 | structure. | ||
31 | |||
32 | =head1 SEE ALSO | ||
33 | |||
34 | L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)> | ||
35 | |||
36 | =head1 HISTORY | ||
37 | |||
38 | X509_STORE_CTX_get_ex_new_index(), X509_STORE_CTX_set_ex_data() and | ||
39 | X509_STORE_CTX_get_ex_data() are available since OpenSSL 0.9.5. | ||
40 | |||
41 | =cut | ||
diff --git a/src/lib/libcrypto/doc/X509_STORE_CTX_new.pod b/src/lib/libcrypto/doc/X509_STORE_CTX_new.pod new file mode 100644 index 0000000000..b17888f149 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_STORE_CTX_new.pod | |||
@@ -0,0 +1,122 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | X509_STORE_CTX_new, X509_STORE_CTX_cleanup, X509_STORE_CTX_free, X509_STORE_CTX_init, X509_STORE_CTX_trusted_stack, X509_STORE_CTX_set_cert, X509_STORE_CTX_set_chain, X509_STORE_CTX_set0_crls, X509_STORE_CTX_get0_param, X509_STORE_CTX_set0_param, X509_STORE_CTX_set_default - X509_STORE_CTX initialisation | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/x509_vfy.h> | ||
10 | |||
11 | X509_STORE_CTX *X509_STORE_CTX_new(void); | ||
12 | void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); | ||
13 | void X509_STORE_CTX_free(X509_STORE_CTX *ctx); | ||
14 | |||
15 | int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, | ||
16 | X509 *x509, STACK_OF(X509) *chain); | ||
17 | |||
18 | void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); | ||
19 | |||
20 | void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx,X509 *x); | ||
21 | void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx,STACK_OF(X509) *sk); | ||
22 | void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk); | ||
23 | |||
24 | X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); | ||
25 | void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); | ||
26 | int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); | ||
27 | |||
28 | =head1 DESCRIPTION | ||
29 | |||
30 | These functions initialise an B<X509_STORE_CTX> structure for subsequent use | ||
31 | by X509_verify_cert(). | ||
32 | |||
33 | X509_STORE_CTX_new() returns a newly initialised B<X509_STORE_CTX> structure. | ||
34 | |||
35 | X509_STORE_CTX_cleanup() internally cleans up an B<X509_STORE_CTX> structure. | ||
36 | The context can then be reused with an new call to X509_STORE_CTX_init(). | ||
37 | |||
38 | X509_STORE_CTX_free() completely frees up B<ctx>. After this call B<ctx> | ||
39 | is no longer valid. | ||
40 | |||
41 | X509_STORE_CTX_init() sets up B<ctx> for a subsequent verification operation. | ||
42 | The trusted certificate store is set to B<store>, the end entity certificate | ||
43 | to be verified is set to B<x509> and a set of additional certificates (which | ||
44 | will be untrusted but may be used to build the chain) in B<chain>. Any or | ||
45 | all of the B<store>, B<x509> and B<chain> parameters can be B<NULL>. | ||
46 | |||
47 | X509_STORE_CTX_trusted_stack() sets the set of trusted certificates of B<ctx> | ||
48 | to B<sk>. This is an alternative way of specifying trusted certificates | ||
49 | instead of using an B<X509_STORE>. | ||
50 | |||
51 | X509_STORE_CTX_set_cert() sets the certificate to be vertified in B<ctx> to | ||
52 | B<x>. | ||
53 | |||
54 | X509_STORE_CTX_set_chain() sets the additional certificate chain used by B<ctx> | ||
55 | to B<sk>. | ||
56 | |||
57 | X509_STORE_CTX_set0_crls() sets a set of CRLs to use to aid certificate | ||
58 | verification to B<sk>. These CRLs will only be used if CRL verification is | ||
59 | enabled in the associated B<X509_VERIFY_PARAM> structure. This might be | ||
60 | used where additional "useful" CRLs are supplied as part of a protocol, | ||
61 | for example in a PKCS#7 structure. | ||
62 | |||
63 | X509_VERIFY_PARAM *X509_STORE_CTX_get0_param() retrieves an intenal pointer | ||
64 | to the verification parameters associated with B<ctx>. | ||
65 | |||
66 | X509_STORE_CTX_set0_param() sets the intenal verification parameter pointer | ||
67 | to B<param>. After this call B<param> should not be used. | ||
68 | |||
69 | X509_STORE_CTX_set_default() looks up and sets the default verification | ||
70 | method to B<name>. This uses the function X509_VERIFY_PARAM_lookup() to | ||
71 | find an appropriate set of parameters from B<name>. | ||
72 | |||
73 | =head1 NOTES | ||
74 | |||
75 | The certificates and CRLs in a store are used internally and should B<not> | ||
76 | be freed up until after the associated B<X509_STORE_CTX> is freed. Legacy | ||
77 | applications might implicitly use an B<X509_STORE_CTX> like this: | ||
78 | |||
79 | X509_STORE_CTX ctx; | ||
80 | X509_STORE_CTX_init(&ctx, store, cert, chain); | ||
81 | |||
82 | this is B<not> recommended in new applications they should instead do: | ||
83 | |||
84 | X509_STORE_CTX *ctx; | ||
85 | ctx = X509_STORE_CTX_new(); | ||
86 | if (ctx == NULL) | ||
87 | /* Bad error */ | ||
88 | X509_STORE_CTX_init(ctx, store, cert, chain); | ||
89 | |||
90 | =head1 BUGS | ||
91 | |||
92 | The certificates and CRLs in a context are used internally and should B<not> | ||
93 | be freed up until after the associated B<X509_STORE_CTX> is freed. Copies | ||
94 | should be made or reference counts increased instead. | ||
95 | |||
96 | =head1 RETURN VALUES | ||
97 | |||
98 | X509_STORE_CTX_new() returns an newly allocates context or B<NULL> is an | ||
99 | error occurred. | ||
100 | |||
101 | X509_STORE_CTX_init() returns 1 for success or 0 if an error occurred. | ||
102 | |||
103 | X509_STORE_CTX_get0_param() returns a pointer to an B<X509_VERIFY_PARAM> | ||
104 | structure or B<NULL> if an error occurred. | ||
105 | |||
106 | X509_STORE_CTX_cleanup(), X509_STORE_CTX_free(), X509_STORE_CTX_trusted_stack(), | ||
107 | X509_STORE_CTX_set_cert(), X509_STORE_CTX_set_chain(), | ||
108 | X509_STORE_CTX_set0_crls() and X509_STORE_CTX_set0_param() do not return | ||
109 | values. | ||
110 | |||
111 | X509_STORE_CTX_set_default() returns 1 for success or 0 if an error occurred. | ||
112 | |||
113 | =head1 SEE ALSO | ||
114 | |||
115 | L<X509_verify_cert(3)|X509_verify_cert(3)> | ||
116 | L<X509_VERIFY_PARAM_set_flags(3)|X509_VERIFY_PARAM_set_flags(3)> | ||
117 | |||
118 | =head1 HISTORY | ||
119 | |||
120 | X509_STORE_CTX_set0_crls() was first added to OpenSSL 1.0.0 | ||
121 | |||
122 | =cut | ||
diff --git a/src/lib/libcrypto/doc/X509_STORE_CTX_set_verify_cb.pod b/src/lib/libcrypto/doc/X509_STORE_CTX_set_verify_cb.pod new file mode 100644 index 0000000000..b9787a6ca6 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_STORE_CTX_set_verify_cb.pod | |||
@@ -0,0 +1,161 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | X509_STORE_CTX_set_verify_cb - set verification callback | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/x509_vfy.h> | ||
10 | |||
11 | void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, | ||
12 | int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); | ||
13 | |||
14 | =head1 DESCRIPTION | ||
15 | |||
16 | X509_STORE_CTX_set_verify_cb() sets the verification callback of B<ctx> to | ||
17 | B<verify_cb> overwriting any existing callback. | ||
18 | |||
19 | The verification callback can be used to customise the operation of certificate | ||
20 | verification, either by overriding error conditions or logging errors for | ||
21 | debugging purposes. | ||
22 | |||
23 | However a verification callback is B<not> essential and the default operation | ||
24 | is often sufficient. | ||
25 | |||
26 | The B<ok> parameter to the callback indicates the value the callback should | ||
27 | return to retain the default behaviour. If it is zero then and error condition | ||
28 | is indicated. If it is 1 then no error occurred. If the flag | ||
29 | B<X509_V_FLAG_NOTIFY_POLICY> is set then B<ok> is set to 2 to indicate the | ||
30 | policy checking is complete. | ||
31 | |||
32 | The B<ctx> parameter to the callback is the B<X509_STORE_CTX> structure that | ||
33 | is performing the verification operation. A callback can examine this | ||
34 | structure and receive additional information about the error, for example | ||
35 | by calling X509_STORE_CTX_get_current_cert(). Additional application data can | ||
36 | be passed to the callback via the B<ex_data> mechanism. | ||
37 | |||
38 | =head1 WARNING | ||
39 | |||
40 | In general a verification callback should B<NOT> unconditionally return 1 in | ||
41 | all circumstances because this will allow verification to succeed no matter | ||
42 | what the error. This effectively removes all security from the application | ||
43 | because B<any> certificate (including untrusted generated ones) will be | ||
44 | accepted. | ||
45 | |||
46 | =head1 NOTES | ||
47 | |||
48 | The verification callback can be set and inherited from the parent structure | ||
49 | performing the operation. In some cases (such as S/MIME verification) the | ||
50 | B<X509_STORE_CTX> structure is created and destroyed internally and the | ||
51 | only way to set a custom verification callback is by inheriting it from the | ||
52 | associated B<X509_STORE>. | ||
53 | |||
54 | =head1 RETURN VALUES | ||
55 | |||
56 | X509_STORE_CTX_set_verify_cb() does not return a value. | ||
57 | |||
58 | =head1 EXAMPLES | ||
59 | |||
60 | Default callback operation: | ||
61 | |||
62 | int verify_callback(int ok, X509_STORE_CTX *ctx) | ||
63 | { | ||
64 | return ok; | ||
65 | } | ||
66 | |||
67 | Simple example, suppose a certificate in the chain is expired and we wish | ||
68 | to continue after this error: | ||
69 | |||
70 | int verify_callback(int ok, X509_STORE_CTX *ctx) | ||
71 | { | ||
72 | /* Tolerate certificate expiration */ | ||
73 | if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED) | ||
74 | return 1; | ||
75 | /* Otherwise don't override */ | ||
76 | return ok; | ||
77 | } | ||
78 | |||
79 | More complex example, we don't wish to continue after B<any> certificate has | ||
80 | expired just one specific case: | ||
81 | |||
82 | int verify_callback(int ok, X509_STORE_CTX *ctx) | ||
83 | { | ||
84 | int err = X509_STORE_CTX_get_error(ctx); | ||
85 | X509 *err_cert = X509_STORE_CTX_get_current_cert(ctx); | ||
86 | if (err == X509_V_ERR_CERT_HAS_EXPIRED) | ||
87 | { | ||
88 | if (check_is_acceptable_expired_cert(err_cert) | ||
89 | return 1; | ||
90 | } | ||
91 | return ok; | ||
92 | } | ||
93 | |||
94 | Full featured logging callback. In this case the B<bio_err> is assumed to be | ||
95 | a global logging B<BIO>, an alternative would to store a BIO in B<ctx> using | ||
96 | B<ex_data>. | ||
97 | |||
98 | int verify_callback(int ok, X509_STORE_CTX *ctx) | ||
99 | { | ||
100 | X509 *err_cert; | ||
101 | int err,depth; | ||
102 | |||
103 | err_cert = X509_STORE_CTX_get_current_cert(ctx); | ||
104 | err = X509_STORE_CTX_get_error(ctx); | ||
105 | depth = X509_STORE_CTX_get_error_depth(ctx); | ||
106 | |||
107 | BIO_printf(bio_err,"depth=%d ",depth); | ||
108 | if (err_cert) | ||
109 | { | ||
110 | X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), | ||
111 | 0, XN_FLAG_ONELINE); | ||
112 | BIO_puts(bio_err, "\n"); | ||
113 | } | ||
114 | else | ||
115 | BIO_puts(bio_err, "<no cert>\n"); | ||
116 | if (!ok) | ||
117 | BIO_printf(bio_err,"verify error:num=%d:%s\n",err, | ||
118 | X509_verify_cert_error_string(err)); | ||
119 | switch (err) | ||
120 | { | ||
121 | case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: | ||
122 | BIO_puts(bio_err,"issuer= "); | ||
123 | X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), | ||
124 | 0, XN_FLAG_ONELINE); | ||
125 | BIO_puts(bio_err, "\n"); | ||
126 | break; | ||
127 | case X509_V_ERR_CERT_NOT_YET_VALID: | ||
128 | case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: | ||
129 | BIO_printf(bio_err,"notBefore="); | ||
130 | ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert)); | ||
131 | BIO_printf(bio_err,"\n"); | ||
132 | break; | ||
133 | case X509_V_ERR_CERT_HAS_EXPIRED: | ||
134 | case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: | ||
135 | BIO_printf(bio_err,"notAfter="); | ||
136 | ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert)); | ||
137 | BIO_printf(bio_err,"\n"); | ||
138 | break; | ||
139 | case X509_V_ERR_NO_EXPLICIT_POLICY: | ||
140 | policies_print(bio_err, ctx); | ||
141 | break; | ||
142 | } | ||
143 | if (err == X509_V_OK && ok == 2) | ||
144 | /* print out policies */ | ||
145 | |||
146 | BIO_printf(bio_err,"verify return:%d\n",ok); | ||
147 | return(ok); | ||
148 | } | ||
149 | |||
150 | =head1 SEE ALSO | ||
151 | |||
152 | L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)> | ||
153 | L<X509_STORE_set_verify_cb_func(3)|X509_STORE_set_verify_cb_func(3)> | ||
154 | L<X509_STORE_CTX_get_ex_new_index(3)|X509_STORE_CTX_get_ex_new_index(3)> | ||
155 | |||
156 | =head1 HISTORY | ||
157 | |||
158 | X509_STORE_CTX_set_verify_cb() is available in all versions of SSLeay and | ||
159 | OpenSSL. | ||
160 | |||
161 | =cut | ||
diff --git a/src/lib/libcrypto/doc/X509_STORE_set_verify_cb_func.pod b/src/lib/libcrypto/doc/X509_STORE_set_verify_cb_func.pod new file mode 100644 index 0000000000..29e3bbe3bc --- /dev/null +++ b/src/lib/libcrypto/doc/X509_STORE_set_verify_cb_func.pod | |||
@@ -0,0 +1,54 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | X509_STORE_set_verify_cb_func, X509_STORE_set_verify_cb - set verification callback | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/x509_vfy.h> | ||
10 | |||
11 | void X509_STORE_set_verify_cb(X509_STORE *st, | ||
12 | int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); | ||
13 | |||
14 | void X509_STORE_set_verify_cb_func(X509_STORE *st, | ||
15 | int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | X509_STORE_set_verify_cb() sets the verification callback of B<ctx> to | ||
20 | B<verify_cb> overwriting any existing callback. | ||
21 | |||
22 | X509_STORE_set_verify_cb_func() also sets the verification callback but it | ||
23 | is implemented as a macro. | ||
24 | |||
25 | =head1 NOTES | ||
26 | |||
27 | The verification callback from an B<X509_STORE> is inherited by | ||
28 | the corresponding B<X509_STORE_CTX> structure when it is initialized. This can | ||
29 | be used to set the verification callback when the B<X509_STORE_CTX> is | ||
30 | otherwise inaccessible (for example during S/MIME verification). | ||
31 | |||
32 | =head1 BUGS | ||
33 | |||
34 | The macro version of this function was the only one available before | ||
35 | OpenSSL 1.0.0. | ||
36 | |||
37 | =head1 RETURN VALUES | ||
38 | |||
39 | X509_STORE_set_verify_cb() and X509_STORE_set_verify_cb_func() do not return | ||
40 | a value. | ||
41 | |||
42 | =head1 SEE ALSO | ||
43 | |||
44 | L<X509_STORE_CTX_set_verify_cb(3)|X509_STORE_CTX_set_verify_cb(3)> | ||
45 | L<CMS_verify(3)|CMS_verify(3)> | ||
46 | |||
47 | =head1 HISTORY | ||
48 | |||
49 | X509_STORE_set_verify_cb_func() is available in all versions of SSLeay and | ||
50 | OpenSSL. | ||
51 | |||
52 | X509_STORE_set_verify_cb() was added to OpenSSL 1.0.0. | ||
53 | |||
54 | =cut | ||
diff --git a/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod b/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod new file mode 100644 index 0000000000..b68eece033 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod | |||
@@ -0,0 +1,171 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_get_flags, X509_VERIFY_PARAM_set_purpose, X509_VERIFY_PARAM_set_trust, X509_VERIFY_PARAM_set_depth, X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies - X509 verification parameters | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/x509_vfy.h> | ||
10 | |||
11 | int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); | ||
12 | int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, | ||
13 | unsigned long flags); | ||
14 | unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); | ||
15 | |||
16 | int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); | ||
17 | int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); | ||
18 | |||
19 | void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); | ||
20 | |||
21 | int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, | ||
22 | ASN1_OBJECT *policy); | ||
23 | int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, | ||
24 | STACK_OF(ASN1_OBJECT) *policies); | ||
25 | |||
26 | void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); | ||
27 | int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); | ||
28 | |||
29 | =head1 DESCRIPTION | ||
30 | |||
31 | These functions manipulate the B<X509_VERIFY_PARAM> structure associated with | ||
32 | a certificate verification operation. | ||
33 | |||
34 | The X509_VERIFY_PARAM_set_flags() function sets the flags in B<param> by oring | ||
35 | it with B<flags>. See the B<VERIFICATION FLAGS> section for a complete | ||
36 | description of values the B<flags> parameter can take. | ||
37 | |||
38 | X509_VERIFY_PARAM_get_flags() returns the flags in B<param>. | ||
39 | |||
40 | X509_VERIFY_PARAM_clear_flags() clears the flags B<flags> in B<param>. | ||
41 | |||
42 | X509_VERIFY_PARAM_set_purpose() sets the verification purpose in B<param> | ||
43 | to B<purpose>. This determines the acceptable purpose of the certificate | ||
44 | chain, for example SSL client or SSL server. | ||
45 | |||
46 | X509_VERIFY_PARAM_set_trust() sets the trust setting in B<param> to | ||
47 | B<trust>. | ||
48 | |||
49 | X509_VERIFY_PARAM_set_time() sets the verification time in B<param> to | ||
50 | B<t>. Normally the current time is used. | ||
51 | |||
52 | X509_VERIFY_PARAM_add0_policy() enables policy checking (it is disabled | ||
53 | by default) and adds B<policy> to the acceptable policy set. | ||
54 | |||
55 | X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled | ||
56 | by default) and sets the acceptable policy set to B<policies>. Any existing | ||
57 | policy set is cleared. The B<policies> parameter can be B<NULL> to clear | ||
58 | an existing policy set. | ||
59 | |||
60 | X509_VERIFY_PARAM_set_depth() sets the maximum verification depth to B<depth>. | ||
61 | That is the maximum number of untrusted CA certificates that can appear in a | ||
62 | chain. | ||
63 | |||
64 | =head1 RETURN VALUES | ||
65 | |||
66 | X509_VERIFY_PARAM_set_flags(), X509_VERIFY_PARAM_clear_flags(), | ||
67 | X509_VERIFY_PARAM_set_purpose(), X509_VERIFY_PARAM_set_trust(), | ||
68 | X509_VERIFY_PARAM_add0_policy() and X509_VERIFY_PARAM_set1_policies() return 1 | ||
69 | for success and 0 for failure. | ||
70 | |||
71 | X509_VERIFY_PARAM_get_flags() returns the current verification flags. | ||
72 | |||
73 | X509_VERIFY_PARAM_set_time() and X509_VERIFY_PARAM_set_depth() do not return | ||
74 | values. | ||
75 | |||
76 | X509_VERIFY_PARAM_get_depth() returns the current verification depth. | ||
77 | |||
78 | =head1 VERIFICATION FLAGS | ||
79 | |||
80 | The verification flags consists of zero or more of the following flags | ||
81 | ored together. | ||
82 | |||
83 | B<X509_V_FLAG_CRL_CHECK> enables CRL checking for the certificate chain leaf | ||
84 | certificate. An error occurs if a suitable CRL cannot be found. | ||
85 | |||
86 | B<X509_V_FLAG_CRL_CHECK_ALL> enables CRL checking for the entire certificate | ||
87 | chain. | ||
88 | |||
89 | B<X509_V_FLAG_IGNORE_CRITICAL> disabled critical extension checking. By default | ||
90 | any unhandled critical extensions in certificates or (if checked) CRLs results | ||
91 | in a fatal error. If this flag is set unhandled critical extensions are | ||
92 | ignored. B<WARNING> setting this option for anything other than debugging | ||
93 | purposes can be a security risk. Finer control over which extensions are | ||
94 | supported can be performed in the verification callback. | ||
95 | |||
96 | THe B<X509_V_FLAG_X509_STRICT> flag disables workarounds for some broken | ||
97 | certificates and makes the verification strictly apply B<X509> rules. | ||
98 | |||
99 | B<X509_V_FLAG_ALLOW_PROXY_CERTS> enables proxy certificate verification. | ||
100 | |||
101 | B<X509_V_FLAG_POLICY_CHECK> enables certificate policy checking, by default | ||
102 | no policy checking is peformed. Additional information is sent to the | ||
103 | verification callback relating to policy checking. | ||
104 | |||
105 | B<X509_V_FLAG_EXPLICIT_POLICY>, B<X509_V_FLAG_INHIBIT_ANY> and | ||
106 | B<X509_V_FLAG_INHIBIT_MAP> set the B<require explicit policy>, B<inhibit any | ||
107 | policy> and B<inhibit policy mapping> flags respectively as defined in | ||
108 | B<RFC3280>. Policy checking is automatically enabled if any of these flags | ||
109 | are set. | ||
110 | |||
111 | If B<X509_V_FLAG_NOTIFY_POLICY> is set and the policy checking is successful | ||
112 | a special status code is set to the verification callback. This permits it | ||
113 | to examine the valid policy tree and perform additional checks or simply | ||
114 | log it for debugging purposes. | ||
115 | |||
116 | By default some addtional features such as indirect CRLs and CRLs signed by | ||
117 | different keys are disabled. If B<X509_V_FLAG_EXTENDED_CRL_SUPPORT> is set | ||
118 | they are enabled. | ||
119 | |||
120 | If B<X509_V_FLAG_USE_DELTAS> ise set delta CRLs (if present) are used to | ||
121 | determine certificate status. If not set deltas are ignored. | ||
122 | |||
123 | B<X509_V_FLAG_CHECK_SS_SIGNATURE> enables checking of the root CA self signed | ||
124 | cerificate signature. By default this check is disabled because it doesn't | ||
125 | add any additional security but in some cases applications might want to | ||
126 | check the signature anyway. A side effect of not checking the root CA | ||
127 | signature is that disabled or unsupported message digests on the root CA | ||
128 | are not treated as fatal errors. | ||
129 | |||
130 | The B<X509_V_FLAG_CB_ISSUER_CHECK> flag enables debugging of certificate | ||
131 | issuer checks. It is B<not> needed unless you are logging certificate | ||
132 | verification. If this flag is set then additional status codes will be sent | ||
133 | to the verification callback and it B<must> be prepared to handle such cases | ||
134 | without assuming they are hard errors. | ||
135 | |||
136 | =head1 NOTES | ||
137 | |||
138 | The above functions should be used to manipulate verification parameters | ||
139 | instead of legacy functions which work in specific structures such as | ||
140 | X509_STORE_CTX_set_flags(). | ||
141 | |||
142 | =head1 BUGS | ||
143 | |||
144 | Delta CRL checking is currently primitive. Only a single delta can be used and | ||
145 | (partly due to limitations of B<X509_STORE>) constructed CRLs are not | ||
146 | maintained. | ||
147 | |||
148 | If CRLs checking is enable CRLs are expected to be available in the | ||
149 | corresponding B<X509_STORE> structure. No attempt is made to download | ||
150 | CRLs from the CRL distribution points extension. | ||
151 | |||
152 | =head1 EXAMPLE | ||
153 | |||
154 | Enable CRL checking when performing certificate verification during SSL | ||
155 | connections associated with an B<SSL_CTX> structure B<ctx>: | ||
156 | |||
157 | X509_VERIFY_PARAM *param; | ||
158 | param = X509_VERIFY_PARAM_new(); | ||
159 | X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); | ||
160 | SSL_CTX_set1_param(ctx, param); | ||
161 | X509_VERIFY_PARAM_free(param); | ||
162 | |||
163 | =head1 SEE ALSO | ||
164 | |||
165 | L<X509_verify_cert(3)|X509_verify_cert(3)> | ||
166 | |||
167 | =head1 HISTORY | ||
168 | |||
169 | TBA | ||
170 | |||
171 | =cut | ||
diff --git a/src/lib/libcrypto/doc/X509_new.pod b/src/lib/libcrypto/doc/X509_new.pod index fd5fc65ce1..d38872335f 100644 --- a/src/lib/libcrypto/doc/X509_new.pod +++ b/src/lib/libcrypto/doc/X509_new.pod | |||
@@ -6,6 +6,8 @@ X509_new, X509_free - X509 certificate ASN1 allocation functions | |||
6 | 6 | ||
7 | =head1 SYNOPSIS | 7 | =head1 SYNOPSIS |
8 | 8 | ||
9 | #include <openssl/x509.h> | ||
10 | |||
9 | X509 *X509_new(void); | 11 | X509 *X509_new(void); |
10 | void X509_free(X509 *a); | 12 | void X509_free(X509 *a); |
11 | 13 | ||
diff --git a/src/lib/libcrypto/doc/X509_verify_cert.pod b/src/lib/libcrypto/doc/X509_verify_cert.pod new file mode 100644 index 0000000000..5253bdcd70 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_verify_cert.pod | |||
@@ -0,0 +1,53 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | X509_verify_cert - discover and verify X509 certificte chain | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/x509.h> | ||
10 | |||
11 | int X509_verify_cert(X509_STORE_CTX *ctx); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | The X509_verify_cert() function attempts to discover and validate a | ||
16 | certificate chain based on parameters in B<ctx>. A complete description of | ||
17 | the process is contained in the L<verify(1)|verify(1)> manual page. | ||
18 | |||
19 | =head1 RETURN VALUES | ||
20 | |||
21 | If a complete chain can be built and validated this function returns 1, | ||
22 | otherwise it return zero, in exceptional circumstances it can also | ||
23 | return a negative code. | ||
24 | |||
25 | If the function fails additional error information can be obtained by | ||
26 | examining B<ctx> using, for example X509_STORE_CTX_get_error(). | ||
27 | |||
28 | =head1 NOTES | ||
29 | |||
30 | Applications rarely call this function directly but it is used by | ||
31 | OpenSSL internally for certificate validation, in both the S/MIME and | ||
32 | SSL/TLS code. | ||
33 | |||
34 | The negative return value from X509_verify_cert() can only occur if no | ||
35 | certificate is set in B<ctx> (due to a programming error) or if a retry | ||
36 | operation is requested during internal lookups (which never happens with | ||
37 | standard lookup methods). It is however recommended that application check | ||
38 | for <= 0 return value on error. | ||
39 | |||
40 | =head1 BUGS | ||
41 | |||
42 | This function uses the header B<x509.h> as opposed to most chain verification | ||
43 | functiosn which use B<x509_vfy.h>. | ||
44 | |||
45 | =head1 SEE ALSO | ||
46 | |||
47 | L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)> | ||
48 | |||
49 | =head1 HISTORY | ||
50 | |||
51 | X509_verify_cert() is available in all versions of SSLeay and OpenSSL. | ||
52 | |||
53 | =cut | ||
diff --git a/src/lib/libcrypto/doc/d2i_X509.pod b/src/lib/libcrypto/doc/d2i_X509.pod index 5bfa18afbb..298ec54a4c 100644 --- a/src/lib/libcrypto/doc/d2i_X509.pod +++ b/src/lib/libcrypto/doc/d2i_X509.pod | |||
@@ -15,8 +15,8 @@ i2d_X509_fp - X509 encode and decode functions | |||
15 | X509 *d2i_X509_bio(BIO *bp, X509 **x); | 15 | X509 *d2i_X509_bio(BIO *bp, X509 **x); |
16 | X509 *d2i_X509_fp(FILE *fp, X509 **x); | 16 | X509 *d2i_X509_fp(FILE *fp, X509 **x); |
17 | 17 | ||
18 | int i2d_X509_bio(X509 *x, BIO *bp); | 18 | int i2d_X509_bio(BIO *bp, X509 *x); |
19 | int i2d_X509_fp(X509 *x, FILE *fp); | 19 | int i2d_X509_fp(FILE *fp, X509 *x); |
20 | 20 | ||
21 | =head1 DESCRIPTION | 21 | =head1 DESCRIPTION |
22 | 22 | ||
@@ -212,11 +212,11 @@ d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B<X509> structure | |||
212 | or B<NULL> if an error occurs. The error code that can be obtained by | 212 | or B<NULL> if an error occurs. The error code that can be obtained by |
213 | L<ERR_get_error(3)|ERR_get_error(3)>. | 213 | L<ERR_get_error(3)|ERR_get_error(3)>. |
214 | 214 | ||
215 | i2d_X509(), i2d_X509_bio() and i2d_X509_fp() return a the number of bytes | 215 | i2d_X509() returns the number of bytes successfully encoded or a negative |
216 | successfully encoded or a negative value if an error occurs. The error code | 216 | value if an error occurs. The error code can be obtained by |
217 | can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | 217 | L<ERR_get_error(3)|ERR_get_error(3)>. |
218 | 218 | ||
219 | i2d_X509_bio() and i2d_X509_fp() returns 1 for success and 0 if an error | 219 | i2d_X509_bio() and i2d_X509_fp() return 1 for success and 0 if an error |
220 | occurs The error code can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | 220 | occurs The error code can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. |
221 | 221 | ||
222 | =head1 SEE ALSO | 222 | =head1 SEE ALSO |
diff --git a/src/lib/libcrypto/doc/d2i_X509_CRL.pod b/src/lib/libcrypto/doc/d2i_X509_CRL.pod index e7295a5d61..224f9e082b 100644 --- a/src/lib/libcrypto/doc/d2i_X509_CRL.pod +++ b/src/lib/libcrypto/doc/d2i_X509_CRL.pod | |||
@@ -15,8 +15,8 @@ i2d_X509_CRL_bio, i2d_X509_CRL_fp - PKCS#10 certificate request functions. | |||
15 | X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x); | 15 | X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x); |
16 | X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **x); | 16 | X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **x); |
17 | 17 | ||
18 | int i2d_X509_CRL_bio(X509_CRL *x, BIO *bp); | 18 | int i2d_X509_CRL_bio(BIO *bp, X509_CRL *x); |
19 | int i2d_X509_CRL_fp(X509_CRL *x, FILE *fp); | 19 | int i2d_X509_CRL_fp(FILE *fp, X509_CRL *x); |
20 | 20 | ||
21 | =head1 DESCRIPTION | 21 | =head1 DESCRIPTION |
22 | 22 | ||
diff --git a/src/lib/libcrypto/doc/d2i_X509_REQ.pod b/src/lib/libcrypto/doc/d2i_X509_REQ.pod index ae32a3891d..91c0c1974b 100644 --- a/src/lib/libcrypto/doc/d2i_X509_REQ.pod +++ b/src/lib/libcrypto/doc/d2i_X509_REQ.pod | |||
@@ -15,8 +15,8 @@ i2d_X509_REQ_bio, i2d_X509_REQ_fp - PKCS#10 certificate request functions. | |||
15 | X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x); | 15 | X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x); |
16 | X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **x); | 16 | X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **x); |
17 | 17 | ||
18 | int i2d_X509_REQ_bio(X509_REQ *x, BIO *bp); | 18 | int i2d_X509_REQ_bio(BIO *bp, X509_REQ *x); |
19 | int i2d_X509_REQ_fp(X509_REQ *x, FILE *fp); | 19 | int i2d_X509_REQ_fp(FILE *fp, X509_REQ *x); |
20 | 20 | ||
21 | =head1 DESCRIPTION | 21 | =head1 DESCRIPTION |
22 | 22 | ||
diff --git a/src/lib/libcrypto/doc/i2d_CMS_bio_stream.pod b/src/lib/libcrypto/doc/i2d_CMS_bio_stream.pod new file mode 100644 index 0000000000..558bdd0812 --- /dev/null +++ b/src/lib/libcrypto/doc/i2d_CMS_bio_stream.pod | |||
@@ -0,0 +1,44 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | i2d_CMS_bio_stream - output CMS_ContentInfo structure in BER format. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/cms.h> | ||
10 | |||
11 | int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | i2d_CMS_bio_stream() outputs a CMS_ContentInfo structure in BER format. | ||
16 | |||
17 | It is otherwise identical to the function SMIME_write_CMS(). | ||
18 | |||
19 | =head1 NOTES | ||
20 | |||
21 | This function is effectively a version of the i2d_CMS_bio() supporting | ||
22 | streaming. | ||
23 | |||
24 | =head1 BUGS | ||
25 | |||
26 | The prefix "i2d" is arguably wrong because the function outputs BER format. | ||
27 | |||
28 | =head1 RETURN VALUES | ||
29 | |||
30 | i2d_CMS_bio_stream() returns 1 for success or 0 for failure. | ||
31 | |||
32 | =head1 SEE ALSO | ||
33 | |||
34 | L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>, | ||
35 | L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)> | ||
36 | L<CMS_decrypt(3)|CMS_decrypt(3)>, | ||
37 | L<SMIME_write_CMS(3)|SMIME_write_CMS(3)>, | ||
38 | L<PEM_write_bio_CMS_stream(3)|PEM_write_bio_CMS_stream(3)> | ||
39 | |||
40 | =head1 HISTORY | ||
41 | |||
42 | i2d_CMS_bio_stream() was added to OpenSSL 1.0.0 | ||
43 | |||
44 | =cut | ||
diff --git a/src/lib/libcrypto/doc/i2d_PKCS7_bio_stream.pod b/src/lib/libcrypto/doc/i2d_PKCS7_bio_stream.pod new file mode 100644 index 0000000000..dc4d884c59 --- /dev/null +++ b/src/lib/libcrypto/doc/i2d_PKCS7_bio_stream.pod | |||
@@ -0,0 +1,44 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | i2d_PKCS7_bio_stream - output PKCS7 structure in BER format. | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/pkcs7.h> | ||
10 | |||
11 | int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *data, int flags); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | i2d_PKCS7_bio_stream() outputs a PKCS7 structure in BER format. | ||
16 | |||
17 | It is otherwise identical to the function SMIME_write_PKCS7(). | ||
18 | |||
19 | =head1 NOTES | ||
20 | |||
21 | This function is effectively a version of the d2i_PKCS7_bio() supporting | ||
22 | streaming. | ||
23 | |||
24 | =head1 BUGS | ||
25 | |||
26 | The prefix "d2i" is arguably wrong because the function outputs BER format. | ||
27 | |||
28 | =head1 RETURN VALUES | ||
29 | |||
30 | i2d_PKCS7_bio_stream() returns 1 for success or 0 for failure. | ||
31 | |||
32 | =head1 SEE ALSO | ||
33 | |||
34 | L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>, | ||
35 | L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)> | ||
36 | L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>, | ||
37 | L<SMIME_write_PKCS7(3)|SMIME_write_PKCS7(3)>, | ||
38 | L<PEM_write_bio_PKCS7_stream(3)|PEM_write_bio_PKCS7_stream(3)> | ||
39 | |||
40 | =head1 HISTORY | ||
41 | |||
42 | i2d_PKCS7_bio_stream() was added to OpenSSL 1.0.0 | ||
43 | |||
44 | =cut | ||
diff --git a/src/lib/libcrypto/dsa/dsa_ameth.c b/src/lib/libcrypto/dsa/dsa_ameth.c new file mode 100644 index 0000000000..6413aae46e --- /dev/null +++ b/src/lib/libcrypto/dsa/dsa_ameth.c | |||
@@ -0,0 +1,657 @@ | |||
1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
2 | * project 2006. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <stdio.h> | ||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/x509.h> | ||
61 | #include <openssl/asn1.h> | ||
62 | #include <openssl/dsa.h> | ||
63 | #include <openssl/bn.h> | ||
64 | #ifndef OPENSSL_NO_CMS | ||
65 | #include <openssl/cms.h> | ||
66 | #endif | ||
67 | #include "asn1_locl.h" | ||
68 | |||
69 | static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) | ||
70 | { | ||
71 | const unsigned char *p, *pm; | ||
72 | int pklen, pmlen; | ||
73 | int ptype; | ||
74 | void *pval; | ||
75 | ASN1_STRING *pstr; | ||
76 | X509_ALGOR *palg; | ||
77 | ASN1_INTEGER *public_key = NULL; | ||
78 | |||
79 | DSA *dsa = NULL; | ||
80 | |||
81 | if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) | ||
82 | return 0; | ||
83 | X509_ALGOR_get0(NULL, &ptype, &pval, palg); | ||
84 | |||
85 | |||
86 | if (ptype == V_ASN1_SEQUENCE) | ||
87 | { | ||
88 | pstr = pval; | ||
89 | pm = pstr->data; | ||
90 | pmlen = pstr->length; | ||
91 | |||
92 | if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) | ||
93 | { | ||
94 | DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); | ||
95 | goto err; | ||
96 | } | ||
97 | |||
98 | } | ||
99 | else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) | ||
100 | { | ||
101 | if (!(dsa = DSA_new())) | ||
102 | { | ||
103 | DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); | ||
104 | goto err; | ||
105 | } | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); | ||
110 | goto err; | ||
111 | } | ||
112 | |||
113 | if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) | ||
114 | { | ||
115 | DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); | ||
116 | goto err; | ||
117 | } | ||
118 | |||
119 | if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) | ||
120 | { | ||
121 | DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); | ||
122 | goto err; | ||
123 | } | ||
124 | |||
125 | ASN1_INTEGER_free(public_key); | ||
126 | EVP_PKEY_assign_DSA(pkey, dsa); | ||
127 | return 1; | ||
128 | |||
129 | err: | ||
130 | if (public_key) | ||
131 | ASN1_INTEGER_free(public_key); | ||
132 | if (dsa) | ||
133 | DSA_free(dsa); | ||
134 | return 0; | ||
135 | |||
136 | } | ||
137 | |||
138 | static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) | ||
139 | { | ||
140 | DSA *dsa; | ||
141 | void *pval = NULL; | ||
142 | int ptype; | ||
143 | unsigned char *penc = NULL; | ||
144 | int penclen; | ||
145 | |||
146 | dsa=pkey->pkey.dsa; | ||
147 | if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) | ||
148 | { | ||
149 | ASN1_STRING *str; | ||
150 | str = ASN1_STRING_new(); | ||
151 | str->length = i2d_DSAparams(dsa, &str->data); | ||
152 | if (str->length <= 0) | ||
153 | { | ||
154 | DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); | ||
155 | goto err; | ||
156 | } | ||
157 | pval = str; | ||
158 | ptype = V_ASN1_SEQUENCE; | ||
159 | } | ||
160 | else | ||
161 | ptype = V_ASN1_UNDEF; | ||
162 | |||
163 | dsa->write_params=0; | ||
164 | |||
165 | penclen = i2d_DSAPublicKey(dsa, &penc); | ||
166 | |||
167 | if (penclen <= 0) | ||
168 | { | ||
169 | DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); | ||
170 | goto err; | ||
171 | } | ||
172 | |||
173 | if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), | ||
174 | ptype, pval, penc, penclen)) | ||
175 | return 1; | ||
176 | |||
177 | err: | ||
178 | if (penc) | ||
179 | OPENSSL_free(penc); | ||
180 | if (pval) | ||
181 | ASN1_STRING_free(pval); | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | /* In PKCS#8 DSA: you just get a private key integer and parameters in the | ||
187 | * AlgorithmIdentifier the pubkey must be recalculated. | ||
188 | */ | ||
189 | |||
190 | static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) | ||
191 | { | ||
192 | const unsigned char *p, *pm; | ||
193 | int pklen, pmlen; | ||
194 | int ptype; | ||
195 | void *pval; | ||
196 | ASN1_STRING *pstr; | ||
197 | X509_ALGOR *palg; | ||
198 | ASN1_INTEGER *privkey = NULL; | ||
199 | BN_CTX *ctx = NULL; | ||
200 | |||
201 | STACK_OF(ASN1_TYPE) *ndsa = NULL; | ||
202 | DSA *dsa = NULL; | ||
203 | |||
204 | if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) | ||
205 | return 0; | ||
206 | X509_ALGOR_get0(NULL, &ptype, &pval, palg); | ||
207 | |||
208 | /* Check for broken DSA PKCS#8, UGH! */ | ||
209 | if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) | ||
210 | { | ||
211 | ASN1_TYPE *t1, *t2; | ||
212 | if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen))) | ||
213 | goto decerr; | ||
214 | if (sk_ASN1_TYPE_num(ndsa) != 2) | ||
215 | goto decerr; | ||
216 | /* Handle Two broken types: | ||
217 | * SEQUENCE {parameters, priv_key} | ||
218 | * SEQUENCE {pub_key, priv_key} | ||
219 | */ | ||
220 | |||
221 | t1 = sk_ASN1_TYPE_value(ndsa, 0); | ||
222 | t2 = sk_ASN1_TYPE_value(ndsa, 1); | ||
223 | if (t1->type == V_ASN1_SEQUENCE) | ||
224 | { | ||
225 | p8->broken = PKCS8_EMBEDDED_PARAM; | ||
226 | pval = t1->value.ptr; | ||
227 | } | ||
228 | else if (ptype == V_ASN1_SEQUENCE) | ||
229 | p8->broken = PKCS8_NS_DB; | ||
230 | else | ||
231 | goto decerr; | ||
232 | |||
233 | if (t2->type != V_ASN1_INTEGER) | ||
234 | goto decerr; | ||
235 | |||
236 | privkey = t2->value.integer; | ||
237 | } | ||
238 | else | ||
239 | { | ||
240 | const unsigned char *q = p; | ||
241 | if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen))) | ||
242 | goto decerr; | ||
243 | if (privkey->type == V_ASN1_NEG_INTEGER) | ||
244 | { | ||
245 | p8->broken = PKCS8_NEG_PRIVKEY; | ||
246 | ASN1_INTEGER_free(privkey); | ||
247 | if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen))) | ||
248 | goto decerr; | ||
249 | } | ||
250 | if (ptype != V_ASN1_SEQUENCE) | ||
251 | goto decerr; | ||
252 | } | ||
253 | |||
254 | pstr = pval; | ||
255 | pm = pstr->data; | ||
256 | pmlen = pstr->length; | ||
257 | if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) | ||
258 | goto decerr; | ||
259 | /* We have parameters now set private key */ | ||
260 | if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) | ||
261 | { | ||
262 | DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); | ||
263 | goto dsaerr; | ||
264 | } | ||
265 | /* Calculate public key */ | ||
266 | if (!(dsa->pub_key = BN_new())) | ||
267 | { | ||
268 | DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); | ||
269 | goto dsaerr; | ||
270 | } | ||
271 | if (!(ctx = BN_CTX_new())) | ||
272 | { | ||
273 | DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); | ||
274 | goto dsaerr; | ||
275 | } | ||
276 | |||
277 | if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) | ||
278 | { | ||
279 | DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); | ||
280 | goto dsaerr; | ||
281 | } | ||
282 | |||
283 | EVP_PKEY_assign_DSA(pkey, dsa); | ||
284 | BN_CTX_free (ctx); | ||
285 | if(ndsa) | ||
286 | sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); | ||
287 | else | ||
288 | ASN1_INTEGER_free(privkey); | ||
289 | |||
290 | return 1; | ||
291 | |||
292 | decerr: | ||
293 | DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR); | ||
294 | dsaerr: | ||
295 | BN_CTX_free (ctx); | ||
296 | if (privkey) | ||
297 | ASN1_INTEGER_free(privkey); | ||
298 | sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); | ||
299 | DSA_free(dsa); | ||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) | ||
304 | { | ||
305 | ASN1_STRING *params = NULL; | ||
306 | ASN1_INTEGER *prkey = NULL; | ||
307 | unsigned char *dp = NULL; | ||
308 | int dplen; | ||
309 | |||
310 | params = ASN1_STRING_new(); | ||
311 | |||
312 | if (!params) | ||
313 | { | ||
314 | DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); | ||
315 | goto err; | ||
316 | } | ||
317 | |||
318 | params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); | ||
319 | if (params->length <= 0) | ||
320 | { | ||
321 | DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); | ||
322 | goto err; | ||
323 | } | ||
324 | params->type = V_ASN1_SEQUENCE; | ||
325 | |||
326 | /* Get private key into integer */ | ||
327 | prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); | ||
328 | |||
329 | if (!prkey) | ||
330 | { | ||
331 | DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR); | ||
332 | goto err; | ||
333 | } | ||
334 | |||
335 | dplen = i2d_ASN1_INTEGER(prkey, &dp); | ||
336 | |||
337 | ASN1_INTEGER_free(prkey); | ||
338 | |||
339 | if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, | ||
340 | V_ASN1_SEQUENCE, params, dp, dplen)) | ||
341 | goto err; | ||
342 | |||
343 | return 1; | ||
344 | |||
345 | err: | ||
346 | if (dp != NULL) | ||
347 | OPENSSL_free(dp); | ||
348 | if (params != NULL) | ||
349 | ASN1_STRING_free(params); | ||
350 | if (prkey != NULL) | ||
351 | ASN1_INTEGER_free(prkey); | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int int_dsa_size(const EVP_PKEY *pkey) | ||
356 | { | ||
357 | return(DSA_size(pkey->pkey.dsa)); | ||
358 | } | ||
359 | |||
360 | static int dsa_bits(const EVP_PKEY *pkey) | ||
361 | { | ||
362 | return BN_num_bits(pkey->pkey.dsa->p); | ||
363 | } | ||
364 | |||
365 | static int dsa_missing_parameters(const EVP_PKEY *pkey) | ||
366 | { | ||
367 | DSA *dsa; | ||
368 | dsa=pkey->pkey.dsa; | ||
369 | if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) | ||
370 | return 1; | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) | ||
375 | { | ||
376 | BIGNUM *a; | ||
377 | |||
378 | if ((a=BN_dup(from->pkey.dsa->p)) == NULL) | ||
379 | return 0; | ||
380 | if (to->pkey.dsa->p != NULL) | ||
381 | BN_free(to->pkey.dsa->p); | ||
382 | to->pkey.dsa->p=a; | ||
383 | |||
384 | if ((a=BN_dup(from->pkey.dsa->q)) == NULL) | ||
385 | return 0; | ||
386 | if (to->pkey.dsa->q != NULL) | ||
387 | BN_free(to->pkey.dsa->q); | ||
388 | to->pkey.dsa->q=a; | ||
389 | |||
390 | if ((a=BN_dup(from->pkey.dsa->g)) == NULL) | ||
391 | return 0; | ||
392 | if (to->pkey.dsa->g != NULL) | ||
393 | BN_free(to->pkey.dsa->g); | ||
394 | to->pkey.dsa->g=a; | ||
395 | return 1; | ||
396 | } | ||
397 | |||
398 | static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) | ||
399 | { | ||
400 | if ( BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) || | ||
401 | BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) || | ||
402 | BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g)) | ||
403 | return 0; | ||
404 | else | ||
405 | return 1; | ||
406 | } | ||
407 | |||
408 | static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) | ||
409 | { | ||
410 | if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0) | ||
411 | return 0; | ||
412 | else | ||
413 | return 1; | ||
414 | } | ||
415 | |||
416 | static void int_dsa_free(EVP_PKEY *pkey) | ||
417 | { | ||
418 | DSA_free(pkey->pkey.dsa); | ||
419 | } | ||
420 | |||
421 | static void update_buflen(const BIGNUM *b, size_t *pbuflen) | ||
422 | { | ||
423 | size_t i; | ||
424 | if (!b) | ||
425 | return; | ||
426 | if (*pbuflen < (i = (size_t)BN_num_bytes(b))) | ||
427 | *pbuflen = i; | ||
428 | } | ||
429 | |||
430 | static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) | ||
431 | { | ||
432 | unsigned char *m=NULL; | ||
433 | int ret=0; | ||
434 | size_t buf_len=0; | ||
435 | const char *ktype = NULL; | ||
436 | |||
437 | const BIGNUM *priv_key, *pub_key; | ||
438 | |||
439 | if (ptype == 2) | ||
440 | priv_key = x->priv_key; | ||
441 | else | ||
442 | priv_key = NULL; | ||
443 | |||
444 | if (ptype > 0) | ||
445 | pub_key = x->pub_key; | ||
446 | else | ||
447 | pub_key = NULL; | ||
448 | |||
449 | if (ptype == 2) | ||
450 | ktype = "Private-Key"; | ||
451 | else if (ptype == 1) | ||
452 | ktype = "Public-Key"; | ||
453 | else | ||
454 | ktype = "DSA-Parameters"; | ||
455 | |||
456 | update_buflen(x->p, &buf_len); | ||
457 | update_buflen(x->q, &buf_len); | ||
458 | update_buflen(x->g, &buf_len); | ||
459 | update_buflen(priv_key, &buf_len); | ||
460 | update_buflen(pub_key, &buf_len); | ||
461 | |||
462 | m=(unsigned char *)OPENSSL_malloc(buf_len+10); | ||
463 | if (m == NULL) | ||
464 | { | ||
465 | DSAerr(DSA_F_DO_DSA_PRINT,ERR_R_MALLOC_FAILURE); | ||
466 | goto err; | ||
467 | } | ||
468 | |||
469 | if (priv_key) | ||
470 | { | ||
471 | if(!BIO_indent(bp,off,128)) | ||
472 | goto err; | ||
473 | if (BIO_printf(bp,"%s: (%d bit)\n",ktype, BN_num_bits(x->p)) | ||
474 | <= 0) goto err; | ||
475 | } | ||
476 | |||
477 | if (!ASN1_bn_print(bp,"priv:",priv_key,m,off)) | ||
478 | goto err; | ||
479 | if (!ASN1_bn_print(bp,"pub: ",pub_key,m,off)) | ||
480 | goto err; | ||
481 | if (!ASN1_bn_print(bp,"P: ",x->p,m,off)) goto err; | ||
482 | if (!ASN1_bn_print(bp,"Q: ",x->q,m,off)) goto err; | ||
483 | if (!ASN1_bn_print(bp,"G: ",x->g,m,off)) goto err; | ||
484 | ret=1; | ||
485 | err: | ||
486 | if (m != NULL) OPENSSL_free(m); | ||
487 | return(ret); | ||
488 | } | ||
489 | |||
490 | static int dsa_param_decode(EVP_PKEY *pkey, | ||
491 | const unsigned char **pder, int derlen) | ||
492 | { | ||
493 | DSA *dsa; | ||
494 | if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) | ||
495 | { | ||
496 | DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); | ||
497 | return 0; | ||
498 | } | ||
499 | EVP_PKEY_assign_DSA(pkey, dsa); | ||
500 | return 1; | ||
501 | } | ||
502 | |||
503 | static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder) | ||
504 | { | ||
505 | return i2d_DSAparams(pkey->pkey.dsa, pder); | ||
506 | } | ||
507 | |||
508 | static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
509 | ASN1_PCTX *ctx) | ||
510 | { | ||
511 | return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); | ||
512 | } | ||
513 | |||
514 | static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
515 | ASN1_PCTX *ctx) | ||
516 | { | ||
517 | return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); | ||
518 | } | ||
519 | |||
520 | |||
521 | static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
522 | ASN1_PCTX *ctx) | ||
523 | { | ||
524 | return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); | ||
525 | } | ||
526 | |||
527 | static int old_dsa_priv_decode(EVP_PKEY *pkey, | ||
528 | const unsigned char **pder, int derlen) | ||
529 | { | ||
530 | DSA *dsa; | ||
531 | if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen))) | ||
532 | { | ||
533 | DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); | ||
534 | return 0; | ||
535 | } | ||
536 | EVP_PKEY_assign_DSA(pkey, dsa); | ||
537 | return 1; | ||
538 | } | ||
539 | |||
540 | static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) | ||
541 | { | ||
542 | return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); | ||
543 | } | ||
544 | |||
545 | static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | ||
546 | { | ||
547 | switch (op) | ||
548 | { | ||
549 | case ASN1_PKEY_CTRL_PKCS7_SIGN: | ||
550 | if (arg1 == 0) | ||
551 | { | ||
552 | int snid, hnid; | ||
553 | X509_ALGOR *alg1, *alg2; | ||
554 | PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); | ||
555 | if (alg1 == NULL || alg1->algorithm == NULL) | ||
556 | return -1; | ||
557 | hnid = OBJ_obj2nid(alg1->algorithm); | ||
558 | if (hnid == NID_undef) | ||
559 | return -1; | ||
560 | if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) | ||
561 | return -1; | ||
562 | X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); | ||
563 | } | ||
564 | return 1; | ||
565 | #ifndef OPENSSL_NO_CMS | ||
566 | case ASN1_PKEY_CTRL_CMS_SIGN: | ||
567 | if (arg1 == 0) | ||
568 | { | ||
569 | int snid, hnid; | ||
570 | X509_ALGOR *alg1, *alg2; | ||
571 | CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); | ||
572 | if (alg1 == NULL || alg1->algorithm == NULL) | ||
573 | return -1; | ||
574 | hnid = OBJ_obj2nid(alg1->algorithm); | ||
575 | if (hnid == NID_undef) | ||
576 | return -1; | ||
577 | if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) | ||
578 | return -1; | ||
579 | X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); | ||
580 | } | ||
581 | return 1; | ||
582 | #endif | ||
583 | |||
584 | case ASN1_PKEY_CTRL_DEFAULT_MD_NID: | ||
585 | *(int *)arg2 = NID_sha1; | ||
586 | return 2; | ||
587 | |||
588 | default: | ||
589 | return -2; | ||
590 | |||
591 | } | ||
592 | |||
593 | } | ||
594 | |||
595 | /* NB these are sorted in pkey_id order, lowest first */ | ||
596 | |||
597 | const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = | ||
598 | { | ||
599 | |||
600 | { | ||
601 | EVP_PKEY_DSA2, | ||
602 | EVP_PKEY_DSA, | ||
603 | ASN1_PKEY_ALIAS | ||
604 | }, | ||
605 | |||
606 | { | ||
607 | EVP_PKEY_DSA1, | ||
608 | EVP_PKEY_DSA, | ||
609 | ASN1_PKEY_ALIAS | ||
610 | }, | ||
611 | |||
612 | { | ||
613 | EVP_PKEY_DSA4, | ||
614 | EVP_PKEY_DSA, | ||
615 | ASN1_PKEY_ALIAS | ||
616 | }, | ||
617 | |||
618 | { | ||
619 | EVP_PKEY_DSA3, | ||
620 | EVP_PKEY_DSA, | ||
621 | ASN1_PKEY_ALIAS | ||
622 | }, | ||
623 | |||
624 | { | ||
625 | EVP_PKEY_DSA, | ||
626 | EVP_PKEY_DSA, | ||
627 | 0, | ||
628 | |||
629 | "DSA", | ||
630 | "OpenSSL DSA method", | ||
631 | |||
632 | dsa_pub_decode, | ||
633 | dsa_pub_encode, | ||
634 | dsa_pub_cmp, | ||
635 | dsa_pub_print, | ||
636 | |||
637 | dsa_priv_decode, | ||
638 | dsa_priv_encode, | ||
639 | dsa_priv_print, | ||
640 | |||
641 | int_dsa_size, | ||
642 | dsa_bits, | ||
643 | |||
644 | dsa_param_decode, | ||
645 | dsa_param_encode, | ||
646 | dsa_missing_parameters, | ||
647 | dsa_copy_parameters, | ||
648 | dsa_cmp_parameters, | ||
649 | dsa_param_print, | ||
650 | |||
651 | int_dsa_free, | ||
652 | dsa_pkey_ctrl, | ||
653 | old_dsa_priv_decode, | ||
654 | old_dsa_priv_encode | ||
655 | } | ||
656 | }; | ||
657 | |||
diff --git a/src/lib/libcrypto/dsa/dsa_locl.h b/src/lib/libcrypto/dsa/dsa_locl.h new file mode 100644 index 0000000000..2b8cfee3db --- /dev/null +++ b/src/lib/libcrypto/dsa/dsa_locl.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2007 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in | ||
13 | * the documentation and/or other materials provided with the | ||
14 | * distribution. | ||
15 | * | ||
16 | * 3. All advertising materials mentioning features or use of this | ||
17 | * software must display the following acknowledgment: | ||
18 | * "This product includes software developed by the OpenSSL Project | ||
19 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
20 | * | ||
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
22 | * endorse or promote products derived from this software without | ||
23 | * prior written permission. For written permission, please contact | ||
24 | * openssl-core@openssl.org. | ||
25 | * | ||
26 | * 5. Products derived from this software may not be called "OpenSSL" | ||
27 | * nor may "OpenSSL" appear in their names without prior written | ||
28 | * permission of the OpenSSL Project. | ||
29 | * | ||
30 | * 6. Redistributions of any form whatsoever must retain the following | ||
31 | * acknowledgment: | ||
32 | * "This product includes software developed by the OpenSSL Project | ||
33 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
34 | * | ||
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
47 | * ==================================================================== | ||
48 | * | ||
49 | * This product includes cryptographic software written by Eric Young | ||
50 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
51 | * Hudson (tjh@cryptsoft.com). | ||
52 | * | ||
53 | */ | ||
54 | |||
55 | #include <openssl/dsa.h> | ||
56 | |||
57 | int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, | ||
58 | const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, | ||
59 | int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); | ||
diff --git a/src/lib/libcrypto/dsa/dsa_pmeth.c b/src/lib/libcrypto/dsa/dsa_pmeth.c new file mode 100644 index 0000000000..4ce91e20c6 --- /dev/null +++ b/src/lib/libcrypto/dsa/dsa_pmeth.c | |||
@@ -0,0 +1,315 @@ | |||
1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
2 | * project 2006. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <stdio.h> | ||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/asn1t.h> | ||
61 | #include <openssl/x509.h> | ||
62 | #include <openssl/evp.h> | ||
63 | #include <openssl/bn.h> | ||
64 | #include "evp_locl.h" | ||
65 | #include "dsa_locl.h" | ||
66 | |||
67 | /* DSA pkey context structure */ | ||
68 | |||
69 | typedef struct | ||
70 | { | ||
71 | /* Parameter gen parameters */ | ||
72 | int nbits; /* size of p in bits (default: 1024) */ | ||
73 | int qbits; /* size of q in bits (default: 160) */ | ||
74 | const EVP_MD *pmd; /* MD for parameter generation */ | ||
75 | /* Keygen callback info */ | ||
76 | int gentmp[2]; | ||
77 | /* message digest */ | ||
78 | const EVP_MD *md; /* MD for the signature */ | ||
79 | } DSA_PKEY_CTX; | ||
80 | |||
81 | static int pkey_dsa_init(EVP_PKEY_CTX *ctx) | ||
82 | { | ||
83 | DSA_PKEY_CTX *dctx; | ||
84 | dctx = OPENSSL_malloc(sizeof(DSA_PKEY_CTX)); | ||
85 | if (!dctx) | ||
86 | return 0; | ||
87 | dctx->nbits = 1024; | ||
88 | dctx->qbits = 160; | ||
89 | dctx->pmd = NULL; | ||
90 | dctx->md = NULL; | ||
91 | |||
92 | ctx->data = dctx; | ||
93 | ctx->keygen_info = dctx->gentmp; | ||
94 | ctx->keygen_info_count = 2; | ||
95 | |||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | ||
100 | { | ||
101 | DSA_PKEY_CTX *dctx, *sctx; | ||
102 | if (!pkey_dsa_init(dst)) | ||
103 | return 0; | ||
104 | sctx = src->data; | ||
105 | dctx = dst->data; | ||
106 | dctx->nbits = sctx->nbits; | ||
107 | dctx->qbits = sctx->qbits; | ||
108 | dctx->pmd = sctx->pmd; | ||
109 | dctx->md = sctx->md; | ||
110 | return 1; | ||
111 | } | ||
112 | |||
113 | static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) | ||
114 | { | ||
115 | DSA_PKEY_CTX *dctx = ctx->data; | ||
116 | if (dctx) | ||
117 | OPENSSL_free(dctx); | ||
118 | } | ||
119 | |||
120 | static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, | ||
121 | const unsigned char *tbs, size_t tbslen) | ||
122 | { | ||
123 | int ret, type; | ||
124 | unsigned int sltmp; | ||
125 | DSA_PKEY_CTX *dctx = ctx->data; | ||
126 | DSA *dsa = ctx->pkey->pkey.dsa; | ||
127 | |||
128 | if (dctx->md) | ||
129 | type = EVP_MD_type(dctx->md); | ||
130 | else | ||
131 | type = NID_sha1; | ||
132 | |||
133 | ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa); | ||
134 | |||
135 | if (ret <= 0) | ||
136 | return ret; | ||
137 | *siglen = sltmp; | ||
138 | return 1; | ||
139 | } | ||
140 | |||
141 | static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, | ||
142 | const unsigned char *sig, size_t siglen, | ||
143 | const unsigned char *tbs, size_t tbslen) | ||
144 | { | ||
145 | int ret, type; | ||
146 | DSA_PKEY_CTX *dctx = ctx->data; | ||
147 | DSA *dsa = ctx->pkey->pkey.dsa; | ||
148 | |||
149 | if (dctx->md) | ||
150 | type = EVP_MD_type(dctx->md); | ||
151 | else | ||
152 | type = NID_sha1; | ||
153 | |||
154 | ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa); | ||
155 | |||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | ||
160 | { | ||
161 | DSA_PKEY_CTX *dctx = ctx->data; | ||
162 | switch (type) | ||
163 | { | ||
164 | case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: | ||
165 | if (p1 < 256) | ||
166 | return -2; | ||
167 | dctx->nbits = p1; | ||
168 | return 1; | ||
169 | |||
170 | case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: | ||
171 | if (p1 != 160 && p1 != 224 && p1 && p1 != 256) | ||
172 | return -2; | ||
173 | dctx->qbits = p1; | ||
174 | return 1; | ||
175 | |||
176 | case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: | ||
177 | if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && | ||
178 | EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && | ||
179 | EVP_MD_type((const EVP_MD *)p2) != NID_sha256) | ||
180 | { | ||
181 | DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); | ||
182 | return 0; | ||
183 | } | ||
184 | dctx->md = p2; | ||
185 | return 1; | ||
186 | |||
187 | case EVP_PKEY_CTRL_MD: | ||
188 | if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && | ||
189 | EVP_MD_type((const EVP_MD *)p2) != NID_dsa && | ||
190 | EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && | ||
191 | EVP_MD_type((const EVP_MD *)p2) != NID_sha256) | ||
192 | { | ||
193 | DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); | ||
194 | return 0; | ||
195 | } | ||
196 | dctx->md = p2; | ||
197 | return 1; | ||
198 | |||
199 | case EVP_PKEY_CTRL_DIGESTINIT: | ||
200 | case EVP_PKEY_CTRL_PKCS7_SIGN: | ||
201 | case EVP_PKEY_CTRL_CMS_SIGN: | ||
202 | return 1; | ||
203 | |||
204 | case EVP_PKEY_CTRL_PEER_KEY: | ||
205 | DSAerr(DSA_F_PKEY_DSA_CTRL, | ||
206 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
207 | return -2; | ||
208 | default: | ||
209 | return -2; | ||
210 | |||
211 | } | ||
212 | } | ||
213 | |||
214 | static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, | ||
215 | const char *type, const char *value) | ||
216 | { | ||
217 | if (!strcmp(type, "dsa_paramgen_bits")) | ||
218 | { | ||
219 | int nbits; | ||
220 | nbits = atoi(value); | ||
221 | return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); | ||
222 | } | ||
223 | if (!strcmp(type, "dsa_paramgen_q_bits")) | ||
224 | { | ||
225 | int qbits = atoi(value); | ||
226 | return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, | ||
227 | EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL); | ||
228 | } | ||
229 | if (!strcmp(type, "dsa_paramgen_md")) | ||
230 | { | ||
231 | return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, | ||
232 | EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, | ||
233 | (void *)EVP_get_digestbyname(value)); | ||
234 | } | ||
235 | return -2; | ||
236 | } | ||
237 | |||
238 | static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
239 | { | ||
240 | DSA *dsa = NULL; | ||
241 | DSA_PKEY_CTX *dctx = ctx->data; | ||
242 | BN_GENCB *pcb, cb; | ||
243 | int ret; | ||
244 | if (ctx->pkey_gencb) | ||
245 | { | ||
246 | pcb = &cb; | ||
247 | evp_pkey_set_cb_translate(pcb, ctx); | ||
248 | } | ||
249 | else | ||
250 | pcb = NULL; | ||
251 | dsa = DSA_new(); | ||
252 | if (!dsa) | ||
253 | return 0; | ||
254 | ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, | ||
255 | NULL, 0, NULL, NULL, pcb); | ||
256 | if (ret) | ||
257 | EVP_PKEY_assign_DSA(pkey, dsa); | ||
258 | else | ||
259 | DSA_free(dsa); | ||
260 | return ret; | ||
261 | } | ||
262 | |||
263 | static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
264 | { | ||
265 | DSA *dsa = NULL; | ||
266 | if (ctx->pkey == NULL) | ||
267 | { | ||
268 | DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET); | ||
269 | return 0; | ||
270 | } | ||
271 | dsa = DSA_new(); | ||
272 | if (!dsa) | ||
273 | return 0; | ||
274 | EVP_PKEY_assign_DSA(pkey, dsa); | ||
275 | /* Note: if error return, pkey is freed by parent routine */ | ||
276 | if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) | ||
277 | return 0; | ||
278 | return DSA_generate_key(pkey->pkey.dsa); | ||
279 | } | ||
280 | |||
281 | const EVP_PKEY_METHOD dsa_pkey_meth = | ||
282 | { | ||
283 | EVP_PKEY_DSA, | ||
284 | EVP_PKEY_FLAG_AUTOARGLEN, | ||
285 | pkey_dsa_init, | ||
286 | pkey_dsa_copy, | ||
287 | pkey_dsa_cleanup, | ||
288 | |||
289 | 0, | ||
290 | pkey_dsa_paramgen, | ||
291 | |||
292 | 0, | ||
293 | pkey_dsa_keygen, | ||
294 | |||
295 | 0, | ||
296 | pkey_dsa_sign, | ||
297 | |||
298 | 0, | ||
299 | pkey_dsa_verify, | ||
300 | |||
301 | 0,0, | ||
302 | |||
303 | 0,0,0,0, | ||
304 | |||
305 | 0,0, | ||
306 | |||
307 | 0,0, | ||
308 | |||
309 | 0,0, | ||
310 | |||
311 | pkey_dsa_ctrl, | ||
312 | pkey_dsa_ctrl_str | ||
313 | |||
314 | |||
315 | }; | ||
diff --git a/src/lib/libcrypto/dsa/dsa_prn.c b/src/lib/libcrypto/dsa/dsa_prn.c new file mode 100644 index 0000000000..6f29f5e240 --- /dev/null +++ b/src/lib/libcrypto/dsa/dsa_prn.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* crypto/dsa/dsa_prn.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2006. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/evp.h> | ||
62 | #include <openssl/dsa.h> | ||
63 | |||
64 | #ifndef OPENSSL_NO_FP_API | ||
65 | int DSA_print_fp(FILE *fp, const DSA *x, int off) | ||
66 | { | ||
67 | BIO *b; | ||
68 | int ret; | ||
69 | |||
70 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
71 | { | ||
72 | DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB); | ||
73 | return(0); | ||
74 | } | ||
75 | BIO_set_fp(b,fp,BIO_NOCLOSE); | ||
76 | ret=DSA_print(b,x,off); | ||
77 | BIO_free(b); | ||
78 | return(ret); | ||
79 | } | ||
80 | |||
81 | int DSAparams_print_fp(FILE *fp, const DSA *x) | ||
82 | { | ||
83 | BIO *b; | ||
84 | int ret; | ||
85 | |||
86 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
87 | { | ||
88 | DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB); | ||
89 | return(0); | ||
90 | } | ||
91 | BIO_set_fp(b,fp,BIO_NOCLOSE); | ||
92 | ret=DSAparams_print(b, x); | ||
93 | BIO_free(b); | ||
94 | return(ret); | ||
95 | } | ||
96 | #endif | ||
97 | |||
98 | int DSA_print(BIO *bp, const DSA *x, int off) | ||
99 | { | ||
100 | EVP_PKEY *pk; | ||
101 | int ret; | ||
102 | pk = EVP_PKEY_new(); | ||
103 | if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) | ||
104 | return 0; | ||
105 | ret = EVP_PKEY_print_private(bp, pk, off, NULL); | ||
106 | EVP_PKEY_free(pk); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | int DSAparams_print(BIO *bp, const DSA *x) | ||
111 | { | ||
112 | EVP_PKEY *pk; | ||
113 | int ret; | ||
114 | pk = EVP_PKEY_new(); | ||
115 | if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) | ||
116 | return 0; | ||
117 | ret = EVP_PKEY_print_params(bp, pk, 4, NULL); | ||
118 | EVP_PKEY_free(pk); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c index ff368fd7d7..ab631a50a2 100644 --- a/src/lib/libcrypto/ec/ec2_mult.c +++ b/src/lib/libcrypto/ec/ec2_mult.c | |||
@@ -76,7 +76,7 @@ | |||
76 | * coordinates. | 76 | * coordinates. |
77 | * Uses algorithm Mdouble in appendix of | 77 | * Uses algorithm Mdouble in appendix of |
78 | * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over | 78 | * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over |
79 | * GF(2^m) without precomputation". | 79 | * GF(2^m) without precomputation" (CHES '99, LNCS 1717). |
80 | * modified to not require precomputation of c=b^{2^{m-1}}. | 80 | * modified to not require precomputation of c=b^{2^{m-1}}. |
81 | */ | 81 | */ |
82 | static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx) | 82 | static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx) |
@@ -107,8 +107,8 @@ static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx | |||
107 | /* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery | 107 | /* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery |
108 | * projective coordinates. | 108 | * projective coordinates. |
109 | * Uses algorithm Madd in appendix of | 109 | * Uses algorithm Madd in appendix of |
110 | * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over | 110 | * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over |
111 | * GF(2^m) without precomputation". | 111 | * GF(2^m) without precomputation" (CHES '99, LNCS 1717). |
112 | */ | 112 | */ |
113 | static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1, | 113 | static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1, |
114 | const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx) | 114 | const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx) |
@@ -140,8 +140,8 @@ static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM | |||
140 | 140 | ||
141 | /* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) | 141 | /* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) |
142 | * using Montgomery point multiplication algorithm Mxy() in appendix of | 142 | * using Montgomery point multiplication algorithm Mxy() in appendix of |
143 | * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over | 143 | * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over |
144 | * GF(2^m) without precomputation". | 144 | * GF(2^m) without precomputation" (CHES '99, LNCS 1717). |
145 | * Returns: | 145 | * Returns: |
146 | * 0 on error | 146 | * 0 on error |
147 | * 1 if return value should be the point at infinity | 147 | * 1 if return value should be the point at infinity |
@@ -209,15 +209,15 @@ static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIG | |||
209 | /* Computes scalar*point and stores the result in r. | 209 | /* Computes scalar*point and stores the result in r. |
210 | * point can not equal r. | 210 | * point can not equal r. |
211 | * Uses algorithm 2P of | 211 | * Uses algorithm 2P of |
212 | * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over | 212 | * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over |
213 | * GF(2^m) without precomputation". | 213 | * GF(2^m) without precomputation" (CHES '99, LNCS 1717). |
214 | */ | 214 | */ |
215 | static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | 215 | static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, |
216 | const EC_POINT *point, BN_CTX *ctx) | 216 | const EC_POINT *point, BN_CTX *ctx) |
217 | { | 217 | { |
218 | BIGNUM *x1, *x2, *z1, *z2; | 218 | BIGNUM *x1, *x2, *z1, *z2; |
219 | int ret = 0, i, j; | 219 | int ret = 0, i; |
220 | BN_ULONG mask; | 220 | BN_ULONG mask,word; |
221 | 221 | ||
222 | if (r == point) | 222 | if (r == point) |
223 | { | 223 | { |
@@ -251,22 +251,24 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, | |||
251 | if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */ | 251 | if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */ |
252 | 252 | ||
253 | /* find top most bit and go one past it */ | 253 | /* find top most bit and go one past it */ |
254 | i = scalar->top - 1; j = BN_BITS2 - 1; | 254 | i = scalar->top - 1; |
255 | mask = BN_TBIT; | 255 | mask = BN_TBIT; |
256 | while (!(scalar->d[i] & mask)) { mask >>= 1; j--; } | 256 | word = scalar->d[i]; |
257 | mask >>= 1; j--; | 257 | while (!(word & mask)) mask >>= 1; |
258 | mask >>= 1; | ||
258 | /* if top most bit was at word break, go to next word */ | 259 | /* if top most bit was at word break, go to next word */ |
259 | if (!mask) | 260 | if (!mask) |
260 | { | 261 | { |
261 | i--; j = BN_BITS2 - 1; | 262 | i--; |
262 | mask = BN_TBIT; | 263 | mask = BN_TBIT; |
263 | } | 264 | } |
264 | 265 | ||
265 | for (; i >= 0; i--) | 266 | for (; i >= 0; i--) |
266 | { | 267 | { |
267 | for (; j >= 0; j--) | 268 | word = scalar->d[i]; |
269 | while (mask) | ||
268 | { | 270 | { |
269 | if (scalar->d[i] & mask) | 271 | if (word & mask) |
270 | { | 272 | { |
271 | if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; | 273 | if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; |
272 | if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; | 274 | if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; |
@@ -278,7 +280,6 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, | |||
278 | } | 280 | } |
279 | mask >>= 1; | 281 | mask >>= 1; |
280 | } | 282 | } |
281 | j = BN_BITS2 - 1; | ||
282 | mask = BN_TBIT; | 283 | mask = BN_TBIT; |
283 | } | 284 | } |
284 | 285 | ||
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c new file mode 100644 index 0000000000..c00f7d746c --- /dev/null +++ b/src/lib/libcrypto/ec/ec_ameth.c | |||
@@ -0,0 +1,659 @@ | |||
1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
2 | * project 2006. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <stdio.h> | ||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/x509.h> | ||
61 | #include <openssl/ec.h> | ||
62 | #include <openssl/bn.h> | ||
63 | #ifndef OPENSSL_NO_CMS | ||
64 | #include <openssl/cms.h> | ||
65 | #endif | ||
66 | #include "asn1_locl.h" | ||
67 | |||
68 | static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) | ||
69 | { | ||
70 | const EC_GROUP *group; | ||
71 | int nid; | ||
72 | if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) | ||
73 | { | ||
74 | ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); | ||
75 | return 0; | ||
76 | } | ||
77 | if (EC_GROUP_get_asn1_flag(group) | ||
78 | && (nid = EC_GROUP_get_curve_name(group))) | ||
79 | /* we have a 'named curve' => just set the OID */ | ||
80 | { | ||
81 | *ppval = OBJ_nid2obj(nid); | ||
82 | *pptype = V_ASN1_OBJECT; | ||
83 | } | ||
84 | else /* explicit parameters */ | ||
85 | { | ||
86 | ASN1_STRING *pstr = NULL; | ||
87 | pstr = ASN1_STRING_new(); | ||
88 | if (!pstr) | ||
89 | return 0; | ||
90 | pstr->length = i2d_ECParameters(ec_key, &pstr->data); | ||
91 | if (pstr->length < 0) | ||
92 | { | ||
93 | ASN1_STRING_free(pstr); | ||
94 | ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); | ||
95 | return 0; | ||
96 | } | ||
97 | *ppval = pstr; | ||
98 | *pptype = V_ASN1_SEQUENCE; | ||
99 | } | ||
100 | return 1; | ||
101 | } | ||
102 | |||
103 | static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) | ||
104 | { | ||
105 | EC_KEY *ec_key = pkey->pkey.ec; | ||
106 | void *pval = NULL; | ||
107 | int ptype; | ||
108 | unsigned char *penc = NULL, *p; | ||
109 | int penclen; | ||
110 | |||
111 | if (!eckey_param2type(&ptype, &pval, ec_key)) | ||
112 | { | ||
113 | ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); | ||
114 | return 0; | ||
115 | } | ||
116 | penclen = i2o_ECPublicKey(ec_key, NULL); | ||
117 | if (penclen <= 0) | ||
118 | goto err; | ||
119 | penc = OPENSSL_malloc(penclen); | ||
120 | if (!penc) | ||
121 | goto err; | ||
122 | p = penc; | ||
123 | penclen = i2o_ECPublicKey(ec_key, &p); | ||
124 | if (penclen <= 0) | ||
125 | goto err; | ||
126 | if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), | ||
127 | ptype, pval, penc, penclen)) | ||
128 | return 1; | ||
129 | err: | ||
130 | if (ptype == V_ASN1_OBJECT) | ||
131 | ASN1_OBJECT_free(pval); | ||
132 | else | ||
133 | ASN1_STRING_free(pval); | ||
134 | if (penc) | ||
135 | OPENSSL_free(penc); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static EC_KEY *eckey_type2param(int ptype, void *pval) | ||
140 | { | ||
141 | EC_KEY *eckey = NULL; | ||
142 | if (ptype == V_ASN1_SEQUENCE) | ||
143 | { | ||
144 | ASN1_STRING *pstr = pval; | ||
145 | const unsigned char *pm = NULL; | ||
146 | int pmlen; | ||
147 | pm = pstr->data; | ||
148 | pmlen = pstr->length; | ||
149 | if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) | ||
150 | { | ||
151 | ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); | ||
152 | goto ecerr; | ||
153 | } | ||
154 | } | ||
155 | else if (ptype == V_ASN1_OBJECT) | ||
156 | { | ||
157 | ASN1_OBJECT *poid = pval; | ||
158 | EC_GROUP *group; | ||
159 | |||
160 | /* type == V_ASN1_OBJECT => the parameters are given | ||
161 | * by an asn1 OID | ||
162 | */ | ||
163 | if ((eckey = EC_KEY_new()) == NULL) | ||
164 | { | ||
165 | ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); | ||
166 | goto ecerr; | ||
167 | } | ||
168 | group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); | ||
169 | if (group == NULL) | ||
170 | goto ecerr; | ||
171 | EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); | ||
172 | if (EC_KEY_set_group(eckey, group) == 0) | ||
173 | goto ecerr; | ||
174 | EC_GROUP_free(group); | ||
175 | } | ||
176 | else | ||
177 | { | ||
178 | ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); | ||
179 | goto ecerr; | ||
180 | } | ||
181 | |||
182 | return eckey; | ||
183 | |||
184 | ecerr: | ||
185 | if (eckey) | ||
186 | EC_KEY_free(eckey); | ||
187 | return NULL; | ||
188 | } | ||
189 | |||
190 | static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) | ||
191 | { | ||
192 | const unsigned char *p = NULL; | ||
193 | void *pval; | ||
194 | int ptype, pklen; | ||
195 | EC_KEY *eckey = NULL; | ||
196 | X509_ALGOR *palg; | ||
197 | |||
198 | if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) | ||
199 | return 0; | ||
200 | X509_ALGOR_get0(NULL, &ptype, &pval, palg); | ||
201 | |||
202 | eckey = eckey_type2param(ptype, pval); | ||
203 | |||
204 | if (!eckey) | ||
205 | { | ||
206 | ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | /* We have parameters now set public key */ | ||
211 | if (!o2i_ECPublicKey(&eckey, &p, pklen)) | ||
212 | { | ||
213 | ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); | ||
214 | goto ecerr; | ||
215 | } | ||
216 | |||
217 | EVP_PKEY_assign_EC_KEY(pkey, eckey); | ||
218 | return 1; | ||
219 | |||
220 | ecerr: | ||
221 | if (eckey) | ||
222 | EC_KEY_free(eckey); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) | ||
227 | { | ||
228 | int r; | ||
229 | const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); | ||
230 | const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), | ||
231 | *pb = EC_KEY_get0_public_key(b->pkey.ec); | ||
232 | r = EC_POINT_cmp(group, pa, pb, NULL); | ||
233 | if (r == 0) | ||
234 | return 1; | ||
235 | if (r == 1) | ||
236 | return 0; | ||
237 | return -2; | ||
238 | } | ||
239 | |||
240 | static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) | ||
241 | { | ||
242 | const unsigned char *p = NULL; | ||
243 | void *pval; | ||
244 | int ptype, pklen; | ||
245 | EC_KEY *eckey = NULL; | ||
246 | X509_ALGOR *palg; | ||
247 | |||
248 | if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) | ||
249 | return 0; | ||
250 | X509_ALGOR_get0(NULL, &ptype, &pval, palg); | ||
251 | |||
252 | eckey = eckey_type2param(ptype, pval); | ||
253 | |||
254 | if (!eckey) | ||
255 | goto ecliberr; | ||
256 | |||
257 | /* We have parameters now set private key */ | ||
258 | if (!d2i_ECPrivateKey(&eckey, &p, pklen)) | ||
259 | { | ||
260 | ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); | ||
261 | goto ecerr; | ||
262 | } | ||
263 | |||
264 | /* calculate public key (if necessary) */ | ||
265 | if (EC_KEY_get0_public_key(eckey) == NULL) | ||
266 | { | ||
267 | const BIGNUM *priv_key; | ||
268 | const EC_GROUP *group; | ||
269 | EC_POINT *pub_key; | ||
270 | /* the public key was not included in the SEC1 private | ||
271 | * key => calculate the public key */ | ||
272 | group = EC_KEY_get0_group(eckey); | ||
273 | pub_key = EC_POINT_new(group); | ||
274 | if (pub_key == NULL) | ||
275 | { | ||
276 | ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); | ||
277 | goto ecliberr; | ||
278 | } | ||
279 | if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) | ||
280 | { | ||
281 | EC_POINT_free(pub_key); | ||
282 | ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); | ||
283 | goto ecliberr; | ||
284 | } | ||
285 | priv_key = EC_KEY_get0_private_key(eckey); | ||
286 | if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) | ||
287 | { | ||
288 | EC_POINT_free(pub_key); | ||
289 | ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); | ||
290 | goto ecliberr; | ||
291 | } | ||
292 | if (EC_KEY_set_public_key(eckey, pub_key) == 0) | ||
293 | { | ||
294 | EC_POINT_free(pub_key); | ||
295 | ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); | ||
296 | goto ecliberr; | ||
297 | } | ||
298 | EC_POINT_free(pub_key); | ||
299 | } | ||
300 | |||
301 | EVP_PKEY_assign_EC_KEY(pkey, eckey); | ||
302 | return 1; | ||
303 | |||
304 | ecliberr: | ||
305 | ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); | ||
306 | ecerr: | ||
307 | if (eckey) | ||
308 | EC_KEY_free(eckey); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) | ||
313 | { | ||
314 | EC_KEY *ec_key; | ||
315 | unsigned char *ep, *p; | ||
316 | int eplen, ptype; | ||
317 | void *pval; | ||
318 | unsigned int tmp_flags, old_flags; | ||
319 | |||
320 | ec_key = pkey->pkey.ec; | ||
321 | |||
322 | if (!eckey_param2type(&ptype, &pval, ec_key)) | ||
323 | { | ||
324 | ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | /* set the private key */ | ||
329 | |||
330 | /* do not include the parameters in the SEC1 private key | ||
331 | * see PKCS#11 12.11 */ | ||
332 | old_flags = EC_KEY_get_enc_flags(ec_key); | ||
333 | tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; | ||
334 | EC_KEY_set_enc_flags(ec_key, tmp_flags); | ||
335 | eplen = i2d_ECPrivateKey(ec_key, NULL); | ||
336 | if (!eplen) | ||
337 | { | ||
338 | EC_KEY_set_enc_flags(ec_key, old_flags); | ||
339 | ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); | ||
340 | return 0; | ||
341 | } | ||
342 | ep = (unsigned char *) OPENSSL_malloc(eplen); | ||
343 | if (!ep) | ||
344 | { | ||
345 | EC_KEY_set_enc_flags(ec_key, old_flags); | ||
346 | ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); | ||
347 | return 0; | ||
348 | } | ||
349 | p = ep; | ||
350 | if (!i2d_ECPrivateKey(ec_key, &p)) | ||
351 | { | ||
352 | EC_KEY_set_enc_flags(ec_key, old_flags); | ||
353 | OPENSSL_free(ep); | ||
354 | ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); | ||
355 | } | ||
356 | /* restore old encoding flags */ | ||
357 | EC_KEY_set_enc_flags(ec_key, old_flags); | ||
358 | |||
359 | if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, | ||
360 | ptype, pval, ep, eplen)) | ||
361 | return 0; | ||
362 | |||
363 | return 1; | ||
364 | } | ||
365 | |||
366 | static int int_ec_size(const EVP_PKEY *pkey) | ||
367 | { | ||
368 | return ECDSA_size(pkey->pkey.ec); | ||
369 | } | ||
370 | |||
371 | static int ec_bits(const EVP_PKEY *pkey) | ||
372 | { | ||
373 | BIGNUM *order = BN_new(); | ||
374 | const EC_GROUP *group; | ||
375 | int ret; | ||
376 | |||
377 | if (!order) | ||
378 | { | ||
379 | ERR_clear_error(); | ||
380 | return 0; | ||
381 | } | ||
382 | group = EC_KEY_get0_group(pkey->pkey.ec); | ||
383 | if (!EC_GROUP_get_order(group, order, NULL)) | ||
384 | { | ||
385 | ERR_clear_error(); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | ret = BN_num_bits(order); | ||
390 | BN_free(order); | ||
391 | return ret; | ||
392 | } | ||
393 | |||
394 | static int ec_missing_parameters(const EVP_PKEY *pkey) | ||
395 | { | ||
396 | if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) | ||
397 | return 1; | ||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) | ||
402 | { | ||
403 | EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); | ||
404 | if (group == NULL) | ||
405 | return 0; | ||
406 | if (EC_KEY_set_group(to->pkey.ec, group) == 0) | ||
407 | return 0; | ||
408 | EC_GROUP_free(group); | ||
409 | return 1; | ||
410 | } | ||
411 | |||
412 | static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) | ||
413 | { | ||
414 | const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), | ||
415 | *group_b = EC_KEY_get0_group(b->pkey.ec); | ||
416 | if (EC_GROUP_cmp(group_a, group_b, NULL)) | ||
417 | return 0; | ||
418 | else | ||
419 | return 1; | ||
420 | } | ||
421 | |||
422 | static void int_ec_free(EVP_PKEY *pkey) | ||
423 | { | ||
424 | EC_KEY_free(pkey->pkey.ec); | ||
425 | } | ||
426 | |||
427 | static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) | ||
428 | { | ||
429 | unsigned char *buffer=NULL; | ||
430 | const char *ecstr; | ||
431 | size_t buf_len=0, i; | ||
432 | int ret=0, reason=ERR_R_BIO_LIB; | ||
433 | BIGNUM *pub_key=NULL, *order=NULL; | ||
434 | BN_CTX *ctx=NULL; | ||
435 | const EC_GROUP *group; | ||
436 | const EC_POINT *public_key; | ||
437 | const BIGNUM *priv_key; | ||
438 | |||
439 | if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) | ||
440 | { | ||
441 | reason = ERR_R_PASSED_NULL_PARAMETER; | ||
442 | goto err; | ||
443 | } | ||
444 | |||
445 | ctx = BN_CTX_new(); | ||
446 | if (ctx == NULL) | ||
447 | { | ||
448 | reason = ERR_R_MALLOC_FAILURE; | ||
449 | goto err; | ||
450 | } | ||
451 | |||
452 | if (ktype > 0) | ||
453 | { | ||
454 | public_key = EC_KEY_get0_public_key(x); | ||
455 | if ((pub_key = EC_POINT_point2bn(group, public_key, | ||
456 | EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) | ||
457 | { | ||
458 | reason = ERR_R_EC_LIB; | ||
459 | goto err; | ||
460 | } | ||
461 | if (pub_key) | ||
462 | buf_len = (size_t)BN_num_bytes(pub_key); | ||
463 | } | ||
464 | |||
465 | if (ktype == 2) | ||
466 | { | ||
467 | priv_key = EC_KEY_get0_private_key(x); | ||
468 | if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) | ||
469 | buf_len = i; | ||
470 | } | ||
471 | else | ||
472 | priv_key = NULL; | ||
473 | |||
474 | if (ktype > 0) | ||
475 | { | ||
476 | buf_len += 10; | ||
477 | if ((buffer = OPENSSL_malloc(buf_len)) == NULL) | ||
478 | { | ||
479 | reason = ERR_R_MALLOC_FAILURE; | ||
480 | goto err; | ||
481 | } | ||
482 | } | ||
483 | if (ktype == 2) | ||
484 | ecstr = "Private-Key"; | ||
485 | else if (ktype == 1) | ||
486 | ecstr = "Public-Key"; | ||
487 | else | ||
488 | ecstr = "ECDSA-Parameters"; | ||
489 | |||
490 | if (!BIO_indent(bp, off, 128)) | ||
491 | goto err; | ||
492 | if ((order = BN_new()) == NULL) | ||
493 | goto err; | ||
494 | if (!EC_GROUP_get_order(group, order, NULL)) | ||
495 | goto err; | ||
496 | if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, | ||
497 | BN_num_bits(order)) <= 0) goto err; | ||
498 | |||
499 | if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, | ||
500 | buffer, off)) | ||
501 | goto err; | ||
502 | if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, | ||
503 | buffer, off)) | ||
504 | goto err; | ||
505 | if (!ECPKParameters_print(bp, group, off)) | ||
506 | goto err; | ||
507 | ret=1; | ||
508 | err: | ||
509 | if (!ret) | ||
510 | ECerr(EC_F_DO_EC_KEY_PRINT, reason); | ||
511 | if (pub_key) | ||
512 | BN_free(pub_key); | ||
513 | if (order) | ||
514 | BN_free(order); | ||
515 | if (ctx) | ||
516 | BN_CTX_free(ctx); | ||
517 | if (buffer != NULL) | ||
518 | OPENSSL_free(buffer); | ||
519 | return(ret); | ||
520 | } | ||
521 | |||
522 | static int eckey_param_decode(EVP_PKEY *pkey, | ||
523 | const unsigned char **pder, int derlen) | ||
524 | { | ||
525 | EC_KEY *eckey; | ||
526 | if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) | ||
527 | { | ||
528 | ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); | ||
529 | return 0; | ||
530 | } | ||
531 | EVP_PKEY_assign_EC_KEY(pkey, eckey); | ||
532 | return 1; | ||
533 | } | ||
534 | |||
535 | static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) | ||
536 | { | ||
537 | return i2d_ECParameters(pkey->pkey.ec, pder); | ||
538 | } | ||
539 | |||
540 | static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
541 | ASN1_PCTX *ctx) | ||
542 | { | ||
543 | return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); | ||
544 | } | ||
545 | |||
546 | static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
547 | ASN1_PCTX *ctx) | ||
548 | { | ||
549 | return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); | ||
550 | } | ||
551 | |||
552 | |||
553 | static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
554 | ASN1_PCTX *ctx) | ||
555 | { | ||
556 | return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); | ||
557 | } | ||
558 | |||
559 | static int old_ec_priv_decode(EVP_PKEY *pkey, | ||
560 | const unsigned char **pder, int derlen) | ||
561 | { | ||
562 | EC_KEY *ec; | ||
563 | if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen))) | ||
564 | { | ||
565 | ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); | ||
566 | return 0; | ||
567 | } | ||
568 | EVP_PKEY_assign_EC_KEY(pkey, ec); | ||
569 | return 1; | ||
570 | } | ||
571 | |||
572 | static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) | ||
573 | { | ||
574 | return i2d_ECPrivateKey(pkey->pkey.ec, pder); | ||
575 | } | ||
576 | |||
577 | static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | ||
578 | { | ||
579 | switch (op) | ||
580 | { | ||
581 | case ASN1_PKEY_CTRL_PKCS7_SIGN: | ||
582 | if (arg1 == 0) | ||
583 | { | ||
584 | int snid, hnid; | ||
585 | X509_ALGOR *alg1, *alg2; | ||
586 | PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); | ||
587 | if (alg1 == NULL || alg1->algorithm == NULL) | ||
588 | return -1; | ||
589 | hnid = OBJ_obj2nid(alg1->algorithm); | ||
590 | if (hnid == NID_undef) | ||
591 | return -1; | ||
592 | if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) | ||
593 | return -1; | ||
594 | X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); | ||
595 | } | ||
596 | return 1; | ||
597 | #ifndef OPENSSL_NO_CMS | ||
598 | case ASN1_PKEY_CTRL_CMS_SIGN: | ||
599 | if (arg1 == 0) | ||
600 | { | ||
601 | int snid, hnid; | ||
602 | X509_ALGOR *alg1, *alg2; | ||
603 | CMS_SignerInfo_get0_algs(arg2, NULL, NULL, | ||
604 | &alg1, &alg2); | ||
605 | if (alg1 == NULL || alg1->algorithm == NULL) | ||
606 | return -1; | ||
607 | hnid = OBJ_obj2nid(alg1->algorithm); | ||
608 | if (hnid == NID_undef) | ||
609 | return -1; | ||
610 | if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) | ||
611 | return -1; | ||
612 | X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); | ||
613 | } | ||
614 | return 1; | ||
615 | #endif | ||
616 | |||
617 | case ASN1_PKEY_CTRL_DEFAULT_MD_NID: | ||
618 | *(int *)arg2 = NID_sha1; | ||
619 | return 2; | ||
620 | |||
621 | default: | ||
622 | return -2; | ||
623 | |||
624 | } | ||
625 | |||
626 | } | ||
627 | |||
628 | const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = | ||
629 | { | ||
630 | EVP_PKEY_EC, | ||
631 | EVP_PKEY_EC, | ||
632 | 0, | ||
633 | "EC", | ||
634 | "OpenSSL EC algorithm", | ||
635 | |||
636 | eckey_pub_decode, | ||
637 | eckey_pub_encode, | ||
638 | eckey_pub_cmp, | ||
639 | eckey_pub_print, | ||
640 | |||
641 | eckey_priv_decode, | ||
642 | eckey_priv_encode, | ||
643 | eckey_priv_print, | ||
644 | |||
645 | int_ec_size, | ||
646 | ec_bits, | ||
647 | |||
648 | eckey_param_decode, | ||
649 | eckey_param_encode, | ||
650 | ec_missing_parameters, | ||
651 | ec_copy_parameters, | ||
652 | ec_cmp_parameters, | ||
653 | eckey_param_print, | ||
654 | |||
655 | int_ec_free, | ||
656 | ec_pkey_ctrl, | ||
657 | old_ec_priv_decode, | ||
658 | old_ec_priv_encode | ||
659 | }; | ||
diff --git a/src/lib/libcrypto/ec/ec_curve.c b/src/lib/libcrypto/ec/ec_curve.c index beac20969b..23274e4031 100644 --- a/src/lib/libcrypto/ec/ec_curve.c +++ b/src/lib/libcrypto/ec/ec_curve.c | |||
@@ -73,926 +73,1690 @@ | |||
73 | #include <openssl/err.h> | 73 | #include <openssl/err.h> |
74 | #include <openssl/obj_mac.h> | 74 | #include <openssl/obj_mac.h> |
75 | 75 | ||
76 | typedef struct ec_curve_data_st { | 76 | typedef struct { |
77 | int field_type; /* either NID_X9_62_prime_field or | 77 | int field_type, /* either NID_X9_62_prime_field or |
78 | * NID_X9_62_characteristic_two_field */ | 78 | * NID_X9_62_characteristic_two_field */ |
79 | const char *p; /* either a prime number or a polynomial */ | 79 | seed_len, |
80 | const char *a; | 80 | param_len; |
81 | const char *b; | 81 | unsigned int cofactor; /* promoted to BN_ULONG */ |
82 | const char *x; /* the x coordinate of the generator */ | ||
83 | const char *y; /* the y coordinate of the generator */ | ||
84 | const char *order; /* the order of the group generated by the | ||
85 | * generator */ | ||
86 | const BN_ULONG cofactor;/* the cofactor */ | ||
87 | const unsigned char *seed;/* the seed (optional) */ | ||
88 | size_t seed_len; | ||
89 | const char *comment; /* a short description of the curve */ | ||
90 | } EC_CURVE_DATA; | 82 | } EC_CURVE_DATA; |
91 | 83 | ||
92 | /* the nist prime curves */ | 84 | /* the nist prime curves */ |
93 | static const unsigned char _EC_NIST_PRIME_192_SEED[] = { | 85 | static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } |
94 | 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57, | 86 | _EC_NIST_PRIME_192 = { |
95 | 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5}; | 87 | { NID_X9_62_prime_field,20,24,1 }, |
96 | static const EC_CURVE_DATA _EC_NIST_PRIME_192 = { | 88 | { 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57, /* seed */ |
97 | NID_X9_62_prime_field, | 89 | 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5, |
98 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", | 90 | |
99 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", | 91 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
100 | "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", | 92 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, |
101 | "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", | 93 | 0xFF,0xFF,0xFF,0xFF, |
102 | "07192b95ffc8da78631011ed6b24cdd573f977a11e794811", | 94 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
103 | "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",1, | 95 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, |
104 | _EC_NIST_PRIME_192_SEED, 20, | 96 | 0xFF,0xFF,0xFF,0xFC, |
105 | "NIST/X9.62/SECG curve over a 192 bit prime field" | 97 | 0x64,0x21,0x05,0x19,0xE5,0x9C,0x80,0xE7,0x0F,0xA7, /* b */ |
98 | 0xE9,0xAB,0x72,0x24,0x30,0x49,0xFE,0xB8,0xDE,0xEC, | ||
99 | 0xC1,0x46,0xB9,0xB1, | ||
100 | 0x18,0x8D,0xA8,0x0E,0xB0,0x30,0x90,0xF6,0x7C,0xBF, /* x */ | ||
101 | 0x20,0xEB,0x43,0xA1,0x88,0x00,0xF4,0xFF,0x0A,0xFD, | ||
102 | 0x82,0xFF,0x10,0x12, | ||
103 | 0x07,0x19,0x2b,0x95,0xff,0xc8,0xda,0x78,0x63,0x10, /* y */ | ||
104 | 0x11,0xed,0x6b,0x24,0xcd,0xd5,0x73,0xf9,0x77,0xa1, | ||
105 | 0x1e,0x79,0x48,0x11, | ||
106 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
107 | 0xFF,0xFF,0x99,0xDE,0xF8,0x36,0x14,0x6B,0xC9,0xB1, | ||
108 | 0xB4,0xD2,0x28,0x31 } | ||
106 | }; | 109 | }; |
107 | 110 | ||
108 | static const unsigned char _EC_NIST_PRIME_224_SEED[] = { | 111 | static const struct { EC_CURVE_DATA h; unsigned char data[20+28*6]; } |
109 | 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45, | 112 | _EC_NIST_PRIME_224 = { |
110 | 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5}; | 113 | { NID_X9_62_prime_field,20,28,1 }, |
111 | static const EC_CURVE_DATA _EC_NIST_PRIME_224 = { | 114 | { 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45, /* seed */ |
112 | NID_X9_62_prime_field, | 115 | 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5, |
113 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", | 116 | |
114 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", | 117 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
115 | "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", | 118 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, |
116 | "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", | 119 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
117 | "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", | 120 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
118 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",1, | 121 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, |
119 | _EC_NIST_PRIME_224_SEED, 20, | 122 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, |
120 | "NIST/SECG curve over a 224 bit prime field" | 123 | 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */ |
124 | 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA, | ||
125 | 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4, | ||
126 | 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */ | ||
127 | 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22, | ||
128 | 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21, | ||
129 | 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */ | ||
130 | 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64, | ||
131 | 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34, | ||
132 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
133 | 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E, | ||
134 | 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D } | ||
121 | }; | 135 | }; |
122 | 136 | ||
123 | static const unsigned char _EC_NIST_PRIME_384_SEED[] = { | 137 | static const struct { EC_CURVE_DATA h; unsigned char data[20+48*6]; } |
124 | 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00, | 138 | _EC_NIST_PRIME_384 = { |
125 | 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73}; | 139 | { NID_X9_62_prime_field,20,48,1 }, |
126 | static const EC_CURVE_DATA _EC_NIST_PRIME_384 = { | 140 | { 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00, /* seed */ |
127 | NID_X9_62_prime_field, | 141 | 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73, |
128 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF" | 142 | |
129 | "FFF0000000000000000FFFFFFFF", | 143 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
130 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF" | 144 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
131 | "FFF0000000000000000FFFFFFFC", | 145 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
132 | "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC6563" | 146 | 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, |
133 | "98D8A2ED19D2A85C8EDD3EC2AEF", | 147 | 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, |
134 | "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F" | 148 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
135 | "25DBF55296C3A545E3872760AB7", | 149 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
136 | "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b" | 150 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
137 | "1ce1d7e819d7a431d7c90ea0e5f", | 151 | 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, |
138 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0" | 152 | 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFC, |
139 | "DB248B0A77AECEC196ACCC52973",1, | 153 | 0xB3,0x31,0x2F,0xA7,0xE2,0x3E,0xE7,0xE4,0x98,0x8E, /* b */ |
140 | _EC_NIST_PRIME_384_SEED, 20, | 154 | 0x05,0x6B,0xE3,0xF8,0x2D,0x19,0x18,0x1D,0x9C,0x6E, |
141 | "NIST/SECG curve over a 384 bit prime field" | 155 | 0xFE,0x81,0x41,0x12,0x03,0x14,0x08,0x8F,0x50,0x13, |
156 | 0x87,0x5A,0xC6,0x56,0x39,0x8D,0x8A,0x2E,0xD1,0x9D, | ||
157 | 0x2A,0x85,0xC8,0xED,0xD3,0xEC,0x2A,0xEF, | ||
158 | 0xAA,0x87,0xCA,0x22,0xBE,0x8B,0x05,0x37,0x8E,0xB1, /* x */ | ||
159 | 0xC7,0x1E,0xF3,0x20,0xAD,0x74,0x6E,0x1D,0x3B,0x62, | ||
160 | 0x8B,0xA7,0x9B,0x98,0x59,0xF7,0x41,0xE0,0x82,0x54, | ||
161 | 0x2A,0x38,0x55,0x02,0xF2,0x5D,0xBF,0x55,0x29,0x6C, | ||
162 | 0x3A,0x54,0x5E,0x38,0x72,0x76,0x0A,0xB7, | ||
163 | 0x36,0x17,0xde,0x4a,0x96,0x26,0x2c,0x6f,0x5d,0x9e, /* y */ | ||
164 | 0x98,0xbf,0x92,0x92,0xdc,0x29,0xf8,0xf4,0x1d,0xbd, | ||
165 | 0x28,0x9a,0x14,0x7c,0xe9,0xda,0x31,0x13,0xb5,0xf0, | ||
166 | 0xb8,0xc0,0x0a,0x60,0xb1,0xce,0x1d,0x7e,0x81,0x9d, | ||
167 | 0x7a,0x43,0x1d,0x7c,0x90,0xea,0x0e,0x5f, | ||
168 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
169 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
170 | 0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x4D,0x81,0xF4,0x37, | ||
171 | 0x2D,0xDF,0x58,0x1A,0x0D,0xB2,0x48,0xB0,0xA7,0x7A, | ||
172 | 0xEC,0xEC,0x19,0x6A,0xCC,0xC5,0x29,0x73 } | ||
142 | }; | 173 | }; |
143 | 174 | ||
144 | static const unsigned char _EC_NIST_PRIME_521_SEED[] = { | 175 | static const struct { EC_CURVE_DATA h; unsigned char data[20+66*6]; } |
145 | 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC, | 176 | _EC_NIST_PRIME_521 = { |
146 | 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA}; | 177 | { NID_X9_62_prime_field,20,66,1 }, |
147 | static const EC_CURVE_DATA _EC_NIST_PRIME_521 = { | 178 | { 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC, /* seed */ |
148 | NID_X9_62_prime_field, | 179 | 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA, |
149 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | 180 | |
150 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | 181 | 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
151 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | 182 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
152 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", | 183 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
153 | "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156" | 184 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
154 | "193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", | 185 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
155 | "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14" | 186 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
156 | "B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", | 187 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
157 | "011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c9" | 188 | 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
158 | "7ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", | 189 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
159 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51" | 190 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
160 | "868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",1, | 191 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
161 | _EC_NIST_PRIME_521_SEED, 20, | 192 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
162 | "NIST/SECG curve over a 521 bit prime field" | 193 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
194 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC, | ||
195 | 0x00,0x51,0x95,0x3E,0xB9,0x61,0x8E,0x1C,0x9A,0x1F, /* b */ | ||
196 | 0x92,0x9A,0x21,0xA0,0xB6,0x85,0x40,0xEE,0xA2,0xDA, | ||
197 | 0x72,0x5B,0x99,0xB3,0x15,0xF3,0xB8,0xB4,0x89,0x91, | ||
198 | 0x8E,0xF1,0x09,0xE1,0x56,0x19,0x39,0x51,0xEC,0x7E, | ||
199 | 0x93,0x7B,0x16,0x52,0xC0,0xBD,0x3B,0xB1,0xBF,0x07, | ||
200 | 0x35,0x73,0xDF,0x88,0x3D,0x2C,0x34,0xF1,0xEF,0x45, | ||
201 | 0x1F,0xD4,0x6B,0x50,0x3F,0x00, | ||
202 | 0x00,0xC6,0x85,0x8E,0x06,0xB7,0x04,0x04,0xE9,0xCD, /* x */ | ||
203 | 0x9E,0x3E,0xCB,0x66,0x23,0x95,0xB4,0x42,0x9C,0x64, | ||
204 | 0x81,0x39,0x05,0x3F,0xB5,0x21,0xF8,0x28,0xAF,0x60, | ||
205 | 0x6B,0x4D,0x3D,0xBA,0xA1,0x4B,0x5E,0x77,0xEF,0xE7, | ||
206 | 0x59,0x28,0xFE,0x1D,0xC1,0x27,0xA2,0xFF,0xA8,0xDE, | ||
207 | 0x33,0x48,0xB3,0xC1,0x85,0x6A,0x42,0x9B,0xF9,0x7E, | ||
208 | 0x7E,0x31,0xC2,0xE5,0xBD,0x66, | ||
209 | 0x01,0x18,0x39,0x29,0x6a,0x78,0x9a,0x3b,0xc0,0x04, /* y */ | ||
210 | 0x5c,0x8a,0x5f,0xb4,0x2c,0x7d,0x1b,0xd9,0x98,0xf5, | ||
211 | 0x44,0x49,0x57,0x9b,0x44,0x68,0x17,0xaf,0xbd,0x17, | ||
212 | 0x27,0x3e,0x66,0x2c,0x97,0xee,0x72,0x99,0x5e,0xf4, | ||
213 | 0x26,0x40,0xc5,0x50,0xb9,0x01,0x3f,0xad,0x07,0x61, | ||
214 | 0x35,0x3c,0x70,0x86,0xa2,0x72,0xc2,0x40,0x88,0xbe, | ||
215 | 0x94,0x76,0x9f,0xd1,0x66,0x50, | ||
216 | 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
217 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
218 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
219 | 0xFF,0xFF,0xFF,0xFA,0x51,0x86,0x87,0x83,0xBF,0x2F, | ||
220 | 0x96,0x6B,0x7F,0xCC,0x01,0x48,0xF7,0x09,0xA5,0xD0, | ||
221 | 0x3B,0xB5,0xC9,0xB8,0x89,0x9C,0x47,0xAE,0xBB,0x6F, | ||
222 | 0xB7,0x1E,0x91,0x38,0x64,0x09 } | ||
163 | }; | 223 | }; |
224 | |||
164 | /* the x9.62 prime curves (minus the nist prime curves) */ | 225 | /* the x9.62 prime curves (minus the nist prime curves) */ |
165 | static const unsigned char _EC_X9_62_PRIME_192V2_SEED[] = { | 226 | static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } |
166 | 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B, | 227 | _EC_X9_62_PRIME_192V2 = { |
167 | 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6}; | 228 | { NID_X9_62_prime_field,20,24,1 }, |
168 | static const EC_CURVE_DATA _EC_X9_62_PRIME_192V2 = { | 229 | { 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B, /* seed */ |
169 | NID_X9_62_prime_field, | 230 | 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6, |
170 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", | 231 | |
171 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", | 232 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
172 | "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", | 233 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, |
173 | "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", | 234 | 0xFF,0xFF,0xFF,0xFF, |
174 | "6574d11d69b6ec7a672bb82a083df2f2b0847de970b2de15", | 235 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
175 | "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",1, | 236 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, |
176 | _EC_X9_62_PRIME_192V2_SEED, 20, | 237 | 0xFF,0xFF,0xFF,0xFC, |
177 | "X9.62 curve over a 192 bit prime field" | 238 | 0xCC,0x22,0xD6,0xDF,0xB9,0x5C,0x6B,0x25,0xE4,0x9C, /* b */ |
239 | 0x0D,0x63,0x64,0xA4,0xE5,0x98,0x0C,0x39,0x3A,0xA2, | ||
240 | 0x16,0x68,0xD9,0x53, | ||
241 | 0xEE,0xA2,0xBA,0xE7,0xE1,0x49,0x78,0x42,0xF2,0xDE, /* x */ | ||
242 | 0x77,0x69,0xCF,0xE9,0xC9,0x89,0xC0,0x72,0xAD,0x69, | ||
243 | 0x6F,0x48,0x03,0x4A, | ||
244 | 0x65,0x74,0xd1,0x1d,0x69,0xb6,0xec,0x7a,0x67,0x2b, /* y */ | ||
245 | 0xb8,0x2a,0x08,0x3d,0xf2,0xf2,0xb0,0x84,0x7d,0xe9, | ||
246 | 0x70,0xb2,0xde,0x15, | ||
247 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
248 | 0xFF,0xFE,0x5F,0xB1,0xA7,0x24,0xDC,0x80,0x41,0x86, | ||
249 | 0x48,0xD8,0xDD,0x31 } | ||
178 | }; | 250 | }; |
179 | 251 | ||
180 | static const unsigned char _EC_X9_62_PRIME_192V3_SEED[] = { | 252 | static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } |
181 | 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6, | 253 | _EC_X9_62_PRIME_192V3 = { |
182 | 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E}; | 254 | { NID_X9_62_prime_field,20,24,1 }, |
183 | static const EC_CURVE_DATA _EC_X9_62_PRIME_192V3 = { | 255 | { 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6, /* seed */ |
184 | NID_X9_62_prime_field, | 256 | 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E, |
185 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", | 257 | |
186 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", | 258 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
187 | "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", | 259 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, |
188 | "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", | 260 | 0xFF,0xFF,0xFF,0xFF, |
189 | "38a90f22637337334b49dcb66a6dc8f9978aca7648a943b0", | 261 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
190 | "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",1, | 262 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, |
191 | _EC_X9_62_PRIME_192V3_SEED, 20, | 263 | 0xFF,0xFF,0xFF,0xFC, |
192 | "X9.62 curve over a 192 bit prime field" | 264 | 0x22,0x12,0x3D,0xC2,0x39,0x5A,0x05,0xCA,0xA7,0x42, /* b */ |
265 | 0x3D,0xAE,0xCC,0xC9,0x47,0x60,0xA7,0xD4,0x62,0x25, | ||
266 | 0x6B,0xD5,0x69,0x16, | ||
267 | 0x7D,0x29,0x77,0x81,0x00,0xC6,0x5A,0x1D,0xA1,0x78, /* x */ | ||
268 | 0x37,0x16,0x58,0x8D,0xCE,0x2B,0x8B,0x4A,0xEE,0x8E, | ||
269 | 0x22,0x8F,0x18,0x96, | ||
270 | 0x38,0xa9,0x0f,0x22,0x63,0x73,0x37,0x33,0x4b,0x49, /* y */ | ||
271 | 0xdc,0xb6,0x6a,0x6d,0xc8,0xf9,0x97,0x8a,0xca,0x76, | ||
272 | 0x48,0xa9,0x43,0xb0, | ||
273 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
274 | 0xFF,0xFF,0x7A,0x62,0xD0,0x31,0xC8,0x3F,0x42,0x94, | ||
275 | 0xF6,0x40,0xEC,0x13 } | ||
193 | }; | 276 | }; |
194 | 277 | ||
195 | static const unsigned char _EC_X9_62_PRIME_239V1_SEED[] = { | 278 | static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } |
196 | 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0, | 279 | _EC_X9_62_PRIME_239V1 = { |
197 | 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D}; | 280 | { NID_X9_62_prime_field,20,30,1 }, |
198 | static const EC_CURVE_DATA _EC_X9_62_PRIME_239V1 = { | 281 | { 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0, /* seed */ |
199 | NID_X9_62_prime_field, | 282 | 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D, |
200 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", | 283 | |
201 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", | 284 | 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
202 | "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", | 285 | 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, |
203 | "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", | 286 | 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF, |
204 | "7debe8e4e90a5dae6e4054ca530ba04654b36818ce226b39fccb7b02f1ae", | 287 | |
205 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",1, | 288 | 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
206 | _EC_X9_62_PRIME_239V1_SEED, 20, | 289 | 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, |
207 | "X9.62 curve over a 239 bit prime field" | 290 | 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC, |
291 | |||
292 | 0x6B,0x01,0x6C,0x3B,0xDC,0xF1,0x89,0x41,0xD0,0xD6, /* b */ | ||
293 | 0x54,0x92,0x14,0x75,0xCA,0x71,0xA9,0xDB,0x2F,0xB2, | ||
294 | 0x7D,0x1D,0x37,0x79,0x61,0x85,0xC2,0x94,0x2C,0x0A, | ||
295 | |||
296 | 0x0F,0xFA,0x96,0x3C,0xDC,0xA8,0x81,0x6C,0xCC,0x33, /* x */ | ||
297 | 0xB8,0x64,0x2B,0xED,0xF9,0x05,0xC3,0xD3,0x58,0x57, | ||
298 | 0x3D,0x3F,0x27,0xFB,0xBD,0x3B,0x3C,0xB9,0xAA,0xAF, | ||
299 | |||
300 | 0x7d,0xeb,0xe8,0xe4,0xe9,0x0a,0x5d,0xae,0x6e,0x40, /* y */ | ||
301 | 0x54,0xca,0x53,0x0b,0xa0,0x46,0x54,0xb3,0x68,0x18, | ||
302 | 0xce,0x22,0x6b,0x39,0xfc,0xcb,0x7b,0x02,0xf1,0xae, | ||
303 | |||
304 | 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
305 | 0xFF,0xFF,0x7F,0xFF,0xFF,0x9E,0x5E,0x9A,0x9F,0x5D, | ||
306 | 0x90,0x71,0xFB,0xD1,0x52,0x26,0x88,0x90,0x9D,0x0B } | ||
208 | }; | 307 | }; |
209 | 308 | ||
210 | static const unsigned char _EC_X9_62_PRIME_239V2_SEED[] = { | 309 | static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } |
211 | 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B, | 310 | _EC_X9_62_PRIME_239V2 = { |
212 | 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16}; | 311 | { NID_X9_62_prime_field,20,30,1 }, |
213 | static const EC_CURVE_DATA _EC_X9_62_PRIME_239V2 = { | 312 | { 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B, /* seed */ |
214 | NID_X9_62_prime_field, | 313 | 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16, |
215 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", | 314 | |
216 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", | 315 | 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
217 | "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", | 316 | 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, |
218 | "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", | 317 | 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF, |
219 | "5b0125e4dbea0ec7206da0fc01d9b081329fb555de6ef460237dff8be4ba", | 318 | |
220 | "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",1, | 319 | 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
221 | _EC_X9_62_PRIME_239V2_SEED, 20, | 320 | 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, |
222 | "X9.62 curve over a 239 bit prime field" | 321 | 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC, |
322 | |||
323 | 0x61,0x7F,0xAB,0x68,0x32,0x57,0x6C,0xBB,0xFE,0xD5, /* b */ | ||
324 | 0x0D,0x99,0xF0,0x24,0x9C,0x3F,0xEE,0x58,0xB9,0x4B, | ||
325 | 0xA0,0x03,0x8C,0x7A,0xE8,0x4C,0x8C,0x83,0x2F,0x2C, | ||
326 | |||
327 | 0x38,0xAF,0x09,0xD9,0x87,0x27,0x70,0x51,0x20,0xC9, /* x */ | ||
328 | 0x21,0xBB,0x5E,0x9E,0x26,0x29,0x6A,0x3C,0xDC,0xF2, | ||
329 | 0xF3,0x57,0x57,0xA0,0xEA,0xFD,0x87,0xB8,0x30,0xE7, | ||
330 | |||
331 | 0x5b,0x01,0x25,0xe4,0xdb,0xea,0x0e,0xc7,0x20,0x6d, /* y */ | ||
332 | 0xa0,0xfc,0x01,0xd9,0xb0,0x81,0x32,0x9f,0xb5,0x55, | ||
333 | 0xde,0x6e,0xf4,0x60,0x23,0x7d,0xff,0x8b,0xe4,0xba, | ||
334 | |||
335 | 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
336 | 0xFF,0xFF,0x80,0x00,0x00,0xCF,0xA7,0xE8,0x59,0x43, | ||
337 | 0x77,0xD4,0x14,0xC0,0x38,0x21,0xBC,0x58,0x20,0x63 } | ||
223 | }; | 338 | }; |
224 | 339 | ||
225 | static const unsigned char _EC_X9_62_PRIME_239V3_SEED[] = { | 340 | static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } |
226 | 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A, | 341 | _EC_X9_62_PRIME_239V3 = { |
227 | 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF}; | 342 | { NID_X9_62_prime_field,20,30,1 }, |
228 | static const EC_CURVE_DATA _EC_X9_62_PRIME_239V3 = { | 343 | { 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A, /* seed */ |
229 | NID_X9_62_prime_field, | 344 | 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF, |
230 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", | 345 | |
231 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", | 346 | 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
232 | "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", | 347 | 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, |
233 | "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", | 348 | 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF, |
234 | "1607e6898f390c06bc1d552bad226f3b6fcfe48b6e818499af18e3ed6cf3", | 349 | |
235 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",1, | 350 | 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
236 | _EC_X9_62_PRIME_239V3_SEED, 20, | 351 | 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00, |
237 | "X9.62 curve over a 239 bit prime field" | 352 | 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC, |
353 | |||
354 | 0x25,0x57,0x05,0xFA,0x2A,0x30,0x66,0x54,0xB1,0xF4, /* b */ | ||
355 | 0xCB,0x03,0xD6,0xA7,0x50,0xA3,0x0C,0x25,0x01,0x02, | ||
356 | 0xD4,0x98,0x87,0x17,0xD9,0xBA,0x15,0xAB,0x6D,0x3E, | ||
357 | |||
358 | 0x67,0x68,0xAE,0x8E,0x18,0xBB,0x92,0xCF,0xCF,0x00, /* x */ | ||
359 | 0x5C,0x94,0x9A,0xA2,0xC6,0xD9,0x48,0x53,0xD0,0xE6, | ||
360 | 0x60,0xBB,0xF8,0x54,0xB1,0xC9,0x50,0x5F,0xE9,0x5A, | ||
361 | |||
362 | 0x16,0x07,0xe6,0x89,0x8f,0x39,0x0c,0x06,0xbc,0x1d, /* y */ | ||
363 | 0x55,0x2b,0xad,0x22,0x6f,0x3b,0x6f,0xcf,0xe4,0x8b, | ||
364 | 0x6e,0x81,0x84,0x99,0xaf,0x18,0xe3,0xed,0x6c,0xf3, | ||
365 | |||
366 | 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
367 | 0xFF,0xFF,0x7F,0xFF,0xFF,0x97,0x5D,0xEB,0x41,0xB3, | ||
368 | 0xA6,0x05,0x7C,0x3C,0x43,0x21,0x46,0x52,0x65,0x51 } | ||
238 | }; | 369 | }; |
239 | 370 | ||
240 | static const unsigned char _EC_X9_62_PRIME_256V1_SEED[] = { | 371 | |
241 | 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66, | 372 | static const struct { EC_CURVE_DATA h; unsigned char data[20+32*6]; } |
242 | 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90}; | 373 | _EC_X9_62_PRIME_256V1 = { |
243 | static const EC_CURVE_DATA _EC_X9_62_PRIME_256V1 = { | 374 | { NID_X9_62_prime_field,20,32,1 }, |
244 | NID_X9_62_prime_field, | 375 | { 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66, /* seed */ |
245 | "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", | 376 | 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90, |
246 | "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", | 377 | |
247 | "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", | 378 | 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* p */ |
248 | "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", | 379 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
249 | "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", | 380 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
250 | "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",1, | 381 | 0xFF,0xFF, |
251 | _EC_X9_62_PRIME_256V1_SEED, 20, | 382 | 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* a */ |
252 | "X9.62/SECG curve over a 256 bit prime field" | 383 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
384 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
385 | 0xFF,0xFC, | ||
386 | 0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB, /* b */ | ||
387 | 0xBD,0x55,0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0, | ||
388 | 0xCC,0x53,0xB0,0xF6,0x3B,0xCE,0x3C,0x3E,0x27,0xD2, | ||
389 | 0x60,0x4B, | ||
390 | 0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC, /* x */ | ||
391 | 0xE6,0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81, | ||
392 | 0x2D,0xEB,0x33,0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98, | ||
393 | 0xC2,0x96, | ||
394 | 0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7, /* y */ | ||
395 | 0xeb,0x4a,0x7c,0x0f,0x9e,0x16,0x2b,0xce,0x33,0x57, | ||
396 | 0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf, | ||
397 | 0x51,0xf5, | ||
398 | 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF, /* order */ | ||
399 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD, | ||
400 | 0xA7,0x17,0x9E,0x84,0xF3,0xB9,0xCA,0xC2,0xFC,0x63, | ||
401 | 0x25,0x51 } | ||
253 | }; | 402 | }; |
403 | |||
254 | /* the secg prime curves (minus the nist and x9.62 prime curves) */ | 404 | /* the secg prime curves (minus the nist and x9.62 prime curves) */ |
255 | static const unsigned char _EC_SECG_PRIME_112R1_SEED[] = { | 405 | static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; } |
256 | 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68, | 406 | _EC_SECG_PRIME_112R1 = { |
257 | 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1}; | 407 | { NID_X9_62_prime_field,20,14,1 }, |
258 | static const EC_CURVE_DATA _EC_SECG_PRIME_112R1 = { | 408 | { 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68, /* seed */ |
259 | NID_X9_62_prime_field, | 409 | 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1, |
260 | "DB7C2ABF62E35E668076BEAD208B", | 410 | |
261 | "DB7C2ABF62E35E668076BEAD2088", | 411 | 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */ |
262 | "659EF8BA043916EEDE8911702B22", | 412 | 0xBE,0xAD,0x20,0x8B, |
263 | "09487239995A5EE76B55F9C2F098", | 413 | 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* a */ |
264 | "a89ce5af8724c0a23e0e0ff77500", | 414 | 0xBE,0xAD,0x20,0x88, |
265 | "DB7C2ABF62E35E7628DFAC6561C5",1, | 415 | 0x65,0x9E,0xF8,0xBA,0x04,0x39,0x16,0xEE,0xDE,0x89, /* b */ |
266 | _EC_SECG_PRIME_112R1_SEED, 20, | 416 | 0x11,0x70,0x2B,0x22, |
267 | "SECG/WTLS curve over a 112 bit prime field" | 417 | 0x09,0x48,0x72,0x39,0x99,0x5A,0x5E,0xE7,0x6B,0x55, /* x */ |
418 | 0xF9,0xC2,0xF0,0x98, | ||
419 | 0xa8,0x9c,0xe5,0xaf,0x87,0x24,0xc0,0xa2,0x3e,0x0e, /* y */ | ||
420 | 0x0f,0xf7,0x75,0x00, | ||
421 | 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x76,0x28,0xDF, /* order */ | ||
422 | 0xAC,0x65,0x61,0xC5 } | ||
268 | }; | 423 | }; |
269 | 424 | ||
270 | static const unsigned char _EC_SECG_PRIME_112R2_SEED[] = { | 425 | static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; } |
271 | 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68, | 426 | _EC_SECG_PRIME_112R2 = { |
272 | 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4}; | 427 | { NID_X9_62_prime_field,20,14,4 }, |
273 | static const EC_CURVE_DATA _EC_SECG_PRIME_112R2 = { | 428 | { 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68, /* seed */ |
274 | NID_X9_62_prime_field, | 429 | 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4, |
275 | "DB7C2ABF62E35E668076BEAD208B", | 430 | |
276 | "6127C24C05F38A0AAAF65C0EF02C", | 431 | 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */ |
277 | "51DEF1815DB5ED74FCC34C85D709", | 432 | 0xBE,0xAD,0x20,0x8B, |
278 | "4BA30AB5E892B4E1649DD0928643", | 433 | 0x61,0x27,0xC2,0x4C,0x05,0xF3,0x8A,0x0A,0xAA,0xF6, /* a */ |
279 | "adcd46f5882e3747def36e956e97", | 434 | 0x5C,0x0E,0xF0,0x2C, |
280 | "36DF0AAFD8B8D7597CA10520D04B",4, | 435 | 0x51,0xDE,0xF1,0x81,0x5D,0xB5,0xED,0x74,0xFC,0xC3, /* b */ |
281 | _EC_SECG_PRIME_112R2_SEED, 20, | 436 | 0x4C,0x85,0xD7,0x09, |
282 | "SECG curve over a 112 bit prime field" | 437 | 0x4B,0xA3,0x0A,0xB5,0xE8,0x92,0xB4,0xE1,0x64,0x9D, /* x */ |
438 | 0xD0,0x92,0x86,0x43, | ||
439 | 0xad,0xcd,0x46,0xf5,0x88,0x2e,0x37,0x47,0xde,0xf3, /* y */ | ||
440 | 0x6e,0x95,0x6e,0x97, | ||
441 | 0x36,0xDF,0x0A,0xAF,0xD8,0xB8,0xD7,0x59,0x7C,0xA1, /* order */ | ||
442 | 0x05,0x20,0xD0,0x4B } | ||
283 | }; | 443 | }; |
284 | 444 | ||
285 | static const unsigned char _EC_SECG_PRIME_128R1_SEED[] = { | 445 | static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; } |
286 | 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, | 446 | _EC_SECG_PRIME_128R1 = { |
287 | 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79}; | 447 | { NID_X9_62_prime_field,20,16,1 }, |
288 | static const EC_CURVE_DATA _EC_SECG_PRIME_128R1 = { | 448 | { 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */ |
289 | NID_X9_62_prime_field, | 449 | 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79, |
290 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", | 450 | |
291 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", | 451 | 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
292 | "E87579C11079F43DD824993C2CEE5ED3", | 452 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
293 | "161FF7528B899B2D0C28607CA52C5B86", | 453 | 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
294 | "cf5ac8395bafeb13c02da292dded7a83", | 454 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC, |
295 | "FFFFFFFE0000000075A30D1B9038A115",1, | 455 | 0xE8,0x75,0x79,0xC1,0x10,0x79,0xF4,0x3D,0xD8,0x24, /* b */ |
296 | _EC_SECG_PRIME_128R1_SEED, 20, | 456 | 0x99,0x3C,0x2C,0xEE,0x5E,0xD3, |
297 | "SECG curve over a 128 bit prime field" | 457 | 0x16,0x1F,0xF7,0x52,0x8B,0x89,0x9B,0x2D,0x0C,0x28, /* x */ |
458 | 0x60,0x7C,0xA5,0x2C,0x5B,0x86, | ||
459 | 0xcf,0x5a,0xc8,0x39,0x5b,0xaf,0xeb,0x13,0xc0,0x2d, /* y */ | ||
460 | 0xa2,0x92,0xdd,0xed,0x7a,0x83, | ||
461 | 0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x75,0xA3, /* order */ | ||
462 | 0x0D,0x1B,0x90,0x38,0xA1,0x15 } | ||
298 | }; | 463 | }; |
299 | 464 | ||
300 | static const unsigned char _EC_SECG_PRIME_128R2_SEED[] = { | 465 | static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; } |
301 | 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75, | 466 | _EC_SECG_PRIME_128R2 = { |
302 | 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4}; | 467 | { NID_X9_62_prime_field,20,16,4 }, |
303 | static const EC_CURVE_DATA _EC_SECG_PRIME_128R2 = { | 468 | { 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75, /* seed */ |
304 | NID_X9_62_prime_field, | 469 | 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4, |
305 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", | 470 | |
306 | "D6031998D1B3BBFEBF59CC9BBFF9AEE1", | 471 | 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
307 | "5EEEFCA380D02919DC2C6558BB6D8A5D", | 472 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
308 | "7B6AA5D85E572983E6FB32A7CDEBC140", | 473 | 0xD6,0x03,0x19,0x98,0xD1,0xB3,0xBB,0xFE,0xBF,0x59, /* a */ |
309 | "27b6916a894d3aee7106fe805fc34b44", | 474 | 0xCC,0x9B,0xBF,0xF9,0xAE,0xE1, |
310 | "3FFFFFFF7FFFFFFFBE0024720613B5A3",4, | 475 | 0x5E,0xEE,0xFC,0xA3,0x80,0xD0,0x29,0x19,0xDC,0x2C, /* b */ |
311 | _EC_SECG_PRIME_128R2_SEED, 20, | 476 | 0x65,0x58,0xBB,0x6D,0x8A,0x5D, |
312 | "SECG curve over a 128 bit prime field" | 477 | 0x7B,0x6A,0xA5,0xD8,0x5E,0x57,0x29,0x83,0xE6,0xFB, /* x */ |
478 | 0x32,0xA7,0xCD,0xEB,0xC1,0x40, | ||
479 | 0x27,0xb6,0x91,0x6a,0x89,0x4d,0x3a,0xee,0x71,0x06, /* y */ | ||
480 | 0xfe,0x80,0x5f,0xc3,0x4b,0x44, | ||
481 | 0x3F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xBE,0x00, /* order */ | ||
482 | 0x24,0x72,0x06,0x13,0xB5,0xA3 } | ||
313 | }; | 483 | }; |
314 | 484 | ||
315 | static const EC_CURVE_DATA _EC_SECG_PRIME_160K1 = { | 485 | static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } |
316 | NID_X9_62_prime_field, | 486 | _EC_SECG_PRIME_160K1 = { |
317 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", | 487 | { NID_X9_62_prime_field,0,21,1 }, |
318 | "0", | 488 | { /* no seed */ |
319 | "7", | 489 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
320 | "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", | 490 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC, |
321 | "938cf935318fdced6bc28286531733c3f03c4fee", | 491 | 0x73, |
322 | "0100000000000000000001B8FA16DFAB9ACA16B6B3",1, | 492 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
323 | NULL, 0, | 493 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
324 | "SECG curve over a 160 bit prime field" | 494 | 0x00, |
495 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
496 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
497 | 0x07, | ||
498 | 0x00,0x3B,0x4C,0x38,0x2C,0xE3,0x7A,0xA1,0x92,0xA4, /* x */ | ||
499 | 0x01,0x9E,0x76,0x30,0x36,0xF4,0xF5,0xDD,0x4D,0x7E, | ||
500 | 0xBB, | ||
501 | 0x00,0x93,0x8c,0xf9,0x35,0x31,0x8f,0xdc,0xed,0x6b, /* y */ | ||
502 | 0xc2,0x82,0x86,0x53,0x17,0x33,0xc3,0xf0,0x3c,0x4f, | ||
503 | 0xee, | ||
504 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
505 | 0x01,0xB8,0xFA,0x16,0xDF,0xAB,0x9A,0xCA,0x16,0xB6, | ||
506 | 0xB3 } | ||
325 | }; | 507 | }; |
326 | 508 | ||
327 | static const unsigned char _EC_SECG_PRIME_160R1_SEED[] = { | 509 | static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } |
328 | 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76, | 510 | _EC_SECG_PRIME_160R1 = { |
329 | 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45}; | 511 | { NID_X9_62_prime_field,20,21,1 }, |
330 | static const EC_CURVE_DATA _EC_SECG_PRIME_160R1 = { | 512 | { 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76, /* seed */ |
331 | NID_X9_62_prime_field, | 513 | 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45, |
332 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", | 514 | |
333 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", | 515 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
334 | "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", | 516 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF, |
335 | "4A96B5688EF573284664698968C38BB913CBFC82", | 517 | 0xFF, |
336 | "23a628553168947d59dcc912042351377ac5fb32", | 518 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
337 | "0100000000000000000001F4C8F927AED3CA752257",1, | 519 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF, |
338 | _EC_SECG_PRIME_160R1_SEED, 20, | 520 | 0xFC, |
339 | "SECG curve over a 160 bit prime field" | 521 | 0x00,0x1C,0x97,0xBE,0xFC,0x54,0xBD,0x7A,0x8B,0x65, /* b */ |
522 | 0xAC,0xF8,0x9F,0x81,0xD4,0xD4,0xAD,0xC5,0x65,0xFA, | ||
523 | 0x45, | ||
524 | 0x00,0x4A,0x96,0xB5,0x68,0x8E,0xF5,0x73,0x28,0x46, /* x */ | ||
525 | 0x64,0x69,0x89,0x68,0xC3,0x8B,0xB9,0x13,0xCB,0xFC, | ||
526 | 0x82, | ||
527 | 0x00,0x23,0xa6,0x28,0x55,0x31,0x68,0x94,0x7d,0x59, /* y */ | ||
528 | 0xdc,0xc9,0x12,0x04,0x23,0x51,0x37,0x7a,0xc5,0xfb, | ||
529 | 0x32, | ||
530 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
531 | 0x01,0xF4,0xC8,0xF9,0x27,0xAE,0xD3,0xCA,0x75,0x22, | ||
532 | 0x57 } | ||
340 | }; | 533 | }; |
341 | 534 | ||
342 | static const unsigned char _EC_SECG_PRIME_160R2_SEED[] = { | 535 | static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } |
343 | 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09, | 536 | _EC_SECG_PRIME_160R2 = { |
344 | 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51}; | 537 | { NID_X9_62_prime_field,20,21,1 }, |
345 | static const EC_CURVE_DATA _EC_SECG_PRIME_160R2 = { | 538 | { 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09, /* seed */ |
346 | NID_X9_62_prime_field, | 539 | 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51, |
347 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", | 540 | |
348 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", | 541 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
349 | "B4E134D3FB59EB8BAB57274904664D5AF50388BA", | 542 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC, |
350 | "52DCB034293A117E1F4FF11B30F7199D3144CE6D", | 543 | 0x73, |
351 | "feaffef2e331f296e071fa0df9982cfea7d43f2e", | 544 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
352 | "0100000000000000000000351EE786A818F3A1A16B",1, | 545 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC, |
353 | _EC_SECG_PRIME_160R2_SEED, 20, | 546 | 0x70, |
354 | "SECG/WTLS curve over a 160 bit prime field" | 547 | 0x00,0xB4,0xE1,0x34,0xD3,0xFB,0x59,0xEB,0x8B,0xAB, /* b */ |
548 | 0x57,0x27,0x49,0x04,0x66,0x4D,0x5A,0xF5,0x03,0x88, | ||
549 | 0xBA, | ||
550 | 0x00,0x52,0xDC,0xB0,0x34,0x29,0x3A,0x11,0x7E,0x1F, /* x */ | ||
551 | 0x4F,0xF1,0x1B,0x30,0xF7,0x19,0x9D,0x31,0x44,0xCE, | ||
552 | 0x6D, | ||
553 | 0x00,0xfe,0xaf,0xfe,0xf2,0xe3,0x31,0xf2,0x96,0xe0, /* y */ | ||
554 | 0x71,0xfa,0x0d,0xf9,0x98,0x2c,0xfe,0xa7,0xd4,0x3f, | ||
555 | 0x2e, | ||
556 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
557 | 0x00,0x35,0x1E,0xE7,0x86,0xA8,0x18,0xF3,0xA1,0xA1, | ||
558 | 0x6B } | ||
355 | }; | 559 | }; |
356 | 560 | ||
357 | static const EC_CURVE_DATA _EC_SECG_PRIME_192K1 = { | 561 | static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; } |
358 | NID_X9_62_prime_field, | 562 | _EC_SECG_PRIME_192K1 = { |
359 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", | 563 | { NID_X9_62_prime_field,0,24,1 }, |
360 | "0", | 564 | { /* no seed */ |
361 | "3", | 565 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
362 | "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", | 566 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, |
363 | "9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d", | 567 | 0xFF,0xFF,0xEE,0x37, |
364 | "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",1, | 568 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
365 | NULL, 20, | 569 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
366 | "SECG curve over a 192 bit prime field" | 570 | 0x00,0x00,0x00,0x00, |
571 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
572 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
573 | 0x00,0x00,0x00,0x03, | ||
574 | 0xDB,0x4F,0xF1,0x0E,0xC0,0x57,0xE9,0xAE,0x26,0xB0, /* x */ | ||
575 | 0x7D,0x02,0x80,0xB7,0xF4,0x34,0x1D,0xA5,0xD1,0xB1, | ||
576 | 0xEA,0xE0,0x6C,0x7D, | ||
577 | 0x9b,0x2f,0x2f,0x6d,0x9c,0x56,0x28,0xa7,0x84,0x41, /* y */ | ||
578 | 0x63,0xd0,0x15,0xbe,0x86,0x34,0x40,0x82,0xaa,0x88, | ||
579 | 0xd9,0x5e,0x2f,0x9d, | ||
580 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
581 | 0xFF,0xFE,0x26,0xF2,0xFC,0x17,0x0F,0x69,0x46,0x6A, | ||
582 | 0x74,0xDE,0xFD,0x8D } | ||
367 | }; | 583 | }; |
368 | 584 | ||
369 | static const EC_CURVE_DATA _EC_SECG_PRIME_224K1 = { | 585 | static const struct { EC_CURVE_DATA h; unsigned char data[0+29*6]; } |
370 | NID_X9_62_prime_field, | 586 | _EC_SECG_PRIME_224K1 = { |
371 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", | 587 | { NID_X9_62_prime_field,0,29,1 }, |
372 | "0", | 588 | { /* no seed */ |
373 | "5", | 589 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
374 | "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", | 590 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
375 | "7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5", | 591 | 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xE5,0x6D, |
376 | "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",1, | 592 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
377 | NULL, 20, | 593 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
378 | "SECG curve over a 224 bit prime field" | 594 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
595 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
596 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
597 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05, | ||
598 | 0x00,0xA1,0x45,0x5B,0x33,0x4D,0xF0,0x99,0xDF,0x30, /* x */ | ||
599 | 0xFC,0x28,0xA1,0x69,0xA4,0x67,0xE9,0xE4,0x70,0x75, | ||
600 | 0xA9,0x0F,0x7E,0x65,0x0E,0xB6,0xB7,0xA4,0x5C, | ||
601 | 0x00,0x7e,0x08,0x9f,0xed,0x7f,0xba,0x34,0x42,0x82, /* y */ | ||
602 | 0xca,0xfb,0xd6,0xf7,0xe3,0x19,0xf7,0xc0,0xb0,0xbd, | ||
603 | 0x59,0xe2,0xca,0x4b,0xdb,0x55,0x6d,0x61,0xa5, | ||
604 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
605 | 0x00,0x00,0x00,0x00,0x01,0xDC,0xE8,0xD2,0xEC,0x61, | ||
606 | 0x84,0xCA,0xF0,0xA9,0x71,0x76,0x9F,0xB1,0xF7 } | ||
379 | }; | 607 | }; |
380 | 608 | ||
381 | static const EC_CURVE_DATA _EC_SECG_PRIME_256K1 = { | 609 | static const struct { EC_CURVE_DATA h; unsigned char data[0+32*6]; } |
382 | NID_X9_62_prime_field, | 610 | _EC_SECG_PRIME_256K1 = { |
383 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", | 611 | { NID_X9_62_prime_field,0,32,1 }, |
384 | "0", | 612 | { /* no seed */ |
385 | "7", | 613 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
386 | "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", | 614 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
387 | "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", | 615 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF, |
388 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",1, | 616 | 0xFC,0x2F, |
389 | NULL, 20, | 617 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
390 | "SECG curve over a 256 bit prime field" | 618 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
619 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
620 | 0x00,0x00, | ||
621 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
622 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
623 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
624 | 0x00,0x07, | ||
625 | 0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0, /* x */ | ||
626 | 0x62,0x95,0xCE,0x87,0x0B,0x07,0x02,0x9B,0xFC,0xDB, | ||
627 | 0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, | ||
628 | 0x17,0x98, | ||
629 | 0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4, /* y */ | ||
630 | 0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48, | ||
631 | 0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10, | ||
632 | 0xd4,0xb8, | ||
633 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
634 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6, | ||
635 | 0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,0x36, | ||
636 | 0x41,0x41 } | ||
391 | }; | 637 | }; |
392 | 638 | ||
393 | /* some wap/wtls curves */ | 639 | /* some wap/wtls curves */ |
394 | static const EC_CURVE_DATA _EC_WTLS_8 = { | 640 | static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; } |
395 | NID_X9_62_prime_field, | 641 | _EC_WTLS_8 = { |
396 | "FFFFFFFFFFFFFFFFFFFFFFFFFDE7", | 642 | { NID_X9_62_prime_field,0,15,1 }, |
397 | "0", | 643 | { /* no seed */ |
398 | "3", | 644 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
399 | "1", | 645 | 0xFF,0xFF,0xFF,0xFD,0xE7, |
400 | "2", | 646 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
401 | "0100000000000001ECEA551AD837E9",1, | 647 | 0x00,0x00,0x00,0x00,0x00, |
402 | NULL, 20, | 648 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ |
403 | "WTLS curve over a 112 bit prime field" | 649 | 0x00,0x00,0x00,0x00,0x03, |
650 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */ | ||
651 | 0x00,0x00,0x00,0x00,0x01, | ||
652 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */ | ||
653 | 0x00,0x00,0x00,0x00,0x02, | ||
654 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xEC,0xEA, /* order */ | ||
655 | 0x55,0x1A,0xD8,0x37,0xE9 } | ||
404 | }; | 656 | }; |
405 | 657 | ||
406 | static const EC_CURVE_DATA _EC_WTLS_9 = { | 658 | static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } |
407 | NID_X9_62_prime_field, | 659 | _EC_WTLS_9 = { |
408 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F", | 660 | { NID_X9_62_prime_field,0,21,1 }, |
409 | "0", | 661 | { /* no seed */ |
410 | "3", | 662 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
411 | "1", | 663 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x80, |
412 | "2", | 664 | 0x8F, |
413 | "0100000000000000000001CDC98AE0E2DE574ABF33",1, | 665 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
414 | NULL, 20, | 666 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
415 | "WTLS curve over a 160 bit prime field" | 667 | 0x00, |
668 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
669 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
670 | 0x03, | ||
671 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */ | ||
672 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
673 | 0x01, | ||
674 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */ | ||
675 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
676 | 0x02, | ||
677 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
678 | 0x01,0xCD,0xC9,0x8A,0xE0,0xE2,0xDE,0x57,0x4A,0xBF, | ||
679 | 0x33 } | ||
416 | }; | 680 | }; |
417 | 681 | ||
418 | static const EC_CURVE_DATA _EC_WTLS_12 = { | 682 | static const struct { EC_CURVE_DATA h; unsigned char data[0+28*6]; } |
419 | NID_X9_62_prime_field, | 683 | _EC_WTLS_12 = { |
420 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", | 684 | { NID_X9_62_prime_field,0,28,1 }, |
421 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", | 685 | { /* no seed */ |
422 | "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", | 686 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */ |
423 | "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", | 687 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, |
424 | "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", | 688 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
425 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1, | 689 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ |
426 | NULL, 0, | 690 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF, |
427 | "WTLS curvs over a 224 bit prime field" | 691 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, |
692 | 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */ | ||
693 | 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA, | ||
694 | 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4, | ||
695 | 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */ | ||
696 | 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22, | ||
697 | 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21, | ||
698 | 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */ | ||
699 | 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64, | ||
700 | 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34, | ||
701 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
702 | 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E, | ||
703 | 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D } | ||
428 | }; | 704 | }; |
429 | 705 | ||
430 | /* characteristic two curves */ | 706 | /* characteristic two curves */ |
431 | static const unsigned char _EC_SECG_CHAR2_113R1_SEED[] = { | 707 | static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; } |
432 | 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87, | 708 | _EC_SECG_CHAR2_113R1 = { |
433 | 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9}; | 709 | { NID_X9_62_characteristic_two_field,20,15,2 }, |
434 | static const EC_CURVE_DATA _EC_SECG_CHAR2_113R1 = { | 710 | { 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87, /* seed */ |
435 | NID_X9_62_characteristic_two_field, | 711 | 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9, |
436 | "020000000000000000000000000201", | 712 | |
437 | "003088250CA6E7C7FE649CE85820F7", | 713 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
438 | "00E8BEE4D3E2260744188BE0E9C723", | 714 | 0x00,0x00,0x00,0x02,0x01, |
439 | "009D73616F35F4AB1407D73562C10F", | 715 | 0x00,0x30,0x88,0x25,0x0C,0xA6,0xE7,0xC7,0xFE,0x64, /* a */ |
440 | "00A52830277958EE84D1315ED31886", | 716 | 0x9C,0xE8,0x58,0x20,0xF7, |
441 | "0100000000000000D9CCEC8A39E56F", 2, | 717 | 0x00,0xE8,0xBE,0xE4,0xD3,0xE2,0x26,0x07,0x44,0x18, /* b */ |
442 | _EC_SECG_CHAR2_113R1_SEED, 20, | 718 | 0x8B,0xE0,0xE9,0xC7,0x23, |
443 | "SECG curve over a 113 bit binary field" | 719 | 0x00,0x9D,0x73,0x61,0x6F,0x35,0xF4,0xAB,0x14,0x07, /* x */ |
720 | 0xD7,0x35,0x62,0xC1,0x0F, | ||
721 | 0x00,0xA5,0x28,0x30,0x27,0x79,0x58,0xEE,0x84,0xD1, /* y */ | ||
722 | 0x31,0x5E,0xD3,0x18,0x86, | ||
723 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xCC, /* order */ | ||
724 | 0xEC,0x8A,0x39,0xE5,0x6F } | ||
444 | }; | 725 | }; |
445 | 726 | ||
446 | static const unsigned char _EC_SECG_CHAR2_113R2_SEED[] = { | 727 | static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; } |
447 | 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, | 728 | _EC_SECG_CHAR2_113R2 = { |
448 | 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D}; | 729 | { NID_X9_62_characteristic_two_field,20,15,2 }, |
449 | static const EC_CURVE_DATA _EC_SECG_CHAR2_113R2 = { | 730 | { 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, /* seed */ |
450 | NID_X9_62_characteristic_two_field, | 731 | 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D, |
451 | "020000000000000000000000000201", | 732 | |
452 | "00689918DBEC7E5A0DD6DFC0AA55C7", | 733 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
453 | "0095E9A9EC9B297BD4BF36E059184F", | 734 | 0x00,0x00,0x00,0x02,0x01, |
454 | "01A57A6A7B26CA5EF52FCDB8164797", | 735 | 0x00,0x68,0x99,0x18,0xDB,0xEC,0x7E,0x5A,0x0D,0xD6, /* a */ |
455 | "00B3ADC94ED1FE674C06E695BABA1D", | 736 | 0xDF,0xC0,0xAA,0x55,0xC7, |
456 | "010000000000000108789B2496AF93", 2, | 737 | 0x00,0x95,0xE9,0xA9,0xEC,0x9B,0x29,0x7B,0xD4,0xBF, /* b */ |
457 | _EC_SECG_CHAR2_113R2_SEED, 20, | 738 | 0x36,0xE0,0x59,0x18,0x4F, |
458 | "SECG curve over a 113 bit binary field" | 739 | 0x01,0xA5,0x7A,0x6A,0x7B,0x26,0xCA,0x5E,0xF5,0x2F, /* x */ |
740 | 0xCD,0xB8,0x16,0x47,0x97, | ||
741 | 0x00,0xB3,0xAD,0xC9,0x4E,0xD1,0xFE,0x67,0x4C,0x06, /* y */ | ||
742 | 0xE6,0x95,0xBA,0xBA,0x1D, | ||
743 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x78, /* order */ | ||
744 | 0x9B,0x24,0x96,0xAF,0x93 } | ||
459 | }; | 745 | }; |
460 | 746 | ||
461 | static const unsigned char _EC_SECG_CHAR2_131R1_SEED[] = { | 747 | static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; } |
462 | 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98, | 748 | _EC_SECG_CHAR2_131R1 = { |
463 | 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2}; | 749 | { NID_X9_62_characteristic_two_field,20,17,2 }, |
464 | static const EC_CURVE_DATA _EC_SECG_CHAR2_131R1 = { | 750 | { 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98, /* seed */ |
465 | NID_X9_62_characteristic_two_field, | 751 | 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2, |
466 | "080000000000000000000000000000010D", | 752 | |
467 | "07A11B09A76B562144418FF3FF8C2570B8", | 753 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
468 | "0217C05610884B63B9C6C7291678F9D341", | 754 | 0x00,0x00,0x00,0x00,0x00,0x01,0x0D, |
469 | "0081BAF91FDF9833C40F9C181343638399", | 755 | 0x07,0xA1,0x1B,0x09,0xA7,0x6B,0x56,0x21,0x44,0x41, /* a */ |
470 | "078C6E7EA38C001F73C8134B1B4EF9E150", | 756 | 0x8F,0xF3,0xFF,0x8C,0x25,0x70,0xB8, |
471 | "0400000000000000023123953A9464B54D", 2, | 757 | 0x02,0x17,0xC0,0x56,0x10,0x88,0x4B,0x63,0xB9,0xC6, /* b */ |
472 | _EC_SECG_CHAR2_131R1_SEED, 20, | 758 | 0xC7,0x29,0x16,0x78,0xF9,0xD3,0x41, |
473 | "SECG/WTLS curve over a 131 bit binary field" | 759 | 0x00,0x81,0xBA,0xF9,0x1F,0xDF,0x98,0x33,0xC4,0x0F, /* x */ |
760 | 0x9C,0x18,0x13,0x43,0x63,0x83,0x99, | ||
761 | 0x07,0x8C,0x6E,0x7E,0xA3,0x8C,0x00,0x1F,0x73,0xC8, /* y */ | ||
762 | 0x13,0x4B,0x1B,0x4E,0xF9,0xE1,0x50, | ||
763 | 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x31, /* order */ | ||
764 | 0x23,0x95,0x3A,0x94,0x64,0xB5,0x4D } | ||
474 | }; | 765 | }; |
475 | 766 | ||
476 | static const unsigned char _EC_SECG_CHAR2_131R2_SEED[] = { | 767 | static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; } |
477 | 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76, | 768 | _EC_SECG_CHAR2_131R2 = { |
478 | 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3}; | 769 | { NID_X9_62_characteristic_two_field,20,17,2 }, |
479 | static const EC_CURVE_DATA _EC_SECG_CHAR2_131R2 = { | 770 | { 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76, /* seed */ |
480 | NID_X9_62_characteristic_two_field, | 771 | 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3, |
481 | "080000000000000000000000000000010D", | 772 | |
482 | "03E5A88919D7CAFCBF415F07C2176573B2", | 773 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
483 | "04B8266A46C55657AC734CE38F018F2192", | 774 | 0x00,0x00,0x00,0x00,0x00,0x01,0x0D, |
484 | "0356DCD8F2F95031AD652D23951BB366A8", | 775 | 0x03,0xE5,0xA8,0x89,0x19,0xD7,0xCA,0xFC,0xBF,0x41, /* a */ |
485 | "0648F06D867940A5366D9E265DE9EB240F", | 776 | 0x5F,0x07,0xC2,0x17,0x65,0x73,0xB2, |
486 | "0400000000000000016954A233049BA98F", 2, | 777 | 0x04,0xB8,0x26,0x6A,0x46,0xC5,0x56,0x57,0xAC,0x73, /* b */ |
487 | _EC_SECG_CHAR2_131R2_SEED, 20, | 778 | 0x4C,0xE3,0x8F,0x01,0x8F,0x21,0x92, |
488 | "SECG curve over a 131 bit binary field" | 779 | 0x03,0x56,0xDC,0xD8,0xF2,0xF9,0x50,0x31,0xAD,0x65, /* x */ |
780 | 0x2D,0x23,0x95,0x1B,0xB3,0x66,0xA8, | ||
781 | 0x06,0x48,0xF0,0x6D,0x86,0x79,0x40,0xA5,0x36,0x6D, /* y */ | ||
782 | 0x9E,0x26,0x5D,0xE9,0xEB,0x24,0x0F, | ||
783 | 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x69, /* order */ | ||
784 | 0x54,0xA2,0x33,0x04,0x9B,0xA9,0x8F } | ||
489 | }; | 785 | }; |
490 | 786 | ||
491 | static const EC_CURVE_DATA _EC_NIST_CHAR2_163K = { | 787 | static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } |
492 | NID_X9_62_characteristic_two_field, | 788 | _EC_NIST_CHAR2_163K = { |
493 | "0800000000000000000000000000000000000000C9", | 789 | { NID_X9_62_characteristic_two_field,0,21,2 }, |
494 | "1", | 790 | { /* no seed */ |
495 | "1", | 791 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
496 | "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", | 792 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
497 | "0289070FB05D38FF58321F2E800536D538CCDAA3D9", | 793 | 0xC9, |
498 | "04000000000000000000020108A2E0CC0D99F8A5EF", 2, | 794 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
499 | NULL, 0, | 795 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
500 | "NIST/SECG/WTLS curve over a 163 bit binary field" | 796 | 0x01, |
797 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
798 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
799 | 0x01, | ||
800 | 0x02,0xFE,0x13,0xC0,0x53,0x7B,0xBC,0x11,0xAC,0xAA, /* x */ | ||
801 | 0x07,0xD7,0x93,0xDE,0x4E,0x6D,0x5E,0x5C,0x94,0xEE, | ||
802 | 0xE8, | ||
803 | 0x02,0x89,0x07,0x0F,0xB0,0x5D,0x38,0xFF,0x58,0x32, /* y */ | ||
804 | 0x1F,0x2E,0x80,0x05,0x36,0xD5,0x38,0xCC,0xDA,0xA3, | ||
805 | 0xD9, | ||
806 | 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
807 | 0x02,0x01,0x08,0xA2,0xE0,0xCC,0x0D,0x99,0xF8,0xA5, | ||
808 | 0xEF } | ||
501 | }; | 809 | }; |
502 | 810 | ||
503 | static const unsigned char _EC_SECG_CHAR2_163R1_SEED[] = { | 811 | static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } |
504 | 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67, | 812 | _EC_SECG_CHAR2_163R1 = { |
505 | 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C}; | 813 | { NID_X9_62_characteristic_two_field,0,21,2 }, |
506 | static const EC_CURVE_DATA _EC_SECG_CHAR2_163R1 = { | 814 | { /* no seed */ |
507 | NID_X9_62_characteristic_two_field, | 815 | #if 0 |
508 | "0800000000000000000000000000000000000000C9", | ||
509 | "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", | ||
510 | "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", | ||
511 | "0369979697AB43897789566789567F787A7876A654", | ||
512 | "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883", | ||
513 | "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2, | ||
514 | /* The algorithm used to derive the curve parameters from | 816 | /* The algorithm used to derive the curve parameters from |
515 | * the seed used here is slightly different than the | 817 | * the seed used here is slightly different than the |
516 | * algorithm described in X9.62 . | 818 | * algorithm described in X9.62 . */ |
517 | */ | 819 | 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67, |
518 | #if 0 | 820 | 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C, |
519 | _EC_SECG_CHAR2_163R1_SEED, 20, | ||
520 | #else | ||
521 | NULL, 0, | ||
522 | #endif | 821 | #endif |
523 | "SECG curve over a 163 bit binary field" | 822 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
823 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
824 | 0xC9, | ||
825 | 0x07,0xB6,0x88,0x2C,0xAA,0xEF,0xA8,0x4F,0x95,0x54, /* a */ | ||
826 | 0xFF,0x84,0x28,0xBD,0x88,0xE2,0x46,0xD2,0x78,0x2A, | ||
827 | 0xE2, | ||
828 | 0x07,0x13,0x61,0x2D,0xCD,0xDC,0xB4,0x0A,0xAB,0x94, /* b */ | ||
829 | 0x6B,0xDA,0x29,0xCA,0x91,0xF7,0x3A,0xF9,0x58,0xAF, | ||
830 | 0xD9, | ||
831 | 0x03,0x69,0x97,0x96,0x97,0xAB,0x43,0x89,0x77,0x89, /* x */ | ||
832 | 0x56,0x67,0x89,0x56,0x7F,0x78,0x7A,0x78,0x76,0xA6, | ||
833 | 0x54, | ||
834 | 0x00,0x43,0x5E,0xDB,0x42,0xEF,0xAF,0xB2,0x98,0x9D, /* y */ | ||
835 | 0x51,0xFE,0xFC,0xE3,0xC8,0x09,0x88,0xF4,0x1F,0xF8, | ||
836 | 0x83, | ||
837 | 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
838 | 0xFF,0x48,0xAA,0xB6,0x89,0xC2,0x9C,0xA7,0x10,0x27, | ||
839 | 0x9B } | ||
524 | }; | 840 | }; |
525 | 841 | ||
526 | static const unsigned char _EC_NIST_CHAR2_163B_SEED[] = { | 842 | static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; } |
527 | 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12, | 843 | _EC_NIST_CHAR2_163B = { |
528 | 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68}; | 844 | { NID_X9_62_characteristic_two_field,0,21,2 }, |
529 | static const EC_CURVE_DATA _EC_NIST_CHAR2_163B ={ | 845 | { /* no seed */ |
530 | NID_X9_62_characteristic_two_field, | ||
531 | "0800000000000000000000000000000000000000C9", | ||
532 | "1", | ||
533 | "020A601907B8C953CA1481EB10512F78744A3205FD", | ||
534 | "03F0EBA16286A2D57EA0991168D4994637E8343E36", | ||
535 | "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", | ||
536 | "040000000000000000000292FE77E70C12A4234C33", 2, | ||
537 | /* The seed here was used to created the curve parameters in normal | ||
538 | * basis representation (and not the polynomial representation used here) | ||
539 | */ | ||
540 | #if 0 | 846 | #if 0 |
541 | _EC_NIST_CHAR2_163B_SEED, 20, | 847 | /* The seed here was used to created the curve parameters in normal |
542 | #else | 848 | * basis representation (and not the polynomial representation used here) */ |
543 | NULL, 0, | 849 | 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12, |
850 | 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68, | ||
544 | #endif | 851 | #endif |
545 | "NIST/SECG curve over a 163 bit binary field" | 852 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
853 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
854 | 0xC9, | ||
855 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ | ||
856 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
857 | 0x01, | ||
858 | 0x02,0x0A,0x60,0x19,0x07,0xB8,0xC9,0x53,0xCA,0x14, /* b */ | ||
859 | 0x81,0xEB,0x10,0x51,0x2F,0x78,0x74,0x4A,0x32,0x05, | ||
860 | 0xFD, | ||
861 | 0x03,0xF0,0xEB,0xA1,0x62,0x86,0xA2,0xD5,0x7E,0xA0, /* x */ | ||
862 | 0x99,0x11,0x68,0xD4,0x99,0x46,0x37,0xE8,0x34,0x3E, | ||
863 | 0x36, | ||
864 | 0x00,0xD5,0x1F,0xBC,0x6C,0x71,0xA0,0x09,0x4F,0xA2, /* y */ | ||
865 | 0xCD,0xD5,0x45,0xB1,0x1C,0x5C,0x0C,0x79,0x73,0x24, | ||
866 | 0xF1, | ||
867 | 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
868 | 0x02,0x92,0xFE,0x77,0xE7,0x0C,0x12,0xA4,0x23,0x4C, | ||
869 | 0x33 } | ||
546 | }; | 870 | }; |
547 | 871 | ||
548 | static const unsigned char _EC_SECG_CHAR2_193R1_SEED[] = { | 872 | static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; } |
549 | 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75, | 873 | _EC_SECG_CHAR2_193R1 = { |
550 | 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30}; | 874 | { NID_X9_62_characteristic_two_field,20,25,2 }, |
551 | static const EC_CURVE_DATA _EC_SECG_CHAR2_193R1 = { | 875 | { 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75, /* seed */ |
552 | NID_X9_62_characteristic_two_field, | 876 | 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30, |
553 | "02000000000000000000000000000000000000000000008001", | 877 | |
554 | "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", | 878 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
555 | "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", | 879 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
556 | "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1", | 880 | 0x00,0x00,0x00,0x80,0x01, |
557 | "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", | 881 | 0x00,0x17,0x85,0x8F,0xEB,0x7A,0x98,0x97,0x51,0x69, /* a */ |
558 | "01000000000000000000000000C7F34A778F443ACC920EBA49", 2, | 882 | 0xE1,0x71,0xF7,0x7B,0x40,0x87,0xDE,0x09,0x8A,0xC8, |
559 | _EC_SECG_CHAR2_193R1_SEED, 20, | 883 | 0xA9,0x11,0xDF,0x7B,0x01, |
560 | "SECG curve over a 193 bit binary field" | 884 | 0x00,0xFD,0xFB,0x49,0xBF,0xE6,0xC3,0xA8,0x9F,0xAC, /* b */ |
885 | 0xAD,0xAA,0x7A,0x1E,0x5B,0xBC,0x7C,0xC1,0xC2,0xE5, | ||
886 | 0xD8,0x31,0x47,0x88,0x14, | ||
887 | 0x01,0xF4,0x81,0xBC,0x5F,0x0F,0xF8,0x4A,0x74,0xAD, /* x */ | ||
888 | 0x6C,0xDF,0x6F,0xDE,0xF4,0xBF,0x61,0x79,0x62,0x53, | ||
889 | 0x72,0xD8,0xC0,0xC5,0xE1, | ||
890 | 0x00,0x25,0xE3,0x99,0xF2,0x90,0x37,0x12,0xCC,0xF3, /* y */ | ||
891 | 0xEA,0x9E,0x3A,0x1A,0xD1,0x7F,0xB0,0xB3,0x20,0x1B, | ||
892 | 0x6A,0xF7,0xCE,0x1B,0x05, | ||
893 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
894 | 0x00,0x00,0x00,0xC7,0xF3,0x4A,0x77,0x8F,0x44,0x3A, | ||
895 | 0xCC,0x92,0x0E,0xBA,0x49 } | ||
561 | }; | 896 | }; |
562 | 897 | ||
563 | static const unsigned char _EC_SECG_CHAR2_193R2_SEED[] = { | 898 | static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; } |
564 | 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15, | 899 | _EC_SECG_CHAR2_193R2 = { |
565 | 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11}; | 900 | { NID_X9_62_characteristic_two_field,20,25,2 }, |
566 | static const EC_CURVE_DATA _EC_SECG_CHAR2_193R2 = { | 901 | { 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15, /* seed */ |
567 | NID_X9_62_characteristic_two_field, | 902 | 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11, |
568 | "02000000000000000000000000000000000000000000008001", | 903 | |
569 | "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", | 904 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
570 | "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", | 905 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
571 | "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F", | 906 | 0x00,0x00,0x00,0x80,0x01, |
572 | "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", | 907 | 0x01,0x63,0xF3,0x5A,0x51,0x37,0xC2,0xCE,0x3E,0xA6, /* a */ |
573 | "010000000000000000000000015AAB561B005413CCD4EE99D5", 2, | 908 | 0xED,0x86,0x67,0x19,0x0B,0x0B,0xC4,0x3E,0xCD,0x69, |
574 | _EC_SECG_CHAR2_193R2_SEED, 20, | 909 | 0x97,0x77,0x02,0x70,0x9B, |
575 | "SECG curve over a 193 bit binary field" | 910 | 0x00,0xC9,0xBB,0x9E,0x89,0x27,0xD4,0xD6,0x4C,0x37, /* b */ |
911 | 0x7E,0x2A,0xB2,0x85,0x6A,0x5B,0x16,0xE3,0xEF,0xB7, | ||
912 | 0xF6,0x1D,0x43,0x16,0xAE, | ||
913 | 0x00,0xD9,0xB6,0x7D,0x19,0x2E,0x03,0x67,0xC8,0x03, /* x */ | ||
914 | 0xF3,0x9E,0x1A,0x7E,0x82,0xCA,0x14,0xA6,0x51,0x35, | ||
915 | 0x0A,0xAE,0x61,0x7E,0x8F, | ||
916 | 0x01,0xCE,0x94,0x33,0x56,0x07,0xC3,0x04,0xAC,0x29, /* y */ | ||
917 | 0xE7,0xDE,0xFB,0xD9,0xCA,0x01,0xF5,0x96,0xF9,0x27, | ||
918 | 0x22,0x4C,0xDE,0xCF,0x6C, | ||
919 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
920 | 0x00,0x00,0x01,0x5A,0xAB,0x56,0x1B,0x00,0x54,0x13, | ||
921 | 0xCC,0xD4,0xEE,0x99,0xD5 } | ||
576 | }; | 922 | }; |
577 | 923 | ||
578 | static const EC_CURVE_DATA _EC_NIST_CHAR2_233K = { | 924 | static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; } |
579 | NID_X9_62_characteristic_two_field, | 925 | _EC_NIST_CHAR2_233K = { |
580 | "020000000000000000000000000000000000000004000000000000000001", | 926 | { NID_X9_62_characteristic_two_field,0,30,4 }, |
581 | "0", | 927 | { /* no seed */ |
582 | "1", | 928 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
583 | "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", | 929 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
584 | "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", | 930 | 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
585 | "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4, | 931 | |
586 | NULL, 0, | 932 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
587 | "NIST/SECG/WTLS curve over a 233 bit binary field" | 933 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
934 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
935 | |||
936 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
937 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
938 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, | ||
939 | |||
940 | 0x01,0x72,0x32,0xBA,0x85,0x3A,0x7E,0x73,0x1A,0xF1, /* x */ | ||
941 | 0x29,0xF2,0x2F,0xF4,0x14,0x95,0x63,0xA4,0x19,0xC2, | ||
942 | 0x6B,0xF5,0x0A,0x4C,0x9D,0x6E,0xEF,0xAD,0x61,0x26, | ||
943 | |||
944 | 0x01,0xDB,0x53,0x7D,0xEC,0xE8,0x19,0xB7,0xF7,0x0F, /* y */ | ||
945 | 0x55,0x5A,0x67,0xC4,0x27,0xA8,0xCD,0x9B,0xF1,0x8A, | ||
946 | 0xEB,0x9B,0x56,0xE0,0xC1,0x10,0x56,0xFA,0xE6,0xA3, | ||
947 | |||
948 | 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
949 | 0x00,0x00,0x00,0x00,0x00,0x06,0x9D,0x5B,0xB9,0x15, | ||
950 | 0xBC,0xD4,0x6E,0xFB,0x1A,0xD5,0xF1,0x73,0xAB,0xDF } | ||
588 | }; | 951 | }; |
589 | 952 | ||
590 | static const unsigned char _EC_NIST_CHAR2_233B_SEED[] = { | 953 | static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } |
591 | 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1, | 954 | _EC_NIST_CHAR2_233B = { |
592 | 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3}; | 955 | { NID_X9_62_characteristic_two_field,20,30,2 }, |
593 | static const EC_CURVE_DATA _EC_NIST_CHAR2_233B = { | 956 | { 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1, /* seed */ |
594 | NID_X9_62_characteristic_two_field, | 957 | 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3, |
595 | "020000000000000000000000000000000000000004000000000000000001", | 958 | |
596 | "000000000000000000000000000000000000000000000000000000000001", | 959 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
597 | "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", | 960 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
598 | "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", | 961 | 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
599 | "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", | 962 | |
600 | "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2, | 963 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
601 | _EC_NIST_CHAR2_233B_SEED, 20, | 964 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
602 | "NIST/SECG/WTLS curve over a 233 bit binary field" | 965 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
966 | |||
967 | 0x00,0x66,0x64,0x7E,0xDE,0x6C,0x33,0x2C,0x7F,0x8C, /* b */ | ||
968 | 0x09,0x23,0xBB,0x58,0x21,0x3B,0x33,0x3B,0x20,0xE9, | ||
969 | 0xCE,0x42,0x81,0xFE,0x11,0x5F,0x7D,0x8F,0x90,0xAD, | ||
970 | |||
971 | 0x00,0xFA,0xC9,0xDF,0xCB,0xAC,0x83,0x13,0xBB,0x21, /* x */ | ||
972 | 0x39,0xF1,0xBB,0x75,0x5F,0xEF,0x65,0xBC,0x39,0x1F, | ||
973 | 0x8B,0x36,0xF8,0xF8,0xEB,0x73,0x71,0xFD,0x55,0x8B, | ||
974 | |||
975 | 0x01,0x00,0x6A,0x08,0xA4,0x19,0x03,0x35,0x06,0x78, /* y */ | ||
976 | 0xE5,0x85,0x28,0xBE,0xBF,0x8A,0x0B,0xEF,0xF8,0x67, | ||
977 | 0xA7,0xCA,0x36,0x71,0x6F,0x7E,0x01,0xF8,0x10,0x52, | ||
978 | |||
979 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
980 | 0x00,0x00,0x00,0x00,0x00,0x13,0xE9,0x74,0xE7,0x2F, | ||
981 | 0x8A,0x69,0x22,0x03,0x1D,0x26,0x03,0xCF,0xE0,0xD7 } | ||
603 | }; | 982 | }; |
604 | 983 | ||
605 | static const EC_CURVE_DATA _EC_SECG_CHAR2_239K1 = { | 984 | static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; } |
606 | NID_X9_62_characteristic_two_field, | 985 | _EC_SECG_CHAR2_239K1 = { |
607 | "800000000000000000004000000000000000000000000000000000000001", | 986 | { NID_X9_62_characteristic_two_field,0,30,4 }, |
608 | "0", | 987 | { /* no seed */ |
609 | "1", | 988 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
610 | "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC", | 989 | 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
611 | "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", | 990 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
612 | "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4, | 991 | |
613 | NULL, 0, | 992 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
614 | "SECG curve over a 239 bit binary field" | 993 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
994 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
995 | |||
996 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
997 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
998 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, | ||
999 | |||
1000 | 0x29,0xA0,0xB6,0xA8,0x87,0xA9,0x83,0xE9,0x73,0x09, /* x */ | ||
1001 | 0x88,0xA6,0x87,0x27,0xA8,0xB2,0xD1,0x26,0xC4,0x4C, | ||
1002 | 0xC2,0xCC,0x7B,0x2A,0x65,0x55,0x19,0x30,0x35,0xDC, | ||
1003 | |||
1004 | 0x76,0x31,0x08,0x04,0xF1,0x2E,0x54,0x9B,0xDB,0x01, /* y */ | ||
1005 | 0x1C,0x10,0x30,0x89,0xE7,0x35,0x10,0xAC,0xB2,0x75, | ||
1006 | 0xFC,0x31,0x2A,0x5D,0xC6,0xB7,0x65,0x53,0xF0,0xCA, | ||
1007 | |||
1008 | 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
1009 | 0x00,0x00,0x00,0x00,0x00,0x5A,0x79,0xFE,0xC6,0x7C, | ||
1010 | 0xB6,0xE9,0x1F,0x1C,0x1D,0xA8,0x00,0xE4,0x78,0xA5 } | ||
615 | }; | 1011 | }; |
616 | 1012 | ||
617 | static const EC_CURVE_DATA _EC_NIST_CHAR2_283K = { | 1013 | static const struct { EC_CURVE_DATA h; unsigned char data[0+36*6]; } |
618 | NID_X9_62_characteristic_two_field, | 1014 | _EC_NIST_CHAR2_283K = { |
619 | "080000000000000000000000000000000000000000000000000000000000000000001" | 1015 | { NID_X9_62_characteristic_two_field,0,36,4 }, |
620 | "0A1", | 1016 | { /* no seed */ |
621 | "0", | 1017 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
622 | "1", | 1018 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
623 | "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492" | 1019 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
624 | "836", | 1020 | 0x00,0x00,0x00,0x00,0x10,0xA1, |
625 | "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2" | 1021 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
626 | "259", | 1022 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
627 | "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163" | 1023 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
628 | "C61", 4, | 1024 | 0x00,0x00,0x00,0x00,0x00,0x00, |
629 | NULL, 20, | 1025 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ |
630 | "NIST/SECG curve over a 283 bit binary field" | 1026 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
1027 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1028 | 0x00,0x00,0x00,0x00,0x00,0x01, | ||
1029 | 0x05,0x03,0x21,0x3F,0x78,0xCA,0x44,0x88,0x3F,0x1A, /* x */ | ||
1030 | 0x3B,0x81,0x62,0xF1,0x88,0xE5,0x53,0xCD,0x26,0x5F, | ||
1031 | 0x23,0xC1,0x56,0x7A,0x16,0x87,0x69,0x13,0xB0,0xC2, | ||
1032 | 0xAC,0x24,0x58,0x49,0x28,0x36, | ||
1033 | 0x01,0xCC,0xDA,0x38,0x0F,0x1C,0x9E,0x31,0x8D,0x90, /* y */ | ||
1034 | 0xF9,0x5D,0x07,0xE5,0x42,0x6F,0xE8,0x7E,0x45,0xC0, | ||
1035 | 0xE8,0x18,0x46,0x98,0xE4,0x59,0x62,0x36,0x4E,0x34, | ||
1036 | 0x11,0x61,0x77,0xDD,0x22,0x59, | ||
1037 | 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
1038 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0xAE, | ||
1039 | 0x2E,0xD0,0x75,0x77,0x26,0x5D,0xFF,0x7F,0x94,0x45, | ||
1040 | 0x1E,0x06,0x1E,0x16,0x3C,0x61 } | ||
631 | }; | 1041 | }; |
632 | 1042 | ||
633 | static const unsigned char _EC_NIST_CHAR2_283B_SEED[] = { | 1043 | static const struct { EC_CURVE_DATA h; unsigned char data[20+36*6]; } |
634 | 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D, | 1044 | _EC_NIST_CHAR2_283B = { |
635 | 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE}; | 1045 | { NID_X9_62_characteristic_two_field,20,36,2 }, |
636 | static const EC_CURVE_DATA _EC_NIST_CHAR2_283B = { | 1046 | { 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D, /* no seed */ |
637 | NID_X9_62_characteristic_two_field, | 1047 | 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE, |
638 | "080000000000000000000000000000000000000000000000000000000000000000001" | 1048 | |
639 | "0A1", | 1049 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
640 | "000000000000000000000000000000000000000000000000000000000000000000000" | 1050 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
641 | "001", | 1051 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
642 | "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A" | 1052 | 0x00,0x00,0x00,0x00,0x10,0xA1, |
643 | "2F5", | 1053 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
644 | "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12" | 1054 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
645 | "053", | 1055 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
646 | "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE811" | 1056 | 0x00,0x00,0x00,0x00,0x00,0x01, |
647 | "2F4", | 1057 | 0x02,0x7B,0x68,0x0A,0xC8,0xB8,0x59,0x6D,0xA5,0xA4, /* b */ |
648 | "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB" | 1058 | 0xAF,0x8A,0x19,0xA0,0x30,0x3F,0xCA,0x97,0xFD,0x76, |
649 | "307", 2, | 1059 | 0x45,0x30,0x9F,0xA2,0xA5,0x81,0x48,0x5A,0xF6,0x26, |
650 | _EC_NIST_CHAR2_283B_SEED, 20, | 1060 | 0x3E,0x31,0x3B,0x79,0xA2,0xF5, |
651 | "NIST/SECG curve over a 283 bit binary field" | 1061 | 0x05,0xF9,0x39,0x25,0x8D,0xB7,0xDD,0x90,0xE1,0x93, /* x */ |
1062 | 0x4F,0x8C,0x70,0xB0,0xDF,0xEC,0x2E,0xED,0x25,0xB8, | ||
1063 | 0x55,0x7E,0xAC,0x9C,0x80,0xE2,0xE1,0x98,0xF8,0xCD, | ||
1064 | 0xBE,0xCD,0x86,0xB1,0x20,0x53, | ||
1065 | 0x03,0x67,0x68,0x54,0xFE,0x24,0x14,0x1C,0xB9,0x8F, /* y */ | ||
1066 | 0xE6,0xD4,0xB2,0x0D,0x02,0xB4,0x51,0x6F,0xF7,0x02, | ||
1067 | 0x35,0x0E,0xDD,0xB0,0x82,0x67,0x79,0xC8,0x13,0xF0, | ||
1068 | 0xDF,0x45,0xBE,0x81,0x12,0xF4, | ||
1069 | 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
1070 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x90, | ||
1071 | 0x39,0x96,0x60,0xFC,0x93,0x8A,0x90,0x16,0x5B,0x04, | ||
1072 | 0x2A,0x7C,0xEF,0xAD,0xB3,0x07 } | ||
652 | }; | 1073 | }; |
653 | 1074 | ||
654 | static const EC_CURVE_DATA _EC_NIST_CHAR2_409K = { | 1075 | static const struct { EC_CURVE_DATA h; unsigned char data[0+52*6]; } |
655 | NID_X9_62_characteristic_two_field, | 1076 | _EC_NIST_CHAR2_409K = { |
656 | "020000000000000000000000000000000000000000000000000000000000000000000" | 1077 | { NID_X9_62_characteristic_two_field,0,52,4 }, |
657 | "00000000000008000000000000000000001", | 1078 | { /* no seed */ |
658 | "0", | 1079 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
659 | "1", | 1080 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
660 | "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C4601" | 1081 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
661 | "89EB5AAAA62EE222EB1B35540CFE9023746", | 1082 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
662 | "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6" | 1083 | 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
663 | "C42E9C55215AA9CA27A5863EC48D8E0286B", | 1084 | 0x00,0x01, |
664 | "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400" | 1085 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
665 | "EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4, | 1086 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
666 | NULL, 0, | 1087 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
667 | "NIST/SECG curve over a 409 bit binary field" | 1088 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
1089 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1090 | 0x00,0x00, | ||
1091 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
1092 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1093 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1094 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1095 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1096 | 0x00,0x01, | ||
1097 | 0x00,0x60,0xF0,0x5F,0x65,0x8F,0x49,0xC1,0xAD,0x3A, /* x */ | ||
1098 | 0xB1,0x89,0x0F,0x71,0x84,0x21,0x0E,0xFD,0x09,0x87, | ||
1099 | 0xE3,0x07,0xC8,0x4C,0x27,0xAC,0xCF,0xB8,0xF9,0xF6, | ||
1100 | 0x7C,0xC2,0xC4,0x60,0x18,0x9E,0xB5,0xAA,0xAA,0x62, | ||
1101 | 0xEE,0x22,0x2E,0xB1,0xB3,0x55,0x40,0xCF,0xE9,0x02, | ||
1102 | 0x37,0x46, | ||
1103 | 0x01,0xE3,0x69,0x05,0x0B,0x7C,0x4E,0x42,0xAC,0xBA, /* y */ | ||
1104 | 0x1D,0xAC,0xBF,0x04,0x29,0x9C,0x34,0x60,0x78,0x2F, | ||
1105 | 0x91,0x8E,0xA4,0x27,0xE6,0x32,0x51,0x65,0xE9,0xEA, | ||
1106 | 0x10,0xE3,0xDA,0x5F,0x6C,0x42,0xE9,0xC5,0x52,0x15, | ||
1107 | 0xAA,0x9C,0xA2,0x7A,0x58,0x63,0xEC,0x48,0xD8,0xE0, | ||
1108 | 0x28,0x6B, | ||
1109 | 0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
1110 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
1111 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0x83,0xB2, | ||
1112 | 0xD4,0xEA,0x20,0x40,0x0E,0xC4,0x55,0x7D,0x5E,0xD3, | ||
1113 | 0xE3,0xE7,0xCA,0x5B,0x4B,0x5C,0x83,0xB8,0xE0,0x1E, | ||
1114 | 0x5F,0xCF } | ||
668 | }; | 1115 | }; |
669 | 1116 | ||
670 | static const unsigned char _EC_NIST_CHAR2_409B_SEED[] = { | 1117 | static const struct { EC_CURVE_DATA h; unsigned char data[20+52*6]; } |
671 | 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21, | 1118 | _EC_NIST_CHAR2_409B = { |
672 | 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B}; | 1119 | { NID_X9_62_characteristic_two_field,20,52,2 }, |
673 | static const EC_CURVE_DATA _EC_NIST_CHAR2_409B = { | 1120 | { 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21, /* seed */ |
674 | NID_X9_62_characteristic_two_field, | 1121 | 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B, |
675 | "020000000000000000000000000000000000000000000000000000000000000000000" | 1122 | |
676 | "00000000000008000000000000000000001", | 1123 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
677 | "000000000000000000000000000000000000000000000000000000000000000000000" | 1124 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
678 | "00000000000000000000000000000000001", | 1125 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
679 | "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A19" | 1126 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
680 | "7B272822F6CD57A55AA4F50AE317B13545F", | 1127 | 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
681 | "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255" | 1128 | 0x00,0x01, |
682 | "A868A1180515603AEAB60794E54BB7996A7", | 1129 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
683 | "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514" | 1130 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
684 | "F1FDF4B4F40D2181B3681C364BA0273C706", | 1131 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
685 | "010000000000000000000000000000000000000000000000000001E2AAD6A612F3330" | 1132 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
686 | "7BE5FA47C3C9E052F838164CD37D9A21173", 2, | 1133 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
687 | _EC_NIST_CHAR2_409B_SEED, 20, | 1134 | 0x00,0x01, |
688 | "NIST/SECG curve over a 409 bit binary field" | 1135 | 0x00,0x21,0xA5,0xC2,0xC8,0xEE,0x9F,0xEB,0x5C,0x4B, /* b */ |
1136 | 0x9A,0x75,0x3B,0x7B,0x47,0x6B,0x7F,0xD6,0x42,0x2E, | ||
1137 | 0xF1,0xF3,0xDD,0x67,0x47,0x61,0xFA,0x99,0xD6,0xAC, | ||
1138 | 0x27,0xC8,0xA9,0xA1,0x97,0xB2,0x72,0x82,0x2F,0x6C, | ||
1139 | 0xD5,0x7A,0x55,0xAA,0x4F,0x50,0xAE,0x31,0x7B,0x13, | ||
1140 | 0x54,0x5F, | ||
1141 | 0x01,0x5D,0x48,0x60,0xD0,0x88,0xDD,0xB3,0x49,0x6B, /* x */ | ||
1142 | 0x0C,0x60,0x64,0x75,0x62,0x60,0x44,0x1C,0xDE,0x4A, | ||
1143 | 0xF1,0x77,0x1D,0x4D,0xB0,0x1F,0xFE,0x5B,0x34,0xE5, | ||
1144 | 0x97,0x03,0xDC,0x25,0x5A,0x86,0x8A,0x11,0x80,0x51, | ||
1145 | 0x56,0x03,0xAE,0xAB,0x60,0x79,0x4E,0x54,0xBB,0x79, | ||
1146 | 0x96,0xA7, | ||
1147 | 0x00,0x61,0xB1,0xCF,0xAB,0x6B,0xE5,0xF3,0x2B,0xBF, /* y */ | ||
1148 | 0xA7,0x83,0x24,0xED,0x10,0x6A,0x76,0x36,0xB9,0xC5, | ||
1149 | 0xA7,0xBD,0x19,0x8D,0x01,0x58,0xAA,0x4F,0x54,0x88, | ||
1150 | 0xD0,0x8F,0x38,0x51,0x4F,0x1F,0xDF,0x4B,0x4F,0x40, | ||
1151 | 0xD2,0x18,0x1B,0x36,0x81,0xC3,0x64,0xBA,0x02,0x73, | ||
1152 | 0xC7,0x06, | ||
1153 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
1154 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1155 | 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0xAA,0xD6, | ||
1156 | 0xA6,0x12,0xF3,0x33,0x07,0xBE,0x5F,0xA4,0x7C,0x3C, | ||
1157 | 0x9E,0x05,0x2F,0x83,0x81,0x64,0xCD,0x37,0xD9,0xA2, | ||
1158 | 0x11,0x73 } | ||
689 | }; | 1159 | }; |
690 | 1160 | ||
691 | static const EC_CURVE_DATA _EC_NIST_CHAR2_571K = { | 1161 | static const struct { EC_CURVE_DATA h; unsigned char data[0+72*6]; } |
692 | NID_X9_62_characteristic_two_field, | 1162 | _EC_NIST_CHAR2_571K = { |
693 | "800000000000000000000000000000000000000000000000000000000000000000000" | 1163 | { NID_X9_62_characteristic_two_field,0,72,4 }, |
694 | "000000000000000000000000000000000000000000000000000000000000000000000" | 1164 | { /* no seed */ |
695 | "00425", | 1165 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
696 | "0", | 1166 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
697 | "1", | 1167 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
698 | "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709" | 1168 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
699 | "58493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A0" | 1169 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
700 | "1C8972", | 1170 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
701 | "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D497" | 1171 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
702 | "9C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143E" | 1172 | 0x04,0x25, |
703 | "F1C7A3", | 1173 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
704 | "020000000000000000000000000000000000000000000000000000000000000000000" | 1174 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
705 | "000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F63" | 1175 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
706 | "7C1001", 4, | 1176 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
707 | NULL, 0, | 1177 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
708 | "NIST/SECG curve over a 571 bit binary field" | 1178 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
1179 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1180 | 0x00,0x00, | ||
1181 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ | ||
1182 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1183 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1184 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1185 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1186 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1187 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1188 | 0x00,0x01, | ||
1189 | 0x02,0x6E,0xB7,0xA8,0x59,0x92,0x3F,0xBC,0x82,0x18, /* x */ | ||
1190 | 0x96,0x31,0xF8,0x10,0x3F,0xE4,0xAC,0x9C,0xA2,0x97, | ||
1191 | 0x00,0x12,0xD5,0xD4,0x60,0x24,0x80,0x48,0x01,0x84, | ||
1192 | 0x1C,0xA4,0x43,0x70,0x95,0x84,0x93,0xB2,0x05,0xE6, | ||
1193 | 0x47,0xDA,0x30,0x4D,0xB4,0xCE,0xB0,0x8C,0xBB,0xD1, | ||
1194 | 0xBA,0x39,0x49,0x47,0x76,0xFB,0x98,0x8B,0x47,0x17, | ||
1195 | 0x4D,0xCA,0x88,0xC7,0xE2,0x94,0x52,0x83,0xA0,0x1C, | ||
1196 | 0x89,0x72, | ||
1197 | 0x03,0x49,0xDC,0x80,0x7F,0x4F,0xBF,0x37,0x4F,0x4A, /* y */ | ||
1198 | 0xEA,0xDE,0x3B,0xCA,0x95,0x31,0x4D,0xD5,0x8C,0xEC, | ||
1199 | 0x9F,0x30,0x7A,0x54,0xFF,0xC6,0x1E,0xFC,0x00,0x6D, | ||
1200 | 0x8A,0x2C,0x9D,0x49,0x79,0xC0,0xAC,0x44,0xAE,0xA7, | ||
1201 | 0x4F,0xBE,0xBB,0xB9,0xF7,0x72,0xAE,0xDC,0xB6,0x20, | ||
1202 | 0xB0,0x1A,0x7B,0xA7,0xAF,0x1B,0x32,0x04,0x30,0xC8, | ||
1203 | 0x59,0x19,0x84,0xF6,0x01,0xCD,0x4C,0x14,0x3E,0xF1, | ||
1204 | 0xC7,0xA3, | ||
1205 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
1206 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1207 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1208 | 0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x18,0x50,0xE1, | ||
1209 | 0xF1,0x9A,0x63,0xE4,0xB3,0x91,0xA8,0xDB,0x91,0x7F, | ||
1210 | 0x41,0x38,0xB6,0x30,0xD8,0x4B,0xE5,0xD6,0x39,0x38, | ||
1211 | 0x1E,0x91,0xDE,0xB4,0x5C,0xFE,0x77,0x8F,0x63,0x7C, | ||
1212 | 0x10,0x01 } | ||
709 | }; | 1213 | }; |
710 | 1214 | ||
711 | static const unsigned char _EC_NIST_CHAR2_571B_SEED[] = { | 1215 | static const struct { EC_CURVE_DATA h; unsigned char data[20+72*6]; } |
712 | 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B, | 1216 | _EC_NIST_CHAR2_571B = { |
713 | 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10}; | 1217 | { NID_X9_62_characteristic_two_field,20,72,2 }, |
714 | static const EC_CURVE_DATA _EC_NIST_CHAR2_571B = { | 1218 | { 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B, /* seed */ |
715 | NID_X9_62_characteristic_two_field, | 1219 | 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10, |
716 | "800000000000000000000000000000000000000000000000000000000000000000000" | 1220 | |
717 | "000000000000000000000000000000000000000000000000000000000000000000000" | 1221 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
718 | "00425", | 1222 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
719 | "000000000000000000000000000000000000000000000000000000000000000000000" | 1223 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
720 | "000000000000000000000000000000000000000000000000000000000000000000000" | 1224 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
721 | "000001", | 1225 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
722 | "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFA" | 1226 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
723 | "BBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F29" | 1227 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
724 | "55727A", | 1228 | 0x04,0x25, |
725 | "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53" | 1229 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
726 | "950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8E" | 1230 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
727 | "EC2D19", | 1231 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
728 | "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423" | 1232 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
729 | "E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B" | 1233 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
730 | "8AC15B", | 1234 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
731 | "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | 1235 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
732 | "FFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2F" | 1236 | 0x00,0x01, |
733 | "E84E47", 2, | 1237 | 0x02,0xF4,0x0E,0x7E,0x22,0x21,0xF2,0x95,0xDE,0x29, /* b */ |
734 | _EC_NIST_CHAR2_571B_SEED, 20, | 1238 | 0x71,0x17,0xB7,0xF3,0xD6,0x2F,0x5C,0x6A,0x97,0xFF, |
735 | "NIST/SECG curve over a 571 bit binary field" | 1239 | 0xCB,0x8C,0xEF,0xF1,0xCD,0x6B,0xA8,0xCE,0x4A,0x9A, |
1240 | 0x18,0xAD,0x84,0xFF,0xAB,0xBD,0x8E,0xFA,0x59,0x33, | ||
1241 | 0x2B,0xE7,0xAD,0x67,0x56,0xA6,0x6E,0x29,0x4A,0xFD, | ||
1242 | 0x18,0x5A,0x78,0xFF,0x12,0xAA,0x52,0x0E,0x4D,0xE7, | ||
1243 | 0x39,0xBA,0xCA,0x0C,0x7F,0xFE,0xFF,0x7F,0x29,0x55, | ||
1244 | 0x72,0x7A, | ||
1245 | 0x03,0x03,0x00,0x1D,0x34,0xB8,0x56,0x29,0x6C,0x16, /* x */ | ||
1246 | 0xC0,0xD4,0x0D,0x3C,0xD7,0x75,0x0A,0x93,0xD1,0xD2, | ||
1247 | 0x95,0x5F,0xA8,0x0A,0xA5,0xF4,0x0F,0xC8,0xDB,0x7B, | ||
1248 | 0x2A,0xBD,0xBD,0xE5,0x39,0x50,0xF4,0xC0,0xD2,0x93, | ||
1249 | 0xCD,0xD7,0x11,0xA3,0x5B,0x67,0xFB,0x14,0x99,0xAE, | ||
1250 | 0x60,0x03,0x86,0x14,0xF1,0x39,0x4A,0xBF,0xA3,0xB4, | ||
1251 | 0xC8,0x50,0xD9,0x27,0xE1,0xE7,0x76,0x9C,0x8E,0xEC, | ||
1252 | 0x2D,0x19, | ||
1253 | 0x03,0x7B,0xF2,0x73,0x42,0xDA,0x63,0x9B,0x6D,0xCC, /* y */ | ||
1254 | 0xFF,0xFE,0xB7,0x3D,0x69,0xD7,0x8C,0x6C,0x27,0xA6, | ||
1255 | 0x00,0x9C,0xBB,0xCA,0x19,0x80,0xF8,0x53,0x39,0x21, | ||
1256 | 0xE8,0xA6,0x84,0x42,0x3E,0x43,0xBA,0xB0,0x8A,0x57, | ||
1257 | 0x62,0x91,0xAF,0x8F,0x46,0x1B,0xB2,0xA8,0xB3,0x53, | ||
1258 | 0x1D,0x2F,0x04,0x85,0xC1,0x9B,0x16,0xE2,0xF1,0x51, | ||
1259 | 0x6E,0x23,0xDD,0x3C,0x1A,0x48,0x27,0xAF,0x1B,0x8A, | ||
1260 | 0xC1,0x5B, | ||
1261 | 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
1262 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
1263 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
1264 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x61,0xCE,0x18, | ||
1265 | 0xFF,0x55,0x98,0x73,0x08,0x05,0x9B,0x18,0x68,0x23, | ||
1266 | 0x85,0x1E,0xC7,0xDD,0x9C,0xA1,0x16,0x1D,0xE9,0x3D, | ||
1267 | 0x51,0x74,0xD6,0x6E,0x83,0x82,0xE9,0xBB,0x2F,0xE8, | ||
1268 | 0x4E,0x47 } | ||
736 | }; | 1269 | }; |
737 | 1270 | ||
738 | static const unsigned char _EC_X9_62_CHAR2_163V1_SEED[] = { | 1271 | static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } |
739 | 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, | 1272 | _EC_X9_62_CHAR2_163V1 = { |
740 | 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54}; | 1273 | { NID_X9_62_characteristic_two_field,20,21,2 }, |
741 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V1 = { | 1274 | { 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, |
742 | NID_X9_62_characteristic_two_field, | 1275 | 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54, /* seed */ |
743 | "080000000000000000000000000000000000000107", | 1276 | |
744 | "072546B5435234A422E0789675F432C89435DE5242", | 1277 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
745 | "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", | 1278 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
746 | "07AF69989546103D79329FCC3D74880F33BBE803CB", | 1279 | 0x07, |
747 | "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F", | 1280 | 0x07,0x25,0x46,0xB5,0x43,0x52,0x34,0xA4,0x22,0xE0, /* a */ |
748 | "0400000000000000000001E60FC8821CC74DAEAFC1", 2, | 1281 | 0x78,0x96,0x75,0xF4,0x32,0xC8,0x94,0x35,0xDE,0x52, |
749 | _EC_X9_62_CHAR2_163V1_SEED, 20, | 1282 | 0x42, |
750 | "X9.62 curve over a 163 bit binary field" | 1283 | 0x00,0xC9,0x51,0x7D,0x06,0xD5,0x24,0x0D,0x3C,0xFF, /* b */ |
1284 | 0x38,0xC7,0x4B,0x20,0xB6,0xCD,0x4D,0x6F,0x9D,0xD4, | ||
1285 | 0xD9, | ||
1286 | 0x07,0xAF,0x69,0x98,0x95,0x46,0x10,0x3D,0x79,0x32, /* x */ | ||
1287 | 0x9F,0xCC,0x3D,0x74,0x88,0x0F,0x33,0xBB,0xE8,0x03, | ||
1288 | 0xCB, | ||
1289 | 0x01,0xEC,0x23,0x21,0x1B,0x59,0x66,0xAD,0xEA,0x1D, /* y */ | ||
1290 | 0x3F,0x87,0xF7,0xEA,0x58,0x48,0xAE,0xF0,0xB7,0xCA, | ||
1291 | 0x9F, | ||
1292 | 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
1293 | 0x01,0xE6,0x0F,0xC8,0x82,0x1C,0xC7,0x4D,0xAE,0xAF, | ||
1294 | 0xC1 } | ||
751 | }; | 1295 | }; |
752 | 1296 | ||
753 | static const unsigned char _EC_X9_62_CHAR2_163V2_SEED[] = { | 1297 | static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } |
754 | 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, | 1298 | _EC_X9_62_CHAR2_163V2 = { |
755 | 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD}; | 1299 | { NID_X9_62_characteristic_two_field,20,21,2 }, |
756 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V2 = { | 1300 | { 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, /* seed */ |
757 | NID_X9_62_characteristic_two_field, | 1301 | 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD, |
758 | "080000000000000000000000000000000000000107", | 1302 | |
759 | "0108B39E77C4B108BED981ED0E890E117C511CF072", | 1303 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
760 | "0667ACEB38AF4E488C407433FFAE4F1C811638DF20", | 1304 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
761 | "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5", | 1305 | 0x07, |
762 | "079F684DDF6684C5CD258B3890021B2386DFD19FC5", | 1306 | 0x01,0x08,0xB3,0x9E,0x77,0xC4,0xB1,0x08,0xBE,0xD9, /* a */ |
763 | "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2, | 1307 | 0x81,0xED,0x0E,0x89,0x0E,0x11,0x7C,0x51,0x1C,0xF0, |
764 | _EC_X9_62_CHAR2_163V2_SEED, 20, | 1308 | 0x72, |
765 | "X9.62 curve over a 163 bit binary field" | 1309 | 0x06,0x67,0xAC,0xEB,0x38,0xAF,0x4E,0x48,0x8C,0x40, /* b */ |
1310 | 0x74,0x33,0xFF,0xAE,0x4F,0x1C,0x81,0x16,0x38,0xDF, | ||
1311 | 0x20, | ||
1312 | 0x00,0x24,0x26,0x6E,0x4E,0xB5,0x10,0x6D,0x0A,0x96, /* x */ | ||
1313 | 0x4D,0x92,0xC4,0x86,0x0E,0x26,0x71,0xDB,0x9B,0x6C, | ||
1314 | 0xC5, | ||
1315 | 0x07,0x9F,0x68,0x4D,0xDF,0x66,0x84,0xC5,0xCD,0x25, /* y */ | ||
1316 | 0x8B,0x38,0x90,0x02,0x1B,0x23,0x86,0xDF,0xD1,0x9F, | ||
1317 | 0xC5, | ||
1318 | 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
1319 | 0xFD,0xF6,0x4D,0xE1,0x15,0x1A,0xDB,0xB7,0x8F,0x10, | ||
1320 | 0xA7 } | ||
766 | }; | 1321 | }; |
767 | 1322 | ||
768 | static const unsigned char _EC_X9_62_CHAR2_163V3_SEED[] = { | 1323 | static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; } |
769 | 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67, | 1324 | _EC_X9_62_CHAR2_163V3 = { |
770 | 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8}; | 1325 | { NID_X9_62_characteristic_two_field,20,21,2 }, |
771 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V3 = { | 1326 | { 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67, /* seed */ |
772 | NID_X9_62_characteristic_two_field, | 1327 | 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8, |
773 | "080000000000000000000000000000000000000107", | 1328 | |
774 | "07A526C63D3E25A256A007699F5447E32AE456B50E", | 1329 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
775 | "03F7061798EB99E238FD6F1BF95B48FEEB4854252B", | 1330 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
776 | "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB", | 1331 | 0x07, |
777 | "05B935590C155E17EA48EB3FF3718B893DF59A05D0", | 1332 | 0x07,0xA5,0x26,0xC6,0x3D,0x3E,0x25,0xA2,0x56,0xA0, /* a */ |
778 | "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2, | 1333 | 0x07,0x69,0x9F,0x54,0x47,0xE3,0x2A,0xE4,0x56,0xB5, |
779 | _EC_X9_62_CHAR2_163V3_SEED, 20, | 1334 | 0x0E, |
780 | "X9.62 curve over a 163 bit binary field" | 1335 | 0x03,0xF7,0x06,0x17,0x98,0xEB,0x99,0xE2,0x38,0xFD, /* b */ |
1336 | 0x6F,0x1B,0xF9,0x5B,0x48,0xFE,0xEB,0x48,0x54,0x25, | ||
1337 | 0x2B, | ||
1338 | 0x02,0xF9,0xF8,0x7B,0x7C,0x57,0x4D,0x0B,0xDE,0xCF, /* x */ | ||
1339 | 0x8A,0x22,0xE6,0x52,0x47,0x75,0xF9,0x8C,0xDE,0xBD, | ||
1340 | 0xCB, | ||
1341 | 0x05,0xB9,0x35,0x59,0x0C,0x15,0x5E,0x17,0xEA,0x48, /* y */ | ||
1342 | 0xEB,0x3F,0xF3,0x71,0x8B,0x89,0x3D,0xF5,0x9A,0x05, | ||
1343 | 0xD0, | ||
1344 | 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
1345 | 0xFE,0x1A,0xEE,0x14,0x0F,0x11,0x0A,0xFF,0x96,0x13, | ||
1346 | 0x09 } | ||
781 | }; | 1347 | }; |
782 | 1348 | ||
783 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_176V1 = { | 1349 | static const struct { EC_CURVE_DATA h; unsigned char data[0+23*6]; } |
784 | NID_X9_62_characteristic_two_field, | 1350 | _EC_X9_62_CHAR2_176V1 = { |
785 | "0100000000000000000000000000000000080000000007", | 1351 | { NID_X9_62_characteristic_two_field,0,23,0xFF6E }, |
786 | "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", | 1352 | { /* no seed */ |
787 | "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", | 1353 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
788 | "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798", | 1354 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00, |
789 | "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C", | 1355 | 0x00,0x00,0x07, |
790 | "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E, | 1356 | 0x00,0xE4,0xE6,0xDB,0x29,0x95,0x06,0x5C,0x40,0x7D, /* a */ |
791 | NULL, 0, | 1357 | 0x9D,0x39,0xB8,0xD0,0x96,0x7B,0x96,0x70,0x4B,0xA8, |
792 | "X9.62 curve over a 176 bit binary field" | 1358 | 0xE9,0xC9,0x0B, |
1359 | 0x00,0x5D,0xDA,0x47,0x0A,0xBE,0x64,0x14,0xDE,0x8E, /* b */ | ||
1360 | 0xC1,0x33,0xAE,0x28,0xE9,0xBB,0xD7,0xFC,0xEC,0x0A, | ||
1361 | 0xE0,0xFF,0xF2, | ||
1362 | 0x00,0x8D,0x16,0xC2,0x86,0x67,0x98,0xB6,0x00,0xF9, /* x */ | ||
1363 | 0xF0,0x8B,0xB4,0xA8,0xE8,0x60,0xF3,0x29,0x8C,0xE0, | ||
1364 | 0x4A,0x57,0x98, | ||
1365 | 0x00,0x6F,0xA4,0x53,0x9C,0x2D,0xAD,0xDD,0xD6,0xBA, /* y */ | ||
1366 | 0xB5,0x16,0x7D,0x61,0xB4,0x36,0xE1,0xD9,0x2B,0xB1, | ||
1367 | 0x6A,0x56,0x2C, | ||
1368 | 0x00,0x00,0x01,0x00,0x92,0x53,0x73,0x97,0xEC,0xA4, /* order */ | ||
1369 | 0xF6,0x14,0x57,0x99,0xD6,0x2B,0x0A,0x19,0xCE,0x06, | ||
1370 | 0xFE,0x26,0xAD } | ||
793 | }; | 1371 | }; |
794 | 1372 | ||
795 | static const unsigned char _EC_X9_62_CHAR2_191V1_SEED[] = { | 1373 | static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } |
796 | 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76, | 1374 | _EC_X9_62_CHAR2_191V1 = { |
797 | 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84}; | 1375 | { NID_X9_62_characteristic_two_field,20,24,2 }, |
798 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V1 = { | 1376 | { 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76, /* seed */ |
799 | NID_X9_62_characteristic_two_field, | 1377 | 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84, |
800 | "800000000000000000000000000000000000000000000201", | 1378 | |
801 | "2866537B676752636A68F56554E12640276B649EF7526267", | 1379 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
802 | "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", | 1380 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
803 | "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D", | 1381 | 0x00,0x00,0x02,0x01, |
804 | "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB", | 1382 | 0x28,0x66,0x53,0x7B,0x67,0x67,0x52,0x63,0x6A,0x68, /* a */ |
805 | "40000000000000000000000004A20E90C39067C893BBB9A5", 2, | 1383 | 0xF5,0x65,0x54,0xE1,0x26,0x40,0x27,0x6B,0x64,0x9E, |
806 | _EC_X9_62_CHAR2_191V1_SEED, 20, | 1384 | 0xF7,0x52,0x62,0x67, |
807 | "X9.62 curve over a 191 bit binary field" | 1385 | 0x2E,0x45,0xEF,0x57,0x1F,0x00,0x78,0x6F,0x67,0xB0, /* b */ |
1386 | 0x08,0x1B,0x94,0x95,0xA3,0xD9,0x54,0x62,0xF5,0xDE, | ||
1387 | 0x0A,0xA1,0x85,0xEC, | ||
1388 | 0x36,0xB3,0xDA,0xF8,0xA2,0x32,0x06,0xF9,0xC4,0xF2, /* x */ | ||
1389 | 0x99,0xD7,0xB2,0x1A,0x9C,0x36,0x91,0x37,0xF2,0xC8, | ||
1390 | 0x4A,0xE1,0xAA,0x0D, | ||
1391 | 0x76,0x5B,0xE7,0x34,0x33,0xB3,0xF9,0x5E,0x33,0x29, /* y */ | ||
1392 | 0x32,0xE7,0x0E,0xA2,0x45,0xCA,0x24,0x18,0xEA,0x0E, | ||
1393 | 0xF9,0x80,0x18,0xFB, | ||
1394 | 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
1395 | 0x00,0x00,0x04,0xA2,0x0E,0x90,0xC3,0x90,0x67,0xC8, | ||
1396 | 0x93,0xBB,0xB9,0xA5 } | ||
808 | }; | 1397 | }; |
809 | 1398 | ||
810 | static const unsigned char _EC_X9_62_CHAR2_191V2_SEED[] = { | 1399 | static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } |
811 | 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76, | 1400 | _EC_X9_62_CHAR2_191V2 = { |
812 | 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15}; | 1401 | { NID_X9_62_characteristic_two_field,20,24,4 }, |
813 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V2 = { | 1402 | { 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76, /* seed */ |
814 | NID_X9_62_characteristic_two_field, | 1403 | 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15, |
815 | "800000000000000000000000000000000000000000000201", | 1404 | |
816 | "401028774D7777C7B7666D1366EA432071274F89FF01E718", | 1405 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
817 | "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", | 1406 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
818 | "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10", | 1407 | 0x00,0x00,0x02,0x01, |
819 | "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A", | 1408 | 0x40,0x10,0x28,0x77,0x4D,0x77,0x77,0xC7,0xB7,0x66, /* a */ |
820 | "20000000000000000000000050508CB89F652824E06B8173", 4, | 1409 | 0x6D,0x13,0x66,0xEA,0x43,0x20,0x71,0x27,0x4F,0x89, |
821 | _EC_X9_62_CHAR2_191V2_SEED, 20, | 1410 | 0xFF,0x01,0xE7,0x18, |
822 | "X9.62 curve over a 191 bit binary field" | 1411 | 0x06,0x20,0x04,0x8D,0x28,0xBC,0xBD,0x03,0xB6,0x24, /* b */ |
1412 | 0x9C,0x99,0x18,0x2B,0x7C,0x8C,0xD1,0x97,0x00,0xC3, | ||
1413 | 0x62,0xC4,0x6A,0x01, | ||
1414 | 0x38,0x09,0xB2,0xB7,0xCC,0x1B,0x28,0xCC,0x5A,0x87, /* x */ | ||
1415 | 0x92,0x6A,0xAD,0x83,0xFD,0x28,0x78,0x9E,0x81,0xE2, | ||
1416 | 0xC9,0xE3,0xBF,0x10, | ||
1417 | 0x17,0x43,0x43,0x86,0x62,0x6D,0x14,0xF3,0xDB,0xF0, /* y */ | ||
1418 | 0x17,0x60,0xD9,0x21,0x3A,0x3E,0x1C,0xF3,0x7A,0xEC, | ||
1419 | 0x43,0x7D,0x66,0x8A, | ||
1420 | 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
1421 | 0x00,0x00,0x50,0x50,0x8C,0xB8,0x9F,0x65,0x28,0x24, | ||
1422 | 0xE0,0x6B,0x81,0x73 } | ||
823 | }; | 1423 | }; |
824 | 1424 | ||
825 | static const unsigned char _EC_X9_62_CHAR2_191V3_SEED[] = { | 1425 | static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; } |
826 | 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76, | 1426 | _EC_X9_62_CHAR2_191V3 = { |
827 | 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F}; | 1427 | { NID_X9_62_characteristic_two_field,20,24,6 }, |
828 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V3 = { | 1428 | { 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76, /* seed */ |
829 | NID_X9_62_characteristic_two_field, | 1429 | 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F, |
830 | "800000000000000000000000000000000000000000000201", | 1430 | |
831 | "6C01074756099122221056911C77D77E77A777E7E7E77FCB", | 1431 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
832 | "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", | 1432 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
833 | "375D4CE24FDE434489DE8746E71786015009E66E38A926DD", | 1433 | 0x00,0x00,0x02,0x01, |
834 | "545A39176196575D985999366E6AD34CE0A77CD7127B06BE", | 1434 | 0x6C,0x01,0x07,0x47,0x56,0x09,0x91,0x22,0x22,0x10, /* a */ |
835 | "155555555555555555555555610C0B196812BFB6288A3EA3", 6, | 1435 | 0x56,0x91,0x1C,0x77,0xD7,0x7E,0x77,0xA7,0x77,0xE7, |
836 | _EC_X9_62_CHAR2_191V3_SEED, 20, | 1436 | 0xE7,0xE7,0x7F,0xCB, |
837 | "X9.62 curve over a 191 bit binary field" | 1437 | 0x71,0xFE,0x1A,0xF9,0x26,0xCF,0x84,0x79,0x89,0xEF, /* b */ |
1438 | 0xEF,0x8D,0xB4,0x59,0xF6,0x63,0x94,0xD9,0x0F,0x32, | ||
1439 | 0xAD,0x3F,0x15,0xE8, | ||
1440 | 0x37,0x5D,0x4C,0xE2,0x4F,0xDE,0x43,0x44,0x89,0xDE, /* x */ | ||
1441 | 0x87,0x46,0xE7,0x17,0x86,0x01,0x50,0x09,0xE6,0x6E, | ||
1442 | 0x38,0xA9,0x26,0xDD, | ||
1443 | 0x54,0x5A,0x39,0x17,0x61,0x96,0x57,0x5D,0x98,0x59, /* y */ | ||
1444 | 0x99,0x36,0x6E,0x6A,0xD3,0x4C,0xE0,0xA7,0x7C,0xD7, | ||
1445 | 0x12,0x7B,0x06,0xBE, | ||
1446 | 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */ | ||
1447 | 0x55,0x55,0x61,0x0C,0x0B,0x19,0x68,0x12,0xBF,0xB6, | ||
1448 | 0x28,0x8A,0x3E,0xA3 } | ||
838 | }; | 1449 | }; |
839 | 1450 | ||
840 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_208W1 = { | 1451 | static const struct { EC_CURVE_DATA h; unsigned char data[0+27*6]; } |
841 | NID_X9_62_characteristic_two_field, | 1452 | _EC_X9_62_CHAR2_208W1 = { |
842 | "010000000000000000000000000000000800000000000000000007", | 1453 | { NID_X9_62_characteristic_two_field,0,27,0xFE48 }, |
843 | "0000000000000000000000000000000000000000000000000000", | 1454 | { /* no seed */ |
844 | "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", | 1455 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
845 | "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A", | 1456 | 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00, |
846 | "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3", | 1457 | 0x00,0x00,0x00,0x00,0x00,0x00,0x07, |
847 | "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48, | 1458 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
848 | NULL, 0, | 1459 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
849 | "X9.62 curve over a 208 bit binary field" | 1460 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
1461 | 0x00,0xC8,0x61,0x9E,0xD4,0x5A,0x62,0xE6,0x21,0x2E, /* b */ | ||
1462 | 0x11,0x60,0x34,0x9E,0x2B,0xFA,0x84,0x44,0x39,0xFA, | ||
1463 | 0xFC,0x2A,0x3F,0xD1,0x63,0x8F,0x9E, | ||
1464 | 0x00,0x89,0xFD,0xFB,0xE4,0xAB,0xE1,0x93,0xDF,0x95, /* x */ | ||
1465 | 0x59,0xEC,0xF0,0x7A,0xC0,0xCE,0x78,0x55,0x4E,0x27, | ||
1466 | 0x84,0xEB,0x8C,0x1E,0xD1,0xA5,0x7A, | ||
1467 | 0x00,0x0F,0x55,0xB5,0x1A,0x06,0xE7,0x8E,0x9A,0xC3, /* y */ | ||
1468 | 0x8A,0x03,0x5F,0xF5,0x20,0xD8,0xB0,0x17,0x81,0xBE, | ||
1469 | 0xB1,0xA6,0xBB,0x08,0x61,0x7D,0xE3, | ||
1470 | 0x00,0x00,0x01,0x01,0xBA,0xF9,0x5C,0x97,0x23,0xC5, /* order */ | ||
1471 | 0x7B,0x6C,0x21,0xDA,0x2E,0xFF,0x2D,0x5E,0xD5,0x88, | ||
1472 | 0xBD,0xD5,0x71,0x7E,0x21,0x2F,0x9D } | ||
850 | }; | 1473 | }; |
851 | 1474 | ||
852 | static const unsigned char _EC_X9_62_CHAR2_239V1_SEED[] = { | 1475 | static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } |
853 | 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, | 1476 | _EC_X9_62_CHAR2_239V1 = { |
854 | 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D}; | 1477 | { NID_X9_62_characteristic_two_field,20,30,4 }, |
855 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V1 = { | 1478 | { 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */ |
856 | NID_X9_62_characteristic_two_field, | 1479 | 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D, |
857 | "800000000000000000000000000000000000000000000000001000000001", | 1480 | |
858 | "32010857077C5431123A46B808906756F543423E8D27877578125778AC76", | 1481 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
859 | "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", | 1482 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
860 | "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D", | 1483 | 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01, |
861 | "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305", | 1484 | |
862 | "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4, | 1485 | 0x32,0x01,0x08,0x57,0x07,0x7C,0x54,0x31,0x12,0x3A, /* a */ |
863 | _EC_X9_62_CHAR2_239V1_SEED, 20, | 1486 | 0x46,0xB8,0x08,0x90,0x67,0x56,0xF5,0x43,0x42,0x3E, |
864 | "X9.62 curve over a 239 bit binary field" | 1487 | 0x8D,0x27,0x87,0x75,0x78,0x12,0x57,0x78,0xAC,0x76, |
1488 | |||
1489 | 0x79,0x04,0x08,0xF2,0xEE,0xDA,0xF3,0x92,0xB0,0x12, /* b */ | ||
1490 | 0xED,0xEF,0xB3,0x39,0x2F,0x30,0xF4,0x32,0x7C,0x0C, | ||
1491 | 0xA3,0xF3,0x1F,0xC3,0x83,0xC4,0x22,0xAA,0x8C,0x16, | ||
1492 | |||
1493 | 0x57,0x92,0x70,0x98,0xFA,0x93,0x2E,0x7C,0x0A,0x96, /* x */ | ||
1494 | 0xD3,0xFD,0x5B,0x70,0x6E,0xF7,0xE5,0xF5,0xC1,0x56, | ||
1495 | 0xE1,0x6B,0x7E,0x7C,0x86,0x03,0x85,0x52,0xE9,0x1D, | ||
1496 | |||
1497 | 0x61,0xD8,0xEE,0x50,0x77,0xC3,0x3F,0xEC,0xF6,0xF1, /* y */ | ||
1498 | 0xA1,0x6B,0x26,0x8D,0xE4,0x69,0xC3,0xC7,0x74,0x4E, | ||
1499 | 0xA9,0xA9,0x71,0x64,0x9F,0xC7,0xA9,0x61,0x63,0x05, | ||
1500 | |||
1501 | 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */ | ||
1502 | 0x00,0x00,0x00,0x00,0x00,0x0F,0x4D,0x42,0xFF,0xE1, | ||
1503 | 0x49,0x2A,0x49,0x93,0xF1,0xCA,0xD6,0x66,0xE4,0x47 } | ||
865 | }; | 1504 | }; |
866 | 1505 | ||
867 | static const unsigned char _EC_X9_62_CHAR2_239V2_SEED[] = { | 1506 | static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } |
868 | 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76, | 1507 | _EC_X9_62_CHAR2_239V2 = { |
869 | 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D}; | 1508 | { NID_X9_62_characteristic_two_field,20,30,6 }, |
870 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V2 = { | 1509 | { 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76, /* seed */ |
871 | NID_X9_62_characteristic_two_field, | 1510 | 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D, |
872 | "800000000000000000000000000000000000000000000000001000000001", | 1511 | |
873 | "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", | 1512 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
874 | "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", | 1513 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
875 | "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205", | 1514 | 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01, |
876 | "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833", | 1515 | |
877 | "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6, | 1516 | 0x42,0x30,0x01,0x77,0x57,0xA7,0x67,0xFA,0xE4,0x23, /* a */ |
878 | _EC_X9_62_CHAR2_239V2_SEED, 20, | 1517 | 0x98,0x56,0x9B,0x74,0x63,0x25,0xD4,0x53,0x13,0xAF, |
879 | "X9.62 curve over a 239 bit binary field" | 1518 | 0x07,0x66,0x26,0x64,0x79,0xB7,0x56,0x54,0xE6,0x5F, |
1519 | |||
1520 | 0x50,0x37,0xEA,0x65,0x41,0x96,0xCF,0xF0,0xCD,0x82, /* b */ | ||
1521 | 0xB2,0xC1,0x4A,0x2F,0xCF,0x2E,0x3F,0xF8,0x77,0x52, | ||
1522 | 0x85,0xB5,0x45,0x72,0x2F,0x03,0xEA,0xCD,0xB7,0x4B, | ||
1523 | |||
1524 | 0x28,0xF9,0xD0,0x4E,0x90,0x00,0x69,0xC8,0xDC,0x47, /* x */ | ||
1525 | 0xA0,0x85,0x34,0xFE,0x76,0xD2,0xB9,0x00,0xB7,0xD7, | ||
1526 | 0xEF,0x31,0xF5,0x70,0x9F,0x20,0x0C,0x4C,0xA2,0x05, | ||
1527 | |||
1528 | 0x56,0x67,0x33,0x4C,0x45,0xAF,0xF3,0xB5,0xA0,0x3B, /* y */ | ||
1529 | 0xAD,0x9D,0xD7,0x5E,0x2C,0x71,0xA9,0x93,0x62,0x56, | ||
1530 | 0x7D,0x54,0x53,0xF7,0xFA,0x6E,0x22,0x7E,0xC8,0x33, | ||
1531 | |||
1532 | 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */ | ||
1533 | 0x55,0x55,0x55,0x55,0x55,0x3C,0x6F,0x28,0x85,0x25, | ||
1534 | 0x9C,0x31,0xE3,0xFC,0xDF,0x15,0x46,0x24,0x52,0x2D } | ||
880 | }; | 1535 | }; |
881 | 1536 | ||
882 | static const unsigned char _EC_X9_62_CHAR2_239V3_SEED[] = { | 1537 | static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; } |
883 | 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, | 1538 | _EC_X9_62_CHAR2_239V3 = { |
884 | 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41}; | 1539 | { NID_X9_62_characteristic_two_field,20,30,0xA }, |
885 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V3 = { | 1540 | { 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */ |
886 | NID_X9_62_characteristic_two_field, | 1541 | 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41, |
887 | "800000000000000000000000000000000000000000000000001000000001", | 1542 | |
888 | "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", | 1543 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
889 | "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", | 1544 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
890 | "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92", | 1545 | 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01, |
891 | "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461", | 1546 | |
892 | "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA, | 1547 | 0x01,0x23,0x87,0x74,0x66,0x6A,0x67,0x76,0x6D,0x66, /* a */ |
893 | _EC_X9_62_CHAR2_239V3_SEED, 20, | 1548 | 0x76,0xF7,0x78,0xE6,0x76,0xB6,0x69,0x99,0x17,0x66, |
894 | "X9.62 curve over a 239 bit binary field" | 1549 | 0x66,0xE6,0x87,0x66,0x6D,0x87,0x66,0xC6,0x6A,0x9F, |
1550 | |||
1551 | 0x6A,0x94,0x19,0x77,0xBA,0x9F,0x6A,0x43,0x51,0x99, /* b */ | ||
1552 | 0xAC,0xFC,0x51,0x06,0x7E,0xD5,0x87,0xF5,0x19,0xC5, | ||
1553 | 0xEC,0xB5,0x41,0xB8,0xE4,0x41,0x11,0xDE,0x1D,0x40, | ||
1554 | |||
1555 | 0x70,0xF6,0xE9,0xD0,0x4D,0x28,0x9C,0x4E,0x89,0x91, /* x */ | ||
1556 | 0x3C,0xE3,0x53,0x0B,0xFD,0xE9,0x03,0x97,0x7D,0x42, | ||
1557 | 0xB1,0x46,0xD5,0x39,0xBF,0x1B,0xDE,0x4E,0x9C,0x92, | ||
1558 | |||
1559 | 0x2E,0x5A,0x0E,0xAF,0x6E,0x5E,0x13,0x05,0xB9,0x00, /* y */ | ||
1560 | 0x4D,0xCE,0x5C,0x0E,0xD7,0xFE,0x59,0xA3,0x56,0x08, | ||
1561 | 0xF3,0x38,0x37,0xC8,0x16,0xD8,0x0B,0x79,0xF4,0x61, | ||
1562 | |||
1563 | 0x0C,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, /* order */ | ||
1564 | 0xCC,0xCC,0xCC,0xCC,0xCC,0xAC,0x49,0x12,0xD2,0xD9, | ||
1565 | 0xDF,0x90,0x3E,0xF9,0x88,0x8B,0x8A,0x0E,0x4C,0xFF } | ||
895 | }; | 1566 | }; |
896 | 1567 | ||
897 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_272W1 = { | 1568 | static const struct { EC_CURVE_DATA h; unsigned char data[0+35*6]; } |
898 | NID_X9_62_characteristic_two_field, | 1569 | _EC_X9_62_CHAR2_272W1 = { |
899 | "010000000000000000000000000000000000000000000000000000010000000000000" | 1570 | { NID_X9_62_characteristic_two_field,0,35,0xFF06 }, |
900 | "B", | 1571 | { /* no seed */ |
901 | "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", | 1572 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
902 | "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", | 1573 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
903 | "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D", | 1574 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, |
904 | "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23", | 1575 | 0x00,0x00,0x00,0x00,0x0B, |
905 | "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", | 1576 | 0x00,0x91,0xA0,0x91,0xF0,0x3B,0x5F,0xBA,0x4A,0xB2, /* a */ |
906 | 0xFF06, | 1577 | 0xCC,0xF4,0x9C,0x4E,0xDD,0x22,0x0F,0xB0,0x28,0x71, |
907 | NULL, 0, | 1578 | 0x2D,0x42,0xBE,0x75,0x2B,0x2C,0x40,0x09,0x4D,0xBA, |
908 | "X9.62 curve over a 272 bit binary field" | 1579 | 0xCD,0xB5,0x86,0xFB,0x20, |
1580 | 0x00,0x71,0x67,0xEF,0xC9,0x2B,0xB2,0xE3,0xCE,0x7C, /* b */ | ||
1581 | 0x8A,0xAA,0xFF,0x34,0xE1,0x2A,0x9C,0x55,0x70,0x03, | ||
1582 | 0xD7,0xC7,0x3A,0x6F,0xAF,0x00,0x3F,0x99,0xF6,0xCC, | ||
1583 | 0x84,0x82,0xE5,0x40,0xF7, | ||
1584 | 0x00,0x61,0x08,0xBA,0xBB,0x2C,0xEE,0xBC,0xF7,0x87, /* x */ | ||
1585 | 0x05,0x8A,0x05,0x6C,0xBE,0x0C,0xFE,0x62,0x2D,0x77, | ||
1586 | 0x23,0xA2,0x89,0xE0,0x8A,0x07,0xAE,0x13,0xEF,0x0D, | ||
1587 | 0x10,0xD1,0x71,0xDD,0x8D, | ||
1588 | 0x00,0x10,0xC7,0x69,0x57,0x16,0x85,0x1E,0xEF,0x6B, /* y */ | ||
1589 | 0xA7,0xF6,0x87,0x2E,0x61,0x42,0xFB,0xD2,0x41,0xB8, | ||
1590 | 0x30,0xFF,0x5E,0xFC,0xAC,0xEC,0xCA,0xB0,0x5E,0x02, | ||
1591 | 0x00,0x5D,0xDE,0x9D,0x23, | ||
1592 | 0x00,0x00,0x01,0x00,0xFA,0xF5,0x13,0x54,0xE0,0xE3, /* order */ | ||
1593 | 0x9E,0x48,0x92,0xDF,0x6E,0x31,0x9C,0x72,0xC8,0x16, | ||
1594 | 0x16,0x03,0xFA,0x45,0xAA,0x7B,0x99,0x8A,0x16,0x7B, | ||
1595 | 0x8F,0x1E,0x62,0x95,0x21 } | ||
909 | }; | 1596 | }; |
910 | 1597 | ||
911 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_304W1 = { | 1598 | static const struct { EC_CURVE_DATA h; unsigned char data[0+39*6]; } |
912 | NID_X9_62_characteristic_two_field, | 1599 | _EC_X9_62_CHAR2_304W1 = { |
913 | "010000000000000000000000000000000000000000000000000000000000000000000" | 1600 | { NID_X9_62_characteristic_two_field,0,39,0xFE2E }, |
914 | "000000807", | 1601 | { /* no seed */ |
915 | "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A039" | 1602 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
916 | "6C8E681", | 1603 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
917 | "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E558" | 1604 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
918 | "27340BE", | 1605 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x07, |
919 | "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F7" | 1606 | 0x00,0xFD,0x0D,0x69,0x31,0x49,0xA1,0x18,0xF6,0x51, /* a */ |
920 | "40A2614", | 1607 | 0xE6,0xDC,0xE6,0x80,0x20,0x85,0x37,0x7E,0x5F,0x88, |
921 | "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1" | 1608 | 0x2D,0x1B,0x51,0x0B,0x44,0x16,0x00,0x74,0xC1,0x28, |
922 | "B92C03B", | 1609 | 0x80,0x78,0x36,0x5A,0x03,0x96,0xC8,0xE6,0x81, |
923 | "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164" | 1610 | 0x00,0xBD,0xDB,0x97,0xE5,0x55,0xA5,0x0A,0x90,0x8E, /* b */ |
924 | "443051D", 0xFE2E, | 1611 | 0x43,0xB0,0x1C,0x79,0x8E,0xA5,0xDA,0xA6,0x78,0x8F, |
925 | NULL, 0, | 1612 | 0x1E,0xA2,0x79,0x4E,0xFC,0xF5,0x71,0x66,0xB8,0xC1, |
926 | "X9.62 curve over a 304 bit binary field" | 1613 | 0x40,0x39,0x60,0x1E,0x55,0x82,0x73,0x40,0xBE, |
1614 | 0x00,0x19,0x7B,0x07,0x84,0x5E,0x9B,0xE2,0xD9,0x6A, /* x */ | ||
1615 | 0xDB,0x0F,0x5F,0x3C,0x7F,0x2C,0xFF,0xBD,0x7A,0x3E, | ||
1616 | 0xB8,0xB6,0xFE,0xC3,0x5C,0x7F,0xD6,0x7F,0x26,0xDD, | ||
1617 | 0xF6,0x28,0x5A,0x64,0x4F,0x74,0x0A,0x26,0x14, | ||
1618 | 0x00,0xE1,0x9F,0xBE,0xB7,0x6E,0x0D,0xA1,0x71,0x51, /* y */ | ||
1619 | 0x7E,0xCF,0x40,0x1B,0x50,0x28,0x9B,0xF0,0x14,0x10, | ||
1620 | 0x32,0x88,0x52,0x7A,0x9B,0x41,0x6A,0x10,0x5E,0x80, | ||
1621 | 0x26,0x0B,0x54,0x9F,0xDC,0x1B,0x92,0xC0,0x3B, | ||
1622 | 0x00,0x00,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC, /* order */ | ||
1623 | 0x80,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,0x80, | ||
1624 | 0x01,0x02,0x2D,0x5C,0x91,0xDD,0x17,0x3F,0x8F,0xB5, | ||
1625 | 0x61,0xDA,0x68,0x99,0x16,0x44,0x43,0x05,0x1D } | ||
927 | }; | 1626 | }; |
928 | 1627 | ||
929 | static const unsigned char _EC_X9_62_CHAR2_359V1_SEED[] = { | 1628 | static const struct { EC_CURVE_DATA h; unsigned char data[20+45*6]; } |
930 | 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76, | 1629 | _EC_X9_62_CHAR2_359V1 = { |
931 | 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6}; | 1630 | { NID_X9_62_characteristic_two_field,20,45,0x4C }, |
932 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_359V1 = { | 1631 | { 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76, /* seed */ |
933 | NID_X9_62_characteristic_two_field, | 1632 | 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6, |
934 | "800000000000000000000000000000000000000000000000000000000000000000000" | 1633 | |
935 | "000100000000000000001", | 1634 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
936 | "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05" | 1635 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
937 | "656FB549016A96656A557", | 1636 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
938 | "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC34562608968" | 1637 | 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00, |
939 | "7742B6329E70680231988", | 1638 | 0x00,0x00,0x00,0x00,0x01, |
940 | "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE9" | 1639 | 0x56,0x67,0x67,0x6A,0x65,0x4B,0x20,0x75,0x4F,0x35, /* a */ |
941 | "8E8E707C07A2239B1B097", | 1640 | 0x6E,0xA9,0x20,0x17,0xD9,0x46,0x56,0x7C,0x46,0x67, |
942 | "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E" | 1641 | 0x55,0x56,0xF1,0x95,0x56,0xA0,0x46,0x16,0xB5,0x67, |
943 | "4AE2DE211305A407104BD", | 1642 | 0xD2,0x23,0xA5,0xE0,0x56,0x56,0xFB,0x54,0x90,0x16, |
944 | "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB9" | 1643 | 0xA9,0x66,0x56,0xA5,0x57, |
945 | "64FE7719E74F490758D3B", 0x4C, | 1644 | 0x24,0x72,0xE2,0xD0,0x19,0x7C,0x49,0x36,0x3F,0x1F, /* b */ |
946 | _EC_X9_62_CHAR2_359V1_SEED, 20, | 1645 | 0xE7,0xF5,0xB6,0xDB,0x07,0x5D,0x52,0xB6,0x94,0x7D, |
947 | "X9.62 curve over a 359 bit binary field" | 1646 | 0x13,0x5D,0x8C,0xA4,0x45,0x80,0x5D,0x39,0xBC,0x34, |
1647 | 0x56,0x26,0x08,0x96,0x87,0x74,0x2B,0x63,0x29,0xE7, | ||
1648 | 0x06,0x80,0x23,0x19,0x88, | ||
1649 | 0x3C,0x25,0x8E,0xF3,0x04,0x77,0x67,0xE7,0xED,0xE0, /* x */ | ||
1650 | 0xF1,0xFD,0xAA,0x79,0xDA,0xEE,0x38,0x41,0x36,0x6A, | ||
1651 | 0x13,0x2E,0x16,0x3A,0xCE,0xD4,0xED,0x24,0x01,0xDF, | ||
1652 | 0x9C,0x6B,0xDC,0xDE,0x98,0xE8,0xE7,0x07,0xC0,0x7A, | ||
1653 | 0x22,0x39,0xB1,0xB0,0x97, | ||
1654 | 0x53,0xD7,0xE0,0x85,0x29,0x54,0x70,0x48,0x12,0x1E, /* y */ | ||
1655 | 0x9C,0x95,0xF3,0x79,0x1D,0xD8,0x04,0x96,0x39,0x48, | ||
1656 | 0xF3,0x4F,0xAE,0x7B,0xF4,0x4E,0xA8,0x23,0x65,0xDC, | ||
1657 | 0x78,0x68,0xFE,0x57,0xE4,0xAE,0x2D,0xE2,0x11,0x30, | ||
1658 | 0x5A,0x40,0x71,0x04,0xBD, | ||
1659 | 0x01,0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1, /* order */ | ||
1660 | 0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,0xAF, | ||
1661 | 0x28,0x6B,0xC9,0xFB,0x8F,0x6B,0x85,0xC5,0x56,0x89, | ||
1662 | 0x2C,0x20,0xA7,0xEB,0x96,0x4F,0xE7,0x71,0x9E,0x74, | ||
1663 | 0xF4,0x90,0x75,0x8D,0x3B } | ||
948 | }; | 1664 | }; |
949 | 1665 | ||
950 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_368W1 = { | 1666 | static const struct { EC_CURVE_DATA h; unsigned char data[0+47*6]; } |
951 | NID_X9_62_characteristic_two_field, | 1667 | _EC_X9_62_CHAR2_368W1 = { |
952 | "010000000000000000000000000000000000000000000000000000000000000000000" | 1668 | { NID_X9_62_characteristic_two_field,0,47,0xFF70 }, |
953 | "0002000000000000000000007", | 1669 | { /* no seed */ |
954 | "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62" | 1670 | 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
955 | "F0AB7519CCD2A1A906AE30D", | 1671 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
956 | "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112" | 1672 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
957 | "D84D164F444F8F74786046A", | 1673 | 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, |
958 | "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E78" | 1674 | 0x00,0x00,0x00,0x00,0x00,0x00,0x07, |
959 | "9E927BE216F02E1FB136A5F", | 1675 | 0x00,0xE0,0xD2,0xEE,0x25,0x09,0x52,0x06,0xF5,0xE2, /* a */ |
960 | "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855" | 1676 | 0xA4,0xF9,0xED,0x22,0x9F,0x1F,0x25,0x6E,0x79,0xA0, |
961 | "ADAA81E2A0750B80FDA2310", | 1677 | 0xE2,0xB4,0x55,0x97,0x0D,0x8D,0x0D,0x86,0x5B,0xD9, |
962 | "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E90" | 1678 | 0x47,0x78,0xC5,0x76,0xD6,0x2F,0x0A,0xB7,0x51,0x9C, |
963 | "9AE40A6F131E9CFCE5BD967", 0xFF70, | 1679 | 0xCD,0x2A,0x1A,0x90,0x6A,0xE3,0x0D, |
964 | NULL, 0, | 1680 | 0x00,0xFC,0x12,0x17,0xD4,0x32,0x0A,0x90,0x45,0x2C, /* b */ |
965 | "X9.62 curve over a 368 bit binary field" | 1681 | 0x76,0x0A,0x58,0xED,0xCD,0x30,0xC8,0xDD,0x06,0x9B, |
1682 | 0x3C,0x34,0x45,0x38,0x37,0xA3,0x4E,0xD5,0x0C,0xB5, | ||
1683 | 0x49,0x17,0xE1,0xC2,0x11,0x2D,0x84,0xD1,0x64,0xF4, | ||
1684 | 0x44,0xF8,0xF7,0x47,0x86,0x04,0x6A, | ||
1685 | 0x00,0x10,0x85,0xE2,0x75,0x53,0x81,0xDC,0xCC,0xE3, /* x */ | ||
1686 | 0xC1,0x55,0x7A,0xFA,0x10,0xC2,0xF0,0xC0,0xC2,0x82, | ||
1687 | 0x56,0x46,0xC5,0xB3,0x4A,0x39,0x4C,0xBC,0xFA,0x8B, | ||
1688 | 0xC1,0x6B,0x22,0xE7,0xE7,0x89,0xE9,0x27,0xBE,0x21, | ||
1689 | 0x6F,0x02,0xE1,0xFB,0x13,0x6A,0x5F, | ||
1690 | 0x00,0x7B,0x3E,0xB1,0xBD,0xDC,0xBA,0x62,0xD5,0xD8, /* y */ | ||
1691 | 0xB2,0x05,0x9B,0x52,0x57,0x97,0xFC,0x73,0x82,0x2C, | ||
1692 | 0x59,0x05,0x9C,0x62,0x3A,0x45,0xFF,0x38,0x43,0xCE, | ||
1693 | 0xE8,0xF8,0x7C,0xD1,0x85,0x5A,0xDA,0xA8,0x1E,0x2A, | ||
1694 | 0x07,0x50,0xB8,0x0F,0xDA,0x23,0x10, | ||
1695 | 0x00,0x00,0x01,0x00,0x90,0x51,0x2D,0xA9,0xAF,0x72, /* order */ | ||
1696 | 0xB0,0x83,0x49,0xD9,0x8A,0x5D,0xD4,0xC7,0xB0,0x53, | ||
1697 | 0x2E,0xCA,0x51,0xCE,0x03,0xE2,0xD1,0x0F,0x3B,0x7A, | ||
1698 | 0xC5,0x79,0xBD,0x87,0xE9,0x09,0xAE,0x40,0xA6,0xF1, | ||
1699 | 0x31,0xE9,0xCF,0xCE,0x5B,0xD9,0x67 } | ||
966 | }; | 1700 | }; |
967 | 1701 | ||
968 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_431R1 = { | 1702 | static const struct { EC_CURVE_DATA h; unsigned char data[0+54*6]; } |
969 | NID_X9_62_characteristic_two_field, | 1703 | _EC_X9_62_CHAR2_431R1 = { |
970 | "800000000000000000000000000000000000000000000000000000000000000000000" | 1704 | { NID_X9_62_characteristic_two_field,0,54,0x2760 }, |
971 | "000000001000000000000000000000000000001", | 1705 | { /* no seed */ |
972 | "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0E" | 1706 | 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
973 | "B9906D0957F6C6FEACD615468DF104DE296CD8F", | 1707 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
974 | "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B6" | 1708 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
975 | "26D4E50A8DD731B107A9962381FB5D807BF2618", | 1709 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, |
976 | "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C2" | 1710 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
977 | "1E7C5EFE965361F6C2999C0C247B0DBD70CE6B7", | 1711 | 0x00,0x00,0x00,0x01, |
978 | "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6" | 1712 | 0x1A,0x82,0x7E,0xF0,0x0D,0xD6,0xFC,0x0E,0x23,0x4C, /* a */ |
979 | "ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760", | 1713 | 0xAF,0x04,0x6C,0x6A,0x5D,0x8A,0x85,0x39,0x5B,0x23, |
980 | "0340340340340340340340340340340340340340340340340340340323C313FAB5058" | 1714 | 0x6C,0xC4,0xAD,0x2C,0xF3,0x2A,0x0C,0xAD,0xBD,0xC9, |
981 | "9703B5EC68D3587FEC60D161CC149C1AD4A91", 0x2760, | 1715 | 0xDD,0xF6,0x20,0xB0,0xEB,0x99,0x06,0xD0,0x95,0x7F, |
982 | NULL, 0, | 1716 | 0x6C,0x6F,0xEA,0xCD,0x61,0x54,0x68,0xDF,0x10,0x4D, |
983 | "X9.62 curve over a 431 bit binary field" | 1717 | 0xE2,0x96,0xCD,0x8F, |
1718 | 0x10,0xD9,0xB4,0xA3,0xD9,0x04,0x7D,0x8B,0x15,0x43, /* b */ | ||
1719 | 0x59,0xAB,0xFB,0x1B,0x7F,0x54,0x85,0xB0,0x4C,0xEB, | ||
1720 | 0x86,0x82,0x37,0xDD,0xC9,0xDE,0xDA,0x98,0x2A,0x67, | ||
1721 | 0x9A,0x5A,0x91,0x9B,0x62,0x6D,0x4E,0x50,0xA8,0xDD, | ||
1722 | 0x73,0x1B,0x10,0x7A,0x99,0x62,0x38,0x1F,0xB5,0xD8, | ||
1723 | 0x07,0xBF,0x26,0x18, | ||
1724 | 0x12,0x0F,0xC0,0x5D,0x3C,0x67,0xA9,0x9D,0xE1,0x61, /* x */ | ||
1725 | 0xD2,0xF4,0x09,0x26,0x22,0xFE,0xCA,0x70,0x1B,0xE4, | ||
1726 | 0xF5,0x0F,0x47,0x58,0x71,0x4E,0x8A,0x87,0xBB,0xF2, | ||
1727 | 0xA6,0x58,0xEF,0x8C,0x21,0xE7,0xC5,0xEF,0xE9,0x65, | ||
1728 | 0x36,0x1F,0x6C,0x29,0x99,0xC0,0xC2,0x47,0xB0,0xDB, | ||
1729 | 0xD7,0x0C,0xE6,0xB7, | ||
1730 | 0x20,0xD0,0xAF,0x89,0x03,0xA9,0x6F,0x8D,0x5F,0xA2, /* y */ | ||
1731 | 0xC2,0x55,0x74,0x5D,0x3C,0x45,0x1B,0x30,0x2C,0x93, | ||
1732 | 0x46,0xD9,0xB7,0xE4,0x85,0xE7,0xBC,0xE4,0x1F,0x6B, | ||
1733 | 0x59,0x1F,0x3E,0x8F,0x6A,0xDD,0xCB,0xB0,0xBC,0x4C, | ||
1734 | 0x2F,0x94,0x7A,0x7D,0xE1,0xA8,0x9B,0x62,0x5D,0x6A, | ||
1735 | 0x59,0x8B,0x37,0x60, | ||
1736 | 0x00,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34, /* order */ | ||
1737 | 0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03, | ||
1738 | 0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x23, | ||
1739 | 0xC3,0x13,0xFA,0xB5,0x05,0x89,0x70,0x3B,0x5E,0xC6, | ||
1740 | 0x8D,0x35,0x87,0xFE,0xC6,0x0D,0x16,0x1C,0xC1,0x49, | ||
1741 | 0xC1,0xAD,0x4A,0x91 } | ||
984 | }; | 1742 | }; |
985 | 1743 | ||
986 | static const EC_CURVE_DATA _EC_WTLS_1 = { | 1744 | static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; } |
987 | NID_X9_62_characteristic_two_field, | 1745 | _EC_WTLS_1 = { |
988 | "020000000000000000000000000201", | 1746 | { NID_X9_62_characteristic_two_field,0,15,2 }, |
989 | "1", | 1747 | { /* no seed */ |
990 | "1", | 1748 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
991 | "01667979A40BA497E5D5C270780617", | 1749 | 0x00,0x00,0x00,0x02,0x01, |
992 | "00F44B4AF1ECC2630E08785CEBCC15", | 1750 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
993 | "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2, | 1751 | 0x00,0x00,0x00,0x00,0x01, |
994 | NULL, 0, | 1752 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ |
995 | "WTLS curve over a 113 bit binary field" | 1753 | 0x00,0x00,0x00,0x00,0x01, |
1754 | 0x01,0x66,0x79,0x79,0xA4,0x0B,0xA4,0x97,0xE5,0xD5, /* x */ | ||
1755 | 0xC2,0x70,0x78,0x06,0x17, | ||
1756 | 0x00,0xF4,0x4B,0x4A,0xF1,0xEC,0xC2,0x63,0x0E,0x08, /* y */ | ||
1757 | 0x78,0x5C,0xEB,0xCC,0x15, | ||
1758 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF, /* order */ | ||
1759 | 0x91,0xAF,0x6D,0xEA,0x73 } | ||
996 | }; | 1760 | }; |
997 | 1761 | ||
998 | /* IPSec curves */ | 1762 | /* IPSec curves */ |
@@ -1001,17 +1765,27 @@ static const EC_CURVE_DATA _EC_WTLS_1 = { | |||
1001 | * As the group order is not a prime this curve is not suitable | 1765 | * As the group order is not a prime this curve is not suitable |
1002 | * for ECDSA. | 1766 | * for ECDSA. |
1003 | */ | 1767 | */ |
1004 | static const EC_CURVE_DATA _EC_IPSEC_155_ID3 = { | 1768 | static const struct { EC_CURVE_DATA h; unsigned char data[0+20*6]; } |
1005 | NID_X9_62_characteristic_two_field, | 1769 | _EC_IPSEC_155_ID3 = { |
1006 | "0800000000000000000000004000000000000001", | 1770 | { NID_X9_62_characteristic_two_field,0,20,3 }, |
1007 | "0", | 1771 | { /* no seed */ |
1008 | "07338f", | 1772 | 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
1009 | "7b", | 1773 | 0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
1010 | "1c8", | 1774 | |
1011 | "2AAAAAAAAAAAAAAAAAAC7F3C7881BD0868FA86C",3, | 1775 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
1012 | NULL, 0, | 1776 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
1013 | "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n" | 1777 | |
1014 | "\tNot suitable for ECDSA.\n\tQuestionable extension field!" | 1778 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ |
1779 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x33,0x8f, | ||
1780 | |||
1781 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */ | ||
1782 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b, | ||
1783 | |||
1784 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */ | ||
1785 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc8, | ||
1786 | |||
1787 | 0x02,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, /* order */ | ||
1788 | 0xC7,0xF3,0xC7,0x88,0x1B,0xD0,0x86,0x8F,0xA8,0x6C } | ||
1015 | }; | 1789 | }; |
1016 | 1790 | ||
1017 | /* NOTE: The of curves over a extension field of non prime degree | 1791 | /* NOTE: The of curves over a extension field of non prime degree |
@@ -1019,106 +1793,118 @@ static const EC_CURVE_DATA _EC_IPSEC_155_ID3 = { | |||
1019 | * As the group order is not a prime this curve is not suitable | 1793 | * As the group order is not a prime this curve is not suitable |
1020 | * for ECDSA. | 1794 | * for ECDSA. |
1021 | */ | 1795 | */ |
1022 | static const EC_CURVE_DATA _EC_IPSEC_185_ID4 = { | 1796 | static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; } |
1023 | NID_X9_62_characteristic_two_field, | 1797 | _EC_IPSEC_185_ID4 = { |
1024 | "020000000000000000000000000000200000000000000001", | 1798 | { NID_X9_62_characteristic_two_field,0,24,2 }, |
1025 | "0", | 1799 | { /* no seed */ |
1026 | "1ee9", | 1800 | 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */ |
1027 | "18", | 1801 | 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00, |
1028 | "0d", | 1802 | 0x00,0x00,0x00,0x01, |
1029 | "FFFFFFFFFFFFFFFFFFFFFFEDF97C44DB9F2420BAFCA75E",2, | 1803 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */ |
1030 | NULL, 0, | 1804 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
1031 | "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n" | 1805 | 0x00,0x00,0x00,0x00, |
1032 | "\tNot suitable for ECDSA.\n\tQuestionable extension field!" | 1806 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */ |
1807 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1808 | 0x00,0x00,0x1e,0xe9, | ||
1809 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */ | ||
1810 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1811 | 0x00,0x00,0x00,0x18, | ||
1812 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */ | ||
1813 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
1814 | 0x00,0x00,0x00,0x0d, | ||
1815 | 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */ | ||
1816 | 0xFF,0xFF,0xED,0xF9,0x7C,0x44,0xDB,0x9F,0x24,0x20, | ||
1817 | 0xBA,0xFC,0xA7,0x5E } | ||
1033 | }; | 1818 | }; |
1034 | 1819 | ||
1035 | typedef struct _ec_list_element_st { | 1820 | typedef struct _ec_list_element_st { |
1036 | int nid; | 1821 | int nid; |
1037 | const EC_CURVE_DATA *data; | 1822 | const EC_CURVE_DATA *data; |
1823 | const char *comment; | ||
1038 | } ec_list_element; | 1824 | } ec_list_element; |
1039 | 1825 | ||
1040 | static const ec_list_element curve_list[] = { | 1826 | static const ec_list_element curve_list[] = { |
1041 | /* prime field curves */ | 1827 | /* prime field curves */ |
1042 | /* secg curves */ | 1828 | /* secg curves */ |
1043 | { NID_secp112r1, &_EC_SECG_PRIME_112R1}, | 1829 | { NID_secp112r1, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"}, |
1044 | { NID_secp112r2, &_EC_SECG_PRIME_112R2}, | 1830 | { NID_secp112r2, &_EC_SECG_PRIME_112R2.h, "SECG curve over a 112 bit prime field"}, |
1045 | { NID_secp128r1, &_EC_SECG_PRIME_128R1}, | 1831 | { NID_secp128r1, &_EC_SECG_PRIME_128R1.h, "SECG curve over a 128 bit prime field"}, |
1046 | { NID_secp128r2, &_EC_SECG_PRIME_128R2}, | 1832 | { NID_secp128r2, &_EC_SECG_PRIME_128R2.h, "SECG curve over a 128 bit prime field"}, |
1047 | { NID_secp160k1, &_EC_SECG_PRIME_160K1}, | 1833 | { NID_secp160k1, &_EC_SECG_PRIME_160K1.h, "SECG curve over a 160 bit prime field"}, |
1048 | { NID_secp160r1, &_EC_SECG_PRIME_160R1}, | 1834 | { NID_secp160r1, &_EC_SECG_PRIME_160R1.h, "SECG curve over a 160 bit prime field"}, |
1049 | { NID_secp160r2, &_EC_SECG_PRIME_160R2}, | 1835 | { NID_secp160r2, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"}, |
1050 | /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ | 1836 | /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ |
1051 | { NID_secp192k1, &_EC_SECG_PRIME_192K1}, | 1837 | { NID_secp192k1, &_EC_SECG_PRIME_192K1.h, "SECG curve over a 192 bit prime field"}, |
1052 | { NID_secp224k1, &_EC_SECG_PRIME_224K1}, | 1838 | { NID_secp224k1, &_EC_SECG_PRIME_224K1.h, "SECG curve over a 224 bit prime field"}, |
1053 | { NID_secp224r1, &_EC_NIST_PRIME_224}, | 1839 | { NID_secp224r1, &_EC_NIST_PRIME_224.h, "NIST/SECG curve over a 224 bit prime field"}, |
1054 | { NID_secp256k1, &_EC_SECG_PRIME_256K1}, | 1840 | { NID_secp256k1, &_EC_SECG_PRIME_256K1.h, "SECG curve over a 256 bit prime field"}, |
1055 | /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ | 1841 | /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ |
1056 | { NID_secp384r1, &_EC_NIST_PRIME_384}, | 1842 | { NID_secp384r1, &_EC_NIST_PRIME_384.h, "NIST/SECG curve over a 384 bit prime field"}, |
1057 | { NID_secp521r1, &_EC_NIST_PRIME_521}, | 1843 | { NID_secp521r1, &_EC_NIST_PRIME_521.h, "NIST/SECG curve over a 521 bit prime field"}, |
1058 | /* X9.62 curves */ | 1844 | /* X9.62 curves */ |
1059 | { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192}, | 1845 | { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, "NIST/X9.62/SECG curve over a 192 bit prime field"}, |
1060 | { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2}, | 1846 | { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, "X9.62 curve over a 192 bit prime field"}, |
1061 | { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3}, | 1847 | { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, "X9.62 curve over a 192 bit prime field"}, |
1062 | { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1}, | 1848 | { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, "X9.62 curve over a 239 bit prime field"}, |
1063 | { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2}, | 1849 | { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, "X9.62 curve over a 239 bit prime field"}, |
1064 | { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3}, | 1850 | { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, "X9.62 curve over a 239 bit prime field"}, |
1065 | { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1}, | 1851 | { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, "X9.62/SECG curve over a 256 bit prime field"}, |
1066 | /* characteristic two field curves */ | 1852 | /* characteristic two field curves */ |
1067 | /* NIST/SECG curves */ | 1853 | /* NIST/SECG curves */ |
1068 | { NID_sect113r1, &_EC_SECG_CHAR2_113R1}, | 1854 | { NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"}, |
1069 | { NID_sect113r2, &_EC_SECG_CHAR2_113R2}, | 1855 | { NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, "SECG curve over a 113 bit binary field"}, |
1070 | { NID_sect131r1, &_EC_SECG_CHAR2_131R1}, | 1856 | { NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, "SECG/WTLS curve over a 131 bit binary field"}, |
1071 | { NID_sect131r2, &_EC_SECG_CHAR2_131R2}, | 1857 | { NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, "SECG curve over a 131 bit binary field"}, |
1072 | { NID_sect163k1, &_EC_NIST_CHAR2_163K }, | 1858 | { NID_sect163k1, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field" }, |
1073 | { NID_sect163r1, &_EC_SECG_CHAR2_163R1}, | 1859 | { NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, "SECG curve over a 163 bit binary field"}, |
1074 | { NID_sect163r2, &_EC_NIST_CHAR2_163B }, | 1860 | { NID_sect163r2, &_EC_NIST_CHAR2_163B.h, "NIST/SECG curve over a 163 bit binary field" }, |
1075 | { NID_sect193r1, &_EC_SECG_CHAR2_193R1}, | 1861 | { NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, "SECG curve over a 193 bit binary field"}, |
1076 | { NID_sect193r2, &_EC_SECG_CHAR2_193R2}, | 1862 | { NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, "SECG curve over a 193 bit binary field"}, |
1077 | { NID_sect233k1, &_EC_NIST_CHAR2_233K }, | 1863 | { NID_sect233k1, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field" }, |
1078 | { NID_sect233r1, &_EC_NIST_CHAR2_233B }, | 1864 | { NID_sect233r1, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field" }, |
1079 | { NID_sect239k1, &_EC_SECG_CHAR2_239K1}, | 1865 | { NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, "SECG curve over a 239 bit binary field"}, |
1080 | { NID_sect283k1, &_EC_NIST_CHAR2_283K }, | 1866 | { NID_sect283k1, &_EC_NIST_CHAR2_283K.h, "NIST/SECG curve over a 283 bit binary field" }, |
1081 | { NID_sect283r1, &_EC_NIST_CHAR2_283B }, | 1867 | { NID_sect283r1, &_EC_NIST_CHAR2_283B.h, "NIST/SECG curve over a 283 bit binary field" }, |
1082 | { NID_sect409k1, &_EC_NIST_CHAR2_409K }, | 1868 | { NID_sect409k1, &_EC_NIST_CHAR2_409K.h, "NIST/SECG curve over a 409 bit binary field" }, |
1083 | { NID_sect409r1, &_EC_NIST_CHAR2_409B }, | 1869 | { NID_sect409r1, &_EC_NIST_CHAR2_409B.h, "NIST/SECG curve over a 409 bit binary field" }, |
1084 | { NID_sect571k1, &_EC_NIST_CHAR2_571K }, | 1870 | { NID_sect571k1, &_EC_NIST_CHAR2_571K.h, "NIST/SECG curve over a 571 bit binary field" }, |
1085 | { NID_sect571r1, &_EC_NIST_CHAR2_571B }, | 1871 | { NID_sect571r1, &_EC_NIST_CHAR2_571B.h, "NIST/SECG curve over a 571 bit binary field" }, |
1086 | /* X9.62 curves */ | 1872 | /* X9.62 curves */ |
1087 | { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1}, | 1873 | { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"}, |
1088 | { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2}, | 1874 | { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, "X9.62 curve over a 163 bit binary field"}, |
1089 | { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3}, | 1875 | { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, "X9.62 curve over a 163 bit binary field"}, |
1090 | { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1}, | 1876 | { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, "X9.62 curve over a 176 bit binary field"}, |
1091 | { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1}, | 1877 | { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, "X9.62 curve over a 191 bit binary field"}, |
1092 | { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2}, | 1878 | { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, "X9.62 curve over a 191 bit binary field"}, |
1093 | { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3}, | 1879 | { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, "X9.62 curve over a 191 bit binary field"}, |
1094 | { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1}, | 1880 | { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, "X9.62 curve over a 208 bit binary field"}, |
1095 | { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1}, | 1881 | { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, "X9.62 curve over a 239 bit binary field"}, |
1096 | { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2}, | 1882 | { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, "X9.62 curve over a 239 bit binary field"}, |
1097 | { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3}, | 1883 | { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, "X9.62 curve over a 239 bit binary field"}, |
1098 | { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1}, | 1884 | { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, "X9.62 curve over a 272 bit binary field"}, |
1099 | { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1}, | 1885 | { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, "X9.62 curve over a 304 bit binary field"}, |
1100 | { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1}, | 1886 | { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, "X9.62 curve over a 359 bit binary field"}, |
1101 | { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1}, | 1887 | { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, "X9.62 curve over a 368 bit binary field"}, |
1102 | { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1}, | 1888 | { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, "X9.62 curve over a 431 bit binary field"}, |
1103 | /* the WAP/WTLS curves | 1889 | /* the WAP/WTLS curves |
1104 | * [unlike SECG, spec has its own OIDs for curves from X9.62] */ | 1890 | * [unlike SECG, spec has its own OIDs for curves from X9.62] */ |
1105 | { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1}, | 1891 | { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, "WTLS curve over a 113 bit binary field"}, |
1106 | { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K}, | 1892 | { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field"}, |
1107 | { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1}, | 1893 | { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"}, |
1108 | { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1}, | 1894 | { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"}, |
1109 | { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1}, | 1895 | { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"}, |
1110 | { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2}, | 1896 | { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"}, |
1111 | { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8}, | 1897 | { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, "WTLS curve over a 112 bit prime field"}, |
1112 | { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9 }, | 1898 | { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, "WTLS curve over a 160 bit prime field" }, |
1113 | { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K}, | 1899 | { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field"}, |
1114 | { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B}, | 1900 | { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field"}, |
1115 | { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12}, | 1901 | { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, "WTLS curvs over a 224 bit prime field"}, |
1116 | /* IPSec curves */ | 1902 | /* IPSec curves */ |
1117 | { NID_ipsec3, &_EC_IPSEC_155_ID3}, | 1903 | { NID_ipsec3, &_EC_IPSEC_155_ID3.h, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, |
1118 | { NID_ipsec4, &_EC_IPSEC_185_ID4}, | 1904 | { NID_ipsec4, &_EC_IPSEC_185_ID4.h, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, |
1119 | }; | 1905 | }; |
1120 | 1906 | ||
1121 | static size_t curve_list_length = sizeof(curve_list)/sizeof(ec_list_element); | 1907 | #define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element)) |
1122 | 1908 | ||
1123 | static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) | 1909 | static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) |
1124 | { | 1910 | { |
@@ -1127,22 +1913,23 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) | |||
1127 | BN_CTX *ctx=NULL; | 1913 | BN_CTX *ctx=NULL; |
1128 | BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL; | 1914 | BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL; |
1129 | int ok=0; | 1915 | int ok=0; |
1916 | int seed_len,param_len; | ||
1917 | const unsigned char *params; | ||
1130 | 1918 | ||
1131 | if ((ctx = BN_CTX_new()) == NULL) | 1919 | if ((ctx = BN_CTX_new()) == NULL) |
1132 | { | 1920 | { |
1133 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); | 1921 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); |
1134 | goto err; | 1922 | goto err; |
1135 | } | 1923 | } |
1136 | if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || | 1924 | |
1137 | (b = BN_new()) == NULL || (x = BN_new()) == NULL || | 1925 | seed_len = data->seed_len; |
1138 | (y = BN_new()) == NULL || (order = BN_new()) == NULL) | 1926 | param_len = data->param_len; |
1139 | { | 1927 | params = (const unsigned char *)(data+1); /* skip header */ |
1140 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); | 1928 | params += seed_len; /* skip seed */ |
1141 | goto err; | 1929 | |
1142 | } | 1930 | if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL)) |
1143 | 1931 | || !(a = BN_bin2bn(params+1*param_len, param_len, NULL)) | |
1144 | if (!BN_hex2bn(&p, data->p) || !BN_hex2bn(&a, data->a) | 1932 | || !(b = BN_bin2bn(params+2*param_len, param_len, NULL))) |
1145 | || !BN_hex2bn(&b, data->b)) | ||
1146 | { | 1933 | { |
1147 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); | 1934 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); |
1148 | goto err; | 1935 | goto err; |
@@ -1156,8 +1943,8 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) | |||
1156 | goto err; | 1943 | goto err; |
1157 | } | 1944 | } |
1158 | } | 1945 | } |
1159 | else | 1946 | else /* field_type == NID_X9_62_characteristic_two_field */ |
1160 | { /* field_type == NID_X9_62_characteristic_two_field */ | 1947 | { |
1161 | if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) | 1948 | if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) |
1162 | { | 1949 | { |
1163 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | 1950 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); |
@@ -1171,7 +1958,8 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) | |||
1171 | goto err; | 1958 | goto err; |
1172 | } | 1959 | } |
1173 | 1960 | ||
1174 | if (!BN_hex2bn(&x, data->x) || !BN_hex2bn(&y, data->y)) | 1961 | if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL)) |
1962 | || !(y = BN_bin2bn(params+4*param_len, param_len, NULL))) | ||
1175 | { | 1963 | { |
1176 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); | 1964 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); |
1177 | goto err; | 1965 | goto err; |
@@ -1181,7 +1969,8 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) | |||
1181 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | 1969 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); |
1182 | goto err; | 1970 | goto err; |
1183 | } | 1971 | } |
1184 | if (!BN_hex2bn(&order, data->order) || !BN_set_word(x, data->cofactor)) | 1972 | if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL)) |
1973 | || !BN_set_word(x, (BN_ULONG)data->cofactor)) | ||
1185 | { | 1974 | { |
1186 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); | 1975 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); |
1187 | goto err; | 1976 | goto err; |
@@ -1191,9 +1980,9 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) | |||
1191 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | 1980 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); |
1192 | goto err; | 1981 | goto err; |
1193 | } | 1982 | } |
1194 | if (data->seed) | 1983 | if (seed_len) |
1195 | { | 1984 | { |
1196 | if (!EC_GROUP_set_seed(group, data->seed, data->seed_len)) | 1985 | if (!EC_GROUP_set_seed(group, params-seed_len, seed_len)) |
1197 | { | 1986 | { |
1198 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | 1987 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); |
1199 | goto err; | 1988 | goto err; |
@@ -1263,7 +2052,7 @@ size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) | |||
1263 | for (i = 0; i < min; i++) | 2052 | for (i = 0; i < min; i++) |
1264 | { | 2053 | { |
1265 | r[i].nid = curve_list[i].nid; | 2054 | r[i].nid = curve_list[i].nid; |
1266 | r[i].comment = curve_list[i].data->comment; | 2055 | r[i].comment = curve_list[i].comment; |
1267 | } | 2056 | } |
1268 | 2057 | ||
1269 | return curve_list_length; | 2058 | return curve_list_length; |
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c new file mode 100644 index 0000000000..f433076ca1 --- /dev/null +++ b/src/lib/libcrypto/ec/ec_pmeth.c | |||
@@ -0,0 +1,340 @@ | |||
1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
2 | * project 2006. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <stdio.h> | ||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/asn1t.h> | ||
61 | #include <openssl/x509.h> | ||
62 | #include <openssl/ec.h> | ||
63 | #include <openssl/ecdsa.h> | ||
64 | #include <openssl/evp.h> | ||
65 | #include "evp_locl.h" | ||
66 | |||
67 | /* EC pkey context structure */ | ||
68 | |||
69 | typedef struct | ||
70 | { | ||
71 | /* Key and paramgen group */ | ||
72 | EC_GROUP *gen_group; | ||
73 | /* message digest */ | ||
74 | const EVP_MD *md; | ||
75 | } EC_PKEY_CTX; | ||
76 | |||
77 | static int pkey_ec_init(EVP_PKEY_CTX *ctx) | ||
78 | { | ||
79 | EC_PKEY_CTX *dctx; | ||
80 | dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX)); | ||
81 | if (!dctx) | ||
82 | return 0; | ||
83 | dctx->gen_group = NULL; | ||
84 | dctx->md = NULL; | ||
85 | |||
86 | ctx->data = dctx; | ||
87 | |||
88 | return 1; | ||
89 | } | ||
90 | |||
91 | static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | ||
92 | { | ||
93 | EC_PKEY_CTX *dctx, *sctx; | ||
94 | if (!pkey_ec_init(dst)) | ||
95 | return 0; | ||
96 | sctx = src->data; | ||
97 | dctx = dst->data; | ||
98 | if (sctx->gen_group) | ||
99 | { | ||
100 | dctx->gen_group = EC_GROUP_dup(sctx->gen_group); | ||
101 | if (!dctx->gen_group) | ||
102 | return 0; | ||
103 | } | ||
104 | dctx->md = sctx->md; | ||
105 | return 1; | ||
106 | } | ||
107 | |||
108 | static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) | ||
109 | { | ||
110 | EC_PKEY_CTX *dctx = ctx->data; | ||
111 | if (dctx) | ||
112 | { | ||
113 | if (dctx->gen_group) | ||
114 | EC_GROUP_free(dctx->gen_group); | ||
115 | OPENSSL_free(dctx); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, | ||
120 | const unsigned char *tbs, size_t tbslen) | ||
121 | { | ||
122 | int ret, type; | ||
123 | unsigned int sltmp; | ||
124 | EC_PKEY_CTX *dctx = ctx->data; | ||
125 | EC_KEY *ec = ctx->pkey->pkey.ec; | ||
126 | |||
127 | if (!sig) | ||
128 | { | ||
129 | *siglen = ECDSA_size(ec); | ||
130 | return 1; | ||
131 | } | ||
132 | else if(*siglen < (size_t)ECDSA_size(ec)) | ||
133 | { | ||
134 | ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | if (dctx->md) | ||
139 | type = EVP_MD_type(dctx->md); | ||
140 | else | ||
141 | type = NID_sha1; | ||
142 | |||
143 | |||
144 | ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); | ||
145 | |||
146 | if (ret <= 0) | ||
147 | return ret; | ||
148 | *siglen = (size_t)sltmp; | ||
149 | return 1; | ||
150 | } | ||
151 | |||
152 | static int pkey_ec_verify(EVP_PKEY_CTX *ctx, | ||
153 | const unsigned char *sig, size_t siglen, | ||
154 | const unsigned char *tbs, size_t tbslen) | ||
155 | { | ||
156 | int ret, type; | ||
157 | EC_PKEY_CTX *dctx = ctx->data; | ||
158 | EC_KEY *ec = ctx->pkey->pkey.ec; | ||
159 | |||
160 | if (dctx->md) | ||
161 | type = EVP_MD_type(dctx->md); | ||
162 | else | ||
163 | type = NID_sha1; | ||
164 | |||
165 | ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); | ||
166 | |||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) | ||
171 | { | ||
172 | int ret; | ||
173 | size_t outlen; | ||
174 | const EC_POINT *pubkey = NULL; | ||
175 | if (!ctx->pkey || !ctx->peerkey) | ||
176 | { | ||
177 | ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | if (!key) | ||
182 | { | ||
183 | const EC_GROUP *group; | ||
184 | group = EC_KEY_get0_group(ctx->pkey->pkey.ec); | ||
185 | *keylen = (EC_GROUP_get_degree(group) + 7)/8; | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); | ||
190 | |||
191 | /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is | ||
192 | * not an error, the result is truncated. | ||
193 | */ | ||
194 | |||
195 | outlen = *keylen; | ||
196 | |||
197 | ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0); | ||
198 | if (ret < 0) | ||
199 | return ret; | ||
200 | *keylen = ret; | ||
201 | return 1; | ||
202 | } | ||
203 | |||
204 | static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | ||
205 | { | ||
206 | EC_PKEY_CTX *dctx = ctx->data; | ||
207 | EC_GROUP *group; | ||
208 | switch (type) | ||
209 | { | ||
210 | case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: | ||
211 | group = EC_GROUP_new_by_curve_name(p1); | ||
212 | if (group == NULL) | ||
213 | { | ||
214 | ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); | ||
215 | return 0; | ||
216 | } | ||
217 | if (dctx->gen_group) | ||
218 | EC_GROUP_free(dctx->gen_group); | ||
219 | dctx->gen_group = group; | ||
220 | return 1; | ||
221 | |||
222 | case EVP_PKEY_CTRL_MD: | ||
223 | if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && | ||
224 | EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && | ||
225 | EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && | ||
226 | EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && | ||
227 | EVP_MD_type((const EVP_MD *)p2) != NID_sha512) | ||
228 | { | ||
229 | ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); | ||
230 | return 0; | ||
231 | } | ||
232 | dctx->md = p2; | ||
233 | return 1; | ||
234 | |||
235 | case EVP_PKEY_CTRL_PEER_KEY: | ||
236 | /* Default behaviour is OK */ | ||
237 | case EVP_PKEY_CTRL_DIGESTINIT: | ||
238 | case EVP_PKEY_CTRL_PKCS7_SIGN: | ||
239 | case EVP_PKEY_CTRL_CMS_SIGN: | ||
240 | return 1; | ||
241 | |||
242 | default: | ||
243 | return -2; | ||
244 | |||
245 | } | ||
246 | } | ||
247 | |||
248 | static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, | ||
249 | const char *type, const char *value) | ||
250 | { | ||
251 | if (!strcmp(type, "ec_paramgen_curve")) | ||
252 | { | ||
253 | int nid; | ||
254 | nid = OBJ_sn2nid(value); | ||
255 | if (nid == NID_undef) | ||
256 | nid = OBJ_ln2nid(value); | ||
257 | if (nid == NID_undef) | ||
258 | { | ||
259 | ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE); | ||
260 | return 0; | ||
261 | } | ||
262 | return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); | ||
263 | } | ||
264 | return -2; | ||
265 | } | ||
266 | |||
267 | static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
268 | { | ||
269 | EC_KEY *ec = NULL; | ||
270 | EC_PKEY_CTX *dctx = ctx->data; | ||
271 | int ret = 0; | ||
272 | if (dctx->gen_group == NULL) | ||
273 | { | ||
274 | ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); | ||
275 | return 0; | ||
276 | } | ||
277 | ec = EC_KEY_new(); | ||
278 | if (!ec) | ||
279 | return 0; | ||
280 | ret = EC_KEY_set_group(ec, dctx->gen_group); | ||
281 | if (ret) | ||
282 | EVP_PKEY_assign_EC_KEY(pkey, ec); | ||
283 | else | ||
284 | EC_KEY_free(ec); | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
289 | { | ||
290 | EC_KEY *ec = NULL; | ||
291 | if (ctx->pkey == NULL) | ||
292 | { | ||
293 | ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); | ||
294 | return 0; | ||
295 | } | ||
296 | ec = EC_KEY_new(); | ||
297 | if (!ec) | ||
298 | return 0; | ||
299 | EVP_PKEY_assign_EC_KEY(pkey, ec); | ||
300 | /* Note: if error return, pkey is freed by parent routine */ | ||
301 | if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) | ||
302 | return 0; | ||
303 | return EC_KEY_generate_key(pkey->pkey.ec); | ||
304 | } | ||
305 | |||
306 | const EVP_PKEY_METHOD ec_pkey_meth = | ||
307 | { | ||
308 | EVP_PKEY_EC, | ||
309 | 0, | ||
310 | pkey_ec_init, | ||
311 | pkey_ec_copy, | ||
312 | pkey_ec_cleanup, | ||
313 | |||
314 | 0, | ||
315 | pkey_ec_paramgen, | ||
316 | |||
317 | 0, | ||
318 | pkey_ec_keygen, | ||
319 | |||
320 | 0, | ||
321 | pkey_ec_sign, | ||
322 | |||
323 | 0, | ||
324 | pkey_ec_verify, | ||
325 | |||
326 | 0,0, | ||
327 | |||
328 | 0,0,0,0, | ||
329 | |||
330 | 0,0, | ||
331 | |||
332 | 0,0, | ||
333 | |||
334 | 0, | ||
335 | pkey_ec_derive, | ||
336 | |||
337 | pkey_ec_ctrl, | ||
338 | pkey_ec_ctrl_str | ||
339 | |||
340 | }; | ||
diff --git a/src/lib/libcrypto/ec/eck_prn.c b/src/lib/libcrypto/ec/eck_prn.c new file mode 100644 index 0000000000..7d3e175ae7 --- /dev/null +++ b/src/lib/libcrypto/ec/eck_prn.c | |||
@@ -0,0 +1,391 @@ | |||
1 | /* crypto/ec/eck_prn.c */ | ||
2 | /* | ||
3 | * Written by Nils Larsch for the OpenSSL project. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * openssl-core@openssl.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | /* ==================================================================== | ||
59 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
60 | * Portions originally developed by SUN MICROSYSTEMS, INC., and | ||
61 | * contributed to the OpenSSL project. | ||
62 | */ | ||
63 | |||
64 | #include <stdio.h> | ||
65 | #include "cryptlib.h" | ||
66 | #include <openssl/evp.h> | ||
67 | #include <openssl/ec.h> | ||
68 | #include <openssl/bn.h> | ||
69 | |||
70 | #ifndef OPENSSL_NO_FP_API | ||
71 | int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) | ||
72 | { | ||
73 | BIO *b; | ||
74 | int ret; | ||
75 | |||
76 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
77 | { | ||
78 | ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB); | ||
79 | return(0); | ||
80 | } | ||
81 | BIO_set_fp(b, fp, BIO_NOCLOSE); | ||
82 | ret = ECPKParameters_print(b, x, off); | ||
83 | BIO_free(b); | ||
84 | return(ret); | ||
85 | } | ||
86 | |||
87 | int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) | ||
88 | { | ||
89 | BIO *b; | ||
90 | int ret; | ||
91 | |||
92 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
93 | { | ||
94 | ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); | ||
95 | return(0); | ||
96 | } | ||
97 | BIO_set_fp(b, fp, BIO_NOCLOSE); | ||
98 | ret = EC_KEY_print(b, x, off); | ||
99 | BIO_free(b); | ||
100 | return(ret); | ||
101 | } | ||
102 | |||
103 | int ECParameters_print_fp(FILE *fp, const EC_KEY *x) | ||
104 | { | ||
105 | BIO *b; | ||
106 | int ret; | ||
107 | |||
108 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
109 | { | ||
110 | ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); | ||
111 | return(0); | ||
112 | } | ||
113 | BIO_set_fp(b, fp, BIO_NOCLOSE); | ||
114 | ret = ECParameters_print(b, x); | ||
115 | BIO_free(b); | ||
116 | return(ret); | ||
117 | } | ||
118 | #endif | ||
119 | |||
120 | int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) | ||
121 | { | ||
122 | EVP_PKEY *pk; | ||
123 | int ret; | ||
124 | pk = EVP_PKEY_new(); | ||
125 | if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) | ||
126 | return 0; | ||
127 | ret = EVP_PKEY_print_private(bp, pk, off, NULL); | ||
128 | EVP_PKEY_free(pk); | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | int ECParameters_print(BIO *bp, const EC_KEY *x) | ||
133 | { | ||
134 | EVP_PKEY *pk; | ||
135 | int ret; | ||
136 | pk = EVP_PKEY_new(); | ||
137 | if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) | ||
138 | return 0; | ||
139 | ret = EVP_PKEY_print_params(bp, pk, 4, NULL); | ||
140 | EVP_PKEY_free(pk); | ||
141 | return ret; | ||
142 | } | ||
143 | |||
144 | static int print_bin(BIO *fp, const char *str, const unsigned char *num, | ||
145 | size_t len, int off); | ||
146 | |||
147 | int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) | ||
148 | { | ||
149 | unsigned char *buffer=NULL; | ||
150 | size_t buf_len=0, i; | ||
151 | int ret=0, reason=ERR_R_BIO_LIB; | ||
152 | BN_CTX *ctx=NULL; | ||
153 | const EC_POINT *point=NULL; | ||
154 | BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL, | ||
155 | *order=NULL, *cofactor=NULL; | ||
156 | const unsigned char *seed; | ||
157 | size_t seed_len=0; | ||
158 | |||
159 | static const char *gen_compressed = "Generator (compressed):"; | ||
160 | static const char *gen_uncompressed = "Generator (uncompressed):"; | ||
161 | static const char *gen_hybrid = "Generator (hybrid):"; | ||
162 | |||
163 | if (!x) | ||
164 | { | ||
165 | reason = ERR_R_PASSED_NULL_PARAMETER; | ||
166 | goto err; | ||
167 | } | ||
168 | |||
169 | ctx = BN_CTX_new(); | ||
170 | if (ctx == NULL) | ||
171 | { | ||
172 | reason = ERR_R_MALLOC_FAILURE; | ||
173 | goto err; | ||
174 | } | ||
175 | |||
176 | if (EC_GROUP_get_asn1_flag(x)) | ||
177 | { | ||
178 | /* the curve parameter are given by an asn1 OID */ | ||
179 | int nid; | ||
180 | |||
181 | if (!BIO_indent(bp, off, 128)) | ||
182 | goto err; | ||
183 | |||
184 | nid = EC_GROUP_get_curve_name(x); | ||
185 | if (nid == 0) | ||
186 | goto err; | ||
187 | |||
188 | if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) | ||
189 | goto err; | ||
190 | if (BIO_printf(bp, "\n") <= 0) | ||
191 | goto err; | ||
192 | } | ||
193 | else | ||
194 | { | ||
195 | /* explicit parameters */ | ||
196 | int is_char_two = 0; | ||
197 | point_conversion_form_t form; | ||
198 | int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); | ||
199 | |||
200 | if (tmp_nid == NID_X9_62_characteristic_two_field) | ||
201 | is_char_two = 1; | ||
202 | |||
203 | if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || | ||
204 | (b = BN_new()) == NULL || (order = BN_new()) == NULL || | ||
205 | (cofactor = BN_new()) == NULL) | ||
206 | { | ||
207 | reason = ERR_R_MALLOC_FAILURE; | ||
208 | goto err; | ||
209 | } | ||
210 | |||
211 | if (is_char_two) | ||
212 | { | ||
213 | if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) | ||
214 | { | ||
215 | reason = ERR_R_EC_LIB; | ||
216 | goto err; | ||
217 | } | ||
218 | } | ||
219 | else /* prime field */ | ||
220 | { | ||
221 | if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) | ||
222 | { | ||
223 | reason = ERR_R_EC_LIB; | ||
224 | goto err; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | if ((point = EC_GROUP_get0_generator(x)) == NULL) | ||
229 | { | ||
230 | reason = ERR_R_EC_LIB; | ||
231 | goto err; | ||
232 | } | ||
233 | if (!EC_GROUP_get_order(x, order, NULL) || | ||
234 | !EC_GROUP_get_cofactor(x, cofactor, NULL)) | ||
235 | { | ||
236 | reason = ERR_R_EC_LIB; | ||
237 | goto err; | ||
238 | } | ||
239 | |||
240 | form = EC_GROUP_get_point_conversion_form(x); | ||
241 | |||
242 | if ((gen = EC_POINT_point2bn(x, point, | ||
243 | form, NULL, ctx)) == NULL) | ||
244 | { | ||
245 | reason = ERR_R_EC_LIB; | ||
246 | goto err; | ||
247 | } | ||
248 | |||
249 | buf_len = (size_t)BN_num_bytes(p); | ||
250 | if (buf_len < (i = (size_t)BN_num_bytes(a))) | ||
251 | buf_len = i; | ||
252 | if (buf_len < (i = (size_t)BN_num_bytes(b))) | ||
253 | buf_len = i; | ||
254 | if (buf_len < (i = (size_t)BN_num_bytes(gen))) | ||
255 | buf_len = i; | ||
256 | if (buf_len < (i = (size_t)BN_num_bytes(order))) | ||
257 | buf_len = i; | ||
258 | if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) | ||
259 | buf_len = i; | ||
260 | |||
261 | if ((seed = EC_GROUP_get0_seed(x)) != NULL) | ||
262 | seed_len = EC_GROUP_get_seed_len(x); | ||
263 | |||
264 | buf_len += 10; | ||
265 | if ((buffer = OPENSSL_malloc(buf_len)) == NULL) | ||
266 | { | ||
267 | reason = ERR_R_MALLOC_FAILURE; | ||
268 | goto err; | ||
269 | } | ||
270 | |||
271 | if (!BIO_indent(bp, off, 128)) | ||
272 | goto err; | ||
273 | |||
274 | /* print the 'short name' of the field type */ | ||
275 | if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) | ||
276 | <= 0) | ||
277 | goto err; | ||
278 | |||
279 | if (is_char_two) | ||
280 | { | ||
281 | /* print the 'short name' of the base type OID */ | ||
282 | int basis_type = EC_GROUP_get_basis_type(x); | ||
283 | if (basis_type == 0) | ||
284 | goto err; | ||
285 | |||
286 | if (!BIO_indent(bp, off, 128)) | ||
287 | goto err; | ||
288 | |||
289 | if (BIO_printf(bp, "Basis Type: %s\n", | ||
290 | OBJ_nid2sn(basis_type)) <= 0) | ||
291 | goto err; | ||
292 | |||
293 | /* print the polynomial */ | ||
294 | if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, | ||
295 | off)) | ||
296 | goto err; | ||
297 | } | ||
298 | else | ||
299 | { | ||
300 | if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off)) | ||
301 | goto err; | ||
302 | } | ||
303 | if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) | ||
304 | goto err; | ||
305 | if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) | ||
306 | goto err; | ||
307 | if (form == POINT_CONVERSION_COMPRESSED) | ||
308 | { | ||
309 | if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, | ||
310 | buffer, off)) | ||
311 | goto err; | ||
312 | } | ||
313 | else if (form == POINT_CONVERSION_UNCOMPRESSED) | ||
314 | { | ||
315 | if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, | ||
316 | buffer, off)) | ||
317 | goto err; | ||
318 | } | ||
319 | else /* form == POINT_CONVERSION_HYBRID */ | ||
320 | { | ||
321 | if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, | ||
322 | buffer, off)) | ||
323 | goto err; | ||
324 | } | ||
325 | if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, | ||
326 | buffer, off)) goto err; | ||
327 | if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, | ||
328 | buffer, off)) goto err; | ||
329 | if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) | ||
330 | goto err; | ||
331 | } | ||
332 | ret=1; | ||
333 | err: | ||
334 | if (!ret) | ||
335 | ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); | ||
336 | if (p) | ||
337 | BN_free(p); | ||
338 | if (a) | ||
339 | BN_free(a); | ||
340 | if (b) | ||
341 | BN_free(b); | ||
342 | if (gen) | ||
343 | BN_free(gen); | ||
344 | if (order) | ||
345 | BN_free(order); | ||
346 | if (cofactor) | ||
347 | BN_free(cofactor); | ||
348 | if (ctx) | ||
349 | BN_CTX_free(ctx); | ||
350 | if (buffer != NULL) | ||
351 | OPENSSL_free(buffer); | ||
352 | return(ret); | ||
353 | } | ||
354 | |||
355 | static int print_bin(BIO *fp, const char *name, const unsigned char *buf, | ||
356 | size_t len, int off) | ||
357 | { | ||
358 | size_t i; | ||
359 | char str[128]; | ||
360 | |||
361 | if (buf == NULL) | ||
362 | return 1; | ||
363 | if (off) | ||
364 | { | ||
365 | if (off > 128) | ||
366 | off=128; | ||
367 | memset(str,' ',off); | ||
368 | if (BIO_write(fp, str, off) <= 0) | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | if (BIO_printf(fp,"%s", name) <= 0) | ||
373 | return 0; | ||
374 | |||
375 | for (i=0; i<len; i++) | ||
376 | { | ||
377 | if ((i%15) == 0) | ||
378 | { | ||
379 | str[0]='\n'; | ||
380 | memset(&(str[1]),' ',off+4); | ||
381 | if (BIO_write(fp, str, off+1+4) <= 0) | ||
382 | return 0; | ||
383 | } | ||
384 | if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0) | ||
385 | return 0; | ||
386 | } | ||
387 | if (BIO_write(fp,"\n",1) <= 0) | ||
388 | return 0; | ||
389 | |||
390 | return 1; | ||
391 | } | ||
diff --git a/src/lib/libcrypto/ecdh/ech_err.c b/src/lib/libcrypto/ecdh/ech_err.c index 4d2ede75bd..6f4b0c9953 100644 --- a/src/lib/libcrypto/ecdh/ech_err.c +++ b/src/lib/libcrypto/ecdh/ech_err.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* crypto/ecdh/ech_err.c */ | 1 | /* crypto/ecdh/ech_err.c */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions | 6 | * modification, are permitted provided that the following conditions |
@@ -71,7 +71,7 @@ | |||
71 | static ERR_STRING_DATA ECDH_str_functs[]= | 71 | static ERR_STRING_DATA ECDH_str_functs[]= |
72 | { | 72 | { |
73 | {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"}, | 73 | {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"}, |
74 | {ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_NEW_METHOD"}, | 74 | {ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_new_method"}, |
75 | {0,NULL} | 75 | {0,NULL} |
76 | }; | 76 | }; |
77 | 77 | ||
diff --git a/src/lib/libcrypto/ecdsa/ecdsa.h b/src/lib/libcrypto/ecdsa/ecdsa.h index f20c8ee738..e61c539812 100644 --- a/src/lib/libcrypto/ecdsa/ecdsa.h +++ b/src/lib/libcrypto/ecdsa/ecdsa.h | |||
@@ -4,7 +4,7 @@ | |||
4 | * \author Written by Nils Larsch for the OpenSSL project | 4 | * \author Written by Nils Larsch for the OpenSSL project |
5 | */ | 5 | */ |
6 | /* ==================================================================== | 6 | /* ==================================================================== |
7 | * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. | 7 | * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. |
8 | * | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
@@ -81,156 +81,143 @@ typedef struct ECDSA_SIG_st | |||
81 | BIGNUM *s; | 81 | BIGNUM *s; |
82 | } ECDSA_SIG; | 82 | } ECDSA_SIG; |
83 | 83 | ||
84 | /** ECDSA_SIG *ECDSA_SIG_new(void) | 84 | /** Allocates and initialize a ECDSA_SIG structure |
85 | * allocates and initialize a ECDSA_SIG structure | 85 | * \return pointer to a ECDSA_SIG structure or NULL if an error occurred |
86 | * \return pointer to a ECDSA_SIG structure or NULL if an error occurred | ||
87 | */ | 86 | */ |
88 | ECDSA_SIG *ECDSA_SIG_new(void); | 87 | ECDSA_SIG *ECDSA_SIG_new(void); |
89 | 88 | ||
90 | /** ECDSA_SIG_free | 89 | /** frees a ECDSA_SIG structure |
91 | * frees a ECDSA_SIG structure | 90 | * \param sig pointer to the ECDSA_SIG structure |
92 | * \param a pointer to the ECDSA_SIG structure | ||
93 | */ | 91 | */ |
94 | void ECDSA_SIG_free(ECDSA_SIG *a); | 92 | void ECDSA_SIG_free(ECDSA_SIG *sig); |
95 | 93 | ||
96 | /** i2d_ECDSA_SIG | 94 | /** DER encode content of ECDSA_SIG object (note: this function modifies *pp |
97 | * DER encode content of ECDSA_SIG object (note: this function modifies *pp | 95 | * (*pp += length of the DER encoded signature)). |
98 | * (*pp += length of the DER encoded signature)). | 96 | * \param sig pointer to the ECDSA_SIG object |
99 | * \param a pointer to the ECDSA_SIG object | 97 | * \param pp pointer to a unsigned char pointer for the output or NULL |
100 | * \param pp pointer to a unsigned char pointer for the output or NULL | 98 | * \return the length of the DER encoded ECDSA_SIG object or 0 |
101 | * \return the length of the DER encoded ECDSA_SIG object or 0 | ||
102 | */ | 99 | */ |
103 | int i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp); | 100 | int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); |
104 | 101 | ||
105 | /** d2i_ECDSA_SIG | 102 | /** Decodes a DER encoded ECDSA signature (note: this function changes *pp |
106 | * decodes a DER encoded ECDSA signature (note: this function changes *pp | 103 | * (*pp += len)). |
107 | * (*pp += len)). | 104 | * \param sig pointer to ECDSA_SIG pointer (may be NULL) |
108 | * \param v pointer to ECDSA_SIG pointer (may be NULL) | 105 | * \param pp memory buffer with the DER encoded signature |
109 | * \param pp buffer with the DER encoded signature | 106 | * \param len length of the buffer |
110 | * \param len bufferlength | 107 | * \return pointer to the decoded ECDSA_SIG structure (or NULL) |
111 | * \return pointer to the decoded ECDSA_SIG structure (or NULL) | ||
112 | */ | 108 | */ |
113 | ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len); | 109 | ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); |
114 | 110 | ||
115 | /** ECDSA_do_sign | 111 | /** Computes the ECDSA signature of the given hash value using |
116 | * computes the ECDSA signature of the given hash value using | 112 | * the supplied private key and returns the created signature. |
117 | * the supplied private key and returns the created signature. | 113 | * \param dgst pointer to the hash value |
118 | * \param dgst pointer to the hash value | 114 | * \param dgst_len length of the hash value |
119 | * \param dgst_len length of the hash value | 115 | * \param eckey EC_KEY object containing a private EC key |
120 | * \param eckey pointer to the EC_KEY object containing a private EC key | 116 | * \return pointer to a ECDSA_SIG structure or NULL if an error occurred |
121 | * \return pointer to a ECDSA_SIG structure or NULL | ||
122 | */ | 117 | */ |
123 | ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey); | 118 | ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey); |
124 | 119 | ||
125 | /** ECDSA_do_sign_ex | 120 | /** Computes ECDSA signature of a given hash value using the supplied |
126 | * computes ECDSA signature of a given hash value using the supplied | 121 | * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). |
127 | * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). | 122 | * \param dgst pointer to the hash value to sign |
128 | * \param dgst pointer to the hash value to sign | 123 | * \param dgstlen length of the hash value |
129 | * \param dgstlen length of the hash value | 124 | * \param kinv BIGNUM with a pre-computed inverse k (optional) |
130 | * \param kinv optional pointer to a pre-computed inverse k | 125 | * \param rp BIGNUM with a pre-computed rp value (optioanl), |
131 | * \param rp optional pointer to the pre-computed rp value (see | 126 | * see ECDSA_sign_setup |
132 | * ECDSA_sign_setup | 127 | * \param eckey EC_KEY object containing a private EC key |
133 | * \param eckey pointer to the EC_KEY object containing a private EC key | 128 | * \return pointer to a ECDSA_SIG structure or NULL if an error occurred |
134 | * \return pointer to a ECDSA_SIG structure or NULL | ||
135 | */ | 129 | */ |
136 | ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, | 130 | ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, |
137 | const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); | 131 | const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); |
138 | 132 | ||
139 | /** ECDSA_do_verify | 133 | /** Verifies that the supplied signature is a valid ECDSA |
140 | * verifies that the supplied signature is a valid ECDSA | 134 | * signature of the supplied hash value using the supplied public key. |
141 | * signature of the supplied hash value using the supplied public key. | 135 | * \param dgst pointer to the hash value |
142 | * \param dgst pointer to the hash value | 136 | * \param dgst_len length of the hash value |
143 | * \param dgst_len length of the hash value | 137 | * \param sig ECDSA_SIG structure |
144 | * \param sig pointer to the ECDSA_SIG structure | 138 | * \param eckey EC_KEY object containing a public EC key |
145 | * \param eckey pointer to the EC_KEY object containing a public EC key | 139 | * \return 1 if the signature is valid, 0 if the signature is invalid |
146 | * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error | 140 | * and -1 on error |
147 | */ | 141 | */ |
148 | int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, | 142 | int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, |
149 | const ECDSA_SIG *sig, EC_KEY* eckey); | 143 | const ECDSA_SIG *sig, EC_KEY* eckey); |
150 | 144 | ||
151 | const ECDSA_METHOD *ECDSA_OpenSSL(void); | 145 | const ECDSA_METHOD *ECDSA_OpenSSL(void); |
152 | 146 | ||
153 | /** ECDSA_set_default_method | 147 | /** Sets the default ECDSA method |
154 | * sets the default ECDSA method | 148 | * \param meth new default ECDSA_METHOD |
155 | * \param meth the new default ECDSA_METHOD | ||
156 | */ | 149 | */ |
157 | void ECDSA_set_default_method(const ECDSA_METHOD *meth); | 150 | void ECDSA_set_default_method(const ECDSA_METHOD *meth); |
158 | 151 | ||
159 | /** ECDSA_get_default_method | 152 | /** Returns the default ECDSA method |
160 | * returns the default ECDSA method | 153 | * \return pointer to ECDSA_METHOD structure containing the default method |
161 | * \return pointer to ECDSA_METHOD structure containing the default method | ||
162 | */ | 154 | */ |
163 | const ECDSA_METHOD *ECDSA_get_default_method(void); | 155 | const ECDSA_METHOD *ECDSA_get_default_method(void); |
164 | 156 | ||
165 | /** ECDSA_set_method | 157 | /** Sets method to be used for the ECDSA operations |
166 | * sets method to be used for the ECDSA operations | 158 | * \param eckey EC_KEY object |
167 | * \param eckey pointer to the EC_KEY object | 159 | * \param meth new method |
168 | * \param meth pointer to the new method | 160 | * \return 1 on success and 0 otherwise |
169 | * \return 1 on success and 0 otherwise | ||
170 | */ | 161 | */ |
171 | int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); | 162 | int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); |
172 | 163 | ||
173 | /** ECDSA_size | 164 | /** Returns the maximum length of the DER encoded signature |
174 | * returns the maximum length of the DER encoded signature | 165 | * \param eckey EC_KEY object |
175 | * \param eckey pointer to a EC_KEY object | 166 | * \return numbers of bytes required for the DER encoded signature |
176 | * \return numbers of bytes required for the DER encoded signature | ||
177 | */ | 167 | */ |
178 | int ECDSA_size(const EC_KEY *eckey); | 168 | int ECDSA_size(const EC_KEY *eckey); |
179 | 169 | ||
180 | /** ECDSA_sign_setup | 170 | /** Precompute parts of the signing operation |
181 | * precompute parts of the signing operation. | 171 | * \param eckey EC_KEY object containing a private EC key |
182 | * \param eckey pointer to the EC_KEY object containing a private EC key | 172 | * \param ctx BN_CTX object (optional) |
183 | * \param ctx pointer to a BN_CTX object (may be NULL) | 173 | * \param kinv BIGNUM pointer for the inverse of k |
184 | * \param kinv pointer to a BIGNUM pointer for the inverse of k | 174 | * \param rp BIGNUM pointer for x coordinate of k * generator |
185 | * \param rp pointer to a BIGNUM pointer for x coordinate of k * generator | 175 | * \return 1 on success and 0 otherwise |
186 | * \return 1 on success and 0 otherwise | ||
187 | */ | 176 | */ |
188 | int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, | 177 | int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, |
189 | BIGNUM **rp); | 178 | BIGNUM **rp); |
190 | 179 | ||
191 | /** ECDSA_sign | 180 | /** Computes ECDSA signature of a given hash value using the supplied |
192 | * computes ECDSA signature of a given hash value using the supplied | 181 | * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). |
193 | * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). | 182 | * \param type this parameter is ignored |
194 | * \param type this parameter is ignored | 183 | * \param dgst pointer to the hash value to sign |
195 | * \param dgst pointer to the hash value to sign | 184 | * \param dgstlen length of the hash value |
196 | * \param dgstlen length of the hash value | 185 | * \param sig memory for the DER encoded created signature |
197 | * \param sig buffer to hold the DER encoded signature | 186 | * \param siglen pointer to the length of the returned signature |
198 | * \param siglen pointer to the length of the returned signature | 187 | * \param eckey EC_KEY object containing a private EC key |
199 | * \param eckey pointer to the EC_KEY object containing a private EC key | 188 | * \return 1 on success and 0 otherwise |
200 | * \return 1 on success and 0 otherwise | ||
201 | */ | 189 | */ |
202 | int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, | 190 | int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, |
203 | unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); | 191 | unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); |
204 | 192 | ||
205 | 193 | ||
206 | /** ECDSA_sign_ex | 194 | /** Computes ECDSA signature of a given hash value using the supplied |
207 | * computes ECDSA signature of a given hash value using the supplied | 195 | * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). |
208 | * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). | 196 | * \param type this parameter is ignored |
209 | * \param type this parameter is ignored | 197 | * \param dgst pointer to the hash value to sign |
210 | * \param dgst pointer to the hash value to sign | 198 | * \param dgstlen length of the hash value |
211 | * \param dgstlen length of the hash value | 199 | * \param sig buffer to hold the DER encoded signature |
212 | * \param sig buffer to hold the DER encoded signature | 200 | * \param siglen pointer to the length of the returned signature |
213 | * \param siglen pointer to the length of the returned signature | 201 | * \param kinv BIGNUM with a pre-computed inverse k (optional) |
214 | * \param kinv optional pointer to a pre-computed inverse k | 202 | * \param rp BIGNUM with a pre-computed rp value (optioanl), |
215 | * \param rp optional pointer to the pre-computed rp value (see | 203 | * see ECDSA_sign_setup |
216 | * ECDSA_sign_setup | 204 | * \param eckey EC_KEY object containing a private EC key |
217 | * \param eckey pointer to the EC_KEY object containing a private EC key | 205 | * \return 1 on success and 0 otherwise |
218 | * \return 1 on success and 0 otherwise | ||
219 | */ | 206 | */ |
220 | int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, | 207 | int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, |
221 | unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, | 208 | unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, |
222 | const BIGNUM *rp, EC_KEY *eckey); | 209 | const BIGNUM *rp, EC_KEY *eckey); |
223 | 210 | ||
224 | /** ECDSA_verify | 211 | /** Verifies that the given signature is valid ECDSA signature |
225 | * verifies that the given signature is valid ECDSA signature | 212 | * of the supplied hash value using the specified public key. |
226 | * of the supplied hash value using the specified public key. | 213 | * \param type this parameter is ignored |
227 | * \param type this parameter is ignored | 214 | * \param dgst pointer to the hash value |
228 | * \param dgst pointer to the hash value | 215 | * \param dgstlen length of the hash value |
229 | * \param dgstlen length of the hash value | 216 | * \param sig pointer to the DER encoded signature |
230 | * \param sig pointer to the DER encoded signature | 217 | * \param siglen length of the DER encoded signature |
231 | * \param siglen length of the DER encoded signature | 218 | * \param eckey EC_KEY object containing a public EC key |
232 | * \param eckey pointer to the EC_KEY object containing a public EC key | 219 | * \return 1 if the signature is valid, 0 if the signature is invalid |
233 | * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error | 220 | * and -1 on error |
234 | */ | 221 | */ |
235 | int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, | 222 | int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, |
236 | const unsigned char *sig, int siglen, EC_KEY *eckey); | 223 | const unsigned char *sig, int siglen, EC_KEY *eckey); |
diff --git a/src/lib/libcrypto/ecdsa/ecs_err.c b/src/lib/libcrypto/ecdsa/ecs_err.c index d2a53730ea..98e38d537f 100644 --- a/src/lib/libcrypto/ecdsa/ecs_err.c +++ b/src/lib/libcrypto/ecdsa/ecs_err.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* crypto/ecdsa/ecs_err.c */ | 1 | /* crypto/ecdsa/ecs_err.c */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions | 6 | * modification, are permitted provided that the following conditions |
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c index 3ead1af94e..551cf5068f 100644 --- a/src/lib/libcrypto/ecdsa/ecs_ossl.c +++ b/src/lib/libcrypto/ecdsa/ecs_ossl.c | |||
@@ -212,7 +212,7 @@ err: | |||
212 | static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | 212 | static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, |
213 | const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) | 213 | const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) |
214 | { | 214 | { |
215 | int ok = 0; | 215 | int ok = 0, i; |
216 | BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL; | 216 | BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL; |
217 | const BIGNUM *ckinv; | 217 | const BIGNUM *ckinv; |
218 | BN_CTX *ctx = NULL; | 218 | BN_CTX *ctx = NULL; |
@@ -251,22 +251,19 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
251 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); | 251 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); |
252 | goto err; | 252 | goto err; |
253 | } | 253 | } |
254 | if (8 * dgst_len > BN_num_bits(order)) | 254 | i = BN_num_bits(order); |
255 | /* Need to truncate digest if it is too long: first truncate whole | ||
256 | * bytes. | ||
257 | */ | ||
258 | if (8 * dgst_len > i) | ||
259 | dgst_len = (i + 7)/8; | ||
260 | if (!BN_bin2bn(dgst, dgst_len, m)) | ||
255 | { | 261 | { |
256 | /* XXX | 262 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); |
257 | * | ||
258 | * Should provide for optional hash truncation: | ||
259 | * Keep the BN_num_bits(order) leftmost bits of dgst | ||
260 | * (see March 2006 FIPS 186-3 draft, which has a few | ||
261 | * confusing errors in this part though) | ||
262 | */ | ||
263 | |||
264 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, | ||
265 | ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); | ||
266 | goto err; | 263 | goto err; |
267 | } | 264 | } |
268 | 265 | /* If still too long truncate remaining bits with a shift */ | |
269 | if (!BN_bin2bn(dgst, dgst_len, m)) | 266 | if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) |
270 | { | 267 | { |
271 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); | 268 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); |
272 | goto err; | 269 | goto err; |
@@ -346,7 +343,7 @@ err: | |||
346 | static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, | 343 | static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, |
347 | const ECDSA_SIG *sig, EC_KEY *eckey) | 344 | const ECDSA_SIG *sig, EC_KEY *eckey) |
348 | { | 345 | { |
349 | int ret = -1; | 346 | int ret = -1, i; |
350 | BN_CTX *ctx; | 347 | BN_CTX *ctx; |
351 | BIGNUM *order, *u1, *u2, *m, *X; | 348 | BIGNUM *order, *u1, *u2, *m, *X; |
352 | EC_POINT *point = NULL; | 349 | EC_POINT *point = NULL; |
@@ -384,21 +381,6 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, | |||
384 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | 381 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); |
385 | goto err; | 382 | goto err; |
386 | } | 383 | } |
387 | if (8 * dgst_len > BN_num_bits(order)) | ||
388 | { | ||
389 | /* XXX | ||
390 | * | ||
391 | * Should provide for optional hash truncation: | ||
392 | * Keep the BN_num_bits(order) leftmost bits of dgst | ||
393 | * (see March 2006 FIPS 186-3 draft, which has a few | ||
394 | * confusing errors in this part though) | ||
395 | */ | ||
396 | |||
397 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, | ||
398 | ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); | ||
399 | ret = 0; | ||
400 | goto err; | ||
401 | } | ||
402 | 384 | ||
403 | if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || | 385 | if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || |
404 | BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || | 386 | BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || |
@@ -415,11 +397,23 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, | |||
415 | goto err; | 397 | goto err; |
416 | } | 398 | } |
417 | /* digest -> m */ | 399 | /* digest -> m */ |
400 | i = BN_num_bits(order); | ||
401 | /* Need to truncate digest if it is too long: first truncate whole | ||
402 | * bytes. | ||
403 | */ | ||
404 | if (8 * dgst_len > i) | ||
405 | dgst_len = (i + 7)/8; | ||
418 | if (!BN_bin2bn(dgst, dgst_len, m)) | 406 | if (!BN_bin2bn(dgst, dgst_len, m)) |
419 | { | 407 | { |
420 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | 408 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); |
421 | goto err; | 409 | goto err; |
422 | } | 410 | } |
411 | /* If still too long truncate remaining bits with a shift */ | ||
412 | if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) | ||
413 | { | ||
414 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | ||
415 | goto err; | ||
416 | } | ||
423 | /* u1 = m * tmp mod order */ | 417 | /* u1 = m * tmp mod order */ |
424 | if (!BN_mod_mul(u1, m, u2, order, ctx)) | 418 | if (!BN_mod_mul(u1, m, u2, order, ctx)) |
425 | { | 419 | { |
diff --git a/src/lib/libcrypto/ecdsa/ecs_sign.c b/src/lib/libcrypto/ecdsa/ecs_sign.c index 74b1fe8caf..353d5af514 100644 --- a/src/lib/libcrypto/ecdsa/ecs_sign.c +++ b/src/lib/libcrypto/ecdsa/ecs_sign.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #ifndef OPENSSL_NO_ENGINE | 57 | #ifndef OPENSSL_NO_ENGINE |
58 | #include <openssl/engine.h> | 58 | #include <openssl/engine.h> |
59 | #endif | 59 | #endif |
60 | #include <openssl/rand.h> | ||
60 | 61 | ||
61 | ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) | 62 | ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) |
62 | { | 63 | { |
@@ -83,6 +84,7 @@ int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char | |||
83 | EC_KEY *eckey) | 84 | EC_KEY *eckey) |
84 | { | 85 | { |
85 | ECDSA_SIG *s; | 86 | ECDSA_SIG *s; |
87 | RAND_seed(dgst, dlen); | ||
86 | s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); | 88 | s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); |
87 | if (s == NULL) | 89 | if (s == NULL) |
88 | { | 90 | { |
diff --git a/src/lib/libcrypto/engine/tb_asnmth.c b/src/lib/libcrypto/engine/tb_asnmth.c new file mode 100644 index 0000000000..75090339f7 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_asnmth.c | |||
@@ -0,0 +1,246 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in | ||
13 | * the documentation and/or other materials provided with the | ||
14 | * distribution. | ||
15 | * | ||
16 | * 3. All advertising materials mentioning features or use of this | ||
17 | * software must display the following acknowledgment: | ||
18 | * "This product includes software developed by the OpenSSL Project | ||
19 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
20 | * | ||
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
22 | * endorse or promote products derived from this software without | ||
23 | * prior written permission. For written permission, please contact | ||
24 | * licensing@OpenSSL.org. | ||
25 | * | ||
26 | * 5. Products derived from this software may not be called "OpenSSL" | ||
27 | * nor may "OpenSSL" appear in their names without prior written | ||
28 | * permission of the OpenSSL Project. | ||
29 | * | ||
30 | * 6. Redistributions of any form whatsoever must retain the following | ||
31 | * acknowledgment: | ||
32 | * "This product includes software developed by the OpenSSL Project | ||
33 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
34 | * | ||
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
47 | * ==================================================================== | ||
48 | * | ||
49 | * This product includes cryptographic software written by Eric Young | ||
50 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
51 | * Hudson (tjh@cryptsoft.com). | ||
52 | * | ||
53 | */ | ||
54 | |||
55 | #include "eng_int.h" | ||
56 | #include "asn1_locl.h" | ||
57 | #include <openssl/evp.h> | ||
58 | |||
59 | /* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the | ||
60 | * function that is used by EVP to hook in pkey_asn1_meth code and cache | ||
61 | * defaults (etc), will display brief debugging summaries to stderr with the | ||
62 | * 'nid'. */ | ||
63 | /* #define ENGINE_PKEY_ASN1_METH_DEBUG */ | ||
64 | |||
65 | static ENGINE_TABLE *pkey_asn1_meth_table = NULL; | ||
66 | |||
67 | void ENGINE_unregister_pkey_asn1_meths(ENGINE *e) | ||
68 | { | ||
69 | engine_table_unregister(&pkey_asn1_meth_table, e); | ||
70 | } | ||
71 | |||
72 | static void engine_unregister_all_pkey_asn1_meths(void) | ||
73 | { | ||
74 | engine_table_cleanup(&pkey_asn1_meth_table); | ||
75 | } | ||
76 | |||
77 | int ENGINE_register_pkey_asn1_meths(ENGINE *e) | ||
78 | { | ||
79 | if(e->pkey_asn1_meths) | ||
80 | { | ||
81 | const int *nids; | ||
82 | int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); | ||
83 | if(num_nids > 0) | ||
84 | return engine_table_register(&pkey_asn1_meth_table, | ||
85 | engine_unregister_all_pkey_asn1_meths, e, nids, | ||
86 | num_nids, 0); | ||
87 | } | ||
88 | return 1; | ||
89 | } | ||
90 | |||
91 | void ENGINE_register_all_pkey_asn1_meths(void) | ||
92 | { | ||
93 | ENGINE *e; | ||
94 | |||
95 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
96 | ENGINE_register_pkey_asn1_meths(e); | ||
97 | } | ||
98 | |||
99 | int ENGINE_set_default_pkey_asn1_meths(ENGINE *e) | ||
100 | { | ||
101 | if(e->pkey_asn1_meths) | ||
102 | { | ||
103 | const int *nids; | ||
104 | int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); | ||
105 | if(num_nids > 0) | ||
106 | return engine_table_register(&pkey_asn1_meth_table, | ||
107 | engine_unregister_all_pkey_asn1_meths, e, nids, | ||
108 | num_nids, 1); | ||
109 | } | ||
110 | return 1; | ||
111 | } | ||
112 | |||
113 | /* Exposed API function to get a functional reference from the implementation | ||
114 | * table (ie. try to get a functional reference from the tabled structural | ||
115 | * references) for a given pkey_asn1_meth 'nid' */ | ||
116 | ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid) | ||
117 | { | ||
118 | return engine_table_select(&pkey_asn1_meth_table, nid); | ||
119 | } | ||
120 | |||
121 | /* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */ | ||
122 | const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid) | ||
123 | { | ||
124 | EVP_PKEY_ASN1_METHOD *ret; | ||
125 | ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e); | ||
126 | if(!fn || !fn(e, &ret, NULL, nid)) | ||
127 | { | ||
128 | ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH, | ||
129 | ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); | ||
130 | return NULL; | ||
131 | } | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | /* Gets the pkey_asn1_meth callback from an ENGINE structure */ | ||
136 | ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e) | ||
137 | { | ||
138 | return e->pkey_asn1_meths; | ||
139 | } | ||
140 | |||
141 | /* Sets the pkey_asn1_meth callback in an ENGINE structure */ | ||
142 | int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f) | ||
143 | { | ||
144 | e->pkey_asn1_meths = f; | ||
145 | return 1; | ||
146 | } | ||
147 | |||
148 | /* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an | ||
149 | * ENGINE is destroyed | ||
150 | */ | ||
151 | |||
152 | void engine_pkey_asn1_meths_free(ENGINE *e) | ||
153 | { | ||
154 | int i; | ||
155 | EVP_PKEY_ASN1_METHOD *pkm; | ||
156 | if (e->pkey_asn1_meths) | ||
157 | { | ||
158 | const int *pknids; | ||
159 | int npknids; | ||
160 | npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0); | ||
161 | for (i = 0; i < npknids; i++) | ||
162 | { | ||
163 | if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i])) | ||
164 | { | ||
165 | EVP_PKEY_asn1_free(pkm); | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | /* Find a method based on a string. This does a linear search through | ||
172 | * all implemented algorithms. This is OK in practice because only | ||
173 | * a small number of algorithms are likely to be implemented in an engine | ||
174 | * and it is not used for speed critical operations. | ||
175 | */ | ||
176 | |||
177 | const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, | ||
178 | const char *str, int len) | ||
179 | { | ||
180 | int i, nidcount; | ||
181 | const int *nids; | ||
182 | EVP_PKEY_ASN1_METHOD *ameth; | ||
183 | if (!e->pkey_asn1_meths) | ||
184 | return NULL; | ||
185 | if (len == -1) | ||
186 | len = strlen(str); | ||
187 | nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0); | ||
188 | for (i = 0; i < nidcount; i++) | ||
189 | { | ||
190 | e->pkey_asn1_meths(e, &ameth, NULL, nids[i]); | ||
191 | if (((int)strlen(ameth->pem_str) == len) && | ||
192 | !strncasecmp(ameth->pem_str, str, len)) | ||
193 | return ameth; | ||
194 | } | ||
195 | return NULL; | ||
196 | } | ||
197 | |||
198 | typedef struct | ||
199 | { | ||
200 | ENGINE *e; | ||
201 | const EVP_PKEY_ASN1_METHOD *ameth; | ||
202 | const char *str; | ||
203 | int len; | ||
204 | } ENGINE_FIND_STR; | ||
205 | |||
206 | static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg) | ||
207 | { | ||
208 | ENGINE_FIND_STR *lk = arg; | ||
209 | int i; | ||
210 | if (lk->ameth) | ||
211 | return; | ||
212 | for (i = 0; i < sk_ENGINE_num(sk); i++) | ||
213 | { | ||
214 | ENGINE *e = sk_ENGINE_value(sk, i); | ||
215 | EVP_PKEY_ASN1_METHOD *ameth; | ||
216 | e->pkey_asn1_meths(e, &ameth, NULL, nid); | ||
217 | if (((int)strlen(ameth->pem_str) == lk->len) && | ||
218 | !strncasecmp(ameth->pem_str, lk->str, lk->len)) | ||
219 | { | ||
220 | lk->e = e; | ||
221 | lk->ameth = ameth; | ||
222 | return; | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | |||
227 | const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, | ||
228 | const char *str, int len) | ||
229 | { | ||
230 | ENGINE_FIND_STR fstr; | ||
231 | fstr.e = NULL; | ||
232 | fstr.ameth = NULL; | ||
233 | fstr.str = str; | ||
234 | fstr.len = len; | ||
235 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
236 | engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr); | ||
237 | /* If found obtain a structural reference to engine */ | ||
238 | if (fstr.e) | ||
239 | { | ||
240 | fstr.e->struct_ref++; | ||
241 | engine_ref_debug(fstr.e, 0, 1) | ||
242 | } | ||
243 | *pe = fstr.e; | ||
244 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
245 | return fstr.ameth; | ||
246 | } | ||
diff --git a/src/lib/libcrypto/engine/tb_pkmeth.c b/src/lib/libcrypto/engine/tb_pkmeth.c new file mode 100644 index 0000000000..1cdb967f25 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_pkmeth.c | |||
@@ -0,0 +1,167 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in | ||
13 | * the documentation and/or other materials provided with the | ||
14 | * distribution. | ||
15 | * | ||
16 | * 3. All advertising materials mentioning features or use of this | ||
17 | * software must display the following acknowledgment: | ||
18 | * "This product includes software developed by the OpenSSL Project | ||
19 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
20 | * | ||
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
22 | * endorse or promote products derived from this software without | ||
23 | * prior written permission. For written permission, please contact | ||
24 | * licensing@OpenSSL.org. | ||
25 | * | ||
26 | * 5. Products derived from this software may not be called "OpenSSL" | ||
27 | * nor may "OpenSSL" appear in their names without prior written | ||
28 | * permission of the OpenSSL Project. | ||
29 | * | ||
30 | * 6. Redistributions of any form whatsoever must retain the following | ||
31 | * acknowledgment: | ||
32 | * "This product includes software developed by the OpenSSL Project | ||
33 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
34 | * | ||
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
47 | * ==================================================================== | ||
48 | * | ||
49 | * This product includes cryptographic software written by Eric Young | ||
50 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
51 | * Hudson (tjh@cryptsoft.com). | ||
52 | * | ||
53 | */ | ||
54 | |||
55 | #include "eng_int.h" | ||
56 | #include <openssl/evp.h> | ||
57 | |||
58 | /* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function | ||
59 | * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will | ||
60 | * display brief debugging summaries to stderr with the 'nid'. */ | ||
61 | /* #define ENGINE_PKEY_METH_DEBUG */ | ||
62 | |||
63 | static ENGINE_TABLE *pkey_meth_table = NULL; | ||
64 | |||
65 | void ENGINE_unregister_pkey_meths(ENGINE *e) | ||
66 | { | ||
67 | engine_table_unregister(&pkey_meth_table, e); | ||
68 | } | ||
69 | |||
70 | static void engine_unregister_all_pkey_meths(void) | ||
71 | { | ||
72 | engine_table_cleanup(&pkey_meth_table); | ||
73 | } | ||
74 | |||
75 | int ENGINE_register_pkey_meths(ENGINE *e) | ||
76 | { | ||
77 | if(e->pkey_meths) | ||
78 | { | ||
79 | const int *nids; | ||
80 | int num_nids = e->pkey_meths(e, NULL, &nids, 0); | ||
81 | if(num_nids > 0) | ||
82 | return engine_table_register(&pkey_meth_table, | ||
83 | engine_unregister_all_pkey_meths, e, nids, | ||
84 | num_nids, 0); | ||
85 | } | ||
86 | return 1; | ||
87 | } | ||
88 | |||
89 | void ENGINE_register_all_pkey_meths() | ||
90 | { | ||
91 | ENGINE *e; | ||
92 | |||
93 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
94 | ENGINE_register_pkey_meths(e); | ||
95 | } | ||
96 | |||
97 | int ENGINE_set_default_pkey_meths(ENGINE *e) | ||
98 | { | ||
99 | if(e->pkey_meths) | ||
100 | { | ||
101 | const int *nids; | ||
102 | int num_nids = e->pkey_meths(e, NULL, &nids, 0); | ||
103 | if(num_nids > 0) | ||
104 | return engine_table_register(&pkey_meth_table, | ||
105 | engine_unregister_all_pkey_meths, e, nids, | ||
106 | num_nids, 1); | ||
107 | } | ||
108 | return 1; | ||
109 | } | ||
110 | |||
111 | /* Exposed API function to get a functional reference from the implementation | ||
112 | * table (ie. try to get a functional reference from the tabled structural | ||
113 | * references) for a given pkey_meth 'nid' */ | ||
114 | ENGINE *ENGINE_get_pkey_meth_engine(int nid) | ||
115 | { | ||
116 | return engine_table_select(&pkey_meth_table, nid); | ||
117 | } | ||
118 | |||
119 | /* Obtains a pkey_meth implementation from an ENGINE functional reference */ | ||
120 | const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid) | ||
121 | { | ||
122 | EVP_PKEY_METHOD *ret; | ||
123 | ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e); | ||
124 | if(!fn || !fn(e, &ret, NULL, nid)) | ||
125 | { | ||
126 | ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH, | ||
127 | ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); | ||
128 | return NULL; | ||
129 | } | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | /* Gets the pkey_meth callback from an ENGINE structure */ | ||
134 | ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e) | ||
135 | { | ||
136 | return e->pkey_meths; | ||
137 | } | ||
138 | |||
139 | /* Sets the pkey_meth callback in an ENGINE structure */ | ||
140 | int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f) | ||
141 | { | ||
142 | e->pkey_meths = f; | ||
143 | return 1; | ||
144 | } | ||
145 | |||
146 | /* Internal function to free up EVP_PKEY_METHOD structures before an | ||
147 | * ENGINE is destroyed | ||
148 | */ | ||
149 | |||
150 | void engine_pkey_meths_free(ENGINE *e) | ||
151 | { | ||
152 | int i; | ||
153 | EVP_PKEY_METHOD *pkm; | ||
154 | if (e->pkey_meths) | ||
155 | { | ||
156 | const int *pknids; | ||
157 | int npknids; | ||
158 | npknids = e->pkey_meths(e, NULL, &pknids, 0); | ||
159 | for (i = 0; i < npknids; i++) | ||
160 | { | ||
161 | if (e->pkey_meths(e, &pkm, NULL, pknids[i])) | ||
162 | { | ||
163 | EVP_PKEY_meth_free(pkm); | ||
164 | } | ||
165 | } | ||
166 | } | ||
167 | } | ||
diff --git a/src/lib/libcrypto/evp/e_camellia.c b/src/lib/libcrypto/evp/e_camellia.c index 365d397164..a7b40d1c60 100644 --- a/src/lib/libcrypto/evp/e_camellia.c +++ b/src/lib/libcrypto/evp/e_camellia.c | |||
@@ -93,7 +93,7 @@ IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY, | |||
93 | EVP_CIPHER_get_asn1_iv, | 93 | EVP_CIPHER_get_asn1_iv, |
94 | NULL) | 94 | NULL) |
95 | 95 | ||
96 | #define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16,0) | 96 | #define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16) |
97 | 97 | ||
98 | IMPLEMENT_CAMELLIA_CFBR(128,1) | 98 | IMPLEMENT_CAMELLIA_CFBR(128,1) |
99 | IMPLEMENT_CAMELLIA_CFBR(192,1) | 99 | IMPLEMENT_CAMELLIA_CFBR(192,1) |
diff --git a/src/lib/libcrypto/evp/m_ecdsa.c b/src/lib/libcrypto/evp/m_ecdsa.c index fad270faca..8d87a49ebe 100644 --- a/src/lib/libcrypto/evp/m_ecdsa.c +++ b/src/lib/libcrypto/evp/m_ecdsa.c | |||
@@ -130,7 +130,7 @@ static const EVP_MD ecdsa_md= | |||
130 | NID_ecdsa_with_SHA1, | 130 | NID_ecdsa_with_SHA1, |
131 | NID_ecdsa_with_SHA1, | 131 | NID_ecdsa_with_SHA1, |
132 | SHA_DIGEST_LENGTH, | 132 | SHA_DIGEST_LENGTH, |
133 | 0, | 133 | EVP_MD_FLAG_PKEY_DIGEST, |
134 | init, | 134 | init, |
135 | update, | 135 | update, |
136 | final, | 136 | final, |
diff --git a/src/lib/libcrypto/evp/m_sigver.c b/src/lib/libcrypto/evp/m_sigver.c new file mode 100644 index 0000000000..f0b7f95059 --- /dev/null +++ b/src/lib/libcrypto/evp/m_sigver.c | |||
@@ -0,0 +1,200 @@ | |||
1 | /* m_sigver.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2006. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006,2007 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/evp.h> | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/x509.h> | ||
64 | #include "evp_locl.h" | ||
65 | |||
66 | static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, | ||
67 | const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, | ||
68 | int ver) | ||
69 | { | ||
70 | if (ctx->pctx == NULL) | ||
71 | ctx->pctx = EVP_PKEY_CTX_new(pkey, e); | ||
72 | if (ctx->pctx == NULL) | ||
73 | return 0; | ||
74 | |||
75 | if (type == NULL) | ||
76 | { | ||
77 | int def_nid; | ||
78 | if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) | ||
79 | type = EVP_get_digestbynid(def_nid); | ||
80 | } | ||
81 | |||
82 | if (type == NULL) | ||
83 | { | ||
84 | EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST); | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | if (ver) | ||
89 | { | ||
90 | if (ctx->pctx->pmeth->verifyctx_init) | ||
91 | { | ||
92 | if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <=0) | ||
93 | return 0; | ||
94 | ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; | ||
95 | } | ||
96 | else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) | ||
97 | return 0; | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | if (ctx->pctx->pmeth->signctx_init) | ||
102 | { | ||
103 | if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) | ||
104 | return 0; | ||
105 | ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; | ||
106 | } | ||
107 | else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) | ||
108 | return 0; | ||
109 | } | ||
110 | if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) | ||
111 | return 0; | ||
112 | if (pctx) | ||
113 | *pctx = ctx->pctx; | ||
114 | if (!EVP_DigestInit_ex(ctx, type, e)) | ||
115 | return 0; | ||
116 | return 1; | ||
117 | } | ||
118 | |||
119 | int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, | ||
120 | const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) | ||
121 | { | ||
122 | return do_sigver_init(ctx, pctx, type, e, pkey, 0); | ||
123 | } | ||
124 | |||
125 | int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, | ||
126 | const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) | ||
127 | { | ||
128 | return do_sigver_init(ctx, pctx, type, e, pkey, 1); | ||
129 | } | ||
130 | |||
131 | int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) | ||
132 | { | ||
133 | int sctx, r = 0; | ||
134 | if (ctx->pctx->pmeth->signctx) | ||
135 | sctx = 1; | ||
136 | else | ||
137 | sctx = 0; | ||
138 | if (sigret) | ||
139 | { | ||
140 | MS_STATIC EVP_MD_CTX tmp_ctx; | ||
141 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
142 | unsigned int mdlen; | ||
143 | EVP_MD_CTX_init(&tmp_ctx); | ||
144 | if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx)) | ||
145 | return 0; | ||
146 | if (sctx) | ||
147 | r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, | ||
148 | sigret, siglen, &tmp_ctx); | ||
149 | else | ||
150 | r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen); | ||
151 | EVP_MD_CTX_cleanup(&tmp_ctx); | ||
152 | if (sctx || !r) | ||
153 | return r; | ||
154 | if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0) | ||
155 | return 0; | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | if (sctx) | ||
160 | { | ||
161 | if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx) <= 0) | ||
162 | return 0; | ||
163 | } | ||
164 | else | ||
165 | { | ||
166 | int s = EVP_MD_size(ctx->digest); | ||
167 | if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, s) <= 0) | ||
168 | return 0; | ||
169 | } | ||
170 | } | ||
171 | return 1; | ||
172 | } | ||
173 | |||
174 | int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen) | ||
175 | { | ||
176 | MS_STATIC EVP_MD_CTX tmp_ctx; | ||
177 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
178 | int r; | ||
179 | unsigned int mdlen; | ||
180 | int vctx; | ||
181 | |||
182 | if (ctx->pctx->pmeth->verifyctx) | ||
183 | vctx = 1; | ||
184 | else | ||
185 | vctx = 0; | ||
186 | EVP_MD_CTX_init(&tmp_ctx); | ||
187 | if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx)) | ||
188 | return -1; | ||
189 | if (vctx) | ||
190 | { | ||
191 | r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, | ||
192 | sig, siglen, &tmp_ctx); | ||
193 | } | ||
194 | else | ||
195 | r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen); | ||
196 | EVP_MD_CTX_cleanup(&tmp_ctx); | ||
197 | if (vctx || !r) | ||
198 | return r; | ||
199 | return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); | ||
200 | } | ||
diff --git a/src/lib/libcrypto/evp/m_wp.c b/src/lib/libcrypto/evp/m_wp.c new file mode 100644 index 0000000000..1ce47c040b --- /dev/null +++ b/src/lib/libcrypto/evp/m_wp.c | |||
@@ -0,0 +1,42 @@ | |||
1 | /* crypto/evp/m_wp.c */ | ||
2 | |||
3 | #include <stdio.h> | ||
4 | #include "cryptlib.h" | ||
5 | |||
6 | #ifndef OPENSSL_NO_WHIRLPOOL | ||
7 | |||
8 | #include <openssl/evp.h> | ||
9 | #include <openssl/objects.h> | ||
10 | #include <openssl/x509.h> | ||
11 | #include <openssl/whrlpool.h> | ||
12 | |||
13 | static int init(EVP_MD_CTX *ctx) | ||
14 | { return WHIRLPOOL_Init(ctx->md_data); } | ||
15 | |||
16 | static int update(EVP_MD_CTX *ctx,const void *data,size_t count) | ||
17 | { return WHIRLPOOL_Update(ctx->md_data,data,count); } | ||
18 | |||
19 | static int final(EVP_MD_CTX *ctx,unsigned char *md) | ||
20 | { return WHIRLPOOL_Final(md,ctx->md_data); } | ||
21 | |||
22 | static const EVP_MD whirlpool_md= | ||
23 | { | ||
24 | NID_whirlpool, | ||
25 | 0, | ||
26 | WHIRLPOOL_DIGEST_LENGTH, | ||
27 | 0, | ||
28 | init, | ||
29 | update, | ||
30 | final, | ||
31 | NULL, | ||
32 | NULL, | ||
33 | EVP_PKEY_NULL_method, | ||
34 | WHIRLPOOL_BBLOCK/8, | ||
35 | sizeof(EVP_MD *)+sizeof(WHIRLPOOL_CTX), | ||
36 | }; | ||
37 | |||
38 | const EVP_MD *EVP_whirlpool(void) | ||
39 | { | ||
40 | return(&whirlpool_md); | ||
41 | } | ||
42 | #endif | ||
diff --git a/src/lib/libcrypto/evp/pmeth_fn.c b/src/lib/libcrypto/evp/pmeth_fn.c new file mode 100644 index 0000000000..c4676f2f8d --- /dev/null +++ b/src/lib/libcrypto/evp/pmeth_fn.c | |||
@@ -0,0 +1,368 @@ | |||
1 | /* pmeth_fn.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2006. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <stdlib.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/evp.h> | ||
64 | #include "evp_locl.h" | ||
65 | |||
66 | #define M_check_autoarg(ctx, arg, arglen, err) \ | ||
67 | if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \ | ||
68 | { \ | ||
69 | size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ | ||
70 | if (!arg) \ | ||
71 | { \ | ||
72 | *arglen = pksize; \ | ||
73 | return 1; \ | ||
74 | } \ | ||
75 | else if (*arglen < pksize) \ | ||
76 | { \ | ||
77 | EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\ | ||
78 | return 0; \ | ||
79 | } \ | ||
80 | } | ||
81 | |||
82 | int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) | ||
83 | { | ||
84 | int ret; | ||
85 | if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) | ||
86 | { | ||
87 | EVPerr(EVP_F_EVP_PKEY_SIGN_INIT, | ||
88 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
89 | return -2; | ||
90 | } | ||
91 | ctx->operation = EVP_PKEY_OP_SIGN; | ||
92 | if (!ctx->pmeth->sign_init) | ||
93 | return 1; | ||
94 | ret = ctx->pmeth->sign_init(ctx); | ||
95 | if (ret <= 0) | ||
96 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | ||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, | ||
101 | unsigned char *sig, size_t *siglen, | ||
102 | const unsigned char *tbs, size_t tbslen) | ||
103 | { | ||
104 | if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) | ||
105 | { | ||
106 | EVPerr(EVP_F_EVP_PKEY_SIGN, | ||
107 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
108 | return -2; | ||
109 | } | ||
110 | if (ctx->operation != EVP_PKEY_OP_SIGN) | ||
111 | { | ||
112 | EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED); | ||
113 | return -1; | ||
114 | } | ||
115 | M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) | ||
116 | return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); | ||
117 | } | ||
118 | |||
119 | int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) | ||
120 | { | ||
121 | int ret; | ||
122 | if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) | ||
123 | { | ||
124 | EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT, | ||
125 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
126 | return -2; | ||
127 | } | ||
128 | ctx->operation = EVP_PKEY_OP_VERIFY; | ||
129 | if (!ctx->pmeth->verify_init) | ||
130 | return 1; | ||
131 | ret = ctx->pmeth->verify_init(ctx); | ||
132 | if (ret <= 0) | ||
133 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | ||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, | ||
138 | const unsigned char *sig, size_t siglen, | ||
139 | const unsigned char *tbs, size_t tbslen) | ||
140 | { | ||
141 | if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) | ||
142 | { | ||
143 | EVPerr(EVP_F_EVP_PKEY_VERIFY, | ||
144 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
145 | return -2; | ||
146 | } | ||
147 | if (ctx->operation != EVP_PKEY_OP_VERIFY) | ||
148 | { | ||
149 | EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED); | ||
150 | return -1; | ||
151 | } | ||
152 | return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); | ||
153 | } | ||
154 | |||
155 | int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) | ||
156 | { | ||
157 | int ret; | ||
158 | if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) | ||
159 | { | ||
160 | EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, | ||
161 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
162 | return -2; | ||
163 | } | ||
164 | ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; | ||
165 | if (!ctx->pmeth->verify_recover_init) | ||
166 | return 1; | ||
167 | ret = ctx->pmeth->verify_recover_init(ctx); | ||
168 | if (ret <= 0) | ||
169 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, | ||
174 | unsigned char *rout, size_t *routlen, | ||
175 | const unsigned char *sig, size_t siglen) | ||
176 | { | ||
177 | if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) | ||
178 | { | ||
179 | EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, | ||
180 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
181 | return -2; | ||
182 | } | ||
183 | if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) | ||
184 | { | ||
185 | EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED); | ||
186 | return -1; | ||
187 | } | ||
188 | M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) | ||
189 | return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); | ||
190 | } | ||
191 | |||
192 | int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) | ||
193 | { | ||
194 | int ret; | ||
195 | if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) | ||
196 | { | ||
197 | EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT, | ||
198 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
199 | return -2; | ||
200 | } | ||
201 | ctx->operation = EVP_PKEY_OP_ENCRYPT; | ||
202 | if (!ctx->pmeth->encrypt_init) | ||
203 | return 1; | ||
204 | ret = ctx->pmeth->encrypt_init(ctx); | ||
205 | if (ret <= 0) | ||
206 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, | ||
211 | unsigned char *out, size_t *outlen, | ||
212 | const unsigned char *in, size_t inlen) | ||
213 | { | ||
214 | if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) | ||
215 | { | ||
216 | EVPerr(EVP_F_EVP_PKEY_ENCRYPT, | ||
217 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
218 | return -2; | ||
219 | } | ||
220 | if (ctx->operation != EVP_PKEY_OP_ENCRYPT) | ||
221 | { | ||
222 | EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED); | ||
223 | return -1; | ||
224 | } | ||
225 | M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) | ||
226 | return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); | ||
227 | } | ||
228 | |||
229 | int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) | ||
230 | { | ||
231 | int ret; | ||
232 | if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) | ||
233 | { | ||
234 | EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT, | ||
235 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
236 | return -2; | ||
237 | } | ||
238 | ctx->operation = EVP_PKEY_OP_DECRYPT; | ||
239 | if (!ctx->pmeth->decrypt_init) | ||
240 | return 1; | ||
241 | ret = ctx->pmeth->decrypt_init(ctx); | ||
242 | if (ret <= 0) | ||
243 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | ||
244 | return ret; | ||
245 | } | ||
246 | |||
247 | int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, | ||
248 | unsigned char *out, size_t *outlen, | ||
249 | const unsigned char *in, size_t inlen) | ||
250 | { | ||
251 | if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) | ||
252 | { | ||
253 | EVPerr(EVP_F_EVP_PKEY_DECRYPT, | ||
254 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
255 | return -2; | ||
256 | } | ||
257 | if (ctx->operation != EVP_PKEY_OP_DECRYPT) | ||
258 | { | ||
259 | EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED); | ||
260 | return -1; | ||
261 | } | ||
262 | M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) | ||
263 | return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); | ||
264 | } | ||
265 | |||
266 | |||
267 | int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) | ||
268 | { | ||
269 | int ret; | ||
270 | if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) | ||
271 | { | ||
272 | EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT, | ||
273 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
274 | return -2; | ||
275 | } | ||
276 | ctx->operation = EVP_PKEY_OP_DERIVE; | ||
277 | if (!ctx->pmeth->derive_init) | ||
278 | return 1; | ||
279 | ret = ctx->pmeth->derive_init(ctx); | ||
280 | if (ret <= 0) | ||
281 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | ||
282 | return ret; | ||
283 | } | ||
284 | |||
285 | int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) | ||
286 | { | ||
287 | int ret; | ||
288 | if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl) | ||
289 | { | ||
290 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, | ||
291 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
292 | return -2; | ||
293 | } | ||
294 | if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT) | ||
295 | { | ||
296 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, | ||
297 | EVP_R_OPERATON_NOT_INITIALIZED); | ||
298 | return -1; | ||
299 | } | ||
300 | |||
301 | ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); | ||
302 | |||
303 | if (ret <= 0) | ||
304 | return ret; | ||
305 | |||
306 | if (ret == 2) | ||
307 | return 1; | ||
308 | |||
309 | if (!ctx->pkey) | ||
310 | { | ||
311 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); | ||
312 | return -1; | ||
313 | } | ||
314 | |||
315 | if (ctx->pkey->type != peer->type) | ||
316 | { | ||
317 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, | ||
318 | EVP_R_DIFFERENT_KEY_TYPES); | ||
319 | return -1; | ||
320 | } | ||
321 | |||
322 | /* ran@cryptocom.ru: For clarity. The error is if parameters in peer are | ||
323 | * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return | ||
324 | * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 | ||
325 | * (different key types) is impossible here because it is checked earlier. | ||
326 | * -2 is OK for us here, as well as 1, so we can check for 0 only. */ | ||
327 | if (!EVP_PKEY_missing_parameters(peer) && | ||
328 | !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) | ||
329 | { | ||
330 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, | ||
331 | EVP_R_DIFFERENT_PARAMETERS); | ||
332 | return -1; | ||
333 | } | ||
334 | |||
335 | if (ctx->peerkey) | ||
336 | EVP_PKEY_free(ctx->peerkey); | ||
337 | ctx->peerkey = peer; | ||
338 | |||
339 | ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); | ||
340 | |||
341 | if (ret <= 0) | ||
342 | { | ||
343 | ctx->peerkey = NULL; | ||
344 | return ret; | ||
345 | } | ||
346 | |||
347 | CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY); | ||
348 | return 1; | ||
349 | } | ||
350 | |||
351 | |||
352 | int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) | ||
353 | { | ||
354 | if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) | ||
355 | { | ||
356 | EVPerr(EVP_F_EVP_PKEY_DERIVE, | ||
357 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
358 | return -2; | ||
359 | } | ||
360 | if (ctx->operation != EVP_PKEY_OP_DERIVE) | ||
361 | { | ||
362 | EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED); | ||
363 | return -1; | ||
364 | } | ||
365 | M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) | ||
366 | return ctx->pmeth->derive(ctx, key, pkeylen); | ||
367 | } | ||
368 | |||
diff --git a/src/lib/libcrypto/evp/pmeth_gn.c b/src/lib/libcrypto/evp/pmeth_gn.c new file mode 100644 index 0000000000..5d74161a09 --- /dev/null +++ b/src/lib/libcrypto/evp/pmeth_gn.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* pmeth_gn.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2006. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <stdlib.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/bn.h> | ||
65 | #include "evp_locl.h" | ||
66 | |||
67 | int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) | ||
68 | { | ||
69 | int ret; | ||
70 | if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) | ||
71 | { | ||
72 | EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT, | ||
73 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
74 | return -2; | ||
75 | } | ||
76 | ctx->operation = EVP_PKEY_OP_PARAMGEN; | ||
77 | if (!ctx->pmeth->paramgen_init) | ||
78 | return 1; | ||
79 | ret = ctx->pmeth->paramgen_init(ctx); | ||
80 | if (ret <= 0) | ||
81 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) | ||
86 | { | ||
87 | int ret; | ||
88 | if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) | ||
89 | { | ||
90 | EVPerr(EVP_F_EVP_PKEY_PARAMGEN, | ||
91 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
92 | return -2; | ||
93 | } | ||
94 | |||
95 | if (ctx->operation != EVP_PKEY_OP_PARAMGEN) | ||
96 | { | ||
97 | EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED); | ||
98 | return -1; | ||
99 | } | ||
100 | |||
101 | if (!ppkey) | ||
102 | return -1; | ||
103 | |||
104 | if (!*ppkey) | ||
105 | *ppkey = EVP_PKEY_new(); | ||
106 | |||
107 | ret = ctx->pmeth->paramgen(ctx, *ppkey); | ||
108 | if (ret <= 0) | ||
109 | { | ||
110 | EVP_PKEY_free(*ppkey); | ||
111 | *ppkey = NULL; | ||
112 | } | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) | ||
117 | { | ||
118 | int ret; | ||
119 | if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) | ||
120 | { | ||
121 | EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT, | ||
122 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
123 | return -2; | ||
124 | } | ||
125 | ctx->operation = EVP_PKEY_OP_KEYGEN; | ||
126 | if (!ctx->pmeth->keygen_init) | ||
127 | return 1; | ||
128 | ret = ctx->pmeth->keygen_init(ctx); | ||
129 | if (ret <= 0) | ||
130 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) | ||
135 | { | ||
136 | int ret; | ||
137 | |||
138 | if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) | ||
139 | { | ||
140 | EVPerr(EVP_F_EVP_PKEY_KEYGEN, | ||
141 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
142 | return -2; | ||
143 | } | ||
144 | if (ctx->operation != EVP_PKEY_OP_KEYGEN) | ||
145 | { | ||
146 | EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED); | ||
147 | return -1; | ||
148 | } | ||
149 | |||
150 | if (!ppkey) | ||
151 | return -1; | ||
152 | |||
153 | if (!*ppkey) | ||
154 | *ppkey = EVP_PKEY_new(); | ||
155 | |||
156 | ret = ctx->pmeth->keygen(ctx, *ppkey); | ||
157 | if (ret <= 0) | ||
158 | { | ||
159 | EVP_PKEY_free(*ppkey); | ||
160 | *ppkey = NULL; | ||
161 | } | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb) | ||
166 | { | ||
167 | ctx->pkey_gencb = cb; | ||
168 | } | ||
169 | |||
170 | EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx) | ||
171 | { | ||
172 | return ctx->pkey_gencb; | ||
173 | } | ||
174 | |||
175 | /* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB | ||
176 | * style callbacks. | ||
177 | */ | ||
178 | |||
179 | static int trans_cb(int a, int b, BN_GENCB *gcb) | ||
180 | { | ||
181 | EVP_PKEY_CTX *ctx = gcb->arg; | ||
182 | ctx->keygen_info[0] = a; | ||
183 | ctx->keygen_info[1] = b; | ||
184 | return ctx->pkey_gencb(ctx); | ||
185 | } | ||
186 | |||
187 | void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx) | ||
188 | { | ||
189 | BN_GENCB_set(cb, trans_cb, ctx) | ||
190 | } | ||
191 | |||
192 | int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) | ||
193 | { | ||
194 | if (idx == -1) | ||
195 | return ctx->keygen_info_count; | ||
196 | if (idx < 0 || idx > ctx->keygen_info_count) | ||
197 | return 0; | ||
198 | return ctx->keygen_info[idx]; | ||
199 | } | ||
200 | |||
201 | EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, | ||
202 | unsigned char *key, int keylen) | ||
203 | { | ||
204 | EVP_PKEY_CTX *mac_ctx = NULL; | ||
205 | EVP_PKEY *mac_key = NULL; | ||
206 | mac_ctx = EVP_PKEY_CTX_new_id(type, e); | ||
207 | if (!mac_ctx) | ||
208 | return NULL; | ||
209 | if (EVP_PKEY_keygen_init(mac_ctx) <= 0) | ||
210 | goto merr; | ||
211 | if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, | ||
212 | EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0) | ||
213 | goto merr; | ||
214 | if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) | ||
215 | goto merr; | ||
216 | merr: | ||
217 | if (mac_ctx) | ||
218 | EVP_PKEY_CTX_free(mac_ctx); | ||
219 | return mac_key; | ||
220 | } | ||
diff --git a/src/lib/libcrypto/evp/pmeth_lib.c b/src/lib/libcrypto/evp/pmeth_lib.c new file mode 100644 index 0000000000..b2d8de3a8d --- /dev/null +++ b/src/lib/libcrypto/evp/pmeth_lib.c | |||
@@ -0,0 +1,538 @@ | |||
1 | /* pmeth_lib.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2006. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <stdlib.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/evp.h> | ||
64 | #ifndef OPENSSL_NO_ENGINE | ||
65 | #include <openssl/engine.h> | ||
66 | #endif | ||
67 | #include "asn1_locl.h" | ||
68 | #include "evp_locl.h" | ||
69 | |||
70 | typedef int sk_cmp_fn_type(const char * const *a, const char * const *b); | ||
71 | |||
72 | DECLARE_STACK_OF(EVP_PKEY_METHOD) | ||
73 | STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; | ||
74 | |||
75 | extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth; | ||
76 | extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth; | ||
77 | |||
78 | static const EVP_PKEY_METHOD *standard_methods[] = | ||
79 | { | ||
80 | #ifndef OPENSSL_NO_RSA | ||
81 | &rsa_pkey_meth, | ||
82 | #endif | ||
83 | #ifndef OPENSSL_NO_DH | ||
84 | &dh_pkey_meth, | ||
85 | #endif | ||
86 | #ifndef OPENSSL_NO_DSA | ||
87 | &dsa_pkey_meth, | ||
88 | #endif | ||
89 | #ifndef OPENSSL_NO_EC | ||
90 | &ec_pkey_meth, | ||
91 | #endif | ||
92 | &hmac_pkey_meth, | ||
93 | }; | ||
94 | |||
95 | DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, | ||
96 | pmeth); | ||
97 | |||
98 | static int pmeth_cmp(const EVP_PKEY_METHOD * const *a, | ||
99 | const EVP_PKEY_METHOD * const *b) | ||
100 | { | ||
101 | return ((*a)->pkey_id - (*b)->pkey_id); | ||
102 | } | ||
103 | |||
104 | IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, | ||
105 | pmeth); | ||
106 | |||
107 | const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) | ||
108 | { | ||
109 | EVP_PKEY_METHOD tmp; | ||
110 | const EVP_PKEY_METHOD *t = &tmp, **ret; | ||
111 | tmp.pkey_id = type; | ||
112 | if (app_pkey_methods) | ||
113 | { | ||
114 | int idx; | ||
115 | idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp); | ||
116 | if (idx >= 0) | ||
117 | return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); | ||
118 | } | ||
119 | ret = OBJ_bsearch_pmeth(&t, standard_methods, | ||
120 | sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *)); | ||
121 | if (!ret || !*ret) | ||
122 | return NULL; | ||
123 | return *ret; | ||
124 | } | ||
125 | |||
126 | static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) | ||
127 | { | ||
128 | EVP_PKEY_CTX *ret; | ||
129 | const EVP_PKEY_METHOD *pmeth; | ||
130 | if (id == -1) | ||
131 | { | ||
132 | if (!pkey || !pkey->ameth) | ||
133 | return NULL; | ||
134 | id = pkey->ameth->pkey_id; | ||
135 | } | ||
136 | #ifndef OPENSSL_NO_ENGINE | ||
137 | /* Try to find an ENGINE which implements this method */ | ||
138 | if (e) | ||
139 | { | ||
140 | if (!ENGINE_init(e)) | ||
141 | { | ||
142 | EVPerr(EVP_F_INT_CTX_NEW,ERR_R_ENGINE_LIB); | ||
143 | return NULL; | ||
144 | } | ||
145 | } | ||
146 | else | ||
147 | e = ENGINE_get_pkey_meth_engine(id); | ||
148 | |||
149 | /* If an ENGINE handled this method look it up. Othewise | ||
150 | * use internal tables. | ||
151 | */ | ||
152 | |||
153 | if (e) | ||
154 | pmeth = ENGINE_get_pkey_meth(e, id); | ||
155 | else | ||
156 | #endif | ||
157 | pmeth = EVP_PKEY_meth_find(id); | ||
158 | |||
159 | if (pmeth == NULL) | ||
160 | { | ||
161 | EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM); | ||
162 | return NULL; | ||
163 | } | ||
164 | |||
165 | ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); | ||
166 | if (!ret) | ||
167 | { | ||
168 | #ifndef OPENSSL_NO_ENGINE | ||
169 | if (e) | ||
170 | ENGINE_finish(e); | ||
171 | #endif | ||
172 | EVPerr(EVP_F_INT_CTX_NEW,ERR_R_MALLOC_FAILURE); | ||
173 | return NULL; | ||
174 | } | ||
175 | ret->engine = e; | ||
176 | ret->pmeth = pmeth; | ||
177 | ret->operation = EVP_PKEY_OP_UNDEFINED; | ||
178 | ret->pkey = pkey; | ||
179 | ret->peerkey = NULL; | ||
180 | ret->pkey_gencb = 0; | ||
181 | if (pkey) | ||
182 | CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); | ||
183 | ret->data = NULL; | ||
184 | |||
185 | if (pmeth->init) | ||
186 | { | ||
187 | if (pmeth->init(ret) <= 0) | ||
188 | { | ||
189 | EVP_PKEY_CTX_free(ret); | ||
190 | return NULL; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags) | ||
198 | { | ||
199 | EVP_PKEY_METHOD *pmeth; | ||
200 | pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD)); | ||
201 | if (!pmeth) | ||
202 | return NULL; | ||
203 | |||
204 | pmeth->pkey_id = id; | ||
205 | pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; | ||
206 | |||
207 | pmeth->init = 0; | ||
208 | pmeth->copy = 0; | ||
209 | pmeth->cleanup = 0; | ||
210 | pmeth->paramgen_init = 0; | ||
211 | pmeth->paramgen = 0; | ||
212 | pmeth->keygen_init = 0; | ||
213 | pmeth->keygen = 0; | ||
214 | pmeth->sign_init = 0; | ||
215 | pmeth->sign = 0; | ||
216 | pmeth->verify_init = 0; | ||
217 | pmeth->verify = 0; | ||
218 | pmeth->verify_recover_init = 0; | ||
219 | pmeth->verify_recover = 0; | ||
220 | pmeth->signctx_init = 0; | ||
221 | pmeth->signctx = 0; | ||
222 | pmeth->verifyctx_init = 0; | ||
223 | pmeth->verifyctx = 0; | ||
224 | pmeth->encrypt_init = 0; | ||
225 | pmeth->encrypt = 0; | ||
226 | pmeth->decrypt_init = 0; | ||
227 | pmeth->decrypt = 0; | ||
228 | pmeth->derive_init = 0; | ||
229 | pmeth->derive = 0; | ||
230 | pmeth->ctrl = 0; | ||
231 | pmeth->ctrl_str = 0; | ||
232 | |||
233 | return pmeth; | ||
234 | } | ||
235 | |||
236 | void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) | ||
237 | { | ||
238 | if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC)) | ||
239 | OPENSSL_free(pmeth); | ||
240 | } | ||
241 | |||
242 | EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) | ||
243 | { | ||
244 | return int_ctx_new(pkey, e, -1); | ||
245 | } | ||
246 | |||
247 | EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) | ||
248 | { | ||
249 | return int_ctx_new(NULL, e, id); | ||
250 | } | ||
251 | |||
252 | EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) | ||
253 | { | ||
254 | EVP_PKEY_CTX *rctx; | ||
255 | if (!pctx->pmeth || !pctx->pmeth->copy) | ||
256 | return NULL; | ||
257 | #ifndef OPENSSL_NO_ENGINE | ||
258 | /* Make sure it's safe to copy a pkey context using an ENGINE */ | ||
259 | if (pctx->engine && !ENGINE_init(pctx->engine)) | ||
260 | { | ||
261 | EVPerr(EVP_F_EVP_PKEY_CTX_DUP,ERR_R_ENGINE_LIB); | ||
262 | return 0; | ||
263 | } | ||
264 | #endif | ||
265 | rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); | ||
266 | if (!rctx) | ||
267 | return NULL; | ||
268 | |||
269 | rctx->pmeth = pctx->pmeth; | ||
270 | #ifndef OPENSSL_NO_ENGINE | ||
271 | rctx->engine = pctx->engine; | ||
272 | #endif | ||
273 | |||
274 | if (pctx->pkey) | ||
275 | CRYPTO_add(&pctx->pkey->references,1,CRYPTO_LOCK_EVP_PKEY); | ||
276 | |||
277 | rctx->pkey = pctx->pkey; | ||
278 | |||
279 | if (pctx->peerkey) | ||
280 | CRYPTO_add(&pctx->peerkey->references,1,CRYPTO_LOCK_EVP_PKEY); | ||
281 | |||
282 | rctx->peerkey = pctx->peerkey; | ||
283 | |||
284 | rctx->data = NULL; | ||
285 | rctx->app_data = NULL; | ||
286 | rctx->operation = pctx->operation; | ||
287 | |||
288 | if (pctx->pmeth->copy(rctx, pctx) > 0) | ||
289 | return rctx; | ||
290 | |||
291 | EVP_PKEY_CTX_free(rctx); | ||
292 | return NULL; | ||
293 | |||
294 | } | ||
295 | |||
296 | int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) | ||
297 | { | ||
298 | if (app_pkey_methods == NULL) | ||
299 | { | ||
300 | app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp); | ||
301 | if (!app_pkey_methods) | ||
302 | return 0; | ||
303 | } | ||
304 | if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) | ||
305 | return 0; | ||
306 | sk_EVP_PKEY_METHOD_sort(app_pkey_methods); | ||
307 | return 1; | ||
308 | } | ||
309 | |||
310 | void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) | ||
311 | { | ||
312 | if (ctx == NULL) | ||
313 | return; | ||
314 | if (ctx->pmeth && ctx->pmeth->cleanup) | ||
315 | ctx->pmeth->cleanup(ctx); | ||
316 | if (ctx->pkey) | ||
317 | EVP_PKEY_free(ctx->pkey); | ||
318 | if (ctx->peerkey) | ||
319 | EVP_PKEY_free(ctx->peerkey); | ||
320 | #ifndef OPENSSL_NO_ENGINE | ||
321 | if(ctx->engine) | ||
322 | /* The EVP_PKEY_CTX we used belongs to an ENGINE, release the | ||
323 | * functional reference we held for this reason. */ | ||
324 | ENGINE_finish(ctx->engine); | ||
325 | #endif | ||
326 | OPENSSL_free(ctx); | ||
327 | } | ||
328 | |||
329 | int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, | ||
330 | int cmd, int p1, void *p2) | ||
331 | { | ||
332 | int ret; | ||
333 | if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) | ||
334 | { | ||
335 | EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); | ||
336 | return -2; | ||
337 | } | ||
338 | if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) | ||
339 | return -1; | ||
340 | |||
341 | if (ctx->operation == EVP_PKEY_OP_UNDEFINED) | ||
342 | { | ||
343 | EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET); | ||
344 | return -1; | ||
345 | } | ||
346 | |||
347 | if ((optype != -1) && !(ctx->operation & optype)) | ||
348 | { | ||
349 | EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION); | ||
350 | return -1; | ||
351 | } | ||
352 | |||
353 | ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); | ||
354 | |||
355 | if (ret == -2) | ||
356 | EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); | ||
357 | |||
358 | return ret; | ||
359 | |||
360 | } | ||
361 | |||
362 | int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, | ||
363 | const char *name, const char *value) | ||
364 | { | ||
365 | if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) | ||
366 | { | ||
367 | EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, | ||
368 | EVP_R_COMMAND_NOT_SUPPORTED); | ||
369 | return -2; | ||
370 | } | ||
371 | if (!strcmp(name, "digest")) | ||
372 | { | ||
373 | const EVP_MD *md; | ||
374 | if (!value || !(md = EVP_get_digestbyname(value))) | ||
375 | { | ||
376 | EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, | ||
377 | EVP_R_INVALID_DIGEST); | ||
378 | return 0; | ||
379 | } | ||
380 | return EVP_PKEY_CTX_set_signature_md(ctx, md); | ||
381 | } | ||
382 | return ctx->pmeth->ctrl_str(ctx, name, value); | ||
383 | } | ||
384 | |||
385 | int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx) | ||
386 | { | ||
387 | return ctx->operation; | ||
388 | } | ||
389 | |||
390 | void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen) | ||
391 | { | ||
392 | ctx->keygen_info = dat; | ||
393 | ctx->keygen_info_count = datlen; | ||
394 | } | ||
395 | |||
396 | void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data) | ||
397 | { | ||
398 | ctx->data = data; | ||
399 | } | ||
400 | |||
401 | void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx) | ||
402 | { | ||
403 | return ctx->data; | ||
404 | } | ||
405 | |||
406 | EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) | ||
407 | { | ||
408 | return ctx->pkey; | ||
409 | } | ||
410 | |||
411 | EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx) | ||
412 | { | ||
413 | return ctx->peerkey; | ||
414 | } | ||
415 | |||
416 | void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) | ||
417 | { | ||
418 | ctx->app_data = data; | ||
419 | } | ||
420 | |||
421 | void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) | ||
422 | { | ||
423 | return ctx->app_data; | ||
424 | } | ||
425 | |||
426 | void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, | ||
427 | int (*init)(EVP_PKEY_CTX *ctx)) | ||
428 | { | ||
429 | pmeth->init = init; | ||
430 | } | ||
431 | |||
432 | void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, | ||
433 | int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)) | ||
434 | { | ||
435 | pmeth->copy = copy; | ||
436 | } | ||
437 | |||
438 | void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, | ||
439 | void (*cleanup)(EVP_PKEY_CTX *ctx)) | ||
440 | { | ||
441 | pmeth->cleanup = cleanup; | ||
442 | } | ||
443 | |||
444 | void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, | ||
445 | int (*paramgen_init)(EVP_PKEY_CTX *ctx), | ||
446 | int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)) | ||
447 | { | ||
448 | pmeth->paramgen_init = paramgen_init; | ||
449 | pmeth->paramgen = paramgen; | ||
450 | } | ||
451 | |||
452 | void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, | ||
453 | int (*keygen_init)(EVP_PKEY_CTX *ctx), | ||
454 | int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)) | ||
455 | { | ||
456 | pmeth->keygen_init = keygen_init; | ||
457 | pmeth->keygen = keygen; | ||
458 | } | ||
459 | |||
460 | void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, | ||
461 | int (*sign_init)(EVP_PKEY_CTX *ctx), | ||
462 | int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, | ||
463 | const unsigned char *tbs, size_t tbslen)) | ||
464 | { | ||
465 | pmeth->sign_init = sign_init; | ||
466 | pmeth->sign = sign; | ||
467 | } | ||
468 | |||
469 | void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, | ||
470 | int (*verify_init)(EVP_PKEY_CTX *ctx), | ||
471 | int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, | ||
472 | const unsigned char *tbs, size_t tbslen)) | ||
473 | { | ||
474 | pmeth->verify_init = verify_init; | ||
475 | pmeth->verify = verify; | ||
476 | } | ||
477 | |||
478 | void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, | ||
479 | int (*verify_recover_init)(EVP_PKEY_CTX *ctx), | ||
480 | int (*verify_recover)(EVP_PKEY_CTX *ctx, | ||
481 | unsigned char *sig, size_t *siglen, | ||
482 | const unsigned char *tbs, size_t tbslen)) | ||
483 | { | ||
484 | pmeth->verify_recover_init = verify_recover_init; | ||
485 | pmeth->verify_recover = verify_recover; | ||
486 | } | ||
487 | |||
488 | void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, | ||
489 | int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), | ||
490 | int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, | ||
491 | EVP_MD_CTX *mctx)) | ||
492 | { | ||
493 | pmeth->signctx_init = signctx_init; | ||
494 | pmeth->signctx = signctx; | ||
495 | } | ||
496 | |||
497 | void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, | ||
498 | int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), | ||
499 | int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen, | ||
500 | EVP_MD_CTX *mctx)) | ||
501 | { | ||
502 | pmeth->verifyctx_init = verifyctx_init; | ||
503 | pmeth->verifyctx = verifyctx; | ||
504 | } | ||
505 | |||
506 | void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, | ||
507 | int (*encrypt_init)(EVP_PKEY_CTX *ctx), | ||
508 | int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, | ||
509 | const unsigned char *in, size_t inlen)) | ||
510 | { | ||
511 | pmeth->encrypt_init = encrypt_init; | ||
512 | pmeth->encrypt = encryptfn; | ||
513 | } | ||
514 | |||
515 | void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, | ||
516 | int (*decrypt_init)(EVP_PKEY_CTX *ctx), | ||
517 | int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, | ||
518 | const unsigned char *in, size_t inlen)) | ||
519 | { | ||
520 | pmeth->decrypt_init = decrypt_init; | ||
521 | pmeth->decrypt = decrypt; | ||
522 | } | ||
523 | |||
524 | void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, | ||
525 | int (*derive_init)(EVP_PKEY_CTX *ctx), | ||
526 | int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)) | ||
527 | { | ||
528 | pmeth->derive_init = derive_init; | ||
529 | pmeth->derive = derive; | ||
530 | } | ||
531 | |||
532 | void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, | ||
533 | int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2), | ||
534 | int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value)) | ||
535 | { | ||
536 | pmeth->ctrl = ctrl; | ||
537 | pmeth->ctrl_str = ctrl_str; | ||
538 | } | ||
diff --git a/src/lib/libcrypto/hmac/hm_ameth.c b/src/lib/libcrypto/hmac/hm_ameth.c new file mode 100644 index 0000000000..6d8a89149e --- /dev/null +++ b/src/lib/libcrypto/hmac/hm_ameth.c | |||
@@ -0,0 +1,167 @@ | |||
1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
2 | * project 2007. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2007 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <stdio.h> | ||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/evp.h> | ||
61 | #include "asn1_locl.h" | ||
62 | |||
63 | #define HMAC_TEST_PRIVATE_KEY_FORMAT | ||
64 | |||
65 | /* HMAC "ASN1" method. This is just here to indicate the | ||
66 | * maximum HMAC output length and to free up an HMAC | ||
67 | * key. | ||
68 | */ | ||
69 | |||
70 | static int hmac_size(const EVP_PKEY *pkey) | ||
71 | { | ||
72 | return EVP_MAX_MD_SIZE; | ||
73 | } | ||
74 | |||
75 | static void hmac_key_free(EVP_PKEY *pkey) | ||
76 | { | ||
77 | ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; | ||
78 | if (os) | ||
79 | { | ||
80 | if (os->data) | ||
81 | OPENSSL_cleanse(os->data, os->length); | ||
82 | ASN1_OCTET_STRING_free(os); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | |||
87 | static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | ||
88 | { | ||
89 | switch (op) | ||
90 | { | ||
91 | case ASN1_PKEY_CTRL_DEFAULT_MD_NID: | ||
92 | *(int *)arg2 = NID_sha1; | ||
93 | return 1; | ||
94 | |||
95 | default: | ||
96 | return -2; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | #ifdef HMAC_TEST_PRIVATE_KEY_FORMAT | ||
101 | /* A bogus private key format for test purposes. This is simply the | ||
102 | * HMAC key with "HMAC PRIVATE KEY" in the headers. When enabled the | ||
103 | * genpkey utility can be used to "generate" HMAC keys. | ||
104 | */ | ||
105 | |||
106 | static int old_hmac_decode(EVP_PKEY *pkey, | ||
107 | const unsigned char **pder, int derlen) | ||
108 | { | ||
109 | ASN1_OCTET_STRING *os; | ||
110 | os = ASN1_OCTET_STRING_new(); | ||
111 | if (!os || !ASN1_OCTET_STRING_set(os, *pder, derlen)) | ||
112 | return 0; | ||
113 | EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os); | ||
114 | return 1; | ||
115 | } | ||
116 | |||
117 | static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder) | ||
118 | { | ||
119 | int inc; | ||
120 | ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; | ||
121 | if (pder) | ||
122 | { | ||
123 | if (!*pder) | ||
124 | { | ||
125 | *pder = OPENSSL_malloc(os->length); | ||
126 | inc = 0; | ||
127 | } | ||
128 | else inc = 1; | ||
129 | |||
130 | memcpy(*pder, os->data, os->length); | ||
131 | |||
132 | if (inc) | ||
133 | *pder += os->length; | ||
134 | } | ||
135 | |||
136 | return os->length; | ||
137 | } | ||
138 | |||
139 | #endif | ||
140 | |||
141 | const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = | ||
142 | { | ||
143 | EVP_PKEY_HMAC, | ||
144 | EVP_PKEY_HMAC, | ||
145 | 0, | ||
146 | |||
147 | "HMAC", | ||
148 | "OpenSSL HMAC method", | ||
149 | |||
150 | 0,0,0,0, | ||
151 | |||
152 | 0,0,0, | ||
153 | |||
154 | hmac_size, | ||
155 | 0, | ||
156 | 0,0,0,0,0,0, | ||
157 | |||
158 | hmac_key_free, | ||
159 | hmac_pkey_ctrl, | ||
160 | #ifdef HMAC_TEST_PRIVATE_KEY_FORMAT | ||
161 | old_hmac_decode, | ||
162 | old_hmac_encode | ||
163 | #else | ||
164 | 0,0 | ||
165 | #endif | ||
166 | }; | ||
167 | |||
diff --git a/src/lib/libcrypto/hmac/hm_pmeth.c b/src/lib/libcrypto/hmac/hm_pmeth.c new file mode 100644 index 0000000000..985921ca1a --- /dev/null +++ b/src/lib/libcrypto/hmac/hm_pmeth.c | |||
@@ -0,0 +1,265 @@ | |||
1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
2 | * project 2007. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2007 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <stdio.h> | ||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/x509.h> | ||
61 | #include <openssl/x509v3.h> | ||
62 | #include <openssl/evp.h> | ||
63 | #include <openssl/hmac.h> | ||
64 | #include "evp_locl.h" | ||
65 | |||
66 | /* HMAC pkey context structure */ | ||
67 | |||
68 | typedef struct | ||
69 | { | ||
70 | const EVP_MD *md; /* MD for HMAC use */ | ||
71 | ASN1_OCTET_STRING ktmp; /* Temp storage for key */ | ||
72 | HMAC_CTX ctx; | ||
73 | } HMAC_PKEY_CTX; | ||
74 | |||
75 | static int pkey_hmac_init(EVP_PKEY_CTX *ctx) | ||
76 | { | ||
77 | HMAC_PKEY_CTX *hctx; | ||
78 | hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX)); | ||
79 | if (!hctx) | ||
80 | return 0; | ||
81 | hctx->md = NULL; | ||
82 | hctx->ktmp.data = NULL; | ||
83 | hctx->ktmp.length = 0; | ||
84 | hctx->ktmp.flags = 0; | ||
85 | hctx->ktmp.type = V_ASN1_OCTET_STRING; | ||
86 | HMAC_CTX_init(&hctx->ctx); | ||
87 | |||
88 | ctx->data = hctx; | ||
89 | ctx->keygen_info_count = 0; | ||
90 | |||
91 | return 1; | ||
92 | } | ||
93 | |||
94 | static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | ||
95 | { | ||
96 | HMAC_PKEY_CTX *sctx, *dctx; | ||
97 | if (!pkey_hmac_init(dst)) | ||
98 | return 0; | ||
99 | sctx = src->data; | ||
100 | dctx = dst->data; | ||
101 | dctx->md = sctx->md; | ||
102 | HMAC_CTX_init(&dctx->ctx); | ||
103 | HMAC_CTX_copy(&dctx->ctx, &sctx->ctx); | ||
104 | if (sctx->ktmp.data) | ||
105 | { | ||
106 | if (!ASN1_OCTET_STRING_set(&dctx->ktmp, | ||
107 | sctx->ktmp.data, sctx->ktmp.length)) | ||
108 | return 0; | ||
109 | } | ||
110 | return 1; | ||
111 | } | ||
112 | |||
113 | static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) | ||
114 | { | ||
115 | HMAC_PKEY_CTX *hctx = ctx->data; | ||
116 | HMAC_CTX_cleanup(&hctx->ctx); | ||
117 | if (hctx->ktmp.data) | ||
118 | { | ||
119 | if (hctx->ktmp.length) | ||
120 | OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length); | ||
121 | OPENSSL_free(hctx->ktmp.data); | ||
122 | hctx->ktmp.data = NULL; | ||
123 | } | ||
124 | OPENSSL_free(hctx); | ||
125 | } | ||
126 | |||
127 | static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
128 | { | ||
129 | ASN1_OCTET_STRING *hkey = NULL; | ||
130 | HMAC_PKEY_CTX *hctx = ctx->data; | ||
131 | if (!hctx->ktmp.data) | ||
132 | return 0; | ||
133 | hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp); | ||
134 | if (!hkey) | ||
135 | return 0; | ||
136 | EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey); | ||
137 | |||
138 | return 1; | ||
139 | } | ||
140 | |||
141 | static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count) | ||
142 | { | ||
143 | HMAC_PKEY_CTX *hctx = ctx->pctx->data; | ||
144 | HMAC_Update(&hctx->ctx, data, count); | ||
145 | return 1; | ||
146 | } | ||
147 | |||
148 | static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) | ||
149 | { | ||
150 | EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); | ||
151 | mctx->update = int_update; | ||
152 | return 1; | ||
153 | } | ||
154 | |||
155 | static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, | ||
156 | EVP_MD_CTX *mctx) | ||
157 | { | ||
158 | unsigned int hlen; | ||
159 | HMAC_PKEY_CTX *hctx = ctx->data; | ||
160 | int l = EVP_MD_CTX_size(mctx); | ||
161 | |||
162 | if (l < 0) | ||
163 | return 0; | ||
164 | *siglen = l; | ||
165 | if (!sig) | ||
166 | return 1; | ||
167 | |||
168 | HMAC_Final(&hctx->ctx, sig, &hlen); | ||
169 | *siglen = (size_t)hlen; | ||
170 | return 1; | ||
171 | } | ||
172 | |||
173 | static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | ||
174 | { | ||
175 | HMAC_PKEY_CTX *hctx = ctx->data; | ||
176 | ASN1_OCTET_STRING *key; | ||
177 | switch (type) | ||
178 | { | ||
179 | |||
180 | case EVP_PKEY_CTRL_SET_MAC_KEY: | ||
181 | if ((!p2 && p1 > 0) || (p1 < -1)) | ||
182 | return 0; | ||
183 | if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) | ||
184 | return 0; | ||
185 | break; | ||
186 | |||
187 | case EVP_PKEY_CTRL_MD: | ||
188 | hctx->md = p2; | ||
189 | break; | ||
190 | |||
191 | case EVP_PKEY_CTRL_DIGESTINIT: | ||
192 | key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; | ||
193 | HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md, | ||
194 | ctx->engine); | ||
195 | break; | ||
196 | |||
197 | default: | ||
198 | return -2; | ||
199 | |||
200 | } | ||
201 | return 1; | ||
202 | } | ||
203 | |||
204 | static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx, | ||
205 | const char *type, const char *value) | ||
206 | { | ||
207 | if (!value) | ||
208 | { | ||
209 | return 0; | ||
210 | } | ||
211 | if (!strcmp(type, "key")) | ||
212 | { | ||
213 | void *p = (void *)value; | ||
214 | return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, | ||
215 | -1, p); | ||
216 | } | ||
217 | if (!strcmp(type, "hexkey")) | ||
218 | { | ||
219 | unsigned char *key; | ||
220 | int r; | ||
221 | long keylen; | ||
222 | key = string_to_hex(value, &keylen); | ||
223 | if (!key) | ||
224 | return 0; | ||
225 | r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); | ||
226 | OPENSSL_free(key); | ||
227 | return r; | ||
228 | } | ||
229 | return -2; | ||
230 | } | ||
231 | |||
232 | const EVP_PKEY_METHOD hmac_pkey_meth = | ||
233 | { | ||
234 | EVP_PKEY_HMAC, | ||
235 | 0, | ||
236 | pkey_hmac_init, | ||
237 | pkey_hmac_copy, | ||
238 | pkey_hmac_cleanup, | ||
239 | |||
240 | 0, 0, | ||
241 | |||
242 | 0, | ||
243 | pkey_hmac_keygen, | ||
244 | |||
245 | 0, 0, | ||
246 | |||
247 | 0, 0, | ||
248 | |||
249 | 0,0, | ||
250 | |||
251 | hmac_signctx_init, | ||
252 | hmac_signctx, | ||
253 | |||
254 | 0,0, | ||
255 | |||
256 | 0,0, | ||
257 | |||
258 | 0,0, | ||
259 | |||
260 | 0,0, | ||
261 | |||
262 | pkey_hmac_ctrl, | ||
263 | pkey_hmac_ctrl_str | ||
264 | |||
265 | }; | ||
diff --git a/src/lib/libcrypto/ia64cpuid.S b/src/lib/libcrypto/ia64cpuid.S index 04fbb3439e..d705fff7ee 100644 --- a/src/lib/libcrypto/ia64cpuid.S +++ b/src/lib/libcrypto/ia64cpuid.S | |||
@@ -1,6 +1,13 @@ | |||
1 | // Works on all IA-64 platforms: Linux, HP-UX, Win64i... | 1 | // Works on all IA-64 platforms: Linux, HP-UX, Win64i... |
2 | // On Win64i compile with ias.exe. | 2 | // On Win64i compile with ias.exe. |
3 | .text | 3 | .text |
4 | |||
5 | .global OPENSSL_cpuid_setup# | ||
6 | .proc OPENSSL_cpuid_setup# | ||
7 | OPENSSL_cpuid_setup: | ||
8 | { .mib; br.ret.sptk.many b0 };; | ||
9 | .endp OPENSSL_cpuid_setup# | ||
10 | |||
4 | .global OPENSSL_rdtsc# | 11 | .global OPENSSL_rdtsc# |
5 | .proc OPENSSL_rdtsc# | 12 | .proc OPENSSL_rdtsc# |
6 | OPENSSL_rdtsc: | 13 | OPENSSL_rdtsc: |
@@ -119,3 +126,42 @@ OPENSSL_wipe_cpu: | |||
119 | mov ar.lc=r3 | 126 | mov ar.lc=r3 |
120 | br.ret.sptk b0 };; | 127 | br.ret.sptk b0 };; |
121 | .endp OPENSSL_wipe_cpu# | 128 | .endp OPENSSL_wipe_cpu# |
129 | |||
130 | .global OPENSSL_cleanse# | ||
131 | .proc OPENSSL_cleanse# | ||
132 | OPENSSL_cleanse: | ||
133 | { .mib; cmp.eq p6,p0=0,r33 // len==0 | ||
134 | #if defined(_HPUX_SOURCE) && !defined(_LP64) | ||
135 | addp4 r32=0,r32 | ||
136 | #endif | ||
137 | (p6) br.ret.spnt b0 };; | ||
138 | { .mib; and r2=7,r32 | ||
139 | cmp.leu p6,p0=15,r33 // len>=15 | ||
140 | (p6) br.cond.dptk .Lot };; | ||
141 | |||
142 | .Little: | ||
143 | { .mib; st1 [r32]=r0,1 | ||
144 | cmp.ltu p6,p7=1,r33 } // len>1 | ||
145 | { .mbb; add r33=-1,r33 // len-- | ||
146 | (p6) br.cond.dptk .Little | ||
147 | (p7) br.ret.sptk.many b0 };; | ||
148 | |||
149 | .Lot: | ||
150 | { .mib; cmp.eq p6,p0=0,r2 | ||
151 | (p6) br.cond.dptk .Laligned };; | ||
152 | { .mmi; st1 [r32]=r0,1;; | ||
153 | and r2=7,r32 } | ||
154 | { .mib; add r33=-1,r33 | ||
155 | br .Lot };; | ||
156 | |||
157 | .Laligned: | ||
158 | { .mmi; st8 [r32]=r0,8 | ||
159 | and r2=-8,r33 // len&~7 | ||
160 | add r33=-8,r33 };; // len-=8 | ||
161 | { .mib; cmp.ltu p6,p0=8,r2 // ((len+8)&~7)>8 | ||
162 | (p6) br.cond.dptk .Laligned };; | ||
163 | |||
164 | { .mbb; cmp.eq p6,p7=r0,r33 | ||
165 | (p7) br.cond.dpnt .Little | ||
166 | (p6) br.ret.sptk.many b0 };; | ||
167 | .endp OPENSSL_cleanse# | ||
diff --git a/src/lib/libcrypto/md5/asm/md5-ia64.S b/src/lib/libcrypto/md5/asm/md5-ia64.S new file mode 100644 index 0000000000..e7de08d46a --- /dev/null +++ b/src/lib/libcrypto/md5/asm/md5-ia64.S | |||
@@ -0,0 +1,992 @@ | |||
1 | /* Copyright (c) 2005 Hewlett-Packard Development Company, L.P. | ||
2 | |||
3 | Permission is hereby granted, free of charge, to any person obtaining | ||
4 | a copy of this software and associated documentation files (the | ||
5 | "Software"), to deal in the Software without restriction, including | ||
6 | without limitation the rights to use, copy, modify, merge, publish, | ||
7 | distribute, sublicense, and/or sell copies of the Software, and to | ||
8 | permit persons to whom the Software is furnished to do so, subject to | ||
9 | the following conditions: | ||
10 | |||
11 | The above copyright notice and this permission notice shall be | ||
12 | included in all copies or substantial portions of the Software. | ||
13 | |||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ | ||
21 | |||
22 | // Common registers are assigned as follows: | ||
23 | // | ||
24 | // COMMON | ||
25 | // | ||
26 | // t0 Const Tbl Ptr TPtr | ||
27 | // t1 Round Constant TRound | ||
28 | // t4 Block residual LenResid | ||
29 | // t5 Residual Data DTmp | ||
30 | // | ||
31 | // {in,out}0 Block 0 Cycle RotateM0 | ||
32 | // {in,out}1 Block Value 12 M12 | ||
33 | // {in,out}2 Block Value 8 M8 | ||
34 | // {in,out}3 Block Value 4 M4 | ||
35 | // {in,out}4 Block Value 0 M0 | ||
36 | // {in,out}5 Block 1 Cycle RotateM1 | ||
37 | // {in,out}6 Block Value 13 M13 | ||
38 | // {in,out}7 Block Value 9 M9 | ||
39 | // {in,out}8 Block Value 5 M5 | ||
40 | // {in,out}9 Block Value 1 M1 | ||
41 | // {in,out}10 Block 2 Cycle RotateM2 | ||
42 | // {in,out}11 Block Value 14 M14 | ||
43 | // {in,out}12 Block Value 10 M10 | ||
44 | // {in,out}13 Block Value 6 M6 | ||
45 | // {in,out}14 Block Value 2 M2 | ||
46 | // {in,out}15 Block 3 Cycle RotateM3 | ||
47 | // {in,out}16 Block Value 15 M15 | ||
48 | // {in,out}17 Block Value 11 M11 | ||
49 | // {in,out}18 Block Value 7 M7 | ||
50 | // {in,out}19 Block Value 3 M3 | ||
51 | // {in,out}20 Scratch Z | ||
52 | // {in,out}21 Scratch Y | ||
53 | // {in,out}22 Scratch X | ||
54 | // {in,out}23 Scratch W | ||
55 | // {in,out}24 Digest A A | ||
56 | // {in,out}25 Digest B B | ||
57 | // {in,out}26 Digest C C | ||
58 | // {in,out}27 Digest D D | ||
59 | // {in,out}28 Active Data Ptr DPtr | ||
60 | // in28 Dummy Value - | ||
61 | // out28 Dummy Value - | ||
62 | // bt0 Coroutine Link QUICK_RTN | ||
63 | // | ||
64 | /// These predicates are used for computing the padding block(s) and | ||
65 | /// are shared between the driver and digest co-routines | ||
66 | // | ||
67 | // pt0 Extra Pad Block pExtra | ||
68 | // pt1 Load next word pLoad | ||
69 | // pt2 Skip next word pSkip | ||
70 | // pt3 Search for Pad pNoPad | ||
71 | // pt4 Pad Word 0 pPad0 | ||
72 | // pt5 Pad Word 1 pPad1 | ||
73 | // pt6 Pad Word 2 pPad2 | ||
74 | // pt7 Pad Word 3 pPad3 | ||
75 | |||
76 | #define DTmp r19 | ||
77 | #define LenResid r18 | ||
78 | #define QUICK_RTN b6 | ||
79 | #define TPtr r14 | ||
80 | #define TRound r15 | ||
81 | #define pExtra p6 | ||
82 | #define pLoad p7 | ||
83 | #define pNoPad p9 | ||
84 | #define pPad0 p10 | ||
85 | #define pPad1 p11 | ||
86 | #define pPad2 p12 | ||
87 | #define pPad3 p13 | ||
88 | #define pSkip p8 | ||
89 | |||
90 | #define A_ out24 | ||
91 | #define B_ out25 | ||
92 | #define C_ out26 | ||
93 | #define D_ out27 | ||
94 | #define DPtr_ out28 | ||
95 | #define M0_ out4 | ||
96 | #define M1_ out9 | ||
97 | #define M10_ out12 | ||
98 | #define M11_ out17 | ||
99 | #define M12_ out1 | ||
100 | #define M13_ out6 | ||
101 | #define M14_ out11 | ||
102 | #define M15_ out16 | ||
103 | #define M2_ out14 | ||
104 | #define M3_ out19 | ||
105 | #define M4_ out3 | ||
106 | #define M5_ out8 | ||
107 | #define M6_ out13 | ||
108 | #define M7_ out18 | ||
109 | #define M8_ out2 | ||
110 | #define M9_ out7 | ||
111 | #define RotateM0_ out0 | ||
112 | #define RotateM1_ out5 | ||
113 | #define RotateM2_ out10 | ||
114 | #define RotateM3_ out15 | ||
115 | #define W_ out23 | ||
116 | #define X_ out22 | ||
117 | #define Y_ out21 | ||
118 | #define Z_ out20 | ||
119 | |||
120 | #define A in24 | ||
121 | #define B in25 | ||
122 | #define C in26 | ||
123 | #define D in27 | ||
124 | #define DPtr in28 | ||
125 | #define M0 in4 | ||
126 | #define M1 in9 | ||
127 | #define M10 in12 | ||
128 | #define M11 in17 | ||
129 | #define M12 in1 | ||
130 | #define M13 in6 | ||
131 | #define M14 in11 | ||
132 | #define M15 in16 | ||
133 | #define M2 in14 | ||
134 | #define M3 in19 | ||
135 | #define M4 in3 | ||
136 | #define M5 in8 | ||
137 | #define M6 in13 | ||
138 | #define M7 in18 | ||
139 | #define M8 in2 | ||
140 | #define M9 in7 | ||
141 | #define RotateM0 in0 | ||
142 | #define RotateM1 in5 | ||
143 | #define RotateM2 in10 | ||
144 | #define RotateM3 in15 | ||
145 | #define W in23 | ||
146 | #define X in22 | ||
147 | #define Y in21 | ||
148 | #define Z in20 | ||
149 | |||
150 | /* register stack configuration for md5_block_asm_data_order(): */ | ||
151 | #define MD5_NINP 3 | ||
152 | #define MD5_NLOC 0 | ||
153 | #define MD5_NOUT 29 | ||
154 | #define MD5_NROT 0 | ||
155 | |||
156 | /* register stack configuration for helpers: */ | ||
157 | #define _NINPUTS MD5_NOUT | ||
158 | #define _NLOCALS 0 | ||
159 | #define _NOUTPUT 0 | ||
160 | #define _NROTATE 24 /* this must be <= _NINPUTS */ | ||
161 | |||
162 | #if defined(_HPUX_SOURCE) && !defined(_LP64) | ||
163 | #define ADDP addp4 | ||
164 | #else | ||
165 | #define ADDP add | ||
166 | #endif | ||
167 | |||
168 | #if defined(_HPUX_SOURCE) || defined(B_ENDIAN) | ||
169 | #define HOST_IS_BIG_ENDIAN | ||
170 | #endif | ||
171 | |||
172 | // Macros for getting the left and right portions of little-endian words | ||
173 | |||
174 | #define GETLW(dst, src, align) dep.z dst = src, 32 - 8 * align, 8 * align | ||
175 | #define GETRW(dst, src, align) extr.u dst = src, 8 * align, 32 - 8 * align | ||
176 | |||
177 | // MD5 driver | ||
178 | // | ||
179 | // Reads an input block, then calls the digest block | ||
180 | // subroutine and adds the results to the accumulated | ||
181 | // digest. It allocates 32 outs which the subroutine | ||
182 | // uses as it's inputs and rotating | ||
183 | // registers. Initializes the round constant pointer and | ||
184 | // takes care of saving/restoring ar.lc | ||
185 | // | ||
186 | /// INPUT | ||
187 | // | ||
188 | // in0 Context Ptr CtxPtr0 | ||
189 | // in1 Input Data Ptr DPtrIn | ||
190 | // in2 Integral Blocks BlockCount | ||
191 | // rp Return Address - | ||
192 | // | ||
193 | /// CODE | ||
194 | // | ||
195 | // v2 Input Align InAlign | ||
196 | // t0 Shared w/digest - | ||
197 | // t1 Shared w/digest - | ||
198 | // t2 Shared w/digest - | ||
199 | // t3 Shared w/digest - | ||
200 | // t4 Shared w/digest - | ||
201 | // t5 Shared w/digest - | ||
202 | // t6 PFS Save PFSSave | ||
203 | // t7 ar.lc Save LCSave | ||
204 | // t8 Saved PR PRSave | ||
205 | // t9 2nd CtxPtr CtxPtr1 | ||
206 | // t10 Table Base CTable | ||
207 | // t11 Table[0] CTable0 | ||
208 | // t13 Accumulator A AccumA | ||
209 | // t14 Accumulator B AccumB | ||
210 | // t15 Accumulator C AccumC | ||
211 | // t16 Accumulator D AccumD | ||
212 | // pt0 Shared w/digest - | ||
213 | // pt1 Shared w/digest - | ||
214 | // pt2 Shared w/digest - | ||
215 | // pt3 Shared w/digest - | ||
216 | // pt4 Shared w/digest - | ||
217 | // pt5 Shared w/digest - | ||
218 | // pt6 Shared w/digest - | ||
219 | // pt7 Shared w/digest - | ||
220 | // pt8 Not Aligned pOff | ||
221 | // pt8 Blocks Left pAgain | ||
222 | |||
223 | #define AccumA r27 | ||
224 | #define AccumB r28 | ||
225 | #define AccumC r29 | ||
226 | #define AccumD r30 | ||
227 | #define CTable r24 | ||
228 | #define CTable0 r25 | ||
229 | #define CtxPtr0 in0 | ||
230 | #define CtxPtr1 r23 | ||
231 | #define DPtrIn in1 | ||
232 | #define BlockCount in2 | ||
233 | #define InAlign r10 | ||
234 | #define LCSave r21 | ||
235 | #define PFSSave r20 | ||
236 | #define PRSave r22 | ||
237 | #define pAgain p63 | ||
238 | #define pOff p63 | ||
239 | |||
240 | .text | ||
241 | |||
242 | /* md5_block_asm_data_order(MD5_CTX *c, const void *data, size_t num) | ||
243 | |||
244 | where: | ||
245 | c: a pointer to a structure of this type: | ||
246 | |||
247 | typedef struct MD5state_st | ||
248 | { | ||
249 | MD5_LONG A,B,C,D; | ||
250 | MD5_LONG Nl,Nh; | ||
251 | MD5_LONG data[MD5_LBLOCK]; | ||
252 | unsigned int num; | ||
253 | } | ||
254 | MD5_CTX; | ||
255 | |||
256 | data: a pointer to the input data (may be misaligned) | ||
257 | num: the number of 16-byte blocks to hash (i.e., the length | ||
258 | of DATA is 16*NUM. | ||
259 | |||
260 | */ | ||
261 | |||
262 | .type md5_block_asm_data_order, @function | ||
263 | .global md5_block_asm_data_order | ||
264 | .align 32 | ||
265 | .proc md5_block_asm_data_order | ||
266 | md5_block_asm_data_order: | ||
267 | .md5_block: | ||
268 | .prologue | ||
269 | { .mmi | ||
270 | .save ar.pfs, PFSSave | ||
271 | alloc PFSSave = ar.pfs, MD5_NINP, MD5_NLOC, MD5_NOUT, MD5_NROT | ||
272 | ADDP CtxPtr1 = 8, CtxPtr0 | ||
273 | mov CTable = ip | ||
274 | } | ||
275 | { .mmi | ||
276 | ADDP DPtrIn = 0, DPtrIn | ||
277 | ADDP CtxPtr0 = 0, CtxPtr0 | ||
278 | .save ar.lc, LCSave | ||
279 | mov LCSave = ar.lc | ||
280 | } | ||
281 | ;; | ||
282 | { .mmi | ||
283 | add CTable = .md5_tbl_data_order#-.md5_block#, CTable | ||
284 | and InAlign = 0x3, DPtrIn | ||
285 | } | ||
286 | |||
287 | { .mmi | ||
288 | ld4 AccumA = [CtxPtr0], 4 | ||
289 | ld4 AccumC = [CtxPtr1], 4 | ||
290 | .save pr, PRSave | ||
291 | mov PRSave = pr | ||
292 | .body | ||
293 | } | ||
294 | ;; | ||
295 | { .mmi | ||
296 | ld4 AccumB = [CtxPtr0] | ||
297 | ld4 AccumD = [CtxPtr1] | ||
298 | dep DPtr_ = 0, DPtrIn, 0, 2 | ||
299 | } ;; | ||
300 | #ifdef HOST_IS_BIG_ENDIAN | ||
301 | rum psr.be;; // switch to little-endian | ||
302 | #endif | ||
303 | { .mmb | ||
304 | ld4 CTable0 = [CTable], 4 | ||
305 | cmp.ne pOff, p0 = 0, InAlign | ||
306 | (pOff) br.cond.spnt.many .md5_unaligned | ||
307 | } ;; | ||
308 | |||
309 | // The FF load/compute loop rotates values three times, so that | ||
310 | // loading into M12 here produces the M0 value, M13 -> M1, etc. | ||
311 | |||
312 | .md5_block_loop0: | ||
313 | { .mmi | ||
314 | ld4 M12_ = [DPtr_], 4 | ||
315 | mov TPtr = CTable | ||
316 | mov TRound = CTable0 | ||
317 | } ;; | ||
318 | { .mmi | ||
319 | ld4 M13_ = [DPtr_], 4 | ||
320 | mov A_ = AccumA | ||
321 | mov B_ = AccumB | ||
322 | } ;; | ||
323 | { .mmi | ||
324 | ld4 M14_ = [DPtr_], 4 | ||
325 | mov C_ = AccumC | ||
326 | mov D_ = AccumD | ||
327 | } ;; | ||
328 | { .mmb | ||
329 | ld4 M15_ = [DPtr_], 4 | ||
330 | add BlockCount = -1, BlockCount | ||
331 | br.call.sptk.many QUICK_RTN = md5_digest_block0 | ||
332 | } ;; | ||
333 | |||
334 | // Now, we add the new digest values and do some clean-up | ||
335 | // before checking if there's another full block to process | ||
336 | |||
337 | { .mmi | ||
338 | add AccumA = AccumA, A_ | ||
339 | add AccumB = AccumB, B_ | ||
340 | cmp.ne pAgain, p0 = 0, BlockCount | ||
341 | } | ||
342 | { .mib | ||
343 | add AccumC = AccumC, C_ | ||
344 | add AccumD = AccumD, D_ | ||
345 | (pAgain) br.cond.dptk.many .md5_block_loop0 | ||
346 | } ;; | ||
347 | |||
348 | .md5_exit: | ||
349 | #ifdef HOST_IS_BIG_ENDIAN | ||
350 | sum psr.be;; // switch back to big-endian mode | ||
351 | #endif | ||
352 | { .mmi | ||
353 | st4 [CtxPtr0] = AccumB, -4 | ||
354 | st4 [CtxPtr1] = AccumD, -4 | ||
355 | mov pr = PRSave, 0x1ffff ;; | ||
356 | } | ||
357 | { .mmi | ||
358 | st4 [CtxPtr0] = AccumA | ||
359 | st4 [CtxPtr1] = AccumC | ||
360 | mov ar.lc = LCSave | ||
361 | } ;; | ||
362 | { .mib | ||
363 | mov ar.pfs = PFSSave | ||
364 | br.ret.sptk.few rp | ||
365 | } ;; | ||
366 | |||
367 | #define MD5UNALIGNED(offset) \ | ||
368 | .md5_process##offset: \ | ||
369 | { .mib ; \ | ||
370 | nop 0x0 ; \ | ||
371 | GETRW(DTmp, DTmp, offset) ; \ | ||
372 | } ;; \ | ||
373 | .md5_block_loop##offset: \ | ||
374 | { .mmi ; \ | ||
375 | ld4 Y_ = [DPtr_], 4 ; \ | ||
376 | mov TPtr = CTable ; \ | ||
377 | mov TRound = CTable0 ; \ | ||
378 | } ;; \ | ||
379 | { .mmi ; \ | ||
380 | ld4 M13_ = [DPtr_], 4 ; \ | ||
381 | mov A_ = AccumA ; \ | ||
382 | mov B_ = AccumB ; \ | ||
383 | } ;; \ | ||
384 | { .mii ; \ | ||
385 | ld4 M14_ = [DPtr_], 4 ; \ | ||
386 | GETLW(W_, Y_, offset) ; \ | ||
387 | mov C_ = AccumC ; \ | ||
388 | } \ | ||
389 | { .mmi ; \ | ||
390 | mov D_ = AccumD ;; \ | ||
391 | or M12_ = W_, DTmp ; \ | ||
392 | GETRW(DTmp, Y_, offset) ; \ | ||
393 | } \ | ||
394 | { .mib ; \ | ||
395 | ld4 M15_ = [DPtr_], 4 ; \ | ||
396 | add BlockCount = -1, BlockCount ; \ | ||
397 | br.call.sptk.many QUICK_RTN = md5_digest_block##offset; \ | ||
398 | } ;; \ | ||
399 | { .mmi ; \ | ||
400 | add AccumA = AccumA, A_ ; \ | ||
401 | add AccumB = AccumB, B_ ; \ | ||
402 | cmp.ne pAgain, p0 = 0, BlockCount ; \ | ||
403 | } \ | ||
404 | { .mib ; \ | ||
405 | add AccumC = AccumC, C_ ; \ | ||
406 | add AccumD = AccumD, D_ ; \ | ||
407 | (pAgain) br.cond.dptk.many .md5_block_loop##offset ; \ | ||
408 | } ;; \ | ||
409 | { .mib ; \ | ||
410 | nop 0x0 ; \ | ||
411 | nop 0x0 ; \ | ||
412 | br.cond.sptk.many .md5_exit ; \ | ||
413 | } ;; | ||
414 | |||
415 | .align 32 | ||
416 | .md5_unaligned: | ||
417 | // | ||
418 | // Because variable shifts are expensive, we special case each of | ||
419 | // the four alignements. In practice, this won't hurt too much | ||
420 | // since only one working set of code will be loaded. | ||
421 | // | ||
422 | { .mib | ||
423 | ld4 DTmp = [DPtr_], 4 | ||
424 | cmp.eq pOff, p0 = 1, InAlign | ||
425 | (pOff) br.cond.dpnt.many .md5_process1 | ||
426 | } ;; | ||
427 | { .mib | ||
428 | cmp.eq pOff, p0 = 2, InAlign | ||
429 | nop 0x0 | ||
430 | (pOff) br.cond.dpnt.many .md5_process2 | ||
431 | } ;; | ||
432 | MD5UNALIGNED(3) | ||
433 | MD5UNALIGNED(1) | ||
434 | MD5UNALIGNED(2) | ||
435 | |||
436 | .endp md5_block_asm_data_order | ||
437 | |||
438 | |||
439 | // MD5 Perform the F function and load | ||
440 | // | ||
441 | // Passed the first 4 words (M0 - M3) and initial (A, B, C, D) values, | ||
442 | // computes the FF() round of functions, then branches to the common | ||
443 | // digest code to finish up with GG(), HH, and II(). | ||
444 | // | ||
445 | // INPUT | ||
446 | // | ||
447 | // rp Return Address - | ||
448 | // | ||
449 | // CODE | ||
450 | // | ||
451 | // v0 PFS bit bucket PFS | ||
452 | // v1 Loop Trip Count LTrip | ||
453 | // pt0 Load next word pMore | ||
454 | |||
455 | /* For F round: */ | ||
456 | #define LTrip r9 | ||
457 | #define PFS r8 | ||
458 | #define pMore p6 | ||
459 | |||
460 | /* For GHI rounds: */ | ||
461 | #define T r9 | ||
462 | #define U r10 | ||
463 | #define V r11 | ||
464 | |||
465 | #define COMPUTE(a, b, s, M, R) \ | ||
466 | { \ | ||
467 | .mii ; \ | ||
468 | ld4 TRound = [TPtr], 4 ; \ | ||
469 | dep.z Y = Z, 32, 32 ;; \ | ||
470 | shrp Z = Z, Y, 64 - s ; \ | ||
471 | } ;; \ | ||
472 | { \ | ||
473 | .mmi ; \ | ||
474 | add a = Z, b ; \ | ||
475 | mov R = M ; \ | ||
476 | nop 0x0 ; \ | ||
477 | } ;; | ||
478 | |||
479 | #define LOOP(a, b, s, M, R, label) \ | ||
480 | { .mii ; \ | ||
481 | ld4 TRound = [TPtr], 4 ; \ | ||
482 | dep.z Y = Z, 32, 32 ;; \ | ||
483 | shrp Z = Z, Y, 64 - s ; \ | ||
484 | } ;; \ | ||
485 | { .mib ; \ | ||
486 | add a = Z, b ; \ | ||
487 | mov R = M ; \ | ||
488 | br.ctop.sptk.many label ; \ | ||
489 | } ;; | ||
490 | |||
491 | // G(B, C, D) = (B & D) | (C & ~D) | ||
492 | |||
493 | #define G(a, b, c, d, M) \ | ||
494 | { .mmi ; \ | ||
495 | add Z = M, TRound ; \ | ||
496 | and Y = b, d ; \ | ||
497 | andcm X = c, d ; \ | ||
498 | } ;; \ | ||
499 | { .mii ; \ | ||
500 | add Z = Z, a ; \ | ||
501 | or Y = Y, X ;; \ | ||
502 | add Z = Z, Y ; \ | ||
503 | } ;; | ||
504 | |||
505 | // H(B, C, D) = B ^ C ^ D | ||
506 | |||
507 | #define H(a, b, c, d, M) \ | ||
508 | { .mmi ; \ | ||
509 | add Z = M, TRound ; \ | ||
510 | xor Y = b, c ; \ | ||
511 | nop 0x0 ; \ | ||
512 | } ;; \ | ||
513 | { .mii ; \ | ||
514 | add Z = Z, a ; \ | ||
515 | xor Y = Y, d ;; \ | ||
516 | add Z = Z, Y ; \ | ||
517 | } ;; | ||
518 | |||
519 | // I(B, C, D) = C ^ (B | ~D) | ||
520 | // | ||
521 | // However, since we have an andcm operator, we use the fact that | ||
522 | // | ||
523 | // Y ^ Z == ~Y ^ ~Z | ||
524 | // | ||
525 | // to rewrite the expression as | ||
526 | // | ||
527 | // I(B, C, D) = ~C ^ (~B & D) | ||
528 | |||
529 | #define I(a, b, c, d, M) \ | ||
530 | { .mmi ; \ | ||
531 | add Z = M, TRound ; \ | ||
532 | andcm Y = d, b ; \ | ||
533 | andcm X = -1, c ; \ | ||
534 | } ;; \ | ||
535 | { .mii ; \ | ||
536 | add Z = Z, a ; \ | ||
537 | xor Y = Y, X ;; \ | ||
538 | add Z = Z, Y ; \ | ||
539 | } ;; | ||
540 | |||
541 | #define GG4(label) \ | ||
542 | G(A, B, C, D, M0) \ | ||
543 | COMPUTE(A, B, 5, M0, RotateM0) \ | ||
544 | G(D, A, B, C, M1) \ | ||
545 | COMPUTE(D, A, 9, M1, RotateM1) \ | ||
546 | G(C, D, A, B, M2) \ | ||
547 | COMPUTE(C, D, 14, M2, RotateM2) \ | ||
548 | G(B, C, D, A, M3) \ | ||
549 | LOOP(B, C, 20, M3, RotateM3, label) | ||
550 | |||
551 | #define HH4(label) \ | ||
552 | H(A, B, C, D, M0) \ | ||
553 | COMPUTE(A, B, 4, M0, RotateM0) \ | ||
554 | H(D, A, B, C, M1) \ | ||
555 | COMPUTE(D, A, 11, M1, RotateM1) \ | ||
556 | H(C, D, A, B, M2) \ | ||
557 | COMPUTE(C, D, 16, M2, RotateM2) \ | ||
558 | H(B, C, D, A, M3) \ | ||
559 | LOOP(B, C, 23, M3, RotateM3, label) | ||
560 | |||
561 | #define II4(label) \ | ||
562 | I(A, B, C, D, M0) \ | ||
563 | COMPUTE(A, B, 6, M0, RotateM0) \ | ||
564 | I(D, A, B, C, M1) \ | ||
565 | COMPUTE(D, A, 10, M1, RotateM1) \ | ||
566 | I(C, D, A, B, M2) \ | ||
567 | COMPUTE(C, D, 15, M2, RotateM2) \ | ||
568 | I(B, C, D, A, M3) \ | ||
569 | LOOP(B, C, 21, M3, RotateM3, label) | ||
570 | |||
571 | #define FFLOAD(a, b, c, d, M, N, s) \ | ||
572 | { .mii ; \ | ||
573 | (pMore) ld4 N = [DPtr], 4 ; \ | ||
574 | add Z = M, TRound ; \ | ||
575 | and Y = c, b ; \ | ||
576 | } \ | ||
577 | { .mmi ; \ | ||
578 | andcm X = d, b ;; \ | ||
579 | add Z = Z, a ; \ | ||
580 | or Y = Y, X ; \ | ||
581 | } ;; \ | ||
582 | { .mii ; \ | ||
583 | ld4 TRound = [TPtr], 4 ; \ | ||
584 | add Z = Z, Y ;; \ | ||
585 | dep.z Y = Z, 32, 32 ; \ | ||
586 | } ;; \ | ||
587 | { .mii ; \ | ||
588 | nop 0x0 ; \ | ||
589 | shrp Z = Z, Y, 64 - s ;; \ | ||
590 | add a = Z, b ; \ | ||
591 | } ;; | ||
592 | |||
593 | #define FFLOOP(a, b, c, d, M, N, s, dest) \ | ||
594 | { .mii ; \ | ||
595 | (pMore) ld4 N = [DPtr], 4 ; \ | ||
596 | add Z = M, TRound ; \ | ||
597 | and Y = c, b ; \ | ||
598 | } \ | ||
599 | { .mmi ; \ | ||
600 | andcm X = d, b ;; \ | ||
601 | add Z = Z, a ; \ | ||
602 | or Y = Y, X ; \ | ||
603 | } ;; \ | ||
604 | { .mii ; \ | ||
605 | ld4 TRound = [TPtr], 4 ; \ | ||
606 | add Z = Z, Y ;; \ | ||
607 | dep.z Y = Z, 32, 32 ; \ | ||
608 | } ;; \ | ||
609 | { .mii ; \ | ||
610 | nop 0x0 ; \ | ||
611 | shrp Z = Z, Y, 64 - s ;; \ | ||
612 | add a = Z, b ; \ | ||
613 | } \ | ||
614 | { .mib ; \ | ||
615 | cmp.ne pMore, p0 = 0, LTrip ; \ | ||
616 | add LTrip = -1, LTrip ; \ | ||
617 | br.ctop.dptk.many dest ; \ | ||
618 | } ;; | ||
619 | |||
620 | .type md5_digest_block0, @function | ||
621 | .align 32 | ||
622 | |||
623 | .proc md5_digest_block0 | ||
624 | .prologue | ||
625 | md5_digest_block0: | ||
626 | .altrp QUICK_RTN | ||
627 | .body | ||
628 | { .mmi | ||
629 | alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE | ||
630 | mov LTrip = 2 | ||
631 | mov ar.lc = 3 | ||
632 | } ;; | ||
633 | { .mii | ||
634 | cmp.eq pMore, p0 = r0, r0 | ||
635 | mov ar.ec = 0 | ||
636 | nop 0x0 | ||
637 | } ;; | ||
638 | |||
639 | .md5_FF_round0: | ||
640 | FFLOAD(A, B, C, D, M12, RotateM0, 7) | ||
641 | FFLOAD(D, A, B, C, M13, RotateM1, 12) | ||
642 | FFLOAD(C, D, A, B, M14, RotateM2, 17) | ||
643 | FFLOOP(B, C, D, A, M15, RotateM3, 22, .md5_FF_round0) | ||
644 | // | ||
645 | // !!! Fall through to md5_digest_GHI | ||
646 | // | ||
647 | .endp md5_digest_block0 | ||
648 | |||
649 | .type md5_digest_GHI, @function | ||
650 | .align 32 | ||
651 | |||
652 | .proc md5_digest_GHI | ||
653 | .prologue | ||
654 | .regstk _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE | ||
655 | md5_digest_GHI: | ||
656 | .altrp QUICK_RTN | ||
657 | .body | ||
658 | // | ||
659 | // The following sequence shuffles the block counstants round for the | ||
660 | // next round: | ||
661 | // | ||
662 | // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ||
663 | // 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12 | ||
664 | // | ||
665 | { .mmi | ||
666 | mov Z = M0 | ||
667 | mov Y = M15 | ||
668 | mov ar.lc = 3 | ||
669 | } | ||
670 | { .mmi | ||
671 | mov X = M2 | ||
672 | mov W = M9 | ||
673 | mov V = M4 | ||
674 | } ;; | ||
675 | |||
676 | { .mmi | ||
677 | mov M0 = M1 | ||
678 | mov M15 = M12 | ||
679 | mov ar.ec = 1 | ||
680 | } | ||
681 | { .mmi | ||
682 | mov M2 = M11 | ||
683 | mov M9 = M14 | ||
684 | mov M4 = M5 | ||
685 | } ;; | ||
686 | |||
687 | { .mmi | ||
688 | mov M1 = M6 | ||
689 | mov M12 = M13 | ||
690 | mov U = M3 | ||
691 | } | ||
692 | { .mmi | ||
693 | mov M11 = M8 | ||
694 | mov M14 = M7 | ||
695 | mov M5 = M10 | ||
696 | } ;; | ||
697 | |||
698 | { .mmi | ||
699 | mov M6 = Y | ||
700 | mov M13 = X | ||
701 | mov M3 = Z | ||
702 | } | ||
703 | { .mmi | ||
704 | mov M8 = W | ||
705 | mov M7 = V | ||
706 | mov M10 = U | ||
707 | } ;; | ||
708 | |||
709 | .md5_GG_round: | ||
710 | GG4(.md5_GG_round) | ||
711 | |||
712 | // The following sequence shuffles the block constants round for the | ||
713 | // next round: | ||
714 | // | ||
715 | // 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12 | ||
716 | // 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2 | ||
717 | |||
718 | { .mmi | ||
719 | mov Z = M0 | ||
720 | mov Y = M1 | ||
721 | mov ar.lc = 3 | ||
722 | } | ||
723 | { .mmi | ||
724 | mov X = M3 | ||
725 | mov W = M5 | ||
726 | mov V = M6 | ||
727 | } ;; | ||
728 | |||
729 | { .mmi | ||
730 | mov M0 = M4 | ||
731 | mov M1 = M11 | ||
732 | mov ar.ec = 1 | ||
733 | } | ||
734 | { .mmi | ||
735 | mov M3 = M9 | ||
736 | mov U = M8 | ||
737 | mov T = M13 | ||
738 | } ;; | ||
739 | |||
740 | { .mmi | ||
741 | mov M4 = Z | ||
742 | mov M11 = Y | ||
743 | mov M5 = M7 | ||
744 | } | ||
745 | { .mmi | ||
746 | mov M6 = M14 | ||
747 | mov M8 = M12 | ||
748 | mov M13 = M15 | ||
749 | } ;; | ||
750 | |||
751 | { .mmi | ||
752 | mov M7 = W | ||
753 | mov M14 = V | ||
754 | nop 0x0 | ||
755 | } | ||
756 | { .mmi | ||
757 | mov M9 = X | ||
758 | mov M12 = U | ||
759 | mov M15 = T | ||
760 | } ;; | ||
761 | |||
762 | .md5_HH_round: | ||
763 | HH4(.md5_HH_round) | ||
764 | |||
765 | // The following sequence shuffles the block constants round for the | ||
766 | // next round: | ||
767 | // | ||
768 | // 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2 | ||
769 | // 0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9 | ||
770 | |||
771 | { .mmi | ||
772 | mov Z = M0 | ||
773 | mov Y = M15 | ||
774 | mov ar.lc = 3 | ||
775 | } | ||
776 | { .mmi | ||
777 | mov X = M10 | ||
778 | mov W = M1 | ||
779 | mov V = M4 | ||
780 | } ;; | ||
781 | |||
782 | { .mmi | ||
783 | mov M0 = M9 | ||
784 | mov M15 = M12 | ||
785 | mov ar.ec = 1 | ||
786 | } | ||
787 | { .mmi | ||
788 | mov M10 = M11 | ||
789 | mov M1 = M6 | ||
790 | mov M4 = M13 | ||
791 | } ;; | ||
792 | |||
793 | { .mmi | ||
794 | mov M9 = M14 | ||
795 | mov M12 = M5 | ||
796 | mov U = M3 | ||
797 | } | ||
798 | { .mmi | ||
799 | mov M11 = M8 | ||
800 | mov M6 = M7 | ||
801 | mov M13 = M2 | ||
802 | } ;; | ||
803 | |||
804 | { .mmi | ||
805 | mov M14 = Y | ||
806 | mov M5 = X | ||
807 | mov M3 = Z | ||
808 | } | ||
809 | { .mmi | ||
810 | mov M8 = W | ||
811 | mov M7 = V | ||
812 | mov M2 = U | ||
813 | } ;; | ||
814 | |||
815 | .md5_II_round: | ||
816 | II4(.md5_II_round) | ||
817 | |||
818 | { .mib | ||
819 | nop 0x0 | ||
820 | nop 0x0 | ||
821 | br.ret.sptk.many QUICK_RTN | ||
822 | } ;; | ||
823 | |||
824 | .endp md5_digest_GHI | ||
825 | |||
826 | #define FFLOADU(a, b, c, d, M, P, N, s, offset) \ | ||
827 | { .mii ; \ | ||
828 | (pMore) ld4 N = [DPtr], 4 ; \ | ||
829 | add Z = M, TRound ; \ | ||
830 | and Y = c, b ; \ | ||
831 | } \ | ||
832 | { .mmi ; \ | ||
833 | andcm X = d, b ;; \ | ||
834 | add Z = Z, a ; \ | ||
835 | or Y = Y, X ; \ | ||
836 | } ;; \ | ||
837 | { .mii ; \ | ||
838 | ld4 TRound = [TPtr], 4 ; \ | ||
839 | GETLW(W, P, offset) ; \ | ||
840 | add Z = Z, Y ; \ | ||
841 | } ;; \ | ||
842 | { .mii ; \ | ||
843 | or W = W, DTmp ; \ | ||
844 | dep.z Y = Z, 32, 32 ;; \ | ||
845 | shrp Z = Z, Y, 64 - s ; \ | ||
846 | } ;; \ | ||
847 | { .mii ; \ | ||
848 | add a = Z, b ; \ | ||
849 | GETRW(DTmp, P, offset) ; \ | ||
850 | mov P = W ; \ | ||
851 | } ;; | ||
852 | |||
853 | #define FFLOOPU(a, b, c, d, M, P, N, s, offset) \ | ||
854 | { .mii ; \ | ||
855 | (pMore) ld4 N = [DPtr], 4 ; \ | ||
856 | add Z = M, TRound ; \ | ||
857 | and Y = c, b ; \ | ||
858 | } \ | ||
859 | { .mmi ; \ | ||
860 | andcm X = d, b ;; \ | ||
861 | add Z = Z, a ; \ | ||
862 | or Y = Y, X ; \ | ||
863 | } ;; \ | ||
864 | { .mii ; \ | ||
865 | ld4 TRound = [TPtr], 4 ; \ | ||
866 | (pMore) GETLW(W, P, offset) ; \ | ||
867 | add Z = Z, Y ; \ | ||
868 | } ;; \ | ||
869 | { .mii ; \ | ||
870 | (pMore) or W = W, DTmp ; \ | ||
871 | dep.z Y = Z, 32, 32 ;; \ | ||
872 | shrp Z = Z, Y, 64 - s ; \ | ||
873 | } ;; \ | ||
874 | { .mii ; \ | ||
875 | add a = Z, b ; \ | ||
876 | (pMore) GETRW(DTmp, P, offset) ; \ | ||
877 | (pMore) mov P = W ; \ | ||
878 | } \ | ||
879 | { .mib ; \ | ||
880 | cmp.ne pMore, p0 = 0, LTrip ; \ | ||
881 | add LTrip = -1, LTrip ; \ | ||
882 | br.ctop.sptk.many .md5_FF_round##offset ; \ | ||
883 | } ;; | ||
884 | |||
885 | #define MD5FBLOCK(offset) \ | ||
886 | .type md5_digest_block##offset, @function ; \ | ||
887 | \ | ||
888 | .align 32 ; \ | ||
889 | .proc md5_digest_block##offset ; \ | ||
890 | .prologue ; \ | ||
891 | .altrp QUICK_RTN ; \ | ||
892 | .body ; \ | ||
893 | md5_digest_block##offset: \ | ||
894 | { .mmi ; \ | ||
895 | alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE ; \ | ||
896 | mov LTrip = 2 ; \ | ||
897 | mov ar.lc = 3 ; \ | ||
898 | } ;; \ | ||
899 | { .mii ; \ | ||
900 | cmp.eq pMore, p0 = r0, r0 ; \ | ||
901 | mov ar.ec = 0 ; \ | ||
902 | nop 0x0 ; \ | ||
903 | } ;; \ | ||
904 | \ | ||
905 | .pred.rel "mutex", pLoad, pSkip ; \ | ||
906 | .md5_FF_round##offset: \ | ||
907 | FFLOADU(A, B, C, D, M12, M13, RotateM0, 7, offset) \ | ||
908 | FFLOADU(D, A, B, C, M13, M14, RotateM1, 12, offset) \ | ||
909 | FFLOADU(C, D, A, B, M14, M15, RotateM2, 17, offset) \ | ||
910 | FFLOOPU(B, C, D, A, M15, RotateM0, RotateM3, 22, offset) \ | ||
911 | \ | ||
912 | { .mib ; \ | ||
913 | nop 0x0 ; \ | ||
914 | nop 0x0 ; \ | ||
915 | br.cond.sptk.many md5_digest_GHI ; \ | ||
916 | } ;; \ | ||
917 | .endp md5_digest_block##offset | ||
918 | |||
919 | MD5FBLOCK(1) | ||
920 | MD5FBLOCK(2) | ||
921 | MD5FBLOCK(3) | ||
922 | |||
923 | .align 64 | ||
924 | .type md5_constants, @object | ||
925 | md5_constants: | ||
926 | .md5_tbl_data_order: // To ensure little-endian data | ||
927 | // order, code as bytes. | ||
928 | data1 0x78, 0xa4, 0x6a, 0xd7 // 0 | ||
929 | data1 0x56, 0xb7, 0xc7, 0xe8 // 1 | ||
930 | data1 0xdb, 0x70, 0x20, 0x24 // 2 | ||
931 | data1 0xee, 0xce, 0xbd, 0xc1 // 3 | ||
932 | data1 0xaf, 0x0f, 0x7c, 0xf5 // 4 | ||
933 | data1 0x2a, 0xc6, 0x87, 0x47 // 5 | ||
934 | data1 0x13, 0x46, 0x30, 0xa8 // 6 | ||
935 | data1 0x01, 0x95, 0x46, 0xfd // 7 | ||
936 | data1 0xd8, 0x98, 0x80, 0x69 // 8 | ||
937 | data1 0xaf, 0xf7, 0x44, 0x8b // 9 | ||
938 | data1 0xb1, 0x5b, 0xff, 0xff // 10 | ||
939 | data1 0xbe, 0xd7, 0x5c, 0x89 // 11 | ||
940 | data1 0x22, 0x11, 0x90, 0x6b // 12 | ||
941 | data1 0x93, 0x71, 0x98, 0xfd // 13 | ||
942 | data1 0x8e, 0x43, 0x79, 0xa6 // 14 | ||
943 | data1 0x21, 0x08, 0xb4, 0x49 // 15 | ||
944 | data1 0x62, 0x25, 0x1e, 0xf6 // 16 | ||
945 | data1 0x40, 0xb3, 0x40, 0xc0 // 17 | ||
946 | data1 0x51, 0x5a, 0x5e, 0x26 // 18 | ||
947 | data1 0xaa, 0xc7, 0xb6, 0xe9 // 19 | ||
948 | data1 0x5d, 0x10, 0x2f, 0xd6 // 20 | ||
949 | data1 0x53, 0x14, 0x44, 0x02 // 21 | ||
950 | data1 0x81, 0xe6, 0xa1, 0xd8 // 22 | ||
951 | data1 0xc8, 0xfb, 0xd3, 0xe7 // 23 | ||
952 | data1 0xe6, 0xcd, 0xe1, 0x21 // 24 | ||
953 | data1 0xd6, 0x07, 0x37, 0xc3 // 25 | ||
954 | data1 0x87, 0x0d, 0xd5, 0xf4 // 26 | ||
955 | data1 0xed, 0x14, 0x5a, 0x45 // 27 | ||
956 | data1 0x05, 0xe9, 0xe3, 0xa9 // 28 | ||
957 | data1 0xf8, 0xa3, 0xef, 0xfc // 29 | ||
958 | data1 0xd9, 0x02, 0x6f, 0x67 // 30 | ||
959 | data1 0x8a, 0x4c, 0x2a, 0x8d // 31 | ||
960 | data1 0x42, 0x39, 0xfa, 0xff // 32 | ||
961 | data1 0x81, 0xf6, 0x71, 0x87 // 33 | ||
962 | data1 0x22, 0x61, 0x9d, 0x6d // 34 | ||
963 | data1 0x0c, 0x38, 0xe5, 0xfd // 35 | ||
964 | data1 0x44, 0xea, 0xbe, 0xa4 // 36 | ||
965 | data1 0xa9, 0xcf, 0xde, 0x4b // 37 | ||
966 | data1 0x60, 0x4b, 0xbb, 0xf6 // 38 | ||
967 | data1 0x70, 0xbc, 0xbf, 0xbe // 39 | ||
968 | data1 0xc6, 0x7e, 0x9b, 0x28 // 40 | ||
969 | data1 0xfa, 0x27, 0xa1, 0xea // 41 | ||
970 | data1 0x85, 0x30, 0xef, 0xd4 // 42 | ||
971 | data1 0x05, 0x1d, 0x88, 0x04 // 43 | ||
972 | data1 0x39, 0xd0, 0xd4, 0xd9 // 44 | ||
973 | data1 0xe5, 0x99, 0xdb, 0xe6 // 45 | ||
974 | data1 0xf8, 0x7c, 0xa2, 0x1f // 46 | ||
975 | data1 0x65, 0x56, 0xac, 0xc4 // 47 | ||
976 | data1 0x44, 0x22, 0x29, 0xf4 // 48 | ||
977 | data1 0x97, 0xff, 0x2a, 0x43 // 49 | ||
978 | data1 0xa7, 0x23, 0x94, 0xab // 50 | ||
979 | data1 0x39, 0xa0, 0x93, 0xfc // 51 | ||
980 | data1 0xc3, 0x59, 0x5b, 0x65 // 52 | ||
981 | data1 0x92, 0xcc, 0x0c, 0x8f // 53 | ||
982 | data1 0x7d, 0xf4, 0xef, 0xff // 54 | ||
983 | data1 0xd1, 0x5d, 0x84, 0x85 // 55 | ||
984 | data1 0x4f, 0x7e, 0xa8, 0x6f // 56 | ||
985 | data1 0xe0, 0xe6, 0x2c, 0xfe // 57 | ||
986 | data1 0x14, 0x43, 0x01, 0xa3 // 58 | ||
987 | data1 0xa1, 0x11, 0x08, 0x4e // 59 | ||
988 | data1 0x82, 0x7e, 0x53, 0xf7 // 60 | ||
989 | data1 0x35, 0xf2, 0x3a, 0xbd // 61 | ||
990 | data1 0xbb, 0xd2, 0xd7, 0x2a // 62 | ||
991 | data1 0x91, 0xd3, 0x86, 0xeb // 63 | ||
992 | .size md5_constants#,64*4 | ||
diff --git a/src/lib/libcrypto/md5/asm/md5-x86_64.pl b/src/lib/libcrypto/md5/asm/md5-x86_64.pl index 9a6fa67224..867885435e 100755 --- a/src/lib/libcrypto/md5/asm/md5-x86_64.pl +++ b/src/lib/libcrypto/md5/asm/md5-x86_64.pl | |||
@@ -15,7 +15,7 @@ my $code; | |||
15 | # dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s) | 15 | # dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s) |
16 | # %r10d = X[k_next] | 16 | # %r10d = X[k_next] |
17 | # %r11d = z' (copy of z for the next step) | 17 | # %r11d = z' (copy of z for the next step) |
18 | # Each round1_step() takes about 5.71 clocks (9 instructions, 1.58 IPC) | 18 | # Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC) |
19 | sub round1_step | 19 | sub round1_step |
20 | { | 20 | { |
21 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; | 21 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; |
@@ -37,22 +37,26 @@ EOF | |||
37 | # round2_step() does: | 37 | # round2_step() does: |
38 | # dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s) | 38 | # dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s) |
39 | # %r10d = X[k_next] | 39 | # %r10d = X[k_next] |
40 | # %r11d = y' (copy of y for the next step) | 40 | # %r11d = z' (copy of z for the next step) |
41 | # Each round2_step() takes about 6.22 clocks (9 instructions, 1.45 IPC) | 41 | # %r12d = z' (copy of z for the next step) |
42 | # Each round2_step() takes about 5.4 clocks (11 instructions, 2.0 IPC) | ||
42 | sub round2_step | 43 | sub round2_step |
43 | { | 44 | { |
44 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; | 45 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; |
45 | $code .= " mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */\n" if ($pos == -1); | 46 | $code .= " mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */\n" if ($pos == -1); |
46 | $code .= " mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */\n" if ($pos == -1); | 47 | $code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1); |
48 | $code .= " mov %edx, %r12d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1); | ||
47 | $code .= <<EOF; | 49 | $code .= <<EOF; |
48 | xor $x, %r11d /* x ^ ... */ | 50 | not %r11d /* not z */ |
49 | lea $T_i($dst,%r10d),$dst /* Const + dst + ... */ | 51 | lea $T_i($dst,%r10d),$dst /* Const + dst + ... */ |
50 | and $z, %r11d /* z & ... */ | 52 | and $x, %r12d /* x & z */ |
51 | xor $y, %r11d /* y ^ ... */ | 53 | and $y, %r11d /* y & (not z) */ |
52 | mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ | 54 | mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ |
53 | add %r11d, $dst /* dst += ... */ | 55 | or %r11d, %r12d /* (y & (not z)) | (x & z) */ |
56 | mov $y, %r11d /* (NEXT STEP) z' = $y */ | ||
57 | add %r12d, $dst /* dst += ... */ | ||
58 | mov $y, %r12d /* (NEXT STEP) z' = $y */ | ||
54 | rol \$$s, $dst /* dst <<< s */ | 59 | rol \$$s, $dst /* dst <<< s */ |
55 | mov $x, %r11d /* (NEXT STEP) y' = $x */ | ||
56 | add $x, $dst /* dst += x */ | 60 | add $x, $dst /* dst += x */ |
57 | EOF | 61 | EOF |
58 | } | 62 | } |
@@ -61,7 +65,7 @@ EOF | |||
61 | # dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s) | 65 | # dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s) |
62 | # %r10d = X[k_next] | 66 | # %r10d = X[k_next] |
63 | # %r11d = y' (copy of y for the next step) | 67 | # %r11d = y' (copy of y for the next step) |
64 | # Each round3_step() takes about 4.26 clocks (8 instructions, 1.88 IPC) | 68 | # Each round3_step() takes about 4.2 clocks (8 instructions, 1.9 IPC) |
65 | sub round3_step | 69 | sub round3_step |
66 | { | 70 | { |
67 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; | 71 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; |
@@ -83,7 +87,7 @@ EOF | |||
83 | # dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s) | 87 | # dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s) |
84 | # %r10d = X[k_next] | 88 | # %r10d = X[k_next] |
85 | # %r11d = not z' (copy of not z for the next step) | 89 | # %r11d = not z' (copy of not z for the next step) |
86 | # Each round4_step() takes about 5.27 clocks (9 instructions, 1.71 IPC) | 90 | # Each round4_step() takes about 5.2 clocks (9 instructions, 1.7 IPC) |
87 | sub round4_step | 91 | sub round4_step |
88 | { | 92 | { |
89 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; | 93 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; |
@@ -104,8 +108,19 @@ sub round4_step | |||
104 | EOF | 108 | EOF |
105 | } | 109 | } |
106 | 110 | ||
107 | my $output = shift; | 111 | my $flavour = shift; |
108 | open STDOUT,"| $^X ../perlasm/x86_64-xlate.pl $output"; | 112 | my $output = shift; |
113 | if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } | ||
114 | |||
115 | my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); | ||
116 | |||
117 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; | ||
118 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | ||
119 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | ||
120 | die "can't locate x86_64-xlate.pl"; | ||
121 | |||
122 | no warnings qw(uninitialized); | ||
123 | open STDOUT,"| $^X $xlate $flavour $output"; | ||
109 | 124 | ||
110 | $code .= <<EOF; | 125 | $code .= <<EOF; |
111 | .text | 126 | .text |
@@ -116,8 +131,10 @@ $code .= <<EOF; | |||
116 | md5_block_asm_data_order: | 131 | md5_block_asm_data_order: |
117 | push %rbp | 132 | push %rbp |
118 | push %rbx | 133 | push %rbx |
134 | push %r12 | ||
119 | push %r14 | 135 | push %r14 |
120 | push %r15 | 136 | push %r15 |
137 | .Lprologue: | ||
121 | 138 | ||
122 | # rdi = arg #1 (ctx, MD5_CTX pointer) | 139 | # rdi = arg #1 (ctx, MD5_CTX pointer) |
123 | # rsi = arg #2 (ptr, data pointer) | 140 | # rsi = arg #2 (ptr, data pointer) |
@@ -232,13 +249,120 @@ $code .= <<EOF; | |||
232 | mov %ecx, 2*4(%rbp) # ctx->C = C | 249 | mov %ecx, 2*4(%rbp) # ctx->C = C |
233 | mov %edx, 3*4(%rbp) # ctx->D = D | 250 | mov %edx, 3*4(%rbp) # ctx->D = D |
234 | 251 | ||
252 | mov (%rsp),%r15 | ||
253 | mov 8(%rsp),%r14 | ||
254 | mov 16(%rsp),%r12 | ||
255 | mov 24(%rsp),%rbx | ||
256 | mov 32(%rsp),%rbp | ||
257 | add \$40,%rsp | ||
258 | .Lepilogue: | ||
259 | ret | ||
260 | .size md5_block_asm_data_order,.-md5_block_asm_data_order | ||
261 | EOF | ||
262 | |||
263 | # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, | ||
264 | # CONTEXT *context,DISPATCHER_CONTEXT *disp) | ||
265 | if ($win64) { | ||
266 | my $rec="%rcx"; | ||
267 | my $frame="%rdx"; | ||
268 | my $context="%r8"; | ||
269 | my $disp="%r9"; | ||
270 | |||
271 | $code.=<<___; | ||
272 | .extern __imp_RtlVirtualUnwind | ||
273 | .type se_handler,\@abi-omnipotent | ||
274 | .align 16 | ||
275 | se_handler: | ||
276 | push %rsi | ||
277 | push %rdi | ||
278 | push %rbx | ||
279 | push %rbp | ||
280 | push %r12 | ||
281 | push %r13 | ||
282 | push %r14 | ||
283 | push %r15 | ||
284 | pushfq | ||
285 | sub \$64,%rsp | ||
286 | |||
287 | mov 120($context),%rax # pull context->Rax | ||
288 | mov 248($context),%rbx # pull context->Rip | ||
289 | |||
290 | lea .Lprologue(%rip),%r10 | ||
291 | cmp %r10,%rbx # context->Rip<.Lprologue | ||
292 | jb .Lin_prologue | ||
293 | |||
294 | mov 152($context),%rax # pull context->Rsp | ||
295 | |||
296 | lea .Lepilogue(%rip),%r10 | ||
297 | cmp %r10,%rbx # context->Rip>=.Lepilogue | ||
298 | jae .Lin_prologue | ||
299 | |||
300 | lea 40(%rax),%rax | ||
301 | |||
302 | mov -8(%rax),%rbp | ||
303 | mov -16(%rax),%rbx | ||
304 | mov -24(%rax),%r12 | ||
305 | mov -32(%rax),%r14 | ||
306 | mov -40(%rax),%r15 | ||
307 | mov %rbx,144($context) # restore context->Rbx | ||
308 | mov %rbp,160($context) # restore context->Rbp | ||
309 | mov %r12,216($context) # restore context->R12 | ||
310 | mov %r14,232($context) # restore context->R14 | ||
311 | mov %r15,240($context) # restore context->R15 | ||
312 | |||
313 | .Lin_prologue: | ||
314 | mov 8(%rax),%rdi | ||
315 | mov 16(%rax),%rsi | ||
316 | mov %rax,152($context) # restore context->Rsp | ||
317 | mov %rsi,168($context) # restore context->Rsi | ||
318 | mov %rdi,176($context) # restore context->Rdi | ||
319 | |||
320 | mov 40($disp),%rdi # disp->ContextRecord | ||
321 | mov $context,%rsi # context | ||
322 | mov \$154,%ecx # sizeof(CONTEXT) | ||
323 | .long 0xa548f3fc # cld; rep movsq | ||
324 | |||
325 | mov $disp,%rsi | ||
326 | xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER | ||
327 | mov 8(%rsi),%rdx # arg2, disp->ImageBase | ||
328 | mov 0(%rsi),%r8 # arg3, disp->ControlPc | ||
329 | mov 16(%rsi),%r9 # arg4, disp->FunctionEntry | ||
330 | mov 40(%rsi),%r10 # disp->ContextRecord | ||
331 | lea 56(%rsi),%r11 # &disp->HandlerData | ||
332 | lea 24(%rsi),%r12 # &disp->EstablisherFrame | ||
333 | mov %r10,32(%rsp) # arg5 | ||
334 | mov %r11,40(%rsp) # arg6 | ||
335 | mov %r12,48(%rsp) # arg7 | ||
336 | mov %rcx,56(%rsp) # arg8, (NULL) | ||
337 | call *__imp_RtlVirtualUnwind(%rip) | ||
338 | |||
339 | mov \$1,%eax # ExceptionContinueSearch | ||
340 | add \$64,%rsp | ||
341 | popfq | ||
235 | pop %r15 | 342 | pop %r15 |
236 | pop %r14 | 343 | pop %r14 |
237 | pop %rbx | 344 | pop %r13 |
345 | pop %r12 | ||
238 | pop %rbp | 346 | pop %rbp |
347 | pop %rbx | ||
348 | pop %rdi | ||
349 | pop %rsi | ||
239 | ret | 350 | ret |
240 | .size md5_block_asm_data_order,.-md5_block_asm_data_order | 351 | .size se_handler,.-se_handler |
241 | EOF | 352 | |
353 | .section .pdata | ||
354 | .align 4 | ||
355 | .rva .LSEH_begin_md5_block_asm_data_order | ||
356 | .rva .LSEH_end_md5_block_asm_data_order | ||
357 | .rva .LSEH_info_md5_block_asm_data_order | ||
358 | |||
359 | .section .xdata | ||
360 | .align 8 | ||
361 | .LSEH_info_md5_block_asm_data_order: | ||
362 | .byte 9,0,0,0 | ||
363 | .rva se_handler | ||
364 | ___ | ||
365 | } | ||
242 | 366 | ||
243 | print $code; | 367 | print $code; |
244 | 368 | ||
diff --git a/src/lib/libcrypto/modes/cbc128.c b/src/lib/libcrypto/modes/cbc128.c new file mode 100644 index 0000000000..8f8bd563b9 --- /dev/null +++ b/src/lib/libcrypto/modes/cbc128.c | |||
@@ -0,0 +1,206 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in | ||
13 | * the documentation and/or other materials provided with the | ||
14 | * distribution. | ||
15 | * | ||
16 | * 3. All advertising materials mentioning features or use of this | ||
17 | * software must display the following acknowledgment: | ||
18 | * "This product includes software developed by the OpenSSL Project | ||
19 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
20 | * | ||
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
22 | * endorse or promote products derived from this software without | ||
23 | * prior written permission. For written permission, please contact | ||
24 | * openssl-core@openssl.org. | ||
25 | * | ||
26 | * 5. Products derived from this software may not be called "OpenSSL" | ||
27 | * nor may "OpenSSL" appear in their names without prior written | ||
28 | * permission of the OpenSSL Project. | ||
29 | * | ||
30 | * 6. Redistributions of any form whatsoever must retain the following | ||
31 | * acknowledgment: | ||
32 | * "This product includes software developed by the OpenSSL Project | ||
33 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
34 | * | ||
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
47 | * ==================================================================== | ||
48 | * | ||
49 | */ | ||
50 | |||
51 | #include "modes.h" | ||
52 | #include <string.h> | ||
53 | |||
54 | #ifndef MODES_DEBUG | ||
55 | # ifndef NDEBUG | ||
56 | # define NDEBUG | ||
57 | # endif | ||
58 | #endif | ||
59 | #include <assert.h> | ||
60 | |||
61 | #define STRICT_ALIGNMENT 1 | ||
62 | #if defined(__i386) || defined(__i386__) || \ | ||
63 | defined(__x86_64) || defined(__x86_64__) || \ | ||
64 | defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ | ||
65 | defined(__s390__) || defined(__s390x__) | ||
66 | # undef STRICT_ALIGNMENT | ||
67 | # define STRICT_ALIGNMENT 0 | ||
68 | #endif | ||
69 | |||
70 | void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, | ||
71 | size_t len, const void *key, | ||
72 | unsigned char ivec[16], block128_f block) | ||
73 | { | ||
74 | size_t n; | ||
75 | const unsigned char *iv = ivec; | ||
76 | |||
77 | assert(in && out && key && ivec); | ||
78 | |||
79 | #if !defined(OPENSSL_SMALL_FOOTPRINT) | ||
80 | if (STRICT_ALIGNMENT && | ||
81 | ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) { | ||
82 | while (len>=16) { | ||
83 | for(n=0; n<16; ++n) | ||
84 | out[n] = in[n] ^ iv[n]; | ||
85 | (*block)(out, out, key); | ||
86 | iv = out; | ||
87 | len -= 16; | ||
88 | in += 16; | ||
89 | out += 16; | ||
90 | } | ||
91 | } else { | ||
92 | while (len>=16) { | ||
93 | for(n=0; n<16; n+=sizeof(size_t)) | ||
94 | *(size_t*)(out+n) = | ||
95 | *(size_t*)(in+n) ^ *(size_t*)(iv+n); | ||
96 | (*block)(out, out, key); | ||
97 | iv = out; | ||
98 | len -= 16; | ||
99 | in += 16; | ||
100 | out += 16; | ||
101 | } | ||
102 | } | ||
103 | #endif | ||
104 | while (len) { | ||
105 | for(n=0; n<16 && n<len; ++n) | ||
106 | out[n] = in[n] ^ iv[n]; | ||
107 | for(; n<16; ++n) | ||
108 | out[n] = iv[n]; | ||
109 | (*block)(out, out, key); | ||
110 | iv = out; | ||
111 | if (len<=16) break; | ||
112 | len -= 16; | ||
113 | in += 16; | ||
114 | out += 16; | ||
115 | } | ||
116 | memcpy(ivec,iv,16); | ||
117 | } | ||
118 | |||
119 | void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, | ||
120 | size_t len, const void *key, | ||
121 | unsigned char ivec[16], block128_f block) | ||
122 | { | ||
123 | size_t n; | ||
124 | union { size_t align; unsigned char c[16]; } tmp; | ||
125 | |||
126 | assert(in && out && key && ivec); | ||
127 | |||
128 | #if !defined(OPENSSL_SMALL_FOOTPRINT) | ||
129 | if (in != out) { | ||
130 | const unsigned char *iv = ivec; | ||
131 | |||
132 | if (STRICT_ALIGNMENT && | ||
133 | ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) { | ||
134 | while (len>=16) { | ||
135 | (*block)(in, out, key); | ||
136 | for(n=0; n<16; ++n) | ||
137 | out[n] ^= iv[n]; | ||
138 | iv = in; | ||
139 | len -= 16; | ||
140 | in += 16; | ||
141 | out += 16; | ||
142 | } | ||
143 | } | ||
144 | else { | ||
145 | while (len>=16) { | ||
146 | (*block)(in, out, key); | ||
147 | for(n=0; n<16; n+=sizeof(size_t)) | ||
148 | *(size_t *)(out+n) ^= *(size_t *)(iv+n); | ||
149 | iv = in; | ||
150 | len -= 16; | ||
151 | in += 16; | ||
152 | out += 16; | ||
153 | } | ||
154 | } | ||
155 | memcpy(ivec,iv,16); | ||
156 | } else { | ||
157 | if (STRICT_ALIGNMENT && | ||
158 | ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) { | ||
159 | unsigned char c; | ||
160 | while (len>=16) { | ||
161 | (*block)(in, tmp.c, key); | ||
162 | for(n=0; n<16; ++n) { | ||
163 | c = in[n]; | ||
164 | out[n] = tmp.c[n] ^ ivec[n]; | ||
165 | ivec[n] = c; | ||
166 | } | ||
167 | len -= 16; | ||
168 | in += 16; | ||
169 | out += 16; | ||
170 | } | ||
171 | } | ||
172 | else { | ||
173 | size_t c; | ||
174 | while (len>=16) { | ||
175 | (*block)(in, tmp.c, key); | ||
176 | for(n=0; n<16; n+=sizeof(size_t)) { | ||
177 | c = *(size_t *)(in+n); | ||
178 | *(size_t *)(out+n) = | ||
179 | *(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n); | ||
180 | *(size_t *)(ivec+n) = c; | ||
181 | } | ||
182 | len -= 16; | ||
183 | in += 16; | ||
184 | out += 16; | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | #endif | ||
189 | while (len) { | ||
190 | unsigned char c; | ||
191 | (*block)(in, tmp.c, key); | ||
192 | for(n=0; n<16 && n<len; ++n) { | ||
193 | c = in[n]; | ||
194 | out[n] = tmp.c[n] ^ ivec[n]; | ||
195 | ivec[n] = c; | ||
196 | } | ||
197 | if (len<=16) { | ||
198 | for (; n<16; ++n) | ||
199 | ivec[n] = in[n]; | ||
200 | break; | ||
201 | } | ||
202 | len -= 16; | ||
203 | in += 16; | ||
204 | out += 16; | ||
205 | } | ||
206 | } | ||
diff --git a/src/lib/libcrypto/modes/cfb128.c b/src/lib/libcrypto/modes/cfb128.c new file mode 100644 index 0000000000..e5938c6137 --- /dev/null +++ b/src/lib/libcrypto/modes/cfb128.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in | ||
13 | * the documentation and/or other materials provided with the | ||
14 | * distribution. | ||
15 | * | ||
16 | * 3. All advertising materials mentioning features or use of this | ||
17 | * software must display the following acknowledgment: | ||
18 | * "This product includes software developed by the OpenSSL Project | ||
19 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
20 | * | ||
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
22 | * endorse or promote products derived from this software without | ||
23 | * prior written permission. For written permission, please contact | ||
24 | * openssl-core@openssl.org. | ||
25 | * | ||
26 | * 5. Products derived from this software may not be called "OpenSSL" | ||
27 | * nor may "OpenSSL" appear in their names without prior written | ||
28 | * permission of the OpenSSL Project. | ||
29 | * | ||
30 | * 6. Redistributions of any form whatsoever must retain the following | ||
31 | * acknowledgment: | ||
32 | * "This product includes software developed by the OpenSSL Project | ||
33 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
34 | * | ||
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
47 | * ==================================================================== | ||
48 | * | ||
49 | */ | ||
50 | |||
51 | #include "modes.h" | ||
52 | #include <string.h> | ||
53 | |||
54 | #ifndef MODES_DEBUG | ||
55 | # ifndef NDEBUG | ||
56 | # define NDEBUG | ||
57 | # endif | ||
58 | #endif | ||
59 | #include <assert.h> | ||
60 | |||
61 | #define STRICT_ALIGNMENT | ||
62 | #if defined(__i386) || defined(__i386__) || \ | ||
63 | defined(__x86_64) || defined(__x86_64__) || \ | ||
64 | defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ | ||
65 | defined(__s390__) || defined(__s390x__) | ||
66 | # undef STRICT_ALIGNMENT | ||
67 | #endif | ||
68 | |||
69 | /* The input and output encrypted as though 128bit cfb mode is being | ||
70 | * used. The extra state information to record how much of the | ||
71 | * 128bit block we have used is contained in *num; | ||
72 | */ | ||
73 | void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, | ||
74 | size_t len, const void *key, | ||
75 | unsigned char ivec[16], int *num, | ||
76 | int enc, block128_f block) | ||
77 | { | ||
78 | unsigned int n; | ||
79 | size_t l = 0; | ||
80 | |||
81 | assert(in && out && key && ivec && num); | ||
82 | |||
83 | n = *num; | ||
84 | |||
85 | if (enc) { | ||
86 | #if !defined(OPENSSL_SMALL_FOOTPRINT) | ||
87 | if (16%sizeof(size_t) == 0) do { /* always true actually */ | ||
88 | while (n && len) { | ||
89 | *(out++) = ivec[n] ^= *(in++); | ||
90 | --len; | ||
91 | n = (n+1) % 16; | ||
92 | } | ||
93 | #if defined(STRICT_ALIGNMENT) | ||
94 | if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) | ||
95 | break; | ||
96 | #endif | ||
97 | while (len>=16) { | ||
98 | (*block)(ivec, ivec, key); | ||
99 | for (; n<16; n+=sizeof(size_t)) { | ||
100 | *(size_t*)(out+n) = | ||
101 | *(size_t*)(ivec+n) ^= *(size_t*)(in+n); | ||
102 | } | ||
103 | len -= 16; | ||
104 | out += 16; | ||
105 | in += 16; | ||
106 | n = 0; | ||
107 | } | ||
108 | if (len) { | ||
109 | (*block)(ivec, ivec, key); | ||
110 | while (len--) { | ||
111 | out[n] = ivec[n] ^= in[n]; | ||
112 | ++n; | ||
113 | } | ||
114 | } | ||
115 | *num = n; | ||
116 | return; | ||
117 | } while (0); | ||
118 | /* the rest would be commonly eliminated by x86* compiler */ | ||
119 | #endif | ||
120 | while (l<len) { | ||
121 | if (n == 0) { | ||
122 | (*block)(ivec, ivec, key); | ||
123 | } | ||
124 | out[l] = ivec[n] ^= in[l]; | ||
125 | ++l; | ||
126 | n = (n+1) % 16; | ||
127 | } | ||
128 | *num = n; | ||
129 | } else { | ||
130 | #if !defined(OPENSSL_SMALL_FOOTPRINT) | ||
131 | if (16%sizeof(size_t) == 0) do { /* always true actually */ | ||
132 | while (n && len) { | ||
133 | unsigned char c; | ||
134 | *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c; | ||
135 | --len; | ||
136 | n = (n+1) % 16; | ||
137 | } | ||
138 | #if defined(STRICT_ALIGNMENT) | ||
139 | if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) | ||
140 | break; | ||
141 | #endif | ||
142 | while (len>=16) { | ||
143 | (*block)(ivec, ivec, key); | ||
144 | for (; n<16; n+=sizeof(size_t)) { | ||
145 | size_t t = *(size_t*)(in+n); | ||
146 | *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t; | ||
147 | *(size_t*)(ivec+n) = t; | ||
148 | } | ||
149 | len -= 16; | ||
150 | out += 16; | ||
151 | in += 16; | ||
152 | n = 0; | ||
153 | } | ||
154 | if (len) { | ||
155 | (*block)(ivec, ivec, key); | ||
156 | while (len--) { | ||
157 | unsigned char c; | ||
158 | out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c; | ||
159 | ++n; | ||
160 | } | ||
161 | } | ||
162 | *num = n; | ||
163 | return; | ||
164 | } while (0); | ||
165 | /* the rest would be commonly eliminated by x86* compiler */ | ||
166 | #endif | ||
167 | while (l<len) { | ||
168 | unsigned char c; | ||
169 | if (n == 0) { | ||
170 | (*block)(ivec, ivec, key); | ||
171 | } | ||
172 | out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c; | ||
173 | ++l; | ||
174 | n = (n+1) % 16; | ||
175 | } | ||
176 | *num=n; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | /* This expects a single block of size nbits for both in and out. Note that | ||
181 | it corrupts any extra bits in the last byte of out */ | ||
182 | static void cfbr_encrypt_block(const unsigned char *in,unsigned char *out, | ||
183 | int nbits,const void *key, | ||
184 | unsigned char ivec[16],int enc, | ||
185 | block128_f block) | ||
186 | { | ||
187 | int n,rem,num; | ||
188 | unsigned char ovec[16*2 + 1]; /* +1 because we dererefence (but don't use) one byte off the end */ | ||
189 | |||
190 | if (nbits<=0 || nbits>128) return; | ||
191 | |||
192 | /* fill in the first half of the new IV with the current IV */ | ||
193 | memcpy(ovec,ivec,16); | ||
194 | /* construct the new IV */ | ||
195 | (*block)(ivec,ivec,key); | ||
196 | num = (nbits+7)/8; | ||
197 | if (enc) /* encrypt the input */ | ||
198 | for(n=0 ; n < num ; ++n) | ||
199 | out[n] = (ovec[16+n] = in[n] ^ ivec[n]); | ||
200 | else /* decrypt the input */ | ||
201 | for(n=0 ; n < num ; ++n) | ||
202 | out[n] = (ovec[16+n] = in[n]) ^ ivec[n]; | ||
203 | /* shift ovec left... */ | ||
204 | rem = nbits%8; | ||
205 | num = nbits/8; | ||
206 | if(rem==0) | ||
207 | memcpy(ivec,ovec+num,16); | ||
208 | else | ||
209 | for(n=0 ; n < 16 ; ++n) | ||
210 | ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem); | ||
211 | |||
212 | /* it is not necessary to cleanse ovec, since the IV is not secret */ | ||
213 | } | ||
214 | |||
215 | /* N.B. This expects the input to be packed, MS bit first */ | ||
216 | void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, | ||
217 | size_t bits, const void *key, | ||
218 | unsigned char ivec[16], int *num, | ||
219 | int enc, block128_f block) | ||
220 | { | ||
221 | size_t n; | ||
222 | unsigned char c[1],d[1]; | ||
223 | |||
224 | assert(in && out && key && ivec && num); | ||
225 | assert(*num == 0); | ||
226 | |||
227 | for(n=0 ; n<bits ; ++n) | ||
228 | { | ||
229 | c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; | ||
230 | cfbr_encrypt_block(c,d,1,key,ivec,enc,block); | ||
231 | out[n/8]=(out[n/8]&~(1 << (unsigned int)(7-n%8))) | | ||
232 | ((d[0]&0x80) >> (unsigned int)(n%8)); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, | ||
237 | size_t length, const void *key, | ||
238 | unsigned char ivec[16], int *num, | ||
239 | int enc, block128_f block) | ||
240 | { | ||
241 | size_t n; | ||
242 | |||
243 | assert(in && out && key && ivec && num); | ||
244 | assert(*num == 0); | ||
245 | |||
246 | for(n=0 ; n<length ; ++n) | ||
247 | cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc,block); | ||
248 | } | ||
249 | |||
diff --git a/src/lib/libcrypto/modes/ctr128.c b/src/lib/libcrypto/modes/ctr128.c new file mode 100644 index 0000000000..932037f551 --- /dev/null +++ b/src/lib/libcrypto/modes/ctr128.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in | ||
13 | * the documentation and/or other materials provided with the | ||
14 | * distribution. | ||
15 | * | ||
16 | * 3. All advertising materials mentioning features or use of this | ||
17 | * software must display the following acknowledgment: | ||
18 | * "This product includes software developed by the OpenSSL Project | ||
19 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
20 | * | ||
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
22 | * endorse or promote products derived from this software without | ||
23 | * prior written permission. For written permission, please contact | ||
24 | * openssl-core@openssl.org. | ||
25 | * | ||
26 | * 5. Products derived from this software may not be called "OpenSSL" | ||
27 | * nor may "OpenSSL" appear in their names without prior written | ||
28 | * permission of the OpenSSL Project. | ||
29 | * | ||
30 | * 6. Redistributions of any form whatsoever must retain the following | ||
31 | * acknowledgment: | ||
32 | * "This product includes software developed by the OpenSSL Project | ||
33 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
34 | * | ||
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
47 | * ==================================================================== | ||
48 | * | ||
49 | */ | ||
50 | |||
51 | #include "modes.h" | ||
52 | #include <string.h> | ||
53 | |||
54 | #ifndef MODES_DEBUG | ||
55 | # ifndef NDEBUG | ||
56 | # define NDEBUG | ||
57 | # endif | ||
58 | #endif | ||
59 | #include <assert.h> | ||
60 | |||
61 | typedef unsigned int u32; | ||
62 | typedef unsigned char u8; | ||
63 | |||
64 | #define STRICT_ALIGNMENT | ||
65 | #if defined(__i386) || defined(__i386__) || \ | ||
66 | defined(__x86_64) || defined(__x86_64__) || \ | ||
67 | defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ | ||
68 | defined(__s390__) || defined(__s390x__) | ||
69 | # undef STRICT_ALIGNMENT | ||
70 | #endif | ||
71 | |||
72 | /* NOTE: the IV/counter CTR mode is big-endian. The code itself | ||
73 | * is endian-neutral. */ | ||
74 | |||
75 | /* increment counter (128-bit int) by 1 */ | ||
76 | static void ctr128_inc(unsigned char *counter) { | ||
77 | u32 n=16; | ||
78 | u8 c; | ||
79 | |||
80 | do { | ||
81 | --n; | ||
82 | c = counter[n]; | ||
83 | ++c; | ||
84 | counter[n] = c; | ||
85 | if (c) return; | ||
86 | } while (n); | ||
87 | } | ||
88 | |||
89 | #if !defined(OPENSSL_SMALL_FOOTPRINT) | ||
90 | static void ctr128_inc_aligned(unsigned char *counter) { | ||
91 | size_t *data,c,n; | ||
92 | const union { long one; char little; } is_endian = {1}; | ||
93 | |||
94 | if (is_endian.little) { | ||
95 | ctr128_inc(counter); | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | data = (size_t *)counter; | ||
100 | n = 16/sizeof(size_t); | ||
101 | do { | ||
102 | --n; | ||
103 | c = data[n]; | ||
104 | ++c; | ||
105 | data[n] = c; | ||
106 | if (c) return; | ||
107 | } while (n); | ||
108 | } | ||
109 | #endif | ||
110 | |||
111 | /* The input encrypted as though 128bit counter mode is being | ||
112 | * used. The extra state information to record how much of the | ||
113 | * 128bit block we have used is contained in *num, and the | ||
114 | * encrypted counter is kept in ecount_buf. Both *num and | ||
115 | * ecount_buf must be initialised with zeros before the first | ||
116 | * call to CRYPTO_ctr128_encrypt(). | ||
117 | * | ||
118 | * This algorithm assumes that the counter is in the x lower bits | ||
119 | * of the IV (ivec), and that the application has full control over | ||
120 | * overflow and the rest of the IV. This implementation takes NO | ||
121 | * responsability for checking that the counter doesn't overflow | ||
122 | * into the rest of the IV when incremented. | ||
123 | */ | ||
124 | void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, | ||
125 | size_t len, const void *key, | ||
126 | unsigned char ivec[16], unsigned char ecount_buf[16], | ||
127 | unsigned int *num, block128_f block) | ||
128 | { | ||
129 | unsigned int n; | ||
130 | size_t l=0; | ||
131 | |||
132 | assert(in && out && key && ecount_buf && num); | ||
133 | assert(*num < 16); | ||
134 | |||
135 | n = *num; | ||
136 | |||
137 | #if !defined(OPENSSL_SMALL_FOOTPRINT) | ||
138 | if (16%sizeof(size_t) == 0) do { /* always true actually */ | ||
139 | while (n && len) { | ||
140 | *(out++) = *(in++) ^ ecount_buf[n]; | ||
141 | --len; | ||
142 | n = (n+1) % 16; | ||
143 | } | ||
144 | |||
145 | #if defined(STRICT_ALIGNMENT) | ||
146 | if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) | ||
147 | break; | ||
148 | #endif | ||
149 | while (len>=16) { | ||
150 | (*block)(ivec, ecount_buf, key); | ||
151 | ctr128_inc_aligned(ivec); | ||
152 | for (; n<16; n+=sizeof(size_t)) | ||
153 | *(size_t *)(out+n) = | ||
154 | *(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n); | ||
155 | len -= 16; | ||
156 | out += 16; | ||
157 | in += 16; | ||
158 | n = 0; | ||
159 | } | ||
160 | if (len) { | ||
161 | (*block)(ivec, ecount_buf, key); | ||
162 | ctr128_inc_aligned(ivec); | ||
163 | while (len--) { | ||
164 | out[n] = in[n] ^ ecount_buf[n]; | ||
165 | ++n; | ||
166 | } | ||
167 | } | ||
168 | *num = n; | ||
169 | return; | ||
170 | } while(0); | ||
171 | /* the rest would be commonly eliminated by x86* compiler */ | ||
172 | #endif | ||
173 | while (l<len) { | ||
174 | if (n==0) { | ||
175 | (*block)(ivec, ecount_buf, key); | ||
176 | ctr128_inc(ivec); | ||
177 | } | ||
178 | out[l] = in[l] ^ ecount_buf[n]; | ||
179 | ++l; | ||
180 | n = (n+1) % 16; | ||
181 | } | ||
182 | |||
183 | *num=n; | ||
184 | } | ||
diff --git a/src/lib/libcrypto/modes/cts128.c b/src/lib/libcrypto/modes/cts128.c new file mode 100644 index 0000000000..e0430f9fdc --- /dev/null +++ b/src/lib/libcrypto/modes/cts128.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Rights for redistribution and usage in source and binary | ||
5 | * forms are granted according to the OpenSSL license. | ||
6 | */ | ||
7 | |||
8 | #include "modes.h" | ||
9 | #include <string.h> | ||
10 | |||
11 | #ifndef MODES_DEBUG | ||
12 | # ifndef NDEBUG | ||
13 | # define NDEBUG | ||
14 | # endif | ||
15 | #endif | ||
16 | #include <assert.h> | ||
17 | |||
18 | /* | ||
19 | * Trouble with Ciphertext Stealing, CTS, mode is that there is no | ||
20 | * common official specification, but couple of cipher/application | ||
21 | * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to | ||
22 | * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which | ||
23 | * deviates from mentioned RFCs. Most notably it allows input to be | ||
24 | * of block length and it doesn't flip the order of the last two | ||
25 | * blocks. CTS is being discussed even in ECB context, but it's not | ||
26 | * adopted for any known application. This implementation complies | ||
27 | * with mentioned RFCs and [as such] extends CBC mode. | ||
28 | */ | ||
29 | |||
30 | size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out, | ||
31 | size_t len, const void *key, | ||
32 | unsigned char ivec[16], block128_f block) | ||
33 | { size_t residue, n; | ||
34 | |||
35 | assert (in && out && key && ivec); | ||
36 | |||
37 | if (len <= 16) return 0; | ||
38 | |||
39 | if ((residue=len%16) == 0) residue = 16; | ||
40 | |||
41 | len -= residue; | ||
42 | |||
43 | CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block); | ||
44 | |||
45 | in += len; | ||
46 | out += len; | ||
47 | |||
48 | for (n=0; n<residue; ++n) | ||
49 | ivec[n] ^= in[n]; | ||
50 | (*block)(ivec,ivec,key); | ||
51 | memcpy(out,out-16,residue); | ||
52 | memcpy(out-16,ivec,16); | ||
53 | |||
54 | return len+residue; | ||
55 | } | ||
56 | |||
57 | size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, | ||
58 | size_t len, const void *key, | ||
59 | unsigned char ivec[16], cbc128_f cbc) | ||
60 | { size_t residue; | ||
61 | union { size_t align; unsigned char c[16]; } tmp; | ||
62 | |||
63 | assert (in && out && key && ivec); | ||
64 | |||
65 | if (len <= 16) return 0; | ||
66 | |||
67 | if ((residue=len%16) == 0) residue = 16; | ||
68 | |||
69 | len -= residue; | ||
70 | |||
71 | (*cbc)(in,out,len,key,ivec,1); | ||
72 | |||
73 | in += len; | ||
74 | out += len; | ||
75 | |||
76 | #if defined(CBC_HANDLES_TRUNCATED_IO) | ||
77 | memcpy(tmp.c,out-16,16); | ||
78 | (*cbc)(in,out-16,residue,key,ivec,1); | ||
79 | memcpy(out,tmp.c,residue); | ||
80 | #else | ||
81 | { | ||
82 | size_t n; | ||
83 | for (n=0; n<16; n+=sizeof(size_t)) | ||
84 | *(size_t *)(tmp.c+n) = 0; | ||
85 | memcpy(tmp.c,in,residue); | ||
86 | } | ||
87 | memcpy(out,out-16,residue); | ||
88 | (*cbc)(tmp.c,out-16,16,key,ivec,1); | ||
89 | #endif | ||
90 | return len+residue; | ||
91 | } | ||
92 | |||
93 | size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out, | ||
94 | size_t len, const void *key, | ||
95 | unsigned char ivec[16], block128_f block) | ||
96 | { size_t residue, n; | ||
97 | union { size_t align; unsigned char c[32]; } tmp; | ||
98 | |||
99 | assert (in && out && key && ivec); | ||
100 | |||
101 | if (len<=16) return 0; | ||
102 | |||
103 | if ((residue=len%16) == 0) residue = 16; | ||
104 | |||
105 | len -= 16+residue; | ||
106 | |||
107 | if (len) { | ||
108 | CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block); | ||
109 | in += len; | ||
110 | out += len; | ||
111 | } | ||
112 | |||
113 | (*block)(in,tmp.c+16,key); | ||
114 | |||
115 | for (n=0; n<16; n+=sizeof(size_t)) | ||
116 | *(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n); | ||
117 | memcpy(tmp.c,in+16,residue); | ||
118 | (*block)(tmp.c,tmp.c,key); | ||
119 | |||
120 | for(n=0; n<16; ++n) { | ||
121 | unsigned char c = in[n]; | ||
122 | out[n] = tmp.c[n] ^ ivec[n]; | ||
123 | ivec[n] = c; | ||
124 | } | ||
125 | for(residue+=16; n<residue; ++n) | ||
126 | out[n] = tmp.c[n] ^ in[n]; | ||
127 | |||
128 | return len+residue-16; | ||
129 | } | ||
130 | |||
131 | size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, | ||
132 | size_t len, const void *key, | ||
133 | unsigned char ivec[16], cbc128_f cbc) | ||
134 | { size_t residue, n; | ||
135 | union { size_t align; unsigned char c[32]; } tmp; | ||
136 | |||
137 | assert (in && out && key && ivec); | ||
138 | |||
139 | if (len<=16) return 0; | ||
140 | |||
141 | if ((residue=len%16) == 0) residue = 16; | ||
142 | |||
143 | len -= 16+residue; | ||
144 | |||
145 | if (len) { | ||
146 | (*cbc)(in,out,len,key,ivec,0); | ||
147 | in += len; | ||
148 | out += len; | ||
149 | } | ||
150 | |||
151 | for (n=16; n<32; n+=sizeof(size_t)) | ||
152 | *(size_t *)(tmp.c+n) = 0; | ||
153 | /* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */ | ||
154 | (*cbc)(in,tmp.c,16,key,tmp.c+16,0); | ||
155 | |||
156 | memcpy(tmp.c,in+16,residue); | ||
157 | #if defined(CBC_HANDLES_TRUNCATED_IO) | ||
158 | (*cbc)(tmp.c,out,16+residue,key,ivec,0); | ||
159 | #else | ||
160 | (*cbc)(tmp.c,tmp.c,32,key,ivec,0); | ||
161 | memcpy(out,tmp.c,16+residue); | ||
162 | #endif | ||
163 | return len+residue; | ||
164 | } | ||
165 | |||
166 | #if defined(SELFTEST) | ||
167 | #include <stdio.h> | ||
168 | #include <openssl/aes.h> | ||
169 | |||
170 | /* test vectors from RFC 3962 */ | ||
171 | static const unsigned char test_key[16] = "chicken teriyaki"; | ||
172 | static const unsigned char test_input[64] = | ||
173 | "I would like the" " General Gau's C" | ||
174 | "hicken, please, " "and wonton soup."; | ||
175 | static const unsigned char test_iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | ||
176 | |||
177 | static const unsigned char vector_17[17] = | ||
178 | {0xc6,0x35,0x35,0x68,0xf2,0xbf,0x8c,0xb4, 0xd8,0xa5,0x80,0x36,0x2d,0xa7,0xff,0x7f, | ||
179 | 0x97}; | ||
180 | static const unsigned char vector_31[31] = | ||
181 | {0xfc,0x00,0x78,0x3e,0x0e,0xfd,0xb2,0xc1, 0xd4,0x45,0xd4,0xc8,0xef,0xf7,0xed,0x22, | ||
182 | 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5}; | ||
183 | static const unsigned char vector_32[32] = | ||
184 | {0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8, | ||
185 | 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84}; | ||
186 | static const unsigned char vector_47[47] = | ||
187 | {0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84, | ||
188 | 0xb3,0xff,0xfd,0x94,0x0c,0x16,0xa1,0x8c, 0x1b,0x55,0x49,0xd2,0xf8,0x38,0x02,0x9e, | ||
189 | 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5}; | ||
190 | static const unsigned char vector_48[48] = | ||
191 | {0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84, | ||
192 | 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8, | ||
193 | 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8}; | ||
194 | static const unsigned char vector_64[64] = | ||
195 | {0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84, | ||
196 | 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8, | ||
197 | 0x48,0x07,0xef,0xe8,0x36,0xee,0x89,0xa5, 0x26,0x73,0x0d,0xbc,0x2f,0x7b,0xc8,0x40, | ||
198 | 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8}; | ||
199 | |||
200 | static AES_KEY encks, decks; | ||
201 | |||
202 | void test_vector(const unsigned char *vector,size_t len) | ||
203 | { unsigned char cleartext[64]; | ||
204 | unsigned char iv[sizeof(test_iv)]; | ||
205 | unsigned char ciphertext[64]; | ||
206 | size_t tail; | ||
207 | |||
208 | printf("vector_%d\n",len); fflush(stdout); | ||
209 | |||
210 | if ((tail=len%16) == 0) tail = 16; | ||
211 | tail += 16; | ||
212 | |||
213 | /* test block-based encryption */ | ||
214 | memcpy(iv,test_iv,sizeof(test_iv)); | ||
215 | CRYPTO_cts128_encrypt_block(test_input,ciphertext,len,&encks,iv,(block128_f)AES_encrypt); | ||
216 | if (memcmp(ciphertext,vector,len)) | ||
217 | fprintf(stderr,"output_%d mismatch\n",len), exit(1); | ||
218 | if (memcmp(iv,vector+len-tail,sizeof(iv))) | ||
219 | fprintf(stderr,"iv_%d mismatch\n",len), exit(1); | ||
220 | |||
221 | /* test block-based decryption */ | ||
222 | memcpy(iv,test_iv,sizeof(test_iv)); | ||
223 | CRYPTO_cts128_decrypt_block(ciphertext,cleartext,len,&decks,iv,(block128_f)AES_decrypt); | ||
224 | if (memcmp(cleartext,test_input,len)) | ||
225 | fprintf(stderr,"input_%d mismatch\n",len), exit(2); | ||
226 | if (memcmp(iv,vector+len-tail,sizeof(iv))) | ||
227 | fprintf(stderr,"iv_%d mismatch\n",len), exit(2); | ||
228 | |||
229 | /* test streamed encryption */ | ||
230 | memcpy(iv,test_iv,sizeof(test_iv)); | ||
231 | CRYPTO_cts128_encrypt(test_input,ciphertext,len,&encks,iv,(cbc128_f)AES_cbc_encrypt); | ||
232 | if (memcmp(ciphertext,vector,len)) | ||
233 | fprintf(stderr,"output_%d mismatch\n",len), exit(3); | ||
234 | if (memcmp(iv,vector+len-tail,sizeof(iv))) | ||
235 | fprintf(stderr,"iv_%d mismatch\n",len), exit(3); | ||
236 | |||
237 | /* test streamed decryption */ | ||
238 | memcpy(iv,test_iv,sizeof(test_iv)); | ||
239 | CRYPTO_cts128_decrypt(ciphertext,cleartext,len,&decks,iv,(cbc128_f)AES_cbc_encrypt); | ||
240 | if (memcmp(cleartext,test_input,len)) | ||
241 | fprintf(stderr,"input_%d mismatch\n",len), exit(4); | ||
242 | if (memcmp(iv,vector+len-tail,sizeof(iv))) | ||
243 | fprintf(stderr,"iv_%d mismatch\n",len), exit(4); | ||
244 | } | ||
245 | |||
246 | main() | ||
247 | { | ||
248 | AES_set_encrypt_key(test_key,128,&encks); | ||
249 | AES_set_decrypt_key(test_key,128,&decks); | ||
250 | |||
251 | test_vector(vector_17,sizeof(vector_17)); | ||
252 | test_vector(vector_31,sizeof(vector_31)); | ||
253 | test_vector(vector_32,sizeof(vector_32)); | ||
254 | test_vector(vector_47,sizeof(vector_47)); | ||
255 | test_vector(vector_48,sizeof(vector_48)); | ||
256 | test_vector(vector_64,sizeof(vector_64)); | ||
257 | exit(0); | ||
258 | } | ||
259 | #endif | ||
diff --git a/src/lib/libcrypto/modes/modes.h b/src/lib/libcrypto/modes/modes.h new file mode 100644 index 0000000000..af8d97d795 --- /dev/null +++ b/src/lib/libcrypto/modes/modes.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Rights for redistribution and usage in source and binary | ||
5 | * forms are granted according to the OpenSSL license. | ||
6 | */ | ||
7 | |||
8 | #include <stddef.h> | ||
9 | |||
10 | typedef void (*block128_f)(const unsigned char in[16], | ||
11 | unsigned char out[16], | ||
12 | const void *key); | ||
13 | |||
14 | typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out, | ||
15 | size_t len, const void *key, | ||
16 | unsigned char ivec[16], int enc); | ||
17 | |||
18 | void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, | ||
19 | size_t len, const void *key, | ||
20 | unsigned char ivec[16], block128_f block); | ||
21 | void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, | ||
22 | size_t len, const void *key, | ||
23 | unsigned char ivec[16], block128_f block); | ||
24 | |||
25 | void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, | ||
26 | size_t len, const void *key, | ||
27 | unsigned char ivec[16], unsigned char ecount_buf[16], | ||
28 | unsigned int *num, block128_f block); | ||
29 | |||
30 | void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, | ||
31 | size_t len, const void *key, | ||
32 | unsigned char ivec[16], int *num, | ||
33 | block128_f block); | ||
34 | |||
35 | void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, | ||
36 | size_t len, const void *key, | ||
37 | unsigned char ivec[16], int *num, | ||
38 | int enc, block128_f block); | ||
39 | void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, | ||
40 | size_t length, const void *key, | ||
41 | unsigned char ivec[16], int *num, | ||
42 | int enc, block128_f block); | ||
43 | void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, | ||
44 | size_t bits, const void *key, | ||
45 | unsigned char ivec[16], int *num, | ||
46 | int enc, block128_f block); | ||
47 | |||
48 | size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out, | ||
49 | size_t len, const void *key, | ||
50 | unsigned char ivec[16], block128_f block); | ||
51 | size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, | ||
52 | size_t len, const void *key, | ||
53 | unsigned char ivec[16], cbc128_f cbc); | ||
54 | size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out, | ||
55 | size_t len, const void *key, | ||
56 | unsigned char ivec[16], block128_f block); | ||
57 | size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, | ||
58 | size_t len, const void *key, | ||
59 | unsigned char ivec[16], cbc128_f cbc); | ||
diff --git a/src/lib/libcrypto/modes/ofb128.c b/src/lib/libcrypto/modes/ofb128.c new file mode 100644 index 0000000000..c732e2ec58 --- /dev/null +++ b/src/lib/libcrypto/modes/ofb128.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in | ||
13 | * the documentation and/or other materials provided with the | ||
14 | * distribution. | ||
15 | * | ||
16 | * 3. All advertising materials mentioning features or use of this | ||
17 | * software must display the following acknowledgment: | ||
18 | * "This product includes software developed by the OpenSSL Project | ||
19 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
20 | * | ||
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
22 | * endorse or promote products derived from this software without | ||
23 | * prior written permission. For written permission, please contact | ||
24 | * openssl-core@openssl.org. | ||
25 | * | ||
26 | * 5. Products derived from this software may not be called "OpenSSL" | ||
27 | * nor may "OpenSSL" appear in their names without prior written | ||
28 | * permission of the OpenSSL Project. | ||
29 | * | ||
30 | * 6. Redistributions of any form whatsoever must retain the following | ||
31 | * acknowledgment: | ||
32 | * "This product includes software developed by the OpenSSL Project | ||
33 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
34 | * | ||
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
47 | * ==================================================================== | ||
48 | * | ||
49 | */ | ||
50 | |||
51 | #include "modes.h" | ||
52 | #include <string.h> | ||
53 | |||
54 | #ifndef MODES_DEBUG | ||
55 | # ifndef NDEBUG | ||
56 | # define NDEBUG | ||
57 | # endif | ||
58 | #endif | ||
59 | #include <assert.h> | ||
60 | |||
61 | #define STRICT_ALIGNMENT | ||
62 | #if defined(__i386) || defined(__i386__) || \ | ||
63 | defined(__x86_64) || defined(__x86_64__) || \ | ||
64 | defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ | ||
65 | defined(__s390__) || defined(__s390x__) | ||
66 | # undef STRICT_ALIGNMENT | ||
67 | #endif | ||
68 | |||
69 | /* The input and output encrypted as though 128bit ofb mode is being | ||
70 | * used. The extra state information to record how much of the | ||
71 | * 128bit block we have used is contained in *num; | ||
72 | */ | ||
73 | void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, | ||
74 | size_t len, const void *key, | ||
75 | unsigned char ivec[16], int *num, | ||
76 | block128_f block) | ||
77 | { | ||
78 | unsigned int n; | ||
79 | size_t l=0; | ||
80 | |||
81 | assert(in && out && key && ivec && num); | ||
82 | |||
83 | n = *num; | ||
84 | |||
85 | #if !defined(OPENSSL_SMALL_FOOTPRINT) | ||
86 | if (16%sizeof(size_t) == 0) do { /* always true actually */ | ||
87 | while (n && len) { | ||
88 | *(out++) = *(in++) ^ ivec[n]; | ||
89 | --len; | ||
90 | n = (n+1) % 16; | ||
91 | } | ||
92 | #if defined(STRICT_ALIGNMENT) | ||
93 | if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) | ||
94 | break; | ||
95 | #endif | ||
96 | while (len>=16) { | ||
97 | (*block)(ivec, ivec, key); | ||
98 | for (; n<16; n+=sizeof(size_t)) | ||
99 | *(size_t*)(out+n) = | ||
100 | *(size_t*)(in+n) ^ *(size_t*)(ivec+n); | ||
101 | len -= 16; | ||
102 | out += 16; | ||
103 | in += 16; | ||
104 | n = 0; | ||
105 | } | ||
106 | if (len) { | ||
107 | (*block)(ivec, ivec, key); | ||
108 | while (len--) { | ||
109 | out[n] = in[n] ^ ivec[n]; | ||
110 | ++n; | ||
111 | } | ||
112 | } | ||
113 | *num = n; | ||
114 | return; | ||
115 | } while(0); | ||
116 | /* the rest would be commonly eliminated by x86* compiler */ | ||
117 | #endif | ||
118 | while (l<len) { | ||
119 | if (n==0) { | ||
120 | (*block)(ivec, ivec, key); | ||
121 | } | ||
122 | out[l] = in[l] ^ ivec[n]; | ||
123 | ++l; | ||
124 | n = (n+1) % 16; | ||
125 | } | ||
126 | |||
127 | *num=n; | ||
128 | } | ||
diff --git a/src/lib/libcrypto/o_str.c b/src/lib/libcrypto/o_str.c index 59cc25094b..56104a6c34 100644 --- a/src/lib/libcrypto/o_str.c +++ b/src/lib/libcrypto/o_str.c | |||
@@ -60,7 +60,9 @@ | |||
60 | #include <e_os.h> | 60 | #include <e_os.h> |
61 | #include "o_str.h" | 61 | #include "o_str.h" |
62 | 62 | ||
63 | #if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && !defined(OPENSSL_SYSNAME_WIN32) | 63 | #if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \ |
64 | !defined(OPENSSL_SYSNAME_WIN32) && \ | ||
65 | !defined(NETWARE_CLIB) | ||
64 | # include <strings.h> | 66 | # include <strings.h> |
65 | #endif | 67 | #endif |
66 | 68 | ||
diff --git a/src/lib/libcrypto/objects/obj_xref.c b/src/lib/libcrypto/objects/obj_xref.c new file mode 100644 index 0000000000..152eca5c67 --- /dev/null +++ b/src/lib/libcrypto/objects/obj_xref.c | |||
@@ -0,0 +1,231 @@ | |||
1 | /* crypto/objects/obj_xref.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2006. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <openssl/objects.h> | ||
60 | #include "obj_xref.h" | ||
61 | |||
62 | DECLARE_STACK_OF(nid_triple) | ||
63 | STACK_OF(nid_triple) *sig_app, *sigx_app; | ||
64 | |||
65 | static int sig_cmp(const nid_triple *a, const nid_triple *b) | ||
66 | { | ||
67 | return a->sign_id - b->sign_id; | ||
68 | } | ||
69 | |||
70 | DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); | ||
71 | IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); | ||
72 | |||
73 | static int sig_sk_cmp(const nid_triple * const *a, const nid_triple * const *b) | ||
74 | { | ||
75 | return (*a)->sign_id - (*b)->sign_id; | ||
76 | } | ||
77 | |||
78 | DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); | ||
79 | |||
80 | static int sigx_cmp(const nid_triple * const *a, const nid_triple * const *b) | ||
81 | { | ||
82 | int ret; | ||
83 | ret = (*a)->hash_id - (*b)->hash_id; | ||
84 | if (ret) | ||
85 | return ret; | ||
86 | return (*a)->pkey_id - (*b)->pkey_id; | ||
87 | } | ||
88 | |||
89 | IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); | ||
90 | |||
91 | int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid) | ||
92 | { | ||
93 | nid_triple tmp; | ||
94 | const nid_triple *rv = NULL; | ||
95 | tmp.sign_id = signid; | ||
96 | |||
97 | if (sig_app) | ||
98 | { | ||
99 | int idx = sk_nid_triple_find(sig_app, &tmp); | ||
100 | if (idx >= 0) | ||
101 | rv = sk_nid_triple_value(sig_app, idx); | ||
102 | } | ||
103 | |||
104 | #ifndef OBJ_XREF_TEST2 | ||
105 | if (rv == NULL) | ||
106 | { | ||
107 | rv = OBJ_bsearch_sig(&tmp, sigoid_srt, | ||
108 | sizeof(sigoid_srt) / sizeof(nid_triple)); | ||
109 | } | ||
110 | #endif | ||
111 | if (rv == NULL) | ||
112 | return 0; | ||
113 | *pdig_nid = rv->hash_id; | ||
114 | *ppkey_nid = rv->pkey_id; | ||
115 | return 1; | ||
116 | } | ||
117 | |||
118 | int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid) | ||
119 | { | ||
120 | nid_triple tmp; | ||
121 | const nid_triple *t=&tmp; | ||
122 | const nid_triple **rv = NULL; | ||
123 | |||
124 | tmp.hash_id = dig_nid; | ||
125 | tmp.pkey_id = pkey_nid; | ||
126 | |||
127 | if (sigx_app) | ||
128 | { | ||
129 | int idx = sk_nid_triple_find(sigx_app, &tmp); | ||
130 | if (idx >= 0) | ||
131 | { | ||
132 | t = sk_nid_triple_value(sigx_app, idx); | ||
133 | rv = &t; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | #ifndef OBJ_XREF_TEST2 | ||
138 | if (rv == NULL) | ||
139 | { | ||
140 | rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref, | ||
141 | sizeof(sigoid_srt_xref) / sizeof(nid_triple *) | ||
142 | ); | ||
143 | } | ||
144 | #endif | ||
145 | if (rv == NULL) | ||
146 | return 0; | ||
147 | *psignid = (*rv)->sign_id; | ||
148 | return 1; | ||
149 | } | ||
150 | |||
151 | int OBJ_add_sigid(int signid, int dig_id, int pkey_id) | ||
152 | { | ||
153 | nid_triple *ntr; | ||
154 | if (!sig_app) | ||
155 | sig_app = sk_nid_triple_new(sig_sk_cmp); | ||
156 | if (!sig_app) | ||
157 | return 0; | ||
158 | if (!sigx_app) | ||
159 | sigx_app = sk_nid_triple_new(sigx_cmp); | ||
160 | if (!sigx_app) | ||
161 | return 0; | ||
162 | ntr = OPENSSL_malloc(sizeof(int) * 3); | ||
163 | if (!ntr) | ||
164 | return 0; | ||
165 | ntr->sign_id = signid; | ||
166 | ntr->hash_id = dig_id; | ||
167 | ntr->pkey_id = pkey_id; | ||
168 | |||
169 | if (!sk_nid_triple_push(sig_app, ntr)) | ||
170 | { | ||
171 | OPENSSL_free(ntr); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | if (!sk_nid_triple_push(sigx_app, ntr)) | ||
176 | return 0; | ||
177 | |||
178 | sk_nid_triple_sort(sig_app); | ||
179 | sk_nid_triple_sort(sigx_app); | ||
180 | |||
181 | return 1; | ||
182 | } | ||
183 | |||
184 | static void sid_free(nid_triple *tt) | ||
185 | { | ||
186 | OPENSSL_free(tt); | ||
187 | } | ||
188 | |||
189 | void OBJ_sigid_free(void) | ||
190 | { | ||
191 | if (sig_app) | ||
192 | { | ||
193 | sk_nid_triple_pop_free(sig_app, sid_free); | ||
194 | sig_app = NULL; | ||
195 | } | ||
196 | if (sigx_app) | ||
197 | { | ||
198 | sk_nid_triple_free(sigx_app); | ||
199 | sigx_app = NULL; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | #ifdef OBJ_XREF_TEST | ||
204 | |||
205 | main() | ||
206 | { | ||
207 | int n1, n2, n3; | ||
208 | |||
209 | int i, rv; | ||
210 | #ifdef OBJ_XREF_TEST2 | ||
211 | for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) | ||
212 | { | ||
213 | OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1], | ||
214 | sigoid_srt[i][2]); | ||
215 | } | ||
216 | #endif | ||
217 | |||
218 | for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) | ||
219 | { | ||
220 | n1 = sigoid_srt[i][0]; | ||
221 | rv = OBJ_find_sigid_algs(n1, &n2, &n3); | ||
222 | printf("Forward: %d, %s %s %s\n", rv, | ||
223 | OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); | ||
224 | n1=0; | ||
225 | rv = OBJ_find_sigid_by_algs(&n1, n2, n3); | ||
226 | printf("Reverse: %d, %s %s %s\n", rv, | ||
227 | OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | #endif | ||
diff --git a/src/lib/libcrypto/objects/obj_xref.h b/src/lib/libcrypto/objects/obj_xref.h new file mode 100644 index 0000000000..d5b9b8e198 --- /dev/null +++ b/src/lib/libcrypto/objects/obj_xref.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* AUTOGENERATED BY objxref.pl, DO NOT EDIT */ | ||
2 | |||
3 | typedef struct | ||
4 | { | ||
5 | int sign_id; | ||
6 | int hash_id; | ||
7 | int pkey_id; | ||
8 | } nid_triple; | ||
9 | |||
10 | static const nid_triple sigoid_srt[] = | ||
11 | { | ||
12 | {NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption}, | ||
13 | {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption}, | ||
14 | {NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption}, | ||
15 | {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption}, | ||
16 | {NID_dsaWithSHA, NID_sha, NID_dsa}, | ||
17 | {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, | ||
18 | {NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption}, | ||
19 | {NID_md5WithRSA, NID_md5, NID_rsa}, | ||
20 | {NID_dsaWithSHA1, NID_sha1, NID_dsa}, | ||
21 | {NID_sha1WithRSA, NID_sha1, NID_rsa}, | ||
22 | {NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption}, | ||
23 | {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption}, | ||
24 | {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey}, | ||
25 | {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, | ||
26 | {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, | ||
27 | {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, | ||
28 | {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption}, | ||
29 | {NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey}, | ||
30 | {NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey}, | ||
31 | {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey}, | ||
32 | {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey}, | ||
33 | {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey}, | ||
34 | {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey}, | ||
35 | {NID_dsa_with_SHA224, NID_sha224, NID_dsa}, | ||
36 | {NID_dsa_with_SHA256, NID_sha256, NID_dsa}, | ||
37 | {NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, NID_id_GostR3410_2001}, | ||
38 | {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, NID_id_GostR3410_94}, | ||
39 | {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, NID_id_GostR3410_94_cc}, | ||
40 | {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc}, | ||
41 | }; | ||
42 | |||
43 | static const nid_triple * const sigoid_srt_xref[] = | ||
44 | { | ||
45 | &sigoid_srt[17], | ||
46 | &sigoid_srt[18], | ||
47 | &sigoid_srt[0], | ||
48 | &sigoid_srt[1], | ||
49 | &sigoid_srt[7], | ||
50 | &sigoid_srt[2], | ||
51 | &sigoid_srt[4], | ||
52 | &sigoid_srt[3], | ||
53 | &sigoid_srt[9], | ||
54 | &sigoid_srt[5], | ||
55 | &sigoid_srt[8], | ||
56 | &sigoid_srt[12], | ||
57 | &sigoid_srt[6], | ||
58 | &sigoid_srt[10], | ||
59 | &sigoid_srt[11], | ||
60 | &sigoid_srt[13], | ||
61 | &sigoid_srt[24], | ||
62 | &sigoid_srt[20], | ||
63 | &sigoid_srt[14], | ||
64 | &sigoid_srt[21], | ||
65 | &sigoid_srt[15], | ||
66 | &sigoid_srt[22], | ||
67 | &sigoid_srt[16], | ||
68 | &sigoid_srt[23], | ||
69 | &sigoid_srt[19], | ||
70 | &sigoid_srt[25], | ||
71 | &sigoid_srt[26], | ||
72 | &sigoid_srt[27], | ||
73 | &sigoid_srt[28], | ||
74 | }; | ||
75 | |||
diff --git a/src/lib/libcrypto/objects/obj_xref.txt b/src/lib/libcrypto/objects/obj_xref.txt new file mode 100644 index 0000000000..e45b3d34b9 --- /dev/null +++ b/src/lib/libcrypto/objects/obj_xref.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | # OID cross reference table. | ||
2 | # Links signatures OIDs to their corresponding public key algorithms | ||
3 | # and digests. | ||
4 | |||
5 | md2WithRSAEncryption md2 rsaEncryption | ||
6 | md5WithRSAEncryption md5 rsaEncryption | ||
7 | shaWithRSAEncryption sha rsaEncryption | ||
8 | sha1WithRSAEncryption sha1 rsaEncryption | ||
9 | md4WithRSAEncryption md4 rsaEncryption | ||
10 | sha256WithRSAEncryption sha256 rsaEncryption | ||
11 | sha384WithRSAEncryption sha384 rsaEncryption | ||
12 | sha512WithRSAEncryption sha512 rsaEncryption | ||
13 | sha224WithRSAEncryption sha224 rsaEncryption | ||
14 | mdc2WithRSA mdc2 rsaEncryption | ||
15 | ripemd160WithRSA ripemd160 rsaEncryption | ||
16 | |||
17 | # Alternative deprecated OIDs. By using the older "rsa" OID this | ||
18 | # type will be recognized by not normally used. | ||
19 | |||
20 | md5WithRSA md5 rsa | ||
21 | sha1WithRSA sha1 rsa | ||
22 | |||
23 | dsaWithSHA sha dsa | ||
24 | dsaWithSHA1 sha1 dsa | ||
25 | |||
26 | dsaWithSHA1_2 sha1 dsa_2 | ||
27 | |||
28 | ecdsa_with_SHA1 sha1 X9_62_id_ecPublicKey | ||
29 | ecdsa_with_SHA224 sha224 X9_62_id_ecPublicKey | ||
30 | ecdsa_with_SHA256 sha256 X9_62_id_ecPublicKey | ||
31 | ecdsa_with_SHA384 sha384 X9_62_id_ecPublicKey | ||
32 | ecdsa_with_SHA512 sha512 X9_62_id_ecPublicKey | ||
33 | ecdsa_with_Recommended undef X9_62_id_ecPublicKey | ||
34 | ecdsa_with_Specified undef X9_62_id_ecPublicKey | ||
35 | |||
36 | dsa_with_SHA224 sha224 dsa | ||
37 | dsa_with_SHA256 sha256 dsa | ||
38 | |||
39 | id_GostR3411_94_with_GostR3410_2001 id_GostR3411_94 id_GostR3410_2001 | ||
40 | id_GostR3411_94_with_GostR3410_94 id_GostR3411_94 id_GostR3410_94 | ||
41 | id_GostR3411_94_with_GostR3410_94_cc id_GostR3411_94 id_GostR3410_94_cc | ||
42 | id_GostR3411_94_with_GostR3410_2001_cc id_GostR3411_94 id_GostR3410_2001_cc | ||
diff --git a/src/lib/libcrypto/objects/objxref.pl b/src/lib/libcrypto/objects/objxref.pl new file mode 100644 index 0000000000..731d3ae22c --- /dev/null +++ b/src/lib/libcrypto/objects/objxref.pl | |||
@@ -0,0 +1,107 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | |||
3 | use strict; | ||
4 | |||
5 | my %xref_tbl; | ||
6 | my %oid_tbl; | ||
7 | |||
8 | my ($mac_file, $xref_file) = @ARGV; | ||
9 | |||
10 | open(IN, $mac_file) || die "Can't open $mac_file"; | ||
11 | |||
12 | # Read in OID nid values for a lookup table. | ||
13 | |||
14 | while (<IN>) | ||
15 | { | ||
16 | chomp; | ||
17 | my ($name, $num) = /^(\S+)\s+(\S+)$/; | ||
18 | $oid_tbl{$name} = $num; | ||
19 | } | ||
20 | close IN; | ||
21 | |||
22 | open(IN, $xref_file) || die "Can't open $xref_file"; | ||
23 | |||
24 | my $ln = 1; | ||
25 | |||
26 | while (<IN>) | ||
27 | { | ||
28 | chomp; | ||
29 | s/#.*$//; | ||
30 | next if (/^\S*$/); | ||
31 | my ($xr, $p1, $p2) = /^(\S+)\s+(\S+)\s+(\S+)/; | ||
32 | check_oid($xr); | ||
33 | check_oid($p1); | ||
34 | check_oid($p2); | ||
35 | $xref_tbl{$xr} = [$p1, $p2, $ln]; | ||
36 | } | ||
37 | |||
38 | my @xrkeys = keys %xref_tbl; | ||
39 | |||
40 | my @srt1 = sort { $oid_tbl{$a} <=> $oid_tbl{$b}} @xrkeys; | ||
41 | |||
42 | for(my $i = 0; $i <= $#srt1; $i++) | ||
43 | { | ||
44 | $xref_tbl{$srt1[$i]}[2] = $i; | ||
45 | } | ||
46 | |||
47 | my @srt2 = sort | ||
48 | { | ||
49 | my$ap1 = $oid_tbl{$xref_tbl{$a}[0]}; | ||
50 | my$bp1 = $oid_tbl{$xref_tbl{$b}[0]}; | ||
51 | return $ap1 - $bp1 if ($ap1 != $bp1); | ||
52 | my$ap2 = $oid_tbl{$xref_tbl{$a}[1]}; | ||
53 | my$bp2 = $oid_tbl{$xref_tbl{$b}[1]}; | ||
54 | |||
55 | return $ap2 - $bp2; | ||
56 | } @xrkeys; | ||
57 | |||
58 | my $pname = $0; | ||
59 | |||
60 | $pname =~ s|^.[^/]/||; | ||
61 | |||
62 | print <<EOF; | ||
63 | /* AUTOGENERATED BY $pname, DO NOT EDIT */ | ||
64 | |||
65 | typedef struct | ||
66 | { | ||
67 | int sign_id; | ||
68 | int hash_id; | ||
69 | int pkey_id; | ||
70 | } nid_triple; | ||
71 | |||
72 | static const nid_triple sigoid_srt[] = | ||
73 | { | ||
74 | EOF | ||
75 | |||
76 | foreach (@srt1) | ||
77 | { | ||
78 | my $xr = $_; | ||
79 | my ($p1, $p2) = @{$xref_tbl{$_}}; | ||
80 | print "\t{NID_$xr, NID_$p1, NID_$p2},\n"; | ||
81 | } | ||
82 | |||
83 | print "\t};"; | ||
84 | print <<EOF; | ||
85 | |||
86 | |||
87 | static const nid_triple * const sigoid_srt_xref[] = | ||
88 | { | ||
89 | EOF | ||
90 | |||
91 | foreach (@srt2) | ||
92 | { | ||
93 | my $x = $xref_tbl{$_}[2]; | ||
94 | print "\t\&sigoid_srt\[$x\],\n"; | ||
95 | } | ||
96 | |||
97 | print "\t};\n\n"; | ||
98 | |||
99 | sub check_oid | ||
100 | { | ||
101 | my ($chk) = @_; | ||
102 | if (!exists $oid_tbl{$chk}) | ||
103 | { | ||
104 | die "Not Found \"$chk\"\n"; | ||
105 | } | ||
106 | } | ||
107 | |||
diff --git a/src/lib/libcrypto/pem/pvkfmt.c b/src/lib/libcrypto/pem/pvkfmt.c new file mode 100644 index 0000000000..d998a67fa5 --- /dev/null +++ b/src/lib/libcrypto/pem/pvkfmt.c | |||
@@ -0,0 +1,942 @@ | |||
1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
2 | * project 2005. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2005 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | /* Support for PVK format keys and related structures (such a PUBLICKEYBLOB | ||
59 | * and PRIVATEKEYBLOB). | ||
60 | */ | ||
61 | |||
62 | #include "cryptlib.h" | ||
63 | #include <openssl/pem.h> | ||
64 | #include <openssl/rand.h> | ||
65 | #include <openssl/bn.h> | ||
66 | #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) | ||
67 | #include <openssl/dsa.h> | ||
68 | #include <openssl/rsa.h> | ||
69 | |||
70 | /* Utility function: read a DWORD (4 byte unsigned integer) in little endian | ||
71 | * format | ||
72 | */ | ||
73 | |||
74 | static unsigned int read_ledword(const unsigned char **in) | ||
75 | { | ||
76 | const unsigned char *p = *in; | ||
77 | unsigned int ret; | ||
78 | ret = *p++; | ||
79 | ret |= (*p++ << 8); | ||
80 | ret |= (*p++ << 16); | ||
81 | ret |= (*p++ << 24); | ||
82 | *in = p; | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | /* Read a BIGNUM in little endian format. The docs say that this should take up | ||
87 | * bitlen/8 bytes. | ||
88 | */ | ||
89 | |||
90 | static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) | ||
91 | { | ||
92 | const unsigned char *p; | ||
93 | unsigned char *tmpbuf, *q; | ||
94 | unsigned int i; | ||
95 | p = *in + nbyte - 1; | ||
96 | tmpbuf = OPENSSL_malloc(nbyte); | ||
97 | if (!tmpbuf) | ||
98 | return 0; | ||
99 | q = tmpbuf; | ||
100 | for (i = 0; i < nbyte; i++) | ||
101 | *q++ = *p--; | ||
102 | *r = BN_bin2bn(tmpbuf, nbyte, NULL); | ||
103 | OPENSSL_free(tmpbuf); | ||
104 | if (*r) | ||
105 | { | ||
106 | *in += nbyte; | ||
107 | return 1; | ||
108 | } | ||
109 | else | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | |||
114 | /* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */ | ||
115 | |||
116 | #define MS_PUBLICKEYBLOB 0x6 | ||
117 | #define MS_PRIVATEKEYBLOB 0x7 | ||
118 | #define MS_RSA1MAGIC 0x31415352L | ||
119 | #define MS_RSA2MAGIC 0x32415352L | ||
120 | #define MS_DSS1MAGIC 0x31535344L | ||
121 | #define MS_DSS2MAGIC 0x32535344L | ||
122 | |||
123 | #define MS_KEYALG_RSA_KEYX 0xa400 | ||
124 | #define MS_KEYALG_DSS_SIGN 0x2200 | ||
125 | |||
126 | #define MS_KEYTYPE_KEYX 0x1 | ||
127 | #define MS_KEYTYPE_SIGN 0x2 | ||
128 | |||
129 | /* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ | ||
130 | #define MS_PVKMAGIC 0xb0b5f11eL | ||
131 | /* Salt length for PVK files */ | ||
132 | #define PVK_SALTLEN 0x10 | ||
133 | |||
134 | static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, | ||
135 | unsigned int bitlen, int ispub); | ||
136 | static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, | ||
137 | unsigned int bitlen, int ispub); | ||
138 | |||
139 | static int do_blob_header(const unsigned char **in, unsigned int length, | ||
140 | unsigned int *pmagic, unsigned int *pbitlen, | ||
141 | int *pisdss, int *pispub) | ||
142 | { | ||
143 | const unsigned char *p = *in; | ||
144 | if (length < 16) | ||
145 | return 0; | ||
146 | /* bType */ | ||
147 | if (*p == MS_PUBLICKEYBLOB) | ||
148 | { | ||
149 | if (*pispub == 0) | ||
150 | { | ||
151 | PEMerr(PEM_F_DO_BLOB_HEADER, | ||
152 | PEM_R_EXPECTING_PRIVATE_KEY_BLOB); | ||
153 | return 0; | ||
154 | } | ||
155 | *pispub = 1; | ||
156 | } | ||
157 | else if (*p == MS_PRIVATEKEYBLOB) | ||
158 | { | ||
159 | if (*pispub == 1) | ||
160 | { | ||
161 | PEMerr(PEM_F_DO_BLOB_HEADER, | ||
162 | PEM_R_EXPECTING_PUBLIC_KEY_BLOB); | ||
163 | return 0; | ||
164 | } | ||
165 | *pispub = 0; | ||
166 | } | ||
167 | else | ||
168 | return 0; | ||
169 | p++; | ||
170 | /* Version */ | ||
171 | if (*p++ != 0x2) | ||
172 | { | ||
173 | PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER); | ||
174 | return 0; | ||
175 | } | ||
176 | /* Ignore reserved, aiKeyAlg */ | ||
177 | p+= 6; | ||
178 | *pmagic = read_ledword(&p); | ||
179 | *pbitlen = read_ledword(&p); | ||
180 | *pisdss = 0; | ||
181 | switch (*pmagic) | ||
182 | { | ||
183 | |||
184 | case MS_DSS1MAGIC: | ||
185 | *pisdss = 1; | ||
186 | case MS_RSA1MAGIC: | ||
187 | if (*pispub == 0) | ||
188 | { | ||
189 | PEMerr(PEM_F_DO_BLOB_HEADER, | ||
190 | PEM_R_EXPECTING_PRIVATE_KEY_BLOB); | ||
191 | return 0; | ||
192 | } | ||
193 | break; | ||
194 | |||
195 | case MS_DSS2MAGIC: | ||
196 | *pisdss = 1; | ||
197 | case MS_RSA2MAGIC: | ||
198 | if (*pispub == 1) | ||
199 | { | ||
200 | PEMerr(PEM_F_DO_BLOB_HEADER, | ||
201 | PEM_R_EXPECTING_PUBLIC_KEY_BLOB); | ||
202 | return 0; | ||
203 | } | ||
204 | break; | ||
205 | |||
206 | default: | ||
207 | PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER); | ||
208 | return -1; | ||
209 | } | ||
210 | *in = p; | ||
211 | return 1; | ||
212 | } | ||
213 | |||
214 | static unsigned int blob_length(unsigned bitlen, int isdss, int ispub) | ||
215 | { | ||
216 | unsigned int nbyte, hnbyte; | ||
217 | nbyte = (bitlen + 7) >> 3; | ||
218 | hnbyte = (bitlen + 15) >> 4; | ||
219 | if (isdss) | ||
220 | { | ||
221 | |||
222 | /* Expected length: 20 for q + 3 components bitlen each + 24 | ||
223 | * for seed structure. | ||
224 | */ | ||
225 | if (ispub) | ||
226 | return 44 + 3 * nbyte; | ||
227 | /* Expected length: 20 for q, priv, 2 bitlen components + 24 | ||
228 | * for seed structure. | ||
229 | */ | ||
230 | else | ||
231 | return 64 + 2 * nbyte; | ||
232 | } | ||
233 | else | ||
234 | { | ||
235 | /* Expected length: 4 for 'e' + 'n' */ | ||
236 | if (ispub) | ||
237 | return 4 + nbyte; | ||
238 | else | ||
239 | /* Expected length: 4 for 'e' and 7 other components. | ||
240 | * 2 components are bitlen size, 5 are bitlen/2 | ||
241 | */ | ||
242 | return 4 + 2*nbyte + 5*hnbyte; | ||
243 | } | ||
244 | |||
245 | } | ||
246 | |||
247 | static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length, | ||
248 | int ispub) | ||
249 | { | ||
250 | const unsigned char *p = *in; | ||
251 | unsigned int bitlen, magic; | ||
252 | int isdss; | ||
253 | if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) | ||
254 | { | ||
255 | PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); | ||
256 | return NULL; | ||
257 | } | ||
258 | length -= 16; | ||
259 | if (length < blob_length(bitlen, isdss, ispub)) | ||
260 | { | ||
261 | PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT); | ||
262 | return NULL; | ||
263 | } | ||
264 | if (isdss) | ||
265 | return b2i_dss(&p, length, bitlen, ispub); | ||
266 | else | ||
267 | return b2i_rsa(&p, length, bitlen, ispub); | ||
268 | } | ||
269 | |||
270 | static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) | ||
271 | { | ||
272 | const unsigned char *p; | ||
273 | unsigned char hdr_buf[16], *buf = NULL; | ||
274 | unsigned int bitlen, magic, length; | ||
275 | int isdss; | ||
276 | EVP_PKEY *ret = NULL; | ||
277 | if (BIO_read(in, hdr_buf, 16) != 16) | ||
278 | { | ||
279 | PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); | ||
280 | return NULL; | ||
281 | } | ||
282 | p = hdr_buf; | ||
283 | if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0) | ||
284 | return NULL; | ||
285 | |||
286 | length = blob_length(bitlen, isdss, ispub); | ||
287 | buf = OPENSSL_malloc(length); | ||
288 | if (!buf) | ||
289 | { | ||
290 | PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE); | ||
291 | goto err; | ||
292 | } | ||
293 | p = buf; | ||
294 | if (BIO_read(in, buf, length) != (int)length) | ||
295 | { | ||
296 | PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); | ||
297 | goto err; | ||
298 | } | ||
299 | |||
300 | if (isdss) | ||
301 | ret = b2i_dss(&p, length, bitlen, ispub); | ||
302 | else | ||
303 | ret = b2i_rsa(&p, length, bitlen, ispub); | ||
304 | |||
305 | err: | ||
306 | if (buf) | ||
307 | OPENSSL_free(buf); | ||
308 | return ret; | ||
309 | } | ||
310 | |||
311 | static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, | ||
312 | unsigned int bitlen, int ispub) | ||
313 | { | ||
314 | const unsigned char *p = *in; | ||
315 | EVP_PKEY *ret = NULL; | ||
316 | DSA *dsa = NULL; | ||
317 | BN_CTX *ctx = NULL; | ||
318 | unsigned int nbyte; | ||
319 | nbyte = (bitlen + 7) >> 3; | ||
320 | |||
321 | dsa = DSA_new(); | ||
322 | ret = EVP_PKEY_new(); | ||
323 | if (!dsa || !ret) | ||
324 | goto memerr; | ||
325 | if (!read_lebn(&p, nbyte, &dsa->p)) | ||
326 | goto memerr; | ||
327 | if (!read_lebn(&p, 20, &dsa->q)) | ||
328 | goto memerr; | ||
329 | if (!read_lebn(&p, nbyte, &dsa->g)) | ||
330 | goto memerr; | ||
331 | if (ispub) | ||
332 | { | ||
333 | if (!read_lebn(&p, nbyte, &dsa->pub_key)) | ||
334 | goto memerr; | ||
335 | } | ||
336 | else | ||
337 | { | ||
338 | if (!read_lebn(&p, 20, &dsa->priv_key)) | ||
339 | goto memerr; | ||
340 | /* Calculate public key */ | ||
341 | if (!(dsa->pub_key = BN_new())) | ||
342 | goto memerr; | ||
343 | if (!(ctx = BN_CTX_new())) | ||
344 | goto memerr; | ||
345 | |||
346 | if (!BN_mod_exp(dsa->pub_key, dsa->g, | ||
347 | dsa->priv_key, dsa->p, ctx)) | ||
348 | |||
349 | goto memerr; | ||
350 | BN_CTX_free(ctx); | ||
351 | } | ||
352 | |||
353 | EVP_PKEY_set1_DSA(ret, dsa); | ||
354 | DSA_free(dsa); | ||
355 | *in = p; | ||
356 | return ret; | ||
357 | |||
358 | memerr: | ||
359 | PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE); | ||
360 | if (dsa) | ||
361 | DSA_free(dsa); | ||
362 | if (ret) | ||
363 | EVP_PKEY_free(ret); | ||
364 | if (ctx) | ||
365 | BN_CTX_free(ctx); | ||
366 | return NULL; | ||
367 | } | ||
368 | |||
369 | static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, | ||
370 | unsigned int bitlen, int ispub) | ||
371 | |||
372 | { | ||
373 | const unsigned char *p = *in; | ||
374 | EVP_PKEY *ret = NULL; | ||
375 | RSA *rsa = NULL; | ||
376 | unsigned int nbyte, hnbyte; | ||
377 | nbyte = (bitlen + 7) >> 3; | ||
378 | hnbyte = (bitlen + 15) >> 4; | ||
379 | rsa = RSA_new(); | ||
380 | ret = EVP_PKEY_new(); | ||
381 | if (!rsa || !ret) | ||
382 | goto memerr; | ||
383 | rsa->e = BN_new(); | ||
384 | if (!rsa->e) | ||
385 | goto memerr; | ||
386 | if (!BN_set_word(rsa->e, read_ledword(&p))) | ||
387 | goto memerr; | ||
388 | if (!read_lebn(&p, nbyte, &rsa->n)) | ||
389 | goto memerr; | ||
390 | if (!ispub) | ||
391 | { | ||
392 | if (!read_lebn(&p, hnbyte, &rsa->p)) | ||
393 | goto memerr; | ||
394 | if (!read_lebn(&p, hnbyte, &rsa->q)) | ||
395 | goto memerr; | ||
396 | if (!read_lebn(&p, hnbyte, &rsa->dmp1)) | ||
397 | goto memerr; | ||
398 | if (!read_lebn(&p, hnbyte, &rsa->dmq1)) | ||
399 | goto memerr; | ||
400 | if (!read_lebn(&p, hnbyte, &rsa->iqmp)) | ||
401 | goto memerr; | ||
402 | if (!read_lebn(&p, nbyte, &rsa->d)) | ||
403 | goto memerr; | ||
404 | } | ||
405 | |||
406 | EVP_PKEY_set1_RSA(ret, rsa); | ||
407 | RSA_free(rsa); | ||
408 | *in = p; | ||
409 | return ret; | ||
410 | memerr: | ||
411 | PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE); | ||
412 | if (rsa) | ||
413 | RSA_free(rsa); | ||
414 | if (ret) | ||
415 | EVP_PKEY_free(ret); | ||
416 | return NULL; | ||
417 | } | ||
418 | |||
419 | EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length) | ||
420 | { | ||
421 | return do_b2i(in, length, 0); | ||
422 | } | ||
423 | |||
424 | EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length) | ||
425 | { | ||
426 | return do_b2i(in, length, 1); | ||
427 | } | ||
428 | |||
429 | |||
430 | EVP_PKEY *b2i_PrivateKey_bio(BIO *in) | ||
431 | { | ||
432 | return do_b2i_bio(in, 0); | ||
433 | } | ||
434 | |||
435 | EVP_PKEY *b2i_PublicKey_bio(BIO *in) | ||
436 | { | ||
437 | return do_b2i_bio(in, 1); | ||
438 | } | ||
439 | |||
440 | static void write_ledword(unsigned char **out, unsigned int dw) | ||
441 | { | ||
442 | unsigned char *p = *out; | ||
443 | *p++ = dw & 0xff; | ||
444 | *p++ = (dw>>8) & 0xff; | ||
445 | *p++ = (dw>>16) & 0xff; | ||
446 | *p++ = (dw>>24) & 0xff; | ||
447 | *out = p; | ||
448 | } | ||
449 | |||
450 | static void write_lebn(unsigned char **out, const BIGNUM *bn, int len) | ||
451 | { | ||
452 | int nb, i; | ||
453 | unsigned char *p = *out, *q, c; | ||
454 | nb = BN_num_bytes(bn); | ||
455 | BN_bn2bin(bn, p); | ||
456 | q = p + nb - 1; | ||
457 | /* In place byte order reversal */ | ||
458 | for (i = 0; i < nb/2; i++) | ||
459 | { | ||
460 | c = *p; | ||
461 | *p++ = *q; | ||
462 | *q-- = c; | ||
463 | } | ||
464 | *out += nb; | ||
465 | /* Pad with zeroes if we have to */ | ||
466 | if (len > 0) | ||
467 | { | ||
468 | len -= nb; | ||
469 | if (len > 0) | ||
470 | { | ||
471 | memset(*out, 0, len); | ||
472 | *out += len; | ||
473 | } | ||
474 | } | ||
475 | } | ||
476 | |||
477 | |||
478 | static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic); | ||
479 | static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic); | ||
480 | |||
481 | static void write_rsa(unsigned char **out, RSA *rsa, int ispub); | ||
482 | static void write_dsa(unsigned char **out, DSA *dsa, int ispub); | ||
483 | |||
484 | static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) | ||
485 | { | ||
486 | unsigned char *p; | ||
487 | unsigned int bitlen, magic = 0, keyalg; | ||
488 | int outlen, noinc = 0; | ||
489 | if (pk->type == EVP_PKEY_DSA) | ||
490 | { | ||
491 | bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic); | ||
492 | keyalg = MS_KEYALG_DSS_SIGN; | ||
493 | } | ||
494 | else if (pk->type == EVP_PKEY_RSA) | ||
495 | { | ||
496 | bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic); | ||
497 | keyalg = MS_KEYALG_RSA_KEYX; | ||
498 | } | ||
499 | else | ||
500 | return -1; | ||
501 | if (bitlen == 0) | ||
502 | return -1; | ||
503 | outlen = 16 + blob_length(bitlen, | ||
504 | keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); | ||
505 | if (out == NULL) | ||
506 | return outlen; | ||
507 | if (*out) | ||
508 | p = *out; | ||
509 | else | ||
510 | { | ||
511 | p = OPENSSL_malloc(outlen); | ||
512 | if (!p) | ||
513 | return -1; | ||
514 | *out = p; | ||
515 | noinc = 1; | ||
516 | } | ||
517 | if (ispub) | ||
518 | *p++ = MS_PUBLICKEYBLOB; | ||
519 | else | ||
520 | *p++ = MS_PRIVATEKEYBLOB; | ||
521 | *p++ = 0x2; | ||
522 | *p++ = 0; | ||
523 | *p++ = 0; | ||
524 | write_ledword(&p, keyalg); | ||
525 | write_ledword(&p, magic); | ||
526 | write_ledword(&p, bitlen); | ||
527 | if (keyalg == MS_KEYALG_DSS_SIGN) | ||
528 | write_dsa(&p, pk->pkey.dsa, ispub); | ||
529 | else | ||
530 | write_rsa(&p, pk->pkey.rsa, ispub); | ||
531 | if (!noinc) | ||
532 | *out += outlen; | ||
533 | return outlen; | ||
534 | } | ||
535 | |||
536 | static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) | ||
537 | { | ||
538 | unsigned char *tmp = NULL; | ||
539 | int outlen, wrlen; | ||
540 | outlen = do_i2b(&tmp, pk, ispub); | ||
541 | if (outlen < 0) | ||
542 | return -1; | ||
543 | wrlen = BIO_write(out, tmp, outlen); | ||
544 | OPENSSL_free(tmp); | ||
545 | if (wrlen == outlen) | ||
546 | return outlen; | ||
547 | return -1; | ||
548 | } | ||
549 | |||
550 | static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic) | ||
551 | { | ||
552 | int bitlen; | ||
553 | bitlen = BN_num_bits(dsa->p); | ||
554 | if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160) | ||
555 | || (BN_num_bits(dsa->g) > bitlen)) | ||
556 | goto badkey; | ||
557 | if (ispub) | ||
558 | { | ||
559 | if (BN_num_bits(dsa->pub_key) > bitlen) | ||
560 | goto badkey; | ||
561 | *pmagic = MS_DSS1MAGIC; | ||
562 | } | ||
563 | else | ||
564 | { | ||
565 | if (BN_num_bits(dsa->priv_key) > 160) | ||
566 | goto badkey; | ||
567 | *pmagic = MS_DSS2MAGIC; | ||
568 | } | ||
569 | |||
570 | return bitlen; | ||
571 | badkey: | ||
572 | PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); | ||
573 | return 0; | ||
574 | } | ||
575 | |||
576 | static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) | ||
577 | { | ||
578 | int nbyte, hnbyte, bitlen; | ||
579 | if (BN_num_bits(rsa->e) > 32) | ||
580 | goto badkey; | ||
581 | bitlen = BN_num_bits(rsa->n); | ||
582 | nbyte = BN_num_bytes(rsa->n); | ||
583 | hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; | ||
584 | if (ispub) | ||
585 | { | ||
586 | *pmagic = MS_RSA1MAGIC; | ||
587 | return bitlen; | ||
588 | } | ||
589 | else | ||
590 | { | ||
591 | *pmagic = MS_RSA2MAGIC; | ||
592 | /* For private key each component must fit within nbyte or | ||
593 | * hnbyte. | ||
594 | */ | ||
595 | if (BN_num_bytes(rsa->d) > nbyte) | ||
596 | goto badkey; | ||
597 | if ((BN_num_bytes(rsa->iqmp) > hnbyte) | ||
598 | || (BN_num_bytes(rsa->p) > hnbyte) | ||
599 | || (BN_num_bytes(rsa->q) > hnbyte) | ||
600 | || (BN_num_bytes(rsa->dmp1) > hnbyte) | ||
601 | || (BN_num_bytes(rsa->dmq1) > hnbyte)) | ||
602 | goto badkey; | ||
603 | } | ||
604 | return bitlen; | ||
605 | badkey: | ||
606 | PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | |||
611 | static void write_rsa(unsigned char **out, RSA *rsa, int ispub) | ||
612 | { | ||
613 | int nbyte, hnbyte; | ||
614 | nbyte = BN_num_bytes(rsa->n); | ||
615 | hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; | ||
616 | write_lebn(out, rsa->e, 4); | ||
617 | write_lebn(out, rsa->n, -1); | ||
618 | if (ispub) | ||
619 | return; | ||
620 | write_lebn(out, rsa->p, hnbyte); | ||
621 | write_lebn(out, rsa->q, hnbyte); | ||
622 | write_lebn(out, rsa->dmp1, hnbyte); | ||
623 | write_lebn(out, rsa->dmq1, hnbyte); | ||
624 | write_lebn(out, rsa->iqmp, hnbyte); | ||
625 | write_lebn(out, rsa->d, nbyte); | ||
626 | } | ||
627 | |||
628 | |||
629 | static void write_dsa(unsigned char **out, DSA *dsa, int ispub) | ||
630 | { | ||
631 | int nbyte; | ||
632 | nbyte = BN_num_bytes(dsa->p); | ||
633 | write_lebn(out, dsa->p, nbyte); | ||
634 | write_lebn(out, dsa->q, 20); | ||
635 | write_lebn(out, dsa->g, nbyte); | ||
636 | if (ispub) | ||
637 | write_lebn(out, dsa->pub_key, nbyte); | ||
638 | else | ||
639 | write_lebn(out, dsa->priv_key, 20); | ||
640 | /* Set "invalid" for seed structure values */ | ||
641 | memset(*out, 0xff, 24); | ||
642 | *out += 24; | ||
643 | return; | ||
644 | } | ||
645 | |||
646 | |||
647 | int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk) | ||
648 | { | ||
649 | return do_i2b_bio(out, pk, 0); | ||
650 | } | ||
651 | |||
652 | int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk) | ||
653 | { | ||
654 | return do_i2b_bio(out, pk, 1); | ||
655 | } | ||
656 | |||
657 | #ifndef OPENSSL_NO_RC4 | ||
658 | |||
659 | static int do_PVK_header(const unsigned char **in, unsigned int length, | ||
660 | int skip_magic, | ||
661 | unsigned int *psaltlen, unsigned int *pkeylen) | ||
662 | |||
663 | { | ||
664 | const unsigned char *p = *in; | ||
665 | unsigned int pvk_magic, keytype, is_encrypted; | ||
666 | if (skip_magic) | ||
667 | { | ||
668 | if (length < 20) | ||
669 | { | ||
670 | PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); | ||
671 | return 0; | ||
672 | } | ||
673 | length -= 20; | ||
674 | } | ||
675 | else | ||
676 | { | ||
677 | if (length < 24) | ||
678 | { | ||
679 | PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); | ||
680 | return 0; | ||
681 | } | ||
682 | length -= 24; | ||
683 | pvk_magic = read_ledword(&p); | ||
684 | if (pvk_magic != MS_PVKMAGIC) | ||
685 | { | ||
686 | PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER); | ||
687 | return 0; | ||
688 | } | ||
689 | } | ||
690 | /* Skip reserved */ | ||
691 | p += 4; | ||
692 | keytype = read_ledword(&p); | ||
693 | is_encrypted = read_ledword(&p); | ||
694 | *psaltlen = read_ledword(&p); | ||
695 | *pkeylen = read_ledword(&p); | ||
696 | |||
697 | if (is_encrypted && !*psaltlen) | ||
698 | { | ||
699 | PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER); | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | *in = p; | ||
704 | return 1; | ||
705 | } | ||
706 | |||
707 | static int derive_pvk_key(unsigned char *key, | ||
708 | const unsigned char *salt, unsigned int saltlen, | ||
709 | const unsigned char *pass, int passlen) | ||
710 | { | ||
711 | EVP_MD_CTX mctx; | ||
712 | EVP_MD_CTX_init(&mctx); | ||
713 | EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL); | ||
714 | EVP_DigestUpdate(&mctx, salt, saltlen); | ||
715 | EVP_DigestUpdate(&mctx, pass, passlen); | ||
716 | EVP_DigestFinal_ex(&mctx, key, NULL); | ||
717 | EVP_MD_CTX_cleanup(&mctx); | ||
718 | return 1; | ||
719 | } | ||
720 | |||
721 | |||
722 | static EVP_PKEY *do_PVK_body(const unsigned char **in, | ||
723 | unsigned int saltlen, unsigned int keylen, | ||
724 | pem_password_cb *cb, void *u) | ||
725 | { | ||
726 | EVP_PKEY *ret = NULL; | ||
727 | const unsigned char *p = *in; | ||
728 | unsigned int magic; | ||
729 | unsigned char *enctmp = NULL, *q; | ||
730 | if (saltlen) | ||
731 | { | ||
732 | char psbuf[PEM_BUFSIZE]; | ||
733 | unsigned char keybuf[20]; | ||
734 | EVP_CIPHER_CTX cctx; | ||
735 | int enctmplen, inlen; | ||
736 | if (cb) | ||
737 | inlen=cb(psbuf,PEM_BUFSIZE,0,u); | ||
738 | else | ||
739 | inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u); | ||
740 | if (inlen <= 0) | ||
741 | { | ||
742 | PEMerr(PEM_F_DO_PVK_BODY,PEM_R_BAD_PASSWORD_READ); | ||
743 | return NULL; | ||
744 | } | ||
745 | enctmp = OPENSSL_malloc(keylen + 8); | ||
746 | if (!enctmp) | ||
747 | { | ||
748 | PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE); | ||
749 | return NULL; | ||
750 | } | ||
751 | if (!derive_pvk_key(keybuf, p, saltlen, | ||
752 | (unsigned char *)psbuf, inlen)) | ||
753 | return NULL; | ||
754 | p += saltlen; | ||
755 | /* Copy BLOBHEADER across, decrypt rest */ | ||
756 | memcpy(enctmp, p, 8); | ||
757 | p += 8; | ||
758 | inlen = keylen - 8; | ||
759 | q = enctmp + 8; | ||
760 | EVP_CIPHER_CTX_init(&cctx); | ||
761 | EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL); | ||
762 | EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen); | ||
763 | EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen); | ||
764 | magic = read_ledword((const unsigned char **)&q); | ||
765 | if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) | ||
766 | { | ||
767 | q = enctmp + 8; | ||
768 | memset(keybuf + 5, 0, 11); | ||
769 | EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, | ||
770 | NULL); | ||
771 | OPENSSL_cleanse(keybuf, 20); | ||
772 | EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen); | ||
773 | EVP_DecryptFinal_ex(&cctx, q + enctmplen, | ||
774 | &enctmplen); | ||
775 | magic = read_ledword((const unsigned char **)&q); | ||
776 | if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) | ||
777 | { | ||
778 | EVP_CIPHER_CTX_cleanup(&cctx); | ||
779 | PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT); | ||
780 | goto err; | ||
781 | } | ||
782 | } | ||
783 | else | ||
784 | OPENSSL_cleanse(keybuf, 20); | ||
785 | EVP_CIPHER_CTX_cleanup(&cctx); | ||
786 | p = enctmp; | ||
787 | } | ||
788 | |||
789 | ret = b2i_PrivateKey(&p, keylen); | ||
790 | err: | ||
791 | if (enctmp && saltlen) | ||
792 | OPENSSL_free(enctmp); | ||
793 | return ret; | ||
794 | } | ||
795 | |||
796 | |||
797 | EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) | ||
798 | { | ||
799 | unsigned char pvk_hdr[24], *buf = NULL; | ||
800 | const unsigned char *p; | ||
801 | int buflen; | ||
802 | EVP_PKEY *ret = NULL; | ||
803 | unsigned int saltlen, keylen; | ||
804 | if (BIO_read(in, pvk_hdr, 24) != 24) | ||
805 | { | ||
806 | PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); | ||
807 | return NULL; | ||
808 | } | ||
809 | p = pvk_hdr; | ||
810 | |||
811 | if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen)) | ||
812 | return 0; | ||
813 | buflen = (int) keylen + saltlen; | ||
814 | buf = OPENSSL_malloc(buflen); | ||
815 | if (!buf) | ||
816 | { | ||
817 | PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE); | ||
818 | return 0; | ||
819 | } | ||
820 | p = buf; | ||
821 | if (BIO_read(in, buf, buflen) != buflen) | ||
822 | { | ||
823 | PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); | ||
824 | goto err; | ||
825 | } | ||
826 | ret = do_PVK_body(&p, saltlen, keylen, cb, u); | ||
827 | |||
828 | err: | ||
829 | if (buf) | ||
830 | { | ||
831 | OPENSSL_cleanse(buf, buflen); | ||
832 | OPENSSL_free(buf); | ||
833 | } | ||
834 | return ret; | ||
835 | } | ||
836 | |||
837 | |||
838 | |||
839 | static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel, | ||
840 | pem_password_cb *cb, void *u) | ||
841 | { | ||
842 | int outlen = 24, noinc, pklen; | ||
843 | unsigned char *p, *salt = NULL; | ||
844 | if (enclevel) | ||
845 | outlen += PVK_SALTLEN; | ||
846 | pklen = do_i2b(NULL, pk, 0); | ||
847 | if (pklen < 0) | ||
848 | return -1; | ||
849 | outlen += pklen; | ||
850 | if (!out) | ||
851 | return outlen; | ||
852 | if (*out) | ||
853 | { | ||
854 | p = *out; | ||
855 | noinc = 0; | ||
856 | } | ||
857 | else | ||
858 | { | ||
859 | p = OPENSSL_malloc(outlen); | ||
860 | if (!p) | ||
861 | { | ||
862 | PEMerr(PEM_F_I2B_PVK,ERR_R_MALLOC_FAILURE); | ||
863 | return -1; | ||
864 | } | ||
865 | *out = p; | ||
866 | noinc = 1; | ||
867 | } | ||
868 | |||
869 | write_ledword(&p, MS_PVKMAGIC); | ||
870 | write_ledword(&p, 0); | ||
871 | if (pk->type == EVP_PKEY_DSA) | ||
872 | write_ledword(&p, MS_KEYTYPE_SIGN); | ||
873 | else | ||
874 | write_ledword(&p, MS_KEYTYPE_KEYX); | ||
875 | write_ledword(&p, enclevel ? 1 : 0); | ||
876 | write_ledword(&p, enclevel ? PVK_SALTLEN: 0); | ||
877 | write_ledword(&p, pklen); | ||
878 | if (enclevel) | ||
879 | { | ||
880 | if (RAND_bytes(p, PVK_SALTLEN) <= 0) | ||
881 | goto error; | ||
882 | salt = p; | ||
883 | p += PVK_SALTLEN; | ||
884 | } | ||
885 | do_i2b(&p, pk, 0); | ||
886 | if (enclevel == 0) | ||
887 | return outlen; | ||
888 | else | ||
889 | { | ||
890 | char psbuf[PEM_BUFSIZE]; | ||
891 | unsigned char keybuf[20]; | ||
892 | EVP_CIPHER_CTX cctx; | ||
893 | int enctmplen, inlen; | ||
894 | if (cb) | ||
895 | inlen=cb(psbuf,PEM_BUFSIZE,1,u); | ||
896 | else | ||
897 | inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,1,u); | ||
898 | if (inlen <= 0) | ||
899 | { | ||
900 | PEMerr(PEM_F_I2B_PVK,PEM_R_BAD_PASSWORD_READ); | ||
901 | goto error; | ||
902 | } | ||
903 | if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, | ||
904 | (unsigned char *)psbuf, inlen)) | ||
905 | goto error; | ||
906 | if (enclevel == 1) | ||
907 | memset(keybuf + 5, 0, 11); | ||
908 | p = salt + PVK_SALTLEN + 8; | ||
909 | EVP_CIPHER_CTX_init(&cctx); | ||
910 | EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL); | ||
911 | OPENSSL_cleanse(keybuf, 20); | ||
912 | EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8); | ||
913 | EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen); | ||
914 | EVP_CIPHER_CTX_cleanup(&cctx); | ||
915 | } | ||
916 | return outlen; | ||
917 | |||
918 | error: | ||
919 | return -1; | ||
920 | } | ||
921 | |||
922 | int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, | ||
923 | pem_password_cb *cb, void *u) | ||
924 | { | ||
925 | unsigned char *tmp = NULL; | ||
926 | int outlen, wrlen; | ||
927 | outlen = i2b_PVK(&tmp, pk, enclevel, cb, u); | ||
928 | if (outlen < 0) | ||
929 | return -1; | ||
930 | wrlen = BIO_write(out, tmp, outlen); | ||
931 | OPENSSL_free(tmp); | ||
932 | if (wrlen == outlen) | ||
933 | { | ||
934 | PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE); | ||
935 | return outlen; | ||
936 | } | ||
937 | return -1; | ||
938 | } | ||
939 | |||
940 | #endif | ||
941 | |||
942 | #endif | ||
diff --git a/src/lib/libcrypto/perlasm/ppc-xlate.pl b/src/lib/libcrypto/perlasm/ppc-xlate.pl new file mode 100755 index 0000000000..4579671c97 --- /dev/null +++ b/src/lib/libcrypto/perlasm/ppc-xlate.pl | |||
@@ -0,0 +1,152 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # PowerPC assembler distiller by <appro>. | ||
4 | |||
5 | my $flavour = shift; | ||
6 | my $output = shift; | ||
7 | open STDOUT,">$output" || die "can't open $output: $!"; | ||
8 | |||
9 | my %GLOBALS; | ||
10 | my $dotinlocallabels=($flavour=~/linux/)?1:0; | ||
11 | |||
12 | ################################################################ | ||
13 | # directives which need special treatment on different platforms | ||
14 | ################################################################ | ||
15 | my $globl = sub { | ||
16 | my $junk = shift; | ||
17 | my $name = shift; | ||
18 | my $global = \$GLOBALS{$name}; | ||
19 | my $ret; | ||
20 | |||
21 | $name =~ s|^[\.\_]||; | ||
22 | |||
23 | SWITCH: for ($flavour) { | ||
24 | /aix/ && do { $name = ".$name"; | ||
25 | last; | ||
26 | }; | ||
27 | /osx/ && do { $name = "_$name"; | ||
28 | last; | ||
29 | }; | ||
30 | /linux.*32/ && do { $ret .= ".globl $name\n"; | ||
31 | $ret .= ".type $name,\@function"; | ||
32 | last; | ||
33 | }; | ||
34 | /linux.*64/ && do { $ret .= ".globl .$name\n"; | ||
35 | $ret .= ".type .$name,\@function\n"; | ||
36 | $ret .= ".section \".opd\",\"aw\"\n"; | ||
37 | $ret .= ".globl $name\n"; | ||
38 | $ret .= ".align 3\n"; | ||
39 | $ret .= "$name:\n"; | ||
40 | $ret .= ".quad .$name,.TOC.\@tocbase,0\n"; | ||
41 | $ret .= ".size $name,24\n"; | ||
42 | $ret .= ".previous\n"; | ||
43 | |||
44 | $name = ".$name"; | ||
45 | last; | ||
46 | }; | ||
47 | } | ||
48 | |||
49 | $ret = ".globl $name" if (!$ret); | ||
50 | $$global = $name; | ||
51 | $ret; | ||
52 | }; | ||
53 | my $text = sub { | ||
54 | ($flavour =~ /aix/) ? ".csect" : ".text"; | ||
55 | }; | ||
56 | my $machine = sub { | ||
57 | my $junk = shift; | ||
58 | my $arch = shift; | ||
59 | if ($flavour =~ /osx/) | ||
60 | { $arch =~ s/\"//g; | ||
61 | $arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any"); | ||
62 | } | ||
63 | ".machine $arch"; | ||
64 | }; | ||
65 | my $asciz = sub { | ||
66 | shift; | ||
67 | my $line = join(",",@_); | ||
68 | if ($line =~ /^"(.*)"$/) | ||
69 | { ".byte " . join(",",unpack("C*",$1),0) . "\n.align 2"; } | ||
70 | else | ||
71 | { ""; } | ||
72 | }; | ||
73 | |||
74 | ################################################################ | ||
75 | # simplified mnemonics not handled by at least one assembler | ||
76 | ################################################################ | ||
77 | my $cmplw = sub { | ||
78 | my $f = shift; | ||
79 | my $cr = 0; $cr = shift if ($#_>1); | ||
80 | # Some out-of-date 32-bit GNU assembler just can't handle cmplw... | ||
81 | ($flavour =~ /linux.*32/) ? | ||
82 | " .long ".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 : | ||
83 | " cmplw ".join(',',$cr,@_); | ||
84 | }; | ||
85 | my $bdnz = sub { | ||
86 | my $f = shift; | ||
87 | my $bo = $f=~/[\+\-]/ ? 16+9 : 16; # optional "to be taken" hint | ||
88 | " bc $bo,0,".shift; | ||
89 | } if ($flavour!~/linux/); | ||
90 | my $bltlr = sub { | ||
91 | my $f = shift; | ||
92 | my $bo = $f=~/\-/ ? 12+2 : 12; # optional "not to be taken" hint | ||
93 | ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints | ||
94 | " .long ".sprintf "0x%x",19<<26|$bo<<21|16<<1 : | ||
95 | " bclr $bo,0"; | ||
96 | }; | ||
97 | my $bnelr = sub { | ||
98 | my $f = shift; | ||
99 | my $bo = $f=~/\-/ ? 4+2 : 4; # optional "not to be taken" hint | ||
100 | ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints | ||
101 | " .long ".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 : | ||
102 | " bclr $bo,2"; | ||
103 | }; | ||
104 | my $beqlr = sub { | ||
105 | my $f = shift; | ||
106 | my $bo = $f=~/-/ ? 12+2 : 12; # optional "not to be taken" hint | ||
107 | ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints | ||
108 | " .long ".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 : | ||
109 | " bclr $bo,2"; | ||
110 | }; | ||
111 | # GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two | ||
112 | # arguments is 64, with "operand out of range" error. | ||
113 | my $extrdi = sub { | ||
114 | my ($f,$ra,$rs,$n,$b) = @_; | ||
115 | $b = ($b+$n)&63; $n = 64-$n; | ||
116 | " rldicl $ra,$rs,$b,$n"; | ||
117 | }; | ||
118 | |||
119 | while($line=<>) { | ||
120 | |||
121 | $line =~ s|[#!;].*$||; # get rid of asm-style comments... | ||
122 | $line =~ s|/\*.*\*/||; # ... and C-style comments... | ||
123 | $line =~ s|^\s+||; # ... and skip white spaces in beginning... | ||
124 | $line =~ s|\s+$||; # ... and at the end | ||
125 | |||
126 | { | ||
127 | $line =~ s|\b\.L(\w+)|L$1|g; # common denominator for Locallabel | ||
128 | $line =~ s|\bL(\w+)|\.L$1|g if ($dotinlocallabels); | ||
129 | } | ||
130 | |||
131 | { | ||
132 | $line =~ s|(^[\.\w]+)\:\s*||; | ||
133 | my $label = $1; | ||
134 | printf "%s:",($GLOBALS{$label} or $label) if ($label); | ||
135 | } | ||
136 | |||
137 | { | ||
138 | $line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||; | ||
139 | my $c = $1; $c = "\t" if ($c eq ""); | ||
140 | my $mnemonic = $2; | ||
141 | my $f = $3; | ||
142 | my $opcode = eval("\$$mnemonic"); | ||
143 | $line =~ s|\bc?[rf]([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/); | ||
144 | if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); } | ||
145 | elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; } | ||
146 | } | ||
147 | |||
148 | print $line if ($line); | ||
149 | print "\n"; | ||
150 | } | ||
151 | |||
152 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/perlasm/x86gas.pl b/src/lib/libcrypto/perlasm/x86gas.pl new file mode 100644 index 0000000000..6eab727fd4 --- /dev/null +++ b/src/lib/libcrypto/perlasm/x86gas.pl | |||
@@ -0,0 +1,247 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | package x86gas; | ||
4 | |||
5 | *out=\@::out; | ||
6 | |||
7 | $::lbdecor=$::aout?"L":".L"; # local label decoration | ||
8 | $nmdecor=($::aout or $::coff)?"_":""; # external name decoration | ||
9 | |||
10 | $initseg=""; | ||
11 | |||
12 | $align=16; | ||
13 | $align=log($align)/log(2) if ($::aout); | ||
14 | $com_start="#" if ($::aout or $::coff); | ||
15 | |||
16 | sub opsize() | ||
17 | { my $reg=shift; | ||
18 | if ($reg =~ m/^%e/o) { "l"; } | ||
19 | elsif ($reg =~ m/^%[a-d][hl]$/o) { "b"; } | ||
20 | elsif ($reg =~ m/^%[xm]/o) { undef; } | ||
21 | else { "w"; } | ||
22 | } | ||
23 | |||
24 | # swap arguments; | ||
25 | # expand opcode with size suffix; | ||
26 | # prefix numeric constants with $; | ||
27 | sub ::generic | ||
28 | { my($opcode,@arg)=@_; | ||
29 | my($suffix,$dst,$src); | ||
30 | |||
31 | @arg=reverse(@arg); | ||
32 | |||
33 | for (@arg) | ||
34 | { s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o; # gp registers | ||
35 | s/^([xy]?mm[0-7])$/%$1/o; # xmm/mmx registers | ||
36 | s/^(\-?[0-9]+)$/\$$1/o; # constants | ||
37 | s/^(\-?0x[0-9a-f]+)$/\$$1/o; # constants | ||
38 | } | ||
39 | |||
40 | $dst = $arg[$#arg] if ($#arg>=0); | ||
41 | $src = $arg[$#arg-1] if ($#arg>=1); | ||
42 | if ($dst =~ m/^%/o) { $suffix=&opsize($dst); } | ||
43 | elsif ($src =~ m/^%/o) { $suffix=&opsize($src); } | ||
44 | else { $suffix="l"; } | ||
45 | undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o); | ||
46 | |||
47 | if ($#_==0) { &::emit($opcode); } | ||
48 | elsif ($opcode =~ m/^j/o && $#_==1) { &::emit($opcode,@arg); } | ||
49 | elsif ($opcode eq "call" && $#_==1) { &::emit($opcode,@arg); } | ||
50 | elsif ($opcode =~ m/^set/&& $#_==1) { &::emit($opcode,@arg); } | ||
51 | else { &::emit($opcode.$suffix,@arg);} | ||
52 | |||
53 | 1; | ||
54 | } | ||
55 | # | ||
56 | # opcodes not covered by ::generic above, mostly inconsistent namings... | ||
57 | # | ||
58 | sub ::movzx { &::movzb(@_); } | ||
59 | sub ::pushfd { &::pushfl; } | ||
60 | sub ::popfd { &::popfl; } | ||
61 | sub ::cpuid { &::emit(".byte\t0x0f,0xa2"); } | ||
62 | sub ::rdtsc { &::emit(".byte\t0x0f,0x31"); } | ||
63 | |||
64 | sub ::call { &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); } | ||
65 | sub ::call_ptr { &::generic("call","*$_[0]"); } | ||
66 | sub ::jmp_ptr { &::generic("jmp","*$_[0]"); } | ||
67 | |||
68 | *::bswap = sub { &::emit("bswap","%$_[0]"); } if (!$::i386); | ||
69 | |||
70 | sub ::DWP | ||
71 | { my($addr,$reg1,$reg2,$idx)=@_; | ||
72 | my $ret=""; | ||
73 | |||
74 | $addr =~ s/^\s+//; | ||
75 | # prepend global references with optional underscore | ||
76 | $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige; | ||
77 | |||
78 | $reg1 = "%$reg1" if ($reg1); | ||
79 | $reg2 = "%$reg2" if ($reg2); | ||
80 | |||
81 | $ret .= $addr if (($addr ne "") && ($addr ne 0)); | ||
82 | |||
83 | if ($reg2) | ||
84 | { $idx!= 0 or $idx=1; | ||
85 | $ret .= "($reg1,$reg2,$idx)"; | ||
86 | } | ||
87 | elsif ($reg1) | ||
88 | { $ret .= "($reg1)"; } | ||
89 | |||
90 | $ret; | ||
91 | } | ||
92 | sub ::QWP { &::DWP(@_); } | ||
93 | sub ::BP { &::DWP(@_); } | ||
94 | sub ::BC { @_; } | ||
95 | sub ::DWC { @_; } | ||
96 | |||
97 | sub ::file | ||
98 | { push(@out,".file\t\"$_[0].s\"\n.text\n"); } | ||
99 | |||
100 | sub ::function_begin_B | ||
101 | { my $func=shift; | ||
102 | my $global=($func !~ /^_/); | ||
103 | my $begin="${::lbdecor}_${func}_begin"; | ||
104 | |||
105 | &::LABEL($func,$global?"$begin":"$nmdecor$func"); | ||
106 | $func=$nmdecor.$func; | ||
107 | |||
108 | push(@out,".globl\t$func\n") if ($global); | ||
109 | if ($::coff) | ||
110 | { push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); } | ||
111 | elsif (($::aout and !$::pic) or $::macosx) | ||
112 | { } | ||
113 | else | ||
114 | { push(@out,".type $func,\@function\n"); } | ||
115 | push(@out,".align\t$align\n"); | ||
116 | push(@out,"$func:\n"); | ||
117 | push(@out,"$begin:\n") if ($global); | ||
118 | $::stack=4; | ||
119 | } | ||
120 | |||
121 | sub ::function_end_B | ||
122 | { my $func=shift; | ||
123 | push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf); | ||
124 | $::stack=0; | ||
125 | &::wipe_labels(); | ||
126 | } | ||
127 | |||
128 | sub ::comment | ||
129 | { | ||
130 | if (!defined($com_start) or $::elf) | ||
131 | { # Regarding $::elf above... | ||
132 | # GNU and SVR4 as'es use different comment delimiters, | ||
133 | push(@out,"\n"); # so we just skip ELF comments... | ||
134 | return; | ||
135 | } | ||
136 | foreach (@_) | ||
137 | { | ||
138 | if (/^\s*$/) | ||
139 | { push(@out,"\n"); } | ||
140 | else | ||
141 | { push(@out,"\t$com_start $_ $com_end\n"); } | ||
142 | } | ||
143 | } | ||
144 | |||
145 | sub ::external_label | ||
146 | { foreach(@_) { &::LABEL($_,$nmdecor.$_); } } | ||
147 | |||
148 | sub ::public_label | ||
149 | { push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n"); } | ||
150 | |||
151 | sub ::file_end | ||
152 | { if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) { | ||
153 | my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,4"; | ||
154 | if ($::elf) { push (@out,"$tmp,4\n"); } | ||
155 | else { push (@out,"$tmp\n"); } | ||
156 | } | ||
157 | if ($::macosx) | ||
158 | { if (%non_lazy_ptr) | ||
159 | { push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n"); | ||
160 | foreach $i (keys %non_lazy_ptr) | ||
161 | { push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n"); } | ||
162 | } | ||
163 | } | ||
164 | push(@out,$initseg) if ($initseg); | ||
165 | } | ||
166 | |||
167 | sub ::data_byte { push(@out,".byte\t".join(',',@_)."\n"); } | ||
168 | sub ::data_word { push(@out,".long\t".join(',',@_)."\n"); } | ||
169 | |||
170 | sub ::align | ||
171 | { my $val=$_[0],$p2,$i; | ||
172 | if ($::aout) | ||
173 | { for ($p2=0;$val!=0;$val>>=1) { $p2++; } | ||
174 | $val=$p2-1; | ||
175 | $val.=",0x90"; | ||
176 | } | ||
177 | push(@out,".align\t$val\n"); | ||
178 | } | ||
179 | |||
180 | sub ::picmeup | ||
181 | { my($dst,$sym,$base,$reflabel)=@_; | ||
182 | |||
183 | if ($::pic && ($::elf || $::aout)) | ||
184 | { if (!defined($base)) | ||
185 | { &::call(&::label("PIC_me_up")); | ||
186 | &::set_label("PIC_me_up"); | ||
187 | &::blindpop($dst); | ||
188 | $base=$dst; | ||
189 | $reflabel=&::label("PIC_me_up"); | ||
190 | } | ||
191 | if ($::macosx) | ||
192 | { my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr"); | ||
193 | &::mov($dst,&::DWP("$indirect-$reflabel",$base)); | ||
194 | $non_lazy_ptr{"$nmdecor$sym"}=$indirect; | ||
195 | } | ||
196 | else | ||
197 | { &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]", | ||
198 | $base)); | ||
199 | &::mov($dst,&::DWP("$sym\@GOT",$dst)); | ||
200 | } | ||
201 | } | ||
202 | else | ||
203 | { &::lea($dst,&::DWP($sym)); } | ||
204 | } | ||
205 | |||
206 | sub ::initseg | ||
207 | { my $f=$nmdecor.shift; | ||
208 | |||
209 | if ($::elf) | ||
210 | { $initseg.=<<___; | ||
211 | .section .init | ||
212 | call $f | ||
213 | jmp .Linitalign | ||
214 | .align $align | ||
215 | .Linitalign: | ||
216 | ___ | ||
217 | } | ||
218 | elsif ($::coff) | ||
219 | { $initseg.=<<___; # applies to both Cygwin and Mingw | ||
220 | .section .ctors | ||
221 | .long $f | ||
222 | ___ | ||
223 | } | ||
224 | elsif ($::macosx) | ||
225 | { $initseg.=<<___; | ||
226 | .mod_init_func | ||
227 | .align 2 | ||
228 | .long $f | ||
229 | ___ | ||
230 | } | ||
231 | elsif ($::aout) | ||
232 | { my $ctor="${nmdecor}_GLOBAL_\$I\$$f"; | ||
233 | $initseg.=".text\n"; | ||
234 | $initseg.=".type $ctor,\@function\n" if ($::pic); | ||
235 | $initseg.=<<___; # OpenBSD way... | ||
236 | .globl $ctor | ||
237 | .align 2 | ||
238 | $ctor: | ||
239 | jmp $f | ||
240 | ___ | ||
241 | } | ||
242 | } | ||
243 | |||
244 | sub ::dataseg | ||
245 | { push(@out,".data\n"); } | ||
246 | |||
247 | 1; | ||
diff --git a/src/lib/libcrypto/pkcs7/bio_pk7.c b/src/lib/libcrypto/pkcs7/bio_pk7.c new file mode 100644 index 0000000000..c8d06d6cdc --- /dev/null +++ b/src/lib/libcrypto/pkcs7/bio_pk7.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* bio_pk7.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | */ | ||
54 | |||
55 | #include <openssl/asn1.h> | ||
56 | #include <openssl/pkcs7.h> | ||
57 | #include <openssl/bio.h> | ||
58 | |||
59 | #ifndef OPENSSL_SYSNAME_NETWARE | ||
60 | #include <memory.h> | ||
61 | #endif | ||
62 | #include <stdio.h> | ||
63 | |||
64 | /* Streaming encode support for PKCS#7 */ | ||
65 | |||
66 | BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7) | ||
67 | { | ||
68 | return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7)); | ||
69 | } | ||
diff --git a/src/lib/libcrypto/ppccpuid.pl b/src/lib/libcrypto/ppccpuid.pl index fe44ff07bc..369e1d0df9 100755 --- a/src/lib/libcrypto/ppccpuid.pl +++ b/src/lib/libcrypto/ppccpuid.pl | |||
@@ -67,6 +67,8 @@ Loop: lwarx r5,0,r3 | |||
67 | $CMPLI r4,7 | 67 | $CMPLI r4,7 |
68 | li r0,0 | 68 | li r0,0 |
69 | bge Lot | 69 | bge Lot |
70 | $CMPLI r4,0 | ||
71 | beqlr- | ||
70 | Little: mtctr r4 | 72 | Little: mtctr r4 |
71 | stb r0,0(r3) | 73 | stb r0,0(r3) |
72 | addi r3,r3,1 | 74 | addi r3,r3,1 |
diff --git a/src/lib/libcrypto/rc4/asm/rc4-ia64.pl b/src/lib/libcrypto/rc4/asm/rc4-ia64.pl new file mode 100644 index 0000000000..49cd5b5e69 --- /dev/null +++ b/src/lib/libcrypto/rc4/asm/rc4-ia64.pl | |||
@@ -0,0 +1,755 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by David Mosberger <David.Mosberger@acm.org> based on the | ||
5 | # Itanium optimized Crypto code which was released by HP Labs at | ||
6 | # http://www.hpl.hp.com/research/linux/crypto/. | ||
7 | # | ||
8 | # Copyright (c) 2005 Hewlett-Packard Development Company, L.P. | ||
9 | # | ||
10 | # Permission is hereby granted, free of charge, to any person obtaining | ||
11 | # a copy of this software and associated documentation files (the | ||
12 | # "Software"), to deal in the Software without restriction, including | ||
13 | # without limitation the rights to use, copy, modify, merge, publish, | ||
14 | # distribute, sublicense, and/or sell copies of the Software, and to | ||
15 | # permit persons to whom the Software is furnished to do so, subject to | ||
16 | # the following conditions: | ||
17 | # | ||
18 | # The above copyright notice and this permission notice shall be | ||
19 | # included in all copies or substantial portions of the Software. | ||
20 | |||
21 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
22 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
23 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
24 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
25 | # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
26 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
27 | # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ | ||
28 | |||
29 | |||
30 | |||
31 | # This is a little helper program which generates a software-pipelined | ||
32 | # for RC4 encryption. The basic algorithm looks like this: | ||
33 | # | ||
34 | # for (counter = 0; counter < len; ++counter) | ||
35 | # { | ||
36 | # in = inp[counter]; | ||
37 | # SI = S[I]; | ||
38 | # J = (SI + J) & 0xff; | ||
39 | # SJ = S[J]; | ||
40 | # T = (SI + SJ) & 0xff; | ||
41 | # S[I] = SJ, S[J] = SI; | ||
42 | # ST = S[T]; | ||
43 | # outp[counter] = in ^ ST; | ||
44 | # I = (I + 1) & 0xff; | ||
45 | # } | ||
46 | # | ||
47 | # Pipelining this loop isn't easy, because the stores to the S[] array | ||
48 | # need to be observed in the right order. The loop generated by the | ||
49 | # code below has the following pipeline diagram: | ||
50 | # | ||
51 | # cycle | ||
52 | # | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 | | ||
53 | # iter | ||
54 | # 1: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx | ||
55 | # 2: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx | ||
56 | # 3: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx | ||
57 | # | ||
58 | # where: | ||
59 | # LDI = load of S[I] | ||
60 | # LDJ = load of S[J] | ||
61 | # SWP = swap of S[I] and S[J] | ||
62 | # LDT = load of S[T] | ||
63 | # | ||
64 | # Note that in the above diagram, the major trouble-spot is that LDI | ||
65 | # of the 2nd iteration is performed BEFORE the SWP of the first | ||
66 | # iteration. Fortunately, this is easy to detect (I of the 1st | ||
67 | # iteration will be equal to J of the 2nd iteration) and when this | ||
68 | # happens, we simply forward the proper value from the 1st iteration | ||
69 | # to the 2nd one. The proper value in this case is simply the value | ||
70 | # of S[I] from the first iteration (thanks to the fact that SWP | ||
71 | # simply swaps the contents of S[I] and S[J]). | ||
72 | # | ||
73 | # Another potential trouble-spot is in cycle 7, where SWP of the 1st | ||
74 | # iteration issues at the same time as the LDI of the 3rd iteration. | ||
75 | # However, thanks to IA-64 execution semantics, this can be taken | ||
76 | # care of simply by placing LDI later in the instruction-group than | ||
77 | # SWP. IA-64 CPUs will automatically forward the value if they | ||
78 | # detect that the SWP and LDI are accessing the same memory-location. | ||
79 | |||
80 | # The core-loop that can be pipelined then looks like this (annotated | ||
81 | # with McKinley/Madison issue port & latency numbers, assuming L1 | ||
82 | # cache hits for the most part): | ||
83 | |||
84 | # operation: instruction: issue-ports: latency | ||
85 | # ------------------ ----------------------------- ------------- ------- | ||
86 | |||
87 | # Data = *inp++ ld1 data = [inp], 1 M0-M1 1 cyc c0 | ||
88 | # shladd Iptr = I, KeyTable, 3 M0-M3, I0, I1 1 cyc | ||
89 | # I = (I + 1) & 0xff padd1 nextI = I, one M0-M3, I0, I1 3 cyc | ||
90 | # ;; | ||
91 | # SI = S[I] ld8 SI = [Iptr] M0-M1 1 cyc c1 * after SWAP! | ||
92 | # ;; | ||
93 | # cmp.eq.unc pBypass = I, J * after J is valid! | ||
94 | # J = SI + J add J = J, SI M0-M3, I0, I1 1 cyc c2 | ||
95 | # (pBypass) br.cond.spnt Bypass | ||
96 | # ;; | ||
97 | # --------------------------------------------------------------------------------------- | ||
98 | # J = J & 0xff zxt1 J = J I0, I1, 1 cyc c3 | ||
99 | # ;; | ||
100 | # shladd Jptr = J, KeyTable, 3 M0-M3, I0, I1 1 cyc c4 | ||
101 | # ;; | ||
102 | # SJ = S[J] ld8 SJ = [Jptr] M0-M1 1 cyc c5 | ||
103 | # ;; | ||
104 | # --------------------------------------------------------------------------------------- | ||
105 | # T = (SI + SJ) add T = SI, SJ M0-M3, I0, I1 1 cyc c6 | ||
106 | # ;; | ||
107 | # T = T & 0xff zxt1 T = T I0, I1 1 cyc | ||
108 | # S[I] = SJ st8 [Iptr] = SJ M2-M3 c7 | ||
109 | # S[J] = SI st8 [Jptr] = SI M2-M3 | ||
110 | # ;; | ||
111 | # shladd Tptr = T, KeyTable, 3 M0-M3, I0, I1 1 cyc c8 | ||
112 | # ;; | ||
113 | # --------------------------------------------------------------------------------------- | ||
114 | # T = S[T] ld8 T = [Tptr] M0-M1 1 cyc c9 | ||
115 | # ;; | ||
116 | # data ^= T xor data = data, T M0-M3, I0, I1 1 cyc c10 | ||
117 | # ;; | ||
118 | # *out++ = Data ^ T dep word = word, data, 8, POS I0, I1 1 cyc c11 | ||
119 | # ;; | ||
120 | # --------------------------------------------------------------------------------------- | ||
121 | |||
122 | # There are several points worth making here: | ||
123 | |||
124 | # - Note that due to the bypass/forwarding-path, the first two | ||
125 | # phases of the loop are strangly mingled together. In | ||
126 | # particular, note that the first stage of the pipeline is | ||
127 | # using the value of "J", as calculated by the second stage. | ||
128 | # - Each bundle-pair will have exactly 6 instructions. | ||
129 | # - Pipelined, the loop can execute in 3 cycles/iteration and | ||
130 | # 4 stages. However, McKinley/Madison can issue "st1" to | ||
131 | # the same bank at a rate of at most one per 4 cycles. Thus, | ||
132 | # instead of storing each byte, we accumulate them in a word | ||
133 | # and then write them back at once with a single "st8" (this | ||
134 | # implies that the setup code needs to ensure that the output | ||
135 | # buffer is properly aligned, if need be, by encoding the | ||
136 | # first few bytes separately). | ||
137 | # - There is no space for a "br.ctop" instruction. For this | ||
138 | # reason we can't use module-loop support in IA-64 and have | ||
139 | # to do a traditional, purely software-pipelined loop. | ||
140 | # - We can't replace any of the remaining "add/zxt1" pairs with | ||
141 | # "padd1" because the latency for that instruction is too high | ||
142 | # and would push the loop to the point where more bypasses | ||
143 | # would be needed, which we don't have space for. | ||
144 | # - The above loop runs at around 3.26 cycles/byte, or roughly | ||
145 | # 440 MByte/sec on a 1.5GHz Madison. This is well below the | ||
146 | # system bus bandwidth and hence with judicious use of | ||
147 | # "lfetch" this loop can run at (almost) peak speed even when | ||
148 | # the input and output data reside in memory. The | ||
149 | # max. latency that can be tolerated is (PREFETCH_DISTANCE * | ||
150 | # L2_LINE_SIZE * 3 cyc), or about 384 cycles assuming (at | ||
151 | # least) 1-ahead prefetching of 128 byte cache-lines. Note | ||
152 | # that we do NOT prefetch into L1, since that would only | ||
153 | # interfere with the S[] table values stored there. This is | ||
154 | # acceptable because there is a 10 cycle latency between | ||
155 | # load and first use of the input data. | ||
156 | # - We use a branch to out-of-line bypass-code of cycle-pressure: | ||
157 | # we calculate the next J, check for the need to activate the | ||
158 | # bypass path, and activate the bypass path ALL IN THE SAME | ||
159 | # CYCLE. If we didn't have these constraints, we could do | ||
160 | # the bypass with a simple conditional move instruction. | ||
161 | # Fortunately, the bypass paths get activated relatively | ||
162 | # infrequently, so the extra branches don't cost all that much | ||
163 | # (about 0.04 cycles/byte, measured on a 16396 byte file with | ||
164 | # random input data). | ||
165 | # | ||
166 | |||
167 | $phases = 4; # number of stages/phases in the pipelined-loop | ||
168 | $unroll_count = 6; # number of times we unrolled it | ||
169 | $pComI = (1 << 0); | ||
170 | $pComJ = (1 << 1); | ||
171 | $pComT = (1 << 2); | ||
172 | $pOut = (1 << 3); | ||
173 | |||
174 | $NData = 4; | ||
175 | $NIP = 3; | ||
176 | $NJP = 2; | ||
177 | $NI = 2; | ||
178 | $NSI = 3; | ||
179 | $NSJ = 2; | ||
180 | $NT = 2; | ||
181 | $NOutWord = 2; | ||
182 | |||
183 | # | ||
184 | # $threshold is the minimum length before we attempt to use the | ||
185 | # big software-pipelined loop. It MUST be greater-or-equal | ||
186 | # to: | ||
187 | # PHASES * (UNROLL_COUNT + 1) + 7 | ||
188 | # | ||
189 | # The "+ 7" comes from the fact we may have to encode up to | ||
190 | # 7 bytes separately before the output pointer is aligned. | ||
191 | # | ||
192 | $threshold = (3 * ($phases * ($unroll_count + 1)) + 7); | ||
193 | |||
194 | sub I { | ||
195 | local *code = shift; | ||
196 | local $format = shift; | ||
197 | $code .= sprintf ("\t\t".$format."\n", @_); | ||
198 | } | ||
199 | |||
200 | sub P { | ||
201 | local *code = shift; | ||
202 | local $format = shift; | ||
203 | $code .= sprintf ($format."\n", @_); | ||
204 | } | ||
205 | |||
206 | sub STOP { | ||
207 | local *code = shift; | ||
208 | $code .=<<___; | ||
209 | ;; | ||
210 | ___ | ||
211 | } | ||
212 | |||
213 | sub emit_body { | ||
214 | local *c = shift; | ||
215 | local *bypass = shift; | ||
216 | local ($iteration, $p) = @_; | ||
217 | |||
218 | local $i0 = $iteration; | ||
219 | local $i1 = $iteration - 1; | ||
220 | local $i2 = $iteration - 2; | ||
221 | local $i3 = $iteration - 3; | ||
222 | local $iw0 = ($iteration - 3) / 8; | ||
223 | local $iw1 = ($iteration > 3) ? ($iteration - 4) / 8 : 1; | ||
224 | local $byte_num = ($iteration - 3) % 8; | ||
225 | local $label = $iteration + 1; | ||
226 | local $pAny = ($p & 0xf) == 0xf; | ||
227 | local $pByp = (($p & $pComI) && ($iteration > 0)); | ||
228 | |||
229 | $c.=<<___; | ||
230 | ////////////////////////////////////////////////// | ||
231 | ___ | ||
232 | |||
233 | if (($p & 0xf) == 0) { | ||
234 | $c.="#ifdef HOST_IS_BIG_ENDIAN\n"; | ||
235 | &I(\$c,"shr.u OutWord[%u] = OutWord[%u], 32;;", | ||
236 | $iw1 % $NOutWord, $iw1 % $NOutWord); | ||
237 | $c.="#endif\n"; | ||
238 | &I(\$c, "st4 [OutPtr] = OutWord[%u], 4", $iw1 % $NOutWord); | ||
239 | return; | ||
240 | } | ||
241 | |||
242 | # Cycle 0 | ||
243 | &I(\$c, "{ .mmi") if ($pAny); | ||
244 | &I(\$c, "ld1 Data[%u] = [InPtr], 1", $i0 % $NData) if ($p & $pComI); | ||
245 | &I(\$c, "padd1 I[%u] = One, I[%u]", $i0 % $NI, $i1 % $NI)if ($p & $pComI); | ||
246 | &I(\$c, "zxt1 J = J") if ($p & $pComJ); | ||
247 | &I(\$c, "}") if ($pAny); | ||
248 | &I(\$c, "{ .mmi") if ($pAny); | ||
249 | &I(\$c, "LKEY T[%u] = [T[%u]]", $i1 % $NT, $i1 % $NT) if ($p & $pOut); | ||
250 | &I(\$c, "add T[%u] = SI[%u], SJ[%u]", | ||
251 | $i0 % $NT, $i2 % $NSI, $i1 % $NSJ) if ($p & $pComT); | ||
252 | &I(\$c, "KEYADDR(IPr[%u], I[%u])", $i0 % $NIP, $i1 % $NI) if ($p & $pComI); | ||
253 | &I(\$c, "}") if ($pAny); | ||
254 | &STOP(\$c); | ||
255 | |||
256 | # Cycle 1 | ||
257 | &I(\$c, "{ .mmi") if ($pAny); | ||
258 | &I(\$c, "SKEY [IPr[%u]] = SJ[%u]", $i2 % $NIP, $i1%$NSJ)if ($p & $pComT); | ||
259 | &I(\$c, "SKEY [JP[%u]] = SI[%u]", $i1 % $NJP, $i2%$NSI) if ($p & $pComT); | ||
260 | &I(\$c, "zxt1 T[%u] = T[%u]", $i0 % $NT, $i0 % $NT) if ($p & $pComT); | ||
261 | &I(\$c, "}") if ($pAny); | ||
262 | &I(\$c, "{ .mmi") if ($pAny); | ||
263 | &I(\$c, "LKEY SI[%u] = [IPr[%u]]", $i0 % $NSI, $i0%$NIP)if ($p & $pComI); | ||
264 | &I(\$c, "KEYADDR(JP[%u], J)", $i0 % $NJP) if ($p & $pComJ); | ||
265 | &I(\$c, "xor Data[%u] = Data[%u], T[%u]", | ||
266 | $i3 % $NData, $i3 % $NData, $i1 % $NT) if ($p & $pOut); | ||
267 | &I(\$c, "}") if ($pAny); | ||
268 | &STOP(\$c); | ||
269 | |||
270 | # Cycle 2 | ||
271 | &I(\$c, "{ .mmi") if ($pAny); | ||
272 | &I(\$c, "LKEY SJ[%u] = [JP[%u]]", $i0 % $NSJ, $i0%$NJP) if ($p & $pComJ); | ||
273 | &I(\$c, "cmp.eq pBypass, p0 = I[%u], J", $i1 % $NI) if ($pByp); | ||
274 | &I(\$c, "dep OutWord[%u] = Data[%u], OutWord[%u], BYTE_POS(%u), 8", | ||
275 | $iw0%$NOutWord, $i3%$NData, $iw1%$NOutWord, $byte_num) if ($p & $pOut); | ||
276 | &I(\$c, "}") if ($pAny); | ||
277 | &I(\$c, "{ .mmb") if ($pAny); | ||
278 | &I(\$c, "add J = J, SI[%u]", $i0 % $NSI) if ($p & $pComI); | ||
279 | &I(\$c, "KEYADDR(T[%u], T[%u])", $i0 % $NT, $i0 % $NT) if ($p & $pComT); | ||
280 | &P(\$c, "(pBypass)\tbr.cond.spnt.many .rc4Bypass%u",$label)if ($pByp); | ||
281 | &I(\$c, "}") if ($pAny); | ||
282 | &STOP(\$c); | ||
283 | |||
284 | &P(\$c, ".rc4Resume%u:", $label) if ($pByp); | ||
285 | if ($byte_num == 0 && $iteration >= $phases) { | ||
286 | &I(\$c, "st8 [OutPtr] = OutWord[%u], 8", | ||
287 | $iw1 % $NOutWord) if ($p & $pOut); | ||
288 | if ($iteration == (1 + $unroll_count) * $phases - 1) { | ||
289 | if ($unroll_count == 6) { | ||
290 | &I(\$c, "mov OutWord[%u] = OutWord[%u]", | ||
291 | $iw1 % $NOutWord, $iw0 % $NOutWord); | ||
292 | } | ||
293 | &I(\$c, "lfetch.nt1 [InPrefetch], %u", | ||
294 | $unroll_count * $phases); | ||
295 | &I(\$c, "lfetch.excl.nt1 [OutPrefetch], %u", | ||
296 | $unroll_count * $phases); | ||
297 | &I(\$c, "br.cloop.sptk.few .rc4Loop"); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | if ($pByp) { | ||
302 | &P(\$bypass, ".rc4Bypass%u:", $label); | ||
303 | &I(\$bypass, "sub J = J, SI[%u]", $i0 % $NSI); | ||
304 | &I(\$bypass, "nop 0"); | ||
305 | &I(\$bypass, "nop 0"); | ||
306 | &I(\$bypass, ";;"); | ||
307 | &I(\$bypass, "add J = J, SI[%u]", $i1 % $NSI); | ||
308 | &I(\$bypass, "mov SI[%u] = SI[%u]", $i0 % $NSI, $i1 % $NSI); | ||
309 | &I(\$bypass, "br.sptk.many .rc4Resume%u\n", $label); | ||
310 | &I(\$bypass, ";;"); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | $code=<<___; | ||
315 | .ident \"rc4-ia64.s, version 3.0\" | ||
316 | .ident \"Copyright (c) 2005 Hewlett-Packard Development Company, L.P.\" | ||
317 | |||
318 | #define LCSave r8 | ||
319 | #define PRSave r9 | ||
320 | |||
321 | /* Inputs become invalid once rotation begins! */ | ||
322 | |||
323 | #define StateTable in0 | ||
324 | #define DataLen in1 | ||
325 | #define InputBuffer in2 | ||
326 | #define OutputBuffer in3 | ||
327 | |||
328 | #define KTable r14 | ||
329 | #define J r15 | ||
330 | #define InPtr r16 | ||
331 | #define OutPtr r17 | ||
332 | #define InPrefetch r18 | ||
333 | #define OutPrefetch r19 | ||
334 | #define One r20 | ||
335 | #define LoopCount r21 | ||
336 | #define Remainder r22 | ||
337 | #define IFinal r23 | ||
338 | #define EndPtr r24 | ||
339 | |||
340 | #define tmp0 r25 | ||
341 | #define tmp1 r26 | ||
342 | |||
343 | #define pBypass p6 | ||
344 | #define pDone p7 | ||
345 | #define pSmall p8 | ||
346 | #define pAligned p9 | ||
347 | #define pUnaligned p10 | ||
348 | |||
349 | #define pComputeI pPhase[0] | ||
350 | #define pComputeJ pPhase[1] | ||
351 | #define pComputeT pPhase[2] | ||
352 | #define pOutput pPhase[3] | ||
353 | |||
354 | #define RetVal r8 | ||
355 | #define L_OK p7 | ||
356 | #define L_NOK p8 | ||
357 | |||
358 | #define _NINPUTS 4 | ||
359 | #define _NOUTPUT 0 | ||
360 | |||
361 | #define _NROTATE 24 | ||
362 | #define _NLOCALS (_NROTATE - _NINPUTS - _NOUTPUT) | ||
363 | |||
364 | #ifndef SZ | ||
365 | # define SZ 4 // this must be set to sizeof(RC4_INT) | ||
366 | #endif | ||
367 | |||
368 | #if SZ == 1 | ||
369 | # define LKEY ld1 | ||
370 | # define SKEY st1 | ||
371 | # define KEYADDR(dst, i) add dst = i, KTable | ||
372 | #elif SZ == 2 | ||
373 | # define LKEY ld2 | ||
374 | # define SKEY st2 | ||
375 | # define KEYADDR(dst, i) shladd dst = i, 1, KTable | ||
376 | #elif SZ == 4 | ||
377 | # define LKEY ld4 | ||
378 | # define SKEY st4 | ||
379 | # define KEYADDR(dst, i) shladd dst = i, 2, KTable | ||
380 | #else | ||
381 | # define LKEY ld8 | ||
382 | # define SKEY st8 | ||
383 | # define KEYADDR(dst, i) shladd dst = i, 3, KTable | ||
384 | #endif | ||
385 | |||
386 | #if defined(_HPUX_SOURCE) && !defined(_LP64) | ||
387 | # define ADDP addp4 | ||
388 | #else | ||
389 | # define ADDP add | ||
390 | #endif | ||
391 | |||
392 | /* Define a macro for the bit number of the n-th byte: */ | ||
393 | |||
394 | #if defined(_HPUX_SOURCE) || defined(B_ENDIAN) | ||
395 | # define HOST_IS_BIG_ENDIAN | ||
396 | # define BYTE_POS(n) (56 - (8 * (n))) | ||
397 | #else | ||
398 | # define BYTE_POS(n) (8 * (n)) | ||
399 | #endif | ||
400 | |||
401 | /* | ||
402 | We must perform the first phase of the pipeline explicitly since | ||
403 | we will always load from the stable the first time. The br.cexit | ||
404 | will never be taken since regardless of the number of bytes because | ||
405 | the epilogue count is 4. | ||
406 | */ | ||
407 | /* MODSCHED_RC4 macro was split to _PROLOGUE and _LOOP, because HP-UX | ||
408 | assembler failed on original macro with syntax error. <appro> */ | ||
409 | #define MODSCHED_RC4_PROLOGUE \\ | ||
410 | { \\ | ||
411 | ld1 Data[0] = [InPtr], 1; \\ | ||
412 | add IFinal = 1, I[1]; \\ | ||
413 | KEYADDR(IPr[0], I[1]); \\ | ||
414 | } ;; \\ | ||
415 | { \\ | ||
416 | LKEY SI[0] = [IPr[0]]; \\ | ||
417 | mov pr.rot = 0x10000; \\ | ||
418 | mov ar.ec = 4; \\ | ||
419 | } ;; \\ | ||
420 | { \\ | ||
421 | add J = J, SI[0]; \\ | ||
422 | zxt1 I[0] = IFinal; \\ | ||
423 | br.cexit.spnt.few .+16; /* never taken */ \\ | ||
424 | } ;; | ||
425 | #define MODSCHED_RC4_LOOP(label) \\ | ||
426 | label: \\ | ||
427 | { .mmi; \\ | ||
428 | (pComputeI) ld1 Data[0] = [InPtr], 1; \\ | ||
429 | (pComputeI) add IFinal = 1, I[1]; \\ | ||
430 | (pComputeJ) zxt1 J = J; \\ | ||
431 | }{ .mmi; \\ | ||
432 | (pOutput) LKEY T[1] = [T[1]]; \\ | ||
433 | (pComputeT) add T[0] = SI[2], SJ[1]; \\ | ||
434 | (pComputeI) KEYADDR(IPr[0], I[1]); \\ | ||
435 | } ;; \\ | ||
436 | { .mmi; \\ | ||
437 | (pComputeT) SKEY [IPr[2]] = SJ[1]; \\ | ||
438 | (pComputeT) SKEY [JP[1]] = SI[2]; \\ | ||
439 | (pComputeT) zxt1 T[0] = T[0]; \\ | ||
440 | }{ .mmi; \\ | ||
441 | (pComputeI) LKEY SI[0] = [IPr[0]]; \\ | ||
442 | (pComputeJ) KEYADDR(JP[0], J); \\ | ||
443 | (pComputeI) cmp.eq.unc pBypass, p0 = I[1], J; \\ | ||
444 | } ;; \\ | ||
445 | { .mmi; \\ | ||
446 | (pComputeJ) LKEY SJ[0] = [JP[0]]; \\ | ||
447 | (pOutput) xor Data[3] = Data[3], T[1]; \\ | ||
448 | nop 0x0; \\ | ||
449 | }{ .mmi; \\ | ||
450 | (pComputeT) KEYADDR(T[0], T[0]); \\ | ||
451 | (pBypass) mov SI[0] = SI[1]; \\ | ||
452 | (pComputeI) zxt1 I[0] = IFinal; \\ | ||
453 | } ;; \\ | ||
454 | { .mmb; \\ | ||
455 | (pOutput) st1 [OutPtr] = Data[3], 1; \\ | ||
456 | (pComputeI) add J = J, SI[0]; \\ | ||
457 | br.ctop.sptk.few label; \\ | ||
458 | } ;; | ||
459 | |||
460 | .text | ||
461 | |||
462 | .align 32 | ||
463 | |||
464 | .type RC4, \@function | ||
465 | .global RC4 | ||
466 | |||
467 | .proc RC4 | ||
468 | .prologue | ||
469 | |||
470 | RC4: | ||
471 | { | ||
472 | .mmi | ||
473 | alloc r2 = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE | ||
474 | |||
475 | .rotr Data[4], I[2], IPr[3], SI[3], JP[2], SJ[2], T[2], \\ | ||
476 | OutWord[2] | ||
477 | .rotp pPhase[4] | ||
478 | |||
479 | ADDP InPrefetch = 0, InputBuffer | ||
480 | ADDP KTable = 0, StateTable | ||
481 | } | ||
482 | { | ||
483 | .mmi | ||
484 | ADDP InPtr = 0, InputBuffer | ||
485 | ADDP OutPtr = 0, OutputBuffer | ||
486 | mov RetVal = r0 | ||
487 | } | ||
488 | ;; | ||
489 | { | ||
490 | .mmi | ||
491 | lfetch.nt1 [InPrefetch], 0x80 | ||
492 | ADDP OutPrefetch = 0, OutputBuffer | ||
493 | } | ||
494 | { // Return 0 if the input length is nonsensical | ||
495 | .mib | ||
496 | ADDP StateTable = 0, StateTable | ||
497 | cmp.ge.unc L_NOK, L_OK = r0, DataLen | ||
498 | (L_NOK) br.ret.sptk.few rp | ||
499 | } | ||
500 | ;; | ||
501 | { | ||
502 | .mib | ||
503 | cmp.eq.or L_NOK, L_OK = r0, InPtr | ||
504 | cmp.eq.or L_NOK, L_OK = r0, OutPtr | ||
505 | nop 0x0 | ||
506 | } | ||
507 | { | ||
508 | .mib | ||
509 | cmp.eq.or L_NOK, L_OK = r0, StateTable | ||
510 | nop 0x0 | ||
511 | (L_NOK) br.ret.sptk.few rp | ||
512 | } | ||
513 | ;; | ||
514 | LKEY I[1] = [KTable], SZ | ||
515 | /* Prefetch the state-table. It contains 256 elements of size SZ */ | ||
516 | |||
517 | #if SZ == 1 | ||
518 | ADDP tmp0 = 1*128, StateTable | ||
519 | #elif SZ == 2 | ||
520 | ADDP tmp0 = 3*128, StateTable | ||
521 | ADDP tmp1 = 2*128, StateTable | ||
522 | #elif SZ == 4 | ||
523 | ADDP tmp0 = 7*128, StateTable | ||
524 | ADDP tmp1 = 6*128, StateTable | ||
525 | #elif SZ == 8 | ||
526 | ADDP tmp0 = 15*128, StateTable | ||
527 | ADDP tmp1 = 14*128, StateTable | ||
528 | #endif | ||
529 | ;; | ||
530 | #if SZ >= 8 | ||
531 | lfetch.fault.nt1 [tmp0], -256 // 15 | ||
532 | lfetch.fault.nt1 [tmp1], -256;; | ||
533 | lfetch.fault.nt1 [tmp0], -256 // 13 | ||
534 | lfetch.fault.nt1 [tmp1], -256;; | ||
535 | lfetch.fault.nt1 [tmp0], -256 // 11 | ||
536 | lfetch.fault.nt1 [tmp1], -256;; | ||
537 | lfetch.fault.nt1 [tmp0], -256 // 9 | ||
538 | lfetch.fault.nt1 [tmp1], -256;; | ||
539 | #endif | ||
540 | #if SZ >= 4 | ||
541 | lfetch.fault.nt1 [tmp0], -256 // 7 | ||
542 | lfetch.fault.nt1 [tmp1], -256;; | ||
543 | lfetch.fault.nt1 [tmp0], -256 // 5 | ||
544 | lfetch.fault.nt1 [tmp1], -256;; | ||
545 | #endif | ||
546 | #if SZ >= 2 | ||
547 | lfetch.fault.nt1 [tmp0], -256 // 3 | ||
548 | lfetch.fault.nt1 [tmp1], -256;; | ||
549 | #endif | ||
550 | { | ||
551 | .mii | ||
552 | lfetch.fault.nt1 [tmp0] // 1 | ||
553 | add I[1]=1,I[1];; | ||
554 | zxt1 I[1]=I[1] | ||
555 | } | ||
556 | { | ||
557 | .mmi | ||
558 | lfetch.nt1 [InPrefetch], 0x80 | ||
559 | lfetch.excl.nt1 [OutPrefetch], 0x80 | ||
560 | .save pr, PRSave | ||
561 | mov PRSave = pr | ||
562 | } ;; | ||
563 | { | ||
564 | .mmi | ||
565 | lfetch.excl.nt1 [OutPrefetch], 0x80 | ||
566 | LKEY J = [KTable], SZ | ||
567 | ADDP EndPtr = DataLen, InPtr | ||
568 | } ;; | ||
569 | { | ||
570 | .mmi | ||
571 | ADDP EndPtr = -1, EndPtr // Make it point to | ||
572 | // last data byte. | ||
573 | mov One = 1 | ||
574 | .save ar.lc, LCSave | ||
575 | mov LCSave = ar.lc | ||
576 | .body | ||
577 | } ;; | ||
578 | { | ||
579 | .mmb | ||
580 | sub Remainder = 0, OutPtr | ||
581 | cmp.gtu pSmall, p0 = $threshold, DataLen | ||
582 | (pSmall) br.cond.dpnt .rc4Remainder // Data too small for | ||
583 | // big loop. | ||
584 | } ;; | ||
585 | { | ||
586 | .mmi | ||
587 | and Remainder = 0x7, Remainder | ||
588 | ;; | ||
589 | cmp.eq pAligned, pUnaligned = Remainder, r0 | ||
590 | nop 0x0 | ||
591 | } ;; | ||
592 | { | ||
593 | .mmb | ||
594 | .pred.rel "mutex",pUnaligned,pAligned | ||
595 | (pUnaligned) add Remainder = -1, Remainder | ||
596 | (pAligned) sub Remainder = EndPtr, InPtr | ||
597 | (pAligned) br.cond.dptk.many .rc4Aligned | ||
598 | } ;; | ||
599 | { | ||
600 | .mmi | ||
601 | nop 0x0 | ||
602 | nop 0x0 | ||
603 | mov.i ar.lc = Remainder | ||
604 | } | ||
605 | |||
606 | /* Do the initial few bytes via the compact, modulo-scheduled loop | ||
607 | until the output pointer is 8-byte-aligned. */ | ||
608 | |||
609 | MODSCHED_RC4_PROLOGUE | ||
610 | MODSCHED_RC4_LOOP(.RC4AlignLoop) | ||
611 | |||
612 | { | ||
613 | .mib | ||
614 | sub Remainder = EndPtr, InPtr | ||
615 | zxt1 IFinal = IFinal | ||
616 | clrrrb // Clear CFM.rrb.pr so | ||
617 | ;; // next "mov pr.rot = N" | ||
618 | // does the right thing. | ||
619 | } | ||
620 | { | ||
621 | .mmi | ||
622 | mov I[1] = IFinal | ||
623 | nop 0x0 | ||
624 | nop 0x0 | ||
625 | } ;; | ||
626 | |||
627 | |||
628 | .rc4Aligned: | ||
629 | |||
630 | /* | ||
631 | Unrolled loop count = (Remainder - ($unroll_count+1)*$phases)/($unroll_count*$phases) | ||
632 | */ | ||
633 | |||
634 | { | ||
635 | .mlx | ||
636 | add LoopCount = 1 - ($unroll_count + 1)*$phases, Remainder | ||
637 | movl Remainder = 0xaaaaaaaaaaaaaaab | ||
638 | } ;; | ||
639 | { | ||
640 | .mmi | ||
641 | setf.sig f6 = LoopCount // M2, M3 6 cyc | ||
642 | setf.sig f7 = Remainder // M2, M3 6 cyc | ||
643 | nop 0x0 | ||
644 | } ;; | ||
645 | { | ||
646 | .mfb | ||
647 | nop 0x0 | ||
648 | xmpy.hu f6 = f6, f7 | ||
649 | nop 0x0 | ||
650 | } ;; | ||
651 | { | ||
652 | .mmi | ||
653 | getf.sig LoopCount = f6;; // M2 5 cyc | ||
654 | nop 0x0 | ||
655 | shr.u LoopCount = LoopCount, 4 | ||
656 | } ;; | ||
657 | { | ||
658 | .mmi | ||
659 | nop 0x0 | ||
660 | nop 0x0 | ||
661 | mov.i ar.lc = LoopCount | ||
662 | } ;; | ||
663 | |||
664 | /* Now comes the unrolled loop: */ | ||
665 | |||
666 | .rc4Prologue: | ||
667 | ___ | ||
668 | |||
669 | $iteration = 0; | ||
670 | |||
671 | # Generate the prologue: | ||
672 | $predicates = 1; | ||
673 | for ($i = 0; $i < $phases; ++$i) { | ||
674 | &emit_body (\$code, \$bypass, $iteration++, $predicates); | ||
675 | $predicates = ($predicates << 1) | 1; | ||
676 | } | ||
677 | |||
678 | $code.=<<___; | ||
679 | .rc4Loop: | ||
680 | ___ | ||
681 | |||
682 | # Generate the body: | ||
683 | for ($i = 0; $i < $unroll_count*$phases; ++$i) { | ||
684 | &emit_body (\$code, \$bypass, $iteration++, $predicates); | ||
685 | } | ||
686 | |||
687 | $code.=<<___; | ||
688 | .rc4Epilogue: | ||
689 | ___ | ||
690 | |||
691 | # Generate the epilogue: | ||
692 | for ($i = 0; $i < $phases; ++$i) { | ||
693 | $predicates <<= 1; | ||
694 | &emit_body (\$code, \$bypass, $iteration++, $predicates); | ||
695 | } | ||
696 | |||
697 | $code.=<<___; | ||
698 | { | ||
699 | .mmi | ||
700 | lfetch.nt1 [EndPtr] // fetch line with last byte | ||
701 | mov IFinal = I[1] | ||
702 | nop 0x0 | ||
703 | } | ||
704 | |||
705 | .rc4Remainder: | ||
706 | { | ||
707 | .mmi | ||
708 | sub Remainder = EndPtr, InPtr // Calculate | ||
709 | // # of bytes | ||
710 | // left - 1 | ||
711 | nop 0x0 | ||
712 | nop 0x0 | ||
713 | } ;; | ||
714 | { | ||
715 | .mib | ||
716 | cmp.eq pDone, p0 = -1, Remainder // done already? | ||
717 | mov.i ar.lc = Remainder | ||
718 | (pDone) br.cond.dptk.few .rc4Complete | ||
719 | } | ||
720 | |||
721 | /* Do the remaining bytes via the compact, modulo-scheduled loop */ | ||
722 | |||
723 | MODSCHED_RC4_PROLOGUE | ||
724 | MODSCHED_RC4_LOOP(.RC4RestLoop) | ||
725 | |||
726 | .rc4Complete: | ||
727 | { | ||
728 | .mmi | ||
729 | add KTable = -SZ, KTable | ||
730 | add IFinal = -1, IFinal | ||
731 | mov ar.lc = LCSave | ||
732 | } ;; | ||
733 | { | ||
734 | .mii | ||
735 | SKEY [KTable] = J,-SZ | ||
736 | zxt1 IFinal = IFinal | ||
737 | mov pr = PRSave, 0x1FFFF | ||
738 | } ;; | ||
739 | { | ||
740 | .mib | ||
741 | SKEY [KTable] = IFinal | ||
742 | add RetVal = 1, r0 | ||
743 | br.ret.sptk.few rp | ||
744 | } ;; | ||
745 | ___ | ||
746 | |||
747 | # Last but not least, emit the code for the bypass-code of the unrolled loop: | ||
748 | |||
749 | $code.=$bypass; | ||
750 | |||
751 | $code.=<<___; | ||
752 | .endp RC4 | ||
753 | ___ | ||
754 | |||
755 | print $code; | ||
diff --git a/src/lib/libcrypto/rc4/asm/rc4-s390x.pl b/src/lib/libcrypto/rc4/asm/rc4-s390x.pl new file mode 100644 index 0000000000..96681fa05e --- /dev/null +++ b/src/lib/libcrypto/rc4/asm/rc4-s390x.pl | |||
@@ -0,0 +1,205 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | # | ||
10 | # February 2009 | ||
11 | # | ||
12 | # Performance is 2x of gcc 3.4.6 on z10. Coding "secret" is to | ||
13 | # "cluster" Address Generation Interlocks, so that one pipeline stall | ||
14 | # resolves several dependencies. | ||
15 | |||
16 | $rp="%r14"; | ||
17 | $sp="%r15"; | ||
18 | $code=<<___; | ||
19 | .text | ||
20 | |||
21 | ___ | ||
22 | |||
23 | # void RC4(RC4_KEY *key,size_t len,const void *inp,void *out) | ||
24 | { | ||
25 | $acc="%r0"; | ||
26 | $cnt="%r1"; | ||
27 | $key="%r2"; | ||
28 | $len="%r3"; | ||
29 | $inp="%r4"; | ||
30 | $out="%r5"; | ||
31 | |||
32 | @XX=("%r6","%r7"); | ||
33 | @TX=("%r8","%r9"); | ||
34 | $YY="%r10"; | ||
35 | $TY="%r11"; | ||
36 | |||
37 | $code.=<<___; | ||
38 | .globl RC4 | ||
39 | .type RC4,\@function | ||
40 | .align 64 | ||
41 | RC4: | ||
42 | stmg %r6,%r11,48($sp) | ||
43 | llgc $XX[0],0($key) | ||
44 | llgc $YY,1($key) | ||
45 | la $XX[0],1($XX[0]) | ||
46 | nill $XX[0],0xff | ||
47 | srlg $cnt,$len,3 | ||
48 | ltgr $cnt,$cnt | ||
49 | llgc $TX[0],2($XX[0],$key) | ||
50 | jz .Lshort | ||
51 | j .Loop8 | ||
52 | |||
53 | .align 64 | ||
54 | .Loop8: | ||
55 | ___ | ||
56 | for ($i=0;$i<8;$i++) { | ||
57 | $code.=<<___; | ||
58 | la $YY,0($YY,$TX[0]) # $i | ||
59 | nill $YY,255 | ||
60 | la $XX[1],1($XX[0]) | ||
61 | nill $XX[1],255 | ||
62 | ___ | ||
63 | $code.=<<___ if ($i==1); | ||
64 | llgc $acc,2($TY,$key) | ||
65 | ___ | ||
66 | $code.=<<___ if ($i>1); | ||
67 | sllg $acc,$acc,8 | ||
68 | ic $acc,2($TY,$key) | ||
69 | ___ | ||
70 | $code.=<<___; | ||
71 | llgc $TY,2($YY,$key) | ||
72 | stc $TX[0],2($YY,$key) | ||
73 | llgc $TX[1],2($XX[1],$key) | ||
74 | stc $TY,2($XX[0],$key) | ||
75 | cr $XX[1],$YY | ||
76 | jne .Lcmov$i | ||
77 | la $TX[1],0($TX[0]) | ||
78 | .Lcmov$i: | ||
79 | la $TY,0($TY,$TX[0]) | ||
80 | nill $TY,255 | ||
81 | ___ | ||
82 | push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers | ||
83 | } | ||
84 | |||
85 | $code.=<<___; | ||
86 | lg $TX[1],0($inp) | ||
87 | sllg $acc,$acc,8 | ||
88 | la $inp,8($inp) | ||
89 | ic $acc,2($TY,$key) | ||
90 | xgr $acc,$TX[1] | ||
91 | stg $acc,0($out) | ||
92 | la $out,8($out) | ||
93 | brct $cnt,.Loop8 | ||
94 | |||
95 | .Lshort: | ||
96 | lghi $acc,7 | ||
97 | ngr $len,$acc | ||
98 | jz .Lexit | ||
99 | j .Loop1 | ||
100 | |||
101 | .align 16 | ||
102 | .Loop1: | ||
103 | la $YY,0($YY,$TX[0]) | ||
104 | nill $YY,255 | ||
105 | llgc $TY,2($YY,$key) | ||
106 | stc $TX[0],2($YY,$key) | ||
107 | stc $TY,2($XX[0],$key) | ||
108 | ar $TY,$TX[0] | ||
109 | ahi $XX[0],1 | ||
110 | nill $TY,255 | ||
111 | nill $XX[0],255 | ||
112 | llgc $acc,0($inp) | ||
113 | la $inp,1($inp) | ||
114 | llgc $TY,2($TY,$key) | ||
115 | llgc $TX[0],2($XX[0],$key) | ||
116 | xr $acc,$TY | ||
117 | stc $acc,0($out) | ||
118 | la $out,1($out) | ||
119 | brct $len,.Loop1 | ||
120 | |||
121 | .Lexit: | ||
122 | ahi $XX[0],-1 | ||
123 | stc $XX[0],0($key) | ||
124 | stc $YY,1($key) | ||
125 | lmg %r6,%r11,48($sp) | ||
126 | br $rp | ||
127 | .size RC4,.-RC4 | ||
128 | .string "RC4 for s390x, CRYPTOGAMS by <appro\@openssl.org>" | ||
129 | |||
130 | ___ | ||
131 | } | ||
132 | |||
133 | # void RC4_set_key(RC4_KEY *key,unsigned int len,const void *inp) | ||
134 | { | ||
135 | $cnt="%r0"; | ||
136 | $idx="%r1"; | ||
137 | $key="%r2"; | ||
138 | $len="%r3"; | ||
139 | $inp="%r4"; | ||
140 | $acc="%r5"; | ||
141 | $dat="%r6"; | ||
142 | $ikey="%r7"; | ||
143 | $iinp="%r8"; | ||
144 | |||
145 | $code.=<<___; | ||
146 | .globl RC4_set_key | ||
147 | .type RC4_set_key,\@function | ||
148 | .align 64 | ||
149 | RC4_set_key: | ||
150 | stmg %r6,%r8,48($sp) | ||
151 | lhi $cnt,256 | ||
152 | la $idx,0(%r0) | ||
153 | sth $idx,0($key) | ||
154 | .align 4 | ||
155 | .L1stloop: | ||
156 | stc $idx,2($idx,$key) | ||
157 | la $idx,1($idx) | ||
158 | brct $cnt,.L1stloop | ||
159 | |||
160 | lghi $ikey,-256 | ||
161 | lr $cnt,$len | ||
162 | la $iinp,0(%r0) | ||
163 | la $idx,0(%r0) | ||
164 | .align 16 | ||
165 | .L2ndloop: | ||
166 | llgc $acc,2+256($ikey,$key) | ||
167 | llgc $dat,0($iinp,$inp) | ||
168 | la $idx,0($idx,$acc) | ||
169 | la $ikey,1($ikey) | ||
170 | la $idx,0($idx,$dat) | ||
171 | nill $idx,255 | ||
172 | la $iinp,1($iinp) | ||
173 | tml $ikey,255 | ||
174 | llgc $dat,2($idx,$key) | ||
175 | stc $dat,2+256-1($ikey,$key) | ||
176 | stc $acc,2($idx,$key) | ||
177 | jz .Ldone | ||
178 | brct $cnt,.L2ndloop | ||
179 | lr $cnt,$len | ||
180 | la $iinp,0(%r0) | ||
181 | j .L2ndloop | ||
182 | .Ldone: | ||
183 | lmg %r6,%r8,48($sp) | ||
184 | br $rp | ||
185 | .size RC4_set_key,.-RC4_set_key | ||
186 | |||
187 | ___ | ||
188 | } | ||
189 | |||
190 | # const char *RC4_options() | ||
191 | $code.=<<___; | ||
192 | .globl RC4_options | ||
193 | .type RC4_options,\@function | ||
194 | .align 16 | ||
195 | RC4_options: | ||
196 | larl %r2,.Loptions | ||
197 | br %r14 | ||
198 | .size RC4_options,.-RC4_options | ||
199 | .section .rodata | ||
200 | .Loptions: | ||
201 | .align 8 | ||
202 | .string "rc4(8x,char)" | ||
203 | ___ | ||
204 | |||
205 | print $code; | ||
diff --git a/src/lib/libcrypto/rsa/rsa_ameth.c b/src/lib/libcrypto/rsa/rsa_ameth.c new file mode 100644 index 0000000000..8c3209885e --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_ameth.c | |||
@@ -0,0 +1,349 @@ | |||
1 | /* crypto/rsa/rsa_ameth.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2006. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1t.h> | ||
62 | #include <openssl/x509.h> | ||
63 | #include <openssl/rsa.h> | ||
64 | #include <openssl/bn.h> | ||
65 | #ifndef OPENSSL_NO_CMS | ||
66 | #include <openssl/cms.h> | ||
67 | #endif | ||
68 | #include "asn1_locl.h" | ||
69 | |||
70 | static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) | ||
71 | { | ||
72 | unsigned char *penc = NULL; | ||
73 | int penclen; | ||
74 | penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); | ||
75 | if (penclen <= 0) | ||
76 | return 0; | ||
77 | if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), | ||
78 | V_ASN1_NULL, NULL, penc, penclen)) | ||
79 | return 1; | ||
80 | |||
81 | OPENSSL_free(penc); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) | ||
86 | { | ||
87 | const unsigned char *p; | ||
88 | int pklen; | ||
89 | RSA *rsa = NULL; | ||
90 | if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) | ||
91 | return 0; | ||
92 | if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) | ||
93 | { | ||
94 | RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); | ||
95 | return 0; | ||
96 | } | ||
97 | EVP_PKEY_assign_RSA (pkey, rsa); | ||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) | ||
102 | { | ||
103 | if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0 | ||
104 | || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0) | ||
105 | return 0; | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | static int old_rsa_priv_decode(EVP_PKEY *pkey, | ||
110 | const unsigned char **pder, int derlen) | ||
111 | { | ||
112 | RSA *rsa; | ||
113 | if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen))) | ||
114 | { | ||
115 | RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); | ||
116 | return 0; | ||
117 | } | ||
118 | EVP_PKEY_assign_RSA(pkey, rsa); | ||
119 | return 1; | ||
120 | } | ||
121 | |||
122 | static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) | ||
123 | { | ||
124 | return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); | ||
125 | } | ||
126 | |||
127 | static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) | ||
128 | { | ||
129 | unsigned char *rk = NULL; | ||
130 | int rklen; | ||
131 | rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); | ||
132 | |||
133 | if (rklen <= 0) | ||
134 | { | ||
135 | RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0, | ||
140 | V_ASN1_NULL, NULL, rk, rklen)) | ||
141 | { | ||
142 | RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | return 1; | ||
147 | } | ||
148 | |||
149 | static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) | ||
150 | { | ||
151 | const unsigned char *p; | ||
152 | int pklen; | ||
153 | if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) | ||
154 | return 0; | ||
155 | return old_rsa_priv_decode(pkey, &p, pklen); | ||
156 | } | ||
157 | |||
158 | static int int_rsa_size(const EVP_PKEY *pkey) | ||
159 | { | ||
160 | return RSA_size(pkey->pkey.rsa); | ||
161 | } | ||
162 | |||
163 | static int rsa_bits(const EVP_PKEY *pkey) | ||
164 | { | ||
165 | return BN_num_bits(pkey->pkey.rsa->n); | ||
166 | } | ||
167 | |||
168 | static void int_rsa_free(EVP_PKEY *pkey) | ||
169 | { | ||
170 | RSA_free(pkey->pkey.rsa); | ||
171 | } | ||
172 | |||
173 | |||
174 | static void update_buflen(const BIGNUM *b, size_t *pbuflen) | ||
175 | { | ||
176 | size_t i; | ||
177 | if (!b) | ||
178 | return; | ||
179 | if (*pbuflen < (i = (size_t)BN_num_bytes(b))) | ||
180 | *pbuflen = i; | ||
181 | } | ||
182 | |||
183 | static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv) | ||
184 | { | ||
185 | char *str; | ||
186 | const char *s; | ||
187 | unsigned char *m=NULL; | ||
188 | int ret=0, mod_len = 0; | ||
189 | size_t buf_len=0; | ||
190 | |||
191 | update_buflen(x->n, &buf_len); | ||
192 | update_buflen(x->e, &buf_len); | ||
193 | |||
194 | if (priv) | ||
195 | { | ||
196 | update_buflen(x->d, &buf_len); | ||
197 | update_buflen(x->p, &buf_len); | ||
198 | update_buflen(x->q, &buf_len); | ||
199 | update_buflen(x->dmp1, &buf_len); | ||
200 | update_buflen(x->dmq1, &buf_len); | ||
201 | update_buflen(x->iqmp, &buf_len); | ||
202 | } | ||
203 | |||
204 | m=(unsigned char *)OPENSSL_malloc(buf_len+10); | ||
205 | if (m == NULL) | ||
206 | { | ||
207 | RSAerr(RSA_F_DO_RSA_PRINT,ERR_R_MALLOC_FAILURE); | ||
208 | goto err; | ||
209 | } | ||
210 | |||
211 | if (x->n != NULL) | ||
212 | mod_len = BN_num_bits(x->n); | ||
213 | |||
214 | if(!BIO_indent(bp,off,128)) | ||
215 | goto err; | ||
216 | |||
217 | if (priv && x->d) | ||
218 | { | ||
219 | if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len) | ||
220 | <= 0) goto err; | ||
221 | str = "modulus:"; | ||
222 | s = "publicExponent:"; | ||
223 | } | ||
224 | else | ||
225 | { | ||
226 | if (BIO_printf(bp,"Public-Key: (%d bit)\n", mod_len) | ||
227 | <= 0) goto err; | ||
228 | str = "Modulus:"; | ||
229 | s= "Exponent:"; | ||
230 | } | ||
231 | if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err; | ||
232 | if (!ASN1_bn_print(bp,s,x->e,m,off)) | ||
233 | goto err; | ||
234 | if (priv) | ||
235 | { | ||
236 | if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off)) | ||
237 | goto err; | ||
238 | if (!ASN1_bn_print(bp,"prime1:",x->p,m,off)) | ||
239 | goto err; | ||
240 | if (!ASN1_bn_print(bp,"prime2:",x->q,m,off)) | ||
241 | goto err; | ||
242 | if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off)) | ||
243 | goto err; | ||
244 | if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off)) | ||
245 | goto err; | ||
246 | if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off)) | ||
247 | goto err; | ||
248 | } | ||
249 | ret=1; | ||
250 | err: | ||
251 | if (m != NULL) OPENSSL_free(m); | ||
252 | return(ret); | ||
253 | } | ||
254 | |||
255 | static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
256 | ASN1_PCTX *ctx) | ||
257 | { | ||
258 | return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); | ||
259 | } | ||
260 | |||
261 | |||
262 | static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, | ||
263 | ASN1_PCTX *ctx) | ||
264 | { | ||
265 | return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); | ||
266 | } | ||
267 | |||
268 | |||
269 | static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | ||
270 | { | ||
271 | X509_ALGOR *alg = NULL; | ||
272 | switch (op) | ||
273 | { | ||
274 | |||
275 | case ASN1_PKEY_CTRL_PKCS7_SIGN: | ||
276 | if (arg1 == 0) | ||
277 | PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); | ||
278 | break; | ||
279 | |||
280 | case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: | ||
281 | if (arg1 == 0) | ||
282 | PKCS7_RECIP_INFO_get0_alg(arg2, &alg); | ||
283 | break; | ||
284 | #ifndef OPENSSL_NO_CMS | ||
285 | case ASN1_PKEY_CTRL_CMS_SIGN: | ||
286 | if (arg1 == 0) | ||
287 | CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg); | ||
288 | break; | ||
289 | |||
290 | case ASN1_PKEY_CTRL_CMS_ENVELOPE: | ||
291 | if (arg1 == 0) | ||
292 | CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg); | ||
293 | break; | ||
294 | #endif | ||
295 | |||
296 | case ASN1_PKEY_CTRL_DEFAULT_MD_NID: | ||
297 | *(int *)arg2 = NID_sha1; | ||
298 | return 1; | ||
299 | |||
300 | default: | ||
301 | return -2; | ||
302 | |||
303 | } | ||
304 | |||
305 | if (alg) | ||
306 | X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), | ||
307 | V_ASN1_NULL, 0); | ||
308 | |||
309 | return 1; | ||
310 | |||
311 | } | ||
312 | |||
313 | |||
314 | const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = | ||
315 | { | ||
316 | { | ||
317 | EVP_PKEY_RSA, | ||
318 | EVP_PKEY_RSA, | ||
319 | ASN1_PKEY_SIGPARAM_NULL, | ||
320 | |||
321 | "RSA", | ||
322 | "OpenSSL RSA method", | ||
323 | |||
324 | rsa_pub_decode, | ||
325 | rsa_pub_encode, | ||
326 | rsa_pub_cmp, | ||
327 | rsa_pub_print, | ||
328 | |||
329 | rsa_priv_decode, | ||
330 | rsa_priv_encode, | ||
331 | rsa_priv_print, | ||
332 | |||
333 | int_rsa_size, | ||
334 | rsa_bits, | ||
335 | |||
336 | 0,0,0,0,0,0, | ||
337 | |||
338 | int_rsa_free, | ||
339 | rsa_pkey_ctrl, | ||
340 | old_rsa_priv_decode, | ||
341 | old_rsa_priv_encode | ||
342 | }, | ||
343 | |||
344 | { | ||
345 | EVP_PKEY_RSA2, | ||
346 | EVP_PKEY_RSA, | ||
347 | ASN1_PKEY_ALIAS | ||
348 | } | ||
349 | }; | ||
diff --git a/src/lib/libcrypto/rsa/rsa_locl.h b/src/lib/libcrypto/rsa/rsa_locl.h new file mode 100644 index 0000000000..f5d2d56628 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_locl.h | |||
@@ -0,0 +1,4 @@ | |||
1 | extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, | ||
2 | unsigned char *rm, size_t *prm_len, | ||
3 | const unsigned char *sigbuf, size_t siglen, | ||
4 | RSA *rsa); | ||
diff --git a/src/lib/libcrypto/rsa/rsa_pmeth.c b/src/lib/libcrypto/rsa/rsa_pmeth.c new file mode 100644 index 0000000000..c6892ecd09 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_pmeth.c | |||
@@ -0,0 +1,587 @@ | |||
1 | /* crypto/rsa/rsa_pmeth.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2006. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1t.h> | ||
62 | #include <openssl/x509.h> | ||
63 | #include <openssl/rsa.h> | ||
64 | #include <openssl/bn.h> | ||
65 | #include <openssl/evp.h> | ||
66 | #include "evp_locl.h" | ||
67 | #include "rsa_locl.h" | ||
68 | |||
69 | /* RSA pkey context structure */ | ||
70 | |||
71 | typedef struct | ||
72 | { | ||
73 | /* Key gen parameters */ | ||
74 | int nbits; | ||
75 | BIGNUM *pub_exp; | ||
76 | /* Keygen callback info */ | ||
77 | int gentmp[2]; | ||
78 | /* RSA padding mode */ | ||
79 | int pad_mode; | ||
80 | /* message digest */ | ||
81 | const EVP_MD *md; | ||
82 | /* PSS/OAEP salt length */ | ||
83 | int saltlen; | ||
84 | /* Temp buffer */ | ||
85 | unsigned char *tbuf; | ||
86 | } RSA_PKEY_CTX; | ||
87 | |||
88 | static int pkey_rsa_init(EVP_PKEY_CTX *ctx) | ||
89 | { | ||
90 | RSA_PKEY_CTX *rctx; | ||
91 | rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); | ||
92 | if (!rctx) | ||
93 | return 0; | ||
94 | rctx->nbits = 1024; | ||
95 | rctx->pub_exp = NULL; | ||
96 | rctx->pad_mode = RSA_PKCS1_PADDING; | ||
97 | rctx->md = NULL; | ||
98 | rctx->tbuf = NULL; | ||
99 | |||
100 | rctx->saltlen = -2; | ||
101 | |||
102 | ctx->data = rctx; | ||
103 | ctx->keygen_info = rctx->gentmp; | ||
104 | ctx->keygen_info_count = 2; | ||
105 | |||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | ||
110 | { | ||
111 | RSA_PKEY_CTX *dctx, *sctx; | ||
112 | if (!pkey_rsa_init(dst)) | ||
113 | return 0; | ||
114 | sctx = src->data; | ||
115 | dctx = dst->data; | ||
116 | dctx->nbits = sctx->nbits; | ||
117 | if (sctx->pub_exp) | ||
118 | { | ||
119 | dctx->pub_exp = BN_dup(sctx->pub_exp); | ||
120 | if (!dctx->pub_exp) | ||
121 | return 0; | ||
122 | } | ||
123 | dctx->pad_mode = sctx->pad_mode; | ||
124 | dctx->md = sctx->md; | ||
125 | return 1; | ||
126 | } | ||
127 | |||
128 | static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) | ||
129 | { | ||
130 | if (ctx->tbuf) | ||
131 | return 1; | ||
132 | ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); | ||
133 | if (!ctx->tbuf) | ||
134 | return 0; | ||
135 | return 1; | ||
136 | } | ||
137 | |||
138 | static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) | ||
139 | { | ||
140 | RSA_PKEY_CTX *rctx = ctx->data; | ||
141 | if (rctx) | ||
142 | { | ||
143 | if (rctx->pub_exp) | ||
144 | BN_free(rctx->pub_exp); | ||
145 | if (rctx->tbuf) | ||
146 | OPENSSL_free(rctx->tbuf); | ||
147 | OPENSSL_free(rctx); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, | ||
152 | const unsigned char *tbs, size_t tbslen) | ||
153 | { | ||
154 | int ret; | ||
155 | RSA_PKEY_CTX *rctx = ctx->data; | ||
156 | RSA *rsa = ctx->pkey->pkey.rsa; | ||
157 | |||
158 | if (rctx->md) | ||
159 | { | ||
160 | if (tbslen != (size_t)EVP_MD_size(rctx->md)) | ||
161 | { | ||
162 | RSAerr(RSA_F_PKEY_RSA_SIGN, | ||
163 | RSA_R_INVALID_DIGEST_LENGTH); | ||
164 | return -1; | ||
165 | } | ||
166 | if (rctx->pad_mode == RSA_X931_PADDING) | ||
167 | { | ||
168 | if (!setup_tbuf(rctx, ctx)) | ||
169 | return -1; | ||
170 | memcpy(rctx->tbuf, tbs, tbslen); | ||
171 | rctx->tbuf[tbslen] = | ||
172 | RSA_X931_hash_id(EVP_MD_type(rctx->md)); | ||
173 | ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, | ||
174 | sig, rsa, RSA_X931_PADDING); | ||
175 | } | ||
176 | else if (rctx->pad_mode == RSA_PKCS1_PADDING) | ||
177 | { | ||
178 | unsigned int sltmp; | ||
179 | ret = RSA_sign(EVP_MD_type(rctx->md), | ||
180 | tbs, tbslen, sig, &sltmp, rsa); | ||
181 | if (ret <= 0) | ||
182 | return ret; | ||
183 | ret = sltmp; | ||
184 | } | ||
185 | else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) | ||
186 | { | ||
187 | if (!setup_tbuf(rctx, ctx)) | ||
188 | return -1; | ||
189 | if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs, | ||
190 | rctx->md, rctx->saltlen)) | ||
191 | return -1; | ||
192 | ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, | ||
193 | sig, rsa, RSA_NO_PADDING); | ||
194 | } | ||
195 | else | ||
196 | return -1; | ||
197 | } | ||
198 | else | ||
199 | ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, | ||
200 | rctx->pad_mode); | ||
201 | if (ret < 0) | ||
202 | return ret; | ||
203 | *siglen = ret; | ||
204 | return 1; | ||
205 | } | ||
206 | |||
207 | |||
208 | static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, | ||
209 | unsigned char *rout, size_t *routlen, | ||
210 | const unsigned char *sig, size_t siglen) | ||
211 | { | ||
212 | int ret; | ||
213 | RSA_PKEY_CTX *rctx = ctx->data; | ||
214 | |||
215 | if (rctx->md) | ||
216 | { | ||
217 | if (rctx->pad_mode == RSA_X931_PADDING) | ||
218 | { | ||
219 | if (!setup_tbuf(rctx, ctx)) | ||
220 | return -1; | ||
221 | ret = RSA_public_decrypt(siglen, sig, | ||
222 | rctx->tbuf, ctx->pkey->pkey.rsa, | ||
223 | RSA_X931_PADDING); | ||
224 | if (ret < 1) | ||
225 | return 0; | ||
226 | ret--; | ||
227 | if (rctx->tbuf[ret] != | ||
228 | RSA_X931_hash_id(EVP_MD_type(rctx->md))) | ||
229 | { | ||
230 | RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, | ||
231 | RSA_R_ALGORITHM_MISMATCH); | ||
232 | return 0; | ||
233 | } | ||
234 | if (ret != EVP_MD_size(rctx->md)) | ||
235 | { | ||
236 | RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, | ||
237 | RSA_R_INVALID_DIGEST_LENGTH); | ||
238 | return 0; | ||
239 | } | ||
240 | if (rout) | ||
241 | memcpy(rout, rctx->tbuf, ret); | ||
242 | } | ||
243 | else if (rctx->pad_mode == RSA_PKCS1_PADDING) | ||
244 | { | ||
245 | size_t sltmp; | ||
246 | ret = int_rsa_verify(EVP_MD_type(rctx->md), | ||
247 | NULL, 0, rout, &sltmp, | ||
248 | sig, siglen, ctx->pkey->pkey.rsa); | ||
249 | if (ret <= 0) | ||
250 | return 0; | ||
251 | ret = sltmp; | ||
252 | } | ||
253 | else | ||
254 | return -1; | ||
255 | } | ||
256 | else | ||
257 | ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, | ||
258 | rctx->pad_mode); | ||
259 | if (ret < 0) | ||
260 | return ret; | ||
261 | *routlen = ret; | ||
262 | return 1; | ||
263 | } | ||
264 | |||
265 | static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, | ||
266 | const unsigned char *sig, size_t siglen, | ||
267 | const unsigned char *tbs, size_t tbslen) | ||
268 | { | ||
269 | RSA_PKEY_CTX *rctx = ctx->data; | ||
270 | RSA *rsa = ctx->pkey->pkey.rsa; | ||
271 | size_t rslen; | ||
272 | if (rctx->md) | ||
273 | { | ||
274 | if (rctx->pad_mode == RSA_PKCS1_PADDING) | ||
275 | return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, | ||
276 | sig, siglen, rsa); | ||
277 | if (rctx->pad_mode == RSA_X931_PADDING) | ||
278 | { | ||
279 | if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, | ||
280 | sig, siglen) <= 0) | ||
281 | return 0; | ||
282 | } | ||
283 | else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) | ||
284 | { | ||
285 | int ret; | ||
286 | if (!setup_tbuf(rctx, ctx)) | ||
287 | return -1; | ||
288 | ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, | ||
289 | rsa, RSA_NO_PADDING); | ||
290 | if (ret <= 0) | ||
291 | return 0; | ||
292 | ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md, | ||
293 | rctx->tbuf, rctx->saltlen); | ||
294 | if (ret <= 0) | ||
295 | return 0; | ||
296 | return 1; | ||
297 | } | ||
298 | else | ||
299 | return -1; | ||
300 | } | ||
301 | else | ||
302 | { | ||
303 | if (!setup_tbuf(rctx, ctx)) | ||
304 | return -1; | ||
305 | rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, | ||
306 | rsa, rctx->pad_mode); | ||
307 | if (rslen == 0) | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen)) | ||
312 | return 0; | ||
313 | |||
314 | return 1; | ||
315 | |||
316 | } | ||
317 | |||
318 | |||
319 | static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, | ||
320 | unsigned char *out, size_t *outlen, | ||
321 | const unsigned char *in, size_t inlen) | ||
322 | { | ||
323 | int ret; | ||
324 | RSA_PKEY_CTX *rctx = ctx->data; | ||
325 | ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, | ||
326 | rctx->pad_mode); | ||
327 | if (ret < 0) | ||
328 | return ret; | ||
329 | *outlen = ret; | ||
330 | return 1; | ||
331 | } | ||
332 | |||
333 | static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, | ||
334 | unsigned char *out, size_t *outlen, | ||
335 | const unsigned char *in, size_t inlen) | ||
336 | { | ||
337 | int ret; | ||
338 | RSA_PKEY_CTX *rctx = ctx->data; | ||
339 | ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, | ||
340 | rctx->pad_mode); | ||
341 | if (ret < 0) | ||
342 | return ret; | ||
343 | *outlen = ret; | ||
344 | return 1; | ||
345 | } | ||
346 | |||
347 | static int check_padding_md(const EVP_MD *md, int padding) | ||
348 | { | ||
349 | if (!md) | ||
350 | return 1; | ||
351 | |||
352 | if (padding == RSA_NO_PADDING) | ||
353 | { | ||
354 | RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | if (padding == RSA_X931_PADDING) | ||
359 | { | ||
360 | if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) | ||
361 | { | ||
362 | RSAerr(RSA_F_CHECK_PADDING_MD, | ||
363 | RSA_R_INVALID_X931_DIGEST); | ||
364 | return 0; | ||
365 | } | ||
366 | return 1; | ||
367 | } | ||
368 | |||
369 | return 1; | ||
370 | } | ||
371 | |||
372 | |||
373 | static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | ||
374 | { | ||
375 | RSA_PKEY_CTX *rctx = ctx->data; | ||
376 | switch (type) | ||
377 | { | ||
378 | case EVP_PKEY_CTRL_RSA_PADDING: | ||
379 | if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) | ||
380 | { | ||
381 | if (!check_padding_md(rctx->md, p1)) | ||
382 | return 0; | ||
383 | if (p1 == RSA_PKCS1_PSS_PADDING) | ||
384 | { | ||
385 | if (!(ctx->operation & | ||
386 | (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) | ||
387 | goto bad_pad; | ||
388 | if (!rctx->md) | ||
389 | rctx->md = EVP_sha1(); | ||
390 | } | ||
391 | if (p1 == RSA_PKCS1_OAEP_PADDING) | ||
392 | { | ||
393 | if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) | ||
394 | goto bad_pad; | ||
395 | if (!rctx->md) | ||
396 | rctx->md = EVP_sha1(); | ||
397 | } | ||
398 | rctx->pad_mode = p1; | ||
399 | return 1; | ||
400 | } | ||
401 | bad_pad: | ||
402 | RSAerr(RSA_F_PKEY_RSA_CTRL, | ||
403 | RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); | ||
404 | return -2; | ||
405 | |||
406 | case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: | ||
407 | if (p1 < -2) | ||
408 | return -2; | ||
409 | if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) | ||
410 | { | ||
411 | RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); | ||
412 | return -2; | ||
413 | } | ||
414 | rctx->saltlen = p1; | ||
415 | return 1; | ||
416 | |||
417 | case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: | ||
418 | if (p1 < 256) | ||
419 | { | ||
420 | RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); | ||
421 | return -2; | ||
422 | } | ||
423 | rctx->nbits = p1; | ||
424 | return 1; | ||
425 | |||
426 | case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: | ||
427 | if (!p2) | ||
428 | return -2; | ||
429 | rctx->pub_exp = p2; | ||
430 | return 1; | ||
431 | |||
432 | case EVP_PKEY_CTRL_MD: | ||
433 | if (!check_padding_md(p2, rctx->pad_mode)) | ||
434 | return 0; | ||
435 | rctx->md = p2; | ||
436 | return 1; | ||
437 | |||
438 | case EVP_PKEY_CTRL_DIGESTINIT: | ||
439 | case EVP_PKEY_CTRL_PKCS7_ENCRYPT: | ||
440 | case EVP_PKEY_CTRL_PKCS7_DECRYPT: | ||
441 | case EVP_PKEY_CTRL_PKCS7_SIGN: | ||
442 | #ifndef OPENSSL_NO_CMS | ||
443 | case EVP_PKEY_CTRL_CMS_ENCRYPT: | ||
444 | case EVP_PKEY_CTRL_CMS_DECRYPT: | ||
445 | case EVP_PKEY_CTRL_CMS_SIGN: | ||
446 | #endif | ||
447 | return 1; | ||
448 | case EVP_PKEY_CTRL_PEER_KEY: | ||
449 | RSAerr(RSA_F_PKEY_RSA_CTRL, | ||
450 | RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | ||
451 | return -2; | ||
452 | |||
453 | default: | ||
454 | return -2; | ||
455 | |||
456 | } | ||
457 | } | ||
458 | |||
459 | static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, | ||
460 | const char *type, const char *value) | ||
461 | { | ||
462 | if (!value) | ||
463 | { | ||
464 | RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); | ||
465 | return 0; | ||
466 | } | ||
467 | if (!strcmp(type, "rsa_padding_mode")) | ||
468 | { | ||
469 | int pm; | ||
470 | if (!strcmp(value, "pkcs1")) | ||
471 | pm = RSA_PKCS1_PADDING; | ||
472 | else if (!strcmp(value, "sslv23")) | ||
473 | pm = RSA_SSLV23_PADDING; | ||
474 | else if (!strcmp(value, "none")) | ||
475 | pm = RSA_NO_PADDING; | ||
476 | else if (!strcmp(value, "oeap")) | ||
477 | pm = RSA_PKCS1_OAEP_PADDING; | ||
478 | else if (!strcmp(value, "x931")) | ||
479 | pm = RSA_X931_PADDING; | ||
480 | else if (!strcmp(value, "pss")) | ||
481 | pm = RSA_PKCS1_PSS_PADDING; | ||
482 | else | ||
483 | { | ||
484 | RSAerr(RSA_F_PKEY_RSA_CTRL_STR, | ||
485 | RSA_R_UNKNOWN_PADDING_TYPE); | ||
486 | return -2; | ||
487 | } | ||
488 | return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); | ||
489 | } | ||
490 | |||
491 | if (!strcmp(type, "rsa_pss_saltlen")) | ||
492 | { | ||
493 | int saltlen; | ||
494 | saltlen = atoi(value); | ||
495 | return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); | ||
496 | } | ||
497 | |||
498 | if (!strcmp(type, "rsa_keygen_bits")) | ||
499 | { | ||
500 | int nbits; | ||
501 | nbits = atoi(value); | ||
502 | return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); | ||
503 | } | ||
504 | |||
505 | if (!strcmp(type, "rsa_keygen_pubexp")) | ||
506 | { | ||
507 | int ret; | ||
508 | BIGNUM *pubexp = NULL; | ||
509 | if (!BN_asc2bn(&pubexp, value)) | ||
510 | return 0; | ||
511 | ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); | ||
512 | if (ret <= 0) | ||
513 | BN_free(pubexp); | ||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | return -2; | ||
518 | } | ||
519 | |||
520 | static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
521 | { | ||
522 | RSA *rsa = NULL; | ||
523 | RSA_PKEY_CTX *rctx = ctx->data; | ||
524 | BN_GENCB *pcb, cb; | ||
525 | int ret; | ||
526 | if (!rctx->pub_exp) | ||
527 | { | ||
528 | rctx->pub_exp = BN_new(); | ||
529 | if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) | ||
530 | return 0; | ||
531 | } | ||
532 | rsa = RSA_new(); | ||
533 | if (!rsa) | ||
534 | return 0; | ||
535 | if (ctx->pkey_gencb) | ||
536 | { | ||
537 | pcb = &cb; | ||
538 | evp_pkey_set_cb_translate(pcb, ctx); | ||
539 | } | ||
540 | else | ||
541 | pcb = NULL; | ||
542 | ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); | ||
543 | if (ret > 0) | ||
544 | EVP_PKEY_assign_RSA(pkey, rsa); | ||
545 | else | ||
546 | RSA_free(rsa); | ||
547 | return ret; | ||
548 | } | ||
549 | |||
550 | const EVP_PKEY_METHOD rsa_pkey_meth = | ||
551 | { | ||
552 | EVP_PKEY_RSA, | ||
553 | EVP_PKEY_FLAG_AUTOARGLEN, | ||
554 | pkey_rsa_init, | ||
555 | pkey_rsa_copy, | ||
556 | pkey_rsa_cleanup, | ||
557 | |||
558 | 0,0, | ||
559 | |||
560 | 0, | ||
561 | pkey_rsa_keygen, | ||
562 | |||
563 | 0, | ||
564 | pkey_rsa_sign, | ||
565 | |||
566 | 0, | ||
567 | pkey_rsa_verify, | ||
568 | |||
569 | 0, | ||
570 | pkey_rsa_verifyrecover, | ||
571 | |||
572 | |||
573 | 0,0,0,0, | ||
574 | |||
575 | 0, | ||
576 | pkey_rsa_encrypt, | ||
577 | |||
578 | 0, | ||
579 | pkey_rsa_decrypt, | ||
580 | |||
581 | 0,0, | ||
582 | |||
583 | pkey_rsa_ctrl, | ||
584 | pkey_rsa_ctrl_str | ||
585 | |||
586 | |||
587 | }; | ||
diff --git a/src/lib/libcrypto/rsa/rsa_prn.c b/src/lib/libcrypto/rsa/rsa_prn.c new file mode 100644 index 0000000000..224db0fae5 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_prn.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* crypto/rsa/rsa_prn.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2006. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/rsa.h> | ||
62 | #include <openssl/evp.h> | ||
63 | |||
64 | #ifndef OPENSSL_NO_FP_API | ||
65 | int RSA_print_fp(FILE *fp, const RSA *x, int off) | ||
66 | { | ||
67 | BIO *b; | ||
68 | int ret; | ||
69 | |||
70 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
71 | { | ||
72 | RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB); | ||
73 | return(0); | ||
74 | } | ||
75 | BIO_set_fp(b,fp,BIO_NOCLOSE); | ||
76 | ret=RSA_print(b,x,off); | ||
77 | BIO_free(b); | ||
78 | return(ret); | ||
79 | } | ||
80 | #endif | ||
81 | |||
82 | int RSA_print(BIO *bp, const RSA *x, int off) | ||
83 | { | ||
84 | EVP_PKEY *pk; | ||
85 | int ret; | ||
86 | pk = EVP_PKEY_new(); | ||
87 | if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x)) | ||
88 | return 0; | ||
89 | ret = EVP_PKEY_print_private(bp, pk, off, NULL); | ||
90 | EVP_PKEY_free(pk); | ||
91 | return ret; | ||
92 | } | ||
93 | |||
diff --git a/src/lib/libcrypto/rsa/rsa_pss.c b/src/lib/libcrypto/rsa/rsa_pss.c index 9b993aca49..ac211e2ffe 100644 --- a/src/lib/libcrypto/rsa/rsa_pss.c +++ b/src/lib/libcrypto/rsa/rsa_pss.c | |||
@@ -81,7 +81,9 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, | |||
81 | EVP_MD_CTX ctx; | 81 | EVP_MD_CTX ctx; |
82 | unsigned char H_[EVP_MAX_MD_SIZE]; | 82 | unsigned char H_[EVP_MAX_MD_SIZE]; |
83 | 83 | ||
84 | hLen = M_EVP_MD_size(Hash); | 84 | hLen = EVP_MD_size(Hash); |
85 | if (hLen < 0) | ||
86 | goto err; | ||
85 | /* | 87 | /* |
86 | * Negative sLen has special meanings: | 88 | * Negative sLen has special meanings: |
87 | * -1 sLen == hLen | 89 | * -1 sLen == hLen |
@@ -126,7 +128,8 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, | |||
126 | RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE); | 128 | RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE); |
127 | goto err; | 129 | goto err; |
128 | } | 130 | } |
129 | PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash); | 131 | if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0) |
132 | goto err; | ||
130 | for (i = 0; i < maskedDBLen; i++) | 133 | for (i = 0; i < maskedDBLen; i++) |
131 | DB[i] ^= EM[i]; | 134 | DB[i] ^= EM[i]; |
132 | if (MSBits) | 135 | if (MSBits) |
@@ -176,7 +179,9 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, | |||
176 | unsigned char *H, *salt = NULL, *p; | 179 | unsigned char *H, *salt = NULL, *p; |
177 | EVP_MD_CTX ctx; | 180 | EVP_MD_CTX ctx; |
178 | 181 | ||
179 | hLen = M_EVP_MD_size(Hash); | 182 | hLen = EVP_MD_size(Hash); |
183 | if (hLen < 0) | ||
184 | goto err; | ||
180 | /* | 185 | /* |
181 | * Negative sLen has special meanings: | 186 | * Negative sLen has special meanings: |
182 | * -1 sLen == hLen | 187 | * -1 sLen == hLen |
@@ -217,7 +222,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, | |||
217 | ERR_R_MALLOC_FAILURE); | 222 | ERR_R_MALLOC_FAILURE); |
218 | goto err; | 223 | goto err; |
219 | } | 224 | } |
220 | if (!RAND_bytes(salt, sLen)) | 225 | if (RAND_bytes(salt, sLen) <= 0) |
221 | goto err; | 226 | goto err; |
222 | } | 227 | } |
223 | maskedDBLen = emLen - hLen - 1; | 228 | maskedDBLen = emLen - hLen - 1; |
@@ -232,7 +237,8 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, | |||
232 | EVP_MD_CTX_cleanup(&ctx); | 237 | EVP_MD_CTX_cleanup(&ctx); |
233 | 238 | ||
234 | /* Generate dbMask in place then perform XOR on it */ | 239 | /* Generate dbMask in place then perform XOR on it */ |
235 | PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash); | 240 | if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash)) |
241 | goto err; | ||
236 | 242 | ||
237 | p = EM; | 243 | p = EM; |
238 | 244 | ||
diff --git a/src/lib/libcrypto/s390xcap.c b/src/lib/libcrypto/s390xcap.c new file mode 100644 index 0000000000..ffbe0235f9 --- /dev/null +++ b/src/lib/libcrypto/s390xcap.c | |||
@@ -0,0 +1,37 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include <setjmp.h> | ||
5 | #include <signal.h> | ||
6 | |||
7 | extern unsigned long OPENSSL_s390xcap_P; | ||
8 | |||
9 | static sigjmp_buf ill_jmp; | ||
10 | static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } | ||
11 | |||
12 | unsigned long OPENSSL_s390x_facilities(void); | ||
13 | |||
14 | void OPENSSL_cpuid_setup(void) | ||
15 | { | ||
16 | sigset_t oset; | ||
17 | struct sigaction ill_act,oact; | ||
18 | |||
19 | if (OPENSSL_s390xcap_P) return; | ||
20 | |||
21 | memset(&ill_act,0,sizeof(ill_act)); | ||
22 | ill_act.sa_handler = ill_handler; | ||
23 | sigfillset(&ill_act.sa_mask); | ||
24 | sigdelset(&ill_act.sa_mask,SIGILL); | ||
25 | sigdelset(&ill_act.sa_mask,SIGTRAP); | ||
26 | sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset); | ||
27 | sigaction (SIGILL,&ill_act,&oact); | ||
28 | |||
29 | /* protection against missing store-facility-list-extended */ | ||
30 | if (sigsetjmp(ill_jmp,0) == 0) | ||
31 | OPENSSL_s390xcap_P = OPENSSL_s390x_facilities(); | ||
32 | else | ||
33 | OPENSSL_s390xcap_P = 1UL<<63; | ||
34 | |||
35 | sigaction (SIGILL,&oact,NULL); | ||
36 | sigprocmask(SIG_SETMASK,&oset,NULL); | ||
37 | } | ||
diff --git a/src/lib/libcrypto/s390xcpuid.S b/src/lib/libcrypto/s390xcpuid.S index 8500133ad0..b053c6a281 100644 --- a/src/lib/libcrypto/s390xcpuid.S +++ b/src/lib/libcrypto/s390xcpuid.S | |||
@@ -1,12 +1,5 @@ | |||
1 | .text | 1 | .text |
2 | 2 | ||
3 | .globl OPENSSL_cpuid_setup | ||
4 | .type OPENSSL_cpuid_setup,@function | ||
5 | .align 16 | ||
6 | OPENSSL_cpuid_setup: | ||
7 | br %r14 # reserved for future | ||
8 | .size OPENSSL_cpuid_setup,.-OPENSSL_cpuid_setup | ||
9 | |||
10 | .globl OPENSSL_s390x_facilities | 3 | .globl OPENSSL_s390x_facilities |
11 | .type OPENSSL_s390x_facilities,@function | 4 | .type OPENSSL_s390x_facilities,@function |
12 | .align 16 | 5 | .align 16 |
@@ -14,6 +7,8 @@ OPENSSL_s390x_facilities: | |||
14 | lghi %r0,0 | 7 | lghi %r0,0 |
15 | .long 0xb2b0f010 # stfle 16(%r15) | 8 | .long 0xb2b0f010 # stfle 16(%r15) |
16 | lg %r2,16(%r15) | 9 | lg %r2,16(%r15) |
10 | larl %r1,OPENSSL_s390xcap_P | ||
11 | stg %r2,0(%r1) | ||
17 | br %r14 | 12 | br %r14 |
18 | .size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities | 13 | .size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities |
19 | 14 | ||
@@ -67,6 +62,8 @@ OPENSSL_cleanse: | |||
67 | lghi %r0,0 | 62 | lghi %r0,0 |
68 | clgr %r3,%r4 | 63 | clgr %r3,%r4 |
69 | jh .Lot | 64 | jh .Lot |
65 | clgr %r3,%r0 | ||
66 | bcr 8,%r14 | ||
70 | .Little: | 67 | .Little: |
71 | stc %r0,0(%r2) | 68 | stc %r0,0(%r2) |
72 | la %r2,1(%r2) | 69 | la %r2,1(%r2) |
@@ -88,3 +85,8 @@ OPENSSL_cleanse: | |||
88 | jnz .Little | 85 | jnz .Little |
89 | br %r14 | 86 | br %r14 |
90 | .size OPENSSL_cleanse,.-OPENSSL_cleanse | 87 | .size OPENSSL_cleanse,.-OPENSSL_cleanse |
88 | |||
89 | .section .init | ||
90 | brasl %r14,OPENSSL_cpuid_setup | ||
91 | |||
92 | .comm OPENSSL_s390xcap_P,8,8 | ||
diff --git a/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl b/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl new file mode 100644 index 0000000000..88861af641 --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl | |||
@@ -0,0 +1,234 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # sha1_block procedure for ARMv4. | ||
11 | # | ||
12 | # January 2007. | ||
13 | |||
14 | # Size/performance trade-off | ||
15 | # ==================================================================== | ||
16 | # impl size in bytes comp cycles[*] measured performance | ||
17 | # ==================================================================== | ||
18 | # thumb 304 3212 4420 | ||
19 | # armv4-small 392/+29% 1958/+64% 2250/+96% | ||
20 | # armv4-compact 740/+89% 1552/+26% 1840/+22% | ||
21 | # armv4-large 1420/+92% 1307/+19% 1370/+34%[***] | ||
22 | # full unroll ~5100/+260% ~1260/+4% ~1300/+5% | ||
23 | # ==================================================================== | ||
24 | # thumb = same as 'small' but in Thumb instructions[**] and | ||
25 | # with recurring code in two private functions; | ||
26 | # small = detached Xload/update, loops are folded; | ||
27 | # compact = detached Xload/update, 5x unroll; | ||
28 | # large = interleaved Xload/update, 5x unroll; | ||
29 | # full unroll = interleaved Xload/update, full unroll, estimated[!]; | ||
30 | # | ||
31 | # [*] Manually counted instructions in "grand" loop body. Measured | ||
32 | # performance is affected by prologue and epilogue overhead, | ||
33 | # i-cache availability, branch penalties, etc. | ||
34 | # [**] While each Thumb instruction is twice smaller, they are not as | ||
35 | # diverse as ARM ones: e.g., there are only two arithmetic | ||
36 | # instructions with 3 arguments, no [fixed] rotate, addressing | ||
37 | # modes are limited. As result it takes more instructions to do | ||
38 | # the same job in Thumb, therefore the code is never twice as | ||
39 | # small and always slower. | ||
40 | # [***] which is also ~35% better than compiler generated code. | ||
41 | |||
42 | $output=shift; | ||
43 | open STDOUT,">$output"; | ||
44 | |||
45 | $ctx="r0"; | ||
46 | $inp="r1"; | ||
47 | $len="r2"; | ||
48 | $a="r3"; | ||
49 | $b="r4"; | ||
50 | $c="r5"; | ||
51 | $d="r6"; | ||
52 | $e="r7"; | ||
53 | $K="r8"; | ||
54 | $t0="r9"; | ||
55 | $t1="r10"; | ||
56 | $t2="r11"; | ||
57 | $t3="r12"; | ||
58 | $Xi="r14"; | ||
59 | @V=($a,$b,$c,$d,$e); | ||
60 | |||
61 | # One can optimize this for aligned access on big-endian architecture, | ||
62 | # but code's endian neutrality makes it too pretty:-) | ||
63 | sub Xload { | ||
64 | my ($a,$b,$c,$d,$e)=@_; | ||
65 | $code.=<<___; | ||
66 | ldrb $t0,[$inp],#4 | ||
67 | ldrb $t1,[$inp,#-3] | ||
68 | ldrb $t2,[$inp,#-2] | ||
69 | ldrb $t3,[$inp,#-1] | ||
70 | add $e,$K,$e,ror#2 @ E+=K_00_19 | ||
71 | orr $t0,$t1,$t0,lsl#8 | ||
72 | add $e,$e,$a,ror#27 @ E+=ROR(A,27) | ||
73 | orr $t0,$t2,$t0,lsl#8 | ||
74 | eor $t1,$c,$d @ F_xx_xx | ||
75 | orr $t0,$t3,$t0,lsl#8 | ||
76 | add $e,$e,$t0 @ E+=X[i] | ||
77 | str $t0,[$Xi,#-4]! | ||
78 | ___ | ||
79 | } | ||
80 | sub Xupdate { | ||
81 | my ($a,$b,$c,$d,$e,$flag)=@_; | ||
82 | $code.=<<___; | ||
83 | ldr $t0,[$Xi,#15*4] | ||
84 | ldr $t1,[$Xi,#13*4] | ||
85 | ldr $t2,[$Xi,#7*4] | ||
86 | ldr $t3,[$Xi,#2*4] | ||
87 | add $e,$K,$e,ror#2 @ E+=K_xx_xx | ||
88 | eor $t0,$t0,$t1 | ||
89 | eor $t0,$t0,$t2 | ||
90 | eor $t0,$t0,$t3 | ||
91 | add $e,$e,$a,ror#27 @ E+=ROR(A,27) | ||
92 | ___ | ||
93 | $code.=<<___ if (!defined($flag)); | ||
94 | eor $t1,$c,$d @ F_xx_xx, but not in 40_59 | ||
95 | ___ | ||
96 | $code.=<<___; | ||
97 | mov $t0,$t0,ror#31 | ||
98 | add $e,$e,$t0 @ E+=X[i] | ||
99 | str $t0,[$Xi,#-4]! | ||
100 | ___ | ||
101 | } | ||
102 | |||
103 | sub BODY_00_15 { | ||
104 | my ($a,$b,$c,$d,$e)=@_; | ||
105 | &Xload(@_); | ||
106 | $code.=<<___; | ||
107 | and $t1,$b,$t1,ror#2 | ||
108 | eor $t1,$t1,$d,ror#2 @ F_00_19(B,C,D) | ||
109 | add $e,$e,$t1 @ E+=F_00_19(B,C,D) | ||
110 | ___ | ||
111 | } | ||
112 | |||
113 | sub BODY_16_19 { | ||
114 | my ($a,$b,$c,$d,$e)=@_; | ||
115 | &Xupdate(@_); | ||
116 | $code.=<<___; | ||
117 | and $t1,$b,$t1,ror#2 | ||
118 | eor $t1,$t1,$d,ror#2 @ F_00_19(B,C,D) | ||
119 | add $e,$e,$t1 @ E+=F_00_19(B,C,D) | ||
120 | ___ | ||
121 | } | ||
122 | |||
123 | sub BODY_20_39 { | ||
124 | my ($a,$b,$c,$d,$e)=@_; | ||
125 | &Xupdate(@_); | ||
126 | $code.=<<___; | ||
127 | eor $t1,$b,$t1,ror#2 @ F_20_39(B,C,D) | ||
128 | add $e,$e,$t1 @ E+=F_20_39(B,C,D) | ||
129 | ___ | ||
130 | } | ||
131 | |||
132 | sub BODY_40_59 { | ||
133 | my ($a,$b,$c,$d,$e)=@_; | ||
134 | &Xupdate(@_,1); | ||
135 | $code.=<<___; | ||
136 | and $t1,$b,$c,ror#2 | ||
137 | orr $t2,$b,$c,ror#2 | ||
138 | and $t2,$t2,$d,ror#2 | ||
139 | orr $t1,$t1,$t2 @ F_40_59(B,C,D) | ||
140 | add $e,$e,$t1 @ E+=F_40_59(B,C,D) | ||
141 | ___ | ||
142 | } | ||
143 | |||
144 | $code=<<___; | ||
145 | .text | ||
146 | |||
147 | .global sha1_block_data_order | ||
148 | .type sha1_block_data_order,%function | ||
149 | |||
150 | .align 2 | ||
151 | sha1_block_data_order: | ||
152 | stmdb sp!,{r4-r12,lr} | ||
153 | add $len,$inp,$len,lsl#6 @ $len to point at the end of $inp | ||
154 | ldmia $ctx,{$a,$b,$c,$d,$e} | ||
155 | .Lloop: | ||
156 | ldr $K,.LK_00_19 | ||
157 | mov $Xi,sp | ||
158 | sub sp,sp,#15*4 | ||
159 | mov $c,$c,ror#30 | ||
160 | mov $d,$d,ror#30 | ||
161 | mov $e,$e,ror#30 @ [6] | ||
162 | .L_00_15: | ||
163 | ___ | ||
164 | for($i=0;$i<5;$i++) { | ||
165 | &BODY_00_15(@V); unshift(@V,pop(@V)); | ||
166 | } | ||
167 | $code.=<<___; | ||
168 | teq $Xi,sp | ||
169 | bne .L_00_15 @ [((11+4)*5+2)*3] | ||
170 | ___ | ||
171 | &BODY_00_15(@V); unshift(@V,pop(@V)); | ||
172 | &BODY_16_19(@V); unshift(@V,pop(@V)); | ||
173 | &BODY_16_19(@V); unshift(@V,pop(@V)); | ||
174 | &BODY_16_19(@V); unshift(@V,pop(@V)); | ||
175 | &BODY_16_19(@V); unshift(@V,pop(@V)); | ||
176 | $code.=<<___; | ||
177 | |||
178 | ldr $K,.LK_20_39 @ [+15+16*4] | ||
179 | sub sp,sp,#25*4 | ||
180 | cmn sp,#0 @ [+3], clear carry to denote 20_39 | ||
181 | .L_20_39_or_60_79: | ||
182 | ___ | ||
183 | for($i=0;$i<5;$i++) { | ||
184 | &BODY_20_39(@V); unshift(@V,pop(@V)); | ||
185 | } | ||
186 | $code.=<<___; | ||
187 | teq $Xi,sp @ preserve carry | ||
188 | bne .L_20_39_or_60_79 @ [+((12+3)*5+2)*4] | ||
189 | bcs .L_done @ [+((12+3)*5+2)*4], spare 300 bytes | ||
190 | |||
191 | ldr $K,.LK_40_59 | ||
192 | sub sp,sp,#20*4 @ [+2] | ||
193 | .L_40_59: | ||
194 | ___ | ||
195 | for($i=0;$i<5;$i++) { | ||
196 | &BODY_40_59(@V); unshift(@V,pop(@V)); | ||
197 | } | ||
198 | $code.=<<___; | ||
199 | teq $Xi,sp | ||
200 | bne .L_40_59 @ [+((12+5)*5+2)*4] | ||
201 | |||
202 | ldr $K,.LK_60_79 | ||
203 | sub sp,sp,#20*4 | ||
204 | cmp sp,#0 @ set carry to denote 60_79 | ||
205 | b .L_20_39_or_60_79 @ [+4], spare 300 bytes | ||
206 | .L_done: | ||
207 | add sp,sp,#80*4 @ "deallocate" stack frame | ||
208 | ldmia $ctx,{$K,$t0,$t1,$t2,$t3} | ||
209 | add $a,$K,$a | ||
210 | add $b,$t0,$b | ||
211 | add $c,$t1,$c,ror#2 | ||
212 | add $d,$t2,$d,ror#2 | ||
213 | add $e,$t3,$e,ror#2 | ||
214 | stmia $ctx,{$a,$b,$c,$d,$e} | ||
215 | teq $inp,$len | ||
216 | bne .Lloop @ [+18], total 1307 | ||
217 | |||
218 | ldmia sp!,{r4-r12,lr} | ||
219 | tst lr,#1 | ||
220 | moveq pc,lr @ be binary compatible with V4, yet | ||
221 | bx lr @ interoperable with Thumb ISA:-) | ||
222 | .align 2 | ||
223 | .LK_00_19: .word 0x5a827999 | ||
224 | .LK_20_39: .word 0x6ed9eba1 | ||
225 | .LK_40_59: .word 0x8f1bbcdc | ||
226 | .LK_60_79: .word 0xca62c1d6 | ||
227 | .size sha1_block_data_order,.-sha1_block_data_order | ||
228 | .asciz "SHA1 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>" | ||
229 | .align 2 | ||
230 | ___ | ||
231 | |||
232 | $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 | ||
233 | print $code; | ||
234 | close STDOUT; # enforce flush | ||
diff --git a/src/lib/libcrypto/sha/asm/sha1-ppc.pl b/src/lib/libcrypto/sha/asm/sha1-ppc.pl new file mode 100755 index 0000000000..dcd0fcdfcf --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha1-ppc.pl | |||
@@ -0,0 +1,319 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # I let hardware handle unaligned input(*), except on page boundaries | ||
11 | # (see below for details). Otherwise straightforward implementation | ||
12 | # with X vector in register bank. The module is big-endian [which is | ||
13 | # not big deal as there're no little-endian targets left around]. | ||
14 | # | ||
15 | # (*) this means that this module is inappropriate for PPC403? Does | ||
16 | # anybody know if pre-POWER3 can sustain unaligned load? | ||
17 | |||
18 | # -m64 -m32 | ||
19 | # ---------------------------------- | ||
20 | # PPC970,gcc-4.0.0 +76% +59% | ||
21 | # Power6,xlc-7 +68% +33% | ||
22 | |||
23 | $flavour = shift; | ||
24 | |||
25 | if ($flavour =~ /64/) { | ||
26 | $SIZE_T =8; | ||
27 | $UCMP ="cmpld"; | ||
28 | $STU ="stdu"; | ||
29 | $POP ="ld"; | ||
30 | $PUSH ="std"; | ||
31 | } elsif ($flavour =~ /32/) { | ||
32 | $SIZE_T =4; | ||
33 | $UCMP ="cmplw"; | ||
34 | $STU ="stwu"; | ||
35 | $POP ="lwz"; | ||
36 | $PUSH ="stw"; | ||
37 | } else { die "nonsense $flavour"; } | ||
38 | |||
39 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | ||
40 | ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or | ||
41 | ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or | ||
42 | die "can't locate ppc-xlate.pl"; | ||
43 | |||
44 | open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; | ||
45 | |||
46 | $FRAME=24*$SIZE_T; | ||
47 | |||
48 | $K ="r0"; | ||
49 | $sp ="r1"; | ||
50 | $toc="r2"; | ||
51 | $ctx="r3"; | ||
52 | $inp="r4"; | ||
53 | $num="r5"; | ||
54 | $t0 ="r15"; | ||
55 | $t1 ="r6"; | ||
56 | |||
57 | $A ="r7"; | ||
58 | $B ="r8"; | ||
59 | $C ="r9"; | ||
60 | $D ="r10"; | ||
61 | $E ="r11"; | ||
62 | $T ="r12"; | ||
63 | |||
64 | @V=($A,$B,$C,$D,$E,$T); | ||
65 | @X=("r16","r17","r18","r19","r20","r21","r22","r23", | ||
66 | "r24","r25","r26","r27","r28","r29","r30","r31"); | ||
67 | |||
68 | sub BODY_00_19 { | ||
69 | my ($i,$a,$b,$c,$d,$e,$f)=@_; | ||
70 | my $j=$i+1; | ||
71 | $code.=<<___ if ($i==0); | ||
72 | lwz @X[$i],`$i*4`($inp) | ||
73 | ___ | ||
74 | $code.=<<___ if ($i<15); | ||
75 | lwz @X[$j],`$j*4`($inp) | ||
76 | add $f,$K,$e | ||
77 | rotlwi $e,$a,5 | ||
78 | add $f,$f,@X[$i] | ||
79 | and $t0,$c,$b | ||
80 | add $f,$f,$e | ||
81 | andc $t1,$d,$b | ||
82 | rotlwi $b,$b,30 | ||
83 | or $t0,$t0,$t1 | ||
84 | add $f,$f,$t0 | ||
85 | ___ | ||
86 | $code.=<<___ if ($i>=15); | ||
87 | add $f,$K,$e | ||
88 | rotlwi $e,$a,5 | ||
89 | xor @X[$j%16],@X[$j%16],@X[($j+2)%16] | ||
90 | add $f,$f,@X[$i%16] | ||
91 | and $t0,$c,$b | ||
92 | xor @X[$j%16],@X[$j%16],@X[($j+8)%16] | ||
93 | add $f,$f,$e | ||
94 | andc $t1,$d,$b | ||
95 | rotlwi $b,$b,30 | ||
96 | or $t0,$t0,$t1 | ||
97 | xor @X[$j%16],@X[$j%16],@X[($j+13)%16] | ||
98 | add $f,$f,$t0 | ||
99 | rotlwi @X[$j%16],@X[$j%16],1 | ||
100 | ___ | ||
101 | } | ||
102 | |||
103 | sub BODY_20_39 { | ||
104 | my ($i,$a,$b,$c,$d,$e,$f)=@_; | ||
105 | my $j=$i+1; | ||
106 | $code.=<<___ if ($i<79); | ||
107 | add $f,$K,$e | ||
108 | rotlwi $e,$a,5 | ||
109 | xor @X[$j%16],@X[$j%16],@X[($j+2)%16] | ||
110 | add $f,$f,@X[$i%16] | ||
111 | xor $t0,$b,$c | ||
112 | xor @X[$j%16],@X[$j%16],@X[($j+8)%16] | ||
113 | add $f,$f,$e | ||
114 | rotlwi $b,$b,30 | ||
115 | xor $t0,$t0,$d | ||
116 | xor @X[$j%16],@X[$j%16],@X[($j+13)%16] | ||
117 | add $f,$f,$t0 | ||
118 | rotlwi @X[$j%16],@X[$j%16],1 | ||
119 | ___ | ||
120 | $code.=<<___ if ($i==79); | ||
121 | add $f,$K,$e | ||
122 | rotlwi $e,$a,5 | ||
123 | lwz r16,0($ctx) | ||
124 | add $f,$f,@X[$i%16] | ||
125 | xor $t0,$b,$c | ||
126 | lwz r17,4($ctx) | ||
127 | add $f,$f,$e | ||
128 | rotlwi $b,$b,30 | ||
129 | lwz r18,8($ctx) | ||
130 | xor $t0,$t0,$d | ||
131 | lwz r19,12($ctx) | ||
132 | add $f,$f,$t0 | ||
133 | lwz r20,16($ctx) | ||
134 | ___ | ||
135 | } | ||
136 | |||
137 | sub BODY_40_59 { | ||
138 | my ($i,$a,$b,$c,$d,$e,$f)=@_; | ||
139 | my $j=$i+1; | ||
140 | $code.=<<___; | ||
141 | add $f,$K,$e | ||
142 | rotlwi $e,$a,5 | ||
143 | xor @X[$j%16],@X[$j%16],@X[($j+2)%16] | ||
144 | add $f,$f,@X[$i%16] | ||
145 | and $t0,$b,$c | ||
146 | xor @X[$j%16],@X[$j%16],@X[($j+8)%16] | ||
147 | add $f,$f,$e | ||
148 | or $t1,$b,$c | ||
149 | rotlwi $b,$b,30 | ||
150 | xor @X[$j%16],@X[$j%16],@X[($j+13)%16] | ||
151 | and $t1,$t1,$d | ||
152 | or $t0,$t0,$t1 | ||
153 | rotlwi @X[$j%16],@X[$j%16],1 | ||
154 | add $f,$f,$t0 | ||
155 | ___ | ||
156 | } | ||
157 | |||
158 | $code=<<___; | ||
159 | .machine "any" | ||
160 | .text | ||
161 | |||
162 | .globl .sha1_block_data_order | ||
163 | .align 4 | ||
164 | .sha1_block_data_order: | ||
165 | mflr r0 | ||
166 | $STU $sp,`-($FRAME+64)`($sp) | ||
167 | $PUSH r0,`$FRAME-$SIZE_T*18`($sp) | ||
168 | $PUSH r15,`$FRAME-$SIZE_T*17`($sp) | ||
169 | $PUSH r16,`$FRAME-$SIZE_T*16`($sp) | ||
170 | $PUSH r17,`$FRAME-$SIZE_T*15`($sp) | ||
171 | $PUSH r18,`$FRAME-$SIZE_T*14`($sp) | ||
172 | $PUSH r19,`$FRAME-$SIZE_T*13`($sp) | ||
173 | $PUSH r20,`$FRAME-$SIZE_T*12`($sp) | ||
174 | $PUSH r21,`$FRAME-$SIZE_T*11`($sp) | ||
175 | $PUSH r22,`$FRAME-$SIZE_T*10`($sp) | ||
176 | $PUSH r23,`$FRAME-$SIZE_T*9`($sp) | ||
177 | $PUSH r24,`$FRAME-$SIZE_T*8`($sp) | ||
178 | $PUSH r25,`$FRAME-$SIZE_T*7`($sp) | ||
179 | $PUSH r26,`$FRAME-$SIZE_T*6`($sp) | ||
180 | $PUSH r27,`$FRAME-$SIZE_T*5`($sp) | ||
181 | $PUSH r28,`$FRAME-$SIZE_T*4`($sp) | ||
182 | $PUSH r29,`$FRAME-$SIZE_T*3`($sp) | ||
183 | $PUSH r30,`$FRAME-$SIZE_T*2`($sp) | ||
184 | $PUSH r31,`$FRAME-$SIZE_T*1`($sp) | ||
185 | lwz $A,0($ctx) | ||
186 | lwz $B,4($ctx) | ||
187 | lwz $C,8($ctx) | ||
188 | lwz $D,12($ctx) | ||
189 | lwz $E,16($ctx) | ||
190 | andi. r0,$inp,3 | ||
191 | bne Lunaligned | ||
192 | Laligned: | ||
193 | mtctr $num | ||
194 | bl Lsha1_block_private | ||
195 | Ldone: | ||
196 | $POP r0,`$FRAME-$SIZE_T*18`($sp) | ||
197 | $POP r15,`$FRAME-$SIZE_T*17`($sp) | ||
198 | $POP r16,`$FRAME-$SIZE_T*16`($sp) | ||
199 | $POP r17,`$FRAME-$SIZE_T*15`($sp) | ||
200 | $POP r18,`$FRAME-$SIZE_T*14`($sp) | ||
201 | $POP r19,`$FRAME-$SIZE_T*13`($sp) | ||
202 | $POP r20,`$FRAME-$SIZE_T*12`($sp) | ||
203 | $POP r21,`$FRAME-$SIZE_T*11`($sp) | ||
204 | $POP r22,`$FRAME-$SIZE_T*10`($sp) | ||
205 | $POP r23,`$FRAME-$SIZE_T*9`($sp) | ||
206 | $POP r24,`$FRAME-$SIZE_T*8`($sp) | ||
207 | $POP r25,`$FRAME-$SIZE_T*7`($sp) | ||
208 | $POP r26,`$FRAME-$SIZE_T*6`($sp) | ||
209 | $POP r27,`$FRAME-$SIZE_T*5`($sp) | ||
210 | $POP r28,`$FRAME-$SIZE_T*4`($sp) | ||
211 | $POP r29,`$FRAME-$SIZE_T*3`($sp) | ||
212 | $POP r30,`$FRAME-$SIZE_T*2`($sp) | ||
213 | $POP r31,`$FRAME-$SIZE_T*1`($sp) | ||
214 | mtlr r0 | ||
215 | addi $sp,$sp,`$FRAME+64` | ||
216 | blr | ||
217 | ___ | ||
218 | |||
219 | # PowerPC specification allows an implementation to be ill-behaved | ||
220 | # upon unaligned access which crosses page boundary. "Better safe | ||
221 | # than sorry" principle makes me treat it specially. But I don't | ||
222 | # look for particular offending word, but rather for 64-byte input | ||
223 | # block which crosses the boundary. Once found that block is aligned | ||
224 | # and hashed separately... | ||
225 | $code.=<<___; | ||
226 | .align 4 | ||
227 | Lunaligned: | ||
228 | subfic $t1,$inp,4096 | ||
229 | andi. $t1,$t1,4095 ; distance to closest page boundary | ||
230 | srwi. $t1,$t1,6 ; t1/=64 | ||
231 | beq Lcross_page | ||
232 | $UCMP $num,$t1 | ||
233 | ble- Laligned ; didn't cross the page boundary | ||
234 | mtctr $t1 | ||
235 | subfc $num,$t1,$num | ||
236 | bl Lsha1_block_private | ||
237 | Lcross_page: | ||
238 | li $t1,16 | ||
239 | mtctr $t1 | ||
240 | addi r20,$sp,$FRAME ; spot below the frame | ||
241 | Lmemcpy: | ||
242 | lbz r16,0($inp) | ||
243 | lbz r17,1($inp) | ||
244 | lbz r18,2($inp) | ||
245 | lbz r19,3($inp) | ||
246 | addi $inp,$inp,4 | ||
247 | stb r16,0(r20) | ||
248 | stb r17,1(r20) | ||
249 | stb r18,2(r20) | ||
250 | stb r19,3(r20) | ||
251 | addi r20,r20,4 | ||
252 | bdnz Lmemcpy | ||
253 | |||
254 | $PUSH $inp,`$FRAME-$SIZE_T*19`($sp) | ||
255 | li $t1,1 | ||
256 | addi $inp,$sp,$FRAME | ||
257 | mtctr $t1 | ||
258 | bl Lsha1_block_private | ||
259 | $POP $inp,`$FRAME-$SIZE_T*19`($sp) | ||
260 | addic. $num,$num,-1 | ||
261 | bne- Lunaligned | ||
262 | b Ldone | ||
263 | ___ | ||
264 | |||
265 | # This is private block function, which uses tailored calling | ||
266 | # interface, namely upon entry SHA_CTX is pre-loaded to given | ||
267 | # registers and counter register contains amount of chunks to | ||
268 | # digest... | ||
269 | $code.=<<___; | ||
270 | .align 4 | ||
271 | Lsha1_block_private: | ||
272 | ___ | ||
273 | $code.=<<___; # load K_00_19 | ||
274 | lis $K,0x5a82 | ||
275 | ori $K,$K,0x7999 | ||
276 | ___ | ||
277 | for($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } | ||
278 | $code.=<<___; # load K_20_39 | ||
279 | lis $K,0x6ed9 | ||
280 | ori $K,$K,0xeba1 | ||
281 | ___ | ||
282 | for(;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
283 | $code.=<<___; # load K_40_59 | ||
284 | lis $K,0x8f1b | ||
285 | ori $K,$K,0xbcdc | ||
286 | ___ | ||
287 | for(;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } | ||
288 | $code.=<<___; # load K_60_79 | ||
289 | lis $K,0xca62 | ||
290 | ori $K,$K,0xc1d6 | ||
291 | ___ | ||
292 | for(;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
293 | $code.=<<___; | ||
294 | add r16,r16,$E | ||
295 | add r17,r17,$T | ||
296 | add r18,r18,$A | ||
297 | add r19,r19,$B | ||
298 | add r20,r20,$C | ||
299 | stw r16,0($ctx) | ||
300 | mr $A,r16 | ||
301 | stw r17,4($ctx) | ||
302 | mr $B,r17 | ||
303 | stw r18,8($ctx) | ||
304 | mr $C,r18 | ||
305 | stw r19,12($ctx) | ||
306 | mr $D,r19 | ||
307 | stw r20,16($ctx) | ||
308 | mr $E,r20 | ||
309 | addi $inp,$inp,`16*4` | ||
310 | bdnz- Lsha1_block_private | ||
311 | blr | ||
312 | ___ | ||
313 | $code.=<<___; | ||
314 | .asciz "SHA1 block transform for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>" | ||
315 | ___ | ||
316 | |||
317 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
318 | print $code; | ||
319 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/sha/asm/sha1-s390x.pl b/src/lib/libcrypto/sha/asm/sha1-s390x.pl new file mode 100644 index 0000000000..4b17848287 --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha1-s390x.pl | |||
@@ -0,0 +1,226 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # SHA1 block procedure for s390x. | ||
11 | |||
12 | # April 2007. | ||
13 | # | ||
14 | # Performance is >30% better than gcc 3.3 generated code. But the real | ||
15 | # twist is that SHA1 hardware support is detected and utilized. In | ||
16 | # which case performance can reach further >4.5x for larger chunks. | ||
17 | |||
18 | # January 2009. | ||
19 | # | ||
20 | # Optimize Xupdate for amount of memory references and reschedule | ||
21 | # instructions to favour dual-issue z10 pipeline. On z10 hardware is | ||
22 | # "only" ~2.3x faster than software. | ||
23 | |||
24 | $kimdfunc=1; # magic function code for kimd instruction | ||
25 | |||
26 | $output=shift; | ||
27 | open STDOUT,">$output"; | ||
28 | |||
29 | $K_00_39="%r0"; $K=$K_00_39; | ||
30 | $K_40_79="%r1"; | ||
31 | $ctx="%r2"; $prefetch="%r2"; | ||
32 | $inp="%r3"; | ||
33 | $len="%r4"; | ||
34 | |||
35 | $A="%r5"; | ||
36 | $B="%r6"; | ||
37 | $C="%r7"; | ||
38 | $D="%r8"; | ||
39 | $E="%r9"; @V=($A,$B,$C,$D,$E); | ||
40 | $t0="%r10"; | ||
41 | $t1="%r11"; | ||
42 | @X=("%r12","%r13","%r14"); | ||
43 | $sp="%r15"; | ||
44 | |||
45 | $frame=160+16*4; | ||
46 | |||
47 | sub Xupdate { | ||
48 | my $i=shift; | ||
49 | |||
50 | $code.=<<___ if ($i==15); | ||
51 | lg $prefetch,160($sp) ### Xupdate(16) warm-up | ||
52 | lr $X[0],$X[2] | ||
53 | ___ | ||
54 | return if ($i&1); # Xupdate is vectorized and executed every 2nd cycle | ||
55 | $code.=<<___ if ($i<16); | ||
56 | lg $X[0],`$i*4`($inp) ### Xload($i) | ||
57 | rllg $X[1],$X[0],32 | ||
58 | ___ | ||
59 | $code.=<<___ if ($i>=16); | ||
60 | xgr $X[0],$prefetch ### Xupdate($i) | ||
61 | lg $prefetch,`160+4*(($i+2)%16)`($sp) | ||
62 | xg $X[0],`160+4*(($i+8)%16)`($sp) | ||
63 | xgr $X[0],$prefetch | ||
64 | rll $X[0],$X[0],1 | ||
65 | rllg $X[1],$X[0],32 | ||
66 | rll $X[1],$X[1],1 | ||
67 | rllg $X[0],$X[1],32 | ||
68 | lr $X[2],$X[1] # feedback | ||
69 | ___ | ||
70 | $code.=<<___ if ($i<=70); | ||
71 | stg $X[0],`160+4*($i%16)`($sp) | ||
72 | ___ | ||
73 | unshift(@X,pop(@X)); | ||
74 | } | ||
75 | |||
76 | sub BODY_00_19 { | ||
77 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
78 | my $xi=$X[1]; | ||
79 | |||
80 | &Xupdate($i); | ||
81 | $code.=<<___; | ||
82 | alr $e,$K ### $i | ||
83 | rll $t1,$a,5 | ||
84 | lr $t0,$d | ||
85 | xr $t0,$c | ||
86 | alr $e,$t1 | ||
87 | nr $t0,$b | ||
88 | alr $e,$xi | ||
89 | xr $t0,$d | ||
90 | rll $b,$b,30 | ||
91 | alr $e,$t0 | ||
92 | ___ | ||
93 | } | ||
94 | |||
95 | sub BODY_20_39 { | ||
96 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
97 | my $xi=$X[1]; | ||
98 | |||
99 | &Xupdate($i); | ||
100 | $code.=<<___; | ||
101 | alr $e,$K ### $i | ||
102 | rll $t1,$a,5 | ||
103 | lr $t0,$b | ||
104 | alr $e,$t1 | ||
105 | xr $t0,$c | ||
106 | alr $e,$xi | ||
107 | xr $t0,$d | ||
108 | rll $b,$b,30 | ||
109 | alr $e,$t0 | ||
110 | ___ | ||
111 | } | ||
112 | |||
113 | sub BODY_40_59 { | ||
114 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
115 | my $xi=$X[1]; | ||
116 | |||
117 | &Xupdate($i); | ||
118 | $code.=<<___; | ||
119 | alr $e,$K ### $i | ||
120 | rll $t1,$a,5 | ||
121 | lr $t0,$b | ||
122 | alr $e,$t1 | ||
123 | or $t0,$c | ||
124 | lr $t1,$b | ||
125 | nr $t0,$d | ||
126 | nr $t1,$c | ||
127 | alr $e,$xi | ||
128 | or $t0,$t1 | ||
129 | rll $b,$b,30 | ||
130 | alr $e,$t0 | ||
131 | ___ | ||
132 | } | ||
133 | |||
134 | $code.=<<___; | ||
135 | .text | ||
136 | .align 64 | ||
137 | .type Ktable,\@object | ||
138 | Ktable: .long 0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6 | ||
139 | .skip 48 #.long 0,0,0,0,0,0,0,0,0,0,0,0 | ||
140 | .size Ktable,.-Ktable | ||
141 | .globl sha1_block_data_order | ||
142 | .type sha1_block_data_order,\@function | ||
143 | sha1_block_data_order: | ||
144 | ___ | ||
145 | $code.=<<___ if ($kimdfunc); | ||
146 | larl %r1,OPENSSL_s390xcap_P | ||
147 | lg %r0,0(%r1) | ||
148 | tmhl %r0,0x4000 # check for message-security assist | ||
149 | jz .Lsoftware | ||
150 | lghi %r0,0 | ||
151 | la %r1,16($sp) | ||
152 | .long 0xb93e0002 # kimd %r0,%r2 | ||
153 | lg %r0,16($sp) | ||
154 | tmhh %r0,`0x8000>>$kimdfunc` | ||
155 | jz .Lsoftware | ||
156 | lghi %r0,$kimdfunc | ||
157 | lgr %r1,$ctx | ||
158 | lgr %r2,$inp | ||
159 | sllg %r3,$len,6 | ||
160 | .long 0xb93e0002 # kimd %r0,%r2 | ||
161 | brc 1,.-4 # pay attention to "partial completion" | ||
162 | br %r14 | ||
163 | .align 16 | ||
164 | .Lsoftware: | ||
165 | ___ | ||
166 | $code.=<<___; | ||
167 | lghi %r1,-$frame | ||
168 | stg $ctx,16($sp) | ||
169 | stmg %r6,%r15,48($sp) | ||
170 | lgr %r0,$sp | ||
171 | la $sp,0(%r1,$sp) | ||
172 | stg %r0,0($sp) | ||
173 | |||
174 | larl $t0,Ktable | ||
175 | llgf $A,0($ctx) | ||
176 | llgf $B,4($ctx) | ||
177 | llgf $C,8($ctx) | ||
178 | llgf $D,12($ctx) | ||
179 | llgf $E,16($ctx) | ||
180 | |||
181 | lg $K_00_39,0($t0) | ||
182 | lg $K_40_79,8($t0) | ||
183 | |||
184 | .Lloop: | ||
185 | rllg $K_00_39,$K_00_39,32 | ||
186 | ___ | ||
187 | for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } | ||
188 | $code.=<<___; | ||
189 | rllg $K_00_39,$K_00_39,32 | ||
190 | ___ | ||
191 | for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
192 | $code.=<<___; $K=$K_40_79; | ||
193 | rllg $K_40_79,$K_40_79,32 | ||
194 | ___ | ||
195 | for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } | ||
196 | $code.=<<___; | ||
197 | rllg $K_40_79,$K_40_79,32 | ||
198 | ___ | ||
199 | for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
200 | $code.=<<___; | ||
201 | |||
202 | lg $ctx,`$frame+16`($sp) | ||
203 | la $inp,64($inp) | ||
204 | al $A,0($ctx) | ||
205 | al $B,4($ctx) | ||
206 | al $C,8($ctx) | ||
207 | al $D,12($ctx) | ||
208 | al $E,16($ctx) | ||
209 | st $A,0($ctx) | ||
210 | st $B,4($ctx) | ||
211 | st $C,8($ctx) | ||
212 | st $D,12($ctx) | ||
213 | st $E,16($ctx) | ||
214 | brct $len,.Lloop | ||
215 | |||
216 | lmg %r6,%r15,`$frame+48`($sp) | ||
217 | br %r14 | ||
218 | .size sha1_block_data_order,.-sha1_block_data_order | ||
219 | .string "SHA1 block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>" | ||
220 | .comm OPENSSL_s390xcap_P,8,8 | ||
221 | ___ | ||
222 | |||
223 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
224 | |||
225 | print $code; | ||
226 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/sha/asm/sha1-sparcv9.pl b/src/lib/libcrypto/sha/asm/sha1-sparcv9.pl new file mode 100644 index 0000000000..8306fc88cc --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha1-sparcv9.pl | |||
@@ -0,0 +1,283 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # Performance improvement is not really impressive on pre-T1 CPU: +8% | ||
11 | # over Sun C and +25% over gcc [3.3]. While on T1, a.k.a. Niagara, it | ||
12 | # turned to be 40% faster than 64-bit code generated by Sun C 5.8 and | ||
13 | # >2x than 64-bit code generated by gcc 3.4. And there is a gimmick. | ||
14 | # X[16] vector is packed to 8 64-bit registers and as result nothing | ||
15 | # is spilled on stack. In addition input data is loaded in compact | ||
16 | # instruction sequence, thus minimizing the window when the code is | ||
17 | # subject to [inter-thread] cache-thrashing hazard. The goal is to | ||
18 | # ensure scalability on UltraSPARC T1, or rather to avoid decay when | ||
19 | # amount of active threads exceeds the number of physical cores. | ||
20 | |||
21 | $bits=32; | ||
22 | for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } | ||
23 | if ($bits==64) { $bias=2047; $frame=192; } | ||
24 | else { $bias=0; $frame=112; } | ||
25 | |||
26 | $output=shift; | ||
27 | open STDOUT,">$output"; | ||
28 | |||
29 | @X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7"); | ||
30 | $rot1m="%g2"; | ||
31 | $tmp64="%g3"; | ||
32 | $Xi="%g4"; | ||
33 | $A="%l0"; | ||
34 | $B="%l1"; | ||
35 | $C="%l2"; | ||
36 | $D="%l3"; | ||
37 | $E="%l4"; | ||
38 | @V=($A,$B,$C,$D,$E); | ||
39 | $K_00_19="%l5"; | ||
40 | $K_20_39="%l6"; | ||
41 | $K_40_59="%l7"; | ||
42 | $K_60_79="%g5"; | ||
43 | @K=($K_00_19,$K_20_39,$K_40_59,$K_60_79); | ||
44 | |||
45 | $ctx="%i0"; | ||
46 | $inp="%i1"; | ||
47 | $len="%i2"; | ||
48 | $tmp0="%i3"; | ||
49 | $tmp1="%i4"; | ||
50 | $tmp2="%i5"; | ||
51 | |||
52 | sub BODY_00_15 { | ||
53 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
54 | my $xi=($i&1)?@X[($i/2)%8]:$Xi; | ||
55 | |||
56 | $code.=<<___; | ||
57 | sll $a,5,$tmp0 !! $i | ||
58 | add @K[$i/20],$e,$e | ||
59 | srl $a,27,$tmp1 | ||
60 | add $tmp0,$e,$e | ||
61 | and $c,$b,$tmp0 | ||
62 | add $tmp1,$e,$e | ||
63 | sll $b,30,$tmp2 | ||
64 | andn $d,$b,$tmp1 | ||
65 | srl $b,2,$b | ||
66 | or $tmp1,$tmp0,$tmp1 | ||
67 | or $tmp2,$b,$b | ||
68 | add $xi,$e,$e | ||
69 | ___ | ||
70 | if ($i&1 && $i<15) { | ||
71 | $code.= | ||
72 | " srlx @X[(($i+1)/2)%8],32,$Xi\n"; | ||
73 | } | ||
74 | $code.=<<___; | ||
75 | add $tmp1,$e,$e | ||
76 | ___ | ||
77 | } | ||
78 | |||
79 | sub Xupdate { | ||
80 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
81 | my $j=$i/2; | ||
82 | |||
83 | if ($i&1) { | ||
84 | $code.=<<___; | ||
85 | sll $a,5,$tmp0 !! $i | ||
86 | add @K[$i/20],$e,$e | ||
87 | srl $a,27,$tmp1 | ||
88 | ___ | ||
89 | } else { | ||
90 | $code.=<<___; | ||
91 | sllx @X[($j+6)%8],32,$Xi ! Xupdate($i) | ||
92 | xor @X[($j+1)%8],@X[$j%8],@X[$j%8] | ||
93 | srlx @X[($j+7)%8],32,$tmp1 | ||
94 | xor @X[($j+4)%8],@X[$j%8],@X[$j%8] | ||
95 | sll $a,5,$tmp0 !! $i | ||
96 | or $tmp1,$Xi,$Xi | ||
97 | add @K[$i/20],$e,$e !! | ||
98 | xor $Xi,@X[$j%8],@X[$j%8] | ||
99 | srlx @X[$j%8],31,$Xi | ||
100 | add @X[$j%8],@X[$j%8],@X[$j%8] | ||
101 | and $Xi,$rot1m,$Xi | ||
102 | andn @X[$j%8],$rot1m,@X[$j%8] | ||
103 | srl $a,27,$tmp1 !! | ||
104 | or $Xi,@X[$j%8],@X[$j%8] | ||
105 | ___ | ||
106 | } | ||
107 | } | ||
108 | |||
109 | sub BODY_16_19 { | ||
110 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
111 | |||
112 | &Xupdate(@_); | ||
113 | if ($i&1) { | ||
114 | $xi=@X[($i/2)%8]; | ||
115 | } else { | ||
116 | $xi=$Xi; | ||
117 | $code.="\tsrlx @X[($i/2)%8],32,$xi\n"; | ||
118 | } | ||
119 | $code.=<<___; | ||
120 | add $tmp0,$e,$e !! | ||
121 | and $c,$b,$tmp0 | ||
122 | add $tmp1,$e,$e | ||
123 | sll $b,30,$tmp2 | ||
124 | add $xi,$e,$e | ||
125 | andn $d,$b,$tmp1 | ||
126 | srl $b,2,$b | ||
127 | or $tmp1,$tmp0,$tmp1 | ||
128 | or $tmp2,$b,$b | ||
129 | add $tmp1,$e,$e | ||
130 | ___ | ||
131 | } | ||
132 | |||
133 | sub BODY_20_39 { | ||
134 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
135 | my $xi; | ||
136 | &Xupdate(@_); | ||
137 | if ($i&1) { | ||
138 | $xi=@X[($i/2)%8]; | ||
139 | } else { | ||
140 | $xi=$Xi; | ||
141 | $code.="\tsrlx @X[($i/2)%8],32,$xi\n"; | ||
142 | } | ||
143 | $code.=<<___; | ||
144 | add $tmp0,$e,$e !! | ||
145 | xor $c,$b,$tmp0 | ||
146 | add $tmp1,$e,$e | ||
147 | sll $b,30,$tmp2 | ||
148 | xor $d,$tmp0,$tmp1 | ||
149 | srl $b,2,$b | ||
150 | add $tmp1,$e,$e | ||
151 | or $tmp2,$b,$b | ||
152 | add $xi,$e,$e | ||
153 | ___ | ||
154 | } | ||
155 | |||
156 | sub BODY_40_59 { | ||
157 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
158 | my $xi; | ||
159 | &Xupdate(@_); | ||
160 | if ($i&1) { | ||
161 | $xi=@X[($i/2)%8]; | ||
162 | } else { | ||
163 | $xi=$Xi; | ||
164 | $code.="\tsrlx @X[($i/2)%8],32,$xi\n"; | ||
165 | } | ||
166 | $code.=<<___; | ||
167 | add $tmp0,$e,$e !! | ||
168 | and $c,$b,$tmp0 | ||
169 | add $tmp1,$e,$e | ||
170 | sll $b,30,$tmp2 | ||
171 | or $c,$b,$tmp1 | ||
172 | srl $b,2,$b | ||
173 | and $d,$tmp1,$tmp1 | ||
174 | add $xi,$e,$e | ||
175 | or $tmp1,$tmp0,$tmp1 | ||
176 | or $tmp2,$b,$b | ||
177 | add $tmp1,$e,$e | ||
178 | ___ | ||
179 | } | ||
180 | |||
181 | $code.=<<___ if ($bits==64); | ||
182 | .register %g2,#scratch | ||
183 | .register %g3,#scratch | ||
184 | ___ | ||
185 | $code.=<<___; | ||
186 | .section ".text",#alloc,#execinstr | ||
187 | |||
188 | .align 32 | ||
189 | .globl sha1_block_data_order | ||
190 | sha1_block_data_order: | ||
191 | save %sp,-$frame,%sp | ||
192 | sllx $len,6,$len | ||
193 | add $inp,$len,$len | ||
194 | |||
195 | or %g0,1,$rot1m | ||
196 | sllx $rot1m,32,$rot1m | ||
197 | or $rot1m,1,$rot1m | ||
198 | |||
199 | ld [$ctx+0],$A | ||
200 | ld [$ctx+4],$B | ||
201 | ld [$ctx+8],$C | ||
202 | ld [$ctx+12],$D | ||
203 | ld [$ctx+16],$E | ||
204 | andn $inp,7,$tmp0 | ||
205 | |||
206 | sethi %hi(0x5a827999),$K_00_19 | ||
207 | or $K_00_19,%lo(0x5a827999),$K_00_19 | ||
208 | sethi %hi(0x6ed9eba1),$K_20_39 | ||
209 | or $K_20_39,%lo(0x6ed9eba1),$K_20_39 | ||
210 | sethi %hi(0x8f1bbcdc),$K_40_59 | ||
211 | or $K_40_59,%lo(0x8f1bbcdc),$K_40_59 | ||
212 | sethi %hi(0xca62c1d6),$K_60_79 | ||
213 | or $K_60_79,%lo(0xca62c1d6),$K_60_79 | ||
214 | |||
215 | .Lloop: | ||
216 | ldx [$tmp0+0],@X[0] | ||
217 | ldx [$tmp0+16],@X[2] | ||
218 | ldx [$tmp0+32],@X[4] | ||
219 | ldx [$tmp0+48],@X[6] | ||
220 | and $inp,7,$tmp1 | ||
221 | ldx [$tmp0+8],@X[1] | ||
222 | sll $tmp1,3,$tmp1 | ||
223 | ldx [$tmp0+24],@X[3] | ||
224 | subcc %g0,$tmp1,$tmp2 ! should be 64-$tmp1, but -$tmp1 works too | ||
225 | ldx [$tmp0+40],@X[5] | ||
226 | bz,pt %icc,.Laligned | ||
227 | ldx [$tmp0+56],@X[7] | ||
228 | |||
229 | sllx @X[0],$tmp1,@X[0] | ||
230 | ldx [$tmp0+64],$tmp64 | ||
231 | ___ | ||
232 | for($i=0;$i<7;$i++) | ||
233 | { $code.=<<___; | ||
234 | srlx @X[$i+1],$tmp2,$Xi | ||
235 | sllx @X[$i+1],$tmp1,@X[$i+1] | ||
236 | or $Xi,@X[$i],@X[$i] | ||
237 | ___ | ||
238 | } | ||
239 | $code.=<<___; | ||
240 | srlx $tmp64,$tmp2,$tmp64 | ||
241 | or $tmp64,@X[7],@X[7] | ||
242 | .Laligned: | ||
243 | srlx @X[0],32,$Xi | ||
244 | ___ | ||
245 | for ($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } | ||
246 | for (;$i<20;$i++) { &BODY_16_19($i,@V); unshift(@V,pop(@V)); } | ||
247 | for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
248 | for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } | ||
249 | for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
250 | $code.=<<___; | ||
251 | |||
252 | ld [$ctx+0],@X[0] | ||
253 | ld [$ctx+4],@X[1] | ||
254 | ld [$ctx+8],@X[2] | ||
255 | ld [$ctx+12],@X[3] | ||
256 | add $inp,64,$inp | ||
257 | ld [$ctx+16],@X[4] | ||
258 | cmp $inp,$len | ||
259 | |||
260 | add $A,@X[0],$A | ||
261 | st $A,[$ctx+0] | ||
262 | add $B,@X[1],$B | ||
263 | st $B,[$ctx+4] | ||
264 | add $C,@X[2],$C | ||
265 | st $C,[$ctx+8] | ||
266 | add $D,@X[3],$D | ||
267 | st $D,[$ctx+12] | ||
268 | add $E,@X[4],$E | ||
269 | st $E,[$ctx+16] | ||
270 | |||
271 | bne `$bits==64?"%xcc":"%icc"`,.Lloop | ||
272 | andn $inp,7,$tmp0 | ||
273 | |||
274 | ret | ||
275 | restore | ||
276 | .type sha1_block_data_order,#function | ||
277 | .size sha1_block_data_order,(.-sha1_block_data_order) | ||
278 | .asciz "SHA1 block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>" | ||
279 | ___ | ||
280 | |||
281 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
282 | print $code; | ||
283 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl b/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl new file mode 100644 index 0000000000..15eb854bad --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl | |||
@@ -0,0 +1,600 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # January 2009 | ||
11 | # | ||
12 | # Provided that UltraSPARC VIS instructions are pipe-lined(*) and | ||
13 | # pairable(*) with IALU ones, offloading of Xupdate to the UltraSPARC | ||
14 | # Graphic Unit would make it possible to achieve higher instruction- | ||
15 | # level parallelism, ILP, and thus higher performance. It should be | ||
16 | # explicitly noted that ILP is the keyword, and it means that this | ||
17 | # code would be unsuitable for cores like UltraSPARC-Tx. The idea is | ||
18 | # not really novel, Sun had VIS-powered implementation for a while. | ||
19 | # Unlike Sun's implementation this one can process multiple unaligned | ||
20 | # input blocks, and as such works as drop-in replacement for OpenSSL | ||
21 | # sha1_block_data_order. Performance improvement was measured to be | ||
22 | # 40% over pure IALU sha1-sparcv9.pl on UltraSPARC-IIi, but 12% on | ||
23 | # UltraSPARC-III. See below for discussion... | ||
24 | # | ||
25 | # The module does not present direct interest for OpenSSL, because | ||
26 | # it doesn't provide better performance on contemporary SPARCv9 CPUs, | ||
27 | # UltraSPARC-Tx and SPARC64-V[II] to be specific. Those who feel they | ||
28 | # absolutely must score on UltraSPARC-I-IV can simply replace | ||
29 | # crypto/sha/asm/sha1-sparcv9.pl with this module. | ||
30 | # | ||
31 | # (*) "Pipe-lined" means that even if it takes several cycles to | ||
32 | # complete, next instruction using same functional unit [but not | ||
33 | # depending on the result of the current instruction] can start | ||
34 | # execution without having to wait for the unit. "Pairable" | ||
35 | # means that two [or more] independent instructions can be | ||
36 | # issued at the very same time. | ||
37 | |||
38 | $bits=32; | ||
39 | for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } | ||
40 | if ($bits==64) { $bias=2047; $frame=192; } | ||
41 | else { $bias=0; $frame=112; } | ||
42 | |||
43 | $output=shift; | ||
44 | open STDOUT,">$output"; | ||
45 | |||
46 | $ctx="%i0"; | ||
47 | $inp="%i1"; | ||
48 | $len="%i2"; | ||
49 | $tmp0="%i3"; | ||
50 | $tmp1="%i4"; | ||
51 | $tmp2="%i5"; | ||
52 | $tmp3="%g5"; | ||
53 | |||
54 | $base="%g1"; | ||
55 | $align="%g4"; | ||
56 | $Xfer="%o5"; | ||
57 | $nXfer=$tmp3; | ||
58 | $Xi="%o7"; | ||
59 | |||
60 | $A="%l0"; | ||
61 | $B="%l1"; | ||
62 | $C="%l2"; | ||
63 | $D="%l3"; | ||
64 | $E="%l4"; | ||
65 | @V=($A,$B,$C,$D,$E); | ||
66 | |||
67 | $Actx="%o0"; | ||
68 | $Bctx="%o1"; | ||
69 | $Cctx="%o2"; | ||
70 | $Dctx="%o3"; | ||
71 | $Ectx="%o4"; | ||
72 | |||
73 | $fmul="%f32"; | ||
74 | $VK_00_19="%f34"; | ||
75 | $VK_20_39="%f36"; | ||
76 | $VK_40_59="%f38"; | ||
77 | $VK_60_79="%f40"; | ||
78 | @VK=($VK_00_19,$VK_20_39,$VK_40_59,$VK_60_79); | ||
79 | @X=("%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", | ||
80 | "%f8", "%f9","%f10","%f11","%f12","%f13","%f14","%f15","%f16"); | ||
81 | |||
82 | # This is reference 2x-parallelized VIS-powered Xupdate procedure. It | ||
83 | # covers even K_NN_MM addition... | ||
84 | sub Xupdate { | ||
85 | my ($i)=@_; | ||
86 | my $K=@VK[($i+16)/20]; | ||
87 | my $j=($i+16)%16; | ||
88 | |||
89 | # [ provided that GSR.alignaddr_offset is 5, $mul contains | ||
90 | # 0x100ULL<<32|0x100 value and K_NN_MM are pre-loaded to | ||
91 | # chosen registers... ] | ||
92 | $code.=<<___; | ||
93 | fxors @X[($j+13)%16],@X[$j],@X[$j] !-1/-1/-1:X[0]^=X[13] | ||
94 | fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14] | ||
95 | fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9] | ||
96 | fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9] | ||
97 | faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24 | ||
98 | fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1 | ||
99 | fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1 | ||
100 | ![fxors %f15,%f2,%f2] | ||
101 | for %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp | ||
102 | ![fxors %f0,%f3,%f3] !10/17/12:X[0] dependency | ||
103 | fpadd32 $K,@X[$j],%f20 | ||
104 | std %f20,[$Xfer+`4*$j`] | ||
105 | ___ | ||
106 | # The numbers delimited with slash are the earliest possible dispatch | ||
107 | # cycles for given instruction assuming 1 cycle latency for simple VIS | ||
108 | # instructions, such as on UltraSPARC-I&II, 3 cycles latency, such as | ||
109 | # on UltraSPARC-III&IV, and 2 cycles latency(*), respectively. Being | ||
110 | # 2x-parallelized the procedure is "worth" 5, 8.5 or 6 ticks per SHA1 | ||
111 | # round. As [long as] FPU/VIS instructions are perfectly pairable with | ||
112 | # IALU ones, the round timing is defined by the maximum between VIS | ||
113 | # and IALU timings. The latter varies from round to round and averages | ||
114 | # out at 6.25 ticks. This means that USI&II should operate at IALU | ||
115 | # rate, while USIII&IV - at VIS rate. This explains why performance | ||
116 | # improvement varies among processors. Well, given that pure IALU | ||
117 | # sha1-sparcv9.pl module exhibits virtually uniform performance of | ||
118 | # ~9.3 cycles per SHA1 round. Timings mentioned above are theoretical | ||
119 | # lower limits. Real-life performance was measured to be 6.6 cycles | ||
120 | # per SHA1 round on USIIi and 8.3 on USIII. The latter is lower than | ||
121 | # half-round VIS timing, because there are 16 Xupdate-free rounds, | ||
122 | # which "push down" average theoretical timing to 8 cycles... | ||
123 | |||
124 | # (*) SPARC64-V[II] was originally believed to have 2 cycles VIS | ||
125 | # latency. Well, it might have, but it doesn't have dedicated | ||
126 | # VIS-unit. Instead, VIS instructions are executed by other | ||
127 | # functional units, ones used here - by IALU. This doesn't | ||
128 | # improve effective ILP... | ||
129 | } | ||
130 | |||
131 | # The reference Xupdate procedure is then "strained" over *pairs* of | ||
132 | # BODY_NN_MM and kind of modulo-scheduled in respect to X[n]^=X[n+13] | ||
133 | # and K_NN_MM addition. It's "running" 15 rounds ahead, which leaves | ||
134 | # plenty of room to amortize for read-after-write hazard, as well as | ||
135 | # to fetch and align input for the next spin. The VIS instructions are | ||
136 | # scheduled for latency of 2 cycles, because there are not enough IALU | ||
137 | # instructions to schedule for latency of 3, while scheduling for 1 | ||
138 | # would give no gain on USI&II anyway. | ||
139 | |||
140 | sub BODY_00_19 { | ||
141 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
142 | my $j=$i&~1; | ||
143 | my $k=($j+16+2)%16; # ahead reference | ||
144 | my $l=($j+16-2)%16; # behind reference | ||
145 | my $K=@VK[($j+16-2)/20]; | ||
146 | |||
147 | $j=($j+16)%16; | ||
148 | |||
149 | $code.=<<___ if (!($i&1)); | ||
150 | sll $a,5,$tmp0 !! $i | ||
151 | and $c,$b,$tmp3 | ||
152 | ld [$Xfer+`4*($i%16)`],$Xi | ||
153 | fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14] | ||
154 | srl $a,27,$tmp1 | ||
155 | add $tmp0,$e,$e | ||
156 | fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9] | ||
157 | sll $b,30,$tmp2 | ||
158 | add $tmp1,$e,$e | ||
159 | andn $d,$b,$tmp1 | ||
160 | add $Xi,$e,$e | ||
161 | fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9] | ||
162 | srl $b,2,$b | ||
163 | or $tmp1,$tmp3,$tmp1 | ||
164 | or $tmp2,$b,$b | ||
165 | add $tmp1,$e,$e | ||
166 | faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24 | ||
167 | ___ | ||
168 | $code.=<<___ if ($i&1); | ||
169 | sll $a,5,$tmp0 !! $i | ||
170 | and $c,$b,$tmp3 | ||
171 | ld [$Xfer+`4*($i%16)`],$Xi | ||
172 | fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1 | ||
173 | srl $a,27,$tmp1 | ||
174 | add $tmp0,$e,$e | ||
175 | fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1 | ||
176 | sll $b,30,$tmp2 | ||
177 | add $tmp1,$e,$e | ||
178 | fpadd32 $K,@X[$l],%f20 ! | ||
179 | andn $d,$b,$tmp1 | ||
180 | add $Xi,$e,$e | ||
181 | fxors @X[($k+13)%16],@X[$k],@X[$k] !-1/-1/-1:X[0]^=X[13] | ||
182 | srl $b,2,$b | ||
183 | or $tmp1,$tmp3,$tmp1 | ||
184 | fxor %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp | ||
185 | or $tmp2,$b,$b | ||
186 | add $tmp1,$e,$e | ||
187 | ___ | ||
188 | $code.=<<___ if ($i&1 && $i>=2); | ||
189 | std %f20,[$Xfer+`4*$l`] ! | ||
190 | ___ | ||
191 | } | ||
192 | |||
193 | sub BODY_20_39 { | ||
194 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
195 | my $j=$i&~1; | ||
196 | my $k=($j+16+2)%16; # ahead reference | ||
197 | my $l=($j+16-2)%16; # behind reference | ||
198 | my $K=@VK[($j+16-2)/20]; | ||
199 | |||
200 | $j=($j+16)%16; | ||
201 | |||
202 | $code.=<<___ if (!($i&1) && $i<64); | ||
203 | sll $a,5,$tmp0 !! $i | ||
204 | ld [$Xfer+`4*($i%16)`],$Xi | ||
205 | fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14] | ||
206 | srl $a,27,$tmp1 | ||
207 | add $tmp0,$e,$e | ||
208 | fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9] | ||
209 | xor $c,$b,$tmp0 | ||
210 | add $tmp1,$e,$e | ||
211 | sll $b,30,$tmp2 | ||
212 | xor $d,$tmp0,$tmp1 | ||
213 | fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9] | ||
214 | srl $b,2,$b | ||
215 | add $tmp1,$e,$e | ||
216 | or $tmp2,$b,$b | ||
217 | add $Xi,$e,$e | ||
218 | faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24 | ||
219 | ___ | ||
220 | $code.=<<___ if ($i&1 && $i<64); | ||
221 | sll $a,5,$tmp0 !! $i | ||
222 | ld [$Xfer+`4*($i%16)`],$Xi | ||
223 | fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1 | ||
224 | srl $a,27,$tmp1 | ||
225 | add $tmp0,$e,$e | ||
226 | fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1 | ||
227 | xor $c,$b,$tmp0 | ||
228 | add $tmp1,$e,$e | ||
229 | fpadd32 $K,@X[$l],%f20 ! | ||
230 | sll $b,30,$tmp2 | ||
231 | xor $d,$tmp0,$tmp1 | ||
232 | fxors @X[($k+13)%16],@X[$k],@X[$k] !-1/-1/-1:X[0]^=X[13] | ||
233 | srl $b,2,$b | ||
234 | add $tmp1,$e,$e | ||
235 | fxor %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp | ||
236 | or $tmp2,$b,$b | ||
237 | add $Xi,$e,$e | ||
238 | std %f20,[$Xfer+`4*$l`] ! | ||
239 | ___ | ||
240 | $code.=<<___ if ($i==64); | ||
241 | sll $a,5,$tmp0 !! $i | ||
242 | ld [$Xfer+`4*($i%16)`],$Xi | ||
243 | fpadd32 $K,@X[$l],%f20 | ||
244 | srl $a,27,$tmp1 | ||
245 | add $tmp0,$e,$e | ||
246 | xor $c,$b,$tmp0 | ||
247 | add $tmp1,$e,$e | ||
248 | sll $b,30,$tmp2 | ||
249 | xor $d,$tmp0,$tmp1 | ||
250 | std %f20,[$Xfer+`4*$l`] | ||
251 | srl $b,2,$b | ||
252 | add $tmp1,$e,$e | ||
253 | or $tmp2,$b,$b | ||
254 | add $Xi,$e,$e | ||
255 | ___ | ||
256 | $code.=<<___ if ($i>64); | ||
257 | sll $a,5,$tmp0 !! $i | ||
258 | ld [$Xfer+`4*($i%16)`],$Xi | ||
259 | srl $a,27,$tmp1 | ||
260 | add $tmp0,$e,$e | ||
261 | xor $c,$b,$tmp0 | ||
262 | add $tmp1,$e,$e | ||
263 | sll $b,30,$tmp2 | ||
264 | xor $d,$tmp0,$tmp1 | ||
265 | srl $b,2,$b | ||
266 | add $tmp1,$e,$e | ||
267 | or $tmp2,$b,$b | ||
268 | add $Xi,$e,$e | ||
269 | ___ | ||
270 | } | ||
271 | |||
272 | sub BODY_40_59 { | ||
273 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
274 | my $j=$i&~1; | ||
275 | my $k=($j+16+2)%16; # ahead reference | ||
276 | my $l=($j+16-2)%16; # behind reference | ||
277 | my $K=@VK[($j+16-2)/20]; | ||
278 | |||
279 | $j=($j+16)%16; | ||
280 | |||
281 | $code.=<<___ if (!($i&1)); | ||
282 | sll $a,5,$tmp0 !! $i | ||
283 | ld [$Xfer+`4*($i%16)`],$Xi | ||
284 | fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14] | ||
285 | srl $a,27,$tmp1 | ||
286 | add $tmp0,$e,$e | ||
287 | fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9] | ||
288 | and $c,$b,$tmp0 | ||
289 | add $tmp1,$e,$e | ||
290 | sll $b,30,$tmp2 | ||
291 | or $c,$b,$tmp1 | ||
292 | fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9] | ||
293 | srl $b,2,$b | ||
294 | and $d,$tmp1,$tmp1 | ||
295 | add $Xi,$e,$e | ||
296 | or $tmp1,$tmp0,$tmp1 | ||
297 | faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24 | ||
298 | or $tmp2,$b,$b | ||
299 | add $tmp1,$e,$e | ||
300 | fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1 | ||
301 | ___ | ||
302 | $code.=<<___ if ($i&1); | ||
303 | sll $a,5,$tmp0 !! $i | ||
304 | ld [$Xfer+`4*($i%16)`],$Xi | ||
305 | srl $a,27,$tmp1 | ||
306 | add $tmp0,$e,$e | ||
307 | fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1 | ||
308 | and $c,$b,$tmp0 | ||
309 | add $tmp1,$e,$e | ||
310 | fpadd32 $K,@X[$l],%f20 ! | ||
311 | sll $b,30,$tmp2 | ||
312 | or $c,$b,$tmp1 | ||
313 | fxors @X[($k+13)%16],@X[$k],@X[$k] !-1/-1/-1:X[0]^=X[13] | ||
314 | srl $b,2,$b | ||
315 | and $d,$tmp1,$tmp1 | ||
316 | fxor %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp | ||
317 | add $Xi,$e,$e | ||
318 | or $tmp1,$tmp0,$tmp1 | ||
319 | or $tmp2,$b,$b | ||
320 | add $tmp1,$e,$e | ||
321 | std %f20,[$Xfer+`4*$l`] ! | ||
322 | ___ | ||
323 | } | ||
324 | |||
325 | # If there is more data to process, then we pre-fetch the data for | ||
326 | # next iteration in last ten rounds... | ||
327 | sub BODY_70_79 { | ||
328 | my ($i,$a,$b,$c,$d,$e)=@_; | ||
329 | my $j=$i&~1; | ||
330 | my $m=($i%8)*2; | ||
331 | |||
332 | $j=($j+16)%16; | ||
333 | |||
334 | $code.=<<___ if ($i==70); | ||
335 | sll $a,5,$tmp0 !! $i | ||
336 | ld [$Xfer+`4*($i%16)`],$Xi | ||
337 | srl $a,27,$tmp1 | ||
338 | add $tmp0,$e,$e | ||
339 | ldd [$inp+64],@X[0] | ||
340 | xor $c,$b,$tmp0 | ||
341 | add $tmp1,$e,$e | ||
342 | sll $b,30,$tmp2 | ||
343 | xor $d,$tmp0,$tmp1 | ||
344 | srl $b,2,$b | ||
345 | add $tmp1,$e,$e | ||
346 | or $tmp2,$b,$b | ||
347 | add $Xi,$e,$e | ||
348 | |||
349 | and $inp,-64,$nXfer | ||
350 | inc 64,$inp | ||
351 | and $nXfer,255,$nXfer | ||
352 | alignaddr %g0,$align,%g0 | ||
353 | add $base,$nXfer,$nXfer | ||
354 | ___ | ||
355 | $code.=<<___ if ($i==71); | ||
356 | sll $a,5,$tmp0 !! $i | ||
357 | ld [$Xfer+`4*($i%16)`],$Xi | ||
358 | srl $a,27,$tmp1 | ||
359 | add $tmp0,$e,$e | ||
360 | xor $c,$b,$tmp0 | ||
361 | add $tmp1,$e,$e | ||
362 | sll $b,30,$tmp2 | ||
363 | xor $d,$tmp0,$tmp1 | ||
364 | srl $b,2,$b | ||
365 | add $tmp1,$e,$e | ||
366 | or $tmp2,$b,$b | ||
367 | add $Xi,$e,$e | ||
368 | ___ | ||
369 | $code.=<<___ if ($i>=72); | ||
370 | faligndata @X[$m],@X[$m+2],@X[$m] | ||
371 | sll $a,5,$tmp0 !! $i | ||
372 | ld [$Xfer+`4*($i%16)`],$Xi | ||
373 | srl $a,27,$tmp1 | ||
374 | add $tmp0,$e,$e | ||
375 | xor $c,$b,$tmp0 | ||
376 | add $tmp1,$e,$e | ||
377 | fpadd32 $VK_00_19,@X[$m],%f20 | ||
378 | sll $b,30,$tmp2 | ||
379 | xor $d,$tmp0,$tmp1 | ||
380 | srl $b,2,$b | ||
381 | add $tmp1,$e,$e | ||
382 | or $tmp2,$b,$b | ||
383 | add $Xi,$e,$e | ||
384 | ___ | ||
385 | $code.=<<___ if ($i<77); | ||
386 | ldd [$inp+`8*($i+1-70)`],@X[2*($i+1-70)] | ||
387 | ___ | ||
388 | $code.=<<___ if ($i==77); # redundant if $inp was aligned | ||
389 | add $align,63,$tmp0 | ||
390 | and $tmp0,-8,$tmp0 | ||
391 | ldd [$inp+$tmp0],@X[16] | ||
392 | ___ | ||
393 | $code.=<<___ if ($i>=72); | ||
394 | std %f20,[$nXfer+`4*$m`] | ||
395 | ___ | ||
396 | } | ||
397 | |||
398 | $code.=<<___; | ||
399 | .section ".text",#alloc,#execinstr | ||
400 | |||
401 | .align 64 | ||
402 | vis_const: | ||
403 | .long 0x5a827999,0x5a827999 ! K_00_19 | ||
404 | .long 0x6ed9eba1,0x6ed9eba1 ! K_20_39 | ||
405 | .long 0x8f1bbcdc,0x8f1bbcdc ! K_40_59 | ||
406 | .long 0xca62c1d6,0xca62c1d6 ! K_60_79 | ||
407 | .long 0x00000100,0x00000100 | ||
408 | .align 64 | ||
409 | .type vis_const,#object | ||
410 | .size vis_const,(.-vis_const) | ||
411 | |||
412 | .globl sha1_block_data_order | ||
413 | sha1_block_data_order: | ||
414 | save %sp,-$frame,%sp | ||
415 | add %fp,$bias-256,$base | ||
416 | |||
417 | 1: call .+8 | ||
418 | add %o7,vis_const-1b,$tmp0 | ||
419 | |||
420 | ldd [$tmp0+0],$VK_00_19 | ||
421 | ldd [$tmp0+8],$VK_20_39 | ||
422 | ldd [$tmp0+16],$VK_40_59 | ||
423 | ldd [$tmp0+24],$VK_60_79 | ||
424 | ldd [$tmp0+32],$fmul | ||
425 | |||
426 | ld [$ctx+0],$Actx | ||
427 | and $base,-256,$base | ||
428 | ld [$ctx+4],$Bctx | ||
429 | sub $base,$bias+$frame,%sp | ||
430 | ld [$ctx+8],$Cctx | ||
431 | and $inp,7,$align | ||
432 | ld [$ctx+12],$Dctx | ||
433 | and $inp,-8,$inp | ||
434 | ld [$ctx+16],$Ectx | ||
435 | |||
436 | ! X[16] is maintained in FP register bank | ||
437 | alignaddr %g0,$align,%g0 | ||
438 | ldd [$inp+0],@X[0] | ||
439 | sub $inp,-64,$Xfer | ||
440 | ldd [$inp+8],@X[2] | ||
441 | and $Xfer,-64,$Xfer | ||
442 | ldd [$inp+16],@X[4] | ||
443 | and $Xfer,255,$Xfer | ||
444 | ldd [$inp+24],@X[6] | ||
445 | add $base,$Xfer,$Xfer | ||
446 | ldd [$inp+32],@X[8] | ||
447 | ldd [$inp+40],@X[10] | ||
448 | ldd [$inp+48],@X[12] | ||
449 | brz,pt $align,.Laligned | ||
450 | ldd [$inp+56],@X[14] | ||
451 | |||
452 | ldd [$inp+64],@X[16] | ||
453 | faligndata @X[0],@X[2],@X[0] | ||
454 | faligndata @X[2],@X[4],@X[2] | ||
455 | faligndata @X[4],@X[6],@X[4] | ||
456 | faligndata @X[6],@X[8],@X[6] | ||
457 | faligndata @X[8],@X[10],@X[8] | ||
458 | faligndata @X[10],@X[12],@X[10] | ||
459 | faligndata @X[12],@X[14],@X[12] | ||
460 | faligndata @X[14],@X[16],@X[14] | ||
461 | |||
462 | .Laligned: | ||
463 | mov 5,$tmp0 | ||
464 | dec 1,$len | ||
465 | alignaddr %g0,$tmp0,%g0 | ||
466 | fpadd32 $VK_00_19,@X[0],%f16 | ||
467 | fpadd32 $VK_00_19,@X[2],%f18 | ||
468 | fpadd32 $VK_00_19,@X[4],%f20 | ||
469 | fpadd32 $VK_00_19,@X[6],%f22 | ||
470 | fpadd32 $VK_00_19,@X[8],%f24 | ||
471 | fpadd32 $VK_00_19,@X[10],%f26 | ||
472 | fpadd32 $VK_00_19,@X[12],%f28 | ||
473 | fpadd32 $VK_00_19,@X[14],%f30 | ||
474 | std %f16,[$Xfer+0] | ||
475 | mov $Actx,$A | ||
476 | std %f18,[$Xfer+8] | ||
477 | mov $Bctx,$B | ||
478 | std %f20,[$Xfer+16] | ||
479 | mov $Cctx,$C | ||
480 | std %f22,[$Xfer+24] | ||
481 | mov $Dctx,$D | ||
482 | std %f24,[$Xfer+32] | ||
483 | mov $Ectx,$E | ||
484 | std %f26,[$Xfer+40] | ||
485 | fxors @X[13],@X[0],@X[0] | ||
486 | std %f28,[$Xfer+48] | ||
487 | ba .Loop | ||
488 | std %f30,[$Xfer+56] | ||
489 | .align 32 | ||
490 | .Loop: | ||
491 | ___ | ||
492 | for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } | ||
493 | for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
494 | for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } | ||
495 | for (;$i<70;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
496 | $code.=<<___; | ||
497 | tst $len | ||
498 | bz,pn `$bits==32?"%icc":"%xcc"`,.Ltail | ||
499 | nop | ||
500 | ___ | ||
501 | for (;$i<80;$i++) { &BODY_70_79($i,@V); unshift(@V,pop(@V)); } | ||
502 | $code.=<<___; | ||
503 | add $A,$Actx,$Actx | ||
504 | add $B,$Bctx,$Bctx | ||
505 | add $C,$Cctx,$Cctx | ||
506 | add $D,$Dctx,$Dctx | ||
507 | add $E,$Ectx,$Ectx | ||
508 | mov 5,$tmp0 | ||
509 | fxors @X[13],@X[0],@X[0] | ||
510 | mov $Actx,$A | ||
511 | mov $Bctx,$B | ||
512 | mov $Cctx,$C | ||
513 | mov $Dctx,$D | ||
514 | mov $Ectx,$E | ||
515 | alignaddr %g0,$tmp0,%g0 | ||
516 | dec 1,$len | ||
517 | ba .Loop | ||
518 | mov $nXfer,$Xfer | ||
519 | |||
520 | .align 32 | ||
521 | .Ltail: | ||
522 | ___ | ||
523 | for($i=70;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
524 | $code.=<<___; | ||
525 | add $A,$Actx,$Actx | ||
526 | add $B,$Bctx,$Bctx | ||
527 | add $C,$Cctx,$Cctx | ||
528 | add $D,$Dctx,$Dctx | ||
529 | add $E,$Ectx,$Ectx | ||
530 | |||
531 | st $Actx,[$ctx+0] | ||
532 | st $Bctx,[$ctx+4] | ||
533 | st $Cctx,[$ctx+8] | ||
534 | st $Dctx,[$ctx+12] | ||
535 | st $Ectx,[$ctx+16] | ||
536 | |||
537 | ret | ||
538 | restore | ||
539 | .type sha1_block_data_order,#function | ||
540 | .size sha1_block_data_order,(.-sha1_block_data_order) | ||
541 | .asciz "SHA1 block transform for SPARCv9a, CRYPTOGAMS by <appro\@openssl.org>" | ||
542 | ___ | ||
543 | |||
544 | # Purpose of these subroutines is to explicitly encode VIS instructions, | ||
545 | # so that one can compile the module without having to specify VIS | ||
546 | # extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a. | ||
547 | # Idea is to reserve for option to produce "universal" binary and let | ||
548 | # programmer detect if current CPU is VIS capable at run-time. | ||
549 | sub unvis { | ||
550 | my ($mnemonic,$rs1,$rs2,$rd)=@_; | ||
551 | my $ref,$opf; | ||
552 | my %visopf = ( "fmul8ulx16" => 0x037, | ||
553 | "faligndata" => 0x048, | ||
554 | "fpadd32" => 0x052, | ||
555 | "fxor" => 0x06c, | ||
556 | "fxors" => 0x06d ); | ||
557 | |||
558 | $ref = "$mnemonic\t$rs1,$rs2,$rd"; | ||
559 | |||
560 | if ($opf=$visopf{$mnemonic}) { | ||
561 | foreach ($rs1,$rs2,$rd) { | ||
562 | return $ref if (!/%f([0-9]{1,2})/); | ||
563 | $_=$1; | ||
564 | if ($1>=32) { | ||
565 | return $ref if ($1&1); | ||
566 | # re-encode for upper double register addressing | ||
567 | $_=($1|$1>>5)&31; | ||
568 | } | ||
569 | } | ||
570 | |||
571 | return sprintf ".word\t0x%08x !%s", | ||
572 | 0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2, | ||
573 | $ref; | ||
574 | } else { | ||
575 | return $ref; | ||
576 | } | ||
577 | } | ||
578 | sub unalignaddr { | ||
579 | my ($mnemonic,$rs1,$rs2,$rd)=@_; | ||
580 | my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 ); | ||
581 | my $ref="$mnemonic\t$rs1,$rs2,$rd"; | ||
582 | |||
583 | foreach ($rs1,$rs2,$rd) { | ||
584 | if (/%([goli])([0-7])/) { $_=$bias{$1}+$2; } | ||
585 | else { return $ref; } | ||
586 | } | ||
587 | return sprintf ".word\t0x%08x !%s", | ||
588 | 0x81b00300|$rd<<25|$rs1<<14|$rs2, | ||
589 | $ref; | ||
590 | } | ||
591 | |||
592 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
593 | $code =~ s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),(%f[0-9]{1,2}),(%f[0-9]{1,2})/ | ||
594 | &unvis($1,$2,$3,$4) | ||
595 | /gem; | ||
596 | $code =~ s/\b(alignaddr)\s+(%[goli][0-7]),(%[goli][0-7]),(%[goli][0-7])/ | ||
597 | &unalignaddr($1,$2,$3,$4) | ||
598 | /gem; | ||
599 | print $code; | ||
600 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/sha/asm/sha1-thumb.pl b/src/lib/libcrypto/sha/asm/sha1-thumb.pl new file mode 100644 index 0000000000..7c9ea9b029 --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha1-thumb.pl | |||
@@ -0,0 +1,259 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # sha1_block for Thumb. | ||
11 | # | ||
12 | # January 2007. | ||
13 | # | ||
14 | # The code does not present direct interest to OpenSSL, because of low | ||
15 | # performance. Its purpose is to establish _size_ benchmark. Pretty | ||
16 | # useless one I must say, because 30% or 88 bytes larger ARMv4 code | ||
17 | # [avialable on demand] is almost _twice_ as fast. It should also be | ||
18 | # noted that in-lining of .Lcommon and .Lrotate improves performance | ||
19 | # by over 40%, while code increases by only 10% or 32 bytes. But once | ||
20 | # again, the goal was to establish _size_ benchmark, not performance. | ||
21 | |||
22 | $output=shift; | ||
23 | open STDOUT,">$output"; | ||
24 | |||
25 | $inline=0; | ||
26 | #$cheat_on_binutils=1; | ||
27 | |||
28 | $t0="r0"; | ||
29 | $t1="r1"; | ||
30 | $t2="r2"; | ||
31 | $a="r3"; | ||
32 | $b="r4"; | ||
33 | $c="r5"; | ||
34 | $d="r6"; | ||
35 | $e="r7"; | ||
36 | $K="r8"; # "upper" registers can be used in add/sub and mov insns | ||
37 | $ctx="r9"; | ||
38 | $inp="r10"; | ||
39 | $len="r11"; | ||
40 | $Xi="r12"; | ||
41 | |||
42 | sub common { | ||
43 | <<___; | ||
44 | sub $t0,#4 | ||
45 | ldr $t1,[$t0] | ||
46 | add $e,$K @ E+=K_xx_xx | ||
47 | lsl $t2,$a,#5 | ||
48 | add $t2,$e | ||
49 | lsr $e,$a,#27 | ||
50 | add $t2,$e @ E+=ROR(A,27) | ||
51 | add $t2,$t1 @ E+=X[i] | ||
52 | ___ | ||
53 | } | ||
54 | sub rotate { | ||
55 | <<___; | ||
56 | mov $e,$d @ E=D | ||
57 | mov $d,$c @ D=C | ||
58 | lsl $c,$b,#30 | ||
59 | lsr $b,$b,#2 | ||
60 | orr $c,$b @ C=ROR(B,2) | ||
61 | mov $b,$a @ B=A | ||
62 | add $a,$t2,$t1 @ A=E+F_xx_xx(B,C,D) | ||
63 | ___ | ||
64 | } | ||
65 | |||
66 | sub BODY_00_19 { | ||
67 | $code.=$inline?&common():"\tbl .Lcommon\n"; | ||
68 | $code.=<<___; | ||
69 | mov $t1,$c | ||
70 | eor $t1,$d | ||
71 | and $t1,$b | ||
72 | eor $t1,$d @ F_00_19(B,C,D) | ||
73 | ___ | ||
74 | $code.=$inline?&rotate():"\tbl .Lrotate\n"; | ||
75 | } | ||
76 | |||
77 | sub BODY_20_39 { | ||
78 | $code.=$inline?&common():"\tbl .Lcommon\n"; | ||
79 | $code.=<<___; | ||
80 | mov $t1,$b | ||
81 | eor $t1,$c | ||
82 | eor $t1,$d @ F_20_39(B,C,D) | ||
83 | ___ | ||
84 | $code.=$inline?&rotate():"\tbl .Lrotate\n"; | ||
85 | } | ||
86 | |||
87 | sub BODY_40_59 { | ||
88 | $code.=$inline?&common():"\tbl .Lcommon\n"; | ||
89 | $code.=<<___; | ||
90 | mov $t1,$b | ||
91 | and $t1,$c | ||
92 | mov $e,$b | ||
93 | orr $e,$c | ||
94 | and $e,$d | ||
95 | orr $t1,$e @ F_40_59(B,C,D) | ||
96 | ___ | ||
97 | $code.=$inline?&rotate():"\tbl .Lrotate\n"; | ||
98 | } | ||
99 | |||
100 | $code=<<___; | ||
101 | .text | ||
102 | .code 16 | ||
103 | |||
104 | .global sha1_block_data_order | ||
105 | .type sha1_block_data_order,%function | ||
106 | |||
107 | .align 2 | ||
108 | sha1_block_data_order: | ||
109 | ___ | ||
110 | if ($cheat_on_binutils) { | ||
111 | $code.=<<___; | ||
112 | .code 32 | ||
113 | add r3,pc,#1 | ||
114 | bx r3 @ switch to Thumb ISA | ||
115 | .code 16 | ||
116 | ___ | ||
117 | } | ||
118 | $code.=<<___; | ||
119 | push {r4-r7} | ||
120 | mov r3,r8 | ||
121 | mov r4,r9 | ||
122 | mov r5,r10 | ||
123 | mov r6,r11 | ||
124 | mov r7,r12 | ||
125 | push {r3-r7,lr} | ||
126 | lsl r2,#6 | ||
127 | mov $ctx,r0 @ save context | ||
128 | mov $inp,r1 @ save inp | ||
129 | mov $len,r2 @ save len | ||
130 | add $len,$inp @ $len to point at inp end | ||
131 | |||
132 | .Lloop: | ||
133 | mov $Xi,sp | ||
134 | mov $t2,sp | ||
135 | sub $t2,#16*4 @ [3] | ||
136 | .LXload: | ||
137 | ldrb $a,[$t1,#0] @ $t1 is r1 and holds inp | ||
138 | ldrb $b,[$t1,#1] | ||
139 | ldrb $c,[$t1,#2] | ||
140 | ldrb $d,[$t1,#3] | ||
141 | lsl $a,#24 | ||
142 | lsl $b,#16 | ||
143 | lsl $c,#8 | ||
144 | orr $a,$b | ||
145 | orr $a,$c | ||
146 | orr $a,$d | ||
147 | add $t1,#4 | ||
148 | push {$a} | ||
149 | cmp sp,$t2 | ||
150 | bne .LXload @ [+14*16] | ||
151 | |||
152 | mov $inp,$t1 @ update $inp | ||
153 | sub $t2,#32*4 | ||
154 | sub $t2,#32*4 | ||
155 | mov $e,#31 @ [+4] | ||
156 | .LXupdate: | ||
157 | ldr $a,[sp,#15*4] | ||
158 | ldr $b,[sp,#13*4] | ||
159 | ldr $c,[sp,#7*4] | ||
160 | ldr $d,[sp,#2*4] | ||
161 | eor $a,$b | ||
162 | eor $a,$c | ||
163 | eor $a,$d | ||
164 | ror $a,$e | ||
165 | push {$a} | ||
166 | cmp sp,$t2 | ||
167 | bne .LXupdate @ [+(11+1)*64] | ||
168 | |||
169 | ldmia $t0!,{$a,$b,$c,$d,$e} @ $t0 is r0 and holds ctx | ||
170 | mov $t0,$Xi | ||
171 | |||
172 | ldr $t2,.LK_00_19 | ||
173 | mov $t1,$t0 | ||
174 | sub $t1,#20*4 | ||
175 | mov $Xi,$t1 | ||
176 | mov $K,$t2 @ [+7+4] | ||
177 | .L_00_19: | ||
178 | ___ | ||
179 | &BODY_00_19(); | ||
180 | $code.=<<___; | ||
181 | cmp $Xi,$t0 | ||
182 | bne .L_00_19 @ [+(2+9+4+2+8+2)*20] | ||
183 | |||
184 | ldr $t2,.LK_20_39 | ||
185 | mov $t1,$t0 | ||
186 | sub $t1,#20*4 | ||
187 | mov $Xi,$t1 | ||
188 | mov $K,$t2 @ [+5] | ||
189 | .L_20_39_or_60_79: | ||
190 | ___ | ||
191 | &BODY_20_39(); | ||
192 | $code.=<<___; | ||
193 | cmp $Xi,$t0 | ||
194 | bne .L_20_39_or_60_79 @ [+(2+9+3+2+8+2)*20*2] | ||
195 | cmp sp,$t0 | ||
196 | beq .Ldone @ [+2] | ||
197 | |||
198 | ldr $t2,.LK_40_59 | ||
199 | mov $t1,$t0 | ||
200 | sub $t1,#20*4 | ||
201 | mov $Xi,$t1 | ||
202 | mov $K,$t2 @ [+5] | ||
203 | .L_40_59: | ||
204 | ___ | ||
205 | &BODY_40_59(); | ||
206 | $code.=<<___; | ||
207 | cmp $Xi,$t0 | ||
208 | bne .L_40_59 @ [+(2+9+6+2+8+2)*20] | ||
209 | |||
210 | ldr $t2,.LK_60_79 | ||
211 | mov $Xi,sp | ||
212 | mov $K,$t2 | ||
213 | b .L_20_39_or_60_79 @ [+4] | ||
214 | .Ldone: | ||
215 | mov $t0,$ctx | ||
216 | ldr $t1,[$t0,#0] | ||
217 | ldr $t2,[$t0,#4] | ||
218 | add $a,$t1 | ||
219 | ldr $t1,[$t0,#8] | ||
220 | add $b,$t2 | ||
221 | ldr $t2,[$t0,#12] | ||
222 | add $c,$t1 | ||
223 | ldr $t1,[$t0,#16] | ||
224 | add $d,$t2 | ||
225 | add $e,$t1 | ||
226 | stmia $t0!,{$a,$b,$c,$d,$e} @ [+20] | ||
227 | |||
228 | add sp,#80*4 @ deallocate stack frame | ||
229 | mov $t0,$ctx @ restore ctx | ||
230 | mov $t1,$inp @ restore inp | ||
231 | cmp $t1,$len | ||
232 | beq .Lexit | ||
233 | b .Lloop @ [+6] total 3212 cycles | ||
234 | .Lexit: | ||
235 | pop {r2-r7} | ||
236 | mov r8,r2 | ||
237 | mov r9,r3 | ||
238 | mov r10,r4 | ||
239 | mov r11,r5 | ||
240 | mov r12,r6 | ||
241 | mov lr,r7 | ||
242 | pop {r4-r7} | ||
243 | bx lr | ||
244 | .align 2 | ||
245 | ___ | ||
246 | $code.=".Lcommon:\n".&common()."\tmov pc,lr\n" if (!$inline); | ||
247 | $code.=".Lrotate:\n".&rotate()."\tmov pc,lr\n" if (!$inline); | ||
248 | $code.=<<___; | ||
249 | .align 2 | ||
250 | .LK_00_19: .word 0x5a827999 | ||
251 | .LK_20_39: .word 0x6ed9eba1 | ||
252 | .LK_40_59: .word 0x8f1bbcdc | ||
253 | .LK_60_79: .word 0xca62c1d6 | ||
254 | .size sha1_block_data_order,.-sha1_block_data_order | ||
255 | .asciz "SHA1 block transform for Thumb, CRYPTOGAMS by <appro\@openssl.org>" | ||
256 | ___ | ||
257 | |||
258 | print $code; | ||
259 | close STDOUT; # enforce flush | ||
diff --git a/src/lib/libcrypto/sha/asm/sha1-x86_64.pl b/src/lib/libcrypto/sha/asm/sha1-x86_64.pl index f7ed67a726..4edc5ea9ad 100755 --- a/src/lib/libcrypto/sha/asm/sha1-x86_64.pl +++ b/src/lib/libcrypto/sha/asm/sha1-x86_64.pl | |||
@@ -29,14 +29,18 @@ | |||
29 | # Xeon P4 +65% +0% 9.9 | 29 | # Xeon P4 +65% +0% 9.9 |
30 | # Core2 +60% +10% 7.0 | 30 | # Core2 +60% +10% 7.0 |
31 | 31 | ||
32 | $output=shift; | 32 | $flavour = shift; |
33 | $output = shift; | ||
34 | if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } | ||
35 | |||
36 | $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); | ||
33 | 37 | ||
34 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | 38 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; |
35 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | 39 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or |
36 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | 40 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or |
37 | die "can't locate x86_64-xlate.pl"; | 41 | die "can't locate x86_64-xlate.pl"; |
38 | 42 | ||
39 | open STDOUT,"| $^X $xlate $output"; | 43 | open STDOUT,"| $^X $xlate $flavour $output"; |
40 | 44 | ||
41 | $ctx="%rdi"; # 1st arg | 45 | $ctx="%rdi"; # 1st arg |
42 | $inp="%rsi"; # 2nd arg | 46 | $inp="%rsi"; # 2nd arg |
@@ -69,13 +73,14 @@ $func: | |||
69 | push %rbx | 73 | push %rbx |
70 | push %rbp | 74 | push %rbp |
71 | push %r12 | 75 | push %r12 |
72 | mov %rsp,%rax | 76 | mov %rsp,%r11 |
73 | mov %rdi,$ctx # reassigned argument | 77 | mov %rdi,$ctx # reassigned argument |
74 | sub \$`8+16*4`,%rsp | 78 | sub \$`8+16*4`,%rsp |
75 | mov %rsi,$inp # reassigned argument | 79 | mov %rsi,$inp # reassigned argument |
76 | and \$-64,%rsp | 80 | and \$-64,%rsp |
77 | mov %rdx,$num # reassigned argument | 81 | mov %rdx,$num # reassigned argument |
78 | mov %rax,`16*4`(%rsp) | 82 | mov %r11,`16*4`(%rsp) |
83 | .Lprologue: | ||
79 | 84 | ||
80 | mov 0($ctx),$A | 85 | mov 0($ctx),$A |
81 | mov 4($ctx),$B | 86 | mov 4($ctx),$B |
@@ -88,10 +93,12 @@ ___ | |||
88 | sub EPILOGUE { | 93 | sub EPILOGUE { |
89 | my $func=shift; | 94 | my $func=shift; |
90 | $code.=<<___; | 95 | $code.=<<___; |
91 | mov `16*4`(%rsp),%rsp | 96 | mov `16*4`(%rsp),%rsi |
92 | pop %r12 | 97 | mov (%rsi),%r12 |
93 | pop %rbp | 98 | mov 8(%rsi),%rbp |
94 | pop %rbx | 99 | mov 16(%rsi),%rbx |
100 | lea 24(%rsi),%rsp | ||
101 | .Lepilogue: | ||
95 | ret | 102 | ret |
96 | .size $func,.-$func | 103 | .size $func,.-$func |
97 | ___ | 104 | ___ |
@@ -233,7 +240,109 @@ ___ | |||
233 | &EPILOGUE("sha1_block_data_order"); | 240 | &EPILOGUE("sha1_block_data_order"); |
234 | $code.=<<___; | 241 | $code.=<<___; |
235 | .asciz "SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>" | 242 | .asciz "SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>" |
243 | .align 16 | ||
244 | ___ | ||
245 | |||
246 | # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, | ||
247 | # CONTEXT *context,DISPATCHER_CONTEXT *disp) | ||
248 | if ($win64) { | ||
249 | $rec="%rcx"; | ||
250 | $frame="%rdx"; | ||
251 | $context="%r8"; | ||
252 | $disp="%r9"; | ||
253 | |||
254 | $code.=<<___; | ||
255 | .extern __imp_RtlVirtualUnwind | ||
256 | .type se_handler,\@abi-omnipotent | ||
257 | .align 16 | ||
258 | se_handler: | ||
259 | push %rsi | ||
260 | push %rdi | ||
261 | push %rbx | ||
262 | push %rbp | ||
263 | push %r12 | ||
264 | push %r13 | ||
265 | push %r14 | ||
266 | push %r15 | ||
267 | pushfq | ||
268 | sub \$64,%rsp | ||
269 | |||
270 | mov 120($context),%rax # pull context->Rax | ||
271 | mov 248($context),%rbx # pull context->Rip | ||
272 | |||
273 | lea .Lprologue(%rip),%r10 | ||
274 | cmp %r10,%rbx # context->Rip<.Lprologue | ||
275 | jb .Lin_prologue | ||
276 | |||
277 | mov 152($context),%rax # pull context->Rsp | ||
278 | |||
279 | lea .Lepilogue(%rip),%r10 | ||
280 | cmp %r10,%rbx # context->Rip>=.Lepilogue | ||
281 | jae .Lin_prologue | ||
282 | |||
283 | mov `16*4`(%rax),%rax # pull saved stack pointer | ||
284 | lea 24(%rax),%rax | ||
285 | |||
286 | mov -8(%rax),%rbx | ||
287 | mov -16(%rax),%rbp | ||
288 | mov -24(%rax),%r12 | ||
289 | mov %rbx,144($context) # restore context->Rbx | ||
290 | mov %rbp,160($context) # restore context->Rbp | ||
291 | mov %r12,216($context) # restore context->R12 | ||
292 | |||
293 | .Lin_prologue: | ||
294 | mov 8(%rax),%rdi | ||
295 | mov 16(%rax),%rsi | ||
296 | mov %rax,152($context) # restore context->Rsp | ||
297 | mov %rsi,168($context) # restore context->Rsi | ||
298 | mov %rdi,176($context) # restore context->Rdi | ||
299 | |||
300 | mov 40($disp),%rdi # disp->ContextRecord | ||
301 | mov $context,%rsi # context | ||
302 | mov \$154,%ecx # sizeof(CONTEXT) | ||
303 | .long 0xa548f3fc # cld; rep movsq | ||
304 | |||
305 | mov $disp,%rsi | ||
306 | xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER | ||
307 | mov 8(%rsi),%rdx # arg2, disp->ImageBase | ||
308 | mov 0(%rsi),%r8 # arg3, disp->ControlPc | ||
309 | mov 16(%rsi),%r9 # arg4, disp->FunctionEntry | ||
310 | mov 40(%rsi),%r10 # disp->ContextRecord | ||
311 | lea 56(%rsi),%r11 # &disp->HandlerData | ||
312 | lea 24(%rsi),%r12 # &disp->EstablisherFrame | ||
313 | mov %r10,32(%rsp) # arg5 | ||
314 | mov %r11,40(%rsp) # arg6 | ||
315 | mov %r12,48(%rsp) # arg7 | ||
316 | mov %rcx,56(%rsp) # arg8, (NULL) | ||
317 | call *__imp_RtlVirtualUnwind(%rip) | ||
318 | |||
319 | mov \$1,%eax # ExceptionContinueSearch | ||
320 | add \$64,%rsp | ||
321 | popfq | ||
322 | pop %r15 | ||
323 | pop %r14 | ||
324 | pop %r13 | ||
325 | pop %r12 | ||
326 | pop %rbp | ||
327 | pop %rbx | ||
328 | pop %rdi | ||
329 | pop %rsi | ||
330 | ret | ||
331 | .size se_handler,.-se_handler | ||
332 | |||
333 | .section .pdata | ||
334 | .align 4 | ||
335 | .rva .LSEH_begin_sha1_block_data_order | ||
336 | .rva .LSEH_end_sha1_block_data_order | ||
337 | .rva .LSEH_info_sha1_block_data_order | ||
338 | |||
339 | .section .xdata | ||
340 | .align 8 | ||
341 | .LSEH_info_sha1_block_data_order: | ||
342 | .byte 9,0,0,0 | ||
343 | .rva se_handler | ||
236 | ___ | 344 | ___ |
345 | } | ||
237 | 346 | ||
238 | #################################################################### | 347 | #################################################################### |
239 | 348 | ||
diff --git a/src/lib/libcrypto/sha/asm/sha256-586.pl b/src/lib/libcrypto/sha/asm/sha256-586.pl new file mode 100644 index 0000000000..ecc8b69c75 --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha256-586.pl | |||
@@ -0,0 +1,251 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | # | ||
10 | # SHA256 block transform for x86. September 2007. | ||
11 | # | ||
12 | # Performance in clock cycles per processed byte (less is better): | ||
13 | # | ||
14 | # Pentium PIII P4 AMD K8 Core2 | ||
15 | # gcc 46 36 41 27 26 | ||
16 | # icc 57 33 38 25 23 | ||
17 | # x86 asm 40 30 35 20 20 | ||
18 | # x86_64 asm(*) - - 21 15.8 16.5 | ||
19 | # | ||
20 | # (*) x86_64 assembler performance is presented for reference | ||
21 | # purposes. | ||
22 | # | ||
23 | # Performance improvement over compiler generated code varies from | ||
24 | # 10% to 40% [see above]. Not very impressive on some µ-archs, but | ||
25 | # it's 5 times smaller and optimizies amount of writes. | ||
26 | |||
27 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | ||
28 | push(@INC,"${dir}","${dir}../../perlasm"); | ||
29 | require "x86asm.pl"; | ||
30 | |||
31 | &asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386"); | ||
32 | |||
33 | $A="eax"; | ||
34 | $E="edx"; | ||
35 | $T="ebx"; | ||
36 | $Aoff=&DWP(0,"esp"); | ||
37 | $Boff=&DWP(4,"esp"); | ||
38 | $Coff=&DWP(8,"esp"); | ||
39 | $Doff=&DWP(12,"esp"); | ||
40 | $Eoff=&DWP(16,"esp"); | ||
41 | $Foff=&DWP(20,"esp"); | ||
42 | $Goff=&DWP(24,"esp"); | ||
43 | $Hoff=&DWP(28,"esp"); | ||
44 | $Xoff=&DWP(32,"esp"); | ||
45 | $K256="ebp"; | ||
46 | |||
47 | sub BODY_00_15() { | ||
48 | my $in_16_63=shift; | ||
49 | |||
50 | &mov ("ecx",$E); | ||
51 | &add ($T,&DWP(4*(8+15+16-9),"esp")) if ($in_16_63); # T += X[-7] | ||
52 | &ror ("ecx",6); | ||
53 | &mov ("edi",$E); | ||
54 | &ror ("edi",11); | ||
55 | &mov ("esi",$Foff); | ||
56 | &xor ("ecx","edi"); | ||
57 | &ror ("edi",25-11); | ||
58 | &mov (&DWP(4*(8+15),"esp"),$T) if ($in_16_63); # save X[0] | ||
59 | &xor ("ecx","edi"); # Sigma1(e) | ||
60 | &mov ("edi",$Goff); | ||
61 | &add ($T,"ecx"); # T += Sigma1(e) | ||
62 | &mov ($Eoff,$E); # modulo-scheduled | ||
63 | |||
64 | &xor ("esi","edi"); | ||
65 | &mov ("ecx",$A); | ||
66 | &and ("esi",$E); | ||
67 | &mov ($E,$Doff); # e becomes d, which is e in next iteration | ||
68 | &xor ("esi","edi"); # Ch(e,f,g) | ||
69 | &mov ("edi",$A); | ||
70 | &add ($T,"esi"); # T += Ch(e,f,g) | ||
71 | |||
72 | &ror ("ecx",2); | ||
73 | &add ($T,$Hoff); # T += h | ||
74 | &ror ("edi",13); | ||
75 | &mov ("esi",$Boff); | ||
76 | &xor ("ecx","edi"); | ||
77 | &ror ("edi",22-13); | ||
78 | &add ($E,$T); # d += T | ||
79 | &xor ("ecx","edi"); # Sigma0(a) | ||
80 | &mov ("edi",$Coff); | ||
81 | |||
82 | &add ($T,"ecx"); # T += Sigma0(a) | ||
83 | &mov ($Aoff,$A); # modulo-scheduled | ||
84 | |||
85 | &mov ("ecx",$A); | ||
86 | &sub ("esp",4); | ||
87 | &or ($A,"esi"); # a becomes h, which is a in next iteration | ||
88 | &and ("ecx","esi"); | ||
89 | &and ($A,"edi"); | ||
90 | &mov ("esi",&DWP(0,$K256)); | ||
91 | &or ($A,"ecx"); # h=Maj(a,b,c) | ||
92 | |||
93 | &add ($K256,4); | ||
94 | &add ($A,$T); # h += T | ||
95 | &mov ($T,&DWP(4*(8+15+16-1),"esp")) if ($in_16_63); # preload T | ||
96 | &add ($E,"esi"); # d += K256[i] | ||
97 | &add ($A,"esi"); # h += K256[i] | ||
98 | } | ||
99 | |||
100 | &function_begin("sha256_block_data_order"); | ||
101 | &mov ("esi",wparam(0)); # ctx | ||
102 | &mov ("edi",wparam(1)); # inp | ||
103 | &mov ("eax",wparam(2)); # num | ||
104 | &mov ("ebx","esp"); # saved sp | ||
105 | |||
106 | &call (&label("pic_point")); # make it PIC! | ||
107 | &set_label("pic_point"); | ||
108 | &blindpop($K256); | ||
109 | &lea ($K256,&DWP(&label("K256")."-".&label("pic_point"),$K256)); | ||
110 | |||
111 | &sub ("esp",16); | ||
112 | &and ("esp",-64); | ||
113 | |||
114 | &shl ("eax",6); | ||
115 | &add ("eax","edi"); | ||
116 | &mov (&DWP(0,"esp"),"esi"); # ctx | ||
117 | &mov (&DWP(4,"esp"),"edi"); # inp | ||
118 | &mov (&DWP(8,"esp"),"eax"); # inp+num*128 | ||
119 | &mov (&DWP(12,"esp"),"ebx"); # saved sp | ||
120 | |||
121 | &set_label("loop",16); | ||
122 | # copy input block to stack reversing byte and dword order | ||
123 | for($i=0;$i<4;$i++) { | ||
124 | &mov ("eax",&DWP($i*16+0,"edi")); | ||
125 | &mov ("ebx",&DWP($i*16+4,"edi")); | ||
126 | &mov ("ecx",&DWP($i*16+8,"edi")); | ||
127 | &mov ("edx",&DWP($i*16+12,"edi")); | ||
128 | &bswap ("eax"); | ||
129 | &bswap ("ebx"); | ||
130 | &bswap ("ecx"); | ||
131 | &bswap ("edx"); | ||
132 | &push ("eax"); | ||
133 | &push ("ebx"); | ||
134 | &push ("ecx"); | ||
135 | &push ("edx"); | ||
136 | } | ||
137 | &add ("edi",64); | ||
138 | &sub ("esp",4*8); # place for A,B,C,D,E,F,G,H | ||
139 | &mov (&DWP(4*(8+16)+4,"esp"),"edi"); | ||
140 | |||
141 | # copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack | ||
142 | &mov ($A,&DWP(0,"esi")); | ||
143 | &mov ("ebx",&DWP(4,"esi")); | ||
144 | &mov ("ecx",&DWP(8,"esi")); | ||
145 | &mov ("edi",&DWP(12,"esi")); | ||
146 | # &mov ($Aoff,$A); | ||
147 | &mov ($Boff,"ebx"); | ||
148 | &mov ($Coff,"ecx"); | ||
149 | &mov ($Doff,"edi"); | ||
150 | &mov ($E,&DWP(16,"esi")); | ||
151 | &mov ("ebx",&DWP(20,"esi")); | ||
152 | &mov ("ecx",&DWP(24,"esi")); | ||
153 | &mov ("edi",&DWP(28,"esi")); | ||
154 | # &mov ($Eoff,$E); | ||
155 | &mov ($Foff,"ebx"); | ||
156 | &mov ($Goff,"ecx"); | ||
157 | &mov ($Hoff,"edi"); | ||
158 | |||
159 | &set_label("00_15",16); | ||
160 | &mov ($T,&DWP(4*(8+15),"esp")); | ||
161 | |||
162 | &BODY_00_15(); | ||
163 | |||
164 | &cmp ("esi",0xc19bf174); | ||
165 | &jne (&label("00_15")); | ||
166 | |||
167 | &mov ($T,&DWP(4*(8+15+16-1),"esp")); # preloaded in BODY_00_15(1) | ||
168 | &set_label("16_63",16); | ||
169 | &mov ("esi",$T); | ||
170 | &mov ("ecx",&DWP(4*(8+15+16-14),"esp")); | ||
171 | &shr ($T,3); | ||
172 | &ror ("esi",7); | ||
173 | &xor ($T,"esi"); | ||
174 | &ror ("esi",18-7); | ||
175 | &mov ("edi","ecx"); | ||
176 | &xor ($T,"esi"); # T = sigma0(X[-15]) | ||
177 | |||
178 | &shr ("ecx",10); | ||
179 | &mov ("esi",&DWP(4*(8+15+16),"esp")); | ||
180 | &ror ("edi",17); | ||
181 | &xor ("ecx","edi"); | ||
182 | &ror ("edi",19-17); | ||
183 | &add ($T,"esi"); # T += X[-16] | ||
184 | &xor ("edi","ecx") # sigma1(X[-2]) | ||
185 | |||
186 | &add ($T,"edi"); # T += sigma1(X[-2]) | ||
187 | # &add ($T,&DWP(4*(8+15+16-9),"esp")); # T += X[-7], moved to BODY_00_15(1) | ||
188 | # &mov (&DWP(4*(8+15),"esp"),$T); # save X[0] | ||
189 | |||
190 | &BODY_00_15(1); | ||
191 | |||
192 | &cmp ("esi",0xc67178f2); | ||
193 | &jne (&label("16_63")); | ||
194 | |||
195 | &mov ("esi",&DWP(4*(8+16+64)+0,"esp"));#ctx | ||
196 | # &mov ($A,$Aoff); | ||
197 | &mov ("ebx",$Boff); | ||
198 | &mov ("ecx",$Coff); | ||
199 | &mov ("edi",$Doff); | ||
200 | &add ($A,&DWP(0,"esi")); | ||
201 | &add ("ebx",&DWP(4,"esi")); | ||
202 | &add ("ecx",&DWP(8,"esi")); | ||
203 | &add ("edi",&DWP(12,"esi")); | ||
204 | &mov (&DWP(0,"esi"),$A); | ||
205 | &mov (&DWP(4,"esi"),"ebx"); | ||
206 | &mov (&DWP(8,"esi"),"ecx"); | ||
207 | &mov (&DWP(12,"esi"),"edi"); | ||
208 | # &mov ($E,$Eoff); | ||
209 | &mov ("eax",$Foff); | ||
210 | &mov ("ebx",$Goff); | ||
211 | &mov ("ecx",$Hoff); | ||
212 | &mov ("edi",&DWP(4*(8+16+64)+4,"esp"));#inp | ||
213 | &add ($E,&DWP(16,"esi")); | ||
214 | &add ("eax",&DWP(20,"esi")); | ||
215 | &add ("ebx",&DWP(24,"esi")); | ||
216 | &add ("ecx",&DWP(28,"esi")); | ||
217 | &mov (&DWP(16,"esi"),$E); | ||
218 | &mov (&DWP(20,"esi"),"eax"); | ||
219 | &mov (&DWP(24,"esi"),"ebx"); | ||
220 | &mov (&DWP(28,"esi"),"ecx"); | ||
221 | |||
222 | &add ("esp",4*(8+16+64)); # destroy frame | ||
223 | &sub ($K256,4*64); # rewind K | ||
224 | |||
225 | &cmp ("edi",&DWP(8,"esp")); # are we done yet? | ||
226 | &jb (&label("loop")); | ||
227 | |||
228 | &mov ("esp",&DWP(12,"esp")); # restore sp | ||
229 | &function_end_A(); | ||
230 | |||
231 | &set_label("K256",64); # Yes! I keep it in the code segment! | ||
232 | &data_word(0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5); | ||
233 | &data_word(0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5); | ||
234 | &data_word(0xd807aa98,0x12835b01,0x243185be,0x550c7dc3); | ||
235 | &data_word(0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174); | ||
236 | &data_word(0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc); | ||
237 | &data_word(0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da); | ||
238 | &data_word(0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7); | ||
239 | &data_word(0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967); | ||
240 | &data_word(0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13); | ||
241 | &data_word(0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85); | ||
242 | &data_word(0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3); | ||
243 | &data_word(0xd192e819,0xd6990624,0xf40e3585,0x106aa070); | ||
244 | &data_word(0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5); | ||
245 | &data_word(0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3); | ||
246 | &data_word(0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208); | ||
247 | &data_word(0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2); | ||
248 | &function_end_B("sha256_block_data_order"); | ||
249 | &asciz("SHA256 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>"); | ||
250 | |||
251 | &asm_finish(); | ||
diff --git a/src/lib/libcrypto/sha/asm/sha256-armv4.pl b/src/lib/libcrypto/sha/asm/sha256-armv4.pl new file mode 100644 index 0000000000..48d846deec --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha256-armv4.pl | |||
@@ -0,0 +1,181 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # SHA256 block procedure for ARMv4. May 2007. | ||
11 | |||
12 | # Performance is ~2x better than gcc 3.4 generated code and in "abso- | ||
13 | # lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per | ||
14 | # byte. | ||
15 | |||
16 | $output=shift; | ||
17 | open STDOUT,">$output"; | ||
18 | |||
19 | $ctx="r0"; $t0="r0"; | ||
20 | $inp="r1"; | ||
21 | $len="r2"; $t1="r2"; | ||
22 | $T1="r3"; | ||
23 | $A="r4"; | ||
24 | $B="r5"; | ||
25 | $C="r6"; | ||
26 | $D="r7"; | ||
27 | $E="r8"; | ||
28 | $F="r9"; | ||
29 | $G="r10"; | ||
30 | $H="r11"; | ||
31 | @V=($A,$B,$C,$D,$E,$F,$G,$H); | ||
32 | $t2="r12"; | ||
33 | $Ktbl="r14"; | ||
34 | |||
35 | @Sigma0=( 2,13,22); | ||
36 | @Sigma1=( 6,11,25); | ||
37 | @sigma0=( 7,18, 3); | ||
38 | @sigma1=(17,19,10); | ||
39 | |||
40 | sub BODY_00_15 { | ||
41 | my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; | ||
42 | |||
43 | $code.=<<___ if ($i<16); | ||
44 | ldrb $T1,[$inp,#3] @ $i | ||
45 | ldrb $t2,[$inp,#2] | ||
46 | ldrb $t1,[$inp,#1] | ||
47 | ldrb $t0,[$inp],#4 | ||
48 | orr $T1,$T1,$t2,lsl#8 | ||
49 | orr $T1,$T1,$t1,lsl#16 | ||
50 | orr $T1,$T1,$t0,lsl#24 | ||
51 | `"str $inp,[sp,#17*4]" if ($i==15)` | ||
52 | ___ | ||
53 | $code.=<<___; | ||
54 | ldr $t2,[$Ktbl],#4 @ *K256++ | ||
55 | str $T1,[sp,#`$i%16`*4] | ||
56 | mov $t0,$e,ror#$Sigma1[0] | ||
57 | eor $t0,$t0,$e,ror#$Sigma1[1] | ||
58 | eor $t0,$t0,$e,ror#$Sigma1[2] @ Sigma1(e) | ||
59 | add $T1,$T1,$t0 | ||
60 | eor $t1,$f,$g | ||
61 | and $t1,$t1,$e | ||
62 | eor $t1,$t1,$g @ Ch(e,f,g) | ||
63 | add $T1,$T1,$t1 | ||
64 | add $T1,$T1,$h | ||
65 | add $T1,$T1,$t2 | ||
66 | mov $h,$a,ror#$Sigma0[0] | ||
67 | eor $h,$h,$a,ror#$Sigma0[1] | ||
68 | eor $h,$h,$a,ror#$Sigma0[2] @ Sigma0(a) | ||
69 | orr $t0,$a,$b | ||
70 | and $t0,$t0,$c | ||
71 | and $t1,$a,$b | ||
72 | orr $t0,$t0,$t1 @ Maj(a,b,c) | ||
73 | add $h,$h,$t0 | ||
74 | add $d,$d,$T1 | ||
75 | add $h,$h,$T1 | ||
76 | ___ | ||
77 | } | ||
78 | |||
79 | sub BODY_16_XX { | ||
80 | my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; | ||
81 | |||
82 | $code.=<<___; | ||
83 | ldr $t1,[sp,#`($i+1)%16`*4] @ $i | ||
84 | ldr $t2,[sp,#`($i+14)%16`*4] | ||
85 | ldr $T1,[sp,#`($i+0)%16`*4] | ||
86 | ldr $inp,[sp,#`($i+9)%16`*4] | ||
87 | mov $t0,$t1,ror#$sigma0[0] | ||
88 | eor $t0,$t0,$t1,ror#$sigma0[1] | ||
89 | eor $t0,$t0,$t1,lsr#$sigma0[2] @ sigma0(X[i+1]) | ||
90 | mov $t1,$t2,ror#$sigma1[0] | ||
91 | eor $t1,$t1,$t2,ror#$sigma1[1] | ||
92 | eor $t1,$t1,$t2,lsr#$sigma1[2] @ sigma1(X[i+14]) | ||
93 | add $T1,$T1,$t0 | ||
94 | add $T1,$T1,$t1 | ||
95 | add $T1,$T1,$inp | ||
96 | ___ | ||
97 | &BODY_00_15(@_); | ||
98 | } | ||
99 | |||
100 | $code=<<___; | ||
101 | .text | ||
102 | .code 32 | ||
103 | |||
104 | .type K256,%object | ||
105 | .align 5 | ||
106 | K256: | ||
107 | .word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 | ||
108 | .word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 | ||
109 | .word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 | ||
110 | .word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 | ||
111 | .word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc | ||
112 | .word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da | ||
113 | .word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 | ||
114 | .word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 | ||
115 | .word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 | ||
116 | .word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 | ||
117 | .word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 | ||
118 | .word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 | ||
119 | .word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 | ||
120 | .word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 | ||
121 | .word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 | ||
122 | .word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 | ||
123 | .size K256,.-K256 | ||
124 | |||
125 | .global sha256_block_data_order | ||
126 | .type sha256_block_data_order,%function | ||
127 | sha256_block_data_order: | ||
128 | sub r3,pc,#8 @ sha256_block_data_order | ||
129 | add $len,$inp,$len,lsl#6 @ len to point at the end of inp | ||
130 | stmdb sp!,{$ctx,$inp,$len,r4-r12,lr} | ||
131 | ldmia $ctx,{$A,$B,$C,$D,$E,$F,$G,$H} | ||
132 | sub $Ktbl,r3,#256 @ K256 | ||
133 | sub sp,sp,#16*4 @ alloca(X[16]) | ||
134 | .Loop: | ||
135 | ___ | ||
136 | for($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } | ||
137 | $code.=".Lrounds_16_xx:\n"; | ||
138 | for (;$i<32;$i++) { &BODY_16_XX($i,@V); unshift(@V,pop(@V)); } | ||
139 | $code.=<<___; | ||
140 | and $t2,$t2,#0xff | ||
141 | cmp $t2,#0xf2 | ||
142 | bne .Lrounds_16_xx | ||
143 | |||
144 | ldr $T1,[sp,#16*4] @ pull ctx | ||
145 | ldr $t0,[$T1,#0] | ||
146 | ldr $t1,[$T1,#4] | ||
147 | ldr $t2,[$T1,#8] | ||
148 | add $A,$A,$t0 | ||
149 | ldr $t0,[$T1,#12] | ||
150 | add $B,$B,$t1 | ||
151 | ldr $t1,[$T1,#16] | ||
152 | add $C,$C,$t2 | ||
153 | ldr $t2,[$T1,#20] | ||
154 | add $D,$D,$t0 | ||
155 | ldr $t0,[$T1,#24] | ||
156 | add $E,$E,$t1 | ||
157 | ldr $t1,[$T1,#28] | ||
158 | add $F,$F,$t2 | ||
159 | ldr $inp,[sp,#17*4] @ pull inp | ||
160 | ldr $t2,[sp,#18*4] @ pull inp+len | ||
161 | add $G,$G,$t0 | ||
162 | add $H,$H,$t1 | ||
163 | stmia $T1,{$A,$B,$C,$D,$E,$F,$G,$H} | ||
164 | cmp $inp,$t2 | ||
165 | sub $Ktbl,$Ktbl,#256 @ rewind Ktbl | ||
166 | bne .Loop | ||
167 | |||
168 | add sp,sp,#`16+3`*4 @ destroy frame | ||
169 | ldmia sp!,{r4-r12,lr} | ||
170 | tst lr,#1 | ||
171 | moveq pc,lr @ be binary compatible with V4, yet | ||
172 | bx lr @ interoperable with Thumb ISA:-) | ||
173 | .size sha256_block_data_order,.-sha256_block_data_order | ||
174 | .asciz "SHA256 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>" | ||
175 | .align 2 | ||
176 | ___ | ||
177 | |||
178 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
179 | $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 | ||
180 | print $code; | ||
181 | close STDOUT; # enforce flush | ||
diff --git a/src/lib/libcrypto/sha/asm/sha512-586.pl b/src/lib/libcrypto/sha/asm/sha512-586.pl new file mode 100644 index 0000000000..5b9f3337ad --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha512-586.pl | |||
@@ -0,0 +1,644 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | # | ||
10 | # SHA512 block transform for x86. September 2007. | ||
11 | # | ||
12 | # Performance in clock cycles per processed byte (less is better): | ||
13 | # | ||
14 | # Pentium PIII P4 AMD K8 Core2 | ||
15 | # gcc 100 75 116 54 66 | ||
16 | # icc 97 77 95 55 57 | ||
17 | # x86 asm 61 56 82 36 40 | ||
18 | # SSE2 asm - - 38 24 20 | ||
19 | # x86_64 asm(*) - - 30 10.0 10.5 | ||
20 | # | ||
21 | # (*) x86_64 assembler performance is presented for reference | ||
22 | # purposes. | ||
23 | # | ||
24 | # IALU code-path is optimized for elder Pentiums. On vanilla Pentium | ||
25 | # performance improvement over compiler generated code reaches ~60%, | ||
26 | # while on PIII - ~35%. On newer µ-archs improvement varies from 15% | ||
27 | # to 50%, but it's less important as they are expected to execute SSE2 | ||
28 | # code-path, which is commonly ~2-3x faster [than compiler generated | ||
29 | # code]. SSE2 code-path is as fast as original sha512-sse2.pl, even | ||
30 | # though it does not use 128-bit operations. The latter means that | ||
31 | # SSE2-aware kernel is no longer required to execute the code. Another | ||
32 | # difference is that new code optimizes amount of writes, but at the | ||
33 | # cost of increased data cache "footprint" by 1/2KB. | ||
34 | |||
35 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | ||
36 | push(@INC,"${dir}","${dir}../../perlasm"); | ||
37 | require "x86asm.pl"; | ||
38 | |||
39 | &asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386"); | ||
40 | |||
41 | $sse2=0; | ||
42 | for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | ||
43 | |||
44 | &external_label("OPENSSL_ia32cap_P") if ($sse2); | ||
45 | |||
46 | $Tlo=&DWP(0,"esp"); $Thi=&DWP(4,"esp"); | ||
47 | $Alo=&DWP(8,"esp"); $Ahi=&DWP(8+4,"esp"); | ||
48 | $Blo=&DWP(16,"esp"); $Bhi=&DWP(16+4,"esp"); | ||
49 | $Clo=&DWP(24,"esp"); $Chi=&DWP(24+4,"esp"); | ||
50 | $Dlo=&DWP(32,"esp"); $Dhi=&DWP(32+4,"esp"); | ||
51 | $Elo=&DWP(40,"esp"); $Ehi=&DWP(40+4,"esp"); | ||
52 | $Flo=&DWP(48,"esp"); $Fhi=&DWP(48+4,"esp"); | ||
53 | $Glo=&DWP(56,"esp"); $Ghi=&DWP(56+4,"esp"); | ||
54 | $Hlo=&DWP(64,"esp"); $Hhi=&DWP(64+4,"esp"); | ||
55 | $K512="ebp"; | ||
56 | |||
57 | $Asse2=&QWP(0,"esp"); | ||
58 | $Bsse2=&QWP(8,"esp"); | ||
59 | $Csse2=&QWP(16,"esp"); | ||
60 | $Dsse2=&QWP(24,"esp"); | ||
61 | $Esse2=&QWP(32,"esp"); | ||
62 | $Fsse2=&QWP(40,"esp"); | ||
63 | $Gsse2=&QWP(48,"esp"); | ||
64 | $Hsse2=&QWP(56,"esp"); | ||
65 | |||
66 | $A="mm0"; # B-D and | ||
67 | $E="mm4"; # F-H are commonly loaded to respectively mm1-mm3 and | ||
68 | # mm5-mm7, but it's done on on-demand basis... | ||
69 | |||
70 | sub BODY_00_15_sse2 { | ||
71 | my $prefetch=shift; | ||
72 | |||
73 | &movq ("mm5",$Fsse2); # load f | ||
74 | &movq ("mm6",$Gsse2); # load g | ||
75 | &movq ("mm7",$Hsse2); # load h | ||
76 | |||
77 | &movq ("mm1",$E); # %mm1 is sliding right | ||
78 | &movq ("mm2",$E); # %mm2 is sliding left | ||
79 | &psrlq ("mm1",14); | ||
80 | &movq ($Esse2,$E); # modulo-scheduled save e | ||
81 | &psllq ("mm2",23); | ||
82 | &movq ("mm3","mm1"); # %mm3 is T1 | ||
83 | &psrlq ("mm1",4); | ||
84 | &pxor ("mm3","mm2"); | ||
85 | &psllq ("mm2",23); | ||
86 | &pxor ("mm3","mm1"); | ||
87 | &psrlq ("mm1",23); | ||
88 | &pxor ("mm3","mm2"); | ||
89 | &psllq ("mm2",4); | ||
90 | &pxor ("mm3","mm1"); | ||
91 | &paddq ("mm7",QWP(0,$K512)); # h+=K512[i] | ||
92 | &pxor ("mm3","mm2"); # T1=Sigma1_512(e) | ||
93 | |||
94 | &pxor ("mm5","mm6"); # f^=g | ||
95 | &movq ("mm1",$Bsse2); # load b | ||
96 | &pand ("mm5",$E); # f&=e | ||
97 | &movq ("mm2",$Csse2); # load c | ||
98 | &pxor ("mm5","mm6"); # f^=g | ||
99 | &movq ($E,$Dsse2); # e = load d | ||
100 | &paddq ("mm3","mm5"); # T1+=Ch(e,f,g) | ||
101 | &movq (&QWP(0,"esp"),$A); # modulo-scheduled save a | ||
102 | &paddq ("mm3","mm7"); # T1+=h | ||
103 | |||
104 | &movq ("mm5",$A); # %mm5 is sliding right | ||
105 | &movq ("mm6",$A); # %mm6 is sliding left | ||
106 | &paddq ("mm3",&QWP(8*9,"esp")); # T1+=X[0] | ||
107 | &psrlq ("mm5",28); | ||
108 | &paddq ($E,"mm3"); # e += T1 | ||
109 | &psllq ("mm6",25); | ||
110 | &movq ("mm7","mm5"); # %mm7 is T2 | ||
111 | &psrlq ("mm5",6); | ||
112 | &pxor ("mm7","mm6"); | ||
113 | &psllq ("mm6",5); | ||
114 | &pxor ("mm7","mm5"); | ||
115 | &psrlq ("mm5",5); | ||
116 | &pxor ("mm7","mm6"); | ||
117 | &psllq ("mm6",6); | ||
118 | &pxor ("mm7","mm5"); | ||
119 | &sub ("esp",8); | ||
120 | &pxor ("mm7","mm6"); # T2=Sigma0_512(a) | ||
121 | |||
122 | &movq ("mm5",$A); # %mm5=a | ||
123 | &por ($A,"mm2"); # a=a|c | ||
124 | &movq ("mm6",&QWP(8*(9+16-14),"esp")) if ($prefetch); | ||
125 | &pand ("mm5","mm2"); # %mm5=a&c | ||
126 | &pand ($A,"mm1"); # a=(a|c)&b | ||
127 | &movq ("mm2",&QWP(8*(9+16-1),"esp")) if ($prefetch); | ||
128 | &por ("mm5",$A); # %mm5=(a&c)|((a|c)&b) | ||
129 | &paddq ("mm7","mm5"); # T2+=Maj(a,b,c) | ||
130 | &movq ($A,"mm3"); # a=T1 | ||
131 | |||
132 | &mov (&LB("edx"),&BP(0,$K512)); | ||
133 | &paddq ($A,"mm7"); # a+=T2 | ||
134 | &add ($K512,8); | ||
135 | } | ||
136 | |||
137 | sub BODY_00_15_x86 { | ||
138 | #define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) | ||
139 | # LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 | ||
140 | # HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 | ||
141 | &mov ("ecx",$Elo); | ||
142 | &mov ("edx",$Ehi); | ||
143 | &mov ("esi","ecx"); | ||
144 | |||
145 | &shr ("ecx",9) # lo>>9 | ||
146 | &mov ("edi","edx"); | ||
147 | &shr ("edx",9) # hi>>9 | ||
148 | &mov ("ebx","ecx"); | ||
149 | &shl ("esi",14); # lo<<14 | ||
150 | &mov ("eax","edx"); | ||
151 | &shl ("edi",14); # hi<<14 | ||
152 | &xor ("ebx","esi"); | ||
153 | |||
154 | &shr ("ecx",14-9); # lo>>14 | ||
155 | &xor ("eax","edi"); | ||
156 | &shr ("edx",14-9); # hi>>14 | ||
157 | &xor ("eax","ecx"); | ||
158 | &shl ("esi",18-14); # lo<<18 | ||
159 | &xor ("ebx","edx"); | ||
160 | &shl ("edi",18-14); # hi<<18 | ||
161 | &xor ("ebx","esi"); | ||
162 | |||
163 | &shr ("ecx",18-14); # lo>>18 | ||
164 | &xor ("eax","edi"); | ||
165 | &shr ("edx",18-14); # hi>>18 | ||
166 | &xor ("eax","ecx"); | ||
167 | &shl ("esi",23-18); # lo<<23 | ||
168 | &xor ("ebx","edx"); | ||
169 | &shl ("edi",23-18); # hi<<23 | ||
170 | &xor ("eax","esi"); | ||
171 | &xor ("ebx","edi"); # T1 = Sigma1(e) | ||
172 | |||
173 | &mov ("ecx",$Flo); | ||
174 | &mov ("edx",$Fhi); | ||
175 | &mov ("esi",$Glo); | ||
176 | &mov ("edi",$Ghi); | ||
177 | &add ("eax",$Hlo); | ||
178 | &adc ("ebx",$Hhi); # T1 += h | ||
179 | &xor ("ecx","esi"); | ||
180 | &xor ("edx","edi"); | ||
181 | &and ("ecx",$Elo); | ||
182 | &and ("edx",$Ehi); | ||
183 | &add ("eax",&DWP(8*(9+15)+0,"esp")); | ||
184 | &adc ("ebx",&DWP(8*(9+15)+4,"esp")); # T1 += X[0] | ||
185 | &xor ("ecx","esi"); | ||
186 | &xor ("edx","edi"); # Ch(e,f,g) = (f^g)&e)^g | ||
187 | |||
188 | &mov ("esi",&DWP(0,$K512)); | ||
189 | &mov ("edi",&DWP(4,$K512)); # K[i] | ||
190 | &add ("eax","ecx"); | ||
191 | &adc ("ebx","edx"); # T1 += Ch(e,f,g) | ||
192 | &mov ("ecx",$Dlo); | ||
193 | &mov ("edx",$Dhi); | ||
194 | &add ("eax","esi"); | ||
195 | &adc ("ebx","edi"); # T1 += K[i] | ||
196 | &mov ($Tlo,"eax"); | ||
197 | &mov ($Thi,"ebx"); # put T1 away | ||
198 | &add ("eax","ecx"); | ||
199 | &adc ("ebx","edx"); # d += T1 | ||
200 | |||
201 | #define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) | ||
202 | # LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 | ||
203 | # HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 | ||
204 | &mov ("ecx",$Alo); | ||
205 | &mov ("edx",$Ahi); | ||
206 | &mov ($Dlo,"eax"); | ||
207 | &mov ($Dhi,"ebx"); | ||
208 | &mov ("esi","ecx"); | ||
209 | |||
210 | &shr ("ecx",2) # lo>>2 | ||
211 | &mov ("edi","edx"); | ||
212 | &shr ("edx",2) # hi>>2 | ||
213 | &mov ("ebx","ecx"); | ||
214 | &shl ("esi",4); # lo<<4 | ||
215 | &mov ("eax","edx"); | ||
216 | &shl ("edi",4); # hi<<4 | ||
217 | &xor ("ebx","esi"); | ||
218 | |||
219 | &shr ("ecx",7-2); # lo>>7 | ||
220 | &xor ("eax","edi"); | ||
221 | &shr ("edx",7-2); # hi>>7 | ||
222 | &xor ("ebx","ecx"); | ||
223 | &shl ("esi",25-4); # lo<<25 | ||
224 | &xor ("eax","edx"); | ||
225 | &shl ("edi",25-4); # hi<<25 | ||
226 | &xor ("eax","esi"); | ||
227 | |||
228 | &shr ("ecx",28-7); # lo>>28 | ||
229 | &xor ("ebx","edi"); | ||
230 | &shr ("edx",28-7); # hi>>28 | ||
231 | &xor ("eax","ecx"); | ||
232 | &shl ("esi",30-25); # lo<<30 | ||
233 | &xor ("ebx","edx"); | ||
234 | &shl ("edi",30-25); # hi<<30 | ||
235 | &xor ("eax","esi"); | ||
236 | &xor ("ebx","edi"); # Sigma0(a) | ||
237 | |||
238 | &mov ("ecx",$Alo); | ||
239 | &mov ("edx",$Ahi); | ||
240 | &mov ("esi",$Blo); | ||
241 | &mov ("edi",$Bhi); | ||
242 | &add ("eax",$Tlo); | ||
243 | &adc ("ebx",$Thi); # T1 = Sigma0(a)+T1 | ||
244 | &or ("ecx","esi"); | ||
245 | &or ("edx","edi"); | ||
246 | &and ("ecx",$Clo); | ||
247 | &and ("edx",$Chi); | ||
248 | &and ("esi",$Alo); | ||
249 | &and ("edi",$Ahi); | ||
250 | &or ("ecx","esi"); | ||
251 | &or ("edx","edi"); # Maj(a,b,c) = ((a|b)&c)|(a&b) | ||
252 | |||
253 | &add ("eax","ecx"); | ||
254 | &adc ("ebx","edx"); # T1 += Maj(a,b,c) | ||
255 | &mov ($Tlo,"eax"); | ||
256 | &mov ($Thi,"ebx"); | ||
257 | |||
258 | &mov (&LB("edx"),&BP(0,$K512)); # pre-fetch LSB of *K | ||
259 | &sub ("esp",8); | ||
260 | &lea ($K512,&DWP(8,$K512)); # K++ | ||
261 | } | ||
262 | |||
263 | |||
264 | &function_begin("sha512_block_data_order"); | ||
265 | &mov ("esi",wparam(0)); # ctx | ||
266 | &mov ("edi",wparam(1)); # inp | ||
267 | &mov ("eax",wparam(2)); # num | ||
268 | &mov ("ebx","esp"); # saved sp | ||
269 | |||
270 | &call (&label("pic_point")); # make it PIC! | ||
271 | &set_label("pic_point"); | ||
272 | &blindpop($K512); | ||
273 | &lea ($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512)); | ||
274 | |||
275 | &sub ("esp",16); | ||
276 | &and ("esp",-64); | ||
277 | |||
278 | &shl ("eax",7); | ||
279 | &add ("eax","edi"); | ||
280 | &mov (&DWP(0,"esp"),"esi"); # ctx | ||
281 | &mov (&DWP(4,"esp"),"edi"); # inp | ||
282 | &mov (&DWP(8,"esp"),"eax"); # inp+num*128 | ||
283 | &mov (&DWP(12,"esp"),"ebx"); # saved sp | ||
284 | |||
285 | if ($sse2) { | ||
286 | &picmeup("edx","OPENSSL_ia32cap_P",$K512,&label("K512")); | ||
287 | &bt (&DWP(0,"edx"),26); | ||
288 | &jnc (&label("loop_x86")); | ||
289 | |||
290 | # load ctx->h[0-7] | ||
291 | &movq ($A,&QWP(0,"esi")); | ||
292 | &movq ("mm1",&QWP(8,"esi")); | ||
293 | &movq ("mm2",&QWP(16,"esi")); | ||
294 | &movq ("mm3",&QWP(24,"esi")); | ||
295 | &movq ($E,&QWP(32,"esi")); | ||
296 | &movq ("mm5",&QWP(40,"esi")); | ||
297 | &movq ("mm6",&QWP(48,"esi")); | ||
298 | &movq ("mm7",&QWP(56,"esi")); | ||
299 | &sub ("esp",8*10); | ||
300 | |||
301 | &set_label("loop_sse2",16); | ||
302 | # &movq ($Asse2,$A); | ||
303 | &movq ($Bsse2,"mm1"); | ||
304 | &movq ($Csse2,"mm2"); | ||
305 | &movq ($Dsse2,"mm3"); | ||
306 | # &movq ($Esse2,$E); | ||
307 | &movq ($Fsse2,"mm5"); | ||
308 | &movq ($Gsse2,"mm6"); | ||
309 | &movq ($Hsse2,"mm7"); | ||
310 | |||
311 | &mov ("ecx",&DWP(0,"edi")); | ||
312 | &mov ("edx",&DWP(4,"edi")); | ||
313 | &add ("edi",8); | ||
314 | &bswap ("ecx"); | ||
315 | &bswap ("edx"); | ||
316 | &mov (&DWP(8*9+4,"esp"),"ecx"); | ||
317 | &mov (&DWP(8*9+0,"esp"),"edx"); | ||
318 | |||
319 | &set_label("00_14_sse2",16); | ||
320 | &mov ("eax",&DWP(0,"edi")); | ||
321 | &mov ("ebx",&DWP(4,"edi")); | ||
322 | &add ("edi",8); | ||
323 | &bswap ("eax"); | ||
324 | &bswap ("ebx"); | ||
325 | &mov (&DWP(8*8+4,"esp"),"eax"); | ||
326 | &mov (&DWP(8*8+0,"esp"),"ebx"); | ||
327 | |||
328 | &BODY_00_15_sse2(); | ||
329 | |||
330 | &cmp (&LB("edx"),0x35); | ||
331 | &jne (&label("00_14_sse2")); | ||
332 | |||
333 | &BODY_00_15_sse2(1); | ||
334 | |||
335 | &set_label("16_79_sse2",16); | ||
336 | #&movq ("mm2",&QWP(8*(9+16-1),"esp")); #prefetched in BODY_00_15 | ||
337 | #&movq ("mm6",&QWP(8*(9+16-14),"esp")); | ||
338 | &movq ("mm1","mm2"); | ||
339 | |||
340 | &psrlq ("mm2",1); | ||
341 | &movq ("mm7","mm6"); | ||
342 | &psrlq ("mm6",6); | ||
343 | &movq ("mm3","mm2"); | ||
344 | |||
345 | &psrlq ("mm2",7-1); | ||
346 | &movq ("mm5","mm6"); | ||
347 | &psrlq ("mm6",19-6); | ||
348 | &pxor ("mm3","mm2"); | ||
349 | |||
350 | &psrlq ("mm2",8-7); | ||
351 | &pxor ("mm5","mm6"); | ||
352 | &psrlq ("mm6",61-19); | ||
353 | &pxor ("mm3","mm2"); | ||
354 | |||
355 | &movq ("mm2",&QWP(8*(9+16),"esp")); | ||
356 | |||
357 | &psllq ("mm1",56); | ||
358 | &pxor ("mm5","mm6"); | ||
359 | &psllq ("mm7",3); | ||
360 | &pxor ("mm3","mm1"); | ||
361 | |||
362 | &paddq ("mm2",&QWP(8*(9+16-9),"esp")); | ||
363 | |||
364 | &psllq ("mm1",63-56); | ||
365 | &pxor ("mm5","mm7"); | ||
366 | &psllq ("mm7",45-3); | ||
367 | &pxor ("mm3","mm1"); | ||
368 | &pxor ("mm5","mm7"); | ||
369 | |||
370 | &paddq ("mm3","mm5"); | ||
371 | &paddq ("mm3","mm2"); | ||
372 | &movq (&QWP(8*9,"esp"),"mm3"); | ||
373 | |||
374 | &BODY_00_15_sse2(1); | ||
375 | |||
376 | &cmp (&LB("edx"),0x17); | ||
377 | &jne (&label("16_79_sse2")); | ||
378 | |||
379 | # &movq ($A,$Asse2); | ||
380 | &movq ("mm1",$Bsse2); | ||
381 | &movq ("mm2",$Csse2); | ||
382 | &movq ("mm3",$Dsse2); | ||
383 | # &movq ($E,$Esse2); | ||
384 | &movq ("mm5",$Fsse2); | ||
385 | &movq ("mm6",$Gsse2); | ||
386 | &movq ("mm7",$Hsse2); | ||
387 | |||
388 | &paddq ($A,&QWP(0,"esi")); | ||
389 | &paddq ("mm1",&QWP(8,"esi")); | ||
390 | &paddq ("mm2",&QWP(16,"esi")); | ||
391 | &paddq ("mm3",&QWP(24,"esi")); | ||
392 | &paddq ($E,&QWP(32,"esi")); | ||
393 | &paddq ("mm5",&QWP(40,"esi")); | ||
394 | &paddq ("mm6",&QWP(48,"esi")); | ||
395 | &paddq ("mm7",&QWP(56,"esi")); | ||
396 | |||
397 | &movq (&QWP(0,"esi"),$A); | ||
398 | &movq (&QWP(8,"esi"),"mm1"); | ||
399 | &movq (&QWP(16,"esi"),"mm2"); | ||
400 | &movq (&QWP(24,"esi"),"mm3"); | ||
401 | &movq (&QWP(32,"esi"),$E); | ||
402 | &movq (&QWP(40,"esi"),"mm5"); | ||
403 | &movq (&QWP(48,"esi"),"mm6"); | ||
404 | &movq (&QWP(56,"esi"),"mm7"); | ||
405 | |||
406 | &add ("esp",8*80); # destroy frame | ||
407 | &sub ($K512,8*80); # rewind K | ||
408 | |||
409 | &cmp ("edi",&DWP(8*10+8,"esp")); # are we done yet? | ||
410 | &jb (&label("loop_sse2")); | ||
411 | |||
412 | &emms (); | ||
413 | &mov ("esp",&DWP(8*10+12,"esp")); # restore sp | ||
414 | &function_end_A(); | ||
415 | } | ||
416 | &set_label("loop_x86",16); | ||
417 | # copy input block to stack reversing byte and qword order | ||
418 | for ($i=0;$i<8;$i++) { | ||
419 | &mov ("eax",&DWP($i*16+0,"edi")); | ||
420 | &mov ("ebx",&DWP($i*16+4,"edi")); | ||
421 | &mov ("ecx",&DWP($i*16+8,"edi")); | ||
422 | &mov ("edx",&DWP($i*16+12,"edi")); | ||
423 | &bswap ("eax"); | ||
424 | &bswap ("ebx"); | ||
425 | &bswap ("ecx"); | ||
426 | &bswap ("edx"); | ||
427 | &push ("eax"); | ||
428 | &push ("ebx"); | ||
429 | &push ("ecx"); | ||
430 | &push ("edx"); | ||
431 | } | ||
432 | &add ("edi",128); | ||
433 | &sub ("esp",9*8); # place for T,A,B,C,D,E,F,G,H | ||
434 | &mov (&DWP(8*(9+16)+4,"esp"),"edi"); | ||
435 | |||
436 | # copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack | ||
437 | &lea ("edi",&DWP(8,"esp")); | ||
438 | &mov ("ecx",16); | ||
439 | &data_word(0xA5F3F689); # rep movsd | ||
440 | |||
441 | &set_label("00_15_x86",16); | ||
442 | &BODY_00_15_x86(); | ||
443 | |||
444 | &cmp (&LB("edx"),0x94); | ||
445 | &jne (&label("00_15_x86")); | ||
446 | |||
447 | &set_label("16_79_x86",16); | ||
448 | #define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) | ||
449 | # LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25 | ||
450 | # HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7 | ||
451 | &mov ("ecx",&DWP(8*(9+15+16-1)+0,"esp")); | ||
452 | &mov ("edx",&DWP(8*(9+15+16-1)+4,"esp")); | ||
453 | &mov ("esi","ecx"); | ||
454 | |||
455 | &shr ("ecx",1) # lo>>1 | ||
456 | &mov ("edi","edx"); | ||
457 | &shr ("edx",1) # hi>>1 | ||
458 | &mov ("eax","ecx"); | ||
459 | &shl ("esi",24); # lo<<24 | ||
460 | &mov ("ebx","edx"); | ||
461 | &shl ("edi",24); # hi<<24 | ||
462 | &xor ("ebx","esi"); | ||
463 | |||
464 | &shr ("ecx",7-1); # lo>>7 | ||
465 | &xor ("eax","edi"); | ||
466 | &shr ("edx",7-1); # hi>>7 | ||
467 | &xor ("eax","ecx"); | ||
468 | &shl ("esi",31-24); # lo<<31 | ||
469 | &xor ("ebx","edx"); | ||
470 | &shl ("edi",25-24); # hi<<25 | ||
471 | &xor ("ebx","esi"); | ||
472 | |||
473 | &shr ("ecx",8-7); # lo>>8 | ||
474 | &xor ("eax","edi"); | ||
475 | &shr ("edx",8-7); # hi>>8 | ||
476 | &xor ("eax","ecx"); | ||
477 | &shl ("edi",31-25); # hi<<31 | ||
478 | &xor ("ebx","edx"); | ||
479 | &xor ("eax","edi"); # T1 = sigma0(X[-15]) | ||
480 | |||
481 | &mov (&DWP(0,"esp"),"eax"); | ||
482 | &mov (&DWP(4,"esp"),"ebx"); # put T1 away | ||
483 | |||
484 | #define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) | ||
485 | # LO lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26 | ||
486 | # HI hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6 | ||
487 | &mov ("ecx",&DWP(8*(9+15+16-14)+0,"esp")); | ||
488 | &mov ("edx",&DWP(8*(9+15+16-14)+4,"esp")); | ||
489 | &mov ("esi","ecx"); | ||
490 | |||
491 | &shr ("ecx",6) # lo>>6 | ||
492 | &mov ("edi","edx"); | ||
493 | &shr ("edx",6) # hi>>6 | ||
494 | &mov ("eax","ecx"); | ||
495 | &shl ("esi",3); # lo<<3 | ||
496 | &mov ("ebx","edx"); | ||
497 | &shl ("edi",3); # hi<<3 | ||
498 | &xor ("eax","esi"); | ||
499 | |||
500 | &shr ("ecx",19-6); # lo>>19 | ||
501 | &xor ("ebx","edi"); | ||
502 | &shr ("edx",19-6); # hi>>19 | ||
503 | &xor ("eax","ecx"); | ||
504 | &shl ("esi",13-3); # lo<<13 | ||
505 | &xor ("ebx","edx"); | ||
506 | &shl ("edi",13-3); # hi<<13 | ||
507 | &xor ("ebx","esi"); | ||
508 | |||
509 | &shr ("ecx",29-19); # lo>>29 | ||
510 | &xor ("eax","edi"); | ||
511 | &shr ("edx",29-19); # hi>>29 | ||
512 | &xor ("ebx","ecx"); | ||
513 | &shl ("edi",26-13); # hi<<26 | ||
514 | &xor ("eax","edx"); | ||
515 | &xor ("eax","edi"); # sigma1(X[-2]) | ||
516 | |||
517 | &mov ("ecx",&DWP(8*(9+15+16)+0,"esp")); | ||
518 | &mov ("edx",&DWP(8*(9+15+16)+4,"esp")); | ||
519 | &add ("eax",&DWP(0,"esp")); | ||
520 | &adc ("ebx",&DWP(4,"esp")); # T1 = sigma1(X[-2])+T1 | ||
521 | &mov ("esi",&DWP(8*(9+15+16-9)+0,"esp")); | ||
522 | &mov ("edi",&DWP(8*(9+15+16-9)+4,"esp")); | ||
523 | &add ("eax","ecx"); | ||
524 | &adc ("ebx","edx"); # T1 += X[-16] | ||
525 | &add ("eax","esi"); | ||
526 | &adc ("ebx","edi"); # T1 += X[-7] | ||
527 | &mov (&DWP(8*(9+15)+0,"esp"),"eax"); | ||
528 | &mov (&DWP(8*(9+15)+4,"esp"),"ebx"); # save X[0] | ||
529 | |||
530 | &BODY_00_15_x86(); | ||
531 | |||
532 | &cmp (&LB("edx"),0x17); | ||
533 | &jne (&label("16_79_x86")); | ||
534 | |||
535 | &mov ("esi",&DWP(8*(9+16+80)+0,"esp"));# ctx | ||
536 | &mov ("edi",&DWP(8*(9+16+80)+4,"esp"));# inp | ||
537 | for($i=0;$i<4;$i++) { | ||
538 | &mov ("eax",&DWP($i*16+0,"esi")); | ||
539 | &mov ("ebx",&DWP($i*16+4,"esi")); | ||
540 | &mov ("ecx",&DWP($i*16+8,"esi")); | ||
541 | &mov ("edx",&DWP($i*16+12,"esi")); | ||
542 | &add ("eax",&DWP(8+($i*16)+0,"esp")); | ||
543 | &adc ("ebx",&DWP(8+($i*16)+4,"esp")); | ||
544 | &mov (&DWP($i*16+0,"esi"),"eax"); | ||
545 | &mov (&DWP($i*16+4,"esi"),"ebx"); | ||
546 | &add ("ecx",&DWP(8+($i*16)+8,"esp")); | ||
547 | &adc ("edx",&DWP(8+($i*16)+12,"esp")); | ||
548 | &mov (&DWP($i*16+8,"esi"),"ecx"); | ||
549 | &mov (&DWP($i*16+12,"esi"),"edx"); | ||
550 | } | ||
551 | &add ("esp",8*(9+16+80)); # destroy frame | ||
552 | &sub ($K512,8*80); # rewind K | ||
553 | |||
554 | &cmp ("edi",&DWP(8,"esp")); # are we done yet? | ||
555 | &jb (&label("loop_x86")); | ||
556 | |||
557 | &mov ("esp",&DWP(12,"esp")); # restore sp | ||
558 | &function_end_A(); | ||
559 | |||
560 | &set_label("K512",64); # Yes! I keep it in the code segment! | ||
561 | &data_word(0xd728ae22,0x428a2f98); # u64 | ||
562 | &data_word(0x23ef65cd,0x71374491); # u64 | ||
563 | &data_word(0xec4d3b2f,0xb5c0fbcf); # u64 | ||
564 | &data_word(0x8189dbbc,0xe9b5dba5); # u64 | ||
565 | &data_word(0xf348b538,0x3956c25b); # u64 | ||
566 | &data_word(0xb605d019,0x59f111f1); # u64 | ||
567 | &data_word(0xaf194f9b,0x923f82a4); # u64 | ||
568 | &data_word(0xda6d8118,0xab1c5ed5); # u64 | ||
569 | &data_word(0xa3030242,0xd807aa98); # u64 | ||
570 | &data_word(0x45706fbe,0x12835b01); # u64 | ||
571 | &data_word(0x4ee4b28c,0x243185be); # u64 | ||
572 | &data_word(0xd5ffb4e2,0x550c7dc3); # u64 | ||
573 | &data_word(0xf27b896f,0x72be5d74); # u64 | ||
574 | &data_word(0x3b1696b1,0x80deb1fe); # u64 | ||
575 | &data_word(0x25c71235,0x9bdc06a7); # u64 | ||
576 | &data_word(0xcf692694,0xc19bf174); # u64 | ||
577 | &data_word(0x9ef14ad2,0xe49b69c1); # u64 | ||
578 | &data_word(0x384f25e3,0xefbe4786); # u64 | ||
579 | &data_word(0x8b8cd5b5,0x0fc19dc6); # u64 | ||
580 | &data_word(0x77ac9c65,0x240ca1cc); # u64 | ||
581 | &data_word(0x592b0275,0x2de92c6f); # u64 | ||
582 | &data_word(0x6ea6e483,0x4a7484aa); # u64 | ||
583 | &data_word(0xbd41fbd4,0x5cb0a9dc); # u64 | ||
584 | &data_word(0x831153b5,0x76f988da); # u64 | ||
585 | &data_word(0xee66dfab,0x983e5152); # u64 | ||
586 | &data_word(0x2db43210,0xa831c66d); # u64 | ||
587 | &data_word(0x98fb213f,0xb00327c8); # u64 | ||
588 | &data_word(0xbeef0ee4,0xbf597fc7); # u64 | ||
589 | &data_word(0x3da88fc2,0xc6e00bf3); # u64 | ||
590 | &data_word(0x930aa725,0xd5a79147); # u64 | ||
591 | &data_word(0xe003826f,0x06ca6351); # u64 | ||
592 | &data_word(0x0a0e6e70,0x14292967); # u64 | ||
593 | &data_word(0x46d22ffc,0x27b70a85); # u64 | ||
594 | &data_word(0x5c26c926,0x2e1b2138); # u64 | ||
595 | &data_word(0x5ac42aed,0x4d2c6dfc); # u64 | ||
596 | &data_word(0x9d95b3df,0x53380d13); # u64 | ||
597 | &data_word(0x8baf63de,0x650a7354); # u64 | ||
598 | &data_word(0x3c77b2a8,0x766a0abb); # u64 | ||
599 | &data_word(0x47edaee6,0x81c2c92e); # u64 | ||
600 | &data_word(0x1482353b,0x92722c85); # u64 | ||
601 | &data_word(0x4cf10364,0xa2bfe8a1); # u64 | ||
602 | &data_word(0xbc423001,0xa81a664b); # u64 | ||
603 | &data_word(0xd0f89791,0xc24b8b70); # u64 | ||
604 | &data_word(0x0654be30,0xc76c51a3); # u64 | ||
605 | &data_word(0xd6ef5218,0xd192e819); # u64 | ||
606 | &data_word(0x5565a910,0xd6990624); # u64 | ||
607 | &data_word(0x5771202a,0xf40e3585); # u64 | ||
608 | &data_word(0x32bbd1b8,0x106aa070); # u64 | ||
609 | &data_word(0xb8d2d0c8,0x19a4c116); # u64 | ||
610 | &data_word(0x5141ab53,0x1e376c08); # u64 | ||
611 | &data_word(0xdf8eeb99,0x2748774c); # u64 | ||
612 | &data_word(0xe19b48a8,0x34b0bcb5); # u64 | ||
613 | &data_word(0xc5c95a63,0x391c0cb3); # u64 | ||
614 | &data_word(0xe3418acb,0x4ed8aa4a); # u64 | ||
615 | &data_word(0x7763e373,0x5b9cca4f); # u64 | ||
616 | &data_word(0xd6b2b8a3,0x682e6ff3); # u64 | ||
617 | &data_word(0x5defb2fc,0x748f82ee); # u64 | ||
618 | &data_word(0x43172f60,0x78a5636f); # u64 | ||
619 | &data_word(0xa1f0ab72,0x84c87814); # u64 | ||
620 | &data_word(0x1a6439ec,0x8cc70208); # u64 | ||
621 | &data_word(0x23631e28,0x90befffa); # u64 | ||
622 | &data_word(0xde82bde9,0xa4506ceb); # u64 | ||
623 | &data_word(0xb2c67915,0xbef9a3f7); # u64 | ||
624 | &data_word(0xe372532b,0xc67178f2); # u64 | ||
625 | &data_word(0xea26619c,0xca273ece); # u64 | ||
626 | &data_word(0x21c0c207,0xd186b8c7); # u64 | ||
627 | &data_word(0xcde0eb1e,0xeada7dd6); # u64 | ||
628 | &data_word(0xee6ed178,0xf57d4f7f); # u64 | ||
629 | &data_word(0x72176fba,0x06f067aa); # u64 | ||
630 | &data_word(0xa2c898a6,0x0a637dc5); # u64 | ||
631 | &data_word(0xbef90dae,0x113f9804); # u64 | ||
632 | &data_word(0x131c471b,0x1b710b35); # u64 | ||
633 | &data_word(0x23047d84,0x28db77f5); # u64 | ||
634 | &data_word(0x40c72493,0x32caab7b); # u64 | ||
635 | &data_word(0x15c9bebc,0x3c9ebe0a); # u64 | ||
636 | &data_word(0x9c100d4c,0x431d67c4); # u64 | ||
637 | &data_word(0xcb3e42b6,0x4cc5d4be); # u64 | ||
638 | &data_word(0xfc657e2a,0x597f299c); # u64 | ||
639 | &data_word(0x3ad6faec,0x5fcb6fab); # u64 | ||
640 | &data_word(0x4a475817,0x6c44198c); # u64 | ||
641 | &function_end_B("sha512_block_data_order"); | ||
642 | &asciz("SHA512 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>"); | ||
643 | |||
644 | &asm_finish(); | ||
diff --git a/src/lib/libcrypto/sha/asm/sha512-armv4.pl b/src/lib/libcrypto/sha/asm/sha512-armv4.pl new file mode 100644 index 0000000000..4fbb94a914 --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha512-armv4.pl | |||
@@ -0,0 +1,399 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # SHA512 block procedure for ARMv4. September 2007. | ||
11 | |||
12 | # This code is ~4.5 (four and a half) times faster than code generated | ||
13 | # by gcc 3.4 and it spends ~72 clock cycles per byte. | ||
14 | |||
15 | # Byte order [in]dependence. ========================================= | ||
16 | # | ||
17 | # Caller is expected to maintain specific *dword* order in h[0-7], | ||
18 | # namely with most significant dword at *lower* address, which is | ||
19 | # reflected in below two parameters. *Byte* order within these dwords | ||
20 | # in turn is whatever *native* byte order on current platform. | ||
21 | $hi=0; | ||
22 | $lo=4; | ||
23 | # ==================================================================== | ||
24 | |||
25 | $output=shift; | ||
26 | open STDOUT,">$output"; | ||
27 | |||
28 | $ctx="r0"; | ||
29 | $inp="r1"; | ||
30 | $len="r2"; | ||
31 | $Tlo="r3"; | ||
32 | $Thi="r4"; | ||
33 | $Alo="r5"; | ||
34 | $Ahi="r6"; | ||
35 | $Elo="r7"; | ||
36 | $Ehi="r8"; | ||
37 | $t0="r9"; | ||
38 | $t1="r10"; | ||
39 | $t2="r11"; | ||
40 | $t3="r12"; | ||
41 | ############ r13 is stack pointer | ||
42 | $Ktbl="r14"; | ||
43 | ############ r15 is program counter | ||
44 | |||
45 | $Aoff=8*0; | ||
46 | $Boff=8*1; | ||
47 | $Coff=8*2; | ||
48 | $Doff=8*3; | ||
49 | $Eoff=8*4; | ||
50 | $Foff=8*5; | ||
51 | $Goff=8*6; | ||
52 | $Hoff=8*7; | ||
53 | $Xoff=8*8; | ||
54 | |||
55 | sub BODY_00_15() { | ||
56 | my $magic = shift; | ||
57 | $code.=<<___; | ||
58 | ldr $t2,[sp,#$Hoff+0] @ h.lo | ||
59 | ldr $t3,[sp,#$Hoff+4] @ h.hi | ||
60 | @ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) | ||
61 | @ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 | ||
62 | @ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 | ||
63 | mov $t0,$Elo,lsr#14 | ||
64 | mov $t1,$Ehi,lsr#14 | ||
65 | eor $t0,$t0,$Ehi,lsl#18 | ||
66 | eor $t1,$t1,$Elo,lsl#18 | ||
67 | eor $t0,$t0,$Elo,lsr#18 | ||
68 | eor $t1,$t1,$Ehi,lsr#18 | ||
69 | eor $t0,$t0,$Ehi,lsl#14 | ||
70 | eor $t1,$t1,$Elo,lsl#14 | ||
71 | eor $t0,$t0,$Ehi,lsr#9 | ||
72 | eor $t1,$t1,$Elo,lsr#9 | ||
73 | eor $t0,$t0,$Elo,lsl#23 | ||
74 | eor $t1,$t1,$Ehi,lsl#23 @ Sigma1(e) | ||
75 | adds $Tlo,$Tlo,$t0 | ||
76 | adc $Thi,$Thi,$t1 @ T += Sigma1(e) | ||
77 | adds $Tlo,$Tlo,$t2 | ||
78 | adc $Thi,$Thi,$t3 @ T += h | ||
79 | |||
80 | ldr $t0,[sp,#$Foff+0] @ f.lo | ||
81 | ldr $t1,[sp,#$Foff+4] @ f.hi | ||
82 | ldr $t2,[sp,#$Goff+0] @ g.lo | ||
83 | ldr $t3,[sp,#$Goff+4] @ g.hi | ||
84 | str $Elo,[sp,#$Eoff+0] | ||
85 | str $Ehi,[sp,#$Eoff+4] | ||
86 | str $Alo,[sp,#$Aoff+0] | ||
87 | str $Ahi,[sp,#$Aoff+4] | ||
88 | |||
89 | eor $t0,$t0,$t2 | ||
90 | eor $t1,$t1,$t3 | ||
91 | and $t0,$t0,$Elo | ||
92 | and $t1,$t1,$Ehi | ||
93 | eor $t0,$t0,$t2 | ||
94 | eor $t1,$t1,$t3 @ Ch(e,f,g) | ||
95 | |||
96 | ldr $t2,[$Ktbl,#4] @ K[i].lo | ||
97 | ldr $t3,[$Ktbl,#0] @ K[i].hi | ||
98 | ldr $Elo,[sp,#$Doff+0] @ d.lo | ||
99 | ldr $Ehi,[sp,#$Doff+4] @ d.hi | ||
100 | |||
101 | adds $Tlo,$Tlo,$t0 | ||
102 | adc $Thi,$Thi,$t1 @ T += Ch(e,f,g) | ||
103 | adds $Tlo,$Tlo,$t2 | ||
104 | adc $Thi,$Thi,$t3 @ T += K[i] | ||
105 | adds $Elo,$Elo,$Tlo | ||
106 | adc $Ehi,$Ehi,$Thi @ d += T | ||
107 | |||
108 | and $t0,$t2,#0xff | ||
109 | teq $t0,#$magic | ||
110 | orreq $Ktbl,$Ktbl,#1 | ||
111 | |||
112 | ldr $t2,[sp,#$Boff+0] @ b.lo | ||
113 | ldr $t3,[sp,#$Coff+0] @ c.lo | ||
114 | @ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) | ||
115 | @ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 | ||
116 | @ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 | ||
117 | mov $t0,$Alo,lsr#28 | ||
118 | mov $t1,$Ahi,lsr#28 | ||
119 | eor $t0,$t0,$Ahi,lsl#4 | ||
120 | eor $t1,$t1,$Alo,lsl#4 | ||
121 | eor $t0,$t0,$Ahi,lsr#2 | ||
122 | eor $t1,$t1,$Alo,lsr#2 | ||
123 | eor $t0,$t0,$Alo,lsl#30 | ||
124 | eor $t1,$t1,$Ahi,lsl#30 | ||
125 | eor $t0,$t0,$Ahi,lsr#7 | ||
126 | eor $t1,$t1,$Alo,lsr#7 | ||
127 | eor $t0,$t0,$Alo,lsl#25 | ||
128 | eor $t1,$t1,$Ahi,lsl#25 @ Sigma0(a) | ||
129 | adds $Tlo,$Tlo,$t0 | ||
130 | adc $Thi,$Thi,$t1 @ T += Sigma0(a) | ||
131 | |||
132 | and $t0,$Alo,$t2 | ||
133 | orr $Alo,$Alo,$t2 | ||
134 | ldr $t1,[sp,#$Boff+4] @ b.hi | ||
135 | ldr $t2,[sp,#$Coff+4] @ c.hi | ||
136 | and $Alo,$Alo,$t3 | ||
137 | orr $Alo,$Alo,$t0 @ Maj(a,b,c).lo | ||
138 | and $t3,$Ahi,$t1 | ||
139 | orr $Ahi,$Ahi,$t1 | ||
140 | and $Ahi,$Ahi,$t2 | ||
141 | orr $Ahi,$Ahi,$t3 @ Maj(a,b,c).hi | ||
142 | adds $Alo,$Alo,$Tlo | ||
143 | adc $Ahi,$Ahi,$Thi @ h += T | ||
144 | |||
145 | sub sp,sp,#8 | ||
146 | add $Ktbl,$Ktbl,#8 | ||
147 | ___ | ||
148 | } | ||
149 | $code=<<___; | ||
150 | .text | ||
151 | .code 32 | ||
152 | .type K512,%object | ||
153 | .align 5 | ||
154 | K512: | ||
155 | .word 0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd | ||
156 | .word 0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc | ||
157 | .word 0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019 | ||
158 | .word 0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118 | ||
159 | .word 0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe | ||
160 | .word 0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2 | ||
161 | .word 0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1 | ||
162 | .word 0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694 | ||
163 | .word 0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3 | ||
164 | .word 0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65 | ||
165 | .word 0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483 | ||
166 | .word 0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5 | ||
167 | .word 0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210 | ||
168 | .word 0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4 | ||
169 | .word 0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725 | ||
170 | .word 0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70 | ||
171 | .word 0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926 | ||
172 | .word 0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df | ||
173 | .word 0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8 | ||
174 | .word 0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b | ||
175 | .word 0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001 | ||
176 | .word 0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30 | ||
177 | .word 0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910 | ||
178 | .word 0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8 | ||
179 | .word 0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53 | ||
180 | .word 0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8 | ||
181 | .word 0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb | ||
182 | .word 0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3 | ||
183 | .word 0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60 | ||
184 | .word 0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec | ||
185 | .word 0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9 | ||
186 | .word 0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b | ||
187 | .word 0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207 | ||
188 | .word 0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178 | ||
189 | .word 0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6 | ||
190 | .word 0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b | ||
191 | .word 0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493 | ||
192 | .word 0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c | ||
193 | .word 0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a | ||
194 | .word 0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817 | ||
195 | .size K512,.-K512 | ||
196 | |||
197 | .global sha512_block_data_order | ||
198 | .type sha512_block_data_order,%function | ||
199 | sha512_block_data_order: | ||
200 | sub r3,pc,#8 @ sha512_block_data_order | ||
201 | add $len,$inp,$len,lsl#7 @ len to point at the end of inp | ||
202 | stmdb sp!,{r4-r12,lr} | ||
203 | sub $Ktbl,r3,#640 @ K512 | ||
204 | sub sp,sp,#9*8 | ||
205 | |||
206 | ldr $Elo,[$ctx,#$Eoff+$lo] | ||
207 | ldr $Ehi,[$ctx,#$Eoff+$hi] | ||
208 | ldr $t0, [$ctx,#$Goff+$lo] | ||
209 | ldr $t1, [$ctx,#$Goff+$hi] | ||
210 | ldr $t2, [$ctx,#$Hoff+$lo] | ||
211 | ldr $t3, [$ctx,#$Hoff+$hi] | ||
212 | .Loop: | ||
213 | str $t0, [sp,#$Goff+0] | ||
214 | str $t1, [sp,#$Goff+4] | ||
215 | str $t2, [sp,#$Hoff+0] | ||
216 | str $t3, [sp,#$Hoff+4] | ||
217 | ldr $Alo,[$ctx,#$Aoff+$lo] | ||
218 | ldr $Ahi,[$ctx,#$Aoff+$hi] | ||
219 | ldr $Tlo,[$ctx,#$Boff+$lo] | ||
220 | ldr $Thi,[$ctx,#$Boff+$hi] | ||
221 | ldr $t0, [$ctx,#$Coff+$lo] | ||
222 | ldr $t1, [$ctx,#$Coff+$hi] | ||
223 | ldr $t2, [$ctx,#$Doff+$lo] | ||
224 | ldr $t3, [$ctx,#$Doff+$hi] | ||
225 | str $Tlo,[sp,#$Boff+0] | ||
226 | str $Thi,[sp,#$Boff+4] | ||
227 | str $t0, [sp,#$Coff+0] | ||
228 | str $t1, [sp,#$Coff+4] | ||
229 | str $t2, [sp,#$Doff+0] | ||
230 | str $t3, [sp,#$Doff+4] | ||
231 | ldr $Tlo,[$ctx,#$Foff+$lo] | ||
232 | ldr $Thi,[$ctx,#$Foff+$hi] | ||
233 | str $Tlo,[sp,#$Foff+0] | ||
234 | str $Thi,[sp,#$Foff+4] | ||
235 | |||
236 | .L00_15: | ||
237 | ldrb $Tlo,[$inp,#7] | ||
238 | ldrb $t0, [$inp,#6] | ||
239 | ldrb $t1, [$inp,#5] | ||
240 | ldrb $t2, [$inp,#4] | ||
241 | ldrb $Thi,[$inp,#3] | ||
242 | ldrb $t3, [$inp,#2] | ||
243 | orr $Tlo,$Tlo,$t0,lsl#8 | ||
244 | ldrb $t0, [$inp,#1] | ||
245 | orr $Tlo,$Tlo,$t1,lsl#16 | ||
246 | ldrb $t1, [$inp],#8 | ||
247 | orr $Tlo,$Tlo,$t2,lsl#24 | ||
248 | orr $Thi,$Thi,$t3,lsl#8 | ||
249 | orr $Thi,$Thi,$t0,lsl#16 | ||
250 | orr $Thi,$Thi,$t1,lsl#24 | ||
251 | str $Tlo,[sp,#$Xoff+0] | ||
252 | str $Thi,[sp,#$Xoff+4] | ||
253 | ___ | ||
254 | &BODY_00_15(0x94); | ||
255 | $code.=<<___; | ||
256 | tst $Ktbl,#1 | ||
257 | beq .L00_15 | ||
258 | bic $Ktbl,$Ktbl,#1 | ||
259 | |||
260 | .L16_79: | ||
261 | ldr $t0,[sp,#`$Xoff+8*(16-1)`+0] | ||
262 | ldr $t1,[sp,#`$Xoff+8*(16-1)`+4] | ||
263 | ldr $t2,[sp,#`$Xoff+8*(16-14)`+0] | ||
264 | ldr $t3,[sp,#`$Xoff+8*(16-14)`+4] | ||
265 | |||
266 | @ sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) | ||
267 | @ LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25 | ||
268 | @ HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7 | ||
269 | mov $Tlo,$t0,lsr#1 | ||
270 | mov $Thi,$t1,lsr#1 | ||
271 | eor $Tlo,$Tlo,$t1,lsl#31 | ||
272 | eor $Thi,$Thi,$t0,lsl#31 | ||
273 | eor $Tlo,$Tlo,$t0,lsr#8 | ||
274 | eor $Thi,$Thi,$t1,lsr#8 | ||
275 | eor $Tlo,$Tlo,$t1,lsl#24 | ||
276 | eor $Thi,$Thi,$t0,lsl#24 | ||
277 | eor $Tlo,$Tlo,$t0,lsr#7 | ||
278 | eor $Thi,$Thi,$t1,lsr#7 | ||
279 | eor $Tlo,$Tlo,$t1,lsl#25 | ||
280 | |||
281 | @ sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) | ||
282 | @ LO lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26 | ||
283 | @ HI hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6 | ||
284 | mov $t0,$t2,lsr#19 | ||
285 | mov $t1,$t3,lsr#19 | ||
286 | eor $t0,$t0,$t3,lsl#13 | ||
287 | eor $t1,$t1,$t2,lsl#13 | ||
288 | eor $t0,$t0,$t3,lsr#29 | ||
289 | eor $t1,$t1,$t2,lsr#29 | ||
290 | eor $t0,$t0,$t2,lsl#3 | ||
291 | eor $t1,$t1,$t3,lsl#3 | ||
292 | eor $t0,$t0,$t2,lsr#6 | ||
293 | eor $t1,$t1,$t3,lsr#6 | ||
294 | eor $t0,$t0,$t3,lsl#26 | ||
295 | |||
296 | ldr $t2,[sp,#`$Xoff+8*(16-9)`+0] | ||
297 | ldr $t3,[sp,#`$Xoff+8*(16-9)`+4] | ||
298 | adds $Tlo,$Tlo,$t0 | ||
299 | adc $Thi,$Thi,$t1 | ||
300 | |||
301 | ldr $t0,[sp,#`$Xoff+8*16`+0] | ||
302 | ldr $t1,[sp,#`$Xoff+8*16`+4] | ||
303 | adds $Tlo,$Tlo,$t2 | ||
304 | adc $Thi,$Thi,$t3 | ||
305 | adds $Tlo,$Tlo,$t0 | ||
306 | adc $Thi,$Thi,$t1 | ||
307 | str $Tlo,[sp,#$Xoff+0] | ||
308 | str $Thi,[sp,#$Xoff+4] | ||
309 | ___ | ||
310 | &BODY_00_15(0x17); | ||
311 | $code.=<<___; | ||
312 | tst $Ktbl,#1 | ||
313 | beq .L16_79 | ||
314 | bic $Ktbl,$Ktbl,#1 | ||
315 | |||
316 | ldr $Tlo,[sp,#$Boff+0] | ||
317 | ldr $Thi,[sp,#$Boff+4] | ||
318 | ldr $t0, [$ctx,#$Aoff+$lo] | ||
319 | ldr $t1, [$ctx,#$Aoff+$hi] | ||
320 | ldr $t2, [$ctx,#$Boff+$lo] | ||
321 | ldr $t3, [$ctx,#$Boff+$hi] | ||
322 | adds $t0,$Alo,$t0 | ||
323 | adc $t1,$Ahi,$t1 | ||
324 | adds $t2,$Tlo,$t2 | ||
325 | adc $t3,$Thi,$t3 | ||
326 | str $t0, [$ctx,#$Aoff+$lo] | ||
327 | str $t1, [$ctx,#$Aoff+$hi] | ||
328 | str $t2, [$ctx,#$Boff+$lo] | ||
329 | str $t3, [$ctx,#$Boff+$hi] | ||
330 | |||
331 | ldr $Alo,[sp,#$Coff+0] | ||
332 | ldr $Ahi,[sp,#$Coff+4] | ||
333 | ldr $Tlo,[sp,#$Doff+0] | ||
334 | ldr $Thi,[sp,#$Doff+4] | ||
335 | ldr $t0, [$ctx,#$Coff+$lo] | ||
336 | ldr $t1, [$ctx,#$Coff+$hi] | ||
337 | ldr $t2, [$ctx,#$Doff+$lo] | ||
338 | ldr $t3, [$ctx,#$Doff+$hi] | ||
339 | adds $t0,$Alo,$t0 | ||
340 | adc $t1,$Ahi,$t1 | ||
341 | adds $t2,$Tlo,$t2 | ||
342 | adc $t3,$Thi,$t3 | ||
343 | str $t0, [$ctx,#$Coff+$lo] | ||
344 | str $t1, [$ctx,#$Coff+$hi] | ||
345 | str $t2, [$ctx,#$Doff+$lo] | ||
346 | str $t3, [$ctx,#$Doff+$hi] | ||
347 | |||
348 | ldr $Tlo,[sp,#$Foff+0] | ||
349 | ldr $Thi,[sp,#$Foff+4] | ||
350 | ldr $t0, [$ctx,#$Eoff+$lo] | ||
351 | ldr $t1, [$ctx,#$Eoff+$hi] | ||
352 | ldr $t2, [$ctx,#$Foff+$lo] | ||
353 | ldr $t3, [$ctx,#$Foff+$hi] | ||
354 | adds $Elo,$Elo,$t0 | ||
355 | adc $Ehi,$Ehi,$t1 | ||
356 | adds $t2,$Tlo,$t2 | ||
357 | adc $t3,$Thi,$t3 | ||
358 | str $Elo,[$ctx,#$Eoff+$lo] | ||
359 | str $Ehi,[$ctx,#$Eoff+$hi] | ||
360 | str $t2, [$ctx,#$Foff+$lo] | ||
361 | str $t3, [$ctx,#$Foff+$hi] | ||
362 | |||
363 | ldr $Alo,[sp,#$Goff+0] | ||
364 | ldr $Ahi,[sp,#$Goff+4] | ||
365 | ldr $Tlo,[sp,#$Hoff+0] | ||
366 | ldr $Thi,[sp,#$Hoff+4] | ||
367 | ldr $t0, [$ctx,#$Goff+$lo] | ||
368 | ldr $t1, [$ctx,#$Goff+$hi] | ||
369 | ldr $t2, [$ctx,#$Hoff+$lo] | ||
370 | ldr $t3, [$ctx,#$Hoff+$hi] | ||
371 | adds $t0,$Alo,$t0 | ||
372 | adc $t1,$Ahi,$t1 | ||
373 | adds $t2,$Tlo,$t2 | ||
374 | adc $t3,$Thi,$t3 | ||
375 | str $t0, [$ctx,#$Goff+$lo] | ||
376 | str $t1, [$ctx,#$Goff+$hi] | ||
377 | str $t2, [$ctx,#$Hoff+$lo] | ||
378 | str $t3, [$ctx,#$Hoff+$hi] | ||
379 | |||
380 | add sp,sp,#640 | ||
381 | sub $Ktbl,$Ktbl,#640 | ||
382 | |||
383 | teq $inp,$len | ||
384 | bne .Loop | ||
385 | |||
386 | add sp,sp,#8*9 @ destroy frame | ||
387 | ldmia sp!,{r4-r12,lr} | ||
388 | tst lr,#1 | ||
389 | moveq pc,lr @ be binary compatible with V4, yet | ||
390 | bx lr @ interoperable with Thumb ISA:-) | ||
391 | .size sha512_block_data_order,.-sha512_block_data_order | ||
392 | .asciz "SHA512 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>" | ||
393 | .align 2 | ||
394 | ___ | ||
395 | |||
396 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
397 | $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 | ||
398 | print $code; | ||
399 | close STDOUT; # enforce flush | ||
diff --git a/src/lib/libcrypto/sha/asm/sha512-ppc.pl b/src/lib/libcrypto/sha/asm/sha512-ppc.pl new file mode 100755 index 0000000000..768a6a6fad --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha512-ppc.pl | |||
@@ -0,0 +1,462 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # I let hardware handle unaligned input, except on page boundaries | ||
11 | # (see below for details). Otherwise straightforward implementation | ||
12 | # with X vector in register bank. The module is big-endian [which is | ||
13 | # not big deal as there're no little-endian targets left around]. | ||
14 | |||
15 | # sha256 | sha512 | ||
16 | # -m64 -m32 | -m64 -m32 | ||
17 | # --------------------------------------+----------------------- | ||
18 | # PPC970,gcc-4.0.0 +50% +38% | +40% +410%(*) | ||
19 | # Power6,xlc-7 +150% +90% | +100% +430%(*) | ||
20 | # | ||
21 | # (*) 64-bit code in 32-bit application context, which actually is | ||
22 | # on TODO list. It should be noted that for safe deployment in | ||
23 | # 32-bit *mutli-threaded* context asyncronous signals should be | ||
24 | # blocked upon entry to SHA512 block routine. This is because | ||
25 | # 32-bit signaling procedure invalidates upper halves of GPRs. | ||
26 | # Context switch procedure preserves them, but not signaling:-( | ||
27 | |||
28 | # Second version is true multi-thread safe. Trouble with the original | ||
29 | # version was that it was using thread local storage pointer register. | ||
30 | # Well, it scrupulously preserved it, but the problem would arise the | ||
31 | # moment asynchronous signal was delivered and signal handler would | ||
32 | # dereference the TLS pointer. While it's never the case in openssl | ||
33 | # application or test suite, we have to respect this scenario and not | ||
34 | # use TLS pointer register. Alternative would be to require caller to | ||
35 | # block signals prior calling this routine. For the record, in 32-bit | ||
36 | # context R2 serves as TLS pointer, while in 64-bit context - R13. | ||
37 | |||
38 | $flavour=shift; | ||
39 | $output =shift; | ||
40 | |||
41 | if ($flavour =~ /64/) { | ||
42 | $SIZE_T=8; | ||
43 | $STU="stdu"; | ||
44 | $UCMP="cmpld"; | ||
45 | $SHL="sldi"; | ||
46 | $POP="ld"; | ||
47 | $PUSH="std"; | ||
48 | } elsif ($flavour =~ /32/) { | ||
49 | $SIZE_T=4; | ||
50 | $STU="stwu"; | ||
51 | $UCMP="cmplw"; | ||
52 | $SHL="slwi"; | ||
53 | $POP="lwz"; | ||
54 | $PUSH="stw"; | ||
55 | } else { die "nonsense $flavour"; } | ||
56 | |||
57 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | ||
58 | ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or | ||
59 | ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or | ||
60 | die "can't locate ppc-xlate.pl"; | ||
61 | |||
62 | open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; | ||
63 | |||
64 | if ($output =~ /512/) { | ||
65 | $func="sha512_block_data_order"; | ||
66 | $SZ=8; | ||
67 | @Sigma0=(28,34,39); | ||
68 | @Sigma1=(14,18,41); | ||
69 | @sigma0=(1, 8, 7); | ||
70 | @sigma1=(19,61, 6); | ||
71 | $rounds=80; | ||
72 | $LD="ld"; | ||
73 | $ST="std"; | ||
74 | $ROR="rotrdi"; | ||
75 | $SHR="srdi"; | ||
76 | } else { | ||
77 | $func="sha256_block_data_order"; | ||
78 | $SZ=4; | ||
79 | @Sigma0=( 2,13,22); | ||
80 | @Sigma1=( 6,11,25); | ||
81 | @sigma0=( 7,18, 3); | ||
82 | @sigma1=(17,19,10); | ||
83 | $rounds=64; | ||
84 | $LD="lwz"; | ||
85 | $ST="stw"; | ||
86 | $ROR="rotrwi"; | ||
87 | $SHR="srwi"; | ||
88 | } | ||
89 | |||
90 | $FRAME=32*$SIZE_T; | ||
91 | |||
92 | $sp ="r1"; | ||
93 | $toc="r2"; | ||
94 | $ctx="r3"; # zapped by $a0 | ||
95 | $inp="r4"; # zapped by $a1 | ||
96 | $num="r5"; # zapped by $t0 | ||
97 | |||
98 | $T ="r0"; | ||
99 | $a0 ="r3"; | ||
100 | $a1 ="r4"; | ||
101 | $t0 ="r5"; | ||
102 | $t1 ="r6"; | ||
103 | $Tbl="r7"; | ||
104 | |||
105 | $A ="r8"; | ||
106 | $B ="r9"; | ||
107 | $C ="r10"; | ||
108 | $D ="r11"; | ||
109 | $E ="r12"; | ||
110 | $F ="r13"; $F="r2" if ($SIZE_T==8);# reassigned to exempt TLS pointer | ||
111 | $G ="r14"; | ||
112 | $H ="r15"; | ||
113 | |||
114 | @V=($A,$B,$C,$D,$E,$F,$G,$H); | ||
115 | @X=("r16","r17","r18","r19","r20","r21","r22","r23", | ||
116 | "r24","r25","r26","r27","r28","r29","r30","r31"); | ||
117 | |||
118 | $inp="r31"; # reassigned $inp! aliases with @X[15] | ||
119 | |||
120 | sub ROUND_00_15 { | ||
121 | my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; | ||
122 | $code.=<<___; | ||
123 | $LD $T,`$i*$SZ`($Tbl) | ||
124 | $ROR $a0,$e,$Sigma1[0] | ||
125 | $ROR $a1,$e,$Sigma1[1] | ||
126 | and $t0,$f,$e | ||
127 | andc $t1,$g,$e | ||
128 | add $T,$T,$h | ||
129 | xor $a0,$a0,$a1 | ||
130 | $ROR $a1,$a1,`$Sigma1[2]-$Sigma1[1]` | ||
131 | or $t0,$t0,$t1 ; Ch(e,f,g) | ||
132 | add $T,$T,@X[$i] | ||
133 | xor $a0,$a0,$a1 ; Sigma1(e) | ||
134 | add $T,$T,$t0 | ||
135 | add $T,$T,$a0 | ||
136 | |||
137 | $ROR $a0,$a,$Sigma0[0] | ||
138 | $ROR $a1,$a,$Sigma0[1] | ||
139 | and $t0,$a,$b | ||
140 | and $t1,$a,$c | ||
141 | xor $a0,$a0,$a1 | ||
142 | $ROR $a1,$a1,`$Sigma0[2]-$Sigma0[1]` | ||
143 | xor $t0,$t0,$t1 | ||
144 | and $t1,$b,$c | ||
145 | xor $a0,$a0,$a1 ; Sigma0(a) | ||
146 | add $d,$d,$T | ||
147 | xor $t0,$t0,$t1 ; Maj(a,b,c) | ||
148 | add $h,$T,$a0 | ||
149 | add $h,$h,$t0 | ||
150 | |||
151 | ___ | ||
152 | } | ||
153 | |||
154 | sub ROUND_16_xx { | ||
155 | my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; | ||
156 | $i-=16; | ||
157 | $code.=<<___; | ||
158 | $ROR $a0,@X[($i+1)%16],$sigma0[0] | ||
159 | $ROR $a1,@X[($i+1)%16],$sigma0[1] | ||
160 | $ROR $t0,@X[($i+14)%16],$sigma1[0] | ||
161 | $ROR $t1,@X[($i+14)%16],$sigma1[1] | ||
162 | xor $a0,$a0,$a1 | ||
163 | $SHR $a1,@X[($i+1)%16],$sigma0[2] | ||
164 | xor $t0,$t0,$t1 | ||
165 | $SHR $t1,@X[($i+14)%16],$sigma1[2] | ||
166 | add @X[$i],@X[$i],@X[($i+9)%16] | ||
167 | xor $a0,$a0,$a1 ; sigma0(X[(i+1)&0x0f]) | ||
168 | xor $t0,$t0,$t1 ; sigma1(X[(i+14)&0x0f]) | ||
169 | add @X[$i],@X[$i],$a0 | ||
170 | add @X[$i],@X[$i],$t0 | ||
171 | ___ | ||
172 | &ROUND_00_15($i,$a,$b,$c,$d,$e,$f,$g,$h); | ||
173 | } | ||
174 | |||
175 | $code=<<___; | ||
176 | .machine "any" | ||
177 | .text | ||
178 | |||
179 | .globl $func | ||
180 | .align 6 | ||
181 | $func: | ||
182 | mflr r0 | ||
183 | $STU $sp,`-($FRAME+16*$SZ)`($sp) | ||
184 | $SHL $num,$num,`log(16*$SZ)/log(2)` | ||
185 | |||
186 | $PUSH $ctx,`$FRAME-$SIZE_T*22`($sp) | ||
187 | |||
188 | $PUSH r0,`$FRAME-$SIZE_T*21`($sp) | ||
189 | $PUSH $toc,`$FRAME-$SIZE_T*20`($sp) | ||
190 | $PUSH r13,`$FRAME-$SIZE_T*19`($sp) | ||
191 | $PUSH r14,`$FRAME-$SIZE_T*18`($sp) | ||
192 | $PUSH r15,`$FRAME-$SIZE_T*17`($sp) | ||
193 | $PUSH r16,`$FRAME-$SIZE_T*16`($sp) | ||
194 | $PUSH r17,`$FRAME-$SIZE_T*15`($sp) | ||
195 | $PUSH r18,`$FRAME-$SIZE_T*14`($sp) | ||
196 | $PUSH r19,`$FRAME-$SIZE_T*13`($sp) | ||
197 | $PUSH r20,`$FRAME-$SIZE_T*12`($sp) | ||
198 | $PUSH r21,`$FRAME-$SIZE_T*11`($sp) | ||
199 | $PUSH r22,`$FRAME-$SIZE_T*10`($sp) | ||
200 | $PUSH r23,`$FRAME-$SIZE_T*9`($sp) | ||
201 | $PUSH r24,`$FRAME-$SIZE_T*8`($sp) | ||
202 | $PUSH r25,`$FRAME-$SIZE_T*7`($sp) | ||
203 | $PUSH r26,`$FRAME-$SIZE_T*6`($sp) | ||
204 | $PUSH r27,`$FRAME-$SIZE_T*5`($sp) | ||
205 | $PUSH r28,`$FRAME-$SIZE_T*4`($sp) | ||
206 | $PUSH r29,`$FRAME-$SIZE_T*3`($sp) | ||
207 | $PUSH r30,`$FRAME-$SIZE_T*2`($sp) | ||
208 | $PUSH r31,`$FRAME-$SIZE_T*1`($sp) | ||
209 | |||
210 | $LD $A,`0*$SZ`($ctx) | ||
211 | mr $inp,r4 ; incarnate $inp | ||
212 | $LD $B,`1*$SZ`($ctx) | ||
213 | $LD $C,`2*$SZ`($ctx) | ||
214 | $LD $D,`3*$SZ`($ctx) | ||
215 | $LD $E,`4*$SZ`($ctx) | ||
216 | $LD $F,`5*$SZ`($ctx) | ||
217 | $LD $G,`6*$SZ`($ctx) | ||
218 | $LD $H,`7*$SZ`($ctx) | ||
219 | |||
220 | b LPICmeup | ||
221 | LPICedup: | ||
222 | andi. r0,$inp,3 | ||
223 | bne Lunaligned | ||
224 | Laligned: | ||
225 | add $num,$inp,$num | ||
226 | $PUSH $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer | ||
227 | $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer | ||
228 | bl Lsha2_block_private | ||
229 | Ldone: | ||
230 | $POP r0,`$FRAME-$SIZE_T*21`($sp) | ||
231 | $POP $toc,`$FRAME-$SIZE_T*20`($sp) | ||
232 | $POP r13,`$FRAME-$SIZE_T*19`($sp) | ||
233 | $POP r14,`$FRAME-$SIZE_T*18`($sp) | ||
234 | $POP r15,`$FRAME-$SIZE_T*17`($sp) | ||
235 | $POP r16,`$FRAME-$SIZE_T*16`($sp) | ||
236 | $POP r17,`$FRAME-$SIZE_T*15`($sp) | ||
237 | $POP r18,`$FRAME-$SIZE_T*14`($sp) | ||
238 | $POP r19,`$FRAME-$SIZE_T*13`($sp) | ||
239 | $POP r20,`$FRAME-$SIZE_T*12`($sp) | ||
240 | $POP r21,`$FRAME-$SIZE_T*11`($sp) | ||
241 | $POP r22,`$FRAME-$SIZE_T*10`($sp) | ||
242 | $POP r23,`$FRAME-$SIZE_T*9`($sp) | ||
243 | $POP r24,`$FRAME-$SIZE_T*8`($sp) | ||
244 | $POP r25,`$FRAME-$SIZE_T*7`($sp) | ||
245 | $POP r26,`$FRAME-$SIZE_T*6`($sp) | ||
246 | $POP r27,`$FRAME-$SIZE_T*5`($sp) | ||
247 | $POP r28,`$FRAME-$SIZE_T*4`($sp) | ||
248 | $POP r29,`$FRAME-$SIZE_T*3`($sp) | ||
249 | $POP r30,`$FRAME-$SIZE_T*2`($sp) | ||
250 | $POP r31,`$FRAME-$SIZE_T*1`($sp) | ||
251 | mtlr r0 | ||
252 | addi $sp,$sp,`$FRAME+16*$SZ` | ||
253 | blr | ||
254 | ___ | ||
255 | |||
256 | # PowerPC specification allows an implementation to be ill-behaved | ||
257 | # upon unaligned access which crosses page boundary. "Better safe | ||
258 | # than sorry" principle makes me treat it specially. But I don't | ||
259 | # look for particular offending word, but rather for the input | ||
260 | # block which crosses the boundary. Once found that block is aligned | ||
261 | # and hashed separately... | ||
262 | $code.=<<___; | ||
263 | .align 4 | ||
264 | Lunaligned: | ||
265 | subfic $t1,$inp,4096 | ||
266 | andi. $t1,$t1,`4096-16*$SZ` ; distance to closest page boundary | ||
267 | beq Lcross_page | ||
268 | $UCMP $num,$t1 | ||
269 | ble- Laligned ; didn't cross the page boundary | ||
270 | subfc $num,$t1,$num | ||
271 | add $t1,$inp,$t1 | ||
272 | $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real remaining num | ||
273 | $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; intermediate end pointer | ||
274 | $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer | ||
275 | bl Lsha2_block_private | ||
276 | ; $inp equals to the intermediate end pointer here | ||
277 | $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real remaining num | ||
278 | Lcross_page: | ||
279 | li $t1,`16*$SZ/4` | ||
280 | mtctr $t1 | ||
281 | addi r20,$sp,$FRAME ; aligned spot below the frame | ||
282 | Lmemcpy: | ||
283 | lbz r16,0($inp) | ||
284 | lbz r17,1($inp) | ||
285 | lbz r18,2($inp) | ||
286 | lbz r19,3($inp) | ||
287 | addi $inp,$inp,4 | ||
288 | stb r16,0(r20) | ||
289 | stb r17,1(r20) | ||
290 | stb r18,2(r20) | ||
291 | stb r19,3(r20) | ||
292 | addi r20,r20,4 | ||
293 | bdnz Lmemcpy | ||
294 | |||
295 | $PUSH $inp,`$FRAME-$SIZE_T*26`($sp) ; save real inp | ||
296 | addi $t1,$sp,`$FRAME+16*$SZ` ; fictitious end pointer | ||
297 | addi $inp,$sp,$FRAME ; fictitious inp pointer | ||
298 | $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real num | ||
299 | $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; end pointer | ||
300 | $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer | ||
301 | bl Lsha2_block_private | ||
302 | $POP $inp,`$FRAME-$SIZE_T*26`($sp) ; restore real inp | ||
303 | $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real num | ||
304 | addic. $num,$num,`-16*$SZ` ; num-- | ||
305 | bne- Lunaligned | ||
306 | b Ldone | ||
307 | ___ | ||
308 | |||
309 | $code.=<<___; | ||
310 | .align 4 | ||
311 | Lsha2_block_private: | ||
312 | ___ | ||
313 | for($i=0;$i<16;$i++) { | ||
314 | $code.=<<___ if ($SZ==4); | ||
315 | lwz @X[$i],`$i*$SZ`($inp) | ||
316 | ___ | ||
317 | # 64-bit loads are split to 2x32-bit ones, as CPU can't handle | ||
318 | # unaligned 64-bit loads, only 32-bit ones... | ||
319 | $code.=<<___ if ($SZ==8); | ||
320 | lwz $t0,`$i*$SZ`($inp) | ||
321 | lwz @X[$i],`$i*$SZ+4`($inp) | ||
322 | insrdi @X[$i],$t0,32,0 | ||
323 | ___ | ||
324 | &ROUND_00_15($i,@V); | ||
325 | unshift(@V,pop(@V)); | ||
326 | } | ||
327 | $code.=<<___; | ||
328 | li $T,`$rounds/16-1` | ||
329 | mtctr $T | ||
330 | .align 4 | ||
331 | Lrounds: | ||
332 | addi $Tbl,$Tbl,`16*$SZ` | ||
333 | ___ | ||
334 | for(;$i<32;$i++) { | ||
335 | &ROUND_16_xx($i,@V); | ||
336 | unshift(@V,pop(@V)); | ||
337 | } | ||
338 | $code.=<<___; | ||
339 | bdnz- Lrounds | ||
340 | |||
341 | $POP $ctx,`$FRAME-$SIZE_T*22`($sp) | ||
342 | $POP $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer | ||
343 | $POP $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer | ||
344 | subi $Tbl,$Tbl,`($rounds-16)*$SZ` ; rewind Tbl | ||
345 | |||
346 | $LD r16,`0*$SZ`($ctx) | ||
347 | $LD r17,`1*$SZ`($ctx) | ||
348 | $LD r18,`2*$SZ`($ctx) | ||
349 | $LD r19,`3*$SZ`($ctx) | ||
350 | $LD r20,`4*$SZ`($ctx) | ||
351 | $LD r21,`5*$SZ`($ctx) | ||
352 | $LD r22,`6*$SZ`($ctx) | ||
353 | addi $inp,$inp,`16*$SZ` ; advance inp | ||
354 | $LD r23,`7*$SZ`($ctx) | ||
355 | add $A,$A,r16 | ||
356 | add $B,$B,r17 | ||
357 | $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) | ||
358 | add $C,$C,r18 | ||
359 | $ST $A,`0*$SZ`($ctx) | ||
360 | add $D,$D,r19 | ||
361 | $ST $B,`1*$SZ`($ctx) | ||
362 | add $E,$E,r20 | ||
363 | $ST $C,`2*$SZ`($ctx) | ||
364 | add $F,$F,r21 | ||
365 | $ST $D,`3*$SZ`($ctx) | ||
366 | add $G,$G,r22 | ||
367 | $ST $E,`4*$SZ`($ctx) | ||
368 | add $H,$H,r23 | ||
369 | $ST $F,`5*$SZ`($ctx) | ||
370 | $ST $G,`6*$SZ`($ctx) | ||
371 | $UCMP $inp,$num | ||
372 | $ST $H,`7*$SZ`($ctx) | ||
373 | bne Lsha2_block_private | ||
374 | blr | ||
375 | ___ | ||
376 | |||
377 | # Ugly hack here, because PPC assembler syntax seem to vary too | ||
378 | # much from platforms to platform... | ||
379 | $code.=<<___; | ||
380 | .align 6 | ||
381 | LPICmeup: | ||
382 | bl LPIC | ||
383 | addi $Tbl,$Tbl,`64-4` ; "distance" between . and last nop | ||
384 | b LPICedup | ||
385 | nop | ||
386 | nop | ||
387 | nop | ||
388 | nop | ||
389 | nop | ||
390 | LPIC: mflr $Tbl | ||
391 | blr | ||
392 | nop | ||
393 | nop | ||
394 | nop | ||
395 | nop | ||
396 | nop | ||
397 | nop | ||
398 | ___ | ||
399 | $code.=<<___ if ($SZ==8); | ||
400 | .long 0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd | ||
401 | .long 0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc | ||
402 | .long 0x3956c25b,0xf348b538,0x59f111f1,0xb605d019 | ||
403 | .long 0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118 | ||
404 | .long 0xd807aa98,0xa3030242,0x12835b01,0x45706fbe | ||
405 | .long 0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2 | ||
406 | .long 0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1 | ||
407 | .long 0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694 | ||
408 | .long 0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3 | ||
409 | .long 0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65 | ||
410 | .long 0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483 | ||
411 | .long 0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5 | ||
412 | .long 0x983e5152,0xee66dfab,0xa831c66d,0x2db43210 | ||
413 | .long 0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4 | ||
414 | .long 0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725 | ||
415 | .long 0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70 | ||
416 | .long 0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926 | ||
417 | .long 0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df | ||
418 | .long 0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8 | ||
419 | .long 0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b | ||
420 | .long 0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001 | ||
421 | .long 0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30 | ||
422 | .long 0xd192e819,0xd6ef5218,0xd6990624,0x5565a910 | ||
423 | .long 0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8 | ||
424 | .long 0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53 | ||
425 | .long 0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8 | ||
426 | .long 0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb | ||
427 | .long 0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3 | ||
428 | .long 0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60 | ||
429 | .long 0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec | ||
430 | .long 0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9 | ||
431 | .long 0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b | ||
432 | .long 0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207 | ||
433 | .long 0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178 | ||
434 | .long 0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6 | ||
435 | .long 0x113f9804,0xbef90dae,0x1b710b35,0x131c471b | ||
436 | .long 0x28db77f5,0x23047d84,0x32caab7b,0x40c72493 | ||
437 | .long 0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c | ||
438 | .long 0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a | ||
439 | .long 0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817 | ||
440 | ___ | ||
441 | $code.=<<___ if ($SZ==4); | ||
442 | .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 | ||
443 | .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 | ||
444 | .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 | ||
445 | .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 | ||
446 | .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc | ||
447 | .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da | ||
448 | .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 | ||
449 | .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 | ||
450 | .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 | ||
451 | .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 | ||
452 | .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 | ||
453 | .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 | ||
454 | .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 | ||
455 | .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 | ||
456 | .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 | ||
457 | .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 | ||
458 | ___ | ||
459 | |||
460 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
461 | print $code; | ||
462 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/sha/asm/sha512-s390x.pl b/src/lib/libcrypto/sha/asm/sha512-s390x.pl new file mode 100644 index 0000000000..e7ef2d5a9f --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha512-s390x.pl | |||
@@ -0,0 +1,301 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # SHA256/512 block procedures for s390x. | ||
11 | |||
12 | # April 2007. | ||
13 | # | ||
14 | # sha256_block_data_order is reportedly >3 times faster than gcc 3.3 | ||
15 | # generated code (must be a bug in compiler, as improvement is | ||
16 | # "pathologically" high, in particular in comparison to other SHA | ||
17 | # modules). But the real twist is that it detects if hardware support | ||
18 | # for SHA256 is available and in such case utilizes it. Then the | ||
19 | # performance can reach >6.5x of assembler one for larger chunks. | ||
20 | # | ||
21 | # sha512_block_data_order is ~70% faster than gcc 3.3 generated code. | ||
22 | |||
23 | # January 2009. | ||
24 | # | ||
25 | # Add support for hardware SHA512 and reschedule instructions to | ||
26 | # favour dual-issue z10 pipeline. Hardware SHA256/512 is ~4.7x faster | ||
27 | # than software. | ||
28 | |||
29 | $t0="%r0"; | ||
30 | $t1="%r1"; | ||
31 | $ctx="%r2"; $t2="%r2"; | ||
32 | $inp="%r3"; | ||
33 | $len="%r4"; # used as index in inner loop | ||
34 | |||
35 | $A="%r5"; | ||
36 | $B="%r6"; | ||
37 | $C="%r7"; | ||
38 | $D="%r8"; | ||
39 | $E="%r9"; | ||
40 | $F="%r10"; | ||
41 | $G="%r11"; | ||
42 | $H="%r12"; @V=($A,$B,$C,$D,$E,$F,$G,$H); | ||
43 | $tbl="%r13"; | ||
44 | $T1="%r14"; | ||
45 | $sp="%r15"; | ||
46 | |||
47 | $output=shift; | ||
48 | open STDOUT,">$output"; | ||
49 | |||
50 | if ($output =~ /512/) { | ||
51 | $label="512"; | ||
52 | $SZ=8; | ||
53 | $LD="lg"; # load from memory | ||
54 | $ST="stg"; # store to memory | ||
55 | $ADD="alg"; # add with memory operand | ||
56 | $ROT="rllg"; # rotate left | ||
57 | $SHR="srlg"; # logical right shift [see even at the end] | ||
58 | @Sigma0=(25,30,36); | ||
59 | @Sigma1=(23,46,50); | ||
60 | @sigma0=(56,63, 7); | ||
61 | @sigma1=( 3,45, 6); | ||
62 | $rounds=80; | ||
63 | $kimdfunc=3; # 0 means unknown/unsupported/unimplemented/disabled | ||
64 | } else { | ||
65 | $label="256"; | ||
66 | $SZ=4; | ||
67 | $LD="llgf"; # load from memory | ||
68 | $ST="st"; # store to memory | ||
69 | $ADD="al"; # add with memory operand | ||
70 | $ROT="rll"; # rotate left | ||
71 | $SHR="srl"; # logical right shift | ||
72 | @Sigma0=(10,19,30); | ||
73 | @Sigma1=( 7,21,26); | ||
74 | @sigma0=(14,25, 3); | ||
75 | @sigma1=(13,15,10); | ||
76 | $rounds=64; | ||
77 | $kimdfunc=2; # magic function code for kimd instruction | ||
78 | } | ||
79 | $Func="sha${label}_block_data_order"; | ||
80 | $Table="K${label}"; | ||
81 | $frame=160+16*$SZ; | ||
82 | |||
83 | sub BODY_00_15 { | ||
84 | my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; | ||
85 | |||
86 | $code.=<<___ if ($i<16); | ||
87 | $LD $T1,`$i*$SZ`($inp) ### $i | ||
88 | ___ | ||
89 | $code.=<<___; | ||
90 | $ROT $t0,$e,$Sigma1[0] | ||
91 | $ROT $t1,$e,$Sigma1[1] | ||
92 | lgr $t2,$f | ||
93 | xgr $t0,$t1 | ||
94 | $ROT $t1,$t1,`$Sigma1[2]-$Sigma1[1]` | ||
95 | xgr $t2,$g | ||
96 | $ST $T1,`160+$SZ*($i%16)`($sp) | ||
97 | xgr $t0,$t1 # Sigma1(e) | ||
98 | la $T1,0($T1,$h) # T1+=h | ||
99 | ngr $t2,$e | ||
100 | lgr $t1,$a | ||
101 | algr $T1,$t0 # T1+=Sigma1(e) | ||
102 | $ROT $h,$a,$Sigma0[0] | ||
103 | xgr $t2,$g # Ch(e,f,g) | ||
104 | $ADD $T1,`$i*$SZ`($len,$tbl) # T1+=K[i] | ||
105 | $ROT $t0,$a,$Sigma0[1] | ||
106 | algr $T1,$t2 # T1+=Ch(e,f,g) | ||
107 | ogr $t1,$b | ||
108 | xgr $h,$t0 | ||
109 | lgr $t2,$a | ||
110 | ngr $t1,$c | ||
111 | $ROT $t0,$t0,`$Sigma0[2]-$Sigma0[1]` | ||
112 | xgr $h,$t0 # h=Sigma0(a) | ||
113 | ngr $t2,$b | ||
114 | algr $h,$T1 # h+=T1 | ||
115 | ogr $t2,$t1 # Maj(a,b,c) | ||
116 | la $d,0($d,$T1) # d+=T1 | ||
117 | algr $h,$t2 # h+=Maj(a,b,c) | ||
118 | ___ | ||
119 | } | ||
120 | |||
121 | sub BODY_16_XX { | ||
122 | my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; | ||
123 | |||
124 | $code.=<<___; | ||
125 | $LD $T1,`160+$SZ*(($i+1)%16)`($sp) ### $i | ||
126 | $LD $t1,`160+$SZ*(($i+14)%16)`($sp) | ||
127 | $ROT $t0,$T1,$sigma0[0] | ||
128 | $SHR $T1,$sigma0[2] | ||
129 | $ROT $t2,$t0,`$sigma0[1]-$sigma0[0]` | ||
130 | xgr $T1,$t0 | ||
131 | $ROT $t0,$t1,$sigma1[0] | ||
132 | xgr $T1,$t2 # sigma0(X[i+1]) | ||
133 | $SHR $t1,$sigma1[2] | ||
134 | $ADD $T1,`160+$SZ*($i%16)`($sp) # +=X[i] | ||
135 | xgr $t1,$t0 | ||
136 | $ROT $t0,$t0,`$sigma1[1]-$sigma1[0]` | ||
137 | $ADD $T1,`160+$SZ*(($i+9)%16)`($sp) # +=X[i+9] | ||
138 | xgr $t1,$t0 # sigma1(X[i+14]) | ||
139 | algr $T1,$t1 # +=sigma1(X[i+14]) | ||
140 | ___ | ||
141 | &BODY_00_15(@_); | ||
142 | } | ||
143 | |||
144 | $code.=<<___; | ||
145 | .text | ||
146 | .align 64 | ||
147 | .type $Table,\@object | ||
148 | $Table: | ||
149 | ___ | ||
150 | $code.=<<___ if ($SZ==4); | ||
151 | .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 | ||
152 | .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 | ||
153 | .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 | ||
154 | .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 | ||
155 | .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc | ||
156 | .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da | ||
157 | .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 | ||
158 | .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 | ||
159 | .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 | ||
160 | .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 | ||
161 | .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 | ||
162 | .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 | ||
163 | .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 | ||
164 | .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 | ||
165 | .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 | ||
166 | .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 | ||
167 | ___ | ||
168 | $code.=<<___ if ($SZ==8); | ||
169 | .quad 0x428a2f98d728ae22,0x7137449123ef65cd | ||
170 | .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc | ||
171 | .quad 0x3956c25bf348b538,0x59f111f1b605d019 | ||
172 | .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 | ||
173 | .quad 0xd807aa98a3030242,0x12835b0145706fbe | ||
174 | .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 | ||
175 | .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 | ||
176 | .quad 0x9bdc06a725c71235,0xc19bf174cf692694 | ||
177 | .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 | ||
178 | .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 | ||
179 | .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 | ||
180 | .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 | ||
181 | .quad 0x983e5152ee66dfab,0xa831c66d2db43210 | ||
182 | .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 | ||
183 | .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 | ||
184 | .quad 0x06ca6351e003826f,0x142929670a0e6e70 | ||
185 | .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 | ||
186 | .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df | ||
187 | .quad 0x650a73548baf63de,0x766a0abb3c77b2a8 | ||
188 | .quad 0x81c2c92e47edaee6,0x92722c851482353b | ||
189 | .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 | ||
190 | .quad 0xc24b8b70d0f89791,0xc76c51a30654be30 | ||
191 | .quad 0xd192e819d6ef5218,0xd69906245565a910 | ||
192 | .quad 0xf40e35855771202a,0x106aa07032bbd1b8 | ||
193 | .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 | ||
194 | .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 | ||
195 | .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb | ||
196 | .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 | ||
197 | .quad 0x748f82ee5defb2fc,0x78a5636f43172f60 | ||
198 | .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec | ||
199 | .quad 0x90befffa23631e28,0xa4506cebde82bde9 | ||
200 | .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b | ||
201 | .quad 0xca273eceea26619c,0xd186b8c721c0c207 | ||
202 | .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 | ||
203 | .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 | ||
204 | .quad 0x113f9804bef90dae,0x1b710b35131c471b | ||
205 | .quad 0x28db77f523047d84,0x32caab7b40c72493 | ||
206 | .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c | ||
207 | .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a | ||
208 | .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 | ||
209 | ___ | ||
210 | $code.=<<___; | ||
211 | .size $Table,.-$Table | ||
212 | .globl $Func | ||
213 | .type $Func,\@function | ||
214 | $Func: | ||
215 | ___ | ||
216 | $code.=<<___ if ($kimdfunc); | ||
217 | larl %r1,OPENSSL_s390xcap_P | ||
218 | lg %r0,0(%r1) | ||
219 | tmhl %r0,0x4000 # check for message-security assist | ||
220 | jz .Lsoftware | ||
221 | lghi %r0,0 | ||
222 | la %r1,16($sp) | ||
223 | .long 0xb93e0002 # kimd %r0,%r2 | ||
224 | lg %r0,16($sp) | ||
225 | tmhh %r0,`0x8000>>$kimdfunc` | ||
226 | jz .Lsoftware | ||
227 | lghi %r0,$kimdfunc | ||
228 | lgr %r1,$ctx | ||
229 | lgr %r2,$inp | ||
230 | sllg %r3,$len,`log(16*$SZ)/log(2)` | ||
231 | .long 0xb93e0002 # kimd %r0,%r2 | ||
232 | brc 1,.-4 # pay attention to "partial completion" | ||
233 | br %r14 | ||
234 | .align 16 | ||
235 | .Lsoftware: | ||
236 | ___ | ||
237 | $code.=<<___; | ||
238 | sllg $len,$len,`log(16*$SZ)/log(2)` | ||
239 | lghi %r1,-$frame | ||
240 | agr $len,$inp | ||
241 | stmg $ctx,%r15,16($sp) | ||
242 | lgr %r0,$sp | ||
243 | la $sp,0(%r1,$sp) | ||
244 | stg %r0,0($sp) | ||
245 | |||
246 | larl $tbl,$Table | ||
247 | $LD $A,`0*$SZ`($ctx) | ||
248 | $LD $B,`1*$SZ`($ctx) | ||
249 | $LD $C,`2*$SZ`($ctx) | ||
250 | $LD $D,`3*$SZ`($ctx) | ||
251 | $LD $E,`4*$SZ`($ctx) | ||
252 | $LD $F,`5*$SZ`($ctx) | ||
253 | $LD $G,`6*$SZ`($ctx) | ||
254 | $LD $H,`7*$SZ`($ctx) | ||
255 | |||
256 | .Lloop: | ||
257 | lghi $len,0 | ||
258 | ___ | ||
259 | for ($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } | ||
260 | $code.=".Lrounds_16_xx:\n"; | ||
261 | for (;$i<32;$i++) { &BODY_16_XX($i,@V); unshift(@V,pop(@V)); } | ||
262 | $code.=<<___; | ||
263 | aghi $len,`16*$SZ` | ||
264 | lghi $t0,`($rounds-16)*$SZ` | ||
265 | clgr $len,$t0 | ||
266 | jne .Lrounds_16_xx | ||
267 | |||
268 | lg $ctx,`$frame+16`($sp) | ||
269 | la $inp,`16*$SZ`($inp) | ||
270 | $ADD $A,`0*$SZ`($ctx) | ||
271 | $ADD $B,`1*$SZ`($ctx) | ||
272 | $ADD $C,`2*$SZ`($ctx) | ||
273 | $ADD $D,`3*$SZ`($ctx) | ||
274 | $ADD $E,`4*$SZ`($ctx) | ||
275 | $ADD $F,`5*$SZ`($ctx) | ||
276 | $ADD $G,`6*$SZ`($ctx) | ||
277 | $ADD $H,`7*$SZ`($ctx) | ||
278 | $ST $A,`0*$SZ`($ctx) | ||
279 | $ST $B,`1*$SZ`($ctx) | ||
280 | $ST $C,`2*$SZ`($ctx) | ||
281 | $ST $D,`3*$SZ`($ctx) | ||
282 | $ST $E,`4*$SZ`($ctx) | ||
283 | $ST $F,`5*$SZ`($ctx) | ||
284 | $ST $G,`6*$SZ`($ctx) | ||
285 | $ST $H,`7*$SZ`($ctx) | ||
286 | clg $inp,`$frame+32`($sp) | ||
287 | jne .Lloop | ||
288 | |||
289 | lmg %r6,%r15,`$frame+48`($sp) | ||
290 | br %r14 | ||
291 | .size $Func,.-$Func | ||
292 | .string "SHA${label} block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>" | ||
293 | .comm OPENSSL_s390xcap_P,8,8 | ||
294 | ___ | ||
295 | |||
296 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
297 | # unlike 32-bit shift 64-bit one takes three arguments | ||
298 | $code =~ s/(srlg\s+)(%r[0-9]+),/$1$2,$2,/gm; | ||
299 | |||
300 | print $code; | ||
301 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/sha/asm/sha512-sparcv9.pl b/src/lib/libcrypto/sha/asm/sha512-sparcv9.pl new file mode 100644 index 0000000000..54241aab50 --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha512-sparcv9.pl | |||
@@ -0,0 +1,593 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # SHA256 performance improvement over compiler generated code varies | ||
11 | # from 40% for Sun C [32-bit build] to 70% for gcc [3.3, 64-bit | ||
12 | # build]. Just like in SHA1 module I aim to ensure scalability on | ||
13 | # UltraSPARC T1 by packing X[16] to 8 64-bit registers. | ||
14 | |||
15 | # SHA512 on pre-T1 UltraSPARC. | ||
16 | # | ||
17 | # Performance is >75% better than 64-bit code generated by Sun C and | ||
18 | # over 2x than 32-bit code. X[16] resides on stack, but access to it | ||
19 | # is scheduled for L2 latency and staged through 32 least significant | ||
20 | # bits of %l0-%l7. The latter is done to achieve 32-/64-bit ABI | ||
21 | # duality. Nevetheless it's ~40% faster than SHA256, which is pretty | ||
22 | # good [optimal coefficient is 50%]. | ||
23 | # | ||
24 | # SHA512 on UltraSPARC T1. | ||
25 | # | ||
26 | # It's not any faster than 64-bit code generated by Sun C 5.8. This is | ||
27 | # because 64-bit code generator has the advantage of using 64-bit | ||
28 | # loads(*) to access X[16], which I consciously traded for 32-/64-bit | ||
29 | # ABI duality [as per above]. But it surpasses 32-bit Sun C generated | ||
30 | # code by 60%, not to mention that it doesn't suffer from severe decay | ||
31 | # when running 4 times physical cores threads and that it leaves gcc | ||
32 | # [3.4] behind by over 4x factor! If compared to SHA256, single thread | ||
33 | # performance is only 10% better, but overall throughput for maximum | ||
34 | # amount of threads for given CPU exceeds corresponding one of SHA256 | ||
35 | # by 30% [again, optimal coefficient is 50%]. | ||
36 | # | ||
37 | # (*) Unlike pre-T1 UltraSPARC loads on T1 are executed strictly | ||
38 | # in-order, i.e. load instruction has to complete prior next | ||
39 | # instruction in given thread is executed, even if the latter is | ||
40 | # not dependent on load result! This means that on T1 two 32-bit | ||
41 | # loads are always slower than one 64-bit load. Once again this | ||
42 | # is unlike pre-T1 UltraSPARC, where, if scheduled appropriately, | ||
43 | # 2x32-bit loads can be as fast as 1x64-bit ones. | ||
44 | |||
45 | $bits=32; | ||
46 | for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } | ||
47 | if ($bits==64) { $bias=2047; $frame=192; } | ||
48 | else { $bias=0; $frame=112; } | ||
49 | |||
50 | $output=shift; | ||
51 | open STDOUT,">$output"; | ||
52 | |||
53 | if ($output =~ /512/) { | ||
54 | $label="512"; | ||
55 | $SZ=8; | ||
56 | $LD="ldx"; # load from memory | ||
57 | $ST="stx"; # store to memory | ||
58 | $SLL="sllx"; # shift left logical | ||
59 | $SRL="srlx"; # shift right logical | ||
60 | @Sigma0=(28,34,39); | ||
61 | @Sigma1=(14,18,41); | ||
62 | @sigma0=( 7, 1, 8); # right shift first | ||
63 | @sigma1=( 6,19,61); # right shift first | ||
64 | $lastK=0x817; | ||
65 | $rounds=80; | ||
66 | $align=4; | ||
67 | |||
68 | $locals=16*$SZ; # X[16] | ||
69 | |||
70 | $A="%o0"; | ||
71 | $B="%o1"; | ||
72 | $C="%o2"; | ||
73 | $D="%o3"; | ||
74 | $E="%o4"; | ||
75 | $F="%o5"; | ||
76 | $G="%g1"; | ||
77 | $H="%o7"; | ||
78 | @V=($A,$B,$C,$D,$E,$F,$G,$H); | ||
79 | } else { | ||
80 | $label="256"; | ||
81 | $SZ=4; | ||
82 | $LD="ld"; # load from memory | ||
83 | $ST="st"; # store to memory | ||
84 | $SLL="sll"; # shift left logical | ||
85 | $SRL="srl"; # shift right logical | ||
86 | @Sigma0=( 2,13,22); | ||
87 | @Sigma1=( 6,11,25); | ||
88 | @sigma0=( 3, 7,18); # right shift first | ||
89 | @sigma1=(10,17,19); # right shift first | ||
90 | $lastK=0x8f2; | ||
91 | $rounds=64; | ||
92 | $align=8; | ||
93 | |||
94 | $locals=0; # X[16] is register resident | ||
95 | @X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7"); | ||
96 | |||
97 | $A="%l0"; | ||
98 | $B="%l1"; | ||
99 | $C="%l2"; | ||
100 | $D="%l3"; | ||
101 | $E="%l4"; | ||
102 | $F="%l5"; | ||
103 | $G="%l6"; | ||
104 | $H="%l7"; | ||
105 | @V=($A,$B,$C,$D,$E,$F,$G,$H); | ||
106 | } | ||
107 | $T1="%g2"; | ||
108 | $tmp0="%g3"; | ||
109 | $tmp1="%g4"; | ||
110 | $tmp2="%g5"; | ||
111 | |||
112 | $ctx="%i0"; | ||
113 | $inp="%i1"; | ||
114 | $len="%i2"; | ||
115 | $Ktbl="%i3"; | ||
116 | $tmp31="%i4"; | ||
117 | $tmp32="%i5"; | ||
118 | |||
119 | ########### SHA256 | ||
120 | $Xload = sub { | ||
121 | my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; | ||
122 | |||
123 | if ($i==0) { | ||
124 | $code.=<<___; | ||
125 | ldx [$inp+0],@X[0] | ||
126 | ldx [$inp+16],@X[2] | ||
127 | ldx [$inp+32],@X[4] | ||
128 | ldx [$inp+48],@X[6] | ||
129 | ldx [$inp+8],@X[1] | ||
130 | ldx [$inp+24],@X[3] | ||
131 | subcc %g0,$tmp31,$tmp32 ! should be 64-$tmp31, but -$tmp31 works too | ||
132 | ldx [$inp+40],@X[5] | ||
133 | bz,pt %icc,.Laligned | ||
134 | ldx [$inp+56],@X[7] | ||
135 | |||
136 | sllx @X[0],$tmp31,@X[0] | ||
137 | ldx [$inp+64],$T1 | ||
138 | ___ | ||
139 | for($j=0;$j<7;$j++) | ||
140 | { $code.=<<___; | ||
141 | srlx @X[$j+1],$tmp32,$tmp1 | ||
142 | sllx @X[$j+1],$tmp31,@X[$j+1] | ||
143 | or $tmp1,@X[$j],@X[$j] | ||
144 | ___ | ||
145 | } | ||
146 | $code.=<<___; | ||
147 | srlx $T1,$tmp32,$T1 | ||
148 | or $T1,@X[7],@X[7] | ||
149 | .Laligned: | ||
150 | ___ | ||
151 | } | ||
152 | |||
153 | if ($i&1) { | ||
154 | $code.="\tadd @X[$i/2],$h,$T1\n"; | ||
155 | } else { | ||
156 | $code.="\tsrlx @X[$i/2],32,$T1\n\tadd $h,$T1,$T1\n"; | ||
157 | } | ||
158 | } if ($SZ==4); | ||
159 | |||
160 | ########### SHA512 | ||
161 | $Xload = sub { | ||
162 | my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; | ||
163 | my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1),"%l".eval((($i+1)*2)%8)); | ||
164 | |||
165 | $code.=<<___ if ($i==0); | ||
166 | ld [$inp+0],%l0 | ||
167 | ld [$inp+4],%l1 | ||
168 | ld [$inp+8],%l2 | ||
169 | ld [$inp+12],%l3 | ||
170 | ld [$inp+16],%l4 | ||
171 | ld [$inp+20],%l5 | ||
172 | ld [$inp+24],%l6 | ||
173 | ld [$inp+28],%l7 | ||
174 | ___ | ||
175 | $code.=<<___ if ($i<15); | ||
176 | sllx @pair[1],$tmp31,$tmp2 ! Xload($i) | ||
177 | add $tmp31,32,$tmp0 | ||
178 | sllx @pair[0],$tmp0,$tmp1 | ||
179 | `"ld [$inp+".eval(32+0+$i*8)."],@pair[0]" if ($i<12)` | ||
180 | srlx @pair[2],$tmp32,@pair[1] | ||
181 | or $tmp1,$tmp2,$tmp2 | ||
182 | or @pair[1],$tmp2,$tmp2 | ||
183 | `"ld [$inp+".eval(32+4+$i*8)."],@pair[1]" if ($i<12)` | ||
184 | add $h,$tmp2,$T1 | ||
185 | $ST $tmp2,[%sp+`$bias+$frame+$i*$SZ`] | ||
186 | ___ | ||
187 | $code.=<<___ if ($i==12); | ||
188 | brnz,a $tmp31,.+8 | ||
189 | ld [$inp+128],%l0 | ||
190 | ___ | ||
191 | $code.=<<___ if ($i==15); | ||
192 | ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2 | ||
193 | sllx @pair[1],$tmp31,$tmp2 ! Xload($i) | ||
194 | add $tmp31,32,$tmp0 | ||
195 | ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3 | ||
196 | sllx @pair[0],$tmp0,$tmp1 | ||
197 | ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4 | ||
198 | srlx @pair[2],$tmp32,@pair[1] | ||
199 | or $tmp1,$tmp2,$tmp2 | ||
200 | ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5 | ||
201 | or @pair[1],$tmp2,$tmp2 | ||
202 | ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6 | ||
203 | add $h,$tmp2,$T1 | ||
204 | $ST $tmp2,[%sp+`$bias+$frame+$i*$SZ`] | ||
205 | ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7 | ||
206 | ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0 | ||
207 | ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1 | ||
208 | ___ | ||
209 | } if ($SZ==8); | ||
210 | |||
211 | ########### common | ||
212 | sub BODY_00_15 { | ||
213 | my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; | ||
214 | |||
215 | if ($i<16) { | ||
216 | &$Xload(@_); | ||
217 | } else { | ||
218 | $code.="\tadd $h,$T1,$T1\n"; | ||
219 | } | ||
220 | |||
221 | $code.=<<___; | ||
222 | $SRL $e,@Sigma1[0],$h !! $i | ||
223 | xor $f,$g,$tmp2 | ||
224 | $SLL $e,`$SZ*8-@Sigma1[2]`,$tmp1 | ||
225 | and $e,$tmp2,$tmp2 | ||
226 | $SRL $e,@Sigma1[1],$tmp0 | ||
227 | xor $tmp1,$h,$h | ||
228 | $SLL $e,`$SZ*8-@Sigma1[1]`,$tmp1 | ||
229 | xor $tmp0,$h,$h | ||
230 | $SRL $e,@Sigma1[2],$tmp0 | ||
231 | xor $tmp1,$h,$h | ||
232 | $SLL $e,`$SZ*8-@Sigma1[0]`,$tmp1 | ||
233 | xor $tmp0,$h,$h | ||
234 | xor $g,$tmp2,$tmp2 ! Ch(e,f,g) | ||
235 | xor $tmp1,$h,$tmp0 ! Sigma1(e) | ||
236 | |||
237 | $SRL $a,@Sigma0[0],$h | ||
238 | add $tmp2,$T1,$T1 | ||
239 | $LD [$Ktbl+`$i*$SZ`],$tmp2 ! K[$i] | ||
240 | $SLL $a,`$SZ*8-@Sigma0[2]`,$tmp1 | ||
241 | add $tmp0,$T1,$T1 | ||
242 | $SRL $a,@Sigma0[1],$tmp0 | ||
243 | xor $tmp1,$h,$h | ||
244 | $SLL $a,`$SZ*8-@Sigma0[1]`,$tmp1 | ||
245 | xor $tmp0,$h,$h | ||
246 | $SRL $a,@Sigma0[2],$tmp0 | ||
247 | xor $tmp1,$h,$h | ||
248 | $SLL $a,`$SZ*8-@Sigma0[0]`,$tmp1 | ||
249 | xor $tmp0,$h,$h | ||
250 | xor $tmp1,$h,$h ! Sigma0(a) | ||
251 | |||
252 | or $a,$b,$tmp0 | ||
253 | and $a,$b,$tmp1 | ||
254 | and $c,$tmp0,$tmp0 | ||
255 | or $tmp0,$tmp1,$tmp1 ! Maj(a,b,c) | ||
256 | add $tmp2,$T1,$T1 ! +=K[$i] | ||
257 | add $tmp1,$h,$h | ||
258 | |||
259 | add $T1,$d,$d | ||
260 | add $T1,$h,$h | ||
261 | ___ | ||
262 | } | ||
263 | |||
264 | ########### SHA256 | ||
265 | $BODY_16_XX = sub { | ||
266 | my $i=@_[0]; | ||
267 | my $xi; | ||
268 | |||
269 | if ($i&1) { | ||
270 | $xi=$tmp32; | ||
271 | $code.="\tsrlx @X[(($i+1)/2)%8],32,$xi\n"; | ||
272 | } else { | ||
273 | $xi=@X[(($i+1)/2)%8]; | ||
274 | } | ||
275 | $code.=<<___; | ||
276 | srl $xi,@sigma0[0],$T1 !! Xupdate($i) | ||
277 | sll $xi,`32-@sigma0[2]`,$tmp1 | ||
278 | srl $xi,@sigma0[1],$tmp0 | ||
279 | xor $tmp1,$T1,$T1 | ||
280 | sll $tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1 | ||
281 | xor $tmp0,$T1,$T1 | ||
282 | srl $xi,@sigma0[2],$tmp0 | ||
283 | xor $tmp1,$T1,$T1 | ||
284 | ___ | ||
285 | if ($i&1) { | ||
286 | $xi=@X[(($i+14)/2)%8]; | ||
287 | } else { | ||
288 | $xi=$tmp32; | ||
289 | $code.="\tsrlx @X[(($i+14)/2)%8],32,$xi\n"; | ||
290 | } | ||
291 | $code.=<<___; | ||
292 | srl $xi,@sigma1[0],$tmp2 | ||
293 | xor $tmp0,$T1,$T1 ! T1=sigma0(X[i+1]) | ||
294 | sll $xi,`32-@sigma1[2]`,$tmp1 | ||
295 | srl $xi,@sigma1[1],$tmp0 | ||
296 | xor $tmp1,$tmp2,$tmp2 | ||
297 | sll $tmp1,`@sigma1[2]-@sigma1[1]`,$tmp1 | ||
298 | xor $tmp0,$tmp2,$tmp2 | ||
299 | srl $xi,@sigma1[2],$tmp0 | ||
300 | xor $tmp1,$tmp2,$tmp2 | ||
301 | ___ | ||
302 | if ($i&1) { | ||
303 | $xi=@X[($i/2)%8]; | ||
304 | $code.=<<___; | ||
305 | srlx @X[(($i+9)/2)%8],32,$tmp1 ! X[i+9] | ||
306 | xor $tmp0,$tmp2,$tmp2 ! sigma1(X[i+14]) | ||
307 | srl @X[($i/2)%8],0,$tmp0 | ||
308 | add $xi,$T1,$T1 ! +=X[i] | ||
309 | xor $tmp0,@X[($i/2)%8],@X[($i/2)%8] | ||
310 | add $tmp2,$T1,$T1 | ||
311 | add $tmp1,$T1,$T1 | ||
312 | |||
313 | srl $T1,0,$T1 | ||
314 | or $T1,@X[($i/2)%8],@X[($i/2)%8] | ||
315 | ___ | ||
316 | } else { | ||
317 | $xi=@X[(($i+9)/2)%8]; | ||
318 | $code.=<<___; | ||
319 | srlx @X[($i/2)%8],32,$tmp1 ! X[i] | ||
320 | xor $tmp0,$tmp2,$tmp2 ! sigma1(X[i+14]) | ||
321 | srl @X[($i/2)%8],0,@X[($i/2)%8] | ||
322 | add $xi,$T1,$T1 ! +=X[i+9] | ||
323 | add $tmp2,$T1,$T1 | ||
324 | add $tmp1,$T1,$T1 | ||
325 | |||
326 | sllx $T1,32,$tmp0 | ||
327 | or $tmp0,@X[($i/2)%8],@X[($i/2)%8] | ||
328 | ___ | ||
329 | } | ||
330 | &BODY_00_15(@_); | ||
331 | } if ($SZ==4); | ||
332 | |||
333 | ########### SHA512 | ||
334 | $BODY_16_XX = sub { | ||
335 | my $i=@_[0]; | ||
336 | my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1)); | ||
337 | |||
338 | $code.=<<___; | ||
339 | sllx %l2,32,$tmp0 !! Xupdate($i) | ||
340 | or %l3,$tmp0,$tmp0 | ||
341 | |||
342 | srlx $tmp0,@sigma0[0],$T1 | ||
343 | ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2 | ||
344 | sllx $tmp0,`64-@sigma0[2]`,$tmp1 | ||
345 | ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3 | ||
346 | srlx $tmp0,@sigma0[1],$tmp0 | ||
347 | xor $tmp1,$T1,$T1 | ||
348 | sllx $tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1 | ||
349 | xor $tmp0,$T1,$T1 | ||
350 | srlx $tmp0,`@sigma0[2]-@sigma0[1]`,$tmp0 | ||
351 | xor $tmp1,$T1,$T1 | ||
352 | sllx %l6,32,$tmp2 | ||
353 | xor $tmp0,$T1,$T1 ! sigma0(X[$i+1]) | ||
354 | or %l7,$tmp2,$tmp2 | ||
355 | |||
356 | srlx $tmp2,@sigma1[0],$tmp1 | ||
357 | ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6 | ||
358 | sllx $tmp2,`64-@sigma1[2]`,$tmp0 | ||
359 | ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7 | ||
360 | srlx $tmp2,@sigma1[1],$tmp2 | ||
361 | xor $tmp0,$tmp1,$tmp1 | ||
362 | sllx $tmp0,`@sigma1[2]-@sigma1[1]`,$tmp0 | ||
363 | xor $tmp2,$tmp1,$tmp1 | ||
364 | srlx $tmp2,`@sigma1[2]-@sigma1[1]`,$tmp2 | ||
365 | xor $tmp0,$tmp1,$tmp1 | ||
366 | sllx %l4,32,$tmp0 | ||
367 | xor $tmp2,$tmp1,$tmp1 ! sigma1(X[$i+14]) | ||
368 | ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4 | ||
369 | or %l5,$tmp0,$tmp0 | ||
370 | ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5 | ||
371 | |||
372 | sllx %l0,32,$tmp2 | ||
373 | add $tmp1,$T1,$T1 | ||
374 | ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0 | ||
375 | or %l1,$tmp2,$tmp2 | ||
376 | add $tmp0,$T1,$T1 ! +=X[$i+9] | ||
377 | ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1 | ||
378 | add $tmp2,$T1,$T1 ! +=X[$i] | ||
379 | $ST $T1,[%sp+`$bias+$frame+($i%16)*$SZ`] | ||
380 | ___ | ||
381 | &BODY_00_15(@_); | ||
382 | } if ($SZ==8); | ||
383 | |||
384 | $code.=<<___ if ($bits==64); | ||
385 | .register %g2,#scratch | ||
386 | .register %g3,#scratch | ||
387 | ___ | ||
388 | $code.=<<___; | ||
389 | .section ".text",#alloc,#execinstr | ||
390 | |||
391 | .align 64 | ||
392 | K${label}: | ||
393 | .type K${label},#object | ||
394 | ___ | ||
395 | if ($SZ==4) { | ||
396 | $code.=<<___; | ||
397 | .long 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5 | ||
398 | .long 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5 | ||
399 | .long 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3 | ||
400 | .long 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174 | ||
401 | .long 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc | ||
402 | .long 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da | ||
403 | .long 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7 | ||
404 | .long 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967 | ||
405 | .long 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13 | ||
406 | .long 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85 | ||
407 | .long 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3 | ||
408 | .long 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070 | ||
409 | .long 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5 | ||
410 | .long 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3 | ||
411 | .long 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208 | ||
412 | .long 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | ||
413 | ___ | ||
414 | } else { | ||
415 | $code.=<<___; | ||
416 | .long 0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd | ||
417 | .long 0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc | ||
418 | .long 0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019 | ||
419 | .long 0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118 | ||
420 | .long 0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe | ||
421 | .long 0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2 | ||
422 | .long 0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1 | ||
423 | .long 0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694 | ||
424 | .long 0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3 | ||
425 | .long 0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65 | ||
426 | .long 0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483 | ||
427 | .long 0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5 | ||
428 | .long 0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210 | ||
429 | .long 0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4 | ||
430 | .long 0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725 | ||
431 | .long 0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70 | ||
432 | .long 0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926 | ||
433 | .long 0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df | ||
434 | .long 0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8 | ||
435 | .long 0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b | ||
436 | .long 0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001 | ||
437 | .long 0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30 | ||
438 | .long 0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910 | ||
439 | .long 0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8 | ||
440 | .long 0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53 | ||
441 | .long 0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8 | ||
442 | .long 0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb | ||
443 | .long 0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3 | ||
444 | .long 0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60 | ||
445 | .long 0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec | ||
446 | .long 0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9 | ||
447 | .long 0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b | ||
448 | .long 0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207 | ||
449 | .long 0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178 | ||
450 | .long 0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6 | ||
451 | .long 0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b | ||
452 | .long 0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493 | ||
453 | .long 0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c | ||
454 | .long 0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a | ||
455 | .long 0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817 | ||
456 | ___ | ||
457 | } | ||
458 | $code.=<<___; | ||
459 | .size K${label},.-K${label} | ||
460 | .globl sha${label}_block_data_order | ||
461 | sha${label}_block_data_order: | ||
462 | save %sp,`-$frame-$locals`,%sp | ||
463 | and $inp,`$align-1`,$tmp31 | ||
464 | sllx $len,`log(16*$SZ)/log(2)`,$len | ||
465 | andn $inp,`$align-1`,$inp | ||
466 | sll $tmp31,3,$tmp31 | ||
467 | add $inp,$len,$len | ||
468 | ___ | ||
469 | $code.=<<___ if ($SZ==8); # SHA512 | ||
470 | mov 32,$tmp32 | ||
471 | sub $tmp32,$tmp31,$tmp32 | ||
472 | ___ | ||
473 | $code.=<<___; | ||
474 | .Lpic: call .+8 | ||
475 | add %o7,K${label}-.Lpic,$Ktbl | ||
476 | |||
477 | $LD [$ctx+`0*$SZ`],$A | ||
478 | $LD [$ctx+`1*$SZ`],$B | ||
479 | $LD [$ctx+`2*$SZ`],$C | ||
480 | $LD [$ctx+`3*$SZ`],$D | ||
481 | $LD [$ctx+`4*$SZ`],$E | ||
482 | $LD [$ctx+`5*$SZ`],$F | ||
483 | $LD [$ctx+`6*$SZ`],$G | ||
484 | $LD [$ctx+`7*$SZ`],$H | ||
485 | |||
486 | .Lloop: | ||
487 | ___ | ||
488 | for ($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } | ||
489 | $code.=".L16_xx:\n"; | ||
490 | for (;$i<32;$i++) { &$BODY_16_XX($i,@V); unshift(@V,pop(@V)); } | ||
491 | $code.=<<___; | ||
492 | and $tmp2,0xfff,$tmp2 | ||
493 | cmp $tmp2,$lastK | ||
494 | bne .L16_xx | ||
495 | add $Ktbl,`16*$SZ`,$Ktbl ! Ktbl+=16 | ||
496 | |||
497 | ___ | ||
498 | $code.=<<___ if ($SZ==4); # SHA256 | ||
499 | $LD [$ctx+`0*$SZ`],@X[0] | ||
500 | $LD [$ctx+`1*$SZ`],@X[1] | ||
501 | $LD [$ctx+`2*$SZ`],@X[2] | ||
502 | $LD [$ctx+`3*$SZ`],@X[3] | ||
503 | $LD [$ctx+`4*$SZ`],@X[4] | ||
504 | $LD [$ctx+`5*$SZ`],@X[5] | ||
505 | $LD [$ctx+`6*$SZ`],@X[6] | ||
506 | $LD [$ctx+`7*$SZ`],@X[7] | ||
507 | |||
508 | add $A,@X[0],$A | ||
509 | $ST $A,[$ctx+`0*$SZ`] | ||
510 | add $B,@X[1],$B | ||
511 | $ST $B,[$ctx+`1*$SZ`] | ||
512 | add $C,@X[2],$C | ||
513 | $ST $C,[$ctx+`2*$SZ`] | ||
514 | add $D,@X[3],$D | ||
515 | $ST $D,[$ctx+`3*$SZ`] | ||
516 | add $E,@X[4],$E | ||
517 | $ST $E,[$ctx+`4*$SZ`] | ||
518 | add $F,@X[5],$F | ||
519 | $ST $F,[$ctx+`5*$SZ`] | ||
520 | add $G,@X[6],$G | ||
521 | $ST $G,[$ctx+`6*$SZ`] | ||
522 | add $H,@X[7],$H | ||
523 | $ST $H,[$ctx+`7*$SZ`] | ||
524 | ___ | ||
525 | $code.=<<___ if ($SZ==8); # SHA512 | ||
526 | ld [$ctx+`0*$SZ+0`],%l0 | ||
527 | ld [$ctx+`0*$SZ+4`],%l1 | ||
528 | ld [$ctx+`1*$SZ+0`],%l2 | ||
529 | ld [$ctx+`1*$SZ+4`],%l3 | ||
530 | ld [$ctx+`2*$SZ+0`],%l4 | ||
531 | ld [$ctx+`2*$SZ+4`],%l5 | ||
532 | ld [$ctx+`3*$SZ+0`],%l6 | ||
533 | |||
534 | sllx %l0,32,$tmp0 | ||
535 | ld [$ctx+`3*$SZ+4`],%l7 | ||
536 | sllx %l2,32,$tmp1 | ||
537 | or %l1,$tmp0,$tmp0 | ||
538 | or %l3,$tmp1,$tmp1 | ||
539 | add $tmp0,$A,$A | ||
540 | add $tmp1,$B,$B | ||
541 | $ST $A,[$ctx+`0*$SZ`] | ||
542 | sllx %l4,32,$tmp2 | ||
543 | $ST $B,[$ctx+`1*$SZ`] | ||
544 | sllx %l6,32,$T1 | ||
545 | or %l5,$tmp2,$tmp2 | ||
546 | or %l7,$T1,$T1 | ||
547 | add $tmp2,$C,$C | ||
548 | $ST $C,[$ctx+`2*$SZ`] | ||
549 | add $T1,$D,$D | ||
550 | $ST $D,[$ctx+`3*$SZ`] | ||
551 | |||
552 | ld [$ctx+`4*$SZ+0`],%l0 | ||
553 | ld [$ctx+`4*$SZ+4`],%l1 | ||
554 | ld [$ctx+`5*$SZ+0`],%l2 | ||
555 | ld [$ctx+`5*$SZ+4`],%l3 | ||
556 | ld [$ctx+`6*$SZ+0`],%l4 | ||
557 | ld [$ctx+`6*$SZ+4`],%l5 | ||
558 | ld [$ctx+`7*$SZ+0`],%l6 | ||
559 | |||
560 | sllx %l0,32,$tmp0 | ||
561 | ld [$ctx+`7*$SZ+4`],%l7 | ||
562 | sllx %l2,32,$tmp1 | ||
563 | or %l1,$tmp0,$tmp0 | ||
564 | or %l3,$tmp1,$tmp1 | ||
565 | add $tmp0,$E,$E | ||
566 | add $tmp1,$F,$F | ||
567 | $ST $E,[$ctx+`4*$SZ`] | ||
568 | sllx %l4,32,$tmp2 | ||
569 | $ST $F,[$ctx+`5*$SZ`] | ||
570 | sllx %l6,32,$T1 | ||
571 | or %l5,$tmp2,$tmp2 | ||
572 | or %l7,$T1,$T1 | ||
573 | add $tmp2,$G,$G | ||
574 | $ST $G,[$ctx+`6*$SZ`] | ||
575 | add $T1,$H,$H | ||
576 | $ST $H,[$ctx+`7*$SZ`] | ||
577 | ___ | ||
578 | $code.=<<___; | ||
579 | add $inp,`16*$SZ`,$inp ! advance inp | ||
580 | cmp $inp,$len | ||
581 | bne `$bits==64?"%xcc":"%icc"`,.Lloop | ||
582 | sub $Ktbl,`($rounds-16)*$SZ`,$Ktbl ! rewind Ktbl | ||
583 | |||
584 | ret | ||
585 | restore | ||
586 | .type sha${label}_block_data_order,#function | ||
587 | .size sha${label}_block_data_order,(.-sha${label}_block_data_order) | ||
588 | .asciz "SHA${label} block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>" | ||
589 | ___ | ||
590 | |||
591 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
592 | print $code; | ||
593 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/sha/asm/sha512-x86_64.pl b/src/lib/libcrypto/sha/asm/sha512-x86_64.pl index b6252d31ec..e6643f8cf6 100755 --- a/src/lib/libcrypto/sha/asm/sha512-x86_64.pl +++ b/src/lib/libcrypto/sha/asm/sha512-x86_64.pl | |||
@@ -40,14 +40,18 @@ | |||
40 | # sha256_block:-( This is presumably because 64-bit shifts/rotates | 40 | # sha256_block:-( This is presumably because 64-bit shifts/rotates |
41 | # apparently are not atomic instructions, but implemented in microcode. | 41 | # apparently are not atomic instructions, but implemented in microcode. |
42 | 42 | ||
43 | $output=shift; | 43 | $flavour = shift; |
44 | $output = shift; | ||
45 | if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } | ||
46 | |||
47 | $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); | ||
44 | 48 | ||
45 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | 49 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; |
46 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | 50 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or |
47 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | 51 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or |
48 | die "can't locate x86_64-xlate.pl"; | 52 | die "can't locate x86_64-xlate.pl"; |
49 | 53 | ||
50 | open STDOUT,"| $^X $xlate $output"; | 54 | open STDOUT,"| $^X $xlate $flavour $output"; |
51 | 55 | ||
52 | if ($output =~ /512/) { | 56 | if ($output =~ /512/) { |
53 | $func="sha512_block_data_order"; | 57 | $func="sha512_block_data_order"; |
@@ -186,7 +190,7 @@ $func: | |||
186 | push %r13 | 190 | push %r13 |
187 | push %r14 | 191 | push %r14 |
188 | push %r15 | 192 | push %r15 |
189 | mov %rsp,%rbp # copy %rsp | 193 | mov %rsp,%r11 # copy %rsp |
190 | shl \$4,%rdx # num*16 | 194 | shl \$4,%rdx # num*16 |
191 | sub \$$framesz,%rsp | 195 | sub \$$framesz,%rsp |
192 | lea ($inp,%rdx,$SZ),%rdx # inp+num*16*$SZ | 196 | lea ($inp,%rdx,$SZ),%rdx # inp+num*16*$SZ |
@@ -194,10 +198,10 @@ $func: | |||
194 | mov $ctx,$_ctx # save ctx, 1st arg | 198 | mov $ctx,$_ctx # save ctx, 1st arg |
195 | mov $inp,$_inp # save inp, 2nd arh | 199 | mov $inp,$_inp # save inp, 2nd arh |
196 | mov %rdx,$_end # save end pointer, "3rd" arg | 200 | mov %rdx,$_end # save end pointer, "3rd" arg |
197 | mov %rbp,$_rsp # save copy of %rsp | 201 | mov %r11,$_rsp # save copy of %rsp |
202 | .Lprologue: | ||
198 | 203 | ||
199 | .picmeup $Tbl | 204 | lea $TABLE(%rip),$Tbl |
200 | lea $TABLE-.($Tbl),$Tbl | ||
201 | 205 | ||
202 | mov $SZ*0($ctx),$A | 206 | mov $SZ*0($ctx),$A |
203 | mov $SZ*1($ctx),$B | 207 | mov $SZ*1($ctx),$B |
@@ -257,14 +261,15 @@ $code.=<<___; | |||
257 | mov $H,$SZ*7($ctx) | 261 | mov $H,$SZ*7($ctx) |
258 | jb .Lloop | 262 | jb .Lloop |
259 | 263 | ||
260 | mov $_rsp,%rsp | 264 | mov $_rsp,%rsi |
261 | pop %r15 | 265 | mov (%rsi),%r15 |
262 | pop %r14 | 266 | mov 8(%rsi),%r14 |
263 | pop %r13 | 267 | mov 16(%rsi),%r13 |
264 | pop %r12 | 268 | mov 24(%rsi),%r12 |
265 | pop %rbp | 269 | mov 32(%rsi),%rbp |
266 | pop %rbx | 270 | mov 40(%rsi),%rbx |
267 | 271 | lea 48(%rsi),%rsp | |
272 | .Lepilogue: | ||
268 | ret | 273 | ret |
269 | .size $func,.-$func | 274 | .size $func,.-$func |
270 | ___ | 275 | ___ |
@@ -339,6 +344,113 @@ $TABLE: | |||
339 | ___ | 344 | ___ |
340 | } | 345 | } |
341 | 346 | ||
347 | # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, | ||
348 | # CONTEXT *context,DISPATCHER_CONTEXT *disp) | ||
349 | if ($win64) { | ||
350 | $rec="%rcx"; | ||
351 | $frame="%rdx"; | ||
352 | $context="%r8"; | ||
353 | $disp="%r9"; | ||
354 | |||
355 | $code.=<<___; | ||
356 | .extern __imp_RtlVirtualUnwind | ||
357 | .type se_handler,\@abi-omnipotent | ||
358 | .align 16 | ||
359 | se_handler: | ||
360 | push %rsi | ||
361 | push %rdi | ||
362 | push %rbx | ||
363 | push %rbp | ||
364 | push %r12 | ||
365 | push %r13 | ||
366 | push %r14 | ||
367 | push %r15 | ||
368 | pushfq | ||
369 | sub \$64,%rsp | ||
370 | |||
371 | mov 120($context),%rax # pull context->Rax | ||
372 | mov 248($context),%rbx # pull context->Rip | ||
373 | |||
374 | lea .Lprologue(%rip),%r10 | ||
375 | cmp %r10,%rbx # context->Rip<.Lprologue | ||
376 | jb .Lin_prologue | ||
377 | |||
378 | mov 152($context),%rax # pull context->Rsp | ||
379 | |||
380 | lea .Lepilogue(%rip),%r10 | ||
381 | cmp %r10,%rbx # context->Rip>=.Lepilogue | ||
382 | jae .Lin_prologue | ||
383 | |||
384 | mov 16*$SZ+3*8(%rax),%rax # pull $_rsp | ||
385 | lea 48(%rax),%rax | ||
386 | |||
387 | mov -8(%rax),%rbx | ||
388 | mov -16(%rax),%rbp | ||
389 | mov -24(%rax),%r12 | ||
390 | mov -32(%rax),%r13 | ||
391 | mov -40(%rax),%r14 | ||
392 | mov -48(%rax),%r15 | ||
393 | mov %rbx,144($context) # restore context->Rbx | ||
394 | mov %rbp,160($context) # restore context->Rbp | ||
395 | mov %r12,216($context) # restore context->R12 | ||
396 | mov %r13,224($context) # restore context->R13 | ||
397 | mov %r14,232($context) # restore context->R14 | ||
398 | mov %r15,240($context) # restore context->R15 | ||
399 | |||
400 | .Lin_prologue: | ||
401 | mov 8(%rax),%rdi | ||
402 | mov 16(%rax),%rsi | ||
403 | mov %rax,152($context) # restore context->Rsp | ||
404 | mov %rsi,168($context) # restore context->Rsi | ||
405 | mov %rdi,176($context) # restore context->Rdi | ||
406 | |||
407 | mov 40($disp),%rdi # disp->ContextRecord | ||
408 | mov $context,%rsi # context | ||
409 | mov \$154,%ecx # sizeof(CONTEXT) | ||
410 | .long 0xa548f3fc # cld; rep movsq | ||
411 | |||
412 | mov $disp,%rsi | ||
413 | xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER | ||
414 | mov 8(%rsi),%rdx # arg2, disp->ImageBase | ||
415 | mov 0(%rsi),%r8 # arg3, disp->ControlPc | ||
416 | mov 16(%rsi),%r9 # arg4, disp->FunctionEntry | ||
417 | mov 40(%rsi),%r10 # disp->ContextRecord | ||
418 | lea 56(%rsi),%r11 # &disp->HandlerData | ||
419 | lea 24(%rsi),%r12 # &disp->EstablisherFrame | ||
420 | mov %r10,32(%rsp) # arg5 | ||
421 | mov %r11,40(%rsp) # arg6 | ||
422 | mov %r12,48(%rsp) # arg7 | ||
423 | mov %rcx,56(%rsp) # arg8, (NULL) | ||
424 | call *__imp_RtlVirtualUnwind(%rip) | ||
425 | |||
426 | mov \$1,%eax # ExceptionContinueSearch | ||
427 | add \$64,%rsp | ||
428 | popfq | ||
429 | pop %r15 | ||
430 | pop %r14 | ||
431 | pop %r13 | ||
432 | pop %r12 | ||
433 | pop %rbp | ||
434 | pop %rbx | ||
435 | pop %rdi | ||
436 | pop %rsi | ||
437 | ret | ||
438 | .size se_handler,.-se_handler | ||
439 | |||
440 | .section .pdata | ||
441 | .align 4 | ||
442 | .rva .LSEH_begin_$func | ||
443 | .rva .LSEH_end_$func | ||
444 | .rva .LSEH_info_$func | ||
445 | |||
446 | .section .xdata | ||
447 | .align 8 | ||
448 | .LSEH_info_$func: | ||
449 | .byte 9,0,0,0 | ||
450 | .rva se_handler | ||
451 | ___ | ||
452 | } | ||
453 | |||
342 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | 454 | $code =~ s/\`([^\`]*)\`/eval $1/gem; |
343 | print $code; | 455 | print $code; |
344 | close STDOUT; | 456 | close STDOUT; |
diff --git a/src/lib/libcrypto/sha/sha256.c b/src/lib/libcrypto/sha/sha256.c index 3256a83e98..8952d87673 100644 --- a/src/lib/libcrypto/sha/sha256.c +++ b/src/lib/libcrypto/sha/sha256.c | |||
@@ -12,39 +12,29 @@ | |||
12 | 12 | ||
13 | #include <openssl/crypto.h> | 13 | #include <openssl/crypto.h> |
14 | #include <openssl/sha.h> | 14 | #include <openssl/sha.h> |
15 | #ifdef OPENSSL_FIPS | ||
16 | #include <openssl/fips.h> | ||
17 | #endif | ||
18 | |||
19 | #include <openssl/opensslv.h> | 15 | #include <openssl/opensslv.h> |
20 | 16 | ||
21 | const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT; | 17 | const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT; |
22 | 18 | ||
23 | int SHA224_Init (SHA256_CTX *c) | 19 | int SHA224_Init (SHA256_CTX *c) |
24 | { | 20 | { |
25 | #ifdef OPENSSL_FIPS | 21 | memset (c,0,sizeof(*c)); |
26 | FIPS_selftest_check(); | ||
27 | #endif | ||
28 | c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL; | 22 | c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL; |
29 | c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; | 23 | c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; |
30 | c->h[4]=0xffc00b31UL; c->h[5]=0x68581511UL; | 24 | c->h[4]=0xffc00b31UL; c->h[5]=0x68581511UL; |
31 | c->h[6]=0x64f98fa7UL; c->h[7]=0xbefa4fa4UL; | 25 | c->h[6]=0x64f98fa7UL; c->h[7]=0xbefa4fa4UL; |
32 | c->Nl=0; c->Nh=0; | 26 | c->md_len=SHA224_DIGEST_LENGTH; |
33 | c->num=0; c->md_len=SHA224_DIGEST_LENGTH; | ||
34 | return 1; | 27 | return 1; |
35 | } | 28 | } |
36 | 29 | ||
37 | int SHA256_Init (SHA256_CTX *c) | 30 | int SHA256_Init (SHA256_CTX *c) |
38 | { | 31 | { |
39 | #ifdef OPENSSL_FIPS | 32 | memset (c,0,sizeof(*c)); |
40 | FIPS_selftest_check(); | ||
41 | #endif | ||
42 | c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL; | 33 | c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL; |
43 | c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; | 34 | c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; |
44 | c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL; | 35 | c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL; |
45 | c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL; | 36 | c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL; |
46 | c->Nl=0; c->Nh=0; | 37 | c->md_len=SHA256_DIGEST_LENGTH; |
47 | c->num=0; c->md_len=SHA256_DIGEST_LENGTH; | ||
48 | return 1; | 38 | return 1; |
49 | } | 39 | } |
50 | 40 | ||
@@ -94,21 +84,21 @@ int SHA224_Final (unsigned char *md, SHA256_CTX *c) | |||
94 | */ | 84 | */ |
95 | #define HASH_MAKE_STRING(c,s) do { \ | 85 | #define HASH_MAKE_STRING(c,s) do { \ |
96 | unsigned long ll; \ | 86 | unsigned long ll; \ |
97 | unsigned int xn; \ | 87 | unsigned int nn; \ |
98 | switch ((c)->md_len) \ | 88 | switch ((c)->md_len) \ |
99 | { case SHA224_DIGEST_LENGTH: \ | 89 | { case SHA224_DIGEST_LENGTH: \ |
100 | for (xn=0;xn<SHA224_DIGEST_LENGTH/4;xn++) \ | 90 | for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++) \ |
101 | { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ | 91 | { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \ |
102 | break; \ | 92 | break; \ |
103 | case SHA256_DIGEST_LENGTH: \ | 93 | case SHA256_DIGEST_LENGTH: \ |
104 | for (xn=0;xn<SHA256_DIGEST_LENGTH/4;xn++) \ | 94 | for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++) \ |
105 | { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ | 95 | { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \ |
106 | break; \ | 96 | break; \ |
107 | default: \ | 97 | default: \ |
108 | if ((c)->md_len > SHA256_DIGEST_LENGTH) \ | 98 | if ((c)->md_len > SHA256_DIGEST_LENGTH) \ |
109 | return 0; \ | 99 | return 0; \ |
110 | for (xn=0;xn<(c)->md_len/4;xn++) \ | 100 | for (nn=0;nn<(c)->md_len/4;nn++) \ |
111 | { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ | 101 | { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \ |
112 | break; \ | 102 | break; \ |
113 | } \ | 103 | } \ |
114 | } while (0) | 104 | } while (0) |
diff --git a/src/lib/libcrypto/sha/sha512.c b/src/lib/libcrypto/sha/sha512.c index f5ed468b85..cbc0e58c48 100644 --- a/src/lib/libcrypto/sha/sha512.c +++ b/src/lib/libcrypto/sha/sha512.c | |||
@@ -5,10 +5,6 @@ | |||
5 | * ==================================================================== | 5 | * ==================================================================== |
6 | */ | 6 | */ |
7 | #include <openssl/opensslconf.h> | 7 | #include <openssl/opensslconf.h> |
8 | #ifdef OPENSSL_FIPS | ||
9 | #include <openssl/fips.h> | ||
10 | #endif | ||
11 | |||
12 | #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) | 8 | #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) |
13 | /* | 9 | /* |
14 | * IMPLEMENTATION NOTES. | 10 | * IMPLEMENTATION NOTES. |
@@ -65,9 +61,19 @@ const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT; | |||
65 | 61 | ||
66 | int SHA384_Init (SHA512_CTX *c) | 62 | int SHA384_Init (SHA512_CTX *c) |
67 | { | 63 | { |
68 | #ifdef OPENSSL_FIPS | 64 | #if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm)) |
69 | FIPS_selftest_check(); | 65 | /* maintain dword order required by assembler module */ |
70 | #endif | 66 | unsigned int *h = (unsigned int *)c->h; |
67 | |||
68 | h[0] = 0xcbbb9d5d; h[1] = 0xc1059ed8; | ||
69 | h[2] = 0x629a292a; h[3] = 0x367cd507; | ||
70 | h[4] = 0x9159015a; h[5] = 0x3070dd17; | ||
71 | h[6] = 0x152fecd8; h[7] = 0xf70e5939; | ||
72 | h[8] = 0x67332667; h[9] = 0xffc00b31; | ||
73 | h[10] = 0x8eb44a87; h[11] = 0x68581511; | ||
74 | h[12] = 0xdb0c2e0d; h[13] = 0x64f98fa7; | ||
75 | h[14] = 0x47b5481d; h[15] = 0xbefa4fa4; | ||
76 | #else | ||
71 | c->h[0]=U64(0xcbbb9d5dc1059ed8); | 77 | c->h[0]=U64(0xcbbb9d5dc1059ed8); |
72 | c->h[1]=U64(0x629a292a367cd507); | 78 | c->h[1]=U64(0x629a292a367cd507); |
73 | c->h[2]=U64(0x9159015a3070dd17); | 79 | c->h[2]=U64(0x9159015a3070dd17); |
@@ -76,6 +82,7 @@ int SHA384_Init (SHA512_CTX *c) | |||
76 | c->h[5]=U64(0x8eb44a8768581511); | 82 | c->h[5]=U64(0x8eb44a8768581511); |
77 | c->h[6]=U64(0xdb0c2e0d64f98fa7); | 83 | c->h[6]=U64(0xdb0c2e0d64f98fa7); |
78 | c->h[7]=U64(0x47b5481dbefa4fa4); | 84 | c->h[7]=U64(0x47b5481dbefa4fa4); |
85 | #endif | ||
79 | c->Nl=0; c->Nh=0; | 86 | c->Nl=0; c->Nh=0; |
80 | c->num=0; c->md_len=SHA384_DIGEST_LENGTH; | 87 | c->num=0; c->md_len=SHA384_DIGEST_LENGTH; |
81 | return 1; | 88 | return 1; |
@@ -83,9 +90,19 @@ int SHA384_Init (SHA512_CTX *c) | |||
83 | 90 | ||
84 | int SHA512_Init (SHA512_CTX *c) | 91 | int SHA512_Init (SHA512_CTX *c) |
85 | { | 92 | { |
86 | #ifdef OPENSSL_FIPS | 93 | #if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm)) |
87 | FIPS_selftest_check(); | 94 | /* maintain dword order required by assembler module */ |
88 | #endif | 95 | unsigned int *h = (unsigned int *)c->h; |
96 | |||
97 | h[0] = 0x6a09e667; h[1] = 0xf3bcc908; | ||
98 | h[2] = 0xbb67ae85; h[3] = 0x84caa73b; | ||
99 | h[4] = 0x3c6ef372; h[5] = 0xfe94f82b; | ||
100 | h[6] = 0xa54ff53a; h[7] = 0x5f1d36f1; | ||
101 | h[8] = 0x510e527f; h[9] = 0xade682d1; | ||
102 | h[10] = 0x9b05688c; h[11] = 0x2b3e6c1f; | ||
103 | h[12] = 0x1f83d9ab; h[13] = 0xfb41bd6b; | ||
104 | h[14] = 0x5be0cd19; h[15] = 0x137e2179; | ||
105 | #else | ||
89 | c->h[0]=U64(0x6a09e667f3bcc908); | 106 | c->h[0]=U64(0x6a09e667f3bcc908); |
90 | c->h[1]=U64(0xbb67ae8584caa73b); | 107 | c->h[1]=U64(0xbb67ae8584caa73b); |
91 | c->h[2]=U64(0x3c6ef372fe94f82b); | 108 | c->h[2]=U64(0x3c6ef372fe94f82b); |
@@ -94,6 +111,7 @@ int SHA512_Init (SHA512_CTX *c) | |||
94 | c->h[5]=U64(0x9b05688c2b3e6c1f); | 111 | c->h[5]=U64(0x9b05688c2b3e6c1f); |
95 | c->h[6]=U64(0x1f83d9abfb41bd6b); | 112 | c->h[6]=U64(0x1f83d9abfb41bd6b); |
96 | c->h[7]=U64(0x5be0cd19137e2179); | 113 | c->h[7]=U64(0x5be0cd19137e2179); |
114 | #endif | ||
97 | c->Nl=0; c->Nh=0; | 115 | c->Nl=0; c->Nh=0; |
98 | c->num=0; c->md_len=SHA512_DIGEST_LENGTH; | 116 | c->num=0; c->md_len=SHA512_DIGEST_LENGTH; |
99 | return 1; | 117 | return 1; |
@@ -142,6 +160,24 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c) | |||
142 | 160 | ||
143 | if (md==0) return 0; | 161 | if (md==0) return 0; |
144 | 162 | ||
163 | #if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm)) | ||
164 | /* recall assembler dword order... */ | ||
165 | n = c->md_len; | ||
166 | if (n == SHA384_DIGEST_LENGTH || n == SHA512_DIGEST_LENGTH) | ||
167 | { | ||
168 | unsigned int *h = (unsigned int *)c->h, t; | ||
169 | |||
170 | for (n/=4;n;n--) | ||
171 | { | ||
172 | t = *(h++); | ||
173 | *(md++) = (unsigned char)(t>>24); | ||
174 | *(md++) = (unsigned char)(t>>16); | ||
175 | *(md++) = (unsigned char)(t>>8); | ||
176 | *(md++) = (unsigned char)(t); | ||
177 | } | ||
178 | } | ||
179 | else return 0; | ||
180 | #else | ||
145 | switch (c->md_len) | 181 | switch (c->md_len) |
146 | { | 182 | { |
147 | /* Let compiler decide if it's appropriate to unroll... */ | 183 | /* Let compiler decide if it's appropriate to unroll... */ |
@@ -178,7 +214,7 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c) | |||
178 | /* ... as well as make sure md_len is not abused. */ | 214 | /* ... as well as make sure md_len is not abused. */ |
179 | default: return 0; | 215 | default: return 0; |
180 | } | 216 | } |
181 | 217 | #endif | |
182 | return 1; | 218 | return 1; |
183 | } | 219 | } |
184 | 220 | ||
@@ -204,7 +240,7 @@ int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len) | |||
204 | 240 | ||
205 | if (len < n) | 241 | if (len < n) |
206 | { | 242 | { |
207 | memcpy (p+c->num,data,len), c->num += len; | 243 | memcpy (p+c->num,data,len), c->num += (unsigned int)len; |
208 | return 1; | 244 | return 1; |
209 | } | 245 | } |
210 | else { | 246 | else { |
@@ -314,7 +350,7 @@ static const SHA_LONG64 K512[80] = { | |||
314 | #ifndef PEDANTIC | 350 | #ifndef PEDANTIC |
315 | # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) | 351 | # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) |
316 | # if defined(__x86_64) || defined(__x86_64__) | 352 | # if defined(__x86_64) || defined(__x86_64__) |
317 | # define ROTR(a,n) ({ unsigned long ret; \ | 353 | # define ROTR(a,n) ({ SHA_LONG64 ret; \ |
318 | asm ("rorq %1,%0" \ | 354 | asm ("rorq %1,%0" \ |
319 | : "=r"(ret) \ | 355 | : "=r"(ret) \ |
320 | : "J"(n),"0"(a) \ | 356 | : "J"(n),"0"(a) \ |
@@ -337,20 +373,21 @@ static const SHA_LONG64 K512[80] = { | |||
337 | ((SHA_LONG64)hi)<<32|lo; }) | 373 | ((SHA_LONG64)hi)<<32|lo; }) |
338 | # else | 374 | # else |
339 | # define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ | 375 | # define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ |
340 | unsigned int hi=p[0],lo=p[1]; \ | 376 | unsigned int hi=p[0],lo=p[1]; \ |
341 | asm ("bswapl %0; bswapl %1;" \ | 377 | asm ("bswapl %0; bswapl %1;" \ |
342 | : "=r"(lo),"=r"(hi) \ | 378 | : "=r"(lo),"=r"(hi) \ |
343 | : "0"(lo),"1"(hi)); \ | 379 | : "0"(lo),"1"(hi)); \ |
344 | ((SHA_LONG64)hi)<<32|lo; }) | 380 | ((SHA_LONG64)hi)<<32|lo; }) |
345 | # endif | 381 | # endif |
346 | # elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) | 382 | # elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) |
347 | # define ROTR(a,n) ({ unsigned long ret; \ | 383 | # define ROTR(a,n) ({ SHA_LONG64 ret; \ |
348 | asm ("rotrdi %0,%1,%2" \ | 384 | asm ("rotrdi %0,%1,%2" \ |
349 | : "=r"(ret) \ | 385 | : "=r"(ret) \ |
350 | : "r"(a),"K"(n)); ret; }) | 386 | : "r"(a),"K"(n)); ret; }) |
351 | # endif | 387 | # endif |
352 | # elif defined(_MSC_VER) | 388 | # elif defined(_MSC_VER) |
353 | # if defined(_WIN64) /* applies to both IA-64 and AMD64 */ | 389 | # if defined(_WIN64) /* applies to both IA-64 and AMD64 */ |
390 | # pragma intrinsic(_rotr64) | ||
354 | # define ROTR(a,n) _rotr64((a),n) | 391 | # define ROTR(a,n) _rotr64((a),n) |
355 | # endif | 392 | # endif |
356 | # if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) | 393 | # if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) |
@@ -398,15 +435,66 @@ static const SHA_LONG64 K512[80] = { | |||
398 | #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) | 435 | #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) |
399 | #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | 436 | #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) |
400 | 437 | ||
401 | #if defined(OPENSSL_IA32_SSE2) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) | 438 | |
402 | #define GO_FOR_SSE2(ctx,in,num) do { \ | 439 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) |
403 | void sha512_block_sse2(void *,const void *,size_t); \ | 440 | /* |
404 | if (!(OPENSSL_ia32cap_P & (1<<26))) break; \ | 441 | * This code should give better results on 32-bit CPU with less than |
405 | sha512_block_sse2(ctx->h,in,num); return; \ | 442 | * ~24 registers, both size and performance wise... |
406 | } while (0) | 443 | */ |
444 | static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) | ||
445 | { | ||
446 | const SHA_LONG64 *W=in; | ||
447 | SHA_LONG64 A,E,T; | ||
448 | SHA_LONG64 X[9+80],*F; | ||
449 | int i; | ||
450 | |||
451 | while (num--) { | ||
452 | |||
453 | F = X+80; | ||
454 | A = ctx->h[0]; F[1] = ctx->h[1]; | ||
455 | F[2] = ctx->h[2]; F[3] = ctx->h[3]; | ||
456 | E = ctx->h[4]; F[5] = ctx->h[5]; | ||
457 | F[6] = ctx->h[6]; F[7] = ctx->h[7]; | ||
458 | |||
459 | for (i=0;i<16;i++,F--) | ||
460 | { | ||
461 | #ifdef B_ENDIAN | ||
462 | T = W[i]; | ||
463 | #else | ||
464 | T = PULL64(W[i]); | ||
407 | #endif | 465 | #endif |
466 | F[0] = A; | ||
467 | F[4] = E; | ||
468 | F[8] = T; | ||
469 | T += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i]; | ||
470 | E = F[3] + T; | ||
471 | A = T + Sigma0(A) + Maj(A,F[1],F[2]); | ||
472 | } | ||
473 | |||
474 | for (;i<80;i++,F--) | ||
475 | { | ||
476 | T = sigma0(F[8+16-1]); | ||
477 | T += sigma1(F[8+16-14]); | ||
478 | T += F[8+16] + F[8+16-9]; | ||
479 | |||
480 | F[0] = A; | ||
481 | F[4] = E; | ||
482 | F[8] = T; | ||
483 | T += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i]; | ||
484 | E = F[3] + T; | ||
485 | A = T + Sigma0(A) + Maj(A,F[1],F[2]); | ||
486 | } | ||
408 | 487 | ||
409 | #ifdef OPENSSL_SMALL_FOOTPRINT | 488 | ctx->h[0] += A; ctx->h[1] += F[1]; |
489 | ctx->h[2] += F[2]; ctx->h[3] += F[3]; | ||
490 | ctx->h[4] += E; ctx->h[5] += F[5]; | ||
491 | ctx->h[6] += F[6]; ctx->h[7] += F[7]; | ||
492 | |||
493 | W+=SHA_LBLOCK; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | #elif defined(OPENSSL_SMALL_FOOTPRINT) | ||
410 | 498 | ||
411 | static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) | 499 | static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) |
412 | { | 500 | { |
@@ -415,10 +503,6 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num | |||
415 | SHA_LONG64 X[16]; | 503 | SHA_LONG64 X[16]; |
416 | int i; | 504 | int i; |
417 | 505 | ||
418 | #ifdef GO_FOR_SSE2 | ||
419 | GO_FOR_SSE2(ctx,in,num); | ||
420 | #endif | ||
421 | |||
422 | while (num--) { | 506 | while (num--) { |
423 | 507 | ||
424 | a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; | 508 | a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; |
@@ -463,11 +547,11 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num | |||
463 | h = Sigma0(a) + Maj(a,b,c); \ | 547 | h = Sigma0(a) + Maj(a,b,c); \ |
464 | d += T1; h += T1; } while (0) | 548 | d += T1; h += T1; } while (0) |
465 | 549 | ||
466 | #define ROUND_16_80(i,a,b,c,d,e,f,g,h,X) do { \ | 550 | #define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X) do { \ |
467 | s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ | 551 | s0 = X[(j+1)&0x0f]; s0 = sigma0(s0); \ |
468 | s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ | 552 | s1 = X[(j+14)&0x0f]; s1 = sigma1(s1); \ |
469 | T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ | 553 | T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f]; \ |
470 | ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) | 554 | ROUND_00_15(i+j,a,b,c,d,e,f,g,h); } while (0) |
471 | 555 | ||
472 | static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) | 556 | static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) |
473 | { | 557 | { |
@@ -476,10 +560,6 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num | |||
476 | SHA_LONG64 X[16]; | 560 | SHA_LONG64 X[16]; |
477 | int i; | 561 | int i; |
478 | 562 | ||
479 | #ifdef GO_FOR_SSE2 | ||
480 | GO_FOR_SSE2(ctx,in,num); | ||
481 | #endif | ||
482 | |||
483 | while (num--) { | 563 | while (num--) { |
484 | 564 | ||
485 | a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; | 565 | a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; |
@@ -521,16 +601,24 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num | |||
521 | T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a); | 601 | T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a); |
522 | #endif | 602 | #endif |
523 | 603 | ||
524 | for (i=16;i<80;i+=8) | 604 | for (i=16;i<80;i+=16) |
525 | { | 605 | { |
526 | ROUND_16_80(i+0,a,b,c,d,e,f,g,h,X); | 606 | ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X); |
527 | ROUND_16_80(i+1,h,a,b,c,d,e,f,g,X); | 607 | ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X); |
528 | ROUND_16_80(i+2,g,h,a,b,c,d,e,f,X); | 608 | ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X); |
529 | ROUND_16_80(i+3,f,g,h,a,b,c,d,e,X); | 609 | ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X); |
530 | ROUND_16_80(i+4,e,f,g,h,a,b,c,d,X); | 610 | ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X); |
531 | ROUND_16_80(i+5,d,e,f,g,h,a,b,c,X); | 611 | ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X); |
532 | ROUND_16_80(i+6,c,d,e,f,g,h,a,b,X); | 612 | ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X); |
533 | ROUND_16_80(i+7,b,c,d,e,f,g,h,a,X); | 613 | ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X); |
614 | ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X); | ||
615 | ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X); | ||
616 | ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X); | ||
617 | ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X); | ||
618 | ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X); | ||
619 | ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X); | ||
620 | ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X); | ||
621 | ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X); | ||
534 | } | 622 | } |
535 | 623 | ||
536 | ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; | 624 | ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; |
@@ -544,4 +632,10 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num | |||
544 | 632 | ||
545 | #endif /* SHA512_ASM */ | 633 | #endif /* SHA512_ASM */ |
546 | 634 | ||
547 | #endif /* OPENSSL_NO_SHA512 */ | 635 | #else /* !OPENSSL_NO_SHA512 */ |
636 | |||
637 | #if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX) | ||
638 | static void *dummy=&dummy; | ||
639 | #endif | ||
640 | |||
641 | #endif /* !OPENSSL_NO_SHA512 */ | ||
diff --git a/src/lib/libcrypto/sparccpuid.S b/src/lib/libcrypto/sparccpuid.S index c17350fc89..aa8b11efc9 100644 --- a/src/lib/libcrypto/sparccpuid.S +++ b/src/lib/libcrypto/sparccpuid.S | |||
@@ -34,7 +34,8 @@ OPENSSL_wipe_cpu: | |||
34 | nop | 34 | nop |
35 | call .PIC.zero.up | 35 | call .PIC.zero.up |
36 | mov .zero-(.-4),%o0 | 36 | mov .zero-(.-4),%o0 |
37 | ldd [%o0],%f0 | 37 | ld [%o0],%f0 |
38 | ld [%o0],%f1 | ||
38 | 39 | ||
39 | subcc %g0,1,%o0 | 40 | subcc %g0,1,%o0 |
40 | ! Following is V9 "rd %ccr,%o0" instruction. However! V8 | 41 | ! Following is V9 "rd %ccr,%o0" instruction. However! V8 |
@@ -166,6 +167,7 @@ walk_reg_wins: | |||
166 | 167 | ||
167 | .global OPENSSL_atomic_add | 168 | .global OPENSSL_atomic_add |
168 | .type OPENSSL_atomic_add,#function | 169 | .type OPENSSL_atomic_add,#function |
170 | .align 32 | ||
169 | OPENSSL_atomic_add: | 171 | OPENSSL_atomic_add: |
170 | #ifndef ABI64 | 172 | #ifndef ABI64 |
171 | subcc %g0,1,%o2 | 173 | subcc %g0,1,%o2 |
@@ -177,7 +179,7 @@ OPENSSL_atomic_add: | |||
177 | ba .enter | 179 | ba .enter |
178 | nop | 180 | nop |
179 | #ifdef __sun | 181 | #ifdef __sun |
180 | ! Note that you don't have to link with libthread to call thr_yield, | 182 | ! Note that you do not have to link with libthread to call thr_yield, |
181 | ! as libc provides a stub, which is overloaded the moment you link | 183 | ! as libc provides a stub, which is overloaded the moment you link |
182 | ! with *either* libpthread or libthread... | 184 | ! with *either* libpthread or libthread... |
183 | #define YIELD_CPU thr_yield | 185 | #define YIELD_CPU thr_yield |
@@ -213,27 +215,106 @@ OPENSSL_atomic_add: | |||
213 | sra %o0,%g0,%o0 ! we return signed int, remember? | 215 | sra %o0,%g0,%o0 ! we return signed int, remember? |
214 | .size OPENSSL_atomic_add,.-OPENSSL_atomic_add | 216 | .size OPENSSL_atomic_add,.-OPENSSL_atomic_add |
215 | 217 | ||
216 | .global OPENSSL_rdtsc | 218 | .global _sparcv9_rdtick |
219 | .align 32 | ||
220 | _sparcv9_rdtick: | ||
217 | subcc %g0,1,%o0 | 221 | subcc %g0,1,%o0 |
218 | .word 0x91408000 !rd %ccr,%o0 | 222 | .word 0x91408000 !rd %ccr,%o0 |
219 | cmp %o0,0x99 | 223 | cmp %o0,0x99 |
220 | bne .notsc | 224 | bne .notick |
221 | xor %o0,%o0,%o0 | 225 | xor %o0,%o0,%o0 |
222 | save %sp,FRAME-16,%sp | 226 | .word 0x91410000 !rd %tick,%o0 |
223 | mov 513,%o0 !SI_PLATFORM | 227 | retl |
224 | add %sp,BIAS+16,%o1 | 228 | .word 0x93323020 !srlx %o2,32,%o1 |
225 | call sysinfo | 229 | .notick: |
226 | mov 256,%o2 | 230 | retl |
231 | xor %o1,%o1,%o1 | ||
232 | .type _sparcv9_rdtick,#function | ||
233 | .size _sparcv9_rdtick,.-_sparcv9_rdtick | ||
227 | 234 | ||
228 | add %sp,BIAS-16,%o1 | 235 | .global OPENSSL_cleanse |
229 | ld [%o1],%l0 | 236 | .align 32 |
230 | ld [%o1+4],%l1 | 237 | OPENSSL_cleanse: |
231 | ld [%o1+8],%l2 | 238 | cmp %o1,14 |
232 | mov %lo('SUNW'),%l3 | 239 | nop |
233 | ret | 240 | #ifdef ABI64 |
234 | restore | 241 | bgu %xcc,.Lot |
235 | .notsc: | 242 | #else |
243 | bgu .Lot | ||
244 | #endif | ||
245 | cmp %o1,0 | ||
246 | bne .Little | ||
247 | nop | ||
248 | retl | ||
249 | nop | ||
250 | |||
251 | .Little: | ||
252 | stb %g0,[%o0] | ||
253 | subcc %o1,1,%o1 | ||
254 | bnz .Little | ||
255 | add %o0,1,%o0 | ||
256 | retl | ||
257 | nop | ||
258 | .align 32 | ||
259 | .Lot: | ||
260 | #ifndef ABI64 | ||
261 | subcc %g0,1,%g1 | ||
262 | ! see above for explanation | ||
263 | .word 0x83408000 !rd %ccr,%g1 | ||
264 | cmp %g1,0x99 | ||
265 | bne .v8lot | ||
266 | nop | ||
267 | #endif | ||
268 | |||
269 | .v9lot: andcc %o0,7,%g0 | ||
270 | bz .v9aligned | ||
271 | nop | ||
272 | stb %g0,[%o0] | ||
273 | sub %o1,1,%o1 | ||
274 | ba .v9lot | ||
275 | add %o0,1,%o0 | ||
276 | .align 16,0x01000000 | ||
277 | .v9aligned: | ||
278 | .word 0xc0720000 !stx %g0,[%o0] | ||
279 | sub %o1,8,%o1 | ||
280 | andcc %o1,-8,%g0 | ||
281 | #ifdef ABI64 | ||
282 | .word 0x126ffffd !bnz %xcc,.v9aligned | ||
283 | #else | ||
284 | .word 0x124ffffd !bnz %icc,.v9aligned | ||
285 | #endif | ||
286 | add %o0,8,%o0 | ||
287 | |||
288 | cmp %o1,0 | ||
289 | bne .Little | ||
290 | nop | ||
236 | retl | 291 | retl |
237 | nop | 292 | nop |
238 | .type OPENSSL_rdtsc,#function | 293 | #ifndef ABI64 |
239 | .size OPENSSL_rdtsc,.-OPENSSL_atomic_add | 294 | .v8lot: andcc %o0,3,%g0 |
295 | bz .v8aligned | ||
296 | nop | ||
297 | stb %g0,[%o0] | ||
298 | sub %o1,1,%o1 | ||
299 | ba .v8lot | ||
300 | add %o0,1,%o0 | ||
301 | nop | ||
302 | .v8aligned: | ||
303 | st %g0,[%o0] | ||
304 | sub %o1,4,%o1 | ||
305 | andcc %o1,-4,%g0 | ||
306 | bnz .v8aligned | ||
307 | add %o0,4,%o0 | ||
308 | |||
309 | cmp %o1,0 | ||
310 | bne .Little | ||
311 | nop | ||
312 | retl | ||
313 | nop | ||
314 | #endif | ||
315 | .type OPENSSL_cleanse,#function | ||
316 | .size OPENSSL_cleanse,.-OPENSSL_cleanse | ||
317 | |||
318 | .section ".init",#alloc,#execinstr | ||
319 | call OPENSSL_cpuid_setup | ||
320 | nop | ||
diff --git a/src/lib/libcrypto/ts/ts.h b/src/lib/libcrypto/ts/ts.h new file mode 100644 index 0000000000..190e8a1bf2 --- /dev/null +++ b/src/lib/libcrypto/ts/ts.h | |||
@@ -0,0 +1,861 @@ | |||
1 | /* crypto/ts/ts.h */ | ||
2 | /* Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL | ||
3 | * project 2002, 2003, 2004. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_TS_H | ||
60 | #define HEADER_TS_H | ||
61 | |||
62 | #include <openssl/opensslconf.h> | ||
63 | #include <openssl/symhacks.h> | ||
64 | #ifndef OPENSSL_NO_BUFFER | ||
65 | #include <openssl/buffer.h> | ||
66 | #endif | ||
67 | #ifndef OPENSSL_NO_EVP | ||
68 | #include <openssl/evp.h> | ||
69 | #endif | ||
70 | #ifndef OPENSSL_NO_BIO | ||
71 | #include <openssl/bio.h> | ||
72 | #endif | ||
73 | #include <openssl/stack.h> | ||
74 | #include <openssl/asn1.h> | ||
75 | #include <openssl/safestack.h> | ||
76 | |||
77 | #ifndef OPENSSL_NO_RSA | ||
78 | #include <openssl/rsa.h> | ||
79 | #endif | ||
80 | |||
81 | #ifndef OPENSSL_NO_DSA | ||
82 | #include <openssl/dsa.h> | ||
83 | #endif | ||
84 | |||
85 | #ifndef OPENSSL_NO_DH | ||
86 | #include <openssl/dh.h> | ||
87 | #endif | ||
88 | |||
89 | #include <openssl/evp.h> | ||
90 | |||
91 | |||
92 | #ifdef __cplusplus | ||
93 | extern "C" { | ||
94 | #endif | ||
95 | |||
96 | #ifdef WIN32 | ||
97 | /* Under Win32 this is defined in wincrypt.h */ | ||
98 | #undef X509_NAME | ||
99 | #endif | ||
100 | |||
101 | #include <openssl/x509.h> | ||
102 | #include <openssl/x509v3.h> | ||
103 | |||
104 | /* | ||
105 | MessageImprint ::= SEQUENCE { | ||
106 | hashAlgorithm AlgorithmIdentifier, | ||
107 | hashedMessage OCTET STRING } | ||
108 | */ | ||
109 | |||
110 | typedef struct TS_msg_imprint_st | ||
111 | { | ||
112 | X509_ALGOR *hash_algo; | ||
113 | ASN1_OCTET_STRING *hashed_msg; | ||
114 | } TS_MSG_IMPRINT; | ||
115 | |||
116 | /* | ||
117 | TimeStampReq ::= SEQUENCE { | ||
118 | version INTEGER { v1(1) }, | ||
119 | messageImprint MessageImprint, | ||
120 | --a hash algorithm OID and the hash value of the data to be | ||
121 | --time-stamped | ||
122 | reqPolicy TSAPolicyId OPTIONAL, | ||
123 | nonce INTEGER OPTIONAL, | ||
124 | certReq BOOLEAN DEFAULT FALSE, | ||
125 | extensions [0] IMPLICIT Extensions OPTIONAL } | ||
126 | */ | ||
127 | |||
128 | typedef struct TS_req_st | ||
129 | { | ||
130 | ASN1_INTEGER *version; | ||
131 | TS_MSG_IMPRINT *msg_imprint; | ||
132 | ASN1_OBJECT *policy_id; /* OPTIONAL */ | ||
133 | ASN1_INTEGER *nonce; /* OPTIONAL */ | ||
134 | ASN1_BOOLEAN cert_req; /* DEFAULT FALSE */ | ||
135 | STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */ | ||
136 | } TS_REQ; | ||
137 | |||
138 | /* | ||
139 | Accuracy ::= SEQUENCE { | ||
140 | seconds INTEGER OPTIONAL, | ||
141 | millis [0] INTEGER (1..999) OPTIONAL, | ||
142 | micros [1] INTEGER (1..999) OPTIONAL } | ||
143 | */ | ||
144 | |||
145 | typedef struct TS_accuracy_st | ||
146 | { | ||
147 | ASN1_INTEGER *seconds; | ||
148 | ASN1_INTEGER *millis; | ||
149 | ASN1_INTEGER *micros; | ||
150 | } TS_ACCURACY; | ||
151 | |||
152 | /* | ||
153 | TSTInfo ::= SEQUENCE { | ||
154 | version INTEGER { v1(1) }, | ||
155 | policy TSAPolicyId, | ||
156 | messageImprint MessageImprint, | ||
157 | -- MUST have the same value as the similar field in | ||
158 | -- TimeStampReq | ||
159 | serialNumber INTEGER, | ||
160 | -- Time-Stamping users MUST be ready to accommodate integers | ||
161 | -- up to 160 bits. | ||
162 | genTime GeneralizedTime, | ||
163 | accuracy Accuracy OPTIONAL, | ||
164 | ordering BOOLEAN DEFAULT FALSE, | ||
165 | nonce INTEGER OPTIONAL, | ||
166 | -- MUST be present if the similar field was present | ||
167 | -- in TimeStampReq. In that case it MUST have the same value. | ||
168 | tsa [0] GeneralName OPTIONAL, | ||
169 | extensions [1] IMPLICIT Extensions OPTIONAL } | ||
170 | */ | ||
171 | |||
172 | typedef struct TS_tst_info_st | ||
173 | { | ||
174 | ASN1_INTEGER *version; | ||
175 | ASN1_OBJECT *policy_id; | ||
176 | TS_MSG_IMPRINT *msg_imprint; | ||
177 | ASN1_INTEGER *serial; | ||
178 | ASN1_GENERALIZEDTIME *time; | ||
179 | TS_ACCURACY *accuracy; | ||
180 | ASN1_BOOLEAN ordering; | ||
181 | ASN1_INTEGER *nonce; | ||
182 | GENERAL_NAME *tsa; | ||
183 | STACK_OF(X509_EXTENSION) *extensions; | ||
184 | } TS_TST_INFO; | ||
185 | |||
186 | /* | ||
187 | PKIStatusInfo ::= SEQUENCE { | ||
188 | status PKIStatus, | ||
189 | statusString PKIFreeText OPTIONAL, | ||
190 | failInfo PKIFailureInfo OPTIONAL } | ||
191 | |||
192 | From RFC 1510 - section 3.1.1: | ||
193 | PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String | ||
194 | -- text encoded as UTF-8 String (note: each UTF8String SHOULD | ||
195 | -- include an RFC 1766 language tag to indicate the language | ||
196 | -- of the contained text) | ||
197 | */ | ||
198 | |||
199 | /* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */ | ||
200 | |||
201 | #define TS_STATUS_GRANTED 0 | ||
202 | #define TS_STATUS_GRANTED_WITH_MODS 1 | ||
203 | #define TS_STATUS_REJECTION 2 | ||
204 | #define TS_STATUS_WAITING 3 | ||
205 | #define TS_STATUS_REVOCATION_WARNING 4 | ||
206 | #define TS_STATUS_REVOCATION_NOTIFICATION 5 | ||
207 | |||
208 | /* Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c */ | ||
209 | |||
210 | #define TS_INFO_BAD_ALG 0 | ||
211 | #define TS_INFO_BAD_REQUEST 2 | ||
212 | #define TS_INFO_BAD_DATA_FORMAT 5 | ||
213 | #define TS_INFO_TIME_NOT_AVAILABLE 14 | ||
214 | #define TS_INFO_UNACCEPTED_POLICY 15 | ||
215 | #define TS_INFO_UNACCEPTED_EXTENSION 16 | ||
216 | #define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 | ||
217 | #define TS_INFO_SYSTEM_FAILURE 25 | ||
218 | |||
219 | typedef struct TS_status_info_st | ||
220 | { | ||
221 | ASN1_INTEGER *status; | ||
222 | STACK_OF(ASN1_UTF8STRING) *text; | ||
223 | ASN1_BIT_STRING *failure_info; | ||
224 | } TS_STATUS_INFO; | ||
225 | |||
226 | DECLARE_STACK_OF(ASN1_UTF8STRING) | ||
227 | DECLARE_ASN1_SET_OF(ASN1_UTF8STRING) | ||
228 | |||
229 | /* | ||
230 | TimeStampResp ::= SEQUENCE { | ||
231 | status PKIStatusInfo, | ||
232 | timeStampToken TimeStampToken OPTIONAL } | ||
233 | */ | ||
234 | |||
235 | typedef struct TS_resp_st | ||
236 | { | ||
237 | TS_STATUS_INFO *status_info; | ||
238 | PKCS7 *token; | ||
239 | TS_TST_INFO *tst_info; | ||
240 | } TS_RESP; | ||
241 | |||
242 | /* The structure below would belong to the ESS component. */ | ||
243 | |||
244 | /* | ||
245 | IssuerSerial ::= SEQUENCE { | ||
246 | issuer GeneralNames, | ||
247 | serialNumber CertificateSerialNumber | ||
248 | } | ||
249 | */ | ||
250 | |||
251 | typedef struct ESS_issuer_serial | ||
252 | { | ||
253 | STACK_OF(GENERAL_NAME) *issuer; | ||
254 | ASN1_INTEGER *serial; | ||
255 | } ESS_ISSUER_SERIAL; | ||
256 | |||
257 | /* | ||
258 | ESSCertID ::= SEQUENCE { | ||
259 | certHash Hash, | ||
260 | issuerSerial IssuerSerial OPTIONAL | ||
261 | } | ||
262 | */ | ||
263 | |||
264 | typedef struct ESS_cert_id | ||
265 | { | ||
266 | ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */ | ||
267 | ESS_ISSUER_SERIAL *issuer_serial; | ||
268 | } ESS_CERT_ID; | ||
269 | |||
270 | DECLARE_STACK_OF(ESS_CERT_ID) | ||
271 | DECLARE_ASN1_SET_OF(ESS_CERT_ID) | ||
272 | |||
273 | /* | ||
274 | SigningCertificate ::= SEQUENCE { | ||
275 | certs SEQUENCE OF ESSCertID, | ||
276 | policies SEQUENCE OF PolicyInformation OPTIONAL | ||
277 | } | ||
278 | */ | ||
279 | |||
280 | typedef struct ESS_signing_cert | ||
281 | { | ||
282 | STACK_OF(ESS_CERT_ID) *cert_ids; | ||
283 | STACK_OF(POLICYINFO) *policy_info; | ||
284 | } ESS_SIGNING_CERT; | ||
285 | |||
286 | |||
287 | TS_REQ *TS_REQ_new(void); | ||
288 | void TS_REQ_free(TS_REQ *a); | ||
289 | int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); | ||
290 | TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); | ||
291 | |||
292 | TS_REQ *TS_REQ_dup(TS_REQ *a); | ||
293 | |||
294 | TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); | ||
295 | int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); | ||
296 | TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); | ||
297 | int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); | ||
298 | |||
299 | TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); | ||
300 | void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); | ||
301 | int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); | ||
302 | TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, | ||
303 | const unsigned char **pp, long length); | ||
304 | |||
305 | TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); | ||
306 | |||
307 | TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); | ||
308 | int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); | ||
309 | TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a); | ||
310 | int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a); | ||
311 | |||
312 | TS_RESP *TS_RESP_new(void); | ||
313 | void TS_RESP_free(TS_RESP *a); | ||
314 | int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); | ||
315 | TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); | ||
316 | TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); | ||
317 | TS_RESP *TS_RESP_dup(TS_RESP *a); | ||
318 | |||
319 | TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); | ||
320 | int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); | ||
321 | TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a); | ||
322 | int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a); | ||
323 | |||
324 | TS_STATUS_INFO *TS_STATUS_INFO_new(void); | ||
325 | void TS_STATUS_INFO_free(TS_STATUS_INFO *a); | ||
326 | int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); | ||
327 | TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, | ||
328 | const unsigned char **pp, long length); | ||
329 | TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); | ||
330 | |||
331 | TS_TST_INFO *TS_TST_INFO_new(void); | ||
332 | void TS_TST_INFO_free(TS_TST_INFO *a); | ||
333 | int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); | ||
334 | TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, | ||
335 | long length); | ||
336 | TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); | ||
337 | |||
338 | TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); | ||
339 | int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); | ||
340 | TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a); | ||
341 | int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a); | ||
342 | |||
343 | TS_ACCURACY *TS_ACCURACY_new(void); | ||
344 | void TS_ACCURACY_free(TS_ACCURACY *a); | ||
345 | int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); | ||
346 | TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, | ||
347 | long length); | ||
348 | TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); | ||
349 | |||
350 | ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); | ||
351 | void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); | ||
352 | int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, | ||
353 | unsigned char **pp); | ||
354 | ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, | ||
355 | const unsigned char **pp, long length); | ||
356 | ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); | ||
357 | |||
358 | ESS_CERT_ID *ESS_CERT_ID_new(void); | ||
359 | void ESS_CERT_ID_free(ESS_CERT_ID *a); | ||
360 | int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); | ||
361 | ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, | ||
362 | long length); | ||
363 | ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); | ||
364 | |||
365 | ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); | ||
366 | void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); | ||
367 | int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, | ||
368 | unsigned char **pp); | ||
369 | ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, | ||
370 | const unsigned char **pp, long length); | ||
371 | ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); | ||
372 | |||
373 | void ERR_load_TS_strings(void); | ||
374 | |||
375 | int TS_REQ_set_version(TS_REQ *a, long version); | ||
376 | long TS_REQ_get_version(const TS_REQ *a); | ||
377 | |||
378 | int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); | ||
379 | TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); | ||
380 | |||
381 | int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); | ||
382 | X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); | ||
383 | |||
384 | int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); | ||
385 | ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); | ||
386 | |||
387 | int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy); | ||
388 | ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); | ||
389 | |||
390 | int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); | ||
391 | const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); | ||
392 | |||
393 | int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); | ||
394 | int TS_REQ_get_cert_req(const TS_REQ *a); | ||
395 | |||
396 | STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); | ||
397 | void TS_REQ_ext_free(TS_REQ *a); | ||
398 | int TS_REQ_get_ext_count(TS_REQ *a); | ||
399 | int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); | ||
400 | int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos); | ||
401 | int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); | ||
402 | X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); | ||
403 | X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); | ||
404 | int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); | ||
405 | void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); | ||
406 | |||
407 | /* Function declarations for TS_REQ defined in ts/ts_req_print.c */ | ||
408 | |||
409 | int TS_REQ_print_bio(BIO *bio, TS_REQ *a); | ||
410 | |||
411 | /* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ | ||
412 | |||
413 | int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); | ||
414 | TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); | ||
415 | |||
416 | /* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ | ||
417 | void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); | ||
418 | PKCS7 *TS_RESP_get_token(TS_RESP *a); | ||
419 | TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); | ||
420 | |||
421 | int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); | ||
422 | long TS_TST_INFO_get_version(const TS_TST_INFO *a); | ||
423 | |||
424 | int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); | ||
425 | ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); | ||
426 | |||
427 | int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); | ||
428 | TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); | ||
429 | |||
430 | int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); | ||
431 | const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); | ||
432 | |||
433 | int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); | ||
434 | const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); | ||
435 | |||
436 | int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); | ||
437 | TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); | ||
438 | |||
439 | int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); | ||
440 | const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); | ||
441 | |||
442 | int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); | ||
443 | const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); | ||
444 | |||
445 | int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); | ||
446 | const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); | ||
447 | |||
448 | int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); | ||
449 | int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); | ||
450 | |||
451 | int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); | ||
452 | const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); | ||
453 | |||
454 | int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); | ||
455 | GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); | ||
456 | |||
457 | STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); | ||
458 | void TS_TST_INFO_ext_free(TS_TST_INFO *a); | ||
459 | int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); | ||
460 | int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); | ||
461 | int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos); | ||
462 | int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); | ||
463 | X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); | ||
464 | X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); | ||
465 | int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); | ||
466 | void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); | ||
467 | |||
468 | /* Declarations related to response generation, defined in ts/ts_resp_sign.c. */ | ||
469 | |||
470 | /* Optional flags for response generation. */ | ||
471 | |||
472 | /* Don't include the TSA name in response. */ | ||
473 | #define TS_TSA_NAME 0x01 | ||
474 | |||
475 | /* Set ordering to true in response. */ | ||
476 | #define TS_ORDERING 0x02 | ||
477 | |||
478 | /* | ||
479 | * Include the signer certificate and the other specified certificates in | ||
480 | * the ESS signing certificate attribute beside the PKCS7 signed data. | ||
481 | * Only the signer certificates is included by default. | ||
482 | */ | ||
483 | #define TS_ESS_CERT_ID_CHAIN 0x04 | ||
484 | |||
485 | /* Forward declaration. */ | ||
486 | struct TS_resp_ctx; | ||
487 | |||
488 | /* This must return a unique number less than 160 bits long. */ | ||
489 | typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *); | ||
490 | |||
491 | /* This must return the seconds and microseconds since Jan 1, 1970 in | ||
492 | the sec and usec variables allocated by the caller. | ||
493 | Return non-zero for success and zero for failure. */ | ||
494 | typedef int (*TS_time_cb)(struct TS_resp_ctx *, void *, long *sec, long *usec); | ||
495 | |||
496 | /* This must process the given extension. | ||
497 | * It can modify the TS_TST_INFO object of the context. | ||
498 | * Return values: !0 (processed), 0 (error, it must set the | ||
499 | * status info/failure info of the response). | ||
500 | */ | ||
501 | typedef int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *, void *); | ||
502 | |||
503 | typedef struct TS_resp_ctx | ||
504 | { | ||
505 | X509 *signer_cert; | ||
506 | EVP_PKEY *signer_key; | ||
507 | STACK_OF(X509) *certs; /* Certs to include in signed data. */ | ||
508 | STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */ | ||
509 | ASN1_OBJECT *default_policy; /* It may appear in policies, too. */ | ||
510 | STACK_OF(EVP_MD) *mds; /* Acceptable message digests. */ | ||
511 | ASN1_INTEGER *seconds; /* accuracy, 0 means not specified. */ | ||
512 | ASN1_INTEGER *millis; /* accuracy, 0 means not specified. */ | ||
513 | ASN1_INTEGER *micros; /* accuracy, 0 means not specified. */ | ||
514 | unsigned clock_precision_digits; /* fraction of seconds in | ||
515 | time stamp token. */ | ||
516 | unsigned flags; /* Optional info, see values above. */ | ||
517 | |||
518 | /* Callback functions. */ | ||
519 | TS_serial_cb serial_cb; | ||
520 | void *serial_cb_data; /* User data for serial_cb. */ | ||
521 | |||
522 | TS_time_cb time_cb; | ||
523 | void *time_cb_data; /* User data for time_cb. */ | ||
524 | |||
525 | TS_extension_cb extension_cb; | ||
526 | void *extension_cb_data; /* User data for extension_cb. */ | ||
527 | |||
528 | /* These members are used only while creating the response. */ | ||
529 | TS_REQ *request; | ||
530 | TS_RESP *response; | ||
531 | TS_TST_INFO *tst_info; | ||
532 | } TS_RESP_CTX; | ||
533 | |||
534 | DECLARE_STACK_OF(EVP_MD) | ||
535 | DECLARE_ASN1_SET_OF(EVP_MD) | ||
536 | |||
537 | /* Creates a response context that can be used for generating responses. */ | ||
538 | TS_RESP_CTX *TS_RESP_CTX_new(void); | ||
539 | void TS_RESP_CTX_free(TS_RESP_CTX *ctx); | ||
540 | |||
541 | /* This parameter must be set. */ | ||
542 | int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); | ||
543 | |||
544 | /* This parameter must be set. */ | ||
545 | int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); | ||
546 | |||
547 | /* This parameter must be set. */ | ||
548 | int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy); | ||
549 | |||
550 | /* No additional certs are included in the response by default. */ | ||
551 | int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); | ||
552 | |||
553 | /* Adds a new acceptable policy, only the default policy | ||
554 | is accepted by default. */ | ||
555 | int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy); | ||
556 | |||
557 | /* Adds a new acceptable message digest. Note that no message digests | ||
558 | are accepted by default. The md argument is shared with the caller. */ | ||
559 | int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); | ||
560 | |||
561 | /* Accuracy is not included by default. */ | ||
562 | int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, | ||
563 | int secs, int millis, int micros); | ||
564 | |||
565 | /* Clock precision digits, i.e. the number of decimal digits: | ||
566 | '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */ | ||
567 | int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, | ||
568 | unsigned clock_precision_digits); | ||
569 | /* At most we accept usec precision. */ | ||
570 | #define TS_MAX_CLOCK_PRECISION_DIGITS 6 | ||
571 | |||
572 | /* No flags are set by default. */ | ||
573 | void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); | ||
574 | |||
575 | /* Default callback always returns a constant. */ | ||
576 | void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); | ||
577 | |||
578 | /* Default callback uses the gettimeofday() and gmtime() system calls. */ | ||
579 | void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); | ||
580 | |||
581 | /* Default callback rejects all extensions. The extension callback is called | ||
582 | * when the TS_TST_INFO object is already set up and not signed yet. */ | ||
583 | /* FIXME: extension handling is not tested yet. */ | ||
584 | void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, | ||
585 | TS_extension_cb cb, void *data); | ||
586 | |||
587 | /* The following methods can be used in the callbacks. */ | ||
588 | int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, | ||
589 | int status, const char *text); | ||
590 | |||
591 | /* Sets the status info only if it is still TS_STATUS_GRANTED. */ | ||
592 | int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, | ||
593 | int status, const char *text); | ||
594 | |||
595 | int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); | ||
596 | |||
597 | /* The get methods below can be used in the extension callback. */ | ||
598 | TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); | ||
599 | |||
600 | TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); | ||
601 | |||
602 | /* | ||
603 | * Creates the signed TS_TST_INFO and puts it in TS_RESP. | ||
604 | * In case of errors it sets the status info properly. | ||
605 | * Returns NULL only in case of memory allocation/fatal error. | ||
606 | */ | ||
607 | TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); | ||
608 | |||
609 | /* | ||
610 | * Declarations related to response verification, | ||
611 | * they are defined in ts/ts_resp_verify.c. | ||
612 | */ | ||
613 | |||
614 | int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, | ||
615 | X509_STORE *store, X509 **signer_out); | ||
616 | |||
617 | /* Context structure for the generic verify method. */ | ||
618 | |||
619 | /* Verify the signer's certificate and the signature of the response. */ | ||
620 | #define TS_VFY_SIGNATURE (1u << 0) | ||
621 | /* Verify the version number of the response. */ | ||
622 | #define TS_VFY_VERSION (1u << 1) | ||
623 | /* Verify if the policy supplied by the user matches the policy of the TSA. */ | ||
624 | #define TS_VFY_POLICY (1u << 2) | ||
625 | /* Verify the message imprint provided by the user. This flag should not be | ||
626 | specified with TS_VFY_DATA. */ | ||
627 | #define TS_VFY_IMPRINT (1u << 3) | ||
628 | /* Verify the message imprint computed by the verify method from the user | ||
629 | provided data and the MD algorithm of the response. This flag should not be | ||
630 | specified with TS_VFY_IMPRINT. */ | ||
631 | #define TS_VFY_DATA (1u << 4) | ||
632 | /* Verify the nonce value. */ | ||
633 | #define TS_VFY_NONCE (1u << 5) | ||
634 | /* Verify if the TSA name field matches the signer certificate. */ | ||
635 | #define TS_VFY_SIGNER (1u << 6) | ||
636 | /* Verify if the TSA name field equals to the user provided name. */ | ||
637 | #define TS_VFY_TSA_NAME (1u << 7) | ||
638 | |||
639 | /* You can use the following convenience constants. */ | ||
640 | #define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ | ||
641 | | TS_VFY_VERSION \ | ||
642 | | TS_VFY_POLICY \ | ||
643 | | TS_VFY_IMPRINT \ | ||
644 | | TS_VFY_NONCE \ | ||
645 | | TS_VFY_SIGNER \ | ||
646 | | TS_VFY_TSA_NAME) | ||
647 | #define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ | ||
648 | | TS_VFY_VERSION \ | ||
649 | | TS_VFY_POLICY \ | ||
650 | | TS_VFY_DATA \ | ||
651 | | TS_VFY_NONCE \ | ||
652 | | TS_VFY_SIGNER \ | ||
653 | | TS_VFY_TSA_NAME) | ||
654 | |||
655 | typedef struct TS_verify_ctx | ||
656 | { | ||
657 | /* Set this to the union of TS_VFY_... flags you want to carry out. */ | ||
658 | unsigned flags; | ||
659 | |||
660 | /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */ | ||
661 | X509_STORE *store; | ||
662 | STACK_OF(X509) *certs; | ||
663 | |||
664 | /* Must be set only with TS_VFY_POLICY. */ | ||
665 | ASN1_OBJECT *policy; | ||
666 | |||
667 | /* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, | ||
668 | the algorithm from the response is used. */ | ||
669 | X509_ALGOR *md_alg; | ||
670 | unsigned char *imprint; | ||
671 | unsigned imprint_len; | ||
672 | |||
673 | /* Must be set only with TS_VFY_DATA. */ | ||
674 | BIO *data; | ||
675 | |||
676 | /* Must be set only with TS_VFY_TSA_NAME. */ | ||
677 | ASN1_INTEGER *nonce; | ||
678 | |||
679 | /* Must be set only with TS_VFY_TSA_NAME. */ | ||
680 | GENERAL_NAME *tsa_name; | ||
681 | } TS_VERIFY_CTX; | ||
682 | |||
683 | int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); | ||
684 | int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); | ||
685 | |||
686 | /* | ||
687 | * Declarations related to response verification context, | ||
688 | * they are defined in ts/ts_verify_ctx.c. | ||
689 | */ | ||
690 | |||
691 | /* Set all fields to zero. */ | ||
692 | TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); | ||
693 | void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); | ||
694 | void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); | ||
695 | void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); | ||
696 | |||
697 | /* | ||
698 | * If ctx is NULL, it allocates and returns a new object, otherwise | ||
699 | * it returns ctx. It initialises all the members as follows: | ||
700 | * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) | ||
701 | * certs = NULL | ||
702 | * store = NULL | ||
703 | * policy = policy from the request or NULL if absent (in this case | ||
704 | * TS_VFY_POLICY is cleared from flags as well) | ||
705 | * md_alg = MD algorithm from request | ||
706 | * imprint, imprint_len = imprint from request | ||
707 | * data = NULL | ||
708 | * nonce, nonce_len = nonce from the request or NULL if absent (in this case | ||
709 | * TS_VFY_NONCE is cleared from flags as well) | ||
710 | * tsa_name = NULL | ||
711 | * Important: after calling this method TS_VFY_SIGNATURE should be added! | ||
712 | */ | ||
713 | TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); | ||
714 | |||
715 | /* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ | ||
716 | |||
717 | int TS_RESP_print_bio(BIO *bio, TS_RESP *a); | ||
718 | int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); | ||
719 | int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); | ||
720 | |||
721 | /* Common utility functions defined in ts/ts_lib.c */ | ||
722 | |||
723 | int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); | ||
724 | int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); | ||
725 | int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); | ||
726 | int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); | ||
727 | int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); | ||
728 | |||
729 | /* Function declarations for handling configuration options, | ||
730 | defined in ts/ts_conf.c */ | ||
731 | |||
732 | X509 *TS_CONF_load_cert(const char *file); | ||
733 | STACK_OF(X509) *TS_CONF_load_certs(const char *file); | ||
734 | EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); | ||
735 | const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); | ||
736 | int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, | ||
737 | TS_RESP_CTX *ctx); | ||
738 | int TS_CONF_set_crypto_device(CONF *conf, const char *section, | ||
739 | const char *device); | ||
740 | int TS_CONF_set_default_engine(const char *name); | ||
741 | int TS_CONF_set_signer_cert(CONF *conf, const char *section, | ||
742 | const char *cert, TS_RESP_CTX *ctx); | ||
743 | int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, | ||
744 | TS_RESP_CTX *ctx); | ||
745 | int TS_CONF_set_signer_key(CONF *conf, const char *section, | ||
746 | const char *key, const char *pass, TS_RESP_CTX *ctx); | ||
747 | int TS_CONF_set_def_policy(CONF *conf, const char *section, | ||
748 | const char *policy, TS_RESP_CTX *ctx); | ||
749 | int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); | ||
750 | int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); | ||
751 | int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); | ||
752 | int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, | ||
753 | TS_RESP_CTX *ctx); | ||
754 | int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); | ||
755 | int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); | ||
756 | int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, | ||
757 | TS_RESP_CTX *ctx); | ||
758 | |||
759 | /* -------------------------------------------------- */ | ||
760 | /* BEGIN ERROR CODES */ | ||
761 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
762 | * made after this point may be overwritten when the script is next run. | ||
763 | */ | ||
764 | void ERR_load_TS_strings(void); | ||
765 | |||
766 | /* Error codes for the TS functions. */ | ||
767 | |||
768 | /* Function codes. */ | ||
769 | #define TS_F_D2I_TS_RESP 147 | ||
770 | #define TS_F_DEF_SERIAL_CB 110 | ||
771 | #define TS_F_DEF_TIME_CB 111 | ||
772 | #define TS_F_ESS_ADD_SIGNING_CERT 112 | ||
773 | #define TS_F_ESS_CERT_ID_NEW_INIT 113 | ||
774 | #define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 | ||
775 | #define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 | ||
776 | #define TS_F_PKCS7_TO_TS_TST_INFO 148 | ||
777 | #define TS_F_TS_ACCURACY_SET_MICROS 115 | ||
778 | #define TS_F_TS_ACCURACY_SET_MILLIS 116 | ||
779 | #define TS_F_TS_ACCURACY_SET_SECONDS 117 | ||
780 | #define TS_F_TS_CHECK_IMPRINTS 100 | ||
781 | #define TS_F_TS_CHECK_NONCES 101 | ||
782 | #define TS_F_TS_CHECK_POLICY 102 | ||
783 | #define TS_F_TS_CHECK_SIGNING_CERTS 103 | ||
784 | #define TS_F_TS_CHECK_STATUS_INFO 104 | ||
785 | #define TS_F_TS_COMPUTE_IMPRINT 145 | ||
786 | #define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 | ||
787 | #define TS_F_TS_GET_STATUS_TEXT 105 | ||
788 | #define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 | ||
789 | #define TS_F_TS_REQ_SET_MSG_IMPRINT 119 | ||
790 | #define TS_F_TS_REQ_SET_NONCE 120 | ||
791 | #define TS_F_TS_REQ_SET_POLICY_ID 121 | ||
792 | #define TS_F_TS_RESP_CREATE_RESPONSE 122 | ||
793 | #define TS_F_TS_RESP_CREATE_TST_INFO 123 | ||
794 | #define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 | ||
795 | #define TS_F_TS_RESP_CTX_ADD_MD 125 | ||
796 | #define TS_F_TS_RESP_CTX_ADD_POLICY 126 | ||
797 | #define TS_F_TS_RESP_CTX_NEW 127 | ||
798 | #define TS_F_TS_RESP_CTX_SET_ACCURACY 128 | ||
799 | #define TS_F_TS_RESP_CTX_SET_CERTS 129 | ||
800 | #define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 | ||
801 | #define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 | ||
802 | #define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 | ||
803 | #define TS_F_TS_RESP_GET_POLICY 133 | ||
804 | #define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 | ||
805 | #define TS_F_TS_RESP_SET_STATUS_INFO 135 | ||
806 | #define TS_F_TS_RESP_SET_TST_INFO 150 | ||
807 | #define TS_F_TS_RESP_SIGN 136 | ||
808 | #define TS_F_TS_RESP_VERIFY_SIGNATURE 106 | ||
809 | #define TS_F_TS_RESP_VERIFY_TOKEN 107 | ||
810 | #define TS_F_TS_TST_INFO_SET_ACCURACY 137 | ||
811 | #define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 | ||
812 | #define TS_F_TS_TST_INFO_SET_NONCE 139 | ||
813 | #define TS_F_TS_TST_INFO_SET_POLICY_ID 140 | ||
814 | #define TS_F_TS_TST_INFO_SET_SERIAL 141 | ||
815 | #define TS_F_TS_TST_INFO_SET_TIME 142 | ||
816 | #define TS_F_TS_TST_INFO_SET_TSA 143 | ||
817 | #define TS_F_TS_VERIFY 108 | ||
818 | #define TS_F_TS_VERIFY_CERT 109 | ||
819 | #define TS_F_TS_VERIFY_CTX_NEW 144 | ||
820 | |||
821 | /* Reason codes. */ | ||
822 | #define TS_R_BAD_PKCS7_TYPE 132 | ||
823 | #define TS_R_BAD_TYPE 133 | ||
824 | #define TS_R_CERTIFICATE_VERIFY_ERROR 100 | ||
825 | #define TS_R_COULD_NOT_SET_ENGINE 127 | ||
826 | #define TS_R_COULD_NOT_SET_TIME 115 | ||
827 | #define TS_R_D2I_TS_RESP_INT_FAILED 128 | ||
828 | #define TS_R_DETACHED_CONTENT 134 | ||
829 | #define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 | ||
830 | #define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 | ||
831 | #define TS_R_INVALID_NULL_POINTER 102 | ||
832 | #define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 | ||
833 | #define TS_R_MESSAGE_IMPRINT_MISMATCH 103 | ||
834 | #define TS_R_NONCE_MISMATCH 104 | ||
835 | #define TS_R_NONCE_NOT_RETURNED 105 | ||
836 | #define TS_R_NO_CONTENT 106 | ||
837 | #define TS_R_NO_TIME_STAMP_TOKEN 107 | ||
838 | #define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 | ||
839 | #define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 | ||
840 | #define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 | ||
841 | #define TS_R_POLICY_MISMATCH 108 | ||
842 | #define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 | ||
843 | #define TS_R_RESPONSE_SETUP_ERROR 121 | ||
844 | #define TS_R_SIGNATURE_FAILURE 109 | ||
845 | #define TS_R_THERE_MUST_BE_ONE_SIGNER 110 | ||
846 | #define TS_R_TIME_SYSCALL_ERROR 122 | ||
847 | #define TS_R_TOKEN_NOT_PRESENT 130 | ||
848 | #define TS_R_TOKEN_PRESENT 131 | ||
849 | #define TS_R_TSA_NAME_MISMATCH 111 | ||
850 | #define TS_R_TSA_UNTRUSTED 112 | ||
851 | #define TS_R_TST_INFO_SETUP_ERROR 123 | ||
852 | #define TS_R_TS_DATASIGN 124 | ||
853 | #define TS_R_UNACCEPTABLE_POLICY 125 | ||
854 | #define TS_R_UNSUPPORTED_MD_ALGORITHM 126 | ||
855 | #define TS_R_UNSUPPORTED_VERSION 113 | ||
856 | #define TS_R_WRONG_CONTENT_TYPE 114 | ||
857 | |||
858 | #ifdef __cplusplus | ||
859 | } | ||
860 | #endif | ||
861 | #endif | ||
diff --git a/src/lib/libcrypto/ts/ts_asn1.c b/src/lib/libcrypto/ts/ts_asn1.c new file mode 100644 index 0000000000..40b730c5e2 --- /dev/null +++ b/src/lib/libcrypto/ts/ts_asn1.c | |||
@@ -0,0 +1,322 @@ | |||
1 | /* crypto/ts/ts_asn1.c */ | ||
2 | /* Written by Nils Larsch for the OpenSSL project 2004. | ||
3 | */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * licensing@OpenSSL.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <openssl/ts.h> | ||
59 | #include <openssl/err.h> | ||
60 | #include <openssl/asn1t.h> | ||
61 | |||
62 | ASN1_SEQUENCE(TS_MSG_IMPRINT) = { | ||
63 | ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR), | ||
64 | ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING) | ||
65 | } ASN1_SEQUENCE_END(TS_MSG_IMPRINT) | ||
66 | |||
67 | IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT) | ||
68 | IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT) | ||
69 | #ifndef OPENSSL_NO_BIO | ||
70 | TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a) | ||
71 | { | ||
72 | return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, bp, a); | ||
73 | } | ||
74 | |||
75 | int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a) | ||
76 | { | ||
77 | return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a); | ||
78 | } | ||
79 | #endif | ||
80 | #ifndef OPENSSL_NO_FP_API | ||
81 | TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a) | ||
82 | { | ||
83 | return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, fp, a); | ||
84 | } | ||
85 | |||
86 | int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a) | ||
87 | { | ||
88 | return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a); | ||
89 | } | ||
90 | #endif | ||
91 | |||
92 | ASN1_SEQUENCE(TS_REQ) = { | ||
93 | ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER), | ||
94 | ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT), | ||
95 | ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT), | ||
96 | ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER), | ||
97 | ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN), | ||
98 | ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0) | ||
99 | } ASN1_SEQUENCE_END(TS_REQ) | ||
100 | |||
101 | IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ) | ||
102 | IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ) | ||
103 | #ifndef OPENSSL_NO_BIO | ||
104 | TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a) | ||
105 | { | ||
106 | return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a); | ||
107 | } | ||
108 | |||
109 | int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a) | ||
110 | { | ||
111 | return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a); | ||
112 | } | ||
113 | #endif | ||
114 | #ifndef OPENSSL_NO_FP_API | ||
115 | TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a) | ||
116 | { | ||
117 | return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a); | ||
118 | } | ||
119 | |||
120 | int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a) | ||
121 | { | ||
122 | return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a); | ||
123 | } | ||
124 | #endif | ||
125 | |||
126 | ASN1_SEQUENCE(TS_ACCURACY) = { | ||
127 | ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER), | ||
128 | ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0), | ||
129 | ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1) | ||
130 | } ASN1_SEQUENCE_END(TS_ACCURACY) | ||
131 | |||
132 | IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY) | ||
133 | IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY) | ||
134 | |||
135 | ASN1_SEQUENCE(TS_TST_INFO) = { | ||
136 | ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER), | ||
137 | ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT), | ||
138 | ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT), | ||
139 | ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER), | ||
140 | ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME), | ||
141 | ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY), | ||
142 | ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN), | ||
143 | ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER), | ||
144 | ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0), | ||
145 | ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1) | ||
146 | } ASN1_SEQUENCE_END(TS_TST_INFO) | ||
147 | |||
148 | IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO) | ||
149 | IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO) | ||
150 | #ifndef OPENSSL_NO_BIO | ||
151 | TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a) | ||
152 | { | ||
153 | return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp, a); | ||
154 | } | ||
155 | |||
156 | int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a) | ||
157 | { | ||
158 | return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a); | ||
159 | } | ||
160 | #endif | ||
161 | #ifndef OPENSSL_NO_FP_API | ||
162 | TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a) | ||
163 | { | ||
164 | return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp, a); | ||
165 | } | ||
166 | |||
167 | int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a) | ||
168 | { | ||
169 | return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a); | ||
170 | } | ||
171 | #endif | ||
172 | |||
173 | ASN1_SEQUENCE(TS_STATUS_INFO) = { | ||
174 | ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER), | ||
175 | ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING), | ||
176 | ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING) | ||
177 | } ASN1_SEQUENCE_END(TS_STATUS_INFO) | ||
178 | |||
179 | IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO) | ||
180 | IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO) | ||
181 | |||
182 | static int ts_resp_set_tst_info(TS_RESP *a) | ||
183 | { | ||
184 | long status; | ||
185 | |||
186 | status = ASN1_INTEGER_get(a->status_info->status); | ||
187 | |||
188 | if (a->token) { | ||
189 | if (status != 0 && status != 1) { | ||
190 | TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT); | ||
191 | return 0; | ||
192 | } | ||
193 | if (a->tst_info != NULL) | ||
194 | TS_TST_INFO_free(a->tst_info); | ||
195 | a->tst_info = PKCS7_to_TS_TST_INFO(a->token); | ||
196 | if (!a->tst_info) { | ||
197 | TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_PKCS7_TO_TS_TST_INFO_FAILED); | ||
198 | return 0; | ||
199 | } | ||
200 | } else if (status == 0 || status == 1) { | ||
201 | TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT); | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | return 1; | ||
206 | } | ||
207 | |||
208 | static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it, | ||
209 | void *exarg) | ||
210 | { | ||
211 | TS_RESP *ts_resp = (TS_RESP *)*pval; | ||
212 | if (op == ASN1_OP_NEW_POST) { | ||
213 | ts_resp->tst_info = NULL; | ||
214 | } else if (op == ASN1_OP_FREE_POST) { | ||
215 | if (ts_resp->tst_info != NULL) | ||
216 | TS_TST_INFO_free(ts_resp->tst_info); | ||
217 | } else if (op == ASN1_OP_D2I_POST) { | ||
218 | if (ts_resp_set_tst_info(ts_resp) == 0) | ||
219 | return 0; | ||
220 | } | ||
221 | return 1; | ||
222 | } | ||
223 | |||
224 | ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = { | ||
225 | ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO), | ||
226 | ASN1_OPT(TS_RESP, token, PKCS7), | ||
227 | } ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP) | ||
228 | |||
229 | IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP) | ||
230 | IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP) | ||
231 | #ifndef OPENSSL_NO_BIO | ||
232 | TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a) | ||
233 | { | ||
234 | return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a); | ||
235 | } | ||
236 | |||
237 | int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a) | ||
238 | { | ||
239 | return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a); | ||
240 | } | ||
241 | #endif | ||
242 | #ifndef OPENSSL_NO_FP_API | ||
243 | TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a) | ||
244 | { | ||
245 | return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a); | ||
246 | } | ||
247 | |||
248 | int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a) | ||
249 | { | ||
250 | return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a); | ||
251 | } | ||
252 | #endif | ||
253 | |||
254 | ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = { | ||
255 | ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME), | ||
256 | ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER) | ||
257 | } ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL) | ||
258 | |||
259 | IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL) | ||
260 | IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL) | ||
261 | |||
262 | ASN1_SEQUENCE(ESS_CERT_ID) = { | ||
263 | ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING), | ||
264 | ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL) | ||
265 | } ASN1_SEQUENCE_END(ESS_CERT_ID) | ||
266 | |||
267 | IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID) | ||
268 | IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID) | ||
269 | |||
270 | ASN1_SEQUENCE(ESS_SIGNING_CERT) = { | ||
271 | ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID), | ||
272 | ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO) | ||
273 | } ASN1_SEQUENCE_END(ESS_SIGNING_CERT) | ||
274 | |||
275 | IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT) | ||
276 | IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT) | ||
277 | |||
278 | /* Getting encapsulated TS_TST_INFO object from PKCS7. */ | ||
279 | TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) | ||
280 | { | ||
281 | PKCS7_SIGNED *pkcs7_signed; | ||
282 | PKCS7 *enveloped; | ||
283 | ASN1_TYPE *tst_info_wrapper; | ||
284 | ASN1_OCTET_STRING *tst_info_der; | ||
285 | const unsigned char *p; | ||
286 | |||
287 | if (!PKCS7_type_is_signed(token)) | ||
288 | { | ||
289 | TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); | ||
290 | return NULL; | ||
291 | } | ||
292 | |||
293 | /* Content must be present. */ | ||
294 | if (PKCS7_get_detached(token)) | ||
295 | { | ||
296 | TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT); | ||
297 | return NULL; | ||
298 | } | ||
299 | |||
300 | /* We have a signed data with content. */ | ||
301 | pkcs7_signed = token->d.sign; | ||
302 | enveloped = pkcs7_signed->contents; | ||
303 | if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) | ||
304 | { | ||
305 | TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); | ||
306 | return NULL; | ||
307 | } | ||
308 | |||
309 | /* We have a DER encoded TST_INFO as the signed data. */ | ||
310 | tst_info_wrapper = enveloped->d.other; | ||
311 | if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) | ||
312 | { | ||
313 | TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE); | ||
314 | return NULL; | ||
315 | } | ||
316 | |||
317 | /* We have the correct ASN1_OCTET_STRING type. */ | ||
318 | tst_info_der = tst_info_wrapper->value.octet_string; | ||
319 | /* At last, decode the TST_INFO. */ | ||
320 | p = tst_info_der->data; | ||
321 | return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length); | ||
322 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_conf.c b/src/lib/libcrypto/ts/ts_conf.c new file mode 100644 index 0000000000..c39be76f28 --- /dev/null +++ b/src/lib/libcrypto/ts/ts_conf.c | |||
@@ -0,0 +1,507 @@ | |||
1 | /* crypto/ts/ts_conf.c */ | ||
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | ||
3 | * project 2002. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <string.h> | ||
60 | |||
61 | #include <openssl/crypto.h> | ||
62 | #include "cryptlib.h" | ||
63 | #include <openssl/pem.h> | ||
64 | #ifndef OPENSSL_NO_ENGINE | ||
65 | #include <openssl/engine.h> | ||
66 | #endif | ||
67 | #include <openssl/ts.h> | ||
68 | |||
69 | /* Macro definitions for the configuration file. */ | ||
70 | |||
71 | #define BASE_SECTION "tsa" | ||
72 | #define ENV_DEFAULT_TSA "default_tsa" | ||
73 | #define ENV_SERIAL "serial" | ||
74 | #define ENV_CRYPTO_DEVICE "crypto_device" | ||
75 | #define ENV_SIGNER_CERT "signer_cert" | ||
76 | #define ENV_CERTS "certs" | ||
77 | #define ENV_SIGNER_KEY "signer_key" | ||
78 | #define ENV_DEFAULT_POLICY "default_policy" | ||
79 | #define ENV_OTHER_POLICIES "other_policies" | ||
80 | #define ENV_DIGESTS "digests" | ||
81 | #define ENV_ACCURACY "accuracy" | ||
82 | #define ENV_ORDERING "ordering" | ||
83 | #define ENV_TSA_NAME "tsa_name" | ||
84 | #define ENV_ESS_CERT_ID_CHAIN "ess_cert_id_chain" | ||
85 | #define ENV_VALUE_SECS "secs" | ||
86 | #define ENV_VALUE_MILLISECS "millisecs" | ||
87 | #define ENV_VALUE_MICROSECS "microsecs" | ||
88 | #define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits" | ||
89 | #define ENV_VALUE_YES "yes" | ||
90 | #define ENV_VALUE_NO "no" | ||
91 | |||
92 | /* Function definitions for certificate and key loading. */ | ||
93 | |||
94 | X509 *TS_CONF_load_cert(const char *file) | ||
95 | { | ||
96 | BIO *cert = NULL; | ||
97 | X509 *x = NULL; | ||
98 | |||
99 | if ((cert = BIO_new_file(file, "r")) == NULL) goto end; | ||
100 | x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL); | ||
101 | end: | ||
102 | if (x == NULL) | ||
103 | fprintf(stderr, "unable to load certificate: %s\n", file); | ||
104 | BIO_free(cert); | ||
105 | return x; | ||
106 | } | ||
107 | |||
108 | STACK_OF(X509) *TS_CONF_load_certs(const char *file) | ||
109 | { | ||
110 | BIO *certs = NULL; | ||
111 | STACK_OF(X509) *othercerts = NULL; | ||
112 | STACK_OF(X509_INFO) *allcerts = NULL; | ||
113 | int i; | ||
114 | |||
115 | if (!(certs = BIO_new_file(file, "r"))) goto end; | ||
116 | |||
117 | if (!(othercerts = sk_X509_new_null())) goto end; | ||
118 | allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL); | ||
119 | for(i = 0; i < sk_X509_INFO_num(allcerts); i++) | ||
120 | { | ||
121 | X509_INFO *xi = sk_X509_INFO_value(allcerts, i); | ||
122 | if (xi->x509) | ||
123 | { | ||
124 | sk_X509_push(othercerts, xi->x509); | ||
125 | xi->x509 = NULL; | ||
126 | } | ||
127 | } | ||
128 | end: | ||
129 | if (othercerts == NULL) | ||
130 | fprintf(stderr, "unable to load certificates: %s\n", file); | ||
131 | sk_X509_INFO_pop_free(allcerts, X509_INFO_free); | ||
132 | BIO_free(certs); | ||
133 | return othercerts; | ||
134 | } | ||
135 | |||
136 | EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass) | ||
137 | { | ||
138 | BIO *key = NULL; | ||
139 | EVP_PKEY *pkey = NULL; | ||
140 | |||
141 | if (!(key = BIO_new_file(file, "r"))) goto end; | ||
142 | pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *) pass); | ||
143 | end: | ||
144 | if (pkey == NULL) | ||
145 | fprintf(stderr, "unable to load private key: %s\n", file); | ||
146 | BIO_free(key); | ||
147 | return pkey; | ||
148 | } | ||
149 | |||
150 | /* Function definitions for handling configuration options. */ | ||
151 | |||
152 | static void TS_CONF_lookup_fail(const char *name, const char *tag) | ||
153 | { | ||
154 | fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag); | ||
155 | } | ||
156 | |||
157 | static void TS_CONF_invalid(const char *name, const char *tag) | ||
158 | { | ||
159 | fprintf(stderr, "invalid variable value for %s::%s\n", name, tag); | ||
160 | } | ||
161 | |||
162 | const char *TS_CONF_get_tsa_section(CONF *conf, const char *section) | ||
163 | { | ||
164 | if (!section) | ||
165 | { | ||
166 | section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA); | ||
167 | if (!section) | ||
168 | TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA); | ||
169 | } | ||
170 | return section; | ||
171 | } | ||
172 | |||
173 | int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, | ||
174 | TS_RESP_CTX *ctx) | ||
175 | { | ||
176 | int ret = 0; | ||
177 | char *serial = NCONF_get_string(conf, section, ENV_SERIAL); | ||
178 | if (!serial) | ||
179 | { | ||
180 | TS_CONF_lookup_fail(section, ENV_SERIAL); | ||
181 | goto err; | ||
182 | } | ||
183 | TS_RESP_CTX_set_serial_cb(ctx, cb, serial); | ||
184 | |||
185 | ret = 1; | ||
186 | err: | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | #ifndef OPENSSL_NO_ENGINE | ||
191 | |||
192 | int TS_CONF_set_crypto_device(CONF *conf, const char *section, | ||
193 | const char *device) | ||
194 | { | ||
195 | int ret = 0; | ||
196 | |||
197 | if (!device) | ||
198 | device = NCONF_get_string(conf, section, | ||
199 | ENV_CRYPTO_DEVICE); | ||
200 | |||
201 | if (device && !TS_CONF_set_default_engine(device)) | ||
202 | { | ||
203 | TS_CONF_invalid(section, ENV_CRYPTO_DEVICE); | ||
204 | goto err; | ||
205 | } | ||
206 | ret = 1; | ||
207 | err: | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | int TS_CONF_set_default_engine(const char *name) | ||
212 | { | ||
213 | ENGINE *e = NULL; | ||
214 | int ret = 0; | ||
215 | |||
216 | /* Leave the default if builtin specified. */ | ||
217 | if (strcmp(name, "builtin") == 0) return 1; | ||
218 | |||
219 | if (!(e = ENGINE_by_id(name))) goto err; | ||
220 | /* Enable the use of the NCipher HSM for forked children. */ | ||
221 | if (strcmp(name, "chil") == 0) | ||
222 | ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0); | ||
223 | /* All the operations are going to be carried out by the engine. */ | ||
224 | if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) goto err; | ||
225 | ret = 1; | ||
226 | err: | ||
227 | if (!ret) | ||
228 | { | ||
229 | TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, | ||
230 | TS_R_COULD_NOT_SET_ENGINE); | ||
231 | ERR_add_error_data(2, "engine:", name); | ||
232 | } | ||
233 | if (e) ENGINE_free(e); | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | #endif | ||
238 | |||
239 | int TS_CONF_set_signer_cert(CONF *conf, const char *section, | ||
240 | const char *cert, TS_RESP_CTX *ctx) | ||
241 | { | ||
242 | int ret = 0; | ||
243 | X509 *cert_obj = NULL; | ||
244 | if (!cert) | ||
245 | cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT); | ||
246 | if (!cert) | ||
247 | { | ||
248 | TS_CONF_lookup_fail(section, ENV_SIGNER_CERT); | ||
249 | goto err; | ||
250 | } | ||
251 | if (!(cert_obj = TS_CONF_load_cert(cert))) | ||
252 | goto err; | ||
253 | if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj)) | ||
254 | goto err; | ||
255 | |||
256 | ret = 1; | ||
257 | err: | ||
258 | X509_free(cert_obj); | ||
259 | return ret; | ||
260 | } | ||
261 | |||
262 | int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, | ||
263 | TS_RESP_CTX *ctx) | ||
264 | { | ||
265 | int ret = 0; | ||
266 | STACK_OF(X509) *certs_obj = NULL; | ||
267 | if (!certs) | ||
268 | certs = NCONF_get_string(conf, section, ENV_CERTS); | ||
269 | /* Certificate chain is optional. */ | ||
270 | if (!certs) goto end; | ||
271 | if (!(certs_obj = TS_CONF_load_certs(certs))) goto err; | ||
272 | if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) goto err; | ||
273 | end: | ||
274 | ret = 1; | ||
275 | err: | ||
276 | sk_X509_pop_free(certs_obj, X509_free); | ||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | int TS_CONF_set_signer_key(CONF *conf, const char *section, | ||
281 | const char *key, const char *pass, | ||
282 | TS_RESP_CTX *ctx) | ||
283 | { | ||
284 | int ret = 0; | ||
285 | EVP_PKEY *key_obj = NULL; | ||
286 | if (!key) | ||
287 | key = NCONF_get_string(conf, section, ENV_SIGNER_KEY); | ||
288 | if (!key) | ||
289 | { | ||
290 | TS_CONF_lookup_fail(section, ENV_SIGNER_KEY); | ||
291 | goto err; | ||
292 | } | ||
293 | if (!(key_obj = TS_CONF_load_key(key, pass))) goto err; | ||
294 | if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) goto err; | ||
295 | |||
296 | ret = 1; | ||
297 | err: | ||
298 | EVP_PKEY_free(key_obj); | ||
299 | return ret; | ||
300 | } | ||
301 | |||
302 | int TS_CONF_set_def_policy(CONF *conf, const char *section, | ||
303 | const char *policy, TS_RESP_CTX *ctx) | ||
304 | { | ||
305 | int ret = 0; | ||
306 | ASN1_OBJECT *policy_obj = NULL; | ||
307 | if (!policy) | ||
308 | policy = NCONF_get_string(conf, section, | ||
309 | ENV_DEFAULT_POLICY); | ||
310 | if (!policy) | ||
311 | { | ||
312 | TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY); | ||
313 | goto err; | ||
314 | } | ||
315 | if (!(policy_obj = OBJ_txt2obj(policy, 0))) | ||
316 | { | ||
317 | TS_CONF_invalid(section, ENV_DEFAULT_POLICY); | ||
318 | goto err; | ||
319 | } | ||
320 | if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj)) | ||
321 | goto err; | ||
322 | |||
323 | ret = 1; | ||
324 | err: | ||
325 | ASN1_OBJECT_free(policy_obj); | ||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | int TS_CONF_set_policies(CONF *conf, const char *section, | ||
330 | TS_RESP_CTX *ctx) | ||
331 | { | ||
332 | int ret = 0; | ||
333 | int i; | ||
334 | STACK_OF(CONF_VALUE) *list = NULL; | ||
335 | char *policies = NCONF_get_string(conf, section, | ||
336 | ENV_OTHER_POLICIES); | ||
337 | /* If no other policy is specified, that's fine. */ | ||
338 | if (policies && !(list = X509V3_parse_list(policies))) | ||
339 | { | ||
340 | TS_CONF_invalid(section, ENV_OTHER_POLICIES); | ||
341 | goto err; | ||
342 | } | ||
343 | for (i = 0; i < sk_CONF_VALUE_num(list); ++i) | ||
344 | { | ||
345 | CONF_VALUE *val = sk_CONF_VALUE_value(list, i); | ||
346 | const char *extval = val->value ? val->value : val->name; | ||
347 | ASN1_OBJECT *objtmp; | ||
348 | if (!(objtmp = OBJ_txt2obj(extval, 0))) | ||
349 | { | ||
350 | TS_CONF_invalid(section, ENV_OTHER_POLICIES); | ||
351 | goto err; | ||
352 | } | ||
353 | if (!TS_RESP_CTX_add_policy(ctx, objtmp)) | ||
354 | goto err; | ||
355 | ASN1_OBJECT_free(objtmp); | ||
356 | } | ||
357 | |||
358 | ret = 1; | ||
359 | err: | ||
360 | sk_CONF_VALUE_pop_free(list, X509V3_conf_free); | ||
361 | return ret; | ||
362 | } | ||
363 | |||
364 | int TS_CONF_set_digests(CONF *conf, const char *section, | ||
365 | TS_RESP_CTX *ctx) | ||
366 | { | ||
367 | int ret = 0; | ||
368 | int i; | ||
369 | STACK_OF(CONF_VALUE) *list = NULL; | ||
370 | char *digests = NCONF_get_string(conf, section, ENV_DIGESTS); | ||
371 | if (!digests) | ||
372 | { | ||
373 | TS_CONF_lookup_fail(section, ENV_DIGESTS); | ||
374 | goto err; | ||
375 | } | ||
376 | if (!(list = X509V3_parse_list(digests))) | ||
377 | { | ||
378 | TS_CONF_invalid(section, ENV_DIGESTS); | ||
379 | goto err; | ||
380 | } | ||
381 | if (sk_CONF_VALUE_num(list) == 0) | ||
382 | { | ||
383 | TS_CONF_invalid(section, ENV_DIGESTS); | ||
384 | goto err; | ||
385 | } | ||
386 | for (i = 0; i < sk_CONF_VALUE_num(list); ++i) | ||
387 | { | ||
388 | CONF_VALUE *val = sk_CONF_VALUE_value(list, i); | ||
389 | const char *extval = val->value ? val->value : val->name; | ||
390 | const EVP_MD *md; | ||
391 | if (!(md = EVP_get_digestbyname(extval))) | ||
392 | { | ||
393 | TS_CONF_invalid(section, ENV_DIGESTS); | ||
394 | goto err; | ||
395 | } | ||
396 | if (!TS_RESP_CTX_add_md(ctx, md)) | ||
397 | goto err; | ||
398 | } | ||
399 | |||
400 | ret = 1; | ||
401 | err: | ||
402 | sk_CONF_VALUE_pop_free(list, X509V3_conf_free); | ||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx) | ||
407 | { | ||
408 | int ret = 0; | ||
409 | int i; | ||
410 | int secs = 0, millis = 0, micros = 0; | ||
411 | STACK_OF(CONF_VALUE) *list = NULL; | ||
412 | char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY); | ||
413 | |||
414 | if (accuracy && !(list = X509V3_parse_list(accuracy))) | ||
415 | { | ||
416 | TS_CONF_invalid(section, ENV_ACCURACY); | ||
417 | goto err; | ||
418 | } | ||
419 | for (i = 0; i < sk_CONF_VALUE_num(list); ++i) | ||
420 | { | ||
421 | CONF_VALUE *val = sk_CONF_VALUE_value(list, i); | ||
422 | if (strcmp(val->name, ENV_VALUE_SECS) == 0) | ||
423 | { | ||
424 | if (val->value) secs = atoi(val->value); | ||
425 | } | ||
426 | else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) | ||
427 | { | ||
428 | if (val->value) millis = atoi(val->value); | ||
429 | } | ||
430 | else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) | ||
431 | { | ||
432 | if (val->value) micros = atoi(val->value); | ||
433 | } | ||
434 | else | ||
435 | { | ||
436 | TS_CONF_invalid(section, ENV_ACCURACY); | ||
437 | goto err; | ||
438 | } | ||
439 | } | ||
440 | if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros)) | ||
441 | goto err; | ||
442 | |||
443 | ret = 1; | ||
444 | err: | ||
445 | sk_CONF_VALUE_pop_free(list, X509V3_conf_free); | ||
446 | return ret; | ||
447 | } | ||
448 | |||
449 | int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, | ||
450 | TS_RESP_CTX *ctx) | ||
451 | { | ||
452 | int ret = 0; | ||
453 | long digits = 0; | ||
454 | |||
455 | /* If not specified, set the default value to 0, i.e. sec precision */ | ||
456 | if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS, | ||
457 | &digits)) | ||
458 | digits = 0; | ||
459 | if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) | ||
460 | { | ||
461 | TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS); | ||
462 | goto err; | ||
463 | } | ||
464 | |||
465 | if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits)) | ||
466 | goto err; | ||
467 | |||
468 | return 1; | ||
469 | err: | ||
470 | return ret; | ||
471 | } | ||
472 | |||
473 | static int TS_CONF_add_flag(CONF *conf, const char *section, const char *field, | ||
474 | int flag, TS_RESP_CTX *ctx) | ||
475 | { | ||
476 | /* Default is false. */ | ||
477 | const char *value = NCONF_get_string(conf, section, field); | ||
478 | if (value) | ||
479 | { | ||
480 | if (strcmp(value, ENV_VALUE_YES) == 0) | ||
481 | TS_RESP_CTX_add_flags(ctx, flag); | ||
482 | else if (strcmp(value, ENV_VALUE_NO) != 0) | ||
483 | { | ||
484 | TS_CONF_invalid(section, field); | ||
485 | return 0; | ||
486 | } | ||
487 | } | ||
488 | |||
489 | return 1; | ||
490 | } | ||
491 | |||
492 | int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx) | ||
493 | { | ||
494 | return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx); | ||
495 | } | ||
496 | |||
497 | int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx) | ||
498 | { | ||
499 | return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx); | ||
500 | } | ||
501 | |||
502 | int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, | ||
503 | TS_RESP_CTX *ctx) | ||
504 | { | ||
505 | return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN, | ||
506 | TS_ESS_CERT_ID_CHAIN, ctx); | ||
507 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_err.c b/src/lib/libcrypto/ts/ts_err.c new file mode 100644 index 0000000000..a08b0ffa23 --- /dev/null +++ b/src/lib/libcrypto/ts/ts_err.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* crypto/ts/ts_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | /* NOTE: this file was auto generated by the mkerr.pl script: any changes | ||
57 | * made to it will be overwritten when the script next updates this file, | ||
58 | * only reason strings will be preserved. | ||
59 | */ | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include <openssl/err.h> | ||
63 | #include <openssl/ts.h> | ||
64 | |||
65 | /* BEGIN ERROR CODES */ | ||
66 | #ifndef OPENSSL_NO_ERR | ||
67 | |||
68 | #define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0) | ||
69 | #define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason) | ||
70 | |||
71 | static ERR_STRING_DATA TS_str_functs[]= | ||
72 | { | ||
73 | {ERR_FUNC(TS_F_D2I_TS_RESP), "d2i_TS_RESP"}, | ||
74 | {ERR_FUNC(TS_F_DEF_SERIAL_CB), "DEF_SERIAL_CB"}, | ||
75 | {ERR_FUNC(TS_F_DEF_TIME_CB), "DEF_TIME_CB"}, | ||
76 | {ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT), "ESS_ADD_SIGNING_CERT"}, | ||
77 | {ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT), "ESS_CERT_ID_NEW_INIT"}, | ||
78 | {ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT), "ESS_SIGNING_CERT_NEW_INIT"}, | ||
79 | {ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN), "INT_TS_RESP_VERIFY_TOKEN"}, | ||
80 | {ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"}, | ||
81 | {ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"}, | ||
82 | {ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS), "TS_ACCURACY_set_millis"}, | ||
83 | {ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS), "TS_ACCURACY_set_seconds"}, | ||
84 | {ERR_FUNC(TS_F_TS_CHECK_IMPRINTS), "TS_CHECK_IMPRINTS"}, | ||
85 | {ERR_FUNC(TS_F_TS_CHECK_NONCES), "TS_CHECK_NONCES"}, | ||
86 | {ERR_FUNC(TS_F_TS_CHECK_POLICY), "TS_CHECK_POLICY"}, | ||
87 | {ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS), "TS_CHECK_SIGNING_CERTS"}, | ||
88 | {ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO), "TS_CHECK_STATUS_INFO"}, | ||
89 | {ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT), "TS_COMPUTE_IMPRINT"}, | ||
90 | {ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE), "TS_CONF_set_default_engine"}, | ||
91 | {ERR_FUNC(TS_F_TS_GET_STATUS_TEXT), "TS_GET_STATUS_TEXT"}, | ||
92 | {ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO), "TS_MSG_IMPRINT_set_algo"}, | ||
93 | {ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT), "TS_REQ_set_msg_imprint"}, | ||
94 | {ERR_FUNC(TS_F_TS_REQ_SET_NONCE), "TS_REQ_set_nonce"}, | ||
95 | {ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID), "TS_REQ_set_policy_id"}, | ||
96 | {ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE), "TS_RESP_create_response"}, | ||
97 | {ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO), "TS_RESP_CREATE_TST_INFO"}, | ||
98 | {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO), "TS_RESP_CTX_add_failure_info"}, | ||
99 | {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD), "TS_RESP_CTX_add_md"}, | ||
100 | {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY), "TS_RESP_CTX_add_policy"}, | ||
101 | {ERR_FUNC(TS_F_TS_RESP_CTX_NEW), "TS_RESP_CTX_new"}, | ||
102 | {ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY), "TS_RESP_CTX_set_accuracy"}, | ||
103 | {ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS), "TS_RESP_CTX_set_certs"}, | ||
104 | {ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY), "TS_RESP_CTX_set_def_policy"}, | ||
105 | {ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT), "TS_RESP_CTX_set_signer_cert"}, | ||
106 | {ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO), "TS_RESP_CTX_set_status_info"}, | ||
107 | {ERR_FUNC(TS_F_TS_RESP_GET_POLICY), "TS_RESP_GET_POLICY"}, | ||
108 | {ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION), "TS_RESP_SET_GENTIME_WITH_PRECISION"}, | ||
109 | {ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO), "TS_RESP_set_status_info"}, | ||
110 | {ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO), "TS_RESP_set_tst_info"}, | ||
111 | {ERR_FUNC(TS_F_TS_RESP_SIGN), "TS_RESP_SIGN"}, | ||
112 | {ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE), "TS_RESP_verify_signature"}, | ||
113 | {ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN), "TS_RESP_verify_token"}, | ||
114 | {ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY), "TS_TST_INFO_set_accuracy"}, | ||
115 | {ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT), "TS_TST_INFO_set_msg_imprint"}, | ||
116 | {ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE), "TS_TST_INFO_set_nonce"}, | ||
117 | {ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID), "TS_TST_INFO_set_policy_id"}, | ||
118 | {ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL), "TS_TST_INFO_set_serial"}, | ||
119 | {ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME), "TS_TST_INFO_set_time"}, | ||
120 | {ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA), "TS_TST_INFO_set_tsa"}, | ||
121 | {ERR_FUNC(TS_F_TS_VERIFY), "TS_VERIFY"}, | ||
122 | {ERR_FUNC(TS_F_TS_VERIFY_CERT), "TS_VERIFY_CERT"}, | ||
123 | {ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW), "TS_VERIFY_CTX_new"}, | ||
124 | {0,NULL} | ||
125 | }; | ||
126 | |||
127 | static ERR_STRING_DATA TS_str_reasons[]= | ||
128 | { | ||
129 | {ERR_REASON(TS_R_BAD_PKCS7_TYPE) ,"bad pkcs7 type"}, | ||
130 | {ERR_REASON(TS_R_BAD_TYPE) ,"bad type"}, | ||
131 | {ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"}, | ||
132 | {ERR_REASON(TS_R_COULD_NOT_SET_ENGINE) ,"could not set engine"}, | ||
133 | {ERR_REASON(TS_R_COULD_NOT_SET_TIME) ,"could not set time"}, | ||
134 | {ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED) ,"d2i ts resp int failed"}, | ||
135 | {ERR_REASON(TS_R_DETACHED_CONTENT) ,"detached content"}, | ||
136 | {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),"ess add signing cert error"}, | ||
137 | {ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),"ess signing certificate error"}, | ||
138 | {ERR_REASON(TS_R_INVALID_NULL_POINTER) ,"invalid null pointer"}, | ||
139 | {ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE),"invalid signer certificate purpose"}, | ||
140 | {ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH),"message imprint mismatch"}, | ||
141 | {ERR_REASON(TS_R_NONCE_MISMATCH) ,"nonce mismatch"}, | ||
142 | {ERR_REASON(TS_R_NONCE_NOT_RETURNED) ,"nonce not returned"}, | ||
143 | {ERR_REASON(TS_R_NO_CONTENT) ,"no content"}, | ||
144 | {ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN) ,"no time stamp token"}, | ||
145 | {ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"}, | ||
146 | {ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR),"pkcs7 add signed attr error"}, | ||
147 | {ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED),"pkcs7 to ts tst info failed"}, | ||
148 | {ERR_REASON(TS_R_POLICY_MISMATCH) ,"policy mismatch"}, | ||
149 | {ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"}, | ||
150 | {ERR_REASON(TS_R_RESPONSE_SETUP_ERROR) ,"response setup error"}, | ||
151 | {ERR_REASON(TS_R_SIGNATURE_FAILURE) ,"signature failure"}, | ||
152 | {ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER),"there must be one signer"}, | ||
153 | {ERR_REASON(TS_R_TIME_SYSCALL_ERROR) ,"time syscall error"}, | ||
154 | {ERR_REASON(TS_R_TOKEN_NOT_PRESENT) ,"token not present"}, | ||
155 | {ERR_REASON(TS_R_TOKEN_PRESENT) ,"token present"}, | ||
156 | {ERR_REASON(TS_R_TSA_NAME_MISMATCH) ,"tsa name mismatch"}, | ||
157 | {ERR_REASON(TS_R_TSA_UNTRUSTED) ,"tsa untrusted"}, | ||
158 | {ERR_REASON(TS_R_TST_INFO_SETUP_ERROR) ,"tst info setup error"}, | ||
159 | {ERR_REASON(TS_R_TS_DATASIGN) ,"ts datasign"}, | ||
160 | {ERR_REASON(TS_R_UNACCEPTABLE_POLICY) ,"unacceptable policy"}, | ||
161 | {ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM),"unsupported md algorithm"}, | ||
162 | {ERR_REASON(TS_R_UNSUPPORTED_VERSION) ,"unsupported version"}, | ||
163 | {ERR_REASON(TS_R_WRONG_CONTENT_TYPE) ,"wrong content type"}, | ||
164 | {0,NULL} | ||
165 | }; | ||
166 | |||
167 | #endif | ||
168 | |||
169 | void ERR_load_TS_strings(void) | ||
170 | { | ||
171 | #ifndef OPENSSL_NO_ERR | ||
172 | |||
173 | if (ERR_func_error_string(TS_str_functs[0].error) == NULL) | ||
174 | { | ||
175 | ERR_load_strings(0,TS_str_functs); | ||
176 | ERR_load_strings(0,TS_str_reasons); | ||
177 | } | ||
178 | #endif | ||
179 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_lib.c b/src/lib/libcrypto/ts/ts_lib.c new file mode 100644 index 0000000000..e8608dbf71 --- /dev/null +++ b/src/lib/libcrypto/ts/ts_lib.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* crypto/ts/ts_lib.c */ | ||
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | ||
3 | * project 2002. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/objects.h> | ||
62 | #include <openssl/bn.h> | ||
63 | #include <openssl/x509v3.h> | ||
64 | #include "ts.h" | ||
65 | |||
66 | /* Local function declarations. */ | ||
67 | |||
68 | /* Function definitions. */ | ||
69 | |||
70 | int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num) | ||
71 | { | ||
72 | BIGNUM num_bn; | ||
73 | int result = 0; | ||
74 | char *hex; | ||
75 | |||
76 | BN_init(&num_bn); | ||
77 | ASN1_INTEGER_to_BN(num, &num_bn); | ||
78 | if ((hex = BN_bn2hex(&num_bn))) | ||
79 | { | ||
80 | result = BIO_write(bio, "0x", 2) > 0; | ||
81 | result = result && BIO_write(bio, hex, strlen(hex)) > 0; | ||
82 | OPENSSL_free(hex); | ||
83 | } | ||
84 | BN_free(&num_bn); | ||
85 | |||
86 | return result; | ||
87 | } | ||
88 | |||
89 | int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj) | ||
90 | { | ||
91 | char obj_txt[128]; | ||
92 | |||
93 | int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); | ||
94 | BIO_write(bio, obj_txt, len); | ||
95 | BIO_write(bio, "\n", 1); | ||
96 | |||
97 | return 1; | ||
98 | } | ||
99 | |||
100 | int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions) | ||
101 | { | ||
102 | int i, critical, n; | ||
103 | X509_EXTENSION *ex; | ||
104 | ASN1_OBJECT *obj; | ||
105 | |||
106 | BIO_printf(bio, "Extensions:\n"); | ||
107 | n = X509v3_get_ext_count(extensions); | ||
108 | for (i = 0; i < n; i++) | ||
109 | { | ||
110 | ex = X509v3_get_ext(extensions, i); | ||
111 | obj = X509_EXTENSION_get_object(ex); | ||
112 | i2a_ASN1_OBJECT(bio, obj); | ||
113 | critical = X509_EXTENSION_get_critical(ex); | ||
114 | BIO_printf(bio, ": %s\n", critical ? "critical" : ""); | ||
115 | if (!X509V3_EXT_print(bio, ex, 0, 4)) | ||
116 | { | ||
117 | BIO_printf(bio, "%4s", ""); | ||
118 | M_ASN1_OCTET_STRING_print(bio, ex->value); | ||
119 | } | ||
120 | BIO_write(bio, "\n", 1); | ||
121 | } | ||
122 | |||
123 | return 1; | ||
124 | } | ||
125 | |||
126 | int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg) | ||
127 | { | ||
128 | int i = OBJ_obj2nid(alg->algorithm); | ||
129 | return BIO_printf(bio, "Hash Algorithm: %s\n", | ||
130 | (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); | ||
131 | } | ||
132 | |||
133 | int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a) | ||
134 | { | ||
135 | const ASN1_OCTET_STRING *msg; | ||
136 | |||
137 | TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a)); | ||
138 | |||
139 | BIO_printf(bio, "Message data:\n"); | ||
140 | msg = TS_MSG_IMPRINT_get_msg(a); | ||
141 | BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg), | ||
142 | M_ASN1_STRING_length(msg), 4); | ||
143 | |||
144 | return 1; | ||
145 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_req_print.c b/src/lib/libcrypto/ts/ts_req_print.c new file mode 100644 index 0000000000..eba12c3824 --- /dev/null +++ b/src/lib/libcrypto/ts/ts_req_print.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* crypto/ts/ts_req_print.c */ | ||
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | ||
3 | * project 2002. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/objects.h> | ||
62 | #include <openssl/bn.h> | ||
63 | #include <openssl/x509v3.h> | ||
64 | #include <openssl/ts.h> | ||
65 | |||
66 | /* Function definitions. */ | ||
67 | |||
68 | int TS_REQ_print_bio(BIO *bio, TS_REQ *a) | ||
69 | { | ||
70 | int v; | ||
71 | ASN1_OBJECT *policy_id; | ||
72 | const ASN1_INTEGER *nonce; | ||
73 | |||
74 | if (a == NULL) return 0; | ||
75 | |||
76 | v = TS_REQ_get_version(a); | ||
77 | BIO_printf(bio, "Version: %d\n", v); | ||
78 | |||
79 | TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a)); | ||
80 | |||
81 | BIO_printf(bio, "Policy OID: "); | ||
82 | policy_id = TS_REQ_get_policy_id(a); | ||
83 | if (policy_id == NULL) | ||
84 | BIO_printf(bio, "unspecified\n"); | ||
85 | else | ||
86 | TS_OBJ_print_bio(bio, policy_id); | ||
87 | |||
88 | BIO_printf(bio, "Nonce: "); | ||
89 | nonce = TS_REQ_get_nonce(a); | ||
90 | if (nonce == NULL) | ||
91 | BIO_printf(bio, "unspecified"); | ||
92 | else | ||
93 | TS_ASN1_INTEGER_print_bio(bio, nonce); | ||
94 | BIO_write(bio, "\n", 1); | ||
95 | |||
96 | BIO_printf(bio, "Certificate required: %s\n", | ||
97 | TS_REQ_get_cert_req(a) ? "yes" : "no"); | ||
98 | |||
99 | TS_ext_print_bio(bio, TS_REQ_get_exts(a)); | ||
100 | |||
101 | return 1; | ||
102 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_req_utils.c b/src/lib/libcrypto/ts/ts_req_utils.c new file mode 100644 index 0000000000..43280c1587 --- /dev/null +++ b/src/lib/libcrypto/ts/ts_req_utils.c | |||
@@ -0,0 +1,234 @@ | |||
1 | /* crypto/ts/ts_req_utils.c */ | ||
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | ||
3 | * project 2002. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/objects.h> | ||
62 | #include <openssl/x509v3.h> | ||
63 | #include <openssl/ts.h> | ||
64 | |||
65 | int TS_REQ_set_version(TS_REQ *a, long version) | ||
66 | { | ||
67 | return ASN1_INTEGER_set(a->version, version); | ||
68 | } | ||
69 | |||
70 | long TS_REQ_get_version(const TS_REQ *a) | ||
71 | { | ||
72 | return ASN1_INTEGER_get(a->version); | ||
73 | } | ||
74 | |||
75 | int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint) | ||
76 | { | ||
77 | TS_MSG_IMPRINT *new_msg_imprint; | ||
78 | |||
79 | if (a->msg_imprint == msg_imprint) | ||
80 | return 1; | ||
81 | new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); | ||
82 | if (new_msg_imprint == NULL) | ||
83 | { | ||
84 | TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); | ||
85 | return 0; | ||
86 | } | ||
87 | TS_MSG_IMPRINT_free(a->msg_imprint); | ||
88 | a->msg_imprint = new_msg_imprint; | ||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a) | ||
93 | { | ||
94 | return a->msg_imprint; | ||
95 | } | ||
96 | |||
97 | int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg) | ||
98 | { | ||
99 | X509_ALGOR *new_alg; | ||
100 | |||
101 | if (a->hash_algo == alg) | ||
102 | return 1; | ||
103 | new_alg = X509_ALGOR_dup(alg); | ||
104 | if (new_alg == NULL) | ||
105 | { | ||
106 | TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE); | ||
107 | return 0; | ||
108 | } | ||
109 | X509_ALGOR_free(a->hash_algo); | ||
110 | a->hash_algo = new_alg; | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a) | ||
115 | { | ||
116 | return a->hash_algo; | ||
117 | } | ||
118 | |||
119 | int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len) | ||
120 | { | ||
121 | return ASN1_OCTET_STRING_set(a->hashed_msg, d, len); | ||
122 | } | ||
123 | |||
124 | ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a) | ||
125 | { | ||
126 | return a->hashed_msg; | ||
127 | } | ||
128 | |||
129 | int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy) | ||
130 | { | ||
131 | ASN1_OBJECT *new_policy; | ||
132 | |||
133 | if (a->policy_id == policy) | ||
134 | return 1; | ||
135 | new_policy = OBJ_dup(policy); | ||
136 | if (new_policy == NULL) | ||
137 | { | ||
138 | TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); | ||
139 | return 0; | ||
140 | } | ||
141 | ASN1_OBJECT_free(a->policy_id); | ||
142 | a->policy_id = new_policy; | ||
143 | return 1; | ||
144 | } | ||
145 | |||
146 | ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a) | ||
147 | { | ||
148 | return a->policy_id; | ||
149 | } | ||
150 | |||
151 | int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce) | ||
152 | { | ||
153 | ASN1_INTEGER *new_nonce; | ||
154 | |||
155 | if (a->nonce == nonce) | ||
156 | return 1; | ||
157 | new_nonce = ASN1_INTEGER_dup(nonce); | ||
158 | if (new_nonce == NULL) | ||
159 | { | ||
160 | TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE); | ||
161 | return 0; | ||
162 | } | ||
163 | ASN1_INTEGER_free(a->nonce); | ||
164 | a->nonce = new_nonce; | ||
165 | return 1; | ||
166 | } | ||
167 | |||
168 | const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a) | ||
169 | { | ||
170 | return a->nonce; | ||
171 | } | ||
172 | |||
173 | int TS_REQ_set_cert_req(TS_REQ *a, int cert_req) | ||
174 | { | ||
175 | a->cert_req = cert_req ? 0xFF : 0x00; | ||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | int TS_REQ_get_cert_req(const TS_REQ *a) | ||
180 | { | ||
181 | return a->cert_req ? 1 : 0; | ||
182 | } | ||
183 | |||
184 | STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a) | ||
185 | { | ||
186 | return a->extensions; | ||
187 | } | ||
188 | |||
189 | void TS_REQ_ext_free(TS_REQ *a) | ||
190 | { | ||
191 | if (!a) return; | ||
192 | sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); | ||
193 | a->extensions = NULL; | ||
194 | } | ||
195 | |||
196 | int TS_REQ_get_ext_count(TS_REQ *a) | ||
197 | { | ||
198 | return X509v3_get_ext_count(a->extensions); | ||
199 | } | ||
200 | |||
201 | int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos) | ||
202 | { | ||
203 | return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); | ||
204 | } | ||
205 | |||
206 | int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos) | ||
207 | { | ||
208 | return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); | ||
209 | } | ||
210 | |||
211 | int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos) | ||
212 | { | ||
213 | return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); | ||
214 | } | ||
215 | |||
216 | X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc) | ||
217 | { | ||
218 | return X509v3_get_ext(a->extensions,loc); | ||
219 | } | ||
220 | |||
221 | X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc) | ||
222 | { | ||
223 | return X509v3_delete_ext(a->extensions,loc); | ||
224 | } | ||
225 | |||
226 | int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc) | ||
227 | { | ||
228 | return X509v3_add_ext(&a->extensions,ex,loc) != NULL; | ||
229 | } | ||
230 | |||
231 | void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx) | ||
232 | { | ||
233 | return X509V3_get_d2i(a->extensions, nid, crit, idx); | ||
234 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_rsp_print.c b/src/lib/libcrypto/ts/ts_rsp_print.c new file mode 100644 index 0000000000..21062517ba --- /dev/null +++ b/src/lib/libcrypto/ts/ts_rsp_print.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* crypto/ts/ts_resp_print.c */ | ||
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | ||
3 | * project 2002. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/objects.h> | ||
62 | #include <openssl/bn.h> | ||
63 | #include <openssl/x509v3.h> | ||
64 | #include "ts.h" | ||
65 | |||
66 | struct status_map_st | ||
67 | { | ||
68 | int bit; | ||
69 | const char *text; | ||
70 | }; | ||
71 | |||
72 | /* Local function declarations. */ | ||
73 | |||
74 | static int TS_status_map_print(BIO *bio, struct status_map_st *a, | ||
75 | ASN1_BIT_STRING *v); | ||
76 | static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy); | ||
77 | |||
78 | /* Function definitions. */ | ||
79 | |||
80 | int TS_RESP_print_bio(BIO *bio, TS_RESP *a) | ||
81 | { | ||
82 | TS_TST_INFO *tst_info; | ||
83 | |||
84 | BIO_printf(bio, "Status info:\n"); | ||
85 | TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a)); | ||
86 | |||
87 | BIO_printf(bio, "\nTST info:\n"); | ||
88 | tst_info = TS_RESP_get_tst_info(a); | ||
89 | if (tst_info != NULL) | ||
90 | TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a)); | ||
91 | else | ||
92 | BIO_printf(bio, "Not included.\n"); | ||
93 | |||
94 | return 1; | ||
95 | } | ||
96 | |||
97 | int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a) | ||
98 | { | ||
99 | static const char *status_map[] = | ||
100 | { | ||
101 | "Granted.", | ||
102 | "Granted with modifications.", | ||
103 | "Rejected.", | ||
104 | "Waiting.", | ||
105 | "Revocation warning.", | ||
106 | "Revoked." | ||
107 | }; | ||
108 | static struct status_map_st failure_map[] = | ||
109 | { | ||
110 | { TS_INFO_BAD_ALG, | ||
111 | "unrecognized or unsupported algorithm identifier" }, | ||
112 | { TS_INFO_BAD_REQUEST, | ||
113 | "transaction not permitted or supported" }, | ||
114 | { TS_INFO_BAD_DATA_FORMAT, | ||
115 | "the data submitted has the wrong format" }, | ||
116 | { TS_INFO_TIME_NOT_AVAILABLE, | ||
117 | "the TSA's time source is not available" }, | ||
118 | { TS_INFO_UNACCEPTED_POLICY, | ||
119 | "the requested TSA policy is not supported by the TSA" }, | ||
120 | { TS_INFO_UNACCEPTED_EXTENSION, | ||
121 | "the requested extension is not supported by the TSA" }, | ||
122 | { TS_INFO_ADD_INFO_NOT_AVAILABLE, | ||
123 | "the additional information requested could not be understood " | ||
124 | "or is not available" }, | ||
125 | { TS_INFO_SYSTEM_FAILURE, | ||
126 | "the request cannot be handled due to system failure" }, | ||
127 | { -1, NULL } | ||
128 | }; | ||
129 | long status; | ||
130 | int i, lines = 0; | ||
131 | |||
132 | /* Printing status code. */ | ||
133 | BIO_printf(bio, "Status: "); | ||
134 | status = ASN1_INTEGER_get(a->status); | ||
135 | if (0 <= status && status < (long)(sizeof(status_map)/sizeof(status_map[0]))) | ||
136 | BIO_printf(bio, "%s\n", status_map[status]); | ||
137 | else | ||
138 | BIO_printf(bio, "out of bounds\n"); | ||
139 | |||
140 | /* Printing status description. */ | ||
141 | BIO_printf(bio, "Status description: "); | ||
142 | for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i) | ||
143 | { | ||
144 | if (i > 0) | ||
145 | BIO_puts(bio, "\t"); | ||
146 | ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i), | ||
147 | 0); | ||
148 | BIO_puts(bio, "\n"); | ||
149 | } | ||
150 | if (i == 0) | ||
151 | BIO_printf(bio, "unspecified\n"); | ||
152 | |||
153 | /* Printing failure information. */ | ||
154 | BIO_printf(bio, "Failure info: "); | ||
155 | if (a->failure_info != NULL) | ||
156 | lines = TS_status_map_print(bio, failure_map, | ||
157 | a->failure_info); | ||
158 | if (lines == 0) | ||
159 | BIO_printf(bio, "unspecified"); | ||
160 | BIO_printf(bio, "\n"); | ||
161 | |||
162 | return 1; | ||
163 | } | ||
164 | |||
165 | static int TS_status_map_print(BIO *bio, struct status_map_st *a, | ||
166 | ASN1_BIT_STRING *v) | ||
167 | { | ||
168 | int lines = 0; | ||
169 | |||
170 | for (; a->bit >= 0; ++a) | ||
171 | { | ||
172 | if (ASN1_BIT_STRING_get_bit(v, a->bit)) | ||
173 | { | ||
174 | if (++lines > 1) | ||
175 | BIO_printf(bio, ", "); | ||
176 | BIO_printf(bio, "%s", a->text); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | return lines; | ||
181 | } | ||
182 | |||
183 | int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a) | ||
184 | { | ||
185 | int v; | ||
186 | ASN1_OBJECT *policy_id; | ||
187 | const ASN1_INTEGER *serial; | ||
188 | const ASN1_GENERALIZEDTIME *gtime; | ||
189 | TS_ACCURACY *accuracy; | ||
190 | const ASN1_INTEGER *nonce; | ||
191 | GENERAL_NAME *tsa_name; | ||
192 | |||
193 | if (a == NULL) return 0; | ||
194 | |||
195 | /* Print version. */ | ||
196 | v = TS_TST_INFO_get_version(a); | ||
197 | BIO_printf(bio, "Version: %d\n", v); | ||
198 | |||
199 | /* Print policy id. */ | ||
200 | BIO_printf(bio, "Policy OID: "); | ||
201 | policy_id = TS_TST_INFO_get_policy_id(a); | ||
202 | TS_OBJ_print_bio(bio, policy_id); | ||
203 | |||
204 | /* Print message imprint. */ | ||
205 | TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a)); | ||
206 | |||
207 | /* Print serial number. */ | ||
208 | BIO_printf(bio, "Serial number: "); | ||
209 | serial = TS_TST_INFO_get_serial(a); | ||
210 | if (serial == NULL) | ||
211 | BIO_printf(bio, "unspecified"); | ||
212 | else | ||
213 | TS_ASN1_INTEGER_print_bio(bio, serial); | ||
214 | BIO_write(bio, "\n", 1); | ||
215 | |||
216 | /* Print time stamp. */ | ||
217 | BIO_printf(bio, "Time stamp: "); | ||
218 | gtime = TS_TST_INFO_get_time(a); | ||
219 | ASN1_GENERALIZEDTIME_print(bio, gtime); | ||
220 | BIO_write(bio, "\n", 1); | ||
221 | |||
222 | /* Print accuracy. */ | ||
223 | BIO_printf(bio, "Accuracy: "); | ||
224 | accuracy = TS_TST_INFO_get_accuracy(a); | ||
225 | if (accuracy == NULL) | ||
226 | BIO_printf(bio, "unspecified"); | ||
227 | else | ||
228 | TS_ACCURACY_print_bio(bio, accuracy); | ||
229 | BIO_write(bio, "\n", 1); | ||
230 | |||
231 | /* Print ordering. */ | ||
232 | BIO_printf(bio, "Ordering: %s\n", | ||
233 | TS_TST_INFO_get_ordering(a) ? "yes" : "no"); | ||
234 | |||
235 | /* Print nonce. */ | ||
236 | BIO_printf(bio, "Nonce: "); | ||
237 | nonce = TS_TST_INFO_get_nonce(a); | ||
238 | if (nonce == NULL) | ||
239 | BIO_printf(bio, "unspecified"); | ||
240 | else | ||
241 | TS_ASN1_INTEGER_print_bio(bio, nonce); | ||
242 | BIO_write(bio, "\n", 1); | ||
243 | |||
244 | /* Print TSA name. */ | ||
245 | BIO_printf(bio, "TSA: "); | ||
246 | tsa_name = TS_TST_INFO_get_tsa(a); | ||
247 | if (tsa_name == NULL) | ||
248 | BIO_printf(bio, "unspecified"); | ||
249 | else | ||
250 | { | ||
251 | STACK_OF(CONF_VALUE) *nval; | ||
252 | if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL))) | ||
253 | X509V3_EXT_val_prn(bio, nval, 0, 0); | ||
254 | sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); | ||
255 | } | ||
256 | BIO_write(bio, "\n", 1); | ||
257 | |||
258 | /* Print extensions. */ | ||
259 | TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a)); | ||
260 | |||
261 | return 1; | ||
262 | } | ||
263 | |||
264 | static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy) | ||
265 | { | ||
266 | const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy); | ||
267 | const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy); | ||
268 | const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy); | ||
269 | |||
270 | if (seconds != NULL) | ||
271 | TS_ASN1_INTEGER_print_bio(bio, seconds); | ||
272 | else | ||
273 | BIO_printf(bio, "unspecified"); | ||
274 | BIO_printf(bio, " seconds, "); | ||
275 | if (millis != NULL) | ||
276 | TS_ASN1_INTEGER_print_bio(bio, millis); | ||
277 | else | ||
278 | BIO_printf(bio, "unspecified"); | ||
279 | BIO_printf(bio, " millis, "); | ||
280 | if (micros != NULL) | ||
281 | TS_ASN1_INTEGER_print_bio(bio, micros); | ||
282 | else | ||
283 | BIO_printf(bio, "unspecified"); | ||
284 | BIO_printf(bio, " micros"); | ||
285 | |||
286 | return 1; | ||
287 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_rsp_sign.c b/src/lib/libcrypto/ts/ts_rsp_sign.c new file mode 100644 index 0000000000..b0f023c9d2 --- /dev/null +++ b/src/lib/libcrypto/ts/ts_rsp_sign.c | |||
@@ -0,0 +1,1020 @@ | |||
1 | /* crypto/ts/ts_resp_sign.c */ | ||
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | ||
3 | * project 2002. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "cryptlib.h" | ||
60 | |||
61 | #if defined(OPENSSL_SYS_UNIX) | ||
62 | #include <sys/time.h> | ||
63 | #endif | ||
64 | |||
65 | #include <openssl/objects.h> | ||
66 | #include <openssl/ts.h> | ||
67 | #include <openssl/pkcs7.h> | ||
68 | |||
69 | /* Private function declarations. */ | ||
70 | |||
71 | static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *); | ||
72 | static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec); | ||
73 | static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *); | ||
74 | |||
75 | static void TS_RESP_CTX_init(TS_RESP_CTX *ctx); | ||
76 | static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx); | ||
77 | static int TS_RESP_check_request(TS_RESP_CTX *ctx); | ||
78 | static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx); | ||
79 | static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, | ||
80 | ASN1_OBJECT *policy); | ||
81 | static int TS_RESP_process_extensions(TS_RESP_CTX *ctx); | ||
82 | static int TS_RESP_sign(TS_RESP_CTX *ctx); | ||
83 | |||
84 | static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, | ||
85 | STACK_OF(X509) *certs); | ||
86 | static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed); | ||
87 | static int TS_TST_INFO_content_new(PKCS7 *p7); | ||
88 | static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); | ||
89 | |||
90 | static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision( | ||
91 | ASN1_GENERALIZEDTIME *, long, long, unsigned); | ||
92 | |||
93 | /* Default callbacks for response generation. */ | ||
94 | |||
95 | static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) | ||
96 | { | ||
97 | ASN1_INTEGER *serial = ASN1_INTEGER_new(); | ||
98 | if (!serial) goto err; | ||
99 | if (!ASN1_INTEGER_set(serial, 1)) goto err; | ||
100 | return serial; | ||
101 | err: | ||
102 | TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE); | ||
103 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
104 | "Error during serial number generation."); | ||
105 | return NULL; | ||
106 | } | ||
107 | |||
108 | #if defined(OPENSSL_SYS_UNIX) | ||
109 | |||
110 | /* Use the gettimeofday function call. */ | ||
111 | static int def_time_cb(struct TS_resp_ctx *ctx, void *data, | ||
112 | long *sec, long *usec) | ||
113 | { | ||
114 | struct timeval tv; | ||
115 | if (gettimeofday(&tv, NULL) != 0) | ||
116 | { | ||
117 | TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); | ||
118 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
119 | "Time is not available."); | ||
120 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); | ||
121 | return 0; | ||
122 | } | ||
123 | /* Return time to caller. */ | ||
124 | *sec = tv.tv_sec; | ||
125 | *usec = tv.tv_usec; | ||
126 | |||
127 | return 1; | ||
128 | } | ||
129 | |||
130 | #else | ||
131 | |||
132 | /* Use the time function call that provides only seconds precision. */ | ||
133 | static int def_time_cb(struct TS_resp_ctx *ctx, void *data, | ||
134 | long *sec, long *usec) | ||
135 | { | ||
136 | time_t t; | ||
137 | if (time(&t) == (time_t) -1) | ||
138 | { | ||
139 | TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); | ||
140 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
141 | "Time is not available."); | ||
142 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); | ||
143 | return 0; | ||
144 | } | ||
145 | /* Return time to caller, only second precision. */ | ||
146 | *sec = (long) t; | ||
147 | *usec = 0; | ||
148 | |||
149 | return 1; | ||
150 | } | ||
151 | |||
152 | #endif | ||
153 | |||
154 | static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, | ||
155 | void *data) | ||
156 | { | ||
157 | /* No extensions are processed here. */ | ||
158 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
159 | "Unsupported extension."); | ||
160 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | /* TS_RESP_CTX management functions. */ | ||
165 | |||
166 | TS_RESP_CTX *TS_RESP_CTX_new() | ||
167 | { | ||
168 | TS_RESP_CTX *ctx; | ||
169 | |||
170 | if (!(ctx = (TS_RESP_CTX *) OPENSSL_malloc(sizeof(TS_RESP_CTX)))) | ||
171 | { | ||
172 | TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE); | ||
173 | return NULL; | ||
174 | } | ||
175 | memset(ctx, 0, sizeof(TS_RESP_CTX)); | ||
176 | |||
177 | /* Setting default callbacks. */ | ||
178 | ctx->serial_cb = def_serial_cb; | ||
179 | ctx->time_cb = def_time_cb; | ||
180 | ctx->extension_cb = def_extension_cb; | ||
181 | |||
182 | return ctx; | ||
183 | } | ||
184 | |||
185 | void TS_RESP_CTX_free(TS_RESP_CTX *ctx) | ||
186 | { | ||
187 | if (!ctx) return; | ||
188 | |||
189 | X509_free(ctx->signer_cert); | ||
190 | EVP_PKEY_free(ctx->signer_key); | ||
191 | sk_X509_pop_free(ctx->certs, X509_free); | ||
192 | sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free); | ||
193 | ASN1_OBJECT_free(ctx->default_policy); | ||
194 | sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */ | ||
195 | ASN1_INTEGER_free(ctx->seconds); | ||
196 | ASN1_INTEGER_free(ctx->millis); | ||
197 | ASN1_INTEGER_free(ctx->micros); | ||
198 | OPENSSL_free(ctx); | ||
199 | } | ||
200 | |||
201 | int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) | ||
202 | { | ||
203 | if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) | ||
204 | { | ||
205 | TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, | ||
206 | TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); | ||
207 | return 0; | ||
208 | } | ||
209 | if (ctx->signer_cert) X509_free(ctx->signer_cert); | ||
210 | ctx->signer_cert = signer; | ||
211 | CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509); | ||
212 | return 1; | ||
213 | } | ||
214 | |||
215 | int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key) | ||
216 | { | ||
217 | if (ctx->signer_key) EVP_PKEY_free(ctx->signer_key); | ||
218 | ctx->signer_key = key; | ||
219 | CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY); | ||
220 | |||
221 | return 1; | ||
222 | } | ||
223 | |||
224 | int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy) | ||
225 | { | ||
226 | if (ctx->default_policy) ASN1_OBJECT_free(ctx->default_policy); | ||
227 | if (!(ctx->default_policy = OBJ_dup(def_policy))) goto err; | ||
228 | return 1; | ||
229 | err: | ||
230 | TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) | ||
235 | { | ||
236 | int i; | ||
237 | |||
238 | if (ctx->certs) | ||
239 | { | ||
240 | sk_X509_pop_free(ctx->certs, X509_free); | ||
241 | ctx->certs = NULL; | ||
242 | } | ||
243 | if (!certs) return 1; | ||
244 | if (!(ctx->certs = sk_X509_dup(certs))) | ||
245 | { | ||
246 | TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE); | ||
247 | return 0; | ||
248 | } | ||
249 | for (i = 0; i < sk_X509_num(ctx->certs); ++i) | ||
250 | { | ||
251 | X509 *cert = sk_X509_value(ctx->certs, i); | ||
252 | CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509); | ||
253 | } | ||
254 | |||
255 | return 1; | ||
256 | } | ||
257 | |||
258 | int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy) | ||
259 | { | ||
260 | ASN1_OBJECT *copy = NULL; | ||
261 | |||
262 | /* Create new policy stack if necessary. */ | ||
263 | if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) | ||
264 | goto err; | ||
265 | if (!(copy = OBJ_dup(policy))) goto err; | ||
266 | if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) goto err; | ||
267 | |||
268 | return 1; | ||
269 | err: | ||
270 | TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE); | ||
271 | ASN1_OBJECT_free(copy); | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md) | ||
276 | { | ||
277 | /* Create new md stack if necessary. */ | ||
278 | if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) | ||
279 | goto err; | ||
280 | /* Add the shared md, no copy needed. */ | ||
281 | if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) goto err; | ||
282 | |||
283 | return 1; | ||
284 | err: | ||
285 | TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE); | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | #define TS_RESP_CTX_accuracy_free(ctx) \ | ||
290 | ASN1_INTEGER_free(ctx->seconds); \ | ||
291 | ctx->seconds = NULL; \ | ||
292 | ASN1_INTEGER_free(ctx->millis); \ | ||
293 | ctx->millis = NULL; \ | ||
294 | ASN1_INTEGER_free(ctx->micros); \ | ||
295 | ctx->micros = NULL; | ||
296 | |||
297 | int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, | ||
298 | int secs, int millis, int micros) | ||
299 | { | ||
300 | |||
301 | TS_RESP_CTX_accuracy_free(ctx); | ||
302 | if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) | ||
303 | || !ASN1_INTEGER_set(ctx->seconds, secs))) | ||
304 | goto err; | ||
305 | if (millis && (!(ctx->millis = ASN1_INTEGER_new()) | ||
306 | || !ASN1_INTEGER_set(ctx->millis, millis))) | ||
307 | goto err; | ||
308 | if (micros && (!(ctx->micros = ASN1_INTEGER_new()) | ||
309 | || !ASN1_INTEGER_set(ctx->micros, micros))) | ||
310 | goto err; | ||
311 | |||
312 | return 1; | ||
313 | err: | ||
314 | TS_RESP_CTX_accuracy_free(ctx); | ||
315 | TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE); | ||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags) | ||
320 | { | ||
321 | ctx->flags |= flags; | ||
322 | } | ||
323 | |||
324 | void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data) | ||
325 | { | ||
326 | ctx->serial_cb = cb; | ||
327 | ctx->serial_cb_data = data; | ||
328 | } | ||
329 | |||
330 | void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data) | ||
331 | { | ||
332 | ctx->time_cb = cb; | ||
333 | ctx->time_cb_data = data; | ||
334 | } | ||
335 | |||
336 | void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, | ||
337 | TS_extension_cb cb, void *data) | ||
338 | { | ||
339 | ctx->extension_cb = cb; | ||
340 | ctx->extension_cb_data = data; | ||
341 | } | ||
342 | |||
343 | int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, | ||
344 | int status, const char *text) | ||
345 | { | ||
346 | TS_STATUS_INFO *si = NULL; | ||
347 | ASN1_UTF8STRING *utf8_text = NULL; | ||
348 | int ret = 0; | ||
349 | |||
350 | if (!(si = TS_STATUS_INFO_new())) goto err; | ||
351 | if (!ASN1_INTEGER_set(si->status, status)) goto err; | ||
352 | if (text) | ||
353 | { | ||
354 | if (!(utf8_text = ASN1_UTF8STRING_new()) | ||
355 | || !ASN1_STRING_set(utf8_text, text, strlen(text))) | ||
356 | goto err; | ||
357 | if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null())) | ||
358 | goto err; | ||
359 | if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) goto err; | ||
360 | utf8_text = NULL; /* Ownership is lost. */ | ||
361 | } | ||
362 | if (!TS_RESP_set_status_info(ctx->response, si)) goto err; | ||
363 | ret = 1; | ||
364 | err: | ||
365 | if (!ret) | ||
366 | TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); | ||
367 | TS_STATUS_INFO_free(si); | ||
368 | ASN1_UTF8STRING_free(utf8_text); | ||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, | ||
373 | int status, const char *text) | ||
374 | { | ||
375 | int ret = 1; | ||
376 | TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); | ||
377 | |||
378 | if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) | ||
379 | { | ||
380 | /* Status has not been set, set it now. */ | ||
381 | ret = TS_RESP_CTX_set_status_info(ctx, status, text); | ||
382 | } | ||
383 | return ret; | ||
384 | } | ||
385 | |||
386 | int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure) | ||
387 | { | ||
388 | TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); | ||
389 | if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new())) | ||
390 | goto err; | ||
391 | if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1)) | ||
392 | goto err; | ||
393 | return 1; | ||
394 | err: | ||
395 | TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx) | ||
400 | { | ||
401 | return ctx->request; | ||
402 | } | ||
403 | |||
404 | TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx) | ||
405 | { | ||
406 | return ctx->tst_info; | ||
407 | } | ||
408 | |||
409 | int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision) | ||
410 | { | ||
411 | if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) | ||
412 | return 0; | ||
413 | ctx->clock_precision_digits = precision; | ||
414 | return 1; | ||
415 | } | ||
416 | |||
417 | /* Main entry method of the response generation. */ | ||
418 | TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) | ||
419 | { | ||
420 | ASN1_OBJECT *policy; | ||
421 | TS_RESP *response; | ||
422 | int result = 0; | ||
423 | |||
424 | TS_RESP_CTX_init(ctx); | ||
425 | |||
426 | /* Creating the response object. */ | ||
427 | if (!(ctx->response = TS_RESP_new())) | ||
428 | { | ||
429 | TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE); | ||
430 | goto end; | ||
431 | } | ||
432 | |||
433 | /* Parsing DER request. */ | ||
434 | if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) | ||
435 | { | ||
436 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
437 | "Bad request format or " | ||
438 | "system error."); | ||
439 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); | ||
440 | goto end; | ||
441 | } | ||
442 | |||
443 | /* Setting default status info. */ | ||
444 | if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL)) | ||
445 | goto end; | ||
446 | |||
447 | /* Checking the request format. */ | ||
448 | if (!TS_RESP_check_request(ctx)) goto end; | ||
449 | |||
450 | /* Checking acceptable policies. */ | ||
451 | if (!(policy = TS_RESP_get_policy(ctx))) goto end; | ||
452 | |||
453 | /* Creating the TS_TST_INFO object. */ | ||
454 | if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy))) | ||
455 | goto end; | ||
456 | |||
457 | /* Processing extensions. */ | ||
458 | if (!TS_RESP_process_extensions(ctx)) goto end; | ||
459 | |||
460 | /* Generating the signature. */ | ||
461 | if (!TS_RESP_sign(ctx)) goto end; | ||
462 | |||
463 | /* Everything was successful. */ | ||
464 | result = 1; | ||
465 | end: | ||
466 | if (!result) | ||
467 | { | ||
468 | TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR); | ||
469 | if (ctx->response != NULL) | ||
470 | { | ||
471 | if (TS_RESP_CTX_set_status_info_cond(ctx, | ||
472 | TS_STATUS_REJECTION, "Error during response " | ||
473 | "generation.") == 0) | ||
474 | { | ||
475 | TS_RESP_free(ctx->response); | ||
476 | ctx->response = NULL; | ||
477 | } | ||
478 | } | ||
479 | } | ||
480 | response = ctx->response; | ||
481 | ctx->response = NULL; /* Ownership will be returned to caller. */ | ||
482 | TS_RESP_CTX_cleanup(ctx); | ||
483 | return response; | ||
484 | } | ||
485 | |||
486 | /* Initializes the variable part of the context. */ | ||
487 | static void TS_RESP_CTX_init(TS_RESP_CTX *ctx) | ||
488 | { | ||
489 | ctx->request = NULL; | ||
490 | ctx->response = NULL; | ||
491 | ctx->tst_info = NULL; | ||
492 | } | ||
493 | |||
494 | /* Cleans up the variable part of the context. */ | ||
495 | static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx) | ||
496 | { | ||
497 | TS_REQ_free(ctx->request); | ||
498 | ctx->request = NULL; | ||
499 | TS_RESP_free(ctx->response); | ||
500 | ctx->response = NULL; | ||
501 | TS_TST_INFO_free(ctx->tst_info); | ||
502 | ctx->tst_info = NULL; | ||
503 | } | ||
504 | |||
505 | /* Checks the format and content of the request. */ | ||
506 | static int TS_RESP_check_request(TS_RESP_CTX *ctx) | ||
507 | { | ||
508 | TS_REQ *request = ctx->request; | ||
509 | TS_MSG_IMPRINT *msg_imprint; | ||
510 | X509_ALGOR *md_alg; | ||
511 | int md_alg_id; | ||
512 | const ASN1_OCTET_STRING *digest; | ||
513 | EVP_MD *md = NULL; | ||
514 | int i; | ||
515 | |||
516 | /* Checking request version. */ | ||
517 | if (TS_REQ_get_version(request) != 1) | ||
518 | { | ||
519 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
520 | "Bad request version."); | ||
521 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST); | ||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | /* Checking message digest algorithm. */ | ||
526 | msg_imprint = TS_REQ_get_msg_imprint(request); | ||
527 | md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint); | ||
528 | md_alg_id = OBJ_obj2nid(md_alg->algorithm); | ||
529 | for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) | ||
530 | { | ||
531 | EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); | ||
532 | if (md_alg_id == EVP_MD_type(current_md)) | ||
533 | md = current_md; | ||
534 | } | ||
535 | if (!md) | ||
536 | { | ||
537 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
538 | "Message digest algorithm is " | ||
539 | "not supported."); | ||
540 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); | ||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | /* No message digest takes parameter. */ | ||
545 | if (md_alg->parameter | ||
546 | && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) | ||
547 | { | ||
548 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
549 | "Superfluous message digest " | ||
550 | "parameter."); | ||
551 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); | ||
552 | return 0; | ||
553 | } | ||
554 | /* Checking message digest size. */ | ||
555 | digest = TS_MSG_IMPRINT_get_msg(msg_imprint); | ||
556 | if (digest->length != EVP_MD_size(md)) | ||
557 | { | ||
558 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
559 | "Bad message digest."); | ||
560 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); | ||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | return 1; | ||
565 | } | ||
566 | |||
567 | /* Returns the TSA policy based on the requested and acceptable policies. */ | ||
568 | static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx) | ||
569 | { | ||
570 | ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request); | ||
571 | ASN1_OBJECT *policy = NULL; | ||
572 | int i; | ||
573 | |||
574 | if (ctx->default_policy == NULL) | ||
575 | { | ||
576 | TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER); | ||
577 | return NULL; | ||
578 | } | ||
579 | /* Return the default policy if none is requested or the default is | ||
580 | requested. */ | ||
581 | if (!requested || !OBJ_cmp(requested, ctx->default_policy)) | ||
582 | policy = ctx->default_policy; | ||
583 | |||
584 | /* Check if the policy is acceptable. */ | ||
585 | for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) | ||
586 | { | ||
587 | ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i); | ||
588 | if (!OBJ_cmp(requested, current)) | ||
589 | policy = current; | ||
590 | } | ||
591 | if (!policy) | ||
592 | { | ||
593 | TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY); | ||
594 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | ||
595 | "Requested policy is not " | ||
596 | "supported."); | ||
597 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY); | ||
598 | } | ||
599 | return policy; | ||
600 | } | ||
601 | |||
602 | /* Creates the TS_TST_INFO object based on the settings of the context. */ | ||
603 | static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, | ||
604 | ASN1_OBJECT *policy) | ||
605 | { | ||
606 | int result = 0; | ||
607 | TS_TST_INFO *tst_info = NULL; | ||
608 | ASN1_INTEGER *serial = NULL; | ||
609 | ASN1_GENERALIZEDTIME *asn1_time = NULL; | ||
610 | long sec, usec; | ||
611 | TS_ACCURACY *accuracy = NULL; | ||
612 | const ASN1_INTEGER *nonce; | ||
613 | GENERAL_NAME *tsa_name = NULL; | ||
614 | |||
615 | if (!(tst_info = TS_TST_INFO_new())) goto end; | ||
616 | if (!TS_TST_INFO_set_version(tst_info, 1)) goto end; | ||
617 | if (!TS_TST_INFO_set_policy_id(tst_info, policy)) goto end; | ||
618 | if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint)) | ||
619 | goto end; | ||
620 | if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data)) | ||
621 | || !TS_TST_INFO_set_serial(tst_info, serial)) | ||
622 | goto end; | ||
623 | if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec) | ||
624 | || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, | ||
625 | sec, usec, | ||
626 | ctx->clock_precision_digits)) | ||
627 | || !TS_TST_INFO_set_time(tst_info, asn1_time)) | ||
628 | goto end; | ||
629 | |||
630 | /* Setting accuracy if needed. */ | ||
631 | if ((ctx->seconds || ctx->millis || ctx->micros) | ||
632 | && !(accuracy = TS_ACCURACY_new())) | ||
633 | goto end; | ||
634 | |||
635 | if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds)) | ||
636 | goto end; | ||
637 | if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis)) | ||
638 | goto end; | ||
639 | if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros)) | ||
640 | goto end; | ||
641 | if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) | ||
642 | goto end; | ||
643 | |||
644 | /* Setting ordering. */ | ||
645 | if ((ctx->flags & TS_ORDERING) | ||
646 | && !TS_TST_INFO_set_ordering(tst_info, 1)) | ||
647 | goto end; | ||
648 | |||
649 | /* Setting nonce if needed. */ | ||
650 | if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL | ||
651 | && !TS_TST_INFO_set_nonce(tst_info, nonce)) | ||
652 | goto end; | ||
653 | |||
654 | /* Setting TSA name to subject of signer certificate. */ | ||
655 | if (ctx->flags & TS_TSA_NAME) | ||
656 | { | ||
657 | if (!(tsa_name = GENERAL_NAME_new())) goto end; | ||
658 | tsa_name->type = GEN_DIRNAME; | ||
659 | tsa_name->d.dirn = | ||
660 | X509_NAME_dup(ctx->signer_cert->cert_info->subject); | ||
661 | if (!tsa_name->d.dirn) goto end; | ||
662 | if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) goto end; | ||
663 | } | ||
664 | |||
665 | result = 1; | ||
666 | end: | ||
667 | if (!result) | ||
668 | { | ||
669 | TS_TST_INFO_free(tst_info); | ||
670 | tst_info = NULL; | ||
671 | TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR); | ||
672 | TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, | ||
673 | "Error during TSTInfo " | ||
674 | "generation."); | ||
675 | } | ||
676 | GENERAL_NAME_free(tsa_name); | ||
677 | TS_ACCURACY_free(accuracy); | ||
678 | ASN1_GENERALIZEDTIME_free(asn1_time); | ||
679 | ASN1_INTEGER_free(serial); | ||
680 | |||
681 | return tst_info; | ||
682 | } | ||
683 | |||
684 | /* Processing the extensions of the request. */ | ||
685 | static int TS_RESP_process_extensions(TS_RESP_CTX *ctx) | ||
686 | { | ||
687 | STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request); | ||
688 | int i; | ||
689 | int ok = 1; | ||
690 | |||
691 | for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) | ||
692 | { | ||
693 | X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); | ||
694 | /* XXXXX The last argument was previously | ||
695 | (void *)ctx->extension_cb, but ISO C doesn't permit | ||
696 | converting a function pointer to void *. For lack of | ||
697 | better information, I'm placing a NULL there instead. | ||
698 | The callback can pick its own address out from the ctx | ||
699 | anyway... | ||
700 | */ | ||
701 | ok = (*ctx->extension_cb)(ctx, ext, NULL); | ||
702 | } | ||
703 | |||
704 | return ok; | ||
705 | } | ||
706 | |||
707 | /* Functions for signing the TS_TST_INFO structure of the context. */ | ||
708 | static int TS_RESP_sign(TS_RESP_CTX *ctx) | ||
709 | { | ||
710 | int ret = 0; | ||
711 | PKCS7 *p7 = NULL; | ||
712 | PKCS7_SIGNER_INFO *si; | ||
713 | STACK_OF(X509) *certs; /* Certificates to include in sc. */ | ||
714 | ESS_SIGNING_CERT *sc = NULL; | ||
715 | ASN1_OBJECT *oid; | ||
716 | BIO *p7bio = NULL; | ||
717 | int i; | ||
718 | |||
719 | /* Check if signcert and pkey match. */ | ||
720 | if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) { | ||
721 | TSerr(TS_F_TS_RESP_SIGN, | ||
722 | TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | ||
723 | goto err; | ||
724 | } | ||
725 | |||
726 | /* Create a new PKCS7 signed object. */ | ||
727 | if (!(p7 = PKCS7_new())) { | ||
728 | TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); | ||
729 | goto err; | ||
730 | } | ||
731 | if (!PKCS7_set_type(p7, NID_pkcs7_signed)) goto err; | ||
732 | |||
733 | /* Force SignedData version to be 3 instead of the default 1. */ | ||
734 | if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) goto err; | ||
735 | |||
736 | /* Add signer certificate and optional certificate chain. */ | ||
737 | if (TS_REQ_get_cert_req(ctx->request)) | ||
738 | { | ||
739 | PKCS7_add_certificate(p7, ctx->signer_cert); | ||
740 | if (ctx->certs) | ||
741 | { | ||
742 | for(i = 0; i < sk_X509_num(ctx->certs); ++i) | ||
743 | { | ||
744 | X509 *cert = sk_X509_value(ctx->certs, i); | ||
745 | PKCS7_add_certificate(p7, cert); | ||
746 | } | ||
747 | } | ||
748 | } | ||
749 | |||
750 | /* Add a new signer info. */ | ||
751 | if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, | ||
752 | ctx->signer_key, EVP_sha1()))) | ||
753 | { | ||
754 | TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR); | ||
755 | goto err; | ||
756 | } | ||
757 | |||
758 | /* Add content type signed attribute to the signer info. */ | ||
759 | oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); | ||
760 | if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, | ||
761 | V_ASN1_OBJECT, oid)) | ||
762 | { | ||
763 | TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR); | ||
764 | goto err; | ||
765 | } | ||
766 | |||
767 | /* Create the ESS SigningCertificate attribute which contains | ||
768 | the signer certificate id and optionally the certificate chain. */ | ||
769 | certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL; | ||
770 | if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs))) | ||
771 | goto err; | ||
772 | |||
773 | /* Add SigningCertificate signed attribute to the signer info. */ | ||
774 | if (!ESS_add_signing_cert(si, sc)) | ||
775 | { | ||
776 | TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR); | ||
777 | goto err; | ||
778 | } | ||
779 | |||
780 | /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */ | ||
781 | if (!TS_TST_INFO_content_new(p7)) goto err; | ||
782 | |||
783 | /* Add the DER encoded tst_info to the PKCS7 structure. */ | ||
784 | if (!(p7bio = PKCS7_dataInit(p7, NULL))) { | ||
785 | TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); | ||
786 | goto err; | ||
787 | } | ||
788 | |||
789 | /* Convert tst_info to DER. */ | ||
790 | if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) | ||
791 | { | ||
792 | TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); | ||
793 | goto err; | ||
794 | } | ||
795 | |||
796 | /* Create the signature and add it to the signer info. */ | ||
797 | if (!PKCS7_dataFinal(p7, p7bio)) | ||
798 | { | ||
799 | TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); | ||
800 | goto err; | ||
801 | } | ||
802 | |||
803 | /* Set new PKCS7 and TST_INFO objects. */ | ||
804 | TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info); | ||
805 | p7 = NULL; /* Ownership is lost. */ | ||
806 | ctx->tst_info = NULL; /* Ownership is lost. */ | ||
807 | |||
808 | ret = 1; | ||
809 | err: | ||
810 | if (!ret) | ||
811 | TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, | ||
812 | "Error during signature " | ||
813 | "generation."); | ||
814 | BIO_free_all(p7bio); | ||
815 | ESS_SIGNING_CERT_free(sc); | ||
816 | PKCS7_free(p7); | ||
817 | return ret; | ||
818 | } | ||
819 | |||
820 | static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, | ||
821 | STACK_OF(X509) *certs) | ||
822 | { | ||
823 | ESS_CERT_ID *cid; | ||
824 | ESS_SIGNING_CERT *sc = NULL; | ||
825 | int i; | ||
826 | |||
827 | /* Creating the ESS_CERT_ID stack. */ | ||
828 | if (!(sc = ESS_SIGNING_CERT_new())) goto err; | ||
829 | if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null())) | ||
830 | goto err; | ||
831 | |||
832 | /* Adding the signing certificate id. */ | ||
833 | if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) | ||
834 | || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) | ||
835 | goto err; | ||
836 | /* Adding the certificate chain ids. */ | ||
837 | for (i = 0; i < sk_X509_num(certs); ++i) | ||
838 | { | ||
839 | X509 *cert = sk_X509_value(certs, i); | ||
840 | if (!(cid = ESS_CERT_ID_new_init(cert, 1)) | ||
841 | || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) | ||
842 | goto err; | ||
843 | } | ||
844 | |||
845 | return sc; | ||
846 | err: | ||
847 | ESS_SIGNING_CERT_free(sc); | ||
848 | TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE); | ||
849 | return NULL; | ||
850 | } | ||
851 | |||
852 | static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) | ||
853 | { | ||
854 | ESS_CERT_ID *cid = NULL; | ||
855 | GENERAL_NAME *name = NULL; | ||
856 | |||
857 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ | ||
858 | X509_check_purpose(cert, -1, 0); | ||
859 | |||
860 | if (!(cid = ESS_CERT_ID_new())) goto err; | ||
861 | if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash, | ||
862 | sizeof(cert->sha1_hash))) | ||
863 | goto err; | ||
864 | |||
865 | /* Setting the issuer/serial if requested. */ | ||
866 | if (issuer_needed) | ||
867 | { | ||
868 | /* Creating issuer/serial structure. */ | ||
869 | if (!cid->issuer_serial | ||
870 | && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new())) | ||
871 | goto err; | ||
872 | /* Creating general name from the certificate issuer. */ | ||
873 | if (!(name = GENERAL_NAME_new())) goto err; | ||
874 | name->type = GEN_DIRNAME; | ||
875 | if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) | ||
876 | goto err; | ||
877 | if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) | ||
878 | goto err; | ||
879 | name = NULL; /* Ownership is lost. */ | ||
880 | /* Setting the serial number. */ | ||
881 | ASN1_INTEGER_free(cid->issuer_serial->serial); | ||
882 | if (!(cid->issuer_serial->serial = | ||
883 | ASN1_INTEGER_dup(cert->cert_info->serialNumber))) | ||
884 | goto err; | ||
885 | } | ||
886 | |||
887 | return cid; | ||
888 | err: | ||
889 | GENERAL_NAME_free(name); | ||
890 | ESS_CERT_ID_free(cid); | ||
891 | TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE); | ||
892 | return NULL; | ||
893 | } | ||
894 | |||
895 | static int TS_TST_INFO_content_new(PKCS7 *p7) | ||
896 | { | ||
897 | PKCS7 *ret = NULL; | ||
898 | ASN1_OCTET_STRING *octet_string = NULL; | ||
899 | |||
900 | /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */ | ||
901 | if (!(ret = PKCS7_new())) goto err; | ||
902 | if (!(ret->d.other = ASN1_TYPE_new())) goto err; | ||
903 | ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); | ||
904 | if (!(octet_string = ASN1_OCTET_STRING_new())) goto err; | ||
905 | ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string); | ||
906 | octet_string = NULL; | ||
907 | |||
908 | /* Add encapsulated content to signed PKCS7 structure. */ | ||
909 | if (!PKCS7_set_content(p7, ret)) goto err; | ||
910 | |||
911 | return 1; | ||
912 | err: | ||
913 | ASN1_OCTET_STRING_free(octet_string); | ||
914 | PKCS7_free(ret); | ||
915 | return 0; | ||
916 | } | ||
917 | |||
918 | static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc) | ||
919 | { | ||
920 | ASN1_STRING *seq = NULL; | ||
921 | unsigned char *p, *pp = NULL; | ||
922 | int len; | ||
923 | |||
924 | len = i2d_ESS_SIGNING_CERT(sc, NULL); | ||
925 | if (!(pp = (unsigned char *) OPENSSL_malloc(len))) | ||
926 | { | ||
927 | TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); | ||
928 | goto err; | ||
929 | } | ||
930 | p = pp; | ||
931 | i2d_ESS_SIGNING_CERT(sc, &p); | ||
932 | if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) | ||
933 | { | ||
934 | TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); | ||
935 | goto err; | ||
936 | } | ||
937 | OPENSSL_free(pp); pp = NULL; | ||
938 | return PKCS7_add_signed_attribute(si, | ||
939 | NID_id_smime_aa_signingCertificate, | ||
940 | V_ASN1_SEQUENCE, seq); | ||
941 | err: | ||
942 | ASN1_STRING_free(seq); | ||
943 | OPENSSL_free(pp); | ||
944 | |||
945 | return 0; | ||
946 | } | ||
947 | |||
948 | |||
949 | static ASN1_GENERALIZEDTIME * | ||
950 | TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, | ||
951 | long sec, long usec, unsigned precision) | ||
952 | { | ||
953 | time_t time_sec = (time_t) sec; | ||
954 | struct tm *tm = NULL; | ||
955 | char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS]; | ||
956 | char *p = genTime_str; | ||
957 | char *p_end = genTime_str + sizeof(genTime_str); | ||
958 | |||
959 | if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) | ||
960 | goto err; | ||
961 | |||
962 | |||
963 | if (!(tm = gmtime(&time_sec))) | ||
964 | goto err; | ||
965 | |||
966 | /* | ||
967 | * Put "genTime_str" in GeneralizedTime format. We work around the | ||
968 | * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST | ||
969 | * NOT include fractional seconds") and OpenSSL related functions to | ||
970 | * meet the rfc3161 requirement: "GeneralizedTime syntax can include | ||
971 | * fraction-of-second details". | ||
972 | */ | ||
973 | p += BIO_snprintf(p, p_end - p, | ||
974 | "%04d%02d%02d%02d%02d%02d", | ||
975 | tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, | ||
976 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
977 | if (precision > 0) | ||
978 | { | ||
979 | /* Add fraction of seconds (leave space for dot and null). */ | ||
980 | BIO_snprintf(p, 2 + precision, ".%ld", usec); | ||
981 | /* We cannot use the snprintf return value, | ||
982 | because it might have been truncated. */ | ||
983 | p += strlen(p); | ||
984 | |||
985 | /* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides | ||
986 | the following restrictions for a DER-encoding, which OpenSSL | ||
987 | (specifically ASN1_GENERALIZEDTIME_check() function) doesn't | ||
988 | support: | ||
989 | "The encoding MUST terminate with a "Z" (which means "Zulu" | ||
990 | time). The decimal point element, if present, MUST be the | ||
991 | point option ".". The fractional-seconds elements, | ||
992 | if present, MUST omit all trailing 0's; | ||
993 | if the elements correspond to 0, they MUST be wholly | ||
994 | omitted, and the decimal point element also MUST be | ||
995 | omitted." */ | ||
996 | /* Remove trailing zeros. The dot guarantees the exit | ||
997 | condition of this loop even if all the digits are zero. */ | ||
998 | while (*--p == '0') | ||
999 | /* empty */; | ||
1000 | /* p points to either the dot or the last non-zero digit. */ | ||
1001 | if (*p != '.') ++p; | ||
1002 | } | ||
1003 | /* Add the trailing Z and the terminating null. */ | ||
1004 | *p++ = 'Z'; | ||
1005 | *p++ = '\0'; | ||
1006 | |||
1007 | /* Now call OpenSSL to check and set our genTime value */ | ||
1008 | if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new())) | ||
1009 | goto err; | ||
1010 | if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) | ||
1011 | { | ||
1012 | ASN1_GENERALIZEDTIME_free(asn1_time); | ||
1013 | goto err; | ||
1014 | } | ||
1015 | |||
1016 | return asn1_time; | ||
1017 | err: | ||
1018 | TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME); | ||
1019 | return NULL; | ||
1020 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_rsp_utils.c b/src/lib/libcrypto/ts/ts_rsp_utils.c new file mode 100644 index 0000000000..401c1fdc51 --- /dev/null +++ b/src/lib/libcrypto/ts/ts_rsp_utils.c | |||
@@ -0,0 +1,409 @@ | |||
1 | /* crypto/ts/ts_resp_utils.c */ | ||
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | ||
3 | * project 2002. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/objects.h> | ||
62 | #include <openssl/ts.h> | ||
63 | #include <openssl/pkcs7.h> | ||
64 | |||
65 | /* Function definitions. */ | ||
66 | |||
67 | int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info) | ||
68 | { | ||
69 | TS_STATUS_INFO *new_status_info; | ||
70 | |||
71 | if (a->status_info == status_info) | ||
72 | return 1; | ||
73 | new_status_info = TS_STATUS_INFO_dup(status_info); | ||
74 | if (new_status_info == NULL) | ||
75 | { | ||
76 | TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); | ||
77 | return 0; | ||
78 | } | ||
79 | TS_STATUS_INFO_free(a->status_info); | ||
80 | a->status_info = new_status_info; | ||
81 | |||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a) | ||
86 | { | ||
87 | return a->status_info; | ||
88 | } | ||
89 | |||
90 | /* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ | ||
91 | void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info) | ||
92 | { | ||
93 | /* Set new PKCS7 and TST_INFO objects. */ | ||
94 | PKCS7_free(a->token); | ||
95 | a->token = p7; | ||
96 | TS_TST_INFO_free(a->tst_info); | ||
97 | a->tst_info = tst_info; | ||
98 | } | ||
99 | |||
100 | PKCS7 *TS_RESP_get_token(TS_RESP *a) | ||
101 | { | ||
102 | return a->token; | ||
103 | } | ||
104 | |||
105 | TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a) | ||
106 | { | ||
107 | return a->tst_info; | ||
108 | } | ||
109 | |||
110 | int TS_TST_INFO_set_version(TS_TST_INFO *a, long version) | ||
111 | { | ||
112 | return ASN1_INTEGER_set(a->version, version); | ||
113 | } | ||
114 | |||
115 | long TS_TST_INFO_get_version(const TS_TST_INFO *a) | ||
116 | { | ||
117 | return ASN1_INTEGER_get(a->version); | ||
118 | } | ||
119 | |||
120 | int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy) | ||
121 | { | ||
122 | ASN1_OBJECT *new_policy; | ||
123 | |||
124 | if (a->policy_id == policy) | ||
125 | return 1; | ||
126 | new_policy = OBJ_dup(policy); | ||
127 | if (new_policy == NULL) | ||
128 | { | ||
129 | TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); | ||
130 | return 0; | ||
131 | } | ||
132 | ASN1_OBJECT_free(a->policy_id); | ||
133 | a->policy_id = new_policy; | ||
134 | return 1; | ||
135 | } | ||
136 | |||
137 | ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a) | ||
138 | { | ||
139 | return a->policy_id; | ||
140 | } | ||
141 | |||
142 | int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint) | ||
143 | { | ||
144 | TS_MSG_IMPRINT *new_msg_imprint; | ||
145 | |||
146 | if (a->msg_imprint == msg_imprint) | ||
147 | return 1; | ||
148 | new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); | ||
149 | if (new_msg_imprint == NULL) | ||
150 | { | ||
151 | TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); | ||
152 | return 0; | ||
153 | } | ||
154 | TS_MSG_IMPRINT_free(a->msg_imprint); | ||
155 | a->msg_imprint = new_msg_imprint; | ||
156 | return 1; | ||
157 | } | ||
158 | |||
159 | TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a) | ||
160 | { | ||
161 | return a->msg_imprint; | ||
162 | } | ||
163 | |||
164 | int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial) | ||
165 | { | ||
166 | ASN1_INTEGER *new_serial; | ||
167 | |||
168 | if (a->serial == serial) | ||
169 | return 1; | ||
170 | new_serial = ASN1_INTEGER_dup(serial); | ||
171 | if (new_serial == NULL) | ||
172 | { | ||
173 | TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE); | ||
174 | return 0; | ||
175 | } | ||
176 | ASN1_INTEGER_free(a->serial); | ||
177 | a->serial = new_serial; | ||
178 | return 1; | ||
179 | } | ||
180 | |||
181 | const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a) | ||
182 | { | ||
183 | return a->serial; | ||
184 | } | ||
185 | |||
186 | int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime) | ||
187 | { | ||
188 | ASN1_GENERALIZEDTIME *new_time; | ||
189 | |||
190 | if (a->time == gtime) | ||
191 | return 1; | ||
192 | new_time = M_ASN1_GENERALIZEDTIME_dup(gtime); | ||
193 | if (new_time == NULL) | ||
194 | { | ||
195 | TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE); | ||
196 | return 0; | ||
197 | } | ||
198 | ASN1_GENERALIZEDTIME_free(a->time); | ||
199 | a->time = new_time; | ||
200 | return 1; | ||
201 | } | ||
202 | |||
203 | const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a) | ||
204 | { | ||
205 | return a->time; | ||
206 | } | ||
207 | |||
208 | int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy) | ||
209 | { | ||
210 | TS_ACCURACY *new_accuracy; | ||
211 | |||
212 | if (a->accuracy == accuracy) | ||
213 | return 1; | ||
214 | new_accuracy = TS_ACCURACY_dup(accuracy); | ||
215 | if (new_accuracy == NULL) | ||
216 | { | ||
217 | TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE); | ||
218 | return 0; | ||
219 | } | ||
220 | TS_ACCURACY_free(a->accuracy); | ||
221 | a->accuracy = new_accuracy; | ||
222 | return 1; | ||
223 | } | ||
224 | |||
225 | TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a) | ||
226 | { | ||
227 | return a->accuracy; | ||
228 | } | ||
229 | |||
230 | int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds) | ||
231 | { | ||
232 | ASN1_INTEGER *new_seconds; | ||
233 | |||
234 | if (a->seconds == seconds) | ||
235 | return 1; | ||
236 | new_seconds = ASN1_INTEGER_dup(seconds); | ||
237 | if (new_seconds == NULL) | ||
238 | { | ||
239 | TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE); | ||
240 | return 0; | ||
241 | } | ||
242 | ASN1_INTEGER_free(a->seconds); | ||
243 | a->seconds = new_seconds; | ||
244 | return 1; | ||
245 | } | ||
246 | |||
247 | const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a) | ||
248 | { | ||
249 | return a->seconds; | ||
250 | } | ||
251 | |||
252 | int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis) | ||
253 | { | ||
254 | ASN1_INTEGER *new_millis = NULL; | ||
255 | |||
256 | if (a->millis == millis) | ||
257 | return 1; | ||
258 | if (millis != NULL) | ||
259 | { | ||
260 | new_millis = ASN1_INTEGER_dup(millis); | ||
261 | if (new_millis == NULL) | ||
262 | { | ||
263 | TSerr(TS_F_TS_ACCURACY_SET_MILLIS, | ||
264 | ERR_R_MALLOC_FAILURE); | ||
265 | return 0; | ||
266 | } | ||
267 | } | ||
268 | ASN1_INTEGER_free(a->millis); | ||
269 | a->millis = new_millis; | ||
270 | return 1; | ||
271 | } | ||
272 | |||
273 | const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a) | ||
274 | { | ||
275 | return a->millis; | ||
276 | } | ||
277 | |||
278 | int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros) | ||
279 | { | ||
280 | ASN1_INTEGER *new_micros = NULL; | ||
281 | |||
282 | if (a->micros == micros) | ||
283 | return 1; | ||
284 | if (micros != NULL) | ||
285 | { | ||
286 | new_micros = ASN1_INTEGER_dup(micros); | ||
287 | if (new_micros == NULL) | ||
288 | { | ||
289 | TSerr(TS_F_TS_ACCURACY_SET_MICROS, | ||
290 | ERR_R_MALLOC_FAILURE); | ||
291 | return 0; | ||
292 | } | ||
293 | } | ||
294 | ASN1_INTEGER_free(a->micros); | ||
295 | a->micros = new_micros; | ||
296 | return 1; | ||
297 | } | ||
298 | |||
299 | const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a) | ||
300 | { | ||
301 | return a->micros; | ||
302 | } | ||
303 | |||
304 | int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering) | ||
305 | { | ||
306 | a->ordering = ordering ? 0xFF : 0x00; | ||
307 | return 1; | ||
308 | } | ||
309 | |||
310 | int TS_TST_INFO_get_ordering(const TS_TST_INFO *a) | ||
311 | { | ||
312 | return a->ordering ? 1 : 0; | ||
313 | } | ||
314 | |||
315 | int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce) | ||
316 | { | ||
317 | ASN1_INTEGER *new_nonce; | ||
318 | |||
319 | if (a->nonce == nonce) | ||
320 | return 1; | ||
321 | new_nonce = ASN1_INTEGER_dup(nonce); | ||
322 | if (new_nonce == NULL) | ||
323 | { | ||
324 | TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE); | ||
325 | return 0; | ||
326 | } | ||
327 | ASN1_INTEGER_free(a->nonce); | ||
328 | a->nonce = new_nonce; | ||
329 | return 1; | ||
330 | } | ||
331 | |||
332 | const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a) | ||
333 | { | ||
334 | return a->nonce; | ||
335 | } | ||
336 | |||
337 | int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa) | ||
338 | { | ||
339 | GENERAL_NAME *new_tsa; | ||
340 | |||
341 | if (a->tsa == tsa) | ||
342 | return 1; | ||
343 | new_tsa = GENERAL_NAME_dup(tsa); | ||
344 | if (new_tsa == NULL) | ||
345 | { | ||
346 | TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE); | ||
347 | return 0; | ||
348 | } | ||
349 | GENERAL_NAME_free(a->tsa); | ||
350 | a->tsa = new_tsa; | ||
351 | return 1; | ||
352 | } | ||
353 | |||
354 | GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a) | ||
355 | { | ||
356 | return a->tsa; | ||
357 | } | ||
358 | |||
359 | STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a) | ||
360 | { | ||
361 | return a->extensions; | ||
362 | } | ||
363 | |||
364 | void TS_TST_INFO_ext_free(TS_TST_INFO *a) | ||
365 | { | ||
366 | if (!a) return; | ||
367 | sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); | ||
368 | a->extensions = NULL; | ||
369 | } | ||
370 | |||
371 | int TS_TST_INFO_get_ext_count(TS_TST_INFO *a) | ||
372 | { | ||
373 | return X509v3_get_ext_count(a->extensions); | ||
374 | } | ||
375 | |||
376 | int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos) | ||
377 | { | ||
378 | return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); | ||
379 | } | ||
380 | |||
381 | int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos) | ||
382 | { | ||
383 | return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); | ||
384 | } | ||
385 | |||
386 | int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos) | ||
387 | { | ||
388 | return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); | ||
389 | } | ||
390 | |||
391 | X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc) | ||
392 | { | ||
393 | return X509v3_get_ext(a->extensions,loc); | ||
394 | } | ||
395 | |||
396 | X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc) | ||
397 | { | ||
398 | return X509v3_delete_ext(a->extensions,loc); | ||
399 | } | ||
400 | |||
401 | int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc) | ||
402 | { | ||
403 | return X509v3_add_ext(&a->extensions,ex,loc) != NULL; | ||
404 | } | ||
405 | |||
406 | void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx) | ||
407 | { | ||
408 | return X509V3_get_d2i(a->extensions, nid, crit, idx); | ||
409 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_rsp_verify.c b/src/lib/libcrypto/ts/ts_rsp_verify.c new file mode 100644 index 0000000000..e1f3b534af --- /dev/null +++ b/src/lib/libcrypto/ts/ts_rsp_verify.c | |||
@@ -0,0 +1,725 @@ | |||
1 | /* crypto/ts/ts_resp_verify.c */ | ||
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | ||
3 | * project 2002. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/objects.h> | ||
62 | #include <openssl/ts.h> | ||
63 | #include <openssl/pkcs7.h> | ||
64 | |||
65 | /* Private function declarations. */ | ||
66 | |||
67 | static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, | ||
68 | X509 *signer, STACK_OF(X509) **chain); | ||
69 | static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); | ||
70 | static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); | ||
71 | static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); | ||
72 | static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo); | ||
73 | static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, | ||
74 | PKCS7 *token, TS_TST_INFO *tst_info); | ||
75 | static int TS_check_status_info(TS_RESP *response); | ||
76 | static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text); | ||
77 | static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info); | ||
78 | static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, | ||
79 | X509_ALGOR **md_alg, | ||
80 | unsigned char **imprint, unsigned *imprint_len); | ||
81 | static int TS_check_imprints(X509_ALGOR *algor_a, | ||
82 | unsigned char *imprint_a, unsigned len_a, | ||
83 | TS_TST_INFO *tst_info); | ||
84 | static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); | ||
85 | static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); | ||
86 | static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name); | ||
87 | |||
88 | /* | ||
89 | * Local mapping between response codes and descriptions. | ||
90 | * Don't forget to change TS_STATUS_BUF_SIZE when modifying | ||
91 | * the elements of this array. | ||
92 | */ | ||
93 | static const char *TS_status_text[] = | ||
94 | { "granted", | ||
95 | "grantedWithMods", | ||
96 | "rejection", | ||
97 | "waiting", | ||
98 | "revocationWarning", | ||
99 | "revocationNotification" }; | ||
100 | |||
101 | #define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text)) | ||
102 | |||
103 | /* | ||
104 | * This must be greater or equal to the sum of the strings in TS_status_text | ||
105 | * plus the number of its elements. | ||
106 | */ | ||
107 | #define TS_STATUS_BUF_SIZE 256 | ||
108 | |||
109 | static struct | ||
110 | { | ||
111 | int code; | ||
112 | const char *text; | ||
113 | } TS_failure_info[] = | ||
114 | { { TS_INFO_BAD_ALG, "badAlg" }, | ||
115 | { TS_INFO_BAD_REQUEST, "badRequest" }, | ||
116 | { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" }, | ||
117 | { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" }, | ||
118 | { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" }, | ||
119 | { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" }, | ||
120 | { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" }, | ||
121 | { TS_INFO_SYSTEM_FAILURE, "systemFailure" } }; | ||
122 | |||
123 | #define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \ | ||
124 | sizeof(*TS_failure_info)) | ||
125 | |||
126 | /* Functions for verifying a signed TS_TST_INFO structure. */ | ||
127 | |||
128 | /* | ||
129 | * This function carries out the following tasks: | ||
130 | * - Checks if there is one and only one signer. | ||
131 | * - Search for the signing certificate in 'certs' and in the response. | ||
132 | * - Check the extended key usage and key usage fields of the signer | ||
133 | * certificate (done by the path validation). | ||
134 | * - Build and validate the certificate path. | ||
135 | * - Check if the certificate path meets the requirements of the | ||
136 | * SigningCertificate ESS signed attribute. | ||
137 | * - Verify the signature value. | ||
138 | * - Returns the signer certificate in 'signer', if 'signer' is not NULL. | ||
139 | */ | ||
140 | int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, | ||
141 | X509_STORE *store, X509 **signer_out) | ||
142 | { | ||
143 | STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; | ||
144 | PKCS7_SIGNER_INFO *si; | ||
145 | STACK_OF(X509) *signers = NULL; | ||
146 | X509 *signer; | ||
147 | STACK_OF(X509) *chain = NULL; | ||
148 | char buf[4096]; | ||
149 | int i, j = 0, ret = 0; | ||
150 | BIO *p7bio = NULL; | ||
151 | |||
152 | /* Some sanity checks first. */ | ||
153 | if (!token) | ||
154 | { | ||
155 | TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER); | ||
156 | goto err; | ||
157 | } | ||
158 | |||
159 | /* Check for the correct content type */ | ||
160 | if(!PKCS7_type_is_signed(token)) | ||
161 | { | ||
162 | TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE); | ||
163 | goto err; | ||
164 | } | ||
165 | |||
166 | /* Check if there is one and only one signer. */ | ||
167 | sinfos = PKCS7_get_signer_info(token); | ||
168 | if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) | ||
169 | { | ||
170 | TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, | ||
171 | TS_R_THERE_MUST_BE_ONE_SIGNER); | ||
172 | goto err; | ||
173 | } | ||
174 | si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); | ||
175 | |||
176 | /* Check for no content: no data to verify signature. */ | ||
177 | if (PKCS7_get_detached(token)) | ||
178 | { | ||
179 | TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT); | ||
180 | goto err; | ||
181 | } | ||
182 | |||
183 | /* Get hold of the signer certificate, search only internal | ||
184 | certificates if it was requested. */ | ||
185 | signers = PKCS7_get0_signers(token, certs, 0); | ||
186 | if (!signers || sk_X509_num(signers) != 1) goto err; | ||
187 | signer = sk_X509_value(signers, 0); | ||
188 | |||
189 | /* Now verify the certificate. */ | ||
190 | if (!TS_verify_cert(store, certs, signer, &chain)) goto err; | ||
191 | |||
192 | /* Check if the signer certificate is consistent with the | ||
193 | ESS extension. */ | ||
194 | if (!TS_check_signing_certs(si, chain)) goto err; | ||
195 | |||
196 | /* Creating the message digest. */ | ||
197 | p7bio = PKCS7_dataInit(token, NULL); | ||
198 | |||
199 | /* We now have to 'read' from p7bio to calculate digests etc. */ | ||
200 | while ((i = BIO_read(p7bio,buf,sizeof(buf))) > 0); | ||
201 | |||
202 | /* Verifying the signature. */ | ||
203 | j = PKCS7_signatureVerify(p7bio, token, si, signer); | ||
204 | if (j <= 0) | ||
205 | { | ||
206 | TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE); | ||
207 | goto err; | ||
208 | } | ||
209 | |||
210 | /* Return the signer certificate if needed. */ | ||
211 | if (signer_out) | ||
212 | { | ||
213 | *signer_out = signer; | ||
214 | CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); | ||
215 | } | ||
216 | |||
217 | ret = 1; | ||
218 | |||
219 | err: | ||
220 | BIO_free_all(p7bio); | ||
221 | sk_X509_pop_free(chain, X509_free); | ||
222 | sk_X509_free(signers); | ||
223 | |||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | /* | ||
228 | * The certificate chain is returned in chain. Caller is responsible for | ||
229 | * freeing the vector. | ||
230 | */ | ||
231 | static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, | ||
232 | X509 *signer, STACK_OF(X509) **chain) | ||
233 | { | ||
234 | X509_STORE_CTX cert_ctx; | ||
235 | int i; | ||
236 | int ret = 1; | ||
237 | |||
238 | /* chain is an out argument. */ | ||
239 | *chain = NULL; | ||
240 | X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted); | ||
241 | X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); | ||
242 | i = X509_verify_cert(&cert_ctx); | ||
243 | if (i <= 0) | ||
244 | { | ||
245 | int j = X509_STORE_CTX_get_error(&cert_ctx); | ||
246 | TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR); | ||
247 | ERR_add_error_data(2, "Verify error:", | ||
248 | X509_verify_cert_error_string(j)); | ||
249 | ret = 0; | ||
250 | } | ||
251 | else | ||
252 | { | ||
253 | /* Get a copy of the certificate chain. */ | ||
254 | *chain = X509_STORE_CTX_get1_chain(&cert_ctx); | ||
255 | } | ||
256 | |||
257 | X509_STORE_CTX_cleanup(&cert_ctx); | ||
258 | |||
259 | return ret; | ||
260 | } | ||
261 | |||
262 | static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain) | ||
263 | { | ||
264 | ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si); | ||
265 | STACK_OF(ESS_CERT_ID) *cert_ids = NULL; | ||
266 | X509 *cert; | ||
267 | int i = 0; | ||
268 | int ret = 0; | ||
269 | |||
270 | if (!ss) goto err; | ||
271 | cert_ids = ss->cert_ids; | ||
272 | /* The signer certificate must be the first in cert_ids. */ | ||
273 | cert = sk_X509_value(chain, 0); | ||
274 | if (TS_find_cert(cert_ids, cert) != 0) goto err; | ||
275 | |||
276 | /* Check the other certificates of the chain if there are more | ||
277 | than one certificate ids in cert_ids. */ | ||
278 | if (sk_ESS_CERT_ID_num(cert_ids) > 1) | ||
279 | { | ||
280 | /* All the certificates of the chain must be in cert_ids. */ | ||
281 | for (i = 1; i < sk_X509_num(chain); ++i) | ||
282 | { | ||
283 | cert = sk_X509_value(chain, i); | ||
284 | if (TS_find_cert(cert_ids, cert) < 0) goto err; | ||
285 | } | ||
286 | } | ||
287 | ret = 1; | ||
288 | err: | ||
289 | if (!ret) | ||
290 | TSerr(TS_F_TS_CHECK_SIGNING_CERTS, | ||
291 | TS_R_ESS_SIGNING_CERTIFICATE_ERROR); | ||
292 | ESS_SIGNING_CERT_free(ss); | ||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) | ||
297 | { | ||
298 | ASN1_TYPE *attr; | ||
299 | const unsigned char *p; | ||
300 | attr = PKCS7_get_signed_attribute(si, | ||
301 | NID_id_smime_aa_signingCertificate); | ||
302 | if (!attr) return NULL; | ||
303 | p = attr->value.sequence->data; | ||
304 | return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); | ||
305 | } | ||
306 | |||
307 | /* Returns < 0 if certificate is not found, certificate index otherwise. */ | ||
308 | static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) | ||
309 | { | ||
310 | int i; | ||
311 | |||
312 | if (!cert_ids || !cert) return -1; | ||
313 | |||
314 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ | ||
315 | X509_check_purpose(cert, -1, 0); | ||
316 | |||
317 | /* Look for cert in the cert_ids vector. */ | ||
318 | for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) | ||
319 | { | ||
320 | ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); | ||
321 | |||
322 | /* Check the SHA-1 hash first. */ | ||
323 | if (cid->hash->length == sizeof(cert->sha1_hash) | ||
324 | && !memcmp(cid->hash->data, cert->sha1_hash, | ||
325 | sizeof(cert->sha1_hash))) | ||
326 | { | ||
327 | /* Check the issuer/serial as well if specified. */ | ||
328 | ESS_ISSUER_SERIAL *is = cid->issuer_serial; | ||
329 | if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) | ||
330 | return i; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | return -1; | ||
335 | } | ||
336 | |||
337 | static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo) | ||
338 | { | ||
339 | GENERAL_NAME *issuer; | ||
340 | |||
341 | if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) return -1; | ||
342 | |||
343 | /* Check the issuer first. It must be a directory name. */ | ||
344 | issuer = sk_GENERAL_NAME_value(is->issuer, 0); | ||
345 | if (issuer->type != GEN_DIRNAME | ||
346 | || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer)) | ||
347 | return -1; | ||
348 | |||
349 | /* Check the serial number, too. */ | ||
350 | if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber)) | ||
351 | return -1; | ||
352 | |||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | /* | ||
357 | * Verifies whether 'response' contains a valid response with regards | ||
358 | * to the settings of the context: | ||
359 | * - Gives an error message if the TS_TST_INFO is not present. | ||
360 | * - Calls _TS_RESP_verify_token to verify the token content. | ||
361 | */ | ||
362 | int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response) | ||
363 | { | ||
364 | PKCS7 *token = TS_RESP_get_token(response); | ||
365 | TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); | ||
366 | int ret = 0; | ||
367 | |||
368 | /* Check if we have a successful TS_TST_INFO object in place. */ | ||
369 | if (!TS_check_status_info(response)) goto err; | ||
370 | |||
371 | /* Check the contents of the time stamp token. */ | ||
372 | if (!int_TS_RESP_verify_token(ctx, token, tst_info)) | ||
373 | goto err; | ||
374 | |||
375 | ret = 1; | ||
376 | err: | ||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * Tries to extract a TS_TST_INFO structure from the PKCS7 token and | ||
382 | * calls the internal int_TS_RESP_verify_token function for verifying it. | ||
383 | */ | ||
384 | int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token) | ||
385 | { | ||
386 | TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token); | ||
387 | int ret = 0; | ||
388 | if (tst_info) | ||
389 | { | ||
390 | ret = int_TS_RESP_verify_token(ctx, token, tst_info); | ||
391 | TS_TST_INFO_free(tst_info); | ||
392 | } | ||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * Verifies whether the 'token' contains a valid time stamp token | ||
398 | * with regards to the settings of the context. Only those checks are | ||
399 | * carried out that are specified in the context: | ||
400 | * - Verifies the signature of the TS_TST_INFO. | ||
401 | * - Checks the version number of the response. | ||
402 | * - Check if the requested and returned policies math. | ||
403 | * - Check if the message imprints are the same. | ||
404 | * - Check if the nonces are the same. | ||
405 | * - Check if the TSA name matches the signer. | ||
406 | * - Check if the TSA name is the expected TSA. | ||
407 | */ | ||
408 | static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, | ||
409 | PKCS7 *token, TS_TST_INFO *tst_info) | ||
410 | { | ||
411 | X509 *signer = NULL; | ||
412 | GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info); | ||
413 | X509_ALGOR *md_alg = NULL; | ||
414 | unsigned char *imprint = NULL; | ||
415 | unsigned imprint_len = 0; | ||
416 | int ret = 0; | ||
417 | |||
418 | /* Verify the signature. */ | ||
419 | if ((ctx->flags & TS_VFY_SIGNATURE) | ||
420 | && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, | ||
421 | &signer)) | ||
422 | goto err; | ||
423 | |||
424 | /* Check version number of response. */ | ||
425 | if ((ctx->flags & TS_VFY_VERSION) | ||
426 | && TS_TST_INFO_get_version(tst_info) != 1) | ||
427 | { | ||
428 | TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION); | ||
429 | goto err; | ||
430 | } | ||
431 | |||
432 | /* Check policies. */ | ||
433 | if ((ctx->flags & TS_VFY_POLICY) | ||
434 | && !TS_check_policy(ctx->policy, tst_info)) | ||
435 | goto err; | ||
436 | |||
437 | /* Check message imprints. */ | ||
438 | if ((ctx->flags & TS_VFY_IMPRINT) | ||
439 | && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len, | ||
440 | tst_info)) | ||
441 | goto err; | ||
442 | |||
443 | /* Compute and check message imprints. */ | ||
444 | if ((ctx->flags & TS_VFY_DATA) | ||
445 | && (!TS_compute_imprint(ctx->data, tst_info, | ||
446 | &md_alg, &imprint, &imprint_len) | ||
447 | || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info))) | ||
448 | goto err; | ||
449 | |||
450 | /* Check nonces. */ | ||
451 | if ((ctx->flags & TS_VFY_NONCE) | ||
452 | && !TS_check_nonces(ctx->nonce, tst_info)) | ||
453 | goto err; | ||
454 | |||
455 | /* Check whether TSA name and signer certificate match. */ | ||
456 | if ((ctx->flags & TS_VFY_SIGNER) | ||
457 | && tsa_name && !TS_check_signer_name(tsa_name, signer)) | ||
458 | { | ||
459 | TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH); | ||
460 | goto err; | ||
461 | } | ||
462 | |||
463 | /* Check whether the TSA is the expected one. */ | ||
464 | if ((ctx->flags & TS_VFY_TSA_NAME) | ||
465 | && !TS_check_signer_name(ctx->tsa_name, signer)) | ||
466 | { | ||
467 | TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED); | ||
468 | goto err; | ||
469 | } | ||
470 | |||
471 | ret = 1; | ||
472 | err: | ||
473 | X509_free(signer); | ||
474 | X509_ALGOR_free(md_alg); | ||
475 | OPENSSL_free(imprint); | ||
476 | return ret; | ||
477 | } | ||
478 | |||
479 | static int TS_check_status_info(TS_RESP *response) | ||
480 | { | ||
481 | TS_STATUS_INFO *info = TS_RESP_get_status_info(response); | ||
482 | long status = ASN1_INTEGER_get(info->status); | ||
483 | const char *status_text = NULL; | ||
484 | char *embedded_status_text = NULL; | ||
485 | char failure_text[TS_STATUS_BUF_SIZE] = ""; | ||
486 | |||
487 | /* Check if everything went fine. */ | ||
488 | if (status == 0 || status == 1) return 1; | ||
489 | |||
490 | /* There was an error, get the description in status_text. */ | ||
491 | if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE) | ||
492 | status_text = TS_status_text[status]; | ||
493 | else | ||
494 | status_text = "unknown code"; | ||
495 | |||
496 | /* Set the embedded_status_text to the returned description. */ | ||
497 | if (sk_ASN1_UTF8STRING_num(info->text) > 0 | ||
498 | && !(embedded_status_text = TS_get_status_text(info->text))) | ||
499 | return 0; | ||
500 | |||
501 | /* Filling in failure_text with the failure information. */ | ||
502 | if (info->failure_info) | ||
503 | { | ||
504 | int i; | ||
505 | int first = 1; | ||
506 | for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) | ||
507 | { | ||
508 | if (ASN1_BIT_STRING_get_bit(info->failure_info, | ||
509 | TS_failure_info[i].code)) | ||
510 | { | ||
511 | if (!first) | ||
512 | strcpy(failure_text, ","); | ||
513 | else | ||
514 | first = 0; | ||
515 | strcat(failure_text, TS_failure_info[i].text); | ||
516 | } | ||
517 | } | ||
518 | } | ||
519 | if (failure_text[0] == '\0') | ||
520 | strcpy(failure_text, "unspecified"); | ||
521 | |||
522 | /* Making up the error string. */ | ||
523 | TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN); | ||
524 | ERR_add_error_data(6, | ||
525 | "status code: ", status_text, | ||
526 | ", status text: ", embedded_status_text ? | ||
527 | embedded_status_text : "unspecified", | ||
528 | ", failure codes: ", failure_text); | ||
529 | OPENSSL_free(embedded_status_text); | ||
530 | |||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) | ||
535 | { | ||
536 | int i; | ||
537 | unsigned int length = 0; | ||
538 | char *result = NULL; | ||
539 | char *p; | ||
540 | |||
541 | /* Determine length first. */ | ||
542 | for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) | ||
543 | { | ||
544 | ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); | ||
545 | length += ASN1_STRING_length(current); | ||
546 | length += 1; /* separator character */ | ||
547 | } | ||
548 | /* Allocate memory (closing '\0' included). */ | ||
549 | if (!(result = OPENSSL_malloc(length))) | ||
550 | { | ||
551 | TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE); | ||
552 | return NULL; | ||
553 | } | ||
554 | /* Concatenate the descriptions. */ | ||
555 | for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) | ||
556 | { | ||
557 | ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); | ||
558 | length = ASN1_STRING_length(current); | ||
559 | if (i > 0) *p++ = '/'; | ||
560 | strncpy(p, (const char *)ASN1_STRING_data(current), length); | ||
561 | p += length; | ||
562 | } | ||
563 | /* We do have space for this, too. */ | ||
564 | *p = '\0'; | ||
565 | |||
566 | return result; | ||
567 | } | ||
568 | |||
569 | static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info) | ||
570 | { | ||
571 | ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info); | ||
572 | |||
573 | if (OBJ_cmp(req_oid, resp_oid) != 0) | ||
574 | { | ||
575 | TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH); | ||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | return 1; | ||
580 | } | ||
581 | |||
582 | static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, | ||
583 | X509_ALGOR **md_alg, | ||
584 | unsigned char **imprint, unsigned *imprint_len) | ||
585 | { | ||
586 | TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info); | ||
587 | X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint); | ||
588 | const EVP_MD *md; | ||
589 | EVP_MD_CTX md_ctx; | ||
590 | unsigned char buffer[4096]; | ||
591 | int length; | ||
592 | |||
593 | *md_alg = NULL; | ||
594 | *imprint = NULL; | ||
595 | |||
596 | /* Return the MD algorithm of the response. */ | ||
597 | if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) goto err; | ||
598 | |||
599 | /* Getting the MD object. */ | ||
600 | if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) | ||
601 | { | ||
602 | TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM); | ||
603 | goto err; | ||
604 | } | ||
605 | |||
606 | /* Compute message digest. */ | ||
607 | length = EVP_MD_size(md); | ||
608 | if (length < 0) | ||
609 | goto err; | ||
610 | *imprint_len = length; | ||
611 | if (!(*imprint = OPENSSL_malloc(*imprint_len))) | ||
612 | { | ||
613 | TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); | ||
614 | goto err; | ||
615 | } | ||
616 | |||
617 | EVP_DigestInit(&md_ctx, md); | ||
618 | while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) | ||
619 | { | ||
620 | EVP_DigestUpdate(&md_ctx, buffer, length); | ||
621 | } | ||
622 | EVP_DigestFinal(&md_ctx, *imprint, NULL); | ||
623 | |||
624 | return 1; | ||
625 | err: | ||
626 | X509_ALGOR_free(*md_alg); | ||
627 | OPENSSL_free(*imprint); | ||
628 | *imprint_len = 0; | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | static int TS_check_imprints(X509_ALGOR *algor_a, | ||
633 | unsigned char *imprint_a, unsigned len_a, | ||
634 | TS_TST_INFO *tst_info) | ||
635 | { | ||
636 | TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info); | ||
637 | X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b); | ||
638 | int ret = 0; | ||
639 | |||
640 | /* algor_a is optional. */ | ||
641 | if (algor_a) | ||
642 | { | ||
643 | /* Compare algorithm OIDs. */ | ||
644 | if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) goto err; | ||
645 | |||
646 | /* The parameter must be NULL in both. */ | ||
647 | if ((algor_a->parameter | ||
648 | && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) | ||
649 | || (algor_b->parameter | ||
650 | && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL)) | ||
651 | goto err; | ||
652 | } | ||
653 | |||
654 | /* Compare octet strings. */ | ||
655 | ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) && | ||
656 | memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0; | ||
657 | err: | ||
658 | if (!ret) | ||
659 | TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH); | ||
660 | return ret; | ||
661 | } | ||
662 | |||
663 | static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) | ||
664 | { | ||
665 | const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info); | ||
666 | |||
667 | /* Error if nonce is missing. */ | ||
668 | if (!b) | ||
669 | { | ||
670 | TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED); | ||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | /* No error if a nonce is returned without being requested. */ | ||
675 | if (ASN1_INTEGER_cmp(a, b) != 0) | ||
676 | { | ||
677 | TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH); | ||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | return 1; | ||
682 | } | ||
683 | |||
684 | /* Check if the specified TSA name matches either the subject | ||
685 | or one of the subject alternative names of the TSA certificate. */ | ||
686 | static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer) | ||
687 | { | ||
688 | STACK_OF(GENERAL_NAME) *gen_names = NULL; | ||
689 | int idx = -1; | ||
690 | int found = 0; | ||
691 | |||
692 | /* Check the subject name first. */ | ||
693 | if (tsa_name->type == GEN_DIRNAME | ||
694 | && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0) | ||
695 | return 1; | ||
696 | |||
697 | /* Check all the alternative names. */ | ||
698 | gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, | ||
699 | NULL, &idx); | ||
700 | while (gen_names != NULL | ||
701 | && !(found = TS_find_name(gen_names, tsa_name) >= 0)) | ||
702 | { | ||
703 | /* Get the next subject alternative name, | ||
704 | although there should be no more than one. */ | ||
705 | GENERAL_NAMES_free(gen_names); | ||
706 | gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, | ||
707 | NULL, &idx); | ||
708 | } | ||
709 | if (gen_names) GENERAL_NAMES_free(gen_names); | ||
710 | |||
711 | return found; | ||
712 | } | ||
713 | |||
714 | /* Returns 1 if name is in gen_names, 0 otherwise. */ | ||
715 | static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name) | ||
716 | { | ||
717 | int i, found; | ||
718 | for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); | ||
719 | ++i) | ||
720 | { | ||
721 | GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i); | ||
722 | found = GENERAL_NAME_cmp(current, name) == 0; | ||
723 | } | ||
724 | return found ? i - 1 : -1; | ||
725 | } | ||
diff --git a/src/lib/libcrypto/ts/ts_verify_ctx.c b/src/lib/libcrypto/ts/ts_verify_ctx.c new file mode 100644 index 0000000000..b079b50fc3 --- /dev/null +++ b/src/lib/libcrypto/ts/ts_verify_ctx.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* crypto/ts/ts_verify_ctx.c */ | ||
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | ||
3 | * project 2003. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <assert.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/objects.h> | ||
62 | #include <openssl/ts.h> | ||
63 | |||
64 | TS_VERIFY_CTX *TS_VERIFY_CTX_new(void) | ||
65 | { | ||
66 | TS_VERIFY_CTX *ctx = | ||
67 | (TS_VERIFY_CTX *) OPENSSL_malloc(sizeof(TS_VERIFY_CTX)); | ||
68 | if (ctx) | ||
69 | memset(ctx, 0, sizeof(TS_VERIFY_CTX)); | ||
70 | else | ||
71 | TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE); | ||
72 | return ctx; | ||
73 | } | ||
74 | |||
75 | void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx) | ||
76 | { | ||
77 | assert(ctx != NULL); | ||
78 | memset(ctx, 0, sizeof(TS_VERIFY_CTX)); | ||
79 | } | ||
80 | |||
81 | void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx) | ||
82 | { | ||
83 | if (!ctx) return; | ||
84 | |||
85 | TS_VERIFY_CTX_cleanup(ctx); | ||
86 | OPENSSL_free(ctx); | ||
87 | } | ||
88 | |||
89 | void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx) | ||
90 | { | ||
91 | if (!ctx) return; | ||
92 | |||
93 | X509_STORE_free(ctx->store); | ||
94 | sk_X509_pop_free(ctx->certs, X509_free); | ||
95 | |||
96 | ASN1_OBJECT_free(ctx->policy); | ||
97 | |||
98 | X509_ALGOR_free(ctx->md_alg); | ||
99 | OPENSSL_free(ctx->imprint); | ||
100 | |||
101 | BIO_free_all(ctx->data); | ||
102 | |||
103 | ASN1_INTEGER_free(ctx->nonce); | ||
104 | |||
105 | GENERAL_NAME_free(ctx->tsa_name); | ||
106 | |||
107 | TS_VERIFY_CTX_init(ctx); | ||
108 | } | ||
109 | |||
110 | TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx) | ||
111 | { | ||
112 | TS_VERIFY_CTX *ret = ctx; | ||
113 | ASN1_OBJECT *policy; | ||
114 | TS_MSG_IMPRINT *imprint; | ||
115 | X509_ALGOR *md_alg; | ||
116 | ASN1_OCTET_STRING *msg; | ||
117 | const ASN1_INTEGER *nonce; | ||
118 | |||
119 | assert(req != NULL); | ||
120 | if (ret) | ||
121 | TS_VERIFY_CTX_cleanup(ret); | ||
122 | else | ||
123 | if (!(ret = TS_VERIFY_CTX_new())) return NULL; | ||
124 | |||
125 | /* Setting flags. */ | ||
126 | ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE); | ||
127 | |||
128 | /* Setting policy. */ | ||
129 | if ((policy = TS_REQ_get_policy_id(req)) != NULL) | ||
130 | { | ||
131 | if (!(ret->policy = OBJ_dup(policy))) goto err; | ||
132 | } | ||
133 | else | ||
134 | ret->flags &= ~TS_VFY_POLICY; | ||
135 | |||
136 | /* Setting md_alg, imprint and imprint_len. */ | ||
137 | imprint = TS_REQ_get_msg_imprint(req); | ||
138 | md_alg = TS_MSG_IMPRINT_get_algo(imprint); | ||
139 | if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) goto err; | ||
140 | msg = TS_MSG_IMPRINT_get_msg(imprint); | ||
141 | ret->imprint_len = ASN1_STRING_length(msg); | ||
142 | if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) goto err; | ||
143 | memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len); | ||
144 | |||
145 | /* Setting nonce. */ | ||
146 | if ((nonce = TS_REQ_get_nonce(req)) != NULL) | ||
147 | { | ||
148 | if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) goto err; | ||
149 | } | ||
150 | else | ||
151 | ret->flags &= ~TS_VFY_NONCE; | ||
152 | |||
153 | return ret; | ||
154 | err: | ||
155 | if (ctx) | ||
156 | TS_VERIFY_CTX_cleanup(ctx); | ||
157 | else | ||
158 | TS_VERIFY_CTX_free(ret); | ||
159 | return NULL; | ||
160 | } | ||
diff --git a/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl b/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl new file mode 100644 index 0000000000..32cf16380b --- /dev/null +++ b/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl | |||
@@ -0,0 +1,493 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. Rights for redistribution and usage in source and binary | ||
6 | # forms are granted according to the OpenSSL license. | ||
7 | # ==================================================================== | ||
8 | # | ||
9 | # whirlpool_block_mmx implementation. | ||
10 | # | ||
11 | *SCALE=\(2); # 2 or 8, that is the question:-) Value of 8 results | ||
12 | # in 16KB large table, which is tough on L1 cache, but eliminates | ||
13 | # unaligned references to it. Value of 2 results in 4KB table, but | ||
14 | # 7/8 of references to it are unaligned. AMD cores seem to be | ||
15 | # allergic to the latter, while Intel ones - to former [see the | ||
16 | # table]. I stick to value of 2 for two reasons: 1. smaller table | ||
17 | # minimizes cache trashing and thus mitigates the hazard of side- | ||
18 | # channel leakage similar to AES cache-timing one; 2. performance | ||
19 | # gap among different µ-archs is smaller. | ||
20 | # | ||
21 | # Performance table lists rounded amounts of CPU cycles spent by | ||
22 | # whirlpool_block_mmx routine on single 64 byte input block, i.e. | ||
23 | # smaller is better and asymptotic throughput can be estimated by | ||
24 | # multiplying 64 by CPU clock frequency and dividing by relevant | ||
25 | # value from the given table: | ||
26 | # | ||
27 | # $SCALE=2/8 icc8 gcc3 | ||
28 | # Intel P4 3200/4600 4600(*) 6400 | ||
29 | # Intel PIII 2900/3000 4900 5400 | ||
30 | # AMD K[78] 2500/1800 9900 8200(**) | ||
31 | # | ||
32 | # (*) I've sketched even non-MMX assembler, but for the record | ||
33 | # I've failed to beat the Intel compiler on P4, without using | ||
34 | # MMX that is... | ||
35 | # (**) ... on AMD on the other hand non-MMX assembler was observed | ||
36 | # to perform significantly better, but I figured this MMX | ||
37 | # implementation is even faster anyway, so why bother? As for | ||
38 | # pre-MMX AMD core[s], the improvement coefficient is more | ||
39 | # than likely to vary anyway and I don't know how. But the | ||
40 | # least I know is that gcc-generated code compiled with | ||
41 | # -DL_ENDIAN and -DOPENSSL_SMALL_FOOTPRINT [see C module for | ||
42 | # details] and optimized for Pentium was observed to perform | ||
43 | # *better* on Pentium 100 than unrolled non-MMX assembler | ||
44 | # loop... So we just say that I don't know if maintaining | ||
45 | # non-MMX implementation would actually pay off, but till | ||
46 | # opposite is proved "unlikely" is assumed. | ||
47 | |||
48 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | ||
49 | push(@INC,"${dir}","${dir}../../perlasm"); | ||
50 | require "x86asm.pl"; | ||
51 | |||
52 | &asm_init($ARGV[0],"wp-mmx.pl"); | ||
53 | |||
54 | sub L() { &data_byte(@_); } | ||
55 | sub LL() | ||
56 | { if ($SCALE==2) { &data_byte(@_); &data_byte(@_); } | ||
57 | elsif ($SCALE==8) { for ($i=0;$i<8;$i++) { | ||
58 | &data_byte(@_); | ||
59 | unshift(@_,pop(@_)); | ||
60 | } | ||
61 | } | ||
62 | else { die "unvalid SCALE value"; } | ||
63 | } | ||
64 | |||
65 | sub scale() | ||
66 | { if ($SCALE==2) { &lea(@_[0],&DWP(0,@_[1],@_[1])); } | ||
67 | elsif ($SCALE==8) { &lea(@_[0],&DWP(0,"",@_[1],8)); } | ||
68 | else { die "unvalid SCALE value"; } | ||
69 | } | ||
70 | |||
71 | sub row() | ||
72 | { if ($SCALE==2) { ((8-shift)&7); } | ||
73 | elsif ($SCALE==8) { (8*shift); } | ||
74 | else { die "unvalid SCALE value"; } | ||
75 | } | ||
76 | |||
77 | $tbl="ebp"; | ||
78 | @mm=("mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7"); | ||
79 | |||
80 | &function_begin_B("whirlpool_block_mmx"); | ||
81 | &push ("ebp"); | ||
82 | &push ("ebx"); | ||
83 | &push ("esi"); | ||
84 | &push ("edi"); | ||
85 | |||
86 | &mov ("esi",&wparam(0)); # hash value | ||
87 | &mov ("edi",&wparam(1)); # input data stream | ||
88 | &mov ("ebp",&wparam(2)); # number of chunks in input | ||
89 | |||
90 | &mov ("eax","esp"); # copy stack pointer | ||
91 | &sub ("esp",128+20); # allocate frame | ||
92 | &and ("esp",-64); # align for cache-line | ||
93 | |||
94 | &lea ("ebx",&DWP(128,"esp")); | ||
95 | &mov (&DWP(0,"ebx"),"esi"); # save parameter block | ||
96 | &mov (&DWP(4,"ebx"),"edi"); | ||
97 | &mov (&DWP(8,"ebx"),"ebp"); | ||
98 | &mov (&DWP(16,"ebx"),"eax"); # saved stack pointer | ||
99 | |||
100 | &call (&label("pic_point")); | ||
101 | &set_label("pic_point"); | ||
102 | &blindpop($tbl); | ||
103 | &lea ($tbl,&DWP(&label("table")."-".&label("pic_point"),$tbl)); | ||
104 | |||
105 | &xor ("ecx","ecx"); | ||
106 | &xor ("edx","edx"); | ||
107 | |||
108 | for($i=0;$i<8;$i++) { &movq(@mm[$i],&QWP($i*8,"esi")); } # L=H | ||
109 | &set_label("outerloop"); | ||
110 | for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); } # K=L | ||
111 | for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); } # L^=inp | ||
112 | for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L | ||
113 | |||
114 | &xor ("esi","esi"); | ||
115 | &mov (&DWP(12,"ebx"),"esi"); # zero round counter | ||
116 | |||
117 | &set_label("round",16); | ||
118 | &movq (@mm[0],&QWP(2048*$SCALE,$tbl,"esi",8)); # rc[r] | ||
119 | &mov ("eax",&DWP(0,"esp")); | ||
120 | &mov ("ebx",&DWP(4,"esp")); | ||
121 | for($i=0;$i<8;$i++) { | ||
122 | my $func = ($i==0)? movq : pxor; | ||
123 | &movb (&LB("ecx"),&LB("eax")); | ||
124 | &movb (&LB("edx"),&HB("eax")); | ||
125 | &scale ("esi","ecx"); | ||
126 | &scale ("edi","edx"); | ||
127 | &shr ("eax",16); | ||
128 | &pxor (@mm[0],&QWP(&row(0),$tbl,"esi",8)); | ||
129 | &$func (@mm[1],&QWP(&row(1),$tbl,"edi",8)); | ||
130 | &movb (&LB("ecx"),&LB("eax")); | ||
131 | &movb (&LB("edx"),&HB("eax")); | ||
132 | &mov ("eax",&DWP(($i+1)*8,"esp")); | ||
133 | &scale ("esi","ecx"); | ||
134 | &scale ("edi","edx"); | ||
135 | &$func (@mm[2],&QWP(&row(2),$tbl,"esi",8)); | ||
136 | &$func (@mm[3],&QWP(&row(3),$tbl,"edi",8)); | ||
137 | &movb (&LB("ecx"),&LB("ebx")); | ||
138 | &movb (&LB("edx"),&HB("ebx")); | ||
139 | &scale ("esi","ecx"); | ||
140 | &scale ("edi","edx"); | ||
141 | &shr ("ebx",16); | ||
142 | &$func (@mm[4],&QWP(&row(4),$tbl,"esi",8)); | ||
143 | &$func (@mm[5],&QWP(&row(5),$tbl,"edi",8)); | ||
144 | &movb (&LB("ecx"),&LB("ebx")); | ||
145 | &movb (&LB("edx"),&HB("ebx")); | ||
146 | &mov ("ebx",&DWP(($i+1)*8+4,"esp")); | ||
147 | &scale ("esi","ecx"); | ||
148 | &scale ("edi","edx"); | ||
149 | &$func (@mm[6],&QWP(&row(6),$tbl,"esi",8)); | ||
150 | &$func (@mm[7],&QWP(&row(7),$tbl,"edi",8)); | ||
151 | push(@mm,shift(@mm)); | ||
152 | } | ||
153 | |||
154 | for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); } # K=L | ||
155 | |||
156 | for($i=0;$i<8;$i++) { | ||
157 | &movb (&LB("ecx"),&LB("eax")); | ||
158 | &movb (&LB("edx"),&HB("eax")); | ||
159 | &scale ("esi","ecx"); | ||
160 | &scale ("edi","edx"); | ||
161 | &shr ("eax",16); | ||
162 | &pxor (@mm[0],&QWP(&row(0),$tbl,"esi",8)); | ||
163 | &pxor (@mm[1],&QWP(&row(1),$tbl,"edi",8)); | ||
164 | &movb (&LB("ecx"),&LB("eax")); | ||
165 | &movb (&LB("edx"),&HB("eax")); | ||
166 | &mov ("eax",&DWP(64+($i+1)*8,"esp")) if ($i<7); | ||
167 | &scale ("esi","ecx"); | ||
168 | &scale ("edi","edx"); | ||
169 | &pxor (@mm[2],&QWP(&row(2),$tbl,"esi",8)); | ||
170 | &pxor (@mm[3],&QWP(&row(3),$tbl,"edi",8)); | ||
171 | &movb (&LB("ecx"),&LB("ebx")); | ||
172 | &movb (&LB("edx"),&HB("ebx")); | ||
173 | &scale ("esi","ecx"); | ||
174 | &scale ("edi","edx"); | ||
175 | &shr ("ebx",16); | ||
176 | &pxor (@mm[4],&QWP(&row(4),$tbl,"esi",8)); | ||
177 | &pxor (@mm[5],&QWP(&row(5),$tbl,"edi",8)); | ||
178 | &movb (&LB("ecx"),&LB("ebx")); | ||
179 | &movb (&LB("edx"),&HB("ebx")); | ||
180 | &mov ("ebx",&DWP(64+($i+1)*8+4,"esp")) if ($i<7); | ||
181 | &scale ("esi","ecx"); | ||
182 | &scale ("edi","edx"); | ||
183 | &pxor (@mm[6],&QWP(&row(6),$tbl,"esi",8)); | ||
184 | &pxor (@mm[7],&QWP(&row(7),$tbl,"edi",8)); | ||
185 | push(@mm,shift(@mm)); | ||
186 | } | ||
187 | &lea ("ebx",&DWP(128,"esp")); | ||
188 | &mov ("esi",&DWP(12,"ebx")); # pull round counter | ||
189 | &add ("esi",1); | ||
190 | &cmp ("esi",10); | ||
191 | &je (&label("roundsdone")); | ||
192 | |||
193 | &mov (&DWP(12,"ebx"),"esi"); # update round counter | ||
194 | for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L | ||
195 | &jmp (&label("round")); | ||
196 | |||
197 | &set_label("roundsdone",16); | ||
198 | &mov ("esi",&DWP(0,"ebx")); # reload argument block | ||
199 | &mov ("edi",&DWP(4,"ebx")); | ||
200 | &mov ("eax",&DWP(8,"ebx")); | ||
201 | |||
202 | for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); } # L^=inp | ||
203 | for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"esi")); } # L^=H | ||
204 | for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esi"),@mm[$i]); } # H=L | ||
205 | |||
206 | &lea ("edi",&DWP(64,"edi")); # inp+=64 | ||
207 | &sub ("eax",1); # num-- | ||
208 | &jz (&label("alldone")); | ||
209 | &mov (&DWP(4,"ebx"),"edi"); # update argument block | ||
210 | &mov (&DWP(8,"ebx"),"eax"); | ||
211 | &jmp (&label("outerloop")); | ||
212 | |||
213 | &set_label("alldone"); | ||
214 | &emms (); | ||
215 | &mov ("esp",&DWP(16,"ebx")); # restore saved stack pointer | ||
216 | &pop ("edi"); | ||
217 | &pop ("esi"); | ||
218 | &pop ("ebx"); | ||
219 | &pop ("ebp"); | ||
220 | &ret (); | ||
221 | |||
222 | &align(64); | ||
223 | &set_label("table"); | ||
224 | &LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8); | ||
225 | &LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26); | ||
226 | &LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8); | ||
227 | &LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb); | ||
228 | &LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb); | ||
229 | &LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11); | ||
230 | &LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09); | ||
231 | &LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d); | ||
232 | &LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b); | ||
233 | &LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff); | ||
234 | &LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c); | ||
235 | &LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e); | ||
236 | &LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96); | ||
237 | &LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30); | ||
238 | &LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d); | ||
239 | &LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8); | ||
240 | &LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47); | ||
241 | &LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35); | ||
242 | &LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37); | ||
243 | &LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a); | ||
244 | &LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2); | ||
245 | &LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c); | ||
246 | &LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84); | ||
247 | &LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80); | ||
248 | &LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5); | ||
249 | &LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3); | ||
250 | &LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21); | ||
251 | &LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c); | ||
252 | &LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43); | ||
253 | &LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29); | ||
254 | &LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d); | ||
255 | &LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5); | ||
256 | &LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd); | ||
257 | &LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8); | ||
258 | &LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92); | ||
259 | &LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e); | ||
260 | &LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13); | ||
261 | &LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23); | ||
262 | &LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20); | ||
263 | &LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44); | ||
264 | &LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2); | ||
265 | &LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf); | ||
266 | &LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c); | ||
267 | &LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a); | ||
268 | &LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50); | ||
269 | &LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9); | ||
270 | &LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14); | ||
271 | &LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9); | ||
272 | &LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c); | ||
273 | &LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f); | ||
274 | &LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90); | ||
275 | &LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07); | ||
276 | &LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd); | ||
277 | &LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3); | ||
278 | &LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d); | ||
279 | &LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78); | ||
280 | &LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97); | ||
281 | &LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02); | ||
282 | &LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73); | ||
283 | &LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7); | ||
284 | &LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6); | ||
285 | &LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2); | ||
286 | &LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49); | ||
287 | &LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56); | ||
288 | &LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70); | ||
289 | &LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd); | ||
290 | &LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb); | ||
291 | &LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71); | ||
292 | &LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b); | ||
293 | &LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf); | ||
294 | &LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45); | ||
295 | &LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a); | ||
296 | &LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4); | ||
297 | &LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58); | ||
298 | &LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e); | ||
299 | &LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f); | ||
300 | &LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac); | ||
301 | &LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0); | ||
302 | &LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef); | ||
303 | &LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6); | ||
304 | &LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c); | ||
305 | &LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12); | ||
306 | &LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93); | ||
307 | &LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde); | ||
308 | &LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6); | ||
309 | &LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1); | ||
310 | &LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b); | ||
311 | &LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f); | ||
312 | &LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31); | ||
313 | &LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8); | ||
314 | &LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9); | ||
315 | &LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc); | ||
316 | &LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e); | ||
317 | &LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b); | ||
318 | &LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf); | ||
319 | &LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59); | ||
320 | &LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2); | ||
321 | &LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77); | ||
322 | &LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33); | ||
323 | &LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4); | ||
324 | &LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27); | ||
325 | &LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb); | ||
326 | &LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89); | ||
327 | &LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32); | ||
328 | &LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54); | ||
329 | &LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d); | ||
330 | &LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64); | ||
331 | &LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d); | ||
332 | &LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d); | ||
333 | &LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f); | ||
334 | &LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca); | ||
335 | &LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7); | ||
336 | &LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d); | ||
337 | &LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce); | ||
338 | &LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f); | ||
339 | &LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f); | ||
340 | &LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63); | ||
341 | &LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a); | ||
342 | &LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc); | ||
343 | &LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82); | ||
344 | &LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a); | ||
345 | &LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48); | ||
346 | &LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95); | ||
347 | &LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf); | ||
348 | &LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d); | ||
349 | &LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0); | ||
350 | &LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91); | ||
351 | &LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8); | ||
352 | &LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b); | ||
353 | &LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); | ||
354 | &LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9); | ||
355 | &LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e); | ||
356 | &LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1); | ||
357 | &LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6); | ||
358 | &LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28); | ||
359 | &LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3); | ||
360 | &LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74); | ||
361 | &LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe); | ||
362 | &LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d); | ||
363 | &LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea); | ||
364 | &LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57); | ||
365 | &LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38); | ||
366 | &LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad); | ||
367 | &LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4); | ||
368 | &LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda); | ||
369 | &LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7); | ||
370 | &LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb); | ||
371 | &LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9); | ||
372 | &LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a); | ||
373 | &LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03); | ||
374 | &LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a); | ||
375 | &LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e); | ||
376 | &LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60); | ||
377 | &LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc); | ||
378 | &LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46); | ||
379 | &LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f); | ||
380 | &LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76); | ||
381 | &LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa); | ||
382 | &LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36); | ||
383 | &LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae); | ||
384 | &LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b); | ||
385 | &LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85); | ||
386 | &LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e); | ||
387 | &LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7); | ||
388 | &LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55); | ||
389 | &LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a); | ||
390 | &LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81); | ||
391 | &LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52); | ||
392 | &LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62); | ||
393 | &LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3); | ||
394 | &LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10); | ||
395 | &LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab); | ||
396 | &LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0); | ||
397 | &LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5); | ||
398 | &LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec); | ||
399 | &LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16); | ||
400 | &LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94); | ||
401 | &LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f); | ||
402 | &LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5); | ||
403 | &LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98); | ||
404 | &LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17); | ||
405 | &LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4); | ||
406 | &LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1); | ||
407 | &LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e); | ||
408 | &LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42); | ||
409 | &LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34); | ||
410 | &LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08); | ||
411 | &LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee); | ||
412 | &LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61); | ||
413 | &LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1); | ||
414 | &LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f); | ||
415 | &LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24); | ||
416 | &LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3); | ||
417 | &LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25); | ||
418 | &LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22); | ||
419 | &LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65); | ||
420 | &LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79); | ||
421 | &LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69); | ||
422 | &LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9); | ||
423 | &LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19); | ||
424 | &LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe); | ||
425 | &LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a); | ||
426 | &LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0); | ||
427 | &LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99); | ||
428 | &LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83); | ||
429 | &LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04); | ||
430 | &LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66); | ||
431 | &LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0); | ||
432 | &LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1); | ||
433 | &LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd); | ||
434 | &LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40); | ||
435 | &LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c); | ||
436 | &LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18); | ||
437 | &LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b); | ||
438 | &LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51); | ||
439 | &LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05); | ||
440 | &LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c); | ||
441 | &LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39); | ||
442 | &LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa); | ||
443 | &LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b); | ||
444 | &LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc); | ||
445 | &LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e); | ||
446 | &LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0); | ||
447 | &LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88); | ||
448 | &LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67); | ||
449 | &LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a); | ||
450 | &LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87); | ||
451 | &LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1); | ||
452 | &LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72); | ||
453 | &LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53); | ||
454 | &LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01); | ||
455 | &LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b); | ||
456 | &LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4); | ||
457 | &LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3); | ||
458 | &LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15); | ||
459 | &LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c); | ||
460 | &LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5); | ||
461 | &LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5); | ||
462 | &LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4); | ||
463 | &LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba); | ||
464 | &LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6); | ||
465 | &LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7); | ||
466 | &LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06); | ||
467 | &LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41); | ||
468 | &LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7); | ||
469 | &LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f); | ||
470 | &LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e); | ||
471 | &LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6); | ||
472 | &LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2); | ||
473 | &LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68); | ||
474 | &LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c); | ||
475 | &LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed); | ||
476 | &LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75); | ||
477 | &LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86); | ||
478 | &LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b); | ||
479 | &LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2); | ||
480 | |||
481 | &L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f); # rc[ROUNDS] | ||
482 | &L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52); | ||
483 | &L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35); | ||
484 | &L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57); | ||
485 | &L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda); | ||
486 | &L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85); | ||
487 | &L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67); | ||
488 | &L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8); | ||
489 | &L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e); | ||
490 | &L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33); | ||
491 | |||
492 | &function_end_B("whirlpool_block_mmx"); | ||
493 | &asm_finish(); | ||
diff --git a/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl b/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl new file mode 100644 index 0000000000..87c0843dc1 --- /dev/null +++ b/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl | |||
@@ -0,0 +1,589 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. Rights for redistribution and usage in source and binary | ||
6 | # forms are granted according to the OpenSSL license. | ||
7 | # ==================================================================== | ||
8 | # | ||
9 | # whirlpool_block for x86_64. | ||
10 | # | ||
11 | # 2500 cycles per 64-byte input block on AMD64, which is *identical* | ||
12 | # to 32-bit MMX version executed on same CPU. So why did I bother? | ||
13 | # Well, it's faster than gcc 3.3.2 generated code by over 50%, and | ||
14 | # over 80% faster than PathScale 1.4, an "ambitious" commercial | ||
15 | # compiler. Furthermore it surpasses gcc 3.4.3 by 170% and Sun Studio | ||
16 | # 10 - by 360%[!]... What is it with x86_64 compilers? It's not the | ||
17 | # first example when they fail to generate more optimal code, when | ||
18 | # I believe they had *all* chances to... | ||
19 | # | ||
20 | # Note that register and stack frame layout are virtually identical | ||
21 | # to 32-bit MMX version, except that %r8-15 are used instead of | ||
22 | # %mm0-8. You can even notice that K[i] and S[i] are loaded to | ||
23 | # %eax:%ebx as pair of 32-bit values and not as single 64-bit one. | ||
24 | # This is done in order to avoid 64-bit shift penalties on Intel | ||
25 | # EM64T core. Speaking of which! I bet it's possible to improve | ||
26 | # Opteron performance by compressing the table to 2KB and replacing | ||
27 | # unaligned references with complementary rotations [which would | ||
28 | # incidentally replace lea instructions], but it would definitely | ||
29 | # just "kill" EM64T, because it has only 1 shifter/rotator [against | ||
30 | # 3 on Opteron] and which is *unacceptably* slow with 64-bit | ||
31 | # operand. | ||
32 | |||
33 | $flavour = shift; | ||
34 | $output = shift; | ||
35 | if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } | ||
36 | |||
37 | $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); | ||
38 | |||
39 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; | ||
40 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | ||
41 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | ||
42 | die "can't locate x86_64-xlate.pl"; | ||
43 | |||
44 | open STDOUT,"| $^X $xlate $flavour $output"; | ||
45 | |||
46 | sub L() { $code.=".byte ".join(',',@_)."\n"; } | ||
47 | sub LL(){ $code.=".byte ".join(',',@_).",".join(',',@_)."\n"; } | ||
48 | |||
49 | @mm=("%r8","%r9","%r10","%r11","%r12","%r13","%r14","%r15"); | ||
50 | |||
51 | $func="whirlpool_block"; | ||
52 | $table=".Ltable"; | ||
53 | |||
54 | $code=<<___; | ||
55 | .text | ||
56 | |||
57 | .globl $func | ||
58 | .type $func,\@function,3 | ||
59 | .align 16 | ||
60 | $func: | ||
61 | push %rbx | ||
62 | push %rbp | ||
63 | push %r12 | ||
64 | push %r13 | ||
65 | push %r14 | ||
66 | push %r15 | ||
67 | |||
68 | mov %rsp,%r11 | ||
69 | sub \$128+40,%rsp | ||
70 | and \$-64,%rsp | ||
71 | |||
72 | lea 128(%rsp),%r10 | ||
73 | mov %rdi,0(%r10) # save parameter block | ||
74 | mov %rsi,8(%r10) | ||
75 | mov %rdx,16(%r10) | ||
76 | mov %r11,32(%r10) # saved stack pointer | ||
77 | .Lprologue: | ||
78 | |||
79 | mov %r10,%rbx | ||
80 | lea $table(%rip),%rbp | ||
81 | |||
82 | xor %rcx,%rcx | ||
83 | xor %rdx,%rdx | ||
84 | ___ | ||
85 | for($i=0;$i<8;$i++) { $code.="mov $i*8(%rdi),@mm[$i]\n"; } # L=H | ||
86 | $code.=".Louterloop:\n"; | ||
87 | for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; } # K=L | ||
88 | for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; } # L^=inp | ||
89 | for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; } # S=L | ||
90 | $code.=<<___; | ||
91 | xor %rsi,%rsi | ||
92 | mov %rsi,24(%rbx) # zero round counter | ||
93 | .align 16 | ||
94 | .Lround: | ||
95 | mov 4096(%rbp,%rsi,8),@mm[0] # rc[r] | ||
96 | mov 0(%rsp),%eax | ||
97 | mov 4(%rsp),%ebx | ||
98 | ___ | ||
99 | for($i=0;$i<8;$i++) { | ||
100 | my $func = ($i==0)? "mov" : "xor"; | ||
101 | $code.=<<___; | ||
102 | mov %al,%cl | ||
103 | mov %ah,%dl | ||
104 | lea (%rcx,%rcx),%rsi | ||
105 | lea (%rdx,%rdx),%rdi | ||
106 | shr \$16,%eax | ||
107 | xor 0(%rbp,%rsi,8),@mm[0] | ||
108 | $func 7(%rbp,%rdi,8),@mm[1] | ||
109 | mov %al,%cl | ||
110 | mov %ah,%dl | ||
111 | mov $i*8+8(%rsp),%eax # ($i+1)*8 | ||
112 | lea (%rcx,%rcx),%rsi | ||
113 | lea (%rdx,%rdx),%rdi | ||
114 | $func 6(%rbp,%rsi,8),@mm[2] | ||
115 | $func 5(%rbp,%rdi,8),@mm[3] | ||
116 | mov %bl,%cl | ||
117 | mov %bh,%dl | ||
118 | lea (%rcx,%rcx),%rsi | ||
119 | lea (%rdx,%rdx),%rdi | ||
120 | shr \$16,%ebx | ||
121 | $func 4(%rbp,%rsi,8),@mm[4] | ||
122 | $func 3(%rbp,%rdi,8),@mm[5] | ||
123 | mov %bl,%cl | ||
124 | mov %bh,%dl | ||
125 | mov $i*8+8+4(%rsp),%ebx # ($i+1)*8+4 | ||
126 | lea (%rcx,%rcx),%rsi | ||
127 | lea (%rdx,%rdx),%rdi | ||
128 | $func 2(%rbp,%rsi,8),@mm[6] | ||
129 | $func 1(%rbp,%rdi,8),@mm[7] | ||
130 | ___ | ||
131 | push(@mm,shift(@mm)); | ||
132 | } | ||
133 | for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; } # K=L | ||
134 | for($i=0;$i<8;$i++) { | ||
135 | $code.=<<___; | ||
136 | mov %al,%cl | ||
137 | mov %ah,%dl | ||
138 | lea (%rcx,%rcx),%rsi | ||
139 | lea (%rdx,%rdx),%rdi | ||
140 | shr \$16,%eax | ||
141 | xor 0(%rbp,%rsi,8),@mm[0] | ||
142 | xor 7(%rbp,%rdi,8),@mm[1] | ||
143 | mov %al,%cl | ||
144 | mov %ah,%dl | ||
145 | `"mov 64+$i*8+8(%rsp),%eax" if($i<7);` # 64+($i+1)*8 | ||
146 | lea (%rcx,%rcx),%rsi | ||
147 | lea (%rdx,%rdx),%rdi | ||
148 | xor 6(%rbp,%rsi,8),@mm[2] | ||
149 | xor 5(%rbp,%rdi,8),@mm[3] | ||
150 | mov %bl,%cl | ||
151 | mov %bh,%dl | ||
152 | lea (%rcx,%rcx),%rsi | ||
153 | lea (%rdx,%rdx),%rdi | ||
154 | shr \$16,%ebx | ||
155 | xor 4(%rbp,%rsi,8),@mm[4] | ||
156 | xor 3(%rbp,%rdi,8),@mm[5] | ||
157 | mov %bl,%cl | ||
158 | mov %bh,%dl | ||
159 | `"mov 64+$i*8+8+4(%rsp),%ebx" if($i<7);` # 64+($i+1)*8+4 | ||
160 | lea (%rcx,%rcx),%rsi | ||
161 | lea (%rdx,%rdx),%rdi | ||
162 | xor 2(%rbp,%rsi,8),@mm[6] | ||
163 | xor 1(%rbp,%rdi,8),@mm[7] | ||
164 | ___ | ||
165 | push(@mm,shift(@mm)); | ||
166 | } | ||
167 | $code.=<<___; | ||
168 | lea 128(%rsp),%rbx | ||
169 | mov 24(%rbx),%rsi # pull round counter | ||
170 | add \$1,%rsi | ||
171 | cmp \$10,%rsi | ||
172 | je .Lroundsdone | ||
173 | |||
174 | mov %rsi,24(%rbx) # update round counter | ||
175 | ___ | ||
176 | for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; } # S=L | ||
177 | $code.=<<___; | ||
178 | jmp .Lround | ||
179 | .align 16 | ||
180 | .Lroundsdone: | ||
181 | mov 0(%rbx),%rdi # reload argument block | ||
182 | mov 8(%rbx),%rsi | ||
183 | mov 16(%rbx),%rax | ||
184 | ___ | ||
185 | for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; } # L^=inp | ||
186 | for($i=0;$i<8;$i++) { $code.="xor $i*8(%rdi),@mm[$i]\n"; } # L^=H | ||
187 | for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rdi)\n"; } # H=L | ||
188 | $code.=<<___; | ||
189 | lea 64(%rsi),%rsi # inp+=64 | ||
190 | sub \$1,%rax # num-- | ||
191 | jz .Lalldone | ||
192 | mov %rsi,8(%rbx) # update parameter block | ||
193 | mov %rax,16(%rbx) | ||
194 | jmp .Louterloop | ||
195 | .Lalldone: | ||
196 | mov 32(%rbx),%rsi # restore saved pointer | ||
197 | mov (%rsi),%r15 | ||
198 | mov 8(%rsi),%r14 | ||
199 | mov 16(%rsi),%r13 | ||
200 | mov 24(%rsi),%r12 | ||
201 | mov 32(%rsi),%rbp | ||
202 | mov 40(%rsi),%rbx | ||
203 | lea 48(%rsi),%rsp | ||
204 | .Lepilogue: | ||
205 | ret | ||
206 | .size $func,.-$func | ||
207 | |||
208 | .align 64 | ||
209 | .type $table,\@object | ||
210 | $table: | ||
211 | ___ | ||
212 | &LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8); | ||
213 | &LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26); | ||
214 | &LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8); | ||
215 | &LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb); | ||
216 | &LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb); | ||
217 | &LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11); | ||
218 | &LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09); | ||
219 | &LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d); | ||
220 | &LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b); | ||
221 | &LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff); | ||
222 | &LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c); | ||
223 | &LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e); | ||
224 | &LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96); | ||
225 | &LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30); | ||
226 | &LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d); | ||
227 | &LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8); | ||
228 | &LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47); | ||
229 | &LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35); | ||
230 | &LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37); | ||
231 | &LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a); | ||
232 | &LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2); | ||
233 | &LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c); | ||
234 | &LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84); | ||
235 | &LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80); | ||
236 | &LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5); | ||
237 | &LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3); | ||
238 | &LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21); | ||
239 | &LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c); | ||
240 | &LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43); | ||
241 | &LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29); | ||
242 | &LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d); | ||
243 | &LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5); | ||
244 | &LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd); | ||
245 | &LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8); | ||
246 | &LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92); | ||
247 | &LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e); | ||
248 | &LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13); | ||
249 | &LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23); | ||
250 | &LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20); | ||
251 | &LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44); | ||
252 | &LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2); | ||
253 | &LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf); | ||
254 | &LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c); | ||
255 | &LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a); | ||
256 | &LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50); | ||
257 | &LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9); | ||
258 | &LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14); | ||
259 | &LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9); | ||
260 | &LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c); | ||
261 | &LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f); | ||
262 | &LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90); | ||
263 | &LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07); | ||
264 | &LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd); | ||
265 | &LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3); | ||
266 | &LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d); | ||
267 | &LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78); | ||
268 | &LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97); | ||
269 | &LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02); | ||
270 | &LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73); | ||
271 | &LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7); | ||
272 | &LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6); | ||
273 | &LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2); | ||
274 | &LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49); | ||
275 | &LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56); | ||
276 | &LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70); | ||
277 | &LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd); | ||
278 | &LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb); | ||
279 | &LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71); | ||
280 | &LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b); | ||
281 | &LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf); | ||
282 | &LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45); | ||
283 | &LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a); | ||
284 | &LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4); | ||
285 | &LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58); | ||
286 | &LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e); | ||
287 | &LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f); | ||
288 | &LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac); | ||
289 | &LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0); | ||
290 | &LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef); | ||
291 | &LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6); | ||
292 | &LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c); | ||
293 | &LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12); | ||
294 | &LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93); | ||
295 | &LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde); | ||
296 | &LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6); | ||
297 | &LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1); | ||
298 | &LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b); | ||
299 | &LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f); | ||
300 | &LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31); | ||
301 | &LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8); | ||
302 | &LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9); | ||
303 | &LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc); | ||
304 | &LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e); | ||
305 | &LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b); | ||
306 | &LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf); | ||
307 | &LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59); | ||
308 | &LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2); | ||
309 | &LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77); | ||
310 | &LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33); | ||
311 | &LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4); | ||
312 | &LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27); | ||
313 | &LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb); | ||
314 | &LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89); | ||
315 | &LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32); | ||
316 | &LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54); | ||
317 | &LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d); | ||
318 | &LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64); | ||
319 | &LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d); | ||
320 | &LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d); | ||
321 | &LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f); | ||
322 | &LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca); | ||
323 | &LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7); | ||
324 | &LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d); | ||
325 | &LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce); | ||
326 | &LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f); | ||
327 | &LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f); | ||
328 | &LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63); | ||
329 | &LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a); | ||
330 | &LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc); | ||
331 | &LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82); | ||
332 | &LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a); | ||
333 | &LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48); | ||
334 | &LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95); | ||
335 | &LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf); | ||
336 | &LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d); | ||
337 | &LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0); | ||
338 | &LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91); | ||
339 | &LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8); | ||
340 | &LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b); | ||
341 | &LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); | ||
342 | &LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9); | ||
343 | &LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e); | ||
344 | &LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1); | ||
345 | &LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6); | ||
346 | &LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28); | ||
347 | &LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3); | ||
348 | &LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74); | ||
349 | &LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe); | ||
350 | &LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d); | ||
351 | &LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea); | ||
352 | &LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57); | ||
353 | &LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38); | ||
354 | &LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad); | ||
355 | &LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4); | ||
356 | &LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda); | ||
357 | &LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7); | ||
358 | &LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb); | ||
359 | &LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9); | ||
360 | &LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a); | ||
361 | &LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03); | ||
362 | &LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a); | ||
363 | &LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e); | ||
364 | &LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60); | ||
365 | &LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc); | ||
366 | &LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46); | ||
367 | &LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f); | ||
368 | &LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76); | ||
369 | &LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa); | ||
370 | &LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36); | ||
371 | &LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae); | ||
372 | &LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b); | ||
373 | &LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85); | ||
374 | &LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e); | ||
375 | &LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7); | ||
376 | &LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55); | ||
377 | &LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a); | ||
378 | &LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81); | ||
379 | &LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52); | ||
380 | &LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62); | ||
381 | &LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3); | ||
382 | &LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10); | ||
383 | &LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab); | ||
384 | &LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0); | ||
385 | &LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5); | ||
386 | &LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec); | ||
387 | &LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16); | ||
388 | &LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94); | ||
389 | &LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f); | ||
390 | &LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5); | ||
391 | &LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98); | ||
392 | &LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17); | ||
393 | &LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4); | ||
394 | &LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1); | ||
395 | &LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e); | ||
396 | &LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42); | ||
397 | &LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34); | ||
398 | &LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08); | ||
399 | &LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee); | ||
400 | &LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61); | ||
401 | &LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1); | ||
402 | &LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f); | ||
403 | &LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24); | ||
404 | &LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3); | ||
405 | &LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25); | ||
406 | &LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22); | ||
407 | &LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65); | ||
408 | &LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79); | ||
409 | &LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69); | ||
410 | &LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9); | ||
411 | &LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19); | ||
412 | &LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe); | ||
413 | &LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a); | ||
414 | &LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0); | ||
415 | &LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99); | ||
416 | &LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83); | ||
417 | &LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04); | ||
418 | &LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66); | ||
419 | &LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0); | ||
420 | &LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1); | ||
421 | &LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd); | ||
422 | &LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40); | ||
423 | &LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c); | ||
424 | &LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18); | ||
425 | &LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b); | ||
426 | &LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51); | ||
427 | &LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05); | ||
428 | &LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c); | ||
429 | &LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39); | ||
430 | &LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa); | ||
431 | &LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b); | ||
432 | &LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc); | ||
433 | &LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e); | ||
434 | &LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0); | ||
435 | &LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88); | ||
436 | &LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67); | ||
437 | &LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a); | ||
438 | &LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87); | ||
439 | &LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1); | ||
440 | &LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72); | ||
441 | &LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53); | ||
442 | &LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01); | ||
443 | &LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b); | ||
444 | &LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4); | ||
445 | &LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3); | ||
446 | &LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15); | ||
447 | &LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c); | ||
448 | &LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5); | ||
449 | &LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5); | ||
450 | &LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4); | ||
451 | &LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba); | ||
452 | &LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6); | ||
453 | &LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7); | ||
454 | &LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06); | ||
455 | &LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41); | ||
456 | &LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7); | ||
457 | &LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f); | ||
458 | &LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e); | ||
459 | &LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6); | ||
460 | &LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2); | ||
461 | &LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68); | ||
462 | &LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c); | ||
463 | &LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed); | ||
464 | &LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75); | ||
465 | &LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86); | ||
466 | &LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b); | ||
467 | &LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2); | ||
468 | |||
469 | &L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f); # rc[ROUNDS] | ||
470 | &L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52); | ||
471 | &L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35); | ||
472 | &L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57); | ||
473 | &L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda); | ||
474 | &L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85); | ||
475 | &L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67); | ||
476 | &L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8); | ||
477 | &L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e); | ||
478 | &L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33); | ||
479 | |||
480 | # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, | ||
481 | # CONTEXT *context,DISPATCHER_CONTEXT *disp) | ||
482 | if ($win64) { | ||
483 | $rec="%rcx"; | ||
484 | $frame="%rdx"; | ||
485 | $context="%r8"; | ||
486 | $disp="%r9"; | ||
487 | |||
488 | $code.=<<___; | ||
489 | .extern __imp_RtlVirtualUnwind | ||
490 | .type se_handler,\@abi-omnipotent | ||
491 | .align 16 | ||
492 | se_handler: | ||
493 | push %rsi | ||
494 | push %rdi | ||
495 | push %rbx | ||
496 | push %rbp | ||
497 | push %r12 | ||
498 | push %r13 | ||
499 | push %r14 | ||
500 | push %r15 | ||
501 | pushfq | ||
502 | sub \$64,%rsp | ||
503 | |||
504 | mov 120($context),%rax # pull context->Rax | ||
505 | mov 248($context),%rbx # pull context->Rip | ||
506 | |||
507 | lea .Lprologue(%rip),%r10 | ||
508 | cmp %r10,%rbx # context->Rip<.Lprologue | ||
509 | jb .Lin_prologue | ||
510 | |||
511 | mov 152($context),%rax # pull context->Rsp | ||
512 | |||
513 | lea .Lepilogue(%rip),%r10 | ||
514 | cmp %r10,%rbx # context->Rip>=.Lepilogue | ||
515 | jae .Lin_prologue | ||
516 | |||
517 | mov 128+32(%rax),%rax # pull saved stack pointer | ||
518 | lea 48(%rax),%rax | ||
519 | |||
520 | mov -8(%rax),%rbx | ||
521 | mov -16(%rax),%rbp | ||
522 | mov -24(%rax),%r12 | ||
523 | mov -32(%rax),%r13 | ||
524 | mov -40(%rax),%r14 | ||
525 | mov -48(%rax),%r15 | ||
526 | mov %rbx,144($context) # restore context->Rbx | ||
527 | mov %rbp,160($context) # restore context->Rbp | ||
528 | mov %r12,216($context) # restore context->R12 | ||
529 | mov %r13,224($context) # restore context->R13 | ||
530 | mov %r14,232($context) # restore context->R14 | ||
531 | mov %r15,240($context) # restore context->R15 | ||
532 | |||
533 | .Lin_prologue: | ||
534 | mov 8(%rax),%rdi | ||
535 | mov 16(%rax),%rsi | ||
536 | mov %rax,152($context) # restore context->Rsp | ||
537 | mov %rsi,168($context) # restore context->Rsi | ||
538 | mov %rdi,176($context) # restore context->Rdi | ||
539 | |||
540 | mov 40($disp),%rdi # disp->ContextRecord | ||
541 | mov $context,%rsi # context | ||
542 | mov \$154,%ecx # sizeof(CONTEXT) | ||
543 | .long 0xa548f3fc # cld; rep movsq | ||
544 | |||
545 | mov $disp,%rsi | ||
546 | xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER | ||
547 | mov 8(%rsi),%rdx # arg2, disp->ImageBase | ||
548 | mov 0(%rsi),%r8 # arg3, disp->ControlPc | ||
549 | mov 16(%rsi),%r9 # arg4, disp->FunctionEntry | ||
550 | mov 40(%rsi),%r10 # disp->ContextRecord | ||
551 | lea 56(%rsi),%r11 # &disp->HandlerData | ||
552 | lea 24(%rsi),%r12 # &disp->EstablisherFrame | ||
553 | mov %r10,32(%rsp) # arg5 | ||
554 | mov %r11,40(%rsp) # arg6 | ||
555 | mov %r12,48(%rsp) # arg7 | ||
556 | mov %rcx,56(%rsp) # arg8, (NULL) | ||
557 | call *__imp_RtlVirtualUnwind(%rip) | ||
558 | |||
559 | mov \$1,%eax # ExceptionContinueSearch | ||
560 | add \$64,%rsp | ||
561 | popfq | ||
562 | pop %r15 | ||
563 | pop %r14 | ||
564 | pop %r13 | ||
565 | pop %r12 | ||
566 | pop %rbp | ||
567 | pop %rbx | ||
568 | pop %rdi | ||
569 | pop %rsi | ||
570 | ret | ||
571 | .size se_handler,.-se_handler | ||
572 | |||
573 | .section .pdata | ||
574 | .align 4 | ||
575 | .rva .LSEH_begin_$func | ||
576 | .rva .LSEH_end_$func | ||
577 | .rva .LSEH_info_$func | ||
578 | |||
579 | .section .xdata | ||
580 | .align 8 | ||
581 | .LSEH_info_$func: | ||
582 | .byte 9,0,0,0 | ||
583 | .rva se_handler | ||
584 | ___ | ||
585 | } | ||
586 | |||
587 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
588 | print $code; | ||
589 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/whrlpool/whrlpool.h b/src/lib/libcrypto/whrlpool/whrlpool.h new file mode 100644 index 0000000000..03c91da115 --- /dev/null +++ b/src/lib/libcrypto/whrlpool/whrlpool.h | |||
@@ -0,0 +1,38 @@ | |||
1 | #ifndef HEADER_WHRLPOOL_H | ||
2 | #define HEADER_WHRLPOOL_H | ||
3 | |||
4 | #include <openssl/e_os2.h> | ||
5 | #include <stddef.h> | ||
6 | |||
7 | #ifdef __cplusplus | ||
8 | extern "C" { | ||
9 | #endif | ||
10 | |||
11 | #define WHIRLPOOL_DIGEST_LENGTH (512/8) | ||
12 | #define WHIRLPOOL_BBLOCK 512 | ||
13 | #define WHIRLPOOL_COUNTER (256/8) | ||
14 | |||
15 | typedef struct { | ||
16 | union { | ||
17 | unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; | ||
18 | /* double q is here to ensure 64-bit alignment */ | ||
19 | double q[WHIRLPOOL_DIGEST_LENGTH/sizeof(double)]; | ||
20 | } H; | ||
21 | unsigned char data[WHIRLPOOL_BBLOCK/8]; | ||
22 | unsigned int bitoff; | ||
23 | size_t bitlen[WHIRLPOOL_COUNTER/sizeof(size_t)]; | ||
24 | } WHIRLPOOL_CTX; | ||
25 | |||
26 | #ifndef OPENSSL_NO_WHIRLPOOL | ||
27 | int WHIRLPOOL_Init (WHIRLPOOL_CTX *c); | ||
28 | int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *inp,size_t bytes); | ||
29 | void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *inp,size_t bits); | ||
30 | int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c); | ||
31 | unsigned char *WHIRLPOOL(const void *inp,size_t bytes,unsigned char *md); | ||
32 | #endif | ||
33 | |||
34 | #ifdef __cplusplus | ||
35 | } | ||
36 | #endif | ||
37 | |||
38 | #endif | ||
diff --git a/src/lib/libcrypto/whrlpool/wp_block.c b/src/lib/libcrypto/whrlpool/wp_block.c new file mode 100644 index 0000000000..221f6cc59f --- /dev/null +++ b/src/lib/libcrypto/whrlpool/wp_block.c | |||
@@ -0,0 +1,655 @@ | |||
1 | /** | ||
2 | * The Whirlpool hashing function. | ||
3 | * | ||
4 | * <P> | ||
5 | * <b>References</b> | ||
6 | * | ||
7 | * <P> | ||
8 | * The Whirlpool algorithm was developed by | ||
9 | * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and | ||
10 | * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>. | ||
11 | * | ||
12 | * See | ||
13 | * P.S.L.M. Barreto, V. Rijmen, | ||
14 | * ``The Whirlpool hashing function,'' | ||
15 | * NESSIE submission, 2000 (tweaked version, 2001), | ||
16 | * <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip> | ||
17 | * | ||
18 | * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and | ||
19 | * Vincent Rijmen. Lookup "reference implementations" on | ||
20 | * <http://planeta.terra.com.br/informatica/paulobarreto/> | ||
21 | * | ||
22 | * ============================================================================= | ||
23 | * | ||
24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS | ||
25 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
26 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE | ||
28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
31 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
32 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
33 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||
34 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
35 | * | ||
36 | */ | ||
37 | |||
38 | #include "wp_locl.h" | ||
39 | #include <string.h> | ||
40 | |||
41 | typedef unsigned char u8; | ||
42 | #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32) | ||
43 | typedef unsigned __int64 u64; | ||
44 | #elif defined(__arch64__) | ||
45 | typedef unsigned long u64; | ||
46 | #else | ||
47 | typedef unsigned long long u64; | ||
48 | #endif | ||
49 | |||
50 | #define ROUNDS 10 | ||
51 | |||
52 | #define STRICT_ALIGNMENT | ||
53 | #if defined(__i386) || defined(__i386__) || \ | ||
54 | defined(__x86_64) || defined(__x86_64__) || \ | ||
55 | defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) | ||
56 | /* Well, formally there're couple of other architectures, which permit | ||
57 | * unaligned loads, specifically those not crossing cache lines, IA-64 | ||
58 | * and PowerPC... */ | ||
59 | # undef STRICT_ALIGNMENT | ||
60 | #endif | ||
61 | |||
62 | #undef SMALL_REGISTER_BANK | ||
63 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) | ||
64 | # define SMALL_REGISTER_BANK | ||
65 | # if defined(WHIRLPOOL_ASM) | ||
66 | # ifndef OPENSSL_SMALL_FOOTPRINT | ||
67 | # define OPENSSL_SMALL_FOOTPRINT /* it appears that for elder non-MMX | ||
68 | CPUs this is actually faster! */ | ||
69 | # endif | ||
70 | # define GO_FOR_MMX(ctx,inp,num) do { \ | ||
71 | extern unsigned long OPENSSL_ia32cap_P; \ | ||
72 | void whirlpool_block_mmx(void *,const void *,size_t); \ | ||
73 | if (!(OPENSSL_ia32cap_P & (1<<23))) break; \ | ||
74 | whirlpool_block_mmx(ctx->H.c,inp,num); return; \ | ||
75 | } while (0) | ||
76 | # endif | ||
77 | #endif | ||
78 | |||
79 | #undef ROTATE | ||
80 | #if defined(_MSC_VER) | ||
81 | # if defined(_WIN64) /* applies to both IA-64 and AMD64 */ | ||
82 | # pragma intrinsic(_rotl64) | ||
83 | # define ROTATE(a,n) _rotl64((a),n) | ||
84 | # endif | ||
85 | #elif defined(__GNUC__) && __GNUC__>=2 | ||
86 | # if defined(__x86_64) || defined(__x86_64__) | ||
87 | # if defined(L_ENDIAN) | ||
88 | # define ROTATE(a,n) ({ u64 ret; asm ("rolq %1,%0" \ | ||
89 | : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) | ||
90 | # elif defined(B_ENDIAN) | ||
91 | /* Most will argue that x86_64 is always little-endian. Well, | ||
92 | * yes, but then we have stratus.com who has modified gcc to | ||
93 | * "emulate" big-endian on x86. Is there evidence that they | ||
94 | * [or somebody else] won't do same for x86_64? Naturally no. | ||
95 | * And this line is waiting ready for that brave soul:-) */ | ||
96 | # define ROTATE(a,n) ({ u64 ret; asm ("rorq %1,%0" \ | ||
97 | : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) | ||
98 | # endif | ||
99 | # elif defined(__ia64) || defined(__ia64__) | ||
100 | # if defined(L_ENDIAN) | ||
101 | # define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ | ||
102 | : "=r"(ret) : "r"(a),"M"(64-(n))); ret; }) | ||
103 | # elif defined(B_ENDIAN) | ||
104 | # define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ | ||
105 | : "=r"(ret) : "r"(a),"M"(n)); ret; }) | ||
106 | # endif | ||
107 | # endif | ||
108 | #endif | ||
109 | |||
110 | #if defined(OPENSSL_SMALL_FOOTPRINT) | ||
111 | # if !defined(ROTATE) | ||
112 | # if defined(L_ENDIAN) /* little-endians have to rotate left */ | ||
113 | # define ROTATE(i,n) ((i)<<(n) ^ (i)>>(64-n)) | ||
114 | # elif defined(B_ENDIAN) /* big-endians have to rotate right */ | ||
115 | # define ROTATE(i,n) ((i)>>(n) ^ (i)<<(64-n)) | ||
116 | # endif | ||
117 | # endif | ||
118 | # if defined(ROTATE) && !defined(STRICT_ALIGNMENT) | ||
119 | # define STRICT_ALIGNMENT /* ensure smallest table size */ | ||
120 | # endif | ||
121 | #endif | ||
122 | |||
123 | /* | ||
124 | * Table size depends on STRICT_ALIGNMENT and whether or not endian- | ||
125 | * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not | ||
126 | * defined, which is normally the case on x86[_64] CPUs, the table is | ||
127 | * 4KB large unconditionally. Otherwise if ROTATE is defined, the | ||
128 | * table is 2KB large, and otherwise - 16KB. 2KB table requires a | ||
129 | * whole bunch of additional rotations, but I'm willing to "trade," | ||
130 | * because 16KB table certainly trashes L1 cache. I wish all CPUs | ||
131 | * could handle unaligned load as 4KB table doesn't trash the cache, | ||
132 | * nor does it require additional rotations. | ||
133 | */ | ||
134 | /* | ||
135 | * Note that every Cn macro expands as two loads: one byte load and | ||
136 | * one quadword load. One can argue that that many single-byte loads | ||
137 | * is too excessive, as one could load a quadword and "milk" it for | ||
138 | * eight 8-bit values instead. Well, yes, but in order to do so *and* | ||
139 | * avoid excessive loads you have to accomodate a handful of 64-bit | ||
140 | * values in the register bank and issue a bunch of shifts and mask. | ||
141 | * It's a tradeoff: loads vs. shift and mask in big register bank[!]. | ||
142 | * On most CPUs eight single-byte loads are faster and I let other | ||
143 | * ones to depend on smart compiler to fold byte loads if beneficial. | ||
144 | * Hand-coded assembler would be another alternative:-) | ||
145 | */ | ||
146 | #ifdef STRICT_ALIGNMENT | ||
147 | # if defined(ROTATE) | ||
148 | # define N 1 | ||
149 | # define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7 | ||
150 | # define C0(K,i) (Cx.q[K.c[(i)*8+0]]) | ||
151 | # define C1(K,i) ROTATE(Cx.q[K.c[(i)*8+1]],8) | ||
152 | # define C2(K,i) ROTATE(Cx.q[K.c[(i)*8+2]],16) | ||
153 | # define C3(K,i) ROTATE(Cx.q[K.c[(i)*8+3]],24) | ||
154 | # define C4(K,i) ROTATE(Cx.q[K.c[(i)*8+4]],32) | ||
155 | # define C5(K,i) ROTATE(Cx.q[K.c[(i)*8+5]],40) | ||
156 | # define C6(K,i) ROTATE(Cx.q[K.c[(i)*8+6]],48) | ||
157 | # define C7(K,i) ROTATE(Cx.q[K.c[(i)*8+7]],56) | ||
158 | # else | ||
159 | # define N 8 | ||
160 | # define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ | ||
161 | c7,c0,c1,c2,c3,c4,c5,c6, \ | ||
162 | c6,c7,c0,c1,c2,c3,c4,c5, \ | ||
163 | c5,c6,c7,c0,c1,c2,c3,c4, \ | ||
164 | c4,c5,c6,c7,c0,c1,c2,c3, \ | ||
165 | c3,c4,c5,c6,c7,c0,c1,c2, \ | ||
166 | c2,c3,c4,c5,c6,c7,c0,c1, \ | ||
167 | c1,c2,c3,c4,c5,c6,c7,c0 | ||
168 | # define C0(K,i) (Cx.q[0+8*K.c[(i)*8+0]]) | ||
169 | # define C1(K,i) (Cx.q[1+8*K.c[(i)*8+1]]) | ||
170 | # define C2(K,i) (Cx.q[2+8*K.c[(i)*8+2]]) | ||
171 | # define C3(K,i) (Cx.q[3+8*K.c[(i)*8+3]]) | ||
172 | # define C4(K,i) (Cx.q[4+8*K.c[(i)*8+4]]) | ||
173 | # define C5(K,i) (Cx.q[5+8*K.c[(i)*8+5]]) | ||
174 | # define C6(K,i) (Cx.q[6+8*K.c[(i)*8+6]]) | ||
175 | # define C7(K,i) (Cx.q[7+8*K.c[(i)*8+7]]) | ||
176 | # endif | ||
177 | #else | ||
178 | # define N 2 | ||
179 | # define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ | ||
180 | c0,c1,c2,c3,c4,c5,c6,c7 | ||
181 | # define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]]) | ||
182 | # define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]]) | ||
183 | # define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]]) | ||
184 | # define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]]) | ||
185 | # define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]]) | ||
186 | # define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]]) | ||
187 | # define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]]) | ||
188 | # define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]]) | ||
189 | #endif | ||
190 | |||
191 | static const | ||
192 | union { | ||
193 | u8 c[(256*N+ROUNDS)*sizeof(u64)]; | ||
194 | u64 q[(256*N+ROUNDS)]; | ||
195 | } Cx = { { | ||
196 | /* Note endian-neutral representation:-) */ | ||
197 | LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8), | ||
198 | LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26), | ||
199 | LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8), | ||
200 | LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb), | ||
201 | LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb), | ||
202 | LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11), | ||
203 | LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09), | ||
204 | LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d), | ||
205 | LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b), | ||
206 | LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff), | ||
207 | LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c), | ||
208 | LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e), | ||
209 | LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96), | ||
210 | LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30), | ||
211 | LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d), | ||
212 | LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8), | ||
213 | LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47), | ||
214 | LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35), | ||
215 | LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37), | ||
216 | LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a), | ||
217 | LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2), | ||
218 | LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c), | ||
219 | LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84), | ||
220 | LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80), | ||
221 | LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5), | ||
222 | LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3), | ||
223 | LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21), | ||
224 | LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c), | ||
225 | LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43), | ||
226 | LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29), | ||
227 | LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d), | ||
228 | LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5), | ||
229 | LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd), | ||
230 | LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8), | ||
231 | LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92), | ||
232 | LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e), | ||
233 | LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13), | ||
234 | LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23), | ||
235 | LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20), | ||
236 | LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44), | ||
237 | LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2), | ||
238 | LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf), | ||
239 | LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c), | ||
240 | LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a), | ||
241 | LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50), | ||
242 | LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9), | ||
243 | LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14), | ||
244 | LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9), | ||
245 | LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c), | ||
246 | LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f), | ||
247 | LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90), | ||
248 | LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07), | ||
249 | LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd), | ||
250 | LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3), | ||
251 | LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d), | ||
252 | LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78), | ||
253 | LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97), | ||
254 | LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02), | ||
255 | LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73), | ||
256 | LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7), | ||
257 | LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6), | ||
258 | LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2), | ||
259 | LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49), | ||
260 | LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56), | ||
261 | LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70), | ||
262 | LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd), | ||
263 | LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb), | ||
264 | LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71), | ||
265 | LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b), | ||
266 | LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf), | ||
267 | LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45), | ||
268 | LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a), | ||
269 | LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4), | ||
270 | LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58), | ||
271 | LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e), | ||
272 | LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f), | ||
273 | LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac), | ||
274 | LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0), | ||
275 | LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef), | ||
276 | LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6), | ||
277 | LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c), | ||
278 | LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12), | ||
279 | LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93), | ||
280 | LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde), | ||
281 | LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6), | ||
282 | LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1), | ||
283 | LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b), | ||
284 | LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f), | ||
285 | LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31), | ||
286 | LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8), | ||
287 | LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9), | ||
288 | LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc), | ||
289 | LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e), | ||
290 | LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b), | ||
291 | LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf), | ||
292 | LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59), | ||
293 | LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2), | ||
294 | LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77), | ||
295 | LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33), | ||
296 | LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4), | ||
297 | LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27), | ||
298 | LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb), | ||
299 | LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89), | ||
300 | LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32), | ||
301 | LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54), | ||
302 | LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d), | ||
303 | LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64), | ||
304 | LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d), | ||
305 | LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d), | ||
306 | LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f), | ||
307 | LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca), | ||
308 | LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7), | ||
309 | LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d), | ||
310 | LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce), | ||
311 | LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f), | ||
312 | LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f), | ||
313 | LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63), | ||
314 | LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a), | ||
315 | LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc), | ||
316 | LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82), | ||
317 | LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a), | ||
318 | LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48), | ||
319 | LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95), | ||
320 | LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf), | ||
321 | LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d), | ||
322 | LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0), | ||
323 | LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91), | ||
324 | LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8), | ||
325 | LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b), | ||
326 | LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00), | ||
327 | LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9), | ||
328 | LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e), | ||
329 | LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1), | ||
330 | LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6), | ||
331 | LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28), | ||
332 | LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3), | ||
333 | LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74), | ||
334 | LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe), | ||
335 | LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d), | ||
336 | LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea), | ||
337 | LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57), | ||
338 | LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38), | ||
339 | LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad), | ||
340 | LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4), | ||
341 | LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda), | ||
342 | LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7), | ||
343 | LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb), | ||
344 | LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9), | ||
345 | LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a), | ||
346 | LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03), | ||
347 | LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a), | ||
348 | LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e), | ||
349 | LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60), | ||
350 | LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc), | ||
351 | LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46), | ||
352 | LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f), | ||
353 | LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76), | ||
354 | LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa), | ||
355 | LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36), | ||
356 | LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae), | ||
357 | LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b), | ||
358 | LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85), | ||
359 | LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e), | ||
360 | LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7), | ||
361 | LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55), | ||
362 | LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a), | ||
363 | LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81), | ||
364 | LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52), | ||
365 | LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62), | ||
366 | LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3), | ||
367 | LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10), | ||
368 | LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab), | ||
369 | LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0), | ||
370 | LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5), | ||
371 | LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec), | ||
372 | LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16), | ||
373 | LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94), | ||
374 | LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f), | ||
375 | LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5), | ||
376 | LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98), | ||
377 | LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17), | ||
378 | LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4), | ||
379 | LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1), | ||
380 | LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e), | ||
381 | LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42), | ||
382 | LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34), | ||
383 | LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08), | ||
384 | LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee), | ||
385 | LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61), | ||
386 | LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1), | ||
387 | LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f), | ||
388 | LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24), | ||
389 | LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3), | ||
390 | LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25), | ||
391 | LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22), | ||
392 | LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65), | ||
393 | LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79), | ||
394 | LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69), | ||
395 | LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9), | ||
396 | LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19), | ||
397 | LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe), | ||
398 | LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a), | ||
399 | LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0), | ||
400 | LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99), | ||
401 | LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83), | ||
402 | LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04), | ||
403 | LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66), | ||
404 | LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0), | ||
405 | LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1), | ||
406 | LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd), | ||
407 | LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40), | ||
408 | LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c), | ||
409 | LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18), | ||
410 | LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b), | ||
411 | LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51), | ||
412 | LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05), | ||
413 | LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c), | ||
414 | LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39), | ||
415 | LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa), | ||
416 | LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b), | ||
417 | LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc), | ||
418 | LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e), | ||
419 | LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0), | ||
420 | LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88), | ||
421 | LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67), | ||
422 | LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a), | ||
423 | LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87), | ||
424 | LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1), | ||
425 | LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72), | ||
426 | LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53), | ||
427 | LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01), | ||
428 | LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b), | ||
429 | LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4), | ||
430 | LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3), | ||
431 | LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15), | ||
432 | LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c), | ||
433 | LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5), | ||
434 | LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5), | ||
435 | LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4), | ||
436 | LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba), | ||
437 | LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6), | ||
438 | LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7), | ||
439 | LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06), | ||
440 | LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41), | ||
441 | LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7), | ||
442 | LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f), | ||
443 | LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e), | ||
444 | LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6), | ||
445 | LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2), | ||
446 | LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68), | ||
447 | LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c), | ||
448 | LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed), | ||
449 | LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75), | ||
450 | LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86), | ||
451 | LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b), | ||
452 | LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2), | ||
453 | #define RC (&(Cx.q[256*N])) | ||
454 | 0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f, /* rc[ROUNDS] */ | ||
455 | 0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52, | ||
456 | 0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35, | ||
457 | 0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57, | ||
458 | 0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda, | ||
459 | 0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85, | ||
460 | 0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67, | ||
461 | 0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8, | ||
462 | 0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e, | ||
463 | 0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33 | ||
464 | } | ||
465 | }; | ||
466 | |||
467 | void whirlpool_block(WHIRLPOOL_CTX *ctx,const void *inp,size_t n) | ||
468 | { | ||
469 | int r; | ||
470 | const u8 *p=inp; | ||
471 | union { u64 q[8]; u8 c[64]; } S,K,*H=(void *)ctx->H.q; | ||
472 | |||
473 | #ifdef GO_FOR_MMX | ||
474 | GO_FOR_MMX(ctx,inp,n); | ||
475 | #endif | ||
476 | do { | ||
477 | #ifdef OPENSSL_SMALL_FOOTPRINT | ||
478 | u64 L[8]; | ||
479 | int i; | ||
480 | |||
481 | for (i=0;i<64;i++) S.c[i] = (K.c[i] = H->c[i]) ^ p[i]; | ||
482 | for (r=0;r<ROUNDS;r++) | ||
483 | { | ||
484 | for (i=0;i<8;i++) | ||
485 | { | ||
486 | L[i] = i ? 0 : RC[r]; | ||
487 | L[i] ^= C0(K,i) ^ C1(K,(i-1)&7) ^ | ||
488 | C2(K,(i-2)&7) ^ C3(K,(i-3)&7) ^ | ||
489 | C4(K,(i-4)&7) ^ C5(K,(i-5)&7) ^ | ||
490 | C6(K,(i-6)&7) ^ C7(K,(i-7)&7); | ||
491 | } | ||
492 | memcpy (K.q,L,64); | ||
493 | for (i=0;i<8;i++) | ||
494 | { | ||
495 | L[i] ^= C0(S,i) ^ C1(S,(i-1)&7) ^ | ||
496 | C2(S,(i-2)&7) ^ C3(S,(i-3)&7) ^ | ||
497 | C4(S,(i-4)&7) ^ C5(S,(i-5)&7) ^ | ||
498 | C6(S,(i-6)&7) ^ C7(S,(i-7)&7); | ||
499 | } | ||
500 | memcpy (S.q,L,64); | ||
501 | } | ||
502 | for (i=0;i<64;i++) H->c[i] ^= S.c[i] ^ p[i]; | ||
503 | #else | ||
504 | u64 L0,L1,L2,L3,L4,L5,L6,L7; | ||
505 | |||
506 | #ifdef STRICT_ALIGNMENT | ||
507 | if ((size_t)p & 7) | ||
508 | { | ||
509 | memcpy (S.c,p,64); | ||
510 | S.q[0] ^= (K.q[0] = H->q[0]); | ||
511 | S.q[1] ^= (K.q[1] = H->q[1]); | ||
512 | S.q[2] ^= (K.q[2] = H->q[2]); | ||
513 | S.q[3] ^= (K.q[3] = H->q[3]); | ||
514 | S.q[4] ^= (K.q[4] = H->q[4]); | ||
515 | S.q[5] ^= (K.q[5] = H->q[5]); | ||
516 | S.q[6] ^= (K.q[6] = H->q[6]); | ||
517 | S.q[7] ^= (K.q[7] = H->q[7]); | ||
518 | } | ||
519 | else | ||
520 | #endif | ||
521 | { | ||
522 | const u64 *pa = (const u64*)p; | ||
523 | S.q[0] = (K.q[0] = H->q[0]) ^ pa[0]; | ||
524 | S.q[1] = (K.q[1] = H->q[1]) ^ pa[1]; | ||
525 | S.q[2] = (K.q[2] = H->q[2]) ^ pa[2]; | ||
526 | S.q[3] = (K.q[3] = H->q[3]) ^ pa[3]; | ||
527 | S.q[4] = (K.q[4] = H->q[4]) ^ pa[4]; | ||
528 | S.q[5] = (K.q[5] = H->q[5]) ^ pa[5]; | ||
529 | S.q[6] = (K.q[6] = H->q[6]) ^ pa[6]; | ||
530 | S.q[7] = (K.q[7] = H->q[7]) ^ pa[7]; | ||
531 | } | ||
532 | |||
533 | for(r=0;r<ROUNDS;r++) | ||
534 | { | ||
535 | #ifdef SMALL_REGISTER_BANK | ||
536 | L0 = C0(K,0) ^ C1(K,7) ^ C2(K,6) ^ C3(K,5) ^ | ||
537 | C4(K,4) ^ C5(K,3) ^ C6(K,2) ^ C7(K,1) ^ RC[r]; | ||
538 | L1 = C0(K,1) ^ C1(K,0) ^ C2(K,7) ^ C3(K,6) ^ | ||
539 | C4(K,5) ^ C5(K,4) ^ C6(K,3) ^ C7(K,2); | ||
540 | L2 = C0(K,2) ^ C1(K,1) ^ C2(K,0) ^ C3(K,7) ^ | ||
541 | C4(K,6) ^ C5(K,5) ^ C6(K,4) ^ C7(K,3); | ||
542 | L3 = C0(K,3) ^ C1(K,2) ^ C2(K,1) ^ C3(K,0) ^ | ||
543 | C4(K,7) ^ C5(K,6) ^ C6(K,5) ^ C7(K,4); | ||
544 | L4 = C0(K,4) ^ C1(K,3) ^ C2(K,2) ^ C3(K,1) ^ | ||
545 | C4(K,0) ^ C5(K,7) ^ C6(K,6) ^ C7(K,5); | ||
546 | L5 = C0(K,5) ^ C1(K,4) ^ C2(K,3) ^ C3(K,2) ^ | ||
547 | C4(K,1) ^ C5(K,0) ^ C6(K,7) ^ C7(K,6); | ||
548 | L6 = C0(K,6) ^ C1(K,5) ^ C2(K,4) ^ C3(K,3) ^ | ||
549 | C4(K,2) ^ C5(K,1) ^ C6(K,0) ^ C7(K,7); | ||
550 | L7 = C0(K,7) ^ C1(K,6) ^ C2(K,5) ^ C3(K,4) ^ | ||
551 | C4(K,3) ^ C5(K,2) ^ C6(K,1) ^ C7(K,0); | ||
552 | |||
553 | K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3; | ||
554 | K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7; | ||
555 | |||
556 | L0 ^= C0(S,0) ^ C1(S,7) ^ C2(S,6) ^ C3(S,5) ^ | ||
557 | C4(S,4) ^ C5(S,3) ^ C6(S,2) ^ C7(S,1); | ||
558 | L1 ^= C0(S,1) ^ C1(S,0) ^ C2(S,7) ^ C3(S,6) ^ | ||
559 | C4(S,5) ^ C5(S,4) ^ C6(S,3) ^ C7(S,2); | ||
560 | L2 ^= C0(S,2) ^ C1(S,1) ^ C2(S,0) ^ C3(S,7) ^ | ||
561 | C4(S,6) ^ C5(S,5) ^ C6(S,4) ^ C7(S,3); | ||
562 | L3 ^= C0(S,3) ^ C1(S,2) ^ C2(S,1) ^ C3(S,0) ^ | ||
563 | C4(S,7) ^ C5(S,6) ^ C6(S,5) ^ C7(S,4); | ||
564 | L4 ^= C0(S,4) ^ C1(S,3) ^ C2(S,2) ^ C3(S,1) ^ | ||
565 | C4(S,0) ^ C5(S,7) ^ C6(S,6) ^ C7(S,5); | ||
566 | L5 ^= C0(S,5) ^ C1(S,4) ^ C2(S,3) ^ C3(S,2) ^ | ||
567 | C4(S,1) ^ C5(S,0) ^ C6(S,7) ^ C7(S,6); | ||
568 | L6 ^= C0(S,6) ^ C1(S,5) ^ C2(S,4) ^ C3(S,3) ^ | ||
569 | C4(S,2) ^ C5(S,1) ^ C6(S,0) ^ C7(S,7); | ||
570 | L7 ^= C0(S,7) ^ C1(S,6) ^ C2(S,5) ^ C3(S,4) ^ | ||
571 | C4(S,3) ^ C5(S,2) ^ C6(S,1) ^ C7(S,0); | ||
572 | |||
573 | S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3; | ||
574 | S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7; | ||
575 | #else | ||
576 | L0 = C0(K,0); L1 = C1(K,0); L2 = C2(K,0); L3 = C3(K,0); | ||
577 | L4 = C4(K,0); L5 = C5(K,0); L6 = C6(K,0); L7 = C7(K,0); | ||
578 | L0 ^= RC[r]; | ||
579 | |||
580 | L1 ^= C0(K,1); L2 ^= C1(K,1); L3 ^= C2(K,1); L4 ^= C3(K,1); | ||
581 | L5 ^= C4(K,1); L6 ^= C5(K,1); L7 ^= C6(K,1); L0 ^= C7(K,1); | ||
582 | |||
583 | L2 ^= C0(K,2); L3 ^= C1(K,2); L4 ^= C2(K,2); L5 ^= C3(K,2); | ||
584 | L6 ^= C4(K,2); L7 ^= C5(K,2); L0 ^= C6(K,2); L1 ^= C7(K,2); | ||
585 | |||
586 | L3 ^= C0(K,3); L4 ^= C1(K,3); L5 ^= C2(K,3); L6 ^= C3(K,3); | ||
587 | L7 ^= C4(K,3); L0 ^= C5(K,3); L1 ^= C6(K,3); L2 ^= C7(K,3); | ||
588 | |||
589 | L4 ^= C0(K,4); L5 ^= C1(K,4); L6 ^= C2(K,4); L7 ^= C3(K,4); | ||
590 | L0 ^= C4(K,4); L1 ^= C5(K,4); L2 ^= C6(K,4); L3 ^= C7(K,4); | ||
591 | |||
592 | L5 ^= C0(K,5); L6 ^= C1(K,5); L7 ^= C2(K,5); L0 ^= C3(K,5); | ||
593 | L1 ^= C4(K,5); L2 ^= C5(K,5); L3 ^= C6(K,5); L4 ^= C7(K,5); | ||
594 | |||
595 | L6 ^= C0(K,6); L7 ^= C1(K,6); L0 ^= C2(K,6); L1 ^= C3(K,6); | ||
596 | L2 ^= C4(K,6); L3 ^= C5(K,6); L4 ^= C6(K,6); L5 ^= C7(K,6); | ||
597 | |||
598 | L7 ^= C0(K,7); L0 ^= C1(K,7); L1 ^= C2(K,7); L2 ^= C3(K,7); | ||
599 | L3 ^= C4(K,7); L4 ^= C5(K,7); L5 ^= C6(K,7); L6 ^= C7(K,7); | ||
600 | |||
601 | K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3; | ||
602 | K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7; | ||
603 | |||
604 | L0 ^= C0(S,0); L1 ^= C1(S,0); L2 ^= C2(S,0); L3 ^= C3(S,0); | ||
605 | L4 ^= C4(S,0); L5 ^= C5(S,0); L6 ^= C6(S,0); L7 ^= C7(S,0); | ||
606 | |||
607 | L1 ^= C0(S,1); L2 ^= C1(S,1); L3 ^= C2(S,1); L4 ^= C3(S,1); | ||
608 | L5 ^= C4(S,1); L6 ^= C5(S,1); L7 ^= C6(S,1); L0 ^= C7(S,1); | ||
609 | |||
610 | L2 ^= C0(S,2); L3 ^= C1(S,2); L4 ^= C2(S,2); L5 ^= C3(S,2); | ||
611 | L6 ^= C4(S,2); L7 ^= C5(S,2); L0 ^= C6(S,2); L1 ^= C7(S,2); | ||
612 | |||
613 | L3 ^= C0(S,3); L4 ^= C1(S,3); L5 ^= C2(S,3); L6 ^= C3(S,3); | ||
614 | L7 ^= C4(S,3); L0 ^= C5(S,3); L1 ^= C6(S,3); L2 ^= C7(S,3); | ||
615 | |||
616 | L4 ^= C0(S,4); L5 ^= C1(S,4); L6 ^= C2(S,4); L7 ^= C3(S,4); | ||
617 | L0 ^= C4(S,4); L1 ^= C5(S,4); L2 ^= C6(S,4); L3 ^= C7(S,4); | ||
618 | |||
619 | L5 ^= C0(S,5); L6 ^= C1(S,5); L7 ^= C2(S,5); L0 ^= C3(S,5); | ||
620 | L1 ^= C4(S,5); L2 ^= C5(S,5); L3 ^= C6(S,5); L4 ^= C7(S,5); | ||
621 | |||
622 | L6 ^= C0(S,6); L7 ^= C1(S,6); L0 ^= C2(S,6); L1 ^= C3(S,6); | ||
623 | L2 ^= C4(S,6); L3 ^= C5(S,6); L4 ^= C6(S,6); L5 ^= C7(S,6); | ||
624 | |||
625 | L7 ^= C0(S,7); L0 ^= C1(S,7); L1 ^= C2(S,7); L2 ^= C3(S,7); | ||
626 | L3 ^= C4(S,7); L4 ^= C5(S,7); L5 ^= C6(S,7); L6 ^= C7(S,7); | ||
627 | |||
628 | S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3; | ||
629 | S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7; | ||
630 | #endif | ||
631 | } | ||
632 | |||
633 | #ifdef STRICT_ALIGNMENT | ||
634 | if ((size_t)p & 7) | ||
635 | { | ||
636 | int i; | ||
637 | for(i=0;i<64;i++) H->c[i] ^= S.c[i] ^ p[i]; | ||
638 | } | ||
639 | else | ||
640 | #endif | ||
641 | { | ||
642 | const u64 *pa=(const u64 *)p; | ||
643 | H->q[0] ^= S.q[0] ^ pa[0]; | ||
644 | H->q[1] ^= S.q[1] ^ pa[1]; | ||
645 | H->q[2] ^= S.q[2] ^ pa[2]; | ||
646 | H->q[3] ^= S.q[3] ^ pa[3]; | ||
647 | H->q[4] ^= S.q[4] ^ pa[4]; | ||
648 | H->q[5] ^= S.q[5] ^ pa[5]; | ||
649 | H->q[6] ^= S.q[6] ^ pa[6]; | ||
650 | H->q[7] ^= S.q[7] ^ pa[7]; | ||
651 | } | ||
652 | #endif | ||
653 | p += 64; | ||
654 | } while(--n); | ||
655 | } | ||
diff --git a/src/lib/libcrypto/whrlpool/wp_dgst.c b/src/lib/libcrypto/whrlpool/wp_dgst.c new file mode 100644 index 0000000000..ee5c5c1bf3 --- /dev/null +++ b/src/lib/libcrypto/whrlpool/wp_dgst.c | |||
@@ -0,0 +1,264 @@ | |||
1 | /** | ||
2 | * The Whirlpool hashing function. | ||
3 | * | ||
4 | * <P> | ||
5 | * <b>References</b> | ||
6 | * | ||
7 | * <P> | ||
8 | * The Whirlpool algorithm was developed by | ||
9 | * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and | ||
10 | * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>. | ||
11 | * | ||
12 | * See | ||
13 | * P.S.L.M. Barreto, V. Rijmen, | ||
14 | * ``The Whirlpool hashing function,'' | ||
15 | * NESSIE submission, 2000 (tweaked version, 2001), | ||
16 | * <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip> | ||
17 | * | ||
18 | * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and | ||
19 | * Vincent Rijmen. Lookup "reference implementations" on | ||
20 | * <http://planeta.terra.com.br/informatica/paulobarreto/> | ||
21 | * | ||
22 | * ============================================================================= | ||
23 | * | ||
24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS | ||
25 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
26 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE | ||
28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
31 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
32 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
33 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||
34 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
35 | * | ||
36 | */ | ||
37 | |||
38 | /* | ||
39 | * OpenSSL-specific implementation notes. | ||
40 | * | ||
41 | * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect | ||
42 | * number of *bytes* as input length argument. Bit-oriented routine | ||
43 | * as specified by authors is called WHIRLPOOL_BitUpdate[!] and | ||
44 | * does not have one-stroke counterpart. | ||
45 | * | ||
46 | * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially | ||
47 | * to serve WHIRLPOOL_Update. This is done for performance. | ||
48 | * | ||
49 | * Unlike authors' reference implementation, block processing | ||
50 | * routine whirlpool_block is designed to operate on multi-block | ||
51 | * input. This is done for perfomance. | ||
52 | */ | ||
53 | |||
54 | #include "wp_locl.h" | ||
55 | #include <string.h> | ||
56 | |||
57 | int WHIRLPOOL_Init (WHIRLPOOL_CTX *c) | ||
58 | { | ||
59 | memset (c,0,sizeof(*c)); | ||
60 | return(1); | ||
61 | } | ||
62 | |||
63 | int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *_inp,size_t bytes) | ||
64 | { | ||
65 | /* Well, largest suitable chunk size actually is | ||
66 | * (1<<(sizeof(size_t)*8-3))-64, but below number | ||
67 | * is large enough for not to care about excessive | ||
68 | * calls to WHIRLPOOL_BitUpdate... */ | ||
69 | size_t chunk = ((size_t)1)<<(sizeof(size_t)*8-4); | ||
70 | const unsigned char *inp = _inp; | ||
71 | |||
72 | while (bytes>=chunk) | ||
73 | { | ||
74 | WHIRLPOOL_BitUpdate(c,inp,chunk*8); | ||
75 | bytes -= chunk; | ||
76 | inp += chunk; | ||
77 | } | ||
78 | if (bytes) | ||
79 | WHIRLPOOL_BitUpdate(c,inp,bytes*8); | ||
80 | |||
81 | return(1); | ||
82 | } | ||
83 | |||
84 | void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *_inp,size_t bits) | ||
85 | { | ||
86 | size_t n; | ||
87 | unsigned int bitoff = c->bitoff, | ||
88 | bitrem = bitoff%8, | ||
89 | inpgap = (8-(unsigned int)bits%8)&7; | ||
90 | const unsigned char *inp=_inp; | ||
91 | |||
92 | /* This 256-bit increment procedure relies on the size_t | ||
93 | * being natural size of CPU register, so that we don't | ||
94 | * have to mask the value in order to detect overflows. */ | ||
95 | c->bitlen[0] += bits; | ||
96 | if (c->bitlen[0] < bits) /* overflow */ | ||
97 | { | ||
98 | n = 1; | ||
99 | do { c->bitlen[n]++; | ||
100 | } while(c->bitlen[n]==0 | ||
101 | && ++n<(WHIRLPOOL_COUNTER/sizeof(size_t))); | ||
102 | } | ||
103 | |||
104 | #ifndef OPENSSL_SMALL_FOOTPRINT | ||
105 | reconsider: | ||
106 | if (inpgap==0 && bitrem==0) /* byte-oriented loop */ | ||
107 | { | ||
108 | while (bits) | ||
109 | { | ||
110 | if (bitoff==0 && (n=bits/WHIRLPOOL_BBLOCK)) | ||
111 | { | ||
112 | whirlpool_block(c,inp,n); | ||
113 | inp += n*WHIRLPOOL_BBLOCK/8; | ||
114 | bits %= WHIRLPOOL_BBLOCK; | ||
115 | } | ||
116 | else | ||
117 | { | ||
118 | unsigned int byteoff = bitoff/8; | ||
119 | |||
120 | bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */ | ||
121 | if (bits >= bitrem) | ||
122 | { | ||
123 | bits -= bitrem; | ||
124 | bitrem /= 8; | ||
125 | memcpy(c->data+byteoff,inp,bitrem); | ||
126 | inp += bitrem; | ||
127 | whirlpool_block(c,c->data,1); | ||
128 | bitoff = 0; | ||
129 | } | ||
130 | else | ||
131 | { | ||
132 | memcpy(c->data+byteoff,inp,bits/8); | ||
133 | bitoff += (unsigned int)bits; | ||
134 | bits = 0; | ||
135 | } | ||
136 | c->bitoff = bitoff; | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | else /* bit-oriented loop */ | ||
141 | #endif | ||
142 | { | ||
143 | /* | ||
144 | inp | ||
145 | | | ||
146 | +-------+-------+------- | ||
147 | ||||||||||||||||||||| | ||
148 | +-------+-------+------- | ||
149 | +-------+-------+-------+-------+------- | ||
150 | |||||||||||||| c->data | ||
151 | +-------+-------+-------+-------+------- | ||
152 | | | ||
153 | c->bitoff/8 | ||
154 | */ | ||
155 | while (bits) | ||
156 | { | ||
157 | unsigned int byteoff = bitoff/8; | ||
158 | unsigned char b; | ||
159 | |||
160 | #ifndef OPENSSL_SMALL_FOOTPRINT | ||
161 | if (bitrem==inpgap) | ||
162 | { | ||
163 | c->data[byteoff++] |= inp[0] & (0xff>>inpgap); | ||
164 | inpgap = 8-inpgap; | ||
165 | bitoff += inpgap; bitrem = 0; /* bitoff%8 */ | ||
166 | bits -= inpgap; inpgap = 0; /* bits%8 */ | ||
167 | inp++; | ||
168 | if (bitoff==WHIRLPOOL_BBLOCK) | ||
169 | { | ||
170 | whirlpool_block(c,c->data,1); | ||
171 | bitoff = 0; | ||
172 | } | ||
173 | c->bitoff = bitoff; | ||
174 | goto reconsider; | ||
175 | } | ||
176 | else | ||
177 | #endif | ||
178 | if (bits>=8) | ||
179 | { | ||
180 | b = ((inp[0]<<inpgap) | (inp[1]>>(8-inpgap))); | ||
181 | b &= 0xff; | ||
182 | if (bitrem) c->data[byteoff++] |= b>>bitrem; | ||
183 | else c->data[byteoff++] = b; | ||
184 | bitoff += 8; | ||
185 | bits -= 8; | ||
186 | inp++; | ||
187 | if (bitoff>=WHIRLPOOL_BBLOCK) | ||
188 | { | ||
189 | whirlpool_block(c,c->data,1); | ||
190 | byteoff = 0; | ||
191 | bitoff %= WHIRLPOOL_BBLOCK; | ||
192 | } | ||
193 | if (bitrem) c->data[byteoff] = b<<(8-bitrem); | ||
194 | } | ||
195 | else /* remaining less than 8 bits */ | ||
196 | { | ||
197 | b = (inp[0]<<inpgap)&0xff; | ||
198 | if (bitrem) c->data[byteoff++] |= b>>bitrem; | ||
199 | else c->data[byteoff++] = b; | ||
200 | bitoff += (unsigned int)bits; | ||
201 | if (bitoff==WHIRLPOOL_BBLOCK) | ||
202 | { | ||
203 | whirlpool_block(c,c->data,1); | ||
204 | byteoff = 0; | ||
205 | bitoff %= WHIRLPOOL_BBLOCK; | ||
206 | } | ||
207 | if (bitrem) c->data[byteoff] = b<<(8-bitrem); | ||
208 | bits = 0; | ||
209 | } | ||
210 | c->bitoff = bitoff; | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | |||
215 | int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c) | ||
216 | { | ||
217 | unsigned int bitoff = c->bitoff, | ||
218 | byteoff = bitoff/8; | ||
219 | size_t i,j,v; | ||
220 | unsigned char *p; | ||
221 | |||
222 | bitoff %= 8; | ||
223 | if (bitoff) c->data[byteoff] |= 0x80>>bitoff; | ||
224 | else c->data[byteoff] = 0x80; | ||
225 | byteoff++; | ||
226 | |||
227 | /* pad with zeros */ | ||
228 | if (byteoff > (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)) | ||
229 | { | ||
230 | if (byteoff<WHIRLPOOL_BBLOCK/8) | ||
231 | memset(&c->data[byteoff],0,WHIRLPOOL_BBLOCK/8-byteoff); | ||
232 | whirlpool_block(c,c->data,1); | ||
233 | byteoff = 0; | ||
234 | } | ||
235 | if (byteoff < (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)) | ||
236 | memset(&c->data[byteoff],0, | ||
237 | (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)-byteoff); | ||
238 | /* smash 256-bit c->bitlen in big-endian order */ | ||
239 | p = &c->data[WHIRLPOOL_BBLOCK/8-1]; /* last byte in c->data */ | ||
240 | for(i=0;i<WHIRLPOOL_COUNTER/sizeof(size_t);i++) | ||
241 | for(v=c->bitlen[i],j=0;j<sizeof(size_t);j++,v>>=8) | ||
242 | *p-- = (unsigned char)(v&0xff); | ||
243 | |||
244 | whirlpool_block(c,c->data,1); | ||
245 | |||
246 | if (md) { | ||
247 | memcpy(md,c->H.c,WHIRLPOOL_DIGEST_LENGTH); | ||
248 | memset(c,0,sizeof(*c)); | ||
249 | return(1); | ||
250 | } | ||
251 | return(0); | ||
252 | } | ||
253 | |||
254 | unsigned char *WHIRLPOOL(const void *inp, size_t bytes,unsigned char *md) | ||
255 | { | ||
256 | WHIRLPOOL_CTX ctx; | ||
257 | static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; | ||
258 | |||
259 | if (md == NULL) md=m; | ||
260 | WHIRLPOOL_Init(&ctx); | ||
261 | WHIRLPOOL_Update(&ctx,inp,bytes); | ||
262 | WHIRLPOOL_Final(md,&ctx); | ||
263 | return(md); | ||
264 | } | ||
diff --git a/src/lib/libcrypto/whrlpool/wp_locl.h b/src/lib/libcrypto/whrlpool/wp_locl.h new file mode 100644 index 0000000000..94e56a39f1 --- /dev/null +++ b/src/lib/libcrypto/whrlpool/wp_locl.h | |||
@@ -0,0 +1,3 @@ | |||
1 | #include <openssl/whrlpool.h> | ||
2 | |||
3 | void whirlpool_block(WHIRLPOOL_CTX *,const void *,size_t); | ||
diff --git a/src/lib/libcrypto/x509/x509_vpm.c b/src/lib/libcrypto/x509/x509_vpm.c index 2b06718aec..dfd89d89fa 100644 --- a/src/lib/libcrypto/x509/x509_vpm.c +++ b/src/lib/libcrypto/x509/x509_vpm.c | |||
@@ -74,6 +74,7 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param) | |||
74 | param->name = NULL; | 74 | param->name = NULL; |
75 | param->purpose = 0; | 75 | param->purpose = 0; |
76 | param->trust = 0; | 76 | param->trust = 0; |
77 | /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/ | ||
77 | param->inh_flags = 0; | 78 | param->inh_flags = 0; |
78 | param->flags = 0; | 79 | param->flags = 0; |
79 | param->depth = -1; | 80 | param->depth = -1; |
@@ -198,8 +199,12 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, | |||
198 | int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, | 199 | int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, |
199 | const X509_VERIFY_PARAM *from) | 200 | const X509_VERIFY_PARAM *from) |
200 | { | 201 | { |
202 | unsigned long save_flags = to->inh_flags; | ||
203 | int ret; | ||
201 | to->inh_flags |= X509_VP_FLAG_DEFAULT; | 204 | to->inh_flags |= X509_VP_FLAG_DEFAULT; |
202 | return X509_VERIFY_PARAM_inherit(to, from); | 205 | ret = X509_VERIFY_PARAM_inherit(to, from); |
206 | to->inh_flags = save_flags; | ||
207 | return ret; | ||
203 | } | 208 | } |
204 | 209 | ||
205 | int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) | 210 | int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) |
@@ -324,7 +329,7 @@ static const X509_VERIFY_PARAM default_table[] = { | |||
324 | NULL /* policies */ | 329 | NULL /* policies */ |
325 | }, | 330 | }, |
326 | { | 331 | { |
327 | "pkcs7", /* S/MIME signing parameters */ | 332 | "pkcs7", /* S/MIME sign parameters */ |
328 | 0, /* Check time */ | 333 | 0, /* Check time */ |
329 | 0, /* internal flags */ | 334 | 0, /* internal flags */ |
330 | 0, /* flags */ | 335 | 0, /* flags */ |
@@ -334,7 +339,7 @@ static const X509_VERIFY_PARAM default_table[] = { | |||
334 | NULL /* policies */ | 339 | NULL /* policies */ |
335 | }, | 340 | }, |
336 | { | 341 | { |
337 | "smime_sign", /* S/MIME signing parameters */ | 342 | "smime_sign", /* S/MIME sign parameters */ |
338 | 0, /* Check time */ | 343 | 0, /* Check time */ |
339 | 0, /* internal flags */ | 344 | 0, /* internal flags */ |
340 | 0, /* flags */ | 345 | 0, /* flags */ |
@@ -366,12 +371,17 @@ static const X509_VERIFY_PARAM default_table[] = { | |||
366 | 371 | ||
367 | static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; | 372 | static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; |
368 | 373 | ||
369 | static int table_cmp(const void *pa, const void *pb) | 374 | static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b) |
375 | |||
370 | { | 376 | { |
371 | const X509_VERIFY_PARAM *a = pa, *b = pb; | ||
372 | return strcmp(a->name, b->name); | 377 | return strcmp(a->name, b->name); |
373 | } | 378 | } |
374 | 379 | ||
380 | DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, | ||
381 | table); | ||
382 | IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, | ||
383 | table); | ||
384 | |||
375 | static int param_cmp(const X509_VERIFY_PARAM * const *a, | 385 | static int param_cmp(const X509_VERIFY_PARAM * const *a, |
376 | const X509_VERIFY_PARAM * const *b) | 386 | const X509_VERIFY_PARAM * const *b) |
377 | { | 387 | { |
@@ -407,6 +417,7 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) | |||
407 | { | 417 | { |
408 | int idx; | 418 | int idx; |
409 | X509_VERIFY_PARAM pm; | 419 | X509_VERIFY_PARAM pm; |
420 | |||
410 | pm.name = (char *)name; | 421 | pm.name = (char *)name; |
411 | if (param_table) | 422 | if (param_table) |
412 | { | 423 | { |
@@ -414,11 +425,8 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) | |||
414 | if (idx != -1) | 425 | if (idx != -1) |
415 | return sk_X509_VERIFY_PARAM_value(param_table, idx); | 426 | return sk_X509_VERIFY_PARAM_value(param_table, idx); |
416 | } | 427 | } |
417 | return (const X509_VERIFY_PARAM *) OBJ_bsearch((char *)&pm, | 428 | return OBJ_bsearch_table(&pm, default_table, |
418 | (char *)&default_table, | 429 | sizeof(default_table)/sizeof(X509_VERIFY_PARAM)); |
419 | sizeof(default_table)/sizeof(X509_VERIFY_PARAM), | ||
420 | sizeof(X509_VERIFY_PARAM), | ||
421 | table_cmp); | ||
422 | } | 430 | } |
423 | 431 | ||
424 | void X509_VERIFY_PARAM_table_cleanup(void) | 432 | void X509_VERIFY_PARAM_table_cleanup(void) |
diff --git a/src/lib/libcrypto/x509v3/pcy_cache.c b/src/lib/libcrypto/x509v3/pcy_cache.c index 1030931b71..172b7e7ee4 100644 --- a/src/lib/libcrypto/x509v3/pcy_cache.c +++ b/src/lib/libcrypto/x509v3/pcy_cache.c | |||
@@ -139,7 +139,6 @@ static int policy_cache_new(X509 *x) | |||
139 | return 0; | 139 | return 0; |
140 | cache->anyPolicy = NULL; | 140 | cache->anyPolicy = NULL; |
141 | cache->data = NULL; | 141 | cache->data = NULL; |
142 | cache->maps = NULL; | ||
143 | cache->any_skip = -1; | 142 | cache->any_skip = -1; |
144 | cache->explicit_skip = -1; | 143 | cache->explicit_skip = -1; |
145 | cache->map_skip = -1; | 144 | cache->map_skip = -1; |
diff --git a/src/lib/libcrypto/x509v3/pcy_int.h b/src/lib/libcrypto/x509v3/pcy_int.h index 3780de4fcd..ccff92846e 100644 --- a/src/lib/libcrypto/x509v3/pcy_int.h +++ b/src/lib/libcrypto/x509v3/pcy_int.h | |||
@@ -56,12 +56,10 @@ | |||
56 | * | 56 | * |
57 | */ | 57 | */ |
58 | 58 | ||
59 | DECLARE_STACK_OF(X509_POLICY_DATA) | ||
60 | DECLARE_STACK_OF(X509_POLICY_REF) | ||
61 | DECLARE_STACK_OF(X509_POLICY_NODE) | ||
62 | 59 | ||
63 | typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; | 60 | typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; |
64 | typedef struct X509_POLICY_REF_st X509_POLICY_REF; | 61 | |
62 | DECLARE_STACK_OF(X509_POLICY_DATA) | ||
65 | 63 | ||
66 | /* Internal structures */ | 64 | /* Internal structures */ |
67 | 65 | ||
@@ -110,16 +108,6 @@ struct X509_POLICY_DATA_st | |||
110 | 108 | ||
111 | #define POLICY_DATA_FLAG_CRITICAL 0x10 | 109 | #define POLICY_DATA_FLAG_CRITICAL 0x10 |
112 | 110 | ||
113 | /* This structure is an entry from a table of mapped policies which | ||
114 | * cross reference the policy it refers to. | ||
115 | */ | ||
116 | |||
117 | struct X509_POLICY_REF_st | ||
118 | { | ||
119 | ASN1_OBJECT *subjectDomainPolicy; | ||
120 | const X509_POLICY_DATA *data; | ||
121 | }; | ||
122 | |||
123 | /* This structure is cached with a certificate */ | 111 | /* This structure is cached with a certificate */ |
124 | 112 | ||
125 | struct X509_POLICY_CACHE_st { | 113 | struct X509_POLICY_CACHE_st { |
@@ -127,8 +115,6 @@ struct X509_POLICY_CACHE_st { | |||
127 | X509_POLICY_DATA *anyPolicy; | 115 | X509_POLICY_DATA *anyPolicy; |
128 | /* other policy data */ | 116 | /* other policy data */ |
129 | STACK_OF(X509_POLICY_DATA) *data; | 117 | STACK_OF(X509_POLICY_DATA) *data; |
130 | /* If policyMappings extension present a table of mapped policies */ | ||
131 | STACK_OF(X509_POLICY_REF) *maps; | ||
132 | /* If InhibitAnyPolicy present this is its value or -1 if absent. */ | 118 | /* If InhibitAnyPolicy present this is its value or -1 if absent. */ |
133 | long any_skip; | 119 | long any_skip; |
134 | /* If policyConstraints and requireExplicitPolicy present this is its | 120 | /* If policyConstraints and requireExplicitPolicy present this is its |
@@ -193,7 +179,7 @@ struct X509_POLICY_TREE_st | |||
193 | 179 | ||
194 | /* Internal functions */ | 180 | /* Internal functions */ |
195 | 181 | ||
196 | X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, | 182 | X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, |
197 | int crit); | 183 | int crit); |
198 | void policy_data_free(X509_POLICY_DATA *data); | 184 | void policy_data_free(X509_POLICY_DATA *data); |
199 | 185 | ||
@@ -209,15 +195,18 @@ void policy_cache_init(void); | |||
209 | void policy_cache_free(X509_POLICY_CACHE *cache); | 195 | void policy_cache_free(X509_POLICY_CACHE *cache); |
210 | 196 | ||
211 | X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, | 197 | X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, |
198 | const X509_POLICY_NODE *parent, | ||
212 | const ASN1_OBJECT *id); | 199 | const ASN1_OBJECT *id); |
213 | 200 | ||
214 | X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, | 201 | X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, |
215 | const ASN1_OBJECT *id); | 202 | const ASN1_OBJECT *id); |
216 | 203 | ||
217 | X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, | 204 | X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, |
218 | X509_POLICY_DATA *data, | 205 | const X509_POLICY_DATA *data, |
219 | X509_POLICY_NODE *parent, | 206 | X509_POLICY_NODE *parent, |
220 | X509_POLICY_TREE *tree); | 207 | X509_POLICY_TREE *tree); |
221 | void policy_node_free(X509_POLICY_NODE *node); | 208 | void policy_node_free(X509_POLICY_NODE *node); |
209 | int policy_node_match(const X509_POLICY_LEVEL *lvl, | ||
210 | const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); | ||
222 | 211 | ||
223 | const X509_POLICY_CACHE *policy_cache_set(X509 *x); | 212 | const X509_POLICY_CACHE *policy_cache_set(X509 *x); |
diff --git a/src/lib/libcrypto/x509v3/pcy_map.c b/src/lib/libcrypto/x509v3/pcy_map.c index f28796e6d4..21163b529d 100644 --- a/src/lib/libcrypto/x509v3/pcy_map.c +++ b/src/lib/libcrypto/x509v3/pcy_map.c | |||
@@ -62,31 +62,6 @@ | |||
62 | 62 | ||
63 | #include "pcy_int.h" | 63 | #include "pcy_int.h" |
64 | 64 | ||
65 | static int ref_cmp(const X509_POLICY_REF * const *a, | ||
66 | const X509_POLICY_REF * const *b) | ||
67 | { | ||
68 | return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy); | ||
69 | } | ||
70 | |||
71 | static void policy_map_free(X509_POLICY_REF *map) | ||
72 | { | ||
73 | if (map->subjectDomainPolicy) | ||
74 | ASN1_OBJECT_free(map->subjectDomainPolicy); | ||
75 | OPENSSL_free(map); | ||
76 | } | ||
77 | |||
78 | static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *id) | ||
79 | { | ||
80 | X509_POLICY_REF tmp; | ||
81 | int idx; | ||
82 | tmp.subjectDomainPolicy = id; | ||
83 | |||
84 | idx = sk_X509_POLICY_REF_find(cache->maps, &tmp); | ||
85 | if (idx == -1) | ||
86 | return NULL; | ||
87 | return sk_X509_POLICY_REF_value(cache->maps, idx); | ||
88 | } | ||
89 | |||
90 | /* Set policy mapping entries in cache. | 65 | /* Set policy mapping entries in cache. |
91 | * Note: this modifies the passed POLICY_MAPPINGS structure | 66 | * Note: this modifies the passed POLICY_MAPPINGS structure |
92 | */ | 67 | */ |
@@ -94,7 +69,6 @@ static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *i | |||
94 | int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) | 69 | int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) |
95 | { | 70 | { |
96 | POLICY_MAPPING *map; | 71 | POLICY_MAPPING *map; |
97 | X509_POLICY_REF *ref = NULL; | ||
98 | X509_POLICY_DATA *data; | 72 | X509_POLICY_DATA *data; |
99 | X509_POLICY_CACHE *cache = x->policy_cache; | 73 | X509_POLICY_CACHE *cache = x->policy_cache; |
100 | int i; | 74 | int i; |
@@ -104,7 +78,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) | |||
104 | ret = -1; | 78 | ret = -1; |
105 | goto bad_mapping; | 79 | goto bad_mapping; |
106 | } | 80 | } |
107 | cache->maps = sk_X509_POLICY_REF_new(ref_cmp); | ||
108 | for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) | 81 | for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) |
109 | { | 82 | { |
110 | map = sk_POLICY_MAPPING_value(maps, i); | 83 | map = sk_POLICY_MAPPING_value(maps, i); |
@@ -116,13 +89,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) | |||
116 | goto bad_mapping; | 89 | goto bad_mapping; |
117 | } | 90 | } |
118 | 91 | ||
119 | /* If we've already mapped from this OID bad mapping */ | ||
120 | if (policy_map_find(cache, map->subjectDomainPolicy) != NULL) | ||
121 | { | ||
122 | ret = -1; | ||
123 | goto bad_mapping; | ||
124 | } | ||
125 | |||
126 | /* Attempt to find matching policy data */ | 92 | /* Attempt to find matching policy data */ |
127 | data = policy_cache_find_data(cache, map->issuerDomainPolicy); | 93 | data = policy_cache_find_data(cache, map->issuerDomainPolicy); |
128 | /* If we don't have anyPolicy can't map */ | 94 | /* If we don't have anyPolicy can't map */ |
@@ -138,7 +104,7 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) | |||
138 | if (!data) | 104 | if (!data) |
139 | goto bad_mapping; | 105 | goto bad_mapping; |
140 | data->qualifier_set = cache->anyPolicy->qualifier_set; | 106 | data->qualifier_set = cache->anyPolicy->qualifier_set; |
141 | map->issuerDomainPolicy = NULL; | 107 | /*map->issuerDomainPolicy = NULL;*/ |
142 | data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; | 108 | data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; |
143 | data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; | 109 | data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; |
144 | if (!sk_X509_POLICY_DATA_push(cache->data, data)) | 110 | if (!sk_X509_POLICY_DATA_push(cache->data, data)) |
@@ -149,23 +115,10 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) | |||
149 | } | 115 | } |
150 | else | 116 | else |
151 | data->flags |= POLICY_DATA_FLAG_MAPPED; | 117 | data->flags |= POLICY_DATA_FLAG_MAPPED; |
152 | |||
153 | if (!sk_ASN1_OBJECT_push(data->expected_policy_set, | 118 | if (!sk_ASN1_OBJECT_push(data->expected_policy_set, |
154 | map->subjectDomainPolicy)) | 119 | map->subjectDomainPolicy)) |
155 | goto bad_mapping; | 120 | goto bad_mapping; |
156 | |||
157 | ref = OPENSSL_malloc(sizeof(X509_POLICY_REF)); | ||
158 | if (!ref) | ||
159 | goto bad_mapping; | ||
160 | |||
161 | ref->subjectDomainPolicy = map->subjectDomainPolicy; | ||
162 | map->subjectDomainPolicy = NULL; | 121 | map->subjectDomainPolicy = NULL; |
163 | ref->data = data; | ||
164 | |||
165 | if (!sk_X509_POLICY_REF_push(cache->maps, ref)) | ||
166 | goto bad_mapping; | ||
167 | |||
168 | ref = NULL; | ||
169 | 122 | ||
170 | } | 123 | } |
171 | 124 | ||
@@ -173,13 +126,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) | |||
173 | bad_mapping: | 126 | bad_mapping: |
174 | if (ret == -1) | 127 | if (ret == -1) |
175 | x->ex_flags |= EXFLAG_INVALID_POLICY; | 128 | x->ex_flags |= EXFLAG_INVALID_POLICY; |
176 | if (ref) | ||
177 | policy_map_free(ref); | ||
178 | if (ret <= 0) | ||
179 | { | ||
180 | sk_X509_POLICY_REF_pop_free(cache->maps, policy_map_free); | ||
181 | cache->maps = NULL; | ||
182 | } | ||
183 | sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); | 129 | sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); |
184 | return ret; | 130 | return ret; |
185 | 131 | ||
diff --git a/src/lib/libcrypto/x509v3/pcy_node.c b/src/lib/libcrypto/x509v3/pcy_node.c index 6587cb05ab..bd1e7f1ae8 100644 --- a/src/lib/libcrypto/x509v3/pcy_node.c +++ b/src/lib/libcrypto/x509v3/pcy_node.c | |||
@@ -92,13 +92,25 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, | |||
92 | } | 92 | } |
93 | 93 | ||
94 | X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, | 94 | X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, |
95 | const X509_POLICY_NODE *parent, | ||
95 | const ASN1_OBJECT *id) | 96 | const ASN1_OBJECT *id) |
96 | { | 97 | { |
97 | return tree_find_sk(level->nodes, id); | 98 | X509_POLICY_NODE *node; |
99 | int i; | ||
100 | for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) | ||
101 | { | ||
102 | node = sk_X509_POLICY_NODE_value(level->nodes, i); | ||
103 | if (node->parent == parent) | ||
104 | { | ||
105 | if (!OBJ_cmp(node->data->valid_policy, id)) | ||
106 | return node; | ||
107 | } | ||
108 | } | ||
109 | return NULL; | ||
98 | } | 110 | } |
99 | 111 | ||
100 | X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, | 112 | X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, |
101 | X509_POLICY_DATA *data, | 113 | const X509_POLICY_DATA *data, |
102 | X509_POLICY_NODE *parent, | 114 | X509_POLICY_NODE *parent, |
103 | X509_POLICY_TREE *tree) | 115 | X509_POLICY_TREE *tree) |
104 | { | 116 | { |
@@ -155,4 +167,31 @@ void policy_node_free(X509_POLICY_NODE *node) | |||
155 | OPENSSL_free(node); | 167 | OPENSSL_free(node); |
156 | } | 168 | } |
157 | 169 | ||
170 | /* See if a policy node matches a policy OID. If mapping enabled look through | ||
171 | * expected policy set otherwise just valid policy. | ||
172 | */ | ||
173 | |||
174 | int policy_node_match(const X509_POLICY_LEVEL *lvl, | ||
175 | const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) | ||
176 | { | ||
177 | int i; | ||
178 | ASN1_OBJECT *policy_oid; | ||
179 | const X509_POLICY_DATA *x = node->data; | ||
180 | |||
181 | if ( (lvl->flags & X509_V_FLAG_INHIBIT_MAP) | ||
182 | || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) | ||
183 | { | ||
184 | if (!OBJ_cmp(x->valid_policy, oid)) | ||
185 | return 1; | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) | ||
190 | { | ||
191 | policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i); | ||
192 | if (!OBJ_cmp(policy_oid, oid)) | ||
193 | return 1; | ||
194 | } | ||
195 | return 0; | ||
158 | 196 | ||
197 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_ncons.c b/src/lib/libcrypto/x509v3/v3_ncons.c index 4e706be3e1..689df46acd 100644 --- a/src/lib/libcrypto/x509v3/v3_ncons.c +++ b/src/lib/libcrypto/x509v3/v3_ncons.c | |||
@@ -63,15 +63,22 @@ | |||
63 | #include <openssl/conf.h> | 63 | #include <openssl/conf.h> |
64 | #include <openssl/x509v3.h> | 64 | #include <openssl/x509v3.h> |
65 | 65 | ||
66 | static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | 66 | static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, |
67 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | 67 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); |
68 | static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | 68 | static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, |
69 | void *a, BIO *bp, int ind); | 69 | void *a, BIO *bp, int ind); |
70 | static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, | 70 | static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, |
71 | STACK_OF(GENERAL_SUBTREE) *trees, | 71 | STACK_OF(GENERAL_SUBTREE) *trees, |
72 | BIO *bp, int ind, char *name); | 72 | BIO *bp, int ind, char *name); |
73 | static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); | 73 | static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); |
74 | 74 | ||
75 | static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); | ||
76 | static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); | ||
77 | static int nc_dn(X509_NAME *sub, X509_NAME *nm); | ||
78 | static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); | ||
79 | static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); | ||
80 | static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); | ||
81 | |||
75 | const X509V3_EXT_METHOD v3_name_constraints = { | 82 | const X509V3_EXT_METHOD v3_name_constraints = { |
76 | NID_name_constraints, 0, | 83 | NID_name_constraints, 0, |
77 | ASN1_ITEM_ref(NAME_CONSTRAINTS), | 84 | ASN1_ITEM_ref(NAME_CONSTRAINTS), |
@@ -99,8 +106,8 @@ ASN1_SEQUENCE(NAME_CONSTRAINTS) = { | |||
99 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) | 106 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) |
100 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) | 107 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) |
101 | 108 | ||
102 | static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | 109 | static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, |
103 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | 110 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) |
104 | { | 111 | { |
105 | int i; | 112 | int i; |
106 | CONF_VALUE tval, *val; | 113 | CONF_VALUE tval, *val; |
@@ -155,8 +162,8 @@ static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | |||
155 | 162 | ||
156 | 163 | ||
157 | 164 | ||
158 | static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | 165 | static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, |
159 | void *a, BIO *bp, int ind) | 166 | BIO *bp, int ind) |
160 | { | 167 | { |
161 | NAME_CONSTRAINTS *ncons = a; | 168 | NAME_CONSTRAINTS *ncons = a; |
162 | do_i2r_name_constraints(method, ncons->permittedSubtrees, | 169 | do_i2r_name_constraints(method, ncons->permittedSubtrees, |
@@ -166,9 +173,9 @@ static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | |||
166 | return 1; | 173 | return 1; |
167 | } | 174 | } |
168 | 175 | ||
169 | static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, | 176 | static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, |
170 | STACK_OF(GENERAL_SUBTREE) *trees, | 177 | STACK_OF(GENERAL_SUBTREE) *trees, |
171 | BIO *bp, int ind, char *name) | 178 | BIO *bp, int ind, char *name) |
172 | { | 179 | { |
173 | GENERAL_SUBTREE *tree; | 180 | GENERAL_SUBTREE *tree; |
174 | int i; | 181 | int i; |
@@ -218,3 +225,282 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) | |||
218 | return 1; | 225 | return 1; |
219 | } | 226 | } |
220 | 227 | ||
228 | /* Check a certificate conforms to a specified set of constraints. | ||
229 | * Return values: | ||
230 | * X509_V_OK: All constraints obeyed. | ||
231 | * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. | ||
232 | * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. | ||
233 | * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. | ||
234 | * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. | ||
235 | * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. | ||
236 | * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name | ||
237 | |||
238 | */ | ||
239 | |||
240 | int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) | ||
241 | { | ||
242 | int r, i; | ||
243 | X509_NAME *nm; | ||
244 | |||
245 | nm = X509_get_subject_name(x); | ||
246 | |||
247 | if (X509_NAME_entry_count(nm) > 0) | ||
248 | { | ||
249 | GENERAL_NAME gntmp; | ||
250 | gntmp.type = GEN_DIRNAME; | ||
251 | gntmp.d.directoryName = nm; | ||
252 | |||
253 | r = nc_match(&gntmp, nc); | ||
254 | |||
255 | if (r != X509_V_OK) | ||
256 | return r; | ||
257 | |||
258 | gntmp.type = GEN_EMAIL; | ||
259 | |||
260 | |||
261 | /* Process any email address attributes in subject name */ | ||
262 | |||
263 | for (i = -1;;) | ||
264 | { | ||
265 | X509_NAME_ENTRY *ne; | ||
266 | i = X509_NAME_get_index_by_NID(nm, | ||
267 | NID_pkcs9_emailAddress, | ||
268 | i); | ||
269 | if (i == -1) | ||
270 | break; | ||
271 | ne = X509_NAME_get_entry(nm, i); | ||
272 | gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); | ||
273 | if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) | ||
274 | return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; | ||
275 | |||
276 | r = nc_match(&gntmp, nc); | ||
277 | |||
278 | if (r != X509_V_OK) | ||
279 | return r; | ||
280 | } | ||
281 | |||
282 | } | ||
283 | |||
284 | for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) | ||
285 | { | ||
286 | GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); | ||
287 | r = nc_match(gen, nc); | ||
288 | if (r != X509_V_OK) | ||
289 | return r; | ||
290 | } | ||
291 | |||
292 | return X509_V_OK; | ||
293 | |||
294 | } | ||
295 | |||
296 | static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) | ||
297 | { | ||
298 | GENERAL_SUBTREE *sub; | ||
299 | int i, r, match = 0; | ||
300 | |||
301 | /* Permitted subtrees: if any subtrees exist of matching the type | ||
302 | * at least one subtree must match. | ||
303 | */ | ||
304 | |||
305 | for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) | ||
306 | { | ||
307 | sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); | ||
308 | if (gen->type != sub->base->type) | ||
309 | continue; | ||
310 | if (sub->minimum || sub->maximum) | ||
311 | return X509_V_ERR_SUBTREE_MINMAX; | ||
312 | /* If we already have a match don't bother trying any more */ | ||
313 | if (match == 2) | ||
314 | continue; | ||
315 | if (match == 0) | ||
316 | match = 1; | ||
317 | r = nc_match_single(gen, sub->base); | ||
318 | if (r == X509_V_OK) | ||
319 | match = 2; | ||
320 | else if (r != X509_V_ERR_PERMITTED_VIOLATION) | ||
321 | return r; | ||
322 | } | ||
323 | |||
324 | if (match == 1) | ||
325 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
326 | |||
327 | /* Excluded subtrees: must not match any of these */ | ||
328 | |||
329 | for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) | ||
330 | { | ||
331 | sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); | ||
332 | if (gen->type != sub->base->type) | ||
333 | continue; | ||
334 | if (sub->minimum || sub->maximum) | ||
335 | return X509_V_ERR_SUBTREE_MINMAX; | ||
336 | |||
337 | r = nc_match_single(gen, sub->base); | ||
338 | if (r == X509_V_OK) | ||
339 | return X509_V_ERR_EXCLUDED_VIOLATION; | ||
340 | else if (r != X509_V_ERR_PERMITTED_VIOLATION) | ||
341 | return r; | ||
342 | |||
343 | } | ||
344 | |||
345 | return X509_V_OK; | ||
346 | |||
347 | } | ||
348 | |||
349 | static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) | ||
350 | { | ||
351 | switch(base->type) | ||
352 | { | ||
353 | case GEN_DIRNAME: | ||
354 | return nc_dn(gen->d.directoryName, base->d.directoryName); | ||
355 | |||
356 | case GEN_DNS: | ||
357 | return nc_dns(gen->d.dNSName, base->d.dNSName); | ||
358 | |||
359 | case GEN_EMAIL: | ||
360 | return nc_email(gen->d.rfc822Name, base->d.rfc822Name); | ||
361 | |||
362 | case GEN_URI: | ||
363 | return nc_uri(gen->d.uniformResourceIdentifier, | ||
364 | base->d.uniformResourceIdentifier); | ||
365 | |||
366 | default: | ||
367 | return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; | ||
368 | } | ||
369 | |||
370 | } | ||
371 | |||
372 | /* directoryName name constraint matching. | ||
373 | * The canonical encoding of X509_NAME makes this comparison easy. It is | ||
374 | * matched if the subtree is a subset of the name. | ||
375 | */ | ||
376 | |||
377 | static int nc_dn(X509_NAME *nm, X509_NAME *base) | ||
378 | { | ||
379 | /* Ensure canonical encodings are up to date. */ | ||
380 | if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) | ||
381 | return X509_V_ERR_OUT_OF_MEM; | ||
382 | if (base->modified && i2d_X509_NAME(base, NULL) < 0) | ||
383 | return X509_V_ERR_OUT_OF_MEM; | ||
384 | if (base->canon_enclen > nm->canon_enclen) | ||
385 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
386 | if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) | ||
387 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
388 | return X509_V_OK; | ||
389 | } | ||
390 | |||
391 | static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) | ||
392 | { | ||
393 | char *baseptr = (char *)base->data; | ||
394 | char *dnsptr = (char *)dns->data; | ||
395 | /* Empty matches everything */ | ||
396 | if (!*baseptr) | ||
397 | return X509_V_OK; | ||
398 | /* Otherwise can add zero or more components on the left so | ||
399 | * compare RHS and if dns is longer and expect '.' as preceding | ||
400 | * character. | ||
401 | */ | ||
402 | if (dns->length > base->length) | ||
403 | { | ||
404 | dnsptr += dns->length - base->length; | ||
405 | if (dnsptr[-1] != '.') | ||
406 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
407 | } | ||
408 | |||
409 | if (strcasecmp(baseptr, dnsptr)) | ||
410 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
411 | |||
412 | return X509_V_OK; | ||
413 | |||
414 | } | ||
415 | |||
416 | static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) | ||
417 | { | ||
418 | const char *baseptr = (char *)base->data; | ||
419 | const char *emlptr = (char *)eml->data; | ||
420 | |||
421 | const char *baseat = strchr(baseptr, '@'); | ||
422 | const char *emlat = strchr(emlptr, '@'); | ||
423 | if (!emlat) | ||
424 | return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; | ||
425 | /* Special case: inital '.' is RHS match */ | ||
426 | if (!baseat && (*baseptr == '.')) | ||
427 | { | ||
428 | if (eml->length > base->length) | ||
429 | { | ||
430 | emlptr += eml->length - base->length; | ||
431 | if (!strcasecmp(baseptr, emlptr)) | ||
432 | return X509_V_OK; | ||
433 | } | ||
434 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
435 | } | ||
436 | |||
437 | /* If we have anything before '@' match local part */ | ||
438 | |||
439 | if (baseat) | ||
440 | { | ||
441 | if (baseat != baseptr) | ||
442 | { | ||
443 | if ((baseat - baseptr) != (emlat - emlptr)) | ||
444 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
445 | /* Case sensitive match of local part */ | ||
446 | if (strncmp(baseptr, emlptr, emlat - emlptr)) | ||
447 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
448 | } | ||
449 | /* Position base after '@' */ | ||
450 | baseptr = baseat + 1; | ||
451 | } | ||
452 | emlptr = emlat + 1; | ||
453 | /* Just have hostname left to match: case insensitive */ | ||
454 | if (strcasecmp(baseptr, emlptr)) | ||
455 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
456 | |||
457 | return X509_V_OK; | ||
458 | |||
459 | } | ||
460 | |||
461 | static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) | ||
462 | { | ||
463 | const char *baseptr = (char *)base->data; | ||
464 | const char *hostptr = (char *)uri->data; | ||
465 | const char *p = strchr(hostptr, ':'); | ||
466 | int hostlen; | ||
467 | /* Check for foo:// and skip past it */ | ||
468 | if (!p || (p[1] != '/') || (p[2] != '/')) | ||
469 | return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; | ||
470 | hostptr = p + 3; | ||
471 | |||
472 | /* Determine length of hostname part of URI */ | ||
473 | |||
474 | /* Look for a port indicator as end of hostname first */ | ||
475 | |||
476 | p = strchr(hostptr, ':'); | ||
477 | /* Otherwise look for trailing slash */ | ||
478 | if (!p) | ||
479 | p = strchr(hostptr, '/'); | ||
480 | |||
481 | if (!p) | ||
482 | hostlen = strlen(hostptr); | ||
483 | else | ||
484 | hostlen = p - hostptr; | ||
485 | |||
486 | if (hostlen == 0) | ||
487 | return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; | ||
488 | |||
489 | /* Special case: inital '.' is RHS match */ | ||
490 | if (*baseptr == '.') | ||
491 | { | ||
492 | if (hostlen > base->length) | ||
493 | { | ||
494 | p = hostptr + hostlen - base->length; | ||
495 | if (!strncasecmp(p, baseptr, base->length)) | ||
496 | return X509_V_OK; | ||
497 | } | ||
498 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
499 | } | ||
500 | |||
501 | if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen)) | ||
502 | return X509_V_ERR_PERMITTED_VIOLATION; | ||
503 | |||
504 | return X509_V_OK; | ||
505 | |||
506 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_pci.c b/src/lib/libcrypto/x509v3/v3_pci.c index 601211f416..0dcfa004fe 100644 --- a/src/lib/libcrypto/x509v3/v3_pci.c +++ b/src/lib/libcrypto/x509v3/v3_pci.c | |||
@@ -82,7 +82,7 @@ static int process_pci_value(CONF_VALUE *val, | |||
82 | { | 82 | { |
83 | if (*language) | 83 | if (*language) |
84 | { | 84 | { |
85 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED); | 85 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); |
86 | X509V3_conf_err(val); | 86 | X509V3_conf_err(val); |
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
@@ -97,7 +97,7 @@ static int process_pci_value(CONF_VALUE *val, | |||
97 | { | 97 | { |
98 | if (*pathlen) | 98 | if (*pathlen) |
99 | { | 99 | { |
100 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED); | 100 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); |
101 | X509V3_conf_err(val); | 101 | X509V3_conf_err(val); |
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
@@ -128,7 +128,12 @@ static int process_pci_value(CONF_VALUE *val, | |||
128 | unsigned char *tmp_data2 = | 128 | unsigned char *tmp_data2 = |
129 | string_to_hex(val->value + 4, &val_len); | 129 | string_to_hex(val->value + 4, &val_len); |
130 | 130 | ||
131 | if (!tmp_data2) goto err; | 131 | if (!tmp_data2) |
132 | { | ||
133 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_ILLEGAL_HEX_DIGIT); | ||
134 | X509V3_conf_err(val); | ||
135 | goto err; | ||
136 | } | ||
132 | 137 | ||
133 | tmp_data = OPENSSL_realloc((*policy)->data, | 138 | tmp_data = OPENSSL_realloc((*policy)->data, |
134 | (*policy)->length + val_len + 1); | 139 | (*policy)->length + val_len + 1); |
@@ -140,6 +145,17 @@ static int process_pci_value(CONF_VALUE *val, | |||
140 | (*policy)->length += val_len; | 145 | (*policy)->length += val_len; |
141 | (*policy)->data[(*policy)->length] = '\0'; | 146 | (*policy)->data[(*policy)->length] = '\0'; |
142 | } | 147 | } |
148 | else | ||
149 | { | ||
150 | OPENSSL_free(tmp_data2); | ||
151 | /* realloc failure implies the original data space is b0rked too! */ | ||
152 | (*policy)->data = NULL; | ||
153 | (*policy)->length = 0; | ||
154 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE); | ||
155 | X509V3_conf_err(val); | ||
156 | goto err; | ||
157 | } | ||
158 | OPENSSL_free(tmp_data2); | ||
143 | } | 159 | } |
144 | else if (strncmp(val->value, "file:", 5) == 0) | 160 | else if (strncmp(val->value, "file:", 5) == 0) |
145 | { | 161 | { |
@@ -169,6 +185,7 @@ static int process_pci_value(CONF_VALUE *val, | |||
169 | (*policy)->length += n; | 185 | (*policy)->length += n; |
170 | (*policy)->data[(*policy)->length] = '\0'; | 186 | (*policy)->data[(*policy)->length] = '\0'; |
171 | } | 187 | } |
188 | BIO_free_all(b); | ||
172 | 189 | ||
173 | if (n < 0) | 190 | if (n < 0) |
174 | { | 191 | { |
@@ -190,6 +207,15 @@ static int process_pci_value(CONF_VALUE *val, | |||
190 | (*policy)->length += val_len; | 207 | (*policy)->length += val_len; |
191 | (*policy)->data[(*policy)->length] = '\0'; | 208 | (*policy)->data[(*policy)->length] = '\0'; |
192 | } | 209 | } |
210 | else | ||
211 | { | ||
212 | /* realloc failure implies the original data space is b0rked too! */ | ||
213 | (*policy)->data = NULL; | ||
214 | (*policy)->length = 0; | ||
215 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE); | ||
216 | X509V3_conf_err(val); | ||
217 | goto err; | ||
218 | } | ||
193 | } | 219 | } |
194 | else | 220 | else |
195 | { | 221 | { |
diff --git a/src/lib/libcrypto/x509v3/v3_pcons.c b/src/lib/libcrypto/x509v3/v3_pcons.c index 86c0ff70e6..30ca652351 100644 --- a/src/lib/libcrypto/x509v3/v3_pcons.c +++ b/src/lib/libcrypto/x509v3/v3_pcons.c | |||
@@ -64,10 +64,12 @@ | |||
64 | #include <openssl/conf.h> | 64 | #include <openssl/conf.h> |
65 | #include <openssl/x509v3.h> | 65 | #include <openssl/x509v3.h> |
66 | 66 | ||
67 | static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, | 67 | static STACK_OF(CONF_VALUE) * |
68 | void *bcons, STACK_OF(CONF_VALUE) *extlist); | 68 | i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons, |
69 | static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, | 69 | STACK_OF(CONF_VALUE) *extlist); |
70 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); | 70 | static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, |
71 | X509V3_CTX *ctx, | ||
72 | STACK_OF(CONF_VALUE) *values); | ||
71 | 73 | ||
72 | const X509V3_EXT_METHOD v3_policy_constraints = { | 74 | const X509V3_EXT_METHOD v3_policy_constraints = { |
73 | NID_policy_constraints, 0, | 75 | NID_policy_constraints, 0, |
@@ -88,8 +90,9 @@ ASN1_SEQUENCE(POLICY_CONSTRAINTS) = { | |||
88 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) | 90 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) |
89 | 91 | ||
90 | 92 | ||
91 | static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, | 93 | static STACK_OF(CONF_VALUE) * |
92 | void *a, STACK_OF(CONF_VALUE) *extlist) | 94 | i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, |
95 | STACK_OF(CONF_VALUE) *extlist) | ||
93 | { | 96 | { |
94 | POLICY_CONSTRAINTS *pcons = a; | 97 | POLICY_CONSTRAINTS *pcons = a; |
95 | X509V3_add_value_int("Require Explicit Policy", | 98 | X509V3_add_value_int("Require Explicit Policy", |
@@ -99,8 +102,9 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, | |||
99 | return extlist; | 102 | return extlist; |
100 | } | 103 | } |
101 | 104 | ||
102 | static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, | 105 | static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, |
103 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values) | 106 | X509V3_CTX *ctx, |
107 | STACK_OF(CONF_VALUE) *values) | ||
104 | { | 108 | { |
105 | POLICY_CONSTRAINTS *pcons=NULL; | 109 | POLICY_CONSTRAINTS *pcons=NULL; |
106 | CONF_VALUE *val; | 110 | CONF_VALUE *val; |
diff --git a/src/lib/libcrypto/x509v3/v3_pmaps.c b/src/lib/libcrypto/x509v3/v3_pmaps.c index da03bbc35d..865bcd3980 100644 --- a/src/lib/libcrypto/x509v3/v3_pmaps.c +++ b/src/lib/libcrypto/x509v3/v3_pmaps.c | |||
@@ -63,10 +63,11 @@ | |||
63 | #include <openssl/conf.h> | 63 | #include <openssl/conf.h> |
64 | #include <openssl/x509v3.h> | 64 | #include <openssl/x509v3.h> |
65 | 65 | ||
66 | static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, | 66 | static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, |
67 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | 67 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); |
68 | static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, | 68 | static STACK_OF(CONF_VALUE) * |
69 | void *pmps, STACK_OF(CONF_VALUE) *extlist); | 69 | i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps, |
70 | STACK_OF(CONF_VALUE) *extlist); | ||
70 | 71 | ||
71 | const X509V3_EXT_METHOD v3_policy_mappings = { | 72 | const X509V3_EXT_METHOD v3_policy_mappings = { |
72 | NID_policy_mappings, 0, | 73 | NID_policy_mappings, 0, |
@@ -92,8 +93,9 @@ ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS) | |||
92 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) | 93 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) |
93 | 94 | ||
94 | 95 | ||
95 | static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, | 96 | static STACK_OF(CONF_VALUE) * |
96 | void *a, STACK_OF(CONF_VALUE) *ext_list) | 97 | i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a, |
98 | STACK_OF(CONF_VALUE) *ext_list) | ||
97 | { | 99 | { |
98 | POLICY_MAPPINGS *pmaps = a; | 100 | POLICY_MAPPINGS *pmaps = a; |
99 | POLICY_MAPPING *pmap; | 101 | POLICY_MAPPING *pmap; |
@@ -109,8 +111,8 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, | |||
109 | return ext_list; | 111 | return ext_list; |
110 | } | 112 | } |
111 | 113 | ||
112 | static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, | 114 | static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, |
113 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | 115 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) |
114 | { | 116 | { |
115 | POLICY_MAPPINGS *pmaps; | 117 | POLICY_MAPPINGS *pmaps; |
116 | POLICY_MAPPING *pmap; | 118 | POLICY_MAPPING *pmap; |
diff --git a/src/lib/libcrypto/x86cpuid.pl b/src/lib/libcrypto/x86cpuid.pl index 4408ef2936..a7464af19b 100644 --- a/src/lib/libcrypto/x86cpuid.pl +++ b/src/lib/libcrypto/x86cpuid.pl | |||
@@ -1,6 +1,7 @@ | |||
1 | #!/usr/bin/env perl | 1 | #!/usr/bin/env perl |
2 | 2 | ||
3 | push(@INC,"perlasm"); | 3 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; |
4 | push(@INC, "${dir}perlasm", "perlasm"); | ||
4 | require "x86asm.pl"; | 5 | require "x86asm.pl"; |
5 | 6 | ||
6 | &asm_init($ARGV[0],"x86cpuid"); | 7 | &asm_init($ARGV[0],"x86cpuid"); |
@@ -22,38 +23,90 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | |||
22 | &jnc (&label("done")); | 23 | &jnc (&label("done")); |
23 | &xor ("eax","eax"); | 24 | &xor ("eax","eax"); |
24 | &cpuid (); | 25 | &cpuid (); |
26 | &mov ("edi","eax"); # max value for standard query level | ||
27 | |||
25 | &xor ("eax","eax"); | 28 | &xor ("eax","eax"); |
26 | &cmp ("ebx",0x756e6547); # "Genu" | 29 | &cmp ("ebx",0x756e6547); # "Genu" |
27 | &data_byte(0x0f,0x95,0xc0); #&setne (&LB("eax")); | 30 | &setne (&LB("eax")); |
28 | &mov ("ebp","eax"); | 31 | &mov ("ebp","eax"); |
29 | &cmp ("edx",0x49656e69); # "ineI" | 32 | &cmp ("edx",0x49656e69); # "ineI" |
30 | &data_byte(0x0f,0x95,0xc0); #&setne (&LB("eax")); | 33 | &setne (&LB("eax")); |
31 | &or ("ebp","eax"); | 34 | &or ("ebp","eax"); |
32 | &cmp ("ecx",0x6c65746e); # "ntel" | 35 | &cmp ("ecx",0x6c65746e); # "ntel" |
33 | &data_byte(0x0f,0x95,0xc0); #&setne (&LB("eax")); | 36 | &setne (&LB("eax")); |
34 | &or ("ebp","eax"); | 37 | &or ("ebp","eax"); # 0 indicates Intel CPU |
38 | &jz (&label("intel")); | ||
39 | |||
40 | &cmp ("ebx",0x68747541); # "Auth" | ||
41 | &setne (&LB("eax")); | ||
42 | &mov ("esi","eax"); | ||
43 | &cmp ("edx",0x69746E65); # "enti" | ||
44 | &setne (&LB("eax")); | ||
45 | &or ("esi","eax"); | ||
46 | &cmp ("ecx",0x444D4163); # "cAMD" | ||
47 | &setne (&LB("eax")); | ||
48 | &or ("esi","eax"); # 0 indicates AMD CPU | ||
49 | &jnz (&label("intel")); | ||
50 | |||
51 | # AMD specific | ||
52 | &mov ("eax",0x80000000); | ||
53 | &cpuid (); | ||
54 | &cmp ("eax",0x80000008); | ||
55 | &jb (&label("intel")); | ||
56 | |||
57 | &mov ("eax",0x80000008); | ||
58 | &cpuid (); | ||
59 | &movz ("esi",&LB("ecx")); # number of cores - 1 | ||
60 | &inc ("esi"); # number of cores | ||
61 | |||
62 | &mov ("eax",1); | ||
63 | &cpuid (); | ||
64 | &bt ("edx",28); | ||
65 | &jnc (&label("done")); | ||
66 | &shr ("ebx",16); | ||
67 | &and ("ebx",0xff); | ||
68 | &cmp ("ebx","esi"); | ||
69 | &ja (&label("done")); | ||
70 | &and ("edx",0xefffffff); # clear hyper-threading bit | ||
71 | &jmp (&label("done")); | ||
72 | |||
73 | &set_label("intel"); | ||
74 | &cmp ("edi",4); | ||
75 | &mov ("edi",-1); | ||
76 | &jb (&label("nocacheinfo")); | ||
77 | |||
78 | &mov ("eax",4); | ||
79 | &mov ("ecx",0); # query L1D | ||
80 | &cpuid (); | ||
81 | &mov ("edi","eax"); | ||
82 | &shr ("edi",14); | ||
83 | &and ("edi",0xfff); # number of cores -1 per L1D | ||
84 | |||
85 | &set_label("nocacheinfo"); | ||
35 | &mov ("eax",1); | 86 | &mov ("eax",1); |
36 | &cpuid (); | 87 | &cpuid (); |
37 | &cmp ("ebp",0); | 88 | &cmp ("ebp",0); |
38 | &jne (&label("notP4")); | 89 | &jne (&label("notP4")); |
39 | &and ("eax",15<<8); # familiy ID | 90 | &and (&HB("eax"),15); # familiy ID |
40 | &cmp ("eax",15<<8); # P4? | 91 | &cmp (&HB("eax"),15); # P4? |
41 | &jne (&label("notP4")); | 92 | &jne (&label("notP4")); |
42 | &or ("edx",1<<20); # use reserved bit to engage RC4_CHAR | 93 | &or ("edx",1<<20); # use reserved bit to engage RC4_CHAR |
43 | &set_label("notP4"); | 94 | &set_label("notP4"); |
44 | &bt ("edx",28); # test hyper-threading bit | 95 | &bt ("edx",28); # test hyper-threading bit |
45 | &jnc (&label("done")); | 96 | &jnc (&label("done")); |
97 | &and ("edx",0xefffffff); | ||
98 | &cmp ("edi",0); | ||
99 | &je (&label("done")); | ||
100 | |||
101 | &or ("edx",0x10000000); | ||
46 | &shr ("ebx",16); | 102 | &shr ("ebx",16); |
47 | &and ("ebx",0xff); | 103 | &cmp (&LB("ebx"),1); |
48 | &cmp ("ebx",1); # see if cache is shared(*) | ||
49 | &ja (&label("done")); | 104 | &ja (&label("done")); |
50 | &and ("edx",0xefffffff); # clear hyper-threading bit if not | 105 | &and ("edx",0xefffffff); # clear hyper-threading bit if not |
51 | &set_label("done"); | 106 | &set_label("done"); |
52 | &mov ("eax","edx"); | 107 | &mov ("eax","edx"); |
53 | &mov ("edx","ecx"); | 108 | &mov ("edx","ecx"); |
54 | &function_end("OPENSSL_ia32_cpuid"); | 109 | &function_end("OPENSSL_ia32_cpuid"); |
55 | # (*) on Core2 this value is set to 2 denoting the fact that L2 | ||
56 | # cache is shared between cores. | ||
57 | 110 | ||
58 | &external_label("OPENSSL_ia32cap_P"); | 111 | &external_label("OPENSSL_ia32cap_P"); |
59 | 112 | ||
@@ -220,6 +273,40 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | |||
220 | } | 273 | } |
221 | &function_end_B("OPENSSL_indirect_call"); | 274 | &function_end_B("OPENSSL_indirect_call"); |
222 | 275 | ||
276 | &function_begin_B("OPENSSL_cleanse"); | ||
277 | &mov ("edx",&wparam(0)); | ||
278 | &mov ("ecx",&wparam(1)); | ||
279 | &xor ("eax","eax"); | ||
280 | &cmp ("ecx",7); | ||
281 | &jae (&label("lot")); | ||
282 | &cmp ("ecx",0); | ||
283 | &je (&label("ret")); | ||
284 | &set_label("little"); | ||
285 | &mov (&BP(0,"edx"),"al"); | ||
286 | &sub ("ecx",1); | ||
287 | &lea ("edx",&DWP(1,"edx")); | ||
288 | &jnz (&label("little")); | ||
289 | &set_label("ret"); | ||
290 | &ret (); | ||
291 | |||
292 | &set_label("lot",16); | ||
293 | &test ("edx",3); | ||
294 | &jz (&label("aligned")); | ||
295 | &mov (&BP(0,"edx"),"al"); | ||
296 | &lea ("ecx",&DWP(-1,"ecx")); | ||
297 | &lea ("edx",&DWP(1,"edx")); | ||
298 | &jmp (&label("lot")); | ||
299 | &set_label("aligned"); | ||
300 | &mov (&DWP(0,"edx"),"eax"); | ||
301 | &lea ("ecx",&DWP(-4,"ecx")); | ||
302 | &test ("ecx",-4); | ||
303 | &lea ("edx",&DWP(4,"edx")); | ||
304 | &jnz (&label("aligned")); | ||
305 | &cmp ("ecx",0); | ||
306 | &jne (&label("little")); | ||
307 | &ret (); | ||
308 | &function_end_B("OPENSSL_cleanse"); | ||
309 | |||
223 | &initseg("OPENSSL_cpuid_setup"); | 310 | &initseg("OPENSSL_cpuid_setup"); |
224 | 311 | ||
225 | &asm_finish(); | 312 | &asm_finish(); |
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c index 15a201a25c..4ce4064cc9 100644 --- a/src/lib/libssl/d1_both.c +++ b/src/lib/libssl/d1_both.c | |||
@@ -123,6 +123,37 @@ | |||
123 | #include <openssl/evp.h> | 123 | #include <openssl/evp.h> |
124 | #include <openssl/x509.h> | 124 | #include <openssl/x509.h> |
125 | 125 | ||
126 | #define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) | ||
127 | |||
128 | #define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ | ||
129 | if ((end) - (start) <= 8) { \ | ||
130 | long ii; \ | ||
131 | for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ | ||
132 | } else { \ | ||
133 | long ii; \ | ||
134 | bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ | ||
135 | for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ | ||
136 | bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ | ||
137 | } } | ||
138 | |||
139 | #define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ | ||
140 | long ii; \ | ||
141 | OPENSSL_assert((msg_len) > 0); \ | ||
142 | is_complete = 1; \ | ||
143 | if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ | ||
144 | if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ | ||
145 | if (bitmask[ii] != 0xff) { is_complete = 0; break; } } | ||
146 | |||
147 | #if 0 | ||
148 | #define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \ | ||
149 | long ii; \ | ||
150 | printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \ | ||
151 | printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \ | ||
152 | printf("\n"); } | ||
153 | #endif | ||
154 | |||
155 | static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; | ||
156 | static unsigned char bitmask_end_values[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; | ||
126 | 157 | ||
127 | /* XDTLS: figure out the right values */ | 158 | /* XDTLS: figure out the right values */ |
128 | static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; | 159 | static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; |
@@ -136,15 +167,15 @@ static unsigned char *dtls1_write_message_header(SSL *s, | |||
136 | static void dtls1_set_message_header_int(SSL *s, unsigned char mt, | 167 | static void dtls1_set_message_header_int(SSL *s, unsigned char mt, |
137 | unsigned long len, unsigned short seq_num, unsigned long frag_off, | 168 | unsigned long len, unsigned short seq_num, unsigned long frag_off, |
138 | unsigned long frag_len); | 169 | unsigned long frag_len); |
139 | static int dtls1_retransmit_buffered_messages(SSL *s); | ||
140 | static long dtls1_get_message_fragment(SSL *s, int st1, int stn, | 170 | static long dtls1_get_message_fragment(SSL *s, int st1, int stn, |
141 | long max, int *ok); | 171 | long max, int *ok); |
142 | 172 | ||
143 | static hm_fragment * | 173 | static hm_fragment * |
144 | dtls1_hm_fragment_new(unsigned long frag_len) | 174 | dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) |
145 | { | 175 | { |
146 | hm_fragment *frag = NULL; | 176 | hm_fragment *frag = NULL; |
147 | unsigned char *buf = NULL; | 177 | unsigned char *buf = NULL; |
178 | unsigned char *bitmask = NULL; | ||
148 | 179 | ||
149 | frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); | 180 | frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); |
150 | if ( frag == NULL) | 181 | if ( frag == NULL) |
@@ -163,6 +194,21 @@ dtls1_hm_fragment_new(unsigned long frag_len) | |||
163 | /* zero length fragment gets zero frag->fragment */ | 194 | /* zero length fragment gets zero frag->fragment */ |
164 | frag->fragment = buf; | 195 | frag->fragment = buf; |
165 | 196 | ||
197 | /* Initialize reassembly bitmask if necessary */ | ||
198 | if (reassembly) | ||
199 | { | ||
200 | bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len)); | ||
201 | if (bitmask == NULL) | ||
202 | { | ||
203 | if (buf != NULL) OPENSSL_free(buf); | ||
204 | OPENSSL_free(frag); | ||
205 | return NULL; | ||
206 | } | ||
207 | memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); | ||
208 | } | ||
209 | |||
210 | frag->reassembly = bitmask; | ||
211 | |||
166 | return frag; | 212 | return frag; |
167 | } | 213 | } |
168 | 214 | ||
@@ -170,6 +216,7 @@ static void | |||
170 | dtls1_hm_fragment_free(hm_fragment *frag) | 216 | dtls1_hm_fragment_free(hm_fragment *frag) |
171 | { | 217 | { |
172 | if (frag->fragment) OPENSSL_free(frag->fragment); | 218 | if (frag->fragment) OPENSSL_free(frag->fragment); |
219 | if (frag->reassembly) OPENSSL_free(frag->reassembly); | ||
173 | OPENSSL_free(frag); | 220 | OPENSSL_free(frag); |
174 | } | 221 | } |
175 | 222 | ||
@@ -178,7 +225,7 @@ int dtls1_do_write(SSL *s, int type) | |||
178 | { | 225 | { |
179 | int ret; | 226 | int ret; |
180 | int curr_mtu; | 227 | int curr_mtu; |
181 | unsigned int len, frag_off; | 228 | unsigned int len, frag_off, mac_size, blocksize; |
182 | 229 | ||
183 | /* AHA! Figure out the MTU, and stick to the right size */ | 230 | /* AHA! Figure out the MTU, and stick to the right size */ |
184 | if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) | 231 | if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) |
@@ -226,11 +273,22 @@ int dtls1_do_write(SSL *s, int type) | |||
226 | OPENSSL_assert(s->init_num == | 273 | OPENSSL_assert(s->init_num == |
227 | (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); | 274 | (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); |
228 | 275 | ||
276 | if (s->write_hash) | ||
277 | mac_size = EVP_MD_CTX_size(s->write_hash); | ||
278 | else | ||
279 | mac_size = 0; | ||
280 | |||
281 | if (s->enc_write_ctx && | ||
282 | (EVP_CIPHER_mode( s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE)) | ||
283 | blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher); | ||
284 | else | ||
285 | blocksize = 0; | ||
286 | |||
229 | frag_off = 0; | 287 | frag_off = 0; |
230 | while( s->init_num) | 288 | while( s->init_num) |
231 | { | 289 | { |
232 | curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - | 290 | curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - |
233 | DTLS1_RT_HEADER_LENGTH; | 291 | DTLS1_RT_HEADER_LENGTH - mac_size - blocksize; |
234 | 292 | ||
235 | if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH) | 293 | if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH) |
236 | { | 294 | { |
@@ -238,7 +296,8 @@ int dtls1_do_write(SSL *s, int type) | |||
238 | ret = BIO_flush(SSL_get_wbio(s)); | 296 | ret = BIO_flush(SSL_get_wbio(s)); |
239 | if ( ret <= 0) | 297 | if ( ret <= 0) |
240 | return ret; | 298 | return ret; |
241 | curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH; | 299 | curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH - |
300 | mac_size - blocksize; | ||
242 | } | 301 | } |
243 | 302 | ||
244 | if ( s->init_num > curr_mtu) | 303 | if ( s->init_num > curr_mtu) |
@@ -280,7 +339,7 @@ int dtls1_do_write(SSL *s, int type) | |||
280 | * retransmit | 339 | * retransmit |
281 | */ | 340 | */ |
282 | if ( BIO_ctrl(SSL_get_wbio(s), | 341 | if ( BIO_ctrl(SSL_get_wbio(s), |
283 | BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL)) | 342 | BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 ) |
284 | s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), | 343 | s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), |
285 | BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); | 344 | BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); |
286 | else | 345 | else |
@@ -301,7 +360,7 @@ int dtls1_do_write(SSL *s, int type) | |||
301 | const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | 360 | const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; |
302 | int xlen; | 361 | int xlen; |
303 | 362 | ||
304 | if (frag_off == 0 && s->client_version != DTLS1_BAD_VER) | 363 | if (frag_off == 0 && s->version != DTLS1_BAD_VER) |
305 | { | 364 | { |
306 | /* reconstruct message header is if it | 365 | /* reconstruct message header is if it |
307 | * is being sent in single fragment */ | 366 | * is being sent in single fragment */ |
@@ -352,6 +411,8 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) | |||
352 | { | 411 | { |
353 | int i, al; | 412 | int i, al; |
354 | struct hm_header_st *msg_hdr; | 413 | struct hm_header_st *msg_hdr; |
414 | unsigned char *p; | ||
415 | unsigned long msg_len; | ||
355 | 416 | ||
356 | /* s3->tmp is used to store messages that are unexpected, caused | 417 | /* s3->tmp is used to store messages that are unexpected, caused |
357 | * by the absence of an optional handshake message */ | 418 | * by the absence of an optional handshake message */ |
@@ -371,76 +432,55 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) | |||
371 | } | 432 | } |
372 | 433 | ||
373 | msg_hdr = &s->d1->r_msg_hdr; | 434 | msg_hdr = &s->d1->r_msg_hdr; |
374 | do | 435 | memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); |
375 | { | ||
376 | if ( msg_hdr->frag_off == 0) | ||
377 | { | ||
378 | /* s->d1->r_message_header.msg_len = 0; */ | ||
379 | memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); | ||
380 | } | ||
381 | 436 | ||
382 | i = dtls1_get_message_fragment(s, st1, stn, max, ok); | 437 | again: |
383 | if ( i == DTLS1_HM_BAD_FRAGMENT || | 438 | i = dtls1_get_message_fragment(s, st1, stn, max, ok); |
384 | i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ | 439 | if ( i == DTLS1_HM_BAD_FRAGMENT || |
385 | continue; | 440 | i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ |
386 | else if ( i <= 0 && !*ok) | 441 | goto again; |
387 | return i; | 442 | else if ( i <= 0 && !*ok) |
443 | return i; | ||
388 | 444 | ||
389 | /* Note that s->init_sum is used as a counter summing | 445 | p = (unsigned char *)s->init_buf->data; |
390 | * up fragments' lengths: as soon as they sum up to | 446 | msg_len = msg_hdr->msg_len; |
391 | * handshake packet length, we assume we have got all | 447 | |
392 | * the fragments. Overlapping fragments would cause | 448 | /* reconstruct message header */ |
393 | * premature termination, so we don't expect overlaps. | 449 | *(p++) = msg_hdr->type; |
394 | * Well, handling overlaps would require something more | 450 | l2n3(msg_len,p); |
395 | * drastic. Indeed, as it is now there is no way to | 451 | s2n (msg_hdr->seq,p); |
396 | * tell if out-of-order fragment from the middle was | 452 | l2n3(0,p); |
397 | * the last. '>=' is the best/least we can do to control | 453 | l2n3(msg_len,p); |
398 | * the potential damage caused by malformed overlaps. */ | 454 | if (s->version != DTLS1_BAD_VER) { |
399 | if ((unsigned int)s->init_num >= msg_hdr->msg_len) | 455 | p -= DTLS1_HM_HEADER_LENGTH; |
400 | { | 456 | msg_len += DTLS1_HM_HEADER_LENGTH; |
401 | unsigned char *p = (unsigned char *)s->init_buf->data; | 457 | } |
402 | unsigned long msg_len = msg_hdr->msg_len; | 458 | |
403 | 459 | ssl3_finish_mac(s, p, msg_len); | |
404 | /* reconstruct message header as if it was | 460 | if (s->msg_callback) |
405 | * sent in single fragment */ | 461 | s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, |
406 | *(p++) = msg_hdr->type; | 462 | p, msg_len, |
407 | l2n3(msg_len,p); | 463 | s, s->msg_callback_arg); |
408 | s2n (msg_hdr->seq,p); | 464 | |
409 | l2n3(0,p); | 465 | memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); |
410 | l2n3(msg_len,p); | 466 | |
411 | if (s->client_version != DTLS1_BAD_VER) | 467 | s->d1->handshake_read_seq++; |
412 | p -= DTLS1_HM_HEADER_LENGTH, | 468 | /* we just read a handshake message from the other side: |
413 | msg_len += DTLS1_HM_HEADER_LENGTH; | 469 | * this means that we don't need to retransmit of the |
414 | 470 | * buffered messages. | |
415 | ssl3_finish_mac(s, p, msg_len); | 471 | * XDTLS: may be able clear out this |
416 | if (s->msg_callback) | 472 | * buffer a little sooner (i.e if an out-of-order |
417 | s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, | 473 | * handshake message/record is received at the record |
418 | p, msg_len, | 474 | * layer. |
419 | s, s->msg_callback_arg); | 475 | * XDTLS: exception is that the server needs to |
420 | 476 | * know that change cipher spec and finished messages | |
421 | memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); | 477 | * have been received by the client before clearing this |
422 | 478 | * buffer. this can simply be done by waiting for the | |
423 | s->d1->handshake_read_seq++; | 479 | * first data segment, but is there a better way? */ |
424 | /* we just read a handshake message from the other side: | 480 | dtls1_clear_record_buffer(s); |
425 | * this means that we don't need to retransmit of the | 481 | |
426 | * buffered messages. | 482 | s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; |
427 | * XDTLS: may be able clear out this | 483 | return s->init_num; |
428 | * buffer a little sooner (i.e if an out-of-order | ||
429 | * handshake message/record is received at the record | ||
430 | * layer. | ||
431 | * XDTLS: exception is that the server needs to | ||
432 | * know that change cipher spec and finished messages | ||
433 | * have been received by the client before clearing this | ||
434 | * buffer. this can simply be done by waiting for the | ||
435 | * first data segment, but is there a better way? */ | ||
436 | dtls1_clear_record_buffer(s); | ||
437 | |||
438 | s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; | ||
439 | return s->init_num; | ||
440 | } | ||
441 | else | ||
442 | msg_hdr->frag_off = i; | ||
443 | } while(1) ; | ||
444 | 484 | ||
445 | f_err: | 485 | f_err: |
446 | ssl3_send_alert(s,SSL3_AL_FATAL,al); | 486 | ssl3_send_alert(s,SSL3_AL_FATAL,al); |
@@ -474,7 +514,7 @@ static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max | |||
474 | { | 514 | { |
475 | /* msg_len is limited to 2^24, but is effectively checked | 515 | /* msg_len is limited to 2^24, but is effectively checked |
476 | * against max above */ | 516 | * against max above */ |
477 | if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH)) | 517 | if (!BUF_MEM_grow_clean(s->init_buf,msg_len+DTLS1_HM_HEADER_LENGTH)) |
478 | { | 518 | { |
479 | SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB); | 519 | SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB); |
480 | return SSL_AD_INTERNAL_ERROR; | 520 | return SSL_AD_INTERNAL_ERROR; |
@@ -516,9 +556,14 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) | |||
516 | return 0; | 556 | return 0; |
517 | 557 | ||
518 | frag = (hm_fragment *)item->data; | 558 | frag = (hm_fragment *)item->data; |
559 | |||
560 | /* Don't return if reassembly still in progress */ | ||
561 | if (frag->reassembly != NULL) | ||
562 | return 0; | ||
519 | 563 | ||
520 | if ( s->d1->handshake_read_seq == frag->msg_header.seq) | 564 | if ( s->d1->handshake_read_seq == frag->msg_header.seq) |
521 | { | 565 | { |
566 | unsigned long frag_len = frag->msg_header.frag_len; | ||
522 | pqueue_pop(s->d1->buffered_messages); | 567 | pqueue_pop(s->d1->buffered_messages); |
523 | 568 | ||
524 | al=dtls1_preprocess_fragment(s,&frag->msg_header,max); | 569 | al=dtls1_preprocess_fragment(s,&frag->msg_header,max); |
@@ -536,7 +581,7 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) | |||
536 | if (al==0) | 581 | if (al==0) |
537 | { | 582 | { |
538 | *ok = 1; | 583 | *ok = 1; |
539 | return frag->msg_header.frag_len; | 584 | return frag_len; |
540 | } | 585 | } |
541 | 586 | ||
542 | ssl3_send_alert(s,SSL3_AL_FATAL,al); | 587 | ssl3_send_alert(s,SSL3_AL_FATAL,al); |
@@ -550,18 +595,50 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) | |||
550 | 595 | ||
551 | 596 | ||
552 | static int | 597 | static int |
553 | dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) | 598 | dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) |
554 | { | 599 | { |
555 | int i=-1; | ||
556 | hm_fragment *frag = NULL; | 600 | hm_fragment *frag = NULL; |
557 | pitem *item = NULL; | 601 | pitem *item = NULL; |
558 | PQ_64BIT seq64; | 602 | int i = -1, is_complete; |
559 | unsigned long frag_len = msg_hdr->frag_len; | 603 | unsigned char seq64be[8]; |
604 | unsigned long frag_len = msg_hdr->frag_len, max_len; | ||
560 | 605 | ||
561 | if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) | 606 | if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) |
562 | goto err; | 607 | goto err; |
563 | 608 | ||
564 | if (msg_hdr->seq <= s->d1->handshake_read_seq) | 609 | /* Determine maximum allowed message size. Depends on (user set) |
610 | * maximum certificate length, but 16k is minimum. | ||
611 | */ | ||
612 | if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list) | ||
613 | max_len = s->max_cert_list; | ||
614 | else | ||
615 | max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; | ||
616 | |||
617 | if ((msg_hdr->frag_off+frag_len) > max_len) | ||
618 | goto err; | ||
619 | |||
620 | /* Try to find item in queue */ | ||
621 | memset(seq64be,0,sizeof(seq64be)); | ||
622 | seq64be[6] = (unsigned char) (msg_hdr->seq>>8); | ||
623 | seq64be[7] = (unsigned char) msg_hdr->seq; | ||
624 | item = pqueue_find(s->d1->buffered_messages, seq64be); | ||
625 | |||
626 | if (item == NULL) | ||
627 | { | ||
628 | frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); | ||
629 | if ( frag == NULL) | ||
630 | goto err; | ||
631 | memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); | ||
632 | frag->msg_header.frag_len = frag->msg_header.msg_len; | ||
633 | frag->msg_header.frag_off = 0; | ||
634 | } | ||
635 | else | ||
636 | frag = (hm_fragment*) item->data; | ||
637 | |||
638 | /* If message is already reassembled, this must be a | ||
639 | * retransmit and can be dropped. | ||
640 | */ | ||
641 | if (frag->reassembly == NULL) | ||
565 | { | 642 | { |
566 | unsigned char devnull [256]; | 643 | unsigned char devnull [256]; |
567 | 644 | ||
@@ -573,32 +650,128 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) | |||
573 | if (i<=0) goto err; | 650 | if (i<=0) goto err; |
574 | frag_len -= i; | 651 | frag_len -= i; |
575 | } | 652 | } |
653 | return DTLS1_HM_FRAGMENT_RETRY; | ||
576 | } | 654 | } |
577 | 655 | ||
578 | frag = dtls1_hm_fragment_new(frag_len); | 656 | /* read the body of the fragment (header has already been read */ |
579 | if ( frag == NULL) | 657 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, |
658 | frag->fragment + msg_hdr->frag_off,frag_len,0); | ||
659 | if (i<=0 || (unsigned long)i!=frag_len) | ||
580 | goto err; | 660 | goto err; |
581 | 661 | ||
582 | memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); | 662 | RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, |
663 | (long)(msg_hdr->frag_off + frag_len)); | ||
583 | 664 | ||
584 | if (frag_len) | 665 | RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, |
666 | is_complete); | ||
667 | |||
668 | if (is_complete) | ||
669 | { | ||
670 | OPENSSL_free(frag->reassembly); | ||
671 | frag->reassembly = NULL; | ||
672 | } | ||
673 | |||
674 | if (item == NULL) | ||
585 | { | 675 | { |
586 | /* read the body of the fragment (header has already been read */ | 676 | memset(seq64be,0,sizeof(seq64be)); |
587 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | 677 | seq64be[6] = (unsigned char)(msg_hdr->seq>>8); |
588 | frag->fragment,frag_len,0); | 678 | seq64be[7] = (unsigned char)(msg_hdr->seq); |
589 | if (i<=0 || (unsigned long)i!=frag_len) | 679 | |
680 | item = pitem_new(seq64be, frag); | ||
681 | if (item == NULL) | ||
682 | { | ||
590 | goto err; | 683 | goto err; |
684 | i = -1; | ||
685 | } | ||
686 | |||
687 | pqueue_insert(s->d1->buffered_messages, item); | ||
591 | } | 688 | } |
592 | 689 | ||
593 | pq_64bit_init(&seq64); | 690 | return DTLS1_HM_FRAGMENT_RETRY; |
594 | pq_64bit_assign_word(&seq64, msg_hdr->seq); | 691 | |
692 | err: | ||
693 | if (frag != NULL) dtls1_hm_fragment_free(frag); | ||
694 | if (item != NULL) OPENSSL_free(item); | ||
695 | *ok = 0; | ||
696 | return i; | ||
697 | } | ||
698 | |||
595 | 699 | ||
596 | item = pitem_new(seq64, frag); | 700 | static int |
597 | pq_64bit_free(&seq64); | 701 | dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) |
598 | if ( item == NULL) | 702 | { |
703 | int i=-1; | ||
704 | hm_fragment *frag = NULL; | ||
705 | pitem *item = NULL; | ||
706 | unsigned char seq64be[8]; | ||
707 | unsigned long frag_len = msg_hdr->frag_len; | ||
708 | |||
709 | if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) | ||
599 | goto err; | 710 | goto err; |
600 | 711 | ||
601 | pqueue_insert(s->d1->buffered_messages, item); | 712 | /* Try to find item in queue, to prevent duplicate entries */ |
713 | memset(seq64be,0,sizeof(seq64be)); | ||
714 | seq64be[6] = (unsigned char) (msg_hdr->seq>>8); | ||
715 | seq64be[7] = (unsigned char) msg_hdr->seq; | ||
716 | item = pqueue_find(s->d1->buffered_messages, seq64be); | ||
717 | |||
718 | /* If we already have an entry and this one is a fragment, | ||
719 | * don't discard it and rather try to reassemble it. | ||
720 | */ | ||
721 | if (item != NULL && frag_len < msg_hdr->msg_len) | ||
722 | item = NULL; | ||
723 | |||
724 | /* Discard the message if sequence number was already there, is | ||
725 | * too far in the future, already in the queue or if we received | ||
726 | * a FINISHED before the SERVER_HELLO, which then must be a stale | ||
727 | * retransmit. | ||
728 | */ | ||
729 | if (msg_hdr->seq <= s->d1->handshake_read_seq || | ||
730 | msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || | ||
731 | (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) | ||
732 | { | ||
733 | unsigned char devnull [256]; | ||
734 | |||
735 | while (frag_len) | ||
736 | { | ||
737 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | ||
738 | devnull, | ||
739 | frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0); | ||
740 | if (i<=0) goto err; | ||
741 | frag_len -= i; | ||
742 | } | ||
743 | } | ||
744 | else | ||
745 | { | ||
746 | if (frag_len && frag_len < msg_hdr->msg_len) | ||
747 | return dtls1_reassemble_fragment(s, msg_hdr, ok); | ||
748 | |||
749 | frag = dtls1_hm_fragment_new(frag_len, 0); | ||
750 | if ( frag == NULL) | ||
751 | goto err; | ||
752 | |||
753 | memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); | ||
754 | |||
755 | if (frag_len) | ||
756 | { | ||
757 | /* read the body of the fragment (header has already been read */ | ||
758 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | ||
759 | frag->fragment,frag_len,0); | ||
760 | if (i<=0 || (unsigned long)i!=frag_len) | ||
761 | goto err; | ||
762 | } | ||
763 | |||
764 | memset(seq64be,0,sizeof(seq64be)); | ||
765 | seq64be[6] = (unsigned char)(msg_hdr->seq>>8); | ||
766 | seq64be[7] = (unsigned char)(msg_hdr->seq); | ||
767 | |||
768 | item = pitem_new(seq64be, frag); | ||
769 | if ( item == NULL) | ||
770 | goto err; | ||
771 | |||
772 | pqueue_insert(s->d1->buffered_messages, item); | ||
773 | } | ||
774 | |||
602 | return DTLS1_HM_FRAGMENT_RETRY; | 775 | return DTLS1_HM_FRAGMENT_RETRY; |
603 | 776 | ||
604 | err: | 777 | err: |
@@ -613,14 +786,14 @@ static long | |||
613 | dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) | 786 | dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) |
614 | { | 787 | { |
615 | unsigned char wire[DTLS1_HM_HEADER_LENGTH]; | 788 | unsigned char wire[DTLS1_HM_HEADER_LENGTH]; |
616 | unsigned long l, frag_off, frag_len; | 789 | unsigned long len, frag_off, frag_len; |
617 | int i,al; | 790 | int i,al; |
618 | struct hm_header_st msg_hdr; | 791 | struct hm_header_st msg_hdr; |
619 | 792 | ||
620 | /* see if we have the required fragment already */ | 793 | /* see if we have the required fragment already */ |
621 | if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) | 794 | if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) |
622 | { | 795 | { |
623 | if (*ok) s->init_num += frag_len; | 796 | if (*ok) s->init_num = frag_len; |
624 | return frag_len; | 797 | return frag_len; |
625 | } | 798 | } |
626 | 799 | ||
@@ -645,10 +818,13 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) | |||
645 | if ( msg_hdr.seq != s->d1->handshake_read_seq) | 818 | if ( msg_hdr.seq != s->d1->handshake_read_seq) |
646 | return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); | 819 | return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); |
647 | 820 | ||
648 | l = msg_hdr.msg_len; | 821 | len = msg_hdr.msg_len; |
649 | frag_off = msg_hdr.frag_off; | 822 | frag_off = msg_hdr.frag_off; |
650 | frag_len = msg_hdr.frag_len; | 823 | frag_len = msg_hdr.frag_len; |
651 | 824 | ||
825 | if (frag_len && frag_len < len) | ||
826 | return dtls1_reassemble_fragment(s, &msg_hdr, ok); | ||
827 | |||
652 | if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && | 828 | if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && |
653 | wire[0] == SSL3_MT_HELLO_REQUEST) | 829 | wire[0] == SSL3_MT_HELLO_REQUEST) |
654 | { | 830 | { |
@@ -708,7 +884,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) | |||
708 | * s->init_buf->data, but as a counter summing up fragments' | 884 | * s->init_buf->data, but as a counter summing up fragments' |
709 | * lengths: as soon as they sum up to handshake packet | 885 | * lengths: as soon as they sum up to handshake packet |
710 | * length, we assume we have got all the fragments. */ | 886 | * length, we assume we have got all the fragments. */ |
711 | s->init_num += frag_len; | 887 | s->init_num = frag_len; |
712 | return frag_len; | 888 | return frag_len; |
713 | 889 | ||
714 | f_err: | 890 | f_err: |
@@ -731,14 +907,30 @@ int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen) | |||
731 | p= &(d[DTLS1_HM_HEADER_LENGTH]); | 907 | p= &(d[DTLS1_HM_HEADER_LENGTH]); |
732 | 908 | ||
733 | i=s->method->ssl3_enc->final_finish_mac(s, | 909 | i=s->method->ssl3_enc->final_finish_mac(s, |
734 | &(s->s3->finish_dgst1), | ||
735 | &(s->s3->finish_dgst2), | ||
736 | sender,slen,s->s3->tmp.finish_md); | 910 | sender,slen,s->s3->tmp.finish_md); |
737 | s->s3->tmp.finish_md_len = i; | 911 | s->s3->tmp.finish_md_len = i; |
738 | memcpy(p, s->s3->tmp.finish_md, i); | 912 | memcpy(p, s->s3->tmp.finish_md, i); |
739 | p+=i; | 913 | p+=i; |
740 | l=i; | 914 | l=i; |
741 | 915 | ||
916 | /* Copy the finished so we can use it for | ||
917 | * renegotiation checks | ||
918 | */ | ||
919 | if(s->type == SSL_ST_CONNECT) | ||
920 | { | ||
921 | OPENSSL_assert(i <= EVP_MAX_MD_SIZE); | ||
922 | memcpy(s->s3->previous_client_finished, | ||
923 | s->s3->tmp.finish_md, i); | ||
924 | s->s3->previous_client_finished_len=i; | ||
925 | } | ||
926 | else | ||
927 | { | ||
928 | OPENSSL_assert(i <= EVP_MAX_MD_SIZE); | ||
929 | memcpy(s->s3->previous_server_finished, | ||
930 | s->s3->tmp.finish_md, i); | ||
931 | s->s3->previous_server_finished_len=i; | ||
932 | } | ||
933 | |||
742 | #ifdef OPENSSL_SYS_WIN16 | 934 | #ifdef OPENSSL_SYS_WIN16 |
743 | /* MSVC 1.5 does not clear the top bytes of the word unless | 935 | /* MSVC 1.5 does not clear the top bytes of the word unless |
744 | * I do this. | 936 | * I do this. |
@@ -779,12 +971,11 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) | |||
779 | s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; | 971 | s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; |
780 | s->init_num=DTLS1_CCS_HEADER_LENGTH; | 972 | s->init_num=DTLS1_CCS_HEADER_LENGTH; |
781 | 973 | ||
782 | if (s->client_version == DTLS1_BAD_VER) | 974 | if (s->version == DTLS1_BAD_VER) { |
783 | { | ||
784 | s->d1->next_handshake_write_seq++; | 975 | s->d1->next_handshake_write_seq++; |
785 | s2n(s->d1->handshake_write_seq,p); | 976 | s2n(s->d1->handshake_write_seq,p); |
786 | s->init_num+=2; | 977 | s->init_num+=2; |
787 | } | 978 | } |
788 | 979 | ||
789 | s->init_off=0; | 980 | s->init_off=0; |
790 | 981 | ||
@@ -801,14 +992,30 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) | |||
801 | return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC)); | 992 | return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC)); |
802 | } | 993 | } |
803 | 994 | ||
995 | static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) | ||
996 | { | ||
997 | int n; | ||
998 | unsigned char *p; | ||
999 | |||
1000 | n=i2d_X509(x,NULL); | ||
1001 | if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3))) | ||
1002 | { | ||
1003 | SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB); | ||
1004 | return 0; | ||
1005 | } | ||
1006 | p=(unsigned char *)&(buf->data[*l]); | ||
1007 | l2n3(n,p); | ||
1008 | i2d_X509(x,&p); | ||
1009 | *l+=n+3; | ||
1010 | |||
1011 | return 1; | ||
1012 | } | ||
804 | unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) | 1013 | unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) |
805 | { | 1014 | { |
806 | unsigned char *p; | 1015 | unsigned char *p; |
807 | int n,i; | 1016 | int i; |
808 | unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH; | 1017 | unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH; |
809 | BUF_MEM *buf; | 1018 | BUF_MEM *buf; |
810 | X509_STORE_CTX xs_ctx; | ||
811 | X509_OBJECT obj; | ||
812 | 1019 | ||
813 | /* TLSv1 sends a chain with nothing in it, instead of an alert */ | 1020 | /* TLSv1 sends a chain with nothing in it, instead of an alert */ |
814 | buf=s->init_buf; | 1021 | buf=s->init_buf; |
@@ -819,54 +1026,35 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) | |||
819 | } | 1026 | } |
820 | if (x != NULL) | 1027 | if (x != NULL) |
821 | { | 1028 | { |
822 | if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL)) | 1029 | X509_STORE_CTX xs_ctx; |
823 | { | 1030 | |
824 | SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); | 1031 | if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL)) |
825 | return(0); | 1032 | { |
826 | } | 1033 | SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); |
827 | 1034 | return(0); | |
828 | for (;;) | 1035 | } |
829 | { | 1036 | |
830 | n=i2d_X509(x,NULL); | 1037 | X509_verify_cert(&xs_ctx); |
831 | if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) | 1038 | /* Don't leave errors in the queue */ |
832 | { | 1039 | ERR_clear_error(); |
833 | SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); | 1040 | for (i=0; i < sk_X509_num(xs_ctx.chain); i++) |
834 | return(0); | 1041 | { |
835 | } | 1042 | x = sk_X509_value(xs_ctx.chain, i); |
836 | p=(unsigned char *)&(buf->data[l]); | 1043 | |
837 | l2n3(n,p); | 1044 | if (!dtls1_add_cert_to_buf(buf, &l, x)) |
838 | i2d_X509(x,&p); | 1045 | { |
839 | l+=n+3; | 1046 | X509_STORE_CTX_cleanup(&xs_ctx); |
840 | if (X509_NAME_cmp(X509_get_subject_name(x), | 1047 | return 0; |
841 | X509_get_issuer_name(x)) == 0) break; | 1048 | } |
842 | 1049 | } | |
843 | i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509, | 1050 | X509_STORE_CTX_cleanup(&xs_ctx); |
844 | X509_get_issuer_name(x),&obj); | 1051 | } |
845 | if (i <= 0) break; | 1052 | /* Thawte special :-) */ |
846 | x=obj.data.x509; | ||
847 | /* Count is one too high since the X509_STORE_get uped the | ||
848 | * ref count */ | ||
849 | X509_free(x); | ||
850 | } | ||
851 | |||
852 | X509_STORE_CTX_cleanup(&xs_ctx); | ||
853 | } | ||
854 | |||
855 | /* Thawte special :-) */ | ||
856 | if (s->ctx->extra_certs != NULL) | ||
857 | for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++) | 1053 | for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++) |
858 | { | 1054 | { |
859 | x=sk_X509_value(s->ctx->extra_certs,i); | 1055 | x=sk_X509_value(s->ctx->extra_certs,i); |
860 | n=i2d_X509(x,NULL); | 1056 | if (!dtls1_add_cert_to_buf(buf, &l, x)) |
861 | if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) | 1057 | return 0; |
862 | { | ||
863 | SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); | ||
864 | return(0); | ||
865 | } | ||
866 | p=(unsigned char *)&(buf->data[l]); | ||
867 | l2n3(n,p); | ||
868 | i2d_X509(x,&p); | ||
869 | l+=n+3; | ||
870 | } | 1058 | } |
871 | 1059 | ||
872 | l-= (3 + DTLS1_HM_HEADER_LENGTH); | 1060 | l-= (3 + DTLS1_HM_HEADER_LENGTH); |
@@ -883,18 +1071,13 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) | |||
883 | 1071 | ||
884 | int dtls1_read_failed(SSL *s, int code) | 1072 | int dtls1_read_failed(SSL *s, int code) |
885 | { | 1073 | { |
886 | DTLS1_STATE *state; | ||
887 | BIO *bio; | ||
888 | int send_alert = 0; | ||
889 | |||
890 | if ( code > 0) | 1074 | if ( code > 0) |
891 | { | 1075 | { |
892 | fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__); | 1076 | fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__); |
893 | return 1; | 1077 | return 1; |
894 | } | 1078 | } |
895 | 1079 | ||
896 | bio = SSL_get_rbio(s); | 1080 | if (!dtls1_is_timer_expired(s)) |
897 | if ( ! BIO_dgram_recv_timedout(bio)) | ||
898 | { | 1081 | { |
899 | /* not a timeout, none of our business, | 1082 | /* not a timeout, none of our business, |
900 | let higher layers handle this. in fact it's probably an error */ | 1083 | let higher layers handle this. in fact it's probably an error */ |
@@ -907,23 +1090,6 @@ int dtls1_read_failed(SSL *s, int code) | |||
907 | return code; | 1090 | return code; |
908 | } | 1091 | } |
909 | 1092 | ||
910 | state = s->d1; | ||
911 | state->timeout.num_alerts++; | ||
912 | if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) | ||
913 | { | ||
914 | /* fail the connection, enough alerts have been sent */ | ||
915 | SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED); | ||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | state->timeout.read_timeouts++; | ||
920 | if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) | ||
921 | { | ||
922 | send_alert = 1; | ||
923 | state->timeout.read_timeouts = 1; | ||
924 | } | ||
925 | |||
926 | |||
927 | #if 0 /* for now, each alert contains only one record number */ | 1093 | #if 0 /* for now, each alert contains only one record number */ |
928 | item = pqueue_peek(state->rcvd_records); | 1094 | item = pqueue_peek(state->rcvd_records); |
929 | if ( item ) | 1095 | if ( item ) |
@@ -934,16 +1100,29 @@ int dtls1_read_failed(SSL *s, int code) | |||
934 | #endif | 1100 | #endif |
935 | 1101 | ||
936 | #if 0 /* no more alert sending, just retransmit the last set of messages */ | 1102 | #if 0 /* no more alert sending, just retransmit the last set of messages */ |
937 | if ( send_alert) | 1103 | if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT) |
938 | ssl3_send_alert(s,SSL3_AL_WARNING, | 1104 | ssl3_send_alert(s,SSL3_AL_WARNING, |
939 | DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); | 1105 | DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); |
940 | #endif | 1106 | #endif |
941 | 1107 | ||
942 | return dtls1_retransmit_buffered_messages(s) ; | 1108 | return dtls1_handle_timeout(s); |
943 | } | 1109 | } |
944 | 1110 | ||
1111 | int | ||
1112 | dtls1_get_queue_priority(unsigned short seq, int is_ccs) | ||
1113 | { | ||
1114 | /* The index of the retransmission queue actually is the message sequence number, | ||
1115 | * since the queue only contains messages of a single handshake. However, the | ||
1116 | * ChangeCipherSpec has no message sequence number and so using only the sequence | ||
1117 | * will result in the CCS and Finished having the same index. To prevent this, | ||
1118 | * the sequence number is multiplied by 2. In case of a CCS 1 is subtracted. | ||
1119 | * This does not only differ CSS and Finished, it also maintains the order of the | ||
1120 | * index (important for priority queues) and fits in the unsigned short variable. | ||
1121 | */ | ||
1122 | return seq * 2 - is_ccs; | ||
1123 | } | ||
945 | 1124 | ||
946 | static int | 1125 | int |
947 | dtls1_retransmit_buffered_messages(SSL *s) | 1126 | dtls1_retransmit_buffered_messages(SSL *s) |
948 | { | 1127 | { |
949 | pqueue sent = s->d1->sent_messages; | 1128 | pqueue sent = s->d1->sent_messages; |
@@ -957,8 +1136,9 @@ dtls1_retransmit_buffered_messages(SSL *s) | |||
957 | for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) | 1136 | for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) |
958 | { | 1137 | { |
959 | frag = (hm_fragment *)item->data; | 1138 | frag = (hm_fragment *)item->data; |
960 | if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 && | 1139 | if ( dtls1_retransmit_message(s, |
961 | found) | 1140 | (unsigned short)dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs), |
1141 | 0, &found) <= 0 && found) | ||
962 | { | 1142 | { |
963 | fprintf(stderr, "dtls1_retransmit_message() failed\n"); | 1143 | fprintf(stderr, "dtls1_retransmit_message() failed\n"); |
964 | return -1; | 1144 | return -1; |
@@ -973,22 +1153,20 @@ dtls1_buffer_message(SSL *s, int is_ccs) | |||
973 | { | 1153 | { |
974 | pitem *item; | 1154 | pitem *item; |
975 | hm_fragment *frag; | 1155 | hm_fragment *frag; |
976 | PQ_64BIT seq64; | 1156 | unsigned char seq64be[8]; |
977 | unsigned int epoch = s->d1->w_epoch; | ||
978 | 1157 | ||
979 | /* this function is called immediately after a message has | 1158 | /* this function is called immediately after a message has |
980 | * been serialized */ | 1159 | * been serialized */ |
981 | OPENSSL_assert(s->init_off == 0); | 1160 | OPENSSL_assert(s->init_off == 0); |
982 | 1161 | ||
983 | frag = dtls1_hm_fragment_new(s->init_num); | 1162 | frag = dtls1_hm_fragment_new(s->init_num, 0); |
984 | 1163 | ||
985 | memcpy(frag->fragment, s->init_buf->data, s->init_num); | 1164 | memcpy(frag->fragment, s->init_buf->data, s->init_num); |
986 | 1165 | ||
987 | if ( is_ccs) | 1166 | if ( is_ccs) |
988 | { | 1167 | { |
989 | OPENSSL_assert(s->d1->w_msg_hdr.msg_len + | 1168 | OPENSSL_assert(s->d1->w_msg_hdr.msg_len + |
990 | DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num); | 1169 | ((s->version==DTLS1_VERSION)?DTLS1_CCS_HEADER_LENGTH:3) == (unsigned int)s->init_num); |
991 | epoch++; | ||
992 | } | 1170 | } |
993 | else | 1171 | else |
994 | { | 1172 | { |
@@ -1003,11 +1181,20 @@ dtls1_buffer_message(SSL *s, int is_ccs) | |||
1003 | frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; | 1181 | frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; |
1004 | frag->msg_header.is_ccs = is_ccs; | 1182 | frag->msg_header.is_ccs = is_ccs; |
1005 | 1183 | ||
1006 | pq_64bit_init(&seq64); | 1184 | /* save current state*/ |
1007 | pq_64bit_assign_word(&seq64, epoch<<16 | frag->msg_header.seq); | 1185 | frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx; |
1008 | 1186 | frag->msg_header.saved_retransmit_state.write_hash = s->write_hash; | |
1009 | item = pitem_new(seq64, frag); | 1187 | frag->msg_header.saved_retransmit_state.compress = s->compress; |
1010 | pq_64bit_free(&seq64); | 1188 | frag->msg_header.saved_retransmit_state.session = s->session; |
1189 | frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch; | ||
1190 | |||
1191 | memset(seq64be,0,sizeof(seq64be)); | ||
1192 | seq64be[6] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq, | ||
1193 | frag->msg_header.is_ccs)>>8); | ||
1194 | seq64be[7] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq, | ||
1195 | frag->msg_header.is_ccs)); | ||
1196 | |||
1197 | item = pitem_new(seq64be, frag); | ||
1011 | if ( item == NULL) | 1198 | if ( item == NULL) |
1012 | { | 1199 | { |
1013 | dtls1_hm_fragment_free(frag); | 1200 | dtls1_hm_fragment_free(frag); |
@@ -1033,7 +1220,9 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, | |||
1033 | pitem *item; | 1220 | pitem *item; |
1034 | hm_fragment *frag ; | 1221 | hm_fragment *frag ; |
1035 | unsigned long header_length; | 1222 | unsigned long header_length; |
1036 | PQ_64BIT seq64; | 1223 | unsigned char seq64be[8]; |
1224 | struct dtls1_retransmit_state saved_state; | ||
1225 | unsigned char save_write_sequence[8]; | ||
1037 | 1226 | ||
1038 | /* | 1227 | /* |
1039 | OPENSSL_assert(s->init_num == 0); | 1228 | OPENSSL_assert(s->init_num == 0); |
@@ -1041,11 +1230,11 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, | |||
1041 | */ | 1230 | */ |
1042 | 1231 | ||
1043 | /* XDTLS: the requested message ought to be found, otherwise error */ | 1232 | /* XDTLS: the requested message ought to be found, otherwise error */ |
1044 | pq_64bit_init(&seq64); | 1233 | memset(seq64be,0,sizeof(seq64be)); |
1045 | pq_64bit_assign_word(&seq64, seq); | 1234 | seq64be[6] = (unsigned char)(seq>>8); |
1235 | seq64be[7] = (unsigned char)seq; | ||
1046 | 1236 | ||
1047 | item = pqueue_find(s->d1->sent_messages, seq64); | 1237 | item = pqueue_find(s->d1->sent_messages, seq64be); |
1048 | pq_64bit_free(&seq64); | ||
1049 | if ( item == NULL) | 1238 | if ( item == NULL) |
1050 | { | 1239 | { |
1051 | fprintf(stderr, "retransmit: message %d non-existant\n", seq); | 1240 | fprintf(stderr, "retransmit: message %d non-existant\n", seq); |
@@ -1069,9 +1258,45 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, | |||
1069 | frag->msg_header.msg_len, frag->msg_header.seq, 0, | 1258 | frag->msg_header.msg_len, frag->msg_header.seq, 0, |
1070 | frag->msg_header.frag_len); | 1259 | frag->msg_header.frag_len); |
1071 | 1260 | ||
1261 | /* save current state */ | ||
1262 | saved_state.enc_write_ctx = s->enc_write_ctx; | ||
1263 | saved_state.write_hash = s->write_hash; | ||
1264 | saved_state.compress = s->compress; | ||
1265 | saved_state.session = s->session; | ||
1266 | saved_state.epoch = s->d1->w_epoch; | ||
1267 | saved_state.epoch = s->d1->w_epoch; | ||
1268 | |||
1072 | s->d1->retransmitting = 1; | 1269 | s->d1->retransmitting = 1; |
1270 | |||
1271 | /* restore state in which the message was originally sent */ | ||
1272 | s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx; | ||
1273 | s->write_hash = frag->msg_header.saved_retransmit_state.write_hash; | ||
1274 | s->compress = frag->msg_header.saved_retransmit_state.compress; | ||
1275 | s->session = frag->msg_header.saved_retransmit_state.session; | ||
1276 | s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch; | ||
1277 | |||
1278 | if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1) | ||
1279 | { | ||
1280 | memcpy(save_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence)); | ||
1281 | memcpy(s->s3->write_sequence, s->d1->last_write_sequence, sizeof(s->s3->write_sequence)); | ||
1282 | } | ||
1283 | |||
1073 | ret = dtls1_do_write(s, frag->msg_header.is_ccs ? | 1284 | ret = dtls1_do_write(s, frag->msg_header.is_ccs ? |
1074 | SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); | 1285 | SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); |
1286 | |||
1287 | /* restore current state */ | ||
1288 | s->enc_write_ctx = saved_state.enc_write_ctx; | ||
1289 | s->write_hash = saved_state.write_hash; | ||
1290 | s->compress = saved_state.compress; | ||
1291 | s->session = saved_state.session; | ||
1292 | s->d1->w_epoch = saved_state.epoch; | ||
1293 | |||
1294 | if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1) | ||
1295 | { | ||
1296 | memcpy(s->d1->last_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence)); | ||
1297 | memcpy(s->s3->write_sequence, save_write_sequence, sizeof(s->s3->write_sequence)); | ||
1298 | } | ||
1299 | |||
1075 | s->d1->retransmitting = 0; | 1300 | s->d1->retransmitting = 0; |
1076 | 1301 | ||
1077 | (void)BIO_flush(SSL_get_wbio(s)); | 1302 | (void)BIO_flush(SSL_get_wbio(s)); |
@@ -1160,7 +1385,7 @@ dtls1_min_mtu(void) | |||
1160 | static unsigned int | 1385 | static unsigned int |
1161 | dtls1_guess_mtu(unsigned int curr_mtu) | 1386 | dtls1_guess_mtu(unsigned int curr_mtu) |
1162 | { | 1387 | { |
1163 | size_t i; | 1388 | unsigned int i; |
1164 | 1389 | ||
1165 | if ( curr_mtu == 0 ) | 1390 | if ( curr_mtu == 0 ) |
1166 | return g_probable_mtu[0] ; | 1391 | return g_probable_mtu[0] ; |
diff --git a/src/lib/libssl/d1_enc.c b/src/lib/libssl/d1_enc.c index cf3332e4e4..8fa57347a9 100644 --- a/src/lib/libssl/d1_enc.c +++ b/src/lib/libssl/d1_enc.c | |||
@@ -136,8 +136,12 @@ int dtls1_enc(SSL *s, int send) | |||
136 | 136 | ||
137 | if (send) | 137 | if (send) |
138 | { | 138 | { |
139 | if (s->write_hash != NULL) | 139 | if (EVP_MD_CTX_md(s->write_hash)) |
140 | n=EVP_MD_size(s->write_hash); | 140 | { |
141 | n=EVP_MD_CTX_size(s->write_hash); | ||
142 | if (n < 0) | ||
143 | return -1; | ||
144 | } | ||
141 | ds=s->enc_write_ctx; | 145 | ds=s->enc_write_ctx; |
142 | rec= &(s->s3->wrec); | 146 | rec= &(s->s3->wrec); |
143 | if (s->enc_write_ctx == NULL) | 147 | if (s->enc_write_ctx == NULL) |
@@ -151,15 +155,19 @@ int dtls1_enc(SSL *s, int send) | |||
151 | __FILE__, __LINE__); | 155 | __FILE__, __LINE__); |
152 | else if ( EVP_CIPHER_block_size(ds->cipher) > 1) | 156 | else if ( EVP_CIPHER_block_size(ds->cipher) > 1) |
153 | { | 157 | { |
154 | if (!RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher))) | 158 | if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0) |
155 | return -1; | 159 | return -1; |
156 | } | 160 | } |
157 | } | 161 | } |
158 | } | 162 | } |
159 | else | 163 | else |
160 | { | 164 | { |
161 | if (s->read_hash != NULL) | 165 | if (EVP_MD_CTX_md(s->read_hash)) |
162 | n=EVP_MD_size(s->read_hash); | 166 | { |
167 | n=EVP_MD_CTX_size(s->read_hash); | ||
168 | if (n < 0) | ||
169 | return -1; | ||
170 | } | ||
163 | ds=s->enc_read_ctx; | 171 | ds=s->enc_read_ctx; |
164 | rec= &(s->s3->rrec); | 172 | rec= &(s->s3->rrec); |
165 | if (s->enc_read_ctx == NULL) | 173 | if (s->enc_read_ctx == NULL) |
@@ -206,11 +214,10 @@ int dtls1_enc(SSL *s, int send) | |||
206 | { | 214 | { |
207 | unsigned long ui; | 215 | unsigned long ui; |
208 | printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", | 216 | printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", |
209 | (void *)ds,rec->data,rec->input,l); | 217 | ds,rec->data,rec->input,l); |
210 | printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n", | 218 | printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", |
211 | ds->buf_len, ds->cipher->key_len, | 219 | ds->buf_len, ds->cipher->key_len, |
212 | (unsigned long)DES_KEY_SZ, | 220 | DES_KEY_SZ, DES_SCHEDULE_SZ, |
213 | (unsigned long)DES_SCHEDULE_SZ, | ||
214 | ds->cipher->iv_len); | 221 | ds->cipher->iv_len); |
215 | printf("\t\tIV: "); | 222 | printf("\t\tIV: "); |
216 | for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]); | 223 | for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]); |
@@ -235,10 +242,10 @@ int dtls1_enc(SSL *s, int send) | |||
235 | 242 | ||
236 | #ifdef KSSL_DEBUG | 243 | #ifdef KSSL_DEBUG |
237 | { | 244 | { |
238 | unsigned long ki; | 245 | unsigned long i; |
239 | printf("\trec->data="); | 246 | printf("\trec->data="); |
240 | for (ki=0; ki<l; ki++) | 247 | for (i=0; i<l; i++) |
241 | printf(" %02x", rec->data[ki]); printf("\n"); | 248 | printf(" %02x", rec->data[i]); printf("\n"); |
242 | } | 249 | } |
243 | #endif /* KSSL_DEBUG */ | 250 | #endif /* KSSL_DEBUG */ |
244 | 251 | ||
diff --git a/src/lib/libssl/d1_lib.c b/src/lib/libssl/d1_lib.c index 3568e97a87..96b220e87c 100644 --- a/src/lib/libssl/d1_lib.c +++ b/src/lib/libssl/d1_lib.c | |||
@@ -58,10 +58,17 @@ | |||
58 | */ | 58 | */ |
59 | 59 | ||
60 | #include <stdio.h> | 60 | #include <stdio.h> |
61 | #define USE_SOCKETS | ||
61 | #include <openssl/objects.h> | 62 | #include <openssl/objects.h> |
62 | #include "ssl_locl.h" | 63 | #include "ssl_locl.h" |
63 | 64 | ||
65 | #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) | ||
66 | #include <sys/timeb.h> | ||
67 | #endif | ||
68 | |||
69 | static void get_current_time(struct timeval *t); | ||
64 | const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; | 70 | const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; |
71 | int dtls1_listen(SSL *s, struct sockaddr *client); | ||
65 | 72 | ||
66 | SSL3_ENC_METHOD DTLSv1_enc_data={ | 73 | SSL3_ENC_METHOD DTLSv1_enc_data={ |
67 | dtls1_enc, | 74 | dtls1_enc, |
@@ -84,11 +91,6 @@ long dtls1_default_timeout(void) | |||
84 | return(60*60*2); | 91 | return(60*60*2); |
85 | } | 92 | } |
86 | 93 | ||
87 | IMPLEMENT_dtls1_meth_func(dtlsv1_base_method, | ||
88 | ssl_undefined_function, | ||
89 | ssl_undefined_function, | ||
90 | ssl_bad_method) | ||
91 | |||
92 | int dtls1_new(SSL *s) | 94 | int dtls1_new(SSL *s) |
93 | { | 95 | { |
94 | DTLS1_STATE *d1; | 96 | DTLS1_STATE *d1; |
@@ -98,22 +100,12 @@ int dtls1_new(SSL *s) | |||
98 | memset(d1,0, sizeof *d1); | 100 | memset(d1,0, sizeof *d1); |
99 | 101 | ||
100 | /* d1->handshake_epoch=0; */ | 102 | /* d1->handshake_epoch=0; */ |
101 | #if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST) | ||
102 | d1->bitmap.length=64; | ||
103 | #else | ||
104 | d1->bitmap.length=sizeof(d1->bitmap.map) * 8; | ||
105 | #endif | ||
106 | pq_64bit_init(&(d1->bitmap.map)); | ||
107 | pq_64bit_init(&(d1->bitmap.max_seq_num)); | ||
108 | |||
109 | d1->next_bitmap.length = d1->bitmap.length; | ||
110 | pq_64bit_init(&(d1->next_bitmap.map)); | ||
111 | pq_64bit_init(&(d1->next_bitmap.max_seq_num)); | ||
112 | 103 | ||
113 | d1->unprocessed_rcds.q=pqueue_new(); | 104 | d1->unprocessed_rcds.q=pqueue_new(); |
114 | d1->processed_rcds.q=pqueue_new(); | 105 | d1->processed_rcds.q=pqueue_new(); |
115 | d1->buffered_messages = pqueue_new(); | 106 | d1->buffered_messages = pqueue_new(); |
116 | d1->sent_messages=pqueue_new(); | 107 | d1->sent_messages=pqueue_new(); |
108 | d1->buffered_app_data.q=pqueue_new(); | ||
117 | 109 | ||
118 | if ( s->server) | 110 | if ( s->server) |
119 | { | 111 | { |
@@ -121,12 +113,13 @@ int dtls1_new(SSL *s) | |||
121 | } | 113 | } |
122 | 114 | ||
123 | if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q | 115 | if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q |
124 | || ! d1->buffered_messages || ! d1->sent_messages) | 116 | || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q) |
125 | { | 117 | { |
126 | if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q); | 118 | if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q); |
127 | if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q); | 119 | if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q); |
128 | if ( d1->buffered_messages) pqueue_free(d1->buffered_messages); | 120 | if ( d1->buffered_messages) pqueue_free(d1->buffered_messages); |
129 | if ( d1->sent_messages) pqueue_free(d1->sent_messages); | 121 | if ( d1->sent_messages) pqueue_free(d1->sent_messages); |
122 | if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.q); | ||
130 | OPENSSL_free(d1); | 123 | OPENSSL_free(d1); |
131 | return (0); | 124 | return (0); |
132 | } | 125 | } |
@@ -175,11 +168,14 @@ void dtls1_free(SSL *s) | |||
175 | } | 168 | } |
176 | pqueue_free(s->d1->sent_messages); | 169 | pqueue_free(s->d1->sent_messages); |
177 | 170 | ||
178 | pq_64bit_free(&(s->d1->bitmap.map)); | 171 | while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) |
179 | pq_64bit_free(&(s->d1->bitmap.max_seq_num)); | 172 | { |
180 | 173 | frag = (hm_fragment *)item->data; | |
181 | pq_64bit_free(&(s->d1->next_bitmap.map)); | 174 | OPENSSL_free(frag->fragment); |
182 | pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); | 175 | OPENSSL_free(frag); |
176 | pitem_free(item); | ||
177 | } | ||
178 | pqueue_free(s->d1->buffered_app_data.q); | ||
183 | 179 | ||
184 | OPENSSL_free(s->d1); | 180 | OPENSSL_free(s->d1); |
185 | } | 181 | } |
@@ -187,7 +183,36 @@ void dtls1_free(SSL *s) | |||
187 | void dtls1_clear(SSL *s) | 183 | void dtls1_clear(SSL *s) |
188 | { | 184 | { |
189 | ssl3_clear(s); | 185 | ssl3_clear(s); |
190 | s->version=DTLS1_VERSION; | 186 | if (s->options & SSL_OP_CISCO_ANYCONNECT) |
187 | s->version=DTLS1_BAD_VER; | ||
188 | else | ||
189 | s->version=DTLS1_VERSION; | ||
190 | } | ||
191 | |||
192 | long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) | ||
193 | { | ||
194 | int ret=0; | ||
195 | |||
196 | switch (cmd) | ||
197 | { | ||
198 | case DTLS_CTRL_GET_TIMEOUT: | ||
199 | if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) | ||
200 | { | ||
201 | ret = 1; | ||
202 | } | ||
203 | break; | ||
204 | case DTLS_CTRL_HANDLE_TIMEOUT: | ||
205 | ret = dtls1_handle_timeout(s); | ||
206 | break; | ||
207 | case DTLS_CTRL_LISTEN: | ||
208 | ret = dtls1_listen(s, parg); | ||
209 | break; | ||
210 | |||
211 | default: | ||
212 | ret = ssl3_ctrl(s, cmd, larg, parg); | ||
213 | break; | ||
214 | } | ||
215 | return(ret); | ||
191 | } | 216 | } |
192 | 217 | ||
193 | /* | 218 | /* |
@@ -197,15 +222,173 @@ void dtls1_clear(SSL *s) | |||
197 | * to explicitly list their SSL_* codes. Currently RC4 is the only one | 222 | * to explicitly list their SSL_* codes. Currently RC4 is the only one |
198 | * available, but if new ones emerge, they will have to be added... | 223 | * available, but if new ones emerge, they will have to be added... |
199 | */ | 224 | */ |
200 | SSL_CIPHER *dtls1_get_cipher(unsigned int u) | 225 | const SSL_CIPHER *dtls1_get_cipher(unsigned int u) |
201 | { | 226 | { |
202 | SSL_CIPHER *ciph = ssl3_get_cipher(u); | 227 | const SSL_CIPHER *ciph = ssl3_get_cipher(u); |
203 | 228 | ||
204 | if (ciph != NULL) | 229 | if (ciph != NULL) |
205 | { | 230 | { |
206 | if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4) | 231 | if (ciph->algorithm_enc == SSL_RC4) |
207 | return NULL; | 232 | return NULL; |
208 | } | 233 | } |
209 | 234 | ||
210 | return ciph; | 235 | return ciph; |
211 | } | 236 | } |
237 | |||
238 | void dtls1_start_timer(SSL *s) | ||
239 | { | ||
240 | /* If timer is not set, initialize duration with 1 second */ | ||
241 | if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) | ||
242 | { | ||
243 | s->d1->timeout_duration = 1; | ||
244 | } | ||
245 | |||
246 | /* Set timeout to current time */ | ||
247 | get_current_time(&(s->d1->next_timeout)); | ||
248 | |||
249 | /* Add duration to current time */ | ||
250 | s->d1->next_timeout.tv_sec += s->d1->timeout_duration; | ||
251 | BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); | ||
252 | } | ||
253 | |||
254 | struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft) | ||
255 | { | ||
256 | struct timeval timenow; | ||
257 | |||
258 | /* If no timeout is set, just return NULL */ | ||
259 | if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) | ||
260 | { | ||
261 | return NULL; | ||
262 | } | ||
263 | |||
264 | /* Get current time */ | ||
265 | get_current_time(&timenow); | ||
266 | |||
267 | /* If timer already expired, set remaining time to 0 */ | ||
268 | if (s->d1->next_timeout.tv_sec < timenow.tv_sec || | ||
269 | (s->d1->next_timeout.tv_sec == timenow.tv_sec && | ||
270 | s->d1->next_timeout.tv_usec <= timenow.tv_usec)) | ||
271 | { | ||
272 | memset(timeleft, 0, sizeof(struct timeval)); | ||
273 | return timeleft; | ||
274 | } | ||
275 | |||
276 | /* Calculate time left until timer expires */ | ||
277 | memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); | ||
278 | timeleft->tv_sec -= timenow.tv_sec; | ||
279 | timeleft->tv_usec -= timenow.tv_usec; | ||
280 | if (timeleft->tv_usec < 0) | ||
281 | { | ||
282 | timeleft->tv_sec--; | ||
283 | timeleft->tv_usec += 1000000; | ||
284 | } | ||
285 | |||
286 | /* If remaining time is less than 15 ms, set it to 0 | ||
287 | * to prevent issues because of small devergences with | ||
288 | * socket timeouts. | ||
289 | */ | ||
290 | if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) | ||
291 | { | ||
292 | memset(timeleft, 0, sizeof(struct timeval)); | ||
293 | } | ||
294 | |||
295 | |||
296 | return timeleft; | ||
297 | } | ||
298 | |||
299 | int dtls1_is_timer_expired(SSL *s) | ||
300 | { | ||
301 | struct timeval timeleft; | ||
302 | |||
303 | /* Get time left until timeout, return false if no timer running */ | ||
304 | if (dtls1_get_timeout(s, &timeleft) == NULL) | ||
305 | { | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | /* Return false if timer is not expired yet */ | ||
310 | if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) | ||
311 | { | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | /* Timer expired, so return true */ | ||
316 | return 1; | ||
317 | } | ||
318 | |||
319 | void dtls1_double_timeout(SSL *s) | ||
320 | { | ||
321 | s->d1->timeout_duration *= 2; | ||
322 | if (s->d1->timeout_duration > 60) | ||
323 | s->d1->timeout_duration = 60; | ||
324 | dtls1_start_timer(s); | ||
325 | } | ||
326 | |||
327 | void dtls1_stop_timer(SSL *s) | ||
328 | { | ||
329 | /* Reset everything */ | ||
330 | memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); | ||
331 | s->d1->timeout_duration = 1; | ||
332 | BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); | ||
333 | } | ||
334 | |||
335 | int dtls1_handle_timeout(SSL *s) | ||
336 | { | ||
337 | DTLS1_STATE *state; | ||
338 | |||
339 | /* if no timer is expired, don't do anything */ | ||
340 | if (!dtls1_is_timer_expired(s)) | ||
341 | { | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | dtls1_double_timeout(s); | ||
346 | state = s->d1; | ||
347 | state->timeout.num_alerts++; | ||
348 | if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) | ||
349 | { | ||
350 | /* fail the connection, enough alerts have been sent */ | ||
351 | SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED); | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | state->timeout.read_timeouts++; | ||
356 | if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) | ||
357 | { | ||
358 | state->timeout.read_timeouts = 1; | ||
359 | } | ||
360 | |||
361 | dtls1_start_timer(s); | ||
362 | return dtls1_retransmit_buffered_messages(s); | ||
363 | } | ||
364 | |||
365 | static void get_current_time(struct timeval *t) | ||
366 | { | ||
367 | #ifdef OPENSSL_SYS_WIN32 | ||
368 | struct _timeb tb; | ||
369 | _ftime(&tb); | ||
370 | t->tv_sec = (long)tb.time; | ||
371 | t->tv_usec = (long)tb.millitm * 1000; | ||
372 | #elif defined(OPENSSL_SYS_VMS) | ||
373 | struct timeb tb; | ||
374 | ftime(&tb); | ||
375 | t->tv_sec = (long)tb.time; | ||
376 | t->tv_usec = (long)tb.millitm * 1000; | ||
377 | #else | ||
378 | gettimeofday(t, NULL); | ||
379 | #endif | ||
380 | } | ||
381 | |||
382 | int dtls1_listen(SSL *s, struct sockaddr *client) | ||
383 | { | ||
384 | int ret; | ||
385 | |||
386 | SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); | ||
387 | s->d1->listen = 1; | ||
388 | |||
389 | ret = SSL_accept(s); | ||
390 | if (ret <= 0) return ret; | ||
391 | |||
392 | (void) BIO_dgram_get_peer(SSL_get_rbio(s), client); | ||
393 | return 1; | ||
394 | } | ||
diff --git a/src/lib/libssl/d1_meth.c b/src/lib/libssl/d1_meth.c index 8a6cf31947..5c4004bfe3 100644 --- a/src/lib/libssl/d1_meth.c +++ b/src/lib/libssl/d1_meth.c | |||
@@ -61,8 +61,8 @@ | |||
61 | #include <openssl/objects.h> | 61 | #include <openssl/objects.h> |
62 | #include "ssl_locl.h" | 62 | #include "ssl_locl.h" |
63 | 63 | ||
64 | static SSL_METHOD *dtls1_get_method(int ver); | 64 | static const SSL_METHOD *dtls1_get_method(int ver); |
65 | static SSL_METHOD *dtls1_get_method(int ver) | 65 | static const SSL_METHOD *dtls1_get_method(int ver) |
66 | { | 66 | { |
67 | if (ver == DTLS1_VERSION) | 67 | if (ver == DTLS1_VERSION) |
68 | return(DTLSv1_method()); | 68 | return(DTLSv1_method()); |
diff --git a/src/lib/libssl/t1_reneg.c b/src/lib/libssl/t1_reneg.c new file mode 100644 index 0000000000..9c2cc3c712 --- /dev/null +++ b/src/lib/libssl/t1_reneg.c | |||
@@ -0,0 +1,292 @@ | |||
1 | /* ssl/t1_reneg.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | /* ==================================================================== | ||
59 | * Copyright (c) 1998-2009 The OpenSSL Project. All rights reserved. | ||
60 | * | ||
61 | * Redistribution and use in source and binary forms, with or without | ||
62 | * modification, are permitted provided that the following conditions | ||
63 | * are met: | ||
64 | * | ||
65 | * 1. Redistributions of source code must retain the above copyright | ||
66 | * notice, this list of conditions and the following disclaimer. | ||
67 | * | ||
68 | * 2. Redistributions in binary form must reproduce the above copyright | ||
69 | * notice, this list of conditions and the following disclaimer in | ||
70 | * the documentation and/or other materials provided with the | ||
71 | * distribution. | ||
72 | * | ||
73 | * 3. All advertising materials mentioning features or use of this | ||
74 | * software must display the following acknowledgment: | ||
75 | * "This product includes software developed by the OpenSSL Project | ||
76 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
77 | * | ||
78 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
79 | * endorse or promote products derived from this software without | ||
80 | * prior written permission. For written permission, please contact | ||
81 | * openssl-core@openssl.org. | ||
82 | * | ||
83 | * 5. Products derived from this software may not be called "OpenSSL" | ||
84 | * nor may "OpenSSL" appear in their names without prior written | ||
85 | * permission of the OpenSSL Project. | ||
86 | * | ||
87 | * 6. Redistributions of any form whatsoever must retain the following | ||
88 | * acknowledgment: | ||
89 | * "This product includes software developed by the OpenSSL Project | ||
90 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
91 | * | ||
92 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
93 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
94 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
95 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
96 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
97 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
98 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
99 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
100 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
101 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
102 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
103 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
104 | * ==================================================================== | ||
105 | * | ||
106 | * This product includes cryptographic software written by Eric Young | ||
107 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
108 | * Hudson (tjh@cryptsoft.com). | ||
109 | * | ||
110 | */ | ||
111 | #include <stdio.h> | ||
112 | #include <openssl/objects.h> | ||
113 | #include "ssl_locl.h" | ||
114 | |||
115 | /* Add the client's renegotiation binding */ | ||
116 | int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, | ||
117 | int maxlen) | ||
118 | { | ||
119 | if(p) | ||
120 | { | ||
121 | if((s->s3->previous_client_finished_len+1) > maxlen) | ||
122 | { | ||
123 | SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | /* Length byte */ | ||
128 | *p = s->s3->previous_client_finished_len; | ||
129 | p++; | ||
130 | |||
131 | memcpy(p, s->s3->previous_client_finished, | ||
132 | s->s3->previous_client_finished_len); | ||
133 | #ifdef OPENSSL_RI_DEBUG | ||
134 | fprintf(stderr, "%s RI extension sent by client\n", | ||
135 | s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); | ||
136 | #endif | ||
137 | } | ||
138 | |||
139 | *len=s->s3->previous_client_finished_len + 1; | ||
140 | |||
141 | |||
142 | return 1; | ||
143 | } | ||
144 | |||
145 | /* Parse the client's renegotiation binding and abort if it's not | ||
146 | right */ | ||
147 | int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, | ||
148 | int *al) | ||
149 | { | ||
150 | int ilen; | ||
151 | |||
152 | /* Parse the length byte */ | ||
153 | if(len < 1) | ||
154 | { | ||
155 | SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR); | ||
156 | *al=SSL_AD_ILLEGAL_PARAMETER; | ||
157 | return 0; | ||
158 | } | ||
159 | ilen = *d; | ||
160 | d++; | ||
161 | |||
162 | /* Consistency check */ | ||
163 | if((ilen+1) != len) | ||
164 | { | ||
165 | SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR); | ||
166 | *al=SSL_AD_ILLEGAL_PARAMETER; | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | /* Check that the extension matches */ | ||
171 | if(ilen != s->s3->previous_client_finished_len) | ||
172 | { | ||
173 | SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); | ||
174 | *al=SSL_AD_HANDSHAKE_FAILURE; | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | if(memcmp(d, s->s3->previous_client_finished, | ||
179 | s->s3->previous_client_finished_len)) | ||
180 | { | ||
181 | SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); | ||
182 | *al=SSL_AD_HANDSHAKE_FAILURE; | ||
183 | return 0; | ||
184 | } | ||
185 | #ifdef OPENSSL_RI_DEBUG | ||
186 | fprintf(stderr, "%s RI extension received by server\n", | ||
187 | ilen ? "Non-empty" : "Empty"); | ||
188 | #endif | ||
189 | |||
190 | s->s3->send_connection_binding=1; | ||
191 | |||
192 | return 1; | ||
193 | } | ||
194 | |||
195 | /* Add the server's renegotiation binding */ | ||
196 | int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, | ||
197 | int maxlen) | ||
198 | { | ||
199 | if(p) | ||
200 | { | ||
201 | if((s->s3->previous_client_finished_len + | ||
202 | s->s3->previous_server_finished_len + 1) > maxlen) | ||
203 | { | ||
204 | SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG); | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | /* Length byte */ | ||
209 | *p = s->s3->previous_client_finished_len + s->s3->previous_server_finished_len; | ||
210 | p++; | ||
211 | |||
212 | memcpy(p, s->s3->previous_client_finished, | ||
213 | s->s3->previous_client_finished_len); | ||
214 | p += s->s3->previous_client_finished_len; | ||
215 | |||
216 | memcpy(p, s->s3->previous_server_finished, | ||
217 | s->s3->previous_server_finished_len); | ||
218 | #ifdef OPENSSL_RI_DEBUG | ||
219 | fprintf(stderr, "%s RI extension sent by server\n", | ||
220 | s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); | ||
221 | #endif | ||
222 | } | ||
223 | |||
224 | *len=s->s3->previous_client_finished_len | ||
225 | + s->s3->previous_server_finished_len + 1; | ||
226 | |||
227 | return 1; | ||
228 | } | ||
229 | |||
230 | /* Parse the server's renegotiation binding and abort if it's not | ||
231 | right */ | ||
232 | int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, | ||
233 | int *al) | ||
234 | { | ||
235 | int expected_len=s->s3->previous_client_finished_len | ||
236 | + s->s3->previous_server_finished_len; | ||
237 | int ilen; | ||
238 | |||
239 | /* Check for logic errors */ | ||
240 | OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len); | ||
241 | OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len); | ||
242 | |||
243 | /* Parse the length byte */ | ||
244 | if(len < 1) | ||
245 | { | ||
246 | SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR); | ||
247 | *al=SSL_AD_ILLEGAL_PARAMETER; | ||
248 | return 0; | ||
249 | } | ||
250 | ilen = *d; | ||
251 | d++; | ||
252 | |||
253 | /* Consistency check */ | ||
254 | if(ilen+1 != len) | ||
255 | { | ||
256 | SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR); | ||
257 | *al=SSL_AD_ILLEGAL_PARAMETER; | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | /* Check that the extension matches */ | ||
262 | if(ilen != expected_len) | ||
263 | { | ||
264 | SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); | ||
265 | *al=SSL_AD_HANDSHAKE_FAILURE; | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | if(memcmp(d, s->s3->previous_client_finished, | ||
270 | s->s3->previous_client_finished_len)) | ||
271 | { | ||
272 | SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); | ||
273 | *al=SSL_AD_HANDSHAKE_FAILURE; | ||
274 | return 0; | ||
275 | } | ||
276 | d += s->s3->previous_client_finished_len; | ||
277 | |||
278 | if(memcmp(d, s->s3->previous_server_finished, | ||
279 | s->s3->previous_server_finished_len)) | ||
280 | { | ||
281 | SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); | ||
282 | *al=SSL_AD_ILLEGAL_PARAMETER; | ||
283 | return 0; | ||
284 | } | ||
285 | #ifdef OPENSSL_RI_DEBUG | ||
286 | fprintf(stderr, "%s RI extension received by client\n", | ||
287 | ilen ? "Non-empty" : "Empty"); | ||
288 | #endif | ||
289 | s->s3->send_connection_binding=1; | ||
290 | |||
291 | return 1; | ||
292 | } | ||
diff --git a/src/lib/libssl/test/CAss.cnf b/src/lib/libssl/test/CAss.cnf index 546e660626..20f8f05e3d 100644 --- a/src/lib/libssl/test/CAss.cnf +++ b/src/lib/libssl/test/CAss.cnf | |||
@@ -7,7 +7,7 @@ RANDFILE = ./.rnd | |||
7 | 7 | ||
8 | #################################################################### | 8 | #################################################################### |
9 | [ req ] | 9 | [ req ] |
10 | default_bits = 1024 | 10 | default_bits = 512 |
11 | default_keyfile = keySS.pem | 11 | default_keyfile = keySS.pem |
12 | distinguished_name = req_distinguished_name | 12 | distinguished_name = req_distinguished_name |
13 | encrypt_rsa_key = no | 13 | encrypt_rsa_key = no |
diff --git a/src/lib/libssl/test/CAtsa.cnf b/src/lib/libssl/test/CAtsa.cnf new file mode 100644 index 0000000000..f5a275bfc2 --- /dev/null +++ b/src/lib/libssl/test/CAtsa.cnf | |||
@@ -0,0 +1,163 @@ | |||
1 | |||
2 | # | ||
3 | # This config is used by the Time Stamp Authority tests. | ||
4 | # | ||
5 | |||
6 | RANDFILE = ./.rnd | ||
7 | |||
8 | # Extra OBJECT IDENTIFIER info: | ||
9 | oid_section = new_oids | ||
10 | |||
11 | TSDNSECT = ts_cert_dn | ||
12 | INDEX = 1 | ||
13 | |||
14 | [ new_oids ] | ||
15 | |||
16 | # Policies used by the TSA tests. | ||
17 | tsa_policy1 = 1.2.3.4.1 | ||
18 | tsa_policy2 = 1.2.3.4.5.6 | ||
19 | tsa_policy3 = 1.2.3.4.5.7 | ||
20 | |||
21 | #---------------------------------------------------------------------- | ||
22 | [ ca ] | ||
23 | default_ca = CA_default # The default ca section | ||
24 | |||
25 | [ CA_default ] | ||
26 | |||
27 | dir = ./demoCA | ||
28 | certs = $dir/certs # Where the issued certs are kept | ||
29 | database = $dir/index.txt # database index file. | ||
30 | new_certs_dir = $dir/newcerts # default place for new certs. | ||
31 | |||
32 | certificate = $dir/cacert.pem # The CA certificate | ||
33 | serial = $dir/serial # The current serial number | ||
34 | private_key = $dir/private/cakey.pem# The private key | ||
35 | RANDFILE = $dir/private/.rand # private random number file | ||
36 | |||
37 | default_days = 365 # how long to certify for | ||
38 | default_md = sha1 # which md to use. | ||
39 | preserve = no # keep passed DN ordering | ||
40 | |||
41 | policy = policy_match | ||
42 | |||
43 | # For the CA policy | ||
44 | [ policy_match ] | ||
45 | countryName = supplied | ||
46 | stateOrProvinceName = supplied | ||
47 | organizationName = supplied | ||
48 | organizationalUnitName = optional | ||
49 | commonName = supplied | ||
50 | emailAddress = optional | ||
51 | |||
52 | #---------------------------------------------------------------------- | ||
53 | [ req ] | ||
54 | default_bits = 1024 | ||
55 | default_md = sha1 | ||
56 | distinguished_name = $ENV::TSDNSECT | ||
57 | encrypt_rsa_key = no | ||
58 | prompt = no | ||
59 | # attributes = req_attributes | ||
60 | x509_extensions = v3_ca # The extentions to add to the self signed cert | ||
61 | |||
62 | string_mask = nombstr | ||
63 | |||
64 | [ ts_ca_dn ] | ||
65 | countryName = HU | ||
66 | stateOrProvinceName = Budapest | ||
67 | localityName = Budapest | ||
68 | organizationName = Gov-CA Ltd. | ||
69 | commonName = ca1 | ||
70 | |||
71 | [ ts_cert_dn ] | ||
72 | countryName = HU | ||
73 | stateOrProvinceName = Budapest | ||
74 | localityName = Buda | ||
75 | organizationName = Hun-TSA Ltd. | ||
76 | commonName = tsa$ENV::INDEX | ||
77 | |||
78 | [ tsa_cert ] | ||
79 | |||
80 | # TSA server cert is not a CA cert. | ||
81 | basicConstraints=CA:FALSE | ||
82 | |||
83 | # The following key usage flags are needed for TSA server certificates. | ||
84 | keyUsage = nonRepudiation, digitalSignature | ||
85 | extendedKeyUsage = critical,timeStamping | ||
86 | |||
87 | # PKIX recommendations harmless if included in all certificates. | ||
88 | subjectKeyIdentifier=hash | ||
89 | authorityKeyIdentifier=keyid,issuer:always | ||
90 | |||
91 | [ non_tsa_cert ] | ||
92 | |||
93 | # This is not a CA cert and not a TSA cert, either (timeStamping usage missing) | ||
94 | basicConstraints=CA:FALSE | ||
95 | |||
96 | # The following key usage flags are needed for TSA server certificates. | ||
97 | keyUsage = nonRepudiation, digitalSignature | ||
98 | # timeStamping is not supported by this certificate | ||
99 | # extendedKeyUsage = critical,timeStamping | ||
100 | |||
101 | # PKIX recommendations harmless if included in all certificates. | ||
102 | subjectKeyIdentifier=hash | ||
103 | authorityKeyIdentifier=keyid,issuer:always | ||
104 | |||
105 | [ v3_req ] | ||
106 | |||
107 | # Extensions to add to a certificate request | ||
108 | basicConstraints = CA:FALSE | ||
109 | keyUsage = nonRepudiation, digitalSignature | ||
110 | |||
111 | [ v3_ca ] | ||
112 | |||
113 | # Extensions for a typical CA | ||
114 | |||
115 | subjectKeyIdentifier=hash | ||
116 | authorityKeyIdentifier=keyid:always,issuer:always | ||
117 | basicConstraints = critical,CA:true | ||
118 | keyUsage = cRLSign, keyCertSign | ||
119 | |||
120 | #---------------------------------------------------------------------- | ||
121 | [ tsa ] | ||
122 | |||
123 | default_tsa = tsa_config1 # the default TSA section | ||
124 | |||
125 | [ tsa_config1 ] | ||
126 | |||
127 | # These are used by the TSA reply generation only. | ||
128 | dir = . # TSA root directory | ||
129 | serial = $dir/tsa_serial # The current serial number (mandatory) | ||
130 | signer_cert = $dir/tsa_cert1.pem # The TSA signing certificate | ||
131 | # (optional) | ||
132 | certs = $dir/tsaca.pem # Certificate chain to include in reply | ||
133 | # (optional) | ||
134 | signer_key = $dir/tsa_key1.pem # The TSA private key (optional) | ||
135 | |||
136 | default_policy = tsa_policy1 # Policy if request did not specify it | ||
137 | # (optional) | ||
138 | other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) | ||
139 | digests = md5, sha1 # Acceptable message digests (mandatory) | ||
140 | accuracy = secs:1, millisecs:500, microsecs:100 # (optional) | ||
141 | ordering = yes # Is ordering defined for timestamps? | ||
142 | # (optional, default: no) | ||
143 | tsa_name = yes # Must the TSA name be included in the reply? | ||
144 | # (optional, default: no) | ||
145 | ess_cert_id_chain = yes # Must the ESS cert id chain be included? | ||
146 | # (optional, default: no) | ||
147 | |||
148 | [ tsa_config2 ] | ||
149 | |||
150 | # This configuration uses a certificate which doesn't have timeStamping usage. | ||
151 | # These are used by the TSA reply generation only. | ||
152 | dir = . # TSA root directory | ||
153 | serial = $dir/tsa_serial # The current serial number (mandatory) | ||
154 | signer_cert = $dir/tsa_cert2.pem # The TSA signing certificate | ||
155 | # (optional) | ||
156 | certs = $dir/demoCA/cacert.pem# Certificate chain to include in reply | ||
157 | # (optional) | ||
158 | signer_key = $dir/tsa_key2.pem # The TSA private key (optional) | ||
159 | |||
160 | default_policy = tsa_policy1 # Policy if request did not specify it | ||
161 | # (optional) | ||
162 | other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) | ||
163 | digests = md5, sha1 # Acceptable message digests (mandatory) | ||
diff --git a/src/lib/libssl/test/Uss.cnf b/src/lib/libssl/test/Uss.cnf index 98b2e054b7..0c0ebb5f67 100644 --- a/src/lib/libssl/test/Uss.cnf +++ b/src/lib/libssl/test/Uss.cnf | |||
@@ -7,7 +7,7 @@ RANDFILE = ./.rnd | |||
7 | 7 | ||
8 | #################################################################### | 8 | #################################################################### |
9 | [ req ] | 9 | [ req ] |
10 | default_bits = 1024 | 10 | default_bits = 512 |
11 | default_keyfile = keySS.pem | 11 | default_keyfile = keySS.pem |
12 | distinguished_name = req_distinguished_name | 12 | distinguished_name = req_distinguished_name |
13 | encrypt_rsa_key = no | 13 | encrypt_rsa_key = no |
diff --git a/src/lib/libssl/test/asn1test.c b/src/lib/libssl/test/asn1test.c new file mode 100755 index 0000000000..9f53d80344 --- /dev/null +++ b/src/lib/libssl/test/asn1test.c | |||
@@ -0,0 +1,22 @@ | |||
1 | #include <openssl/x509.h> | ||
2 | #include <openssl/asn1_mac.h> | ||
3 | |||
4 | typedef struct X | ||
5 | { | ||
6 | STACK_OF(X509_EXTENSION) *ext; | ||
7 | } X; | ||
8 | |||
9 | /* This isn't meant to run particularly, it's just to test type checking */ | ||
10 | int main(int argc, char **argv) | ||
11 | { | ||
12 | X *x = NULL; | ||
13 | unsigned char **pp = NULL; | ||
14 | |||
15 | M_ASN1_I2D_vars(x); | ||
16 | M_ASN1_I2D_len_SEQUENCE_opt_type(X509_EXTENSION, x->ext, | ||
17 | i2d_X509_EXTENSION); | ||
18 | M_ASN1_I2D_seq_total(); | ||
19 | M_ASN1_I2D_put_SEQUENCE_opt_type(X509_EXTENSION, x->ext, | ||
20 | i2d_X509_EXTENSION); | ||
21 | M_ASN1_I2D_finish(); | ||
22 | } | ||
diff --git a/src/lib/libssl/test/cms-test.pl b/src/lib/libssl/test/cms-test.pl index a84e089ddc..9c50dff3e9 100644 --- a/src/lib/libssl/test/cms-test.pl +++ b/src/lib/libssl/test/cms-test.pl | |||
@@ -54,8 +54,12 @@ | |||
54 | # OpenSSL PKCS#7 and CMS implementations. | 54 | # OpenSSL PKCS#7 and CMS implementations. |
55 | 55 | ||
56 | my $ossl_path; | 56 | my $ossl_path; |
57 | 57 | my $redir = " 2>cms.err 1>cms.out"; | |
58 | if ( -f "../apps/openssl" ) { | 58 | # Make MSYS work |
59 | if ( $^O eq "MSWin32" && -f "../apps/openssl.exe" ) { | ||
60 | $ossl_path = "cmd /c ..\\apps\\openssl"; | ||
61 | } | ||
62 | elsif ( -f "../apps/openssl$ENV{EXE_EXT}" ) { | ||
59 | $ossl_path = "../util/shlib_wrap.sh ../apps/openssl"; | 63 | $ossl_path = "../util/shlib_wrap.sh ../apps/openssl"; |
60 | } | 64 | } |
61 | elsif ( -f "..\\out32dll\\openssl.exe" ) { | 65 | elsif ( -f "..\\out32dll\\openssl.exe" ) { |
@@ -232,7 +236,7 @@ my @smime_cms_tests = ( | |||
232 | [ | 236 | [ |
233 | "signed content MIME format, RSA key, signed receipt request", | 237 | "signed content MIME format, RSA key, signed receipt request", |
234 | "-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach" | 238 | "-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach" |
235 | . " -receipt_request_to test@openssl.org -receipt_request_all" | 239 | . " -receipt_request_to test\@openssl.org -receipt_request_all" |
236 | . " -out test.cms", | 240 | . " -out test.cms", |
237 | "-verify -in test.cms " | 241 | "-verify -in test.cms " |
238 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | 242 | . " -CAfile $smdir/smroot.pem -out smtst.txt" |
@@ -333,10 +337,6 @@ my @smime_cms_comp_tests = ( | |||
333 | 337 | ||
334 | ); | 338 | ); |
335 | 339 | ||
336 | print "PKCS#7 <=> PKCS#7 consistency tests\n"; | ||
337 | |||
338 | run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $pk7cmd ); | ||
339 | |||
340 | print "CMS => PKCS#7 compatibility tests\n"; | 340 | print "CMS => PKCS#7 compatibility tests\n"; |
341 | 341 | ||
342 | run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd ); | 342 | run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd ); |
@@ -386,14 +386,14 @@ sub run_smime_tests { | |||
386 | $rscmd =~ s/-stream//; | 386 | $rscmd =~ s/-stream//; |
387 | $rvcmd =~ s/-stream//; | 387 | $rvcmd =~ s/-stream//; |
388 | } | 388 | } |
389 | system("$scmd$rscmd 2>cms.err 1>cms.out"); | 389 | system("$scmd$rscmd$redir"); |
390 | if ($?) { | 390 | if ($?) { |
391 | print "$tnam: generation error\n"; | 391 | print "$tnam: generation error\n"; |
392 | $$rv++; | 392 | $$rv++; |
393 | exit 1 if $halt_err; | 393 | exit 1 if $halt_err; |
394 | next; | 394 | next; |
395 | } | 395 | } |
396 | system("$vcmd$rvcmd 2>cms.err 1>cms.out"); | 396 | system("$vcmd$rvcmd$redir"); |
397 | if ($?) { | 397 | if ($?) { |
398 | print "$tnam: verify error\n"; | 398 | print "$tnam: verify error\n"; |
399 | $$rv++; | 399 | $$rv++; |
diff --git a/src/lib/libssl/test/pkits-test.pl b/src/lib/libssl/test/pkits-test.pl new file mode 100644 index 0000000000..69dffa16f9 --- /dev/null +++ b/src/lib/libssl/test/pkits-test.pl | |||
@@ -0,0 +1,940 @@ | |||
1 | # test/pkits-test.pl | ||
2 | # Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | # project. | ||
4 | # | ||
5 | # ==================================================================== | ||
6 | # Copyright (c) 2008 The OpenSSL Project. All rights reserved. | ||
7 | # | ||
8 | # Redistribution and use in source and binary forms, with or without | ||
9 | # modification, are permitted provided that the following conditions | ||
10 | # are met: | ||
11 | # | ||
12 | # 1. Redistributions of source code must retain the above copyright | ||
13 | # notice, this list of conditions and the following disclaimer. | ||
14 | # | ||
15 | # 2. Redistributions in binary form must reproduce the above copyright | ||
16 | # notice, this list of conditions and the following disclaimer in | ||
17 | # the documentation and/or other materials provided with the | ||
18 | # distribution. | ||
19 | # | ||
20 | # 3. All advertising materials mentioning features or use of this | ||
21 | # software must display the following acknowledgment: | ||
22 | # "This product includes software developed by the OpenSSL Project | ||
23 | # for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | # | ||
25 | # 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | # endorse or promote products derived from this software without | ||
27 | # prior written permission. For written permission, please contact | ||
28 | # licensing@OpenSSL.org. | ||
29 | # | ||
30 | # 5. Products derived from this software may not be called "OpenSSL" | ||
31 | # nor may "OpenSSL" appear in their names without prior written | ||
32 | # permission of the OpenSSL Project. | ||
33 | # | ||
34 | # 6. Redistributions of any form whatsoever must retain the following | ||
35 | # acknowledgment: | ||
36 | # "This product includes software developed by the OpenSSL Project | ||
37 | # for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | # | ||
39 | # THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | # ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | # OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | # ==================================================================== | ||
52 | |||
53 | # Perl utility to run PKITS tests for RFC3280 compliance. | ||
54 | |||
55 | my $ossl_path; | ||
56 | |||
57 | if ( -f "../apps/openssl" ) { | ||
58 | $ossl_path = "../util/shlib_wrap.sh ../apps/openssl"; | ||
59 | } | ||
60 | elsif ( -f "..\\out32dll\\openssl.exe" ) { | ||
61 | $ossl_path = "..\\out32dll\\openssl.exe"; | ||
62 | } | ||
63 | elsif ( -f "..\\out32\\openssl.exe" ) { | ||
64 | $ossl_path = "..\\out32\\openssl.exe"; | ||
65 | } | ||
66 | else { | ||
67 | die "Can't find OpenSSL executable"; | ||
68 | } | ||
69 | |||
70 | my $pkitsdir = "pkits/smime"; | ||
71 | my $pkitsta = "pkits/certs/TrustAnchorRootCertificate.crt"; | ||
72 | |||
73 | die "Can't find PKITS test data" if !-d $pkitsdir; | ||
74 | |||
75 | my $nist1 = "2.16.840.1.101.3.2.1.48.1"; | ||
76 | my $nist2 = "2.16.840.1.101.3.2.1.48.2"; | ||
77 | my $nist3 = "2.16.840.1.101.3.2.1.48.3"; | ||
78 | my $nist4 = "2.16.840.1.101.3.2.1.48.4"; | ||
79 | my $nist5 = "2.16.840.1.101.3.2.1.48.5"; | ||
80 | my $nist6 = "2.16.840.1.101.3.2.1.48.6"; | ||
81 | |||
82 | my $apolicy = "X509v3 Any Policy"; | ||
83 | |||
84 | # This table contains the chapter headings of the accompanying PKITS | ||
85 | # document. They provide useful informational output and their names | ||
86 | # can be converted into the filename to test. | ||
87 | |||
88 | my @testlists = ( | ||
89 | [ "4.1", "Signature Verification" ], | ||
90 | [ "4.1.1", "Valid Signatures Test1", 0 ], | ||
91 | [ "4.1.2", "Invalid CA Signature Test2", 7 ], | ||
92 | [ "4.1.3", "Invalid EE Signature Test3", 7 ], | ||
93 | [ "4.1.4", "Valid DSA Signatures Test4", 0 ], | ||
94 | [ "4.1.5", "Valid DSA Parameter Inheritance Test5", 0 ], | ||
95 | [ "4.1.6", "Invalid DSA Signature Test6", 7 ], | ||
96 | [ "4.2", "Validity Periods" ], | ||
97 | [ "4.2.1", "Invalid CA notBefore Date Test1", 9 ], | ||
98 | [ "4.2.2", "Invalid EE notBefore Date Test2", 9 ], | ||
99 | [ "4.2.3", "Valid pre2000 UTC notBefore Date Test3", 0 ], | ||
100 | [ "4.2.4", "Valid GeneralizedTime notBefore Date Test4", 0 ], | ||
101 | [ "4.2.5", "Invalid CA notAfter Date Test5", 10 ], | ||
102 | [ "4.2.6", "Invalid EE notAfter Date Test6", 10 ], | ||
103 | [ "4.2.7", "Invalid pre2000 UTC EE notAfter Date Test7", 10 ], | ||
104 | [ "4.2.8", "Valid GeneralizedTime notAfter Date Test8", 0 ], | ||
105 | [ "4.3", "Verifying Name Chaining" ], | ||
106 | [ "4.3.1", "Invalid Name Chaining EE Test1", 20 ], | ||
107 | [ "4.3.2", "Invalid Name Chaining Order Test2", 20 ], | ||
108 | [ "4.3.3", "Valid Name Chaining Whitespace Test3", 0 ], | ||
109 | [ "4.3.4", "Valid Name Chaining Whitespace Test4", 0 ], | ||
110 | [ "4.3.5", "Valid Name Chaining Capitalization Test5", 0 ], | ||
111 | [ "4.3.6", "Valid Name Chaining UIDs Test6", 0 ], | ||
112 | [ "4.3.7", "Valid RFC3280 Mandatory Attribute Types Test7", 0 ], | ||
113 | [ "4.3.8", "Valid RFC3280 Optional Attribute Types Test8", 0 ], | ||
114 | [ "4.3.9", "Valid UTF8String Encoded Names Test9", 0 ], | ||
115 | [ "4.3.10", "Valid Rollover from PrintableString to UTF8String Test10", 0 ], | ||
116 | [ "4.3.11", "Valid UTF8String Case Insensitive Match Test11", 0 ], | ||
117 | [ "4.4", "Basic Certificate Revocation Tests" ], | ||
118 | [ "4.4.1", "Missing CRL Test1", 3 ], | ||
119 | [ "4.4.2", "Invalid Revoked CA Test2", 23 ], | ||
120 | [ "4.4.3", "Invalid Revoked EE Test3", 23 ], | ||
121 | [ "4.4.4", "Invalid Bad CRL Signature Test4", 8 ], | ||
122 | [ "4.4.5", "Invalid Bad CRL Issuer Name Test5", 3 ], | ||
123 | [ "4.4.6", "Invalid Wrong CRL Test6", 3 ], | ||
124 | [ "4.4.7", "Valid Two CRLs Test7", 0 ], | ||
125 | |||
126 | # The test document suggests these should return certificate revoked... | ||
127 | # Subsquent discussion has concluded they should not due to unhandle | ||
128 | # critical CRL extensions. | ||
129 | [ "4.4.8", "Invalid Unknown CRL Entry Extension Test8", 36 ], | ||
130 | [ "4.4.9", "Invalid Unknown CRL Extension Test9", 36 ], | ||
131 | |||
132 | [ "4.4.10", "Invalid Unknown CRL Extension Test10", 36 ], | ||
133 | [ "4.4.11", "Invalid Old CRL nextUpdate Test11", 12 ], | ||
134 | [ "4.4.12", "Invalid pre2000 CRL nextUpdate Test12", 12 ], | ||
135 | [ "4.4.13", "Valid GeneralizedTime CRL nextUpdate Test13", 0 ], | ||
136 | [ "4.4.14", "Valid Negative Serial Number Test14", 0 ], | ||
137 | [ "4.4.15", "Invalid Negative Serial Number Test15", 23 ], | ||
138 | [ "4.4.16", "Valid Long Serial Number Test16", 0 ], | ||
139 | [ "4.4.17", "Valid Long Serial Number Test17", 0 ], | ||
140 | [ "4.4.18", "Invalid Long Serial Number Test18", 23 ], | ||
141 | [ "4.4.19", "Valid Separate Certificate and CRL Keys Test19", 0 ], | ||
142 | [ "4.4.20", "Invalid Separate Certificate and CRL Keys Test20", 23 ], | ||
143 | |||
144 | # CRL path is revoked so get a CRL path validation error | ||
145 | [ "4.4.21", "Invalid Separate Certificate and CRL Keys Test21", 54 ], | ||
146 | [ "4.5", "Verifying Paths with Self-Issued Certificates" ], | ||
147 | [ "4.5.1", "Valid Basic Self-Issued Old With New Test1", 0 ], | ||
148 | [ "4.5.2", "Invalid Basic Self-Issued Old With New Test2", 23 ], | ||
149 | [ "4.5.3", "Valid Basic Self-Issued New With Old Test3", 0 ], | ||
150 | [ "4.5.4", "Valid Basic Self-Issued New With Old Test4", 0 ], | ||
151 | [ "4.5.5", "Invalid Basic Self-Issued New With Old Test5", 23 ], | ||
152 | [ "4.5.6", "Valid Basic Self-Issued CRL Signing Key Test6", 0 ], | ||
153 | [ "4.5.7", "Invalid Basic Self-Issued CRL Signing Key Test7", 23 ], | ||
154 | [ "4.5.8", "Invalid Basic Self-Issued CRL Signing Key Test8", 20 ], | ||
155 | [ "4.6", "Verifying Basic Constraints" ], | ||
156 | [ "4.6.1", "Invalid Missing basicConstraints Test1", 24 ], | ||
157 | [ "4.6.2", "Invalid cA False Test2", 24 ], | ||
158 | [ "4.6.3", "Invalid cA False Test3", 24 ], | ||
159 | [ "4.6.4", "Valid basicConstraints Not Critical Test4", 0 ], | ||
160 | [ "4.6.5", "Invalid pathLenConstraint Test5", 25 ], | ||
161 | [ "4.6.6", "Invalid pathLenConstraint Test6", 25 ], | ||
162 | [ "4.6.7", "Valid pathLenConstraint Test7", 0 ], | ||
163 | [ "4.6.8", "Valid pathLenConstraint Test8", 0 ], | ||
164 | [ "4.6.9", "Invalid pathLenConstraint Test9", 25 ], | ||
165 | [ "4.6.10", "Invalid pathLenConstraint Test10", 25 ], | ||
166 | [ "4.6.11", "Invalid pathLenConstraint Test11", 25 ], | ||
167 | [ "4.6.12", "Invalid pathLenConstraint Test12", 25 ], | ||
168 | [ "4.6.13", "Valid pathLenConstraint Test13", 0 ], | ||
169 | [ "4.6.14", "Valid pathLenConstraint Test14", 0 ], | ||
170 | [ "4.6.15", "Valid Self-Issued pathLenConstraint Test15", 0 ], | ||
171 | [ "4.6.16", "Invalid Self-Issued pathLenConstraint Test16", 25 ], | ||
172 | [ "4.6.17", "Valid Self-Issued pathLenConstraint Test17", 0 ], | ||
173 | [ "4.7", "Key Usage" ], | ||
174 | [ "4.7.1", "Invalid keyUsage Critical keyCertSign False Test1", 20 ], | ||
175 | [ "4.7.2", "Invalid keyUsage Not Critical keyCertSign False Test2", 20 ], | ||
176 | [ "4.7.3", "Valid keyUsage Not Critical Test3", 0 ], | ||
177 | [ "4.7.4", "Invalid keyUsage Critical cRLSign False Test4", 35 ], | ||
178 | [ "4.7.5", "Invalid keyUsage Not Critical cRLSign False Test5", 35 ], | ||
179 | |||
180 | # Certificate policy tests need special handling. They can have several | ||
181 | # sub tests and we need to check the outputs are correct. | ||
182 | |||
183 | [ "4.8", "Certificate Policies" ], | ||
184 | [ | ||
185 | "4.8.1.1", | ||
186 | "All Certificates Same Policy Test1", | ||
187 | "-policy anyPolicy -explicit_policy", | ||
188 | "True", $nist1, $nist1, 0 | ||
189 | ], | ||
190 | [ | ||
191 | "4.8.1.2", | ||
192 | "All Certificates Same Policy Test1", | ||
193 | "-policy $nist1 -explicit_policy", | ||
194 | "True", $nist1, $nist1, 0 | ||
195 | ], | ||
196 | [ | ||
197 | "4.8.1.3", | ||
198 | "All Certificates Same Policy Test1", | ||
199 | "-policy $nist2 -explicit_policy", | ||
200 | "True", $nist1, "<empty>", 43 | ||
201 | ], | ||
202 | [ | ||
203 | "4.8.1.4", | ||
204 | "All Certificates Same Policy Test1", | ||
205 | "-policy $nist1 -policy $nist2 -explicit_policy", | ||
206 | "True", $nist1, $nist1, 0 | ||
207 | ], | ||
208 | [ | ||
209 | "4.8.2.1", | ||
210 | "All Certificates No Policies Test2", | ||
211 | "-policy anyPolicy", | ||
212 | "False", "<empty>", "<empty>", 0 | ||
213 | ], | ||
214 | [ | ||
215 | "4.8.2.2", | ||
216 | "All Certificates No Policies Test2", | ||
217 | "-policy anyPolicy -explicit_policy", | ||
218 | "True", "<empty>", "<empty>", 43 | ||
219 | ], | ||
220 | [ | ||
221 | "4.8.3.1", | ||
222 | "Different Policies Test3", | ||
223 | "-policy anyPolicy", | ||
224 | "False", "<empty>", "<empty>", 0 | ||
225 | ], | ||
226 | [ | ||
227 | "4.8.3.2", | ||
228 | "Different Policies Test3", | ||
229 | "-policy anyPolicy -explicit_policy", | ||
230 | "True", "<empty>", "<empty>", 43 | ||
231 | ], | ||
232 | [ | ||
233 | "4.8.3.3", | ||
234 | "Different Policies Test3", | ||
235 | "-policy $nist1 -policy $nist2 -explicit_policy", | ||
236 | "True", "<empty>", "<empty>", 43 | ||
237 | ], | ||
238 | |||
239 | [ | ||
240 | "4.8.4", | ||
241 | "Different Policies Test4", | ||
242 | "-policy anyPolicy", | ||
243 | "True", "<empty>", "<empty>", 43 | ||
244 | ], | ||
245 | [ | ||
246 | "4.8.5", | ||
247 | "Different Policies Test5", | ||
248 | "-policy anyPolicy", | ||
249 | "True", "<empty>", "<empty>", 43 | ||
250 | ], | ||
251 | [ | ||
252 | "4.8.6.1", | ||
253 | "Overlapping Policies Test6", | ||
254 | "-policy anyPolicy", | ||
255 | "True", $nist1, $nist1, 0 | ||
256 | ], | ||
257 | [ | ||
258 | "4.8.6.2", | ||
259 | "Overlapping Policies Test6", | ||
260 | "-policy $nist1", | ||
261 | "True", $nist1, $nist1, 0 | ||
262 | ], | ||
263 | [ | ||
264 | "4.8.6.3", | ||
265 | "Overlapping Policies Test6", | ||
266 | "-policy $nist2", | ||
267 | "True", $nist1, "<empty>", 43 | ||
268 | ], | ||
269 | [ | ||
270 | "4.8.7", | ||
271 | "Different Policies Test7", | ||
272 | "-policy anyPolicy", | ||
273 | "True", "<empty>", "<empty>", 43 | ||
274 | ], | ||
275 | [ | ||
276 | "4.8.8", | ||
277 | "Different Policies Test8", | ||
278 | "-policy anyPolicy", | ||
279 | "True", "<empty>", "<empty>", 43 | ||
280 | ], | ||
281 | [ | ||
282 | "4.8.9", | ||
283 | "Different Policies Test9", | ||
284 | "-policy anyPolicy", | ||
285 | "True", "<empty>", "<empty>", 43 | ||
286 | ], | ||
287 | [ | ||
288 | "4.8.10.1", | ||
289 | "All Certificates Same Policies Test10", | ||
290 | "-policy $nist1", | ||
291 | "True", "$nist1:$nist2", "$nist1", 0 | ||
292 | ], | ||
293 | [ | ||
294 | "4.8.10.2", | ||
295 | "All Certificates Same Policies Test10", | ||
296 | "-policy $nist2", | ||
297 | "True", "$nist1:$nist2", "$nist2", 0 | ||
298 | ], | ||
299 | [ | ||
300 | "4.8.10.3", | ||
301 | "All Certificates Same Policies Test10", | ||
302 | "-policy anyPolicy", | ||
303 | "True", "$nist1:$nist2", "$nist1:$nist2", 0 | ||
304 | ], | ||
305 | [ | ||
306 | "4.8.11.1", | ||
307 | "All Certificates AnyPolicy Test11", | ||
308 | "-policy anyPolicy", | ||
309 | "True", "$apolicy", "$apolicy", 0 | ||
310 | ], | ||
311 | [ | ||
312 | "4.8.11.2", | ||
313 | "All Certificates AnyPolicy Test11", | ||
314 | "-policy $nist1", | ||
315 | "True", "$apolicy", "$nist1", 0 | ||
316 | ], | ||
317 | [ | ||
318 | "4.8.12", | ||
319 | "Different Policies Test12", | ||
320 | "-policy anyPolicy", | ||
321 | "True", "<empty>", "<empty>", 43 | ||
322 | ], | ||
323 | [ | ||
324 | "4.8.13.1", | ||
325 | "All Certificates Same Policies Test13", | ||
326 | "-policy $nist1", | ||
327 | "True", "$nist1:$nist2:$nist3", "$nist1", 0 | ||
328 | ], | ||
329 | [ | ||
330 | "4.8.13.2", | ||
331 | "All Certificates Same Policies Test13", | ||
332 | "-policy $nist2", | ||
333 | "True", "$nist1:$nist2:$nist3", "$nist2", 0 | ||
334 | ], | ||
335 | [ | ||
336 | "4.8.13.3", | ||
337 | "All Certificates Same Policies Test13", | ||
338 | "-policy $nist3", | ||
339 | "True", "$nist1:$nist2:$nist3", "$nist3", 0 | ||
340 | ], | ||
341 | [ | ||
342 | "4.8.14.1", "AnyPolicy Test14", | ||
343 | "-policy $nist1", "True", | ||
344 | "$nist1", "$nist1", | ||
345 | 0 | ||
346 | ], | ||
347 | [ | ||
348 | "4.8.14.2", "AnyPolicy Test14", | ||
349 | "-policy $nist2", "True", | ||
350 | "$nist1", "<empty>", | ||
351 | 43 | ||
352 | ], | ||
353 | [ | ||
354 | "4.8.15", | ||
355 | "User Notice Qualifier Test15", | ||
356 | "-policy anyPolicy", | ||
357 | "False", "$nist1", "$nist1", 0 | ||
358 | ], | ||
359 | [ | ||
360 | "4.8.16", | ||
361 | "User Notice Qualifier Test16", | ||
362 | "-policy anyPolicy", | ||
363 | "False", "$nist1", "$nist1", 0 | ||
364 | ], | ||
365 | [ | ||
366 | "4.8.17", | ||
367 | "User Notice Qualifier Test17", | ||
368 | "-policy anyPolicy", | ||
369 | "False", "$nist1", "$nist1", 0 | ||
370 | ], | ||
371 | [ | ||
372 | "4.8.18.1", | ||
373 | "User Notice Qualifier Test18", | ||
374 | "-policy $nist1", | ||
375 | "True", "$nist1:$nist2", "$nist1", 0 | ||
376 | ], | ||
377 | [ | ||
378 | "4.8.18.2", | ||
379 | "User Notice Qualifier Test18", | ||
380 | "-policy $nist2", | ||
381 | "True", "$nist1:$nist2", "$nist2", 0 | ||
382 | ], | ||
383 | [ | ||
384 | "4.8.19", | ||
385 | "User Notice Qualifier Test19", | ||
386 | "-policy anyPolicy", | ||
387 | "False", "$nist1", "$nist1", 0 | ||
388 | ], | ||
389 | [ | ||
390 | "4.8.20", | ||
391 | "CPS Pointer Qualifier Test20", | ||
392 | "-policy anyPolicy -explicit_policy", | ||
393 | "True", "$nist1", "$nist1", 0 | ||
394 | ], | ||
395 | [ "4.9", "Require Explicit Policy" ], | ||
396 | [ | ||
397 | "4.9.1", | ||
398 | "Valid RequireExplicitPolicy Test1", | ||
399 | "-policy anyPolicy", | ||
400 | "False", "<empty>", "<empty>", 0 | ||
401 | ], | ||
402 | [ | ||
403 | "4.9.2", | ||
404 | "Valid RequireExplicitPolicy Test2", | ||
405 | "-policy anyPolicy", | ||
406 | "False", "<empty>", "<empty>", 0 | ||
407 | ], | ||
408 | [ | ||
409 | "4.9.3", | ||
410 | "Invalid RequireExplicitPolicy Test3", | ||
411 | "-policy anyPolicy", | ||
412 | "True", "<empty>", "<empty>", 43 | ||
413 | ], | ||
414 | [ | ||
415 | "4.9.4", | ||
416 | "Valid RequireExplicitPolicy Test4", | ||
417 | "-policy anyPolicy", | ||
418 | "True", "$nist1", "$nist1", 0 | ||
419 | ], | ||
420 | [ | ||
421 | "4.9.5", | ||
422 | "Invalid RequireExplicitPolicy Test5", | ||
423 | "-policy anyPolicy", | ||
424 | "True", "<empty>", "<empty>", 43 | ||
425 | ], | ||
426 | [ | ||
427 | "4.9.6", | ||
428 | "Valid Self-Issued requireExplicitPolicy Test6", | ||
429 | "-policy anyPolicy", | ||
430 | "False", "<empty>", "<empty>", 0 | ||
431 | ], | ||
432 | [ | ||
433 | "4.9.7", | ||
434 | "Invalid Self-Issued requireExplicitPolicy Test7", | ||
435 | "-policy anyPolicy", | ||
436 | "True", "<empty>", "<empty>", 43 | ||
437 | ], | ||
438 | [ | ||
439 | "4.9.8", | ||
440 | "Invalid Self-Issued requireExplicitPolicy Test8", | ||
441 | "-policy anyPolicy", | ||
442 | "True", "<empty>", "<empty>", 43 | ||
443 | ], | ||
444 | [ "4.10", "Policy Mappings" ], | ||
445 | [ | ||
446 | "4.10.1.1", | ||
447 | "Valid Policy Mapping Test1", | ||
448 | "-policy $nist1", | ||
449 | "True", "$nist1", "$nist1", 0 | ||
450 | ], | ||
451 | [ | ||
452 | "4.10.1.2", | ||
453 | "Valid Policy Mapping Test1", | ||
454 | "-policy $nist2", | ||
455 | "True", "$nist1", "<empty>", 43 | ||
456 | ], | ||
457 | [ | ||
458 | "4.10.1.3", | ||
459 | "Valid Policy Mapping Test1", | ||
460 | "-policy anyPolicy -inhibit_map", | ||
461 | "True", "<empty>", "<empty>", 43 | ||
462 | ], | ||
463 | [ | ||
464 | "4.10.2.1", | ||
465 | "Invalid Policy Mapping Test2", | ||
466 | "-policy anyPolicy", | ||
467 | "True", "<empty>", "<empty>", 43 | ||
468 | ], | ||
469 | [ | ||
470 | "4.10.2.2", | ||
471 | "Invalid Policy Mapping Test2", | ||
472 | "-policy anyPolicy -inhibit_map", | ||
473 | "True", "<empty>", "<empty>", 43 | ||
474 | ], | ||
475 | [ | ||
476 | "4.10.3.1", | ||
477 | "Valid Policy Mapping Test3", | ||
478 | "-policy $nist1", | ||
479 | "True", "$nist2", "<empty>", 43 | ||
480 | ], | ||
481 | [ | ||
482 | "4.10.3.2", | ||
483 | "Valid Policy Mapping Test3", | ||
484 | "-policy $nist2", | ||
485 | "True", "$nist2", "$nist2", 0 | ||
486 | ], | ||
487 | [ | ||
488 | "4.10.4", | ||
489 | "Invalid Policy Mapping Test4", | ||
490 | "-policy anyPolicy", | ||
491 | "True", "<empty>", "<empty>", 43 | ||
492 | ], | ||
493 | [ | ||
494 | "4.10.5.1", | ||
495 | "Valid Policy Mapping Test5", | ||
496 | "-policy $nist1", | ||
497 | "True", "$nist1", "$nist1", 0 | ||
498 | ], | ||
499 | [ | ||
500 | "4.10.5.2", | ||
501 | "Valid Policy Mapping Test5", | ||
502 | "-policy $nist6", | ||
503 | "True", "$nist1", "<empty>", 43 | ||
504 | ], | ||
505 | [ | ||
506 | "4.10.6.1", | ||
507 | "Valid Policy Mapping Test6", | ||
508 | "-policy $nist1", | ||
509 | "True", "$nist1", "$nist1", 0 | ||
510 | ], | ||
511 | [ | ||
512 | "4.10.6.2", | ||
513 | "Valid Policy Mapping Test6", | ||
514 | "-policy $nist6", | ||
515 | "True", "$nist1", "<empty>", 43 | ||
516 | ], | ||
517 | [ "4.10.7", "Invalid Mapping From anyPolicy Test7", 42 ], | ||
518 | [ "4.10.8", "Invalid Mapping To anyPolicy Test8", 42 ], | ||
519 | [ | ||
520 | "4.10.9", | ||
521 | "Valid Policy Mapping Test9", | ||
522 | "-policy anyPolicy", | ||
523 | "True", "$nist1", "$nist1", 0 | ||
524 | ], | ||
525 | [ | ||
526 | "4.10.10", | ||
527 | "Invalid Policy Mapping Test10", | ||
528 | "-policy anyPolicy", | ||
529 | "True", "<empty>", "<empty>", 43 | ||
530 | ], | ||
531 | [ | ||
532 | "4.10.11", | ||
533 | "Valid Policy Mapping Test11", | ||
534 | "-policy anyPolicy", | ||
535 | "True", "$nist1", "$nist1", 0 | ||
536 | ], | ||
537 | |||
538 | # TODO: check notice display | ||
539 | [ | ||
540 | "4.10.12.1", | ||
541 | "Valid Policy Mapping Test12", | ||
542 | "-policy $nist1", | ||
543 | "True", "$nist1:$nist2", "$nist1", 0 | ||
544 | ], | ||
545 | |||
546 | # TODO: check notice display | ||
547 | [ | ||
548 | "4.10.12.2", | ||
549 | "Valid Policy Mapping Test12", | ||
550 | "-policy $nist2", | ||
551 | "True", "$nist1:$nist2", "$nist2", 0 | ||
552 | ], | ||
553 | [ | ||
554 | "4.10.13", | ||
555 | "Valid Policy Mapping Test13", | ||
556 | "-policy anyPolicy", | ||
557 | "True", "$nist1", "$nist1", 0 | ||
558 | ], | ||
559 | |||
560 | # TODO: check notice display | ||
561 | [ | ||
562 | "4.10.14", | ||
563 | "Valid Policy Mapping Test14", | ||
564 | "-policy anyPolicy", | ||
565 | "True", "$nist1", "$nist1", 0 | ||
566 | ], | ||
567 | [ "4.11", "Inhibit Policy Mapping" ], | ||
568 | [ | ||
569 | "4.11.1", | ||
570 | "Invalid inhibitPolicyMapping Test1", | ||
571 | "-policy anyPolicy", | ||
572 | "True", "<empty>", "<empty>", 43 | ||
573 | ], | ||
574 | [ | ||
575 | "4.11.2", | ||
576 | "Valid inhibitPolicyMapping Test2", | ||
577 | "-policy anyPolicy", | ||
578 | "True", "$nist1", "$nist1", 0 | ||
579 | ], | ||
580 | [ | ||
581 | "4.11.3", | ||
582 | "Invalid inhibitPolicyMapping Test3", | ||
583 | "-policy anyPolicy", | ||
584 | "True", "<empty>", "<empty>", 43 | ||
585 | ], | ||
586 | [ | ||
587 | "4.11.4", | ||
588 | "Valid inhibitPolicyMapping Test4", | ||
589 | "-policy anyPolicy", | ||
590 | "True", "$nist2", "$nist2", 0 | ||
591 | ], | ||
592 | [ | ||
593 | "4.11.5", | ||
594 | "Invalid inhibitPolicyMapping Test5", | ||
595 | "-policy anyPolicy", | ||
596 | "True", "<empty>", "<empty>", 43 | ||
597 | ], | ||
598 | [ | ||
599 | "4.11.6", | ||
600 | "Invalid inhibitPolicyMapping Test6", | ||
601 | "-policy anyPolicy", | ||
602 | "True", "<empty>", "<empty>", 43 | ||
603 | ], | ||
604 | [ | ||
605 | "4.11.7", | ||
606 | "Valid Self-Issued inhibitPolicyMapping Test7", | ||
607 | "-policy anyPolicy", | ||
608 | "True", "$nist1", "$nist1", 0 | ||
609 | ], | ||
610 | [ | ||
611 | "4.11.8", | ||
612 | "Invalid Self-Issued inhibitPolicyMapping Test8", | ||
613 | "-policy anyPolicy", | ||
614 | "True", "<empty>", "<empty>", 43 | ||
615 | ], | ||
616 | [ | ||
617 | "4.11.9", | ||
618 | "Invalid Self-Issued inhibitPolicyMapping Test9", | ||
619 | "-policy anyPolicy", | ||
620 | "True", "<empty>", "<empty>", 43 | ||
621 | ], | ||
622 | [ | ||
623 | "4.11.10", | ||
624 | "Invalid Self-Issued inhibitPolicyMapping Test10", | ||
625 | "-policy anyPolicy", | ||
626 | "True", "<empty>", "<empty>", 43 | ||
627 | ], | ||
628 | [ | ||
629 | "4.11.11", | ||
630 | "Invalid Self-Issued inhibitPolicyMapping Test11", | ||
631 | "-policy anyPolicy", | ||
632 | "True", "<empty>", "<empty>", 43 | ||
633 | ], | ||
634 | [ "4.12", "Inhibit Any Policy" ], | ||
635 | [ | ||
636 | "4.12.1", | ||
637 | "Invalid inhibitAnyPolicy Test1", | ||
638 | "-policy anyPolicy", | ||
639 | "True", "<empty>", "<empty>", 43 | ||
640 | ], | ||
641 | [ | ||
642 | "4.12.2", | ||
643 | "Valid inhibitAnyPolicy Test2", | ||
644 | "-policy anyPolicy", | ||
645 | "True", "$nist1", "$nist1", 0 | ||
646 | ], | ||
647 | [ | ||
648 | "4.12.3.1", | ||
649 | "inhibitAnyPolicy Test3", | ||
650 | "-policy anyPolicy", | ||
651 | "True", "$nist1", "$nist1", 0 | ||
652 | ], | ||
653 | [ | ||
654 | "4.12.3.2", | ||
655 | "inhibitAnyPolicy Test3", | ||
656 | "-policy anyPolicy -inhibit_any", | ||
657 | "True", "<empty>", "<empty>", 43 | ||
658 | ], | ||
659 | [ | ||
660 | "4.12.4", | ||
661 | "Invalid inhibitAnyPolicy Test4", | ||
662 | "-policy anyPolicy", | ||
663 | "True", "<empty>", "<empty>", 43 | ||
664 | ], | ||
665 | [ | ||
666 | "4.12.5", | ||
667 | "Invalid inhibitAnyPolicy Test5", | ||
668 | "-policy anyPolicy", | ||
669 | "True", "<empty>", "<empty>", 43 | ||
670 | ], | ||
671 | [ | ||
672 | "4.12.6", | ||
673 | "Invalid inhibitAnyPolicy Test6", | ||
674 | "-policy anyPolicy", | ||
675 | "True", "<empty>", "<empty>", 43 | ||
676 | ], | ||
677 | [ "4.12.7", "Valid Self-Issued inhibitAnyPolicy Test7", 0 ], | ||
678 | [ "4.12.8", "Invalid Self-Issued inhibitAnyPolicy Test8", 43 ], | ||
679 | [ "4.12.9", "Valid Self-Issued inhibitAnyPolicy Test9", 0 ], | ||
680 | [ "4.12.10", "Invalid Self-Issued inhibitAnyPolicy Test10", 43 ], | ||
681 | [ "4.13", "Name Constraints" ], | ||
682 | [ "4.13.1", "Valid DN nameConstraints Test1", 0 ], | ||
683 | [ "4.13.2", "Invalid DN nameConstraints Test2", 47 ], | ||
684 | [ "4.13.3", "Invalid DN nameConstraints Test3", 47 ], | ||
685 | [ "4.13.4", "Valid DN nameConstraints Test4", 0 ], | ||
686 | [ "4.13.5", "Valid DN nameConstraints Test5", 0 ], | ||
687 | [ "4.13.6", "Valid DN nameConstraints Test6", 0 ], | ||
688 | [ "4.13.7", "Invalid DN nameConstraints Test7", 48 ], | ||
689 | [ "4.13.8", "Invalid DN nameConstraints Test8", 48 ], | ||
690 | [ "4.13.9", "Invalid DN nameConstraints Test9", 48 ], | ||
691 | [ "4.13.10", "Invalid DN nameConstraints Test10", 48 ], | ||
692 | [ "4.13.11", "Valid DN nameConstraints Test11", 0 ], | ||
693 | [ "4.13.12", "Invalid DN nameConstraints Test12", 47 ], | ||
694 | [ "4.13.13", "Invalid DN nameConstraints Test13", 47 ], | ||
695 | [ "4.13.14", "Valid DN nameConstraints Test14", 0 ], | ||
696 | [ "4.13.15", "Invalid DN nameConstraints Test15", 48 ], | ||
697 | [ "4.13.16", "Invalid DN nameConstraints Test16", 48 ], | ||
698 | [ "4.13.17", "Invalid DN nameConstraints Test17", 48 ], | ||
699 | [ "4.13.18", "Valid DN nameConstraints Test18", 0 ], | ||
700 | [ "4.13.19", "Valid Self-Issued DN nameConstraints Test19", 0 ], | ||
701 | [ "4.13.20", "Invalid Self-Issued DN nameConstraints Test20", 47 ], | ||
702 | [ "4.13.21", "Valid RFC822 nameConstraints Test21", 0 ], | ||
703 | [ "4.13.22", "Invalid RFC822 nameConstraints Test22", 47 ], | ||
704 | [ "4.13.23", "Valid RFC822 nameConstraints Test23", 0 ], | ||
705 | [ "4.13.24", "Invalid RFC822 nameConstraints Test24", 47 ], | ||
706 | [ "4.13.25", "Valid RFC822 nameConstraints Test25", 0 ], | ||
707 | [ "4.13.26", "Invalid RFC822 nameConstraints Test26", 48 ], | ||
708 | [ "4.13.27", "Valid DN and RFC822 nameConstraints Test27", 0 ], | ||
709 | [ "4.13.28", "Invalid DN and RFC822 nameConstraints Test28", 47 ], | ||
710 | [ "4.13.29", "Invalid DN and RFC822 nameConstraints Test29", 47 ], | ||
711 | [ "4.13.30", "Valid DNS nameConstraints Test30", 0 ], | ||
712 | [ "4.13.31", "Invalid DNS nameConstraints Test31", 47 ], | ||
713 | [ "4.13.32", "Valid DNS nameConstraints Test32", 0 ], | ||
714 | [ "4.13.33", "Invalid DNS nameConstraints Test33", 48 ], | ||
715 | [ "4.13.34", "Valid URI nameConstraints Test34", 0 ], | ||
716 | [ "4.13.35", "Invalid URI nameConstraints Test35", 47 ], | ||
717 | [ "4.13.36", "Valid URI nameConstraints Test36", 0 ], | ||
718 | [ "4.13.37", "Invalid URI nameConstraints Test37", 48 ], | ||
719 | [ "4.13.38", "Invalid DNS nameConstraints Test38", 47 ], | ||
720 | [ "4.14", "Distribution Points" ], | ||
721 | [ "4.14.1", "Valid distributionPoint Test1", 0 ], | ||
722 | [ "4.14.2", "Invalid distributionPoint Test2", 23 ], | ||
723 | [ "4.14.3", "Invalid distributionPoint Test3", 44 ], | ||
724 | [ "4.14.4", "Valid distributionPoint Test4", 0 ], | ||
725 | [ "4.14.5", "Valid distributionPoint Test5", 0 ], | ||
726 | [ "4.14.6", "Invalid distributionPoint Test6", 23 ], | ||
727 | [ "4.14.7", "Valid distributionPoint Test7", 0 ], | ||
728 | [ "4.14.8", "Invalid distributionPoint Test8", 44 ], | ||
729 | [ "4.14.9", "Invalid distributionPoint Test9", 44 ], | ||
730 | [ "4.14.10", "Valid No issuingDistributionPoint Test10", 0 ], | ||
731 | [ "4.14.11", "Invalid onlyContainsUserCerts CRL Test11", 44 ], | ||
732 | [ "4.14.12", "Invalid onlyContainsCACerts CRL Test12", 44 ], | ||
733 | [ "4.14.13", "Valid onlyContainsCACerts CRL Test13", 0 ], | ||
734 | [ "4.14.14", "Invalid onlyContainsAttributeCerts Test14", 44 ], | ||
735 | [ "4.14.15", "Invalid onlySomeReasons Test15", 23 ], | ||
736 | [ "4.14.16", "Invalid onlySomeReasons Test16", 23 ], | ||
737 | [ "4.14.17", "Invalid onlySomeReasons Test17", 3 ], | ||
738 | [ "4.14.18", "Valid onlySomeReasons Test18", 0 ], | ||
739 | [ "4.14.19", "Valid onlySomeReasons Test19", 0 ], | ||
740 | [ "4.14.20", "Invalid onlySomeReasons Test20", 23 ], | ||
741 | [ "4.14.21", "Invalid onlySomeReasons Test21", 23 ], | ||
742 | [ "4.14.22", "Valid IDP with indirectCRL Test22", 0 ], | ||
743 | [ "4.14.23", "Invalid IDP with indirectCRL Test23", 23 ], | ||
744 | [ "4.14.24", "Valid IDP with indirectCRL Test24", 0 ], | ||
745 | [ "4.14.25", "Valid IDP with indirectCRL Test25", 0 ], | ||
746 | [ "4.14.26", "Invalid IDP with indirectCRL Test26", 44 ], | ||
747 | [ "4.14.27", "Invalid cRLIssuer Test27", 3 ], | ||
748 | [ "4.14.28", "Valid cRLIssuer Test28", 0 ], | ||
749 | [ "4.14.29", "Valid cRLIssuer Test29", 0 ], | ||
750 | |||
751 | # Although this test is valid it has a circular dependency. As a result | ||
752 | # an attempt is made to reursively checks a CRL path and rejected due to | ||
753 | # a CRL path validation error. PKITS notes suggest this test does not | ||
754 | # need to be run due to this issue. | ||
755 | [ "4.14.30", "Valid cRLIssuer Test30", 54 ], | ||
756 | [ "4.14.31", "Invalid cRLIssuer Test31", 23 ], | ||
757 | [ "4.14.32", "Invalid cRLIssuer Test32", 23 ], | ||
758 | [ "4.14.33", "Valid cRLIssuer Test33", 0 ], | ||
759 | [ "4.14.34", "Invalid cRLIssuer Test34", 23 ], | ||
760 | [ "4.14.35", "Invalid cRLIssuer Test35", 44 ], | ||
761 | [ "4.15", "Delta-CRLs" ], | ||
762 | [ "4.15.1", "Invalid deltaCRLIndicator No Base Test1", 3 ], | ||
763 | [ "4.15.2", "Valid delta-CRL Test2", 0 ], | ||
764 | [ "4.15.3", "Invalid delta-CRL Test3", 23 ], | ||
765 | [ "4.15.4", "Invalid delta-CRL Test4", 23 ], | ||
766 | [ "4.15.5", "Valid delta-CRL Test5", 0 ], | ||
767 | [ "4.15.6", "Invalid delta-CRL Test6", 23 ], | ||
768 | [ "4.15.7", "Valid delta-CRL Test7", 0 ], | ||
769 | [ "4.15.8", "Valid delta-CRL Test8", 0 ], | ||
770 | [ "4.15.9", "Invalid delta-CRL Test9", 23 ], | ||
771 | [ "4.15.10", "Invalid delta-CRL Test10", 12 ], | ||
772 | [ "4.16", "Private Certificate Extensions" ], | ||
773 | [ "4.16.1", "Valid Unknown Not Critical Certificate Extension Test1", 0 ], | ||
774 | [ "4.16.2", "Invalid Unknown Critical Certificate Extension Test2", 34 ], | ||
775 | ); | ||
776 | |||
777 | |||
778 | my $verbose = 1; | ||
779 | |||
780 | my $numtest = 0; | ||
781 | my $numfail = 0; | ||
782 | |||
783 | my $ossl = "ossl/apps/openssl"; | ||
784 | |||
785 | my $ossl_cmd = "$ossl_path cms -verify -verify_retcode "; | ||
786 | $ossl_cmd .= "-CAfile pkitsta.pem -crl_check_all -x509_strict "; | ||
787 | $ossl_cmd .= "-policy_check -extended_crl -use_deltas -out /dev/null 2>&1 "; | ||
788 | |||
789 | system "$ossl_path x509 -inform DER -in $pkitsta -out pkitsta.pem"; | ||
790 | |||
791 | die "Can't create trust anchor file" if $?; | ||
792 | |||
793 | print "Running PKITS tests:\n" if $verbose; | ||
794 | |||
795 | foreach (@testlists) { | ||
796 | my $argnum = @$_; | ||
797 | if ( $argnum == 2 ) { | ||
798 | my ( $tnum, $title ) = @$_; | ||
799 | print "$tnum $title\n" if $verbose; | ||
800 | } | ||
801 | elsif ( $argnum == 3 ) { | ||
802 | my ( $tnum, $title, $exp_ret ) = @$_; | ||
803 | my $filename = $title; | ||
804 | $exp_ret += 32 if $exp_ret; | ||
805 | $filename =~ tr/ -//d; | ||
806 | $filename = "Signed${filename}.eml"; | ||
807 | if ( !-f "$pkitsdir/$filename" ) { | ||
808 | print "\"$filename\" not found\n"; | ||
809 | } | ||
810 | else { | ||
811 | my $ret; | ||
812 | my $test_fail = 0; | ||
813 | my $errmsg = ""; | ||
814 | my $cmd = $ossl_cmd; | ||
815 | $cmd .= "-in $pkitsdir/$filename -policy anyPolicy"; | ||
816 | my $cmdout = `$cmd`; | ||
817 | $ret = $? >> 8; | ||
818 | if ( $? & 0xff ) { | ||
819 | $errmsg .= "Abnormal OpenSSL termination\n"; | ||
820 | $test_fail = 1; | ||
821 | } | ||
822 | if ( $exp_ret != $ret ) { | ||
823 | $errmsg .= "Return code:$ret, "; | ||
824 | $errmsg .= "expected $exp_ret\n"; | ||
825 | $test_fail = 1; | ||
826 | } | ||
827 | if ($test_fail) { | ||
828 | print "$tnum $title : Failed!\n"; | ||
829 | print "Filename: $pkitsdir/$filename\n"; | ||
830 | print $errmsg; | ||
831 | print "Command output:\n$cmdout\n"; | ||
832 | $numfail++; | ||
833 | } | ||
834 | $numtest++; | ||
835 | } | ||
836 | } | ||
837 | elsif ( $argnum == 7 ) { | ||
838 | my ( $tnum, $title, $exargs, $exp_epol, $exp_aset, $exp_uset, $exp_ret ) | ||
839 | = @$_; | ||
840 | my $filename = $title; | ||
841 | $exp_ret += 32 if $exp_ret; | ||
842 | $filename =~ tr/ -//d; | ||
843 | $filename = "Signed${filename}.eml"; | ||
844 | if ( !-f "$pkitsdir/$filename" ) { | ||
845 | print "\"$filename\" not found\n"; | ||
846 | } | ||
847 | else { | ||
848 | my $ret; | ||
849 | my $cmdout = ""; | ||
850 | my $errmsg = ""; | ||
851 | my $epol = ""; | ||
852 | my $aset = ""; | ||
853 | my $uset = ""; | ||
854 | my $pol = -1; | ||
855 | my $test_fail = 0; | ||
856 | my $cmd = $ossl_cmd; | ||
857 | $cmd .= "-in $pkitsdir/$filename $exargs -policy_print"; | ||
858 | @oparr = `$cmd`; | ||
859 | $ret = $? >> 8; | ||
860 | |||
861 | if ( $? & 0xff ) { | ||
862 | $errmsg .= "Abnormal OpenSSL termination\n"; | ||
863 | $test_fail = 1; | ||
864 | } | ||
865 | foreach (@oparr) { | ||
866 | my $test_failed = 0; | ||
867 | $cmdout .= $_; | ||
868 | if (/^Require explicit Policy: (.*)$/) { | ||
869 | $epol = $1; | ||
870 | } | ||
871 | if (/^Authority Policies/) { | ||
872 | if (/empty/) { | ||
873 | $aset = "<empty>"; | ||
874 | } | ||
875 | else { | ||
876 | $pol = 1; | ||
877 | } | ||
878 | } | ||
879 | $test_fail = 1 if (/leak/i); | ||
880 | if (/^User Policies/) { | ||
881 | if (/empty/) { | ||
882 | $uset = "<empty>"; | ||
883 | } | ||
884 | else { | ||
885 | $pol = 2; | ||
886 | } | ||
887 | } | ||
888 | if (/\s+Policy: (.*)$/) { | ||
889 | if ( $pol == 1 ) { | ||
890 | $aset .= ":" if $aset ne ""; | ||
891 | $aset .= $1; | ||
892 | } | ||
893 | elsif ( $pol == 2 ) { | ||
894 | $uset .= ":" if $uset ne ""; | ||
895 | $uset .= $1; | ||
896 | } | ||
897 | } | ||
898 | } | ||
899 | |||
900 | if ( $epol ne $exp_epol ) { | ||
901 | $errmsg .= "Explicit policy:$epol, "; | ||
902 | $errmsg .= "expected $exp_epol\n"; | ||
903 | $test_fail = 1; | ||
904 | } | ||
905 | if ( $aset ne $exp_aset ) { | ||
906 | $errmsg .= "Authority policy set :$aset, "; | ||
907 | $errmsg .= "expected $exp_aset\n"; | ||
908 | $test_fail = 1; | ||
909 | } | ||
910 | if ( $uset ne $exp_uset ) { | ||
911 | $errmsg .= "User policy set :$uset, "; | ||
912 | $errmsg .= "expected $exp_uset\n"; | ||
913 | $test_fail = 1; | ||
914 | } | ||
915 | |||
916 | if ( $exp_ret != $ret ) { | ||
917 | print "Return code:$ret, expected $exp_ret\n"; | ||
918 | $test_fail = 1; | ||
919 | } | ||
920 | |||
921 | if ($test_fail) { | ||
922 | print "$tnum $title : Failed!\n"; | ||
923 | print "Filename: $pkitsdir/$filename\n"; | ||
924 | print "Command output:\n$cmdout\n"; | ||
925 | $numfail++; | ||
926 | } | ||
927 | $numtest++; | ||
928 | } | ||
929 | } | ||
930 | } | ||
931 | |||
932 | if ($numfail) { | ||
933 | print "$numfail tests failed out of $numtest\n"; | ||
934 | } | ||
935 | else { | ||
936 | print "All Tests Successful.\n"; | ||
937 | } | ||
938 | |||
939 | unlink "pkitsta.pem"; | ||
940 | |||
diff --git a/src/lib/libssl/test/test_padlock b/src/lib/libssl/test/test_padlock new file mode 100755 index 0000000000..5c0f21043c --- /dev/null +++ b/src/lib/libssl/test/test_padlock | |||
@@ -0,0 +1,64 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | PROG=$1 | ||
4 | |||
5 | if [ -x $PROG ]; then | ||
6 | if expr "x`$PROG version`" : "xOpenSSL" > /dev/null; then | ||
7 | : | ||
8 | else | ||
9 | echo "$PROG is not OpenSSL executable" | ||
10 | exit 1 | ||
11 | fi | ||
12 | else | ||
13 | echo "$PROG is not executable" | ||
14 | exit 1; | ||
15 | fi | ||
16 | |||
17 | if $PROG engine padlock | grep -v no-ACE; then | ||
18 | |||
19 | HASH=`cat $PROG | $PROG dgst -hex` | ||
20 | |||
21 | ACE_ALGS=" aes-128-ecb aes-192-ecb aes-256-ecb \ | ||
22 | aes-128-cbc aes-192-cbc aes-256-cbc \ | ||
23 | aes-128-cfb aes-192-cfb aes-256-cfb \ | ||
24 | aes-128-ofb aes-192-ofb aes-256-ofb" | ||
25 | |||
26 | nerr=0 | ||
27 | |||
28 | for alg in $ACE_ALGS; do | ||
29 | echo $alg | ||
30 | TEST=`( cat $PROG | \ | ||
31 | $PROG enc -e -k "$HASH" -$alg -bufsize 999 -engine padlock | \ | ||
32 | $PROG enc -d -k "$HASH" -$alg | \ | ||
33 | $PROG dgst -hex ) 2>/dev/null` | ||
34 | if [ "$TEST" != "$HASH" ]; then | ||
35 | echo "-$alg encrypt test failed" | ||
36 | nerr=`expr $nerr + 1` | ||
37 | fi | ||
38 | TEST=`( cat $PROG | \ | ||
39 | $PROG enc -e -k "$HASH" -$alg | \ | ||
40 | $PROG enc -d -k "$HASH" -$alg -bufsize 999 -engine padlock | \ | ||
41 | $PROG dgst -hex ) 2>/dev/null` | ||
42 | if [ "$TEST" != "$HASH" ]; then | ||
43 | echo "-$alg decrypt test failed" | ||
44 | nerr=`expr $nerr + 1` | ||
45 | fi | ||
46 | TEST=`( cat $PROG | \ | ||
47 | $PROG enc -e -k "$HASH" -$alg -engine padlock | \ | ||
48 | $PROG enc -d -k "$HASH" -$alg -engine padlock | \ | ||
49 | $PROG dgst -hex ) 2>/dev/null` | ||
50 | if [ "$TEST" != "$HASH" ]; then | ||
51 | echo "-$alg en/decrypt test failed" | ||
52 | nerr=`expr $nerr + 1` | ||
53 | fi | ||
54 | done | ||
55 | |||
56 | if [ $nerr -gt 0 ]; then | ||
57 | echo "PadLock ACE test failed." | ||
58 | exit 1; | ||
59 | fi | ||
60 | else | ||
61 | echo "PadLock ACE is not available" | ||
62 | fi | ||
63 | |||
64 | exit 0 | ||
diff --git a/src/lib/libssl/test/testtsa b/src/lib/libssl/test/testtsa new file mode 100644 index 0000000000..bb653b5f73 --- /dev/null +++ b/src/lib/libssl/test/testtsa | |||
@@ -0,0 +1,238 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # | ||
4 | # A few very basic tests for the 'ts' time stamping authority command. | ||
5 | # | ||
6 | |||
7 | SH="/bin/sh" | ||
8 | if test "$OSTYPE" = msdosdjgpp; then | ||
9 | PATH="../apps\;$PATH" | ||
10 | else | ||
11 | PATH="../apps:$PATH" | ||
12 | fi | ||
13 | export SH PATH | ||
14 | |||
15 | OPENSSL_CONF="../CAtsa.cnf" | ||
16 | export OPENSSL_CONF | ||
17 | # Because that's what ../apps/CA.sh really looks at | ||
18 | SSLEAY_CONFIG="-config $OPENSSL_CONF" | ||
19 | export SSLEAY_CONFIG | ||
20 | |||
21 | OPENSSL="`pwd`/../util/opensslwrap.sh" | ||
22 | export OPENSSL | ||
23 | |||
24 | error () { | ||
25 | |||
26 | echo "TSA test failed!" >&2 | ||
27 | exit 1 | ||
28 | } | ||
29 | |||
30 | setup_dir () { | ||
31 | |||
32 | rm -rf tsa 2>/dev/null | ||
33 | mkdir tsa | ||
34 | cd ./tsa | ||
35 | } | ||
36 | |||
37 | clean_up_dir () { | ||
38 | |||
39 | cd .. | ||
40 | rm -rf tsa | ||
41 | } | ||
42 | |||
43 | create_ca () { | ||
44 | |||
45 | echo "Creating a new CA for the TSA tests..." | ||
46 | TSDNSECT=ts_ca_dn | ||
47 | export TSDNSECT | ||
48 | ../../util/shlib_wrap.sh ../../apps/openssl req -new -x509 -nodes \ | ||
49 | -out tsaca.pem -keyout tsacakey.pem | ||
50 | test $? != 0 && error | ||
51 | } | ||
52 | |||
53 | create_tsa_cert () { | ||
54 | |||
55 | INDEX=$1 | ||
56 | export INDEX | ||
57 | EXT=$2 | ||
58 | TSDNSECT=ts_cert_dn | ||
59 | export TSDNSECT | ||
60 | |||
61 | ../../util/shlib_wrap.sh ../../apps/openssl req -new \ | ||
62 | -out tsa_req${INDEX}.pem -keyout tsa_key${INDEX}.pem | ||
63 | test $? != 0 && error | ||
64 | echo Using extension $EXT | ||
65 | ../../util/shlib_wrap.sh ../../apps/openssl x509 -req \ | ||
66 | -in tsa_req${INDEX}.pem -out tsa_cert${INDEX}.pem \ | ||
67 | -CA tsaca.pem -CAkey tsacakey.pem -CAcreateserial \ | ||
68 | -extfile $OPENSSL_CONF -extensions $EXT | ||
69 | test $? != 0 && error | ||
70 | } | ||
71 | |||
72 | print_request () { | ||
73 | |||
74 | ../../util/shlib_wrap.sh ../../apps/openssl ts -query -in $1 -text | ||
75 | } | ||
76 | |||
77 | create_time_stamp_request1 () { | ||
78 | |||
79 | ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy1 -cert -out req1.tsq | ||
80 | test $? != 0 && error | ||
81 | } | ||
82 | |||
83 | create_time_stamp_request2 () { | ||
84 | |||
85 | ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy2 -no_nonce \ | ||
86 | -out req2.tsq | ||
87 | test $? != 0 && error | ||
88 | } | ||
89 | |||
90 | create_time_stamp_request3 () { | ||
91 | |||
92 | ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../CAtsa.cnf -no_nonce -out req3.tsq | ||
93 | test $? != 0 && error | ||
94 | } | ||
95 | |||
96 | print_response () { | ||
97 | |||
98 | ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $1 -text | ||
99 | test $? != 0 && error | ||
100 | } | ||
101 | |||
102 | create_time_stamp_response () { | ||
103 | |||
104 | ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -section $3 -queryfile $1 -out $2 | ||
105 | test $? != 0 && error | ||
106 | } | ||
107 | |||
108 | time_stamp_response_token_test () { | ||
109 | |||
110 | RESPONSE2=$2.copy.tsr | ||
111 | TOKEN_DER=$2.token.der | ||
112 | ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $TOKEN_DER -token_out | ||
113 | test $? != 0 && error | ||
114 | ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -out $RESPONSE2 | ||
115 | test $? != 0 && error | ||
116 | cmp $RESPONSE2 $2 | ||
117 | test $? != 0 && error | ||
118 | ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -text -token_out | ||
119 | test $? != 0 && error | ||
120 | ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -text -token_out | ||
121 | test $? != 0 && error | ||
122 | ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -queryfile $1 -text -token_out | ||
123 | test $? != 0 && error | ||
124 | } | ||
125 | |||
126 | verify_time_stamp_response () { | ||
127 | |||
128 | ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \ | ||
129 | -untrusted tsa_cert1.pem | ||
130 | test $? != 0 && error | ||
131 | ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2 -CAfile tsaca.pem \ | ||
132 | -untrusted tsa_cert1.pem | ||
133 | test $? != 0 && error | ||
134 | } | ||
135 | |||
136 | verify_time_stamp_token () { | ||
137 | |||
138 | # create the token from the response first | ||
139 | ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $2.token -token_out | ||
140 | test $? != 0 && error | ||
141 | ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2.token -token_in \ | ||
142 | -CAfile tsaca.pem -untrusted tsa_cert1.pem | ||
143 | test $? != 0 && error | ||
144 | ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2.token -token_in \ | ||
145 | -CAfile tsaca.pem -untrusted tsa_cert1.pem | ||
146 | test $? != 0 && error | ||
147 | } | ||
148 | |||
149 | verify_time_stamp_response_fail () { | ||
150 | |||
151 | ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \ | ||
152 | -untrusted tsa_cert1.pem | ||
153 | # Checks if the verification failed, as it should have. | ||
154 | test $? = 0 && error | ||
155 | echo Ok | ||
156 | } | ||
157 | |||
158 | # main functions | ||
159 | |||
160 | echo "Setting up TSA test directory..." | ||
161 | setup_dir | ||
162 | |||
163 | echo "Creating CA for TSA tests..." | ||
164 | create_ca | ||
165 | |||
166 | echo "Creating tsa_cert1.pem TSA server cert..." | ||
167 | create_tsa_cert 1 tsa_cert | ||
168 | |||
169 | echo "Creating tsa_cert2.pem non-TSA server cert..." | ||
170 | create_tsa_cert 2 non_tsa_cert | ||
171 | |||
172 | echo "Creating req1.req time stamp request for file testtsa..." | ||
173 | create_time_stamp_request1 | ||
174 | |||
175 | echo "Printing req1.req..." | ||
176 | print_request req1.tsq | ||
177 | |||
178 | echo "Generating valid response for req1.req..." | ||
179 | create_time_stamp_response req1.tsq resp1.tsr tsa_config1 | ||
180 | |||
181 | echo "Printing response..." | ||
182 | print_response resp1.tsr | ||
183 | |||
184 | echo "Verifying valid response..." | ||
185 | verify_time_stamp_response req1.tsq resp1.tsr ../testtsa | ||
186 | |||
187 | echo "Verifying valid token..." | ||
188 | verify_time_stamp_token req1.tsq resp1.tsr ../testtsa | ||
189 | |||
190 | # The tests below are commented out, because invalid signer certificates | ||
191 | # can no longer be specified in the config file. | ||
192 | |||
193 | # echo "Generating _invalid_ response for req1.req..." | ||
194 | # create_time_stamp_response req1.tsq resp1_bad.tsr tsa_config2 | ||
195 | |||
196 | # echo "Printing response..." | ||
197 | # print_response resp1_bad.tsr | ||
198 | |||
199 | # echo "Verifying invalid response, it should fail..." | ||
200 | # verify_time_stamp_response_fail req1.tsq resp1_bad.tsr | ||
201 | |||
202 | echo "Creating req2.req time stamp request for file testtsa..." | ||
203 | create_time_stamp_request2 | ||
204 | |||
205 | echo "Printing req2.req..." | ||
206 | print_request req2.tsq | ||
207 | |||
208 | echo "Generating valid response for req2.req..." | ||
209 | create_time_stamp_response req2.tsq resp2.tsr tsa_config1 | ||
210 | |||
211 | echo "Checking '-token_in' and '-token_out' options with '-reply'..." | ||
212 | time_stamp_response_token_test req2.tsq resp2.tsr | ||
213 | |||
214 | echo "Printing response..." | ||
215 | print_response resp2.tsr | ||
216 | |||
217 | echo "Verifying valid response..." | ||
218 | verify_time_stamp_response req2.tsq resp2.tsr ../testtsa | ||
219 | |||
220 | echo "Verifying response against wrong request, it should fail..." | ||
221 | verify_time_stamp_response_fail req1.tsq resp2.tsr | ||
222 | |||
223 | echo "Verifying response against wrong request, it should fail..." | ||
224 | verify_time_stamp_response_fail req2.tsq resp1.tsr | ||
225 | |||
226 | echo "Creating req3.req time stamp request for file CAtsa.cnf..." | ||
227 | create_time_stamp_request3 | ||
228 | |||
229 | echo "Printing req3.req..." | ||
230 | print_request req3.tsq | ||
231 | |||
232 | echo "Verifying response against wrong request, it should fail..." | ||
233 | verify_time_stamp_response_fail req3.tsq resp1.tsr | ||
234 | |||
235 | echo "Cleaning up..." | ||
236 | clean_up_dir | ||
237 | |||
238 | exit 0 | ||