Compare commits
2081 Commits
OpenSSL_0_
...
OpenSSL_0_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
67956bda58 | ||
![]() |
4e52b9845e | ||
![]() |
e22b864846 | ||
![]() |
b6af2c7e3e | ||
![]() |
57db09906b | ||
![]() |
4c78bc05c4 | ||
![]() |
ef8e772805 | ||
![]() |
54571ba004 | ||
![]() |
237d7b6cae | ||
![]() |
854a225a27 | ||
![]() |
e39acc1c90 | ||
![]() |
a0b76569b2 | ||
![]() |
78625cac82 | ||
![]() |
c28a9165f2 | ||
![]() |
617298dca3 | ||
![]() |
33ab2e31f3 | ||
![]() |
bb7ccdfbe2 | ||
![]() |
c836f8ef73 | ||
![]() |
4df100935f | ||
![]() |
2a0ff7ad20 | ||
![]() |
c2a548a884 | ||
![]() |
77202a85a0 | ||
![]() |
73bfcf2226 | ||
![]() |
2121f15daf | ||
![]() |
b2cf7c6452 | ||
![]() |
7587347bc4 | ||
![]() |
ae3b4f2336 | ||
![]() |
605b04f661 | ||
![]() |
97132a0f8e | ||
![]() |
30e5e39a3d | ||
![]() |
2c618ab993 | ||
![]() |
b5d5c0a21f | ||
![]() |
f8ea4757cc | ||
![]() |
0ed6b52687 | ||
![]() |
a63bf2c53c | ||
![]() |
b3f3407850 | ||
![]() |
477fd4596f | ||
![]() |
30b1b28aff | ||
![]() |
46400c97a9 | ||
![]() |
c558c99fd8 | ||
![]() |
13c3a1defa | ||
![]() |
aaa29f9e83 | ||
![]() |
ede6ef5e08 | ||
![]() |
0f529cbdc3 | ||
![]() |
eb55b9fc19 | ||
![]() |
7012d2a8fa | ||
![]() |
8626230a02 | ||
![]() |
c23632d3f1 | ||
![]() |
3859d7ee78 | ||
![]() |
d615bceb2d | ||
![]() |
7ca1cfbac3 | ||
![]() |
d8e8fc4803 | ||
![]() |
57f39cc826 | ||
![]() |
6489573224 | ||
![]() |
079e00e646 | ||
![]() |
5871ddb016 | ||
![]() |
c7ba21493a | ||
![]() |
8bf5001612 | ||
![]() |
6ed9dfb23a | ||
![]() |
7f62532030 | ||
![]() |
c2c99e2860 | ||
![]() |
8125d9f99c | ||
![]() |
8e6925b0cd | ||
![]() |
d7ecd42255 | ||
![]() |
41b7619596 | ||
![]() |
211655fcdd | ||
![]() |
363bd0b48e | ||
![]() |
60aee6ce15 | ||
![]() |
bab534057b | ||
![]() |
cec2af7510 | ||
![]() |
6de3683908 | ||
![]() |
fceac0bc74 | ||
![]() |
792bbc2374 | ||
![]() |
4a94003a51 | ||
![]() |
ab4d689832 | ||
![]() |
23b973e600 | ||
![]() |
b3b201b6f7 | ||
![]() |
d41c785d69 | ||
![]() |
a370537bde | ||
![]() |
2bd45dc94c | ||
![]() |
121f9e743c | ||
![]() |
0eab41fb78 | ||
![]() |
8aa02e97a7 | ||
![]() |
a68c7b9171 | ||
![]() |
5cabcf96e7 | ||
![]() |
85e878f224 | ||
![]() |
fe1c7fecf1 | ||
![]() |
0e941da6fa | ||
![]() |
2d1cbc85c8 | ||
![]() |
d195d60a5f | ||
![]() |
e81695205e | ||
![]() |
fe150ac25d | ||
![]() |
bec45a35bb | ||
![]() |
3b0ee0d2bf | ||
![]() |
dde5b979d2 | ||
![]() |
57a6ac7c4f | ||
![]() |
9b9cb004f7 | ||
![]() |
6ba71a7173 | ||
![]() |
4ded7b44a8 | ||
![]() |
1457619e13 | ||
![]() |
ccf529928f | ||
![]() |
5ceb595dfa | ||
![]() |
44390fadc0 | ||
![]() |
974d05a323 | ||
![]() |
0f76640fba | ||
![]() |
a11974180f | ||
![]() |
5d48a66a6a | ||
![]() |
63fc7f848d | ||
![]() |
830457ce4f | ||
![]() |
ea4d5005d9 | ||
![]() |
9f03d0fc04 | ||
![]() |
2140659b00 | ||
![]() |
e527201f6b | ||
![]() |
70531c147c | ||
![]() |
75bbf6e14c | ||
![]() |
702e742515 | ||
![]() |
be01f79d3d | ||
![]() |
bf785c9849 | ||
![]() |
4db4882402 | ||
![]() |
6786f52ada | ||
![]() |
2e6a7b3efc | ||
![]() |
63461b8db1 | ||
![]() |
e77228ba11 | ||
![]() |
5c60b1637a | ||
![]() |
26397d2e8c | ||
![]() |
85b2c0ce7f | ||
![]() |
f826bf7798 | ||
![]() |
3ebbe8853f | ||
![]() |
ac71d81e84 | ||
![]() |
a9dbe71ee0 | ||
![]() |
ecd3370ba0 | ||
![]() |
19d300d07c | ||
![]() |
071920d9f6 | ||
![]() |
1f6e9bce21 | ||
![]() |
434ba03ca9 | ||
![]() |
d88d941c87 | ||
![]() |
9d44cd1642 | ||
![]() |
1d4e879106 | ||
![]() |
ae381fef5c | ||
![]() |
48114ec952 | ||
![]() |
7a76219774 | ||
![]() |
2900fc8ae1 | ||
![]() |
e9afa08cd1 | ||
![]() |
bcaa36fd11 | ||
![]() |
71702f7ed0 | ||
![]() |
fd252de312 | ||
![]() |
349e78e2e8 | ||
![]() |
79bd20fd17 | ||
![]() |
d0c3628834 | ||
![]() |
31636a3ed1 | ||
![]() |
f3b7bdadbc | ||
![]() |
ad7159ea84 | ||
![]() |
0b0dbb2cac | ||
![]() |
12bf56c017 | ||
![]() |
93c4ba07d7 | ||
![]() |
36d46234c7 | ||
![]() |
774b2fe700 | ||
![]() |
6c901ae8c1 | ||
![]() |
90c65a9838 | ||
![]() |
5eba1ab346 | ||
![]() |
4e50072d56 | ||
![]() |
dd9557a8ba | ||
![]() |
ed551cddf7 | ||
![]() |
5aca224ecd | ||
![]() |
dab6293482 | ||
![]() |
1416aec60d | ||
![]() |
aa8f38e49b | ||
![]() |
8525377265 | ||
![]() |
2fbc8a2aad | ||
![]() |
6343829a39 | ||
![]() |
2401debe83 | ||
![]() |
5c61111bff | ||
![]() |
bc645199c0 | ||
![]() |
0a8c9f7de1 | ||
![]() |
7b808412c9 | ||
![]() |
706c5a4d35 | ||
![]() |
0afc9f5bc0 | ||
![]() |
2e5975285e | ||
![]() |
5947ca0409 | ||
![]() |
d40a1b865f | ||
![]() |
f80921b6a6 | ||
![]() |
9be5481297 | ||
![]() |
8fe8bae15a | ||
![]() |
f2c0230518 | ||
![]() |
e6e0c9018c | ||
![]() |
9619b730b4 | ||
![]() |
2766515fca | ||
![]() |
87d52468aa | ||
![]() |
70d71f6185 | ||
![]() |
5ee92a5ec1 | ||
![]() |
c76fd290be | ||
![]() |
d0a20cafa1 | ||
![]() |
8da07655ee | ||
![]() |
befe1fbc29 | ||
![]() |
5e4430e70d | ||
![]() |
4d6e1e4f29 | ||
![]() |
122396f2db | ||
![]() |
09a60c9833 | ||
![]() |
b444ac3e6f | ||
![]() |
f768be81d8 | ||
![]() |
91173829db | ||
![]() |
bfaead2b12 | ||
![]() |
e6b4578540 | ||
![]() |
0dd4850ee0 | ||
![]() |
c650168a4f | ||
![]() |
ea71ec1b11 | ||
![]() |
f1455b3063 | ||
![]() |
b764f82c64 | ||
![]() |
436bdcff4e | ||
![]() |
27f864e8ac | ||
![]() |
80aa9cc985 | ||
![]() |
ab7e09f59b | ||
![]() |
e9eda23ae6 | ||
![]() |
6caa4edd3e | ||
![]() |
ac786241a2 | ||
![]() |
df0681e554 | ||
![]() |
e19106f5fb | ||
![]() |
ae7ec4c71d | ||
![]() |
020d67fb89 | ||
![]() |
3fdc6c11aa | ||
![]() |
dcf6b3e9b6 | ||
![]() |
606f6c477a | ||
![]() |
1581f82243 | ||
![]() |
0d6f9c7181 | ||
![]() |
640b86cb24 | ||
![]() |
111a6e2a23 | ||
![]() |
d764e7edb8 | ||
![]() |
aff8259510 | ||
![]() |
256b3e9c5f | ||
![]() |
762a2e3cab | ||
![]() |
28b6d5020e | ||
![]() |
d5bbead449 | ||
![]() |
0f7efbc859 | ||
![]() |
a7ae4abfd9 | ||
![]() |
30661b1b01 | ||
![]() |
1ea6472e60 | ||
![]() |
b8dfde2a36 | ||
![]() |
570006f3a2 | ||
![]() |
babb379849 | ||
![]() |
6665ef303e | ||
![]() |
7e7af0bc51 | ||
![]() |
87d3a0cd90 | ||
![]() |
1e369b375e | ||
![]() |
6bf24568bc | ||
![]() |
837f2fc7a4 | ||
![]() |
1a489c9af1 | ||
![]() |
8c864e5466 | ||
![]() |
be5707c820 | ||
![]() |
4a4f3071ec | ||
![]() |
d7235a9d68 | ||
![]() |
fa0f834c20 | ||
![]() |
96562f2fb3 | ||
![]() |
b9790c1cd4 | ||
![]() |
fcbdde0dfe | ||
![]() |
51ec776b7d | ||
![]() |
e65bcbcef0 | ||
![]() |
e710de12ce | ||
![]() |
db99c52509 | ||
![]() |
f8d6be3f81 | ||
![]() |
d493899579 | ||
![]() |
492279f6f3 | ||
![]() |
3ad74edce8 | ||
![]() |
2b7b1cad10 | ||
![]() |
43048d13c8 | ||
![]() |
e8da6a1d0f | ||
![]() |
305514000c | ||
![]() |
0702150f53 | ||
![]() |
a0ee081515 | ||
![]() |
d43c4497ce | ||
![]() |
4b96839f06 | ||
![]() |
249a77f5fb | ||
![]() |
d0fff69dc9 | ||
![]() |
8c9bd89338 | ||
![]() |
2e415778f2 | ||
![]() |
1cbf663a6c | ||
![]() |
9be8035b11 | ||
![]() |
2ecd2edede | ||
![]() |
9d84d4ed5e | ||
![]() |
2e0c7db950 | ||
![]() |
002e66c0e8 | ||
![]() |
e9746e03ee | ||
![]() |
ab9c689ad3 | ||
![]() |
4c3296960d | ||
![]() |
96826bfc84 | ||
![]() |
eb1aa135d8 | ||
![]() |
99649b5990 | ||
![]() |
6d6c47980e | ||
![]() |
474b3b1cc8 | ||
![]() |
3e727a3b37 | ||
![]() |
a9ff742e42 | ||
![]() |
787287af40 | ||
![]() |
5cbd203302 | ||
![]() |
592a207b94 | ||
![]() |
6bcbac0abb | ||
![]() |
4c048211f1 | ||
![]() |
b94551e823 | ||
![]() |
9b634c9b37 | ||
![]() |
5b331ab77a | ||
![]() |
dd6f479ea8 | ||
![]() |
87facba376 | ||
![]() |
e4662fdb62 | ||
![]() |
efa73a77e4 | ||
![]() |
89778b7f3f | ||
![]() |
c79c5a256b | ||
![]() |
9960bdc6fa | ||
![]() |
23dcb447ff | ||
![]() |
39c63e162c | ||
![]() |
34d05a4023 | ||
![]() |
dcc0c29876 | ||
![]() |
db50661fce | ||
![]() |
f9afd9f861 | ||
![]() |
d4cdbab99b | ||
![]() |
5f834ab123 | ||
![]() |
8528128b2a | ||
![]() |
a0f3679b52 | ||
![]() |
8228fd89fc | ||
![]() |
869eb9e767 | ||
![]() |
6c2878344f | ||
![]() |
2836cb3816 | ||
![]() |
46d4782888 | ||
![]() |
a01a351cc2 | ||
![]() |
adb92d56eb | ||
![]() |
ce04f91951 | ||
![]() |
6cb9fca70d | ||
![]() |
ec0bfca7e7 | ||
![]() |
1cd504e7be | ||
![]() |
11f3cee93b | ||
![]() |
6bf79e30ea | ||
![]() |
7555c9337f | ||
![]() |
ffc2b3e927 | ||
![]() |
9ab89286a2 | ||
![]() |
5329130333 | ||
![]() |
e1451bb51d | ||
![]() |
0b44c26d78 | ||
![]() |
4db9677bac | ||
![]() |
1381bf90f4 | ||
![]() |
e0f7b87227 | ||
![]() |
985de86340 | ||
![]() |
b814c01a76 | ||
![]() |
c07a126fb2 | ||
![]() |
09a6e19431 | ||
![]() |
863d447e0b | ||
![]() |
5ce278a77b | ||
![]() |
37cf49a3df | ||
![]() |
f79262e94b | ||
![]() |
7d537d4fc7 | ||
![]() |
ca89fc1fb4 | ||
![]() |
59d2d48f64 | ||
![]() |
b3c8dd4eab | ||
![]() |
45d3767d28 | ||
![]() |
8671b89860 | ||
![]() |
4f7f411719 | ||
![]() |
eac442ddd3 | ||
![]() |
55bef26d8a | ||
![]() |
2aa2a5775f | ||
![]() |
c451bd828f | ||
![]() |
8ecfbedd85 | ||
![]() |
c173fce4e2 | ||
![]() |
953174f46e | ||
![]() |
c621c7e432 | ||
![]() |
2bbe8f9129 | ||
![]() |
4be0a5d429 | ||
![]() |
bdfe932dca | ||
![]() |
3fc59c8406 | ||
![]() |
c61915c659 | ||
![]() |
368888bcb6 | ||
![]() |
eafd6e5110 | ||
![]() |
05935c47b2 | ||
![]() |
d8bd55a364 | ||
![]() |
841c91d6e4 | ||
![]() |
a4792168ec | ||
![]() |
90b96776cd | ||
![]() |
408f906592 | ||
![]() |
7a18ecb2df | ||
![]() |
174c86a216 | ||
![]() |
c6ddacf7f8 | ||
![]() |
ab3eafd5b5 | ||
![]() |
dd043cd501 | ||
![]() |
a75c662fd1 | ||
![]() |
83574cf808 | ||
![]() |
2cd81830ef | ||
![]() |
e194fe8f47 | ||
![]() |
40a706286f | ||
![]() |
c6f6c380c7 | ||
![]() |
8f395e0f4d | ||
![]() |
595852f3b5 | ||
![]() |
0a56761f19 | ||
![]() |
220903f92e | ||
![]() |
3c1d6bbc92 | ||
![]() |
cab14b9803 | ||
![]() |
17a4a4dff8 | ||
![]() |
c2c2e7a438 | ||
![]() |
d18ef847f4 | ||
![]() |
5c0d90a699 | ||
![]() |
f434730524 | ||
![]() |
65fd877515 | ||
![]() |
64ddafc6b6 | ||
![]() |
781f0a9bb5 | ||
![]() |
3de5a7745f | ||
![]() |
94fd382f8b | ||
![]() |
4bd4afa34e | ||
![]() |
148bb9515c | ||
![]() |
51e00db226 | ||
![]() |
a92ebf2290 | ||
![]() |
f49c687507 | ||
![]() |
8b99c79fae | ||
![]() |
718f8f7a9e | ||
![]() |
e718520cc5 | ||
![]() |
4f46934269 | ||
![]() |
fabe640f5e | ||
![]() |
19048b5c8d | ||
![]() |
156ee88285 | ||
![]() |
c386f8ac38 | ||
![]() |
4a954b56c9 | ||
![]() |
d05a474556 | ||
![]() |
8a2062fefe | ||
![]() |
2f63ad5b35 | ||
![]() |
c78bba2343 | ||
![]() |
d26c905c67 | ||
![]() |
8fcc9caecc | ||
![]() |
e7b097f558 | ||
![]() |
5ee6f96cea | ||
![]() |
dc634aff25 | ||
![]() |
8e3b2dbb31 | ||
![]() |
ba6f95e81b | ||
![]() |
281066cb03 | ||
![]() |
830b8877ba | ||
![]() |
9912ab6770 | ||
![]() |
299ab428ce | ||
![]() |
e6ef05d5f3 | ||
![]() |
0f401ff08b | ||
![]() |
5558128541 | ||
![]() |
e33c72dfc6 | ||
![]() |
44a877aa88 | ||
![]() |
6b6fe3d8e4 | ||
![]() |
4c1a6e004a | ||
![]() |
6e6ada18c6 | ||
![]() |
b35a131069 | ||
![]() |
1728756255 | ||
![]() |
a12a6b9962 | ||
![]() |
852bd35065 | ||
![]() |
a5db50d005 | ||
![]() |
f3eba36c4c | ||
![]() |
529d329ce1 | ||
![]() |
47a6d388c7 | ||
![]() |
c02b6b6b21 | ||
![]() |
3b28bc9910 | ||
![]() |
fc003bcecb | ||
![]() |
38d3a73808 | ||
![]() |
73b3c2d861 | ||
![]() |
4670e00ff5 | ||
![]() |
287df2fe49 | ||
![]() |
e0fbd07309 | ||
![]() |
eaee098e1f | ||
![]() |
43d9e9d07f | ||
![]() |
c420fab52b | ||
![]() |
6469a1fda3 | ||
![]() |
7f50d9a4b0 | ||
![]() |
da6ea110b5 | ||
![]() |
fb777e1f79 | ||
![]() |
360bb61d86 | ||
![]() |
847e551f39 | ||
![]() |
d4122504a2 | ||
![]() |
2c4226c42b | ||
![]() |
86173db853 | ||
![]() |
9034c56c6c | ||
![]() |
e33ffaca12 | ||
![]() |
853eae51e0 | ||
![]() |
b4be380889 | ||
![]() |
ff80280b01 | ||
![]() |
e45641bd17 | ||
![]() |
d5a37b0293 | ||
![]() |
6819050722 | ||
![]() |
88db4e6b9e | ||
![]() |
be86dd85e4 | ||
![]() |
3df9357103 | ||
![]() |
992e92a46e | ||
![]() |
3247812e34 | ||
![]() |
a5cdb7d5bd | ||
![]() |
4a6bb116c4 | ||
![]() |
2819ffb520 | ||
![]() |
964c7e8f6d | ||
![]() |
f6a45ac5ac | ||
![]() |
2e86f0d8d7 | ||
![]() |
e2a29d49ca | ||
![]() |
b99674103d | ||
![]() |
41f81a0143 | ||
![]() |
36309aa2be | ||
![]() |
eb9d8d8cd4 | ||
![]() |
f7ccba3edf | ||
![]() |
eb77ebe26c | ||
![]() |
f5e2354c9d | ||
![]() |
f4cc56f494 | ||
![]() |
be86c7fc87 | ||
![]() |
6205171362 | ||
![]() |
ab568a17cf | ||
![]() |
fe591284be | ||
![]() |
7122aafce5 | ||
![]() |
5ffba305c8 | ||
![]() |
ceee538af5 | ||
![]() |
054307e7ed | ||
![]() |
8cd358bef8 | ||
![]() |
eeb9cdfc94 | ||
![]() |
16fe5f8b50 | ||
![]() |
041e7f2eee | ||
![]() |
ab12438030 | ||
![]() |
c220e58f9e | ||
![]() |
6bd05ad472 | ||
![]() |
90ec4c0af0 | ||
![]() |
52e9196d7e | ||
![]() |
f7e85c371e | ||
![]() |
f5cbf8fbe1 | ||
![]() |
7d7e640e0b | ||
![]() |
e4f0e40eac | ||
![]() |
6e3bc4f073 | ||
![]() |
c36e936b60 | ||
![]() |
761ffa729f | ||
![]() |
1e26a8baed | ||
![]() |
7c337e00d2 | ||
![]() |
7e8481afd1 | ||
![]() |
1266cec2fe | ||
![]() |
3667a6f5b3 | ||
![]() |
deb21fbae9 | ||
![]() |
057039f782 | ||
![]() |
d7c738a09a | ||
![]() |
a981e2adbc | ||
![]() |
88fce8539f | ||
![]() |
4f1aa191b3 | ||
![]() |
e540d1cd77 | ||
![]() |
fd47c36136 | ||
![]() |
d9f5f07e28 | ||
![]() |
b31db9ee96 | ||
![]() |
1021f9aa5e | ||
![]() |
320bfc1be7 | ||
![]() |
b820455c6e | ||
![]() |
5c4436c977 | ||
![]() |
a78a03744d | ||
![]() |
a329fdde51 | ||
![]() |
31d3c84422 | ||
![]() |
afff52a3ba | ||
![]() |
8931b30d84 | ||
![]() |
27dc105f51 | ||
![]() |
3964038fe6 | ||
![]() |
b510d77535 | ||
![]() |
56c7754cab | ||
![]() |
92e2c81aff | ||
![]() |
a70a49a018 | ||
![]() |
61b05a0025 | ||
![]() |
7c9882eb24 | ||
![]() |
0d7f6fc76a | ||
![]() |
a9e96d724d | ||
![]() |
d9e427f09c | ||
![]() |
a23e3dbee1 | ||
![]() |
400ca0e467 | ||
![]() |
9536b85c07 | ||
![]() |
4d318c79b2 | ||
![]() |
1ad90a916b | ||
![]() |
8ab9025e31 | ||
![]() |
9e5df8e448 | ||
![]() |
96d13fe62b | ||
![]() |
089458b096 | ||
![]() |
7c1722c60d | ||
![]() |
c020c3213e | ||
![]() |
930875ef77 | ||
![]() |
3b979c5450 | ||
![]() |
339ad7ce73 | ||
![]() |
676517e08e | ||
![]() |
52108cecc0 | ||
![]() |
addd641f3a | ||
![]() |
f63e4be392 | ||
![]() |
ca55d11f84 | ||
![]() |
abe7f8b457 | ||
![]() |
a078befcbe | ||
![]() |
f12797a447 | ||
![]() |
fa8e921f66 | ||
![]() |
4287ade5b4 | ||
![]() |
7398053149 | ||
![]() |
4d1f3f7a6c | ||
![]() |
aff686df91 | ||
![]() |
637f90621d | ||
![]() |
6d0624aca3 | ||
![]() |
085ea80371 | ||
![]() |
ab0ff06205 | ||
![]() |
79eeb47031 | ||
![]() |
9911b7496f | ||
![]() |
3dbd453f41 | ||
![]() |
731339627f | ||
![]() |
26e71a1850 | ||
![]() |
db01bad30f | ||
![]() |
6ff28e017d | ||
![]() |
4664eb5230 | ||
![]() |
744ecaa5b6 | ||
![]() |
76d761ccd3 | ||
![]() |
eef0c1f34c | ||
![]() |
82a2431327 | ||
![]() |
96fc37f145 | ||
![]() |
3a87756fed | ||
![]() |
c8ec4a1b0b | ||
![]() |
699e1a3a82 | ||
![]() |
64214a2183 | ||
![]() |
0fcb905b0d | ||
![]() |
4be63cfb55 | ||
![]() |
ca64056836 | ||
![]() |
df77428443 | ||
![]() |
3e583572b3 | ||
![]() |
43d8f27dca | ||
![]() |
b045299113 | ||
![]() |
13baedc55b | ||
![]() |
9400d9ac83 | ||
![]() |
341e18b497 | ||
![]() |
339a1820fd | ||
![]() |
cec2538ca9 | ||
![]() |
28f7e60d47 | ||
![]() |
544b82e493 | ||
![]() |
8789af8db8 | ||
![]() |
1ad6a1b5e9 | ||
![]() |
6e150083bb | ||
![]() |
98d8baabbd | ||
![]() |
c1d2e00ec5 | ||
![]() |
ad8bd4ece8 | ||
![]() |
2f0550c4c1 | ||
![]() |
98057eba77 | ||
![]() |
097f9d8c52 | ||
![]() |
60447e59ef | ||
![]() |
94e6ae7a69 | ||
![]() |
f670738987 | ||
![]() |
b6a338cb29 | ||
![]() |
4726fcfc25 | ||
![]() |
15bd07e923 | ||
![]() |
fdf355878c | ||
![]() |
da989402f2 | ||
![]() |
10f0c85cfc | ||
![]() |
70ba4ee5d5 | ||
![]() |
31f528b15d | ||
![]() |
86140095b5 | ||
![]() |
8e1d3ba50e | ||
![]() |
37210fe7e2 | ||
![]() |
0e1dba934f | ||
![]() |
11d01d371f | ||
![]() |
76c3ef7446 | ||
![]() |
659f7f3168 | ||
![]() |
3d3bf9c730 | ||
![]() |
4017e8706c | ||
![]() |
3ce54f35b3 | ||
![]() |
ebc06fba67 | ||
![]() |
e979c039f9 | ||
![]() |
90acf770b5 | ||
![]() |
0d89e45690 | ||
![]() |
1948c7e6dd | ||
![]() |
a6db6a0070 | ||
![]() |
fdb2fe6dc2 | ||
![]() |
a2115c5d17 | ||
![]() |
4fe55663df | ||
![]() |
ae1552ee99 | ||
![]() |
debf380122 | ||
![]() |
ddb038d349 | ||
![]() |
b7cc9dffac | ||
![]() |
e1b81fed33 | ||
![]() |
5d58f1bbfe | ||
![]() |
fcd1cb666c | ||
![]() |
4f19a9cb9f | ||
![]() |
0023adb47a | ||
![]() |
81fe8dcfe1 | ||
![]() |
d527834a1d | ||
![]() |
89c333e3e5 | ||
![]() |
0d97d00b6c | ||
![]() |
e7adda52b3 | ||
![]() |
7432d073af | ||
![]() |
04e2ab2c02 | ||
![]() |
b7fcc08976 | ||
![]() |
7722e53f12 | ||
![]() |
2c3ee16272 | ||
![]() |
19112771d6 | ||
![]() |
4c7c5ff667 | ||
![]() |
d7e915616d | ||
![]() |
67c8e7f414 | ||
![]() |
74eb3e0914 | ||
![]() |
79fe664f19 | ||
![]() |
5f0477f47b | ||
![]() |
7bbce69721 | ||
![]() |
870d6541f2 | ||
![]() |
02c27b113c | ||
![]() |
86d4bc3aea | ||
![]() |
761772d7e1 | ||
![]() |
54ef01b54b | ||
![]() |
9311c4421a | ||
![]() |
aaa4f448cf | ||
![]() |
5f8b524619 | ||
![]() |
08111768a2 | ||
![]() |
1b827d7b6f | ||
![]() |
a005fb019f | ||
![]() |
b5e5760d01 | ||
![]() |
cf2bc94e5c | ||
![]() |
26f0cf69d3 | ||
![]() |
61836c1b70 | ||
![]() |
2a1b0c8d65 | ||
![]() |
75a8e30f4f | ||
![]() |
716b87a026 | ||
![]() |
08b229e13f | ||
![]() |
a529a80108 | ||
![]() |
c81898cbc4 | ||
![]() |
330591fdfc | ||
![]() |
c7503f5240 | ||
![]() |
eff371c866 | ||
![]() |
8dc899dee4 | ||
![]() |
cc3d7bd0fc | ||
![]() |
7df4c86bdd | ||
![]() |
c313e32a8b | ||
![]() |
77519b51db | ||
![]() |
1a01868e35 | ||
![]() |
563d3e5948 | ||
![]() |
1187ee7dad | ||
![]() |
7c5921e736 | ||
![]() |
399f94bfb4 | ||
![]() |
1fa29843fa | ||
![]() |
ee0449b17c | ||
![]() |
e28eddc51f | ||
![]() |
d82a612a90 | ||
![]() |
e7e8f4b333 | ||
![]() |
a6fbcb4220 | ||
![]() |
8164032a2e | ||
![]() |
a5804a750b | ||
![]() |
81025661a9 | ||
![]() |
4ece7eb6f4 | ||
![]() |
0bb01b7df0 | ||
![]() |
1c56e95e28 | ||
![]() |
446124a258 | ||
![]() |
583b0b67ab | ||
![]() |
584502d4a0 | ||
![]() |
d8803d5ae6 | ||
![]() |
acfb4b5b9f | ||
![]() |
0ddd3ea217 | ||
![]() |
6a8517f274 | ||
![]() |
94d511cdbd | ||
![]() |
ec5d747328 | ||
![]() |
c6880b2533 | ||
![]() |
eb6eb3e630 | ||
![]() |
ae4eb3c9ac | ||
![]() |
ba0e826d83 | ||
![]() |
f3fef74b09 | ||
![]() |
014f62b649 | ||
![]() |
55eab3b74b | ||
![]() |
dc0fcb98df | ||
![]() |
d24a9c8f5a | ||
![]() |
42fe218b9f | ||
![]() |
956006b741 | ||
![]() |
167066fed4 | ||
![]() |
525de5d335 | ||
![]() |
367eb1f125 | ||
![]() |
3444961787 | ||
![]() |
710069c19e | ||
![]() |
ddd3a617ca | ||
![]() |
6434abbfc6 | ||
![]() |
e45c100762 | ||
![]() |
5a22a8e7f9 | ||
![]() |
d6c764573c | ||
![]() |
9d35d08ab6 | ||
![]() |
f7b61702a0 | ||
![]() |
983180bb8b | ||
![]() |
cdb0392159 | ||
![]() |
1891f5b395 | ||
![]() |
a3963619f6 | ||
![]() |
34994068a4 | ||
![]() |
afaad0ada6 | ||
![]() |
05f9cb3b77 | ||
![]() |
1988a456a7 | ||
![]() |
69216cc5a5 | ||
![]() |
2cf6fa4c8b | ||
![]() |
a61710b868 | ||
![]() |
20f7563f3d | ||
![]() |
3df2eff4bd | ||
![]() |
a415ebd026 | ||
![]() |
52ee3d01ae | ||
![]() |
e59f992be6 | ||
![]() |
8bae7722a2 | ||
![]() |
0d7dba92c8 | ||
![]() |
ce1390aedc | ||
![]() |
287a9ee76e | ||
![]() |
96b0f6c16d | ||
![]() |
e1612ea59d | ||
![]() |
71f4ea44eb | ||
![]() |
35295bdbee | ||
![]() |
aa8d6f3e86 | ||
![]() |
62aa5dd415 | ||
![]() |
673c55a2fe | ||
![]() |
949ce10e88 | ||
![]() |
8dee823e61 | ||
![]() |
5d86336746 | ||
![]() |
5b89f78a89 | ||
![]() |
85a5668dba | ||
![]() |
c943ca5404 | ||
![]() |
1c7f8707fd | ||
![]() |
a21c46e70b | ||
![]() |
f3c26535ad | ||
![]() |
2329694222 | ||
![]() |
206a975752 | ||
![]() |
9677bf0f30 | ||
![]() |
6d6496ed52 | ||
![]() |
7d9cf7c0bb | ||
![]() |
55525742f4 | ||
![]() |
c693b5a55c | ||
![]() |
6b6443dead | ||
![]() |
54b5fd537f | ||
![]() |
0b99d4f1d1 | ||
![]() |
3c07d3a3d3 | ||
![]() |
1d1a64653c | ||
![]() |
297e6f1917 | ||
![]() |
b948e2c59e | ||
![]() |
18096abb29 | ||
![]() |
0aa08a2e34 | ||
![]() |
f20af72312 | ||
![]() |
7ef643360d | ||
![]() |
76c828c627 | ||
![]() |
281cfff026 | ||
![]() |
64a5c5d1be | ||
![]() |
7b8b797375 | ||
![]() |
a1a382dbc9 | ||
![]() |
19f6c524bf | ||
![]() |
8dbdf6314c | ||
![]() |
9c54e18bf0 | ||
![]() |
9aba74e55a | ||
![]() |
e4317d2031 | ||
![]() |
61775daf00 | ||
![]() |
86d8f3ee19 | ||
![]() |
cb1fbf9f63 | ||
![]() |
3005764c18 | ||
![]() |
b1e8b4e65d | ||
![]() |
c6149e2f02 | ||
![]() |
aa5c99fa01 | ||
![]() |
9c200f5471 | ||
![]() |
ec06417d52 | ||
![]() |
a4346646f1 | ||
![]() |
a70c09e2a2 | ||
![]() |
0f9e0abbee | ||
![]() |
e77dbf325f | ||
![]() |
f03620ea15 | ||
![]() |
47b2e238e5 | ||
![]() |
ad35cdac74 | ||
![]() |
4eba5d8c86 | ||
![]() |
e69adea539 | ||
![]() |
9660cbcd6b | ||
![]() |
9c9c83ccb9 | ||
![]() |
1d42fb5f4a | ||
![]() |
e119769480 | ||
![]() |
b2dba9bf1f | ||
![]() |
932cc129ee | ||
![]() |
1a42839ba7 | ||
![]() |
232a938c75 | ||
![]() |
69ab085290 | ||
![]() |
5f09d0ecc2 | ||
![]() |
76b46e7707 | ||
![]() |
6217896145 | ||
![]() |
ee7ca0941a | ||
![]() |
f8492ffeaa | ||
![]() |
308595638a | ||
![]() |
0bd8d6e2e1 | ||
![]() |
160065c5bb | ||
![]() |
ae0d6e3e36 | ||
![]() |
6fa8a01c72 | ||
![]() |
3f6916cf29 | ||
![]() |
a4470ae7b2 | ||
![]() |
251718e4c1 | ||
![]() |
c504a5e783 | ||
![]() |
f6fb2c95ef | ||
![]() |
708311267a | ||
![]() |
cdd1d7a618 | ||
![]() |
2f324768b2 | ||
![]() |
6ef18c21c9 | ||
![]() |
b38c0add30 | ||
![]() |
b900df5258 | ||
![]() |
a2a54ffc5f | ||
![]() |
20c04a13e6 | ||
![]() |
a291745eeb | ||
![]() |
0862caf27e | ||
![]() |
cb1bab1a04 | ||
![]() |
96afc1cfd5 | ||
![]() |
24a8c25ab5 | ||
![]() |
d1e7d1d96c | ||
![]() |
18f547734e | ||
![]() |
be3b365a34 | ||
![]() |
b2b2dafc28 | ||
![]() |
14ab6cdd69 | ||
![]() |
eeec060df0 | ||
![]() |
0efb7b1eea | ||
![]() |
f000f705ea | ||
![]() |
2749cc1ede | ||
![]() |
a44e4f2cf8 | ||
![]() |
30b10f947a | ||
![]() |
731c6802d7 | ||
![]() |
4cfb986f27 | ||
![]() |
9cfc8a9d5c | ||
![]() |
18327cd0e4 | ||
![]() |
2022cfe07e | ||
![]() |
47b71e6ee9 | ||
![]() |
74633553a9 | ||
![]() |
376bf1d4aa | ||
![]() |
d318fb79d2 | ||
![]() |
0cc361f3e7 | ||
![]() |
baecb96e8a | ||
![]() |
6181f5e404 | ||
![]() |
d952c79a7b | ||
![]() |
3dfb6b3353 | ||
![]() |
48bd505c0b | ||
![]() |
ab2d91bd6b | ||
![]() |
3b2eead381 | ||
![]() |
f3d2a9db09 | ||
![]() |
8bbf6ac010 | ||
![]() |
38e952e8ae | ||
![]() |
fa9fed1c3a | ||
![]() |
f6301f6888 | ||
![]() |
44907e6064 | ||
![]() |
907e99623c | ||
![]() |
231671b9ff | ||
![]() |
4f1a0b2c21 | ||
![]() |
260c497cdd | ||
![]() |
313fce7b61 | ||
![]() |
2f877235a3 | ||
![]() |
309fa55bbb | ||
![]() |
4b8747e440 | ||
![]() |
2ff7a0edef | ||
![]() |
442cbb062d | ||
![]() |
c971ca4c86 | ||
![]() |
9babf3929b | ||
![]() |
2ec0be9e77 | ||
![]() |
c2d1c2d319 | ||
![]() |
162f677def | ||
![]() |
2875462425 | ||
![]() |
a1d915990b | ||
![]() |
b002265ee3 | ||
![]() |
bd31fb2145 | ||
![]() |
b506821d43 | ||
![]() |
4bfb49b3cf | ||
![]() |
9981a51e42 | ||
![]() |
ebb326afe6 | ||
![]() |
0d1aa74d6f | ||
![]() |
0f32c841a6 | ||
![]() |
41a8d5167f | ||
![]() |
8f41e4fa4d | ||
![]() |
de50494505 | ||
![]() |
3d1def0132 | ||
![]() |
0a29f5110d | ||
![]() |
8b71d35458 | ||
![]() |
760e353528 | ||
![]() |
3627fedbea | ||
![]() |
bbb5cf05db | ||
![]() |
ebb01b84b8 | ||
![]() |
a0d48e7e7e | ||
![]() |
1fcfa22222 | ||
![]() |
c9fb4e2c8d | ||
![]() |
6e7ca5e1eb | ||
![]() |
954b274789 | ||
![]() |
0d5ac5a738 | ||
![]() |
c209a35820 | ||
![]() |
dd2b6750db | ||
![]() |
4bb89bca9e | ||
![]() |
ac63b8370e | ||
![]() |
882d29dd87 | ||
![]() |
ee373e7f19 | ||
![]() |
8d72476e2b | ||
![]() |
02756aa8ba | ||
![]() |
072dfb9e4e | ||
![]() |
0636c39bb1 | ||
![]() |
a2e623c011 | ||
![]() |
aa79dd6895 | ||
![]() |
60cad2caed | ||
![]() |
114c9c36b1 | ||
![]() |
fd5bc65cc8 | ||
![]() |
e041863905 | ||
![]() |
0a05123a6c | ||
![]() |
2afe316721 | ||
![]() |
7e69565fe6 | ||
![]() |
ccae144d62 | ||
![]() |
5d5ca32fa1 | ||
![]() |
52b8dad8ec | ||
![]() |
cc684e330b | ||
![]() |
85c6749216 | ||
![]() |
30e5e8aca5 | ||
![]() |
b900a6b42f | ||
![]() |
15780a1ea0 | ||
![]() |
92ada7cc52 | ||
![]() |
53ca4761cc | ||
![]() |
52cfa39716 | ||
![]() |
b3bad17d1a | ||
![]() |
feaaf1dbea | ||
![]() |
82bf227e91 | ||
![]() |
8807a2dfc4 | ||
![]() |
bcb38217c4 | ||
![]() |
af32f9fdda | ||
![]() |
357d5de5b9 | ||
![]() |
0501f02b06 | ||
![]() |
689f9faba4 | ||
![]() |
82686bdcaa | ||
![]() |
14b1d089b6 | ||
![]() |
a296239bdd | ||
![]() |
0b0896cdd2 | ||
![]() |
2d3e956ae0 | ||
![]() |
36b7c06975 | ||
![]() |
42182852f5 | ||
![]() |
560b79cbff | ||
![]() |
a6d799d705 | ||
![]() |
64aecc6720 | ||
![]() |
8ac40b4dea | ||
![]() |
43b8fe1cd0 | ||
![]() |
39d764ed58 | ||
![]() |
a6ebe229e3 | ||
![]() |
5c914f204a | ||
![]() |
8876e58f34 | ||
![]() |
7321a84d4c | ||
![]() |
bb11c28246 | ||
![]() |
8d9f136d06 | ||
![]() |
00b4e083fd | ||
![]() |
4cfe3df1f5 | ||
![]() |
8f2d60ec26 | ||
![]() |
123b23fa95 | ||
![]() |
423a5d54a1 | ||
![]() |
8bbf6bcf17 | ||
![]() |
ea46f5e0e5 | ||
![]() |
7f6c848242 | ||
![]() |
559d50138f | ||
![]() |
11d8cdc6ad | ||
![]() |
e49978dafe | ||
![]() |
e1d9e533b5 | ||
![]() |
f946dd7198 | ||
![]() |
1702c8c4bf | ||
![]() |
afda1385bd | ||
![]() |
fec38ca4ed | ||
![]() |
ec1edeb5fa | ||
![]() |
b0ec114685 | ||
![]() |
c92da5a605 | ||
![]() |
06e2dd037e | ||
![]() |
34f0a19309 | ||
![]() |
772e3c07b4 | ||
![]() |
360ff3cf58 | ||
![]() |
5dfe910023 | ||
![]() |
91b73acb19 | ||
![]() |
87d3af6475 | ||
![]() |
98c1509f34 | ||
![]() |
98939a05b6 | ||
![]() |
d28134b8f3 | ||
![]() |
8583eba015 | ||
![]() |
5894b98f99 | ||
![]() |
5de3a0ff3d | ||
![]() |
10ca15f3fa | ||
![]() |
da736b31b2 | ||
![]() |
fa9ac569b8 | ||
![]() |
10a10fb834 | ||
![]() |
0f997d0dc3 | ||
![]() |
b0eedd77f6 | ||
![]() |
502aef5aaf | ||
![]() |
9f8cfb1c62 | ||
![]() |
c163b5f7a0 | ||
![]() |
20da8b8f90 | ||
![]() |
ae93dc13ab | ||
![]() |
77e87e6148 | ||
![]() |
a6e700e665 | ||
![]() |
4d7aff707e | ||
![]() |
d137b56a5b | ||
![]() |
7806f3dd4b | ||
![]() |
1e24b3a09e | ||
![]() |
73b979e601 | ||
![]() |
ebae8092cb | ||
![]() |
2e21922eb6 | ||
![]() |
1c3d2b94be | ||
![]() |
48d2335d73 | ||
![]() |
96ea4ae91c | ||
![]() |
7af5726108 | ||
![]() |
69d4646f4e | ||
![]() |
8bd11f3ec2 | ||
![]() |
47a9d527ab | ||
![]() |
d9907c972b | ||
![]() |
1444bfb2c8 | ||
![]() |
14975faa60 | ||
![]() |
3f12464861 | ||
![]() |
de12116417 | ||
![]() |
28b987aec9 | ||
![]() |
fb596f3bb7 | ||
![]() |
84948b39df | ||
![]() |
cf32ad7fe3 | ||
![]() |
ad0e439604 | ||
![]() |
5456583294 | ||
![]() |
f1845cbee8 | ||
![]() |
51cc37b69d | ||
![]() |
ff1b10dca1 | ||
![]() |
ebeb17e2e0 | ||
![]() |
137de5b157 | ||
![]() |
224328e404 | ||
![]() |
1611b9ed80 | ||
![]() |
8a4af56fc6 | ||
![]() |
05cfe06607 | ||
![]() |
b37a68cc8f | ||
![]() |
a2688c872d | ||
![]() |
5b50f99e1e | ||
![]() |
b8994b6130 | ||
![]() |
d7917c584a | ||
![]() |
544d845585 | ||
![]() |
a6efc2d1b8 | ||
![]() |
3189772e07 | ||
![]() |
08a638237d | ||
![]() |
d8cdd1567f | ||
![]() |
cbfb39d1be | ||
![]() |
a4d64c7f49 | ||
![]() |
1e7b6c029c | ||
![]() |
3634d7e97a | ||
![]() |
53d7efea76 | ||
![]() |
002684d693 | ||
![]() |
c038b8aa56 | ||
![]() |
c5f17d45c1 | ||
![]() |
31439046e0 | ||
![]() |
11d0ebc841 | ||
![]() |
cecfdbf72d | ||
![]() |
f0f61f6d0d | ||
![]() |
d68ff71004 | ||
![]() |
591e85e928 | ||
![]() |
c69ed6ea39 | ||
![]() |
55a08fac68 | ||
![]() |
2fc281d01f | ||
![]() |
d326582cab | ||
![]() |
f4c630abb3 | ||
![]() |
c2cccfc585 | ||
![]() |
3c5406b35c | ||
![]() |
5e3225cc44 | ||
![]() |
61118caa86 | ||
![]() |
348be7ec60 | ||
![]() |
3ff55e9680 | ||
![]() |
cbb92dfaf0 | ||
![]() |
019bfef899 | ||
![]() |
0709249f4c | ||
![]() |
89c9c66736 | ||
![]() |
347ed3b93c | ||
![]() |
5b73c3609b | ||
![]() |
eebeb52b29 | ||
![]() |
6ec6cfc767 | ||
![]() |
44181ea836 | ||
![]() |
c80c7bf999 | ||
![]() |
ffa5ebf3f4 | ||
![]() |
926c41bd29 | ||
![]() |
1182301ca7 | ||
![]() |
010fa0b331 | ||
![]() |
4ca7d975af | ||
![]() |
b774111020 | ||
![]() |
78260d890b | ||
![]() |
4b67fefe5a | ||
![]() |
3a8012cbf2 | ||
![]() |
a53cdc5b08 | ||
![]() |
5d20c4fb35 | ||
![]() |
a04549cc75 | ||
![]() |
bc7535bc7f | ||
![]() |
83357f047d | ||
![]() |
b6699c3f07 | ||
![]() |
016bc5ceb3 | ||
![]() |
ed65f7dc34 | ||
![]() |
4d50a2b4d6 | ||
![]() |
7f4301668f | ||
![]() |
29a1bb07e5 | ||
![]() |
99e9a90081 | ||
![]() |
715020e334 | ||
![]() |
2952886010 | ||
![]() |
613e7d2a65 | ||
![]() |
6a2c471077 | ||
![]() |
b79aa05e3b | ||
![]() |
500b5a181d | ||
![]() |
2b8a5406f9 | ||
![]() |
2f35ae90fe | ||
![]() |
0fca32a7aa | ||
![]() |
02c9b66a6c | ||
![]() |
539d4c1030 | ||
![]() |
aa6d1a0c19 | ||
![]() |
777c47acbe | ||
![]() |
5776c3c4c6 | ||
![]() |
0c3d346cb7 | ||
![]() |
1c23bc5670 | ||
![]() |
8ea975d070 | ||
![]() |
6c69aa532e | ||
![]() |
6264c9b2a9 | ||
![]() |
fc92414273 | ||
![]() |
53154d71c3 | ||
![]() |
8cebec9802 | ||
![]() |
0209d1605d | ||
![]() |
c8a0d0aaf9 | ||
![]() |
0cc46efa09 | ||
![]() |
22c268e6c9 | ||
![]() |
dd0514e2cc | ||
![]() |
f6e7d01450 | ||
![]() |
edc540211c | ||
![]() |
2eed3a3cc8 | ||
![]() |
1aa44cc797 | ||
![]() |
37c8fd0eba | ||
![]() |
786aa98da1 | ||
![]() |
413e0853d7 | ||
![]() |
8e4560c42f | ||
![]() |
450ea83495 | ||
![]() |
af8c1d81a3 | ||
![]() |
b589427941 | ||
![]() |
f0fa285f75 | ||
![]() |
a0b5b07010 | ||
![]() |
5c95c2ac23 | ||
![]() |
454dbbc593 | ||
![]() |
c1c6c0bf45 | ||
![]() |
dff2922aa7 | ||
![]() |
f253a058d3 | ||
![]() |
b3c6a33185 | ||
![]() |
31780d0e26 | ||
![]() |
f489ab3147 | ||
![]() |
29cf84c692 | ||
![]() |
e454929558 | ||
![]() |
105f6a6323 | ||
![]() |
8845701719 | ||
![]() |
b7683e3a5d | ||
![]() |
0ee2166cc5 | ||
![]() |
067707e367 | ||
![]() |
8211a33c7f | ||
![]() |
7441052be6 | ||
![]() |
90ccf05f82 | ||
![]() |
112161bd33 | ||
![]() |
5ba4bf35c5 | ||
![]() |
aa93b18c2c | ||
![]() |
ba702545fc | ||
![]() |
436369100d | ||
![]() |
6535bd42e6 | ||
![]() |
64cee65ebc | ||
![]() |
ba544377fb | ||
![]() |
5165148f72 | ||
![]() |
8d970ca70b | ||
![]() |
383b8b8ca9 | ||
![]() |
5ce60a20f2 | ||
![]() |
49131a7d94 | ||
![]() |
d884c5bad1 | ||
![]() |
86bdc0a3ee | ||
![]() |
1a4e245f3e | ||
![]() |
975efcbaee | ||
![]() |
90e1b1fd7d | ||
![]() |
86207c1960 | ||
![]() |
9c62bca11a | ||
![]() |
75d61b33bc | ||
![]() |
3df760b83a | ||
![]() |
e34aa5a3b3 | ||
![]() |
985e4c4154 | ||
![]() |
9598fa8759 | ||
![]() |
ac8173515a | ||
![]() |
944f858021 | ||
![]() |
27a3d9f9aa | ||
![]() |
48fc582f66 | ||
![]() |
81de1028bc | ||
![]() |
850815cb6e | ||
![]() |
c4e7870ac1 | ||
![]() |
4584eccea0 | ||
![]() |
ed3ecd801e | ||
![]() |
b166f13eb5 | ||
![]() |
076944d920 | ||
![]() |
09e20e0bd8 | ||
![]() |
a717831da4 | ||
![]() |
4dfc8f1f0b | ||
![]() |
5b57fe0a1e | ||
![]() |
89bbe14c50 | ||
![]() |
6635b48cd1 | ||
![]() |
675f605d44 | ||
![]() |
6a983d4287 | ||
![]() |
1a159e08af | ||
![]() |
dd030860c4 | ||
![]() |
2d09372434 | ||
![]() |
67912e0032 | ||
![]() |
f3dea9a595 | ||
![]() |
fb7b393278 | ||
![]() |
61e5ec4b1e | ||
![]() |
6f344eab03 | ||
![]() |
41eacc84a0 | ||
![]() |
01b8b3c7d2 | ||
![]() |
8fecd4b4f1 | ||
![]() |
41fc5f2dbe | ||
![]() |
bcfd3d68f5 | ||
![]() |
d3a6461d71 | ||
![]() |
17478fdede | ||
![]() |
4dca00cec8 | ||
![]() |
061d774b99 | ||
![]() |
20469da285 | ||
![]() |
e18e3eba76 | ||
![]() |
de9fcfe348 | ||
![]() |
7e5b06813d | ||
![]() |
1892c8bf97 | ||
![]() |
5e428e7d0d | ||
![]() |
c9777d2659 | ||
![]() |
3aedd213a9 | ||
![]() |
e0c1ea9038 | ||
![]() |
6f88c6a634 | ||
![]() |
58aa573ac2 | ||
![]() |
0ed110b969 | ||
![]() |
b28dea4e10 | ||
![]() |
21f0db692d | ||
![]() |
4d4e08ec1c | ||
![]() |
25074d6c22 | ||
![]() |
0cfc80c4c3 | ||
![]() |
b8bb15fb51 | ||
![]() |
994df5a248 | ||
![]() |
6657b9c73a | ||
![]() |
ba0d04a986 | ||
![]() |
3cb9eb30d3 | ||
![]() |
e0b624e20e | ||
![]() |
c27309edcb | ||
![]() |
3207e61222 | ||
![]() |
3671233089 | ||
![]() |
3a828611e9 | ||
![]() |
8bdcef40e4 | ||
![]() |
91c9e62123 | ||
![]() |
0e3453536e | ||
![]() |
eaff5a1412 | ||
![]() |
216e0d5b91 | ||
![]() |
0965991600 | ||
![]() |
74aa1a4378 | ||
![]() |
5531192151 | ||
![]() |
a620626a33 | ||
![]() |
f13a71c66b | ||
![]() |
3ef3e07a49 | ||
![]() |
76fa8f1838 | ||
![]() |
f2b139ed1f | ||
![]() |
a6e7fcd140 | ||
![]() |
76cf3fcb43 | ||
![]() |
121dd39f9f | ||
![]() |
a263253545 | ||
![]() |
76d6ac4b06 | ||
![]() |
60f20632e2 | ||
![]() |
ae519a247f | ||
![]() |
8de916bcee | ||
![]() |
1631d5f9b9 | ||
![]() |
98c82b899e | ||
![]() |
6d3a1eac3b | ||
![]() |
b8f702a0af | ||
![]() |
43c9825c2a | ||
![]() |
fbf6643607 | ||
![]() |
3f36baa9f4 | ||
![]() |
b0e69a0500 | ||
![]() |
856640b54f | ||
![]() |
76240b3a39 | ||
![]() |
34b3c72e4e | ||
![]() |
c264592d69 | ||
![]() |
1bd06bd0c4 | ||
![]() |
9540ccdf1f | ||
![]() |
98bf13c36b | ||
![]() |
7e76e56387 | ||
![]() |
759d8ac6ee | ||
![]() |
959e8dfe06 | ||
![]() |
7f57b076a6 | ||
![]() |
7144c4212a | ||
![]() |
399a6f0bd1 | ||
![]() |
3d47929968 | ||
![]() |
03919683f9 | ||
![]() |
5cda6c4582 | ||
![]() |
83ed49149c | ||
![]() |
67d990904e | ||
![]() |
f3df90b2bb | ||
![]() |
11e46bd7ae | ||
![]() |
c09a0318b7 | ||
![]() |
fe716ba686 | ||
![]() |
9a97800813 | ||
![]() |
e881f6175a | ||
![]() |
36e77b1059 | ||
![]() |
a9c32ace06 | ||
![]() |
2c5d4daac5 | ||
![]() |
b46343583c | ||
![]() |
816c2b5a79 | ||
![]() |
a78568b7e9 | ||
![]() |
ee5b2a1e51 | ||
![]() |
e4b21c74fc | ||
![]() |
4edcb93dca | ||
![]() |
15f80eea31 | ||
![]() |
81cebb8b79 | ||
![]() |
a4e75b3dfd | ||
![]() |
cddaba8ede | ||
![]() |
49c5f38d3d | ||
![]() |
f8296228f1 | ||
![]() |
930b0c4b8a | ||
![]() |
3d153f7985 | ||
![]() |
ee1d9ec019 | ||
![]() |
614b448a67 | ||
![]() |
a19c9f179d | ||
![]() |
a784b943c1 | ||
![]() |
d202709808 | ||
![]() |
51ff0abb05 | ||
![]() |
492a9e2415 | ||
![]() |
7bf7333d68 | ||
![]() |
c20276e4ae | ||
![]() |
9ca7047d71 | ||
![]() |
ba3b2f1538 | ||
![]() |
b010b7c434 | ||
![]() |
9dc17a2536 | ||
![]() |
5950bf7943 | ||
![]() |
4141c803d8 | ||
![]() |
ba1ba5f0fb | ||
![]() |
51aa7bd321 | ||
![]() |
09b88a4a55 | ||
![]() |
f3481ca28f | ||
![]() |
ba30bad57b | ||
![]() |
ffb1ac674c | ||
![]() |
3be34589e8 | ||
![]() |
d87e615209 | ||
![]() |
92511cff48 | ||
![]() |
7b82159865 | ||
![]() |
52c11dce31 | ||
![]() |
3ba0885a3e | ||
![]() |
023c9d8dd5 | ||
![]() |
4c97a04e2e | ||
![]() |
fb05e1cdf6 | ||
![]() |
ceb4678956 | ||
![]() |
0cb8499b73 | ||
![]() |
4d62ec32e0 | ||
![]() |
75ef718820 | ||
![]() |
c927df3fa1 | ||
![]() |
4700aea951 | ||
![]() |
60cdb821db | ||
![]() |
0ef888cd3e | ||
![]() |
26c777d516 | ||
![]() |
9555339007 | ||
![]() |
2fbe371f53 | ||
![]() |
15181d7811 | ||
![]() |
1edba2110f | ||
![]() |
54d853ebc3 | ||
![]() |
f5cda4cbb1 | ||
![]() |
f9a6348a53 | ||
![]() |
a7ffd9d19c | ||
![]() |
29db322e8f | ||
![]() |
25dc89eb9b | ||
![]() |
716630c0eb | ||
![]() |
4f59b6587f | ||
![]() |
9befdf1d20 | ||
![]() |
75d44c0452 | ||
![]() |
a58a636838 | ||
![]() |
9fdab72dd7 | ||
![]() |
b2a97be7f4 | ||
![]() |
6471c9f478 | ||
![]() |
4a3dc3c0e3 | ||
![]() |
a2318e86bd | ||
![]() |
a9164153d1 | ||
![]() |
8795d38906 | ||
![]() |
8cd44e3630 | ||
![]() |
07e970c7e6 | ||
![]() |
d1aa0d38c5 | ||
![]() |
9e4d0f0be2 | ||
![]() |
cd7638980a | ||
![]() |
f733a5ef0e | ||
![]() |
5da98aa687 | ||
![]() |
0b6f3c66cd | ||
![]() |
a01d9ac558 | ||
![]() |
e46691a0bc | ||
![]() |
732a40e107 | ||
![]() |
29da3ade3c | ||
![]() |
de908d6319 | ||
![]() |
9c9c98ad2e | ||
![]() |
5e0e9fce5d | ||
![]() |
53ec8809cf | ||
![]() |
863779065e | ||
![]() |
0b33dac310 | ||
![]() |
e2bce37720 | ||
![]() |
228b4e426b | ||
![]() |
a4974de937 | ||
![]() |
22f41c9b99 | ||
![]() |
a123c552cd | ||
![]() |
b2172f4f8e | ||
![]() |
dc1d1b6934 | ||
![]() |
67475a7ed7 | ||
![]() |
362ab3e4f9 | ||
![]() |
2aed84d16b | ||
![]() |
5deea1c015 | ||
![]() |
99516f81b1 | ||
![]() |
d6091d5a39 | ||
![]() |
5a47825ece | ||
![]() |
16f66ae794 | ||
![]() |
7ce1d9e9a6 | ||
![]() |
a70183bc80 | ||
![]() |
332737217a | ||
![]() |
bcbe37b716 | ||
![]() |
f393b7449d | ||
![]() |
531308d929 | ||
![]() |
74e564cd46 | ||
![]() |
42eae426df | ||
![]() |
246e09319c | ||
![]() |
f7a3296d8c | ||
![]() |
3e4585c8fd | ||
![]() |
3e84b6e15f | ||
![]() |
d505d1ef4a | ||
![]() |
70b2ae3edf | ||
![]() |
9e5dba197c | ||
![]() |
a61114c38b | ||
![]() |
db98bbc114 | ||
![]() |
e42633140e | ||
![]() |
bd50e31325 | ||
![]() |
b2c0518e6a | ||
![]() |
d82e2718e2 | ||
![]() |
18e377b4ff | ||
![]() |
043b2e9c2e | ||
![]() |
1b593194be | ||
![]() |
35208f368c | ||
![]() |
c788e59365 | ||
![]() |
cb08f4a6a3 | ||
![]() |
adbc603d24 | ||
![]() |
6f81892e6b | ||
![]() |
448be74335 | ||
![]() |
1a5a1a93f6 | ||
![]() |
d917188a46 | ||
![]() |
b4e88ccb28 | ||
![]() |
d916ba1ba1 | ||
![]() |
33af4421f2 | ||
![]() |
95e362c6da | ||
![]() |
c58d983e3b | ||
![]() |
a84c9d1ed9 | ||
![]() |
c6a27f0178 | ||
![]() |
67b6f1ca88 | ||
![]() |
a4ff392503 | ||
![]() |
40f51f506c | ||
![]() |
eeb821f707 | ||
![]() |
47d5566646 | ||
![]() |
90bdfd97a6 | ||
![]() |
b9865f110e | ||
![]() |
07ef612968 | ||
![]() |
019fdc7850 | ||
![]() |
7c382796be | ||
![]() |
b6acb8d0de | ||
![]() |
6adbcb9755 | ||
![]() |
e968089485 | ||
![]() |
c2cd422ac6 | ||
![]() |
36ca4ba63d | ||
![]() |
ed4a1d12b9 | ||
![]() |
a0aa8b4b61 | ||
![]() |
2c059d58d9 | ||
![]() |
cd346d3e22 | ||
![]() |
561d93aa00 | ||
![]() |
ddac197404 | ||
![]() |
0e8e6f19b2 | ||
![]() |
c03e4f9bf0 | ||
![]() |
c3bb1f8166 | ||
![]() |
959a7201b8 | ||
![]() |
6c73d01142 | ||
![]() |
2932ad5677 | ||
![]() |
036bbcc53f | ||
![]() |
6384e46da3 | ||
![]() |
6e2fcc44bd | ||
![]() |
8721fc2d0b | ||
![]() |
c1facbb681 | ||
![]() |
f2c33fa6fd | ||
![]() |
5aae935038 | ||
![]() |
11503177d1 | ||
![]() |
9ab899a660 | ||
![]() |
8937a13e0c | ||
![]() |
19017d4061 | ||
![]() |
f53ac639c6 | ||
![]() |
f71165b556 | ||
![]() |
350a404cb8 | ||
![]() |
827c55741b | ||
![]() |
e0c8c08936 | ||
![]() |
4e397d07ea | ||
![]() |
9eb8794149 | ||
![]() |
dc24110311 | ||
![]() |
b3e72fc37f | ||
![]() |
90076b96df | ||
![]() |
9c339a7227 | ||
![]() |
e7a8b47f1a | ||
![]() |
7ac7a4bc37 | ||
![]() |
a628901dda | ||
![]() |
2ab75dee27 | ||
![]() |
a3f586cdab | ||
![]() |
fcfd87168a | ||
![]() |
95a0e8ab31 | ||
![]() |
0c9caf04de | ||
![]() |
21e8bbf290 | ||
![]() |
3b408d83fe | ||
![]() |
8573552e8c | ||
![]() |
c7235be6e3 | ||
![]() |
1c17d91c53 | ||
![]() |
a070f0dac5 | ||
![]() |
b480283c56 | ||
![]() |
f5ce5e1465 | ||
![]() |
d7db77a0cb | ||
![]() |
346ac30120 | ||
![]() |
07bb51b6b4 | ||
![]() |
bbab9b61dd | ||
![]() |
82e8372f17 | ||
![]() |
e67ed82877 | ||
![]() |
15ac971681 | ||
![]() |
0c21e13012 | ||
![]() |
d5fd72fd0d | ||
![]() |
c7474d077b | ||
![]() |
826b52d26f | ||
![]() |
8c5a2bd6bb | ||
![]() |
25a58453ff | ||
![]() |
00fe865dbe | ||
![]() |
9e9bececa9 | ||
![]() |
90890074b0 | ||
![]() |
31676a3540 | ||
![]() |
6b9e941ee3 | ||
![]() |
802d7fa6d5 | ||
![]() |
3798cb8182 | ||
![]() |
2c5fadbce3 | ||
![]() |
58ece83395 | ||
![]() |
c75c096aa8 | ||
![]() |
ab961dc8b0 | ||
![]() |
6ad47e83b4 | ||
![]() |
241520e66d | ||
![]() |
a13c20f603 | ||
![]() |
db6251ad54 | ||
![]() |
51eb1b81f6 | ||
![]() |
2adc42e43e | ||
![]() |
52cc46a237 | ||
![]() |
a07b4dc038 | ||
![]() |
739a543ea8 | ||
![]() |
01c76c6606 | ||
![]() |
d32f888db1 | ||
![]() |
f7914dbf9a | ||
![]() |
3ff94a009b | ||
![]() |
1aeb3da83f | ||
![]() |
e8e5b46e2b | ||
![]() |
c9d67d4ddf | ||
![]() |
8de5b7f548 | ||
![]() |
9ee0f7b7e0 | ||
![]() |
f1fd4544a3 | ||
![]() |
349eb12fd5 | ||
![]() |
6a8f17de1e | ||
![]() |
b1277b9902 | ||
![]() |
ed3883d21b | ||
![]() |
ea558241e0 | ||
![]() |
61aa2134a4 | ||
![]() |
4eb76e2397 | ||
![]() |
68e575362f | ||
![]() |
aab3bb04cf | ||
![]() |
481d81cb76 | ||
![]() |
c6cb42e4fb | ||
![]() |
2d43a89488 | ||
![]() |
302ea8c260 | ||
![]() |
a1f3462bc0 | ||
![]() |
7476f3ac3b | ||
![]() |
68b64fb610 | ||
![]() |
34b537ee66 | ||
![]() |
7a5dbeb782 | ||
![]() |
6c06918ede | ||
![]() |
ee8f293701 | ||
![]() |
3b4a0225e2 | ||
![]() |
c8e1edaae5 | ||
![]() |
63d3fc9106 | ||
![]() |
5d7324e42d | ||
![]() |
be7b4458f2 | ||
![]() |
7304956e39 | ||
![]() |
c510eec090 | ||
![]() |
1b167a4343 | ||
![]() |
9ab5170197 | ||
![]() |
a00e414faf | ||
![]() |
4c5e19b6c6 | ||
![]() |
ed26604a71 | ||
![]() |
0fbd4bf044 | ||
![]() |
d719e60cb4 | ||
![]() |
0cb9d93d0c | ||
![]() |
f5826b8014 | ||
![]() |
4a47f55639 | ||
![]() |
b884556ed8 | ||
![]() |
c06b0f3d5e | ||
![]() |
68ea60683a | ||
![]() |
6df8c74d5b | ||
![]() |
877e8e970c | ||
![]() |
d56349a2aa | ||
![]() |
67c03ff185 | ||
![]() |
35e00cc2d8 | ||
![]() |
064f6cb6f2 | ||
![]() |
20ab8b4b41 | ||
![]() |
7395d852c3 | ||
![]() |
3ebf898e88 | ||
![]() |
a4c886e4c8 | ||
![]() |
1291dfdead | ||
![]() |
df278aff3e | ||
![]() |
7c510d6f43 | ||
![]() |
7bbcb2f690 | ||
![]() |
ad2695b1b7 | ||
![]() |
9cbf062a70 | ||
![]() |
ec645d9017 | ||
![]() |
0d894c9dbe | ||
![]() |
c6709b89c4 | ||
![]() |
061bebc0d8 | ||
![]() |
802e1d692b | ||
![]() |
dbf33b344c | ||
![]() |
b40228a61d | ||
![]() |
da5a0e8722 | ||
![]() |
200fc02848 | ||
![]() |
7096217d39 | ||
![]() |
f1eb83a013 | ||
![]() |
fec82dbc86 | ||
![]() |
7b1b47a8e6 | ||
![]() |
8b9afce53a | ||
![]() |
137db78b46 | ||
![]() |
a3344c8e5e | ||
![]() |
c173d09c56 | ||
![]() |
cb49a3cfa1 | ||
![]() |
adab80053d | ||
![]() |
f106fb85d4 | ||
![]() |
5fa6d850a2 | ||
![]() |
4adfe93cc5 | ||
![]() |
d1593e6b15 | ||
![]() |
a53cb070e3 | ||
![]() |
452ae49db5 | ||
![]() |
8c5c5b6517 | ||
![]() |
6f44d4d247 | ||
![]() |
d804f86b88 | ||
![]() |
8dee9f844f | ||
![]() |
963ba10012 | ||
![]() |
07645deeb8 | ||
![]() |
c52c82ffc1 | ||
![]() |
d6a03a23a8 | ||
![]() |
e347b0da2b | ||
![]() |
52b1fbbd99 | ||
![]() |
65613f23ba | ||
![]() |
4f92a764f1 | ||
![]() |
6a3a7f3076 | ||
![]() |
63d3a9c5ea | ||
![]() |
2c730f6fc2 | ||
![]() |
df8dae1df4 | ||
![]() |
2e9f1bf0e1 | ||
![]() |
b1e0ccbaa8 | ||
![]() |
bd2abcae37 | ||
![]() |
f1fbd4c7d1 | ||
![]() |
eed22ac4ac | ||
![]() |
176a614899 | ||
![]() |
f858d222f2 | ||
![]() |
16094305bc | ||
![]() |
fbf002bb88 | ||
![]() |
9135fddb0e | ||
![]() |
d88fcf73f1 | ||
![]() |
a950f28762 | ||
![]() |
c629204688 | ||
![]() |
e22f63f231 | ||
![]() |
d256b95768 | ||
![]() |
f530138876 | ||
![]() |
0a39d8f207 | ||
![]() |
6852d1d8c3 | ||
![]() |
a1ad253f17 | ||
![]() |
ffa101872f | ||
![]() |
4d24b4c466 | ||
![]() |
474b8a9716 | ||
![]() |
53261831f1 | ||
![]() |
49e3c9d8e6 | ||
![]() |
1715e4885a | ||
![]() |
eff7cb41d1 | ||
![]() |
7a6f825f0f | ||
![]() |
29afd31dd1 | ||
![]() |
d86b0f1f5f | ||
![]() |
998ac55e19 | ||
![]() |
d6f25d70f1 | ||
![]() |
b02da8eb50 | ||
![]() |
2f52a41054 | ||
![]() |
99c675b2f7 | ||
![]() |
72dce7685e | ||
![]() |
ee8836c442 | ||
![]() |
a1006c373d | ||
![]() |
755c5b3330 | ||
![]() |
ce6aa1e496 | ||
![]() |
6c1fc273f3 | ||
![]() |
aa8b03b415 | ||
![]() |
96ec4abd07 | ||
![]() |
70532b7d6b | ||
![]() |
a4d729f31d | ||
![]() |
fcbc5a3fdd | ||
![]() |
8c0ceb17a2 | ||
![]() |
c2012f9b82 | ||
![]() |
aa2be094ae | ||
![]() |
4d524040bc | ||
![]() |
0fe120ba25 | ||
![]() |
2e7aa150f7 | ||
![]() |
04fac37311 | ||
![]() |
bcb43bb358 | ||
![]() |
89ec4332ec | ||
![]() |
34736de4c0 | ||
![]() |
5f50d597f2 | ||
![]() |
df94f187b9 | ||
![]() |
b92c0df834 | ||
![]() |
d357be38b9 | ||
![]() |
912e296070 | ||
![]() |
35593b33f4 | ||
![]() |
54f3d200d3 | ||
![]() |
3f67e11fab | ||
![]() |
c1de1a190d | ||
![]() |
566dda07ba | ||
![]() |
7a2f4cbfe8 | ||
![]() |
5ac7bde7c9 | ||
![]() |
9b4eab501a | ||
![]() |
ca04d7a208 | ||
![]() |
40a3c12305 | ||
![]() |
3001a770ed | ||
![]() |
2608383c5e | ||
![]() |
3d6312e807 | ||
![]() |
22cd982566 | ||
![]() |
682b112abc | ||
![]() |
e738280547 | ||
![]() |
8265328def | ||
![]() |
231b98a5e1 | ||
![]() |
13e4670c29 | ||
![]() |
d08b6b44ba | ||
![]() |
09b6c2ef15 | ||
![]() |
cc29c1204b | ||
![]() |
94c00f3d4d | ||
![]() |
3c2b73672e | ||
![]() |
23acb0eeb2 | ||
![]() |
bfa4b8c5ab | ||
![]() |
ce75ca04b1 | ||
![]() |
9dba0554a5 | ||
![]() |
59947880f4 | ||
![]() |
61094cf3dc | ||
![]() |
6d00101e9d | ||
![]() |
7a06050cd3 | ||
![]() |
6f9afa68cd | ||
![]() |
c038b90619 | ||
![]() |
9c4fe78260 | ||
![]() |
60dd08573d | ||
![]() |
f5204c61fb | ||
![]() |
9ddeefe39d | ||
![]() |
0293371a1b | ||
![]() |
dd31c6fcb0 | ||
![]() |
6708df7bf0 | ||
![]() |
6d9c46b811 | ||
![]() |
af2c2823a7 | ||
![]() |
b17ecb642b | ||
![]() |
ba12070f7e | ||
![]() |
29b9763d9f | ||
![]() |
270da80bfa | ||
![]() |
701d35d12f | ||
![]() |
2238e8e477 | ||
![]() |
4b08da5538 | ||
![]() |
8a616a5a5f | ||
![]() |
9455d430cb | ||
![]() |
137023dd0c | ||
![]() |
2a45408c4a | ||
![]() |
9e201014f8 | ||
![]() |
0c072a0b46 | ||
![]() |
c11c64fbe0 | ||
![]() |
f022c177db | ||
![]() |
5f10073c95 | ||
![]() |
33ac8b3139 | ||
![]() |
244847591f | ||
![]() |
5abe32d861 | ||
![]() |
9194296de8 | ||
![]() |
6273a91cb7 | ||
![]() |
1ef7acfe92 | ||
![]() |
a0156a926f | ||
![]() |
96998822b5 | ||
![]() |
8215e7a938 | ||
![]() |
f7622f86d9 | ||
![]() |
337e368239 | ||
![]() |
64b6840d8d | ||
![]() |
6e119bb02e | ||
![]() |
2c2e46dbf5 | ||
![]() |
770bc596e1 | ||
![]() |
7534d131d6 | ||
![]() |
7f3c9036ea | ||
![]() |
725111f7cb | ||
![]() |
bf3d6c0c9b | ||
![]() |
b8e8ccdc79 | ||
![]() |
6b80c20bdb | ||
![]() |
eea374fd19 | ||
![]() |
2e8879fa6e | ||
![]() |
f5a07779dd | ||
![]() |
c51f2d4238 | ||
![]() |
45e2738585 | ||
![]() |
b173acfc96 | ||
![]() |
4ebb342fcd | ||
![]() |
8e5ef8538a | ||
![]() |
ff82bf3b07 | ||
![]() |
5147c3c914 | ||
![]() |
fbbbffc5a8 | ||
![]() |
7cfe2a5e65 | ||
![]() |
df2a346b30 | ||
![]() |
270512ab12 | ||
![]() |
eba63ef58b | ||
![]() |
01a9792f05 | ||
![]() |
0491e05833 | ||
![]() |
9a1a5b8785 | ||
![]() |
f3b656b246 | ||
![]() |
53b38d37a9 | ||
![]() |
8f2e4fdf86 | ||
![]() |
11de71b04c | ||
![]() |
19bd66fe74 | ||
![]() |
45771abbd6 | ||
![]() |
573969cd53 | ||
![]() |
34be0bb1a5 | ||
![]() |
2031eca588 | ||
![]() |
6321c3a034 | ||
![]() |
1fda6c4f8c | ||
![]() |
11a4e58fc1 | ||
![]() |
8a35fb3bea | ||
![]() |
e85d67af9f | ||
![]() |
b37fb16dcb | ||
![]() |
1e1c5047f2 | ||
![]() |
b2be099d16 | ||
![]() |
28d8362934 | ||
![]() |
01039d0bff | ||
![]() |
c755c5fd8b | ||
![]() |
5c8e9139d1 | ||
![]() |
56defd9a98 | ||
![]() |
8eb7217580 | ||
![]() |
b2a9d36a7f | ||
![]() |
04f15edb91 | ||
![]() |
4e98a44593 | ||
![]() |
1385ddbb14 | ||
![]() |
7f0c65703a | ||
![]() |
3a6dec8a05 | ||
![]() |
209b12814f | ||
![]() |
f920c5b590 | ||
![]() |
05fc7018f8 | ||
![]() |
a384002724 | ||
![]() |
0260405c68 | ||
![]() |
0537f9689c | ||
![]() |
0c010a1517 | ||
![]() |
0745d0892d | ||
![]() |
5e64f8c44c | ||
![]() |
4a5b8a5bee | ||
![]() |
b3836ed3cb | ||
![]() |
47738cbad7 | ||
![]() |
0a882b6394 | ||
![]() |
612a91110f | ||
![]() |
2337eb5823 | ||
![]() |
9aa9d70ddb | ||
![]() |
231493c93c | ||
![]() |
20a90e3a76 | ||
![]() |
17a2994dbd | ||
![]() |
b554eef43b | ||
![]() |
0066590f98 | ||
![]() |
165a28abae | ||
![]() |
63999e5299 | ||
![]() |
2802ec65c2 | ||
![]() |
b3f56e8b38 | ||
![]() |
5826e4f481 | ||
![]() |
66ee67be03 | ||
![]() |
a7ad2afa5e | ||
![]() |
0f04379d9c | ||
![]() |
7e4d335943 | ||
![]() |
26c07054a1 | ||
![]() |
843d9d0b39 | ||
![]() |
4ac210c16a | ||
![]() |
02703c74a4 | ||
![]() |
ef428d5681 | ||
![]() |
afbe674edb | ||
![]() |
f42e6d24f2 | ||
![]() |
449bd384ed | ||
![]() |
3eeaab4bed | ||
![]() |
57eb1d3250 | ||
![]() |
b4f5e5c959 | ||
![]() |
0d2848b3ba | ||
![]() |
e84b663a93 | ||
![]() |
d85185217b | ||
![]() |
8f3bdc72d0 | ||
![]() |
7d368fcbd8 | ||
![]() |
2bd2cd9b78 | ||
![]() |
c83101248a | ||
![]() |
8d3509b937 | ||
![]() |
1875e6db29 | ||
![]() |
0962fbbf98 | ||
![]() |
cbdac46d58 | ||
![]() |
d2e0c81720 | ||
![]() |
109080ae48 | ||
![]() |
31efffbdba | ||
![]() |
aaa5dc614f | ||
![]() |
8be97c01d1 | ||
![]() |
9e1a112336 | ||
![]() |
4e28f13209 | ||
![]() |
53a20bfd94 | ||
![]() |
a28062338c | ||
![]() |
1c2f1fe505 | ||
![]() |
14365bd820 | ||
![]() |
a51a97262d | ||
![]() |
45d8574b93 | ||
![]() |
417f8973ff | ||
![]() |
b3b72cd92c | ||
![]() |
bb00084863 | ||
![]() |
db22e5faa6 | ||
![]() |
55d03c3179 | ||
![]() |
7e0a494f13 | ||
![]() |
83e68987b3 | ||
![]() |
53bb3bee34 | ||
![]() |
c9edf6fe98 | ||
![]() |
14cc0aaf7b | ||
![]() |
2f3c39bc62 | ||
![]() |
c5de8b2a27 | ||
![]() |
a4022932ee | ||
![]() |
0e3b6b70df | ||
![]() |
c49a0aa08d | ||
![]() |
5503b6a352 | ||
![]() |
60021d9165 | ||
![]() |
97b708910a | ||
![]() |
2f6ebed1dc | ||
![]() |
156f657209 | ||
![]() |
816f74d1c7 | ||
![]() |
ec14c80c7c | ||
![]() |
543b4ecc13 | ||
![]() |
1110cea007 | ||
![]() |
0ed64ce310 | ||
![]() |
0e441bc2be | ||
![]() |
d996a9af2b | ||
![]() |
ab6cf1b8a2 | ||
![]() |
c25f2f1cbf | ||
![]() |
62526671e9 | ||
![]() |
88ebf53577 | ||
![]() |
a41b0aade2 | ||
![]() |
02c31fa461 | ||
![]() |
5df70a9e21 | ||
![]() |
cbe52c3166 | ||
![]() |
7858cc03da | ||
![]() |
bbada33271 | ||
![]() |
f5d51a9362 | ||
![]() |
0fc6b2c9e2 | ||
![]() |
7a5ad5d5a1 | ||
![]() |
44eff497e8 | ||
![]() |
8b452002e8 | ||
![]() |
e442c36252 | ||
![]() |
50ec3951dc | ||
![]() |
11cd239707 | ||
![]() |
f6098f2dda | ||
![]() |
857c6092b6 | ||
![]() |
eef468e330 | ||
![]() |
4bd46774bb | ||
![]() |
283c3e2437 | ||
![]() |
306aae6cee | ||
![]() |
edb0600583 | ||
![]() |
ac86d923fc | ||
![]() |
fbd63d0784 | ||
![]() |
78ebeee2c4 | ||
![]() |
55805fd2d0 | ||
![]() |
7ebd220a8f | ||
![]() |
e8a1f6d190 | ||
![]() |
034bae10fc | ||
![]() |
a7c924c041 | ||
![]() |
27b762af60 | ||
![]() |
b764ab9537 | ||
![]() |
a761b89d2f | ||
![]() |
a136862afe | ||
![]() |
f0747cd950 | ||
![]() |
21ac2b964b | ||
![]() |
79e1dd65ab | ||
![]() |
13e393607b | ||
![]() |
052ec89927 | ||
![]() |
2073d95fb4 | ||
![]() |
cbed917fee | ||
![]() |
dffdb56b7f | ||
![]() |
a78c0632ed | ||
![]() |
8fa6a40be2 | ||
![]() |
4b5598682a | ||
![]() |
e9f5428d3a | ||
![]() |
34f0b26424 | ||
![]() |
cd27b13b1d | ||
![]() |
3ecbd099eb | ||
![]() |
e43d03e30e | ||
![]() |
d1acb9b44f | ||
![]() |
acd1c4b5af | ||
![]() |
40808cedc1 | ||
![]() |
51054a1b39 | ||
![]() |
e774a3299e | ||
![]() |
99febc8b9a | ||
![]() |
1ce8efbdda | ||
![]() |
0b0a60d861 | ||
![]() |
9e5b378081 | ||
![]() |
7ed876533a | ||
![]() |
b2d91a6913 | ||
![]() |
ce074604c4 | ||
![]() |
19ac190252 | ||
![]() |
02c5ddf91e | ||
![]() |
1aaeaf8a3d | ||
![]() |
5d6c4985d1 | ||
![]() |
b615ad90c8 | ||
![]() |
c7aaf3918d | ||
![]() |
d51204f1b1 | ||
![]() |
b3f6325988 | ||
![]() |
3129acbd83 | ||
![]() |
12f89d32b5 | ||
![]() |
1d42741a19 | ||
![]() |
88737991d2 | ||
![]() |
75c00536ba | ||
![]() |
63d740752f | ||
![]() |
6e04afb8c5 | ||
![]() |
165fca51e0 | ||
![]() |
db6b4e3791 | ||
![]() |
20a85e9f69 | ||
![]() |
2a6144a1b6 | ||
![]() |
f8bc3e1bd8 | ||
![]() |
5b737a0731 | ||
![]() |
6e0ef10915 | ||
![]() |
7017605dce | ||
![]() |
b29228836a | ||
![]() |
188b05792f | ||
![]() |
575901e537 | ||
![]() |
2333d65880 | ||
![]() |
ffd1df0579 |
440
apps/genpkey.c
Normal file
440
apps/genpkey.c
Normal file
@@ -0,0 +1,440 @@
|
||||
/* apps/genpkey.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
|
||||
static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
|
||||
const char *file, ENGINE *e);
|
||||
static int genpkey_cb(EVP_PKEY_CTX *ctx);
|
||||
|
||||
#define PROG genpkey_main
|
||||
|
||||
int MAIN(int, char **);
|
||||
|
||||
int MAIN(int argc, char **argv)
|
||||
{
|
||||
ENGINE *e = NULL;
|
||||
char **args, *outfile = NULL;
|
||||
char *passarg = NULL;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
int outformat;
|
||||
int text = 0;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
char *pass = NULL;
|
||||
int badarg = 0;
|
||||
int ret = 1, rv;
|
||||
|
||||
int do_param = 0;
|
||||
|
||||
if (bio_err == NULL)
|
||||
bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
|
||||
|
||||
if (!load_config(bio_err, NULL))
|
||||
goto end;
|
||||
|
||||
outformat=FORMAT_PEM;
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
args = argv + 1;
|
||||
while (!badarg && *args && *args[0] == '-')
|
||||
{
|
||||
if (!strcmp(*args,"-outform"))
|
||||
{
|
||||
if (args[1])
|
||||
{
|
||||
args++;
|
||||
outformat=str2fmt(*args);
|
||||
}
|
||||
else badarg = 1;
|
||||
}
|
||||
else if (!strcmp(*args,"-pass"))
|
||||
{
|
||||
if (!args[1]) goto bad;
|
||||
passarg= *(++args);
|
||||
}
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
else if (strcmp(*args,"-engine") == 0)
|
||||
{
|
||||
if (!args[1])
|
||||
goto bad;
|
||||
e = setup_engine(bio_err, *(++args), 0);
|
||||
}
|
||||
#endif
|
||||
else if (!strcmp (*args, "-paramfile"))
|
||||
{
|
||||
if (!args[1])
|
||||
goto bad;
|
||||
args++;
|
||||
if (do_param == 1)
|
||||
goto bad;
|
||||
if (!init_keygen_file(bio_err, &ctx, *args, e))
|
||||
goto end;
|
||||
}
|
||||
else if (!strcmp (*args, "-out"))
|
||||
{
|
||||
if (args[1])
|
||||
{
|
||||
args++;
|
||||
outfile = *args;
|
||||
}
|
||||
else badarg = 1;
|
||||
}
|
||||
else if (strcmp(*args,"-algorithm") == 0)
|
||||
{
|
||||
if (!args[1])
|
||||
goto bad;
|
||||
if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
|
||||
goto end;
|
||||
}
|
||||
else if (strcmp(*args,"-pkeyopt") == 0)
|
||||
{
|
||||
if (!args[1])
|
||||
goto bad;
|
||||
if (!ctx)
|
||||
{
|
||||
BIO_puts(bio_err, "No keytype specified\n");
|
||||
goto bad;
|
||||
}
|
||||
else if (pkey_ctrl_string(ctx, *(++args)) <= 0)
|
||||
{
|
||||
BIO_puts(bio_err, "parameter setting error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else if (strcmp(*args,"-genparam") == 0)
|
||||
{
|
||||
if (ctx)
|
||||
goto bad;
|
||||
do_param = 1;
|
||||
}
|
||||
else if (strcmp(*args,"-text") == 0)
|
||||
text=1;
|
||||
else
|
||||
{
|
||||
cipher = EVP_get_cipherbyname(*args + 1);
|
||||
if (!cipher)
|
||||
{
|
||||
BIO_printf(bio_err, "Unknown cipher %s\n",
|
||||
*args + 1);
|
||||
badarg = 1;
|
||||
}
|
||||
if (do_param == 1)
|
||||
badarg = 1;
|
||||
}
|
||||
args++;
|
||||
}
|
||||
|
||||
if (!ctx)
|
||||
badarg = 1;
|
||||
|
||||
if (badarg)
|
||||
{
|
||||
bad:
|
||||
BIO_printf(bio_err, "Usage: genpkey [options]\n");
|
||||
BIO_printf(bio_err, "where options may be\n");
|
||||
BIO_printf(bio_err, "-out file output file\n");
|
||||
BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
|
||||
BIO_printf(bio_err, "-pass arg output file pass phrase source\n");
|
||||
BIO_printf(bio_err, "-<cipher> use cipher <cipher> to encrypt the key\n");
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
|
||||
#endif
|
||||
BIO_printf(bio_err, "-paramfile file parameters file\n");
|
||||
BIO_printf(bio_err, "-algorithm alg the public key algorithm\n");
|
||||
BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n"
|
||||
" to value <value>\n");
|
||||
BIO_printf(bio_err, "-genparam generate parameters, not key\n");
|
||||
BIO_printf(bio_err, "-text print the in text\n");
|
||||
BIO_printf(bio_err, "NB: options order may be important! See the manual page.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
|
||||
{
|
||||
BIO_puts(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (outfile)
|
||||
{
|
||||
if (!(out = BIO_new_file (outfile, "wb")))
|
||||
{
|
||||
BIO_printf(bio_err,
|
||||
"Can't open output file %s\n", outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out = BIO_new_fp (stdout, BIO_NOCLOSE);
|
||||
#ifdef OPENSSL_SYS_VMS
|
||||
{
|
||||
BIO *tmpbio = BIO_new(BIO_f_linebuffer());
|
||||
out = BIO_push(tmpbio, out);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
|
||||
EVP_PKEY_CTX_set_app_data(ctx, bio_err);
|
||||
|
||||
if (do_param)
|
||||
{
|
||||
if (EVP_PKEY_paramgen(ctx, &pkey) <= 0)
|
||||
{
|
||||
BIO_puts(bio_err, "Error generating parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
|
||||
{
|
||||
BIO_puts(bio_err, "Error generating key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_param)
|
||||
rv = PEM_write_bio_Parameters(out, pkey);
|
||||
else if (outformat == FORMAT_PEM)
|
||||
rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
|
||||
NULL, pass);
|
||||
else if (outformat == FORMAT_ASN1)
|
||||
rv = i2d_PrivateKey_bio(out, pkey);
|
||||
else
|
||||
{
|
||||
BIO_printf(bio_err, "Bad format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (rv <= 0)
|
||||
{
|
||||
BIO_puts(bio_err, "Error writing key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
|
||||
if (text)
|
||||
{
|
||||
if (do_param)
|
||||
rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
|
||||
else
|
||||
rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
|
||||
|
||||
if (rv <= 0)
|
||||
{
|
||||
BIO_puts(bio_err, "Error printing key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
if (pkey)
|
||||
EVP_PKEY_free(pkey);
|
||||
if (ctx)
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
if (out)
|
||||
BIO_free_all(out);
|
||||
BIO_free(in);
|
||||
if (pass)
|
||||
OPENSSL_free(pass);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
|
||||
const char *file, ENGINE *e)
|
||||
{
|
||||
BIO *pbio;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
if (*pctx)
|
||||
{
|
||||
BIO_puts(err, "Parameters already set!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pbio = BIO_new_file(file, "r");
|
||||
if (!pbio)
|
||||
{
|
||||
BIO_printf(err, "Can't open parameter file %s\n", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey = PEM_read_bio_Parameters(pbio, NULL);
|
||||
BIO_free(pbio);
|
||||
|
||||
if (!pkey)
|
||||
{
|
||||
BIO_printf(bio_err, "Error reading parameter file %s\n", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx = EVP_PKEY_CTX_new(pkey, e);
|
||||
if (!ctx)
|
||||
goto err;
|
||||
if (EVP_PKEY_keygen_init(ctx) <= 0)
|
||||
goto err;
|
||||
EVP_PKEY_free(pkey);
|
||||
*pctx = ctx;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BIO_puts(err, "Error initializing context\n");
|
||||
ERR_print_errors(err);
|
||||
if (ctx)
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
if (pkey)
|
||||
EVP_PKEY_free(pkey);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
|
||||
const char *algname, ENGINE *e, int do_param)
|
||||
{
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ENGINE *tmpeng = NULL;
|
||||
int pkey_id;
|
||||
|
||||
if (*pctx)
|
||||
{
|
||||
BIO_puts(err, "Algorithm already set!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (!ameth && e)
|
||||
ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
|
||||
#endif
|
||||
|
||||
if (!ameth)
|
||||
{
|
||||
BIO_printf(bio_err, "Algorithm %s not found\n", algname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (tmpeng)
|
||||
ENGINE_finish(tmpeng);
|
||||
#endif
|
||||
ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
|
||||
|
||||
if (!ctx)
|
||||
goto err;
|
||||
if (do_param)
|
||||
{
|
||||
if (EVP_PKEY_paramgen_init(ctx) <= 0)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EVP_PKEY_keygen_init(ctx) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
*pctx = ctx;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BIO_printf(err, "Error initializing %s context\n", algname);
|
||||
ERR_print_errors(err);
|
||||
if (ctx)
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int genpkey_cb(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
char c='*';
|
||||
BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
|
||||
int p;
|
||||
p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
|
||||
if (p == 0) c='.';
|
||||
if (p == 1) c='+';
|
||||
if (p == 2) c='*';
|
||||
if (p == 3) c='\n';
|
||||
BIO_write(b,&c,1);
|
||||
(void)BIO_flush(b);
|
||||
#ifdef LINT
|
||||
p=n;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
284
apps/pkey.c
Normal file
284
apps/pkey.c
Normal file
@@ -0,0 +1,284 @@
|
||||
/* apps/pkey.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#define PROG pkey_main
|
||||
|
||||
int MAIN(int, char **);
|
||||
|
||||
int MAIN(int argc, char **argv)
|
||||
{
|
||||
ENGINE *e = NULL;
|
||||
char **args, *infile = NULL, *outfile = NULL;
|
||||
char *passargin = NULL, *passargout = NULL;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
int informat, outformat;
|
||||
int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
char *passin = NULL, *passout = NULL;
|
||||
int badarg = 0;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
char *engine=NULL;
|
||||
#endif
|
||||
int ret = 1;
|
||||
|
||||
if (bio_err == NULL)
|
||||
bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
|
||||
|
||||
if (!load_config(bio_err, NULL))
|
||||
goto end;
|
||||
|
||||
informat=FORMAT_PEM;
|
||||
outformat=FORMAT_PEM;
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
args = argv + 1;
|
||||
while (!badarg && *args && *args[0] == '-')
|
||||
{
|
||||
if (!strcmp(*args,"-inform"))
|
||||
{
|
||||
if (args[1])
|
||||
{
|
||||
args++;
|
||||
informat=str2fmt(*args);
|
||||
}
|
||||
else badarg = 1;
|
||||
}
|
||||
else if (!strcmp(*args,"-outform"))
|
||||
{
|
||||
if (args[1])
|
||||
{
|
||||
args++;
|
||||
outformat=str2fmt(*args);
|
||||
}
|
||||
else badarg = 1;
|
||||
}
|
||||
else if (!strcmp(*args,"-passin"))
|
||||
{
|
||||
if (!args[1]) goto bad;
|
||||
passargin= *(++args);
|
||||
}
|
||||
else if (!strcmp(*args,"-passout"))
|
||||
{
|
||||
if (!args[1]) goto bad;
|
||||
passargout= *(++args);
|
||||
}
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
else if (strcmp(*args,"-engine") == 0)
|
||||
{
|
||||
if (!args[1]) goto bad;
|
||||
engine= *(++args);
|
||||
}
|
||||
#endif
|
||||
else if (!strcmp (*args, "-in"))
|
||||
{
|
||||
if (args[1])
|
||||
{
|
||||
args++;
|
||||
infile = *args;
|
||||
}
|
||||
else badarg = 1;
|
||||
}
|
||||
else if (!strcmp (*args, "-out"))
|
||||
{
|
||||
if (args[1])
|
||||
{
|
||||
args++;
|
||||
outfile = *args;
|
||||
}
|
||||
else badarg = 1;
|
||||
}
|
||||
else if (strcmp(*args,"-pubin") == 0)
|
||||
{
|
||||
pubin=1;
|
||||
pubout=1;
|
||||
pubtext=1;
|
||||
}
|
||||
else if (strcmp(*args,"-pubout") == 0)
|
||||
pubout=1;
|
||||
else if (strcmp(*args,"-text_pub") == 0)
|
||||
{
|
||||
pubtext=1;
|
||||
text=1;
|
||||
}
|
||||
else if (strcmp(*args,"-text") == 0)
|
||||
text=1;
|
||||
else if (strcmp(*args,"-noout") == 0)
|
||||
noout=1;
|
||||
else
|
||||
{
|
||||
cipher = EVP_get_cipherbyname(*args + 1);
|
||||
if (!cipher)
|
||||
{
|
||||
BIO_printf(bio_err, "Unknown cipher %s\n",
|
||||
*args + 1);
|
||||
badarg = 1;
|
||||
}
|
||||
}
|
||||
args++;
|
||||
}
|
||||
|
||||
if (badarg)
|
||||
{
|
||||
bad:
|
||||
BIO_printf(bio_err, "Usage pkey [options]\n");
|
||||
BIO_printf(bio_err, "where options are\n");
|
||||
BIO_printf(bio_err, "-in file input file\n");
|
||||
BIO_printf(bio_err, "-inform X input format (DER or PEM)\n");
|
||||
BIO_printf(bio_err, "-passin arg input file pass phrase source\n");
|
||||
BIO_printf(bio_err, "-outform X output format (DER or PEM)\n");
|
||||
BIO_printf(bio_err, "-out file output file\n");
|
||||
BIO_printf(bio_err, "-passout arg output file pass phrase source\n");
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
e = setup_engine(bio_err, engine, 0);
|
||||
#endif
|
||||
|
||||
if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
|
||||
{
|
||||
BIO_printf(bio_err, "Error getting passwords\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (outfile)
|
||||
{
|
||||
if (!(out = BIO_new_file (outfile, "wb")))
|
||||
{
|
||||
BIO_printf(bio_err,
|
||||
"Can't open output file %s\n", outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out = BIO_new_fp (stdout, BIO_NOCLOSE);
|
||||
#ifdef OPENSSL_SYS_VMS
|
||||
{
|
||||
BIO *tmpbio = BIO_new(BIO_f_linebuffer());
|
||||
out = BIO_push(tmpbio, out);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pubin)
|
||||
pkey = load_pubkey(bio_err, infile, informat, 1,
|
||||
passin, e, "Public Key");
|
||||
else
|
||||
pkey = load_key(bio_err, infile, informat, 1,
|
||||
passin, e, "key");
|
||||
if (!pkey)
|
||||
goto end;
|
||||
|
||||
if (!noout)
|
||||
{
|
||||
if (outformat == FORMAT_PEM)
|
||||
{
|
||||
if (pubout)
|
||||
PEM_write_bio_PUBKEY(out,pkey);
|
||||
else
|
||||
PEM_write_bio_PrivateKey(out, pkey, cipher,
|
||||
NULL, 0, NULL, passout);
|
||||
}
|
||||
else if (outformat == FORMAT_ASN1)
|
||||
{
|
||||
if (pubout)
|
||||
i2d_PUBKEY_bio(out, pkey);
|
||||
else
|
||||
i2d_PrivateKey_bio(out, pkey);
|
||||
}
|
||||
else
|
||||
{
|
||||
BIO_printf(bio_err, "Bad format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (text)
|
||||
{
|
||||
if (pubtext)
|
||||
EVP_PKEY_print_public(out, pkey, 0, NULL);
|
||||
else
|
||||
EVP_PKEY_print_private(out, pkey, 0, NULL);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free_all(out);
|
||||
BIO_free(in);
|
||||
if (passin)
|
||||
OPENSSL_free(passin);
|
||||
if (passout)
|
||||
OPENSSL_free(passout);
|
||||
|
||||
return ret;
|
||||
}
|
201
apps/pkeyparam.c
Normal file
201
apps/pkeyparam.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/* apps/pkeyparam.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#define PROG pkeyparam_main
|
||||
|
||||
int MAIN(int, char **);
|
||||
|
||||
int MAIN(int argc, char **argv)
|
||||
{
|
||||
char **args, *infile = NULL, *outfile = NULL;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
int text = 0, noout = 0;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
int badarg = 0;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE *e = NULL;
|
||||
char *engine=NULL;
|
||||
#endif
|
||||
int ret = 1;
|
||||
|
||||
if (bio_err == NULL)
|
||||
bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
|
||||
|
||||
if (!load_config(bio_err, NULL))
|
||||
goto end;
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
args = argv + 1;
|
||||
while (!badarg && *args && *args[0] == '-')
|
||||
{
|
||||
if (!strcmp (*args, "-in"))
|
||||
{
|
||||
if (args[1])
|
||||
{
|
||||
args++;
|
||||
infile = *args;
|
||||
}
|
||||
else badarg = 1;
|
||||
}
|
||||
else if (!strcmp (*args, "-out"))
|
||||
{
|
||||
if (args[1])
|
||||
{
|
||||
args++;
|
||||
outfile = *args;
|
||||
}
|
||||
else badarg = 1;
|
||||
}
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
else if (strcmp(*args,"-engine") == 0)
|
||||
{
|
||||
if (!args[1]) goto bad;
|
||||
engine= *(++args);
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (strcmp(*args,"-text") == 0)
|
||||
text=1;
|
||||
else if (strcmp(*args,"-noout") == 0)
|
||||
noout=1;
|
||||
args++;
|
||||
}
|
||||
|
||||
if (badarg)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
bad:
|
||||
#endif
|
||||
BIO_printf(bio_err, "Usage pkeyparam [options]\n");
|
||||
BIO_printf(bio_err, "where options are\n");
|
||||
BIO_printf(bio_err, "-in file input file\n");
|
||||
BIO_printf(bio_err, "-out file output file\n");
|
||||
BIO_printf(bio_err, "-text print parameters as text\n");
|
||||
BIO_printf(bio_err, "-noout don't output encoded parameters\n");
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
e = setup_engine(bio_err, engine, 0);
|
||||
#endif
|
||||
|
||||
if (infile)
|
||||
{
|
||||
if (!(in = BIO_new_file (infile, "r")))
|
||||
{
|
||||
BIO_printf(bio_err,
|
||||
"Can't open input file %s\n", infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
in = BIO_new_fp (stdin, BIO_NOCLOSE);
|
||||
|
||||
if (outfile)
|
||||
{
|
||||
if (!(out = BIO_new_file (outfile, "w")))
|
||||
{
|
||||
BIO_printf(bio_err,
|
||||
"Can't open output file %s\n", outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out = BIO_new_fp (stdout, BIO_NOCLOSE);
|
||||
#ifdef OPENSSL_SYS_VMS
|
||||
{
|
||||
BIO *tmpbio = BIO_new(BIO_f_linebuffer());
|
||||
out = BIO_push(tmpbio, out);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
pkey = PEM_read_bio_Parameters(in, NULL);
|
||||
if (!pkey)
|
||||
{
|
||||
BIO_printf(bio_err, "Error reading paramters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!noout)
|
||||
PEM_write_bio_Parameters(out,pkey);
|
||||
|
||||
if (text)
|
||||
EVP_PKEY_print_params(out, pkey, 0, NULL);
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free_all(out);
|
||||
BIO_free(in);
|
||||
|
||||
return ret;
|
||||
}
|
570
apps/pkeyutl.c
Normal file
570
apps/pkeyutl.c
Normal file
@@ -0,0 +1,570 @@
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "apps.h"
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#define KEY_PRIVKEY 1
|
||||
#define KEY_PUBKEY 2
|
||||
#define KEY_CERT 3
|
||||
|
||||
static void usage(void);
|
||||
|
||||
#undef PROG
|
||||
|
||||
#define PROG pkeyutl_main
|
||||
|
||||
static EVP_PKEY_CTX *init_ctx(int *pkeysize,
|
||||
char *keyfile, int keyform, int key_type,
|
||||
char *passargin, int pkey_op, ENGINE *e);
|
||||
|
||||
static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
|
||||
const char *file);
|
||||
|
||||
static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
|
||||
unsigned char *out, size_t *poutlen,
|
||||
unsigned char *in, size_t inlen);
|
||||
|
||||
int MAIN(int argc, char **);
|
||||
|
||||
int MAIN(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
char *infile = NULL, *outfile = NULL, *sigfile = NULL;
|
||||
ENGINE *e = NULL;
|
||||
int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
|
||||
int keyform = FORMAT_PEM, peerform = FORMAT_PEM;
|
||||
char badarg = 0, rev = 0;
|
||||
char hexdump = 0, asn1parse = 0;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
char *passargin = NULL;
|
||||
int keysize = -1;
|
||||
|
||||
unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
|
||||
size_t buf_outlen;
|
||||
int buf_inlen = 0, siglen = -1;
|
||||
|
||||
int ret = 1, rv = -1;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||
|
||||
if (!load_config(bio_err, NULL))
|
||||
goto end;
|
||||
ERR_load_crypto_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
while(argc >= 1)
|
||||
{
|
||||
if (!strcmp(*argv,"-in"))
|
||||
{
|
||||
if (--argc < 1) badarg = 1;
|
||||
infile= *(++argv);
|
||||
}
|
||||
else if (!strcmp(*argv,"-out"))
|
||||
{
|
||||
if (--argc < 1) badarg = 1;
|
||||
outfile= *(++argv);
|
||||
}
|
||||
else if (!strcmp(*argv,"-sigfile"))
|
||||
{
|
||||
if (--argc < 1) badarg = 1;
|
||||
sigfile= *(++argv);
|
||||
}
|
||||
else if(!strcmp(*argv, "-inkey"))
|
||||
{
|
||||
if (--argc < 1)
|
||||
badarg = 1;
|
||||
else
|
||||
{
|
||||
ctx = init_ctx(&keysize,
|
||||
*(++argv), keyform, key_type,
|
||||
passargin, pkey_op, e);
|
||||
if (!ctx)
|
||||
{
|
||||
BIO_puts(bio_err,
|
||||
"Error initializing context\n");
|
||||
ERR_print_errors(bio_err);
|
||||
badarg = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(*argv,"-peerkey"))
|
||||
{
|
||||
if (--argc < 1)
|
||||
badarg = 1;
|
||||
else if (!setup_peer(bio_err, ctx, peerform, *(++argv)))
|
||||
badarg = 1;
|
||||
}
|
||||
else if (!strcmp(*argv,"-passin"))
|
||||
{
|
||||
if (--argc < 1) badarg = 1;
|
||||
passargin= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-peerform") == 0)
|
||||
{
|
||||
if (--argc < 1) badarg = 1;
|
||||
peerform=str2fmt(*(++argv));
|
||||
}
|
||||
else if (strcmp(*argv,"-keyform") == 0)
|
||||
{
|
||||
if (--argc < 1) badarg = 1;
|
||||
keyform=str2fmt(*(++argv));
|
||||
}
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
else if(!strcmp(*argv, "-engine"))
|
||||
{
|
||||
if (--argc < 1)
|
||||
badarg = 1;
|
||||
else
|
||||
e = setup_engine(bio_err, *(++argv), 0);
|
||||
}
|
||||
#endif
|
||||
else if(!strcmp(*argv, "-pubin"))
|
||||
key_type = KEY_PUBKEY;
|
||||
else if(!strcmp(*argv, "-certin"))
|
||||
key_type = KEY_CERT;
|
||||
else if(!strcmp(*argv, "-asn1parse"))
|
||||
asn1parse = 1;
|
||||
else if(!strcmp(*argv, "-hexdump"))
|
||||
hexdump = 1;
|
||||
else if(!strcmp(*argv, "-sign"))
|
||||
pkey_op = EVP_PKEY_OP_SIGN;
|
||||
else if(!strcmp(*argv, "-verify"))
|
||||
pkey_op = EVP_PKEY_OP_VERIFY;
|
||||
else if(!strcmp(*argv, "-verifyrecover"))
|
||||
pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
|
||||
else if(!strcmp(*argv, "-rev"))
|
||||
rev = 1;
|
||||
else if(!strcmp(*argv, "-encrypt"))
|
||||
pkey_op = EVP_PKEY_OP_ENCRYPT;
|
||||
else if(!strcmp(*argv, "-decrypt"))
|
||||
pkey_op = EVP_PKEY_OP_DECRYPT;
|
||||
else if(!strcmp(*argv, "-derive"))
|
||||
pkey_op = EVP_PKEY_OP_DERIVE;
|
||||
else if (strcmp(*argv,"-pkeyopt") == 0)
|
||||
{
|
||||
if (--argc < 1)
|
||||
badarg = 1;
|
||||
else if (!ctx)
|
||||
{
|
||||
BIO_puts(bio_err,
|
||||
"-pkeyopt command before -inkey\n");
|
||||
badarg = 1;
|
||||
}
|
||||
else if (pkey_ctrl_string(ctx, *(++argv)) <= 0)
|
||||
{
|
||||
BIO_puts(bio_err, "parameter setting error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else badarg = 1;
|
||||
if(badarg)
|
||||
{
|
||||
usage();
|
||||
goto end;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!ctx)
|
||||
{
|
||||
usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY))
|
||||
{
|
||||
BIO_puts(bio_err, "Signature file specified for non verify\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY))
|
||||
{
|
||||
BIO_puts(bio_err, "No signature file specified for verify\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* FIXME: seed PRNG only if needed */
|
||||
app_RAND_load_file(NULL, bio_err, 0);
|
||||
|
||||
if (pkey_op != EVP_PKEY_OP_DERIVE)
|
||||
{
|
||||
if(infile)
|
||||
{
|
||||
if(!(in = BIO_new_file(infile, "rb")))
|
||||
{
|
||||
BIO_puts(bio_err,
|
||||
"Error Opening Input File\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
in = BIO_new_fp(stdin, BIO_NOCLOSE);
|
||||
}
|
||||
|
||||
if(outfile)
|
||||
{
|
||||
if(!(out = BIO_new_file(outfile, "wb")))
|
||||
{
|
||||
BIO_printf(bio_err, "Error Creating Output File\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
#ifdef OPENSSL_SYS_VMS
|
||||
{
|
||||
BIO *tmpbio = BIO_new(BIO_f_linebuffer());
|
||||
out = BIO_push(tmpbio, out);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (sigfile)
|
||||
{
|
||||
BIO *sigbio = BIO_new_file(sigfile, "rb");
|
||||
if (!sigbio)
|
||||
{
|
||||
BIO_printf(bio_err, "Can't open signature file %s\n",
|
||||
sigfile);
|
||||
goto end;
|
||||
}
|
||||
siglen = bio_to_mem(&sig, keysize * 10, sigbio);
|
||||
BIO_free(sigbio);
|
||||
if (siglen <= 0)
|
||||
{
|
||||
BIO_printf(bio_err, "Error reading signature data\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (in)
|
||||
{
|
||||
/* Read the input data */
|
||||
buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
|
||||
if(buf_inlen <= 0)
|
||||
{
|
||||
BIO_printf(bio_err, "Error reading input Data\n");
|
||||
exit(1);
|
||||
}
|
||||
if(rev)
|
||||
{
|
||||
size_t i;
|
||||
unsigned char ctmp;
|
||||
size_t l = (size_t)buf_inlen;
|
||||
for(i = 0; i < l/2; i++)
|
||||
{
|
||||
ctmp = buf_in[i];
|
||||
buf_in[i] = buf_in[l - 1 - i];
|
||||
buf_in[l - 1 - i] = ctmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pkey_op == EVP_PKEY_OP_VERIFY)
|
||||
{
|
||||
rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
|
||||
buf_in, (size_t)buf_inlen);
|
||||
if (rv == 0)
|
||||
BIO_puts(out, "Signature Verification Failure\n");
|
||||
else if (rv == 1)
|
||||
BIO_puts(out, "Signature Verified Successfully\n");
|
||||
if (rv >= 0)
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
|
||||
buf_in, (size_t)buf_inlen);
|
||||
if (rv > 0)
|
||||
{
|
||||
buf_out = OPENSSL_malloc(buf_outlen);
|
||||
if (!buf_out)
|
||||
rv = -1;
|
||||
else
|
||||
rv = do_keyop(ctx, pkey_op,
|
||||
buf_out, (size_t *)&buf_outlen,
|
||||
buf_in, (size_t)buf_inlen);
|
||||
}
|
||||
}
|
||||
|
||||
if(rv <= 0)
|
||||
{
|
||||
BIO_printf(bio_err, "Public Key operation error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
if(asn1parse)
|
||||
{
|
||||
if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
else if(hexdump)
|
||||
BIO_dump(out, (char *)buf_out, buf_outlen);
|
||||
else
|
||||
BIO_write(out, buf_out, buf_outlen);
|
||||
|
||||
end:
|
||||
if (ctx)
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
if (buf_in)
|
||||
OPENSSL_free(buf_in);
|
||||
if (buf_out)
|
||||
OPENSSL_free(buf_out);
|
||||
if (sig)
|
||||
OPENSSL_free(sig);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void usage()
|
||||
{
|
||||
BIO_printf(bio_err, "Usage: pkeyutl [options]\n");
|
||||
BIO_printf(bio_err, "-in file input file\n");
|
||||
BIO_printf(bio_err, "-out file output file\n");
|
||||
BIO_printf(bio_err, "-signature file signature file (verify operation only)\n");
|
||||
BIO_printf(bio_err, "-inkey file input key\n");
|
||||
BIO_printf(bio_err, "-keyform arg private key format - default PEM\n");
|
||||
BIO_printf(bio_err, "-pubin input is a public key\n");
|
||||
BIO_printf(bio_err, "-certin input is a certificate carrying a public key\n");
|
||||
BIO_printf(bio_err, "-pkeyopt X:Y public key options\n");
|
||||
BIO_printf(bio_err, "-sign sign with private key\n");
|
||||
BIO_printf(bio_err, "-verify verify with public key\n");
|
||||
BIO_printf(bio_err, "-verifyrecover verify with public key, recover original data\n");
|
||||
BIO_printf(bio_err, "-encrypt encrypt with public key\n");
|
||||
BIO_printf(bio_err, "-decrypt decrypt with private key\n");
|
||||
BIO_printf(bio_err, "-derive derive shared secret\n");
|
||||
BIO_printf(bio_err, "-hexdump hex dump output\n");
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
|
||||
#endif
|
||||
BIO_printf(bio_err, "-passin arg pass phrase source\n");
|
||||
|
||||
}
|
||||
|
||||
static EVP_PKEY_CTX *init_ctx(int *pkeysize,
|
||||
char *keyfile, int keyform, int key_type,
|
||||
char *passargin, int pkey_op, ENGINE *e)
|
||||
{
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
char *passin = NULL;
|
||||
int rv = -1;
|
||||
X509 *x;
|
||||
if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)
|
||||
|| (pkey_op == EVP_PKEY_OP_DERIVE))
|
||||
&& (key_type != KEY_PRIVKEY))
|
||||
{
|
||||
BIO_printf(bio_err, "A private key is needed for this operation\n");
|
||||
goto end;
|
||||
}
|
||||
if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
|
||||
{
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
switch(key_type)
|
||||
{
|
||||
case KEY_PRIVKEY:
|
||||
pkey = load_key(bio_err, keyfile, keyform, 0,
|
||||
passin, e, "Private Key");
|
||||
break;
|
||||
|
||||
case KEY_PUBKEY:
|
||||
pkey = load_pubkey(bio_err, keyfile, keyform, 0,
|
||||
NULL, e, "Public Key");
|
||||
break;
|
||||
|
||||
case KEY_CERT:
|
||||
x = load_cert(bio_err, keyfile, keyform,
|
||||
NULL, e, "Certificate");
|
||||
if(x)
|
||||
{
|
||||
pkey = X509_get_pubkey(x);
|
||||
X509_free(x);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
*pkeysize = EVP_PKEY_size(pkey);
|
||||
|
||||
if (!pkey)
|
||||
goto end;
|
||||
|
||||
ctx = EVP_PKEY_CTX_new(pkey, e);
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
if (!ctx)
|
||||
goto end;
|
||||
|
||||
switch(pkey_op)
|
||||
{
|
||||
case EVP_PKEY_OP_SIGN:
|
||||
rv = EVP_PKEY_sign_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_VERIFY:
|
||||
rv = EVP_PKEY_verify_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_VERIFYRECOVER:
|
||||
rv = EVP_PKEY_verify_recover_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_ENCRYPT:
|
||||
rv = EVP_PKEY_encrypt_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DECRYPT:
|
||||
rv = EVP_PKEY_decrypt_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DERIVE:
|
||||
rv = EVP_PKEY_derive_init(ctx);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rv <= 0)
|
||||
{
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
if (passin)
|
||||
OPENSSL_free(passin);
|
||||
|
||||
return ctx;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
|
||||
const char *file)
|
||||
{
|
||||
EVP_PKEY *peer = NULL;
|
||||
int ret;
|
||||
if (!ctx)
|
||||
{
|
||||
BIO_puts(err, "-peerkey command before -inkey\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key");
|
||||
|
||||
if (!peer)
|
||||
{
|
||||
BIO_printf(bio_err, "Error reading peer key %s\n", file);
|
||||
ERR_print_errors(err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = EVP_PKEY_derive_set_peer(ctx, peer);
|
||||
|
||||
EVP_PKEY_free(peer);
|
||||
if (ret <= 0)
|
||||
ERR_print_errors(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
|
||||
unsigned char *out, size_t *poutlen,
|
||||
unsigned char *in, size_t inlen)
|
||||
{
|
||||
int rv = 0;
|
||||
switch(pkey_op)
|
||||
{
|
||||
case EVP_PKEY_OP_VERIFYRECOVER:
|
||||
rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_SIGN:
|
||||
rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_ENCRYPT:
|
||||
rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DECRYPT:
|
||||
rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DERIVE:
|
||||
rv = EVP_PKEY_derive(ctx, out, poutlen);
|
||||
break;
|
||||
|
||||
}
|
||||
return rv;
|
||||
}
|
195
apps/tsget
Normal file
195
apps/tsget
Normal file
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/perl -w
|
||||
# Written by Zoltan Glozik <zglozik@stones.com>.
|
||||
# Copyright (c) 2002 The OpenTSA Project. All rights reserved.
|
||||
$::version = '$Id: tsget,v 1.1 2006/02/12 23:11:21 ulf Exp $';
|
||||
|
||||
use strict;
|
||||
use IO::Handle;
|
||||
use Getopt::Std;
|
||||
use File::Basename;
|
||||
use WWW::Curl::easy;
|
||||
|
||||
use vars qw(%options);
|
||||
|
||||
# Callback for reading the body.
|
||||
sub read_body {
|
||||
my ($maxlength, $state) = @_;
|
||||
my $return_data = "";
|
||||
my $data_len = length ${$state->{data}};
|
||||
if ($state->{bytes} < $data_len) {
|
||||
$data_len = $data_len - $state->{bytes};
|
||||
$data_len = $maxlength if $data_len > $maxlength;
|
||||
$return_data = substr ${$state->{data}}, $state->{bytes}, $data_len;
|
||||
$state->{bytes} += $data_len;
|
||||
}
|
||||
return $return_data;
|
||||
}
|
||||
|
||||
# Callback for writing the body into a variable.
|
||||
sub write_body {
|
||||
my ($data, $pointer) = @_;
|
||||
${$pointer} .= $data;
|
||||
return length($data);
|
||||
}
|
||||
|
||||
# Initialise a new Curl object.
|
||||
sub create_curl {
|
||||
my $url = shift;
|
||||
|
||||
# Create Curl object.
|
||||
my $curl = WWW::Curl::easy::new();
|
||||
|
||||
# Error-handling related options.
|
||||
$curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
|
||||
$curl->setopt(CURLOPT_FAILONERROR, 1);
|
||||
$curl->setopt(CURLOPT_USERAGENT, "OpenTSA tsget.pl/" . (split / /, $::version)[2]);
|
||||
|
||||
# Options for POST method.
|
||||
$curl->setopt(CURLOPT_UPLOAD, 1);
|
||||
$curl->setopt(CURLOPT_CUSTOMREQUEST, "POST");
|
||||
$curl->setopt(CURLOPT_HTTPHEADER,
|
||||
["Content-Type: application/timestamp-query",
|
||||
"Accept: application/timestamp-reply"]);
|
||||
$curl->setopt(CURLOPT_READFUNCTION, \&read_body);
|
||||
$curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[0]); });
|
||||
|
||||
# Options for getting the result.
|
||||
$curl->setopt(CURLOPT_WRITEFUNCTION, \&write_body);
|
||||
|
||||
# SSL related options.
|
||||
$curl->setopt(CURLOPT_SSLKEYTYPE, "PEM");
|
||||
$curl->setopt(CURLOPT_SSL_VERIFYPEER, 1); # Verify server's certificate.
|
||||
$curl->setopt(CURLOPT_SSL_VERIFYHOST, 2); # Check server's CN.
|
||||
$curl->setopt(CURLOPT_SSLKEY, $options{k}) if defined($options{k});
|
||||
$curl->setopt(CURLOPT_SSLKEYPASSWD, $options{p}) if defined($options{p});
|
||||
$curl->setopt(CURLOPT_SSLCERT, $options{c}) if defined($options{c});
|
||||
$curl->setopt(CURLOPT_CAINFO, $options{C}) if defined($options{C});
|
||||
$curl->setopt(CURLOPT_CAPATH, $options{P}) if defined($options{P});
|
||||
$curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r});
|
||||
$curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g});
|
||||
|
||||
# Setting destination.
|
||||
$curl->setopt(CURLOPT_URL, $url);
|
||||
|
||||
return $curl;
|
||||
}
|
||||
|
||||
# Send a request and returns the body back.
|
||||
sub get_timestamp {
|
||||
my $curl = shift;
|
||||
my $body = shift;
|
||||
my $ts_body;
|
||||
local $::error_buf;
|
||||
|
||||
# Error-handling related options.
|
||||
$curl->setopt(CURLOPT_ERRORBUFFER, "::error_buf");
|
||||
|
||||
# Options for POST method.
|
||||
$curl->setopt(CURLOPT_INFILE, {data => $body, bytes => 0});
|
||||
$curl->setopt(CURLOPT_INFILESIZE, length(${$body}));
|
||||
|
||||
# Options for getting the result.
|
||||
$curl->setopt(CURLOPT_FILE, \$ts_body);
|
||||
|
||||
# Send the request...
|
||||
my $error_code = $curl->perform();
|
||||
my $error_string;
|
||||
if ($error_code != 0) {
|
||||
my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE);
|
||||
$error_string = "could not get timestamp";
|
||||
$error_string .= ", http code: $http_code" unless $http_code == 0;
|
||||
$error_string .= ", curl code: $error_code";
|
||||
$error_string .= " ($::error_buf)" if defined($::error_buf);
|
||||
} else {
|
||||
my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE);
|
||||
if (lc($ct) ne "application/timestamp-reply") {
|
||||
$error_string = "unexpected content type returned: $ct";
|
||||
}
|
||||
}
|
||||
return ($ts_body, $error_string);
|
||||
|
||||
}
|
||||
|
||||
# Print usage information and exists.
|
||||
sub usage {
|
||||
|
||||
print STDERR "usage: $0 -h <server_url> [-e <extension>] [-o <output>] ";
|
||||
print STDERR "[-v] [-d] [-k <private_key.pem>] [-p <key_password>] ";
|
||||
print STDERR "[-c <client_cert.pem>] [-C <CA_certs.pem>] [-P <CA_path>] ";
|
||||
print STDERR "[-r <file:file...>] [-g <EGD_socket>] [<request>]...\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Main program
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# Getting command-line options (default comes from TSGET environment variable).
|
||||
my $getopt_arg = "h:e:o:vdk:p:c:C:P:r:g:";
|
||||
if (exists $ENV{TSGET}) {
|
||||
my @old_argv = @ARGV;
|
||||
@ARGV = split /\s+/, $ENV{TSGET};
|
||||
getopts($getopt_arg, \%options) or usage;
|
||||
@ARGV = @old_argv;
|
||||
}
|
||||
getopts($getopt_arg, \%options) or usage;
|
||||
|
||||
# Checking argument consistency.
|
||||
if (!exists($options{h}) || (@ARGV == 0 && !exists($options{o}))
|
||||
|| (@ARGV > 1 && exists($options{o}))) {
|
||||
print STDERR "Inconsistent command line options.\n";
|
||||
usage;
|
||||
}
|
||||
# Setting defaults.
|
||||
@ARGV = ("-") unless @ARGV != 0;
|
||||
$options{e} = ".tsr" unless defined($options{e});
|
||||
|
||||
# Processing requests.
|
||||
my $curl = create_curl $options{h};
|
||||
undef $/; # For reading whole files.
|
||||
REQUEST: foreach (@ARGV) {
|
||||
my $input = $_;
|
||||
my ($base, $path) = fileparse($input, '\.[^.]*');
|
||||
my $output_base = $base . $options{e};
|
||||
my $output = defined($options{o}) ? $options{o} : $path . $output_base;
|
||||
|
||||
STDERR->printflush("$input: ") if $options{v};
|
||||
# Read request.
|
||||
my $body;
|
||||
if ($input eq "-") {
|
||||
# Read the request from STDIN;
|
||||
$body = <STDIN>;
|
||||
} else {
|
||||
# Read the request from file.
|
||||
open INPUT, "<" . $input
|
||||
or warn("$input: could not open input file: $!\n"), next REQUEST;
|
||||
$body = <INPUT>;
|
||||
close INPUT
|
||||
or warn("$input: could not close input file: $!\n"), next REQUEST;
|
||||
}
|
||||
|
||||
# Send request.
|
||||
STDERR->printflush("sending request") if $options{v};
|
||||
|
||||
my ($ts_body, $error) = get_timestamp $curl, \$body;
|
||||
if (defined($error)) {
|
||||
die "$input: fatal error: $error\n";
|
||||
}
|
||||
STDERR->printflush(", reply received") if $options{v};
|
||||
|
||||
# Write response.
|
||||
if ($output eq "-") {
|
||||
# Write to STDOUT.
|
||||
print $ts_body;
|
||||
} else {
|
||||
# Write to file.
|
||||
open OUTPUT, ">", $output
|
||||
or warn("$output: could not open output file: $!\n"), next REQUEST;
|
||||
print OUTPUT $ts_body;
|
||||
close OUTPUT
|
||||
or warn("$output: could not close output file: $!\n"), next REQUEST;
|
||||
}
|
||||
STDERR->printflush(", $output written.\n") if $options{v};
|
||||
}
|
||||
$curl->cleanup();
|
||||
WWW::Curl::easy::global_cleanup();
|
1063
crypto/aes/aes_x86core.c
Normal file
1063
crypto/aes/aes_x86core.c
Normal file
File diff suppressed because it is too large
Load Diff
1030
crypto/aes/asm/aes-armv4.pl
Normal file
1030
crypto/aes/asm/aes-armv4.pl
Normal file
File diff suppressed because it is too large
Load Diff
1176
crypto/aes/asm/aes-ppc.pl
Normal file
1176
crypto/aes/asm/aes-ppc.pl
Normal file
File diff suppressed because it is too large
Load Diff
1333
crypto/aes/asm/aes-s390x.pl
Normal file
1333
crypto/aes/asm/aes-s390x.pl
Normal file
File diff suppressed because it is too large
Load Diff
1181
crypto/aes/asm/aes-sparcv9.pl
Executable file
1181
crypto/aes/asm/aes-sparcv9.pl
Executable file
File diff suppressed because it is too large
Load Diff
124
crypto/alphacpuid.s
Normal file
124
crypto/alphacpuid.s
Normal file
@@ -0,0 +1,124 @@
|
||||
.text
|
||||
|
||||
.set noat
|
||||
|
||||
.globl OPENSSL_cpuid_setup
|
||||
.ent OPENSSL_cpuid_setup
|
||||
OPENSSL_cpuid_setup:
|
||||
.frame $30,0,$26
|
||||
.prologue 0
|
||||
ret ($26)
|
||||
.end OPENSSL_cpuid_setup
|
||||
|
||||
.globl OPENSSL_wipe_cpu
|
||||
.ent OPENSSL_wipe_cpu
|
||||
OPENSSL_wipe_cpu:
|
||||
.frame $30,0,$26
|
||||
.prologue 0
|
||||
clr $1
|
||||
clr $2
|
||||
clr $3
|
||||
clr $4
|
||||
clr $5
|
||||
clr $6
|
||||
clr $7
|
||||
clr $8
|
||||
clr $16
|
||||
clr $17
|
||||
clr $18
|
||||
clr $19
|
||||
clr $20
|
||||
clr $21
|
||||
clr $22
|
||||
clr $23
|
||||
clr $24
|
||||
clr $25
|
||||
clr $27
|
||||
clr $at
|
||||
clr $29
|
||||
fclr $f0
|
||||
fclr $f1
|
||||
fclr $f10
|
||||
fclr $f11
|
||||
fclr $f12
|
||||
fclr $f13
|
||||
fclr $f14
|
||||
fclr $f15
|
||||
fclr $f16
|
||||
fclr $f17
|
||||
fclr $f18
|
||||
fclr $f19
|
||||
fclr $f20
|
||||
fclr $f21
|
||||
fclr $f22
|
||||
fclr $f23
|
||||
fclr $f24
|
||||
fclr $f25
|
||||
fclr $f26
|
||||
fclr $f27
|
||||
fclr $f28
|
||||
fclr $f29
|
||||
fclr $f30
|
||||
mov $sp,$0
|
||||
ret ($26)
|
||||
.end OPENSSL_wipe_cpu
|
||||
|
||||
.globl OPENSSL_atomic_add
|
||||
.ent OPENSSL_atomic_add
|
||||
OPENSSL_atomic_add:
|
||||
.frame $30,0,$26
|
||||
.prologue 0
|
||||
1: ldl_l $0,($16)
|
||||
addl $0,$17,$1
|
||||
stl_c $1,($16)
|
||||
beq $1,1b
|
||||
addl $0,$17,$0
|
||||
ret ($26)
|
||||
.end OPENSSL_atomic_add
|
||||
|
||||
.globl OPENSSL_rdtsc
|
||||
.ent OPENSSL_rdtsc
|
||||
OPENSSL_rdtsc:
|
||||
.frame $30,0,$26
|
||||
.prologue 0
|
||||
rpcc $0
|
||||
ret ($26)
|
||||
.end OPENSSL_rdtsc
|
||||
|
||||
.globl OPENSSL_cleanse
|
||||
.ent OPENSSL_cleanse
|
||||
OPENSSL_cleanse:
|
||||
.frame $30,0,$26
|
||||
.prologue 0
|
||||
and $16,7,$0
|
||||
bic $17,7,$at
|
||||
beq $at,.Little
|
||||
beq $0,.Laligned
|
||||
|
||||
.Little:
|
||||
ldq_u $1,0($16)
|
||||
mov $16,$2
|
||||
.Lalign:
|
||||
mskbl $1,$16,$1
|
||||
lda $16,1($16)
|
||||
subq $17,1,$17
|
||||
subq $0,1,$0
|
||||
beq $17,.Lout
|
||||
bne $0,.Lalign
|
||||
.Lout: stq_u $1,0($2)
|
||||
beq $17,.Ldone
|
||||
bic $17,7,$at
|
||||
mov $17,$0
|
||||
beq $at,.Little
|
||||
|
||||
.Laligned:
|
||||
stq $31,0($16)
|
||||
subq $17,8,$17
|
||||
lda $16,8($16)
|
||||
bic $17,7,$at
|
||||
bne $at,.Laligned
|
||||
beq $17,.Ldone
|
||||
mov $17,$0
|
||||
br .Little
|
||||
.Ldone: ret ($26)
|
||||
.end OPENSSL_cleanse
|
446
crypto/asn1/ameth_lib.c
Normal file
446
crypto/asn1/ameth_lib.c
Normal file
@@ -0,0 +1,446 @@
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509.h>
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
#include "asn1_locl.h"
|
||||
|
||||
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
|
||||
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
|
||||
extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
|
||||
extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
|
||||
extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
|
||||
|
||||
/* Keep this sorted in type order !! */
|
||||
static const EVP_PKEY_ASN1_METHOD *standard_methods[] =
|
||||
{
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
&rsa_asn1_meths[0],
|
||||
&rsa_asn1_meths[1],
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
&dh_asn1_meth,
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
&dsa_asn1_meths[0],
|
||||
&dsa_asn1_meths[1],
|
||||
&dsa_asn1_meths[2],
|
||||
&dsa_asn1_meths[3],
|
||||
&dsa_asn1_meths[4],
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
&eckey_asn1_meth,
|
||||
#endif
|
||||
&hmac_asn1_meth
|
||||
};
|
||||
|
||||
typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
|
||||
DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
|
||||
static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
|
||||
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
void main()
|
||||
{
|
||||
int i;
|
||||
for (i = 0;
|
||||
i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
|
||||
i++)
|
||||
fprintf(stderr, "Number %d id=%d (%s)\n", i,
|
||||
standard_methods[i]->pkey_id,
|
||||
OBJ_nid2sn(standard_methods[i]->pkey_id));
|
||||
}
|
||||
#endif
|
||||
|
||||
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
|
||||
const EVP_PKEY_ASN1_METHOD *, ameth);
|
||||
|
||||
static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
|
||||
const EVP_PKEY_ASN1_METHOD * const *b)
|
||||
{
|
||||
return ((*a)->pkey_id - (*b)->pkey_id);
|
||||
}
|
||||
|
||||
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
|
||||
const EVP_PKEY_ASN1_METHOD *, ameth);
|
||||
|
||||
int EVP_PKEY_asn1_get_count(void)
|
||||
{
|
||||
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
|
||||
if (app_methods)
|
||||
num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
|
||||
return num;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
|
||||
{
|
||||
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
if (idx < num)
|
||||
return standard_methods[idx];
|
||||
idx -= num;
|
||||
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
|
||||
}
|
||||
|
||||
static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
|
||||
{
|
||||
EVP_PKEY_ASN1_METHOD tmp;
|
||||
const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
|
||||
tmp.pkey_id = type;
|
||||
if (app_methods)
|
||||
{
|
||||
int idx;
|
||||
idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
|
||||
if (idx >= 0)
|
||||
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
|
||||
}
|
||||
ret = OBJ_bsearch_ameth(&t, standard_methods,
|
||||
sizeof(standard_methods)
|
||||
/sizeof(EVP_PKEY_ASN1_METHOD *));
|
||||
if (!ret || !*ret)
|
||||
return NULL;
|
||||
return *ret;
|
||||
}
|
||||
|
||||
/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
|
||||
* also search through engines and set *pe to a functional reference
|
||||
* to the engine implementing 'type' or NULL if no engine implements
|
||||
* it.
|
||||
*/
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
|
||||
{
|
||||
const EVP_PKEY_ASN1_METHOD *t;
|
||||
ENGINE *e;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
t = pkey_asn1_find(type);
|
||||
if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
|
||||
break;
|
||||
type = t->pkey_base_id;
|
||||
}
|
||||
if (pe)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* type will contain the final unaliased type */
|
||||
e = ENGINE_get_pkey_asn1_meth_engine(type);
|
||||
if (e)
|
||||
{
|
||||
*pe = e;
|
||||
return ENGINE_get_pkey_asn1_meth(e, type);
|
||||
}
|
||||
#endif
|
||||
*pe = NULL;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
|
||||
const char *str, int len)
|
||||
{
|
||||
int i;
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
if (len == -1)
|
||||
len = strlen(str);
|
||||
if (pe)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE *e;
|
||||
ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
|
||||
if (ameth)
|
||||
{
|
||||
/* Convert structural into
|
||||
* functional reference
|
||||
*/
|
||||
if (!ENGINE_init(e))
|
||||
ameth = NULL;
|
||||
ENGINE_free(e);
|
||||
*pe = e;
|
||||
return ameth;
|
||||
}
|
||||
#endif
|
||||
*pe = NULL;
|
||||
}
|
||||
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
|
||||
{
|
||||
ameth = EVP_PKEY_asn1_get0(i);
|
||||
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
|
||||
continue;
|
||||
if (((int)strlen(ameth->pem_str) == len) &&
|
||||
!strncasecmp(ameth->pem_str, str, len))
|
||||
return ameth;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
|
||||
{
|
||||
if (app_methods == NULL)
|
||||
{
|
||||
app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
|
||||
if (!app_methods)
|
||||
return 0;
|
||||
}
|
||||
if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
|
||||
return 0;
|
||||
sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_asn1_add_alias(int to, int from)
|
||||
{
|
||||
EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
|
||||
if (!ameth)
|
||||
return 0;
|
||||
ameth->pkey_base_id = to;
|
||||
return EVP_PKEY_asn1_add0(ameth);
|
||||
}
|
||||
|
||||
int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
|
||||
const char **pinfo, const char **ppem_str,
|
||||
const EVP_PKEY_ASN1_METHOD *ameth)
|
||||
{
|
||||
if (!ameth)
|
||||
return 0;
|
||||
if (ppkey_id)
|
||||
*ppkey_id = ameth->pkey_id;
|
||||
if (ppkey_base_id)
|
||||
*ppkey_base_id = ameth->pkey_base_id;
|
||||
if (ppkey_flags)
|
||||
*ppkey_flags = ameth->pkey_flags;
|
||||
if (pinfo)
|
||||
*pinfo = ameth->info;
|
||||
if (ppem_str)
|
||||
*ppem_str = ameth->pem_str;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
|
||||
{
|
||||
return pkey->ameth;
|
||||
}
|
||||
|
||||
EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
|
||||
const char *pem_str, const char *info)
|
||||
{
|
||||
EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
|
||||
if (!ameth)
|
||||
return NULL;
|
||||
|
||||
ameth->pkey_id = id;
|
||||
ameth->pkey_base_id = id;
|
||||
ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
|
||||
|
||||
if (info)
|
||||
{
|
||||
ameth->info = BUF_strdup(info);
|
||||
if (!ameth->info)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (pem_str)
|
||||
{
|
||||
ameth->pem_str = BUF_strdup(pem_str);
|
||||
if (!ameth->pem_str)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ameth->pub_decode = 0;
|
||||
ameth->pub_encode = 0;
|
||||
ameth->pub_cmp = 0;
|
||||
ameth->pub_print = 0;
|
||||
|
||||
ameth->priv_decode = 0;
|
||||
ameth->priv_encode = 0;
|
||||
ameth->priv_print = 0;
|
||||
|
||||
ameth->old_priv_encode = 0;
|
||||
ameth->old_priv_decode = 0;
|
||||
|
||||
ameth->pkey_size = 0;
|
||||
ameth->pkey_bits = 0;
|
||||
|
||||
ameth->param_decode = 0;
|
||||
ameth->param_encode = 0;
|
||||
ameth->param_missing = 0;
|
||||
ameth->param_copy = 0;
|
||||
ameth->param_cmp = 0;
|
||||
ameth->param_print = 0;
|
||||
|
||||
ameth->pkey_free = 0;
|
||||
ameth->pkey_ctrl = 0;
|
||||
|
||||
return ameth;
|
||||
|
||||
err:
|
||||
|
||||
EVP_PKEY_asn1_free(ameth);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
|
||||
const EVP_PKEY_ASN1_METHOD *src)
|
||||
{
|
||||
|
||||
dst->pub_decode = src->pub_decode;
|
||||
dst->pub_encode = src->pub_encode;
|
||||
dst->pub_cmp = src->pub_cmp;
|
||||
dst->pub_print = src->pub_print;
|
||||
|
||||
dst->priv_decode = src->priv_decode;
|
||||
dst->priv_encode = src->priv_encode;
|
||||
dst->priv_print = src->priv_print;
|
||||
|
||||
dst->old_priv_encode = src->old_priv_encode;
|
||||
dst->old_priv_decode = src->old_priv_decode;
|
||||
|
||||
dst->pkey_size = src->pkey_size;
|
||||
dst->pkey_bits = src->pkey_bits;
|
||||
|
||||
dst->param_decode = src->param_decode;
|
||||
dst->param_encode = src->param_encode;
|
||||
dst->param_missing = src->param_missing;
|
||||
dst->param_copy = src->param_copy;
|
||||
dst->param_cmp = src->param_cmp;
|
||||
dst->param_print = src->param_print;
|
||||
|
||||
dst->pkey_free = src->pkey_free;
|
||||
dst->pkey_ctrl = src->pkey_ctrl;
|
||||
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
|
||||
{
|
||||
if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
|
||||
{
|
||||
if (ameth->pem_str)
|
||||
OPENSSL_free(ameth->pem_str);
|
||||
if (ameth->info)
|
||||
OPENSSL_free(ameth->info);
|
||||
OPENSSL_free(ameth);
|
||||
}
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
|
||||
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
|
||||
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
|
||||
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx),
|
||||
int (*pkey_size)(const EVP_PKEY *pk),
|
||||
int (*pkey_bits)(const EVP_PKEY *pk))
|
||||
{
|
||||
ameth->pub_decode = pub_decode;
|
||||
ameth->pub_encode = pub_encode;
|
||||
ameth->pub_cmp = pub_cmp;
|
||||
ameth->pub_print = pub_print;
|
||||
ameth->pkey_size = pkey_size;
|
||||
ameth->pkey_bits = pkey_bits;
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
|
||||
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
|
||||
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx))
|
||||
{
|
||||
ameth->priv_decode = priv_decode;
|
||||
ameth->priv_encode = priv_encode;
|
||||
ameth->priv_print = priv_print;
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*param_decode)(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen),
|
||||
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
|
||||
int (*param_missing)(const EVP_PKEY *pk),
|
||||
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
|
||||
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
|
||||
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx))
|
||||
{
|
||||
ameth->param_decode = param_decode;
|
||||
ameth->param_encode = param_encode;
|
||||
ameth->param_missing = param_missing;
|
||||
ameth->param_copy = param_copy;
|
||||
ameth->param_cmp = param_cmp;
|
||||
ameth->param_print = param_print;
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
void (*pkey_free)(EVP_PKEY *pkey))
|
||||
{
|
||||
ameth->pkey_free = pkey_free;
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
|
||||
long arg1, void *arg2))
|
||||
{
|
||||
ameth->pkey_ctrl = pkey_ctrl;
|
||||
}
|
134
crypto/asn1/asn1_locl.h
Normal file
134
crypto/asn1/asn1_locl.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/* asn1t.h */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/* Internal ASN1 structures and functions: not for application use */
|
||||
|
||||
/* ASN1 print context structure */
|
||||
|
||||
struct asn1_pctx_st
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long nm_flags;
|
||||
unsigned long cert_flags;
|
||||
unsigned long oid_flags;
|
||||
unsigned long str_flags;
|
||||
} /* ASN1_PCTX */;
|
||||
|
||||
/* ASN1 public key method structure */
|
||||
|
||||
struct evp_pkey_asn1_method_st
|
||||
{
|
||||
int pkey_id;
|
||||
int pkey_base_id;
|
||||
unsigned long pkey_flags;
|
||||
|
||||
char *pem_str;
|
||||
char *info;
|
||||
|
||||
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
|
||||
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
|
||||
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
|
||||
int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
|
||||
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
|
||||
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
|
||||
int (*pkey_size)(const EVP_PKEY *pk);
|
||||
int (*pkey_bits)(const EVP_PKEY *pk);
|
||||
|
||||
int (*param_decode)(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen);
|
||||
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
int (*param_missing)(const EVP_PKEY *pk);
|
||||
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
|
||||
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
|
||||
void (*pkey_free)(EVP_PKEY *pkey);
|
||||
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
|
||||
|
||||
/* Legacy functions for old PEM */
|
||||
|
||||
int (*old_priv_decode)(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen);
|
||||
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
|
||||
} /* EVP_PKEY_ASN1_METHOD */;
|
||||
|
||||
/* Method to handle CRL access.
|
||||
* In general a CRL could be very large (several Mb) and can consume large
|
||||
* amounts of resources if stored in memory by multiple processes.
|
||||
* This method allows general CRL operations to be redirected to more
|
||||
* efficient callbacks: for example a CRL entry database.
|
||||
*/
|
||||
|
||||
#define X509_CRL_METHOD_DYNAMIC 1
|
||||
|
||||
struct x509_crl_method_st
|
||||
{
|
||||
int flags;
|
||||
int (*crl_init)(X509_CRL *crl);
|
||||
int (*crl_free)(X509_CRL *crl);
|
||||
int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
|
||||
ASN1_INTEGER *ser, X509_NAME *issuer);
|
||||
int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
|
||||
};
|
495
crypto/asn1/bio_asn1.c
Normal file
495
crypto/asn1/bio_asn1.c
Normal file
@@ -0,0 +1,495 @@
|
||||
/* bio_asn1.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/* Experimental ASN1 BIO. When written through the data is converted
|
||||
* to an ASN1 string type: default is OCTET STRING. Additional functions
|
||||
* can be provided to add prefix and suffix data.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
/* Must be large enough for biggest tag+length */
|
||||
#define DEFAULT_ASN1_BUF_SIZE 20
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ASN1_STATE_START,
|
||||
ASN1_STATE_PRE_COPY,
|
||||
ASN1_STATE_HEADER,
|
||||
ASN1_STATE_HEADER_COPY,
|
||||
ASN1_STATE_DATA_COPY,
|
||||
ASN1_STATE_POST_COPY,
|
||||
ASN1_STATE_DONE
|
||||
} asn1_bio_state_t;
|
||||
|
||||
typedef struct BIO_ASN1_EX_FUNCS_st
|
||||
{
|
||||
asn1_ps_func *ex_func;
|
||||
asn1_ps_func *ex_free_func;
|
||||
} BIO_ASN1_EX_FUNCS;
|
||||
|
||||
typedef struct BIO_ASN1_BUF_CTX_t
|
||||
{
|
||||
/* Internal state */
|
||||
asn1_bio_state_t state;
|
||||
/* Internal buffer */
|
||||
unsigned char *buf;
|
||||
/* Size of buffer */
|
||||
int bufsize;
|
||||
/* Current position in buffer */
|
||||
int bufpos;
|
||||
/* Current buffer length */
|
||||
int buflen;
|
||||
/* Amount of data to copy */
|
||||
int copylen;
|
||||
/* Class and tag to use */
|
||||
int asn1_class, asn1_tag;
|
||||
asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
|
||||
/* Extra buffer for prefix and suffix data */
|
||||
unsigned char *ex_buf;
|
||||
int ex_len;
|
||||
int ex_pos;
|
||||
void *ex_arg;
|
||||
} BIO_ASN1_BUF_CTX;
|
||||
|
||||
|
||||
static int asn1_bio_write(BIO *h, const char *buf,int num);
|
||||
static int asn1_bio_read(BIO *h, char *buf, int size);
|
||||
static int asn1_bio_puts(BIO *h, const char *str);
|
||||
static int asn1_bio_gets(BIO *h, char *str, int size);
|
||||
static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
|
||||
static int asn1_bio_new(BIO *h);
|
||||
static int asn1_bio_free(BIO *data);
|
||||
static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
|
||||
|
||||
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
|
||||
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
|
||||
asn1_ps_func *cleanup, asn1_bio_state_t next);
|
||||
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
|
||||
asn1_ps_func *setup,
|
||||
asn1_bio_state_t ex_state,
|
||||
asn1_bio_state_t other_state);
|
||||
|
||||
static BIO_METHOD methods_asn1=
|
||||
{
|
||||
BIO_TYPE_ASN1,
|
||||
"asn1",
|
||||
asn1_bio_write,
|
||||
asn1_bio_read,
|
||||
asn1_bio_puts,
|
||||
asn1_bio_gets,
|
||||
asn1_bio_ctrl,
|
||||
asn1_bio_new,
|
||||
asn1_bio_free,
|
||||
asn1_bio_callback_ctrl,
|
||||
};
|
||||
|
||||
BIO_METHOD *BIO_f_asn1(void)
|
||||
{
|
||||
return(&methods_asn1);
|
||||
}
|
||||
|
||||
|
||||
static int asn1_bio_new(BIO *b)
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
|
||||
if (!ctx)
|
||||
return 0;
|
||||
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
|
||||
return 0;
|
||||
b->init = 1;
|
||||
b->ptr = (char *)ctx;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
|
||||
{
|
||||
ctx->buf = OPENSSL_malloc(size);
|
||||
if (!ctx->buf)
|
||||
return 0;
|
||||
ctx->bufsize = size;
|
||||
ctx->bufpos = 0;
|
||||
ctx->buflen = 0;
|
||||
ctx->copylen = 0;
|
||||
ctx->asn1_class = V_ASN1_UNIVERSAL;
|
||||
ctx->asn1_tag = V_ASN1_OCTET_STRING;
|
||||
ctx->ex_buf = 0;
|
||||
ctx->ex_pos = 0;
|
||||
ctx->ex_len = 0;
|
||||
ctx->state = ASN1_STATE_START;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int asn1_bio_free(BIO *b)
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
if (ctx->buf)
|
||||
OPENSSL_free(ctx->buf);
|
||||
OPENSSL_free(ctx);
|
||||
b->init = 0;
|
||||
b->ptr = NULL;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int asn1_bio_write(BIO *b, const char *in , int inl)
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
int wrmax, wrlen, ret;
|
||||
unsigned char *p;
|
||||
if (!in || (inl < 0) || (b->next_bio == NULL))
|
||||
return 0;
|
||||
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
wrlen = 0;
|
||||
ret = -1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
switch (ctx->state)
|
||||
{
|
||||
|
||||
/* Setup prefix data, call it */
|
||||
case ASN1_STATE_START:
|
||||
if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
|
||||
ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/* Copy any pre data first */
|
||||
case ASN1_STATE_PRE_COPY:
|
||||
|
||||
ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
|
||||
ASN1_STATE_HEADER);
|
||||
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
|
||||
break;
|
||||
|
||||
case ASN1_STATE_HEADER:
|
||||
ctx->buflen =
|
||||
ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
|
||||
OPENSSL_assert(ctx->buflen <= ctx->bufsize);
|
||||
p = ctx->buf;
|
||||
ASN1_put_object(&p, 0, inl,
|
||||
ctx->asn1_tag, ctx->asn1_class);
|
||||
ctx->copylen = inl;
|
||||
ctx->state = ASN1_STATE_HEADER_COPY;
|
||||
|
||||
break;
|
||||
|
||||
case ASN1_STATE_HEADER_COPY:
|
||||
ret = BIO_write(b->next_bio,
|
||||
ctx->buf + ctx->bufpos, ctx->buflen);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
|
||||
ctx->buflen -= ret;
|
||||
if (ctx->buflen)
|
||||
ctx->bufpos += ret;
|
||||
else
|
||||
{
|
||||
ctx->bufpos = 0;
|
||||
ctx->state = ASN1_STATE_DATA_COPY;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ASN1_STATE_DATA_COPY:
|
||||
|
||||
if (inl > ctx->copylen)
|
||||
wrmax = ctx->copylen;
|
||||
else
|
||||
wrmax = inl;
|
||||
ret = BIO_write(b->next_bio, in, wrmax);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
wrlen += ret;
|
||||
ctx->copylen -= ret;
|
||||
in += ret;
|
||||
inl -= ret;
|
||||
|
||||
if (ctx->copylen == 0)
|
||||
ctx->state = ASN1_STATE_HEADER;
|
||||
|
||||
if (inl == 0)
|
||||
goto done;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
done:
|
||||
BIO_clear_retry_flags(b);
|
||||
BIO_copy_next_retry(b);
|
||||
|
||||
return (wrlen > 0) ? wrlen : ret;
|
||||
|
||||
}
|
||||
|
||||
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
|
||||
asn1_ps_func *cleanup, asn1_bio_state_t next)
|
||||
{
|
||||
int ret;
|
||||
if (ctx->ex_len <= 0)
|
||||
return 1;
|
||||
for(;;)
|
||||
{
|
||||
ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
|
||||
ctx->ex_len);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
ctx->ex_len -= ret;
|
||||
if (ctx->ex_len > 0)
|
||||
ctx->ex_pos += ret;
|
||||
else
|
||||
{
|
||||
if(cleanup)
|
||||
cleanup(b, &ctx->ex_buf, &ctx->ex_len,
|
||||
&ctx->ex_arg);
|
||||
ctx->state = next;
|
||||
ctx->ex_pos = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
|
||||
asn1_ps_func *setup,
|
||||
asn1_bio_state_t ex_state,
|
||||
asn1_bio_state_t other_state)
|
||||
{
|
||||
if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
|
||||
{
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->ex_len > 0)
|
||||
ctx->state = ex_state;
|
||||
else
|
||||
ctx->state = other_state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int asn1_bio_read(BIO *b, char *in , int inl)
|
||||
{
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
return BIO_read(b->next_bio, in , inl);
|
||||
}
|
||||
|
||||
static int asn1_bio_puts(BIO *b, const char *str)
|
||||
{
|
||||
return asn1_bio_write(b, str, strlen(str));
|
||||
}
|
||||
|
||||
static int asn1_bio_gets(BIO *b, char *str, int size)
|
||||
{
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
return BIO_gets(b->next_bio, str , size);
|
||||
}
|
||||
|
||||
static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
|
||||
{
|
||||
if (b->next_bio == NULL) return(0);
|
||||
return BIO_callback_ctrl(b->next_bio,cmd,fp);
|
||||
}
|
||||
|
||||
static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
BIO_ASN1_EX_FUNCS *ex_func;
|
||||
long ret = 1;
|
||||
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
switch(cmd)
|
||||
{
|
||||
|
||||
case BIO_C_SET_PREFIX:
|
||||
ex_func = arg2;
|
||||
ctx->prefix = ex_func->ex_func;
|
||||
ctx->prefix_free = ex_func->ex_free_func;
|
||||
break;
|
||||
|
||||
case BIO_C_GET_PREFIX:
|
||||
ex_func = arg2;
|
||||
ex_func->ex_func = ctx->prefix;
|
||||
ex_func->ex_free_func = ctx->prefix_free;
|
||||
break;
|
||||
|
||||
case BIO_C_SET_SUFFIX:
|
||||
ex_func = arg2;
|
||||
ctx->suffix = ex_func->ex_func;
|
||||
ctx->suffix_free = ex_func->ex_free_func;
|
||||
break;
|
||||
|
||||
case BIO_C_GET_SUFFIX:
|
||||
ex_func = arg2;
|
||||
ex_func->ex_func = ctx->suffix;
|
||||
ex_func->ex_free_func = ctx->suffix_free;
|
||||
break;
|
||||
|
||||
case BIO_C_SET_EX_ARG:
|
||||
ctx->ex_arg = arg2;
|
||||
break;
|
||||
|
||||
case BIO_C_GET_EX_ARG:
|
||||
*(void **)arg2 = ctx->ex_arg;
|
||||
break;
|
||||
|
||||
case BIO_CTRL_FLUSH:
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
|
||||
/* Call post function if possible */
|
||||
if (ctx->state == ASN1_STATE_HEADER)
|
||||
{
|
||||
if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
|
||||
ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->state == ASN1_STATE_POST_COPY)
|
||||
{
|
||||
ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
|
||||
ASN1_STATE_DONE);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ctx->state == ASN1_STATE_DONE)
|
||||
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
|
||||
else
|
||||
{
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int asn1_bio_set_ex(BIO *b, int cmd,
|
||||
asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
|
||||
{
|
||||
BIO_ASN1_EX_FUNCS extmp;
|
||||
extmp.ex_func = ex_func;
|
||||
extmp.ex_free_func = ex_free_func;
|
||||
return BIO_ctrl(b, cmd, 0, &extmp);
|
||||
}
|
||||
|
||||
static int asn1_bio_get_ex(BIO *b, int cmd,
|
||||
asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
|
||||
{
|
||||
BIO_ASN1_EX_FUNCS extmp;
|
||||
int ret;
|
||||
ret = BIO_ctrl(b, cmd, 0, &extmp);
|
||||
if (ret > 0)
|
||||
{
|
||||
*ex_func = extmp.ex_func;
|
||||
*ex_free_func = extmp.ex_free_func;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
|
||||
{
|
||||
return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
|
||||
}
|
||||
|
||||
int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
|
||||
{
|
||||
return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
|
||||
}
|
||||
|
||||
int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
|
||||
{
|
||||
return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
|
||||
}
|
||||
|
||||
int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
|
||||
{
|
||||
return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
|
||||
}
|
246
crypto/asn1/bio_ndef.c
Normal file
246
crypto/asn1/bio_ndef.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/* bio_ndef.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#ifndef OPENSSL_SYSNAME_NETWARE
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
/* Experimental NDEF ASN1 BIO support routines */
|
||||
|
||||
/* The usage is quite simple, initialize an ASN1 structure,
|
||||
* get a BIO from it then any data written through the BIO
|
||||
* will end up translated to approptiate format on the fly.
|
||||
* The data is streamed out and does *not* need to be
|
||||
* all held in memory at once.
|
||||
*
|
||||
* When the BIO is flushed the output is finalized and any
|
||||
* signatures etc written out.
|
||||
*
|
||||
* The BIO is a 'proper' BIO and can handle non blocking I/O
|
||||
* correctly.
|
||||
*
|
||||
* The usage is simple. The implementation is *not*...
|
||||
*/
|
||||
|
||||
/* BIO support data stored in the ASN1 BIO ex_arg */
|
||||
|
||||
typedef struct ndef_aux_st
|
||||
{
|
||||
/* ASN1 structure this BIO refers to */
|
||||
ASN1_VALUE *val;
|
||||
const ASN1_ITEM *it;
|
||||
/* Top of the BIO chain */
|
||||
BIO *ndef_bio;
|
||||
/* Output BIO */
|
||||
BIO *out;
|
||||
/* Boundary where content is inserted */
|
||||
unsigned char **boundary;
|
||||
/* DER buffer start */
|
||||
unsigned char *derbuf;
|
||||
} NDEF_SUPPORT;
|
||||
|
||||
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||
|
||||
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux = NULL;
|
||||
BIO *asn_bio = NULL;
|
||||
const ASN1_AUX *aux = it->funcs;
|
||||
ASN1_STREAM_ARG sarg;
|
||||
|
||||
if (!aux || !aux->asn1_cb)
|
||||
{
|
||||
ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
|
||||
asn_bio = BIO_new(BIO_f_asn1());
|
||||
|
||||
/* ASN1 bio needs to be next to output BIO */
|
||||
|
||||
out = BIO_push(asn_bio, out);
|
||||
|
||||
if (!ndef_aux || !asn_bio || !out)
|
||||
goto err;
|
||||
|
||||
BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
|
||||
BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
|
||||
|
||||
/* Now let callback prepend any digest, cipher etc BIOs
|
||||
* ASN1 structure needs.
|
||||
*/
|
||||
|
||||
sarg.out = out;
|
||||
sarg.ndef_bio = NULL;
|
||||
sarg.boundary = NULL;
|
||||
|
||||
if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
|
||||
goto err;
|
||||
|
||||
ndef_aux->val = val;
|
||||
ndef_aux->it = it;
|
||||
ndef_aux->ndef_bio = sarg.ndef_bio;
|
||||
ndef_aux->boundary = sarg.boundary;
|
||||
ndef_aux->out = out;
|
||||
|
||||
BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
|
||||
|
||||
return sarg.ndef_bio;
|
||||
|
||||
err:
|
||||
if (asn_bio)
|
||||
BIO_free(asn_bio);
|
||||
if (ndef_aux)
|
||||
OPENSSL_free(ndef_aux);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux;
|
||||
unsigned char *p;
|
||||
int derlen;
|
||||
|
||||
if (!parg)
|
||||
return 0;
|
||||
|
||||
ndef_aux = *(NDEF_SUPPORT **)parg;
|
||||
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
|
||||
p = OPENSSL_malloc(derlen);
|
||||
ndef_aux->derbuf = p;
|
||||
*pbuf = p;
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
|
||||
|
||||
if (!*ndef_aux->boundary)
|
||||
return 0;
|
||||
|
||||
*plen = *ndef_aux->boundary - *pbuf;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux;
|
||||
|
||||
if (!parg)
|
||||
return 0;
|
||||
|
||||
ndef_aux = *(NDEF_SUPPORT **)parg;
|
||||
|
||||
if (ndef_aux->derbuf)
|
||||
OPENSSL_free(ndef_aux->derbuf);
|
||||
|
||||
ndef_aux->derbuf = NULL;
|
||||
*pbuf = NULL;
|
||||
*plen = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
{
|
||||
NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
|
||||
if (!ndef_prefix_free(b, pbuf, plen, parg))
|
||||
return 0;
|
||||
OPENSSL_free(*pndef_aux);
|
||||
*pndef_aux = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux;
|
||||
unsigned char *p;
|
||||
int derlen;
|
||||
const ASN1_AUX *aux;
|
||||
ASN1_STREAM_ARG sarg;
|
||||
|
||||
if (!parg)
|
||||
return 0;
|
||||
|
||||
ndef_aux = *(NDEF_SUPPORT **)parg;
|
||||
|
||||
aux = ndef_aux->it->funcs;
|
||||
|
||||
/* Finalize structures */
|
||||
sarg.ndef_bio = ndef_aux->ndef_bio;
|
||||
sarg.out = ndef_aux->out;
|
||||
sarg.boundary = ndef_aux->boundary;
|
||||
if (aux->asn1_cb(ASN1_OP_STREAM_POST,
|
||||
&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
|
||||
return 0;
|
||||
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
|
||||
p = OPENSSL_malloc(derlen);
|
||||
ndef_aux->derbuf = p;
|
||||
*pbuf = p;
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
|
||||
|
||||
if (!*ndef_aux->boundary)
|
||||
return 0;
|
||||
*pbuf = *ndef_aux->boundary;
|
||||
*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
|
||||
|
||||
return 1;
|
||||
}
|
72
crypto/asn1/x_nx509.c
Normal file
72
crypto/asn1/x_nx509.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/* x_nx509.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/asn1t.h>
|
||||
|
||||
/* Old netscape certificate wrapper format */
|
||||
|
||||
ASN1_SEQUENCE(NETSCAPE_X509) = {
|
||||
ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
|
||||
ASN1_OPT(NETSCAPE_X509, cert, X509)
|
||||
} ASN1_SEQUENCE_END(NETSCAPE_X509)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509)
|
||||
|
317
crypto/bn/asm/alpha-mont.pl
Normal file
317
crypto/bn/asm/alpha-mont.pl
Normal file
@@ -0,0 +1,317 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
#
|
||||
# On 21264 RSA sign performance improves by 70/35/20/15 percent for
|
||||
# 512/1024/2048/4096 bit key lengths. This is against vendor compiler
|
||||
# instructed to '-tune host' code with in-line assembler. Other
|
||||
# benchmarks improve by 15-20%. To anchor it to something else, the
|
||||
# code provides approximately the same performance per GHz as AMD64.
|
||||
# I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x
|
||||
# difference.
|
||||
|
||||
# int bn_mul_mont(
|
||||
$rp="a0"; # BN_ULONG *rp,
|
||||
$ap="a1"; # const BN_ULONG *ap,
|
||||
$bp="a2"; # const BN_ULONG *bp,
|
||||
$np="a3"; # const BN_ULONG *np,
|
||||
$n0="a4"; # const BN_ULONG *n0,
|
||||
$num="a5"; # int num);
|
||||
|
||||
$lo0="t0";
|
||||
$hi0="t1";
|
||||
$lo1="t2";
|
||||
$hi1="t3";
|
||||
$aj="t4";
|
||||
$bi="t5";
|
||||
$nj="t6";
|
||||
$tp="t7";
|
||||
$alo="t8";
|
||||
$ahi="t9";
|
||||
$nlo="t10";
|
||||
$nhi="t11";
|
||||
$tj="t12";
|
||||
$i="s3";
|
||||
$j="s4";
|
||||
$m1="s5";
|
||||
|
||||
$code=<<___;
|
||||
#include <asm.h>
|
||||
#include <regdef.h>
|
||||
|
||||
.text
|
||||
|
||||
.set noat
|
||||
.set noreorder
|
||||
|
||||
.globl bn_mul_mont
|
||||
.align 5
|
||||
.ent bn_mul_mont
|
||||
bn_mul_mont:
|
||||
lda sp,-40(sp)
|
||||
stq ra,0(sp)
|
||||
stq s3,8(sp)
|
||||
stq s4,16(sp)
|
||||
stq s5,24(sp)
|
||||
stq fp,32(sp)
|
||||
mov sp,fp
|
||||
.mask 0x0400f000,-40
|
||||
.frame fp,40,ra
|
||||
.prologue 0
|
||||
|
||||
.align 4
|
||||
.set reorder
|
||||
sextl $num,$num
|
||||
mov 0,v0
|
||||
cmplt $num,4,AT
|
||||
bne AT,.Lexit
|
||||
|
||||
ldq $hi0,0($ap) # ap[0]
|
||||
s8addq $num,16,AT
|
||||
ldq $aj,8($ap)
|
||||
subq sp,AT,sp
|
||||
ldq $bi,0($bp) # bp[0]
|
||||
mov -4096,AT
|
||||
ldq $n0,0($n0)
|
||||
and sp,AT,sp
|
||||
|
||||
mulq $hi0,$bi,$lo0
|
||||
ldq $hi1,0($np) # np[0]
|
||||
umulh $hi0,$bi,$hi0
|
||||
ldq $nj,8($np)
|
||||
|
||||
mulq $lo0,$n0,$m1
|
||||
|
||||
mulq $hi1,$m1,$lo1
|
||||
umulh $hi1,$m1,$hi1
|
||||
|
||||
addq $lo1,$lo0,$lo1
|
||||
cmpult $lo1,$lo0,AT
|
||||
addq $hi1,AT,$hi1
|
||||
|
||||
mulq $aj,$bi,$alo
|
||||
mov 2,$j
|
||||
umulh $aj,$bi,$ahi
|
||||
mov sp,$tp
|
||||
|
||||
mulq $nj,$m1,$nlo
|
||||
s8addq $j,$ap,$aj
|
||||
umulh $nj,$m1,$nhi
|
||||
s8addq $j,$np,$nj
|
||||
.align 4
|
||||
.L1st:
|
||||
.set noreorder
|
||||
ldq $aj,($aj)
|
||||
addl $j,1,$j
|
||||
ldq $nj,($nj)
|
||||
lda $tp,8($tp)
|
||||
|
||||
addq $alo,$hi0,$lo0
|
||||
mulq $aj,$bi,$alo
|
||||
cmpult $lo0,$hi0,AT
|
||||
addq $nlo,$hi1,$lo1
|
||||
|
||||
mulq $nj,$m1,$nlo
|
||||
addq $ahi,AT,$hi0
|
||||
cmpult $lo1,$hi1,v0
|
||||
cmplt $j,$num,$tj
|
||||
|
||||
umulh $aj,$bi,$ahi
|
||||
addq $nhi,v0,$hi1
|
||||
addq $lo1,$lo0,$lo1
|
||||
s8addq $j,$ap,$aj
|
||||
|
||||
umulh $nj,$m1,$nhi
|
||||
cmpult $lo1,$lo0,v0
|
||||
addq $hi1,v0,$hi1
|
||||
s8addq $j,$np,$nj
|
||||
|
||||
stq $lo1,-8($tp)
|
||||
nop
|
||||
unop
|
||||
bne $tj,.L1st
|
||||
.set reorder
|
||||
|
||||
addq $alo,$hi0,$lo0
|
||||
addq $nlo,$hi1,$lo1
|
||||
cmpult $lo0,$hi0,AT
|
||||
cmpult $lo1,$hi1,v0
|
||||
addq $ahi,AT,$hi0
|
||||
addq $nhi,v0,$hi1
|
||||
|
||||
addq $lo1,$lo0,$lo1
|
||||
cmpult $lo1,$lo0,v0
|
||||
addq $hi1,v0,$hi1
|
||||
|
||||
stq $lo1,0($tp)
|
||||
|
||||
addq $hi1,$hi0,$hi1
|
||||
cmpult $hi1,$hi0,AT
|
||||
stq $hi1,8($tp)
|
||||
stq AT,16($tp)
|
||||
|
||||
mov 1,$i
|
||||
.align 4
|
||||
.Louter:
|
||||
s8addq $i,$bp,$bi
|
||||
ldq $hi0,($ap)
|
||||
ldq $aj,8($ap)
|
||||
ldq $bi,($bi)
|
||||
ldq $hi1,($np)
|
||||
ldq $nj,8($np)
|
||||
ldq $tj,(sp)
|
||||
|
||||
mulq $hi0,$bi,$lo0
|
||||
umulh $hi0,$bi,$hi0
|
||||
|
||||
addq $lo0,$tj,$lo0
|
||||
cmpult $lo0,$tj,AT
|
||||
addq $hi0,AT,$hi0
|
||||
|
||||
mulq $lo0,$n0,$m1
|
||||
|
||||
mulq $hi1,$m1,$lo1
|
||||
umulh $hi1,$m1,$hi1
|
||||
|
||||
addq $lo1,$lo0,$lo1
|
||||
cmpult $lo1,$lo0,AT
|
||||
mov 2,$j
|
||||
addq $hi1,AT,$hi1
|
||||
|
||||
mulq $aj,$bi,$alo
|
||||
mov sp,$tp
|
||||
umulh $aj,$bi,$ahi
|
||||
|
||||
mulq $nj,$m1,$nlo
|
||||
s8addq $j,$ap,$aj
|
||||
umulh $nj,$m1,$nhi
|
||||
.align 4
|
||||
.Linner:
|
||||
.set noreorder
|
||||
ldq $tj,8($tp) #L0
|
||||
nop #U1
|
||||
ldq $aj,($aj) #L1
|
||||
s8addq $j,$np,$nj #U0
|
||||
|
||||
ldq $nj,($nj) #L0
|
||||
nop #U1
|
||||
addq $alo,$hi0,$lo0 #L1
|
||||
lda $tp,8($tp)
|
||||
|
||||
mulq $aj,$bi,$alo #U1
|
||||
cmpult $lo0,$hi0,AT #L0
|
||||
addq $nlo,$hi1,$lo1 #L1
|
||||
addl $j,1,$j
|
||||
|
||||
mulq $nj,$m1,$nlo #U1
|
||||
addq $ahi,AT,$hi0 #L0
|
||||
addq $lo0,$tj,$lo0 #L1
|
||||
cmpult $lo1,$hi1,v0 #U0
|
||||
|
||||
umulh $aj,$bi,$ahi #U1
|
||||
cmpult $lo0,$tj,AT #L0
|
||||
addq $lo1,$lo0,$lo1 #L1
|
||||
addq $nhi,v0,$hi1 #U0
|
||||
|
||||
umulh $nj,$m1,$nhi #U1
|
||||
s8addq $j,$ap,$aj #L0
|
||||
cmpult $lo1,$lo0,v0 #L1
|
||||
cmplt $j,$num,$tj #U0 # borrow $tj
|
||||
|
||||
addq $hi0,AT,$hi0 #L0
|
||||
addq $hi1,v0,$hi1 #U1
|
||||
stq $lo1,-8($tp) #L1
|
||||
bne $tj,.Linner #U0
|
||||
.set reorder
|
||||
|
||||
ldq $tj,8($tp)
|
||||
addq $alo,$hi0,$lo0
|
||||
addq $nlo,$hi1,$lo1
|
||||
cmpult $lo0,$hi0,AT
|
||||
cmpult $lo1,$hi1,v0
|
||||
addq $ahi,AT,$hi0
|
||||
addq $nhi,v0,$hi1
|
||||
|
||||
addq $lo0,$tj,$lo0
|
||||
cmpult $lo0,$tj,AT
|
||||
addq $hi0,AT,$hi0
|
||||
|
||||
ldq $tj,16($tp)
|
||||
addq $lo1,$lo0,$j
|
||||
cmpult $j,$lo0,v0
|
||||
addq $hi1,v0,$hi1
|
||||
|
||||
addq $hi1,$hi0,$lo1
|
||||
stq $j,($tp)
|
||||
cmpult $lo1,$hi0,$hi1
|
||||
addq $lo1,$tj,$lo1
|
||||
cmpult $lo1,$tj,AT
|
||||
addl $i,1,$i
|
||||
addq $hi1,AT,$hi1
|
||||
stq $lo1,8($tp)
|
||||
cmplt $i,$num,$tj # borrow $tj
|
||||
stq $hi1,16($tp)
|
||||
bne $tj,.Louter
|
||||
|
||||
s8addq $num,sp,$tj # &tp[num]
|
||||
mov $rp,$bp # put rp aside
|
||||
mov sp,$tp
|
||||
mov sp,$ap
|
||||
mov 0,$hi0 # clear borrow bit
|
||||
|
||||
.align 4
|
||||
.Lsub: ldq $lo0,($tp)
|
||||
ldq $lo1,($np)
|
||||
lda $tp,8($tp)
|
||||
lda $np,8($np)
|
||||
subq $lo0,$lo1,$lo1 # tp[i]-np[i]
|
||||
cmpult $lo0,$lo1,AT
|
||||
subq $lo1,$hi0,$lo0
|
||||
cmpult $lo1,$lo0,$hi0
|
||||
or $hi0,AT,$hi0
|
||||
stq $lo0,($rp)
|
||||
cmpult $tp,$tj,v0
|
||||
lda $rp,8($rp)
|
||||
bne v0,.Lsub
|
||||
|
||||
subq $hi1,$hi0,$hi0 # handle upmost overflow bit
|
||||
mov sp,$tp
|
||||
mov $bp,$rp # restore rp
|
||||
|
||||
and sp,$hi0,$ap
|
||||
bic $bp,$hi0,$bp
|
||||
bis $bp,$ap,$ap # ap=borrow?tp:rp
|
||||
|
||||
.align 4
|
||||
.Lcopy: ldq $aj,($ap) # copy or in-place refresh
|
||||
lda $tp,8($tp)
|
||||
lda $rp,8($rp)
|
||||
lda $ap,8($ap)
|
||||
stq zero,-8($tp) # zap tp
|
||||
cmpult $tp,$tj,AT
|
||||
stq $aj,-8($rp)
|
||||
bne AT,.Lcopy
|
||||
mov 1,v0
|
||||
|
||||
.Lexit:
|
||||
.set noreorder
|
||||
mov fp,sp
|
||||
/*ldq ra,0(sp)*/
|
||||
ldq s3,8(sp)
|
||||
ldq s4,16(sp)
|
||||
ldq s5,24(sp)
|
||||
ldq fp,32(sp)
|
||||
lda sp,40(sp)
|
||||
ret (ra)
|
||||
.end bn_mul_mont
|
||||
.rdata
|
||||
.asciiz "Montgomery Multiplication for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
___
|
||||
|
||||
print $code;
|
||||
close STDOUT;
|
200
crypto/bn/asm/armv4-mont.pl
Normal file
200
crypto/bn/asm/armv4-mont.pl
Normal file
@@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# January 2007.
|
||||
|
||||
# Montgomery multiplication for ARMv4.
|
||||
#
|
||||
# Performance improvement naturally varies among CPU implementations
|
||||
# and compilers. The code was observed to provide +65-35% improvement
|
||||
# [depending on key length, less for longer keys] on ARM920T, and
|
||||
# +115-80% on Intel IXP425. This is compared to pre-bn_mul_mont code
|
||||
# base and compiler generated code with in-lined umull and even umlal
|
||||
# instructions. The latter means that this code didn't really have an
|
||||
# "advantage" of utilizing some "secret" instruction.
|
||||
#
|
||||
# The code is interoperable with Thumb ISA and is rather compact, less
|
||||
# than 1/2KB. Windows CE port would be trivial, as it's exclusively
|
||||
# about decorations, ABI and instruction syntax are identical.
|
||||
|
||||
$num="r0"; # starts as num argument, but holds &tp[num-1]
|
||||
$ap="r1";
|
||||
$bp="r2"; $bi="r2"; $rp="r2";
|
||||
$np="r3";
|
||||
$tp="r4";
|
||||
$aj="r5";
|
||||
$nj="r6";
|
||||
$tj="r7";
|
||||
$n0="r8";
|
||||
########### # r9 is reserved by ELF as platform specific, e.g. TLS pointer
|
||||
$alo="r10"; # sl, gcc uses it to keep @GOT
|
||||
$ahi="r11"; # fp
|
||||
$nlo="r12"; # ip
|
||||
########### # r13 is stack pointer
|
||||
$nhi="r14"; # lr
|
||||
########### # r15 is program counter
|
||||
|
||||
#### argument block layout relative to &tp[num-1], a.k.a. $num
|
||||
$_rp="$num,#12*4";
|
||||
# ap permanently resides in r1
|
||||
$_bp="$num,#13*4";
|
||||
# np permanently resides in r3
|
||||
$_n0="$num,#14*4";
|
||||
$_num="$num,#15*4"; $_bpend=$_num;
|
||||
|
||||
$code=<<___;
|
||||
.text
|
||||
|
||||
.global bn_mul_mont
|
||||
.type bn_mul_mont,%function
|
||||
|
||||
.align 2
|
||||
bn_mul_mont:
|
||||
stmdb sp!,{r0,r2} @ sp points at argument block
|
||||
ldr $num,[sp,#3*4] @ load num
|
||||
cmp $num,#2
|
||||
movlt r0,#0
|
||||
addlt sp,sp,#2*4
|
||||
blt .Labrt
|
||||
|
||||
stmdb sp!,{r4-r12,lr} @ save 10 registers
|
||||
|
||||
mov $num,$num,lsl#2 @ rescale $num for byte count
|
||||
sub sp,sp,$num @ alloca(4*num)
|
||||
sub sp,sp,#4 @ +extra dword
|
||||
sub $num,$num,#4 @ "num=num-1"
|
||||
add $tp,$bp,$num @ &bp[num-1]
|
||||
|
||||
add $num,sp,$num @ $num to point at &tp[num-1]
|
||||
ldr $n0,[$_n0] @ &n0
|
||||
ldr $bi,[$bp] @ bp[0]
|
||||
ldr $aj,[$ap],#4 @ ap[0],ap++
|
||||
ldr $nj,[$np],#4 @ np[0],np++
|
||||
ldr $n0,[$n0] @ *n0
|
||||
str $tp,[$_bpend] @ save &bp[num]
|
||||
|
||||
umull $alo,$ahi,$aj,$bi @ ap[0]*bp[0]
|
||||
str $n0,[$_n0] @ save n0 value
|
||||
mul $n0,$alo,$n0 @ "tp[0]"*n0
|
||||
mov $nlo,#0
|
||||
umlal $alo,$nlo,$nj,$n0 @ np[0]*n0+"t[0]"
|
||||
mov $tp,sp
|
||||
|
||||
.L1st:
|
||||
ldr $aj,[$ap],#4 @ ap[j],ap++
|
||||
mov $alo,$ahi
|
||||
mov $ahi,#0
|
||||
umlal $alo,$ahi,$aj,$bi @ ap[j]*bp[0]
|
||||
ldr $nj,[$np],#4 @ np[j],np++
|
||||
mov $nhi,#0
|
||||
umlal $nlo,$nhi,$nj,$n0 @ np[j]*n0
|
||||
adds $nlo,$nlo,$alo
|
||||
str $nlo,[$tp],#4 @ tp[j-1]=,tp++
|
||||
adc $nlo,$nhi,#0
|
||||
cmp $tp,$num
|
||||
bne .L1st
|
||||
|
||||
adds $nlo,$nlo,$ahi
|
||||
mov $nhi,#0
|
||||
adc $nhi,$nhi,#0
|
||||
ldr $tp,[$_bp] @ restore bp
|
||||
str $nlo,[$num] @ tp[num-1]=
|
||||
ldr $n0,[$_n0] @ restore n0
|
||||
str $nhi,[$num,#4] @ tp[num]=
|
||||
|
||||
.Louter:
|
||||
sub $tj,$num,sp @ "original" $num-1 value
|
||||
sub $ap,$ap,$tj @ "rewind" ap to &ap[1]
|
||||
sub $np,$np,$tj @ "rewind" np to &np[1]
|
||||
ldr $bi,[$tp,#4]! @ *(++bp)
|
||||
ldr $aj,[$ap,#-4] @ ap[0]
|
||||
ldr $nj,[$np,#-4] @ np[0]
|
||||
ldr $alo,[sp] @ tp[0]
|
||||
ldr $tj,[sp,#4] @ tp[1]
|
||||
|
||||
mov $ahi,#0
|
||||
umlal $alo,$ahi,$aj,$bi @ ap[0]*bp[i]+tp[0]
|
||||
str $tp,[$_bp] @ save bp
|
||||
mul $n0,$alo,$n0
|
||||
mov $nlo,#0
|
||||
umlal $alo,$nlo,$nj,$n0 @ np[0]*n0+"tp[0]"
|
||||
mov $tp,sp
|
||||
|
||||
.Linner:
|
||||
ldr $aj,[$ap],#4 @ ap[j],ap++
|
||||
adds $alo,$ahi,$tj @ +=tp[j]
|
||||
mov $ahi,#0
|
||||
umlal $alo,$ahi,$aj,$bi @ ap[j]*bp[i]
|
||||
ldr $nj,[$np],#4 @ np[j],np++
|
||||
mov $nhi,#0
|
||||
umlal $nlo,$nhi,$nj,$n0 @ np[j]*n0
|
||||
ldr $tj,[$tp,#8] @ tp[j+1]
|
||||
adc $ahi,$ahi,#0
|
||||
adds $nlo,$nlo,$alo
|
||||
str $nlo,[$tp],#4 @ tp[j-1]=,tp++
|
||||
adc $nlo,$nhi,#0
|
||||
cmp $tp,$num
|
||||
bne .Linner
|
||||
|
||||
adds $nlo,$nlo,$ahi
|
||||
mov $nhi,#0
|
||||
adc $nhi,$nhi,#0
|
||||
adds $nlo,$nlo,$tj
|
||||
adc $nhi,$nhi,#0
|
||||
ldr $tp,[$_bp] @ restore bp
|
||||
ldr $tj,[$_bpend] @ restore &bp[num]
|
||||
str $nlo,[$num] @ tp[num-1]=
|
||||
ldr $n0,[$_n0] @ restore n0
|
||||
str $nhi,[$num,#4] @ tp[num]=
|
||||
|
||||
cmp $tp,$tj
|
||||
bne .Louter
|
||||
|
||||
ldr $rp,[$_rp] @ pull rp
|
||||
add $num,$num,#4 @ $num to point at &tp[num]
|
||||
sub $aj,$num,sp @ "original" num value
|
||||
mov $tp,sp @ "rewind" $tp
|
||||
mov $ap,$tp @ "borrow" $ap
|
||||
sub $np,$np,$aj @ "rewind" $np to &np[0]
|
||||
|
||||
subs $tj,$tj,$tj @ "clear" carry flag
|
||||
.Lsub: ldr $tj,[$tp],#4
|
||||
ldr $nj,[$np],#4
|
||||
sbcs $tj,$tj,$nj @ tp[j]-np[j]
|
||||
str $tj,[$rp],#4 @ rp[j]=
|
||||
teq $tp,$num @ preserve carry
|
||||
bne .Lsub
|
||||
sbcs $nhi,$nhi,#0 @ upmost carry
|
||||
mov $tp,sp @ "rewind" $tp
|
||||
sub $rp,$rp,$aj @ "rewind" $rp
|
||||
|
||||
and $ap,$tp,$nhi
|
||||
bic $np,$rp,$nhi
|
||||
orr $ap,$ap,$np @ ap=borrow?tp:rp
|
||||
|
||||
.Lcopy: ldr $tj,[$ap],#4 @ copy or in-place refresh
|
||||
str sp,[$tp],#4 @ zap tp
|
||||
str $tj,[$rp],#4
|
||||
cmp $tp,$num
|
||||
bne .Lcopy
|
||||
|
||||
add sp,$num,#4 @ skip over tp[num+1]
|
||||
ldmia sp!,{r4-r12,lr} @ restore registers
|
||||
add sp,sp,#2*4 @ skip over {r0,r2}
|
||||
mov r0,#1
|
||||
.Labrt: tst lr,#1
|
||||
moveq pc,lr @ be binary compatible with V4, yet
|
||||
bx lr @ interoperable with Thumb ISA:-)
|
||||
.size bn_mul_mont,.-bn_mul_mont
|
||||
.asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
___
|
||||
|
||||
$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
|
||||
print $code;
|
||||
close STDOUT;
|
327
crypto/bn/asm/mips3-mont.pl
Normal file
327
crypto/bn/asm/mips3-mont.pl
Normal file
@@ -0,0 +1,327 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# This module doesn't present direct interest for OpenSSL, because it
|
||||
# doesn't provide better performance for longer keys. While 512-bit
|
||||
# RSA private key operations are 40% faster, 1024-bit ones are hardly
|
||||
# faster at all, while longer key operations are slower by up to 20%.
|
||||
# It might be of interest to embedded system developers though, as
|
||||
# it's smaller than 1KB, yet offers ~3x improvement over compiler
|
||||
# generated code.
|
||||
#
|
||||
# The module targets N32 and N64 MIPS ABIs and currently is a bit
|
||||
# IRIX-centric, i.e. is likely to require adaptation for other OSes.
|
||||
|
||||
# int bn_mul_mont(
|
||||
$rp="a0"; # BN_ULONG *rp,
|
||||
$ap="a1"; # const BN_ULONG *ap,
|
||||
$bp="a2"; # const BN_ULONG *bp,
|
||||
$np="a3"; # const BN_ULONG *np,
|
||||
$n0="a4"; # const BN_ULONG *n0,
|
||||
$num="a5"; # int num);
|
||||
|
||||
$lo0="a6";
|
||||
$hi0="a7";
|
||||
$lo1="v0";
|
||||
$hi1="v1";
|
||||
$aj="t0";
|
||||
$bi="t1";
|
||||
$nj="t2";
|
||||
$tp="t3";
|
||||
$alo="s0";
|
||||
$ahi="s1";
|
||||
$nlo="s2";
|
||||
$nhi="s3";
|
||||
$tj="s4";
|
||||
$i="s5";
|
||||
$j="s6";
|
||||
$fp="t8";
|
||||
$m1="t9";
|
||||
|
||||
$FRAME=8*(2+8);
|
||||
|
||||
$code=<<___;
|
||||
#include <asm.h>
|
||||
#include <regdef.h>
|
||||
|
||||
.text
|
||||
|
||||
.set noat
|
||||
.set reorder
|
||||
|
||||
.align 5
|
||||
.globl bn_mul_mont
|
||||
.ent bn_mul_mont
|
||||
bn_mul_mont:
|
||||
.set noreorder
|
||||
PTR_SUB sp,64
|
||||
move $fp,sp
|
||||
.frame $fp,64,ra
|
||||
slt AT,$num,4
|
||||
li v0,0
|
||||
beqzl AT,.Lproceed
|
||||
nop
|
||||
jr ra
|
||||
PTR_ADD sp,$fp,64
|
||||
.set reorder
|
||||
.align 5
|
||||
.Lproceed:
|
||||
ld $n0,0($n0)
|
||||
ld $bi,0($bp) # bp[0]
|
||||
ld $aj,0($ap) # ap[0]
|
||||
ld $nj,0($np) # np[0]
|
||||
PTR_SUB sp,16 # place for two extra words
|
||||
sll $num,3
|
||||
li AT,-4096
|
||||
PTR_SUB sp,$num
|
||||
and sp,AT
|
||||
|
||||
sd s0,0($fp)
|
||||
sd s1,8($fp)
|
||||
sd s2,16($fp)
|
||||
sd s3,24($fp)
|
||||
sd s4,32($fp)
|
||||
sd s5,40($fp)
|
||||
sd s6,48($fp)
|
||||
sd s7,56($fp)
|
||||
|
||||
dmultu $aj,$bi
|
||||
ld $alo,8($ap)
|
||||
ld $nlo,8($np)
|
||||
mflo $lo0
|
||||
mfhi $hi0
|
||||
dmultu $lo0,$n0
|
||||
mflo $m1
|
||||
|
||||
dmultu $alo,$bi
|
||||
mflo $alo
|
||||
mfhi $ahi
|
||||
|
||||
dmultu $nj,$m1
|
||||
mflo $lo1
|
||||
mfhi $hi1
|
||||
dmultu $nlo,$m1
|
||||
daddu $lo1,$lo0
|
||||
sltu AT,$lo1,$lo0
|
||||
daddu $hi1,AT
|
||||
mflo $nlo
|
||||
mfhi $nhi
|
||||
|
||||
move $tp,sp
|
||||
li $j,16
|
||||
.align 4
|
||||
.L1st:
|
||||
.set noreorder
|
||||
PTR_ADD $aj,$ap,$j
|
||||
ld $aj,($aj)
|
||||
PTR_ADD $nj,$np,$j
|
||||
ld $nj,($nj)
|
||||
|
||||
dmultu $aj,$bi
|
||||
daddu $lo0,$alo,$hi0
|
||||
daddu $lo1,$nlo,$hi1
|
||||
sltu AT,$lo0,$hi0
|
||||
sltu s7,$lo1,$hi1
|
||||
daddu $hi0,$ahi,AT
|
||||
daddu $hi1,$nhi,s7
|
||||
mflo $alo
|
||||
mfhi $ahi
|
||||
|
||||
daddu $lo1,$lo0
|
||||
sltu AT,$lo1,$lo0
|
||||
dmultu $nj,$m1
|
||||
daddu $hi1,AT
|
||||
addu $j,8
|
||||
sd $lo1,($tp)
|
||||
sltu s7,$j,$num
|
||||
mflo $nlo
|
||||
mfhi $nhi
|
||||
|
||||
bnez s7,.L1st
|
||||
PTR_ADD $tp,8
|
||||
.set reorder
|
||||
|
||||
daddu $lo0,$alo,$hi0
|
||||
sltu AT,$lo0,$hi0
|
||||
daddu $hi0,$ahi,AT
|
||||
|
||||
daddu $lo1,$nlo,$hi1
|
||||
sltu s7,$lo1,$hi1
|
||||
daddu $hi1,$nhi,s7
|
||||
daddu $lo1,$lo0
|
||||
sltu AT,$lo1,$lo0
|
||||
daddu $hi1,AT
|
||||
|
||||
sd $lo1,($tp)
|
||||
|
||||
daddu $hi1,$hi0
|
||||
sltu AT,$hi1,$hi0
|
||||
sd $hi1,8($tp)
|
||||
sd AT,16($tp)
|
||||
|
||||
li $i,8
|
||||
.align 4
|
||||
.Louter:
|
||||
PTR_ADD $bi,$bp,$i
|
||||
ld $bi,($bi)
|
||||
ld $aj,($ap)
|
||||
ld $alo,8($ap)
|
||||
ld $tj,(sp)
|
||||
|
||||
dmultu $aj,$bi
|
||||
ld $nj,($np)
|
||||
ld $nlo,8($np)
|
||||
mflo $lo0
|
||||
mfhi $hi0
|
||||
daddu $lo0,$tj
|
||||
dmultu $lo0,$n0
|
||||
sltu AT,$lo0,$tj
|
||||
daddu $hi0,AT
|
||||
mflo $m1
|
||||
|
||||
dmultu $alo,$bi
|
||||
mflo $alo
|
||||
mfhi $ahi
|
||||
|
||||
dmultu $nj,$m1
|
||||
mflo $lo1
|
||||
mfhi $hi1
|
||||
|
||||
dmultu $nlo,$m1
|
||||
daddu $lo1,$lo0
|
||||
sltu AT,$lo1,$lo0
|
||||
daddu $hi1,AT
|
||||
mflo $nlo
|
||||
mfhi $nhi
|
||||
|
||||
move $tp,sp
|
||||
li $j,16
|
||||
ld $tj,8($tp)
|
||||
.align 4
|
||||
.Linner:
|
||||
.set noreorder
|
||||
PTR_ADD $aj,$ap,$j
|
||||
ld $aj,($aj)
|
||||
PTR_ADD $nj,$np,$j
|
||||
ld $nj,($nj)
|
||||
|
||||
dmultu $aj,$bi
|
||||
daddu $lo0,$alo,$hi0
|
||||
daddu $lo1,$nlo,$hi1
|
||||
sltu AT,$lo0,$hi0
|
||||
sltu s7,$lo1,$hi1
|
||||
daddu $hi0,$ahi,AT
|
||||
daddu $hi1,$nhi,s7
|
||||
mflo $alo
|
||||
mfhi $ahi
|
||||
|
||||
daddu $lo0,$tj
|
||||
addu $j,8
|
||||
dmultu $nj,$m1
|
||||
sltu AT,$lo0,$tj
|
||||
daddu $lo1,$lo0
|
||||
daddu $hi0,AT
|
||||
sltu s7,$lo1,$lo0
|
||||
ld $tj,16($tp)
|
||||
daddu $hi1,s7
|
||||
sltu AT,$j,$num
|
||||
mflo $nlo
|
||||
mfhi $nhi
|
||||
sd $lo1,($tp)
|
||||
bnez AT,.Linner
|
||||
PTR_ADD $tp,8
|
||||
.set reorder
|
||||
|
||||
daddu $lo0,$alo,$hi0
|
||||
sltu AT,$lo0,$hi0
|
||||
daddu $hi0,$ahi,AT
|
||||
daddu $lo0,$tj
|
||||
sltu s7,$lo0,$tj
|
||||
daddu $hi0,s7
|
||||
|
||||
ld $tj,16($tp)
|
||||
daddu $lo1,$nlo,$hi1
|
||||
sltu AT,$lo1,$hi1
|
||||
daddu $hi1,$nhi,AT
|
||||
daddu $lo1,$lo0
|
||||
sltu s7,$lo1,$lo0
|
||||
daddu $hi1,s7
|
||||
sd $lo1,($tp)
|
||||
|
||||
daddu $lo1,$hi1,$hi0
|
||||
sltu $hi1,$lo1,$hi0
|
||||
daddu $lo1,$tj
|
||||
sltu AT,$lo1,$tj
|
||||
daddu $hi1,AT
|
||||
sd $lo1,8($tp)
|
||||
sd $hi1,16($tp)
|
||||
|
||||
addu $i,8
|
||||
sltu s7,$i,$num
|
||||
bnez s7,.Louter
|
||||
|
||||
.set noreorder
|
||||
PTR_ADD $tj,sp,$num # &tp[num]
|
||||
move $tp,sp
|
||||
move $ap,sp
|
||||
li $hi0,0 # clear borrow bit
|
||||
|
||||
.align 4
|
||||
.Lsub: ld $lo0,($tp)
|
||||
ld $lo1,($np)
|
||||
PTR_ADD $tp,8
|
||||
PTR_ADD $np,8
|
||||
dsubu $lo1,$lo0,$lo1 # tp[i]-np[i]
|
||||
sgtu AT,$lo1,$lo0
|
||||
dsubu $lo0,$lo1,$hi0
|
||||
sgtu $hi0,$lo0,$lo1
|
||||
sd $lo0,($rp)
|
||||
or $hi0,AT
|
||||
sltu AT,$tp,$tj
|
||||
bnez AT,.Lsub
|
||||
PTR_ADD $rp,8
|
||||
|
||||
dsubu $hi0,$hi1,$hi0 # handle upmost overflow bit
|
||||
move $tp,sp
|
||||
PTR_SUB $rp,$num # restore rp
|
||||
not $hi1,$hi0
|
||||
|
||||
and $ap,$hi0,sp
|
||||
and $bp,$hi1,$rp
|
||||
or $ap,$ap,$bp # ap=borrow?tp:rp
|
||||
|
||||
.align 4
|
||||
.Lcopy: ld $aj,($ap)
|
||||
PTR_ADD $ap,8
|
||||
PTR_ADD $tp,8
|
||||
sd zero,-8($tp)
|
||||
sltu AT,$tp,$tj
|
||||
sd $aj,($rp)
|
||||
bnez AT,.Lcopy
|
||||
PTR_ADD $rp,8
|
||||
|
||||
ld s0,0($fp)
|
||||
ld s1,8($fp)
|
||||
ld s2,16($fp)
|
||||
ld s3,24($fp)
|
||||
ld s4,32($fp)
|
||||
ld s5,40($fp)
|
||||
ld s6,48($fp)
|
||||
ld s7,56($fp)
|
||||
li v0,1
|
||||
jr ra
|
||||
PTR_ADD sp,$fp,64
|
||||
.set reorder
|
||||
END(bn_mul_mont)
|
||||
.rdata
|
||||
.asciiz "Montgomery Multiplication for MIPS III/IV, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
___
|
||||
|
||||
print $code;
|
||||
close STDOUT;
|
323
crypto/bn/asm/ppc-mont.pl
Normal file
323
crypto/bn/asm/ppc-mont.pl
Normal file
@@ -0,0 +1,323 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# April 2006
|
||||
|
||||
# "Teaser" Montgomery multiplication module for PowerPC. It's possible
|
||||
# to gain a bit more by modulo-scheduling outer loop, then dedicated
|
||||
# squaring procedure should give further 20% and code can be adapted
|
||||
# for 32-bit application running on 64-bit CPU. As for the latter.
|
||||
# It won't be able to achieve "native" 64-bit performance, because in
|
||||
# 32-bit application context every addc instruction will have to be
|
||||
# expanded as addc, twice right shift by 32 and finally adde, etc.
|
||||
# So far RSA *sign* performance improvement over pre-bn_mul_mont asm
|
||||
# for 64-bit application running on PPC970/G5 is:
|
||||
#
|
||||
# 512-bit +65%
|
||||
# 1024-bit +35%
|
||||
# 2048-bit +18%
|
||||
# 4096-bit +4%
|
||||
|
||||
$flavour = shift;
|
||||
|
||||
if ($flavour =~ /32/) {
|
||||
$BITS= 32;
|
||||
$BNSZ= $BITS/8;
|
||||
$SIZE_T=4;
|
||||
$RZONE= 224;
|
||||
$FRAME= $SIZE_T*16;
|
||||
|
||||
$LD= "lwz"; # load
|
||||
$LDU= "lwzu"; # load and update
|
||||
$LDX= "lwzx"; # load indexed
|
||||
$ST= "stw"; # store
|
||||
$STU= "stwu"; # store and update
|
||||
$STX= "stwx"; # store indexed
|
||||
$STUX= "stwux"; # store indexed and update
|
||||
$UMULL= "mullw"; # unsigned multiply low
|
||||
$UMULH= "mulhwu"; # unsigned multiply high
|
||||
$UCMP= "cmplw"; # unsigned compare
|
||||
$SHRI= "srwi"; # unsigned shift right by immediate
|
||||
$PUSH= $ST;
|
||||
$POP= $LD;
|
||||
} elsif ($flavour =~ /64/) {
|
||||
$BITS= 64;
|
||||
$BNSZ= $BITS/8;
|
||||
$SIZE_T=8;
|
||||
$RZONE= 288;
|
||||
$FRAME= $SIZE_T*16;
|
||||
|
||||
# same as above, but 64-bit mnemonics...
|
||||
$LD= "ld"; # load
|
||||
$LDU= "ldu"; # load and update
|
||||
$LDX= "ldx"; # load indexed
|
||||
$ST= "std"; # store
|
||||
$STU= "stdu"; # store and update
|
||||
$STX= "stdx"; # store indexed
|
||||
$STUX= "stdux"; # store indexed and update
|
||||
$UMULL= "mulld"; # unsigned multiply low
|
||||
$UMULH= "mulhdu"; # unsigned multiply high
|
||||
$UCMP= "cmpld"; # unsigned compare
|
||||
$SHRI= "srdi"; # unsigned shift right by immediate
|
||||
$PUSH= $ST;
|
||||
$POP= $LD;
|
||||
} else { die "nonsense $flavour"; }
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
|
||||
( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
|
||||
die "can't locate ppc-xlate.pl";
|
||||
|
||||
open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
|
||||
|
||||
$sp="r1";
|
||||
$toc="r2";
|
||||
$rp="r3"; $ovf="r3";
|
||||
$ap="r4";
|
||||
$bp="r5";
|
||||
$np="r6";
|
||||
$n0="r7";
|
||||
$num="r8";
|
||||
$rp="r9"; # $rp is reassigned
|
||||
$aj="r10";
|
||||
$nj="r11";
|
||||
$tj="r12";
|
||||
# non-volatile registers
|
||||
$i="r14";
|
||||
$j="r15";
|
||||
$tp="r16";
|
||||
$m0="r17";
|
||||
$m1="r18";
|
||||
$lo0="r19";
|
||||
$hi0="r20";
|
||||
$lo1="r21";
|
||||
$hi1="r22";
|
||||
$alo="r23";
|
||||
$ahi="r24";
|
||||
$nlo="r25";
|
||||
#
|
||||
$nhi="r0";
|
||||
|
||||
$code=<<___;
|
||||
.machine "any"
|
||||
.text
|
||||
|
||||
.globl .bn_mul_mont
|
||||
.align 4
|
||||
.bn_mul_mont:
|
||||
cmpwi $num,4
|
||||
mr $rp,r3 ; $rp is reassigned
|
||||
li r3,0
|
||||
bltlr
|
||||
|
||||
slwi $num,$num,`log($BNSZ)/log(2)`
|
||||
li $tj,-4096
|
||||
addi $ovf,$num,`$FRAME+$RZONE`
|
||||
subf $ovf,$ovf,$sp ; $sp-$ovf
|
||||
and $ovf,$ovf,$tj ; minimize TLB usage
|
||||
subf $ovf,$sp,$ovf ; $ovf-$sp
|
||||
srwi $num,$num,`log($BNSZ)/log(2)`
|
||||
$STUX $sp,$sp,$ovf
|
||||
|
||||
$PUSH r14,`4*$SIZE_T`($sp)
|
||||
$PUSH r15,`5*$SIZE_T`($sp)
|
||||
$PUSH r16,`6*$SIZE_T`($sp)
|
||||
$PUSH r17,`7*$SIZE_T`($sp)
|
||||
$PUSH r18,`8*$SIZE_T`($sp)
|
||||
$PUSH r19,`9*$SIZE_T`($sp)
|
||||
$PUSH r20,`10*$SIZE_T`($sp)
|
||||
$PUSH r21,`11*$SIZE_T`($sp)
|
||||
$PUSH r22,`12*$SIZE_T`($sp)
|
||||
$PUSH r23,`13*$SIZE_T`($sp)
|
||||
$PUSH r24,`14*$SIZE_T`($sp)
|
||||
$PUSH r25,`15*$SIZE_T`($sp)
|
||||
|
||||
$LD $n0,0($n0) ; pull n0[0] value
|
||||
addi $num,$num,-2 ; adjust $num for counter register
|
||||
|
||||
$LD $m0,0($bp) ; m0=bp[0]
|
||||
$LD $aj,0($ap) ; ap[0]
|
||||
addi $tp,$sp,$FRAME
|
||||
$UMULL $lo0,$aj,$m0 ; ap[0]*bp[0]
|
||||
$UMULH $hi0,$aj,$m0
|
||||
|
||||
$LD $aj,$BNSZ($ap) ; ap[1]
|
||||
$LD $nj,0($np) ; np[0]
|
||||
|
||||
$UMULL $m1,$lo0,$n0 ; "tp[0]"*n0
|
||||
|
||||
$UMULL $alo,$aj,$m0 ; ap[1]*bp[0]
|
||||
$UMULH $ahi,$aj,$m0
|
||||
|
||||
$UMULL $lo1,$nj,$m1 ; np[0]*m1
|
||||
$UMULH $hi1,$nj,$m1
|
||||
$LD $nj,$BNSZ($np) ; np[1]
|
||||
addc $lo1,$lo1,$lo0
|
||||
addze $hi1,$hi1
|
||||
|
||||
$UMULL $nlo,$nj,$m1 ; np[1]*m1
|
||||
$UMULH $nhi,$nj,$m1
|
||||
|
||||
mtctr $num
|
||||
li $j,`2*$BNSZ`
|
||||
.align 4
|
||||
L1st:
|
||||
$LDX $aj,$ap,$j ; ap[j]
|
||||
addc $lo0,$alo,$hi0
|
||||
$LDX $nj,$np,$j ; np[j]
|
||||
addze $hi0,$ahi
|
||||
$UMULL $alo,$aj,$m0 ; ap[j]*bp[0]
|
||||
addc $lo1,$nlo,$hi1
|
||||
$UMULH $ahi,$aj,$m0
|
||||
addze $hi1,$nhi
|
||||
$UMULL $nlo,$nj,$m1 ; np[j]*m1
|
||||
addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[0]
|
||||
$UMULH $nhi,$nj,$m1
|
||||
addze $hi1,$hi1
|
||||
$ST $lo1,0($tp) ; tp[j-1]
|
||||
|
||||
addi $j,$j,$BNSZ ; j++
|
||||
addi $tp,$tp,$BNSZ ; tp++
|
||||
bdnz- L1st
|
||||
;L1st
|
||||
addc $lo0,$alo,$hi0
|
||||
addze $hi0,$ahi
|
||||
|
||||
addc $lo1,$nlo,$hi1
|
||||
addze $hi1,$nhi
|
||||
addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[0]
|
||||
addze $hi1,$hi1
|
||||
$ST $lo1,0($tp) ; tp[j-1]
|
||||
|
||||
li $ovf,0
|
||||
addc $hi1,$hi1,$hi0
|
||||
addze $ovf,$ovf ; upmost overflow bit
|
||||
$ST $hi1,$BNSZ($tp)
|
||||
|
||||
li $i,$BNSZ
|
||||
.align 4
|
||||
Louter:
|
||||
$LDX $m0,$bp,$i ; m0=bp[i]
|
||||
$LD $aj,0($ap) ; ap[0]
|
||||
addi $tp,$sp,$FRAME
|
||||
$LD $tj,$FRAME($sp) ; tp[0]
|
||||
$UMULL $lo0,$aj,$m0 ; ap[0]*bp[i]
|
||||
$UMULH $hi0,$aj,$m0
|
||||
$LD $aj,$BNSZ($ap) ; ap[1]
|
||||
$LD $nj,0($np) ; np[0]
|
||||
addc $lo0,$lo0,$tj ; ap[0]*bp[i]+tp[0]
|
||||
$UMULL $alo,$aj,$m0 ; ap[j]*bp[i]
|
||||
addze $hi0,$hi0
|
||||
$UMULL $m1,$lo0,$n0 ; tp[0]*n0
|
||||
$UMULH $ahi,$aj,$m0
|
||||
$UMULL $lo1,$nj,$m1 ; np[0]*m1
|
||||
$UMULH $hi1,$nj,$m1
|
||||
$LD $nj,$BNSZ($np) ; np[1]
|
||||
addc $lo1,$lo1,$lo0
|
||||
$UMULL $nlo,$nj,$m1 ; np[1]*m1
|
||||
addze $hi1,$hi1
|
||||
$UMULH $nhi,$nj,$m1
|
||||
|
||||
mtctr $num
|
||||
li $j,`2*$BNSZ`
|
||||
.align 4
|
||||
Linner:
|
||||
$LDX $aj,$ap,$j ; ap[j]
|
||||
addc $lo0,$alo,$hi0
|
||||
$LD $tj,$BNSZ($tp) ; tp[j]
|
||||
addze $hi0,$ahi
|
||||
$LDX $nj,$np,$j ; np[j]
|
||||
addc $lo1,$nlo,$hi1
|
||||
$UMULL $alo,$aj,$m0 ; ap[j]*bp[i]
|
||||
addze $hi1,$nhi
|
||||
$UMULH $ahi,$aj,$m0
|
||||
addc $lo0,$lo0,$tj ; ap[j]*bp[i]+tp[j]
|
||||
$UMULL $nlo,$nj,$m1 ; np[j]*m1
|
||||
addze $hi0,$hi0
|
||||
$UMULH $nhi,$nj,$m1
|
||||
addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[i]+tp[j]
|
||||
addi $j,$j,$BNSZ ; j++
|
||||
addze $hi1,$hi1
|
||||
$ST $lo1,0($tp) ; tp[j-1]
|
||||
addi $tp,$tp,$BNSZ ; tp++
|
||||
bdnz- Linner
|
||||
;Linner
|
||||
$LD $tj,$BNSZ($tp) ; tp[j]
|
||||
addc $lo0,$alo,$hi0
|
||||
addze $hi0,$ahi
|
||||
addc $lo0,$lo0,$tj ; ap[j]*bp[i]+tp[j]
|
||||
addze $hi0,$hi0
|
||||
|
||||
addc $lo1,$nlo,$hi1
|
||||
addze $hi1,$nhi
|
||||
addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[i]+tp[j]
|
||||
addze $hi1,$hi1
|
||||
$ST $lo1,0($tp) ; tp[j-1]
|
||||
|
||||
addic $ovf,$ovf,-1 ; move upmost overflow to XER[CA]
|
||||
li $ovf,0
|
||||
adde $hi1,$hi1,$hi0
|
||||
addze $ovf,$ovf
|
||||
$ST $hi1,$BNSZ($tp)
|
||||
;
|
||||
slwi $tj,$num,`log($BNSZ)/log(2)`
|
||||
$UCMP $i,$tj
|
||||
addi $i,$i,$BNSZ
|
||||
ble- Louter
|
||||
|
||||
addi $num,$num,2 ; restore $num
|
||||
subfc $j,$j,$j ; j=0 and "clear" XER[CA]
|
||||
addi $tp,$sp,$FRAME
|
||||
mtctr $num
|
||||
|
||||
.align 4
|
||||
Lsub: $LDX $tj,$tp,$j
|
||||
$LDX $nj,$np,$j
|
||||
subfe $aj,$nj,$tj ; tp[j]-np[j]
|
||||
$STX $aj,$rp,$j
|
||||
addi $j,$j,$BNSZ
|
||||
bdnz- Lsub
|
||||
|
||||
li $j,0
|
||||
mtctr $num
|
||||
subfe $ovf,$j,$ovf ; handle upmost overflow bit
|
||||
and $ap,$tp,$ovf
|
||||
andc $np,$rp,$ovf
|
||||
or $ap,$ap,$np ; ap=borrow?tp:rp
|
||||
|
||||
.align 4
|
||||
Lcopy: ; copy or in-place refresh
|
||||
$LDX $tj,$ap,$j
|
||||
$STX $tj,$rp,$j
|
||||
$STX $j,$tp,$j ; zap at once
|
||||
addi $j,$j,$BNSZ
|
||||
bdnz- Lcopy
|
||||
|
||||
$POP r14,`4*$SIZE_T`($sp)
|
||||
$POP r15,`5*$SIZE_T`($sp)
|
||||
$POP r16,`6*$SIZE_T`($sp)
|
||||
$POP r17,`7*$SIZE_T`($sp)
|
||||
$POP r18,`8*$SIZE_T`($sp)
|
||||
$POP r19,`9*$SIZE_T`($sp)
|
||||
$POP r20,`10*$SIZE_T`($sp)
|
||||
$POP r21,`11*$SIZE_T`($sp)
|
||||
$POP r22,`12*$SIZE_T`($sp)
|
||||
$POP r23,`13*$SIZE_T`($sp)
|
||||
$POP r24,`14*$SIZE_T`($sp)
|
||||
$POP r25,`15*$SIZE_T`($sp)
|
||||
$POP $sp,0($sp)
|
||||
li r3,1
|
||||
blr
|
||||
.long 0
|
||||
.asciz "Montgomery Multiplication for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
|
||||
___
|
||||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
918
crypto/bn/asm/ppc64-mont.pl
Normal file
918
crypto/bn/asm/ppc64-mont.pl
Normal file
@@ -0,0 +1,918 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# December 2007
|
||||
|
||||
# The reason for undertaken effort is basically following. Even though
|
||||
# Power 6 CPU operates at incredible 4.7GHz clock frequency, its PKI
|
||||
# performance was observed to be less than impressive, essentially as
|
||||
# fast as 1.8GHz PPC970, or 2.6 times(!) slower than one would hope.
|
||||
# Well, it's not surprising that IBM had to make some sacrifices to
|
||||
# boost the clock frequency that much, but no overall improvement?
|
||||
# Having observed how much difference did switching to FPU make on
|
||||
# UltraSPARC, playing same stunt on Power 6 appeared appropriate...
|
||||
# Unfortunately the resulting performance improvement is not as
|
||||
# impressive, ~30%, and in absolute terms is still very far from what
|
||||
# one would expect from 4.7GHz CPU. There is a chance that I'm doing
|
||||
# something wrong, but in the lack of assembler level micro-profiling
|
||||
# data or at least decent platform guide I can't tell... Or better
|
||||
# results might be achieved with VMX... Anyway, this module provides
|
||||
# *worse* performance on other PowerPC implementations, ~40-15% slower
|
||||
# on PPC970 depending on key length and ~40% slower on Power 5 for all
|
||||
# key lengths. As it's obviously inappropriate as "best all-round"
|
||||
# alternative, it has to be complemented with run-time CPU family
|
||||
# detection. Oh! It should also be noted that unlike other PowerPC
|
||||
# implementation IALU ppc-mont.pl module performs *suboptimaly* on
|
||||
# >=1024-bit key lengths on Power 6. It should also be noted that
|
||||
# *everything* said so far applies to 64-bit builds! As far as 32-bit
|
||||
# application executed on 64-bit CPU goes, this module is likely to
|
||||
# become preferred choice, because it's easy to adapt it for such
|
||||
# case and *is* faster than 32-bit ppc-mont.pl on *all* processors.
|
||||
|
||||
# February 2008
|
||||
|
||||
# Micro-profiling assisted optimization results in ~15% improvement
|
||||
# over original ppc64-mont.pl version, or overall ~50% improvement
|
||||
# over ppc.pl module on Power 6. If compared to ppc-mont.pl on same
|
||||
# Power 6 CPU, this module is 5-150% faster depending on key length,
|
||||
# [hereafter] more for longer keys. But if compared to ppc-mont.pl
|
||||
# on 1.8GHz PPC970, it's only 5-55% faster. Still far from impressive
|
||||
# in absolute terms, but it's apparently the way Power 6 is...
|
||||
|
||||
$flavour = shift;
|
||||
|
||||
if ($flavour =~ /32/) {
|
||||
$SIZE_T=4;
|
||||
$RZONE= 224;
|
||||
$FRAME= $SIZE_T*12+8*12;
|
||||
$fname= "bn_mul_mont_ppc64";
|
||||
|
||||
$STUX= "stwux"; # store indexed and update
|
||||
$PUSH= "stw";
|
||||
$POP= "lwz";
|
||||
die "not implemented yet";
|
||||
} elsif ($flavour =~ /64/) {
|
||||
$SIZE_T=8;
|
||||
$RZONE= 288;
|
||||
$FRAME= $SIZE_T*12+8*12;
|
||||
$fname= "bn_mul_mont";
|
||||
|
||||
# same as above, but 64-bit mnemonics...
|
||||
$STUX= "stdux"; # store indexed and update
|
||||
$PUSH= "std";
|
||||
$POP= "ld";
|
||||
} else { die "nonsense $flavour"; }
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
|
||||
( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
|
||||
die "can't locate ppc-xlate.pl";
|
||||
|
||||
open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
|
||||
|
||||
$FRAME=($FRAME+63)&~63;
|
||||
$TRANSFER=16*8;
|
||||
|
||||
$carry="r0";
|
||||
$sp="r1";
|
||||
$toc="r2";
|
||||
$rp="r3"; $ovf="r3";
|
||||
$ap="r4";
|
||||
$bp="r5";
|
||||
$np="r6";
|
||||
$n0="r7";
|
||||
$num="r8";
|
||||
$rp="r9"; # $rp is reassigned
|
||||
$tp="r10";
|
||||
$j="r11";
|
||||
$i="r12";
|
||||
# non-volatile registers
|
||||
$nap_d="r14"; # interleaved ap and np in double format
|
||||
$a0="r15"; # ap[0]
|
||||
$t0="r16"; # temporary registers
|
||||
$t1="r17";
|
||||
$t2="r18";
|
||||
$t3="r19";
|
||||
$t4="r20";
|
||||
$t5="r21";
|
||||
$t6="r22";
|
||||
$t7="r23";
|
||||
|
||||
# PPC offers enough register bank capacity to unroll inner loops twice
|
||||
#
|
||||
# ..A3A2A1A0
|
||||
# dcba
|
||||
# -----------
|
||||
# A0a
|
||||
# A0b
|
||||
# A0c
|
||||
# A0d
|
||||
# A1a
|
||||
# A1b
|
||||
# A1c
|
||||
# A1d
|
||||
# A2a
|
||||
# A2b
|
||||
# A2c
|
||||
# A2d
|
||||
# A3a
|
||||
# A3b
|
||||
# A3c
|
||||
# A3d
|
||||
# ..a
|
||||
# ..b
|
||||
#
|
||||
$ba="f0"; $bb="f1"; $bc="f2"; $bd="f3";
|
||||
$na="f4"; $nb="f5"; $nc="f6"; $nd="f7";
|
||||
$dota="f8"; $dotb="f9";
|
||||
$A0="f10"; $A1="f11"; $A2="f12"; $A3="f13";
|
||||
$N0="f14"; $N1="f15"; $N2="f16"; $N3="f17";
|
||||
$T0a="f18"; $T0b="f19";
|
||||
$T1a="f20"; $T1b="f21";
|
||||
$T2a="f22"; $T2b="f23";
|
||||
$T3a="f24"; $T3b="f25";
|
||||
|
||||
# sp----------->+-------------------------------+
|
||||
# | saved sp |
|
||||
# +-------------------------------+
|
||||
# | |
|
||||
# +-------------------------------+
|
||||
# | 10 saved gpr, r14-r23 |
|
||||
# . .
|
||||
# . .
|
||||
# +12*size_t +-------------------------------+
|
||||
# | 12 saved fpr, f14-f25 |
|
||||
# . .
|
||||
# . .
|
||||
# +12*8 +-------------------------------+
|
||||
# | padding to 64 byte boundary |
|
||||
# . .
|
||||
# +X +-------------------------------+
|
||||
# | 16 gpr<->fpr transfer zone |
|
||||
# . .
|
||||
# . .
|
||||
# +16*8 +-------------------------------+
|
||||
# | __int64 tmp[-1] |
|
||||
# +-------------------------------+
|
||||
# | __int64 tmp[num] |
|
||||
# . .
|
||||
# . .
|
||||
# . .
|
||||
# +(num+1)*8 +-------------------------------+
|
||||
# | padding to 64 byte boundary |
|
||||
# . .
|
||||
# +X +-------------------------------+
|
||||
# | double nap_d[4*num] |
|
||||
# . .
|
||||
# . .
|
||||
# . .
|
||||
# +-------------------------------+
|
||||
|
||||
$code=<<___;
|
||||
.machine "any"
|
||||
.text
|
||||
|
||||
.globl .$fname
|
||||
.align 5
|
||||
.$fname:
|
||||
cmpwi $num,4
|
||||
mr $rp,r3 ; $rp is reassigned
|
||||
li r3,0 ; possible "not handled" return code
|
||||
bltlr-
|
||||
andi. r0,$num,1 ; $num has to be even
|
||||
bnelr-
|
||||
|
||||
slwi $num,$num,3 ; num*=8
|
||||
li $i,-4096
|
||||
slwi $tp,$num,2 ; place for {an}p_{lh}[num], i.e. 4*num
|
||||
add $tp,$tp,$num ; place for tp[num+1]
|
||||
addi $tp,$tp,`$FRAME+$TRANSFER+8+64+$RZONE`
|
||||
subf $tp,$tp,$sp ; $sp-$tp
|
||||
and $tp,$tp,$i ; minimize TLB usage
|
||||
subf $tp,$sp,$tp ; $tp-$sp
|
||||
$STUX $sp,$sp,$tp ; alloca
|
||||
|
||||
$PUSH r14,`2*$SIZE_T`($sp)
|
||||
$PUSH r15,`3*$SIZE_T`($sp)
|
||||
$PUSH r16,`4*$SIZE_T`($sp)
|
||||
$PUSH r17,`5*$SIZE_T`($sp)
|
||||
$PUSH r18,`6*$SIZE_T`($sp)
|
||||
$PUSH r19,`7*$SIZE_T`($sp)
|
||||
$PUSH r20,`8*$SIZE_T`($sp)
|
||||
$PUSH r21,`9*$SIZE_T`($sp)
|
||||
$PUSH r22,`10*$SIZE_T`($sp)
|
||||
$PUSH r23,`11*$SIZE_T`($sp)
|
||||
stfd f14,`12*$SIZE_T+0`($sp)
|
||||
stfd f15,`12*$SIZE_T+8`($sp)
|
||||
stfd f16,`12*$SIZE_T+16`($sp)
|
||||
stfd f17,`12*$SIZE_T+24`($sp)
|
||||
stfd f18,`12*$SIZE_T+32`($sp)
|
||||
stfd f19,`12*$SIZE_T+40`($sp)
|
||||
stfd f20,`12*$SIZE_T+48`($sp)
|
||||
stfd f21,`12*$SIZE_T+56`($sp)
|
||||
stfd f22,`12*$SIZE_T+64`($sp)
|
||||
stfd f23,`12*$SIZE_T+72`($sp)
|
||||
stfd f24,`12*$SIZE_T+80`($sp)
|
||||
stfd f25,`12*$SIZE_T+88`($sp)
|
||||
|
||||
ld $a0,0($ap) ; pull ap[0] value
|
||||
ld $n0,0($n0) ; pull n0[0] value
|
||||
ld $t3,0($bp) ; bp[0]
|
||||
|
||||
addi $tp,$sp,`$FRAME+$TRANSFER+8+64`
|
||||
li $i,-64
|
||||
add $nap_d,$tp,$num
|
||||
and $nap_d,$nap_d,$i ; align to 64 bytes
|
||||
|
||||
mulld $t7,$a0,$t3 ; ap[0]*bp[0]
|
||||
; nap_d is off by 1, because it's used with stfdu/lfdu
|
||||
addi $nap_d,$nap_d,-8
|
||||
srwi $j,$num,`3+1` ; counter register, num/2
|
||||
mulld $t7,$t7,$n0 ; tp[0]*n0
|
||||
addi $j,$j,-1
|
||||
addi $tp,$sp,`$FRAME+$TRANSFER-8`
|
||||
li $carry,0
|
||||
mtctr $j
|
||||
|
||||
; transfer bp[0] to FPU as 4x16-bit values
|
||||
extrdi $t0,$t3,16,48
|
||||
extrdi $t1,$t3,16,32
|
||||
extrdi $t2,$t3,16,16
|
||||
extrdi $t3,$t3,16,0
|
||||
std $t0,`$FRAME+0`($sp)
|
||||
std $t1,`$FRAME+8`($sp)
|
||||
std $t2,`$FRAME+16`($sp)
|
||||
std $t3,`$FRAME+24`($sp)
|
||||
; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values
|
||||
extrdi $t4,$t7,16,48
|
||||
extrdi $t5,$t7,16,32
|
||||
extrdi $t6,$t7,16,16
|
||||
extrdi $t7,$t7,16,0
|
||||
std $t4,`$FRAME+32`($sp)
|
||||
std $t5,`$FRAME+40`($sp)
|
||||
std $t6,`$FRAME+48`($sp)
|
||||
std $t7,`$FRAME+56`($sp)
|
||||
lwz $t0,4($ap) ; load a[j] as 32-bit word pair
|
||||
lwz $t1,0($ap)
|
||||
lwz $t2,12($ap) ; load a[j+1] as 32-bit word pair
|
||||
lwz $t3,8($ap)
|
||||
lwz $t4,4($np) ; load n[j] as 32-bit word pair
|
||||
lwz $t5,0($np)
|
||||
lwz $t6,12($np) ; load n[j+1] as 32-bit word pair
|
||||
lwz $t7,8($np)
|
||||
lfd $ba,`$FRAME+0`($sp)
|
||||
lfd $bb,`$FRAME+8`($sp)
|
||||
lfd $bc,`$FRAME+16`($sp)
|
||||
lfd $bd,`$FRAME+24`($sp)
|
||||
lfd $na,`$FRAME+32`($sp)
|
||||
lfd $nb,`$FRAME+40`($sp)
|
||||
lfd $nc,`$FRAME+48`($sp)
|
||||
lfd $nd,`$FRAME+56`($sp)
|
||||
std $t0,`$FRAME+64`($sp)
|
||||
std $t1,`$FRAME+72`($sp)
|
||||
std $t2,`$FRAME+80`($sp)
|
||||
std $t3,`$FRAME+88`($sp)
|
||||
std $t4,`$FRAME+96`($sp)
|
||||
std $t5,`$FRAME+104`($sp)
|
||||
std $t6,`$FRAME+112`($sp)
|
||||
std $t7,`$FRAME+120`($sp)
|
||||
fcfid $ba,$ba
|
||||
fcfid $bb,$bb
|
||||
fcfid $bc,$bc
|
||||
fcfid $bd,$bd
|
||||
fcfid $na,$na
|
||||
fcfid $nb,$nb
|
||||
fcfid $nc,$nc
|
||||
fcfid $nd,$nd
|
||||
|
||||
lfd $A0,`$FRAME+64`($sp)
|
||||
lfd $A1,`$FRAME+72`($sp)
|
||||
lfd $A2,`$FRAME+80`($sp)
|
||||
lfd $A3,`$FRAME+88`($sp)
|
||||
lfd $N0,`$FRAME+96`($sp)
|
||||
lfd $N1,`$FRAME+104`($sp)
|
||||
lfd $N2,`$FRAME+112`($sp)
|
||||
lfd $N3,`$FRAME+120`($sp)
|
||||
fcfid $A0,$A0
|
||||
fcfid $A1,$A1
|
||||
fcfid $A2,$A2
|
||||
fcfid $A3,$A3
|
||||
fcfid $N0,$N0
|
||||
fcfid $N1,$N1
|
||||
fcfid $N2,$N2
|
||||
fcfid $N3,$N3
|
||||
addi $ap,$ap,16
|
||||
addi $np,$np,16
|
||||
|
||||
fmul $T1a,$A1,$ba
|
||||
fmul $T1b,$A1,$bb
|
||||
stfd $A0,8($nap_d) ; save a[j] in double format
|
||||
stfd $A1,16($nap_d)
|
||||
fmul $T2a,$A2,$ba
|
||||
fmul $T2b,$A2,$bb
|
||||
stfd $A2,24($nap_d) ; save a[j+1] in double format
|
||||
stfd $A3,32($nap_d)
|
||||
fmul $T3a,$A3,$ba
|
||||
fmul $T3b,$A3,$bb
|
||||
stfd $N0,40($nap_d) ; save n[j] in double format
|
||||
stfd $N1,48($nap_d)
|
||||
fmul $T0a,$A0,$ba
|
||||
fmul $T0b,$A0,$bb
|
||||
stfd $N2,56($nap_d) ; save n[j+1] in double format
|
||||
stfdu $N3,64($nap_d)
|
||||
|
||||
fmadd $T1a,$A0,$bc,$T1a
|
||||
fmadd $T1b,$A0,$bd,$T1b
|
||||
fmadd $T2a,$A1,$bc,$T2a
|
||||
fmadd $T2b,$A1,$bd,$T2b
|
||||
fmadd $T3a,$A2,$bc,$T3a
|
||||
fmadd $T3b,$A2,$bd,$T3b
|
||||
fmul $dota,$A3,$bc
|
||||
fmul $dotb,$A3,$bd
|
||||
|
||||
fmadd $T1a,$N1,$na,$T1a
|
||||
fmadd $T1b,$N1,$nb,$T1b
|
||||
fmadd $T2a,$N2,$na,$T2a
|
||||
fmadd $T2b,$N2,$nb,$T2b
|
||||
fmadd $T3a,$N3,$na,$T3a
|
||||
fmadd $T3b,$N3,$nb,$T3b
|
||||
fmadd $T0a,$N0,$na,$T0a
|
||||
fmadd $T0b,$N0,$nb,$T0b
|
||||
|
||||
fmadd $T1a,$N0,$nc,$T1a
|
||||
fmadd $T1b,$N0,$nd,$T1b
|
||||
fmadd $T2a,$N1,$nc,$T2a
|
||||
fmadd $T2b,$N1,$nd,$T2b
|
||||
fmadd $T3a,$N2,$nc,$T3a
|
||||
fmadd $T3b,$N2,$nd,$T3b
|
||||
fmadd $dota,$N3,$nc,$dota
|
||||
fmadd $dotb,$N3,$nd,$dotb
|
||||
|
||||
fctid $T0a,$T0a
|
||||
fctid $T0b,$T0b
|
||||
fctid $T1a,$T1a
|
||||
fctid $T1b,$T1b
|
||||
fctid $T2a,$T2a
|
||||
fctid $T2b,$T2b
|
||||
fctid $T3a,$T3a
|
||||
fctid $T3b,$T3b
|
||||
|
||||
stfd $T0a,`$FRAME+0`($sp)
|
||||
stfd $T0b,`$FRAME+8`($sp)
|
||||
stfd $T1a,`$FRAME+16`($sp)
|
||||
stfd $T1b,`$FRAME+24`($sp)
|
||||
stfd $T2a,`$FRAME+32`($sp)
|
||||
stfd $T2b,`$FRAME+40`($sp)
|
||||
stfd $T3a,`$FRAME+48`($sp)
|
||||
stfd $T3b,`$FRAME+56`($sp)
|
||||
|
||||
.align 5
|
||||
L1st:
|
||||
lwz $t0,4($ap) ; load a[j] as 32-bit word pair
|
||||
lwz $t1,0($ap)
|
||||
lwz $t2,12($ap) ; load a[j+1] as 32-bit word pair
|
||||
lwz $t3,8($ap)
|
||||
lwz $t4,4($np) ; load n[j] as 32-bit word pair
|
||||
lwz $t5,0($np)
|
||||
lwz $t6,12($np) ; load n[j+1] as 32-bit word pair
|
||||
lwz $t7,8($np)
|
||||
std $t0,`$FRAME+64`($sp)
|
||||
std $t1,`$FRAME+72`($sp)
|
||||
std $t2,`$FRAME+80`($sp)
|
||||
std $t3,`$FRAME+88`($sp)
|
||||
std $t4,`$FRAME+96`($sp)
|
||||
std $t5,`$FRAME+104`($sp)
|
||||
std $t6,`$FRAME+112`($sp)
|
||||
std $t7,`$FRAME+120`($sp)
|
||||
ld $t0,`$FRAME+0`($sp)
|
||||
ld $t1,`$FRAME+8`($sp)
|
||||
ld $t2,`$FRAME+16`($sp)
|
||||
ld $t3,`$FRAME+24`($sp)
|
||||
ld $t4,`$FRAME+32`($sp)
|
||||
ld $t5,`$FRAME+40`($sp)
|
||||
ld $t6,`$FRAME+48`($sp)
|
||||
ld $t7,`$FRAME+56`($sp)
|
||||
lfd $A0,`$FRAME+64`($sp)
|
||||
lfd $A1,`$FRAME+72`($sp)
|
||||
lfd $A2,`$FRAME+80`($sp)
|
||||
lfd $A3,`$FRAME+88`($sp)
|
||||
lfd $N0,`$FRAME+96`($sp)
|
||||
lfd $N1,`$FRAME+104`($sp)
|
||||
lfd $N2,`$FRAME+112`($sp)
|
||||
lfd $N3,`$FRAME+120`($sp)
|
||||
fcfid $A0,$A0
|
||||
fcfid $A1,$A1
|
||||
fcfid $A2,$A2
|
||||
fcfid $A3,$A3
|
||||
fcfid $N0,$N0
|
||||
fcfid $N1,$N1
|
||||
fcfid $N2,$N2
|
||||
fcfid $N3,$N3
|
||||
addi $ap,$ap,16
|
||||
addi $np,$np,16
|
||||
|
||||
fmul $T1a,$A1,$ba
|
||||
fmul $T1b,$A1,$bb
|
||||
fmul $T2a,$A2,$ba
|
||||
fmul $T2b,$A2,$bb
|
||||
stfd $A0,8($nap_d) ; save a[j] in double format
|
||||
stfd $A1,16($nap_d)
|
||||
fmul $T3a,$A3,$ba
|
||||
fmul $T3b,$A3,$bb
|
||||
fmadd $T0a,$A0,$ba,$dota
|
||||
fmadd $T0b,$A0,$bb,$dotb
|
||||
stfd $A2,24($nap_d) ; save a[j+1] in double format
|
||||
stfd $A3,32($nap_d)
|
||||
|
||||
fmadd $T1a,$A0,$bc,$T1a
|
||||
fmadd $T1b,$A0,$bd,$T1b
|
||||
fmadd $T2a,$A1,$bc,$T2a
|
||||
fmadd $T2b,$A1,$bd,$T2b
|
||||
stfd $N0,40($nap_d) ; save n[j] in double format
|
||||
stfd $N1,48($nap_d)
|
||||
fmadd $T3a,$A2,$bc,$T3a
|
||||
fmadd $T3b,$A2,$bd,$T3b
|
||||
add $t0,$t0,$carry ; can not overflow
|
||||
fmul $dota,$A3,$bc
|
||||
fmul $dotb,$A3,$bd
|
||||
stfd $N2,56($nap_d) ; save n[j+1] in double format
|
||||
stfdu $N3,64($nap_d)
|
||||
srdi $carry,$t0,16
|
||||
add $t1,$t1,$carry
|
||||
srdi $carry,$t1,16
|
||||
|
||||
fmadd $T1a,$N1,$na,$T1a
|
||||
fmadd $T1b,$N1,$nb,$T1b
|
||||
insrdi $t0,$t1,16,32
|
||||
fmadd $T2a,$N2,$na,$T2a
|
||||
fmadd $T2b,$N2,$nb,$T2b
|
||||
add $t2,$t2,$carry
|
||||
fmadd $T3a,$N3,$na,$T3a
|
||||
fmadd $T3b,$N3,$nb,$T3b
|
||||
srdi $carry,$t2,16
|
||||
fmadd $T0a,$N0,$na,$T0a
|
||||
fmadd $T0b,$N0,$nb,$T0b
|
||||
insrdi $t0,$t2,16,16
|
||||
add $t3,$t3,$carry
|
||||
srdi $carry,$t3,16
|
||||
|
||||
fmadd $T1a,$N0,$nc,$T1a
|
||||
fmadd $T1b,$N0,$nd,$T1b
|
||||
insrdi $t0,$t3,16,0 ; 0..63 bits
|
||||
fmadd $T2a,$N1,$nc,$T2a
|
||||
fmadd $T2b,$N1,$nd,$T2b
|
||||
add $t4,$t4,$carry
|
||||
fmadd $T3a,$N2,$nc,$T3a
|
||||
fmadd $T3b,$N2,$nd,$T3b
|
||||
srdi $carry,$t4,16
|
||||
fmadd $dota,$N3,$nc,$dota
|
||||
fmadd $dotb,$N3,$nd,$dotb
|
||||
add $t5,$t5,$carry
|
||||
srdi $carry,$t5,16
|
||||
insrdi $t4,$t5,16,32
|
||||
|
||||
fctid $T0a,$T0a
|
||||
fctid $T0b,$T0b
|
||||
add $t6,$t6,$carry
|
||||
fctid $T1a,$T1a
|
||||
fctid $T1b,$T1b
|
||||
srdi $carry,$t6,16
|
||||
fctid $T2a,$T2a
|
||||
fctid $T2b,$T2b
|
||||
insrdi $t4,$t6,16,16
|
||||
fctid $T3a,$T3a
|
||||
fctid $T3b,$T3b
|
||||
add $t7,$t7,$carry
|
||||
insrdi $t4,$t7,16,0 ; 64..127 bits
|
||||
srdi $carry,$t7,16 ; upper 33 bits
|
||||
|
||||
stfd $T0a,`$FRAME+0`($sp)
|
||||
stfd $T0b,`$FRAME+8`($sp)
|
||||
stfd $T1a,`$FRAME+16`($sp)
|
||||
stfd $T1b,`$FRAME+24`($sp)
|
||||
stfd $T2a,`$FRAME+32`($sp)
|
||||
stfd $T2b,`$FRAME+40`($sp)
|
||||
stfd $T3a,`$FRAME+48`($sp)
|
||||
stfd $T3b,`$FRAME+56`($sp)
|
||||
std $t0,8($tp) ; tp[j-1]
|
||||
stdu $t4,16($tp) ; tp[j]
|
||||
bdnz- L1st
|
||||
|
||||
fctid $dota,$dota
|
||||
fctid $dotb,$dotb
|
||||
|
||||
ld $t0,`$FRAME+0`($sp)
|
||||
ld $t1,`$FRAME+8`($sp)
|
||||
ld $t2,`$FRAME+16`($sp)
|
||||
ld $t3,`$FRAME+24`($sp)
|
||||
ld $t4,`$FRAME+32`($sp)
|
||||
ld $t5,`$FRAME+40`($sp)
|
||||
ld $t6,`$FRAME+48`($sp)
|
||||
ld $t7,`$FRAME+56`($sp)
|
||||
stfd $dota,`$FRAME+64`($sp)
|
||||
stfd $dotb,`$FRAME+72`($sp)
|
||||
|
||||
add $t0,$t0,$carry ; can not overflow
|
||||
srdi $carry,$t0,16
|
||||
add $t1,$t1,$carry
|
||||
srdi $carry,$t1,16
|
||||
insrdi $t0,$t1,16,32
|
||||
add $t2,$t2,$carry
|
||||
srdi $carry,$t2,16
|
||||
insrdi $t0,$t2,16,16
|
||||
add $t3,$t3,$carry
|
||||
srdi $carry,$t3,16
|
||||
insrdi $t0,$t3,16,0 ; 0..63 bits
|
||||
add $t4,$t4,$carry
|
||||
srdi $carry,$t4,16
|
||||
add $t5,$t5,$carry
|
||||
srdi $carry,$t5,16
|
||||
insrdi $t4,$t5,16,32
|
||||
add $t6,$t6,$carry
|
||||
srdi $carry,$t6,16
|
||||
insrdi $t4,$t6,16,16
|
||||
add $t7,$t7,$carry
|
||||
insrdi $t4,$t7,16,0 ; 64..127 bits
|
||||
srdi $carry,$t7,16 ; upper 33 bits
|
||||
ld $t6,`$FRAME+64`($sp)
|
||||
ld $t7,`$FRAME+72`($sp)
|
||||
|
||||
std $t0,8($tp) ; tp[j-1]
|
||||
stdu $t4,16($tp) ; tp[j]
|
||||
|
||||
add $t6,$t6,$carry ; can not overflow
|
||||
srdi $carry,$t6,16
|
||||
add $t7,$t7,$carry
|
||||
insrdi $t6,$t7,48,0
|
||||
srdi $ovf,$t7,48
|
||||
std $t6,8($tp) ; tp[num-1]
|
||||
|
||||
slwi $t7,$num,2
|
||||
subf $nap_d,$t7,$nap_d ; rewind pointer
|
||||
|
||||
li $i,8 ; i=1
|
||||
.align 5
|
||||
Louter:
|
||||
ldx $t3,$bp,$i ; bp[i]
|
||||
ld $t6,`$FRAME+$TRANSFER+8`($sp) ; tp[0]
|
||||
mulld $t7,$a0,$t3 ; ap[0]*bp[i]
|
||||
|
||||
addi $tp,$sp,`$FRAME+$TRANSFER`
|
||||
add $t7,$t7,$t6 ; ap[0]*bp[i]+tp[0]
|
||||
li $carry,0
|
||||
mulld $t7,$t7,$n0 ; tp[0]*n0
|
||||
mtctr $j
|
||||
|
||||
; transfer bp[i] to FPU as 4x16-bit values
|
||||
extrdi $t0,$t3,16,48
|
||||
extrdi $t1,$t3,16,32
|
||||
extrdi $t2,$t3,16,16
|
||||
extrdi $t3,$t3,16,0
|
||||
std $t0,`$FRAME+0`($sp)
|
||||
std $t1,`$FRAME+8`($sp)
|
||||
std $t2,`$FRAME+16`($sp)
|
||||
std $t3,`$FRAME+24`($sp)
|
||||
; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values
|
||||
extrdi $t4,$t7,16,48
|
||||
extrdi $t5,$t7,16,32
|
||||
extrdi $t6,$t7,16,16
|
||||
extrdi $t7,$t7,16,0
|
||||
std $t4,`$FRAME+32`($sp)
|
||||
std $t5,`$FRAME+40`($sp)
|
||||
std $t6,`$FRAME+48`($sp)
|
||||
std $t7,`$FRAME+56`($sp)
|
||||
|
||||
lfd $A0,8($nap_d) ; load a[j] in double format
|
||||
lfd $A1,16($nap_d)
|
||||
lfd $A2,24($nap_d) ; load a[j+1] in double format
|
||||
lfd $A3,32($nap_d)
|
||||
lfd $N0,40($nap_d) ; load n[j] in double format
|
||||
lfd $N1,48($nap_d)
|
||||
lfd $N2,56($nap_d) ; load n[j+1] in double format
|
||||
lfdu $N3,64($nap_d)
|
||||
|
||||
lfd $ba,`$FRAME+0`($sp)
|
||||
lfd $bb,`$FRAME+8`($sp)
|
||||
lfd $bc,`$FRAME+16`($sp)
|
||||
lfd $bd,`$FRAME+24`($sp)
|
||||
lfd $na,`$FRAME+32`($sp)
|
||||
lfd $nb,`$FRAME+40`($sp)
|
||||
lfd $nc,`$FRAME+48`($sp)
|
||||
lfd $nd,`$FRAME+56`($sp)
|
||||
|
||||
fcfid $ba,$ba
|
||||
fcfid $bb,$bb
|
||||
fcfid $bc,$bc
|
||||
fcfid $bd,$bd
|
||||
fcfid $na,$na
|
||||
fcfid $nb,$nb
|
||||
fcfid $nc,$nc
|
||||
fcfid $nd,$nd
|
||||
|
||||
fmul $T1a,$A1,$ba
|
||||
fmul $T1b,$A1,$bb
|
||||
fmul $T2a,$A2,$ba
|
||||
fmul $T2b,$A2,$bb
|
||||
fmul $T3a,$A3,$ba
|
||||
fmul $T3b,$A3,$bb
|
||||
fmul $T0a,$A0,$ba
|
||||
fmul $T0b,$A0,$bb
|
||||
|
||||
fmadd $T1a,$A0,$bc,$T1a
|
||||
fmadd $T1b,$A0,$bd,$T1b
|
||||
fmadd $T2a,$A1,$bc,$T2a
|
||||
fmadd $T2b,$A1,$bd,$T2b
|
||||
fmadd $T3a,$A2,$bc,$T3a
|
||||
fmadd $T3b,$A2,$bd,$T3b
|
||||
fmul $dota,$A3,$bc
|
||||
fmul $dotb,$A3,$bd
|
||||
|
||||
fmadd $T1a,$N1,$na,$T1a
|
||||
fmadd $T1b,$N1,$nb,$T1b
|
||||
lfd $A0,8($nap_d) ; load a[j] in double format
|
||||
lfd $A1,16($nap_d)
|
||||
fmadd $T2a,$N2,$na,$T2a
|
||||
fmadd $T2b,$N2,$nb,$T2b
|
||||
lfd $A2,24($nap_d) ; load a[j+1] in double format
|
||||
lfd $A3,32($nap_d)
|
||||
fmadd $T3a,$N3,$na,$T3a
|
||||
fmadd $T3b,$N3,$nb,$T3b
|
||||
fmadd $T0a,$N0,$na,$T0a
|
||||
fmadd $T0b,$N0,$nb,$T0b
|
||||
|
||||
fmadd $T1a,$N0,$nc,$T1a
|
||||
fmadd $T1b,$N0,$nd,$T1b
|
||||
fmadd $T2a,$N1,$nc,$T2a
|
||||
fmadd $T2b,$N1,$nd,$T2b
|
||||
fmadd $T3a,$N2,$nc,$T3a
|
||||
fmadd $T3b,$N2,$nd,$T3b
|
||||
fmadd $dota,$N3,$nc,$dota
|
||||
fmadd $dotb,$N3,$nd,$dotb
|
||||
|
||||
fctid $T0a,$T0a
|
||||
fctid $T0b,$T0b
|
||||
fctid $T1a,$T1a
|
||||
fctid $T1b,$T1b
|
||||
fctid $T2a,$T2a
|
||||
fctid $T2b,$T2b
|
||||
fctid $T3a,$T3a
|
||||
fctid $T3b,$T3b
|
||||
|
||||
stfd $T0a,`$FRAME+0`($sp)
|
||||
stfd $T0b,`$FRAME+8`($sp)
|
||||
stfd $T1a,`$FRAME+16`($sp)
|
||||
stfd $T1b,`$FRAME+24`($sp)
|
||||
stfd $T2a,`$FRAME+32`($sp)
|
||||
stfd $T2b,`$FRAME+40`($sp)
|
||||
stfd $T3a,`$FRAME+48`($sp)
|
||||
stfd $T3b,`$FRAME+56`($sp)
|
||||
|
||||
.align 5
|
||||
Linner:
|
||||
fmul $T1a,$A1,$ba
|
||||
fmul $T1b,$A1,$bb
|
||||
fmul $T2a,$A2,$ba
|
||||
fmul $T2b,$A2,$bb
|
||||
lfd $N0,40($nap_d) ; load n[j] in double format
|
||||
lfd $N1,48($nap_d)
|
||||
fmul $T3a,$A3,$ba
|
||||
fmul $T3b,$A3,$bb
|
||||
fmadd $T0a,$A0,$ba,$dota
|
||||
fmadd $T0b,$A0,$bb,$dotb
|
||||
lfd $N2,56($nap_d) ; load n[j+1] in double format
|
||||
lfdu $N3,64($nap_d)
|
||||
|
||||
fmadd $T1a,$A0,$bc,$T1a
|
||||
fmadd $T1b,$A0,$bd,$T1b
|
||||
fmadd $T2a,$A1,$bc,$T2a
|
||||
fmadd $T2b,$A1,$bd,$T2b
|
||||
lfd $A0,8($nap_d) ; load a[j] in double format
|
||||
lfd $A1,16($nap_d)
|
||||
fmadd $T3a,$A2,$bc,$T3a
|
||||
fmadd $T3b,$A2,$bd,$T3b
|
||||
fmul $dota,$A3,$bc
|
||||
fmul $dotb,$A3,$bd
|
||||
lfd $A2,24($nap_d) ; load a[j+1] in double format
|
||||
lfd $A3,32($nap_d)
|
||||
|
||||
fmadd $T1a,$N1,$na,$T1a
|
||||
fmadd $T1b,$N1,$nb,$T1b
|
||||
ld $t0,`$FRAME+0`($sp)
|
||||
ld $t1,`$FRAME+8`($sp)
|
||||
fmadd $T2a,$N2,$na,$T2a
|
||||
fmadd $T2b,$N2,$nb,$T2b
|
||||
ld $t2,`$FRAME+16`($sp)
|
||||
ld $t3,`$FRAME+24`($sp)
|
||||
fmadd $T3a,$N3,$na,$T3a
|
||||
fmadd $T3b,$N3,$nb,$T3b
|
||||
add $t0,$t0,$carry ; can not overflow
|
||||
ld $t4,`$FRAME+32`($sp)
|
||||
ld $t5,`$FRAME+40`($sp)
|
||||
fmadd $T0a,$N0,$na,$T0a
|
||||
fmadd $T0b,$N0,$nb,$T0b
|
||||
srdi $carry,$t0,16
|
||||
add $t1,$t1,$carry
|
||||
srdi $carry,$t1,16
|
||||
ld $t6,`$FRAME+48`($sp)
|
||||
ld $t7,`$FRAME+56`($sp)
|
||||
|
||||
fmadd $T1a,$N0,$nc,$T1a
|
||||
fmadd $T1b,$N0,$nd,$T1b
|
||||
insrdi $t0,$t1,16,32
|
||||
ld $t1,8($tp) ; tp[j]
|
||||
fmadd $T2a,$N1,$nc,$T2a
|
||||
fmadd $T2b,$N1,$nd,$T2b
|
||||
add $t2,$t2,$carry
|
||||
fmadd $T3a,$N2,$nc,$T3a
|
||||
fmadd $T3b,$N2,$nd,$T3b
|
||||
srdi $carry,$t2,16
|
||||
insrdi $t0,$t2,16,16
|
||||
fmadd $dota,$N3,$nc,$dota
|
||||
fmadd $dotb,$N3,$nd,$dotb
|
||||
add $t3,$t3,$carry
|
||||
ldu $t2,16($tp) ; tp[j+1]
|
||||
srdi $carry,$t3,16
|
||||
insrdi $t0,$t3,16,0 ; 0..63 bits
|
||||
add $t4,$t4,$carry
|
||||
|
||||
fctid $T0a,$T0a
|
||||
fctid $T0b,$T0b
|
||||
srdi $carry,$t4,16
|
||||
fctid $T1a,$T1a
|
||||
fctid $T1b,$T1b
|
||||
add $t5,$t5,$carry
|
||||
fctid $T2a,$T2a
|
||||
fctid $T2b,$T2b
|
||||
srdi $carry,$t5,16
|
||||
insrdi $t4,$t5,16,32
|
||||
fctid $T3a,$T3a
|
||||
fctid $T3b,$T3b
|
||||
add $t6,$t6,$carry
|
||||
srdi $carry,$t6,16
|
||||
insrdi $t4,$t6,16,16
|
||||
|
||||
stfd $T0a,`$FRAME+0`($sp)
|
||||
stfd $T0b,`$FRAME+8`($sp)
|
||||
add $t7,$t7,$carry
|
||||
addc $t3,$t0,$t1
|
||||
stfd $T1a,`$FRAME+16`($sp)
|
||||
stfd $T1b,`$FRAME+24`($sp)
|
||||
insrdi $t4,$t7,16,0 ; 64..127 bits
|
||||
srdi $carry,$t7,16 ; upper 33 bits
|
||||
stfd $T2a,`$FRAME+32`($sp)
|
||||
stfd $T2b,`$FRAME+40`($sp)
|
||||
adde $t5,$t4,$t2
|
||||
stfd $T3a,`$FRAME+48`($sp)
|
||||
stfd $T3b,`$FRAME+56`($sp)
|
||||
addze $carry,$carry
|
||||
std $t3,-16($tp) ; tp[j-1]
|
||||
std $t5,-8($tp) ; tp[j]
|
||||
bdnz- Linner
|
||||
|
||||
fctid $dota,$dota
|
||||
fctid $dotb,$dotb
|
||||
ld $t0,`$FRAME+0`($sp)
|
||||
ld $t1,`$FRAME+8`($sp)
|
||||
ld $t2,`$FRAME+16`($sp)
|
||||
ld $t3,`$FRAME+24`($sp)
|
||||
ld $t4,`$FRAME+32`($sp)
|
||||
ld $t5,`$FRAME+40`($sp)
|
||||
ld $t6,`$FRAME+48`($sp)
|
||||
ld $t7,`$FRAME+56`($sp)
|
||||
stfd $dota,`$FRAME+64`($sp)
|
||||
stfd $dotb,`$FRAME+72`($sp)
|
||||
|
||||
add $t0,$t0,$carry ; can not overflow
|
||||
srdi $carry,$t0,16
|
||||
add $t1,$t1,$carry
|
||||
srdi $carry,$t1,16
|
||||
insrdi $t0,$t1,16,32
|
||||
add $t2,$t2,$carry
|
||||
ld $t1,8($tp) ; tp[j]
|
||||
srdi $carry,$t2,16
|
||||
insrdi $t0,$t2,16,16
|
||||
add $t3,$t3,$carry
|
||||
ldu $t2,16($tp) ; tp[j+1]
|
||||
srdi $carry,$t3,16
|
||||
insrdi $t0,$t3,16,0 ; 0..63 bits
|
||||
add $t4,$t4,$carry
|
||||
srdi $carry,$t4,16
|
||||
add $t5,$t5,$carry
|
||||
srdi $carry,$t5,16
|
||||
insrdi $t4,$t5,16,32
|
||||
add $t6,$t6,$carry
|
||||
srdi $carry,$t6,16
|
||||
insrdi $t4,$t6,16,16
|
||||
add $t7,$t7,$carry
|
||||
insrdi $t4,$t7,16,0 ; 64..127 bits
|
||||
srdi $carry,$t7,16 ; upper 33 bits
|
||||
ld $t6,`$FRAME+64`($sp)
|
||||
ld $t7,`$FRAME+72`($sp)
|
||||
|
||||
addc $t3,$t0,$t1
|
||||
adde $t5,$t4,$t2
|
||||
addze $carry,$carry
|
||||
|
||||
std $t3,-16($tp) ; tp[j-1]
|
||||
std $t5,-8($tp) ; tp[j]
|
||||
|
||||
add $carry,$carry,$ovf ; comsume upmost overflow
|
||||
add $t6,$t6,$carry ; can not overflow
|
||||
srdi $carry,$t6,16
|
||||
add $t7,$t7,$carry
|
||||
insrdi $t6,$t7,48,0
|
||||
srdi $ovf,$t7,48
|
||||
std $t6,0($tp) ; tp[num-1]
|
||||
|
||||
slwi $t7,$num,2
|
||||
addi $i,$i,8
|
||||
subf $nap_d,$t7,$nap_d ; rewind pointer
|
||||
cmpw $i,$num
|
||||
blt- Louter
|
||||
|
||||
subf $np,$num,$np ; rewind np
|
||||
addi $j,$j,1 ; restore counter
|
||||
subfc $i,$i,$i ; j=0 and "clear" XER[CA]
|
||||
addi $tp,$sp,`$FRAME+$TRANSFER+8`
|
||||
addi $t4,$sp,`$FRAME+$TRANSFER+16`
|
||||
addi $t5,$np,8
|
||||
addi $t6,$rp,8
|
||||
mtctr $j
|
||||
|
||||
.align 4
|
||||
Lsub: ldx $t0,$tp,$i
|
||||
ldx $t1,$np,$i
|
||||
ldx $t2,$t4,$i
|
||||
ldx $t3,$t5,$i
|
||||
subfe $t0,$t1,$t0 ; tp[j]-np[j]
|
||||
subfe $t2,$t3,$t2 ; tp[j+1]-np[j+1]
|
||||
stdx $t0,$rp,$i
|
||||
stdx $t2,$t6,$i
|
||||
addi $i,$i,16
|
||||
bdnz- Lsub
|
||||
|
||||
li $i,0
|
||||
subfe $ovf,$i,$ovf ; handle upmost overflow bit
|
||||
and $ap,$tp,$ovf
|
||||
andc $np,$rp,$ovf
|
||||
or $ap,$ap,$np ; ap=borrow?tp:rp
|
||||
addi $t7,$ap,8
|
||||
mtctr $j
|
||||
|
||||
.align 4
|
||||
Lcopy: ; copy or in-place refresh
|
||||
ldx $t0,$ap,$i
|
||||
ldx $t1,$t7,$i
|
||||
std $i,8($nap_d) ; zap nap_d
|
||||
std $i,16($nap_d)
|
||||
std $i,24($nap_d)
|
||||
std $i,32($nap_d)
|
||||
std $i,40($nap_d)
|
||||
std $i,48($nap_d)
|
||||
std $i,56($nap_d)
|
||||
stdu $i,64($nap_d)
|
||||
stdx $t0,$rp,$i
|
||||
stdx $t1,$t6,$i
|
||||
stdx $i,$tp,$i ; zap tp at once
|
||||
stdx $i,$t4,$i
|
||||
addi $i,$i,16
|
||||
bdnz- Lcopy
|
||||
|
||||
$POP r14,`2*$SIZE_T`($sp)
|
||||
$POP r15,`3*$SIZE_T`($sp)
|
||||
$POP r16,`4*$SIZE_T`($sp)
|
||||
$POP r17,`5*$SIZE_T`($sp)
|
||||
$POP r18,`6*$SIZE_T`($sp)
|
||||
$POP r19,`7*$SIZE_T`($sp)
|
||||
$POP r20,`8*$SIZE_T`($sp)
|
||||
$POP r21,`9*$SIZE_T`($sp)
|
||||
$POP r22,`10*$SIZE_T`($sp)
|
||||
$POP r23,`11*$SIZE_T`($sp)
|
||||
lfd f14,`12*$SIZE_T+0`($sp)
|
||||
lfd f15,`12*$SIZE_T+8`($sp)
|
||||
lfd f16,`12*$SIZE_T+16`($sp)
|
||||
lfd f17,`12*$SIZE_T+24`($sp)
|
||||
lfd f18,`12*$SIZE_T+32`($sp)
|
||||
lfd f19,`12*$SIZE_T+40`($sp)
|
||||
lfd f20,`12*$SIZE_T+48`($sp)
|
||||
lfd f21,`12*$SIZE_T+56`($sp)
|
||||
lfd f22,`12*$SIZE_T+64`($sp)
|
||||
lfd f23,`12*$SIZE_T+72`($sp)
|
||||
lfd f24,`12*$SIZE_T+80`($sp)
|
||||
lfd f25,`12*$SIZE_T+88`($sp)
|
||||
$POP $sp,0($sp)
|
||||
li r3,1 ; signal "handled"
|
||||
blr
|
||||
.long 0
|
||||
.asciz "Montgomery Multiplication for PPC64, CRYPTOGAMS by <appro\@fy.chalmers.se>"
|
||||
___
|
||||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
225
crypto/bn/asm/s390x-mont.pl
Normal file
225
crypto/bn/asm/s390x-mont.pl
Normal file
@@ -0,0 +1,225 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# April 2007.
|
||||
#
|
||||
# Performance improvement over vanilla C code varies from 85% to 45%
|
||||
# depending on key length and benchmark. Unfortunately in this context
|
||||
# these are not very impressive results [for code that utilizes "wide"
|
||||
# 64x64=128-bit multiplication, which is not commonly available to C
|
||||
# programmers], at least hand-coded bn_asm.c replacement is known to
|
||||
# provide 30-40% better results for longest keys. Well, on a second
|
||||
# thought it's not very surprising, because z-CPUs are single-issue
|
||||
# and _strictly_ in-order execution, while bn_mul_mont is more or less
|
||||
# dependent on CPU ability to pipe-line instructions and have several
|
||||
# of them "in-flight" at the same time. I mean while other methods,
|
||||
# for example Karatsuba, aim to minimize amount of multiplications at
|
||||
# the cost of other operations increase, bn_mul_mont aim to neatly
|
||||
# "overlap" multiplications and the other operations [and on most
|
||||
# platforms even minimize the amount of the other operations, in
|
||||
# particular references to memory]. But it's possible to improve this
|
||||
# module performance by implementing dedicated squaring code-path and
|
||||
# possibly by unrolling loops...
|
||||
|
||||
# January 2009.
|
||||
#
|
||||
# Reschedule to minimize/avoid Address Generation Interlock hazard,
|
||||
# make inner loops counter-based.
|
||||
|
||||
$mn0="%r0";
|
||||
$num="%r1";
|
||||
|
||||
# int bn_mul_mont(
|
||||
$rp="%r2"; # BN_ULONG *rp,
|
||||
$ap="%r3"; # const BN_ULONG *ap,
|
||||
$bp="%r4"; # const BN_ULONG *bp,
|
||||
$np="%r5"; # const BN_ULONG *np,
|
||||
$n0="%r6"; # const BN_ULONG *n0,
|
||||
#$num="160(%r15)" # int num);
|
||||
|
||||
$bi="%r2"; # zaps rp
|
||||
$j="%r7";
|
||||
|
||||
$ahi="%r8";
|
||||
$alo="%r9";
|
||||
$nhi="%r10";
|
||||
$nlo="%r11";
|
||||
$AHI="%r12";
|
||||
$NHI="%r13";
|
||||
$count="%r14";
|
||||
$sp="%r15";
|
||||
|
||||
$code.=<<___;
|
||||
.text
|
||||
.globl bn_mul_mont
|
||||
.type bn_mul_mont,\@function
|
||||
bn_mul_mont:
|
||||
lgf $num,164($sp) # pull $num
|
||||
sla $num,3 # $num to enumerate bytes
|
||||
la $bp,0($num,$bp)
|
||||
|
||||
stg %r2,16($sp)
|
||||
|
||||
cghi $num,16 #
|
||||
lghi %r2,0 #
|
||||
blr %r14 # if($num<16) return 0;
|
||||
cghi $num,128 #
|
||||
bhr %r14 # if($num>128) return 0;
|
||||
|
||||
stmg %r3,%r15,24($sp)
|
||||
|
||||
lghi $rp,-160-8 # leave room for carry bit
|
||||
lcgr $j,$num # -$num
|
||||
lgr %r0,$sp
|
||||
la $rp,0($rp,$sp)
|
||||
la $sp,0($j,$rp) # alloca
|
||||
stg %r0,0($sp) # back chain
|
||||
|
||||
sra $num,3 # restore $num
|
||||
la $bp,0($j,$bp) # restore $bp
|
||||
ahi $num,-1 # adjust $num for inner loop
|
||||
lg $n0,0($n0) # pull n0
|
||||
|
||||
lg $bi,0($bp)
|
||||
lg $alo,0($ap)
|
||||
mlgr $ahi,$bi # ap[0]*bp[0]
|
||||
lgr $AHI,$ahi
|
||||
|
||||
lgr $mn0,$alo # "tp[0]"*n0
|
||||
msgr $mn0,$n0
|
||||
|
||||
lg $nlo,0($np) #
|
||||
mlgr $nhi,$mn0 # np[0]*m1
|
||||
algr $nlo,$alo # +="tp[0]"
|
||||
lghi $NHI,0
|
||||
alcgr $NHI,$nhi
|
||||
|
||||
la $j,8(%r0) # j=1
|
||||
lr $count,$num
|
||||
|
||||
.align 16
|
||||
.L1st:
|
||||
lg $alo,0($j,$ap)
|
||||
mlgr $ahi,$bi # ap[j]*bp[0]
|
||||
algr $alo,$AHI
|
||||
lghi $AHI,0
|
||||
alcgr $AHI,$ahi
|
||||
|
||||
lg $nlo,0($j,$np)
|
||||
mlgr $nhi,$mn0 # np[j]*m1
|
||||
algr $nlo,$NHI
|
||||
lghi $NHI,0
|
||||
alcgr $nhi,$NHI # +="tp[j]"
|
||||
algr $nlo,$alo
|
||||
alcgr $NHI,$nhi
|
||||
|
||||
stg $nlo,160-8($j,$sp) # tp[j-1]=
|
||||
la $j,8($j) # j++
|
||||
brct $count,.L1st
|
||||
|
||||
algr $NHI,$AHI
|
||||
lghi $AHI,0
|
||||
alcgr $AHI,$AHI # upmost overflow bit
|
||||
stg $NHI,160-8($j,$sp)
|
||||
stg $AHI,160($j,$sp)
|
||||
la $bp,8($bp) # bp++
|
||||
|
||||
.Louter:
|
||||
lg $bi,0($bp) # bp[i]
|
||||
lg $alo,0($ap)
|
||||
mlgr $ahi,$bi # ap[0]*bp[i]
|
||||
alg $alo,160($sp) # +=tp[0]
|
||||
lghi $AHI,0
|
||||
alcgr $AHI,$ahi
|
||||
|
||||
lgr $mn0,$alo
|
||||
msgr $mn0,$n0 # tp[0]*n0
|
||||
|
||||
lg $nlo,0($np) # np[0]
|
||||
mlgr $nhi,$mn0 # np[0]*m1
|
||||
algr $nlo,$alo # +="tp[0]"
|
||||
lghi $NHI,0
|
||||
alcgr $NHI,$nhi
|
||||
|
||||
la $j,8(%r0) # j=1
|
||||
lr $count,$num
|
||||
|
||||
.align 16
|
||||
.Linner:
|
||||
lg $alo,0($j,$ap)
|
||||
mlgr $ahi,$bi # ap[j]*bp[i]
|
||||
algr $alo,$AHI
|
||||
lghi $AHI,0
|
||||
alcgr $ahi,$AHI
|
||||
alg $alo,160($j,$sp)# +=tp[j]
|
||||
alcgr $AHI,$ahi
|
||||
|
||||
lg $nlo,0($j,$np)
|
||||
mlgr $nhi,$mn0 # np[j]*m1
|
||||
algr $nlo,$NHI
|
||||
lghi $NHI,0
|
||||
alcgr $nhi,$NHI
|
||||
algr $nlo,$alo # +="tp[j]"
|
||||
alcgr $NHI,$nhi
|
||||
|
||||
stg $nlo,160-8($j,$sp) # tp[j-1]=
|
||||
la $j,8($j) # j++
|
||||
brct $count,.Linner
|
||||
|
||||
algr $NHI,$AHI
|
||||
lghi $AHI,0
|
||||
alcgr $AHI,$AHI
|
||||
alg $NHI,160($j,$sp)# accumulate previous upmost overflow bit
|
||||
lghi $ahi,0
|
||||
alcgr $AHI,$ahi # new upmost overflow bit
|
||||
stg $NHI,160-8($j,$sp)
|
||||
stg $AHI,160($j,$sp)
|
||||
|
||||
la $bp,8($bp) # bp++
|
||||
clg $bp,160+8+32($j,$sp) # compare to &bp[num]
|
||||
jne .Louter
|
||||
|
||||
lg $rp,160+8+16($j,$sp) # reincarnate rp
|
||||
la $ap,160($sp)
|
||||
ahi $num,1 # restore $num, incidentally clears "borrow"
|
||||
|
||||
la $j,0(%r0)
|
||||
lr $count,$num
|
||||
.Lsub: lg $alo,0($j,$ap)
|
||||
slbg $alo,0($j,$np)
|
||||
stg $alo,0($j,$rp)
|
||||
la $j,8($j)
|
||||
brct $count,.Lsub
|
||||
lghi $ahi,0
|
||||
slbgr $AHI,$ahi # handle upmost carry
|
||||
|
||||
ngr $ap,$AHI
|
||||
lghi $np,-1
|
||||
xgr $np,$AHI
|
||||
ngr $np,$rp
|
||||
ogr $ap,$np # ap=borrow?tp:rp
|
||||
|
||||
la $j,0(%r0)
|
||||
lgr $count,$num
|
||||
.Lcopy: lg $alo,0($j,$ap) # copy or in-place refresh
|
||||
stg $j,160($j,$sp) # zap tp
|
||||
stg $alo,0($j,$rp)
|
||||
la $j,8($j)
|
||||
brct $count,.Lcopy
|
||||
|
||||
la %r1,160+8+48($j,$sp)
|
||||
lmg %r6,%r15,0(%r1)
|
||||
lghi %r2,1 # signal "processed"
|
||||
br %r14
|
||||
.size bn_mul_mont,.-bn_mul_mont
|
||||
.string "Montgomery Multiplication for s390x, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
___
|
||||
|
||||
print $code;
|
||||
close STDOUT;
|
678
crypto/bn/asm/s390x.S
Executable file
678
crypto/bn/asm/s390x.S
Executable file
@@ -0,0 +1,678 @@
|
||||
.ident "s390x.S, version 1.0"
|
||||
// ====================================================================
|
||||
// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
// project.
|
||||
//
|
||||
// Rights for redistribution and usage in source and binary forms are
|
||||
// granted according to the OpenSSL license. Warranty of any kind is
|
||||
// disclaimed.
|
||||
// ====================================================================
|
||||
|
||||
.text
|
||||
|
||||
#define zero %r0
|
||||
|
||||
// BN_ULONG bn_mul_add_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
|
||||
.globl bn_mul_add_words
|
||||
.type bn_mul_add_words,@function
|
||||
.align 4
|
||||
bn_mul_add_words:
|
||||
lghi zero,0 // zero = 0
|
||||
la %r1,0(%r2) // put rp aside
|
||||
lghi %r2,0 // i=0;
|
||||
ltgfr %r4,%r4
|
||||
bler %r14 // if (len<=0) return 0;
|
||||
|
||||
stmg %r6,%r10,48(%r15)
|
||||
lghi %r8,0 // carry = 0
|
||||
srag %r10,%r4,2 // cnt=len/4
|
||||
jz .Loop1_madd
|
||||
|
||||
.Loop4_madd:
|
||||
lg %r7,0(%r2,%r3) // ap[i]
|
||||
mlgr %r6,%r5 // *=w
|
||||
algr %r7,%r8 // +=carry
|
||||
alcgr %r6,zero
|
||||
alg %r7,0(%r2,%r1) // +=rp[i]
|
||||
alcgr %r6,zero
|
||||
stg %r7,0(%r2,%r1) // rp[i]=
|
||||
|
||||
lg %r9,8(%r2,%r3)
|
||||
mlgr %r8,%r5
|
||||
algr %r9,%r6
|
||||
alcgr %r8,zero
|
||||
alg %r9,8(%r2,%r1)
|
||||
alcgr %r8,zero
|
||||
stg %r9,8(%r2,%r1)
|
||||
|
||||
lg %r7,16(%r2,%r3)
|
||||
mlgr %r6,%r5
|
||||
algr %r7,%r8
|
||||
alcgr %r6,zero
|
||||
alg %r7,16(%r2,%r1)
|
||||
alcgr %r6,zero
|
||||
stg %r7,16(%r2,%r1)
|
||||
|
||||
lg %r9,24(%r2,%r3)
|
||||
mlgr %r8,%r5
|
||||
algr %r9,%r6
|
||||
alcgr %r8,zero
|
||||
alg %r9,24(%r2,%r1)
|
||||
alcgr %r8,zero
|
||||
stg %r9,24(%r2,%r1)
|
||||
|
||||
la %r2,32(%r2) // i+=4
|
||||
brct %r10,.Loop4_madd
|
||||
|
||||
lghi %r10,3
|
||||
nr %r4,%r10 // cnt=len%4
|
||||
jz .Lend_madd
|
||||
|
||||
.Loop1_madd:
|
||||
lg %r7,0(%r2,%r3) // ap[i]
|
||||
mlgr %r6,%r5 // *=w
|
||||
algr %r7,%r8 // +=carry
|
||||
alcgr %r6,zero
|
||||
alg %r7,0(%r2,%r1) // +=rp[i]
|
||||
alcgr %r6,zero
|
||||
stg %r7,0(%r2,%r1) // rp[i]=
|
||||
|
||||
lgr %r8,%r6
|
||||
la %r2,8(%r2) // i++
|
||||
brct %r4,.Loop1_madd
|
||||
|
||||
.Lend_madd:
|
||||
lgr %r2,%r8
|
||||
lmg %r6,%r10,48(%r15)
|
||||
br %r14
|
||||
.size bn_mul_add_words,.-bn_mul_add_words
|
||||
|
||||
// BN_ULONG bn_mul_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
|
||||
.globl bn_mul_words
|
||||
.type bn_mul_words,@function
|
||||
.align 4
|
||||
bn_mul_words:
|
||||
lghi zero,0 // zero = 0
|
||||
la %r1,0(%r2) // put rp aside
|
||||
lghi %r2,0 // i=0;
|
||||
ltgfr %r4,%r4
|
||||
bler %r14 // if (len<=0) return 0;
|
||||
|
||||
stmg %r6,%r10,48(%r15)
|
||||
lghi %r8,0 // carry = 0
|
||||
srag %r10,%r4,2 // cnt=len/4
|
||||
jz .Loop1_mul
|
||||
|
||||
.Loop4_mul:
|
||||
lg %r7,0(%r2,%r3) // ap[i]
|
||||
mlgr %r6,%r5 // *=w
|
||||
algr %r7,%r8 // +=carry
|
||||
alcgr %r6,zero
|
||||
stg %r7,0(%r2,%r1) // rp[i]=
|
||||
|
||||
lg %r9,8(%r2,%r3)
|
||||
mlgr %r8,%r5
|
||||
algr %r9,%r6
|
||||
alcgr %r8,zero
|
||||
stg %r9,8(%r2,%r1)
|
||||
|
||||
lg %r7,16(%r2,%r3)
|
||||
mlgr %r6,%r5
|
||||
algr %r7,%r8
|
||||
alcgr %r6,zero
|
||||
stg %r7,16(%r2,%r1)
|
||||
|
||||
lg %r9,24(%r2,%r3)
|
||||
mlgr %r8,%r5
|
||||
algr %r9,%r6
|
||||
alcgr %r8,zero
|
||||
stg %r9,24(%r2,%r1)
|
||||
|
||||
la %r2,32(%r2) // i+=4
|
||||
brct %r10,.Loop4_mul
|
||||
|
||||
lghi %r10,3
|
||||
nr %r4,%r10 // cnt=len%4
|
||||
jz .Lend_mul
|
||||
|
||||
.Loop1_mul:
|
||||
lg %r7,0(%r2,%r3) // ap[i]
|
||||
mlgr %r6,%r5 // *=w
|
||||
algr %r7,%r8 // +=carry
|
||||
alcgr %r6,zero
|
||||
stg %r7,0(%r2,%r1) // rp[i]=
|
||||
|
||||
lgr %r8,%r6
|
||||
la %r2,8(%r2) // i++
|
||||
brct %r4,.Loop1_mul
|
||||
|
||||
.Lend_mul:
|
||||
lgr %r2,%r8
|
||||
lmg %r6,%r10,48(%r15)
|
||||
br %r14
|
||||
.size bn_mul_words,.-bn_mul_words
|
||||
|
||||
// void bn_sqr_words(BN_ULONG *r2,BN_ULONG *r2,int r4)
|
||||
.globl bn_sqr_words
|
||||
.type bn_sqr_words,@function
|
||||
.align 4
|
||||
bn_sqr_words:
|
||||
ltgfr %r4,%r4
|
||||
bler %r14
|
||||
|
||||
stmg %r6,%r7,48(%r15)
|
||||
srag %r1,%r4,2 // cnt=len/4
|
||||
jz .Loop1_sqr
|
||||
|
||||
.Loop4_sqr:
|
||||
lg %r7,0(%r3)
|
||||
mlgr %r6,%r7
|
||||
stg %r7,0(%r2)
|
||||
stg %r6,8(%r2)
|
||||
|
||||
lg %r7,8(%r3)
|
||||
mlgr %r6,%r7
|
||||
stg %r7,16(%r2)
|
||||
stg %r6,24(%r2)
|
||||
|
||||
lg %r7,16(%r3)
|
||||
mlgr %r6,%r7
|
||||
stg %r7,32(%r2)
|
||||
stg %r6,40(%r2)
|
||||
|
||||
lg %r7,24(%r3)
|
||||
mlgr %r6,%r7
|
||||
stg %r7,48(%r2)
|
||||
stg %r6,56(%r2)
|
||||
|
||||
la %r3,32(%r3)
|
||||
la %r2,64(%r2)
|
||||
brct %r1,.Loop4_sqr
|
||||
|
||||
lghi %r1,3
|
||||
nr %r4,%r1 // cnt=len%4
|
||||
jz .Lend_sqr
|
||||
|
||||
.Loop1_sqr:
|
||||
lg %r7,0(%r3)
|
||||
mlgr %r6,%r7
|
||||
stg %r7,0(%r2)
|
||||
stg %r6,8(%r2)
|
||||
|
||||
la %r3,8(%r3)
|
||||
la %r2,16(%r2)
|
||||
brct %r4,.Loop1_sqr
|
||||
|
||||
.Lend_sqr:
|
||||
lmg %r6,%r7,48(%r15)
|
||||
br %r14
|
||||
.size bn_sqr_words,.-bn_sqr_words
|
||||
|
||||
// BN_ULONG bn_div_words(BN_ULONG h,BN_ULONG l,BN_ULONG d);
|
||||
.globl bn_div_words
|
||||
.type bn_div_words,@function
|
||||
.align 4
|
||||
bn_div_words:
|
||||
dlgr %r2,%r4
|
||||
lgr %r2,%r3
|
||||
br %r14
|
||||
.size bn_div_words,.-bn_div_words
|
||||
|
||||
// BN_ULONG bn_add_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
|
||||
.globl bn_add_words
|
||||
.type bn_add_words,@function
|
||||
.align 4
|
||||
bn_add_words:
|
||||
la %r1,0(%r2) // put rp aside
|
||||
lghi %r2,0 // i=0
|
||||
ltgfr %r5,%r5
|
||||
bler %r14 // if (len<=0) return 0;
|
||||
|
||||
stg %r6,48(%r15)
|
||||
lghi %r6,3
|
||||
nr %r6,%r5 // len%4
|
||||
sra %r5,2 // len/4, use sra because it sets condition code
|
||||
jz .Loop1_add // carry is incidentally cleared if branch taken
|
||||
algr %r2,%r2 // clear carry
|
||||
|
||||
.Loop4_add:
|
||||
lg %r0,0(%r2,%r3)
|
||||
alcg %r0,0(%r2,%r4)
|
||||
stg %r0,0(%r2,%r1)
|
||||
lg %r0,8(%r2,%r3)
|
||||
alcg %r0,8(%r2,%r4)
|
||||
stg %r0,8(%r2,%r1)
|
||||
lg %r0,16(%r2,%r3)
|
||||
alcg %r0,16(%r2,%r4)
|
||||
stg %r0,16(%r2,%r1)
|
||||
lg %r0,24(%r2,%r3)
|
||||
alcg %r0,24(%r2,%r4)
|
||||
stg %r0,24(%r2,%r1)
|
||||
|
||||
la %r2,32(%r2) // i+=4
|
||||
brct %r5,.Loop4_add
|
||||
|
||||
la %r6,1(%r6) // see if len%4 is zero ...
|
||||
brct %r6,.Loop1_add // without touching condition code:-)
|
||||
|
||||
.Lexit_add:
|
||||
lghi %r2,0
|
||||
alcgr %r2,%r2
|
||||
lg %r6,48(%r15)
|
||||
br %r14
|
||||
|
||||
.Loop1_add:
|
||||
lg %r0,0(%r2,%r3)
|
||||
alcg %r0,0(%r2,%r4)
|
||||
stg %r0,0(%r2,%r1)
|
||||
|
||||
la %r2,8(%r2) // i++
|
||||
brct %r6,.Loop1_add
|
||||
|
||||
j .Lexit_add
|
||||
.size bn_add_words,.-bn_add_words
|
||||
|
||||
// BN_ULONG bn_sub_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
|
||||
.globl bn_sub_words
|
||||
.type bn_sub_words,@function
|
||||
.align 4
|
||||
bn_sub_words:
|
||||
la %r1,0(%r2) // put rp aside
|
||||
lghi %r2,0 // i=0
|
||||
ltgfr %r5,%r5
|
||||
bler %r14 // if (len<=0) return 0;
|
||||
|
||||
stg %r6,48(%r15)
|
||||
lghi %r6,3
|
||||
nr %r6,%r5 // len%4
|
||||
sra %r5,2 // len/4, use sra because it sets condition code
|
||||
jnz .Loop4_sub // borrow is incidentally cleared if branch taken
|
||||
slgr %r2,%r2 // clear borrow
|
||||
|
||||
.Loop1_sub:
|
||||
lg %r0,0(%r2,%r3)
|
||||
slbg %r0,0(%r2,%r4)
|
||||
stg %r0,0(%r2,%r1)
|
||||
|
||||
la %r2,8(%r2) // i++
|
||||
brct %r6,.Loop1_sub
|
||||
j .Lexit_sub
|
||||
|
||||
.Loop4_sub:
|
||||
lg %r0,0(%r2,%r3)
|
||||
slbg %r0,0(%r2,%r4)
|
||||
stg %r0,0(%r2,%r1)
|
||||
lg %r0,8(%r2,%r3)
|
||||
slbg %r0,8(%r2,%r4)
|
||||
stg %r0,8(%r2,%r1)
|
||||
lg %r0,16(%r2,%r3)
|
||||
slbg %r0,16(%r2,%r4)
|
||||
stg %r0,16(%r2,%r1)
|
||||
lg %r0,24(%r2,%r3)
|
||||
slbg %r0,24(%r2,%r4)
|
||||
stg %r0,24(%r2,%r1)
|
||||
|
||||
la %r2,32(%r2) // i+=4
|
||||
brct %r5,.Loop4_sub
|
||||
|
||||
la %r6,1(%r6) // see if len%4 is zero ...
|
||||
brct %r6,.Loop1_sub // without touching condition code:-)
|
||||
|
||||
.Lexit_sub:
|
||||
lghi %r2,0
|
||||
slbgr %r2,%r2
|
||||
lcgr %r2,%r2
|
||||
lg %r6,48(%r15)
|
||||
br %r14
|
||||
.size bn_sub_words,.-bn_sub_words
|
||||
|
||||
#define c1 %r1
|
||||
#define c2 %r5
|
||||
#define c3 %r8
|
||||
|
||||
#define mul_add_c(ai,bi,c1,c2,c3) \
|
||||
lg %r7,ai*8(%r3); \
|
||||
mlg %r6,bi*8(%r4); \
|
||||
algr c1,%r7; \
|
||||
alcgr c2,%r6; \
|
||||
alcgr c3,zero
|
||||
|
||||
// void bn_mul_comba8(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
|
||||
.globl bn_mul_comba8
|
||||
.type bn_mul_comba8,@function
|
||||
.align 4
|
||||
bn_mul_comba8:
|
||||
stmg %r6,%r8,48(%r15)
|
||||
|
||||
lghi c1,0
|
||||
lghi c2,0
|
||||
lghi c3,0
|
||||
lghi zero,0
|
||||
|
||||
mul_add_c(0,0,c1,c2,c3);
|
||||
stg c1,0*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
mul_add_c(0,1,c2,c3,c1);
|
||||
mul_add_c(1,0,c2,c3,c1);
|
||||
stg c2,1*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
mul_add_c(2,0,c3,c1,c2);
|
||||
mul_add_c(1,1,c3,c1,c2);
|
||||
mul_add_c(0,2,c3,c1,c2);
|
||||
stg c3,2*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
mul_add_c(0,3,c1,c2,c3);
|
||||
mul_add_c(1,2,c1,c2,c3);
|
||||
mul_add_c(2,1,c1,c2,c3);
|
||||
mul_add_c(3,0,c1,c2,c3);
|
||||
stg c1,3*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
mul_add_c(4,0,c2,c3,c1);
|
||||
mul_add_c(3,1,c2,c3,c1);
|
||||
mul_add_c(2,2,c2,c3,c1);
|
||||
mul_add_c(1,3,c2,c3,c1);
|
||||
mul_add_c(0,4,c2,c3,c1);
|
||||
stg c2,4*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
mul_add_c(0,5,c3,c1,c2);
|
||||
mul_add_c(1,4,c3,c1,c2);
|
||||
mul_add_c(2,3,c3,c1,c2);
|
||||
mul_add_c(3,2,c3,c1,c2);
|
||||
mul_add_c(4,1,c3,c1,c2);
|
||||
mul_add_c(5,0,c3,c1,c2);
|
||||
stg c3,5*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
mul_add_c(6,0,c1,c2,c3);
|
||||
mul_add_c(5,1,c1,c2,c3);
|
||||
mul_add_c(4,2,c1,c2,c3);
|
||||
mul_add_c(3,3,c1,c2,c3);
|
||||
mul_add_c(2,4,c1,c2,c3);
|
||||
mul_add_c(1,5,c1,c2,c3);
|
||||
mul_add_c(0,6,c1,c2,c3);
|
||||
stg c1,6*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
mul_add_c(0,7,c2,c3,c1);
|
||||
mul_add_c(1,6,c2,c3,c1);
|
||||
mul_add_c(2,5,c2,c3,c1);
|
||||
mul_add_c(3,4,c2,c3,c1);
|
||||
mul_add_c(4,3,c2,c3,c1);
|
||||
mul_add_c(5,2,c2,c3,c1);
|
||||
mul_add_c(6,1,c2,c3,c1);
|
||||
mul_add_c(7,0,c2,c3,c1);
|
||||
stg c2,7*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
mul_add_c(7,1,c3,c1,c2);
|
||||
mul_add_c(6,2,c3,c1,c2);
|
||||
mul_add_c(5,3,c3,c1,c2);
|
||||
mul_add_c(4,4,c3,c1,c2);
|
||||
mul_add_c(3,5,c3,c1,c2);
|
||||
mul_add_c(2,6,c3,c1,c2);
|
||||
mul_add_c(1,7,c3,c1,c2);
|
||||
stg c3,8*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
mul_add_c(2,7,c1,c2,c3);
|
||||
mul_add_c(3,6,c1,c2,c3);
|
||||
mul_add_c(4,5,c1,c2,c3);
|
||||
mul_add_c(5,4,c1,c2,c3);
|
||||
mul_add_c(6,3,c1,c2,c3);
|
||||
mul_add_c(7,2,c1,c2,c3);
|
||||
stg c1,9*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
mul_add_c(7,3,c2,c3,c1);
|
||||
mul_add_c(6,4,c2,c3,c1);
|
||||
mul_add_c(5,5,c2,c3,c1);
|
||||
mul_add_c(4,6,c2,c3,c1);
|
||||
mul_add_c(3,7,c2,c3,c1);
|
||||
stg c2,10*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
mul_add_c(4,7,c3,c1,c2);
|
||||
mul_add_c(5,6,c3,c1,c2);
|
||||
mul_add_c(6,5,c3,c1,c2);
|
||||
mul_add_c(7,4,c3,c1,c2);
|
||||
stg c3,11*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
mul_add_c(7,5,c1,c2,c3);
|
||||
mul_add_c(6,6,c1,c2,c3);
|
||||
mul_add_c(5,7,c1,c2,c3);
|
||||
stg c1,12*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
|
||||
mul_add_c(6,7,c2,c3,c1);
|
||||
mul_add_c(7,6,c2,c3,c1);
|
||||
stg c2,13*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
mul_add_c(7,7,c3,c1,c2);
|
||||
stg c3,14*8(%r2)
|
||||
stg c1,15*8(%r2)
|
||||
|
||||
lmg %r6,%r8,48(%r15)
|
||||
br %r14
|
||||
.size bn_mul_comba8,.-bn_mul_comba8
|
||||
|
||||
// void bn_mul_comba4(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
|
||||
.globl bn_mul_comba4
|
||||
.type bn_mul_comba4,@function
|
||||
.align 4
|
||||
bn_mul_comba4:
|
||||
stmg %r6,%r8,48(%r15)
|
||||
|
||||
lghi c1,0
|
||||
lghi c2,0
|
||||
lghi c3,0
|
||||
lghi zero,0
|
||||
|
||||
mul_add_c(0,0,c1,c2,c3);
|
||||
stg c1,0*8(%r3)
|
||||
lghi c1,0
|
||||
|
||||
mul_add_c(0,1,c2,c3,c1);
|
||||
mul_add_c(1,0,c2,c3,c1);
|
||||
stg c2,1*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
mul_add_c(2,0,c3,c1,c2);
|
||||
mul_add_c(1,1,c3,c1,c2);
|
||||
mul_add_c(0,2,c3,c1,c2);
|
||||
stg c3,2*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
mul_add_c(0,3,c1,c2,c3);
|
||||
mul_add_c(1,2,c1,c2,c3);
|
||||
mul_add_c(2,1,c1,c2,c3);
|
||||
mul_add_c(3,0,c1,c2,c3);
|
||||
stg c1,3*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
mul_add_c(3,1,c2,c3,c1);
|
||||
mul_add_c(2,2,c2,c3,c1);
|
||||
mul_add_c(1,3,c2,c3,c1);
|
||||
stg c2,4*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
mul_add_c(2,3,c3,c1,c2);
|
||||
mul_add_c(3,2,c3,c1,c2);
|
||||
stg c3,5*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
mul_add_c(3,3,c1,c2,c3);
|
||||
stg c1,6*8(%r2)
|
||||
stg c2,7*8(%r2)
|
||||
|
||||
stmg %r6,%r8,48(%r15)
|
||||
br %r14
|
||||
.size bn_mul_comba4,.-bn_mul_comba4
|
||||
|
||||
#define sqr_add_c(ai,c1,c2,c3) \
|
||||
lg %r7,ai*8(%r3); \
|
||||
mlgr %r6,%r7; \
|
||||
algr c1,%r7; \
|
||||
alcgr c2,%r6; \
|
||||
alcgr c3,zero
|
||||
|
||||
#define sqr_add_c2(ai,aj,c1,c2,c3) \
|
||||
lg %r7,ai*8(%r3); \
|
||||
mlg %r6,aj*8(%r3); \
|
||||
algr c1,%r7; \
|
||||
alcgr c2,%r6; \
|
||||
alcgr c3,zero; \
|
||||
algr c1,%r7; \
|
||||
alcgr c2,%r6; \
|
||||
alcgr c3,zero
|
||||
|
||||
// void bn_sqr_comba8(BN_ULONG *r2,BN_ULONG *r3);
|
||||
.globl bn_sqr_comba8
|
||||
.type bn_sqr_comba8,@function
|
||||
.align 4
|
||||
bn_sqr_comba8:
|
||||
stmg %r6,%r8,48(%r15)
|
||||
|
||||
lghi c1,0
|
||||
lghi c2,0
|
||||
lghi c3,0
|
||||
lghi zero,0
|
||||
|
||||
sqr_add_c(0,c1,c2,c3);
|
||||
stg c1,0*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
sqr_add_c2(1,0,c2,c3,c1);
|
||||
stg c2,1*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
sqr_add_c(1,c3,c1,c2);
|
||||
sqr_add_c2(2,0,c3,c1,c2);
|
||||
stg c3,2*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
sqr_add_c2(3,0,c1,c2,c3);
|
||||
sqr_add_c2(2,1,c1,c2,c3);
|
||||
stg c1,3*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
sqr_add_c(2,c2,c3,c1);
|
||||
sqr_add_c2(3,1,c2,c3,c1);
|
||||
sqr_add_c2(4,0,c2,c3,c1);
|
||||
stg c2,4*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
sqr_add_c2(5,0,c3,c1,c2);
|
||||
sqr_add_c2(4,1,c3,c1,c2);
|
||||
sqr_add_c2(3,2,c3,c1,c2);
|
||||
stg c3,5*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
sqr_add_c(3,c1,c2,c3);
|
||||
sqr_add_c2(4,2,c1,c2,c3);
|
||||
sqr_add_c2(5,1,c1,c2,c3);
|
||||
sqr_add_c2(6,0,c1,c2,c3);
|
||||
stg c1,6*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
sqr_add_c2(7,0,c2,c3,c1);
|
||||
sqr_add_c2(6,1,c2,c3,c1);
|
||||
sqr_add_c2(5,2,c2,c3,c1);
|
||||
sqr_add_c2(4,3,c2,c3,c1);
|
||||
stg c2,7*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
sqr_add_c(4,c3,c1,c2);
|
||||
sqr_add_c2(5,3,c3,c1,c2);
|
||||
sqr_add_c2(6,2,c3,c1,c2);
|
||||
sqr_add_c2(7,1,c3,c1,c2);
|
||||
stg c3,8*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
sqr_add_c2(7,2,c1,c2,c3);
|
||||
sqr_add_c2(6,3,c1,c2,c3);
|
||||
sqr_add_c2(5,4,c1,c2,c3);
|
||||
stg c1,9*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
sqr_add_c(5,c2,c3,c1);
|
||||
sqr_add_c2(6,4,c2,c3,c1);
|
||||
sqr_add_c2(7,3,c2,c3,c1);
|
||||
stg c2,10*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
sqr_add_c2(7,4,c3,c1,c2);
|
||||
sqr_add_c2(6,5,c3,c1,c2);
|
||||
stg c3,11*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
sqr_add_c(6,c1,c2,c3);
|
||||
sqr_add_c2(7,5,c1,c2,c3);
|
||||
stg c1,12*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
sqr_add_c2(7,6,c2,c3,c1);
|
||||
stg c2,13*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
sqr_add_c(7,c3,c1,c2);
|
||||
stg c3,14*8(%r2)
|
||||
stg c1,15*8(%r2)
|
||||
|
||||
lmg %r6,%r8,48(%r15)
|
||||
br %r14
|
||||
.size bn_sqr_comba8,.-bn_sqr_comba8
|
||||
|
||||
// void bn_sqr_comba4(BN_ULONG *r2,BN_ULONG *r3);
|
||||
.globl bn_sqr_comba4
|
||||
.type bn_sqr_comba4,@function
|
||||
.align 4
|
||||
bn_sqr_comba4:
|
||||
stmg %r6,%r8,48(%r15)
|
||||
|
||||
lghi c1,0
|
||||
lghi c2,0
|
||||
lghi c3,0
|
||||
lghi zero,0
|
||||
|
||||
sqr_add_c(0,c1,c2,c3);
|
||||
stg c1,0*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
sqr_add_c2(1,0,c2,c3,c1);
|
||||
stg c2,1*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
sqr_add_c(1,c3,c1,c2);
|
||||
sqr_add_c2(2,0,c3,c1,c2);
|
||||
stg c3,2*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
sqr_add_c2(3,0,c1,c2,c3);
|
||||
sqr_add_c2(2,1,c1,c2,c3);
|
||||
stg c1,3*8(%r2)
|
||||
lghi c1,0
|
||||
|
||||
sqr_add_c(2,c2,c3,c1);
|
||||
sqr_add_c2(3,1,c2,c3,c1);
|
||||
stg c2,4*8(%r2)
|
||||
lghi c2,0
|
||||
|
||||
sqr_add_c2(3,2,c3,c1,c2);
|
||||
stg c3,5*8(%r2)
|
||||
lghi c3,0
|
||||
|
||||
sqr_add_c(3,c1,c2,c3);
|
||||
stg c1,6*8(%r2)
|
||||
stg c2,7*8(%r2)
|
||||
|
||||
lmg %r6,%r8,48(%r15)
|
||||
br %r14
|
||||
.size bn_sqr_comba4,.-bn_sqr_comba4
|
606
crypto/bn/asm/sparcv9-mont.pl
Normal file
606
crypto/bn/asm/sparcv9-mont.pl
Normal file
@@ -0,0 +1,606 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# December 2005
|
||||
#
|
||||
# Pure SPARCv9/8+ and IALU-only bn_mul_mont implementation. The reasons
|
||||
# for undertaken effort are multiple. First of all, UltraSPARC is not
|
||||
# the whole SPARCv9 universe and other VIS-free implementations deserve
|
||||
# optimized code as much. Secondly, newly introduced UltraSPARC T1,
|
||||
# a.k.a. Niagara, has shared FPU and concurrent FPU-intensive pathes,
|
||||
# such as sparcv9a-mont, will simply sink it. Yes, T1 is equipped with
|
||||
# several integrated RSA/DSA accelerator circuits accessible through
|
||||
# kernel driver [only(*)], but having decent user-land software
|
||||
# implementation is important too. Finally, reasons like desire to
|
||||
# experiment with dedicated squaring procedure. Yes, this module
|
||||
# implements one, because it was easiest to draft it in SPARCv9
|
||||
# instructions...
|
||||
|
||||
# (*) Engine accessing the driver in question is on my TODO list.
|
||||
# For reference, acceleator is estimated to give 6 to 10 times
|
||||
# improvement on single-threaded RSA sign. It should be noted
|
||||
# that 6-10x improvement coefficient does not actually mean
|
||||
# something extraordinary in terms of absolute [single-threaded]
|
||||
# performance, as SPARCv9 instruction set is by all means least
|
||||
# suitable for high performance crypto among other 64 bit
|
||||
# platforms. 6-10x factor simply places T1 in same performance
|
||||
# domain as say AMD64 and IA-64. Improvement of RSA verify don't
|
||||
# appear impressive at all, but it's the sign operation which is
|
||||
# far more critical/interesting.
|
||||
|
||||
# You might notice that inner loops are modulo-scheduled:-) This has
|
||||
# essentially negligible impact on UltraSPARC performance, it's
|
||||
# Fujitsu SPARC64 V users who should notice and hopefully appreciate
|
||||
# the advantage... Currently this module surpasses sparcv9a-mont.pl
|
||||
# by ~20% on UltraSPARC-III and later cores, but recall that sparcv9a
|
||||
# module still have hidden potential [see TODO list there], which is
|
||||
# estimated to be larger than 20%...
|
||||
|
||||
# int bn_mul_mont(
|
||||
$rp="%i0"; # BN_ULONG *rp,
|
||||
$ap="%i1"; # const BN_ULONG *ap,
|
||||
$bp="%i2"; # const BN_ULONG *bp,
|
||||
$np="%i3"; # const BN_ULONG *np,
|
||||
$n0="%i4"; # const BN_ULONG *n0,
|
||||
$num="%i5"; # int num);
|
||||
|
||||
$bits=32;
|
||||
for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
|
||||
if ($bits==64) { $bias=2047; $frame=192; }
|
||||
else { $bias=0; $frame=128; }
|
||||
|
||||
$car0="%o0";
|
||||
$car1="%o1";
|
||||
$car2="%o2"; # 1 bit
|
||||
$acc0="%o3";
|
||||
$acc1="%o4";
|
||||
$mask="%g1"; # 32 bits, what a waste...
|
||||
$tmp0="%g4";
|
||||
$tmp1="%g5";
|
||||
|
||||
$i="%l0";
|
||||
$j="%l1";
|
||||
$mul0="%l2";
|
||||
$mul1="%l3";
|
||||
$tp="%l4";
|
||||
$apj="%l5";
|
||||
$npj="%l6";
|
||||
$tpj="%l7";
|
||||
|
||||
$fname="bn_mul_mont_int";
|
||||
|
||||
$code=<<___;
|
||||
.section ".text",#alloc,#execinstr
|
||||
|
||||
.global $fname
|
||||
.align 32
|
||||
$fname:
|
||||
cmp %o5,4 ! 128 bits minimum
|
||||
bge,pt %icc,.Lenter
|
||||
sethi %hi(0xffffffff),$mask
|
||||
retl
|
||||
clr %o0
|
||||
.align 32
|
||||
.Lenter:
|
||||
save %sp,-$frame,%sp
|
||||
sll $num,2,$num ! num*=4
|
||||
or $mask,%lo(0xffffffff),$mask
|
||||
ld [$n0],$n0
|
||||
cmp $ap,$bp
|
||||
and $num,$mask,$num
|
||||
ld [$bp],$mul0 ! bp[0]
|
||||
nop
|
||||
|
||||
add %sp,$bias,%o7 ! real top of stack
|
||||
ld [$ap],$car0 ! ap[0] ! redundant in squaring context
|
||||
sub %o7,$num,%o7
|
||||
ld [$ap+4],$apj ! ap[1]
|
||||
and %o7,-1024,%o7
|
||||
ld [$np],$car1 ! np[0]
|
||||
sub %o7,$bias,%sp ! alloca
|
||||
ld [$np+4],$npj ! np[1]
|
||||
be,pt `$bits==32?"%icc":"%xcc"`,.Lbn_sqr_mont
|
||||
mov 12,$j
|
||||
|
||||
mulx $car0,$mul0,$car0 ! ap[0]*bp[0]
|
||||
mulx $apj,$mul0,$tmp0 !prologue! ap[1]*bp[0]
|
||||
and $car0,$mask,$acc0
|
||||
add %sp,$bias+$frame,$tp
|
||||
ld [$ap+8],$apj !prologue!
|
||||
|
||||
mulx $n0,$acc0,$mul1 ! "t[0]"*n0
|
||||
and $mul1,$mask,$mul1
|
||||
|
||||
mulx $car1,$mul1,$car1 ! np[0]*"t[0]"*n0
|
||||
mulx $npj,$mul1,$acc1 !prologue! np[1]*"t[0]"*n0
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$car1,$car1
|
||||
ld [$np+8],$npj !prologue!
|
||||
srlx $car1,32,$car1
|
||||
mov $tmp0,$acc0 !prologue!
|
||||
|
||||
.L1st:
|
||||
mulx $apj,$mul0,$tmp0
|
||||
mulx $npj,$mul1,$tmp1
|
||||
add $acc0,$car0,$car0
|
||||
ld [$ap+$j],$apj ! ap[j]
|
||||
and $car0,$mask,$acc0
|
||||
add $acc1,$car1,$car1
|
||||
ld [$np+$j],$npj ! np[j]
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$car1,$car1
|
||||
add $j,4,$j ! j++
|
||||
mov $tmp0,$acc0
|
||||
st $car1,[$tp]
|
||||
cmp $j,$num
|
||||
mov $tmp1,$acc1
|
||||
srlx $car1,32,$car1
|
||||
bl %icc,.L1st
|
||||
add $tp,4,$tp ! tp++
|
||||
!.L1st
|
||||
|
||||
mulx $apj,$mul0,$tmp0 !epilogue!
|
||||
mulx $npj,$mul1,$tmp1
|
||||
add $acc0,$car0,$car0
|
||||
and $car0,$mask,$acc0
|
||||
add $acc1,$car1,$car1
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$car1,$car1
|
||||
st $car1,[$tp]
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $tmp0,$car0,$car0
|
||||
and $car0,$mask,$acc0
|
||||
add $tmp1,$car1,$car1
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$car1,$car1
|
||||
st $car1,[$tp+4]
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $car0,$car1,$car1
|
||||
st $car1,[$tp+8]
|
||||
srlx $car1,32,$car2
|
||||
|
||||
mov 4,$i ! i++
|
||||
ld [$bp+4],$mul0 ! bp[1]
|
||||
.Louter:
|
||||
add %sp,$bias+$frame,$tp
|
||||
ld [$ap],$car0 ! ap[0]
|
||||
ld [$ap+4],$apj ! ap[1]
|
||||
ld [$np],$car1 ! np[0]
|
||||
ld [$np+4],$npj ! np[1]
|
||||
ld [$tp],$tmp1 ! tp[0]
|
||||
ld [$tp+4],$tpj ! tp[1]
|
||||
mov 12,$j
|
||||
|
||||
mulx $car0,$mul0,$car0
|
||||
mulx $apj,$mul0,$tmp0 !prologue!
|
||||
add $tmp1,$car0,$car0
|
||||
ld [$ap+8],$apj !prologue!
|
||||
and $car0,$mask,$acc0
|
||||
|
||||
mulx $n0,$acc0,$mul1
|
||||
and $mul1,$mask,$mul1
|
||||
|
||||
mulx $car1,$mul1,$car1
|
||||
mulx $npj,$mul1,$acc1 !prologue!
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$car1,$car1
|
||||
ld [$np+8],$npj !prologue!
|
||||
srlx $car1,32,$car1
|
||||
mov $tmp0,$acc0 !prologue!
|
||||
|
||||
.Linner:
|
||||
mulx $apj,$mul0,$tmp0
|
||||
mulx $npj,$mul1,$tmp1
|
||||
add $tpj,$car0,$car0
|
||||
ld [$ap+$j],$apj ! ap[j]
|
||||
add $acc0,$car0,$car0
|
||||
add $acc1,$car1,$car1
|
||||
ld [$np+$j],$npj ! np[j]
|
||||
and $car0,$mask,$acc0
|
||||
ld [$tp+8],$tpj ! tp[j]
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$car1,$car1
|
||||
add $j,4,$j ! j++
|
||||
mov $tmp0,$acc0
|
||||
st $car1,[$tp] ! tp[j-1]
|
||||
srlx $car1,32,$car1
|
||||
mov $tmp1,$acc1
|
||||
cmp $j,$num
|
||||
bl %icc,.Linner
|
||||
add $tp,4,$tp ! tp++
|
||||
!.Linner
|
||||
|
||||
mulx $apj,$mul0,$tmp0 !epilogue!
|
||||
mulx $npj,$mul1,$tmp1
|
||||
add $tpj,$car0,$car0
|
||||
add $acc0,$car0,$car0
|
||||
ld [$tp+8],$tpj ! tp[j]
|
||||
and $car0,$mask,$acc0
|
||||
add $acc1,$car1,$car1
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$car1,$car1
|
||||
st $car1,[$tp] ! tp[j-1]
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $tpj,$car0,$car0
|
||||
add $tmp0,$car0,$car0
|
||||
and $car0,$mask,$acc0
|
||||
add $tmp1,$car1,$car1
|
||||
add $acc0,$car1,$car1
|
||||
st $car1,[$tp+4] ! tp[j-1]
|
||||
srlx $car0,32,$car0
|
||||
add $i,4,$i ! i++
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $car0,$car1,$car1
|
||||
cmp $i,$num
|
||||
add $car2,$car1,$car1
|
||||
st $car1,[$tp+8]
|
||||
|
||||
srlx $car1,32,$car2
|
||||
bl,a %icc,.Louter
|
||||
ld [$bp+$i],$mul0 ! bp[i]
|
||||
!.Louter
|
||||
|
||||
add $tp,12,$tp
|
||||
|
||||
.Ltail:
|
||||
add $np,$num,$np
|
||||
add $rp,$num,$rp
|
||||
mov $tp,$ap
|
||||
sub %g0,$num,%o7 ! k=-num
|
||||
ba .Lsub
|
||||
subcc %g0,%g0,%g0 ! clear %icc.c
|
||||
.align 16
|
||||
.Lsub:
|
||||
ld [$tp+%o7],%o0
|
||||
ld [$np+%o7],%o1
|
||||
subccc %o0,%o1,%o1 ! tp[j]-np[j]
|
||||
add $rp,%o7,$i
|
||||
add %o7,4,%o7
|
||||
brnz %o7,.Lsub
|
||||
st %o1,[$i]
|
||||
subc $car2,0,$car2 ! handle upmost overflow bit
|
||||
and $tp,$car2,$ap
|
||||
andn $rp,$car2,$np
|
||||
or $ap,$np,$ap
|
||||
sub %g0,$num,%o7
|
||||
|
||||
.Lcopy:
|
||||
ld [$ap+%o7],%o0 ! copy or in-place refresh
|
||||
st %g0,[$tp+%o7] ! zap tp
|
||||
st %o0,[$rp+%o7]
|
||||
add %o7,4,%o7
|
||||
brnz %o7,.Lcopy
|
||||
nop
|
||||
mov 1,%i0
|
||||
ret
|
||||
restore
|
||||
___
|
||||
|
||||
########
|
||||
######## .Lbn_sqr_mont gives up to 20% *overall* improvement over
|
||||
######## code without following dedicated squaring procedure.
|
||||
########
|
||||
$sbit="%i2"; # re-use $bp!
|
||||
|
||||
$code.=<<___;
|
||||
.align 32
|
||||
.Lbn_sqr_mont:
|
||||
mulx $mul0,$mul0,$car0 ! ap[0]*ap[0]
|
||||
mulx $apj,$mul0,$tmp0 !prologue!
|
||||
and $car0,$mask,$acc0
|
||||
add %sp,$bias+$frame,$tp
|
||||
ld [$ap+8],$apj !prologue!
|
||||
|
||||
mulx $n0,$acc0,$mul1 ! "t[0]"*n0
|
||||
srlx $car0,32,$car0
|
||||
and $mul1,$mask,$mul1
|
||||
|
||||
mulx $car1,$mul1,$car1 ! np[0]*"t[0]"*n0
|
||||
mulx $npj,$mul1,$acc1 !prologue!
|
||||
and $car0,1,$sbit
|
||||
ld [$np+8],$npj !prologue!
|
||||
srlx $car0,1,$car0
|
||||
add $acc0,$car1,$car1
|
||||
srlx $car1,32,$car1
|
||||
mov $tmp0,$acc0 !prologue!
|
||||
|
||||
.Lsqr_1st:
|
||||
mulx $apj,$mul0,$tmp0
|
||||
mulx $npj,$mul1,$tmp1
|
||||
add $acc0,$car0,$car0 ! ap[j]*a0+c0
|
||||
add $acc1,$car1,$car1
|
||||
ld [$ap+$j],$apj ! ap[j]
|
||||
and $car0,$mask,$acc0
|
||||
ld [$np+$j],$npj ! np[j]
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$acc0,$acc0
|
||||
or $sbit,$acc0,$acc0
|
||||
mov $tmp1,$acc1
|
||||
srlx $acc0,32,$sbit
|
||||
add $j,4,$j ! j++
|
||||
and $acc0,$mask,$acc0
|
||||
cmp $j,$num
|
||||
add $acc0,$car1,$car1
|
||||
st $car1,[$tp]
|
||||
mov $tmp0,$acc0
|
||||
srlx $car1,32,$car1
|
||||
bl %icc,.Lsqr_1st
|
||||
add $tp,4,$tp ! tp++
|
||||
!.Lsqr_1st
|
||||
|
||||
mulx $apj,$mul0,$tmp0 ! epilogue
|
||||
mulx $npj,$mul1,$tmp1
|
||||
add $acc0,$car0,$car0 ! ap[j]*a0+c0
|
||||
add $acc1,$car1,$car1
|
||||
and $car0,$mask,$acc0
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$acc0,$acc0
|
||||
or $sbit,$acc0,$acc0
|
||||
srlx $acc0,32,$sbit
|
||||
and $acc0,$mask,$acc0
|
||||
add $acc0,$car1,$car1
|
||||
st $car1,[$tp]
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $tmp0,$car0,$car0 ! ap[j]*a0+c0
|
||||
add $tmp1,$car1,$car1
|
||||
and $car0,$mask,$acc0
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$acc0,$acc0
|
||||
or $sbit,$acc0,$acc0
|
||||
srlx $acc0,32,$sbit
|
||||
and $acc0,$mask,$acc0
|
||||
add $acc0,$car1,$car1
|
||||
st $car1,[$tp+4]
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $car0,$car0,$car0
|
||||
or $sbit,$car0,$car0
|
||||
add $car0,$car1,$car1
|
||||
st $car1,[$tp+8]
|
||||
srlx $car1,32,$car2
|
||||
|
||||
ld [%sp+$bias+$frame],$tmp0 ! tp[0]
|
||||
ld [%sp+$bias+$frame+4],$tmp1 ! tp[1]
|
||||
ld [%sp+$bias+$frame+8],$tpj ! tp[2]
|
||||
ld [$ap+4],$mul0 ! ap[1]
|
||||
ld [$ap+8],$apj ! ap[2]
|
||||
ld [$np],$car1 ! np[0]
|
||||
ld [$np+4],$npj ! np[1]
|
||||
mulx $n0,$tmp0,$mul1
|
||||
|
||||
mulx $mul0,$mul0,$car0
|
||||
and $mul1,$mask,$mul1
|
||||
|
||||
mulx $car1,$mul1,$car1
|
||||
mulx $npj,$mul1,$acc1
|
||||
add $tmp0,$car1,$car1
|
||||
and $car0,$mask,$acc0
|
||||
ld [$np+8],$npj ! np[2]
|
||||
srlx $car1,32,$car1
|
||||
add $tmp1,$car1,$car1
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$car1,$car1
|
||||
and $car0,1,$sbit
|
||||
add $acc1,$car1,$car1
|
||||
srlx $car0,1,$car0
|
||||
mov 12,$j
|
||||
st $car1,[%sp+$bias+$frame] ! tp[0]=
|
||||
srlx $car1,32,$car1
|
||||
add %sp,$bias+$frame+4,$tp
|
||||
|
||||
.Lsqr_2nd:
|
||||
mulx $apj,$mul0,$acc0
|
||||
mulx $npj,$mul1,$acc1
|
||||
add $acc0,$car0,$car0
|
||||
add $tpj,$car1,$car1
|
||||
ld [$ap+$j],$apj ! ap[j]
|
||||
and $car0,$mask,$acc0
|
||||
ld [$np+$j],$npj ! np[j]
|
||||
srlx $car0,32,$car0
|
||||
add $acc1,$car1,$car1
|
||||
ld [$tp+8],$tpj ! tp[j]
|
||||
add $acc0,$acc0,$acc0
|
||||
add $j,4,$j ! j++
|
||||
or $sbit,$acc0,$acc0
|
||||
srlx $acc0,32,$sbit
|
||||
and $acc0,$mask,$acc0
|
||||
cmp $j,$num
|
||||
add $acc0,$car1,$car1
|
||||
st $car1,[$tp] ! tp[j-1]
|
||||
srlx $car1,32,$car1
|
||||
bl %icc,.Lsqr_2nd
|
||||
add $tp,4,$tp ! tp++
|
||||
!.Lsqr_2nd
|
||||
|
||||
mulx $apj,$mul0,$acc0
|
||||
mulx $npj,$mul1,$acc1
|
||||
add $acc0,$car0,$car0
|
||||
add $tpj,$car1,$car1
|
||||
and $car0,$mask,$acc0
|
||||
srlx $car0,32,$car0
|
||||
add $acc1,$car1,$car1
|
||||
add $acc0,$acc0,$acc0
|
||||
or $sbit,$acc0,$acc0
|
||||
srlx $acc0,32,$sbit
|
||||
and $acc0,$mask,$acc0
|
||||
add $acc0,$car1,$car1
|
||||
st $car1,[$tp] ! tp[j-1]
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $car0,$car0,$car0
|
||||
or $sbit,$car0,$car0
|
||||
add $car0,$car1,$car1
|
||||
add $car2,$car1,$car1
|
||||
st $car1,[$tp+4]
|
||||
srlx $car1,32,$car2
|
||||
|
||||
ld [%sp+$bias+$frame],$tmp1 ! tp[0]
|
||||
ld [%sp+$bias+$frame+4],$tpj ! tp[1]
|
||||
ld [$ap+8],$mul0 ! ap[2]
|
||||
ld [$np],$car1 ! np[0]
|
||||
ld [$np+4],$npj ! np[1]
|
||||
mulx $n0,$tmp1,$mul1
|
||||
and $mul1,$mask,$mul1
|
||||
mov 8,$i
|
||||
|
||||
mulx $mul0,$mul0,$car0
|
||||
mulx $car1,$mul1,$car1
|
||||
and $car0,$mask,$acc0
|
||||
add $tmp1,$car1,$car1
|
||||
srlx $car0,32,$car0
|
||||
add %sp,$bias+$frame,$tp
|
||||
srlx $car1,32,$car1
|
||||
and $car0,1,$sbit
|
||||
srlx $car0,1,$car0
|
||||
mov 4,$j
|
||||
|
||||
.Lsqr_outer:
|
||||
.Lsqr_inner1:
|
||||
mulx $npj,$mul1,$acc1
|
||||
add $tpj,$car1,$car1
|
||||
add $j,4,$j
|
||||
ld [$tp+8],$tpj
|
||||
cmp $j,$i
|
||||
add $acc1,$car1,$car1
|
||||
ld [$np+$j],$npj
|
||||
st $car1,[$tp]
|
||||
srlx $car1,32,$car1
|
||||
bl %icc,.Lsqr_inner1
|
||||
add $tp,4,$tp
|
||||
!.Lsqr_inner1
|
||||
|
||||
add $j,4,$j
|
||||
ld [$ap+$j],$apj ! ap[j]
|
||||
mulx $npj,$mul1,$acc1
|
||||
add $tpj,$car1,$car1
|
||||
ld [$np+$j],$npj ! np[j]
|
||||
add $acc0,$car1,$car1
|
||||
ld [$tp+8],$tpj ! tp[j]
|
||||
add $acc1,$car1,$car1
|
||||
st $car1,[$tp]
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $j,4,$j
|
||||
cmp $j,$num
|
||||
be,pn %icc,.Lsqr_no_inner2
|
||||
add $tp,4,$tp
|
||||
|
||||
.Lsqr_inner2:
|
||||
mulx $apj,$mul0,$acc0
|
||||
mulx $npj,$mul1,$acc1
|
||||
add $tpj,$car1,$car1
|
||||
add $acc0,$car0,$car0
|
||||
ld [$ap+$j],$apj ! ap[j]
|
||||
and $car0,$mask,$acc0
|
||||
ld [$np+$j],$npj ! np[j]
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$acc0,$acc0
|
||||
ld [$tp+8],$tpj ! tp[j]
|
||||
or $sbit,$acc0,$acc0
|
||||
add $j,4,$j ! j++
|
||||
srlx $acc0,32,$sbit
|
||||
and $acc0,$mask,$acc0
|
||||
cmp $j,$num
|
||||
add $acc0,$car1,$car1
|
||||
add $acc1,$car1,$car1
|
||||
st $car1,[$tp] ! tp[j-1]
|
||||
srlx $car1,32,$car1
|
||||
bl %icc,.Lsqr_inner2
|
||||
add $tp,4,$tp ! tp++
|
||||
|
||||
.Lsqr_no_inner2:
|
||||
mulx $apj,$mul0,$acc0
|
||||
mulx $npj,$mul1,$acc1
|
||||
add $tpj,$car1,$car1
|
||||
add $acc0,$car0,$car0
|
||||
and $car0,$mask,$acc0
|
||||
srlx $car0,32,$car0
|
||||
add $acc0,$acc0,$acc0
|
||||
or $sbit,$acc0,$acc0
|
||||
srlx $acc0,32,$sbit
|
||||
and $acc0,$mask,$acc0
|
||||
add $acc0,$car1,$car1
|
||||
add $acc1,$car1,$car1
|
||||
st $car1,[$tp] ! tp[j-1]
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $car0,$car0,$car0
|
||||
or $sbit,$car0,$car0
|
||||
add $car0,$car1,$car1
|
||||
add $car2,$car1,$car1
|
||||
st $car1,[$tp+4]
|
||||
srlx $car1,32,$car2
|
||||
|
||||
add $i,4,$i ! i++
|
||||
ld [%sp+$bias+$frame],$tmp1 ! tp[0]
|
||||
ld [%sp+$bias+$frame+4],$tpj ! tp[1]
|
||||
ld [$ap+$i],$mul0 ! ap[j]
|
||||
ld [$np],$car1 ! np[0]
|
||||
ld [$np+4],$npj ! np[1]
|
||||
mulx $n0,$tmp1,$mul1
|
||||
and $mul1,$mask,$mul1
|
||||
add $i,4,$tmp0
|
||||
|
||||
mulx $mul0,$mul0,$car0
|
||||
mulx $car1,$mul1,$car1
|
||||
and $car0,$mask,$acc0
|
||||
add $tmp1,$car1,$car1
|
||||
srlx $car0,32,$car0
|
||||
add %sp,$bias+$frame,$tp
|
||||
srlx $car1,32,$car1
|
||||
and $car0,1,$sbit
|
||||
srlx $car0,1,$car0
|
||||
|
||||
cmp $tmp0,$num ! i<num-1
|
||||
bl %icc,.Lsqr_outer
|
||||
mov 4,$j
|
||||
|
||||
.Lsqr_last:
|
||||
mulx $npj,$mul1,$acc1
|
||||
add $tpj,$car1,$car1
|
||||
add $j,4,$j
|
||||
ld [$tp+8],$tpj
|
||||
cmp $j,$i
|
||||
add $acc1,$car1,$car1
|
||||
ld [$np+$j],$npj
|
||||
st $car1,[$tp]
|
||||
srlx $car1,32,$car1
|
||||
bl %icc,.Lsqr_last
|
||||
add $tp,4,$tp
|
||||
!.Lsqr_last
|
||||
|
||||
mulx $npj,$mul1,$acc1
|
||||
add $tpj,$car1,$car1
|
||||
add $acc0,$car1,$car1
|
||||
add $acc1,$car1,$car1
|
||||
st $car1,[$tp]
|
||||
srlx $car1,32,$car1
|
||||
|
||||
add $car0,$car0,$car0 ! recover $car0
|
||||
or $sbit,$car0,$car0
|
||||
add $car0,$car1,$car1
|
||||
add $car2,$car1,$car1
|
||||
st $car1,[$tp+4]
|
||||
srlx $car1,32,$car2
|
||||
|
||||
ba .Ltail
|
||||
add $tp,8,$tp
|
||||
.type $fname,#function
|
||||
.size $fname,(.-$fname)
|
||||
.asciz "Montgomery Multipltication for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
.align 32
|
||||
___
|
||||
$code =~ s/\`([^\`]*)\`/eval($1)/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
882
crypto/bn/asm/sparcv9a-mont.pl
Executable file
882
crypto/bn/asm/sparcv9a-mont.pl
Executable file
@@ -0,0 +1,882 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# October 2005
|
||||
#
|
||||
# "Teaser" Montgomery multiplication module for UltraSPARC. Why FPU?
|
||||
# Because unlike integer multiplier, which simply stalls whole CPU,
|
||||
# FPU is fully pipelined and can effectively emit 48 bit partial
|
||||
# product every cycle. Why not blended SPARC v9? One can argue that
|
||||
# making this module dependent on UltraSPARC VIS extension limits its
|
||||
# binary compatibility. Well yes, it does exclude SPARC64 prior-V(!)
|
||||
# implementations from compatibility matrix. But the rest, whole Sun
|
||||
# UltraSPARC family and brand new Fujitsu's SPARC64 V, all support
|
||||
# VIS extension instructions used in this module. This is considered
|
||||
# good enough to not care about HAL SPARC64 users [if any] who have
|
||||
# integer-only pure SPARCv9 module to "fall down" to.
|
||||
|
||||
# USI&II cores currently exhibit uniform 2x improvement [over pre-
|
||||
# bn_mul_mont codebase] for all key lengths and benchmarks. On USIII
|
||||
# performance improves few percents for shorter keys and worsens few
|
||||
# percents for longer keys. This is because USIII integer multiplier
|
||||
# is >3x faster than USI&II one, which is harder to match [but see
|
||||
# TODO list below]. It should also be noted that SPARC64 V features
|
||||
# out-of-order execution, which *might* mean that integer multiplier
|
||||
# is pipelined, which in turn *might* be impossible to match... On
|
||||
# additional note, SPARC64 V implements FP Multiply-Add instruction,
|
||||
# which is perfectly usable in this context... In other words, as far
|
||||
# as Fujitsu SPARC64 V goes, talk to the author:-)
|
||||
|
||||
# The implementation implies following "non-natural" limitations on
|
||||
# input arguments:
|
||||
# - num may not be less than 4;
|
||||
# - num has to be even;
|
||||
# Failure to meet either condition has no fatal effects, simply
|
||||
# doesn't give any performance gain.
|
||||
|
||||
# TODO:
|
||||
# - modulo-schedule inner loop for better performance (on in-order
|
||||
# execution core such as UltraSPARC this shall result in further
|
||||
# noticeable(!) improvement);
|
||||
# - dedicated squaring procedure[?];
|
||||
|
||||
######################################################################
|
||||
# November 2006
|
||||
#
|
||||
# Modulo-scheduled inner loops allow to interleave floating point and
|
||||
# integer instructions and minimize Read-After-Write penalties. This
|
||||
# results in *further* 20-50% perfromance improvement [depending on
|
||||
# key length, more for longer keys] on USI&II cores and 30-80% - on
|
||||
# USIII&IV.
|
||||
|
||||
$fname="bn_mul_mont_fpu";
|
||||
$bits=32;
|
||||
for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
|
||||
|
||||
if ($bits==64) {
|
||||
$bias=2047;
|
||||
$frame=192;
|
||||
} else {
|
||||
$bias=0;
|
||||
$frame=128; # 96 rounded up to largest known cache-line
|
||||
}
|
||||
$locals=64;
|
||||
|
||||
# In order to provide for 32-/64-bit ABI duality, I keep integers wider
|
||||
# than 32 bit in %g1-%g4 and %o0-%o5. %l0-%l7 and %i0-%i5 are used
|
||||
# exclusively for pointers, indexes and other small values...
|
||||
# int bn_mul_mont(
|
||||
$rp="%i0"; # BN_ULONG *rp,
|
||||
$ap="%i1"; # const BN_ULONG *ap,
|
||||
$bp="%i2"; # const BN_ULONG *bp,
|
||||
$np="%i3"; # const BN_ULONG *np,
|
||||
$n0="%i4"; # const BN_ULONG *n0,
|
||||
$num="%i5"; # int num);
|
||||
|
||||
$tp="%l0"; # t[num]
|
||||
$ap_l="%l1"; # a[num],n[num] are smashed to 32-bit words and saved
|
||||
$ap_h="%l2"; # to these four vectors as double-precision FP values.
|
||||
$np_l="%l3"; # This way a bunch of fxtods are eliminated in second
|
||||
$np_h="%l4"; # loop and L1-cache aliasing is minimized...
|
||||
$i="%l5";
|
||||
$j="%l6";
|
||||
$mask="%l7"; # 16-bit mask, 0xffff
|
||||
|
||||
$n0="%g4"; # reassigned(!) to "64-bit" register
|
||||
$carry="%i4"; # %i4 reused(!) for a carry bit
|
||||
|
||||
# FP register naming chart
|
||||
#
|
||||
# ..HILO
|
||||
# dcba
|
||||
# --------
|
||||
# LOa
|
||||
# LOb
|
||||
# LOc
|
||||
# LOd
|
||||
# HIa
|
||||
# HIb
|
||||
# HIc
|
||||
# HId
|
||||
# ..a
|
||||
# ..b
|
||||
$ba="%f0"; $bb="%f2"; $bc="%f4"; $bd="%f6";
|
||||
$na="%f8"; $nb="%f10"; $nc="%f12"; $nd="%f14";
|
||||
$alo="%f16"; $alo_="%f17"; $ahi="%f18"; $ahi_="%f19";
|
||||
$nlo="%f20"; $nlo_="%f21"; $nhi="%f22"; $nhi_="%f23";
|
||||
|
||||
$dota="%f24"; $dotb="%f26";
|
||||
|
||||
$aloa="%f32"; $alob="%f34"; $aloc="%f36"; $alod="%f38";
|
||||
$ahia="%f40"; $ahib="%f42"; $ahic="%f44"; $ahid="%f46";
|
||||
$nloa="%f48"; $nlob="%f50"; $nloc="%f52"; $nlod="%f54";
|
||||
$nhia="%f56"; $nhib="%f58"; $nhic="%f60"; $nhid="%f62";
|
||||
|
||||
$ASI_FL16_P=0xD2; # magic ASI value to engage 16-bit FP load
|
||||
|
||||
$code=<<___;
|
||||
.section ".text",#alloc,#execinstr
|
||||
|
||||
.global $fname
|
||||
.align 32
|
||||
$fname:
|
||||
save %sp,-$frame-$locals,%sp
|
||||
|
||||
cmp $num,4
|
||||
bl,a,pn %icc,.Lret
|
||||
clr %i0
|
||||
andcc $num,1,%g0 ! $num has to be even...
|
||||
bnz,a,pn %icc,.Lret
|
||||
clr %i0 ! signal "unsupported input value"
|
||||
|
||||
srl $num,1,$num
|
||||
sethi %hi(0xffff),$mask
|
||||
ld [%i4+0],$n0 ! $n0 reassigned, remember?
|
||||
or $mask,%lo(0xffff),$mask
|
||||
ld [%i4+4],%o0
|
||||
sllx %o0,32,%o0
|
||||
or %o0,$n0,$n0 ! $n0=n0[1].n0[0]
|
||||
|
||||
sll $num,3,$num ! num*=8
|
||||
|
||||
add %sp,$bias,%o0 ! real top of stack
|
||||
sll $num,2,%o1
|
||||
add %o1,$num,%o1 ! %o1=num*5
|
||||
sub %o0,%o1,%o0
|
||||
and %o0,-2048,%o0 ! optimize TLB utilization
|
||||
sub %o0,$bias,%sp ! alloca(5*num*8)
|
||||
|
||||
rd %asi,%o7 ! save %asi
|
||||
add %sp,$bias+$frame+$locals,$tp
|
||||
add $tp,$num,$ap_l
|
||||
add $ap_l,$num,$ap_l ! [an]p_[lh] point at the vectors' ends !
|
||||
add $ap_l,$num,$ap_h
|
||||
add $ap_h,$num,$np_l
|
||||
add $np_l,$num,$np_h
|
||||
|
||||
wr %g0,$ASI_FL16_P,%asi ! setup %asi for 16-bit FP loads
|
||||
|
||||
add $rp,$num,$rp ! readjust input pointers to point
|
||||
add $ap,$num,$ap ! at the ends too...
|
||||
add $bp,$num,$bp
|
||||
add $np,$num,$np
|
||||
|
||||
stx %o7,[%sp+$bias+$frame+48] ! save %asi
|
||||
|
||||
sub %g0,$num,$i ! i=-num
|
||||
sub %g0,$num,$j ! j=-num
|
||||
|
||||
add $ap,$j,%o3
|
||||
add $bp,$i,%o4
|
||||
|
||||
ld [%o3+4],%g1 ! bp[0]
|
||||
ld [%o3+0],%o0
|
||||
ld [%o4+4],%g5 ! ap[0]
|
||||
sllx %g1,32,%g1
|
||||
ld [%o4+0],%o1
|
||||
sllx %g5,32,%g5
|
||||
or %g1,%o0,%o0
|
||||
or %g5,%o1,%o1
|
||||
|
||||
add $np,$j,%o5
|
||||
|
||||
mulx %o1,%o0,%o0 ! ap[0]*bp[0]
|
||||
mulx $n0,%o0,%o0 ! ap[0]*bp[0]*n0
|
||||
stx %o0,[%sp+$bias+$frame+0]
|
||||
|
||||
ld [%o3+0],$alo_ ! load a[j] as pair of 32-bit words
|
||||
fzeros $alo
|
||||
ld [%o3+4],$ahi_
|
||||
fzeros $ahi
|
||||
ld [%o5+0],$nlo_ ! load n[j] as pair of 32-bit words
|
||||
fzeros $nlo
|
||||
ld [%o5+4],$nhi_
|
||||
fzeros $nhi
|
||||
|
||||
! transfer b[i] to FPU as 4x16-bit values
|
||||
ldda [%o4+2]%asi,$ba
|
||||
fxtod $alo,$alo
|
||||
ldda [%o4+0]%asi,$bb
|
||||
fxtod $ahi,$ahi
|
||||
ldda [%o4+6]%asi,$bc
|
||||
fxtod $nlo,$nlo
|
||||
ldda [%o4+4]%asi,$bd
|
||||
fxtod $nhi,$nhi
|
||||
|
||||
! transfer ap[0]*b[0]*n0 to FPU as 4x16-bit values
|
||||
ldda [%sp+$bias+$frame+6]%asi,$na
|
||||
fxtod $ba,$ba
|
||||
ldda [%sp+$bias+$frame+4]%asi,$nb
|
||||
fxtod $bb,$bb
|
||||
ldda [%sp+$bias+$frame+2]%asi,$nc
|
||||
fxtod $bc,$bc
|
||||
ldda [%sp+$bias+$frame+0]%asi,$nd
|
||||
fxtod $bd,$bd
|
||||
|
||||
std $alo,[$ap_l+$j] ! save smashed ap[j] in double format
|
||||
fxtod $na,$na
|
||||
std $ahi,[$ap_h+$j]
|
||||
fxtod $nb,$nb
|
||||
std $nlo,[$np_l+$j] ! save smashed np[j] in double format
|
||||
fxtod $nc,$nc
|
||||
std $nhi,[$np_h+$j]
|
||||
fxtod $nd,$nd
|
||||
|
||||
fmuld $alo,$ba,$aloa
|
||||
fmuld $nlo,$na,$nloa
|
||||
fmuld $alo,$bb,$alob
|
||||
fmuld $nlo,$nb,$nlob
|
||||
fmuld $alo,$bc,$aloc
|
||||
faddd $aloa,$nloa,$nloa
|
||||
fmuld $nlo,$nc,$nloc
|
||||
fmuld $alo,$bd,$alod
|
||||
faddd $alob,$nlob,$nlob
|
||||
fmuld $nlo,$nd,$nlod
|
||||
fmuld $ahi,$ba,$ahia
|
||||
faddd $aloc,$nloc,$nloc
|
||||
fmuld $nhi,$na,$nhia
|
||||
fmuld $ahi,$bb,$ahib
|
||||
faddd $alod,$nlod,$nlod
|
||||
fmuld $nhi,$nb,$nhib
|
||||
fmuld $ahi,$bc,$ahic
|
||||
faddd $ahia,$nhia,$nhia
|
||||
fmuld $nhi,$nc,$nhic
|
||||
fmuld $ahi,$bd,$ahid
|
||||
faddd $ahib,$nhib,$nhib
|
||||
fmuld $nhi,$nd,$nhid
|
||||
|
||||
faddd $ahic,$nhic,$dota ! $nhic
|
||||
faddd $ahid,$nhid,$dotb ! $nhid
|
||||
|
||||
faddd $nloc,$nhia,$nloc
|
||||
faddd $nlod,$nhib,$nlod
|
||||
|
||||
fdtox $nloa,$nloa
|
||||
fdtox $nlob,$nlob
|
||||
fdtox $nloc,$nloc
|
||||
fdtox $nlod,$nlod
|
||||
|
||||
std $nloa,[%sp+$bias+$frame+0]
|
||||
add $j,8,$j
|
||||
std $nlob,[%sp+$bias+$frame+8]
|
||||
add $ap,$j,%o4
|
||||
std $nloc,[%sp+$bias+$frame+16]
|
||||
add $np,$j,%o5
|
||||
std $nlod,[%sp+$bias+$frame+24]
|
||||
|
||||
ld [%o4+0],$alo_ ! load a[j] as pair of 32-bit words
|
||||
fzeros $alo
|
||||
ld [%o4+4],$ahi_
|
||||
fzeros $ahi
|
||||
ld [%o5+0],$nlo_ ! load n[j] as pair of 32-bit words
|
||||
fzeros $nlo
|
||||
ld [%o5+4],$nhi_
|
||||
fzeros $nhi
|
||||
|
||||
fxtod $alo,$alo
|
||||
fxtod $ahi,$ahi
|
||||
fxtod $nlo,$nlo
|
||||
fxtod $nhi,$nhi
|
||||
|
||||
ldx [%sp+$bias+$frame+0],%o0
|
||||
fmuld $alo,$ba,$aloa
|
||||
ldx [%sp+$bias+$frame+8],%o1
|
||||
fmuld $nlo,$na,$nloa
|
||||
ldx [%sp+$bias+$frame+16],%o2
|
||||
fmuld $alo,$bb,$alob
|
||||
ldx [%sp+$bias+$frame+24],%o3
|
||||
fmuld $nlo,$nb,$nlob
|
||||
|
||||
srlx %o0,16,%o7
|
||||
std $alo,[$ap_l+$j] ! save smashed ap[j] in double format
|
||||
fmuld $alo,$bc,$aloc
|
||||
add %o7,%o1,%o1
|
||||
std $ahi,[$ap_h+$j]
|
||||
faddd $aloa,$nloa,$nloa
|
||||
fmuld $nlo,$nc,$nloc
|
||||
srlx %o1,16,%o7
|
||||
std $nlo,[$np_l+$j] ! save smashed np[j] in double format
|
||||
fmuld $alo,$bd,$alod
|
||||
add %o7,%o2,%o2
|
||||
std $nhi,[$np_h+$j]
|
||||
faddd $alob,$nlob,$nlob
|
||||
fmuld $nlo,$nd,$nlod
|
||||
srlx %o2,16,%o7
|
||||
fmuld $ahi,$ba,$ahia
|
||||
add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
|
||||
faddd $aloc,$nloc,$nloc
|
||||
fmuld $nhi,$na,$nhia
|
||||
!and %o0,$mask,%o0
|
||||
!and %o1,$mask,%o1
|
||||
!and %o2,$mask,%o2
|
||||
!sllx %o1,16,%o1
|
||||
!sllx %o2,32,%o2
|
||||
!sllx %o3,48,%o7
|
||||
!or %o1,%o0,%o0
|
||||
!or %o2,%o0,%o0
|
||||
!or %o7,%o0,%o0 ! 64-bit result
|
||||
srlx %o3,16,%g1 ! 34-bit carry
|
||||
fmuld $ahi,$bb,$ahib
|
||||
|
||||
faddd $alod,$nlod,$nlod
|
||||
fmuld $nhi,$nb,$nhib
|
||||
fmuld $ahi,$bc,$ahic
|
||||
faddd $ahia,$nhia,$nhia
|
||||
fmuld $nhi,$nc,$nhic
|
||||
fmuld $ahi,$bd,$ahid
|
||||
faddd $ahib,$nhib,$nhib
|
||||
fmuld $nhi,$nd,$nhid
|
||||
|
||||
faddd $dota,$nloa,$nloa
|
||||
faddd $dotb,$nlob,$nlob
|
||||
faddd $ahic,$nhic,$dota ! $nhic
|
||||
faddd $ahid,$nhid,$dotb ! $nhid
|
||||
|
||||
faddd $nloc,$nhia,$nloc
|
||||
faddd $nlod,$nhib,$nlod
|
||||
|
||||
fdtox $nloa,$nloa
|
||||
fdtox $nlob,$nlob
|
||||
fdtox $nloc,$nloc
|
||||
fdtox $nlod,$nlod
|
||||
|
||||
std $nloa,[%sp+$bias+$frame+0]
|
||||
std $nlob,[%sp+$bias+$frame+8]
|
||||
addcc $j,8,$j
|
||||
std $nloc,[%sp+$bias+$frame+16]
|
||||
bz,pn %icc,.L1stskip
|
||||
std $nlod,[%sp+$bias+$frame+24]
|
||||
|
||||
.align 32 ! incidentally already aligned !
|
||||
.L1st:
|
||||
add $ap,$j,%o4
|
||||
add $np,$j,%o5
|
||||
ld [%o4+0],$alo_ ! load a[j] as pair of 32-bit words
|
||||
fzeros $alo
|
||||
ld [%o4+4],$ahi_
|
||||
fzeros $ahi
|
||||
ld [%o5+0],$nlo_ ! load n[j] as pair of 32-bit words
|
||||
fzeros $nlo
|
||||
ld [%o5+4],$nhi_
|
||||
fzeros $nhi
|
||||
|
||||
fxtod $alo,$alo
|
||||
fxtod $ahi,$ahi
|
||||
fxtod $nlo,$nlo
|
||||
fxtod $nhi,$nhi
|
||||
|
||||
ldx [%sp+$bias+$frame+0],%o0
|
||||
fmuld $alo,$ba,$aloa
|
||||
ldx [%sp+$bias+$frame+8],%o1
|
||||
fmuld $nlo,$na,$nloa
|
||||
ldx [%sp+$bias+$frame+16],%o2
|
||||
fmuld $alo,$bb,$alob
|
||||
ldx [%sp+$bias+$frame+24],%o3
|
||||
fmuld $nlo,$nb,$nlob
|
||||
|
||||
srlx %o0,16,%o7
|
||||
std $alo,[$ap_l+$j] ! save smashed ap[j] in double format
|
||||
fmuld $alo,$bc,$aloc
|
||||
add %o7,%o1,%o1
|
||||
std $ahi,[$ap_h+$j]
|
||||
faddd $aloa,$nloa,$nloa
|
||||
fmuld $nlo,$nc,$nloc
|
||||
srlx %o1,16,%o7
|
||||
std $nlo,[$np_l+$j] ! save smashed np[j] in double format
|
||||
fmuld $alo,$bd,$alod
|
||||
add %o7,%o2,%o2
|
||||
std $nhi,[$np_h+$j]
|
||||
faddd $alob,$nlob,$nlob
|
||||
fmuld $nlo,$nd,$nlod
|
||||
srlx %o2,16,%o7
|
||||
fmuld $ahi,$ba,$ahia
|
||||
add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
|
||||
and %o0,$mask,%o0
|
||||
faddd $aloc,$nloc,$nloc
|
||||
fmuld $nhi,$na,$nhia
|
||||
and %o1,$mask,%o1
|
||||
and %o2,$mask,%o2
|
||||
fmuld $ahi,$bb,$ahib
|
||||
sllx %o1,16,%o1
|
||||
faddd $alod,$nlod,$nlod
|
||||
fmuld $nhi,$nb,$nhib
|
||||
sllx %o2,32,%o2
|
||||
fmuld $ahi,$bc,$ahic
|
||||
sllx %o3,48,%o7
|
||||
or %o1,%o0,%o0
|
||||
faddd $ahia,$nhia,$nhia
|
||||
fmuld $nhi,$nc,$nhic
|
||||
or %o2,%o0,%o0
|
||||
fmuld $ahi,$bd,$ahid
|
||||
or %o7,%o0,%o0 ! 64-bit result
|
||||
faddd $ahib,$nhib,$nhib
|
||||
fmuld $nhi,$nd,$nhid
|
||||
addcc %g1,%o0,%o0
|
||||
faddd $dota,$nloa,$nloa
|
||||
srlx %o3,16,%g1 ! 34-bit carry
|
||||
faddd $dotb,$nlob,$nlob
|
||||
bcs,a %xcc,.+8
|
||||
add %g1,1,%g1
|
||||
|
||||
stx %o0,[$tp] ! tp[j-1]=
|
||||
|
||||
faddd $ahic,$nhic,$dota ! $nhic
|
||||
faddd $ahid,$nhid,$dotb ! $nhid
|
||||
|
||||
faddd $nloc,$nhia,$nloc
|
||||
faddd $nlod,$nhib,$nlod
|
||||
|
||||
fdtox $nloa,$nloa
|
||||
fdtox $nlob,$nlob
|
||||
fdtox $nloc,$nloc
|
||||
fdtox $nlod,$nlod
|
||||
|
||||
std $nloa,[%sp+$bias+$frame+0]
|
||||
std $nlob,[%sp+$bias+$frame+8]
|
||||
std $nloc,[%sp+$bias+$frame+16]
|
||||
std $nlod,[%sp+$bias+$frame+24]
|
||||
|
||||
addcc $j,8,$j
|
||||
bnz,pt %icc,.L1st
|
||||
add $tp,8,$tp
|
||||
|
||||
.L1stskip:
|
||||
fdtox $dota,$dota
|
||||
fdtox $dotb,$dotb
|
||||
|
||||
ldx [%sp+$bias+$frame+0],%o0
|
||||
ldx [%sp+$bias+$frame+8],%o1
|
||||
ldx [%sp+$bias+$frame+16],%o2
|
||||
ldx [%sp+$bias+$frame+24],%o3
|
||||
|
||||
srlx %o0,16,%o7
|
||||
std $dota,[%sp+$bias+$frame+32]
|
||||
add %o7,%o1,%o1
|
||||
std $dotb,[%sp+$bias+$frame+40]
|
||||
srlx %o1,16,%o7
|
||||
add %o7,%o2,%o2
|
||||
srlx %o2,16,%o7
|
||||
add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
|
||||
and %o0,$mask,%o0
|
||||
and %o1,$mask,%o1
|
||||
and %o2,$mask,%o2
|
||||
sllx %o1,16,%o1
|
||||
sllx %o2,32,%o2
|
||||
sllx %o3,48,%o7
|
||||
or %o1,%o0,%o0
|
||||
or %o2,%o0,%o0
|
||||
or %o7,%o0,%o0 ! 64-bit result
|
||||
ldx [%sp+$bias+$frame+32],%o4
|
||||
addcc %g1,%o0,%o0
|
||||
ldx [%sp+$bias+$frame+40],%o5
|
||||
srlx %o3,16,%g1 ! 34-bit carry
|
||||
bcs,a %xcc,.+8
|
||||
add %g1,1,%g1
|
||||
|
||||
stx %o0,[$tp] ! tp[j-1]=
|
||||
add $tp,8,$tp
|
||||
|
||||
srlx %o4,16,%o7
|
||||
add %o7,%o5,%o5
|
||||
and %o4,$mask,%o4
|
||||
sllx %o5,16,%o7
|
||||
or %o7,%o4,%o4
|
||||
addcc %g1,%o4,%o4
|
||||
srlx %o5,48,%g1
|
||||
bcs,a %xcc,.+8
|
||||
add %g1,1,%g1
|
||||
|
||||
mov %g1,$carry
|
||||
stx %o4,[$tp] ! tp[num-1]=
|
||||
|
||||
ba .Louter
|
||||
add $i,8,$i
|
||||
.align 32
|
||||
.Louter:
|
||||
sub %g0,$num,$j ! j=-num
|
||||
add %sp,$bias+$frame+$locals,$tp
|
||||
|
||||
add $ap,$j,%o3
|
||||
add $bp,$i,%o4
|
||||
|
||||
ld [%o3+4],%g1 ! bp[i]
|
||||
ld [%o3+0],%o0
|
||||
ld [%o4+4],%g5 ! ap[0]
|
||||
sllx %g1,32,%g1
|
||||
ld [%o4+0],%o1
|
||||
sllx %g5,32,%g5
|
||||
or %g1,%o0,%o0
|
||||
or %g5,%o1,%o1
|
||||
|
||||
ldx [$tp],%o2 ! tp[0]
|
||||
mulx %o1,%o0,%o0
|
||||
addcc %o2,%o0,%o0
|
||||
mulx $n0,%o0,%o0 ! (ap[0]*bp[i]+t[0])*n0
|
||||
stx %o0,[%sp+$bias+$frame+0]
|
||||
|
||||
! transfer b[i] to FPU as 4x16-bit values
|
||||
ldda [%o4+2]%asi,$ba
|
||||
ldda [%o4+0]%asi,$bb
|
||||
ldda [%o4+6]%asi,$bc
|
||||
ldda [%o4+4]%asi,$bd
|
||||
|
||||
! transfer (ap[0]*b[i]+t[0])*n0 to FPU as 4x16-bit values
|
||||
ldda [%sp+$bias+$frame+6]%asi,$na
|
||||
fxtod $ba,$ba
|
||||
ldda [%sp+$bias+$frame+4]%asi,$nb
|
||||
fxtod $bb,$bb
|
||||
ldda [%sp+$bias+$frame+2]%asi,$nc
|
||||
fxtod $bc,$bc
|
||||
ldda [%sp+$bias+$frame+0]%asi,$nd
|
||||
fxtod $bd,$bd
|
||||
ldd [$ap_l+$j],$alo ! load a[j] in double format
|
||||
fxtod $na,$na
|
||||
ldd [$ap_h+$j],$ahi
|
||||
fxtod $nb,$nb
|
||||
ldd [$np_l+$j],$nlo ! load n[j] in double format
|
||||
fxtod $nc,$nc
|
||||
ldd [$np_h+$j],$nhi
|
||||
fxtod $nd,$nd
|
||||
|
||||
fmuld $alo,$ba,$aloa
|
||||
fmuld $nlo,$na,$nloa
|
||||
fmuld $alo,$bb,$alob
|
||||
fmuld $nlo,$nb,$nlob
|
||||
fmuld $alo,$bc,$aloc
|
||||
faddd $aloa,$nloa,$nloa
|
||||
fmuld $nlo,$nc,$nloc
|
||||
fmuld $alo,$bd,$alod
|
||||
faddd $alob,$nlob,$nlob
|
||||
fmuld $nlo,$nd,$nlod
|
||||
fmuld $ahi,$ba,$ahia
|
||||
faddd $aloc,$nloc,$nloc
|
||||
fmuld $nhi,$na,$nhia
|
||||
fmuld $ahi,$bb,$ahib
|
||||
faddd $alod,$nlod,$nlod
|
||||
fmuld $nhi,$nb,$nhib
|
||||
fmuld $ahi,$bc,$ahic
|
||||
faddd $ahia,$nhia,$nhia
|
||||
fmuld $nhi,$nc,$nhic
|
||||
fmuld $ahi,$bd,$ahid
|
||||
faddd $ahib,$nhib,$nhib
|
||||
fmuld $nhi,$nd,$nhid
|
||||
|
||||
faddd $ahic,$nhic,$dota ! $nhic
|
||||
faddd $ahid,$nhid,$dotb ! $nhid
|
||||
|
||||
faddd $nloc,$nhia,$nloc
|
||||
faddd $nlod,$nhib,$nlod
|
||||
|
||||
fdtox $nloa,$nloa
|
||||
fdtox $nlob,$nlob
|
||||
fdtox $nloc,$nloc
|
||||
fdtox $nlod,$nlod
|
||||
|
||||
std $nloa,[%sp+$bias+$frame+0]
|
||||
std $nlob,[%sp+$bias+$frame+8]
|
||||
std $nloc,[%sp+$bias+$frame+16]
|
||||
add $j,8,$j
|
||||
std $nlod,[%sp+$bias+$frame+24]
|
||||
|
||||
ldd [$ap_l+$j],$alo ! load a[j] in double format
|
||||
ldd [$ap_h+$j],$ahi
|
||||
ldd [$np_l+$j],$nlo ! load n[j] in double format
|
||||
ldd [$np_h+$j],$nhi
|
||||
|
||||
fmuld $alo,$ba,$aloa
|
||||
fmuld $nlo,$na,$nloa
|
||||
fmuld $alo,$bb,$alob
|
||||
fmuld $nlo,$nb,$nlob
|
||||
fmuld $alo,$bc,$aloc
|
||||
ldx [%sp+$bias+$frame+0],%o0
|
||||
faddd $aloa,$nloa,$nloa
|
||||
fmuld $nlo,$nc,$nloc
|
||||
ldx [%sp+$bias+$frame+8],%o1
|
||||
fmuld $alo,$bd,$alod
|
||||
ldx [%sp+$bias+$frame+16],%o2
|
||||
faddd $alob,$nlob,$nlob
|
||||
fmuld $nlo,$nd,$nlod
|
||||
ldx [%sp+$bias+$frame+24],%o3
|
||||
fmuld $ahi,$ba,$ahia
|
||||
|
||||
srlx %o0,16,%o7
|
||||
faddd $aloc,$nloc,$nloc
|
||||
fmuld $nhi,$na,$nhia
|
||||
add %o7,%o1,%o1
|
||||
fmuld $ahi,$bb,$ahib
|
||||
srlx %o1,16,%o7
|
||||
faddd $alod,$nlod,$nlod
|
||||
fmuld $nhi,$nb,$nhib
|
||||
add %o7,%o2,%o2
|
||||
fmuld $ahi,$bc,$ahic
|
||||
srlx %o2,16,%o7
|
||||
faddd $ahia,$nhia,$nhia
|
||||
fmuld $nhi,$nc,$nhic
|
||||
add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
|
||||
! why?
|
||||
and %o0,$mask,%o0
|
||||
fmuld $ahi,$bd,$ahid
|
||||
and %o1,$mask,%o1
|
||||
and %o2,$mask,%o2
|
||||
faddd $ahib,$nhib,$nhib
|
||||
fmuld $nhi,$nd,$nhid
|
||||
sllx %o1,16,%o1
|
||||
faddd $dota,$nloa,$nloa
|
||||
sllx %o2,32,%o2
|
||||
faddd $dotb,$nlob,$nlob
|
||||
sllx %o3,48,%o7
|
||||
or %o1,%o0,%o0
|
||||
faddd $ahic,$nhic,$dota ! $nhic
|
||||
or %o2,%o0,%o0
|
||||
faddd $ahid,$nhid,$dotb ! $nhid
|
||||
or %o7,%o0,%o0 ! 64-bit result
|
||||
ldx [$tp],%o7
|
||||
faddd $nloc,$nhia,$nloc
|
||||
addcc %o7,%o0,%o0
|
||||
! end-of-why?
|
||||
faddd $nlod,$nhib,$nlod
|
||||
srlx %o3,16,%g1 ! 34-bit carry
|
||||
fdtox $nloa,$nloa
|
||||
bcs,a %xcc,.+8
|
||||
add %g1,1,%g1
|
||||
|
||||
fdtox $nlob,$nlob
|
||||
fdtox $nloc,$nloc
|
||||
fdtox $nlod,$nlod
|
||||
|
||||
std $nloa,[%sp+$bias+$frame+0]
|
||||
std $nlob,[%sp+$bias+$frame+8]
|
||||
addcc $j,8,$j
|
||||
std $nloc,[%sp+$bias+$frame+16]
|
||||
bz,pn %icc,.Linnerskip
|
||||
std $nlod,[%sp+$bias+$frame+24]
|
||||
|
||||
ba .Linner
|
||||
nop
|
||||
.align 32
|
||||
.Linner:
|
||||
ldd [$ap_l+$j],$alo ! load a[j] in double format
|
||||
ldd [$ap_h+$j],$ahi
|
||||
ldd [$np_l+$j],$nlo ! load n[j] in double format
|
||||
ldd [$np_h+$j],$nhi
|
||||
|
||||
fmuld $alo,$ba,$aloa
|
||||
fmuld $nlo,$na,$nloa
|
||||
fmuld $alo,$bb,$alob
|
||||
fmuld $nlo,$nb,$nlob
|
||||
fmuld $alo,$bc,$aloc
|
||||
ldx [%sp+$bias+$frame+0],%o0
|
||||
faddd $aloa,$nloa,$nloa
|
||||
fmuld $nlo,$nc,$nloc
|
||||
ldx [%sp+$bias+$frame+8],%o1
|
||||
fmuld $alo,$bd,$alod
|
||||
ldx [%sp+$bias+$frame+16],%o2
|
||||
faddd $alob,$nlob,$nlob
|
||||
fmuld $nlo,$nd,$nlod
|
||||
ldx [%sp+$bias+$frame+24],%o3
|
||||
fmuld $ahi,$ba,$ahia
|
||||
|
||||
srlx %o0,16,%o7
|
||||
faddd $aloc,$nloc,$nloc
|
||||
fmuld $nhi,$na,$nhia
|
||||
add %o7,%o1,%o1
|
||||
fmuld $ahi,$bb,$ahib
|
||||
srlx %o1,16,%o7
|
||||
faddd $alod,$nlod,$nlod
|
||||
fmuld $nhi,$nb,$nhib
|
||||
add %o7,%o2,%o2
|
||||
fmuld $ahi,$bc,$ahic
|
||||
srlx %o2,16,%o7
|
||||
faddd $ahia,$nhia,$nhia
|
||||
fmuld $nhi,$nc,$nhic
|
||||
add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
|
||||
and %o0,$mask,%o0
|
||||
fmuld $ahi,$bd,$ahid
|
||||
and %o1,$mask,%o1
|
||||
and %o2,$mask,%o2
|
||||
faddd $ahib,$nhib,$nhib
|
||||
fmuld $nhi,$nd,$nhid
|
||||
sllx %o1,16,%o1
|
||||
faddd $dota,$nloa,$nloa
|
||||
sllx %o2,32,%o2
|
||||
faddd $dotb,$nlob,$nlob
|
||||
sllx %o3,48,%o7
|
||||
or %o1,%o0,%o0
|
||||
faddd $ahic,$nhic,$dota ! $nhic
|
||||
or %o2,%o0,%o0
|
||||
faddd $ahid,$nhid,$dotb ! $nhid
|
||||
or %o7,%o0,%o0 ! 64-bit result
|
||||
faddd $nloc,$nhia,$nloc
|
||||
addcc %g1,%o0,%o0
|
||||
ldx [$tp+8],%o7 ! tp[j]
|
||||
faddd $nlod,$nhib,$nlod
|
||||
srlx %o3,16,%g1 ! 34-bit carry
|
||||
fdtox $nloa,$nloa
|
||||
bcs,a %xcc,.+8
|
||||
add %g1,1,%g1
|
||||
fdtox $nlob,$nlob
|
||||
addcc %o7,%o0,%o0
|
||||
fdtox $nloc,$nloc
|
||||
bcs,a %xcc,.+8
|
||||
add %g1,1,%g1
|
||||
|
||||
stx %o0,[$tp] ! tp[j-1]
|
||||
fdtox $nlod,$nlod
|
||||
|
||||
std $nloa,[%sp+$bias+$frame+0]
|
||||
std $nlob,[%sp+$bias+$frame+8]
|
||||
std $nloc,[%sp+$bias+$frame+16]
|
||||
addcc $j,8,$j
|
||||
std $nlod,[%sp+$bias+$frame+24]
|
||||
bnz,pt %icc,.Linner
|
||||
add $tp,8,$tp
|
||||
|
||||
.Linnerskip:
|
||||
fdtox $dota,$dota
|
||||
fdtox $dotb,$dotb
|
||||
|
||||
ldx [%sp+$bias+$frame+0],%o0
|
||||
ldx [%sp+$bias+$frame+8],%o1
|
||||
ldx [%sp+$bias+$frame+16],%o2
|
||||
ldx [%sp+$bias+$frame+24],%o3
|
||||
|
||||
srlx %o0,16,%o7
|
||||
std $dota,[%sp+$bias+$frame+32]
|
||||
add %o7,%o1,%o1
|
||||
std $dotb,[%sp+$bias+$frame+40]
|
||||
srlx %o1,16,%o7
|
||||
add %o7,%o2,%o2
|
||||
srlx %o2,16,%o7
|
||||
add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
|
||||
and %o0,$mask,%o0
|
||||
and %o1,$mask,%o1
|
||||
and %o2,$mask,%o2
|
||||
sllx %o1,16,%o1
|
||||
sllx %o2,32,%o2
|
||||
sllx %o3,48,%o7
|
||||
or %o1,%o0,%o0
|
||||
or %o2,%o0,%o0
|
||||
ldx [%sp+$bias+$frame+32],%o4
|
||||
or %o7,%o0,%o0 ! 64-bit result
|
||||
ldx [%sp+$bias+$frame+40],%o5
|
||||
addcc %g1,%o0,%o0
|
||||
ldx [$tp+8],%o7 ! tp[j]
|
||||
srlx %o3,16,%g1 ! 34-bit carry
|
||||
bcs,a %xcc,.+8
|
||||
add %g1,1,%g1
|
||||
|
||||
addcc %o7,%o0,%o0
|
||||
bcs,a %xcc,.+8
|
||||
add %g1,1,%g1
|
||||
|
||||
stx %o0,[$tp] ! tp[j-1]
|
||||
add $tp,8,$tp
|
||||
|
||||
srlx %o4,16,%o7
|
||||
add %o7,%o5,%o5
|
||||
and %o4,$mask,%o4
|
||||
sllx %o5,16,%o7
|
||||
or %o7,%o4,%o4
|
||||
addcc %g1,%o4,%o4
|
||||
srlx %o5,48,%g1
|
||||
bcs,a %xcc,.+8
|
||||
add %g1,1,%g1
|
||||
|
||||
addcc $carry,%o4,%o4
|
||||
stx %o4,[$tp] ! tp[num-1]
|
||||
mov %g1,$carry
|
||||
bcs,a %xcc,.+8
|
||||
add $carry,1,$carry
|
||||
|
||||
addcc $i,8,$i
|
||||
bnz %icc,.Louter
|
||||
nop
|
||||
|
||||
add $tp,8,$tp ! adjust tp to point at the end
|
||||
orn %g0,%g0,%g4
|
||||
sub %g0,$num,%o7 ! n=-num
|
||||
ba .Lsub
|
||||
subcc %g0,%g0,%g0 ! clear %icc.c
|
||||
|
||||
.align 32
|
||||
.Lsub:
|
||||
ldx [$tp+%o7],%o0
|
||||
add $np,%o7,%g1
|
||||
ld [%g1+0],%o2
|
||||
ld [%g1+4],%o3
|
||||
srlx %o0,32,%o1
|
||||
subccc %o0,%o2,%o2
|
||||
add $rp,%o7,%g1
|
||||
subccc %o1,%o3,%o3
|
||||
st %o2,[%g1+0]
|
||||
add %o7,8,%o7
|
||||
brnz,pt %o7,.Lsub
|
||||
st %o3,[%g1+4]
|
||||
subc $carry,0,%g4
|
||||
sub %g0,$num,%o7 ! n=-num
|
||||
ba .Lcopy
|
||||
nop
|
||||
|
||||
.align 32
|
||||
.Lcopy:
|
||||
ldx [$tp+%o7],%o0
|
||||
add $rp,%o7,%g1
|
||||
ld [%g1+0],%o2
|
||||
ld [%g1+4],%o3
|
||||
stx %g0,[$tp+%o7]
|
||||
and %o0,%g4,%o0
|
||||
srlx %o0,32,%o1
|
||||
andn %o2,%g4,%o2
|
||||
andn %o3,%g4,%o3
|
||||
or %o2,%o0,%o0
|
||||
or %o3,%o1,%o1
|
||||
st %o0,[%g1+0]
|
||||
add %o7,8,%o7
|
||||
brnz,pt %o7,.Lcopy
|
||||
st %o1,[%g1+4]
|
||||
sub %g0,$num,%o7 ! n=-num
|
||||
|
||||
.Lzap:
|
||||
stx %g0,[$ap_l+%o7]
|
||||
stx %g0,[$ap_h+%o7]
|
||||
stx %g0,[$np_l+%o7]
|
||||
stx %g0,[$np_h+%o7]
|
||||
add %o7,8,%o7
|
||||
brnz,pt %o7,.Lzap
|
||||
nop
|
||||
|
||||
ldx [%sp+$bias+$frame+48],%o7
|
||||
wr %g0,%o7,%asi ! restore %asi
|
||||
|
||||
mov 1,%i0
|
||||
.Lret:
|
||||
ret
|
||||
restore
|
||||
.type $fname,#function
|
||||
.size $fname,(.-$fname)
|
||||
.asciz "Montgomery Multipltication for UltraSPARC, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
.align 32
|
||||
___
|
||||
|
||||
$code =~ s/\`([^\`]*)\`/eval($1)/gem;
|
||||
|
||||
# Below substitution makes it possible to compile without demanding
|
||||
# VIS extentions on command line, e.g. -xarch=v9 vs. -xarch=v9a. I
|
||||
# dare to do this, because VIS capability is detected at run-time now
|
||||
# and this routine is not called on CPU not capable to execute it. Do
|
||||
# note that fzeros is not the only VIS dependency! Another dependency
|
||||
# is implicit and is just _a_ numerical value loaded to %asi register,
|
||||
# which assembler can't recognize as VIS specific...
|
||||
$code =~ s/fzeros\s+%f([0-9]+)/
|
||||
sprintf(".word\t0x%x\t! fzeros %%f%d",0x81b00c20|($1<<25),$1)
|
||||
/gem;
|
||||
|
||||
print $code;
|
||||
# flush
|
||||
close STDOUT;
|
242
crypto/bn/asm/via-mont.pl
Normal file
242
crypto/bn/asm/via-mont.pl
Normal file
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
#
|
||||
# Wrapper around 'rep montmul', VIA-specific instruction accessing
|
||||
# PadLock Montgomery Multiplier. The wrapper is designed as drop-in
|
||||
# replacement for OpenSSL bn_mul_mont [first implemented in 0.9.9].
|
||||
#
|
||||
# Below are interleaved outputs from 'openssl speed rsa dsa' for 4
|
||||
# different software configurations on 1.5GHz VIA Esther processor.
|
||||
# Lines marked with "software integer" denote performance of hand-
|
||||
# coded integer-only assembler found in OpenSSL 0.9.7. "Software SSE2"
|
||||
# refers to hand-coded SSE2 Montgomery multiplication procedure found
|
||||
# OpenSSL 0.9.9. "Hardware VIA SDK" refers to padlock_pmm routine from
|
||||
# Padlock SDK 2.0.1 available for download from VIA, which naturally
|
||||
# utilizes the magic 'repz montmul' instruction. And finally "hardware
|
||||
# this" refers to *this* implementation which also uses 'repz montmul'
|
||||
#
|
||||
# sign verify sign/s verify/s
|
||||
# rsa 512 bits 0.001720s 0.000140s 581.4 7149.7 software integer
|
||||
# rsa 512 bits 0.000690s 0.000086s 1450.3 11606.0 software SSE2
|
||||
# rsa 512 bits 0.006136s 0.000201s 163.0 4974.5 hardware VIA SDK
|
||||
# rsa 512 bits 0.000712s 0.000050s 1404.9 19858.5 hardware this
|
||||
#
|
||||
# rsa 1024 bits 0.008518s 0.000413s 117.4 2420.8 software integer
|
||||
# rsa 1024 bits 0.004275s 0.000277s 233.9 3609.7 software SSE2
|
||||
# rsa 1024 bits 0.012136s 0.000260s 82.4 3844.5 hardware VIA SDK
|
||||
# rsa 1024 bits 0.002522s 0.000116s 396.5 8650.9 hardware this
|
||||
#
|
||||
# rsa 2048 bits 0.050101s 0.001371s 20.0 729.6 software integer
|
||||
# rsa 2048 bits 0.030273s 0.001008s 33.0 991.9 software SSE2
|
||||
# rsa 2048 bits 0.030833s 0.000976s 32.4 1025.1 hardware VIA SDK
|
||||
# rsa 2048 bits 0.011879s 0.000342s 84.2 2921.7 hardware this
|
||||
#
|
||||
# rsa 4096 bits 0.327097s 0.004859s 3.1 205.8 software integer
|
||||
# rsa 4096 bits 0.229318s 0.003859s 4.4 259.2 software SSE2
|
||||
# rsa 4096 bits 0.233953s 0.003274s 4.3 305.4 hardware VIA SDK
|
||||
# rsa 4096 bits 0.070493s 0.001166s 14.2 857.6 hardware this
|
||||
#
|
||||
# dsa 512 bits 0.001342s 0.001651s 745.2 605.7 software integer
|
||||
# dsa 512 bits 0.000844s 0.000987s 1185.3 1013.1 software SSE2
|
||||
# dsa 512 bits 0.001902s 0.002247s 525.6 444.9 hardware VIA SDK
|
||||
# dsa 512 bits 0.000458s 0.000524s 2182.2 1909.1 hardware this
|
||||
#
|
||||
# dsa 1024 bits 0.003964s 0.004926s 252.3 203.0 software integer
|
||||
# dsa 1024 bits 0.002686s 0.003166s 372.3 315.8 software SSE2
|
||||
# dsa 1024 bits 0.002397s 0.002823s 417.1 354.3 hardware VIA SDK
|
||||
# dsa 1024 bits 0.000978s 0.001170s 1022.2 855.0 hardware this
|
||||
#
|
||||
# dsa 2048 bits 0.013280s 0.016518s 75.3 60.5 software integer
|
||||
# dsa 2048 bits 0.009911s 0.011522s 100.9 86.8 software SSE2
|
||||
# dsa 2048 bits 0.009542s 0.011763s 104.8 85.0 hardware VIA SDK
|
||||
# dsa 2048 bits 0.002884s 0.003352s 346.8 298.3 hardware this
|
||||
#
|
||||
# To give you some other reference point here is output for 2.4GHz P4
|
||||
# running hand-coded SSE2 bn_mul_mont found in 0.9.9, i.e. "software
|
||||
# SSE2" in above terms.
|
||||
#
|
||||
# rsa 512 bits 0.000407s 0.000047s 2454.2 21137.0
|
||||
# rsa 1024 bits 0.002426s 0.000141s 412.1 7100.0
|
||||
# rsa 2048 bits 0.015046s 0.000491s 66.5 2034.9
|
||||
# rsa 4096 bits 0.109770s 0.002379s 9.1 420.3
|
||||
# dsa 512 bits 0.000438s 0.000525s 2281.1 1904.1
|
||||
# dsa 1024 bits 0.001346s 0.001595s 742.7 627.0
|
||||
# dsa 2048 bits 0.004745s 0.005582s 210.7 179.1
|
||||
#
|
||||
# Conclusions:
|
||||
# - VIA SDK leaves a *lot* of room for improvement (which this
|
||||
# implementation successfully fills:-);
|
||||
# - 'rep montmul' gives up to >3x performance improvement depending on
|
||||
# key length;
|
||||
# - in terms of absolute performance it delivers approximately as much
|
||||
# as modern out-of-order 32-bit cores [again, for longer keys].
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
push(@INC,"${dir}","${dir}../../perlasm");
|
||||
require "x86asm.pl";
|
||||
|
||||
&asm_init($ARGV[0],"via-mont.pl");
|
||||
|
||||
# int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
|
||||
$func="bn_mul_mont_padlock";
|
||||
|
||||
$pad=16*1; # amount of reserved bytes on top of every vector
|
||||
|
||||
# stack layout
|
||||
$mZeroPrime=&DWP(0,"esp"); # these are specified by VIA
|
||||
$A=&DWP(4,"esp");
|
||||
$B=&DWP(8,"esp");
|
||||
$T=&DWP(12,"esp");
|
||||
$M=&DWP(16,"esp");
|
||||
$scratch=&DWP(20,"esp");
|
||||
$rp=&DWP(24,"esp"); # these are mine
|
||||
$sp=&DWP(28,"esp");
|
||||
# &DWP(32,"esp") # 32 byte scratch area
|
||||
# &DWP(64+(4*$num+$pad)*0,"esp") # padded tp[num]
|
||||
# &DWP(64+(4*$num+$pad)*1,"esp") # padded copy of ap[num]
|
||||
# &DWP(64+(4*$num+$pad)*2,"esp") # padded copy of bp[num]
|
||||
# &DWP(64+(4*$num+$pad)*3,"esp") # padded copy of np[num]
|
||||
# Note that SDK suggests to unconditionally allocate 2K per vector. This
|
||||
# has quite an impact on performance. It naturally depends on key length,
|
||||
# but to give an example 1024 bit private RSA key operations suffer >30%
|
||||
# penalty. I allocate only as much as actually required...
|
||||
|
||||
&function_begin($func);
|
||||
&xor ("eax","eax");
|
||||
&mov ("ecx",&wparam(5)); # num
|
||||
# meet VIA's limitations for num [note that the specification
|
||||
# expresses them in bits, while we work with amount of 32-bit words]
|
||||
&test ("ecx",3);
|
||||
&jnz (&label("leave")); # num % 4 != 0
|
||||
&cmp ("ecx",8);
|
||||
&jb (&label("leave")); # num < 8
|
||||
&cmp ("ecx",1024);
|
||||
&ja (&label("leave")); # num > 1024
|
||||
|
||||
&pushf ();
|
||||
&cld ();
|
||||
|
||||
&mov ("edi",&wparam(0)); # rp
|
||||
&mov ("eax",&wparam(1)); # ap
|
||||
&mov ("ebx",&wparam(2)); # bp
|
||||
&mov ("edx",&wparam(3)); # np
|
||||
&mov ("esi",&wparam(4)); # n0
|
||||
&mov ("esi",&DWP(0,"esi")); # *n0
|
||||
|
||||
&lea ("ecx",&DWP($pad,"","ecx",4)); # ecx becomes vector size in bytes
|
||||
&lea ("ebp",&DWP(64,"","ecx",4)); # allocate 4 vectors + 64 bytes
|
||||
&neg ("ebp");
|
||||
&add ("ebp","esp");
|
||||
&and ("ebp",-64); # align to cache-line
|
||||
&xchg ("ebp","esp"); # alloca
|
||||
|
||||
&mov ($rp,"edi"); # save rp
|
||||
&mov ($sp,"ebp"); # save esp
|
||||
|
||||
&mov ($mZeroPrime,"esi");
|
||||
&lea ("esi",&DWP(64,"esp")); # tp
|
||||
&mov ($T,"esi");
|
||||
&lea ("edi",&DWP(32,"esp")); # scratch area
|
||||
&mov ($scratch,"edi");
|
||||
&mov ("esi","eax");
|
||||
|
||||
&lea ("ebp",&DWP(-$pad,"ecx"));
|
||||
&shr ("ebp",2); # restore original num value in ebp
|
||||
|
||||
&xor ("eax","eax");
|
||||
|
||||
&mov ("ecx","ebp");
|
||||
&lea ("ecx",&DWP((32+$pad)/4,"ecx"));# padded tp + scratch
|
||||
&data_byte(0xf3,0xab); # rep stosl, bzero
|
||||
|
||||
&mov ("ecx","ebp");
|
||||
&lea ("edi",&DWP(64+$pad,"esp","ecx",4));# pointer to ap copy
|
||||
&mov ($A,"edi");
|
||||
&data_byte(0xf3,0xa5); # rep movsl, memcpy
|
||||
&mov ("ecx",$pad/4);
|
||||
&data_byte(0xf3,0xab); # rep stosl, bzero pad
|
||||
# edi points at the end of padded ap copy...
|
||||
|
||||
&mov ("ecx","ebp");
|
||||
&mov ("esi","ebx");
|
||||
&mov ($B,"edi");
|
||||
&data_byte(0xf3,0xa5); # rep movsl, memcpy
|
||||
&mov ("ecx",$pad/4);
|
||||
&data_byte(0xf3,0xab); # rep stosl, bzero pad
|
||||
# edi points at the end of padded bp copy...
|
||||
|
||||
&mov ("ecx","ebp");
|
||||
&mov ("esi","edx");
|
||||
&mov ($M,"edi");
|
||||
&data_byte(0xf3,0xa5); # rep movsl, memcpy
|
||||
&mov ("ecx",$pad/4);
|
||||
&data_byte(0xf3,0xab); # rep stosl, bzero pad
|
||||
# edi points at the end of padded np copy...
|
||||
|
||||
# let magic happen...
|
||||
&mov ("ecx","ebp");
|
||||
&mov ("esi","esp");
|
||||
&shl ("ecx",5); # convert word counter to bit counter
|
||||
&align (4);
|
||||
&data_byte(0xf3,0x0f,0xa6,0xc0);# rep montmul
|
||||
|
||||
&mov ("ecx","ebp");
|
||||
&lea ("esi",&DWP(64,"esp")); # tp
|
||||
# edi still points at the end of padded np copy...
|
||||
&neg ("ebp");
|
||||
&lea ("ebp",&DWP(-$pad,"edi","ebp",4)); # so just "rewind"
|
||||
&mov ("edi",$rp); # restore rp
|
||||
&xor ("edx","edx"); # i=0 and clear CF
|
||||
|
||||
&set_label("sub",8);
|
||||
&mov ("eax",&DWP(0,"esi","edx",4));
|
||||
&sbb ("eax",&DWP(0,"ebp","edx",4));
|
||||
&mov (&DWP(0,"edi","edx",4),"eax"); # rp[i]=tp[i]-np[i]
|
||||
&lea ("edx",&DWP(1,"edx")); # i++
|
||||
&loop (&label("sub")); # doesn't affect CF!
|
||||
|
||||
&mov ("eax",&DWP(0,"esi","edx",4)); # upmost overflow bit
|
||||
&sbb ("eax",0);
|
||||
&and ("esi","eax");
|
||||
¬ ("eax");
|
||||
&mov ("ebp","edi");
|
||||
&and ("ebp","eax");
|
||||
&or ("esi","ebp"); # tp=carry?tp:rp
|
||||
|
||||
&mov ("ecx","edx"); # num
|
||||
&xor ("edx","edx"); # i=0
|
||||
|
||||
&set_label("copy",8);
|
||||
&mov ("eax",&DWP(0,"esi","edx",4));
|
||||
&mov (&DWP(64,"esp","edx",4),"ecx"); # zap tp
|
||||
&mov (&DWP(0,"edi","edx",4),"eax");
|
||||
&lea ("edx",&DWP(1,"edx")); # i++
|
||||
&loop (&label("copy"));
|
||||
|
||||
&mov ("ebp",$sp);
|
||||
&xor ("eax","eax");
|
||||
|
||||
&mov ("ecx",64/4);
|
||||
&mov ("edi","esp"); # zap frame including scratch area
|
||||
&data_byte(0xf3,0xab); # rep stosl, bzero
|
||||
|
||||
# zap copies of ap, bp and np
|
||||
&lea ("edi",&DWP(64+$pad,"esp","edx",4));# pointer to ap
|
||||
&lea ("ecx",&DWP(3*$pad/4,"edx","edx",2));
|
||||
&data_byte(0xf3,0xab); # rep stosl, bzero
|
||||
|
||||
&mov ("esp","ebp");
|
||||
&inc ("eax"); # signal "done"
|
||||
&popf ();
|
||||
&set_label("leave");
|
||||
&function_end($func);
|
||||
|
||||
&asciz("Padlock Montgomery Multiplication, CRYPTOGAMS by <appro\@openssl.org>");
|
||||
|
||||
&asm_finish();
|
591
crypto/bn/asm/x86-mont.pl
Executable file
591
crypto/bn/asm/x86-mont.pl
Executable file
@@ -0,0 +1,591 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# October 2005
|
||||
#
|
||||
# This is a "teaser" code, as it can be improved in several ways...
|
||||
# First of all non-SSE2 path should be implemented (yes, for now it
|
||||
# performs Montgomery multiplication/convolution only on SSE2-capable
|
||||
# CPUs such as P4, others fall down to original code). Then inner loop
|
||||
# can be unrolled and modulo-scheduled to improve ILP and possibly
|
||||
# moved to 128-bit XMM register bank (though it would require input
|
||||
# rearrangement and/or increase bus bandwidth utilization). Dedicated
|
||||
# squaring procedure should give further performance improvement...
|
||||
# Yet, for being draft, the code improves rsa512 *sign* benchmark by
|
||||
# 110%(!), rsa1024 one - by 70% and rsa4096 - by 20%:-)
|
||||
|
||||
# December 2006
|
||||
#
|
||||
# Modulo-scheduling SSE2 loops results in further 15-20% improvement.
|
||||
# Integer-only code [being equipped with dedicated squaring procedure]
|
||||
# gives ~40% on rsa512 sign benchmark...
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
push(@INC,"${dir}","${dir}../../perlasm");
|
||||
require "x86asm.pl";
|
||||
|
||||
&asm_init($ARGV[0],$0);
|
||||
|
||||
$sse2=0;
|
||||
for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
|
||||
|
||||
&external_label("OPENSSL_ia32cap_P") if ($sse2);
|
||||
|
||||
&function_begin("bn_mul_mont");
|
||||
|
||||
$i="edx";
|
||||
$j="ecx";
|
||||
$ap="esi"; $tp="esi"; # overlapping variables!!!
|
||||
$rp="edi"; $bp="edi"; # overlapping variables!!!
|
||||
$np="ebp";
|
||||
$num="ebx";
|
||||
|
||||
$_num=&DWP(4*0,"esp"); # stack top layout
|
||||
$_rp=&DWP(4*1,"esp");
|
||||
$_ap=&DWP(4*2,"esp");
|
||||
$_bp=&DWP(4*3,"esp");
|
||||
$_np=&DWP(4*4,"esp");
|
||||
$_n0=&DWP(4*5,"esp"); $_n0q=&QWP(4*5,"esp");
|
||||
$_sp=&DWP(4*6,"esp");
|
||||
$_bpend=&DWP(4*7,"esp");
|
||||
$frame=32; # size of above frame rounded up to 16n
|
||||
|
||||
&xor ("eax","eax");
|
||||
&mov ("edi",&wparam(5)); # int num
|
||||
&cmp ("edi",4);
|
||||
&jl (&label("just_leave"));
|
||||
|
||||
&lea ("esi",&wparam(0)); # put aside pointer to argument block
|
||||
&lea ("edx",&wparam(1)); # load ap
|
||||
&mov ("ebp","esp"); # saved stack pointer!
|
||||
&add ("edi",2); # extra two words on top of tp
|
||||
&neg ("edi");
|
||||
&lea ("esp",&DWP(-$frame,"esp","edi",4)); # alloca($frame+4*(num+2))
|
||||
&neg ("edi");
|
||||
|
||||
# minimize cache contention by arraning 2K window between stack
|
||||
# pointer and ap argument [np is also position sensitive vector,
|
||||
# but it's assumed to be near ap, as it's allocated at ~same
|
||||
# time].
|
||||
&mov ("eax","esp");
|
||||
&sub ("eax","edx");
|
||||
&and ("eax",2047);
|
||||
&sub ("esp","eax"); # this aligns sp and ap modulo 2048
|
||||
|
||||
&xor ("edx","esp");
|
||||
&and ("edx",2048);
|
||||
&xor ("edx",2048);
|
||||
&sub ("esp","edx"); # this splits them apart modulo 4096
|
||||
|
||||
&and ("esp",-64); # align to cache line
|
||||
|
||||
################################# load argument block...
|
||||
&mov ("eax",&DWP(0*4,"esi"));# BN_ULONG *rp
|
||||
&mov ("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap
|
||||
&mov ("ecx",&DWP(2*4,"esi"));# const BN_ULONG *bp
|
||||
&mov ("edx",&DWP(3*4,"esi"));# const BN_ULONG *np
|
||||
&mov ("esi",&DWP(4*4,"esi"));# const BN_ULONG *n0
|
||||
#&mov ("edi",&DWP(5*4,"esi"));# int num
|
||||
|
||||
&mov ("esi",&DWP(0,"esi")); # pull n0[0]
|
||||
&mov ($_rp,"eax"); # ... save a copy of argument block
|
||||
&mov ($_ap,"ebx");
|
||||
&mov ($_bp,"ecx");
|
||||
&mov ($_np,"edx");
|
||||
&mov ($_n0,"esi");
|
||||
&lea ($num,&DWP(-3,"edi")); # num=num-1 to assist modulo-scheduling
|
||||
#&mov ($_num,$num); # redundant as $num is not reused
|
||||
&mov ($_sp,"ebp"); # saved stack pointer!
|
||||
|
||||
if($sse2) {
|
||||
$acc0="mm0"; # mmx register bank layout
|
||||
$acc1="mm1";
|
||||
$car0="mm2";
|
||||
$car1="mm3";
|
||||
$mul0="mm4";
|
||||
$mul1="mm5";
|
||||
$temp="mm6";
|
||||
$mask="mm7";
|
||||
|
||||
&picmeup("eax","OPENSSL_ia32cap_P");
|
||||
&bt (&DWP(0,"eax"),26);
|
||||
&jnc (&label("non_sse2"));
|
||||
|
||||
&mov ("eax",-1);
|
||||
&movd ($mask,"eax"); # mask 32 lower bits
|
||||
|
||||
&mov ($ap,$_ap); # load input pointers
|
||||
&mov ($bp,$_bp);
|
||||
&mov ($np,$_np);
|
||||
|
||||
&xor ($i,$i); # i=0
|
||||
&xor ($j,$j); # j=0
|
||||
|
||||
&movd ($mul0,&DWP(0,$bp)); # bp[0]
|
||||
&movd ($mul1,&DWP(0,$ap)); # ap[0]
|
||||
&movd ($car1,&DWP(0,$np)); # np[0]
|
||||
|
||||
&pmuludq($mul1,$mul0); # ap[0]*bp[0]
|
||||
&movq ($car0,$mul1);
|
||||
&movq ($acc0,$mul1); # I wish movd worked for
|
||||
&pand ($acc0,$mask); # inter-register transfers
|
||||
|
||||
&pmuludq($mul1,$_n0q); # *=n0
|
||||
|
||||
&pmuludq($car1,$mul1); # "t[0]"*np[0]*n0
|
||||
&paddq ($car1,$acc0);
|
||||
|
||||
&movd ($acc1,&DWP(4,$np)); # np[1]
|
||||
&movd ($acc0,&DWP(4,$ap)); # ap[1]
|
||||
|
||||
&psrlq ($car0,32);
|
||||
&psrlq ($car1,32);
|
||||
|
||||
&inc ($j); # j++
|
||||
&set_label("1st",16);
|
||||
&pmuludq($acc0,$mul0); # ap[j]*bp[0]
|
||||
&pmuludq($acc1,$mul1); # np[j]*m1
|
||||
&paddq ($car0,$acc0); # +=c0
|
||||
&paddq ($car1,$acc1); # +=c1
|
||||
|
||||
&movq ($acc0,$car0);
|
||||
&pand ($acc0,$mask);
|
||||
&movd ($acc1,&DWP(4,$np,$j,4)); # np[j+1]
|
||||
&paddq ($car1,$acc0); # +=ap[j]*bp[0];
|
||||
&movd ($acc0,&DWP(4,$ap,$j,4)); # ap[j+1]
|
||||
&psrlq ($car0,32);
|
||||
&movd (&DWP($frame-4,"esp",$j,4),$car1); # tp[j-1]=
|
||||
&psrlq ($car1,32);
|
||||
|
||||
&lea ($j,&DWP(1,$j));
|
||||
&cmp ($j,$num);
|
||||
&jl (&label("1st"));
|
||||
|
||||
&pmuludq($acc0,$mul0); # ap[num-1]*bp[0]
|
||||
&pmuludq($acc1,$mul1); # np[num-1]*m1
|
||||
&paddq ($car0,$acc0); # +=c0
|
||||
&paddq ($car1,$acc1); # +=c1
|
||||
|
||||
&movq ($acc0,$car0);
|
||||
&pand ($acc0,$mask);
|
||||
&paddq ($car1,$acc0); # +=ap[num-1]*bp[0];
|
||||
&movd (&DWP($frame-4,"esp",$j,4),$car1); # tp[num-2]=
|
||||
|
||||
&psrlq ($car0,32);
|
||||
&psrlq ($car1,32);
|
||||
|
||||
&paddq ($car1,$car0);
|
||||
&movq (&QWP($frame,"esp",$num,4),$car1); # tp[num].tp[num-1]
|
||||
|
||||
&inc ($i); # i++
|
||||
&set_label("outer");
|
||||
&xor ($j,$j); # j=0
|
||||
|
||||
&movd ($mul0,&DWP(0,$bp,$i,4)); # bp[i]
|
||||
&movd ($mul1,&DWP(0,$ap)); # ap[0]
|
||||
&movd ($temp,&DWP($frame,"esp")); # tp[0]
|
||||
&movd ($car1,&DWP(0,$np)); # np[0]
|
||||
&pmuludq($mul1,$mul0); # ap[0]*bp[i]
|
||||
|
||||
&paddq ($mul1,$temp); # +=tp[0]
|
||||
&movq ($acc0,$mul1);
|
||||
&movq ($car0,$mul1);
|
||||
&pand ($acc0,$mask);
|
||||
|
||||
&pmuludq($mul1,$_n0q); # *=n0
|
||||
|
||||
&pmuludq($car1,$mul1);
|
||||
&paddq ($car1,$acc0);
|
||||
|
||||
&movd ($temp,&DWP($frame+4,"esp")); # tp[1]
|
||||
&movd ($acc1,&DWP(4,$np)); # np[1]
|
||||
&movd ($acc0,&DWP(4,$ap)); # ap[1]
|
||||
|
||||
&psrlq ($car0,32);
|
||||
&psrlq ($car1,32);
|
||||
&paddq ($car0,$temp); # +=tp[1]
|
||||
|
||||
&inc ($j); # j++
|
||||
&dec ($num);
|
||||
&set_label("inner");
|
||||
&pmuludq($acc0,$mul0); # ap[j]*bp[i]
|
||||
&pmuludq($acc1,$mul1); # np[j]*m1
|
||||
&paddq ($car0,$acc0); # +=c0
|
||||
&paddq ($car1,$acc1); # +=c1
|
||||
|
||||
&movq ($acc0,$car0);
|
||||
&movd ($temp,&DWP($frame+4,"esp",$j,4));# tp[j+1]
|
||||
&pand ($acc0,$mask);
|
||||
&movd ($acc1,&DWP(4,$np,$j,4)); # np[j+1]
|
||||
&paddq ($car1,$acc0); # +=ap[j]*bp[i]+tp[j]
|
||||
&movd ($acc0,&DWP(4,$ap,$j,4)); # ap[j+1]
|
||||
&psrlq ($car0,32);
|
||||
&movd (&DWP($frame-4,"esp",$j,4),$car1);# tp[j-1]=
|
||||
&psrlq ($car1,32);
|
||||
&paddq ($car0,$temp); # +=tp[j+1]
|
||||
|
||||
&dec ($num);
|
||||
&lea ($j,&DWP(1,$j)); # j++
|
||||
&jnz (&label("inner"));
|
||||
|
||||
&mov ($num,$j);
|
||||
&pmuludq($acc0,$mul0); # ap[num-1]*bp[i]
|
||||
&pmuludq($acc1,$mul1); # np[num-1]*m1
|
||||
&paddq ($car0,$acc0); # +=c0
|
||||
&paddq ($car1,$acc1); # +=c1
|
||||
|
||||
&movq ($acc0,$car0);
|
||||
&pand ($acc0,$mask);
|
||||
&paddq ($car1,$acc0); # +=ap[num-1]*bp[i]+tp[num-1]
|
||||
&movd (&DWP($frame-4,"esp",$j,4),$car1); # tp[num-2]=
|
||||
&psrlq ($car0,32);
|
||||
&psrlq ($car1,32);
|
||||
|
||||
&movd ($temp,&DWP($frame+4,"esp",$num,4)); # += tp[num]
|
||||
&paddq ($car1,$car0);
|
||||
&paddq ($car1,$temp);
|
||||
&movq (&QWP($frame,"esp",$num,4),$car1); # tp[num].tp[num-1]
|
||||
|
||||
&lea ($i,&DWP(1,$i)); # i++
|
||||
&cmp ($i,$num);
|
||||
&jle (&label("outer"));
|
||||
|
||||
&emms (); # done with mmx bank
|
||||
&jmp (&label("common_tail"));
|
||||
|
||||
&set_label("non_sse2",16);
|
||||
}
|
||||
|
||||
if (0) {
|
||||
&mov ("esp",$_sp);
|
||||
&xor ("eax","eax"); # signal "not fast enough [yet]"
|
||||
&jmp (&label("just_leave"));
|
||||
# While the below code provides competitive performance for
|
||||
# all key lengthes on modern Intel cores, it's still more
|
||||
# than 10% slower for 4096-bit key elsewhere:-( "Competitive"
|
||||
# means compared to the original integer-only assembler.
|
||||
# 512-bit RSA sign is better by ~40%, but that's about all
|
||||
# one can say about all CPUs...
|
||||
} else {
|
||||
$inp="esi"; # integer path uses these registers differently
|
||||
$word="edi";
|
||||
$carry="ebp";
|
||||
|
||||
&mov ($inp,$_ap);
|
||||
&lea ($carry,&DWP(1,$num));
|
||||
&mov ($word,$_bp);
|
||||
&xor ($j,$j); # j=0
|
||||
&mov ("edx",$inp);
|
||||
&and ($carry,1); # see if num is even
|
||||
&sub ("edx",$word); # see if ap==bp
|
||||
&lea ("eax",&DWP(4,$word,$num,4)); # &bp[num]
|
||||
&or ($carry,"edx");
|
||||
&mov ($word,&DWP(0,$word)); # bp[0]
|
||||
&jz (&label("bn_sqr_mont"));
|
||||
&mov ($_bpend,"eax");
|
||||
&mov ("eax",&DWP(0,$inp));
|
||||
&xor ("edx","edx");
|
||||
|
||||
&set_label("mull",16);
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # ap[j]*bp[0]
|
||||
&add ($carry,"eax");
|
||||
&lea ($j,&DWP(1,$j));
|
||||
&adc ("edx",0);
|
||||
&mov ("eax",&DWP(0,$inp,$j,4)); # ap[j+1]
|
||||
&cmp ($j,$num);
|
||||
&mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]=
|
||||
&jl (&label("mull"));
|
||||
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # ap[num-1]*bp[0]
|
||||
&mov ($word,$_n0);
|
||||
&add ("eax",$carry);
|
||||
&mov ($inp,$_np);
|
||||
&adc ("edx",0);
|
||||
&imul ($word,&DWP($frame,"esp")); # n0*tp[0]
|
||||
|
||||
&mov (&DWP($frame,"esp",$num,4),"eax"); # tp[num-1]=
|
||||
&xor ($j,$j);
|
||||
&mov (&DWP($frame+4,"esp",$num,4),"edx"); # tp[num]=
|
||||
&mov (&DWP($frame+8,"esp",$num,4),$j); # tp[num+1]=
|
||||
|
||||
&mov ("eax",&DWP(0,$inp)); # np[0]
|
||||
&mul ($word); # np[0]*m
|
||||
&add ("eax",&DWP($frame,"esp")); # +=tp[0]
|
||||
&mov ("eax",&DWP(4,$inp)); # np[1]
|
||||
&adc ("edx",0);
|
||||
&inc ($j);
|
||||
|
||||
&jmp (&label("2ndmadd"));
|
||||
|
||||
&set_label("1stmadd",16);
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # ap[j]*bp[i]
|
||||
&add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j]
|
||||
&lea ($j,&DWP(1,$j));
|
||||
&adc ("edx",0);
|
||||
&add ($carry,"eax");
|
||||
&mov ("eax",&DWP(0,$inp,$j,4)); # ap[j+1]
|
||||
&adc ("edx",0);
|
||||
&cmp ($j,$num);
|
||||
&mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]=
|
||||
&jl (&label("1stmadd"));
|
||||
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # ap[num-1]*bp[i]
|
||||
&add ("eax",&DWP($frame,"esp",$num,4)); # +=tp[num-1]
|
||||
&mov ($word,$_n0);
|
||||
&adc ("edx",0);
|
||||
&mov ($inp,$_np);
|
||||
&add ($carry,"eax");
|
||||
&adc ("edx",0);
|
||||
&imul ($word,&DWP($frame,"esp")); # n0*tp[0]
|
||||
|
||||
&xor ($j,$j);
|
||||
&add ("edx",&DWP($frame+4,"esp",$num,4)); # carry+=tp[num]
|
||||
&mov (&DWP($frame,"esp",$num,4),$carry); # tp[num-1]=
|
||||
&adc ($j,0);
|
||||
&mov ("eax",&DWP(0,$inp)); # np[0]
|
||||
&mov (&DWP($frame+4,"esp",$num,4),"edx"); # tp[num]=
|
||||
&mov (&DWP($frame+8,"esp",$num,4),$j); # tp[num+1]=
|
||||
|
||||
&mul ($word); # np[0]*m
|
||||
&add ("eax",&DWP($frame,"esp")); # +=tp[0]
|
||||
&mov ("eax",&DWP(4,$inp)); # np[1]
|
||||
&adc ("edx",0);
|
||||
&mov ($j,1);
|
||||
|
||||
&set_label("2ndmadd",16);
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # np[j]*m
|
||||
&add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j]
|
||||
&lea ($j,&DWP(1,$j));
|
||||
&adc ("edx",0);
|
||||
&add ($carry,"eax");
|
||||
&mov ("eax",&DWP(0,$inp,$j,4)); # np[j+1]
|
||||
&adc ("edx",0);
|
||||
&cmp ($j,$num);
|
||||
&mov (&DWP($frame-8,"esp",$j,4),$carry); # tp[j-1]=
|
||||
&jl (&label("2ndmadd"));
|
||||
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # np[j]*m
|
||||
&add ($carry,&DWP($frame,"esp",$num,4)); # +=tp[num-1]
|
||||
&adc ("edx",0);
|
||||
&add ($carry,"eax");
|
||||
&adc ("edx",0);
|
||||
&mov (&DWP($frame-4,"esp",$num,4),$carry); # tp[num-2]=
|
||||
|
||||
&xor ("eax","eax");
|
||||
&mov ($j,$_bp); # &bp[i]
|
||||
&add ("edx",&DWP($frame+4,"esp",$num,4)); # carry+=tp[num]
|
||||
&adc ("eax",&DWP($frame+8,"esp",$num,4)); # +=tp[num+1]
|
||||
&lea ($j,&DWP(4,$j));
|
||||
&mov (&DWP($frame,"esp",$num,4),"edx"); # tp[num-1]=
|
||||
&cmp ($j,$_bpend);
|
||||
&mov (&DWP($frame+4,"esp",$num,4),"eax"); # tp[num]=
|
||||
&je (&label("common_tail"));
|
||||
|
||||
&mov ($word,&DWP(0,$j)); # bp[i+1]
|
||||
&mov ($inp,$_ap);
|
||||
&mov ($_bp,$j); # &bp[++i]
|
||||
&xor ($j,$j);
|
||||
&xor ("edx","edx");
|
||||
&mov ("eax",&DWP(0,$inp));
|
||||
&jmp (&label("1stmadd"));
|
||||
|
||||
&set_label("bn_sqr_mont",16);
|
||||
$sbit=$num;
|
||||
&mov ($_num,$num);
|
||||
&mov ($_bp,$j); # i=0
|
||||
|
||||
&mov ("eax",$word); # ap[0]
|
||||
&mul ($word); # ap[0]*ap[0]
|
||||
&mov (&DWP($frame,"esp"),"eax"); # tp[0]=
|
||||
&mov ($sbit,"edx");
|
||||
&shr ("edx",1);
|
||||
&and ($sbit,1);
|
||||
&inc ($j);
|
||||
&set_label("sqr",16);
|
||||
&mov ("eax",&DWP(0,$inp,$j,4)); # ap[j]
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # ap[j]*ap[0]
|
||||
&add ("eax",$carry);
|
||||
&lea ($j,&DWP(1,$j));
|
||||
&adc ("edx",0);
|
||||
&lea ($carry,&DWP(0,$sbit,"eax",2));
|
||||
&shr ("eax",31);
|
||||
&cmp ($j,$_num);
|
||||
&mov ($sbit,"eax");
|
||||
&mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]=
|
||||
&jl (&label("sqr"));
|
||||
|
||||
&mov ("eax",&DWP(0,$inp,$j,4)); # ap[num-1]
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # ap[num-1]*ap[0]
|
||||
&add ("eax",$carry);
|
||||
&mov ($word,$_n0);
|
||||
&adc ("edx",0);
|
||||
&mov ($inp,$_np);
|
||||
&lea ($carry,&DWP(0,$sbit,"eax",2));
|
||||
&imul ($word,&DWP($frame,"esp")); # n0*tp[0]
|
||||
&shr ("eax",31);
|
||||
&mov (&DWP($frame,"esp",$j,4),$carry); # tp[num-1]=
|
||||
|
||||
&lea ($carry,&DWP(0,"eax","edx",2));
|
||||
&mov ("eax",&DWP(0,$inp)); # np[0]
|
||||
&shr ("edx",31);
|
||||
&mov (&DWP($frame+4,"esp",$j,4),$carry); # tp[num]=
|
||||
&mov (&DWP($frame+8,"esp",$j,4),"edx"); # tp[num+1]=
|
||||
|
||||
&mul ($word); # np[0]*m
|
||||
&add ("eax",&DWP($frame,"esp")); # +=tp[0]
|
||||
&mov ($num,$j);
|
||||
&adc ("edx",0);
|
||||
&mov ("eax",&DWP(4,$inp)); # np[1]
|
||||
&mov ($j,1);
|
||||
|
||||
&set_label("3rdmadd",16);
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # np[j]*m
|
||||
&add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j]
|
||||
&adc ("edx",0);
|
||||
&add ($carry,"eax");
|
||||
&mov ("eax",&DWP(4,$inp,$j,4)); # np[j+1]
|
||||
&adc ("edx",0);
|
||||
&mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j-1]=
|
||||
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # np[j+1]*m
|
||||
&add ($carry,&DWP($frame+4,"esp",$j,4)); # +=tp[j+1]
|
||||
&lea ($j,&DWP(2,$j));
|
||||
&adc ("edx",0);
|
||||
&add ($carry,"eax");
|
||||
&mov ("eax",&DWP(0,$inp,$j,4)); # np[j+2]
|
||||
&adc ("edx",0);
|
||||
&cmp ($j,$num);
|
||||
&mov (&DWP($frame-8,"esp",$j,4),$carry); # tp[j]=
|
||||
&jl (&label("3rdmadd"));
|
||||
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # np[j]*m
|
||||
&add ($carry,&DWP($frame,"esp",$num,4)); # +=tp[num-1]
|
||||
&adc ("edx",0);
|
||||
&add ($carry,"eax");
|
||||
&adc ("edx",0);
|
||||
&mov (&DWP($frame-4,"esp",$num,4),$carry); # tp[num-2]=
|
||||
|
||||
&mov ($j,$_bp); # i
|
||||
&xor ("eax","eax");
|
||||
&mov ($inp,$_ap);
|
||||
&add ("edx",&DWP($frame+4,"esp",$num,4)); # carry+=tp[num]
|
||||
&adc ("eax",&DWP($frame+8,"esp",$num,4)); # +=tp[num+1]
|
||||
&mov (&DWP($frame,"esp",$num,4),"edx"); # tp[num-1]=
|
||||
&cmp ($j,$num);
|
||||
&mov (&DWP($frame+4,"esp",$num,4),"eax"); # tp[num]=
|
||||
&je (&label("common_tail"));
|
||||
|
||||
&mov ($word,&DWP(4,$inp,$j,4)); # ap[i]
|
||||
&lea ($j,&DWP(1,$j));
|
||||
&mov ("eax",$word);
|
||||
&mov ($_bp,$j); # ++i
|
||||
&mul ($word); # ap[i]*ap[i]
|
||||
&add ("eax",&DWP($frame,"esp",$j,4)); # +=tp[i]
|
||||
&adc ("edx",0);
|
||||
&mov (&DWP($frame,"esp",$j,4),"eax"); # tp[i]=
|
||||
&xor ($carry,$carry);
|
||||
&cmp ($j,$num);
|
||||
&lea ($j,&DWP(1,$j));
|
||||
&je (&label("sqrlast"));
|
||||
|
||||
&mov ($sbit,"edx"); # zaps $num
|
||||
&shr ("edx",1);
|
||||
&and ($sbit,1);
|
||||
&set_label("sqradd",16);
|
||||
&mov ("eax",&DWP(0,$inp,$j,4)); # ap[j]
|
||||
&mov ($carry,"edx");
|
||||
&mul ($word); # ap[j]*ap[i]
|
||||
&add ("eax",$carry);
|
||||
&lea ($carry,&DWP(0,"eax","eax"));
|
||||
&adc ("edx",0);
|
||||
&shr ("eax",31);
|
||||
&add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j]
|
||||
&lea ($j,&DWP(1,$j));
|
||||
&adc ("eax",0);
|
||||
&add ($carry,$sbit);
|
||||
&adc ("eax",0);
|
||||
&cmp ($j,$_num);
|
||||
&mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]=
|
||||
&mov ($sbit,"eax");
|
||||
&jle (&label("sqradd"));
|
||||
|
||||
&mov ($carry,"edx");
|
||||
&lea ("edx",&DWP(0,$sbit,"edx",2));
|
||||
&shr ($carry,31);
|
||||
&set_label("sqrlast");
|
||||
&mov ($word,$_n0);
|
||||
&mov ($inp,$_np);
|
||||
&imul ($word,&DWP($frame,"esp")); # n0*tp[0]
|
||||
|
||||
&add ("edx",&DWP($frame,"esp",$j,4)); # +=tp[num]
|
||||
&mov ("eax",&DWP(0,$inp)); # np[0]
|
||||
&adc ($carry,0);
|
||||
&mov (&DWP($frame,"esp",$j,4),"edx"); # tp[num]=
|
||||
&mov (&DWP($frame+4,"esp",$j,4),$carry); # tp[num+1]=
|
||||
|
||||
&mul ($word); # np[0]*m
|
||||
&add ("eax",&DWP($frame,"esp")); # +=tp[0]
|
||||
&lea ($num,&DWP(-1,$j));
|
||||
&adc ("edx",0);
|
||||
&mov ($j,1);
|
||||
&mov ("eax",&DWP(4,$inp)); # np[1]
|
||||
|
||||
&jmp (&label("3rdmadd"));
|
||||
}
|
||||
|
||||
&set_label("common_tail",16);
|
||||
&mov ($np,$_np); # load modulus pointer
|
||||
&mov ($rp,$_rp); # load result pointer
|
||||
&lea ($tp,&DWP($frame,"esp")); # [$ap and $bp are zapped]
|
||||
|
||||
&mov ("eax",&DWP(0,$tp)); # tp[0]
|
||||
&mov ($j,$num); # j=num-1
|
||||
&xor ($i,$i); # i=0 and clear CF!
|
||||
|
||||
&set_label("sub",16);
|
||||
&sbb ("eax",&DWP(0,$np,$i,4));
|
||||
&mov (&DWP(0,$rp,$i,4),"eax"); # rp[i]=tp[i]-np[i]
|
||||
&dec ($j); # doesn't affect CF!
|
||||
&mov ("eax",&DWP(4,$tp,$i,4)); # tp[i+1]
|
||||
&lea ($i,&DWP(1,$i)); # i++
|
||||
&jge (&label("sub"));
|
||||
|
||||
&sbb ("eax",0); # handle upmost overflow bit
|
||||
&and ($tp,"eax");
|
||||
¬ ("eax");
|
||||
&mov ($np,$rp);
|
||||
&and ($np,"eax");
|
||||
&or ($tp,$np); # tp=carry?tp:rp
|
||||
|
||||
&set_label("copy",16); # copy or in-place refresh
|
||||
&mov ("eax",&DWP(0,$tp,$num,4));
|
||||
&mov (&DWP(0,$rp,$num,4),"eax"); # rp[i]=tp[i]
|
||||
&mov (&DWP($frame,"esp",$num,4),$j); # zap temporary vector
|
||||
&dec ($num);
|
||||
&jge (&label("copy"));
|
||||
|
||||
&mov ("esp",$_sp); # pull saved stack pointer
|
||||
&mov ("eax",1);
|
||||
&set_label("just_leave");
|
||||
&function_end("bn_mul_mont");
|
||||
|
||||
&asciz("Montgomery Multiplication for x86, CRYPTOGAMS by <appro\@openssl.org>");
|
||||
|
||||
&asm_finish();
|
3
crypto/camellia/.cvsignore
Normal file
3
crypto/camellia/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
lib
|
||||
Makefile.save
|
||||
cmll-*.s
|
1138
crypto/camellia/asm/cmll-x86.pl
Normal file
1138
crypto/camellia/asm/cmll-x86.pl
Normal file
File diff suppressed because it is too large
Load Diff
1080
crypto/camellia/asm/cmll-x86_64.pl
Normal file
1080
crypto/camellia/asm/cmll-x86_64.pl
Normal file
File diff suppressed because it is too large
Load Diff
4
crypto/cms/.cvsignore
Normal file
4
crypto/cms/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
lib
|
||||
Makefile.save
|
||||
*.flc
|
||||
semantic.cache
|
94
crypto/ppccpuid.pl
Executable file
94
crypto/ppccpuid.pl
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
$flavour = shift;
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
|
||||
( $xlate="${dir}perlasm/ppc-xlate.pl" and -f $xlate) or
|
||||
die "can't locate ppc-xlate.pl";
|
||||
|
||||
open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
|
||||
|
||||
if ($flavour=~/64/) {
|
||||
$CMPLI="cmpldi";
|
||||
$SHRLI="srdi";
|
||||
$SIGNX="extsw";
|
||||
} else {
|
||||
$CMPLI="cmplwi";
|
||||
$SHRLI="srwi";
|
||||
$SIGNX="mr";
|
||||
}
|
||||
|
||||
$code=<<___;
|
||||
.machine "any"
|
||||
.text
|
||||
|
||||
.globl .OPENSSL_cpuid_setup
|
||||
.align 4
|
||||
.OPENSSL_cpuid_setup:
|
||||
blr
|
||||
|
||||
.globl .OPENSSL_wipe_cpu
|
||||
.align 4
|
||||
.OPENSSL_wipe_cpu:
|
||||
xor r0,r0,r0
|
||||
mr r3,r1
|
||||
xor r4,r4,r4
|
||||
xor r5,r5,r5
|
||||
xor r6,r6,r6
|
||||
xor r7,r7,r7
|
||||
xor r8,r8,r8
|
||||
xor r9,r9,r9
|
||||
xor r10,r10,r10
|
||||
xor r11,r11,r11
|
||||
xor r12,r12,r12
|
||||
blr
|
||||
|
||||
.globl .OPENSSL_atomic_add
|
||||
.align 4
|
||||
.OPENSSL_atomic_add:
|
||||
Loop: lwarx r5,0,r3
|
||||
add r0,r4,r5
|
||||
stwcx. r0,0,r3
|
||||
bne- Loop
|
||||
$SIGNX r3,r0
|
||||
blr
|
||||
|
||||
.globl .OPENSSL_rdtsc
|
||||
.align 4
|
||||
.OPENSSL_rdtsc:
|
||||
mftb r3
|
||||
mftbu r4
|
||||
blr
|
||||
|
||||
.globl .OPENSSL_cleanse
|
||||
.align 4
|
||||
.OPENSSL_cleanse:
|
||||
$CMPLI r4,7
|
||||
li r0,0
|
||||
bge Lot
|
||||
Little: mtctr r4
|
||||
stb r0,0(r3)
|
||||
addi r3,r3,1
|
||||
bdnz- \$-8
|
||||
blr
|
||||
Lot: andi. r5,r3,3
|
||||
beq Laligned
|
||||
stb r0,0(r3)
|
||||
subi r4,r4,1
|
||||
addi r3,r3,1
|
||||
b Lot
|
||||
Laligned:
|
||||
$SHRLI r5,r4,2
|
||||
mtctr r5
|
||||
stw r0,0(r3)
|
||||
addi r3,r3,4
|
||||
bdnz- \$-8
|
||||
andi. r4,r4,3
|
||||
bne Little
|
||||
blr
|
||||
___
|
||||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
90
crypto/s390xcpuid.S
Normal file
90
crypto/s390xcpuid.S
Normal file
@@ -0,0 +1,90 @@
|
||||
.text
|
||||
|
||||
.globl OPENSSL_cpuid_setup
|
||||
.type OPENSSL_cpuid_setup,@function
|
||||
.align 16
|
||||
OPENSSL_cpuid_setup:
|
||||
br %r14 # reserved for future
|
||||
.size OPENSSL_cpuid_setup,.-OPENSSL_cpuid_setup
|
||||
|
||||
.globl OPENSSL_s390x_facilities
|
||||
.type OPENSSL_s390x_facilities,@function
|
||||
.align 16
|
||||
OPENSSL_s390x_facilities:
|
||||
lghi %r0,0
|
||||
.long 0xb2b0f010 # stfle 16(%r15)
|
||||
lg %r2,16(%r15)
|
||||
br %r14
|
||||
.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
|
||||
|
||||
.globl OPENSSL_rdtsc
|
||||
.type OPENSSL_rdtsc,@function
|
||||
.align 16
|
||||
OPENSSL_rdtsc:
|
||||
stck 16(%r15)
|
||||
lg %r2,16(%r15)
|
||||
br %r14
|
||||
.size OPENSSL_rdtsc,.-OPENSSL_rdtsc
|
||||
|
||||
.globl OPENSSL_atomic_add
|
||||
.type OPENSSL_atomic_add,@function
|
||||
.align 16
|
||||
OPENSSL_atomic_add:
|
||||
l %r1,0(%r2)
|
||||
.Lspin: lr %r0,%r1
|
||||
ar %r0,%r3
|
||||
cs %r1,%r0,0(%r2)
|
||||
brc 4,.Lspin
|
||||
lgfr %r2,%r0 # OpenSSL expects the new value
|
||||
br %r14
|
||||
.size OPENSSL_atomic_add,.-OPENSSL_atomic_add
|
||||
|
||||
.globl OPENSSL_wipe_cpu
|
||||
.type OPENSSL_wipe_cpu,@function
|
||||
.align 16
|
||||
OPENSSL_wipe_cpu:
|
||||
xgr %r0,%r0
|
||||
xgr %r1,%r1
|
||||
lgr %r2,%r15
|
||||
xgr %r3,%r3
|
||||
xgr %r4,%r4
|
||||
lzdr %f0
|
||||
lzdr %f1
|
||||
lzdr %f2
|
||||
lzdr %f3
|
||||
lzdr %f4
|
||||
lzdr %f5
|
||||
lzdr %f6
|
||||
lzdr %f7
|
||||
br %r14
|
||||
.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
|
||||
|
||||
.globl OPENSSL_cleanse
|
||||
.type OPENSSL_cleanse,@function
|
||||
.align 16
|
||||
OPENSSL_cleanse:
|
||||
lghi %r4,15
|
||||
lghi %r0,0
|
||||
clgr %r3,%r4
|
||||
jh .Lot
|
||||
.Little:
|
||||
stc %r0,0(%r2)
|
||||
la %r2,1(%r2)
|
||||
brctg %r3,.Little
|
||||
br %r14
|
||||
.align 4
|
||||
.Lot: tmll %r2,7
|
||||
jz .Laligned
|
||||
stc %r0,0(%r2)
|
||||
la %r2,1(%r2)
|
||||
brctg %r3,.Lot
|
||||
.Laligned:
|
||||
srlg %r4,%r3,3
|
||||
.Loop: stg %r0,0(%r2)
|
||||
la %r2,8(%r2)
|
||||
brctg %r4,.Loop
|
||||
lghi %r4,7
|
||||
ngr %r3,%r4
|
||||
jnz .Little
|
||||
br %r14
|
||||
.size OPENSSL_cleanse,.-OPENSSL_cleanse
|
154
crypto/sparcv9cap.c
Normal file
154
crypto/sparcv9cap.c
Normal file
@@ -0,0 +1,154 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#define SPARCV9_TICK_PRIVILEGED (1<<0)
|
||||
#define SPARCV9_PREFER_FPU (1<<1)
|
||||
#define SPARCV9_VIS1 (1<<2)
|
||||
#define SPARCV9_VIS2 (1<<3) /* reserved */
|
||||
#define SPARCV9_FMADD (1<<4) /* reserved for SPARC64 V */
|
||||
static int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED;
|
||||
|
||||
int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
|
||||
{
|
||||
int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
|
||||
int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
|
||||
|
||||
if ((OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
|
||||
(SPARCV9_PREFER_FPU|SPARCV9_VIS1))
|
||||
return bn_mul_mont_fpu(rp,ap,bp,np,n0,num);
|
||||
else
|
||||
return bn_mul_mont_int(rp,ap,bp,np,n0,num);
|
||||
}
|
||||
|
||||
unsigned long OPENSSL_rdtsc(void)
|
||||
{
|
||||
unsigned long _sparcv9_rdtick(void);
|
||||
|
||||
if (OPENSSL_sparcv9cap_P&SPARCV9_TICK_PRIVILEGED)
|
||||
#if defined(__sun) && defined(__SVR4)
|
||||
return gethrtime();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
else
|
||||
return _sparcv9_rdtick();
|
||||
}
|
||||
|
||||
#if defined(__sun) && defined(__SVR4)
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <libdevinfo.h>
|
||||
#include <sys/systeminfo.h>
|
||||
|
||||
typedef di_node_t (*di_init_t)(const char *,uint_t);
|
||||
typedef void (*di_fini_t)(di_node_t);
|
||||
typedef char * (*di_node_name_t)(di_node_t);
|
||||
typedef int (*di_walk_node_t)(di_node_t,uint_t,di_node_name_t,int (*)(di_node_t,di_node_name_t));
|
||||
|
||||
#define DLLINK(h,name) (name=(name##_t)dlsym((h),#name))
|
||||
|
||||
static int walk_nodename(di_node_t node, di_node_name_t di_node_name)
|
||||
{
|
||||
char *name = (*di_node_name)(node);
|
||||
|
||||
/* This is expected to catch all UltraSPARC flavors prior T1 */
|
||||
if (!strcmp (name,"SUNW,UltraSPARC") ||
|
||||
!strncmp(name,"SUNW,UltraSPARC-I",17)) /* covers II,III,IV */
|
||||
{
|
||||
OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
|
||||
|
||||
/* %tick is privileged only on UltraSPARC-I/II, but not IIe */
|
||||
if (name[14]!='\0' && name[17]!='\0' && name[18]!='\0')
|
||||
OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
|
||||
|
||||
return DI_WALK_TERMINATE;
|
||||
}
|
||||
/* This is expected to catch remaining UltraSPARCs, such as T1 */
|
||||
else if (!strncmp(name,"SUNW,UltraSPARC",15))
|
||||
{
|
||||
OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
|
||||
|
||||
return DI_WALK_TERMINATE;
|
||||
}
|
||||
|
||||
return DI_WALK_CONTINUE;
|
||||
}
|
||||
|
||||
void OPENSSL_cpuid_setup(void)
|
||||
{
|
||||
void *h;
|
||||
char *e,si[256];
|
||||
static int trigger=0;
|
||||
|
||||
if (trigger) return;
|
||||
trigger=1;
|
||||
|
||||
if ((e=getenv("OPENSSL_sparcv9cap")))
|
||||
{
|
||||
OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sysinfo(SI_MACHINE,si,sizeof(si))>0)
|
||||
{
|
||||
if (strcmp(si,"sun4v"))
|
||||
/* FPU is preferred for all CPUs, but US-T1/2 */
|
||||
OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU;
|
||||
}
|
||||
|
||||
if (sysinfo(SI_ISALIST,si,sizeof(si))>0)
|
||||
{
|
||||
if (strstr(si,"+vis"))
|
||||
OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
|
||||
if (strstr(si,"+vis2"))
|
||||
{
|
||||
OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
|
||||
OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((h = dlopen("libdevinfo.so.1",RTLD_LAZY))) do
|
||||
{
|
||||
di_init_t di_init;
|
||||
di_fini_t di_fini;
|
||||
di_walk_node_t di_walk_node;
|
||||
di_node_name_t di_node_name;
|
||||
di_node_t root_node;
|
||||
|
||||
if (!DLLINK(h,di_init)) break;
|
||||
if (!DLLINK(h,di_fini)) break;
|
||||
if (!DLLINK(h,di_walk_node)) break;
|
||||
if (!DLLINK(h,di_node_name)) break;
|
||||
|
||||
if ((root_node = (*di_init)("/",DINFOSUBTREE))!=DI_NODE_NIL)
|
||||
{
|
||||
(*di_walk_node)(root_node,DI_WALK_SIBFIRST,
|
||||
di_node_name,walk_nodename);
|
||||
(*di_fini)(root_node);
|
||||
}
|
||||
} while(0);
|
||||
|
||||
if (h) dlclose(h);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void OPENSSL_cpuid_setup(void)
|
||||
{
|
||||
char *e;
|
||||
|
||||
if ((e=getenv("OPENSSL_sparcv9cap")))
|
||||
{
|
||||
OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* For now we assume that the rest supports UltraSPARC-I* only */
|
||||
OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user