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