3 # ====================================================================
4 # Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
6 # This module may be used under the terms of either the GNU General
7 # Public License version 2 or later, the GNU Lesser General Public
8 # License version 2.1 or later, the Mozilla Public License version
9 # 1.1 or the BSD License. The exact terms of either license are
10 # distributed along with this module. For further details see
11 # http://www.openssl.org/~appro/camellia/.
12 # ====================================================================
14 # Performance in cycles per processed byte (less is better) in
15 # 'openssl speed ...' benchmark:
18 # -evp camellia-128-ecb 16.7 21.0 22.7
19 # + over gcc 3.4.6 +25% +5% 0%
21 # camellia-128-cbc 15.7 20.4 21.1
23 # 128-bit key setup 128 216 205 cycles/key
24 # + over gcc 3.4.6 +54% +39% +15%
26 # Numbers in "+" rows represent performance improvement over compiler
27 # generated code. Key setup timings are impressive on AMD and Core2
28 # thanks to 64-bit operations being covertly deployed. Improvement on
29 # EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it
30 # apparently emulates some of 64-bit operations in [32-bit] microcode.
34 if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
36 $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
38 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
39 ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
40 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
41 die "can't locate x86_64-xlate.pl";
43 open STDOUT,"| \"$^X\" $xlate $flavour $output";
45 sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; }
46 sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
47 $r =~ s/%[er]([sd]i)/%\1l/;
48 $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; }
50 $t0="%eax";$t1="%ebx";$t2="%ecx";$t3="%edx";
51 @S=("%r8d","%r9d","%r10d","%r11d");
54 $Tbl="%rbp"; # size optimization
59 $arg0d=$win64?"%ecx":"%edi";
61 # const unsigned int Camellia_SBOX[4][256];
62 # Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
63 # and [2][] - with [3][]. This is done to minimize code size.
64 $SBOX1_1110=0; # Camellia_SBOX[0]
65 $SBOX4_4404=4; # Camellia_SBOX[1]
66 $SBOX2_0222=2048; # Camellia_SBOX[2]
67 $SBOX3_3033=2052; # Camellia_SBOX[3]
69 sub Camellia_Feistel {
71 my $seed=defined(@_[1])?@_[1]:0;
72 my $scale=$seed<0?-8:8;
74 my ($s0,$s1,$s2,$s3)=(@S[($j)%4],@S[($j+1)%4],@S[($j+2)%4],@S[($j+3)%4]);
77 xor $s0,$t0 # t0^=key[0]
78 xor $s1,$t1 # t1^=key[1]
79 movz `&hi("$t0")`,$i0 # (t0>>8)&0xff
80 movz `&lo("$t1")`,$i1 # (t1>>0)&0xff
81 mov $SBOX3_3033($Tbl,$i0,8),$t3 # t3=SBOX3_3033[0]
82 mov $SBOX1_1110($Tbl,$i1,8),$t2 # t2=SBOX1_1110[1]
83 movz `&lo("$t0")`,$i0 # (t0>>0)&0xff
85 movz `&hi("$t1")`,$i1 # (t1>>8)&0xff
86 xor $SBOX4_4404($Tbl,$i0,8),$t3 # t3^=SBOX4_4404[0]
88 xor $SBOX4_4404($Tbl,$i1,8),$t2 # t2^=SBOX4_4404[1]
89 movz `&hi("$t0")`,$i0 # (t0>>24)&0xff
90 movz `&lo("$t1")`,$i1 # (t1>>16)&0xff
91 xor $SBOX1_1110($Tbl,$i0,8),$t3 # t3^=SBOX1_1110[0]
92 xor $SBOX3_3033($Tbl,$i1,8),$t2 # t2^=SBOX3_3033[1]
93 movz `&lo("$t0")`,$i0 # (t0>>16)&0xff
94 movz `&hi("$t1")`,$i1 # (t1>>24)&0xff
95 xor $SBOX2_0222($Tbl,$i0,8),$t3 # t3^=SBOX2_0222[0]
96 xor $SBOX2_0222($Tbl,$i1,8),$t2 # t2^=SBOX2_0222[1]
97 mov `$seed+($i+1)*$scale`($key),$t1 # prefetch key[i+1]
98 mov `$seed+($i+1)*$scale+4`($key),$t0
100 ror \$8,$t3 # t3=RightRotate(t3,8)
107 # void Camellia_EncryptBlock_Rounds(
109 # const Byte plaintext[],
110 # const KEY_TABLE_TYPE keyTable,
116 .globl Camellia_EncryptBlock
117 .type Camellia_EncryptBlock,\@abi-omnipotent
119 Camellia_EncryptBlock:
123 adcl \$0,$arg0d # keyBitLength==128?3:4
125 .size Camellia_EncryptBlock,.-Camellia_EncryptBlock
127 .globl Camellia_EncryptBlock_Rounds
128 .type Camellia_EncryptBlock_Rounds,\@function,4
131 Camellia_EncryptBlock_Rounds:
139 #mov %rsi,$inp # put away arguments
143 shl \$6,%edi # process grandRounds
144 lea .LCamellia_SBOX(%rip),$Tbl
145 lea ($key,%rdi),$keyend
147 mov 0(%rsi),@S[0] # load plaintext
156 call _x86_64_Camellia_encrypt
175 .size Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds
177 .type _x86_64_Camellia_encrypt,\@abi-omnipotent
179 _x86_64_Camellia_encrypt:
181 xor 4($key),@S[0] # ^=key[0-3]
186 mov 16($key),$t1 # prefetch key[4-5]
190 for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16); }
194 mov 8($key),$t3 # prefetch key[2-3]
201 xor $t3,@S[2] # s2^=s3|key[3];
202 xor $t0,@S[1] # s1^=LeftRotate(s0&key[0],1);
206 xor $t1,@S[0] # s0^=s1|key[1];
207 xor $t2,@S[3] # s3^=LeftRotate(s2&key[2],1);
212 xor @S[2],$t0 # SwapHalf
222 .byte 0xf3,0xc3 # rep ret
223 .size _x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt
226 .globl Camellia_DecryptBlock
227 .type Camellia_DecryptBlock,\@abi-omnipotent
229 Camellia_DecryptBlock:
233 adcl \$0,$arg0d # keyBitLength==128?3:4
235 .size Camellia_DecryptBlock,.-Camellia_DecryptBlock
237 .globl Camellia_DecryptBlock_Rounds
238 .type Camellia_DecryptBlock_Rounds,\@function,4
241 Camellia_DecryptBlock_Rounds:
249 #mov %rsi,$inp # put away arguments
253 shl \$6,%edi # process grandRounds
254 lea .LCamellia_SBOX(%rip),$Tbl
255 lea ($keyend,%rdi),$key
257 mov 0(%rsi),@S[0] # load plaintext
266 call _x86_64_Camellia_decrypt
285 .size Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds
287 .type _x86_64_Camellia_decrypt,\@abi-omnipotent
289 _x86_64_Camellia_decrypt:
291 xor 4($key),@S[0] # ^=key[0-3]
296 mov -8($key),$t1 # prefetch key[4-5]
300 for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8); }
304 mov 0($key),$t3 # prefetch key[2-3]
311 xor $t3,@S[2] # s2^=s3|key[3];
312 xor $t0,@S[1] # s1^=LeftRotate(s0&key[0],1);
316 xor $t1,@S[0] # s0^=s1|key[1];
317 xor $t2,@S[3] # s3^=LeftRotate(s2&key[2],1);
328 mov $t2,@S[0] # SwapHalf
333 .byte 0xf3,0xc3 # rep ret
334 .size _x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt
338 my ($rnd,$key,@T)=@_;
339 my $bias=int(@T[0])?shift(@T):0;
343 mov @T[1],`$bias+$rnd*8+0`($key)
344 mov @T[0],`$bias+$rnd*8+4`($key)
345 mov @T[3],`$bias+$rnd*8+8`($key)
346 mov @T[2],`$bias+$rnd*8+12`($key)
349 $code.=" mov @T[0],`$bias+$rnd*8+0`($key)\n";
350 $code.=" mov @T[1],`$bias+$rnd*8+8`($key)\n" if ($#T>=1);
355 my ($rnd,$key,@T)=@_;
356 my $bias=int(@T[0])?shift(@T):0;
358 $code.=" mov `$bias+$rnd*8+0`($key),@T[0]\n";
359 $code.=" mov `$bias+$rnd*8+8`($key),@T[1]\n" if ($#T>=1);
362 # shld is very slow on Intel EM64T family. Even on AMD it limits
363 # instruction decode rate [because it's VectorPath] and consequently
366 my ($i0,$i1,$rot)=@_;
377 # ... Implementing 128-bit rotate without shld gives 80% better
378 # performance EM64T, +15% on AMD64 and only ~7% degradation on
379 # Core2. This is therefore preferred.
381 my ($i0,$i1,$rot)=@_;
400 .globl Camellia_Ekeygen
401 .type Camellia_Ekeygen,\@function,3
411 mov %edi,${keyend}d # put away arguments, keyBitLength
412 mov %rdx,$out # keyTable
414 mov 0(%rsi),@S[0] # load 0-127 bits
424 &_saveround (0,$out,@S); # KL<<<0
426 cmp \$128,$keyend # check keyBitLength
429 mov 16(%rsi),@S[0] # load 128-191 bits
433 mov 24(%rsi),@S[2] # load 192-255 bits
447 &_saveround (4,$out,@S); # temp storage for KR!
449 xor 0($out),@S[1] # KR^KL
455 lea .LCamellia_SIGMA(%rip),$key
456 lea .LCamellia_SBOX(%rip),$Tbl
461 &Camellia_Feistel($step++);
462 &Camellia_Feistel($step++);
464 xor 0($out),@S[1] # ^KL
469 &Camellia_Feistel($step++);
470 &Camellia_Feistel($step++);
475 lea 128($out),$out # size optimization
476 shl \$32,%r8 # @S[0]||
477 shl \$32,%r10 # @S[2]||
479 or %r11,%r10 # ||@S[3]
481 &_loadround (0,$out,-128,"%rax","%rbx"); # KL
482 &_saveround (2,$out,-128,"%r8","%r10"); # KA<<<0
483 &_rotl128 ("%rax","%rbx",15);
484 &_saveround (4,$out,-128,"%rax","%rbx"); # KL<<<15
485 &_rotl128 ("%r8","%r10",15);
486 &_saveround (6,$out,-128,"%r8","%r10"); # KA<<<15
487 &_rotl128 ("%r8","%r10",15); # 15+15=30
488 &_saveround (8,$out,-128,"%r8","%r10"); # KA<<<30
489 &_rotl128 ("%rax","%rbx",30); # 15+30=45
490 &_saveround (10,$out,-128,"%rax","%rbx"); # KL<<<45
491 &_rotl128 ("%r8","%r10",15); # 30+15=45
492 &_saveround (12,$out,-128,"%r8"); # KA<<<45
493 &_rotl128 ("%rax","%rbx",15); # 45+15=60
494 &_saveround (13,$out,-128,"%rbx"); # KL<<<60
495 &_rotl128 ("%r8","%r10",15); # 45+15=60
496 &_saveround (14,$out,-128,"%r8","%r10"); # KA<<<60
497 &_rotl128 ("%rax","%rbx",17); # 60+17=77
498 &_saveround (16,$out,-128,"%rax","%rbx"); # KL<<<77
499 &_rotl128 ("%rax","%rbx",17); # 77+17=94
500 &_saveround (18,$out,-128,"%rax","%rbx"); # KL<<<94
501 &_rotl128 ("%r8","%r10",34); # 60+34=94
502 &_saveround (20,$out,-128,"%r8","%r10"); # KA<<<94
503 &_rotl128 ("%rax","%rbx",17); # 94+17=111
504 &_saveround (22,$out,-128,"%rax","%rbx"); # KL<<<111
505 &_rotl128 ("%r8","%r10",17); # 94+17=111
506 &_saveround (24,$out,-128,"%r8","%r10"); # KA<<<111
513 &_saveround (6,$out,@S); # temp storage for KA!
515 xor `4*8+0`($out),@S[1] # KA^KR
516 xor `4*8+4`($out),@S[0]
517 xor `5*8+0`($out),@S[3]
518 xor `5*8+4`($out),@S[2]
520 &Camellia_Feistel($step++);
521 &Camellia_Feistel($step++);
523 &_loadround (0,$out,"%rax","%rbx"); # KL
524 &_loadround (4,$out,"%rcx","%rdx"); # KR
525 &_loadround (6,$out,"%r14","%r15"); # KA
527 lea 128($out),$out # size optimization
528 shl \$32,%r8 # @S[0]||
529 shl \$32,%r10 # @S[2]||
531 or %r11,%r10 # ||@S[3]
533 &_saveround (2,$out,-128,"%r8","%r10"); # KB<<<0
534 &_rotl128 ("%rcx","%rdx",15);
535 &_saveround (4,$out,-128,"%rcx","%rdx"); # KR<<<15
536 &_rotl128 ("%r14","%r15",15);
537 &_saveround (6,$out,-128,"%r14","%r15"); # KA<<<15
538 &_rotl128 ("%rcx","%rdx",15); # 15+15=30
539 &_saveround (8,$out,-128,"%rcx","%rdx"); # KR<<<30
540 &_rotl128 ("%r8","%r10",30);
541 &_saveround (10,$out,-128,"%r8","%r10"); # KB<<<30
542 &_rotl128 ("%rax","%rbx",45);
543 &_saveround (12,$out,-128,"%rax","%rbx"); # KL<<<45
544 &_rotl128 ("%r14","%r15",30); # 15+30=45
545 &_saveround (14,$out,-128,"%r14","%r15"); # KA<<<45
546 &_rotl128 ("%rax","%rbx",15); # 45+15=60
547 &_saveround (16,$out,-128,"%rax","%rbx"); # KL<<<60
548 &_rotl128 ("%rcx","%rdx",30); # 30+30=60
549 &_saveround (18,$out,-128,"%rcx","%rdx"); # KR<<<60
550 &_rotl128 ("%r8","%r10",30); # 30+30=60
551 &_saveround (20,$out,-128,"%r8","%r10"); # KB<<<60
552 &_rotl128 ("%rax","%rbx",17); # 60+17=77
553 &_saveround (22,$out,-128,"%rax","%rbx"); # KL<<<77
554 &_rotl128 ("%r14","%r15",32); # 45+32=77
555 &_saveround (24,$out,-128,"%r14","%r15"); # KA<<<77
556 &_rotl128 ("%rcx","%rdx",34); # 60+34=94
557 &_saveround (26,$out,-128,"%rcx","%rdx"); # KR<<<94
558 &_rotl128 ("%r14","%r15",17); # 77+17=94
559 &_saveround (28,$out,-128,"%r14","%r15"); # KA<<<77
560 &_rotl128 ("%rax","%rbx",34); # 77+34=111
561 &_saveround (30,$out,-128,"%rax","%rbx"); # KL<<<111
562 &_rotl128 ("%r8","%r10",51); # 60+51=111
563 &_saveround (32,$out,-128,"%r8","%r10"); # KB<<<111
575 .size Camellia_Ekeygen,.-Camellia_Ekeygen
580 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
581 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
582 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
583 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
584 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
585 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
586 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
587 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
588 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
589 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
590 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
591 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
592 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
593 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
594 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
595 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
597 sub S1110 { my $i=shift; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i<<8; sprintf("0x%08x",$i); }
598 sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i; sprintf("0x%08x",$i); }
599 sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; $i=$i<<16|$i<<8|$i; sprintf("0x%08x",$i); }
600 sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; $i=$i<<24|$i<<8|$i; sprintf("0x%08x",$i); }
605 .long 0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
606 .long 0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
607 .long 0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
611 # tables are interleaved, remember?
612 sub data_word { $code.=".long\t".join(',',@_)."\n"; }
613 for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
614 for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
616 # void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
617 # size_t length, const CAMELLIA_KEY *key,
618 # unsigned char *ivp,const int enc);
621 $_end="8(%rsp)"; # inp+len&~15
622 $_res="16(%rsp)"; # len&15
628 .globl Camellia_cbc_encrypt
629 .type Camellia_cbc_encrypt,\@function,6
631 Camellia_cbc_encrypt:
646 # place stack frame just "above mod 1024" the key schedule,
647 # this ensures that cache associativity suffices
648 lea -64-63(%rcx),%r10
653 #add \$8,%rsp # 8 is reserved for callee's ra
655 mov %rdi,$inp # inp argument
656 mov %rsi,$out # out argument
657 mov %r8,%rbx # ivp argument
658 mov %rcx,$key # key argument
659 mov 272(%rcx),${keyend}d # grandRounds
665 lea .LCamellia_SBOX(%rip),$Tbl
675 loop .Lcbc_prefetch_sbox
678 mov %rdx,%rcx # len argument
679 lea ($key,$keyend),$keyend
681 cmp \$0,%r9d # enc argument
685 and \$15,%rcx # length residue
692 mov 0(%rbx),@S[0] # load IV
710 call _x86_64_Camellia_encrypt
712 mov $_key,$key # "rewind" the key
732 mov @S[0],0($out) # write out IV residue
750 .long 0x9066A4F3 # rep movsb
757 jmp .Lcbc_eloop # one more time
763 and \$15,%rcx # length residue
770 mov (%rbx),%rax # load IV
781 mov %rax,0+$ivec # save IV to temporary storage
786 call _x86_64_Camellia_decrypt
788 mov $_key,$key # "rewind" the key
793 mov ($inp),%rax # load IV for next iteration
825 mov %rax,(%rdx) # write out IV residue
840 .long 0x9066A4F3 # rep movsb
844 mov %rax,(%rdx) # write out IV residue
860 .size Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
862 .asciz "Camellia for x86_64 by <appro\@openssl.org>"
866 # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
867 # CONTEXT *context,DISPATCHER_CONTEXT *disp)
875 .extern __imp_RtlVirtualUnwind
876 .type common_se_handler,\@abi-omnipotent
890 mov 120($context),%rax # pull context->Rax
891 mov 248($context),%rbx # pull context->Rip
893 mov 8($disp),%rsi # disp->ImageBase
894 mov 56($disp),%r11 # disp->HandlerData
896 mov 0(%r11),%r10d # HandlerData[0]
897 lea (%rsi,%r10),%r10 # prologue label
898 cmp %r10,%rbx # context->Rip<prologue label
901 mov 152($context),%rax # pull context->Rsp
903 mov 4(%r11),%r10d # HandlerData[1]
904 lea (%rsi,%r10),%r10 # epilogue label
905 cmp %r10,%rbx # context->Rip>=epilogue label
914 mov %rbx,144($context) # restore context->Rbx
915 mov %rbp,160($context) # restore context->Rbp
916 mov %r13,224($context) # restore context->R13
917 mov %r14,232($context) # restore context->R14
918 mov %r15,240($context) # restore context->R15
923 mov %rax,152($context) # restore context->Rsp
924 mov %rsi,168($context) # restore context->Rsi
925 mov %rdi,176($context) # restore context->Rdi
927 jmp .Lcommon_seh_exit
928 .size common_se_handler,.-common_se_handler
930 .type cbc_se_handler,\@abi-omnipotent
944 mov 120($context),%rax # pull context->Rax
945 mov 248($context),%rbx # pull context->Rip
947 lea .Lcbc_prologue(%rip),%r10
948 cmp %r10,%rbx # context->Rip<.Lcbc_prologue
951 lea .Lcbc_body(%rip),%r10
952 cmp %r10,%rbx # context->Rip<.Lcbc_body
953 jb .Lin_cbc_frame_setup
955 mov 152($context),%rax # pull context->Rsp
957 lea .Lcbc_abort(%rip),%r10
958 cmp %r10,%rbx # context->Rip>=.Lcbc_abort
959 jae .Lin_cbc_prologue
961 # handle pushf/popf in Camellia_cbc_encrypt
962 lea .Lcbc_enc_pushf(%rip),%r10
963 cmp %r10,%rbx # context->Rip<=.Lcbc_enc_pushf
966 lea .Lcbc_enc_popf(%rip),%r10
967 cmp %r10,%rbx # context->Rip<.Lcbc_enc_popf
970 lea .Lcbc_dec_pushf(%rip),%r10
971 cmp %r10,%rbx # context->Rip<=.Lcbc_dec_pushf
974 lea .Lcbc_dec_popf(%rip),%r10
975 cmp %r10,%rbx # context->Rip<.Lcbc_dec_popf
980 mov 48(%rax),%rax # $_rsp
983 .Lin_cbc_frame_setup:
990 mov %rbx,144($context) # restore context->Rbx
991 mov %rbp,160($context) # restore context->Rbp
992 mov %r12,216($context) # restore context->R12
993 mov %r13,224($context) # restore context->R13
994 mov %r14,232($context) # restore context->R14
995 mov %r15,240($context) # restore context->R15
1000 mov %rax,152($context) # restore context->Rsp
1001 mov %rsi,168($context) # restore context->Rsi
1002 mov %rdi,176($context) # restore context->Rdi
1007 mov 40($disp),%rdi # disp->ContextRecord
1008 mov $context,%rsi # context
1009 mov \$`1232/8`,%ecx # sizeof(CONTEXT)
1010 .long 0xa548f3fc # cld; rep movsq
1013 xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
1014 mov 8(%rsi),%rdx # arg2, disp->ImageBase
1015 mov 0(%rsi),%r8 # arg3, disp->ControlPc
1016 mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
1017 mov 40(%rsi),%r10 # disp->ContextRecord
1018 lea 56(%rsi),%r11 # &disp->HandlerData
1019 lea 24(%rsi),%r12 # &disp->EstablisherFrame
1020 mov %r10,32(%rsp) # arg5
1021 mov %r11,40(%rsp) # arg6
1022 mov %r12,48(%rsp) # arg7
1023 mov %rcx,56(%rsp) # arg8, (NULL)
1024 call *__imp_RtlVirtualUnwind(%rip)
1026 mov \$1,%eax # ExceptionContinueSearch
1038 .size cbc_se_handler,.-cbc_se_handler
1042 .rva .LSEH_begin_Camellia_EncryptBlock_Rounds
1043 .rva .LSEH_end_Camellia_EncryptBlock_Rounds
1044 .rva .LSEH_info_Camellia_EncryptBlock_Rounds
1046 .rva .LSEH_begin_Camellia_DecryptBlock_Rounds
1047 .rva .LSEH_end_Camellia_DecryptBlock_Rounds
1048 .rva .LSEH_info_Camellia_DecryptBlock_Rounds
1050 .rva .LSEH_begin_Camellia_Ekeygen
1051 .rva .LSEH_end_Camellia_Ekeygen
1052 .rva .LSEH_info_Camellia_Ekeygen
1054 .rva .LSEH_begin_Camellia_cbc_encrypt
1055 .rva .LSEH_end_Camellia_cbc_encrypt
1056 .rva .LSEH_info_Camellia_cbc_encrypt
1060 .LSEH_info_Camellia_EncryptBlock_Rounds:
1062 .rva common_se_handler
1063 .rva .Lenc_prologue,.Lenc_epilogue # HandlerData[]
1064 .LSEH_info_Camellia_DecryptBlock_Rounds:
1066 .rva common_se_handler
1067 .rva .Ldec_prologue,.Ldec_epilogue # HandlerData[]
1068 .LSEH_info_Camellia_Ekeygen:
1070 .rva common_se_handler
1071 .rva .Lkey_prologue,.Lkey_epilogue # HandlerData[]
1072 .LSEH_info_Camellia_cbc_encrypt:
1078 $code =~ s/\`([^\`]*)\`/eval $1/gem;