diff options
author | Adam Langley <agl@chromium.org> | 2016-01-15 01:00:33 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-01-15 01:00:33 +0000 |
commit | 6290bff2114c67a0d1a57e75b0a11544ad894406 (patch) | |
tree | 80b47f41b8e3971267452f49e48560c9c36434e2 | |
parent | 7410f4ee26ae91ef240e8e767e9f91e83ba32d38 (diff) | |
parent | 4139edb02e59e7ad48e0a8f4c02e45923bc8a344 (diff) | |
download | external_boringssl-6290bff2114c67a0d1a57e75b0a11544ad894406.zip external_boringssl-6290bff2114c67a0d1a57e75b0a11544ad894406.tar.gz external_boringssl-6290bff2114c67a0d1a57e75b0a11544ad894406.tar.bz2 |
external/boringssl: sync to 7b8b9c17
am: 4139edb02e
* commit '4139edb02e59e7ad48e0a8f4c02e45923bc8a344':
external/boringssl: sync to 7b8b9c17
246 files changed, 44966 insertions, 14256 deletions
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION index a4cd7f9..6e9fe82 100644 --- a/BORINGSSL_REVISION +++ b/BORINGSSL_REVISION @@ -1 +1 @@ -7104cc96b752c45e02fd3f1728cf313263f04548 +7b8b9c17db93ea5287575b437c77fb36eeb81b31 @@ -54,178 +54,178 @@ OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); const uint32_t kOpenSSLReasonValues[] = { - 0xc3207ba, - 0xc3287d4, - 0xc3307e3, - 0xc3387f3, - 0xc340802, - 0xc34881b, - 0xc350827, - 0xc358844, - 0xc360856, - 0xc368864, - 0xc370874, - 0xc378881, - 0xc380891, - 0xc38889c, - 0xc3908b2, - 0xc3988c1, - 0xc3a08d5, - 0xc3a87c7, + 0xc3207ab, + 0xc3287c5, + 0xc3307d4, + 0xc3387e4, + 0xc3407f3, + 0xc34880c, + 0xc350818, + 0xc358835, + 0xc360847, + 0xc368855, + 0xc370865, + 0xc378872, + 0xc380882, + 0xc38888d, + 0xc3908a3, + 0xc3988b2, + 0xc3a08c6, + 0xc3a87b8, 0xc3b00b0, - 0x10321478, - 0x10329484, - 0x1033149d, - 0x103394b0, - 0x10340de1, - 0x103494cf, - 0x103514e4, - 0x10359516, - 0x1036152f, - 0x10369544, - 0x10371562, - 0x10379571, - 0x1038158d, - 0x103895a8, - 0x103915b7, - 0x103995d3, - 0x103a15ee, - 0x103a9605, - 0x103b1616, - 0x103b962a, - 0x103c1649, - 0x103c9658, - 0x103d166f, - 0x103d9682, - 0x103e0b6c, - 0x103e96b3, - 0x103f16c6, - 0x103f96e0, - 0x104016f0, - 0x10409704, - 0x1041171a, - 0x10419732, - 0x10421747, - 0x1042975b, - 0x1043176d, - 0x104385d0, - 0x104408c1, - 0x10449782, - 0x10451799, - 0x104597ae, - 0x104617bc, - 0x10469695, - 0x104714f7, - 0x104787c7, + 0x10321469, + 0x10329475, + 0x1033148e, + 0x103394a1, + 0x10340dd2, + 0x103494c0, + 0x103514d5, + 0x10359507, + 0x10361520, + 0x10369535, + 0x10371553, + 0x10379562, + 0x1038157e, + 0x10389599, + 0x103915a8, + 0x103995c4, + 0x103a15df, + 0x103a95f6, + 0x103b1607, + 0x103b961b, + 0x103c163a, + 0x103c9649, + 0x103d1660, + 0x103d9673, + 0x103e0b5d, + 0x103e96a4, + 0x103f16b7, + 0x103f96d1, + 0x104016e1, + 0x104096f5, + 0x1041170b, + 0x10419723, + 0x10421738, + 0x1042974c, + 0x1043175e, + 0x104385c1, + 0x104408b2, + 0x10449773, + 0x1045178a, + 0x1045979f, + 0x104617ad, + 0x10469686, + 0x104714e8, + 0x104787b8, 0x104800b0, - 0x104894c3, - 0x14320b4f, - 0x14328b5d, - 0x14330b6c, - 0x14338b7e, + 0x104894b4, + 0x14320b40, + 0x14328b4e, + 0x14330b5d, + 0x14338b6f, 0x18320083, - 0x18328e47, - 0x18340e75, - 0x18348e89, - 0x18358ec0, - 0x18368eed, - 0x18370f00, - 0x18378f14, - 0x18380f38, - 0x18388f46, - 0x18390f5c, - 0x18398f70, - 0x183a0f80, - 0x183b0f90, - 0x183b8fa5, - 0x183c8fd0, - 0x183d0fe4, - 0x183d8ff4, - 0x183e0b9b, - 0x183e9001, - 0x183f1013, - 0x183f901e, - 0x1840102e, - 0x1840903f, - 0x18411050, - 0x18419062, - 0x1842108b, - 0x184290bd, - 0x184310cc, - 0x18451135, - 0x1845914b, - 0x18461166, - 0x18468ed8, - 0x184709d9, + 0x18328e38, + 0x18340e66, + 0x18348e7a, + 0x18358eb1, + 0x18368ede, + 0x18370ef1, + 0x18378f05, + 0x18380f29, + 0x18388f37, + 0x18390f4d, + 0x18398f61, + 0x183a0f71, + 0x183b0f81, + 0x183b8f96, + 0x183c8fc1, + 0x183d0fd5, + 0x183d8fe5, + 0x183e0b8c, + 0x183e8ff2, + 0x183f1004, + 0x183f900f, + 0x1840101f, + 0x18409030, + 0x18411041, + 0x18419053, + 0x1842107c, + 0x184290ae, + 0x184310bd, + 0x18451126, + 0x1845913c, + 0x18461157, + 0x18468ec9, + 0x184709ca, 0x18478094, - 0x18480fbc, - 0x18489101, - 0x18490e5d, - 0x18498e9e, - 0x184a119c, - 0x184a9119, - 0x184b10e0, - 0x184b8e37, - 0x184c10a4, - 0x184c866b, - 0x184d1181, - 0x203211c3, - 0x243211cf, - 0x24328907, - 0x243311e1, - 0x243391ee, - 0x243411fb, - 0x2434920d, - 0x2435121c, - 0x24359239, - 0x24361246, - 0x24369254, - 0x24371262, - 0x24379270, - 0x24381279, - 0x24389286, - 0x24391299, - 0x28320b8f, - 0x28328b9b, - 0x28330b6c, - 0x28338bae, - 0x2c322bfd, - 0x2c32ac0b, - 0x2c332c1d, - 0x2c33ac2f, - 0x2c342c43, - 0x2c34ac55, - 0x2c352c70, - 0x2c35ac82, - 0x2c362c95, + 0x18480fad, + 0x184890f2, + 0x18490e4e, + 0x18498e8f, + 0x184a118d, + 0x184a910a, + 0x184b10d1, + 0x184b8e28, + 0x184c1095, + 0x184c865c, + 0x184d1172, + 0x203211b4, + 0x243211c0, + 0x243288f8, + 0x243311d2, + 0x243391df, + 0x243411ec, + 0x243491fe, + 0x2435120d, + 0x2435922a, + 0x24361237, + 0x24369245, + 0x24371253, + 0x24379261, + 0x2438126a, + 0x24389277, + 0x2439128a, + 0x28320b80, + 0x28328b8c, + 0x28330b5d, + 0x28338b9f, + 0x2c32280e, + 0x2c32a81c, + 0x2c33282e, + 0x2c33a840, + 0x2c342854, + 0x2c34a866, + 0x2c352881, + 0x2c35a893, + 0x2c3628a6, 0x2c3682f3, - 0x2c372ca2, - 0x2c37acb4, - 0x2c382cc7, - 0x2c38acd5, - 0x2c392ce5, - 0x2c39acf7, - 0x2c3a2d0b, - 0x2c3aad1c, - 0x2c3b1359, - 0x2c3bad2d, - 0x2c3c2d41, - 0x2c3cad57, - 0x2c3d2d70, - 0x2c3dad9e, - 0x2c3e2dac, - 0x2c3eadc4, - 0x2c3f2ddc, - 0x2c3fade9, - 0x2c402e0c, - 0x2c40ae2b, - 0x2c4111c3, - 0x2c41ae3c, - 0x2c422e4f, - 0x2c429135, - 0x2c432e60, - 0x2c4386a2, - 0x2c442d8d, + 0x2c3728b3, + 0x2c37a8c5, + 0x2c3828d8, + 0x2c38a8e6, + 0x2c3928f6, + 0x2c39a908, + 0x2c3a291c, + 0x2c3aa92d, + 0x2c3b134a, + 0x2c3ba93e, + 0x2c3c2952, + 0x2c3ca968, + 0x2c3d2981, + 0x2c3da9af, + 0x2c3e29bd, + 0x2c3ea9d5, + 0x2c3f29ed, + 0x2c3fa9fa, + 0x2c402a1d, + 0x2c40aa3c, + 0x2c4111b4, + 0x2c41aa4d, + 0x2c422a60, + 0x2c429126, + 0x2c432a71, + 0x2c438693, + 0x2c44299e, 0x30320000, 0x30328015, 0x3033001f, @@ -277,436 +277,398 @@ const uint32_t kOpenSSLReasonValues[] = { 0x304a03b4, 0x304a83c7, 0x304b03d2, - 0x304b83e1, - 0x304c03f2, - 0x304c83fe, - 0x304d0414, - 0x304d8422, - 0x304e0438, - 0x304e844a, - 0x304f045c, - 0x304f846f, - 0x30500482, - 0x30508493, - 0x305104a3, - 0x305184bb, - 0x305204d0, - 0x305284e8, - 0x305304fc, - 0x30538514, - 0x3054052d, - 0x30548546, - 0x30550563, - 0x3055856e, - 0x30560586, - 0x30568596, - 0x305705a7, - 0x305785ba, - 0x305805d0, - 0x305885d9, - 0x305905ee, + 0x304b83e3, + 0x304c03ef, + 0x304c8405, + 0x304d0413, + 0x304d8429, + 0x304e043b, + 0x304e844d, + 0x304f0460, + 0x304f8473, + 0x30500484, + 0x30508494, + 0x305104ac, + 0x305184c1, + 0x305204d9, + 0x305284ed, + 0x30530505, + 0x3053851e, + 0x30540537, + 0x30548554, + 0x3055055f, + 0x30558577, + 0x30560587, + 0x30568598, + 0x305705ab, + 0x305785c1, + 0x305805ca, + 0x305885df, + 0x305905f2, 0x30598601, - 0x305a0610, + 0x305a0621, 0x305a8630, - 0x305b063f, - 0x305b864b, - 0x305c066b, - 0x305c8687, - 0x305d0698, - 0x305d86a2, - 0x34320ac9, - 0x34328add, - 0x34330afa, - 0x34338b0d, - 0x34340b1c, - 0x34348b39, + 0x305b063c, + 0x305b865c, + 0x305c0678, + 0x305c8689, + 0x305d0693, + 0x34320aba, + 0x34328ace, + 0x34330aeb, + 0x34338afe, + 0x34340b0d, + 0x34348b2a, 0x3c320083, - 0x3c328bd8, - 0x3c330bf1, - 0x3c338c0c, - 0x3c340c29, - 0x3c348c44, - 0x3c350c5f, - 0x3c358c74, - 0x3c360c8d, - 0x3c368ca5, - 0x3c370cb6, - 0x3c378cc4, - 0x3c380cd1, - 0x3c388ce5, - 0x3c390b9b, - 0x3c398cf9, - 0x3c3a0d0d, - 0x3c3a8881, - 0x3c3b0d1d, - 0x3c3b8d38, - 0x3c3c0d4a, - 0x3c3c8d60, - 0x3c3d0d6a, - 0x3c3d8d7e, - 0x3c3e0d8c, - 0x3c3e8db1, - 0x3c3f0bc4, - 0x3c3f8d9a, - 0x403217d3, - 0x403297e9, - 0x40331817, - 0x40339821, - 0x40341838, - 0x40349856, - 0x40351866, - 0x40359878, - 0x40361885, - 0x40369891, - 0x403718a6, - 0x403798bb, - 0x403818cd, - 0x403898d8, - 0x403918ea, - 0x40398de1, - 0x403a18fa, - 0x403a990d, - 0x403b192e, - 0x403b993f, - 0x403c194f, - 0x403c8064, - 0x403d195b, - 0x403d9977, - 0x403e198d, - 0x403e999c, - 0x403f19af, - 0x403f99c9, - 0x404019d7, - 0x404099ec, - 0x40411a00, - 0x40419a1d, - 0x40421a36, - 0x40429a51, - 0x40431a6a, - 0x40439a7d, - 0x40441a91, - 0x40449aa9, - 0x40451af4, - 0x40459b02, - 0x40461b20, - 0x40468094, - 0x40471b35, - 0x40479b47, - 0x40481b6b, - 0x40489b8b, - 0x40491b9f, - 0x40499bb4, - 0x404a1bcd, - 0x404a9c07, - 0x404b1c38, - 0x404b9c6e, - 0x404c1c89, - 0x404c9ca3, - 0x404d1cba, - 0x404d9ce2, - 0x404e1cf9, - 0x404e9d15, - 0x404f1d31, - 0x404f9d52, - 0x40501d74, - 0x40509d90, - 0x40511da4, - 0x40519db1, - 0x40521dc8, - 0x40529dd8, - 0x40531de8, - 0x40539dfc, - 0x40541e17, - 0x40549e27, - 0x40551e3e, - 0x40559e4d, - 0x40561e7a, - 0x40569e92, - 0x40571eae, - 0x40579ec7, - 0x40581eda, - 0x40589eef, - 0x40591f12, - 0x40599f3d, - 0x405a1f4a, - 0x405a9f63, - 0x405b1f7b, - 0x405b9f8e, - 0x405c1fa3, - 0x405c9fb5, - 0x405d1fca, - 0x405d9fda, - 0x405e1ff3, - 0x405ea007, - 0x405f2017, - 0x405fa02f, - 0x40602040, - 0x4060a053, - 0x40612064, - 0x4061a082, - 0x40622093, - 0x4062a0a0, - 0x406320b7, - 0x4063a0f8, - 0x4064210f, - 0x4064a11c, - 0x4065212a, - 0x4065a14c, - 0x40662174, - 0x4066a189, - 0x406721a0, - 0x4067a1b1, - 0x406821c2, - 0x4068a1d3, - 0x406921e8, - 0x4069a1ff, - 0x406a2210, - 0x406aa229, - 0x406b2244, - 0x406ba25b, - 0x406c22c8, - 0x406ca2e9, - 0x406d22fc, - 0x406da31d, - 0x406e2338, - 0x406ea381, - 0x406f23a2, - 0x406fa3c8, - 0x407023e8, - 0x4070a404, - 0x40712591, - 0x4071a5b4, - 0x407225ca, - 0x4072a5e9, - 0x40732601, - 0x4073a621, - 0x4074284b, - 0x4074a870, - 0x4075288b, - 0x4075a8aa, - 0x407628d9, - 0x4076a901, - 0x40772932, - 0x4077a951, - 0x4078298b, - 0x4078a9a2, - 0x407929b5, - 0x4079a9d2, - 0x407a0782, - 0x407aa9e4, - 0x407b29f7, - 0x407baa10, - 0x407c2a28, - 0x407c90bd, - 0x407d2a3c, - 0x407daa56, - 0x407e2a67, - 0x407eaa7b, - 0x407f2a89, - 0x407faaa4, - 0x40801286, - 0x4080aac9, - 0x40812aeb, - 0x4081ab06, - 0x40822b1b, - 0x4082ab33, - 0x40832b4b, - 0x4083ab62, - 0x40842b78, - 0x4084ab84, - 0x40852b97, - 0x4085abac, - 0x40862bbe, - 0x4086abd3, - 0x40872bdc, - 0x40879cd0, - 0x40880083, - 0x4088a0d7, - 0x40890a17, - 0x4089a273, - 0x408a1bf0, - 0x408aa29d, - 0x408b291a, - 0x408ba976, - 0x408c2353, - 0x408c9c21, - 0x408d1c56, - 0x408d9e68, - 0x408e1ab9, - 0x408e9add, - 0x408f1f20, - 0x41f424bc, - 0x41f9254e, - 0x41fe2441, - 0x41fea672, - 0x41ff2763, - 0x420324d5, - 0x420824f7, - 0x4208a533, - 0x42092425, - 0x4209a56d, - 0x420a247c, - 0x420aa45c, - 0x420b249c, - 0x420ba515, - 0x420c277f, - 0x420ca63f, - 0x420d2659, - 0x420da690, - 0x421226aa, - 0x42172746, - 0x4217a6ec, - 0x421c270e, - 0x421f26c9, - 0x42212796, - 0x42262729, - 0x422b282f, - 0x422ba7f8, - 0x422c2817, - 0x422ca7d2, - 0x422d27b1, - 0x443206ad, - 0x443286bc, - 0x443306c8, - 0x443386d6, - 0x443406e9, - 0x443486fa, - 0x44350701, - 0x4435870b, - 0x4436071e, - 0x44368734, - 0x44370746, - 0x44378753, - 0x44380762, - 0x4438876a, - 0x44390782, - 0x44398790, - 0x443a07a3, - 0x4c3212b0, - 0x4c3292c0, - 0x4c3312d3, - 0x4c3392f3, + 0x3c328bc9, + 0x3c330be2, + 0x3c338bfd, + 0x3c340c1a, + 0x3c348c35, + 0x3c350c50, + 0x3c358c65, + 0x3c360c7e, + 0x3c368c96, + 0x3c370ca7, + 0x3c378cb5, + 0x3c380cc2, + 0x3c388cd6, + 0x3c390b8c, + 0x3c398cea, + 0x3c3a0cfe, + 0x3c3a8872, + 0x3c3b0d0e, + 0x3c3b8d29, + 0x3c3c0d3b, + 0x3c3c8d51, + 0x3c3d0d5b, + 0x3c3d8d6f, + 0x3c3e0d7d, + 0x3c3e8da2, + 0x3c3f0bb5, + 0x3c3f8d8b, + 0x403217c4, + 0x403297da, + 0x40331808, + 0x40339812, + 0x40341829, + 0x40349847, + 0x40351857, + 0x40359869, + 0x40361876, + 0x40369882, + 0x40371897, + 0x403798a9, + 0x403818b4, + 0x403898c6, + 0x40390dd2, + 0x403998d6, + 0x403a18e9, + 0x403a990a, + 0x403b191b, + 0x403b992b, + 0x403c0064, + 0x403c8083, + 0x403d1937, + 0x403d994d, + 0x403e195c, + 0x403e996f, + 0x403f1989, + 0x403f9997, + 0x404019ac, + 0x404099c0, + 0x404119dd, + 0x404199f8, + 0x40421a11, + 0x40429a24, + 0x40431a38, + 0x40439a50, + 0x40441a67, + 0x40448094, + 0x40451a7c, + 0x40459a8e, + 0x40461ab2, + 0x40469ad2, + 0x40471ae0, + 0x40479af4, + 0x40481b09, + 0x40489b22, + 0x40491b39, + 0x40499b53, + 0x404a1b6a, + 0x404a9b88, + 0x404b1ba0, + 0x404b9bb7, + 0x404c1bcd, + 0x404c9bdf, + 0x404d1c00, + 0x404d9c22, + 0x404e1c36, + 0x404e9c43, + 0x404f1c5a, + 0x404f9c6a, + 0x40501c7a, + 0x40509c8e, + 0x40511ca9, + 0x40519cb9, + 0x40521cd0, + 0x40529ce2, + 0x40531cfa, + 0x40539d0d, + 0x40541d22, + 0x40549d45, + 0x40551d53, + 0x40559d70, + 0x40561d7d, + 0x40569d96, + 0x40571dae, + 0x40579dc1, + 0x40581dd6, + 0x40589de8, + 0x40591df8, + 0x40599e11, + 0x405a1e25, + 0x405a9e35, + 0x405b1e4d, + 0x405b9e5e, + 0x405c1e71, + 0x405c9e82, + 0x405d1e8f, + 0x405d9ea6, + 0x405e1ec6, + 0x405e8a08, + 0x405f1ee7, + 0x405f9ef4, + 0x40601f02, + 0x40609f24, + 0x40611f4c, + 0x40619f61, + 0x40621f78, + 0x40629f89, + 0x40631f9a, + 0x40639faf, + 0x40641fc6, + 0x40649fd7, + 0x40651ff2, + 0x4065a009, + 0x40662021, + 0x4066a04b, + 0x40672076, + 0x4067a097, + 0x406820aa, + 0x4068a0cb, + 0x406920e6, + 0x4069a114, + 0x406a2135, + 0x406aa155, + 0x406b22dd, + 0x406ba300, + 0x406c2316, + 0x406ca542, + 0x406d2571, + 0x406da599, + 0x406e25b2, + 0x406ea5ca, + 0x406f25e9, + 0x406fa5fe, + 0x40702611, + 0x4070a62e, + 0x40710773, + 0x4071a640, + 0x40722653, + 0x4072a66c, + 0x40732684, + 0x407390ae, + 0x40742698, + 0x4074a6b2, + 0x407526c3, + 0x4075a6d7, + 0x407626e5, + 0x40769277, + 0x4077270a, + 0x4077a72c, + 0x40782747, + 0x4078a75c, + 0x40792773, + 0x4079a789, + 0x407a2795, + 0x407aa7a8, + 0x407b27bd, + 0x407ba7cf, + 0x407c27e4, + 0x407ca7ed, + 0x41f42208, + 0x41f9229a, + 0x41fe218d, + 0x41fea369, + 0x41ff245a, + 0x42032221, + 0x42082243, + 0x4208a27f, + 0x42092171, + 0x4209a2b9, + 0x420a21c8, + 0x420aa1a8, + 0x420b21e8, + 0x420ba261, + 0x420c2476, + 0x420ca336, + 0x420d2350, + 0x420da387, + 0x421223a1, + 0x4217243d, + 0x4217a3e3, + 0x421c2405, + 0x421f23c0, + 0x4221248d, + 0x42262420, + 0x422b2526, + 0x422ba4ef, + 0x422c250e, + 0x422ca4c9, + 0x422d24a8, + 0x4432069e, + 0x443286ad, + 0x443306b9, + 0x443386c7, + 0x443406da, + 0x443486eb, + 0x443506f2, + 0x443586fc, + 0x4436070f, + 0x44368725, + 0x44370737, + 0x44378744, + 0x44380753, + 0x4438875b, + 0x44390773, + 0x44398781, + 0x443a0794, + 0x4c3212a1, + 0x4c3292b1, + 0x4c3312c4, + 0x4c3392e4, 0x4c340094, 0x4c3480b0, - 0x4c3512ff, - 0x4c35930d, - 0x4c361329, - 0x4c36933c, - 0x4c37134b, - 0x4c379359, - 0x4c38136e, - 0x4c38937a, - 0x4c39139a, - 0x4c3993c4, - 0x4c3a13dd, - 0x4c3a93f6, - 0x4c3b05d0, - 0x4c3b940f, - 0x4c3c1421, - 0x4c3c9430, - 0x4c3d10bd, - 0x4c3d9449, - 0x4c3e1456, - 0x50322e72, - 0x5032ae81, - 0x50332e8c, - 0x5033ae9c, - 0x50342eb5, - 0x5034aecf, - 0x50352edd, - 0x5035aef3, - 0x50362f05, - 0x5036af1b, - 0x50372f34, - 0x5037af47, - 0x50382f5f, - 0x5038af70, - 0x50392f85, - 0x5039af99, - 0x503a2fb9, - 0x503aafcf, - 0x503b2fe7, - 0x503baff9, - 0x503c3015, - 0x503cb02c, - 0x503d3045, - 0x503db05b, - 0x503e3068, - 0x503eb07e, - 0x503f3090, + 0x4c3512f0, + 0x4c3592fe, + 0x4c36131a, + 0x4c36932d, + 0x4c37133c, + 0x4c37934a, + 0x4c38135f, + 0x4c38936b, + 0x4c39138b, + 0x4c3993b5, + 0x4c3a13ce, + 0x4c3a93e7, + 0x4c3b05c1, + 0x4c3b9400, + 0x4c3c1412, + 0x4c3c9421, + 0x4c3d10ae, + 0x4c3d943a, + 0x4c3e1447, + 0x50322a83, + 0x5032aa92, + 0x50332a9d, + 0x5033aaad, + 0x50342ac6, + 0x5034aae0, + 0x50352aee, + 0x5035ab04, + 0x50362b16, + 0x5036ab2c, + 0x50372b45, + 0x5037ab58, + 0x50382b70, + 0x5038ab81, + 0x50392b96, + 0x5039abaa, + 0x503a2bca, + 0x503aabe0, + 0x503b2bf8, + 0x503bac0a, + 0x503c2c26, + 0x503cac3d, + 0x503d2c56, + 0x503dac6c, + 0x503e2c79, + 0x503eac8f, + 0x503f2ca1, 0x503f8348, - 0x504030a3, - 0x5040b0b3, - 0x504130cd, - 0x5041b0dc, - 0x504230f6, - 0x5042b113, - 0x50433123, - 0x5043b133, - 0x50443142, - 0x50448414, - 0x50453156, - 0x5045b174, - 0x50463187, - 0x5046b19d, - 0x504731af, - 0x5047b1c4, - 0x504831ea, - 0x5048b1f8, - 0x5049320b, - 0x5049b220, - 0x504a3236, - 0x504ab246, - 0x504b3266, - 0x504bb279, - 0x504c329c, - 0x504cb2ca, - 0x504d32dc, - 0x504db2f9, - 0x504e3314, - 0x504eb330, - 0x504f3342, - 0x504fb359, - 0x50503368, - 0x50508687, - 0x5051337b, - 0x58320e1f, - 0x68320de1, - 0x68328b9b, - 0x68330bae, - 0x68338def, - 0x68340dff, + 0x50402cb4, + 0x5040acc4, + 0x50412cde, + 0x5041aced, + 0x50422d07, + 0x5042ad24, + 0x50432d34, + 0x5043ad44, + 0x50442d53, + 0x50448405, + 0x50452d67, + 0x5045ad85, + 0x50462d98, + 0x5046adae, + 0x50472dc0, + 0x5047add5, + 0x50482dfb, + 0x5048ae09, + 0x50492e1c, + 0x5049ae31, + 0x504a2e47, + 0x504aae57, + 0x504b2e77, + 0x504bae8a, + 0x504c2ead, + 0x504caedb, + 0x504d2eed, + 0x504daf0a, + 0x504e2f25, + 0x504eaf41, + 0x504f2f53, + 0x504faf6a, + 0x50502f79, + 0x50508678, + 0x50512f8c, + 0x58320e10, + 0x68320dd2, + 0x68328b8c, + 0x68330b9f, + 0x68338de0, + 0x68340df0, 0x683480b0, - 0x6c320dbd, - 0x6c328b7e, - 0x6c330dc8, - 0x7432098d, - 0x783208f2, - 0x78328907, - 0x78330913, + 0x6c320dae, + 0x6c328b6f, + 0x6c330db9, + 0x7432097e, + 0x783208e3, + 0x783288f8, + 0x78330904, 0x78338083, - 0x78340922, - 0x78348937, - 0x78350956, - 0x78358978, - 0x7836098d, - 0x783689a3, - 0x783709b3, - 0x783789c6, - 0x783809d9, - 0x783889eb, - 0x783909f8, - 0x78398a17, - 0x783a0a2c, - 0x783a8a3a, - 0x783b0a44, - 0x783b8a58, - 0x783c0a6f, - 0x783c8a84, - 0x783d0a9b, - 0x783d8ab0, - 0x783e0a06, - 0x7c3211b2, + 0x78340913, + 0x78348928, + 0x78350947, + 0x78358969, + 0x7836097e, + 0x78368994, + 0x783709a4, + 0x783789b7, + 0x783809ca, + 0x783889dc, + 0x783909e9, + 0x78398a08, + 0x783a0a1d, + 0x783a8a2b, + 0x783b0a35, + 0x783b8a49, + 0x783c0a60, + 0x783c8a75, + 0x783d0a8c, + 0x783d8aa1, + 0x783e09f7, + 0x7c3211a3, }; const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); @@ -762,7 +724,6 @@ const char kOpenSSLReasonStringData[] = "INVALID_UNIVERSALSTRING_LENGTH\0" "INVALID_UTF8STRING\0" "LIST_ERROR\0" - "MALLOC_FAILURE\0" "MISSING_ASN1_EOS\0" "MISSING_EOC\0" "MISSING_SECOND_NUMBER\0" @@ -1030,7 +991,6 @@ const char kOpenSSLReasonStringData[] = "BAD_DIGEST_LENGTH\0" "BAD_ECC_CERT\0" "BAD_ECPOINT\0" - "BAD_HANDSHAKE_LENGTH\0" "BAD_HANDSHAKE_RECORD\0" "BAD_HELLO_REQUEST\0" "BAD_LENGTH\0" @@ -1041,7 +1001,6 @@ const char kOpenSSLReasonStringData[] = "BAD_SSL_FILETYPE\0" "BAD_WRITE_RETRY\0" "BIO_NOT_SET\0" - "CANNOT_SERIALIZE_PUBLIC_KEY\0" "CA_DN_LENGTH_MISMATCH\0" "CA_DN_TOO_LONG\0" "CCS_RECEIVED_EARLY\0" @@ -1050,41 +1009,30 @@ const char kOpenSSLReasonStringData[] = "CERT_LENGTH_MISMATCH\0" "CHANNEL_ID_NOT_P256\0" "CHANNEL_ID_SIGNATURE_INVALID\0" - "CIPHER_CODE_WRONG_LENGTH\0" "CIPHER_OR_HASH_UNAVAILABLE\0" "CLIENTHELLO_PARSE_FAILED\0" "CLIENTHELLO_TLSEXT\0" "CONNECTION_REJECTED\0" "CONNECTION_TYPE_NOT_SET\0" - "COOKIE_MISMATCH\0" - "CUSTOM_EXTENSION_CONTENTS_TOO_LARGE\0" "CUSTOM_EXTENSION_ERROR\0" - "D2I_ECDSA_SIG\0" - "DATA_BETWEEN_CCS_AND_FINISHED\0" "DATA_LENGTH_TOO_LONG\0" "DECRYPTION_FAILED\0" "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\0" "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\0" + "DH_P_TOO_LONG\0" "DIGEST_CHECK_FAILED\0" "DTLS_MESSAGE_TOO_BIG\0" "ECC_CERT_NOT_FOR_SIGNING\0" - "EMPTY_SRTP_PROTECTION_PROFILE_LIST\0" "EMS_STATE_INCONSISTENT\0" "ENCRYPTED_LENGTH_TOO_LONG\0" "ERROR_ADDING_EXTENSION\0" "ERROR_IN_RECEIVED_CIPHER_LIST\0" "ERROR_PARSING_EXTENSION\0" - "EVP_DIGESTSIGNFINAL_FAILED\0" - "EVP_DIGESTSIGNINIT_FAILED\0" "EXCESSIVE_MESSAGE_SIZE\0" "EXTRA_DATA_IN_MESSAGE\0" "FRAGMENT_MISMATCH\0" - "GOT_A_FIN_BEFORE_A_CCS\0" - "GOT_CHANNEL_ID_BEFORE_A_CCS\0" - "GOT_NEXT_PROTO_BEFORE_A_CCS\0" "GOT_NEXT_PROTO_WITHOUT_EXTENSION\0" "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\0" - "HANDSHAKE_RECORD_BEFORE_CCS\0" "HTTPS_PROXY_REQUEST\0" "HTTP_REQUEST\0" "INAPPROPRIATE_FALLBACK\0" @@ -1094,12 +1042,8 @@ const char kOpenSSLReasonStringData[] = "INVALID_TICKET_KEYS_LENGTH\0" "LENGTH_MISMATCH\0" "LIBRARY_HAS_NO_CIPHERS\0" - "MISSING_DH_KEY\0" - "MISSING_ECDSA_SIGNING_CERT\0" "MISSING_EXTENSION\0" "MISSING_RSA_CERTIFICATE\0" - "MISSING_RSA_ENCRYPTING_CERT\0" - "MISSING_RSA_SIGNING_CERT\0" "MISSING_TMP_DH_KEY\0" "MISSING_TMP_ECDH_KEY\0" "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\0" @@ -1111,7 +1055,6 @@ const char kOpenSSLReasonStringData[] = "NO_CERTIFICATE_SET\0" "NO_CIPHERS_AVAILABLE\0" "NO_CIPHERS_PASSED\0" - "NO_CIPHERS_SPECIFIED\0" "NO_CIPHER_MATCH\0" "NO_COMPRESSION_SPECIFIED\0" "NO_METHOD_SPECIFIED\0" @@ -1120,13 +1063,10 @@ const char kOpenSSLReasonStringData[] = "NO_RENEGOTIATION\0" "NO_REQUIRED_DIGEST\0" "NO_SHARED_CIPHER\0" - "NO_SHARED_SIGATURE_ALGORITHMS\0" - "NO_SRTP_PROFILES\0" "NULL_SSL_CTX\0" "NULL_SSL_METHOD_PASSED\0" "OLD_SESSION_CIPHER_NOT_RETURNED\0" "OLD_SESSION_VERSION_NOT_RETURNED\0" - "PACKET_LENGTH_TOO_LONG\0" "PARSE_TLSEXT\0" "PATH_TOO_LONG\0" "PEER_DID_NOT_RETURN_A_CERTIFICATE\0" @@ -1135,11 +1075,9 @@ const char kOpenSSLReasonStringData[] = "PSK_IDENTITY_NOT_FOUND\0" "PSK_NO_CLIENT_CB\0" "PSK_NO_SERVER_CB\0" - "READ_BIO_NOT_SET\0" "READ_TIMEOUT_EXPIRED\0" "RECORD_LENGTH_MISMATCH\0" "RECORD_TOO_LARGE\0" - "RENEGOTIATE_EXT_TOO_LONG\0" "RENEGOTIATION_ENCODING_ERR\0" "RENEGOTIATION_MISMATCH\0" "REQUIRED_CIPHER_MISSING\0" @@ -1149,13 +1087,10 @@ const char kOpenSSLReasonStringData[] = "SERVERHELLO_TLSEXT\0" "SESSION_ID_CONTEXT_UNINITIALIZED\0" "SESSION_MAY_NOT_BE_CREATED\0" - "SIGNATURE_ALGORITHMS_ERROR\0" "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\0" "SRTP_COULD_NOT_ALLOCATE_PROFILES\0" - "SRTP_PROTECTION_PROFILE_LIST_TOO_LONG\0" "SRTP_UNKNOWN_PROTECTION_PROFILE\0" "SSL3_EXT_INVALID_SERVERNAME\0" - "SSL3_EXT_INVALID_SERVERNAME_TYPE\0" "SSLV3_ALERT_BAD_CERTIFICATE\0" "SSLV3_ALERT_BAD_RECORD_MAC\0" "SSLV3_ALERT_CERTIFICATE_EXPIRED\0" @@ -1170,10 +1105,7 @@ const char kOpenSSLReasonStringData[] = "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\0" "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\0" "SSL_HANDSHAKE_FAILURE\0" - "SSL_SESSION_ID_CALLBACK_FAILED\0" - "SSL_SESSION_ID_CONFLICT\0" "SSL_SESSION_ID_CONTEXT_TOO_LONG\0" - "SSL_SESSION_ID_HAS_BAD_LENGTH\0" "TLSV1_ALERT_ACCESS_DENIED\0" "TLSV1_ALERT_DECODE_ERROR\0" "TLSV1_ALERT_DECRYPTION_FAILED\0" @@ -1192,17 +1124,12 @@ const char kOpenSSLReasonStringData[] = "TLSV1_CERTIFICATE_UNOBTAINABLE\0" "TLSV1_UNRECOGNIZED_NAME\0" "TLSV1_UNSUPPORTED_EXTENSION\0" - "TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER\0" - "TLS_ILLEGAL_EXPORTER_LABEL\0" - "TLS_INVALID_ECPOINTFORMAT_LIST\0" "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0" "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\0" "TOO_MANY_EMPTY_FRAGMENTS\0" "TOO_MANY_WARNING_ALERTS\0" "UNABLE_TO_FIND_ECDH_PARAMETERS\0" - "UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS\0" "UNEXPECTED_EXTENSION\0" - "UNEXPECTED_GROUP_CLOSE\0" "UNEXPECTED_MESSAGE\0" "UNEXPECTED_OPERATOR_IN_GROUP\0" "UNEXPECTED_RECORD\0" @@ -1214,13 +1141,10 @@ const char kOpenSSLReasonStringData[] = "UNKNOWN_PROTOCOL\0" "UNKNOWN_SSL_VERSION\0" "UNKNOWN_STATE\0" - "UNPROCESSED_HANDSHAKE_DATA\0" "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\0" "UNSUPPORTED_COMPRESSION_ALGORITHM\0" "UNSUPPORTED_ELLIPTIC_CURVE\0" "UNSUPPORTED_PROTOCOL\0" - "UNSUPPORTED_SSL_VERSION\0" - "USE_SRTP_NOT_NEGOTIATED\0" "WRONG_CERTIFICATE_TYPE\0" "WRONG_CIPHER_RETURNED\0" "WRONG_CURVE\0" diff --git a/linux-arm/crypto/modes/ghash-armv4.S b/linux-arm/crypto/modes/ghash-armv4.S index 0a43989..d955d82 100644 --- a/linux-arm/crypto/modes/ghash-armv4.S +++ b/linux-arm/crypto/modes/ghash-armv4.S @@ -6,7 +6,7 @@ .text .code 32 -#ifdef __APPLE__ +#ifdef __clang__ #define ldrplb ldrbpl #define ldrneb ldrbne #endif diff --git a/linux-x86/crypto/sha/sha1-586.S b/linux-x86/crypto/sha/sha1-586.S index dd86f31..58d0bc1 100644 --- a/linux-x86/crypto/sha/sha1-586.S +++ b/linux-x86/crypto/sha/sha1-586.S @@ -23,6 +23,11 @@ sha1_block_data_order: movl 8(%esi),%ecx testl $16777216,%eax jz .L001x86 + andl $268435456,%edx + andl $1073741824,%eax + orl %edx,%eax + cmpl $1342177280,%eax + je .Lavx_shortcut jmp .Lssse3_shortcut .align 16 .L001x86: @@ -2611,6 +2616,1177 @@ _sha1_block_data_order_ssse3: popl %ebp ret .size _sha1_block_data_order_ssse3,.-_sha1_block_data_order_ssse3 +.hidden _sha1_block_data_order_avx +.type _sha1_block_data_order_avx,@function +.align 16 +_sha1_block_data_order_avx: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + call .L006pic_point +.L006pic_point: + popl %ebp + leal .LK_XX_XX-.L006pic_point(%ebp),%ebp +.Lavx_shortcut: + vzeroall + vmovdqa (%ebp),%xmm7 + vmovdqa 16(%ebp),%xmm0 + vmovdqa 32(%ebp),%xmm1 + vmovdqa 48(%ebp),%xmm2 + vmovdqa 64(%ebp),%xmm6 + movl 20(%esp),%edi + movl 24(%esp),%ebp + movl 28(%esp),%edx + movl %esp,%esi + subl $208,%esp + andl $-64,%esp + vmovdqa %xmm0,112(%esp) + vmovdqa %xmm1,128(%esp) + vmovdqa %xmm2,144(%esp) + shll $6,%edx + vmovdqa %xmm7,160(%esp) + addl %ebp,%edx + vmovdqa %xmm6,176(%esp) + addl $64,%ebp + movl %edi,192(%esp) + movl %ebp,196(%esp) + movl %edx,200(%esp) + movl %esi,204(%esp) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl 16(%edi),%edi + movl %ebx,%esi + vmovdqu -64(%ebp),%xmm0 + vmovdqu -48(%ebp),%xmm1 + vmovdqu -32(%ebp),%xmm2 + vmovdqu -16(%ebp),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vmovdqa %xmm7,96(%esp) + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm7,%xmm0,%xmm4 + vpaddd %xmm7,%xmm1,%xmm5 + vpaddd %xmm7,%xmm2,%xmm6 + vmovdqa %xmm4,(%esp) + movl %ecx,%ebp + vmovdqa %xmm5,16(%esp) + xorl %edx,%ebp + vmovdqa %xmm6,32(%esp) + andl %ebp,%esi + jmp .L007loop +.align 16 +.L007loop: + shrdl $2,%ebx,%ebx + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%ebp + addl (%esp),%edi + vpaddd %xmm3,%xmm7,%xmm7 + vmovdqa %xmm0,64(%esp) + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm6 + addl %esi,%edi + andl %ebx,%ebp + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%edi + vpxor %xmm2,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%ebp + vmovdqa %xmm7,48(%esp) + movl %edi,%esi + addl 4(%esp),%edx + vpxor %xmm6,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%edi,%edi + addl %ebp,%edx + andl %eax,%esi + vpsrld $31,%xmm4,%xmm6 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm0 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%ebp + addl 8(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpsrld $30,%xmm0,%xmm7 + vpor %xmm6,%xmm4,%xmm4 + addl %esi,%ecx + andl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + vpslld $2,%xmm0,%xmm0 + shrdl $7,%edx,%edx + xorl %eax,%ebp + vpxor %xmm7,%xmm4,%xmm4 + movl %ecx,%esi + addl 12(%esp),%ebx + xorl %edi,%edx + shldl $5,%ecx,%ecx + vpxor %xmm0,%xmm4,%xmm4 + addl %ebp,%ebx + andl %edx,%esi + vmovdqa 96(%esp),%xmm0 + xorl %edi,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %edi,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%ebp + addl 16(%esp),%eax + vpaddd %xmm4,%xmm0,%xmm0 + vmovdqa %xmm1,80(%esp) + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm7 + addl %esi,%eax + andl %ecx,%ebp + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + xorl %edx,%ebp + vmovdqa %xmm0,(%esp) + movl %eax,%esi + addl 20(%esp),%edi + vpxor %xmm7,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %ebp,%edi + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm7 + xorl %ecx,%ebx + addl %eax,%edi + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm1 + vpaddd %xmm5,%xmm5,%xmm5 + movl %edi,%ebp + addl 24(%esp),%edx + xorl %ebx,%eax + shldl $5,%edi,%edi + vpsrld $30,%xmm1,%xmm0 + vpor %xmm7,%xmm5,%xmm5 + addl %esi,%edx + andl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + vpslld $2,%xmm1,%xmm1 + shrdl $7,%edi,%edi + xorl %ebx,%ebp + vpxor %xmm0,%xmm5,%xmm5 + movl %edx,%esi + addl 28(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpxor %xmm1,%xmm5,%xmm5 + addl %ebp,%ecx + andl %edi,%esi + vmovdqa 112(%esp),%xmm1 + xorl %eax,%edi + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%ebp + addl 32(%esp),%ebx + vpaddd %xmm5,%xmm1,%xmm1 + vmovdqa %xmm2,96(%esp) + xorl %edi,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm0 + addl %esi,%ebx + andl %edx,%ebp + vpxor %xmm2,%xmm6,%xmm6 + xorl %edi,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%ecx,%ecx + xorl %edi,%ebp + vmovdqa %xmm1,16(%esp) + movl %ebx,%esi + addl 36(%esp),%eax + vpxor %xmm0,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + addl %ebp,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm0 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm2 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%ebp + addl 40(%esp),%edi + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm1 + vpor %xmm0,%xmm6,%xmm6 + addl %esi,%edi + andl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + vpslld $2,%xmm2,%xmm2 + vmovdqa 64(%esp),%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%ebp + vpxor %xmm1,%xmm6,%xmm6 + movl %edi,%esi + addl 44(%esp),%edx + xorl %ebx,%eax + shldl $5,%edi,%edi + vpxor %xmm2,%xmm6,%xmm6 + addl %ebp,%edx + andl %eax,%esi + vmovdqa 112(%esp),%xmm2 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%ebp + addl 48(%esp),%ecx + vpaddd %xmm6,%xmm2,%xmm2 + vmovdqa %xmm3,64(%esp) + xorl %eax,%edi + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm1 + addl %esi,%ecx + andl %edi,%ebp + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%edi + addl %edx,%ecx + vpxor %xmm5,%xmm1,%xmm1 + shrdl $7,%edx,%edx + xorl %eax,%ebp + vmovdqa %xmm2,32(%esp) + movl %ecx,%esi + addl 52(%esp),%ebx + vpxor %xmm1,%xmm7,%xmm7 + xorl %edi,%edx + shldl $5,%ecx,%ecx + addl %ebp,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm1 + xorl %edi,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %edi,%esi + vpslldq $12,%xmm7,%xmm3 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%ebp + addl 56(%esp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm2 + vpor %xmm1,%xmm7,%xmm7 + addl %esi,%eax + andl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + vmovdqa 80(%esp),%xmm1 + shrdl $7,%ebx,%ebx + xorl %edx,%ebp + vpxor %xmm2,%xmm7,%xmm7 + movl %eax,%esi + addl 60(%esp),%edi + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpxor %xmm3,%xmm7,%xmm7 + addl %ebp,%edi + andl %ebx,%esi + vmovdqa 112(%esp),%xmm3 + xorl %ecx,%ebx + addl %eax,%edi + vpalignr $8,%xmm6,%xmm7,%xmm2 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %edi,%ebp + addl (%esp),%edx + vpxor %xmm1,%xmm0,%xmm0 + vmovdqa %xmm4,80(%esp) + xorl %ebx,%eax + shldl $5,%edi,%edi + vmovdqa %xmm3,%xmm4 + vpaddd %xmm7,%xmm3,%xmm3 + addl %esi,%edx + andl %eax,%ebp + vpxor %xmm2,%xmm0,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%ebp + vpsrld $30,%xmm0,%xmm2 + vmovdqa %xmm3,48(%esp) + movl %edx,%esi + addl 4(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %ebp,%ecx + andl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%ebp + addl 8(%esp),%ebx + vpor %xmm2,%xmm0,%xmm0 + xorl %edi,%edx + shldl $5,%ecx,%ecx + vmovdqa 96(%esp),%xmm2 + addl %esi,%ebx + andl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 12(%esp),%eax + xorl %edi,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm3 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm5,96(%esp) + addl %esi,%edi + xorl %ecx,%ebp + vmovdqa %xmm4,%xmm5 + vpaddd %xmm0,%xmm4,%xmm4 + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpxor %xmm3,%xmm1,%xmm1 + addl 20(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + vpsrld $30,%xmm1,%xmm3 + vmovdqa %xmm4,(%esp) + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vpor %xmm3,%xmm1,%xmm1 + addl 28(%esp),%ebx + xorl %edi,%ebp + vmovdqa 64(%esp),%xmm3 + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm4 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + vmovdqa %xmm6,64(%esp) + addl %esi,%eax + xorl %edx,%ebp + vmovdqa 128(%esp),%xmm6 + vpaddd %xmm1,%xmm5,%xmm5 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm4,%xmm2,%xmm2 + addl 36(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm4 + vmovdqa %xmm5,16(%esp) + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpslld $2,%xmm2,%xmm2 + addl 40(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + vpor %xmm4,%xmm2,%xmm2 + addl 44(%esp),%ecx + xorl %eax,%ebp + vmovdqa 80(%esp),%xmm4 + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm5 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + vmovdqa %xmm7,80(%esp) + addl %esi,%ebx + xorl %edi,%ebp + vmovdqa %xmm6,%xmm7 + vpaddd %xmm2,%xmm6,%xmm6 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm5,%xmm3,%xmm3 + addl 52(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm5 + vmovdqa %xmm6,32(%esp) + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpor %xmm5,%xmm3,%xmm3 + addl 60(%esp),%edx + xorl %ebx,%ebp + vmovdqa 96(%esp),%xmm5 + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpalignr $8,%xmm2,%xmm3,%xmm6 + vpxor %xmm0,%xmm4,%xmm4 + addl (%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + vmovdqa %xmm0,96(%esp) + addl %esi,%ecx + xorl %eax,%ebp + vmovdqa %xmm7,%xmm0 + vpaddd %xmm3,%xmm7,%xmm7 + shrdl $7,%edi,%edi + addl %edx,%ecx + vpxor %xmm6,%xmm4,%xmm4 + addl 4(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm6 + vmovdqa %xmm7,48(%esp) + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm6,%xmm4,%xmm4 + addl 12(%esp),%edi + xorl %ecx,%ebp + vmovdqa 64(%esp),%xmm6 + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpalignr $8,%xmm3,%xmm4,%xmm7 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + vpxor %xmm6,%xmm5,%xmm5 + vmovdqa %xmm1,64(%esp) + addl %esi,%edx + xorl %ebx,%ebp + vmovdqa %xmm0,%xmm1 + vpaddd %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + addl %edi,%edx + vpxor %xmm7,%xmm5,%xmm5 + addl 20(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm7 + vmovdqa %xmm0,(%esp) + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm7,%xmm5,%xmm5 + addl 28(%esp),%eax + vmovdqa 80(%esp),%xmm7 + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm0 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%esp),%edi + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + vmovdqa %xmm2,80(%esp) + movl %eax,%ebp + xorl %ecx,%esi + vmovdqa %xmm1,%xmm2 + vpaddd %xmm5,%xmm1,%xmm1 + shldl $5,%eax,%eax + addl %esi,%edi + vpxor %xmm0,%xmm6,%xmm6 + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + addl 36(%esp),%edx + vpsrld $30,%xmm6,%xmm0 + vmovdqa %xmm1,16(%esp) + andl %ebx,%ebp + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %edi,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%ebp + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + addl 40(%esp),%ecx + andl %eax,%esi + vpor %xmm0,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%edi,%edi + vmovdqa 96(%esp),%xmm0 + movl %edx,%ebp + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + addl 44(%esp),%ebx + andl %edi,%ebp + xorl %eax,%edi + shrdl $7,%edx,%edx + movl %ecx,%esi + xorl %edi,%ebp + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm1 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%esp),%eax + andl %edx,%esi + xorl %edi,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + vmovdqa %xmm3,96(%esp) + movl %ebx,%ebp + xorl %edx,%esi + vmovdqa 144(%esp),%xmm3 + vpaddd %xmm6,%xmm2,%xmm2 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm1,%xmm7,%xmm7 + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%esp),%edi + vpsrld $30,%xmm7,%xmm1 + vmovdqa %xmm2,32(%esp) + andl %ecx,%ebp + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%ebp + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + addl 56(%esp),%edx + andl %ebx,%esi + vpor %xmm1,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vmovdqa 64(%esp),%xmm1 + movl %edi,%ebp + xorl %ebx,%esi + shldl $5,%edi,%edi + addl %esi,%edx + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + addl 60(%esp),%ecx + andl %eax,%ebp + xorl %ebx,%eax + shrdl $7,%edi,%edi + movl %edx,%esi + xorl %eax,%ebp + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm2 + vpxor %xmm4,%xmm0,%xmm0 + addl (%esp),%ebx + andl %edi,%esi + xorl %eax,%edi + shrdl $7,%edx,%edx + vpxor %xmm1,%xmm0,%xmm0 + vmovdqa %xmm4,64(%esp) + movl %ecx,%ebp + xorl %edi,%esi + vmovdqa %xmm3,%xmm4 + vpaddd %xmm7,%xmm3,%xmm3 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm2,%xmm0,%xmm0 + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 4(%esp),%eax + vpsrld $30,%xmm0,%xmm2 + vmovdqa %xmm3,48(%esp) + andl %edx,%ebp + xorl %edi,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%esp),%edi + andl %ecx,%esi + vpor %xmm2,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vmovdqa 80(%esp),%xmm2 + movl %eax,%ebp + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + addl 12(%esp),%edx + andl %ebx,%ebp + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %edi,%esi + xorl %ebx,%ebp + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + vpalignr $8,%xmm7,%xmm0,%xmm3 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%esp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%edi,%edi + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm5,80(%esp) + movl %edx,%ebp + xorl %eax,%esi + vmovdqa %xmm4,%xmm5 + vpaddd %xmm0,%xmm4,%xmm4 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm3,%xmm1,%xmm1 + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + addl 20(%esp),%ebx + vpsrld $30,%xmm1,%xmm3 + vmovdqa %xmm4,(%esp) + andl %edi,%ebp + xorl %eax,%edi + shrdl $7,%edx,%edx + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %edi,%ebp + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + addl 24(%esp),%eax + andl %edx,%esi + vpor %xmm3,%xmm1,%xmm1 + xorl %edi,%edx + shrdl $7,%ecx,%ecx + vmovdqa 96(%esp),%xmm3 + movl %ebx,%ebp + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%esp),%edi + andl %ecx,%ebp + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%ebp + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + vpalignr $8,%xmm0,%xmm1,%xmm4 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%esp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + vmovdqa %xmm6,96(%esp) + movl %edi,%ebp + xorl %ebx,%esi + vmovdqa %xmm5,%xmm6 + vpaddd %xmm1,%xmm5,%xmm5 + shldl $5,%edi,%edi + addl %esi,%edx + vpxor %xmm4,%xmm2,%xmm2 + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + addl 36(%esp),%ecx + vpsrld $30,%xmm2,%xmm4 + vmovdqa %xmm5,16(%esp) + andl %eax,%ebp + xorl %ebx,%eax + shrdl $7,%edi,%edi + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%ebp + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + addl 40(%esp),%ebx + andl %edi,%esi + vpor %xmm4,%xmm2,%xmm2 + xorl %eax,%edi + shrdl $7,%edx,%edx + vmovdqa 64(%esp),%xmm4 + movl %ecx,%ebp + xorl %edi,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 44(%esp),%eax + andl %edx,%ebp + xorl %edi,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm5 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + vmovdqa %xmm7,64(%esp) + addl %esi,%edi + xorl %ecx,%ebp + vmovdqa %xmm6,%xmm7 + vpaddd %xmm2,%xmm6,%xmm6 + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpxor %xmm5,%xmm3,%xmm3 + addl 52(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + vpsrld $30,%xmm3,%xmm5 + vmovdqa %xmm6,32(%esp) + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vpor %xmm5,%xmm3,%xmm3 + addl 60(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl (%esp),%eax + vpaddd %xmm3,%xmm7,%xmm7 + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm7,48(%esp) + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 8(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + addl 12(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + movl 196(%esp),%ebp + cmpl 200(%esp),%ebp + je .L008done + vmovdqa 160(%esp),%xmm7 + vmovdqa 176(%esp),%xmm6 + vmovdqu (%ebp),%xmm0 + vmovdqu 16(%ebp),%xmm1 + vmovdqu 32(%ebp),%xmm2 + vmovdqu 48(%ebp),%xmm3 + addl $64,%ebp + vpshufb %xmm6,%xmm0,%xmm0 + movl %ebp,196(%esp) + vmovdqa %xmm7,96(%esp) + addl 16(%esp),%ebx + xorl %edi,%esi + vpshufb %xmm6,%xmm1,%xmm1 + movl %ecx,%ebp + shldl $5,%ecx,%ecx + vpaddd %xmm7,%xmm0,%xmm4 + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm4,(%esp) + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + vpshufb %xmm6,%xmm2,%xmm2 + movl %edx,%ebp + shldl $5,%edx,%edx + vpaddd %xmm7,%xmm1,%xmm5 + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vmovdqa %xmm5,16(%esp) + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + vpshufb %xmm6,%xmm3,%xmm3 + movl %edi,%ebp + shldl $5,%edi,%edi + vpaddd %xmm7,%xmm2,%xmm6 + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + vmovdqa %xmm6,32(%esp) + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + movl 192(%esp),%ebp + addl (%ebp),%eax + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,%ebx + movl %ecx,8(%ebp) + xorl %edx,%ebx + movl %edx,12(%ebp) + movl %edi,16(%ebp) + movl %esi,%ebp + andl %ebx,%esi + movl %ebp,%ebx + jmp .L007loop +.align 16 +.L008done: + addl 16(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vzeroall + movl 192(%esp),%ebp + addl (%ebp),%eax + movl 204(%esp),%esp + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,8(%ebp) + movl %edx,12(%ebp) + movl %edi,16(%ebp) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _sha1_block_data_order_avx,.-_sha1_block_data_order_avx .align 64 .LK_XX_XX: .long 1518500249,1518500249,1518500249,1518500249 diff --git a/linux-x86/crypto/sha/sha256-586.S b/linux-x86/crypto/sha/sha256-586.S index 196f7f9..38acbd8 100644 --- a/linux-x86/crypto/sha/sha256-586.S +++ b/linux-x86/crypto/sha/sha256-586.S @@ -40,12 +40,13 @@ sha256_block_data_order: orl %ebx,%ecx andl $1342177280,%ecx cmpl $1342177280,%ecx + je .L004AVX testl $512,%ebx - jnz .L004SSSE3 + jnz .L005SSSE3 .L003no_xmm: subl %edi,%eax cmpl $256,%eax - jae .L005unrolled + jae .L006unrolled jmp .L002loop .align 16 .L002loop: @@ -117,7 +118,7 @@ sha256_block_data_order: movl %ecx,28(%esp) movl %edi,32(%esp) .align 16 -.L00600_15: +.L00700_15: movl %edx,%ecx movl 24(%esp),%esi rorl $14,%ecx @@ -155,11 +156,11 @@ sha256_block_data_order: addl $4,%ebp addl %ebx,%eax cmpl $3248222580,%esi - jne .L00600_15 + jne .L00700_15 movl 156(%esp),%ecx - jmp .L00716_63 + jmp .L00816_63 .align 16 -.L00716_63: +.L00816_63: movl %ecx,%ebx movl 104(%esp),%esi rorl $11,%ecx @@ -214,7 +215,7 @@ sha256_block_data_order: addl $4,%ebp addl %ebx,%eax cmpl $3329325298,%esi - jne .L00716_63 + jne .L00816_63 movl 356(%esp),%esi movl 8(%esp),%ebx movl 16(%esp),%ecx @@ -258,7 +259,7 @@ sha256_block_data_order: .byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 .byte 62,0 .align 16 -.L005unrolled: +.L006unrolled: leal -96(%esp),%esp movl (%esi),%eax movl 4(%esi),%ebp @@ -275,9 +276,9 @@ sha256_block_data_order: movl %ebx,20(%esp) movl %ecx,24(%esp) movl %esi,28(%esp) - jmp .L008grand_loop + jmp .L009grand_loop .align 16 -.L008grand_loop: +.L009grand_loop: movl (%edi),%ebx movl 4(%edi),%ecx bswap %ebx @@ -3157,7 +3158,7 @@ sha256_block_data_order: movl %ebx,24(%esp) movl %ecx,28(%esp) cmpl 104(%esp),%edi - jb .L008grand_loop + jb .L009grand_loop movl 108(%esp),%esp popl %edi popl %esi @@ -3165,7 +3166,7 @@ sha256_block_data_order: popl %ebp ret .align 32 -.L004SSSE3: +.L005SSSE3: leal -96(%esp),%esp movl (%esi),%eax movl 4(%esi),%ebx @@ -3184,9 +3185,9 @@ sha256_block_data_order: movl %ecx,24(%esp) movl %esi,28(%esp) movdqa 256(%ebp),%xmm7 - jmp .L009grand_ssse3 + jmp .L010grand_ssse3 .align 16 -.L009grand_ssse3: +.L010grand_ssse3: movdqu (%edi),%xmm0 movdqu 16(%edi),%xmm1 movdqu 32(%edi),%xmm2 @@ -3209,9 +3210,9 @@ sha256_block_data_order: paddd %xmm3,%xmm7 movdqa %xmm6,64(%esp) movdqa %xmm7,80(%esp) - jmp .L010ssse3_00_47 + jmp .L011ssse3_00_47 .align 16 -.L010ssse3_00_47: +.L011ssse3_00_47: addl $64,%ebp movl %edx,%ecx movdqa %xmm1,%xmm4 @@ -3854,7 +3855,7 @@ sha256_block_data_order: addl %ecx,%eax movdqa %xmm6,80(%esp) cmpl $66051,64(%ebp) - jne .L010ssse3_00_47 + jne .L011ssse3_00_47 movl %edx,%ecx rorl $14,%edx movl 20(%esp),%esi @@ -4368,12 +4369,1193 @@ sha256_block_data_order: movdqa 64(%ebp),%xmm7 subl $192,%ebp cmpl 104(%esp),%edi - jb .L009grand_ssse3 + jb .L010grand_ssse3 movl 108(%esp),%esp popl %edi popl %esi popl %ebx popl %ebp ret +.align 32 +.L004AVX: + leal -96(%esp),%esp + vzeroall + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edi + movl %ebx,4(%esp) + xorl %ecx,%ebx + movl %ecx,8(%esp) + movl %edi,12(%esp) + movl 16(%esi),%edx + movl 20(%esi),%edi + movl 24(%esi),%ecx + movl 28(%esi),%esi + movl %edi,20(%esp) + movl 100(%esp),%edi + movl %ecx,24(%esp) + movl %esi,28(%esp) + vmovdqa 256(%ebp),%xmm7 + jmp .L012grand_avx +.align 32 +.L012grand_avx: + vmovdqu (%edi),%xmm0 + vmovdqu 16(%edi),%xmm1 + vmovdqu 32(%edi),%xmm2 + vmovdqu 48(%edi),%xmm3 + addl $64,%edi + vpshufb %xmm7,%xmm0,%xmm0 + movl %edi,100(%esp) + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd (%ebp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 16(%ebp),%xmm1,%xmm5 + vpaddd 32(%ebp),%xmm2,%xmm6 + vpaddd 48(%ebp),%xmm3,%xmm7 + vmovdqa %xmm4,32(%esp) + vmovdqa %xmm5,48(%esp) + vmovdqa %xmm6,64(%esp) + vmovdqa %xmm7,80(%esp) + jmp .L013avx_00_47 +.align 16 +.L013avx_00_47: + addl $64,%ebp + vpalignr $4,%xmm0,%xmm1,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + vpalignr $4,%xmm2,%xmm3,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + vpaddd %xmm7,%xmm0,%xmm0 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + vpshufd $250,%xmm3,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 32(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + vpaddd %xmm4,%xmm0,%xmm0 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 36(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + vpaddd %xmm7,%xmm0,%xmm0 + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm0,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 40(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm0,%xmm0 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + vpaddd (%ebp),%xmm0,%xmm6 + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,32(%esp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + vpalignr $4,%xmm3,%xmm0,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + vpaddd %xmm7,%xmm1,%xmm1 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + vpshufd $250,%xmm0,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 48(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + vpaddd %xmm4,%xmm1,%xmm1 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 52(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + vpaddd %xmm7,%xmm1,%xmm1 + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm1,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 56(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm1,%xmm1 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + vpaddd 16(%ebp),%xmm1,%xmm6 + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,48(%esp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + vpalignr $4,%xmm0,%xmm1,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + vpaddd %xmm7,%xmm2,%xmm2 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + vpshufd $250,%xmm1,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 64(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + vpaddd %xmm4,%xmm2,%xmm2 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 68(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + vpaddd %xmm7,%xmm2,%xmm2 + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm2,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 72(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm2,%xmm2 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + vpaddd 32(%ebp),%xmm2,%xmm6 + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,64(%esp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + vpalignr $4,%xmm1,%xmm2,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + vpaddd %xmm7,%xmm3,%xmm3 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + vpshufd $250,%xmm2,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 80(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + vpaddd %xmm4,%xmm3,%xmm3 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 84(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + vpaddd %xmm7,%xmm3,%xmm3 + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm3,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 88(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm3,%xmm3 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + vpaddd 48(%ebp),%xmm3,%xmm6 + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,80(%esp) + cmpl $66051,64(%ebp) + jne .L013avx_00_47 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 32(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 36(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 40(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 48(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 52(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 56(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 64(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 68(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 72(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 80(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 84(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 88(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl 96(%esp),%esi + xorl %edi,%ebx + movl 12(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebx + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl %ebx,4(%esp) + xorl %edi,%ebx + movl %edi,8(%esp) + movl %ecx,12(%esp) + movl 20(%esp),%edi + movl 24(%esp),%ecx + addl 16(%esi),%edx + addl 20(%esi),%edi + addl 24(%esi),%ecx + movl %edx,16(%esi) + movl %edi,20(%esi) + movl %edi,20(%esp) + movl 28(%esp),%edi + movl %ecx,24(%esi) + addl 28(%esi),%edi + movl %ecx,24(%esp) + movl %edi,28(%esi) + movl %edi,28(%esp) + movl 100(%esp),%edi + vmovdqa 64(%ebp),%xmm7 + subl $192,%ebp + cmpl 104(%esp),%edi + jb .L012grand_avx + movl 108(%esp),%esp + vzeroall + popl %edi + popl %esi + popl %ebx + popl %ebp + ret .size sha256_block_data_order,.-.L_sha256_block_data_order_begin #endif diff --git a/linux-x86_64/crypto/bn/x86_64-mont5.S b/linux-x86_64/crypto/bn/x86_64-mont5.S index 02edc69..214064e 100644 --- a/linux-x86_64/crypto/bn/x86_64-mont5.S +++ b/linux-x86_64/crypto/bn/x86_64-mont5.S @@ -1561,6 +1561,15 @@ sqr8x_reduction: .align 32 .L8x_tail_done: addq (%rdx),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + + xorq %rax,%rax negq %rsi diff --git a/linux-x86_64/crypto/ec/p256-x86_64-asm.S b/linux-x86_64/crypto/ec/p256-x86_64-asm.S index db00544..2884c69 100644 --- a/linux-x86_64/crypto/ec/p256-x86_64-asm.S +++ b/linux-x86_64/crypto/ec/p256-x86_64-asm.S @@ -8,10 +8,6 @@ .Lpoly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 - -.LRR: -.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd - .LOne: .long 1,1,1,1,1,1,1,1 .LTwo: @@ -21,8 +17,6 @@ .LONE_mont: .quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe -.globl ecp_nistz256_mul_by_2 -.hidden ecp_nistz256_mul_by_2 .type ecp_nistz256_mul_by_2,@function .align 64 ecp_nistz256_mul_by_2: @@ -66,228 +60,6 @@ ecp_nistz256_mul_by_2: -.globl ecp_nistz256_div_by_2 -.hidden ecp_nistz256_div_by_2 -.type ecp_nistz256_div_by_2,@function -.align 32 -ecp_nistz256_div_by_2: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq %r8,%rax - movq 24(%rsi),%r11 - leaq .Lpoly(%rip),%rsi - - movq %r9,%rdx - xorq %r13,%r13 - addq 0(%rsi),%r8 - movq %r10,%rcx - adcq 8(%rsi),%r9 - adcq 16(%rsi),%r10 - movq %r11,%r12 - adcq 24(%rsi),%r11 - adcq $0,%r13 - xorq %rsi,%rsi - testq $1,%rax - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - cmovzq %rcx,%r10 - cmovzq %r12,%r11 - cmovzq %rsi,%r13 - - movq %r9,%rax - shrq $1,%r8 - shlq $63,%rax - movq %r10,%rdx - shrq $1,%r9 - orq %rax,%r8 - shlq $63,%rdx - movq %r11,%rcx - shrq $1,%r10 - orq %rdx,%r9 - shlq $63,%rcx - shrq $1,%r11 - shlq $63,%r13 - orq %rcx,%r10 - orq %r13,%r11 - - movq %r8,0(%rdi) - movq %r9,8(%rdi) - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 -.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 - - - -.globl ecp_nistz256_mul_by_3 -.hidden ecp_nistz256_mul_by_3 -.type ecp_nistz256_mul_by_3,@function -.align 32 -ecp_nistz256_mul_by_3: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - addq %r8,%r8 - movq 16(%rsi),%r10 - adcq %r9,%r9 - movq 24(%rsi),%r11 - movq %r8,%rax - adcq %r10,%r10 - adcq %r11,%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq $-1,%r8 - movq %r10,%rcx - sbbq .Lpoly+8(%rip),%r9 - sbbq $0,%r10 - movq %r11,%r12 - sbbq .Lpoly+24(%rip),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - cmovzq %rcx,%r10 - cmovzq %r12,%r11 - - xorq %r13,%r13 - addq 0(%rsi),%r8 - adcq 8(%rsi),%r9 - movq %r8,%rax - adcq 16(%rsi),%r10 - adcq 24(%rsi),%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq $-1,%r8 - movq %r10,%rcx - sbbq .Lpoly+8(%rip),%r9 - sbbq $0,%r10 - movq %r11,%r12 - sbbq .Lpoly+24(%rip),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 -.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 - - - -.globl ecp_nistz256_add -.hidden ecp_nistz256_add -.type ecp_nistz256_add,@function -.align 32 -ecp_nistz256_add: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq 24(%rsi),%r11 - leaq .Lpoly(%rip),%rsi - - addq 0(%rdx),%r8 - adcq 8(%rdx),%r9 - movq %r8,%rax - adcq 16(%rdx),%r10 - adcq 24(%rdx),%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq 0(%rsi),%r8 - movq %r10,%rcx - sbbq 8(%rsi),%r9 - sbbq 16(%rsi),%r10 - movq %r11,%r12 - sbbq 24(%rsi),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 -.size ecp_nistz256_add,.-ecp_nistz256_add - - - -.globl ecp_nistz256_sub -.hidden ecp_nistz256_sub -.type ecp_nistz256_sub,@function -.align 32 -ecp_nistz256_sub: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq 24(%rsi),%r11 - leaq .Lpoly(%rip),%rsi - - subq 0(%rdx),%r8 - sbbq 8(%rdx),%r9 - movq %r8,%rax - sbbq 16(%rdx),%r10 - sbbq 24(%rdx),%r11 - movq %r9,%rdx - sbbq $0,%r13 - - addq 0(%rsi),%r8 - movq %r10,%rcx - adcq 8(%rsi),%r9 - adcq 16(%rsi),%r10 - movq %r11,%r12 - adcq 24(%rsi),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 -.size ecp_nistz256_sub,.-ecp_nistz256_sub - - - .globl ecp_nistz256_neg .hidden ecp_nistz256_neg .type ecp_nistz256_neg,@function @@ -336,19 +108,6 @@ ecp_nistz256_neg: -.globl ecp_nistz256_to_mont -.hidden ecp_nistz256_to_mont -.type ecp_nistz256_to_mont,@function -.align 32 -ecp_nistz256_to_mont: - leaq .LRR(%rip),%rdx - jmp .Lmul_mont -.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont - - - - - .globl ecp_nistz256_mul_mont diff --git a/linux-x86_64/crypto/rc4/rc4-md5-x86_64.S b/linux-x86_64/crypto/rc4/rc4-md5-x86_64.S deleted file mode 100644 index 06c8d67..0000000 --- a/linux-x86_64/crypto/rc4/rc4-md5-x86_64.S +++ /dev/null @@ -1,1262 +0,0 @@ -#if defined(__x86_64__) -.text -.align 16 - -.globl rc4_md5_enc -.hidden rc4_md5_enc -.type rc4_md5_enc,@function -rc4_md5_enc: - cmpq $0,%r9 - je .Labort - pushq %rbx - pushq %rbp - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - subq $40,%rsp -.Lbody: - movq %rcx,%r11 - movq %r9,%r12 - movq %rsi,%r13 - movq %rdx,%r14 - movq %r8,%r15 - xorq %rbp,%rbp - xorq %rcx,%rcx - - leaq 8(%rdi),%rdi - movb -8(%rdi),%bpl - movb -4(%rdi),%cl - - incb %bpl - subq %r13,%r14 - movl (%rdi,%rbp,4),%eax - addb %al,%cl - leaq (%rdi,%rbp,4),%rsi - shlq $6,%r12 - addq %r15,%r12 - movq %r12,16(%rsp) - - movq %r11,24(%rsp) - movl 0(%r11),%r8d - movl 4(%r11),%r9d - movl 8(%r11),%r10d - movl 12(%r11),%r11d - jmp .Loop - -.align 16 -.Loop: - movl %r8d,0(%rsp) - movl %r9d,4(%rsp) - movl %r10d,8(%rsp) - movl %r11d,%r12d - movl %r11d,12(%rsp) - pxor %xmm0,%xmm0 - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 0(%r15),%r8d - addb %dl,%al - movl 4(%rsi),%ebx - addl $3614090360,%r8d - xorl %r11d,%r12d - movzbl %al,%eax - movl %edx,0(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $7,%r8d - movl %r10d,%r12d - movd (%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - pxor %xmm1,%xmm1 - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 4(%r15),%r11d - addb %dl,%bl - movl 8(%rsi),%eax - addl $3905402710,%r11d - xorl %r10d,%r12d - movzbl %bl,%ebx - movl %edx,4(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $12,%r11d - movl %r9d,%r12d - movd (%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 8(%r15),%r10d - addb %dl,%al - movl 12(%rsi),%ebx - addl $606105819,%r10d - xorl %r9d,%r12d - movzbl %al,%eax - movl %edx,8(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $17,%r10d - movl %r8d,%r12d - pinsrw $1,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 12(%r15),%r9d - addb %dl,%bl - movl 16(%rsi),%eax - addl $3250441966,%r9d - xorl %r8d,%r12d - movzbl %bl,%ebx - movl %edx,12(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $22,%r9d - movl %r11d,%r12d - pinsrw $1,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 16(%r15),%r8d - addb %dl,%al - movl 20(%rsi),%ebx - addl $4118548399,%r8d - xorl %r11d,%r12d - movzbl %al,%eax - movl %edx,16(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $7,%r8d - movl %r10d,%r12d - pinsrw $2,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 20(%r15),%r11d - addb %dl,%bl - movl 24(%rsi),%eax - addl $1200080426,%r11d - xorl %r10d,%r12d - movzbl %bl,%ebx - movl %edx,20(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $12,%r11d - movl %r9d,%r12d - pinsrw $2,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 24(%r15),%r10d - addb %dl,%al - movl 28(%rsi),%ebx - addl $2821735955,%r10d - xorl %r9d,%r12d - movzbl %al,%eax - movl %edx,24(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $17,%r10d - movl %r8d,%r12d - pinsrw $3,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 28(%r15),%r9d - addb %dl,%bl - movl 32(%rsi),%eax - addl $4249261313,%r9d - xorl %r8d,%r12d - movzbl %bl,%ebx - movl %edx,28(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $22,%r9d - movl %r11d,%r12d - pinsrw $3,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 32(%r15),%r8d - addb %dl,%al - movl 36(%rsi),%ebx - addl $1770035416,%r8d - xorl %r11d,%r12d - movzbl %al,%eax - movl %edx,32(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $7,%r8d - movl %r10d,%r12d - pinsrw $4,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 36(%r15),%r11d - addb %dl,%bl - movl 40(%rsi),%eax - addl $2336552879,%r11d - xorl %r10d,%r12d - movzbl %bl,%ebx - movl %edx,36(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $12,%r11d - movl %r9d,%r12d - pinsrw $4,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 40(%r15),%r10d - addb %dl,%al - movl 44(%rsi),%ebx - addl $4294925233,%r10d - xorl %r9d,%r12d - movzbl %al,%eax - movl %edx,40(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $17,%r10d - movl %r8d,%r12d - pinsrw $5,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 44(%r15),%r9d - addb %dl,%bl - movl 48(%rsi),%eax - addl $2304563134,%r9d - xorl %r8d,%r12d - movzbl %bl,%ebx - movl %edx,44(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $22,%r9d - movl %r11d,%r12d - pinsrw $5,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 48(%r15),%r8d - addb %dl,%al - movl 52(%rsi),%ebx - addl $1804603682,%r8d - xorl %r11d,%r12d - movzbl %al,%eax - movl %edx,48(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $7,%r8d - movl %r10d,%r12d - pinsrw $6,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 52(%r15),%r11d - addb %dl,%bl - movl 56(%rsi),%eax - addl $4254626195,%r11d - xorl %r10d,%r12d - movzbl %bl,%ebx - movl %edx,52(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $12,%r11d - movl %r9d,%r12d - pinsrw $6,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 56(%r15),%r10d - addb %dl,%al - movl 60(%rsi),%ebx - addl $2792965006,%r10d - xorl %r9d,%r12d - movzbl %al,%eax - movl %edx,56(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $17,%r10d - movl %r8d,%r12d - pinsrw $7,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movdqu (%r13),%xmm2 - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 60(%r15),%r9d - addb %dl,%bl - movl 64(%rsi),%eax - addl $1236535329,%r9d - xorl %r8d,%r12d - movzbl %bl,%ebx - movl %edx,60(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $22,%r9d - movl %r10d,%r12d - pinsrw $7,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - psllq $8,%xmm1 - pxor %xmm0,%xmm2 - pxor %xmm1,%xmm2 - pxor %xmm0,%xmm0 - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 4(%r15),%r8d - addb %dl,%al - movl 68(%rsi),%ebx - addl $4129170786,%r8d - xorl %r10d,%r12d - movzbl %al,%eax - movl %edx,64(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $5,%r8d - movl %r9d,%r12d - movd (%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - pxor %xmm1,%xmm1 - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 24(%r15),%r11d - addb %dl,%bl - movl 72(%rsi),%eax - addl $3225465664,%r11d - xorl %r9d,%r12d - movzbl %bl,%ebx - movl %edx,68(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $9,%r11d - movl %r8d,%r12d - movd (%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 44(%r15),%r10d - addb %dl,%al - movl 76(%rsi),%ebx - addl $643717713,%r10d - xorl %r8d,%r12d - movzbl %al,%eax - movl %edx,72(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $14,%r10d - movl %r11d,%r12d - pinsrw $1,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 0(%r15),%r9d - addb %dl,%bl - movl 80(%rsi),%eax - addl $3921069994,%r9d - xorl %r11d,%r12d - movzbl %bl,%ebx - movl %edx,76(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $20,%r9d - movl %r10d,%r12d - pinsrw $1,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 20(%r15),%r8d - addb %dl,%al - movl 84(%rsi),%ebx - addl $3593408605,%r8d - xorl %r10d,%r12d - movzbl %al,%eax - movl %edx,80(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $5,%r8d - movl %r9d,%r12d - pinsrw $2,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 40(%r15),%r11d - addb %dl,%bl - movl 88(%rsi),%eax - addl $38016083,%r11d - xorl %r9d,%r12d - movzbl %bl,%ebx - movl %edx,84(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $9,%r11d - movl %r8d,%r12d - pinsrw $2,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 60(%r15),%r10d - addb %dl,%al - movl 92(%rsi),%ebx - addl $3634488961,%r10d - xorl %r8d,%r12d - movzbl %al,%eax - movl %edx,88(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $14,%r10d - movl %r11d,%r12d - pinsrw $3,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 16(%r15),%r9d - addb %dl,%bl - movl 96(%rsi),%eax - addl $3889429448,%r9d - xorl %r11d,%r12d - movzbl %bl,%ebx - movl %edx,92(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $20,%r9d - movl %r10d,%r12d - pinsrw $3,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 36(%r15),%r8d - addb %dl,%al - movl 100(%rsi),%ebx - addl $568446438,%r8d - xorl %r10d,%r12d - movzbl %al,%eax - movl %edx,96(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $5,%r8d - movl %r9d,%r12d - pinsrw $4,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 56(%r15),%r11d - addb %dl,%bl - movl 104(%rsi),%eax - addl $3275163606,%r11d - xorl %r9d,%r12d - movzbl %bl,%ebx - movl %edx,100(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $9,%r11d - movl %r8d,%r12d - pinsrw $4,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 12(%r15),%r10d - addb %dl,%al - movl 108(%rsi),%ebx - addl $4107603335,%r10d - xorl %r8d,%r12d - movzbl %al,%eax - movl %edx,104(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $14,%r10d - movl %r11d,%r12d - pinsrw $5,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 32(%r15),%r9d - addb %dl,%bl - movl 112(%rsi),%eax - addl $1163531501,%r9d - xorl %r11d,%r12d - movzbl %bl,%ebx - movl %edx,108(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $20,%r9d - movl %r10d,%r12d - pinsrw $5,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 52(%r15),%r8d - addb %dl,%al - movl 116(%rsi),%ebx - addl $2850285829,%r8d - xorl %r10d,%r12d - movzbl %al,%eax - movl %edx,112(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $5,%r8d - movl %r9d,%r12d - pinsrw $6,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 8(%r15),%r11d - addb %dl,%bl - movl 120(%rsi),%eax - addl $4243563512,%r11d - xorl %r9d,%r12d - movzbl %bl,%ebx - movl %edx,116(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $9,%r11d - movl %r8d,%r12d - pinsrw $6,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 28(%r15),%r10d - addb %dl,%al - movl 124(%rsi),%ebx - addl $1735328473,%r10d - xorl %r8d,%r12d - movzbl %al,%eax - movl %edx,120(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $14,%r10d - movl %r11d,%r12d - pinsrw $7,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movdqu 16(%r13),%xmm3 - addb $32,%bpl - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 48(%r15),%r9d - addb %dl,%bl - movl 0(%rdi,%rbp,4),%eax - addl $2368359562,%r9d - xorl %r11d,%r12d - movzbl %bl,%ebx - movl %edx,124(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $20,%r9d - movl %r11d,%r12d - pinsrw $7,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movq %rcx,%rsi - xorq %rcx,%rcx - movb %sil,%cl - leaq (%rdi,%rbp,4),%rsi - psllq $8,%xmm1 - pxor %xmm0,%xmm3 - pxor %xmm1,%xmm3 - pxor %xmm0,%xmm0 - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r9d,%r12d - addl 20(%r15),%r8d - addb %dl,%al - movl 4(%rsi),%ebx - addl $4294588738,%r8d - movzbl %al,%eax - addl %r12d,%r8d - movl %edx,0(%rsi) - addb %bl,%cl - roll $4,%r8d - movl %r10d,%r12d - movd (%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - pxor %xmm1,%xmm1 - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r8d,%r12d - addl 32(%r15),%r11d - addb %dl,%bl - movl 8(%rsi),%eax - addl $2272392833,%r11d - movzbl %bl,%ebx - addl %r12d,%r11d - movl %edx,4(%rsi) - addb %al,%cl - roll $11,%r11d - movl %r9d,%r12d - movd (%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r11d,%r12d - addl 44(%r15),%r10d - addb %dl,%al - movl 12(%rsi),%ebx - addl $1839030562,%r10d - movzbl %al,%eax - addl %r12d,%r10d - movl %edx,8(%rsi) - addb %bl,%cl - roll $16,%r10d - movl %r8d,%r12d - pinsrw $1,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r10d,%r12d - addl 56(%r15),%r9d - addb %dl,%bl - movl 16(%rsi),%eax - addl $4259657740,%r9d - movzbl %bl,%ebx - addl %r12d,%r9d - movl %edx,12(%rsi) - addb %al,%cl - roll $23,%r9d - movl %r11d,%r12d - pinsrw $1,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r9d,%r12d - addl 4(%r15),%r8d - addb %dl,%al - movl 20(%rsi),%ebx - addl $2763975236,%r8d - movzbl %al,%eax - addl %r12d,%r8d - movl %edx,16(%rsi) - addb %bl,%cl - roll $4,%r8d - movl %r10d,%r12d - pinsrw $2,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r8d,%r12d - addl 16(%r15),%r11d - addb %dl,%bl - movl 24(%rsi),%eax - addl $1272893353,%r11d - movzbl %bl,%ebx - addl %r12d,%r11d - movl %edx,20(%rsi) - addb %al,%cl - roll $11,%r11d - movl %r9d,%r12d - pinsrw $2,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r11d,%r12d - addl 28(%r15),%r10d - addb %dl,%al - movl 28(%rsi),%ebx - addl $4139469664,%r10d - movzbl %al,%eax - addl %r12d,%r10d - movl %edx,24(%rsi) - addb %bl,%cl - roll $16,%r10d - movl %r8d,%r12d - pinsrw $3,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r10d,%r12d - addl 40(%r15),%r9d - addb %dl,%bl - movl 32(%rsi),%eax - addl $3200236656,%r9d - movzbl %bl,%ebx - addl %r12d,%r9d - movl %edx,28(%rsi) - addb %al,%cl - roll $23,%r9d - movl %r11d,%r12d - pinsrw $3,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r9d,%r12d - addl 52(%r15),%r8d - addb %dl,%al - movl 36(%rsi),%ebx - addl $681279174,%r8d - movzbl %al,%eax - addl %r12d,%r8d - movl %edx,32(%rsi) - addb %bl,%cl - roll $4,%r8d - movl %r10d,%r12d - pinsrw $4,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r8d,%r12d - addl 0(%r15),%r11d - addb %dl,%bl - movl 40(%rsi),%eax - addl $3936430074,%r11d - movzbl %bl,%ebx - addl %r12d,%r11d - movl %edx,36(%rsi) - addb %al,%cl - roll $11,%r11d - movl %r9d,%r12d - pinsrw $4,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r11d,%r12d - addl 12(%r15),%r10d - addb %dl,%al - movl 44(%rsi),%ebx - addl $3572445317,%r10d - movzbl %al,%eax - addl %r12d,%r10d - movl %edx,40(%rsi) - addb %bl,%cl - roll $16,%r10d - movl %r8d,%r12d - pinsrw $5,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r10d,%r12d - addl 24(%r15),%r9d - addb %dl,%bl - movl 48(%rsi),%eax - addl $76029189,%r9d - movzbl %bl,%ebx - addl %r12d,%r9d - movl %edx,44(%rsi) - addb %al,%cl - roll $23,%r9d - movl %r11d,%r12d - pinsrw $5,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r9d,%r12d - addl 36(%r15),%r8d - addb %dl,%al - movl 52(%rsi),%ebx - addl $3654602809,%r8d - movzbl %al,%eax - addl %r12d,%r8d - movl %edx,48(%rsi) - addb %bl,%cl - roll $4,%r8d - movl %r10d,%r12d - pinsrw $6,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r8d,%r12d - addl 48(%r15),%r11d - addb %dl,%bl - movl 56(%rsi),%eax - addl $3873151461,%r11d - movzbl %bl,%ebx - addl %r12d,%r11d - movl %edx,52(%rsi) - addb %al,%cl - roll $11,%r11d - movl %r9d,%r12d - pinsrw $6,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r11d,%r12d - addl 60(%r15),%r10d - addb %dl,%al - movl 60(%rsi),%ebx - addl $530742520,%r10d - movzbl %al,%eax - addl %r12d,%r10d - movl %edx,56(%rsi) - addb %bl,%cl - roll $16,%r10d - movl %r8d,%r12d - pinsrw $7,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movdqu 32(%r13),%xmm4 - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r10d,%r12d - addl 8(%r15),%r9d - addb %dl,%bl - movl 64(%rsi),%eax - addl $3299628645,%r9d - movzbl %bl,%ebx - addl %r12d,%r9d - movl %edx,60(%rsi) - addb %al,%cl - roll $23,%r9d - movl $-1,%r12d - pinsrw $7,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - psllq $8,%xmm1 - pxor %xmm0,%xmm4 - pxor %xmm1,%xmm4 - pxor %xmm0,%xmm0 - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r9d,%r12d - addl 0(%r15),%r8d - addb %dl,%al - movl 68(%rsi),%ebx - addl $4096336452,%r8d - movzbl %al,%eax - xorl %r10d,%r12d - movl %edx,64(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $6,%r8d - movl $-1,%r12d - movd (%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - pxor %xmm1,%xmm1 - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r8d,%r12d - addl 28(%r15),%r11d - addb %dl,%bl - movl 72(%rsi),%eax - addl $1126891415,%r11d - movzbl %bl,%ebx - xorl %r9d,%r12d - movl %edx,68(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $10,%r11d - movl $-1,%r12d - movd (%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r11d,%r12d - addl 56(%r15),%r10d - addb %dl,%al - movl 76(%rsi),%ebx - addl $2878612391,%r10d - movzbl %al,%eax - xorl %r8d,%r12d - movl %edx,72(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $15,%r10d - movl $-1,%r12d - pinsrw $1,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r10d,%r12d - addl 20(%r15),%r9d - addb %dl,%bl - movl 80(%rsi),%eax - addl $4237533241,%r9d - movzbl %bl,%ebx - xorl %r11d,%r12d - movl %edx,76(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $21,%r9d - movl $-1,%r12d - pinsrw $1,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r9d,%r12d - addl 48(%r15),%r8d - addb %dl,%al - movl 84(%rsi),%ebx - addl $1700485571,%r8d - movzbl %al,%eax - xorl %r10d,%r12d - movl %edx,80(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $6,%r8d - movl $-1,%r12d - pinsrw $2,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r8d,%r12d - addl 12(%r15),%r11d - addb %dl,%bl - movl 88(%rsi),%eax - addl $2399980690,%r11d - movzbl %bl,%ebx - xorl %r9d,%r12d - movl %edx,84(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $10,%r11d - movl $-1,%r12d - pinsrw $2,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r11d,%r12d - addl 40(%r15),%r10d - addb %dl,%al - movl 92(%rsi),%ebx - addl $4293915773,%r10d - movzbl %al,%eax - xorl %r8d,%r12d - movl %edx,88(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $15,%r10d - movl $-1,%r12d - pinsrw $3,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r10d,%r12d - addl 4(%r15),%r9d - addb %dl,%bl - movl 96(%rsi),%eax - addl $2240044497,%r9d - movzbl %bl,%ebx - xorl %r11d,%r12d - movl %edx,92(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $21,%r9d - movl $-1,%r12d - pinsrw $3,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r9d,%r12d - addl 32(%r15),%r8d - addb %dl,%al - movl 100(%rsi),%ebx - addl $1873313359,%r8d - movzbl %al,%eax - xorl %r10d,%r12d - movl %edx,96(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $6,%r8d - movl $-1,%r12d - pinsrw $4,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r8d,%r12d - addl 60(%r15),%r11d - addb %dl,%bl - movl 104(%rsi),%eax - addl $4264355552,%r11d - movzbl %bl,%ebx - xorl %r9d,%r12d - movl %edx,100(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $10,%r11d - movl $-1,%r12d - pinsrw $4,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r11d,%r12d - addl 24(%r15),%r10d - addb %dl,%al - movl 108(%rsi),%ebx - addl $2734768916,%r10d - movzbl %al,%eax - xorl %r8d,%r12d - movl %edx,104(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $15,%r10d - movl $-1,%r12d - pinsrw $5,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r10d,%r12d - addl 52(%r15),%r9d - addb %dl,%bl - movl 112(%rsi),%eax - addl $1309151649,%r9d - movzbl %bl,%ebx - xorl %r11d,%r12d - movl %edx,108(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $21,%r9d - movl $-1,%r12d - pinsrw $5,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r9d,%r12d - addl 16(%r15),%r8d - addb %dl,%al - movl 116(%rsi),%ebx - addl $4149444226,%r8d - movzbl %al,%eax - xorl %r10d,%r12d - movl %edx,112(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $6,%r8d - movl $-1,%r12d - pinsrw $6,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r8d,%r12d - addl 44(%r15),%r11d - addb %dl,%bl - movl 120(%rsi),%eax - addl $3174756917,%r11d - movzbl %bl,%ebx - xorl %r9d,%r12d - movl %edx,116(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $10,%r11d - movl $-1,%r12d - pinsrw $6,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r11d,%r12d - addl 8(%r15),%r10d - addb %dl,%al - movl 124(%rsi),%ebx - addl $718787259,%r10d - movzbl %al,%eax - xorl %r8d,%r12d - movl %edx,120(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $15,%r10d - movl $-1,%r12d - pinsrw $7,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movdqu 48(%r13),%xmm5 - addb $32,%bpl - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r10d,%r12d - addl 36(%r15),%r9d - addb %dl,%bl - movl 0(%rdi,%rbp,4),%eax - addl $3951481745,%r9d - movzbl %bl,%ebx - xorl %r11d,%r12d - movl %edx,124(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $21,%r9d - movl $-1,%r12d - pinsrw $7,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movq %rbp,%rsi - xorq %rbp,%rbp - movb %sil,%bpl - movq %rcx,%rsi - xorq %rcx,%rcx - movb %sil,%cl - leaq (%rdi,%rbp,4),%rsi - psllq $8,%xmm1 - pxor %xmm0,%xmm5 - pxor %xmm1,%xmm5 - addl 0(%rsp),%r8d - addl 4(%rsp),%r9d - addl 8(%rsp),%r10d - addl 12(%rsp),%r11d - - movdqu %xmm2,(%r14,%r13,1) - movdqu %xmm3,16(%r14,%r13,1) - movdqu %xmm4,32(%r14,%r13,1) - movdqu %xmm5,48(%r14,%r13,1) - leaq 64(%r15),%r15 - leaq 64(%r13),%r13 - cmpq 16(%rsp),%r15 - jb .Loop - - movq 24(%rsp),%r12 - subb %al,%cl - movl %r8d,0(%r12) - movl %r9d,4(%r12) - movl %r10d,8(%r12) - movl %r11d,12(%r12) - subb $1,%bpl - movl %ebp,-8(%rdi) - movl %ecx,-4(%rdi) - - movq 40(%rsp),%r15 - movq 48(%rsp),%r14 - movq 56(%rsp),%r13 - movq 64(%rsp),%r12 - movq 72(%rsp),%rbp - movq 80(%rsp),%rbx - leaq 88(%rsp),%rsp -.Lepilogue: -.Labort: - .byte 0xf3,0xc3 -.size rc4_md5_enc,.-rc4_md5_enc -#endif diff --git a/linux-x86_64/crypto/sha/sha1-x86_64.S b/linux-x86_64/crypto/sha/sha1-x86_64.S index 7668c2b..d830b53 100644 --- a/linux-x86_64/crypto/sha/sha1-x86_64.S +++ b/linux-x86_64/crypto/sha/sha1-x86_64.S @@ -13,6 +13,11 @@ sha1_block_data_order: movl OPENSSL_ia32cap_P+8(%rip),%r10d testl $512,%r8d jz .Lialu + andl $268435456,%r8d + andl $1073741824,%r9d + orl %r9d,%r8d + cmpl $1342177280,%r8d + je _avx_shortcut jmp _ssse3_shortcut .align 16 @@ -2408,6 +2413,1122 @@ _ssse3_shortcut: .Lepilogue_ssse3: .byte 0xf3,0xc3 .size sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3 +.type sha1_block_data_order_avx,@function +.align 16 +sha1_block_data_order_avx: +_avx_shortcut: + movq %rsp,%rax + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + leaq -64(%rsp),%rsp + vzeroupper + movq %rax,%r14 + andq $-64,%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r11 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + vmovdqa 64(%r11),%xmm6 + vmovdqa -64(%r11),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm11,%xmm0,%xmm4 + vpaddd %xmm11,%xmm1,%xmm5 + vpaddd %xmm11,%xmm2,%xmm6 + vmovdqa %xmm4,0(%rsp) + vmovdqa %xmm5,16(%rsp) + vmovdqa %xmm6,32(%rsp) + jmp .Loop_avx +.align 16 +.Loop_avx: + shrdl $2,%ebx,%ebx + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%edi + addl 0(%rsp),%ebp + vpaddd %xmm3,%xmm11,%xmm9 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm8 + addl %esi,%ebp + andl %ebx,%edi + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%ebp + vpxor %xmm2,%xmm8,%xmm8 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + vpxor %xmm8,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vmovdqa %xmm9,48(%rsp) + addl %edi,%edx + andl %eax,%esi + vpsrld $31,%xmm4,%xmm8 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm10 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%edi + addl 8(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm4,%xmm4 + addl %esi,%ecx + andl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm4,%xmm4 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + vpxor %xmm10,%xmm4,%xmm4 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %edi,%ebx + andl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%edi + addl 16(%rsp),%eax + vpaddd %xmm4,%xmm11,%xmm9 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm8 + addl %esi,%eax + andl %ecx,%edi + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm8,%xmm8 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + vpxor %xmm8,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vmovdqa %xmm9,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm8 + xorl %ecx,%ebx + addl %eax,%ebp + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm10 + vpaddd %xmm5,%xmm5,%xmm5 + movl %ebp,%edi + addl 24(%rsp),%edx + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm5,%xmm5 + addl %esi,%edx + andl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm5,%xmm5 + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + vpxor %xmm10,%xmm5,%xmm5 + xorl %eax,%ebp + shldl $5,%edx,%edx + vmovdqa -32(%r11),%xmm11 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%edi + addl 32(%rsp),%ebx + vpaddd %xmm5,%xmm11,%xmm9 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm8 + addl %esi,%ebx + andl %edx,%edi + vpxor %xmm2,%xmm6,%xmm6 + xorl %ebp,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm8,%xmm8 + shrdl $7,%ecx,%ecx + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + vpxor %xmm8,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vmovdqa %xmm9,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm8 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm10 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%edi + addl 40(%rsp),%ebp + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm6,%xmm6 + addl %esi,%ebp + andl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + vpxor %xmm10,%xmm6,%xmm6 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + addl %edi,%edx + andl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%edi + addl 48(%rsp),%ecx + vpaddd %xmm6,%xmm11,%xmm9 + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm8 + addl %esi,%ecx + andl %ebp,%edi + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%ebp + addl %edx,%ecx + vpxor %xmm5,%xmm8,%xmm8 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + vpxor %xmm8,%xmm7,%xmm7 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vmovdqa %xmm9,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm8 + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpslldq $12,%xmm7,%xmm10 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%edi + addl 56(%rsp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm7,%xmm7 + addl %esi,%eax + andl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + vpxor %xmm10,%xmm7,%xmm7 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %edi,%ebp + andl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + vpxor %xmm1,%xmm0,%xmm0 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpaddd %xmm7,%xmm11,%xmm9 + addl %esi,%edx + andl %eax,%edi + vpxor %xmm8,%xmm0,%xmm0 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + movl %edx,%esi + addl 4(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + vpor %xmm8,%xmm0,%xmm0 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm0,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm1,%xmm1 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm1,%xmm1 + addl 28(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + addl %esi,%eax + xorl %edx,%edi + vpaddd %xmm1,%xmm11,%xmm9 + vmovdqa 0(%r11),%xmm11 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm8,%xmm2,%xmm2 + addl 36(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpslld $2,%xmm2,%xmm2 + addl 40(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpor %xmm8,%xmm2,%xmm2 + addl 44(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebx + xorl %ebp,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpalignr $8,%xmm2,%xmm3,%xmm8 + vpxor %xmm0,%xmm4,%xmm4 + addl 0(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + addl %esi,%ecx + xorl %eax,%edi + vpaddd %xmm3,%xmm11,%xmm9 + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpxor %xmm8,%xmm4,%xmm4 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm8 + vmovdqa %xmm9,48(%rsp) + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm8,%xmm4,%xmm4 + addl 12(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm3,%xmm4,%xmm8 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpxor %xmm6,%xmm5,%xmm5 + addl %esi,%edx + xorl %ebx,%edi + vpaddd %xmm4,%xmm11,%xmm9 + shrdl $7,%eax,%eax + addl %ebp,%edx + vpxor %xmm8,%xmm5,%xmm5 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm8,%xmm5,%xmm5 + addl 28(%rsp),%eax + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm8 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + movl %eax,%edi + xorl %ecx,%esi + vpaddd %xmm5,%xmm11,%xmm9 + shldl $5,%eax,%eax + addl %esi,%ebp + vpxor %xmm8,%xmm6,%xmm6 + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 36(%rsp),%edx + vpsrld $30,%xmm6,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + addl 40(%rsp),%ecx + andl %eax,%esi + vpor %xmm8,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%edi + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm8 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + movl %ebx,%edi + xorl %edx,%esi + vpaddd %xmm6,%xmm11,%xmm9 + vmovdqa 32(%r11),%xmm11 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm8,%xmm7,%xmm7 + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%rsp),%ebp + vpsrld $30,%xmm7,%xmm8 + vmovdqa %xmm9,32(%rsp) + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + addl 56(%rsp),%edx + andl %ebx,%esi + vpor %xmm8,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%edi + xorl %ebx,%esi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + shrdl $7,%edx,%edx + vpxor %xmm1,%xmm0,%xmm0 + movl %ecx,%edi + xorl %ebp,%esi + vpaddd %xmm7,%xmm11,%xmm9 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm8,%xmm0,%xmm0 + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 4(%rsp),%eax + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%rsp),%ebp + andl %ecx,%esi + vpor %xmm8,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%edi + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + vpxor %xmm2,%xmm1,%xmm1 + movl %edx,%edi + xorl %eax,%esi + vpaddd %xmm0,%xmm11,%xmm9 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 20(%rsp),%ebx + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + addl 24(%rsp),%eax + andl %edx,%esi + vpor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%edi + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + movl %ebp,%edi + xorl %ebx,%esi + vpaddd %xmm1,%xmm11,%xmm9 + shldl $5,%ebp,%ebp + addl %esi,%edx + vpxor %xmm8,%xmm2,%xmm2 + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 36(%rsp),%ecx + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + addl 40(%rsp),%ebx + andl %ebp,%esi + vpor %xmm8,%xmm2,%xmm2 + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%edi + xorl %ebp,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + vpaddd %xmm3,%xmm11,%xmm9 + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm9,48(%rsp) + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + cmpq %r10,%r9 + je .Ldone_avx + vmovdqa 64(%r11),%xmm6 + vmovdqa -64(%r11),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %ebp,%esi + vpshufb %xmm6,%xmm1,%xmm1 + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpaddd %xmm11,%xmm0,%xmm4 + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm4,0(%rsp) + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + vpshufb %xmm6,%xmm2,%xmm2 + movl %edx,%edi + shldl $5,%edx,%edx + vpaddd %xmm11,%xmm1,%xmm5 + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vmovdqa %xmm5,16(%rsp) + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + vpshufb %xmm6,%xmm3,%xmm3 + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpaddd %xmm11,%xmm2,%xmm6 + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vmovdqa %xmm6,32(%rsp) + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %ecx,%edi + movl %edx,12(%r8) + xorl %edx,%edi + movl %ebp,16(%r8) + andl %edi,%esi + jmp .Loop_avx + +.align 16 +.Ldone_avx: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vzeroupper + + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + leaq (%r14),%rsi + movq -40(%rsi),%r14 + movq -32(%rsi),%r13 + movq -24(%rsi),%r12 + movq -16(%rsi),%rbp + movq -8(%rsi),%rbx + leaq (%rsi),%rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.size sha1_block_data_order_avx,.-sha1_block_data_order_avx .align 64 K_XX_XX: .long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 diff --git a/linux-x86_64/crypto/sha/sha256-x86_64.S b/linux-x86_64/crypto/sha/sha256-x86_64.S index f526de5..445b497 100644 --- a/linux-x86_64/crypto/sha/sha256-x86_64.S +++ b/linux-x86_64/crypto/sha/sha256-x86_64.S @@ -12,6 +12,11 @@ sha256_block_data_order: movl 0(%r11),%r9d movl 4(%r11),%r10d movl 8(%r11),%r11d + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je .Lavx_shortcut testl $512,%r10d jnz .Lssse3_shortcut pushq %rbx @@ -2841,4 +2846,1061 @@ sha256_block_data_order_ssse3: .Lepilogue_ssse3: .byte 0xf3,0xc3 .size sha256_block_data_order_ssse3,.-sha256_block_data_order_ssse3 +.type sha256_block_data_order_avx,@function +.align 64 +sha256_block_data_order_avx: +.Lavx_shortcut: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $96,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %r11,64+24(%rsp) +.Lprologue_avx: + + vzeroupper + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + vmovdqa K256+512+32(%rip),%xmm8 + vmovdqa K256+512+64(%rip),%xmm9 + jmp .Lloop_avx +.align 16 +.Lloop_avx: + vmovdqa K256+512(%rip),%xmm7 + vmovdqu 0(%rsi),%xmm0 + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm7,%xmm0,%xmm0 + leaq K256(%rip),%rbp + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd 0(%rbp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 32(%rbp),%xmm1,%xmm5 + vpaddd 64(%rbp),%xmm2,%xmm6 + vpaddd 96(%rbp),%xmm3,%xmm7 + vmovdqa %xmm4,0(%rsp) + movl %eax,%r14d + vmovdqa %xmm5,16(%rsp) + movl %ebx,%edi + vmovdqa %xmm6,32(%rsp) + xorl %ecx,%edi + vmovdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp .Lavx_00_47 + +.align 16 +.Lavx_00_47: + subq $-128,%rbp + vpalignr $4,%xmm0,%xmm1,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm2,%xmm3,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm0,%xmm0 + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm3,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm0,%xmm0 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm0,%xmm0 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + vpshufd $80,%xmm0,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm0,%xmm0 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 0(%rbp),%xmm0,%xmm6 + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,0(%rsp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm3,%xmm0,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm1,%xmm1 + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm0,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm1,%xmm1 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm1,%xmm1 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + vpshufd $80,%xmm1,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm1,%xmm1 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 32(%rbp),%xmm1,%xmm6 + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,16(%rsp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm0,%xmm1,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm2,%xmm2 + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm1,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm2,%xmm2 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm2,%xmm2 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + vpshufd $80,%xmm2,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm2,%xmm2 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 64(%rbp),%xmm2,%xmm6 + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,32(%rsp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm1,%xmm2,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm3,%xmm3 + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm2,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm3,%xmm3 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm3,%xmm3 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + vpshufd $80,%xmm3,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm3,%xmm3 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 96(%rbp),%xmm3,%xmm6 + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,48(%rsp) + cmpb $0,131(%rbp) + jne .Lavx_00_47 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%rdi + movl %r14d,%eax + + addl 0(%rdi),%eax + leaq 64(%rsi),%rsi + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb .Lloop_avx + + movq 64+24(%rsp),%rsi + vzeroupper + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.size sha256_block_data_order_avx,.-sha256_block_data_order_avx #endif diff --git a/linux-x86_64/crypto/sha/sha512-x86_64.S b/linux-x86_64/crypto/sha/sha512-x86_64.S index ca3a3a1..d65743f 100644 --- a/linux-x86_64/crypto/sha/sha512-x86_64.S +++ b/linux-x86_64/crypto/sha/sha512-x86_64.S @@ -8,6 +8,17 @@ .type sha512_block_data_order,@function .align 16 sha512_block_data_order: + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl 0(%r11),%r9d + movl 4(%r11),%r10d + movl 8(%r11),%r11d + testl $2048,%r10d + jnz .Lxop_shortcut + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je .Lavx_shortcut pushq %rbx pushq %rbp pushq %r12 @@ -1784,4 +1795,2234 @@ K512: .quad 0x0001020304050607,0x08090a0b0c0d0e0f .quad 0x0001020304050607,0x08090a0b0c0d0e0f .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.type sha512_block_data_order_xop,@function +.align 64 +sha512_block_data_order_xop: +.Lxop_shortcut: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $160,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %r11,128+24(%rsp) +.Lprologue_xop: + + vzeroupper + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Lloop_xop +.align 16 +.Lloop_xop: + vmovdqa K512+1280(%rip),%xmm11 + vmovdqu 0(%rsi),%xmm0 + leaq K512+128(%rip),%rbp + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vpshufb %xmm11,%xmm0,%xmm0 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm11,%xmm1,%xmm1 + vmovdqu 64(%rsi),%xmm4 + vpshufb %xmm11,%xmm2,%xmm2 + vmovdqu 80(%rsi),%xmm5 + vpshufb %xmm11,%xmm3,%xmm3 + vmovdqu 96(%rsi),%xmm6 + vpshufb %xmm11,%xmm4,%xmm4 + vmovdqu 112(%rsi),%xmm7 + vpshufb %xmm11,%xmm5,%xmm5 + vpaddq -128(%rbp),%xmm0,%xmm8 + vpshufb %xmm11,%xmm6,%xmm6 + vpaddq -96(%rbp),%xmm1,%xmm9 + vpshufb %xmm11,%xmm7,%xmm7 + vpaddq -64(%rbp),%xmm2,%xmm10 + vpaddq -32(%rbp),%xmm3,%xmm11 + vmovdqa %xmm8,0(%rsp) + vpaddq 0(%rbp),%xmm4,%xmm8 + vmovdqa %xmm9,16(%rsp) + vpaddq 32(%rbp),%xmm5,%xmm9 + vmovdqa %xmm10,32(%rsp) + vpaddq 64(%rbp),%xmm6,%xmm10 + vmovdqa %xmm11,48(%rsp) + vpaddq 96(%rbp),%xmm7,%xmm11 + vmovdqa %xmm8,64(%rsp) + movq %rax,%r14 + vmovdqa %xmm9,80(%rsp) + movq %rbx,%rdi + vmovdqa %xmm10,96(%rsp) + xorq %rcx,%rdi + vmovdqa %xmm11,112(%rsp) + movq %r8,%r13 + jmp .Lxop_00_47 + +.align 16 +.Lxop_00_47: + addq $256,%rbp + vpalignr $8,%xmm0,%xmm1,%xmm8 + rorq $23,%r13 + movq %r14,%rax + vpalignr $8,%xmm4,%xmm5,%xmm11 + movq %r9,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r8,%r13 + xorq %r10,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rax,%r14 + vpaddq %xmm11,%xmm0,%xmm0 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 +.byte 143,72,120,195,209,7 + xorq %r10,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,223,3 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm7,%xmm10 + addq %r11,%rdx + addq %rdi,%r11 + vpaddq %xmm8,%xmm0,%xmm0 + movq %rdx,%r13 + addq %r11,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r11 + vpxor %xmm10,%xmm11,%xmm11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + vpaddq %xmm11,%xmm0,%xmm0 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + vpaddq -128(%rbp),%xmm0,%xmm10 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,0(%rsp) + vpalignr $8,%xmm1,%xmm2,%xmm8 + rorq $23,%r13 + movq %r14,%r10 + vpalignr $8,%xmm5,%xmm6,%xmm11 + movq %rdx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rcx,%r13 + xorq %r8,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r10,%r14 + vpaddq %xmm11,%xmm1,%xmm1 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 +.byte 143,72,120,195,209,7 + xorq %r8,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,216,3 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm0,%xmm10 + addq %r9,%rbx + addq %rdi,%r9 + vpaddq %xmm8,%xmm1,%xmm1 + movq %rbx,%r13 + addq %r9,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r9 + vpxor %xmm10,%xmm11,%xmm11 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + vpaddq %xmm11,%xmm1,%xmm1 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + vpaddq -96(%rbp),%xmm1,%xmm10 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,16(%rsp) + vpalignr $8,%xmm2,%xmm3,%xmm8 + rorq $23,%r13 + movq %r14,%r8 + vpalignr $8,%xmm6,%xmm7,%xmm11 + movq %rbx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rax,%r13 + xorq %rcx,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r8,%r14 + vpaddq %xmm11,%xmm2,%xmm2 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 +.byte 143,72,120,195,209,7 + xorq %rcx,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,217,3 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm1,%xmm10 + addq %rdx,%r11 + addq %rdi,%rdx + vpaddq %xmm8,%xmm2,%xmm2 + movq %r11,%r13 + addq %rdx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rdx + vpxor %xmm10,%xmm11,%xmm11 + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + vpaddq %xmm11,%xmm2,%xmm2 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + vpaddq -64(%rbp),%xmm2,%xmm10 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,32(%rsp) + vpalignr $8,%xmm3,%xmm4,%xmm8 + rorq $23,%r13 + movq %r14,%rcx + vpalignr $8,%xmm7,%xmm0,%xmm11 + movq %r11,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r10,%r13 + xorq %rax,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rcx,%r14 + vpaddq %xmm11,%xmm3,%xmm3 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 +.byte 143,72,120,195,209,7 + xorq %rax,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,218,3 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm2,%xmm10 + addq %rbx,%r9 + addq %rdi,%rbx + vpaddq %xmm8,%xmm3,%xmm3 + movq %r9,%r13 + addq %rbx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rbx + vpxor %xmm10,%xmm11,%xmm11 + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + vpaddq %xmm11,%xmm3,%xmm3 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + vpaddq -32(%rbp),%xmm3,%xmm10 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,48(%rsp) + vpalignr $8,%xmm4,%xmm5,%xmm8 + rorq $23,%r13 + movq %r14,%rax + vpalignr $8,%xmm0,%xmm1,%xmm11 + movq %r9,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r8,%r13 + xorq %r10,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rax,%r14 + vpaddq %xmm11,%xmm4,%xmm4 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 +.byte 143,72,120,195,209,7 + xorq %r10,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,219,3 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm3,%xmm10 + addq %r11,%rdx + addq %rdi,%r11 + vpaddq %xmm8,%xmm4,%xmm4 + movq %rdx,%r13 + addq %r11,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r11 + vpxor %xmm10,%xmm11,%xmm11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + vpaddq %xmm11,%xmm4,%xmm4 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + vpaddq 0(%rbp),%xmm4,%xmm10 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,64(%rsp) + vpalignr $8,%xmm5,%xmm6,%xmm8 + rorq $23,%r13 + movq %r14,%r10 + vpalignr $8,%xmm1,%xmm2,%xmm11 + movq %rdx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rcx,%r13 + xorq %r8,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r10,%r14 + vpaddq %xmm11,%xmm5,%xmm5 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 +.byte 143,72,120,195,209,7 + xorq %r8,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,220,3 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm4,%xmm10 + addq %r9,%rbx + addq %rdi,%r9 + vpaddq %xmm8,%xmm5,%xmm5 + movq %rbx,%r13 + addq %r9,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r9 + vpxor %xmm10,%xmm11,%xmm11 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + vpaddq %xmm11,%xmm5,%xmm5 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + vpaddq 32(%rbp),%xmm5,%xmm10 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,80(%rsp) + vpalignr $8,%xmm6,%xmm7,%xmm8 + rorq $23,%r13 + movq %r14,%r8 + vpalignr $8,%xmm2,%xmm3,%xmm11 + movq %rbx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rax,%r13 + xorq %rcx,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r8,%r14 + vpaddq %xmm11,%xmm6,%xmm6 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 +.byte 143,72,120,195,209,7 + xorq %rcx,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,221,3 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm5,%xmm10 + addq %rdx,%r11 + addq %rdi,%rdx + vpaddq %xmm8,%xmm6,%xmm6 + movq %r11,%r13 + addq %rdx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rdx + vpxor %xmm10,%xmm11,%xmm11 + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + vpaddq %xmm11,%xmm6,%xmm6 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + vpaddq 64(%rbp),%xmm6,%xmm10 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,96(%rsp) + vpalignr $8,%xmm7,%xmm0,%xmm8 + rorq $23,%r13 + movq %r14,%rcx + vpalignr $8,%xmm3,%xmm4,%xmm11 + movq %r11,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r10,%r13 + xorq %rax,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rcx,%r14 + vpaddq %xmm11,%xmm7,%xmm7 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 +.byte 143,72,120,195,209,7 + xorq %rax,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,222,3 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm6,%xmm10 + addq %rbx,%r9 + addq %rdi,%rbx + vpaddq %xmm8,%xmm7,%xmm7 + movq %r9,%r13 + addq %rbx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rbx + vpxor %xmm10,%xmm11,%xmm11 + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + vpaddq %xmm11,%xmm7,%xmm7 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + vpaddq 96(%rbp),%xmm7,%xmm10 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,112(%rsp) + cmpb $0,135(%rbp) + jne .Lxop_00_47 + rorq $23,%r13 + movq %r14,%rax + movq %r9,%r12 + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + rorq $4,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + rorq $6,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + rorq $28,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + rorq $23,%r13 + movq %r14,%r11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + rorq $23,%r13 + movq %r14,%r10 + movq %rdx,%r12 + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + rorq $4,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + rorq $6,%r14 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + rorq $28,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + rorq $23,%r13 + movq %r14,%r9 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + rorq $23,%r13 + movq %r14,%r8 + movq %rbx,%r12 + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + rorq $4,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + rorq $6,%r14 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + rorq $28,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + rorq $23,%r13 + movq %r14,%rdx + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + rorq $23,%r13 + movq %r14,%rcx + movq %r11,%r12 + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + rorq $4,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + rorq $6,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + rorq $28,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + rorq $23,%r13 + movq %r14,%rbx + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + rorq $23,%r13 + movq %r14,%rax + movq %r9,%r12 + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + rorq $4,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + rorq $6,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + rorq $28,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + rorq $23,%r13 + movq %r14,%r11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + rorq $23,%r13 + movq %r14,%r10 + movq %rdx,%r12 + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + rorq $4,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + rorq $6,%r14 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + rorq $28,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + rorq $23,%r13 + movq %r14,%r9 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + rorq $23,%r13 + movq %r14,%r8 + movq %rbx,%r12 + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + rorq $4,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + rorq $6,%r14 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + rorq $28,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + rorq $23,%r13 + movq %r14,%rdx + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + rorq $23,%r13 + movq %r14,%rcx + movq %r11,%r12 + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + rorq $4,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + rorq $6,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + rorq $28,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + rorq $23,%r13 + movq %r14,%rbx + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + movq 128+0(%rsp),%rdi + movq %r14,%rax + + addq 0(%rdi),%rax + leaq 128(%rsi),%rsi + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb .Lloop_xop + + movq 128+24(%rsp),%rsi + vzeroupper + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lepilogue_xop: + .byte 0xf3,0xc3 +.size sha512_block_data_order_xop,.-sha512_block_data_order_xop +.type sha512_block_data_order_avx,@function +.align 64 +sha512_block_data_order_avx: +.Lavx_shortcut: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $160,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %r11,128+24(%rsp) +.Lprologue_avx: + + vzeroupper + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Lloop_avx +.align 16 +.Lloop_avx: + vmovdqa K512+1280(%rip),%xmm11 + vmovdqu 0(%rsi),%xmm0 + leaq K512+128(%rip),%rbp + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vpshufb %xmm11,%xmm0,%xmm0 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm11,%xmm1,%xmm1 + vmovdqu 64(%rsi),%xmm4 + vpshufb %xmm11,%xmm2,%xmm2 + vmovdqu 80(%rsi),%xmm5 + vpshufb %xmm11,%xmm3,%xmm3 + vmovdqu 96(%rsi),%xmm6 + vpshufb %xmm11,%xmm4,%xmm4 + vmovdqu 112(%rsi),%xmm7 + vpshufb %xmm11,%xmm5,%xmm5 + vpaddq -128(%rbp),%xmm0,%xmm8 + vpshufb %xmm11,%xmm6,%xmm6 + vpaddq -96(%rbp),%xmm1,%xmm9 + vpshufb %xmm11,%xmm7,%xmm7 + vpaddq -64(%rbp),%xmm2,%xmm10 + vpaddq -32(%rbp),%xmm3,%xmm11 + vmovdqa %xmm8,0(%rsp) + vpaddq 0(%rbp),%xmm4,%xmm8 + vmovdqa %xmm9,16(%rsp) + vpaddq 32(%rbp),%xmm5,%xmm9 + vmovdqa %xmm10,32(%rsp) + vpaddq 64(%rbp),%xmm6,%xmm10 + vmovdqa %xmm11,48(%rsp) + vpaddq 96(%rbp),%xmm7,%xmm11 + vmovdqa %xmm8,64(%rsp) + movq %rax,%r14 + vmovdqa %xmm9,80(%rsp) + movq %rbx,%rdi + vmovdqa %xmm10,96(%rsp) + xorq %rcx,%rdi + vmovdqa %xmm11,112(%rsp) + movq %r8,%r13 + jmp .Lavx_00_47 + +.align 16 +.Lavx_00_47: + addq $256,%rbp + vpalignr $8,%xmm0,%xmm1,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm4,%xmm5,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm0,%xmm0 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 0(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm7,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm7,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm0,%xmm0 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm7,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 8(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm0,%xmm0 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq -128(%rbp),%xmm0,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,0(%rsp) + vpalignr $8,%xmm1,%xmm2,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm5,%xmm6,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm1,%xmm1 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 16(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm0,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm0,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm1,%xmm1 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm0,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 24(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm1,%xmm1 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq -96(%rbp),%xmm1,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,16(%rsp) + vpalignr $8,%xmm2,%xmm3,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm6,%xmm7,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm2,%xmm2 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 32(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm1,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm1,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm2,%xmm2 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm1,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 40(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm2,%xmm2 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq -64(%rbp),%xmm2,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,32(%rsp) + vpalignr $8,%xmm3,%xmm4,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm7,%xmm0,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm3,%xmm3 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 48(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm2,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm2,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm3,%xmm3 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm2,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 56(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm3,%xmm3 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq -32(%rbp),%xmm3,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,48(%rsp) + vpalignr $8,%xmm4,%xmm5,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm0,%xmm1,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm4,%xmm4 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 64(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm3,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm3,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm4,%xmm4 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm3,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 72(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm4,%xmm4 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq 0(%rbp),%xmm4,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,64(%rsp) + vpalignr $8,%xmm5,%xmm6,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm1,%xmm2,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm5,%xmm5 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 80(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm4,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm4,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm5,%xmm5 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm4,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 88(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm5,%xmm5 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq 32(%rbp),%xmm5,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,80(%rsp) + vpalignr $8,%xmm6,%xmm7,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm2,%xmm3,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm6,%xmm6 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 96(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm5,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm5,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm6,%xmm6 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm5,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 104(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm6,%xmm6 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq 64(%rbp),%xmm6,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,96(%rsp) + vpalignr $8,%xmm7,%xmm0,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm3,%xmm4,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm7,%xmm7 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 112(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm6,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm6,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm7,%xmm7 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm6,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 120(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm7,%xmm7 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq 96(%rbp),%xmm7,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,112(%rsp) + cmpb $0,135(%rbp) + jne .Lavx_00_47 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + movq 128+0(%rsp),%rdi + movq %r14,%rax + + addq 0(%rdi),%rax + leaq 128(%rsi),%rsi + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb .Lloop_avx + + movq 128+24(%rsp),%rsi + vzeroupper + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.size sha512_block_data_order_avx,.-sha512_block_data_order_avx #endif diff --git a/mac-x86/crypto/sha/sha1-586.S b/mac-x86/crypto/sha/sha1-586.S index f880e7e..72a7205 100644 --- a/mac-x86/crypto/sha/sha1-586.S +++ b/mac-x86/crypto/sha/sha1-586.S @@ -22,6 +22,11 @@ L000pic_point: movl 8(%esi),%ecx testl $16777216,%eax jz L001x86 + andl $268435456,%edx + andl $1073741824,%eax + orl %edx,%eax + cmpl $1342177280,%eax + je Lavx_shortcut jmp Lssse3_shortcut .align 4,0x90 L001x86: @@ -2607,6 +2612,1175 @@ L005done: popl %ebx popl %ebp ret +.private_extern __sha1_block_data_order_avx +.align 4 +__sha1_block_data_order_avx: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + call L006pic_point +L006pic_point: + popl %ebp + leal LK_XX_XX-L006pic_point(%ebp),%ebp +Lavx_shortcut: + vzeroall + vmovdqa (%ebp),%xmm7 + vmovdqa 16(%ebp),%xmm0 + vmovdqa 32(%ebp),%xmm1 + vmovdqa 48(%ebp),%xmm2 + vmovdqa 64(%ebp),%xmm6 + movl 20(%esp),%edi + movl 24(%esp),%ebp + movl 28(%esp),%edx + movl %esp,%esi + subl $208,%esp + andl $-64,%esp + vmovdqa %xmm0,112(%esp) + vmovdqa %xmm1,128(%esp) + vmovdqa %xmm2,144(%esp) + shll $6,%edx + vmovdqa %xmm7,160(%esp) + addl %ebp,%edx + vmovdqa %xmm6,176(%esp) + addl $64,%ebp + movl %edi,192(%esp) + movl %ebp,196(%esp) + movl %edx,200(%esp) + movl %esi,204(%esp) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl 16(%edi),%edi + movl %ebx,%esi + vmovdqu -64(%ebp),%xmm0 + vmovdqu -48(%ebp),%xmm1 + vmovdqu -32(%ebp),%xmm2 + vmovdqu -16(%ebp),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vmovdqa %xmm7,96(%esp) + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm7,%xmm0,%xmm4 + vpaddd %xmm7,%xmm1,%xmm5 + vpaddd %xmm7,%xmm2,%xmm6 + vmovdqa %xmm4,(%esp) + movl %ecx,%ebp + vmovdqa %xmm5,16(%esp) + xorl %edx,%ebp + vmovdqa %xmm6,32(%esp) + andl %ebp,%esi + jmp L007loop +.align 4,0x90 +L007loop: + shrdl $2,%ebx,%ebx + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%ebp + addl (%esp),%edi + vpaddd %xmm3,%xmm7,%xmm7 + vmovdqa %xmm0,64(%esp) + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm6 + addl %esi,%edi + andl %ebx,%ebp + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%edi + vpxor %xmm2,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%ebp + vmovdqa %xmm7,48(%esp) + movl %edi,%esi + addl 4(%esp),%edx + vpxor %xmm6,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%edi,%edi + addl %ebp,%edx + andl %eax,%esi + vpsrld $31,%xmm4,%xmm6 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm0 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%ebp + addl 8(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpsrld $30,%xmm0,%xmm7 + vpor %xmm6,%xmm4,%xmm4 + addl %esi,%ecx + andl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + vpslld $2,%xmm0,%xmm0 + shrdl $7,%edx,%edx + xorl %eax,%ebp + vpxor %xmm7,%xmm4,%xmm4 + movl %ecx,%esi + addl 12(%esp),%ebx + xorl %edi,%edx + shldl $5,%ecx,%ecx + vpxor %xmm0,%xmm4,%xmm4 + addl %ebp,%ebx + andl %edx,%esi + vmovdqa 96(%esp),%xmm0 + xorl %edi,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %edi,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%ebp + addl 16(%esp),%eax + vpaddd %xmm4,%xmm0,%xmm0 + vmovdqa %xmm1,80(%esp) + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm7 + addl %esi,%eax + andl %ecx,%ebp + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + xorl %edx,%ebp + vmovdqa %xmm0,(%esp) + movl %eax,%esi + addl 20(%esp),%edi + vpxor %xmm7,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %ebp,%edi + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm7 + xorl %ecx,%ebx + addl %eax,%edi + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm1 + vpaddd %xmm5,%xmm5,%xmm5 + movl %edi,%ebp + addl 24(%esp),%edx + xorl %ebx,%eax + shldl $5,%edi,%edi + vpsrld $30,%xmm1,%xmm0 + vpor %xmm7,%xmm5,%xmm5 + addl %esi,%edx + andl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + vpslld $2,%xmm1,%xmm1 + shrdl $7,%edi,%edi + xorl %ebx,%ebp + vpxor %xmm0,%xmm5,%xmm5 + movl %edx,%esi + addl 28(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpxor %xmm1,%xmm5,%xmm5 + addl %ebp,%ecx + andl %edi,%esi + vmovdqa 112(%esp),%xmm1 + xorl %eax,%edi + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%ebp + addl 32(%esp),%ebx + vpaddd %xmm5,%xmm1,%xmm1 + vmovdqa %xmm2,96(%esp) + xorl %edi,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm0 + addl %esi,%ebx + andl %edx,%ebp + vpxor %xmm2,%xmm6,%xmm6 + xorl %edi,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%ecx,%ecx + xorl %edi,%ebp + vmovdqa %xmm1,16(%esp) + movl %ebx,%esi + addl 36(%esp),%eax + vpxor %xmm0,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + addl %ebp,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm0 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm2 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%ebp + addl 40(%esp),%edi + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm1 + vpor %xmm0,%xmm6,%xmm6 + addl %esi,%edi + andl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + vpslld $2,%xmm2,%xmm2 + vmovdqa 64(%esp),%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%ebp + vpxor %xmm1,%xmm6,%xmm6 + movl %edi,%esi + addl 44(%esp),%edx + xorl %ebx,%eax + shldl $5,%edi,%edi + vpxor %xmm2,%xmm6,%xmm6 + addl %ebp,%edx + andl %eax,%esi + vmovdqa 112(%esp),%xmm2 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%ebp + addl 48(%esp),%ecx + vpaddd %xmm6,%xmm2,%xmm2 + vmovdqa %xmm3,64(%esp) + xorl %eax,%edi + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm1 + addl %esi,%ecx + andl %edi,%ebp + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%edi + addl %edx,%ecx + vpxor %xmm5,%xmm1,%xmm1 + shrdl $7,%edx,%edx + xorl %eax,%ebp + vmovdqa %xmm2,32(%esp) + movl %ecx,%esi + addl 52(%esp),%ebx + vpxor %xmm1,%xmm7,%xmm7 + xorl %edi,%edx + shldl $5,%ecx,%ecx + addl %ebp,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm1 + xorl %edi,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %edi,%esi + vpslldq $12,%xmm7,%xmm3 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%ebp + addl 56(%esp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm2 + vpor %xmm1,%xmm7,%xmm7 + addl %esi,%eax + andl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + vmovdqa 80(%esp),%xmm1 + shrdl $7,%ebx,%ebx + xorl %edx,%ebp + vpxor %xmm2,%xmm7,%xmm7 + movl %eax,%esi + addl 60(%esp),%edi + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpxor %xmm3,%xmm7,%xmm7 + addl %ebp,%edi + andl %ebx,%esi + vmovdqa 112(%esp),%xmm3 + xorl %ecx,%ebx + addl %eax,%edi + vpalignr $8,%xmm6,%xmm7,%xmm2 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %edi,%ebp + addl (%esp),%edx + vpxor %xmm1,%xmm0,%xmm0 + vmovdqa %xmm4,80(%esp) + xorl %ebx,%eax + shldl $5,%edi,%edi + vmovdqa %xmm3,%xmm4 + vpaddd %xmm7,%xmm3,%xmm3 + addl %esi,%edx + andl %eax,%ebp + vpxor %xmm2,%xmm0,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%ebp + vpsrld $30,%xmm0,%xmm2 + vmovdqa %xmm3,48(%esp) + movl %edx,%esi + addl 4(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %ebp,%ecx + andl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%ebp + addl 8(%esp),%ebx + vpor %xmm2,%xmm0,%xmm0 + xorl %edi,%edx + shldl $5,%ecx,%ecx + vmovdqa 96(%esp),%xmm2 + addl %esi,%ebx + andl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 12(%esp),%eax + xorl %edi,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm3 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm5,96(%esp) + addl %esi,%edi + xorl %ecx,%ebp + vmovdqa %xmm4,%xmm5 + vpaddd %xmm0,%xmm4,%xmm4 + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpxor %xmm3,%xmm1,%xmm1 + addl 20(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + vpsrld $30,%xmm1,%xmm3 + vmovdqa %xmm4,(%esp) + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vpor %xmm3,%xmm1,%xmm1 + addl 28(%esp),%ebx + xorl %edi,%ebp + vmovdqa 64(%esp),%xmm3 + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm4 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + vmovdqa %xmm6,64(%esp) + addl %esi,%eax + xorl %edx,%ebp + vmovdqa 128(%esp),%xmm6 + vpaddd %xmm1,%xmm5,%xmm5 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm4,%xmm2,%xmm2 + addl 36(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm4 + vmovdqa %xmm5,16(%esp) + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpslld $2,%xmm2,%xmm2 + addl 40(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + vpor %xmm4,%xmm2,%xmm2 + addl 44(%esp),%ecx + xorl %eax,%ebp + vmovdqa 80(%esp),%xmm4 + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm5 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + vmovdqa %xmm7,80(%esp) + addl %esi,%ebx + xorl %edi,%ebp + vmovdqa %xmm6,%xmm7 + vpaddd %xmm2,%xmm6,%xmm6 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm5,%xmm3,%xmm3 + addl 52(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm5 + vmovdqa %xmm6,32(%esp) + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpor %xmm5,%xmm3,%xmm3 + addl 60(%esp),%edx + xorl %ebx,%ebp + vmovdqa 96(%esp),%xmm5 + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpalignr $8,%xmm2,%xmm3,%xmm6 + vpxor %xmm0,%xmm4,%xmm4 + addl (%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + vmovdqa %xmm0,96(%esp) + addl %esi,%ecx + xorl %eax,%ebp + vmovdqa %xmm7,%xmm0 + vpaddd %xmm3,%xmm7,%xmm7 + shrdl $7,%edi,%edi + addl %edx,%ecx + vpxor %xmm6,%xmm4,%xmm4 + addl 4(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm6 + vmovdqa %xmm7,48(%esp) + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm6,%xmm4,%xmm4 + addl 12(%esp),%edi + xorl %ecx,%ebp + vmovdqa 64(%esp),%xmm6 + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpalignr $8,%xmm3,%xmm4,%xmm7 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + vpxor %xmm6,%xmm5,%xmm5 + vmovdqa %xmm1,64(%esp) + addl %esi,%edx + xorl %ebx,%ebp + vmovdqa %xmm0,%xmm1 + vpaddd %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + addl %edi,%edx + vpxor %xmm7,%xmm5,%xmm5 + addl 20(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm7 + vmovdqa %xmm0,(%esp) + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm7,%xmm5,%xmm5 + addl 28(%esp),%eax + vmovdqa 80(%esp),%xmm7 + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm0 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%esp),%edi + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + vmovdqa %xmm2,80(%esp) + movl %eax,%ebp + xorl %ecx,%esi + vmovdqa %xmm1,%xmm2 + vpaddd %xmm5,%xmm1,%xmm1 + shldl $5,%eax,%eax + addl %esi,%edi + vpxor %xmm0,%xmm6,%xmm6 + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + addl 36(%esp),%edx + vpsrld $30,%xmm6,%xmm0 + vmovdqa %xmm1,16(%esp) + andl %ebx,%ebp + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %edi,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%ebp + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + addl 40(%esp),%ecx + andl %eax,%esi + vpor %xmm0,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%edi,%edi + vmovdqa 96(%esp),%xmm0 + movl %edx,%ebp + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + addl 44(%esp),%ebx + andl %edi,%ebp + xorl %eax,%edi + shrdl $7,%edx,%edx + movl %ecx,%esi + xorl %edi,%ebp + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm1 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%esp),%eax + andl %edx,%esi + xorl %edi,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + vmovdqa %xmm3,96(%esp) + movl %ebx,%ebp + xorl %edx,%esi + vmovdqa 144(%esp),%xmm3 + vpaddd %xmm6,%xmm2,%xmm2 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm1,%xmm7,%xmm7 + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%esp),%edi + vpsrld $30,%xmm7,%xmm1 + vmovdqa %xmm2,32(%esp) + andl %ecx,%ebp + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%ebp + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + addl 56(%esp),%edx + andl %ebx,%esi + vpor %xmm1,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vmovdqa 64(%esp),%xmm1 + movl %edi,%ebp + xorl %ebx,%esi + shldl $5,%edi,%edi + addl %esi,%edx + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + addl 60(%esp),%ecx + andl %eax,%ebp + xorl %ebx,%eax + shrdl $7,%edi,%edi + movl %edx,%esi + xorl %eax,%ebp + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm2 + vpxor %xmm4,%xmm0,%xmm0 + addl (%esp),%ebx + andl %edi,%esi + xorl %eax,%edi + shrdl $7,%edx,%edx + vpxor %xmm1,%xmm0,%xmm0 + vmovdqa %xmm4,64(%esp) + movl %ecx,%ebp + xorl %edi,%esi + vmovdqa %xmm3,%xmm4 + vpaddd %xmm7,%xmm3,%xmm3 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm2,%xmm0,%xmm0 + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 4(%esp),%eax + vpsrld $30,%xmm0,%xmm2 + vmovdqa %xmm3,48(%esp) + andl %edx,%ebp + xorl %edi,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%esp),%edi + andl %ecx,%esi + vpor %xmm2,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vmovdqa 80(%esp),%xmm2 + movl %eax,%ebp + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + addl 12(%esp),%edx + andl %ebx,%ebp + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %edi,%esi + xorl %ebx,%ebp + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + vpalignr $8,%xmm7,%xmm0,%xmm3 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%esp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%edi,%edi + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm5,80(%esp) + movl %edx,%ebp + xorl %eax,%esi + vmovdqa %xmm4,%xmm5 + vpaddd %xmm0,%xmm4,%xmm4 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm3,%xmm1,%xmm1 + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + addl 20(%esp),%ebx + vpsrld $30,%xmm1,%xmm3 + vmovdqa %xmm4,(%esp) + andl %edi,%ebp + xorl %eax,%edi + shrdl $7,%edx,%edx + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %edi,%ebp + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + addl 24(%esp),%eax + andl %edx,%esi + vpor %xmm3,%xmm1,%xmm1 + xorl %edi,%edx + shrdl $7,%ecx,%ecx + vmovdqa 96(%esp),%xmm3 + movl %ebx,%ebp + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%esp),%edi + andl %ecx,%ebp + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%ebp + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + vpalignr $8,%xmm0,%xmm1,%xmm4 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%esp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + vmovdqa %xmm6,96(%esp) + movl %edi,%ebp + xorl %ebx,%esi + vmovdqa %xmm5,%xmm6 + vpaddd %xmm1,%xmm5,%xmm5 + shldl $5,%edi,%edi + addl %esi,%edx + vpxor %xmm4,%xmm2,%xmm2 + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + addl 36(%esp),%ecx + vpsrld $30,%xmm2,%xmm4 + vmovdqa %xmm5,16(%esp) + andl %eax,%ebp + xorl %ebx,%eax + shrdl $7,%edi,%edi + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%ebp + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + addl 40(%esp),%ebx + andl %edi,%esi + vpor %xmm4,%xmm2,%xmm2 + xorl %eax,%edi + shrdl $7,%edx,%edx + vmovdqa 64(%esp),%xmm4 + movl %ecx,%ebp + xorl %edi,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 44(%esp),%eax + andl %edx,%ebp + xorl %edi,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm5 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + vmovdqa %xmm7,64(%esp) + addl %esi,%edi + xorl %ecx,%ebp + vmovdqa %xmm6,%xmm7 + vpaddd %xmm2,%xmm6,%xmm6 + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpxor %xmm5,%xmm3,%xmm3 + addl 52(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + vpsrld $30,%xmm3,%xmm5 + vmovdqa %xmm6,32(%esp) + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vpor %xmm5,%xmm3,%xmm3 + addl 60(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl (%esp),%eax + vpaddd %xmm3,%xmm7,%xmm7 + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm7,48(%esp) + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 8(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + addl 12(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + movl 196(%esp),%ebp + cmpl 200(%esp),%ebp + je L008done + vmovdqa 160(%esp),%xmm7 + vmovdqa 176(%esp),%xmm6 + vmovdqu (%ebp),%xmm0 + vmovdqu 16(%ebp),%xmm1 + vmovdqu 32(%ebp),%xmm2 + vmovdqu 48(%ebp),%xmm3 + addl $64,%ebp + vpshufb %xmm6,%xmm0,%xmm0 + movl %ebp,196(%esp) + vmovdqa %xmm7,96(%esp) + addl 16(%esp),%ebx + xorl %edi,%esi + vpshufb %xmm6,%xmm1,%xmm1 + movl %ecx,%ebp + shldl $5,%ecx,%ecx + vpaddd %xmm7,%xmm0,%xmm4 + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm4,(%esp) + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + vpshufb %xmm6,%xmm2,%xmm2 + movl %edx,%ebp + shldl $5,%edx,%edx + vpaddd %xmm7,%xmm1,%xmm5 + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vmovdqa %xmm5,16(%esp) + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + vpshufb %xmm6,%xmm3,%xmm3 + movl %edi,%ebp + shldl $5,%edi,%edi + vpaddd %xmm7,%xmm2,%xmm6 + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + vmovdqa %xmm6,32(%esp) + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + movl 192(%esp),%ebp + addl (%ebp),%eax + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,%ebx + movl %ecx,8(%ebp) + xorl %edx,%ebx + movl %edx,12(%ebp) + movl %edi,16(%ebp) + movl %esi,%ebp + andl %ebx,%esi + movl %ebp,%ebx + jmp L007loop +.align 4,0x90 +L008done: + addl 16(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vzeroall + movl 192(%esp),%ebp + addl (%ebp),%eax + movl 204(%esp),%esp + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,8(%ebp) + movl %edx,12(%ebp) + movl %edi,16(%ebp) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret .align 6,0x90 LK_XX_XX: .long 1518500249,1518500249,1518500249,1518500249 diff --git a/mac-x86/crypto/sha/sha256-586.S b/mac-x86/crypto/sha/sha256-586.S index 4615588..841854f 100644 --- a/mac-x86/crypto/sha/sha256-586.S +++ b/mac-x86/crypto/sha/sha256-586.S @@ -39,12 +39,13 @@ L000pic_point: orl %ebx,%ecx andl $1342177280,%ecx cmpl $1342177280,%ecx + je L004AVX testl $512,%ebx - jnz L004SSSE3 + jnz L005SSSE3 L003no_xmm: subl %edi,%eax cmpl $256,%eax - jae L005unrolled + jae L006unrolled jmp L002loop .align 4,0x90 L002loop: @@ -116,7 +117,7 @@ L002loop: movl %ecx,28(%esp) movl %edi,32(%esp) .align 4,0x90 -L00600_15: +L00700_15: movl %edx,%ecx movl 24(%esp),%esi rorl $14,%ecx @@ -154,11 +155,11 @@ L00600_15: addl $4,%ebp addl %ebx,%eax cmpl $3248222580,%esi - jne L00600_15 + jne L00700_15 movl 156(%esp),%ecx - jmp L00716_63 + jmp L00816_63 .align 4,0x90 -L00716_63: +L00816_63: movl %ecx,%ebx movl 104(%esp),%esi rorl $11,%ecx @@ -213,7 +214,7 @@ L00716_63: addl $4,%ebp addl %ebx,%eax cmpl $3329325298,%esi - jne L00716_63 + jne L00816_63 movl 356(%esp),%esi movl 8(%esp),%ebx movl 16(%esp),%ecx @@ -257,7 +258,7 @@ L001K256: .byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 .byte 62,0 .align 4,0x90 -L005unrolled: +L006unrolled: leal -96(%esp),%esp movl (%esi),%eax movl 4(%esi),%ebp @@ -274,9 +275,9 @@ L005unrolled: movl %ebx,20(%esp) movl %ecx,24(%esp) movl %esi,28(%esp) - jmp L008grand_loop + jmp L009grand_loop .align 4,0x90 -L008grand_loop: +L009grand_loop: movl (%edi),%ebx movl 4(%edi),%ecx bswap %ebx @@ -3156,7 +3157,7 @@ L008grand_loop: movl %ebx,24(%esp) movl %ecx,28(%esp) cmpl 104(%esp),%edi - jb L008grand_loop + jb L009grand_loop movl 108(%esp),%esp popl %edi popl %esi @@ -3164,7 +3165,7 @@ L008grand_loop: popl %ebp ret .align 5,0x90 -L004SSSE3: +L005SSSE3: leal -96(%esp),%esp movl (%esi),%eax movl 4(%esi),%ebx @@ -3183,9 +3184,9 @@ L004SSSE3: movl %ecx,24(%esp) movl %esi,28(%esp) movdqa 256(%ebp),%xmm7 - jmp L009grand_ssse3 + jmp L010grand_ssse3 .align 4,0x90 -L009grand_ssse3: +L010grand_ssse3: movdqu (%edi),%xmm0 movdqu 16(%edi),%xmm1 movdqu 32(%edi),%xmm2 @@ -3208,9 +3209,9 @@ L009grand_ssse3: paddd %xmm3,%xmm7 movdqa %xmm6,64(%esp) movdqa %xmm7,80(%esp) - jmp L010ssse3_00_47 + jmp L011ssse3_00_47 .align 4,0x90 -L010ssse3_00_47: +L011ssse3_00_47: addl $64,%ebp movl %edx,%ecx movdqa %xmm1,%xmm4 @@ -3853,7 +3854,7 @@ L010ssse3_00_47: addl %ecx,%eax movdqa %xmm6,80(%esp) cmpl $66051,64(%ebp) - jne L010ssse3_00_47 + jne L011ssse3_00_47 movl %edx,%ecx rorl $14,%edx movl 20(%esp),%esi @@ -4367,13 +4368,1194 @@ L010ssse3_00_47: movdqa 64(%ebp),%xmm7 subl $192,%ebp cmpl 104(%esp),%edi - jb L009grand_ssse3 + jb L010grand_ssse3 movl 108(%esp),%esp popl %edi popl %esi popl %ebx popl %ebp ret +.align 5,0x90 +L004AVX: + leal -96(%esp),%esp + vzeroall + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edi + movl %ebx,4(%esp) + xorl %ecx,%ebx + movl %ecx,8(%esp) + movl %edi,12(%esp) + movl 16(%esi),%edx + movl 20(%esi),%edi + movl 24(%esi),%ecx + movl 28(%esi),%esi + movl %edi,20(%esp) + movl 100(%esp),%edi + movl %ecx,24(%esp) + movl %esi,28(%esp) + vmovdqa 256(%ebp),%xmm7 + jmp L012grand_avx +.align 5,0x90 +L012grand_avx: + vmovdqu (%edi),%xmm0 + vmovdqu 16(%edi),%xmm1 + vmovdqu 32(%edi),%xmm2 + vmovdqu 48(%edi),%xmm3 + addl $64,%edi + vpshufb %xmm7,%xmm0,%xmm0 + movl %edi,100(%esp) + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd (%ebp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 16(%ebp),%xmm1,%xmm5 + vpaddd 32(%ebp),%xmm2,%xmm6 + vpaddd 48(%ebp),%xmm3,%xmm7 + vmovdqa %xmm4,32(%esp) + vmovdqa %xmm5,48(%esp) + vmovdqa %xmm6,64(%esp) + vmovdqa %xmm7,80(%esp) + jmp L013avx_00_47 +.align 4,0x90 +L013avx_00_47: + addl $64,%ebp + vpalignr $4,%xmm0,%xmm1,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + vpalignr $4,%xmm2,%xmm3,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + vpaddd %xmm7,%xmm0,%xmm0 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + vpshufd $250,%xmm3,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 32(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + vpaddd %xmm4,%xmm0,%xmm0 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 36(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + vpaddd %xmm7,%xmm0,%xmm0 + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm0,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 40(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm0,%xmm0 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + vpaddd (%ebp),%xmm0,%xmm6 + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,32(%esp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + vpalignr $4,%xmm3,%xmm0,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + vpaddd %xmm7,%xmm1,%xmm1 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + vpshufd $250,%xmm0,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 48(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + vpaddd %xmm4,%xmm1,%xmm1 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 52(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + vpaddd %xmm7,%xmm1,%xmm1 + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm1,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 56(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm1,%xmm1 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + vpaddd 16(%ebp),%xmm1,%xmm6 + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,48(%esp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + vpalignr $4,%xmm0,%xmm1,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + vpaddd %xmm7,%xmm2,%xmm2 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + vpshufd $250,%xmm1,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 64(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + vpaddd %xmm4,%xmm2,%xmm2 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 68(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + vpaddd %xmm7,%xmm2,%xmm2 + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm2,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 72(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm2,%xmm2 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + vpaddd 32(%ebp),%xmm2,%xmm6 + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,64(%esp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + vpalignr $4,%xmm1,%xmm2,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + vpaddd %xmm7,%xmm3,%xmm3 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + vpshufd $250,%xmm2,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 80(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + vpaddd %xmm4,%xmm3,%xmm3 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 84(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + vpaddd %xmm7,%xmm3,%xmm3 + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm3,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 88(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm3,%xmm3 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + vpaddd 48(%ebp),%xmm3,%xmm6 + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,80(%esp) + cmpl $66051,64(%ebp) + jne L013avx_00_47 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 32(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 36(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 40(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 48(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 52(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 56(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 64(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 68(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 72(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 80(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 84(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 88(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl 96(%esp),%esi + xorl %edi,%ebx + movl 12(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebx + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl %ebx,4(%esp) + xorl %edi,%ebx + movl %edi,8(%esp) + movl %ecx,12(%esp) + movl 20(%esp),%edi + movl 24(%esp),%ecx + addl 16(%esi),%edx + addl 20(%esi),%edi + addl 24(%esi),%ecx + movl %edx,16(%esi) + movl %edi,20(%esi) + movl %edi,20(%esp) + movl 28(%esp),%edi + movl %ecx,24(%esi) + addl 28(%esi),%edi + movl %ecx,24(%esp) + movl %edi,28(%esi) + movl %edi,28(%esp) + movl 100(%esp),%edi + vmovdqa 64(%ebp),%xmm7 + subl $192,%ebp + cmpl 104(%esp),%edi + jb L012grand_avx + movl 108(%esp),%esp + vzeroall + popl %edi + popl %esi + popl %ebx + popl %ebp + ret .section __IMPORT,__pointers,non_lazy_symbol_pointers L_OPENSSL_ia32cap_P$non_lazy_ptr: .indirect_symbol _OPENSSL_ia32cap_P diff --git a/mac-x86_64/crypto/bn/x86_64-mont5.S b/mac-x86_64/crypto/bn/x86_64-mont5.S index 2e8f469..461bfb2 100644 --- a/mac-x86_64/crypto/bn/x86_64-mont5.S +++ b/mac-x86_64/crypto/bn/x86_64-mont5.S @@ -1560,6 +1560,15 @@ L$8x_tail: .p2align 5 L$8x_tail_done: addq (%rdx),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + + xorq %rax,%rax negq %rsi diff --git a/mac-x86_64/crypto/ec/p256-x86_64-asm.S b/mac-x86_64/crypto/ec/p256-x86_64-asm.S index 43f7dff..bed1130 100644 --- a/mac-x86_64/crypto/ec/p256-x86_64-asm.S +++ b/mac-x86_64/crypto/ec/p256-x86_64-asm.S @@ -7,10 +7,6 @@ L$poly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 - -L$RR: -.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd - L$One: .long 1,1,1,1,1,1,1,1 L$Two: @@ -20,11 +16,9 @@ L$Three: L$ONE_mont: .quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe -.globl _ecp_nistz256_mul_by_2 -.private_extern _ecp_nistz256_mul_by_2 .p2align 6 -_ecp_nistz256_mul_by_2: +ecp_nistz256_mul_by_2: pushq %r12 pushq %r13 @@ -65,228 +59,6 @@ _ecp_nistz256_mul_by_2: -.globl _ecp_nistz256_div_by_2 -.private_extern _ecp_nistz256_div_by_2 - -.p2align 5 -_ecp_nistz256_div_by_2: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq %r8,%rax - movq 24(%rsi),%r11 - leaq L$poly(%rip),%rsi - - movq %r9,%rdx - xorq %r13,%r13 - addq 0(%rsi),%r8 - movq %r10,%rcx - adcq 8(%rsi),%r9 - adcq 16(%rsi),%r10 - movq %r11,%r12 - adcq 24(%rsi),%r11 - adcq $0,%r13 - xorq %rsi,%rsi - testq $1,%rax - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - cmovzq %rcx,%r10 - cmovzq %r12,%r11 - cmovzq %rsi,%r13 - - movq %r9,%rax - shrq $1,%r8 - shlq $63,%rax - movq %r10,%rdx - shrq $1,%r9 - orq %rax,%r8 - shlq $63,%rdx - movq %r11,%rcx - shrq $1,%r10 - orq %rdx,%r9 - shlq $63,%rcx - shrq $1,%r11 - shlq $63,%r13 - orq %rcx,%r10 - orq %r13,%r11 - - movq %r8,0(%rdi) - movq %r9,8(%rdi) - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 - - - - -.globl _ecp_nistz256_mul_by_3 -.private_extern _ecp_nistz256_mul_by_3 - -.p2align 5 -_ecp_nistz256_mul_by_3: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - addq %r8,%r8 - movq 16(%rsi),%r10 - adcq %r9,%r9 - movq 24(%rsi),%r11 - movq %r8,%rax - adcq %r10,%r10 - adcq %r11,%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq $-1,%r8 - movq %r10,%rcx - sbbq L$poly+8(%rip),%r9 - sbbq $0,%r10 - movq %r11,%r12 - sbbq L$poly+24(%rip),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - cmovzq %rcx,%r10 - cmovzq %r12,%r11 - - xorq %r13,%r13 - addq 0(%rsi),%r8 - adcq 8(%rsi),%r9 - movq %r8,%rax - adcq 16(%rsi),%r10 - adcq 24(%rsi),%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq $-1,%r8 - movq %r10,%rcx - sbbq L$poly+8(%rip),%r9 - sbbq $0,%r10 - movq %r11,%r12 - sbbq L$poly+24(%rip),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 - - - - -.globl _ecp_nistz256_add -.private_extern _ecp_nistz256_add - -.p2align 5 -_ecp_nistz256_add: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq 24(%rsi),%r11 - leaq L$poly(%rip),%rsi - - addq 0(%rdx),%r8 - adcq 8(%rdx),%r9 - movq %r8,%rax - adcq 16(%rdx),%r10 - adcq 24(%rdx),%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq 0(%rsi),%r8 - movq %r10,%rcx - sbbq 8(%rsi),%r9 - sbbq 16(%rsi),%r10 - movq %r11,%r12 - sbbq 24(%rsi),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 - - - - -.globl _ecp_nistz256_sub -.private_extern _ecp_nistz256_sub - -.p2align 5 -_ecp_nistz256_sub: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq 24(%rsi),%r11 - leaq L$poly(%rip),%rsi - - subq 0(%rdx),%r8 - sbbq 8(%rdx),%r9 - movq %r8,%rax - sbbq 16(%rdx),%r10 - sbbq 24(%rdx),%r11 - movq %r9,%rdx - sbbq $0,%r13 - - addq 0(%rsi),%r8 - movq %r10,%rcx - adcq 8(%rsi),%r9 - adcq 16(%rsi),%r10 - movq %r11,%r12 - adcq 24(%rsi),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 - - - - .globl _ecp_nistz256_neg .private_extern _ecp_nistz256_neg @@ -335,19 +107,6 @@ _ecp_nistz256_neg: -.globl _ecp_nistz256_to_mont -.private_extern _ecp_nistz256_to_mont - -.p2align 5 -_ecp_nistz256_to_mont: - leaq L$RR(%rip),%rdx - jmp L$mul_mont - - - - - - .globl _ecp_nistz256_mul_mont diff --git a/mac-x86_64/crypto/rc4/rc4-md5-x86_64.S b/mac-x86_64/crypto/rc4/rc4-md5-x86_64.S deleted file mode 100644 index 31ee7d2..0000000 --- a/mac-x86_64/crypto/rc4/rc4-md5-x86_64.S +++ /dev/null @@ -1,1262 +0,0 @@ -#if defined(__x86_64__) -.text -.p2align 4 - -.globl _rc4_md5_enc -.private_extern _rc4_md5_enc - -_rc4_md5_enc: - cmpq $0,%r9 - je L$abort - pushq %rbx - pushq %rbp - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - subq $40,%rsp -L$body: - movq %rcx,%r11 - movq %r9,%r12 - movq %rsi,%r13 - movq %rdx,%r14 - movq %r8,%r15 - xorq %rbp,%rbp - xorq %rcx,%rcx - - leaq 8(%rdi),%rdi - movb -8(%rdi),%bpl - movb -4(%rdi),%cl - - incb %bpl - subq %r13,%r14 - movl (%rdi,%rbp,4),%eax - addb %al,%cl - leaq (%rdi,%rbp,4),%rsi - shlq $6,%r12 - addq %r15,%r12 - movq %r12,16(%rsp) - - movq %r11,24(%rsp) - movl 0(%r11),%r8d - movl 4(%r11),%r9d - movl 8(%r11),%r10d - movl 12(%r11),%r11d - jmp L$oop - -.p2align 4 -L$oop: - movl %r8d,0(%rsp) - movl %r9d,4(%rsp) - movl %r10d,8(%rsp) - movl %r11d,%r12d - movl %r11d,12(%rsp) - pxor %xmm0,%xmm0 - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 0(%r15),%r8d - addb %dl,%al - movl 4(%rsi),%ebx - addl $3614090360,%r8d - xorl %r11d,%r12d - movzbl %al,%eax - movl %edx,0(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $7,%r8d - movl %r10d,%r12d - movd (%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - pxor %xmm1,%xmm1 - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 4(%r15),%r11d - addb %dl,%bl - movl 8(%rsi),%eax - addl $3905402710,%r11d - xorl %r10d,%r12d - movzbl %bl,%ebx - movl %edx,4(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $12,%r11d - movl %r9d,%r12d - movd (%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 8(%r15),%r10d - addb %dl,%al - movl 12(%rsi),%ebx - addl $606105819,%r10d - xorl %r9d,%r12d - movzbl %al,%eax - movl %edx,8(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $17,%r10d - movl %r8d,%r12d - pinsrw $1,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 12(%r15),%r9d - addb %dl,%bl - movl 16(%rsi),%eax - addl $3250441966,%r9d - xorl %r8d,%r12d - movzbl %bl,%ebx - movl %edx,12(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $22,%r9d - movl %r11d,%r12d - pinsrw $1,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 16(%r15),%r8d - addb %dl,%al - movl 20(%rsi),%ebx - addl $4118548399,%r8d - xorl %r11d,%r12d - movzbl %al,%eax - movl %edx,16(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $7,%r8d - movl %r10d,%r12d - pinsrw $2,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 20(%r15),%r11d - addb %dl,%bl - movl 24(%rsi),%eax - addl $1200080426,%r11d - xorl %r10d,%r12d - movzbl %bl,%ebx - movl %edx,20(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $12,%r11d - movl %r9d,%r12d - pinsrw $2,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 24(%r15),%r10d - addb %dl,%al - movl 28(%rsi),%ebx - addl $2821735955,%r10d - xorl %r9d,%r12d - movzbl %al,%eax - movl %edx,24(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $17,%r10d - movl %r8d,%r12d - pinsrw $3,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 28(%r15),%r9d - addb %dl,%bl - movl 32(%rsi),%eax - addl $4249261313,%r9d - xorl %r8d,%r12d - movzbl %bl,%ebx - movl %edx,28(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $22,%r9d - movl %r11d,%r12d - pinsrw $3,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 32(%r15),%r8d - addb %dl,%al - movl 36(%rsi),%ebx - addl $1770035416,%r8d - xorl %r11d,%r12d - movzbl %al,%eax - movl %edx,32(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $7,%r8d - movl %r10d,%r12d - pinsrw $4,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 36(%r15),%r11d - addb %dl,%bl - movl 40(%rsi),%eax - addl $2336552879,%r11d - xorl %r10d,%r12d - movzbl %bl,%ebx - movl %edx,36(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $12,%r11d - movl %r9d,%r12d - pinsrw $4,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 40(%r15),%r10d - addb %dl,%al - movl 44(%rsi),%ebx - addl $4294925233,%r10d - xorl %r9d,%r12d - movzbl %al,%eax - movl %edx,40(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $17,%r10d - movl %r8d,%r12d - pinsrw $5,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 44(%r15),%r9d - addb %dl,%bl - movl 48(%rsi),%eax - addl $2304563134,%r9d - xorl %r8d,%r12d - movzbl %bl,%ebx - movl %edx,44(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $22,%r9d - movl %r11d,%r12d - pinsrw $5,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 48(%r15),%r8d - addb %dl,%al - movl 52(%rsi),%ebx - addl $1804603682,%r8d - xorl %r11d,%r12d - movzbl %al,%eax - movl %edx,48(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $7,%r8d - movl %r10d,%r12d - pinsrw $6,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 52(%r15),%r11d - addb %dl,%bl - movl 56(%rsi),%eax - addl $4254626195,%r11d - xorl %r10d,%r12d - movzbl %bl,%ebx - movl %edx,52(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $12,%r11d - movl %r9d,%r12d - pinsrw $6,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 56(%r15),%r10d - addb %dl,%al - movl 60(%rsi),%ebx - addl $2792965006,%r10d - xorl %r9d,%r12d - movzbl %al,%eax - movl %edx,56(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $17,%r10d - movl %r8d,%r12d - pinsrw $7,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movdqu (%r13),%xmm2 - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 60(%r15),%r9d - addb %dl,%bl - movl 64(%rsi),%eax - addl $1236535329,%r9d - xorl %r8d,%r12d - movzbl %bl,%ebx - movl %edx,60(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $22,%r9d - movl %r10d,%r12d - pinsrw $7,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - psllq $8,%xmm1 - pxor %xmm0,%xmm2 - pxor %xmm1,%xmm2 - pxor %xmm0,%xmm0 - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 4(%r15),%r8d - addb %dl,%al - movl 68(%rsi),%ebx - addl $4129170786,%r8d - xorl %r10d,%r12d - movzbl %al,%eax - movl %edx,64(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $5,%r8d - movl %r9d,%r12d - movd (%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - pxor %xmm1,%xmm1 - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 24(%r15),%r11d - addb %dl,%bl - movl 72(%rsi),%eax - addl $3225465664,%r11d - xorl %r9d,%r12d - movzbl %bl,%ebx - movl %edx,68(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $9,%r11d - movl %r8d,%r12d - movd (%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 44(%r15),%r10d - addb %dl,%al - movl 76(%rsi),%ebx - addl $643717713,%r10d - xorl %r8d,%r12d - movzbl %al,%eax - movl %edx,72(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $14,%r10d - movl %r11d,%r12d - pinsrw $1,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 0(%r15),%r9d - addb %dl,%bl - movl 80(%rsi),%eax - addl $3921069994,%r9d - xorl %r11d,%r12d - movzbl %bl,%ebx - movl %edx,76(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $20,%r9d - movl %r10d,%r12d - pinsrw $1,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 20(%r15),%r8d - addb %dl,%al - movl 84(%rsi),%ebx - addl $3593408605,%r8d - xorl %r10d,%r12d - movzbl %al,%eax - movl %edx,80(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $5,%r8d - movl %r9d,%r12d - pinsrw $2,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 40(%r15),%r11d - addb %dl,%bl - movl 88(%rsi),%eax - addl $38016083,%r11d - xorl %r9d,%r12d - movzbl %bl,%ebx - movl %edx,84(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $9,%r11d - movl %r8d,%r12d - pinsrw $2,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 60(%r15),%r10d - addb %dl,%al - movl 92(%rsi),%ebx - addl $3634488961,%r10d - xorl %r8d,%r12d - movzbl %al,%eax - movl %edx,88(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $14,%r10d - movl %r11d,%r12d - pinsrw $3,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 16(%r15),%r9d - addb %dl,%bl - movl 96(%rsi),%eax - addl $3889429448,%r9d - xorl %r11d,%r12d - movzbl %bl,%ebx - movl %edx,92(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $20,%r9d - movl %r10d,%r12d - pinsrw $3,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 36(%r15),%r8d - addb %dl,%al - movl 100(%rsi),%ebx - addl $568446438,%r8d - xorl %r10d,%r12d - movzbl %al,%eax - movl %edx,96(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $5,%r8d - movl %r9d,%r12d - pinsrw $4,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 56(%r15),%r11d - addb %dl,%bl - movl 104(%rsi),%eax - addl $3275163606,%r11d - xorl %r9d,%r12d - movzbl %bl,%ebx - movl %edx,100(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $9,%r11d - movl %r8d,%r12d - pinsrw $4,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 12(%r15),%r10d - addb %dl,%al - movl 108(%rsi),%ebx - addl $4107603335,%r10d - xorl %r8d,%r12d - movzbl %al,%eax - movl %edx,104(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $14,%r10d - movl %r11d,%r12d - pinsrw $5,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 32(%r15),%r9d - addb %dl,%bl - movl 112(%rsi),%eax - addl $1163531501,%r9d - xorl %r11d,%r12d - movzbl %bl,%ebx - movl %edx,108(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $20,%r9d - movl %r10d,%r12d - pinsrw $5,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r11d,%r12d - addl 52(%r15),%r8d - addb %dl,%al - movl 116(%rsi),%ebx - addl $2850285829,%r8d - xorl %r10d,%r12d - movzbl %al,%eax - movl %edx,112(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $5,%r8d - movl %r9d,%r12d - pinsrw $6,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r10d,%r12d - addl 8(%r15),%r11d - addb %dl,%bl - movl 120(%rsi),%eax - addl $4243563512,%r11d - xorl %r9d,%r12d - movzbl %bl,%ebx - movl %edx,116(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $9,%r11d - movl %r8d,%r12d - pinsrw $6,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - andl %r9d,%r12d - addl 28(%r15),%r10d - addb %dl,%al - movl 124(%rsi),%ebx - addl $1735328473,%r10d - xorl %r8d,%r12d - movzbl %al,%eax - movl %edx,120(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $14,%r10d - movl %r11d,%r12d - pinsrw $7,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movdqu 16(%r13),%xmm3 - addb $32,%bpl - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - andl %r8d,%r12d - addl 48(%r15),%r9d - addb %dl,%bl - movl 0(%rdi,%rbp,4),%eax - addl $2368359562,%r9d - xorl %r11d,%r12d - movzbl %bl,%ebx - movl %edx,124(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $20,%r9d - movl %r11d,%r12d - pinsrw $7,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movq %rcx,%rsi - xorq %rcx,%rcx - movb %sil,%cl - leaq (%rdi,%rbp,4),%rsi - psllq $8,%xmm1 - pxor %xmm0,%xmm3 - pxor %xmm1,%xmm3 - pxor %xmm0,%xmm0 - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r9d,%r12d - addl 20(%r15),%r8d - addb %dl,%al - movl 4(%rsi),%ebx - addl $4294588738,%r8d - movzbl %al,%eax - addl %r12d,%r8d - movl %edx,0(%rsi) - addb %bl,%cl - roll $4,%r8d - movl %r10d,%r12d - movd (%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - pxor %xmm1,%xmm1 - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r8d,%r12d - addl 32(%r15),%r11d - addb %dl,%bl - movl 8(%rsi),%eax - addl $2272392833,%r11d - movzbl %bl,%ebx - addl %r12d,%r11d - movl %edx,4(%rsi) - addb %al,%cl - roll $11,%r11d - movl %r9d,%r12d - movd (%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r11d,%r12d - addl 44(%r15),%r10d - addb %dl,%al - movl 12(%rsi),%ebx - addl $1839030562,%r10d - movzbl %al,%eax - addl %r12d,%r10d - movl %edx,8(%rsi) - addb %bl,%cl - roll $16,%r10d - movl %r8d,%r12d - pinsrw $1,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r10d,%r12d - addl 56(%r15),%r9d - addb %dl,%bl - movl 16(%rsi),%eax - addl $4259657740,%r9d - movzbl %bl,%ebx - addl %r12d,%r9d - movl %edx,12(%rsi) - addb %al,%cl - roll $23,%r9d - movl %r11d,%r12d - pinsrw $1,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r9d,%r12d - addl 4(%r15),%r8d - addb %dl,%al - movl 20(%rsi),%ebx - addl $2763975236,%r8d - movzbl %al,%eax - addl %r12d,%r8d - movl %edx,16(%rsi) - addb %bl,%cl - roll $4,%r8d - movl %r10d,%r12d - pinsrw $2,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r8d,%r12d - addl 16(%r15),%r11d - addb %dl,%bl - movl 24(%rsi),%eax - addl $1272893353,%r11d - movzbl %bl,%ebx - addl %r12d,%r11d - movl %edx,20(%rsi) - addb %al,%cl - roll $11,%r11d - movl %r9d,%r12d - pinsrw $2,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r11d,%r12d - addl 28(%r15),%r10d - addb %dl,%al - movl 28(%rsi),%ebx - addl $4139469664,%r10d - movzbl %al,%eax - addl %r12d,%r10d - movl %edx,24(%rsi) - addb %bl,%cl - roll $16,%r10d - movl %r8d,%r12d - pinsrw $3,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r10d,%r12d - addl 40(%r15),%r9d - addb %dl,%bl - movl 32(%rsi),%eax - addl $3200236656,%r9d - movzbl %bl,%ebx - addl %r12d,%r9d - movl %edx,28(%rsi) - addb %al,%cl - roll $23,%r9d - movl %r11d,%r12d - pinsrw $3,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r9d,%r12d - addl 52(%r15),%r8d - addb %dl,%al - movl 36(%rsi),%ebx - addl $681279174,%r8d - movzbl %al,%eax - addl %r12d,%r8d - movl %edx,32(%rsi) - addb %bl,%cl - roll $4,%r8d - movl %r10d,%r12d - pinsrw $4,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r8d,%r12d - addl 0(%r15),%r11d - addb %dl,%bl - movl 40(%rsi),%eax - addl $3936430074,%r11d - movzbl %bl,%ebx - addl %r12d,%r11d - movl %edx,36(%rsi) - addb %al,%cl - roll $11,%r11d - movl %r9d,%r12d - pinsrw $4,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r11d,%r12d - addl 12(%r15),%r10d - addb %dl,%al - movl 44(%rsi),%ebx - addl $3572445317,%r10d - movzbl %al,%eax - addl %r12d,%r10d - movl %edx,40(%rsi) - addb %bl,%cl - roll $16,%r10d - movl %r8d,%r12d - pinsrw $5,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r10d,%r12d - addl 24(%r15),%r9d - addb %dl,%bl - movl 48(%rsi),%eax - addl $76029189,%r9d - movzbl %bl,%ebx - addl %r12d,%r9d - movl %edx,44(%rsi) - addb %al,%cl - roll $23,%r9d - movl %r11d,%r12d - pinsrw $5,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r9d,%r12d - addl 36(%r15),%r8d - addb %dl,%al - movl 52(%rsi),%ebx - addl $3654602809,%r8d - movzbl %al,%eax - addl %r12d,%r8d - movl %edx,48(%rsi) - addb %bl,%cl - roll $4,%r8d - movl %r10d,%r12d - pinsrw $6,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r8d,%r12d - addl 48(%r15),%r11d - addb %dl,%bl - movl 56(%rsi),%eax - addl $3873151461,%r11d - movzbl %bl,%ebx - addl %r12d,%r11d - movl %edx,52(%rsi) - addb %al,%cl - roll $11,%r11d - movl %r9d,%r12d - pinsrw $6,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %eax,(%rdi,%rcx,4) - xorl %r11d,%r12d - addl 60(%r15),%r10d - addb %dl,%al - movl 60(%rsi),%ebx - addl $530742520,%r10d - movzbl %al,%eax - addl %r12d,%r10d - movl %edx,56(%rsi) - addb %bl,%cl - roll $16,%r10d - movl %r8d,%r12d - pinsrw $7,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movdqu 32(%r13),%xmm4 - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %ebx,(%rdi,%rcx,4) - xorl %r10d,%r12d - addl 8(%r15),%r9d - addb %dl,%bl - movl 64(%rsi),%eax - addl $3299628645,%r9d - movzbl %bl,%ebx - addl %r12d,%r9d - movl %edx,60(%rsi) - addb %al,%cl - roll $23,%r9d - movl $-1,%r12d - pinsrw $7,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - psllq $8,%xmm1 - pxor %xmm0,%xmm4 - pxor %xmm1,%xmm4 - pxor %xmm0,%xmm0 - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r9d,%r12d - addl 0(%r15),%r8d - addb %dl,%al - movl 68(%rsi),%ebx - addl $4096336452,%r8d - movzbl %al,%eax - xorl %r10d,%r12d - movl %edx,64(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $6,%r8d - movl $-1,%r12d - movd (%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - pxor %xmm1,%xmm1 - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r8d,%r12d - addl 28(%r15),%r11d - addb %dl,%bl - movl 72(%rsi),%eax - addl $1126891415,%r11d - movzbl %bl,%ebx - xorl %r9d,%r12d - movl %edx,68(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $10,%r11d - movl $-1,%r12d - movd (%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r11d,%r12d - addl 56(%r15),%r10d - addb %dl,%al - movl 76(%rsi),%ebx - addl $2878612391,%r10d - movzbl %al,%eax - xorl %r8d,%r12d - movl %edx,72(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $15,%r10d - movl $-1,%r12d - pinsrw $1,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r10d,%r12d - addl 20(%r15),%r9d - addb %dl,%bl - movl 80(%rsi),%eax - addl $4237533241,%r9d - movzbl %bl,%ebx - xorl %r11d,%r12d - movl %edx,76(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $21,%r9d - movl $-1,%r12d - pinsrw $1,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r9d,%r12d - addl 48(%r15),%r8d - addb %dl,%al - movl 84(%rsi),%ebx - addl $1700485571,%r8d - movzbl %al,%eax - xorl %r10d,%r12d - movl %edx,80(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $6,%r8d - movl $-1,%r12d - pinsrw $2,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r8d,%r12d - addl 12(%r15),%r11d - addb %dl,%bl - movl 88(%rsi),%eax - addl $2399980690,%r11d - movzbl %bl,%ebx - xorl %r9d,%r12d - movl %edx,84(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $10,%r11d - movl $-1,%r12d - pinsrw $2,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r11d,%r12d - addl 40(%r15),%r10d - addb %dl,%al - movl 92(%rsi),%ebx - addl $4293915773,%r10d - movzbl %al,%eax - xorl %r8d,%r12d - movl %edx,88(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $15,%r10d - movl $-1,%r12d - pinsrw $3,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r10d,%r12d - addl 4(%r15),%r9d - addb %dl,%bl - movl 96(%rsi),%eax - addl $2240044497,%r9d - movzbl %bl,%ebx - xorl %r11d,%r12d - movl %edx,92(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $21,%r9d - movl $-1,%r12d - pinsrw $3,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r9d,%r12d - addl 32(%r15),%r8d - addb %dl,%al - movl 100(%rsi),%ebx - addl $1873313359,%r8d - movzbl %al,%eax - xorl %r10d,%r12d - movl %edx,96(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $6,%r8d - movl $-1,%r12d - pinsrw $4,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r8d,%r12d - addl 60(%r15),%r11d - addb %dl,%bl - movl 104(%rsi),%eax - addl $4264355552,%r11d - movzbl %bl,%ebx - xorl %r9d,%r12d - movl %edx,100(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $10,%r11d - movl $-1,%r12d - pinsrw $4,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r11d,%r12d - addl 24(%r15),%r10d - addb %dl,%al - movl 108(%rsi),%ebx - addl $2734768916,%r10d - movzbl %al,%eax - xorl %r8d,%r12d - movl %edx,104(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $15,%r10d - movl $-1,%r12d - pinsrw $5,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r10d,%r12d - addl 52(%r15),%r9d - addb %dl,%bl - movl 112(%rsi),%eax - addl $1309151649,%r9d - movzbl %bl,%ebx - xorl %r11d,%r12d - movl %edx,108(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $21,%r9d - movl $-1,%r12d - pinsrw $5,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movl (%rdi,%rcx,4),%edx - xorl %r11d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r9d,%r12d - addl 16(%r15),%r8d - addb %dl,%al - movl 116(%rsi),%ebx - addl $4149444226,%r8d - movzbl %al,%eax - xorl %r10d,%r12d - movl %edx,112(%rsi) - addl %r12d,%r8d - addb %bl,%cl - roll $6,%r8d - movl $-1,%r12d - pinsrw $6,(%rdi,%rax,4),%xmm0 - - addl %r9d,%r8d - movl (%rdi,%rcx,4),%edx - xorl %r10d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r8d,%r12d - addl 44(%r15),%r11d - addb %dl,%bl - movl 120(%rsi),%eax - addl $3174756917,%r11d - movzbl %bl,%ebx - xorl %r9d,%r12d - movl %edx,116(%rsi) - addl %r12d,%r11d - addb %al,%cl - roll $10,%r11d - movl $-1,%r12d - pinsrw $6,(%rdi,%rbx,4),%xmm1 - - addl %r8d,%r11d - movl (%rdi,%rcx,4),%edx - xorl %r9d,%r12d - movl %eax,(%rdi,%rcx,4) - orl %r11d,%r12d - addl 8(%r15),%r10d - addb %dl,%al - movl 124(%rsi),%ebx - addl $718787259,%r10d - movzbl %al,%eax - xorl %r8d,%r12d - movl %edx,120(%rsi) - addl %r12d,%r10d - addb %bl,%cl - roll $15,%r10d - movl $-1,%r12d - pinsrw $7,(%rdi,%rax,4),%xmm0 - - addl %r11d,%r10d - movdqu 48(%r13),%xmm5 - addb $32,%bpl - movl (%rdi,%rcx,4),%edx - xorl %r8d,%r12d - movl %ebx,(%rdi,%rcx,4) - orl %r10d,%r12d - addl 36(%r15),%r9d - addb %dl,%bl - movl 0(%rdi,%rbp,4),%eax - addl $3951481745,%r9d - movzbl %bl,%ebx - xorl %r11d,%r12d - movl %edx,124(%rsi) - addl %r12d,%r9d - addb %al,%cl - roll $21,%r9d - movl $-1,%r12d - pinsrw $7,(%rdi,%rbx,4),%xmm1 - - addl %r10d,%r9d - movq %rbp,%rsi - xorq %rbp,%rbp - movb %sil,%bpl - movq %rcx,%rsi - xorq %rcx,%rcx - movb %sil,%cl - leaq (%rdi,%rbp,4),%rsi - psllq $8,%xmm1 - pxor %xmm0,%xmm5 - pxor %xmm1,%xmm5 - addl 0(%rsp),%r8d - addl 4(%rsp),%r9d - addl 8(%rsp),%r10d - addl 12(%rsp),%r11d - - movdqu %xmm2,(%r14,%r13,1) - movdqu %xmm3,16(%r14,%r13,1) - movdqu %xmm4,32(%r14,%r13,1) - movdqu %xmm5,48(%r14,%r13,1) - leaq 64(%r15),%r15 - leaq 64(%r13),%r13 - cmpq 16(%rsp),%r15 - jb L$oop - - movq 24(%rsp),%r12 - subb %al,%cl - movl %r8d,0(%r12) - movl %r9d,4(%r12) - movl %r10d,8(%r12) - movl %r11d,12(%r12) - subb $1,%bpl - movl %ebp,-8(%rdi) - movl %ecx,-4(%rdi) - - movq 40(%rsp),%r15 - movq 48(%rsp),%r14 - movq 56(%rsp),%r13 - movq 64(%rsp),%r12 - movq 72(%rsp),%rbp - movq 80(%rsp),%rbx - leaq 88(%rsp),%rsp -L$epilogue: -L$abort: - .byte 0xf3,0xc3 - -#endif diff --git a/mac-x86_64/crypto/sha/sha1-x86_64.S b/mac-x86_64/crypto/sha/sha1-x86_64.S index 044dc5b..0509d45 100644 --- a/mac-x86_64/crypto/sha/sha1-x86_64.S +++ b/mac-x86_64/crypto/sha/sha1-x86_64.S @@ -12,6 +12,11 @@ _sha1_block_data_order: movl _OPENSSL_ia32cap_P+8(%rip),%r10d testl $512,%r8d jz L$ialu + andl $268435456,%r8d + andl $1073741824,%r9d + orl %r9d,%r8d + cmpl $1342177280,%r8d + je _avx_shortcut jmp _ssse3_shortcut .p2align 4 @@ -2407,6 +2412,1122 @@ L$done_ssse3: L$epilogue_ssse3: .byte 0xf3,0xc3 + +.p2align 4 +sha1_block_data_order_avx: +_avx_shortcut: + movq %rsp,%rax + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + leaq -64(%rsp),%rsp + vzeroupper + movq %rax,%r14 + andq $-64,%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r11 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + vmovdqa 64(%r11),%xmm6 + vmovdqa -64(%r11),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm11,%xmm0,%xmm4 + vpaddd %xmm11,%xmm1,%xmm5 + vpaddd %xmm11,%xmm2,%xmm6 + vmovdqa %xmm4,0(%rsp) + vmovdqa %xmm5,16(%rsp) + vmovdqa %xmm6,32(%rsp) + jmp L$oop_avx +.p2align 4 +L$oop_avx: + shrdl $2,%ebx,%ebx + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%edi + addl 0(%rsp),%ebp + vpaddd %xmm3,%xmm11,%xmm9 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm8 + addl %esi,%ebp + andl %ebx,%edi + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%ebp + vpxor %xmm2,%xmm8,%xmm8 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + vpxor %xmm8,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vmovdqa %xmm9,48(%rsp) + addl %edi,%edx + andl %eax,%esi + vpsrld $31,%xmm4,%xmm8 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm10 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%edi + addl 8(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm4,%xmm4 + addl %esi,%ecx + andl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm4,%xmm4 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + vpxor %xmm10,%xmm4,%xmm4 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %edi,%ebx + andl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%edi + addl 16(%rsp),%eax + vpaddd %xmm4,%xmm11,%xmm9 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm8 + addl %esi,%eax + andl %ecx,%edi + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm8,%xmm8 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + vpxor %xmm8,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vmovdqa %xmm9,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm8 + xorl %ecx,%ebx + addl %eax,%ebp + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm10 + vpaddd %xmm5,%xmm5,%xmm5 + movl %ebp,%edi + addl 24(%rsp),%edx + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm5,%xmm5 + addl %esi,%edx + andl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm5,%xmm5 + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + vpxor %xmm10,%xmm5,%xmm5 + xorl %eax,%ebp + shldl $5,%edx,%edx + vmovdqa -32(%r11),%xmm11 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%edi + addl 32(%rsp),%ebx + vpaddd %xmm5,%xmm11,%xmm9 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm8 + addl %esi,%ebx + andl %edx,%edi + vpxor %xmm2,%xmm6,%xmm6 + xorl %ebp,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm8,%xmm8 + shrdl $7,%ecx,%ecx + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + vpxor %xmm8,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vmovdqa %xmm9,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm8 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm10 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%edi + addl 40(%rsp),%ebp + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm6,%xmm6 + addl %esi,%ebp + andl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + vpxor %xmm10,%xmm6,%xmm6 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + addl %edi,%edx + andl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%edi + addl 48(%rsp),%ecx + vpaddd %xmm6,%xmm11,%xmm9 + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm8 + addl %esi,%ecx + andl %ebp,%edi + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%ebp + addl %edx,%ecx + vpxor %xmm5,%xmm8,%xmm8 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + vpxor %xmm8,%xmm7,%xmm7 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vmovdqa %xmm9,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm8 + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpslldq $12,%xmm7,%xmm10 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%edi + addl 56(%rsp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm7,%xmm7 + addl %esi,%eax + andl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + vpxor %xmm10,%xmm7,%xmm7 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %edi,%ebp + andl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + vpxor %xmm1,%xmm0,%xmm0 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpaddd %xmm7,%xmm11,%xmm9 + addl %esi,%edx + andl %eax,%edi + vpxor %xmm8,%xmm0,%xmm0 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + movl %edx,%esi + addl 4(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + vpor %xmm8,%xmm0,%xmm0 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm0,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm1,%xmm1 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm1,%xmm1 + addl 28(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + addl %esi,%eax + xorl %edx,%edi + vpaddd %xmm1,%xmm11,%xmm9 + vmovdqa 0(%r11),%xmm11 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm8,%xmm2,%xmm2 + addl 36(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpslld $2,%xmm2,%xmm2 + addl 40(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpor %xmm8,%xmm2,%xmm2 + addl 44(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebx + xorl %ebp,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpalignr $8,%xmm2,%xmm3,%xmm8 + vpxor %xmm0,%xmm4,%xmm4 + addl 0(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + addl %esi,%ecx + xorl %eax,%edi + vpaddd %xmm3,%xmm11,%xmm9 + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpxor %xmm8,%xmm4,%xmm4 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm8 + vmovdqa %xmm9,48(%rsp) + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm8,%xmm4,%xmm4 + addl 12(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm3,%xmm4,%xmm8 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpxor %xmm6,%xmm5,%xmm5 + addl %esi,%edx + xorl %ebx,%edi + vpaddd %xmm4,%xmm11,%xmm9 + shrdl $7,%eax,%eax + addl %ebp,%edx + vpxor %xmm8,%xmm5,%xmm5 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm8,%xmm5,%xmm5 + addl 28(%rsp),%eax + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm8 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + movl %eax,%edi + xorl %ecx,%esi + vpaddd %xmm5,%xmm11,%xmm9 + shldl $5,%eax,%eax + addl %esi,%ebp + vpxor %xmm8,%xmm6,%xmm6 + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 36(%rsp),%edx + vpsrld $30,%xmm6,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + addl 40(%rsp),%ecx + andl %eax,%esi + vpor %xmm8,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%edi + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm8 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + movl %ebx,%edi + xorl %edx,%esi + vpaddd %xmm6,%xmm11,%xmm9 + vmovdqa 32(%r11),%xmm11 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm8,%xmm7,%xmm7 + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%rsp),%ebp + vpsrld $30,%xmm7,%xmm8 + vmovdqa %xmm9,32(%rsp) + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + addl 56(%rsp),%edx + andl %ebx,%esi + vpor %xmm8,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%edi + xorl %ebx,%esi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + shrdl $7,%edx,%edx + vpxor %xmm1,%xmm0,%xmm0 + movl %ecx,%edi + xorl %ebp,%esi + vpaddd %xmm7,%xmm11,%xmm9 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm8,%xmm0,%xmm0 + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 4(%rsp),%eax + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%rsp),%ebp + andl %ecx,%esi + vpor %xmm8,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%edi + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + vpxor %xmm2,%xmm1,%xmm1 + movl %edx,%edi + xorl %eax,%esi + vpaddd %xmm0,%xmm11,%xmm9 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 20(%rsp),%ebx + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + addl 24(%rsp),%eax + andl %edx,%esi + vpor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%edi + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + movl %ebp,%edi + xorl %ebx,%esi + vpaddd %xmm1,%xmm11,%xmm9 + shldl $5,%ebp,%ebp + addl %esi,%edx + vpxor %xmm8,%xmm2,%xmm2 + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 36(%rsp),%ecx + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + addl 40(%rsp),%ebx + andl %ebp,%esi + vpor %xmm8,%xmm2,%xmm2 + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%edi + xorl %ebp,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + vpaddd %xmm3,%xmm11,%xmm9 + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm9,48(%rsp) + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + cmpq %r10,%r9 + je L$done_avx + vmovdqa 64(%r11),%xmm6 + vmovdqa -64(%r11),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %ebp,%esi + vpshufb %xmm6,%xmm1,%xmm1 + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpaddd %xmm11,%xmm0,%xmm4 + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm4,0(%rsp) + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + vpshufb %xmm6,%xmm2,%xmm2 + movl %edx,%edi + shldl $5,%edx,%edx + vpaddd %xmm11,%xmm1,%xmm5 + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vmovdqa %xmm5,16(%rsp) + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + vpshufb %xmm6,%xmm3,%xmm3 + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpaddd %xmm11,%xmm2,%xmm6 + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vmovdqa %xmm6,32(%rsp) + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %ecx,%edi + movl %edx,12(%r8) + xorl %edx,%edi + movl %ebp,16(%r8) + andl %edi,%esi + jmp L$oop_avx + +.p2align 4 +L$done_avx: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vzeroupper + + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + leaq (%r14),%rsi + movq -40(%rsi),%r14 + movq -32(%rsi),%r13 + movq -24(%rsi),%r12 + movq -16(%rsi),%rbp + movq -8(%rsi),%rbx + leaq (%rsi),%rsp +L$epilogue_avx: + .byte 0xf3,0xc3 + .p2align 6 K_XX_XX: .long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 diff --git a/mac-x86_64/crypto/sha/sha256-x86_64.S b/mac-x86_64/crypto/sha/sha256-x86_64.S index da02d4c..0146ff5 100644 --- a/mac-x86_64/crypto/sha/sha256-x86_64.S +++ b/mac-x86_64/crypto/sha/sha256-x86_64.S @@ -11,6 +11,11 @@ _sha256_block_data_order: movl 0(%r11),%r9d movl 4(%r11),%r10d movl 8(%r11),%r11d + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je L$avx_shortcut testl $512,%r10d jnz L$ssse3_shortcut pushq %rbx @@ -2840,4 +2845,1061 @@ L$ssse3_00_47: L$epilogue_ssse3: .byte 0xf3,0xc3 + +.p2align 6 +sha256_block_data_order_avx: +L$avx_shortcut: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $96,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %r11,64+24(%rsp) +L$prologue_avx: + + vzeroupper + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + vmovdqa K256+512+32(%rip),%xmm8 + vmovdqa K256+512+64(%rip),%xmm9 + jmp L$loop_avx +.p2align 4 +L$loop_avx: + vmovdqa K256+512(%rip),%xmm7 + vmovdqu 0(%rsi),%xmm0 + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm7,%xmm0,%xmm0 + leaq K256(%rip),%rbp + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd 0(%rbp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 32(%rbp),%xmm1,%xmm5 + vpaddd 64(%rbp),%xmm2,%xmm6 + vpaddd 96(%rbp),%xmm3,%xmm7 + vmovdqa %xmm4,0(%rsp) + movl %eax,%r14d + vmovdqa %xmm5,16(%rsp) + movl %ebx,%edi + vmovdqa %xmm6,32(%rsp) + xorl %ecx,%edi + vmovdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp L$avx_00_47 + +.p2align 4 +L$avx_00_47: + subq $-128,%rbp + vpalignr $4,%xmm0,%xmm1,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm2,%xmm3,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm0,%xmm0 + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm3,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm0,%xmm0 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm0,%xmm0 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + vpshufd $80,%xmm0,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm0,%xmm0 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 0(%rbp),%xmm0,%xmm6 + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,0(%rsp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm3,%xmm0,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm1,%xmm1 + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm0,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm1,%xmm1 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm1,%xmm1 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + vpshufd $80,%xmm1,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm1,%xmm1 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 32(%rbp),%xmm1,%xmm6 + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,16(%rsp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm0,%xmm1,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm2,%xmm2 + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm1,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm2,%xmm2 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm2,%xmm2 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + vpshufd $80,%xmm2,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm2,%xmm2 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 64(%rbp),%xmm2,%xmm6 + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,32(%rsp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm1,%xmm2,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm3,%xmm3 + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm2,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm3,%xmm3 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm3,%xmm3 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + vpshufd $80,%xmm3,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm3,%xmm3 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 96(%rbp),%xmm3,%xmm6 + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,48(%rsp) + cmpb $0,131(%rbp) + jne L$avx_00_47 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%rdi + movl %r14d,%eax + + addl 0(%rdi),%eax + leaq 64(%rsi),%rsi + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb L$loop_avx + + movq 64+24(%rsp),%rsi + vzeroupper + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$epilogue_avx: + .byte 0xf3,0xc3 + #endif diff --git a/mac-x86_64/crypto/sha/sha512-x86_64.S b/mac-x86_64/crypto/sha/sha512-x86_64.S index 2f5d912..aeabd3f 100644 --- a/mac-x86_64/crypto/sha/sha512-x86_64.S +++ b/mac-x86_64/crypto/sha/sha512-x86_64.S @@ -7,6 +7,17 @@ .p2align 4 _sha512_block_data_order: + leaq _OPENSSL_ia32cap_P(%rip),%r11 + movl 0(%r11),%r9d + movl 4(%r11),%r10d + movl 8(%r11),%r11d + testl $2048,%r10d + jnz L$xop_shortcut + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je L$avx_shortcut pushq %rbx pushq %rbp pushq %r12 @@ -1783,4 +1794,2234 @@ K512: .quad 0x0001020304050607,0x08090a0b0c0d0e0f .quad 0x0001020304050607,0x08090a0b0c0d0e0f .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + +.p2align 6 +sha512_block_data_order_xop: +L$xop_shortcut: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $160,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %r11,128+24(%rsp) +L$prologue_xop: + + vzeroupper + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp L$loop_xop +.p2align 4 +L$loop_xop: + vmovdqa K512+1280(%rip),%xmm11 + vmovdqu 0(%rsi),%xmm0 + leaq K512+128(%rip),%rbp + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vpshufb %xmm11,%xmm0,%xmm0 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm11,%xmm1,%xmm1 + vmovdqu 64(%rsi),%xmm4 + vpshufb %xmm11,%xmm2,%xmm2 + vmovdqu 80(%rsi),%xmm5 + vpshufb %xmm11,%xmm3,%xmm3 + vmovdqu 96(%rsi),%xmm6 + vpshufb %xmm11,%xmm4,%xmm4 + vmovdqu 112(%rsi),%xmm7 + vpshufb %xmm11,%xmm5,%xmm5 + vpaddq -128(%rbp),%xmm0,%xmm8 + vpshufb %xmm11,%xmm6,%xmm6 + vpaddq -96(%rbp),%xmm1,%xmm9 + vpshufb %xmm11,%xmm7,%xmm7 + vpaddq -64(%rbp),%xmm2,%xmm10 + vpaddq -32(%rbp),%xmm3,%xmm11 + vmovdqa %xmm8,0(%rsp) + vpaddq 0(%rbp),%xmm4,%xmm8 + vmovdqa %xmm9,16(%rsp) + vpaddq 32(%rbp),%xmm5,%xmm9 + vmovdqa %xmm10,32(%rsp) + vpaddq 64(%rbp),%xmm6,%xmm10 + vmovdqa %xmm11,48(%rsp) + vpaddq 96(%rbp),%xmm7,%xmm11 + vmovdqa %xmm8,64(%rsp) + movq %rax,%r14 + vmovdqa %xmm9,80(%rsp) + movq %rbx,%rdi + vmovdqa %xmm10,96(%rsp) + xorq %rcx,%rdi + vmovdqa %xmm11,112(%rsp) + movq %r8,%r13 + jmp L$xop_00_47 + +.p2align 4 +L$xop_00_47: + addq $256,%rbp + vpalignr $8,%xmm0,%xmm1,%xmm8 + rorq $23,%r13 + movq %r14,%rax + vpalignr $8,%xmm4,%xmm5,%xmm11 + movq %r9,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r8,%r13 + xorq %r10,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rax,%r14 + vpaddq %xmm11,%xmm0,%xmm0 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 +.byte 143,72,120,195,209,7 + xorq %r10,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,223,3 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm7,%xmm10 + addq %r11,%rdx + addq %rdi,%r11 + vpaddq %xmm8,%xmm0,%xmm0 + movq %rdx,%r13 + addq %r11,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r11 + vpxor %xmm10,%xmm11,%xmm11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + vpaddq %xmm11,%xmm0,%xmm0 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + vpaddq -128(%rbp),%xmm0,%xmm10 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,0(%rsp) + vpalignr $8,%xmm1,%xmm2,%xmm8 + rorq $23,%r13 + movq %r14,%r10 + vpalignr $8,%xmm5,%xmm6,%xmm11 + movq %rdx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rcx,%r13 + xorq %r8,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r10,%r14 + vpaddq %xmm11,%xmm1,%xmm1 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 +.byte 143,72,120,195,209,7 + xorq %r8,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,216,3 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm0,%xmm10 + addq %r9,%rbx + addq %rdi,%r9 + vpaddq %xmm8,%xmm1,%xmm1 + movq %rbx,%r13 + addq %r9,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r9 + vpxor %xmm10,%xmm11,%xmm11 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + vpaddq %xmm11,%xmm1,%xmm1 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + vpaddq -96(%rbp),%xmm1,%xmm10 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,16(%rsp) + vpalignr $8,%xmm2,%xmm3,%xmm8 + rorq $23,%r13 + movq %r14,%r8 + vpalignr $8,%xmm6,%xmm7,%xmm11 + movq %rbx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rax,%r13 + xorq %rcx,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r8,%r14 + vpaddq %xmm11,%xmm2,%xmm2 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 +.byte 143,72,120,195,209,7 + xorq %rcx,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,217,3 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm1,%xmm10 + addq %rdx,%r11 + addq %rdi,%rdx + vpaddq %xmm8,%xmm2,%xmm2 + movq %r11,%r13 + addq %rdx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rdx + vpxor %xmm10,%xmm11,%xmm11 + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + vpaddq %xmm11,%xmm2,%xmm2 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + vpaddq -64(%rbp),%xmm2,%xmm10 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,32(%rsp) + vpalignr $8,%xmm3,%xmm4,%xmm8 + rorq $23,%r13 + movq %r14,%rcx + vpalignr $8,%xmm7,%xmm0,%xmm11 + movq %r11,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r10,%r13 + xorq %rax,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rcx,%r14 + vpaddq %xmm11,%xmm3,%xmm3 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 +.byte 143,72,120,195,209,7 + xorq %rax,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,218,3 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm2,%xmm10 + addq %rbx,%r9 + addq %rdi,%rbx + vpaddq %xmm8,%xmm3,%xmm3 + movq %r9,%r13 + addq %rbx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rbx + vpxor %xmm10,%xmm11,%xmm11 + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + vpaddq %xmm11,%xmm3,%xmm3 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + vpaddq -32(%rbp),%xmm3,%xmm10 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,48(%rsp) + vpalignr $8,%xmm4,%xmm5,%xmm8 + rorq $23,%r13 + movq %r14,%rax + vpalignr $8,%xmm0,%xmm1,%xmm11 + movq %r9,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r8,%r13 + xorq %r10,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rax,%r14 + vpaddq %xmm11,%xmm4,%xmm4 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 +.byte 143,72,120,195,209,7 + xorq %r10,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,219,3 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm3,%xmm10 + addq %r11,%rdx + addq %rdi,%r11 + vpaddq %xmm8,%xmm4,%xmm4 + movq %rdx,%r13 + addq %r11,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r11 + vpxor %xmm10,%xmm11,%xmm11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + vpaddq %xmm11,%xmm4,%xmm4 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + vpaddq 0(%rbp),%xmm4,%xmm10 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,64(%rsp) + vpalignr $8,%xmm5,%xmm6,%xmm8 + rorq $23,%r13 + movq %r14,%r10 + vpalignr $8,%xmm1,%xmm2,%xmm11 + movq %rdx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rcx,%r13 + xorq %r8,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r10,%r14 + vpaddq %xmm11,%xmm5,%xmm5 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 +.byte 143,72,120,195,209,7 + xorq %r8,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,220,3 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm4,%xmm10 + addq %r9,%rbx + addq %rdi,%r9 + vpaddq %xmm8,%xmm5,%xmm5 + movq %rbx,%r13 + addq %r9,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r9 + vpxor %xmm10,%xmm11,%xmm11 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + vpaddq %xmm11,%xmm5,%xmm5 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + vpaddq 32(%rbp),%xmm5,%xmm10 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,80(%rsp) + vpalignr $8,%xmm6,%xmm7,%xmm8 + rorq $23,%r13 + movq %r14,%r8 + vpalignr $8,%xmm2,%xmm3,%xmm11 + movq %rbx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rax,%r13 + xorq %rcx,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r8,%r14 + vpaddq %xmm11,%xmm6,%xmm6 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 +.byte 143,72,120,195,209,7 + xorq %rcx,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,221,3 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm5,%xmm10 + addq %rdx,%r11 + addq %rdi,%rdx + vpaddq %xmm8,%xmm6,%xmm6 + movq %r11,%r13 + addq %rdx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rdx + vpxor %xmm10,%xmm11,%xmm11 + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + vpaddq %xmm11,%xmm6,%xmm6 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + vpaddq 64(%rbp),%xmm6,%xmm10 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,96(%rsp) + vpalignr $8,%xmm7,%xmm0,%xmm8 + rorq $23,%r13 + movq %r14,%rcx + vpalignr $8,%xmm3,%xmm4,%xmm11 + movq %r11,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r10,%r13 + xorq %rax,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rcx,%r14 + vpaddq %xmm11,%xmm7,%xmm7 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 +.byte 143,72,120,195,209,7 + xorq %rax,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,222,3 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm6,%xmm10 + addq %rbx,%r9 + addq %rdi,%rbx + vpaddq %xmm8,%xmm7,%xmm7 + movq %r9,%r13 + addq %rbx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rbx + vpxor %xmm10,%xmm11,%xmm11 + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + vpaddq %xmm11,%xmm7,%xmm7 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + vpaddq 96(%rbp),%xmm7,%xmm10 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,112(%rsp) + cmpb $0,135(%rbp) + jne L$xop_00_47 + rorq $23,%r13 + movq %r14,%rax + movq %r9,%r12 + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + rorq $4,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + rorq $6,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + rorq $28,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + rorq $23,%r13 + movq %r14,%r11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + rorq $23,%r13 + movq %r14,%r10 + movq %rdx,%r12 + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + rorq $4,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + rorq $6,%r14 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + rorq $28,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + rorq $23,%r13 + movq %r14,%r9 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + rorq $23,%r13 + movq %r14,%r8 + movq %rbx,%r12 + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + rorq $4,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + rorq $6,%r14 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + rorq $28,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + rorq $23,%r13 + movq %r14,%rdx + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + rorq $23,%r13 + movq %r14,%rcx + movq %r11,%r12 + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + rorq $4,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + rorq $6,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + rorq $28,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + rorq $23,%r13 + movq %r14,%rbx + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + rorq $23,%r13 + movq %r14,%rax + movq %r9,%r12 + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + rorq $4,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + rorq $6,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + rorq $28,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + rorq $23,%r13 + movq %r14,%r11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + rorq $23,%r13 + movq %r14,%r10 + movq %rdx,%r12 + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + rorq $4,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + rorq $6,%r14 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + rorq $28,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + rorq $23,%r13 + movq %r14,%r9 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + rorq $23,%r13 + movq %r14,%r8 + movq %rbx,%r12 + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + rorq $4,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + rorq $6,%r14 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + rorq $28,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + rorq $23,%r13 + movq %r14,%rdx + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + rorq $23,%r13 + movq %r14,%rcx + movq %r11,%r12 + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + rorq $4,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + rorq $6,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + rorq $28,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + rorq $23,%r13 + movq %r14,%rbx + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + movq 128+0(%rsp),%rdi + movq %r14,%rax + + addq 0(%rdi),%rax + leaq 128(%rsi),%rsi + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb L$loop_xop + + movq 128+24(%rsp),%rsi + vzeroupper + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$epilogue_xop: + .byte 0xf3,0xc3 + + +.p2align 6 +sha512_block_data_order_avx: +L$avx_shortcut: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp,%r11 + shlq $4,%rdx + subq $160,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %r11,128+24(%rsp) +L$prologue_avx: + + vzeroupper + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp L$loop_avx +.p2align 4 +L$loop_avx: + vmovdqa K512+1280(%rip),%xmm11 + vmovdqu 0(%rsi),%xmm0 + leaq K512+128(%rip),%rbp + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vpshufb %xmm11,%xmm0,%xmm0 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm11,%xmm1,%xmm1 + vmovdqu 64(%rsi),%xmm4 + vpshufb %xmm11,%xmm2,%xmm2 + vmovdqu 80(%rsi),%xmm5 + vpshufb %xmm11,%xmm3,%xmm3 + vmovdqu 96(%rsi),%xmm6 + vpshufb %xmm11,%xmm4,%xmm4 + vmovdqu 112(%rsi),%xmm7 + vpshufb %xmm11,%xmm5,%xmm5 + vpaddq -128(%rbp),%xmm0,%xmm8 + vpshufb %xmm11,%xmm6,%xmm6 + vpaddq -96(%rbp),%xmm1,%xmm9 + vpshufb %xmm11,%xmm7,%xmm7 + vpaddq -64(%rbp),%xmm2,%xmm10 + vpaddq -32(%rbp),%xmm3,%xmm11 + vmovdqa %xmm8,0(%rsp) + vpaddq 0(%rbp),%xmm4,%xmm8 + vmovdqa %xmm9,16(%rsp) + vpaddq 32(%rbp),%xmm5,%xmm9 + vmovdqa %xmm10,32(%rsp) + vpaddq 64(%rbp),%xmm6,%xmm10 + vmovdqa %xmm11,48(%rsp) + vpaddq 96(%rbp),%xmm7,%xmm11 + vmovdqa %xmm8,64(%rsp) + movq %rax,%r14 + vmovdqa %xmm9,80(%rsp) + movq %rbx,%rdi + vmovdqa %xmm10,96(%rsp) + xorq %rcx,%rdi + vmovdqa %xmm11,112(%rsp) + movq %r8,%r13 + jmp L$avx_00_47 + +.p2align 4 +L$avx_00_47: + addq $256,%rbp + vpalignr $8,%xmm0,%xmm1,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm4,%xmm5,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm0,%xmm0 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 0(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm7,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm7,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm0,%xmm0 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm7,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 8(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm0,%xmm0 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq -128(%rbp),%xmm0,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,0(%rsp) + vpalignr $8,%xmm1,%xmm2,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm5,%xmm6,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm1,%xmm1 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 16(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm0,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm0,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm1,%xmm1 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm0,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 24(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm1,%xmm1 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq -96(%rbp),%xmm1,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,16(%rsp) + vpalignr $8,%xmm2,%xmm3,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm6,%xmm7,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm2,%xmm2 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 32(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm1,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm1,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm2,%xmm2 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm1,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 40(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm2,%xmm2 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq -64(%rbp),%xmm2,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,32(%rsp) + vpalignr $8,%xmm3,%xmm4,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm7,%xmm0,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm3,%xmm3 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 48(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm2,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm2,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm3,%xmm3 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm2,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 56(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm3,%xmm3 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq -32(%rbp),%xmm3,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,48(%rsp) + vpalignr $8,%xmm4,%xmm5,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm0,%xmm1,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm4,%xmm4 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 64(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm3,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm3,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm4,%xmm4 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm3,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 72(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm4,%xmm4 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq 0(%rbp),%xmm4,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,64(%rsp) + vpalignr $8,%xmm5,%xmm6,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm1,%xmm2,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm5,%xmm5 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 80(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm4,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm4,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm5,%xmm5 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm4,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 88(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm5,%xmm5 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq 32(%rbp),%xmm5,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,80(%rsp) + vpalignr $8,%xmm6,%xmm7,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm2,%xmm3,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm6,%xmm6 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 96(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm5,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm5,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm6,%xmm6 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm5,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 104(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm6,%xmm6 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq 64(%rbp),%xmm6,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,96(%rsp) + vpalignr $8,%xmm7,%xmm0,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm3,%xmm4,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm7,%xmm7 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 112(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm6,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm6,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm7,%xmm7 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm6,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 120(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm7,%xmm7 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq 96(%rbp),%xmm7,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,112(%rsp) + cmpb $0,135(%rbp) + jne L$avx_00_47 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + movq 128+0(%rsp),%rdi + movq %r14,%rax + + addq 0(%rdi),%rax + leaq 128(%rsi),%rsi + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb L$loop_avx + + movq 128+24(%rsp),%rsi + vzeroupper + movq (%rsi),%r15 + movq 8(%rsi),%r14 + movq 16(%rsi),%r13 + movq 24(%rsi),%r12 + movq 32(%rsi),%rbp + movq 40(%rsi),%rbx + leaq 48(%rsi),%rsp +L$epilogue_avx: + .byte 0xf3,0xc3 + #endif @@ -109,6 +109,8 @@ crypto_sources := \ src/crypto/cpu-arm.c\ src/crypto/cpu-intel.c\ src/crypto/crypto.c\ + src/crypto/curve25519/curve25519.c\ + src/crypto/curve25519/x25519-x86_64.c\ src/crypto/des/des.c\ src/crypto/dh/check.c\ src/crypto/dh/dh.c\ @@ -302,6 +304,7 @@ ssl_sources := \ src/ssl/ssl_buffer.c\ src/ssl/ssl_cert.c\ src/ssl/ssl_cipher.c\ + src/ssl/ssl_ecdh.c\ src/ssl/ssl_file.c\ src/ssl/ssl_lib.c\ src/ssl/ssl_rsa.c\ @@ -317,6 +320,7 @@ tool_sources := \ src/tool/client.cc\ src/tool/const.cc\ src/tool/digest.cc\ + src/tool/generate_ed25519.cc\ src/tool/genrsa.cc\ src/tool/pkcs12.cc\ src/tool/rand.cc\ @@ -345,6 +349,7 @@ linux_arm_sources := \ linux-arm/crypto/sha/sha512-armv4.S\ src/crypto/chacha/chacha_vec_arm.S\ src/crypto/cpu-arm-asm.S\ + src/crypto/curve25519/asm/x25519-asm-arm.S\ src/crypto/poly1305/poly1305_arm_asm.S\ linux_x86_sources := \ @@ -375,7 +380,6 @@ linux_x86_64_sources := \ linux-x86_64/crypto/modes/aesni-gcm-x86_64.S\ linux-x86_64/crypto/modes/ghash-x86_64.S\ linux-x86_64/crypto/rand/rdrand-x86_64.S\ - linux-x86_64/crypto/rc4/rc4-md5-x86_64.S\ linux-x86_64/crypto/rc4/rc4-x86_64.S\ linux-x86_64/crypto/sha/sha1-x86_64.S\ linux-x86_64/crypto/sha/sha256-x86_64.S\ @@ -409,7 +413,6 @@ mac_x86_64_sources := \ mac-x86_64/crypto/modes/aesni-gcm-x86_64.S\ mac-x86_64/crypto/modes/ghash-x86_64.S\ mac-x86_64/crypto/rand/rdrand-x86_64.S\ - mac-x86_64/crypto/rc4/rc4-md5-x86_64.S\ mac-x86_64/crypto/rc4/rc4-x86_64.S\ mac-x86_64/crypto/sha/sha1-x86_64.S\ mac-x86_64/crypto/sha/sha256-x86_64.S\ @@ -443,7 +446,6 @@ win_x86_64_sources := \ win-x86_64/crypto/modes/aesni-gcm-x86_64.asm\ win-x86_64/crypto/modes/ghash-x86_64.asm\ win-x86_64/crypto/rand/rdrand-x86_64.asm\ - win-x86_64/crypto/rc4/rc4-md5-x86_64.asm\ win-x86_64/crypto/rc4/rc4-x86_64.asm\ win-x86_64/crypto/sha/sha1-x86_64.asm\ win-x86_64/crypto/sha/sha256-x86_64.asm\ diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index 89f4ce5..6651f29 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -105,6 +105,7 @@ add_subdirectory(rc4) add_subdirectory(conf) add_subdirectory(chacha) add_subdirectory(poly1305) +add_subdirectory(curve25519) # Level 1, depends only on 0.* add_subdirectory(digest) @@ -174,6 +175,7 @@ add_library( $<TARGET_OBJECTS:conf> $<TARGET_OBJECTS:chacha> $<TARGET_OBJECTS:poly1305> + $<TARGET_OBJECTS:curve25519> $<TARGET_OBJECTS:buf> $<TARGET_OBJECTS:bn> $<TARGET_OBJECTS:bio> diff --git a/src/crypto/asn1/asn1_lib.c b/src/crypto/asn1/asn1_lib.c index a109749..0f2ce50 100644 --- a/src/crypto/asn1/asn1_lib.c +++ b/src/crypto/asn1/asn1_lib.c @@ -64,10 +64,6 @@ #include <openssl/mem.h> -/* Used in asn1_mac.h. - * TODO(davidben): Remove this once asn1_mac.h is gone or trimmed. */ -OPENSSL_DECLARE_ERROR_REASON(ASN1, MALLOC_FAILURE); - /* Cross-module errors from crypto/x509/i2d_pr.c */ OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE); diff --git a/src/crypto/asn1/asn1_par.c b/src/crypto/asn1/asn1_par.c index aff3e2b..e04aa1e 100644 --- a/src/crypto/asn1/asn1_par.c +++ b/src/crypto/asn1/asn1_par.c @@ -61,6 +61,8 @@ #include <openssl/mem.h> +#define ASN1_PARSE_MAXDEPTH 128 + static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed, int indent); static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, @@ -125,6 +127,13 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse #else dump_indent = 6; /* Because we know BIO_dump_indent() */ #endif + + if (depth > ASN1_PARSE_MAXDEPTH) + { + BIO_puts(bp, "BAD RECURSION DEPTH\n"); + return 0; + } + p= *pp; tot=p+length; op=p-1; diff --git a/src/crypto/asn1/tasn_dec.c b/src/crypto/asn1/tasn_dec.c index d852ad7..7c81753 100644 --- a/src/crypto/asn1/tasn_dec.c +++ b/src/crypto/asn1/tasn_dec.c @@ -170,6 +170,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, int otag; int ret = 0; ASN1_VALUE **pchptr, *ptmpval; + int combine = aclass & ASN1_TFLG_COMBINE; if (!pval) return 0; if (aux && aux->asn1_cb) @@ -526,7 +527,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, auxerr: OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); err: - ASN1_item_ex_free(pval, it); + if (combine == 0) + ASN1_item_ex_free(pval, it); if (errtt) ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname); @@ -742,7 +744,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, { /* Nothing special */ ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), - -1, 0, opt, ctx); + -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); diff --git a/src/crypto/asn1/tasn_prn.c b/src/crypto/asn1/tasn_prn.c index 6a097a1..a574055 100644 --- a/src/crypto/asn1/tasn_prn.c +++ b/src/crypto/asn1/tasn_prn.c @@ -72,7 +72,7 @@ /* ASN1_PCTX routines */ -ASN1_PCTX default_pctx = +static ASN1_PCTX default_pctx = { ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ 0, /* nm_flags */ diff --git a/src/crypto/bio/pair.c b/src/crypto/bio/pair.c index 6f78890..fba4be2 100644 --- a/src/crypto/bio/pair.c +++ b/src/crypto/bio/pair.c @@ -256,8 +256,8 @@ int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) { return 0; } + assert(peer_b->len >= bytes_read); peer_b->len -= bytes_read; - assert(peer_b->len >= 0); assert(peer_b->offset + bytes_read <= peer_b->size); /* Move read offset. If zero_copy_write_lock == 1 we must advance the diff --git a/src/crypto/bn/add.c b/src/crypto/bn/add.c index a043d83..23f9f80 100644 --- a/src/crypto/bn/add.c +++ b/src/crypto/bn/add.c @@ -56,6 +56,8 @@ #include <openssl/bn.h> +#include <string.h> + #include <openssl/err.h> #include <openssl/mem.h> @@ -311,27 +313,8 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { } } - if (rp != ap) { - for (;;) { - if (!dif--) { - break; - } - rp[0] = ap[0]; - if (!dif--) { - break; - } - rp[1] = ap[1]; - if (!dif--) { - break; - } - rp[2] = ap[2]; - if (!dif--) { - break; - } - rp[3] = ap[3]; - rp += 4; - ap += 4; - } + if (dif > 0 && rp != ap) { + memcpy(rp, ap, sizeof(*rp) * dif); } r->top = max; diff --git a/src/crypto/bn/asm/x86_64-mont5.pl b/src/crypto/bn/asm/x86_64-mont5.pl index 38def07..3c5a8fc 100644 --- a/src/crypto/bn/asm/x86_64-mont5.pl +++ b/src/crypto/bn/asm/x86_64-mont5.pl @@ -1770,6 +1770,15 @@ sqr8x_reduction: .align 32 .L8x_tail_done: add (%rdx),%r8 # can this overflow? + adc \$0,%r9 + adc \$0,%r10 + adc \$0,%r11 + adc \$0,%r12 + adc \$0,%r13 + adc \$0,%r14 + adc \$0,%r15 # can't overflow, because we + # started with "overhung" part + # of multiplication xor %rax,%rax neg $carry @@ -3116,6 +3125,15 @@ sqrx8x_reduction: .align 32 .Lsqrx8x_tail_done: add 24+8(%rsp),%r8 # can this overflow? + adc \$0,%r9 + adc \$0,%r10 + adc \$0,%r11 + adc \$0,%r12 + adc \$0,%r13 + adc \$0,%r14 + adc \$0,%r15 # can't overflow, because we + # started with "overhung" part + # of multiplication mov $carry,%rax # xor %rax,%rax sub 16+8(%rsp),$carry # mov 16(%rsp),%cf @@ -3159,13 +3177,11 @@ my ($rptr,$nptr)=("%rdx","%rbp"); my @ri=map("%r$_",(10..13)); my @ni=map("%r$_",(14..15)); $code.=<<___; - xor %rbx,%rbx + xor %ebx,%ebx sub %r15,%rsi # compare top-most words adc %rbx,%rbx mov %rcx,%r10 # -$num - .byte 0x67 or %rbx,%rax - .byte 0x67 mov %rcx,%r9 # -$num xor \$1,%rax sar \$3+2,%rcx # cf=0 diff --git a/src/crypto/bn/bn.c b/src/crypto/bn/bn.c index b342749..543c148 100644 --- a/src/crypto/bn/bn.c +++ b/src/crypto/bn/bn.c @@ -166,11 +166,10 @@ void BN_clear(BIGNUM *bn) { } const BIGNUM *BN_value_one(void) { - static const BN_ULONG data_one = 1; - static const BIGNUM const_one = {(BN_ULONG *)&data_one, 1, 1, 0, - BN_FLG_STATIC_DATA}; + static const BN_ULONG kOneLimbs[1] = { 1 }; + static const BIGNUM kOne = STATIC_BIGNUM(kOneLimbs); - return &const_one; + return &kOne; } void BN_with_flags(BIGNUM *out, const BIGNUM *in, int flags) { diff --git a/src/crypto/bn/bn_test.cc b/src/crypto/bn/bn_test.cc index 47093a7..e7e04f1 100644 --- a/src/crypto/bn/bn_test.cc +++ b/src/crypto/bn/bn_test.cc @@ -76,6 +76,8 @@ #include <stdio.h> #include <string.h> +#include <utility> + #include <openssl/bn.h> #include <openssl/crypto.h> #include <openssl/err.h> @@ -211,7 +213,7 @@ int main(int argc, char *argv[]) { if (!sample) { return 1; } - if (!test_lshift(bc_file.get(), ctx.get(), bssl::move(sample))) { + if (!test_lshift(bc_file.get(), ctx.get(), std::move(sample))) { return 1; } flush_fp(bc_file.get()); @@ -328,6 +330,13 @@ int main(int argc, char *argv[]) { return 0; } +static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) { + BIGNUM *raw = NULL; + int ret = BN_hex2bn(&raw, in); + out->reset(raw); + return ret; +} + static bool test_add(FILE *fp) { ScopedBIGNUM a(BN_new()); ScopedBIGNUM b(BN_new()); @@ -1105,6 +1114,27 @@ static bool test_mod_exp(FILE *fp, BN_CTX *ctx) { return false; } } + + // Regression test for carry propagation bug in sqr8x_reduction. + if (!HexToBIGNUM(&a, "050505050505") || + !HexToBIGNUM(&b, "02") || + !HexToBIGNUM( + &c, + "4141414141414141414141274141414141414141414141414141414141414141" + "4141414141414141414141414141414141414141414141414141414141414141" + "4141414141414141414141800000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000001") || + !BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx) || + !BN_mul(e.get(), a.get(), a.get(), ctx)) { + return false; + } + if (BN_cmp(d.get(), e.get()) != 0) { + fprintf(stderr, "BN_mod_exp and BN_mul produce different results!\n"); + return false; + } + return true; } @@ -1286,23 +1316,23 @@ static bool test_exp(FILE *fp, BN_CTX *ctx) { // test_exp_mod_zero tests that 1**0 mod 1 == 0. static bool test_exp_mod_zero(void) { - ScopedBIGNUM zero(BN_new()); - if (!zero) { + ScopedBIGNUM zero(BN_new()), a(BN_new()), r(BN_new()); + if (!zero || !a || !r || !BN_rand(a.get(), 1024, 0, 0)) { return false; } BN_zero(zero.get()); - ScopedBN_CTX ctx(BN_CTX_new()); - ScopedBIGNUM r(BN_new()); - if (!ctx || !r || - !BN_mod_exp(r.get(), BN_value_one(), zero.get(), BN_value_one(), ctx.get())) { - return false; - } - - if (!BN_is_zero(r.get())) { - fprintf(stderr, "1**0 mod 1 = "); - BN_print_fp(stderr, r.get()); - fprintf(stderr, ", should be 0\n"); + if (!BN_mod_exp(r.get(), a.get(), zero.get(), BN_value_one(), nullptr) || + !BN_is_zero(r.get()) || + !BN_mod_exp_mont(r.get(), a.get(), zero.get(), BN_value_one(), nullptr, + nullptr) || + !BN_is_zero(r.get()) || + !BN_mod_exp_mont_consttime(r.get(), a.get(), zero.get(), BN_value_one(), + nullptr, nullptr) || + !BN_is_zero(r.get()) || + !BN_mod_exp_mont_word(r.get(), 42, zero.get(), BN_value_one(), nullptr, + nullptr) || + !BN_is_zero(r.get())) { return false; } @@ -1543,13 +1573,6 @@ static bool test_dec2bn(BN_CTX *ctx) { return true; } -static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) { - BIGNUM *raw = NULL; - int ret = BN_hex2bn(&raw, in); - out->reset(raw); - return ret; -} - static bool test_hex2bn(BN_CTX *ctx) { ScopedBIGNUM bn; int ret = HexToBIGNUM(&bn, "0"); diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c index 0122709..1f7af64 100644 --- a/src/crypto/bn/convert.c +++ b/src/crypto/bn/convert.c @@ -63,6 +63,7 @@ #include <string.h> #include <openssl/bio.h> +#include <openssl/bytestring.h> #include <openssl/err.h> #include <openssl/mem.h> @@ -195,6 +196,11 @@ int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in) { return 1; } +int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in) { + uint8_t *ptr; + return CBB_add_space(out, &ptr, len) && BN_bn2bin_padded(ptr, len, in); +} + static const char hextable[] = "0123456789abcdef"; char *BN_bn2hex(const BIGNUM *bn) { diff --git a/src/crypto/bn/div.c b/src/crypto/bn/div.c index 779dda2..f9e144a 100644 --- a/src/crypto/bn/div.c +++ b/src/crypto/bn/div.c @@ -260,10 +260,10 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, q = BN_MASK2; } else { /* n0 < d0 */ -#ifdef BN_LLONG +#ifdef BN_ULLONG BN_ULLONG t2; -#if defined(BN_LLONG) && !defined(div_asm) +#if defined(BN_ULLONG) && !defined(div_asm) q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2) | n1) / d0); #else q = div_asm(n0, n1, d0); @@ -288,7 +288,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, } t2 -= d1; } -#else /* !BN_LLONG */ +#else /* !BN_ULLONG */ BN_ULONG t2l, t2h; #if defined(div_asm) @@ -331,7 +331,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, } t2l -= d1; } -#endif /* !BN_LLONG */ +#endif /* !BN_ULLONG */ } l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q); @@ -601,7 +601,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) { } BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) { -#ifndef BN_LLONG +#ifndef BN_ULLONG BN_ULONG ret = 0; #else BN_ULLONG ret = 0; @@ -614,7 +614,7 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) { w &= BN_MASK2; for (i = a->top - 1; i >= 0; i--) { -#ifndef BN_LLONG +#ifndef BN_ULLONG ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w; ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w; #else diff --git a/src/crypto/bn/exponentiation.c b/src/crypto/bn/exponentiation.c index c580248..72a8db4 100644 --- a/src/crypto/bn/exponentiation.c +++ b/src/crypto/bn/exponentiation.c @@ -445,8 +445,12 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, bits = BN_num_bits(p); if (bits == 0) { - ret = BN_one(r); - return ret; + /* x**0 mod 1 is still zero. */ + if (BN_is_one(m)) { + BN_zero(r); + return 1; + } + return BN_one(r); } BN_CTX_start(ctx); @@ -632,8 +636,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, } bits = BN_num_bits(p); if (bits == 0) { - ret = BN_one(rr); - return ret; + /* x**0 mod 1 is still zero. */ + if (BN_is_one(m)) { + BN_zero(rr); + return 1; + } + return BN_one(rr); } BN_CTX_start(ctx); @@ -875,8 +883,12 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, bits = BN_num_bits(p); if (bits == 0) { - ret = BN_one(rr); - return ret; + /* x**0 mod 1 is still zero. */ + if (BN_is_one(m)) { + BN_zero(rr); + return 1; + } + return BN_one(rr); } BN_CTX_start(ctx); @@ -1230,17 +1242,14 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, if (bits == 0) { /* x**0 mod 1 is still zero. */ if (BN_is_one(m)) { - ret = 1; BN_zero(rr); - } else { - ret = BN_one(rr); + return 1; } - return ret; + return BN_one(rr); } if (a == 0) { BN_zero(rr); - ret = 1; - return ret; + return 1; } BN_CTX_start(ctx); diff --git a/src/crypto/bn/gcd.c b/src/crypto/bn/gcd.c index e106149..41ca6d2 100644 --- a/src/crypto/bn/gcd.c +++ b/src/crypto/bn/gcd.c @@ -279,7 +279,7 @@ BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, * sign*Y*a == A (mod |n|). */ - if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) { + if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS2 <= 32 ? 450 : 2048))) { /* Binary inversion algorithm; requires odd modulus. * This is faster than the general algorithm if the modulus * is sufficiently small (about 400 .. 500 bits on 32-bit diff --git a/src/crypto/bn/generic.c b/src/crypto/bn/generic.c index 7fd4819..7303ca5 100644 --- a/src/crypto/bn/generic.c +++ b/src/crypto/bn/generic.c @@ -69,13 +69,7 @@ (!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || \ (defined(OPENSSL_X86_64) && defined(OPENSSL_WINDOWS)) -#if defined(OPENSSL_WINDOWS) -#define alloca _alloca -#else -#include <alloca.h> -#endif - -#ifdef BN_LLONG +#ifdef BN_ULLONG #define mul_add(r, a, w, c) \ { \ BN_ULLONG t; \ @@ -222,9 +216,9 @@ (c) = h & BN_MASK2; \ (r) = l & BN_MASK2; \ } -#endif /* !BN_LLONG */ +#endif /* !BN_ULLONG */ -#if defined(BN_LLONG) || defined(BN_UMULT_HIGH) +#if defined(BN_ULLONG) || defined(BN_UMULT_HIGH) BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) { @@ -304,7 +298,7 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) { } } -#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */ +#else /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) { @@ -390,9 +384,9 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) { } } -#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */ +#endif /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */ -#if defined(BN_LLONG) +#if defined(BN_ULLONG) BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) { return (BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2) | l) / (BN_ULLONG)d); @@ -470,9 +464,9 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) { return ret; } -#endif /* !defined(BN_LLONG) */ +#endif /* !defined(BN_ULLONG) */ -#ifdef BN_LLONG +#ifdef BN_ULLONG BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) { BN_ULLONG ll = 0; @@ -512,7 +506,7 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, return (BN_ULONG)ll; } -#else /* !BN_LLONG */ +#else /* !BN_ULLONG */ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) { @@ -569,7 +563,7 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, return (BN_ULONG)c; } -#endif /* !BN_LLONG */ +#endif /* !BN_ULLONG */ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) { @@ -631,7 +625,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, /* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */ -#ifdef BN_LLONG +#ifdef BN_ULLONG /* Keep in mind that additions to multiplication result can not overflow, * because its high half cannot be all-ones. */ @@ -722,7 +716,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, #define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) -#else /* !BN_LLONG */ +#else /* !BN_ULLONG */ /* Keep in mind that additions to hi can not overflow, because * the high word of a multiplication result cannot be all-ones. */ @@ -774,7 +768,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, } while (0) #define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) -#endif /* !BN_LLONG */ +#endif /* !BN_ULLONG */ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) { BN_ULONG c1, c2, c3; diff --git a/src/crypto/bn/internal.h b/src/crypto/bn/internal.h index 0d0eb44..72ef4e9 100644 --- a/src/crypto/bn/internal.h +++ b/src/crypto/bn/internal.h @@ -144,44 +144,41 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits); #if !defined(_MSC_VER) /* MSVC doesn't support two-word integers on 64-bit. */ -#define BN_LLONG __int128_t #define BN_ULLONG __uint128_t #endif -#define BN_BITS 128 #define BN_BITS2 64 #define BN_BYTES 8 #define BN_BITS4 32 -#define BN_MASK (0xffffffffffffffffffffffffffffffffLL) -#define BN_MASK2 (0xffffffffffffffffL) -#define BN_MASK2l (0xffffffffL) -#define BN_MASK2h (0xffffffff00000000L) -#define BN_MASK2h1 (0xffffffff80000000L) -#define BN_TBIT (0x8000000000000000L) +#define BN_MASK2 (0xffffffffffffffffUL) +#define BN_MASK2l (0xffffffffUL) +#define BN_MASK2h (0xffffffff00000000UL) +#define BN_MASK2h1 (0xffffffff80000000UL) +#define BN_TBIT (0x8000000000000000UL) #define BN_DEC_CONV (10000000000000000000UL) #define BN_DEC_NUM 19 +#define TOBN(hi, lo) ((BN_ULONG)hi << 32 | lo) #elif defined(OPENSSL_32_BIT) -#define BN_LLONG int64_t #define BN_ULLONG uint64_t -#define BN_MASK (0xffffffffffffffffLL) -#define BN_BITS 64 #define BN_BITS2 32 #define BN_BYTES 4 #define BN_BITS4 16 -#define BN_MASK2 (0xffffffffL) -#define BN_MASK2l (0xffff) -#define BN_MASK2h1 (0xffff8000L) -#define BN_MASK2h (0xffff0000L) -#define BN_TBIT (0x80000000L) -#define BN_DEC_CONV (1000000000L) +#define BN_MASK2 (0xffffffffUL) +#define BN_MASK2l (0xffffUL) +#define BN_MASK2h1 (0xffff8000UL) +#define BN_MASK2h (0xffff0000UL) +#define BN_TBIT (0x80000000UL) +#define BN_DEC_CONV (1000000000UL) #define BN_DEC_NUM 9 +#define TOBN(hi, lo) lo, hi #else #error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" #endif + /* Pentium pro 16,16,16,32,64 */ /* Alpha 16,16,16,16.64 */ #define BN_MULL_SIZE_NORMAL (16) /* 32 */ @@ -190,7 +187,13 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits); #define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */ #define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */ -#if defined(BN_LLONG) +#define STATIC_BIGNUM(x) \ + { \ + (BN_ULONG *)x, sizeof(x) / sizeof(BN_ULONG), \ + sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \ + } + +#if defined(BN_ULLONG) #define Lw(t) (((BN_ULONG)(t))&BN_MASK2) #define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2) #endif @@ -220,7 +223,7 @@ int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl); 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); -#if !defined(BN_LLONG) +#if !defined(BN_ULLONG) #define LBITS(a) ((a) & BN_MASK2l) #define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l) @@ -252,7 +255,7 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, (h) = ht; \ } -#endif /* !defined(BN_LLONG) */ +#endif /* !defined(BN_ULLONG) */ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) # if defined(__GNUC__) && __GNUC__ >= 2 diff --git a/src/crypto/bn/montgomery.c b/src/crypto/bn/montgomery.c index 11edcbf..18da0da 100644 --- a/src/crypto/bn/montgomery.c +++ b/src/crypto/bn/montgomery.c @@ -134,7 +134,6 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) { memset(ret, 0, sizeof(BN_MONT_CTX)); BN_init(&ret->RR); BN_init(&ret->N); - BN_init(&ret->Ni); return ret; } @@ -146,7 +145,6 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont) { BN_free(&mont->RR); BN_free(&mont->N); - BN_free(&mont->Ni); OPENSSL_free(mont); } @@ -156,11 +154,9 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) { } if (!BN_copy(&to->RR, &from->RR) || - !BN_copy(&to->N, &from->N) || - !BN_copy(&to->Ni, &from->Ni)) { + !BN_copy(&to->N, &from->N)) { return NULL; } - to->ri = from->ri; to->n0[0] = from->n0[0]; to->n0[1] = from->n0[1]; return to; @@ -193,8 +189,6 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { tmod.dmax = 2; tmod.neg = 0; - mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; - #if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2 <= 32) /* Only certain BN_BITS2<=32 platforms actually make use of * n0[1], and we could use the #else case (with a shorter R @@ -278,9 +272,10 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { mont->n0[1] = 0; #endif - /* setup RR for conversions */ + /* RR = (2^ri)^2 == 2^(ri*2) == 1 << (ri*2), which has its (ri*2)th bit set. */ + int ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; BN_zero(&(mont->RR)); - if (!BN_set_bit(&(mont->RR), mont->ri * 2)) { + if (!BN_set_bit(&(mont->RR), ri * 2)) { goto err; } if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) { diff --git a/src/crypto/bytestring/bytestring_test.cc b/src/crypto/bytestring/bytestring_test.cc index eae88d9..188c63d 100644 --- a/src/crypto/bytestring/bytestring_test.cc +++ b/src/crypto/bytestring/bytestring_test.cc @@ -12,6 +12,10 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if !defined(__STDC_CONSTANT_MACROS) +#define __STDC_CONSTANT_MACROS +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -22,7 +26,6 @@ #include <openssl/bytestring.h> #include "internal.h" -#include "../internal.h" #include "../test/scoped_types.h" @@ -341,12 +344,14 @@ static bool TestCBBPrefixed() { size_t buf_len; CBB cbb, contents, inner_contents, inner_inner_contents; - if (!CBB_init(&cbb, 0)) { - return false; - } - if (!CBB_add_u8_length_prefixed(&cbb, &contents) || + if (!CBB_init(&cbb, 0) || + CBB_len(&cbb) != 0 || + !CBB_add_u8_length_prefixed(&cbb, &contents) || !CBB_add_u8_length_prefixed(&cbb, &contents) || !CBB_add_u8(&contents, 1) || + CBB_len(&contents) != 1 || + !CBB_flush(&cbb) || + CBB_len(&cbb) != 3 || !CBB_add_u16_length_prefixed(&cbb, &contents) || !CBB_add_u16(&contents, 0x203) || !CBB_add_u24_length_prefixed(&cbb, &contents) || @@ -483,7 +488,7 @@ static bool TestCBBASN1() { return false; } if (!CBB_add_asn1(&cbb, &contents, 0x30) || - !CBB_add_bytes(&contents, bssl::vector_data(&test_data), 130) || + !CBB_add_bytes(&contents, test_data.data(), 130) || !CBB_finish(&cbb, &buf, &buf_len)) { CBB_cleanup(&cbb); return false; @@ -492,7 +497,7 @@ static bool TestCBBASN1() { if (buf_len != 3 + 130 || memcmp(buf, "\x30\x81\x82", 3) != 0 || - memcmp(buf + 3, bssl::vector_data(&test_data), 130) != 0) { + memcmp(buf + 3, test_data.data(), 130) != 0) { return false; } @@ -500,7 +505,7 @@ static bool TestCBBASN1() { return false; } if (!CBB_add_asn1(&cbb, &contents, 0x30) || - !CBB_add_bytes(&contents, bssl::vector_data(&test_data), 1000) || + !CBB_add_bytes(&contents, test_data.data(), 1000) || !CBB_finish(&cbb, &buf, &buf_len)) { CBB_cleanup(&cbb); return false; @@ -509,7 +514,7 @@ static bool TestCBBASN1() { if (buf_len != 4 + 1000 || memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 || - memcmp(buf + 4, bssl::vector_data(&test_data), 1000)) { + memcmp(buf + 4, test_data.data(), 1000)) { return false; } @@ -518,7 +523,7 @@ static bool TestCBBASN1() { } if (!CBB_add_asn1(&cbb, &contents, 0x30) || !CBB_add_asn1(&contents, &inner_contents, 0x30) || - !CBB_add_bytes(&inner_contents, bssl::vector_data(&test_data), 100000) || + !CBB_add_bytes(&inner_contents, test_data.data(), 100000) || !CBB_finish(&cbb, &buf, &buf_len)) { CBB_cleanup(&cbb); return false; @@ -527,7 +532,7 @@ static bool TestCBBASN1() { if (buf_len != 5 + 5 + 100000 || memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 || - memcmp(buf + 10, bssl::vector_data(&test_data), 100000)) { + memcmp(buf + 10, test_data.data(), 100000)) { return false; } @@ -627,9 +632,9 @@ static const ASN1Uint64Test kASN1Uint64Tests[] = { {127, "\x02\x01\x7f", 3}, {128, "\x02\x02\x00\x80", 4}, {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7}, - {OPENSSL_U64(0x0102030405060708), + {UINT64_C(0x0102030405060708), "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10}, - {OPENSSL_U64(0xffffffffffffffff), + {UINT64_C(0xffffffffffffffff), "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11}, }; @@ -698,12 +703,32 @@ static bool TestASN1Uint64() { return true; } -static int TestZero() { +static bool TestZero() { CBB cbb; CBB_zero(&cbb); // Calling |CBB_cleanup| on a zero-state |CBB| must not crash. CBB_cleanup(&cbb); - return 1; + return true; +} + +static bool TestCBBReserve() { + uint8_t buf[10]; + uint8_t *ptr; + size_t len; + ScopedCBB cbb; + if (!CBB_init_fixed(cbb.get(), buf, sizeof(buf)) || + // Too large. + CBB_reserve(cbb.get(), &ptr, 11) || + // Successfully reserve the entire space. + !CBB_reserve(cbb.get(), &ptr, 10) || + ptr != buf || + // Advancing under the maximum bytes is legal. + !CBB_did_write(cbb.get(), 5) || + !CBB_finish(cbb.get(), NULL, &len) || + len != 5) { + return false; + } + return true; } int main(void) { @@ -724,7 +749,8 @@ int main(void) { !TestBerConvert() || !TestASN1Uint64() || !TestGetOptionalASN1Bool() || - !TestZero()) { + !TestZero() || + !TestCBBReserve()) { return 1; } diff --git a/src/crypto/bytestring/cbb.c b/src/crypto/bytestring/cbb.c index 434ec13..8fc5187 100644 --- a/src/crypto/bytestring/cbb.c +++ b/src/crypto/bytestring/cbb.c @@ -25,6 +25,7 @@ void CBB_zero(CBB *cbb) { } static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { + /* This assumes that |cbb| has already been zeroed. */ struct cbb_buffer_st *base; base = OPENSSL_malloc(sizeof(struct cbb_buffer_st)); @@ -37,16 +38,15 @@ static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { base->cap = cap; base->can_resize = 1; - memset(cbb, 0, sizeof(CBB)); cbb->base = base; cbb->is_top_level = 1; return 1; } int CBB_init(CBB *cbb, size_t initial_capacity) { - uint8_t *buf; + CBB_zero(cbb); - buf = OPENSSL_malloc(initial_capacity); + uint8_t *buf = OPENSSL_malloc(initial_capacity); if (initial_capacity > 0 && buf == NULL) { return 0; } @@ -60,6 +60,8 @@ int CBB_init(CBB *cbb, size_t initial_capacity) { } int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) { + CBB_zero(cbb); + if (!cbb_init(cbb, buf, len)) { return 0; } @@ -82,8 +84,8 @@ void CBB_cleanup(CBB *cbb) { cbb->base = NULL; } -static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, - size_t len) { +static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { size_t newlen; if (base == NULL) { @@ -119,7 +121,17 @@ static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, if (out) { *out = base->buf + base->len; } - base->len = newlen; + + return 1; +} + +static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { + if (!cbb_buffer_reserve(base, out, len)) { + return 0; + } + /* This will not overflow or |cbb_buffer_reserve| would have failed. */ + base->len += len; return 1; } @@ -177,28 +189,28 @@ int CBB_flush(CBB *cbb) { return 0; } - if (cbb->child == NULL || cbb->pending_len_len == 0) { + if (cbb->child == NULL || cbb->child->pending_len_len == 0) { return 1; } - child_start = cbb->offset + cbb->pending_len_len; + child_start = cbb->child->offset + cbb->child->pending_len_len; if (!CBB_flush(cbb->child) || - child_start < cbb->offset || + child_start < cbb->child->offset || cbb->base->len < child_start) { return 0; } len = cbb->base->len - child_start; - if (cbb->pending_is_asn1) { + if (cbb->child->pending_is_asn1) { /* For ASN.1 we assume that we'll only need a single byte for the length. * If that turned out to be incorrect, we have to move the contents along * in order to make space. */ size_t len_len; uint8_t initial_length_byte; - assert (cbb->pending_len_len == 1); + assert (cbb->child->pending_len_len == 1); if (len > 0xfffffffe) { /* Too large. */ @@ -230,12 +242,13 @@ int CBB_flush(CBB *cbb) { memmove(cbb->base->buf + child_start + extra_bytes, cbb->base->buf + child_start, len); } - cbb->base->buf[cbb->offset++] = initial_length_byte; - cbb->pending_len_len = len_len - 1; + cbb->base->buf[cbb->child->offset++] = initial_length_byte; + cbb->child->pending_len_len = len_len - 1; } - for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) { - cbb->base->buf[cbb->offset + i] = len; + for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len; + i--) { + cbb->base->buf[cbb->child->offset + i] = len; len >>= 8; } if (len != 0) { @@ -244,17 +257,20 @@ int CBB_flush(CBB *cbb) { cbb->child->base = NULL; cbb->child = NULL; - cbb->pending_len_len = 0; - cbb->pending_is_asn1 = 0; - cbb->offset = 0; return 1; } +const uint8_t *CBB_data(const CBB *cbb) { + assert(cbb->child == NULL); + return cbb->base->buf + cbb->offset + cbb->pending_len_len; +} + size_t CBB_len(const CBB *cbb) { assert(cbb->child == NULL); + assert(cbb->offset + cbb->pending_len_len <= cbb->base->len); - return cbb->base->len; + return cbb->base->len - cbb->offset - cbb->pending_len_len; } static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, @@ -265,7 +281,7 @@ static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, return 0; } - cbb->offset = cbb->base->len; + size_t offset = cbb->base->len; if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) { return 0; } @@ -274,8 +290,9 @@ static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, memset(out_contents, 0, sizeof(CBB)); out_contents->base = cbb->base; cbb->child = out_contents; - cbb->pending_len_len = len_len; - cbb->pending_is_asn1 = 0; + cbb->child->offset = offset; + cbb->child->pending_len_len = len_len; + cbb->child->pending_is_asn1 = 0; return 1; } @@ -303,7 +320,7 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) { return 0; } - cbb->offset = cbb->base->len; + size_t offset = cbb->base->len; if (!CBB_add_u8(cbb, 0)) { return 0; } @@ -311,8 +328,9 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) { memset(out_contents, 0, sizeof(CBB)); out_contents->base = cbb->base; cbb->child = out_contents; - cbb->pending_len_len = 1; - cbb->pending_is_asn1 = 1; + cbb->child->offset = offset; + cbb->child->pending_len_len = 1; + cbb->child->pending_is_asn1 = 1; return 1; } @@ -336,6 +354,25 @@ int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { return 1; } +int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) { + if (!CBB_flush(cbb) || + !cbb_buffer_reserve(cbb->base, out_data, len)) { + return 0; + } + return 1; +} + +int CBB_did_write(CBB *cbb, size_t len) { + size_t newlen = cbb->base->len + len; + if (cbb->child != NULL || + newlen < cbb->base->len || + newlen > cbb->base->cap) { + return 0; + } + cbb->base->len = newlen; + return 1; +} + int CBB_add_u8(CBB *cbb, uint8_t value) { if (!CBB_flush(cbb)) { return 0; @@ -365,13 +402,10 @@ void CBB_discard_child(CBB *cbb) { return; } - cbb->base->len = cbb->offset; + cbb->base->len = cbb->child->offset; cbb->child->base = NULL; cbb->child = NULL; - cbb->pending_len_len = 0; - cbb->pending_is_asn1 = 0; - cbb->offset = 0; } int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { diff --git a/src/crypto/cipher/aead_test.cc b/src/crypto/cipher/aead_test.cc index a4ddd3b..79d7110 100644 --- a/src/crypto/cipher/aead_test.cc +++ b/src/crypto/cipher/aead_test.cc @@ -23,7 +23,6 @@ #include "../test/file_test.h" #include "../test/scoped_types.h" -#include "../test/stl_compat.h" // This program tests an AEAD against a series of test vectors from a file, @@ -50,8 +49,7 @@ static bool TestAEAD(FileTest *t, void *arg) { } ScopedEVP_AEAD_CTX ctx; - if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, - bssl::vector_data(&key), key.size(), + if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(), tag.size(), evp_aead_seal)) { t->PrintLine("Failed to init AEAD."); return false; @@ -60,10 +58,9 @@ static bool TestAEAD(FileTest *t, void *arg) { std::vector<uint8_t> out(in.size() + EVP_AEAD_max_overhead(aead)); if (!t->HasAttribute("NO_SEAL")) { size_t out_len; - if (!EVP_AEAD_CTX_seal(ctx.get(), bssl::vector_data(&out), &out_len, - out.size(), bssl::vector_data(&nonce), nonce.size(), - bssl::vector_data(&in), in.size(), - bssl::vector_data(&ad), ad.size())) { + if (!EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(), + nonce.data(), nonce.size(), in.data(), in.size(), + ad.data(), ad.size())) { t->PrintLine("Failed to run AEAD."); return false; } @@ -74,24 +71,21 @@ static bool TestAEAD(FileTest *t, void *arg) { (unsigned)(ct.size() + tag.size())); return false; } - if (!t->ExpectBytesEqual(bssl::vector_data(&ct), ct.size(), - bssl::vector_data(&out), ct.size()) || - !t->ExpectBytesEqual(bssl::vector_data(&tag), tag.size(), - bssl::vector_data(&out) + ct.size(), tag.size())) { + if (!t->ExpectBytesEqual(ct.data(), ct.size(), out.data(), ct.size()) || + !t->ExpectBytesEqual(tag.data(), tag.size(), out.data() + ct.size(), + tag.size())) { return false; } } else { out.resize(ct.size() + tag.size()); - memcpy(bssl::vector_data(&out), bssl::vector_data(&ct), ct.size()); - memcpy(bssl::vector_data(&out) + ct.size(), bssl::vector_data(&tag), - tag.size()); + memcpy(out.data(), ct.data(), ct.size()); + memcpy(out.data() + ct.size(), tag.data(), tag.size()); } // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be // reset after each operation. ctx.Reset(); - if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, - bssl::vector_data(&key), key.size(), + if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(), tag.size(), evp_aead_open)) { t->PrintLine("Failed to init AEAD."); return false; @@ -99,11 +93,9 @@ static bool TestAEAD(FileTest *t, void *arg) { std::vector<uint8_t> out2(out.size()); size_t out2_len; - int ret = EVP_AEAD_CTX_open(ctx.get(), - bssl::vector_data(&out2), &out2_len, out2.size(), - bssl::vector_data(&nonce), nonce.size(), - bssl::vector_data(&out), out.size(), - bssl::vector_data(&ad), ad.size()); + int ret = EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(), + nonce.data(), nonce.size(), out.data(), + out.size(), ad.data(), ad.size()); if (t->HasAttribute("FAILS")) { if (ret) { t->PrintLine("Decrypted bad data."); @@ -118,16 +110,14 @@ static bool TestAEAD(FileTest *t, void *arg) { return false; } out2.resize(out2_len); - if (!t->ExpectBytesEqual(bssl::vector_data(&in), in.size(), - bssl::vector_data(&out2), out2.size())) { + if (!t->ExpectBytesEqual(in.data(), in.size(), out2.data(), out2.size())) { return false; } // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be // reset after each operation. ctx.Reset(); - if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, - bssl::vector_data(&key), key.size(), + if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(), tag.size(), evp_aead_open)) { t->PrintLine("Failed to init AEAD."); return false; @@ -136,10 +126,9 @@ static bool TestAEAD(FileTest *t, void *arg) { // Garbage at the end isn't ignored. out.push_back(0); out2.resize(out.size()); - if (EVP_AEAD_CTX_open(ctx.get(), bssl::vector_data(&out2), &out2_len, - out2.size(), bssl::vector_data(&nonce), nonce.size(), - bssl::vector_data(&out), out.size(), - bssl::vector_data(&ad), ad.size())) { + if (EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(), + nonce.data(), nonce.size(), out.data(), out.size(), + ad.data(), ad.size())) { t->PrintLine("Decrypted bad data with trailing garbage."); return false; } @@ -148,8 +137,7 @@ static bool TestAEAD(FileTest *t, void *arg) { // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be // reset after each operation. ctx.Reset(); - if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, - bssl::vector_data(&key), key.size(), + if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(), tag.size(), evp_aead_open)) { t->PrintLine("Failed to init AEAD."); return false; @@ -159,10 +147,9 @@ static bool TestAEAD(FileTest *t, void *arg) { out[0] ^= 0x80; out.resize(out.size() - 1); out2.resize(out.size()); - if (EVP_AEAD_CTX_open(ctx.get(), bssl::vector_data(&out2), &out2_len, - out2.size(), bssl::vector_data(&nonce), nonce.size(), - bssl::vector_data(&out), out.size(), - bssl::vector_data(&ad), ad.size())) { + if (EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(), + nonce.data(), nonce.size(), out.data(), out.size(), + ad.data(), ad.size())) { t->PrintLine("Decrypted bad data with corrupted byte."); return false; } @@ -213,7 +200,7 @@ struct AEADName { static const struct AEADName kAEADs[] = { { "aes-128-gcm", EVP_aead_aes_128_gcm }, { "aes-256-gcm", EVP_aead_aes_256_gcm }, - { "chacha20-poly1305", EVP_aead_chacha20_poly1305_rfc7539 }, + { "chacha20-poly1305", EVP_aead_chacha20_poly1305 }, { "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old }, { "rc4-md5-tls", EVP_aead_rc4_md5_tls }, { "rc4-sha1-tls", EVP_aead_rc4_sha1_tls }, diff --git a/src/crypto/cipher/cipher_test.cc b/src/crypto/cipher/cipher_test.cc index 5f04178..1cbfae9 100644 --- a/src/crypto/cipher/cipher_test.cc +++ b/src/crypto/cipher/cipher_test.cc @@ -63,7 +63,6 @@ #include "../test/file_test.h" #include "../test/scoped_types.h" -#include "../test/stl_compat.h" static const EVP_CIPHER *GetCipher(const std::string &name) { @@ -146,7 +145,7 @@ static bool TestOperation(FileTest *t, } if (is_aead && !encrypt && !EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, tag.size(), - const_cast<uint8_t*>(bssl::vector_data(&tag)))) { + const_cast<uint8_t*>(tag.data()))) { return false; } // The ciphers are run with no padding. For each of the ciphers we test, the @@ -162,10 +161,10 @@ static bool TestOperation(FileTest *t, // |EVP_CipherUpdate| calls when empty. int unused, result_len1 = 0, result_len2; if (!EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size()) || - !EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, bssl::vector_data(&key), - bssl::vector_data(&iv), -1) || + !EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, key.data(), iv.data(), + -1) || (!aad.empty() && - !EVP_CipherUpdate(ctx.get(), nullptr, &unused, bssl::vector_data(&aad), + !EVP_CipherUpdate(ctx.get(), nullptr, &unused, aad.data(), aad.size())) || !EVP_CIPHER_CTX_set_padding(ctx.get(), 0)) { t->PrintLine("Operation failed."); @@ -175,28 +174,27 @@ static bool TestOperation(FileTest *t, for (size_t i = 0; i < in->size(); i++) { uint8_t c = (*in)[i]; int len; - if (!EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result) + result_len1, - &len, &c, 1)) { + if (!EVP_CipherUpdate(ctx.get(), result.data() + result_len1, &len, &c, + 1)) { t->PrintLine("Operation failed."); return false; } result_len1 += len; } } else if (!in->empty() && - !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result), - &result_len1, bssl::vector_data(in), - in->size())) { + !EVP_CipherUpdate(ctx.get(), result.data(), &result_len1, + in->data(), in->size())) { t->PrintLine("Operation failed."); return false; } - if (!EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1, + if (!EVP_CipherFinal_ex(ctx.get(), result.data() + result_len1, &result_len2)) { t->PrintLine("Operation failed."); return false; } result.resize(result_len1 + result_len2); - if (!t->ExpectBytesEqual(bssl::vector_data(out), out->size(), - bssl::vector_data(&result), result.size())) { + if (!t->ExpectBytesEqual(out->data(), out->size(), result.data(), + result.size())) { return false; } if (encrypt && is_aead) { @@ -207,7 +205,7 @@ static bool TestOperation(FileTest *t, } if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, tag.size(), rtag) || - !t->ExpectBytesEqual(bssl::vector_data(&tag), tag.size(), rtag, + !t->ExpectBytesEqual(tag.data(), tag.size(), rtag, tag.size())) { return false; } diff --git a/src/crypto/cipher/e_aes.c b/src/crypto/cipher/e_aes.c index b46fed4..e5104b4 100644 --- a/src/crypto/cipher/e_aes.c +++ b/src/crypto/cipher/e_aes.c @@ -1652,7 +1652,7 @@ static int aead_aes_ctr_hmac_sha256_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, if (in_len + aes_ctx->tag_len < in_len || /* This input is so large it would overflow the 32-bit block counter. */ - in_len_64 >= (OPENSSL_U64(1) << 32) * AES_BLOCK_SIZE) { + in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); return 0; } diff --git a/src/crypto/cipher/e_chacha20poly1305.c b/src/crypto/cipher/e_chacha20poly1305.c index c3ba457..f384950 100644 --- a/src/crypto/cipher/e_chacha20poly1305.c +++ b/src/crypto/cipher/e_chacha20poly1305.c @@ -108,10 +108,11 @@ static void aead_poly1305(aead_poly1305_update update, CRYPTO_poly1305_finish(&ctx, tag); } -static int seal(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx, - uint8_t *out, size_t *out_len, size_t max_out_len, - const uint8_t nonce[12], const uint8_t *in, size_t in_len, - const uint8_t *ad, size_t ad_len) { +static int seal_impl(aead_poly1305_update poly1305_update, + const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t nonce[12], + const uint8_t *in, size_t in_len, const uint8_t *ad, + size_t ad_len) { const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; const uint64_t in_len_64 = in_len; @@ -146,10 +147,11 @@ static int seal(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx, return 1; } -static int open(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx, - uint8_t *out, size_t *out_len, size_t max_out_len, - const uint8_t nonce[12], const uint8_t *in, size_t in_len, - const uint8_t *ad, size_t ad_len) { +static int open_impl(aead_poly1305_update poly1305_update, + const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t nonce[12], + const uint8_t *in, size_t in_len, const uint8_t *ad, + size_t ad_len) { const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; size_t plaintext_len; const uint64_t in_len_64 = in_len; @@ -212,8 +214,8 @@ static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); return 0; } - return seal(poly1305_update, ctx, out, out_len, max_out_len, nonce, in, - in_len, ad, ad_len); + return seal_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in, + in_len, ad, ad_len); } static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out, @@ -225,8 +227,8 @@ static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out, OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); return 0; } - return open(poly1305_update, ctx, out, out_len, max_out_len, nonce, in, - in_len, ad, ad_len); + return open_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in, + in_len, ad, ad_len); } static const EVP_AEAD aead_chacha20_poly1305 = { @@ -243,10 +245,14 @@ static const EVP_AEAD aead_chacha20_poly1305 = { NULL, /* get_iv */ }; -const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) { +const EVP_AEAD *EVP_aead_chacha20_poly1305(void) { return &aead_chacha20_poly1305; } +const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) { + return EVP_aead_chacha20_poly1305(); +} + static void poly1305_update_old(poly1305_state *ctx, const uint8_t *ad, size_t ad_len, const uint8_t *ciphertext, size_t ciphertext_len) { @@ -267,8 +273,8 @@ static int aead_chacha20_poly1305_old_seal( uint8_t nonce_96[12]; memset(nonce_96, 0, 4); memcpy(nonce_96 + 4, nonce, 8); - return seal(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in, - in_len, ad, ad_len); + return seal_impl(poly1305_update_old, ctx, out, out_len, max_out_len, + nonce_96, in, in_len, ad, ad_len); } static int aead_chacha20_poly1305_old_open( @@ -282,8 +288,8 @@ static int aead_chacha20_poly1305_old_open( uint8_t nonce_96[12]; memset(nonce_96, 0, 4); memcpy(nonce_96 + 4, nonce, 8); - return open(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in, - in_len, ad, ad_len); + return open_impl(poly1305_update_old, ctx, out, out_len, max_out_len, + nonce_96, in, in_len, ad, ad_len); } static const EVP_AEAD aead_chacha20_poly1305_old = { @@ -303,7 +309,3 @@ static const EVP_AEAD aead_chacha20_poly1305_old = { const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void) { return &aead_chacha20_poly1305_old; } - -const EVP_AEAD *EVP_aead_chacha20_poly1305(void) { - return &aead_chacha20_poly1305_old; -} diff --git a/src/crypto/cipher/e_rc4.c b/src/crypto/cipher/e_rc4.c index 86d9395..3a2c166 100644 --- a/src/crypto/cipher/e_rc4.c +++ b/src/crypto/cipher/e_rc4.c @@ -54,21 +54,13 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -#include <openssl/aead.h> - #include <assert.h> #include <string.h> #include <openssl/cipher.h> -#include <openssl/cpu.h> -#include <openssl/err.h> -#include <openssl/md5.h> -#include <openssl/mem.h> #include <openssl/obj.h> #include <openssl/rc4.h> -#include "internal.h" - static int rc4_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, int enc) { @@ -93,306 +85,3 @@ static const EVP_CIPHER rc4 = { NULL /* cleanup */, NULL /* ctrl */, }; const EVP_CIPHER *EVP_rc4(void) { return &rc4; } - - -struct aead_rc4_md5_tls_ctx { - RC4_KEY rc4; - MD5_CTX head, tail, md; - size_t payload_length; - unsigned char tag_len; -}; - - -static int -aead_rc4_md5_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, - size_t tag_len) { - struct aead_rc4_md5_tls_ctx *rc4_ctx; - size_t i; - uint8_t hmac_key[MD5_CBLOCK]; - - if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { - tag_len = MD5_DIGEST_LENGTH; - } - - if (tag_len > MD5_DIGEST_LENGTH) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); - return 0; - } - - /* The keys consists of |MD5_DIGEST_LENGTH| bytes of HMAC(MD5) key followed - * by some number of bytes of RC4 key. */ - if (key_len <= MD5_DIGEST_LENGTH) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); - return 0; - } - - rc4_ctx = OPENSSL_malloc(sizeof(struct aead_rc4_md5_tls_ctx)); - if (rc4_ctx == NULL) { - OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); - return 0; - } - memset(rc4_ctx, 0, sizeof(struct aead_rc4_md5_tls_ctx)); - - RC4_set_key(&rc4_ctx->rc4, key_len - MD5_DIGEST_LENGTH, - key + MD5_DIGEST_LENGTH); - - memset(hmac_key, 0, sizeof(hmac_key)); - memcpy(hmac_key, key, MD5_DIGEST_LENGTH); - for (i = 0; i < sizeof(hmac_key); i++) { - hmac_key[i] ^= 0x36; - } - MD5_Init(&rc4_ctx->head); - MD5_Update(&rc4_ctx->head, hmac_key, sizeof(hmac_key)); - for (i = 0; i < sizeof(hmac_key); i++) { - hmac_key[i] ^= 0x36 ^ 0x5c; - } - MD5_Init(&rc4_ctx->tail); - MD5_Update(&rc4_ctx->tail, hmac_key, sizeof(hmac_key)); - - rc4_ctx->tag_len = tag_len; - ctx->aead_state = rc4_ctx; - - return 1; -} - -static void aead_rc4_md5_tls_cleanup(EVP_AEAD_CTX *ctx) { - struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state; - OPENSSL_cleanse(rc4_ctx, sizeof(struct aead_rc4_md5_tls_ctx)); - OPENSSL_free(rc4_ctx); -} - -#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) -#define STITCHED_CALL - -/* rc4_md5_enc is defined in rc4_md5-x86_64.pl */ -void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out, MD5_CTX *ctx, - const void *inp, size_t blocks); -#endif - -static int aead_rc4_md5_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, - size_t *out_len, size_t max_out_len, - const uint8_t *nonce, size_t nonce_len, - const uint8_t *in, size_t in_len, - const uint8_t *ad, size_t ad_len) { - struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state; - MD5_CTX md; -#if defined(STITCHED_CALL) - size_t rc4_off, md5_off, blocks; -#else - const size_t rc4_off = 0; - const size_t md5_off = 0; -#endif - uint8_t digest[MD5_DIGEST_LENGTH]; - - if (in_len + rc4_ctx->tag_len < in_len) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); - return 0; - } - - if (nonce_len != 0) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE); - return 0; - } - - if (max_out_len < in_len + rc4_ctx->tag_len) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); - return 0; - } - - if (nonce_len != 0) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); - return 0; - } - - memcpy(&md, &rc4_ctx->head, sizeof(MD5_CTX)); - /* The MAC's payload begins with the additional data. See - * https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */ - MD5_Update(&md, ad, ad_len); - - /* To allow for CBC mode which changes cipher length, |ad| doesn't include the - * length for legacy ciphers. */ - uint8_t ad_extra[2]; - ad_extra[0] = (uint8_t)(in_len >> 8); - ad_extra[1] = (uint8_t)(in_len & 0xff); - MD5_Update(&md, ad_extra, sizeof(ad_extra)); - -#if defined(STITCHED_CALL) - /* 32 is $MOD from rc4_md5-x86_64.pl. */ - rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1)); - md5_off = MD5_CBLOCK - md.num; - /* Ensure RC4 is behind MD5. */ - if (rc4_off > md5_off) { - md5_off += MD5_CBLOCK; - } - assert(md5_off >= rc4_off); - - if (in_len > md5_off && (blocks = (in_len - md5_off) / MD5_CBLOCK) && - (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) { - /* Process the initial portions of the plaintext normally. */ - MD5_Update(&md, in, md5_off); - RC4(&rc4_ctx->rc4, rc4_off, in, out); - - /* Process the next |blocks| blocks of plaintext with stitched routines. */ - rc4_md5_enc(&rc4_ctx->rc4, in + rc4_off, out + rc4_off, &md, in + md5_off, - blocks); - blocks *= MD5_CBLOCK; - rc4_off += blocks; - md5_off += blocks; - md.Nh += blocks >> 29; - md.Nl += blocks <<= 3; - if (md.Nl < (unsigned int)blocks) { - md.Nh++; - } - } else { - rc4_off = 0; - md5_off = 0; - } -#endif - /* Finish computing the MAC. */ - MD5_Update(&md, in + md5_off, in_len - md5_off); - MD5_Final(digest, &md); - - memcpy(&md, &rc4_ctx->tail, sizeof(MD5_CTX)); - MD5_Update(&md, digest, sizeof(digest)); - if (rc4_ctx->tag_len == MD5_DIGEST_LENGTH) { - MD5_Final(out + in_len, &md); - } else { - MD5_Final(digest, &md); - memcpy(out + in_len, digest, rc4_ctx->tag_len); - } - - /* Encrypt the remainder of the plaintext and the MAC. */ - RC4(&rc4_ctx->rc4, in_len - rc4_off, in + rc4_off, out + rc4_off); - RC4(&rc4_ctx->rc4, MD5_DIGEST_LENGTH, out + in_len, out + in_len); - - *out_len = in_len + rc4_ctx->tag_len; - return 1; -} - -static int aead_rc4_md5_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, - size_t *out_len, size_t max_out_len, - const uint8_t *nonce, size_t nonce_len, - const uint8_t *in, size_t in_len, - const uint8_t *ad, size_t ad_len) { - struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state; - MD5_CTX md; - size_t plaintext_len; -#if defined(STITCHED_CALL) - unsigned int l; - size_t rc4_off, md5_off, blocks; - extern unsigned int OPENSSL_ia32cap_P[]; -#else - const size_t rc4_off = 0; - const size_t md5_off = 0; -#endif - uint8_t digest[MD5_DIGEST_LENGTH]; - - if (in_len < rc4_ctx->tag_len) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); - return 0; - } - - plaintext_len = in_len - rc4_ctx->tag_len; - - if (nonce_len != 0) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); - return 0; - } - - if (max_out_len < in_len) { - /* This requires that the caller provide space for the MAC, even though it - * will always be removed on return. */ - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); - return 0; - } - - memcpy(&md, &rc4_ctx->head, sizeof(MD5_CTX)); - /* The MAC's payload begins with the additional data. See - * https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */ - MD5_Update(&md, ad, ad_len); - - /* To allow for CBC mode which changes cipher length, |ad| doesn't include the - * length for legacy ciphers. */ - uint8_t ad_extra[2]; - ad_extra[0] = (uint8_t)(plaintext_len >> 8); - ad_extra[1] = (uint8_t)(plaintext_len & 0xff); - MD5_Update(&md, ad_extra, sizeof(ad_extra)); - -#if defined(STITCHED_CALL) - rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1)); - md5_off = MD5_CBLOCK - md.num; - /* Ensure MD5 is a full block behind RC4 so it has plaintext to operate on in - * both normal and stitched routines. */ - if (md5_off > rc4_off) { - rc4_off += 2 * MD5_CBLOCK; - } else { - rc4_off += MD5_CBLOCK; - } - - if (in_len > rc4_off && (blocks = (in_len - rc4_off) / MD5_CBLOCK) && - (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) { - /* Decrypt the initial portion of the ciphertext and digest the plaintext - * normally. */ - RC4(&rc4_ctx->rc4, rc4_off, in, out); - MD5_Update(&md, out, md5_off); - - /* Decrypt and digest the next |blocks| blocks of ciphertext with the - * stitched routines. */ - rc4_md5_enc(&rc4_ctx->rc4, in + rc4_off, out + rc4_off, &md, out + md5_off, - blocks); - blocks *= MD5_CBLOCK; - rc4_off += blocks; - md5_off += blocks; - l = (md.Nl + (blocks << 3)) & 0xffffffffU; - if (l < md.Nl) { - md.Nh++; - } - md.Nl = l; - md.Nh += blocks >> 29; - } else { - md5_off = 0; - rc4_off = 0; - } -#endif - - /* Process the remainder of the input. */ - RC4(&rc4_ctx->rc4, in_len - rc4_off, in + rc4_off, out + rc4_off); - MD5_Update(&md, out + md5_off, plaintext_len - md5_off); - MD5_Final(digest, &md); - - /* Calculate HMAC and verify it */ - memcpy(&md, &rc4_ctx->tail, sizeof(MD5_CTX)); - MD5_Update(&md, digest, MD5_DIGEST_LENGTH); - MD5_Final(digest, &md); - - if (CRYPTO_memcmp(out + plaintext_len, digest, rc4_ctx->tag_len)) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); - return 0; - } - - *out_len = plaintext_len; - return 1; -} - -static int aead_rc4_md5_tls_get_rc4_state(const EVP_AEAD_CTX *ctx, - const RC4_KEY **out_key) { - struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state; - *out_key = &rc4_ctx->rc4; - return 1; -} - -static const EVP_AEAD aead_rc4_md5_tls = { - 16 + MD5_DIGEST_LENGTH, /* key len (RC4 + MD5) */ - 0, /* nonce len */ - MD5_DIGEST_LENGTH, /* overhead */ - MD5_DIGEST_LENGTH, /* max tag length */ - aead_rc4_md5_tls_init, - NULL, /* init_with_direction */ - aead_rc4_md5_tls_cleanup, - aead_rc4_md5_tls_seal, - aead_rc4_md5_tls_open, - aead_rc4_md5_tls_get_rc4_state, - NULL, /* get_iv */ -}; - -const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; } diff --git a/src/crypto/cipher/e_tls.c b/src/crypto/cipher/e_tls.c index d781da1..b87b0d6 100644 --- a/src/crypto/cipher/e_tls.c +++ b/src/crypto/cipher/e_tls.c @@ -20,6 +20,7 @@ #include <openssl/cipher.h> #include <openssl/err.h> #include <openssl/hmac.h> +#include <openssl/md5.h> #include <openssl/mem.h> #include <openssl/sha.h> #include <openssl/type_check.h> @@ -111,7 +112,6 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, /* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); return 0; - } if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len || @@ -146,17 +146,13 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, * in-place. */ uint8_t mac[EVP_MAX_MD_SIZE]; unsigned mac_len; - HMAC_CTX hmac_ctx; - HMAC_CTX_init(&hmac_ctx); - if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) || - !HMAC_Update(&hmac_ctx, ad, ad_len) || - !HMAC_Update(&hmac_ctx, ad_extra, sizeof(ad_extra)) || - !HMAC_Update(&hmac_ctx, in, in_len) || - !HMAC_Final(&hmac_ctx, mac, &mac_len)) { - HMAC_CTX_cleanup(&hmac_ctx); + if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) || + !HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) || + !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) { return 0; } - HMAC_CTX_cleanup(&hmac_ctx); /* Configure the explicit IV. */ if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && @@ -216,7 +212,6 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, /* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); return 0; - } if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) { @@ -324,18 +319,14 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, * implemented. */ assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE); - HMAC_CTX hmac_ctx; - HMAC_CTX_init(&hmac_ctx); unsigned mac_len_u; - if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) || - !HMAC_Update(&hmac_ctx, ad_fixed, ad_len) || - !HMAC_Update(&hmac_ctx, out, data_len) || - !HMAC_Final(&hmac_ctx, mac, &mac_len_u)) { - HMAC_CTX_cleanup(&hmac_ctx); + if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) || + !HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) || + !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) { return 0; } mac_len = mac_len_u; - HMAC_CTX_cleanup(&hmac_ctx); assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); record_mac = &out[data_len]; @@ -359,6 +350,13 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, return 1; } +static int aead_rc4_md5_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_rc4(), EVP_md5(), + 0); +} + static int aead_rc4_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, enum evp_aead_direction_t dir) { @@ -433,8 +431,8 @@ static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init( EVP_sha1(), 1); } -static int aead_rc4_sha1_tls_get_rc4_state(const EVP_AEAD_CTX *ctx, - const RC4_KEY **out_key) { +static int aead_rc4_tls_get_rc4_state(const EVP_AEAD_CTX *ctx, + const RC4_KEY **out_key) { const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX*) ctx->aead_state; if (EVP_CIPHER_CTX_cipher(&tls_ctx->cipher_ctx) != EVP_rc4()) { return 0; @@ -464,18 +462,32 @@ static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, EVP_sha1(), 1 /* implicit iv */); } +static const EVP_AEAD aead_rc4_md5_tls = { + MD5_DIGEST_LENGTH + 16, /* key len (MD5 + RC4) */ + 0, /* nonce len */ + MD5_DIGEST_LENGTH, /* overhead */ + MD5_DIGEST_LENGTH, /* max tag length */ + NULL, /* init */ + aead_rc4_md5_tls_init, + aead_tls_cleanup, + aead_tls_seal, + aead_tls_open, + aead_rc4_tls_get_rc4_state, /* get_rc4_state */ + NULL, /* get_iv */ +}; + static const EVP_AEAD aead_rc4_sha1_tls = { SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + RC4) */ 0, /* nonce len */ SHA_DIGEST_LENGTH, /* overhead */ SHA_DIGEST_LENGTH, /* max tag length */ - NULL, /* init */ + NULL, /* init */ aead_rc4_sha1_tls_init, aead_tls_cleanup, aead_tls_seal, aead_tls_open, - aead_rc4_sha1_tls_get_rc4_state, /* get_rc4_state */ - NULL, /* get_iv */ + aead_rc4_tls_get_rc4_state, /* get_rc4_state */ + NULL, /* get_iv */ }; static const EVP_AEAD aead_aes_128_cbc_sha1_tls = { @@ -618,6 +630,8 @@ static const EVP_AEAD aead_null_sha1_tls = { NULL, /* get_iv */ }; +const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; } + const EVP_AEAD *EVP_aead_rc4_sha1_tls(void) { return &aead_rc4_sha1_tls; } const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) { diff --git a/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt b/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt index 55c506d..d40b21c 100644 --- a/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt +++ b/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt @@ -418,5 +418,107 @@ AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813 CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f TAG: f7d3b58a34a86e99267e5db206f17bbe -# BoringSSL has additional tests here for truncated tags. *ring* doesn't -# support tag truncation, so those tests were removed. +KEY: 3304e4917ad7777b86c26a636292c9cc4c10d32003c49e07209eb0ef8505031a +NONCE: 4d572d116fbd8c4d +IN: 2f242c2ba33790ecef862b0e077ff8b15eb9d10cf2ff621ed65902494431dcbd +AD: e699bbf250cdd93d229d0740e433897e2d19132e2b722df8b69bb6a7c2cf3b93 +CT: fb81e30436e437c7f686f86b1b65c73549a9d09db810d320785c3634934150b3 +TAG: 8b + +KEY: ed6057bb163f1609ff28b938122f495e3d5ae4ec3dbd7456c9b5c82e28e952dc +NONCE: e6ff6852f3a3afde +IN: 3c50edc967eb0b3b2355f6400e0a036e796c8b7d72c5e583a86e820d53e76c43 +AD: 2441db55148e14e9e241d68296eb60d529408f0534143089671bce546db96d88 +CT: 6ecabccee31519374d4bed11296e7483d1cb759bea3f4446a96bda8b4ca6d7ac +TAG: 355f + +KEY: 73568183c1f9725af30e0f2067606ce802c3fe3ab5cff8d02b3db8c35176ee0d +NONCE: 0bc9e19321b3d00a +IN: ec2590af5ccd226a32ff750c1b029c11e3dd76c469a5579da9418e4c3fdc0d41 +AD: df30160ae0cbf2cf8992221bd62dffe691dd602afa784ca691479e957af3acf1 +CT: 9e8d8ac30626f8b831448d6976933aa5bb8c6dbc794e1f4b7eeb0e4a59342c07 +TAG: 9fd36a + +KEY: 273bcb3f8c067da4ec3418799ad40e7e4aee74ad7e629499d646df4a7e585025 +NONCE: f60be3eb894b4030 +IN: 697498ba964d5ef401da4d94844fab1efc635e7157d0831a325bb5a4cf1fbd34 +AD: 9129715deab14f02c76ba8172571b1fa9d50365cd795bfccdfc28e7e7b4f66fc +CT: bd4cd5af83be1c13933302675d9fcaf1c4cacdf269f6ff441d1ea2211c54e7ed +TAG: 7ab12a37 + +KEY: ad39610c2e6a6d0961207390e076e972c2edadca885c92965fa648b2ce34fdbf +NONCE: a90db690bba83b78 +IN: 31c49e3cd3d80a82e6b90316dfb94b38b8a23042519bf40c8181fec873c99002 +AD: ddbd7d821d18d44c66295abf245b227b5cf4366811b7b34c07679600abdbfc29 +CT: 94628fc303a0546edd51e966f2bd87968f37800c607d5e5a91f727fc1fec406f +TAG: c22ec4e4c8 + +KEY: 29984954060ba06ece1bcfc0e50195f4632c6df48da1e02ae6c14f7065668971 +NONCE: cce53a25aeeaf747 +IN: b9b87433a9894f3c9ca8212623d62369a565a2edcddd276e07d611eda3597426 +AD: 19fa9aa59697559d8b46d9cd49c3b763c0b73b26b9e334a3eeac2c86fdbaca8d +CT: b68c83397770c36f073710882fa86d43b0e54e8efef0ff75075604d0d7ec4e1b +TAG: 40d4ab752f3d + +KEY: 5c3b838b84100b2a818c0842e9fe19a7c50cf5f3ea73364c816ef588e500ff3f +NONCE: fdf6b0229e4bcc2a +IN: 2ba91904c143be99297b39f52856904af41705c176c8c6554b6bc89bddffbcc1 +AD: 3539d9dd821f004f4ced1637071f4be6abd7fe98f017f0a8ce3f49dc8d496f46 +CT: ff9d6d924e737a1df8c2bd3047e40ab401f903aa0e5b51acb991bac38ac2cc4d +TAG: 1bcaa415a6a3c7 + +KEY: 6d65e627cab6d5eb1a088b25bd6c3a8a004a7a19cccae909d62fed3559c812f7 +NONCE: 7ff00a8798b792de +IN: 6848ee4ac820291a2e1dc3baad97f1ad8b7160dfeaa1bc83b2700ae42b5a366b +AD: d2437b1306bf0ea211449fac863ca0d1074d84caee9009c5d54b9e9bdc8de6b1 +CT: 2da0abe2a71e1c0b1ab309c160a8cebe45c6e16170aa5561806484ba2b5b9a9a +TAG: 566003e1f78d2a90 + +KEY: 63401046a96efbc8c6483a2c396b2a593d3fae0db565525b85999fae13a46b6a +NONCE: 051393d775e635ee +IN: 2b4b6477580382aae782f8b5772c0948a444d8d95caacd85c0856c7e4393fe09 +AD: 3d84d2e70e9c062d1f511eb685a9a90c8d5fa50eadf8455c7148666b3e7155e0 +CT: 880c1123e54fd8ffb3c293720dd174913572e619ef46504cdaa64fc451b0ec1c +TAG: 339274339c88d50ac0 + +KEY: 291fccfce0782f1787d62d4b9293d2ada4c04d37a8288ba9ba9aae0d31aad204 +NONCE: 7450bbd62e4aba7b +IN: adc251e793181e5d4c4bd983b853eb13f2096ccb340996b6eca4cd2157efcec7 +AD: 4c598f6deedc8c1d97da33654763495cca3517430eec4edb006b10c95e031ae6 +CT: 28bda22e4922cd8ff6739cd8a6bdafce036d9c61a145a65ca1b86f6d4d3206a1 +TAG: d98fd43fe7ac74d4b016 + +KEY: fa3a9674d4a0eb36b2f7547c956443d09e6b4e4acfc9deda838eb7ebdb999a8d +NONCE: 0a2572592c3bbbf6 +IN: ae27f70fda9f5a5be0f704a27f0b8a9c04ce83d3c2e0d7ec152da25f473b0c8a +AD: 6ee8705a9a3655d198497ad410da02005872ecbe397824851b80f4050bfdd311 +CT: f356cbd88e4e2aff62d91e3f914032085388955bbba995fde013758b8702e38f +TAG: 00324c76fecd3f50e1e3b8 + +KEY: 471ec87b992b104d369748d96856b5f66149cb45ca05c17f29d24eb9526fe6db +NONCE: 23a2df9ed0b47439 +IN: 2b9452bca0f48e5519ec3d0736597608df6ad9ce799eba913cff71573d79c092 +AD: a56722ddfaee5f1b64398c225ee8bcdcfde5c2127101c363bfac52bc409c1082 +CT: 7bbc464aac5dd29c25262fe0b116c176d827c2cc8dd63428393b0a9110f3c194 +TAG: 2e87f4a6663a62e47c7e197f + +KEY: a29d1cfd4ccdc18803fbca9500f4bb29ce99cfcbf8acc41b8208dae4b7ee5d64 +NONCE: 634f99e88e237ef0 +IN: 09ee5982c5743f396d0c29c13e3fbb8fb89f61705da05466291e010effd51a5c +AD: 564dddfcc3227b413244f1105b610f192decf15c4cfa067f4d7fcd6bd7af11b8 +CT: 32916b67a6f32733623344c98c49773f3e721dc2ded105fb245799525bc9c84c +TAG: ff463c07e7ef831321d3fd775f + +KEY: 08ba23616d911188f91da063278bef1237dcbf17f52585e53c2c4b6cf3ac9f0d +NONCE: 989ae593eddd3874 +IN: 749152c9478944c8271c0c11e07bc1c569eec01493e65b3b94842a1bf5d721f8 +AD: a12d1a45b7c9b91ab08751a70b753714052ad24e0b2619fe8c3be303c65f2dbc +CT: 34c40538ee1d22ddf8ac290dd7d423dfc622b5cf8f3412a5343e277822aea713 +TAG: 014c7c678e0949e88071d1fe3531 + +KEY: c2ba8bed8634156afc6bfe3754c91744d4131de39d059f3a866399f916553b5c +NONCE: 80fbf7b433a4cd9c +IN: 419be6623e7964f9f26068dd969e4a139617e67c5ffb269b3013c433fe771c77 +AD: 3937592db78a61ff469691b6800792019bc2b3d42512f23c1b1a66a8274495cb +CT: 9d5bd1c7e766763eb00684c038043111d8c6390a8d6e17a15ef97c02ab16f09c +TAG: a64d0eeb4a01481ec0cee8c1c357e3 diff --git a/src/crypto/cipher/test/chacha20_poly1305_tests.txt b/src/crypto/cipher/test/chacha20_poly1305_tests.txt index a71ac14..103c196 100644 --- a/src/crypto/cipher/test/chacha20_poly1305_tests.txt +++ b/src/crypto/cipher/test/chacha20_poly1305_tests.txt @@ -47,8 +47,8 @@ AD: "123456789abcdef0" CT: e275aeb341e1fc9a70c4fd4496fc7cdb TAG: 41acd0560ea6843d3e5d4e5babf6e946 -# Test vectors from chacha20_poly1305_deprecated_tests.txt, modified for the -# RFC 7539 AEAD construction. +# Test vectors from chacha20_poly1305_old_tests.txt, modified for the RFC 7539 +# AEAD construction. KEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6 NONCE: 000000003de9c0da2bd7f91e @@ -470,5 +470,109 @@ AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813 CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f TAG: 296a397d280d026fc3627f4718971be9 -# BoringSSL has additional tests here for truncated tags. *ring* doesn't -# support tag truncation, so those tests were removed. +# Tag truncation tests. + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c2 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f3 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f37465 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a84 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a8413 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a841386 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a84138648 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a84138648a5 + +KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865 +NONCE: 000000005d9856060c54ab06 +IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e +AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51 +CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36 +TAG: d3f7b9c295f374651a84138648a591 diff --git a/src/crypto/cpu-arm.c b/src/crypto/cpu-arm.c index 14ad2ee..675d174 100644 --- a/src/crypto/cpu-arm.c +++ b/src/crypto/cpu-arm.c @@ -34,7 +34,7 @@ unsigned long getauxval(unsigned long type) __attribute__((weak)); extern uint32_t OPENSSL_armcap_P; -char CRYPTO_is_NEON_capable(void) { +char CRYPTO_is_NEON_capable_at_runtime(void) { return (OPENSSL_armcap_P & ARMV7_NEON) != 0; } diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c index d70c8c7..ace1c82 100644 --- a/src/crypto/crypto.c +++ b/src/crypto/crypto.c @@ -14,6 +14,8 @@ #include <openssl/crypto.h> +#include <openssl/cpu.h> + #include "internal.h" @@ -86,22 +88,22 @@ uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL; #endif -#if defined(OPENSSL_WINDOWS) +#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_NO_STATIC_INITIALIZER) #define OPENSSL_CDECL __cdecl #else #define OPENSSL_CDECL #endif -#if !defined(BORINGSSL_NO_STATIC_INITIALIZER) -#if !defined(OPENSSL_WINDOWS) -static void do_library_init(void) __attribute__ ((constructor)); -#else +#if defined(BORINGSSL_NO_STATIC_INITIALIZER) +static CRYPTO_once_t once = CRYPTO_ONCE_INIT; +#elif defined(OPENSSL_WINDOWS) #pragma section(".CRT$XCU", read) static void __cdecl do_library_init(void); __declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) = do_library_init; +#else +static void do_library_init(void) __attribute__ ((constructor)); #endif -#endif /* !BORINGSSL_NO_STATIC_INITIALIZER */ /* do_library_init is the actual initialization function. If * BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static @@ -117,9 +119,9 @@ static void OPENSSL_CDECL do_library_init(void) { void CRYPTO_library_init(void) { /* TODO(davidben): It would be tidier if this build knob could be replaced * with an internal lazy-init mechanism that would handle things correctly - * in-library. */ + * in-library. https://crbug.com/542879 */ #if defined(BORINGSSL_NO_STATIC_INITIALIZER) - do_library_init(); + CRYPTO_once(&once, do_library_init); #endif } diff --git a/src/crypto/curve25519/CMakeLists.txt b/src/crypto/curve25519/CMakeLists.txt new file mode 100644 index 0000000..a2ef3bb --- /dev/null +++ b/src/crypto/curve25519/CMakeLists.txt @@ -0,0 +1,47 @@ +include_directories(../../include) + +if (${ARCH} STREQUAL "arm") + set( + CURVE25519_ARCH_SOURCES + + asm/x25519-asm-arm.S + ) +endif() + +if (${ARCH} STREQUAL "x86_64") + set( + CURVE25519_ARCH_SOURCES + + asm/x25519-asm-x86_64.S + ) +endif() + +add_library( + curve25519 + + OBJECT + + curve25519.c + x25519-x86_64.c + + ${CURVE25519_ARCH_SOURCES} +) + +add_executable( + ed25519_test + + ed25519_test.cc + $<TARGET_OBJECTS:test_support> +) + +target_link_libraries(ed25519_test crypto) +add_dependencies(all_tests ed25519_test) + +add_executable( + x25519_test + + x25519_test.cc +) + +target_link_libraries(x25519_test crypto) +add_dependencies(all_tests x25519_test) diff --git a/src/crypto/curve25519/asm/x25519-asm-arm.S b/src/crypto/curve25519/asm/x25519-asm-arm.S new file mode 100644 index 0000000..60d08dd --- /dev/null +++ b/src/crypto/curve25519/asm/x25519-asm-arm.S @@ -0,0 +1,2118 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This file is taken from crypto_scalarmult/curve25519/neon2/scalarmult.s in + * SUPERCOP 20141124 (http://bench.cr.yp.to/supercop.html). That code is public + * domain licensed but the standard ISC license is included above to keep + * licensing simple. */ + +.fpu neon +.text +.align 4 + +.global x25519_NEON +.hidden x25519_NEON +.type x25519_NEON, %function +x25519_NEON: +vpush {q4,q5,q6,q7} +mov r12,sp +sub sp,sp,#736 +and sp,sp,#0xffffffe0 +strd r4,[sp,#0] +strd r6,[sp,#8] +strd r8,[sp,#16] +strd r10,[sp,#24] +str r12,[sp,#480] +str r14,[sp,#484] +mov r0,r0 +mov r1,r1 +mov r2,r2 +add r3,sp,#32 +ldr r4,=0 +ldr r5,=254 +vmov.i32 q0,#1 +vshr.u64 q1,q0,#7 +vshr.u64 q0,q0,#8 +vmov.i32 d4,#19 +vmov.i32 d5,#38 +add r6,sp,#512 +vst1.8 {d2-d3},[r6,: 128] +add r6,sp,#528 +vst1.8 {d0-d1},[r6,: 128] +add r6,sp,#544 +vst1.8 {d4-d5},[r6,: 128] +add r6,r3,#0 +vmov.i32 q2,#0 +vst1.8 {d4-d5},[r6,: 128]! +vst1.8 {d4-d5},[r6,: 128]! +vst1.8 d4,[r6,: 64] +add r6,r3,#0 +ldr r7,=960 +sub r7,r7,#2 +neg r7,r7 +sub r7,r7,r7,LSL #7 +str r7,[r6] +add r6,sp,#704 +vld1.8 {d4-d5},[r1]! +vld1.8 {d6-d7},[r1] +vst1.8 {d4-d5},[r6,: 128]! +vst1.8 {d6-d7},[r6,: 128] +sub r1,r6,#16 +ldrb r6,[r1] +and r6,r6,#248 +strb r6,[r1] +ldrb r6,[r1,#31] +and r6,r6,#127 +orr r6,r6,#64 +strb r6,[r1,#31] +vmov.i64 q2,#0xffffffff +vshr.u64 q3,q2,#7 +vshr.u64 q2,q2,#6 +vld1.8 {d8},[r2] +vld1.8 {d10},[r2] +add r2,r2,#6 +vld1.8 {d12},[r2] +vld1.8 {d14},[r2] +add r2,r2,#6 +vld1.8 {d16},[r2] +add r2,r2,#4 +vld1.8 {d18},[r2] +vld1.8 {d20},[r2] +add r2,r2,#6 +vld1.8 {d22},[r2] +add r2,r2,#2 +vld1.8 {d24},[r2] +vld1.8 {d26},[r2] +vshr.u64 q5,q5,#26 +vshr.u64 q6,q6,#3 +vshr.u64 q7,q7,#29 +vshr.u64 q8,q8,#6 +vshr.u64 q10,q10,#25 +vshr.u64 q11,q11,#3 +vshr.u64 q12,q12,#12 +vshr.u64 q13,q13,#38 +vand q4,q4,q2 +vand q6,q6,q2 +vand q8,q8,q2 +vand q10,q10,q2 +vand q2,q12,q2 +vand q5,q5,q3 +vand q7,q7,q3 +vand q9,q9,q3 +vand q11,q11,q3 +vand q3,q13,q3 +add r2,r3,#48 +vadd.i64 q12,q4,q1 +vadd.i64 q13,q10,q1 +vshr.s64 q12,q12,#26 +vshr.s64 q13,q13,#26 +vadd.i64 q5,q5,q12 +vshl.i64 q12,q12,#26 +vadd.i64 q14,q5,q0 +vadd.i64 q11,q11,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q15,q11,q0 +vsub.i64 q4,q4,q12 +vshr.s64 q12,q14,#25 +vsub.i64 q10,q10,q13 +vshr.s64 q13,q15,#25 +vadd.i64 q6,q6,q12 +vshl.i64 q12,q12,#25 +vadd.i64 q14,q6,q1 +vadd.i64 q2,q2,q13 +vsub.i64 q5,q5,q12 +vshr.s64 q12,q14,#26 +vshl.i64 q13,q13,#25 +vadd.i64 q14,q2,q1 +vadd.i64 q7,q7,q12 +vshl.i64 q12,q12,#26 +vadd.i64 q15,q7,q0 +vsub.i64 q11,q11,q13 +vshr.s64 q13,q14,#26 +vsub.i64 q6,q6,q12 +vshr.s64 q12,q15,#25 +vadd.i64 q3,q3,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q14,q3,q0 +vadd.i64 q8,q8,q12 +vshl.i64 q12,q12,#25 +vadd.i64 q15,q8,q1 +add r2,r2,#8 +vsub.i64 q2,q2,q13 +vshr.s64 q13,q14,#25 +vsub.i64 q7,q7,q12 +vshr.s64 q12,q15,#26 +vadd.i64 q14,q13,q13 +vadd.i64 q9,q9,q12 +vtrn.32 d12,d14 +vshl.i64 q12,q12,#26 +vtrn.32 d13,d15 +vadd.i64 q0,q9,q0 +vadd.i64 q4,q4,q14 +vst1.8 d12,[r2,: 64]! +vshl.i64 q6,q13,#4 +vsub.i64 q7,q8,q12 +vshr.s64 q0,q0,#25 +vadd.i64 q4,q4,q6 +vadd.i64 q6,q10,q0 +vshl.i64 q0,q0,#25 +vadd.i64 q8,q6,q1 +vadd.i64 q4,q4,q13 +vshl.i64 q10,q13,#25 +vadd.i64 q1,q4,q1 +vsub.i64 q0,q9,q0 +vshr.s64 q8,q8,#26 +vsub.i64 q3,q3,q10 +vtrn.32 d14,d0 +vshr.s64 q1,q1,#26 +vtrn.32 d15,d1 +vadd.i64 q0,q11,q8 +vst1.8 d14,[r2,: 64] +vshl.i64 q7,q8,#26 +vadd.i64 q5,q5,q1 +vtrn.32 d4,d6 +vshl.i64 q1,q1,#26 +vtrn.32 d5,d7 +vsub.i64 q3,q6,q7 +add r2,r2,#16 +vsub.i64 q1,q4,q1 +vst1.8 d4,[r2,: 64] +vtrn.32 d6,d0 +vtrn.32 d7,d1 +sub r2,r2,#8 +vtrn.32 d2,d10 +vtrn.32 d3,d11 +vst1.8 d6,[r2,: 64] +sub r2,r2,#24 +vst1.8 d2,[r2,: 64] +add r2,r3,#96 +vmov.i32 q0,#0 +vmov.i64 d2,#0xff +vmov.i64 d3,#0 +vshr.u32 q1,q1,#7 +vst1.8 {d2-d3},[r2,: 128]! +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 d0,[r2,: 64] +add r2,r3,#144 +vmov.i32 q0,#0 +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 d0,[r2,: 64] +add r2,r3,#240 +vmov.i32 q0,#0 +vmov.i64 d2,#0xff +vmov.i64 d3,#0 +vshr.u32 q1,q1,#7 +vst1.8 {d2-d3},[r2,: 128]! +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 d0,[r2,: 64] +add r2,r3,#48 +add r6,r3,#192 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4},[r2,: 64] +vst1.8 {d0-d1},[r6,: 128]! +vst1.8 {d2-d3},[r6,: 128]! +vst1.8 d4,[r6,: 64] +._mainloop: +mov r2,r5,LSR #3 +and r6,r5,#7 +ldrb r2,[r1,r2] +mov r2,r2,LSR r6 +and r2,r2,#1 +str r5,[sp,#488] +eor r4,r4,r2 +str r2,[sp,#492] +neg r2,r4 +add r4,r3,#96 +add r5,r3,#192 +add r6,r3,#144 +vld1.8 {d8-d9},[r4,: 128]! +add r7,r3,#240 +vld1.8 {d10-d11},[r5,: 128]! +veor q6,q4,q5 +vld1.8 {d14-d15},[r6,: 128]! +vdup.i32 q8,r2 +vld1.8 {d18-d19},[r7,: 128]! +veor q10,q7,q9 +vld1.8 {d22-d23},[r4,: 128]! +vand q6,q6,q8 +vld1.8 {d24-d25},[r5,: 128]! +vand q10,q10,q8 +vld1.8 {d26-d27},[r6,: 128]! +veor q4,q4,q6 +vld1.8 {d28-d29},[r7,: 128]! +veor q5,q5,q6 +vld1.8 {d0},[r4,: 64] +veor q6,q7,q10 +vld1.8 {d2},[r5,: 64] +veor q7,q9,q10 +vld1.8 {d4},[r6,: 64] +veor q9,q11,q12 +vld1.8 {d6},[r7,: 64] +veor q10,q0,q1 +sub r2,r4,#32 +vand q9,q9,q8 +sub r4,r5,#32 +vand q10,q10,q8 +sub r5,r6,#32 +veor q11,q11,q9 +sub r6,r7,#32 +veor q0,q0,q10 +veor q9,q12,q9 +veor q1,q1,q10 +veor q10,q13,q14 +veor q12,q2,q3 +vand q10,q10,q8 +vand q8,q12,q8 +veor q12,q13,q10 +veor q2,q2,q8 +veor q10,q14,q10 +veor q3,q3,q8 +vadd.i32 q8,q4,q6 +vsub.i32 q4,q4,q6 +vst1.8 {d16-d17},[r2,: 128]! +vadd.i32 q6,q11,q12 +vst1.8 {d8-d9},[r5,: 128]! +vsub.i32 q4,q11,q12 +vst1.8 {d12-d13},[r2,: 128]! +vadd.i32 q6,q0,q2 +vst1.8 {d8-d9},[r5,: 128]! +vsub.i32 q0,q0,q2 +vst1.8 d12,[r2,: 64] +vadd.i32 q2,q5,q7 +vst1.8 d0,[r5,: 64] +vsub.i32 q0,q5,q7 +vst1.8 {d4-d5},[r4,: 128]! +vadd.i32 q2,q9,q10 +vst1.8 {d0-d1},[r6,: 128]! +vsub.i32 q0,q9,q10 +vst1.8 {d4-d5},[r4,: 128]! +vadd.i32 q2,q1,q3 +vst1.8 {d0-d1},[r6,: 128]! +vsub.i32 q0,q1,q3 +vst1.8 d4,[r4,: 64] +vst1.8 d0,[r6,: 64] +add r2,sp,#544 +add r4,r3,#96 +add r5,r3,#144 +vld1.8 {d0-d1},[r2,: 128] +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4-d5},[r5,: 128]! +vzip.i32 q1,q2 +vld1.8 {d6-d7},[r4,: 128]! +vld1.8 {d8-d9},[r5,: 128]! +vshl.i32 q5,q1,#1 +vzip.i32 q3,q4 +vshl.i32 q6,q2,#1 +vld1.8 {d14},[r4,: 64] +vshl.i32 q8,q3,#1 +vld1.8 {d15},[r5,: 64] +vshl.i32 q9,q4,#1 +vmul.i32 d21,d7,d1 +vtrn.32 d14,d15 +vmul.i32 q11,q4,q0 +vmul.i32 q0,q7,q0 +vmull.s32 q12,d2,d2 +vmlal.s32 q12,d11,d1 +vmlal.s32 q12,d12,d0 +vmlal.s32 q12,d13,d23 +vmlal.s32 q12,d16,d22 +vmlal.s32 q12,d7,d21 +vmull.s32 q10,d2,d11 +vmlal.s32 q10,d4,d1 +vmlal.s32 q10,d13,d0 +vmlal.s32 q10,d6,d23 +vmlal.s32 q10,d17,d22 +vmull.s32 q13,d10,d4 +vmlal.s32 q13,d11,d3 +vmlal.s32 q13,d13,d1 +vmlal.s32 q13,d16,d0 +vmlal.s32 q13,d17,d23 +vmlal.s32 q13,d8,d22 +vmull.s32 q1,d10,d5 +vmlal.s32 q1,d11,d4 +vmlal.s32 q1,d6,d1 +vmlal.s32 q1,d17,d0 +vmlal.s32 q1,d8,d23 +vmull.s32 q14,d10,d6 +vmlal.s32 q14,d11,d13 +vmlal.s32 q14,d4,d4 +vmlal.s32 q14,d17,d1 +vmlal.s32 q14,d18,d0 +vmlal.s32 q14,d9,d23 +vmull.s32 q11,d10,d7 +vmlal.s32 q11,d11,d6 +vmlal.s32 q11,d12,d5 +vmlal.s32 q11,d8,d1 +vmlal.s32 q11,d19,d0 +vmull.s32 q15,d10,d8 +vmlal.s32 q15,d11,d17 +vmlal.s32 q15,d12,d6 +vmlal.s32 q15,d13,d5 +vmlal.s32 q15,d19,d1 +vmlal.s32 q15,d14,d0 +vmull.s32 q2,d10,d9 +vmlal.s32 q2,d11,d8 +vmlal.s32 q2,d12,d7 +vmlal.s32 q2,d13,d6 +vmlal.s32 q2,d14,d1 +vmull.s32 q0,d15,d1 +vmlal.s32 q0,d10,d14 +vmlal.s32 q0,d11,d19 +vmlal.s32 q0,d12,d8 +vmlal.s32 q0,d13,d17 +vmlal.s32 q0,d6,d6 +add r2,sp,#512 +vld1.8 {d18-d19},[r2,: 128] +vmull.s32 q3,d16,d7 +vmlal.s32 q3,d10,d15 +vmlal.s32 q3,d11,d14 +vmlal.s32 q3,d12,d9 +vmlal.s32 q3,d13,d8 +add r2,sp,#528 +vld1.8 {d8-d9},[r2,: 128] +vadd.i64 q5,q12,q9 +vadd.i64 q6,q15,q9 +vshr.s64 q5,q5,#26 +vshr.s64 q6,q6,#26 +vadd.i64 q7,q10,q5 +vshl.i64 q5,q5,#26 +vadd.i64 q8,q7,q4 +vadd.i64 q2,q2,q6 +vshl.i64 q6,q6,#26 +vadd.i64 q10,q2,q4 +vsub.i64 q5,q12,q5 +vshr.s64 q8,q8,#25 +vsub.i64 q6,q15,q6 +vshr.s64 q10,q10,#25 +vadd.i64 q12,q13,q8 +vshl.i64 q8,q8,#25 +vadd.i64 q13,q12,q9 +vadd.i64 q0,q0,q10 +vsub.i64 q7,q7,q8 +vshr.s64 q8,q13,#26 +vshl.i64 q10,q10,#25 +vadd.i64 q13,q0,q9 +vadd.i64 q1,q1,q8 +vshl.i64 q8,q8,#26 +vadd.i64 q15,q1,q4 +vsub.i64 q2,q2,q10 +vshr.s64 q10,q13,#26 +vsub.i64 q8,q12,q8 +vshr.s64 q12,q15,#25 +vadd.i64 q3,q3,q10 +vshl.i64 q10,q10,#26 +vadd.i64 q13,q3,q4 +vadd.i64 q14,q14,q12 +add r2,r3,#288 +vshl.i64 q12,q12,#25 +add r4,r3,#336 +vadd.i64 q15,q14,q9 +add r2,r2,#8 +vsub.i64 q0,q0,q10 +add r4,r4,#8 +vshr.s64 q10,q13,#25 +vsub.i64 q1,q1,q12 +vshr.s64 q12,q15,#26 +vadd.i64 q13,q10,q10 +vadd.i64 q11,q11,q12 +vtrn.32 d16,d2 +vshl.i64 q12,q12,#26 +vtrn.32 d17,d3 +vadd.i64 q1,q11,q4 +vadd.i64 q4,q5,q13 +vst1.8 d16,[r2,: 64]! +vshl.i64 q5,q10,#4 +vst1.8 d17,[r4,: 64]! +vsub.i64 q8,q14,q12 +vshr.s64 q1,q1,#25 +vadd.i64 q4,q4,q5 +vadd.i64 q5,q6,q1 +vshl.i64 q1,q1,#25 +vadd.i64 q6,q5,q9 +vadd.i64 q4,q4,q10 +vshl.i64 q10,q10,#25 +vadd.i64 q9,q4,q9 +vsub.i64 q1,q11,q1 +vshr.s64 q6,q6,#26 +vsub.i64 q3,q3,q10 +vtrn.32 d16,d2 +vshr.s64 q9,q9,#26 +vtrn.32 d17,d3 +vadd.i64 q1,q2,q6 +vst1.8 d16,[r2,: 64] +vshl.i64 q2,q6,#26 +vst1.8 d17,[r4,: 64] +vadd.i64 q6,q7,q9 +vtrn.32 d0,d6 +vshl.i64 q7,q9,#26 +vtrn.32 d1,d7 +vsub.i64 q2,q5,q2 +add r2,r2,#16 +vsub.i64 q3,q4,q7 +vst1.8 d0,[r2,: 64] +add r4,r4,#16 +vst1.8 d1,[r4,: 64] +vtrn.32 d4,d2 +vtrn.32 d5,d3 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d6,d12 +vtrn.32 d7,d13 +vst1.8 d4,[r2,: 64] +vst1.8 d5,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d6,[r2,: 64] +vst1.8 d7,[r4,: 64] +add r2,r3,#240 +add r4,r3,#96 +vld1.8 {d0-d1},[r4,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4},[r4,: 64] +add r4,r3,#144 +vld1.8 {d6-d7},[r4,: 128]! +vtrn.32 q0,q3 +vld1.8 {d8-d9},[r4,: 128]! +vshl.i32 q5,q0,#4 +vtrn.32 q1,q4 +vshl.i32 q6,q3,#4 +vadd.i32 q5,q5,q0 +vadd.i32 q6,q6,q3 +vshl.i32 q7,q1,#4 +vld1.8 {d5},[r4,: 64] +vshl.i32 q8,q4,#4 +vtrn.32 d4,d5 +vadd.i32 q7,q7,q1 +vadd.i32 q8,q8,q4 +vld1.8 {d18-d19},[r2,: 128]! +vshl.i32 q10,q2,#4 +vld1.8 {d22-d23},[r2,: 128]! +vadd.i32 q10,q10,q2 +vld1.8 {d24},[r2,: 64] +vadd.i32 q5,q5,q0 +add r2,r3,#192 +vld1.8 {d26-d27},[r2,: 128]! +vadd.i32 q6,q6,q3 +vld1.8 {d28-d29},[r2,: 128]! +vadd.i32 q8,q8,q4 +vld1.8 {d25},[r2,: 64] +vadd.i32 q10,q10,q2 +vtrn.32 q9,q13 +vadd.i32 q7,q7,q1 +vadd.i32 q5,q5,q0 +vtrn.32 q11,q14 +vadd.i32 q6,q6,q3 +add r2,sp,#560 +vadd.i32 q10,q10,q2 +vtrn.32 d24,d25 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q6,q13,#1 +add r2,sp,#576 +vst1.8 {d20-d21},[r2,: 128] +vshl.i32 q10,q14,#1 +add r2,sp,#592 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q15,q12,#1 +vadd.i32 q8,q8,q4 +vext.32 d10,d31,d30,#0 +vadd.i32 q7,q7,q1 +add r2,sp,#608 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q8,d18,d5 +vmlal.s32 q8,d26,d4 +vmlal.s32 q8,d19,d9 +vmlal.s32 q8,d27,d3 +vmlal.s32 q8,d22,d8 +vmlal.s32 q8,d28,d2 +vmlal.s32 q8,d23,d7 +vmlal.s32 q8,d29,d1 +vmlal.s32 q8,d24,d6 +vmlal.s32 q8,d25,d0 +add r2,sp,#624 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q2,d18,d4 +vmlal.s32 q2,d12,d9 +vmlal.s32 q2,d13,d8 +vmlal.s32 q2,d19,d3 +vmlal.s32 q2,d22,d2 +vmlal.s32 q2,d23,d1 +vmlal.s32 q2,d24,d0 +add r2,sp,#640 +vst1.8 {d20-d21},[r2,: 128] +vmull.s32 q7,d18,d9 +vmlal.s32 q7,d26,d3 +vmlal.s32 q7,d19,d8 +vmlal.s32 q7,d27,d2 +vmlal.s32 q7,d22,d7 +vmlal.s32 q7,d28,d1 +vmlal.s32 q7,d23,d6 +vmlal.s32 q7,d29,d0 +add r2,sp,#656 +vst1.8 {d10-d11},[r2,: 128] +vmull.s32 q5,d18,d3 +vmlal.s32 q5,d19,d2 +vmlal.s32 q5,d22,d1 +vmlal.s32 q5,d23,d0 +vmlal.s32 q5,d12,d8 +add r2,sp,#672 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q4,d18,d8 +vmlal.s32 q4,d26,d2 +vmlal.s32 q4,d19,d7 +vmlal.s32 q4,d27,d1 +vmlal.s32 q4,d22,d6 +vmlal.s32 q4,d28,d0 +vmull.s32 q8,d18,d7 +vmlal.s32 q8,d26,d1 +vmlal.s32 q8,d19,d6 +vmlal.s32 q8,d27,d0 +add r2,sp,#576 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q7,d24,d21 +vmlal.s32 q7,d25,d20 +vmlal.s32 q4,d23,d21 +vmlal.s32 q4,d29,d20 +vmlal.s32 q8,d22,d21 +vmlal.s32 q8,d28,d20 +vmlal.s32 q5,d24,d20 +add r2,sp,#576 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q7,d18,d6 +vmlal.s32 q7,d26,d0 +add r2,sp,#656 +vld1.8 {d30-d31},[r2,: 128] +vmlal.s32 q2,d30,d21 +vmlal.s32 q7,d19,d21 +vmlal.s32 q7,d27,d20 +add r2,sp,#624 +vld1.8 {d26-d27},[r2,: 128] +vmlal.s32 q4,d25,d27 +vmlal.s32 q8,d29,d27 +vmlal.s32 q8,d25,d26 +vmlal.s32 q7,d28,d27 +vmlal.s32 q7,d29,d26 +add r2,sp,#608 +vld1.8 {d28-d29},[r2,: 128] +vmlal.s32 q4,d24,d29 +vmlal.s32 q8,d23,d29 +vmlal.s32 q8,d24,d28 +vmlal.s32 q7,d22,d29 +vmlal.s32 q7,d23,d28 +add r2,sp,#608 +vst1.8 {d8-d9},[r2,: 128] +add r2,sp,#560 +vld1.8 {d8-d9},[r2,: 128] +vmlal.s32 q7,d24,d9 +vmlal.s32 q7,d25,d31 +vmull.s32 q1,d18,d2 +vmlal.s32 q1,d19,d1 +vmlal.s32 q1,d22,d0 +vmlal.s32 q1,d24,d27 +vmlal.s32 q1,d23,d20 +vmlal.s32 q1,d12,d7 +vmlal.s32 q1,d13,d6 +vmull.s32 q6,d18,d1 +vmlal.s32 q6,d19,d0 +vmlal.s32 q6,d23,d27 +vmlal.s32 q6,d22,d20 +vmlal.s32 q6,d24,d26 +vmull.s32 q0,d18,d0 +vmlal.s32 q0,d22,d27 +vmlal.s32 q0,d23,d26 +vmlal.s32 q0,d24,d31 +vmlal.s32 q0,d19,d20 +add r2,sp,#640 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q2,d18,d7 +vmlal.s32 q2,d19,d6 +vmlal.s32 q5,d18,d6 +vmlal.s32 q5,d19,d21 +vmlal.s32 q1,d18,d21 +vmlal.s32 q1,d19,d29 +vmlal.s32 q0,d18,d28 +vmlal.s32 q0,d19,d9 +vmlal.s32 q6,d18,d29 +vmlal.s32 q6,d19,d28 +add r2,sp,#592 +vld1.8 {d18-d19},[r2,: 128] +add r2,sp,#512 +vld1.8 {d22-d23},[r2,: 128] +vmlal.s32 q5,d19,d7 +vmlal.s32 q0,d18,d21 +vmlal.s32 q0,d19,d29 +vmlal.s32 q6,d18,d6 +add r2,sp,#528 +vld1.8 {d6-d7},[r2,: 128] +vmlal.s32 q6,d19,d21 +add r2,sp,#576 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q0,d30,d8 +add r2,sp,#672 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q5,d30,d29 +add r2,sp,#608 +vld1.8 {d24-d25},[r2,: 128] +vmlal.s32 q1,d30,d28 +vadd.i64 q13,q0,q11 +vadd.i64 q14,q5,q11 +vmlal.s32 q6,d30,d9 +vshr.s64 q4,q13,#26 +vshr.s64 q13,q14,#26 +vadd.i64 q7,q7,q4 +vshl.i64 q4,q4,#26 +vadd.i64 q14,q7,q3 +vadd.i64 q9,q9,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q15,q9,q3 +vsub.i64 q0,q0,q4 +vshr.s64 q4,q14,#25 +vsub.i64 q5,q5,q13 +vshr.s64 q13,q15,#25 +vadd.i64 q6,q6,q4 +vshl.i64 q4,q4,#25 +vadd.i64 q14,q6,q11 +vadd.i64 q2,q2,q13 +vsub.i64 q4,q7,q4 +vshr.s64 q7,q14,#26 +vshl.i64 q13,q13,#25 +vadd.i64 q14,q2,q11 +vadd.i64 q8,q8,q7 +vshl.i64 q7,q7,#26 +vadd.i64 q15,q8,q3 +vsub.i64 q9,q9,q13 +vshr.s64 q13,q14,#26 +vsub.i64 q6,q6,q7 +vshr.s64 q7,q15,#25 +vadd.i64 q10,q10,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q14,q10,q3 +vadd.i64 q1,q1,q7 +add r2,r3,#144 +vshl.i64 q7,q7,#25 +add r4,r3,#96 +vadd.i64 q15,q1,q11 +add r2,r2,#8 +vsub.i64 q2,q2,q13 +add r4,r4,#8 +vshr.s64 q13,q14,#25 +vsub.i64 q7,q8,q7 +vshr.s64 q8,q15,#26 +vadd.i64 q14,q13,q13 +vadd.i64 q12,q12,q8 +vtrn.32 d12,d14 +vshl.i64 q8,q8,#26 +vtrn.32 d13,d15 +vadd.i64 q3,q12,q3 +vadd.i64 q0,q0,q14 +vst1.8 d12,[r2,: 64]! +vshl.i64 q7,q13,#4 +vst1.8 d13,[r4,: 64]! +vsub.i64 q1,q1,q8 +vshr.s64 q3,q3,#25 +vadd.i64 q0,q0,q7 +vadd.i64 q5,q5,q3 +vshl.i64 q3,q3,#25 +vadd.i64 q6,q5,q11 +vadd.i64 q0,q0,q13 +vshl.i64 q7,q13,#25 +vadd.i64 q8,q0,q11 +vsub.i64 q3,q12,q3 +vshr.s64 q6,q6,#26 +vsub.i64 q7,q10,q7 +vtrn.32 d2,d6 +vshr.s64 q8,q8,#26 +vtrn.32 d3,d7 +vadd.i64 q3,q9,q6 +vst1.8 d2,[r2,: 64] +vshl.i64 q6,q6,#26 +vst1.8 d3,[r4,: 64] +vadd.i64 q1,q4,q8 +vtrn.32 d4,d14 +vshl.i64 q4,q8,#26 +vtrn.32 d5,d15 +vsub.i64 q5,q5,q6 +add r2,r2,#16 +vsub.i64 q0,q0,q4 +vst1.8 d4,[r2,: 64] +add r4,r4,#16 +vst1.8 d5,[r4,: 64] +vtrn.32 d10,d6 +vtrn.32 d11,d7 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d0,d2 +vtrn.32 d1,d3 +vst1.8 d10,[r2,: 64] +vst1.8 d11,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d0,[r2,: 64] +vst1.8 d1,[r4,: 64] +add r2,r3,#288 +add r4,r3,#336 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vsub.i32 q0,q0,q1 +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4-d5},[r4,: 128]! +vsub.i32 q1,q1,q2 +add r5,r3,#240 +vld1.8 {d4},[r2,: 64] +vld1.8 {d6},[r4,: 64] +vsub.i32 q2,q2,q3 +vst1.8 {d0-d1},[r5,: 128]! +vst1.8 {d2-d3},[r5,: 128]! +vst1.8 d4,[r5,: 64] +add r2,r3,#144 +add r4,r3,#96 +add r5,r3,#144 +add r6,r3,#192 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vsub.i32 q2,q0,q1 +vadd.i32 q0,q0,q1 +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d6-d7},[r4,: 128]! +vsub.i32 q4,q1,q3 +vadd.i32 q1,q1,q3 +vld1.8 {d6},[r2,: 64] +vld1.8 {d10},[r4,: 64] +vsub.i32 q6,q3,q5 +vadd.i32 q3,q3,q5 +vst1.8 {d4-d5},[r5,: 128]! +vst1.8 {d0-d1},[r6,: 128]! +vst1.8 {d8-d9},[r5,: 128]! +vst1.8 {d2-d3},[r6,: 128]! +vst1.8 d12,[r5,: 64] +vst1.8 d6,[r6,: 64] +add r2,r3,#0 +add r4,r3,#240 +vld1.8 {d0-d1},[r4,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4},[r4,: 64] +add r4,r3,#336 +vld1.8 {d6-d7},[r4,: 128]! +vtrn.32 q0,q3 +vld1.8 {d8-d9},[r4,: 128]! +vshl.i32 q5,q0,#4 +vtrn.32 q1,q4 +vshl.i32 q6,q3,#4 +vadd.i32 q5,q5,q0 +vadd.i32 q6,q6,q3 +vshl.i32 q7,q1,#4 +vld1.8 {d5},[r4,: 64] +vshl.i32 q8,q4,#4 +vtrn.32 d4,d5 +vadd.i32 q7,q7,q1 +vadd.i32 q8,q8,q4 +vld1.8 {d18-d19},[r2,: 128]! +vshl.i32 q10,q2,#4 +vld1.8 {d22-d23},[r2,: 128]! +vadd.i32 q10,q10,q2 +vld1.8 {d24},[r2,: 64] +vadd.i32 q5,q5,q0 +add r2,r3,#288 +vld1.8 {d26-d27},[r2,: 128]! +vadd.i32 q6,q6,q3 +vld1.8 {d28-d29},[r2,: 128]! +vadd.i32 q8,q8,q4 +vld1.8 {d25},[r2,: 64] +vadd.i32 q10,q10,q2 +vtrn.32 q9,q13 +vadd.i32 q7,q7,q1 +vadd.i32 q5,q5,q0 +vtrn.32 q11,q14 +vadd.i32 q6,q6,q3 +add r2,sp,#560 +vadd.i32 q10,q10,q2 +vtrn.32 d24,d25 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q6,q13,#1 +add r2,sp,#576 +vst1.8 {d20-d21},[r2,: 128] +vshl.i32 q10,q14,#1 +add r2,sp,#592 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q15,q12,#1 +vadd.i32 q8,q8,q4 +vext.32 d10,d31,d30,#0 +vadd.i32 q7,q7,q1 +add r2,sp,#608 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q8,d18,d5 +vmlal.s32 q8,d26,d4 +vmlal.s32 q8,d19,d9 +vmlal.s32 q8,d27,d3 +vmlal.s32 q8,d22,d8 +vmlal.s32 q8,d28,d2 +vmlal.s32 q8,d23,d7 +vmlal.s32 q8,d29,d1 +vmlal.s32 q8,d24,d6 +vmlal.s32 q8,d25,d0 +add r2,sp,#624 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q2,d18,d4 +vmlal.s32 q2,d12,d9 +vmlal.s32 q2,d13,d8 +vmlal.s32 q2,d19,d3 +vmlal.s32 q2,d22,d2 +vmlal.s32 q2,d23,d1 +vmlal.s32 q2,d24,d0 +add r2,sp,#640 +vst1.8 {d20-d21},[r2,: 128] +vmull.s32 q7,d18,d9 +vmlal.s32 q7,d26,d3 +vmlal.s32 q7,d19,d8 +vmlal.s32 q7,d27,d2 +vmlal.s32 q7,d22,d7 +vmlal.s32 q7,d28,d1 +vmlal.s32 q7,d23,d6 +vmlal.s32 q7,d29,d0 +add r2,sp,#656 +vst1.8 {d10-d11},[r2,: 128] +vmull.s32 q5,d18,d3 +vmlal.s32 q5,d19,d2 +vmlal.s32 q5,d22,d1 +vmlal.s32 q5,d23,d0 +vmlal.s32 q5,d12,d8 +add r2,sp,#672 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q4,d18,d8 +vmlal.s32 q4,d26,d2 +vmlal.s32 q4,d19,d7 +vmlal.s32 q4,d27,d1 +vmlal.s32 q4,d22,d6 +vmlal.s32 q4,d28,d0 +vmull.s32 q8,d18,d7 +vmlal.s32 q8,d26,d1 +vmlal.s32 q8,d19,d6 +vmlal.s32 q8,d27,d0 +add r2,sp,#576 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q7,d24,d21 +vmlal.s32 q7,d25,d20 +vmlal.s32 q4,d23,d21 +vmlal.s32 q4,d29,d20 +vmlal.s32 q8,d22,d21 +vmlal.s32 q8,d28,d20 +vmlal.s32 q5,d24,d20 +add r2,sp,#576 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q7,d18,d6 +vmlal.s32 q7,d26,d0 +add r2,sp,#656 +vld1.8 {d30-d31},[r2,: 128] +vmlal.s32 q2,d30,d21 +vmlal.s32 q7,d19,d21 +vmlal.s32 q7,d27,d20 +add r2,sp,#624 +vld1.8 {d26-d27},[r2,: 128] +vmlal.s32 q4,d25,d27 +vmlal.s32 q8,d29,d27 +vmlal.s32 q8,d25,d26 +vmlal.s32 q7,d28,d27 +vmlal.s32 q7,d29,d26 +add r2,sp,#608 +vld1.8 {d28-d29},[r2,: 128] +vmlal.s32 q4,d24,d29 +vmlal.s32 q8,d23,d29 +vmlal.s32 q8,d24,d28 +vmlal.s32 q7,d22,d29 +vmlal.s32 q7,d23,d28 +add r2,sp,#608 +vst1.8 {d8-d9},[r2,: 128] +add r2,sp,#560 +vld1.8 {d8-d9},[r2,: 128] +vmlal.s32 q7,d24,d9 +vmlal.s32 q7,d25,d31 +vmull.s32 q1,d18,d2 +vmlal.s32 q1,d19,d1 +vmlal.s32 q1,d22,d0 +vmlal.s32 q1,d24,d27 +vmlal.s32 q1,d23,d20 +vmlal.s32 q1,d12,d7 +vmlal.s32 q1,d13,d6 +vmull.s32 q6,d18,d1 +vmlal.s32 q6,d19,d0 +vmlal.s32 q6,d23,d27 +vmlal.s32 q6,d22,d20 +vmlal.s32 q6,d24,d26 +vmull.s32 q0,d18,d0 +vmlal.s32 q0,d22,d27 +vmlal.s32 q0,d23,d26 +vmlal.s32 q0,d24,d31 +vmlal.s32 q0,d19,d20 +add r2,sp,#640 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q2,d18,d7 +vmlal.s32 q2,d19,d6 +vmlal.s32 q5,d18,d6 +vmlal.s32 q5,d19,d21 +vmlal.s32 q1,d18,d21 +vmlal.s32 q1,d19,d29 +vmlal.s32 q0,d18,d28 +vmlal.s32 q0,d19,d9 +vmlal.s32 q6,d18,d29 +vmlal.s32 q6,d19,d28 +add r2,sp,#592 +vld1.8 {d18-d19},[r2,: 128] +add r2,sp,#512 +vld1.8 {d22-d23},[r2,: 128] +vmlal.s32 q5,d19,d7 +vmlal.s32 q0,d18,d21 +vmlal.s32 q0,d19,d29 +vmlal.s32 q6,d18,d6 +add r2,sp,#528 +vld1.8 {d6-d7},[r2,: 128] +vmlal.s32 q6,d19,d21 +add r2,sp,#576 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q0,d30,d8 +add r2,sp,#672 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q5,d30,d29 +add r2,sp,#608 +vld1.8 {d24-d25},[r2,: 128] +vmlal.s32 q1,d30,d28 +vadd.i64 q13,q0,q11 +vadd.i64 q14,q5,q11 +vmlal.s32 q6,d30,d9 +vshr.s64 q4,q13,#26 +vshr.s64 q13,q14,#26 +vadd.i64 q7,q7,q4 +vshl.i64 q4,q4,#26 +vadd.i64 q14,q7,q3 +vadd.i64 q9,q9,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q15,q9,q3 +vsub.i64 q0,q0,q4 +vshr.s64 q4,q14,#25 +vsub.i64 q5,q5,q13 +vshr.s64 q13,q15,#25 +vadd.i64 q6,q6,q4 +vshl.i64 q4,q4,#25 +vadd.i64 q14,q6,q11 +vadd.i64 q2,q2,q13 +vsub.i64 q4,q7,q4 +vshr.s64 q7,q14,#26 +vshl.i64 q13,q13,#25 +vadd.i64 q14,q2,q11 +vadd.i64 q8,q8,q7 +vshl.i64 q7,q7,#26 +vadd.i64 q15,q8,q3 +vsub.i64 q9,q9,q13 +vshr.s64 q13,q14,#26 +vsub.i64 q6,q6,q7 +vshr.s64 q7,q15,#25 +vadd.i64 q10,q10,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q14,q10,q3 +vadd.i64 q1,q1,q7 +add r2,r3,#288 +vshl.i64 q7,q7,#25 +add r4,r3,#96 +vadd.i64 q15,q1,q11 +add r2,r2,#8 +vsub.i64 q2,q2,q13 +add r4,r4,#8 +vshr.s64 q13,q14,#25 +vsub.i64 q7,q8,q7 +vshr.s64 q8,q15,#26 +vadd.i64 q14,q13,q13 +vadd.i64 q12,q12,q8 +vtrn.32 d12,d14 +vshl.i64 q8,q8,#26 +vtrn.32 d13,d15 +vadd.i64 q3,q12,q3 +vadd.i64 q0,q0,q14 +vst1.8 d12,[r2,: 64]! +vshl.i64 q7,q13,#4 +vst1.8 d13,[r4,: 64]! +vsub.i64 q1,q1,q8 +vshr.s64 q3,q3,#25 +vadd.i64 q0,q0,q7 +vadd.i64 q5,q5,q3 +vshl.i64 q3,q3,#25 +vadd.i64 q6,q5,q11 +vadd.i64 q0,q0,q13 +vshl.i64 q7,q13,#25 +vadd.i64 q8,q0,q11 +vsub.i64 q3,q12,q3 +vshr.s64 q6,q6,#26 +vsub.i64 q7,q10,q7 +vtrn.32 d2,d6 +vshr.s64 q8,q8,#26 +vtrn.32 d3,d7 +vadd.i64 q3,q9,q6 +vst1.8 d2,[r2,: 64] +vshl.i64 q6,q6,#26 +vst1.8 d3,[r4,: 64] +vadd.i64 q1,q4,q8 +vtrn.32 d4,d14 +vshl.i64 q4,q8,#26 +vtrn.32 d5,d15 +vsub.i64 q5,q5,q6 +add r2,r2,#16 +vsub.i64 q0,q0,q4 +vst1.8 d4,[r2,: 64] +add r4,r4,#16 +vst1.8 d5,[r4,: 64] +vtrn.32 d10,d6 +vtrn.32 d11,d7 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d0,d2 +vtrn.32 d1,d3 +vst1.8 d10,[r2,: 64] +vst1.8 d11,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d0,[r2,: 64] +vst1.8 d1,[r4,: 64] +add r2,sp,#544 +add r4,r3,#144 +add r5,r3,#192 +vld1.8 {d0-d1},[r2,: 128] +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4-d5},[r5,: 128]! +vzip.i32 q1,q2 +vld1.8 {d6-d7},[r4,: 128]! +vld1.8 {d8-d9},[r5,: 128]! +vshl.i32 q5,q1,#1 +vzip.i32 q3,q4 +vshl.i32 q6,q2,#1 +vld1.8 {d14},[r4,: 64] +vshl.i32 q8,q3,#1 +vld1.8 {d15},[r5,: 64] +vshl.i32 q9,q4,#1 +vmul.i32 d21,d7,d1 +vtrn.32 d14,d15 +vmul.i32 q11,q4,q0 +vmul.i32 q0,q7,q0 +vmull.s32 q12,d2,d2 +vmlal.s32 q12,d11,d1 +vmlal.s32 q12,d12,d0 +vmlal.s32 q12,d13,d23 +vmlal.s32 q12,d16,d22 +vmlal.s32 q12,d7,d21 +vmull.s32 q10,d2,d11 +vmlal.s32 q10,d4,d1 +vmlal.s32 q10,d13,d0 +vmlal.s32 q10,d6,d23 +vmlal.s32 q10,d17,d22 +vmull.s32 q13,d10,d4 +vmlal.s32 q13,d11,d3 +vmlal.s32 q13,d13,d1 +vmlal.s32 q13,d16,d0 +vmlal.s32 q13,d17,d23 +vmlal.s32 q13,d8,d22 +vmull.s32 q1,d10,d5 +vmlal.s32 q1,d11,d4 +vmlal.s32 q1,d6,d1 +vmlal.s32 q1,d17,d0 +vmlal.s32 q1,d8,d23 +vmull.s32 q14,d10,d6 +vmlal.s32 q14,d11,d13 +vmlal.s32 q14,d4,d4 +vmlal.s32 q14,d17,d1 +vmlal.s32 q14,d18,d0 +vmlal.s32 q14,d9,d23 +vmull.s32 q11,d10,d7 +vmlal.s32 q11,d11,d6 +vmlal.s32 q11,d12,d5 +vmlal.s32 q11,d8,d1 +vmlal.s32 q11,d19,d0 +vmull.s32 q15,d10,d8 +vmlal.s32 q15,d11,d17 +vmlal.s32 q15,d12,d6 +vmlal.s32 q15,d13,d5 +vmlal.s32 q15,d19,d1 +vmlal.s32 q15,d14,d0 +vmull.s32 q2,d10,d9 +vmlal.s32 q2,d11,d8 +vmlal.s32 q2,d12,d7 +vmlal.s32 q2,d13,d6 +vmlal.s32 q2,d14,d1 +vmull.s32 q0,d15,d1 +vmlal.s32 q0,d10,d14 +vmlal.s32 q0,d11,d19 +vmlal.s32 q0,d12,d8 +vmlal.s32 q0,d13,d17 +vmlal.s32 q0,d6,d6 +add r2,sp,#512 +vld1.8 {d18-d19},[r2,: 128] +vmull.s32 q3,d16,d7 +vmlal.s32 q3,d10,d15 +vmlal.s32 q3,d11,d14 +vmlal.s32 q3,d12,d9 +vmlal.s32 q3,d13,d8 +add r2,sp,#528 +vld1.8 {d8-d9},[r2,: 128] +vadd.i64 q5,q12,q9 +vadd.i64 q6,q15,q9 +vshr.s64 q5,q5,#26 +vshr.s64 q6,q6,#26 +vadd.i64 q7,q10,q5 +vshl.i64 q5,q5,#26 +vadd.i64 q8,q7,q4 +vadd.i64 q2,q2,q6 +vshl.i64 q6,q6,#26 +vadd.i64 q10,q2,q4 +vsub.i64 q5,q12,q5 +vshr.s64 q8,q8,#25 +vsub.i64 q6,q15,q6 +vshr.s64 q10,q10,#25 +vadd.i64 q12,q13,q8 +vshl.i64 q8,q8,#25 +vadd.i64 q13,q12,q9 +vadd.i64 q0,q0,q10 +vsub.i64 q7,q7,q8 +vshr.s64 q8,q13,#26 +vshl.i64 q10,q10,#25 +vadd.i64 q13,q0,q9 +vadd.i64 q1,q1,q8 +vshl.i64 q8,q8,#26 +vadd.i64 q15,q1,q4 +vsub.i64 q2,q2,q10 +vshr.s64 q10,q13,#26 +vsub.i64 q8,q12,q8 +vshr.s64 q12,q15,#25 +vadd.i64 q3,q3,q10 +vshl.i64 q10,q10,#26 +vadd.i64 q13,q3,q4 +vadd.i64 q14,q14,q12 +add r2,r3,#144 +vshl.i64 q12,q12,#25 +add r4,r3,#192 +vadd.i64 q15,q14,q9 +add r2,r2,#8 +vsub.i64 q0,q0,q10 +add r4,r4,#8 +vshr.s64 q10,q13,#25 +vsub.i64 q1,q1,q12 +vshr.s64 q12,q15,#26 +vadd.i64 q13,q10,q10 +vadd.i64 q11,q11,q12 +vtrn.32 d16,d2 +vshl.i64 q12,q12,#26 +vtrn.32 d17,d3 +vadd.i64 q1,q11,q4 +vadd.i64 q4,q5,q13 +vst1.8 d16,[r2,: 64]! +vshl.i64 q5,q10,#4 +vst1.8 d17,[r4,: 64]! +vsub.i64 q8,q14,q12 +vshr.s64 q1,q1,#25 +vadd.i64 q4,q4,q5 +vadd.i64 q5,q6,q1 +vshl.i64 q1,q1,#25 +vadd.i64 q6,q5,q9 +vadd.i64 q4,q4,q10 +vshl.i64 q10,q10,#25 +vadd.i64 q9,q4,q9 +vsub.i64 q1,q11,q1 +vshr.s64 q6,q6,#26 +vsub.i64 q3,q3,q10 +vtrn.32 d16,d2 +vshr.s64 q9,q9,#26 +vtrn.32 d17,d3 +vadd.i64 q1,q2,q6 +vst1.8 d16,[r2,: 64] +vshl.i64 q2,q6,#26 +vst1.8 d17,[r4,: 64] +vadd.i64 q6,q7,q9 +vtrn.32 d0,d6 +vshl.i64 q7,q9,#26 +vtrn.32 d1,d7 +vsub.i64 q2,q5,q2 +add r2,r2,#16 +vsub.i64 q3,q4,q7 +vst1.8 d0,[r2,: 64] +add r4,r4,#16 +vst1.8 d1,[r4,: 64] +vtrn.32 d4,d2 +vtrn.32 d5,d3 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d6,d12 +vtrn.32 d7,d13 +vst1.8 d4,[r2,: 64] +vst1.8 d5,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d6,[r2,: 64] +vst1.8 d7,[r4,: 64] +add r2,r3,#336 +add r4,r3,#288 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vadd.i32 q0,q0,q1 +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4-d5},[r4,: 128]! +vadd.i32 q1,q1,q2 +add r5,r3,#288 +vld1.8 {d4},[r2,: 64] +vld1.8 {d6},[r4,: 64] +vadd.i32 q2,q2,q3 +vst1.8 {d0-d1},[r5,: 128]! +vst1.8 {d2-d3},[r5,: 128]! +vst1.8 d4,[r5,: 64] +add r2,r3,#48 +add r4,r3,#144 +vld1.8 {d0-d1},[r4,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4},[r4,: 64] +add r4,r3,#288 +vld1.8 {d6-d7},[r4,: 128]! +vtrn.32 q0,q3 +vld1.8 {d8-d9},[r4,: 128]! +vshl.i32 q5,q0,#4 +vtrn.32 q1,q4 +vshl.i32 q6,q3,#4 +vadd.i32 q5,q5,q0 +vadd.i32 q6,q6,q3 +vshl.i32 q7,q1,#4 +vld1.8 {d5},[r4,: 64] +vshl.i32 q8,q4,#4 +vtrn.32 d4,d5 +vadd.i32 q7,q7,q1 +vadd.i32 q8,q8,q4 +vld1.8 {d18-d19},[r2,: 128]! +vshl.i32 q10,q2,#4 +vld1.8 {d22-d23},[r2,: 128]! +vadd.i32 q10,q10,q2 +vld1.8 {d24},[r2,: 64] +vadd.i32 q5,q5,q0 +add r2,r3,#240 +vld1.8 {d26-d27},[r2,: 128]! +vadd.i32 q6,q6,q3 +vld1.8 {d28-d29},[r2,: 128]! +vadd.i32 q8,q8,q4 +vld1.8 {d25},[r2,: 64] +vadd.i32 q10,q10,q2 +vtrn.32 q9,q13 +vadd.i32 q7,q7,q1 +vadd.i32 q5,q5,q0 +vtrn.32 q11,q14 +vadd.i32 q6,q6,q3 +add r2,sp,#560 +vadd.i32 q10,q10,q2 +vtrn.32 d24,d25 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q6,q13,#1 +add r2,sp,#576 +vst1.8 {d20-d21},[r2,: 128] +vshl.i32 q10,q14,#1 +add r2,sp,#592 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q15,q12,#1 +vadd.i32 q8,q8,q4 +vext.32 d10,d31,d30,#0 +vadd.i32 q7,q7,q1 +add r2,sp,#608 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q8,d18,d5 +vmlal.s32 q8,d26,d4 +vmlal.s32 q8,d19,d9 +vmlal.s32 q8,d27,d3 +vmlal.s32 q8,d22,d8 +vmlal.s32 q8,d28,d2 +vmlal.s32 q8,d23,d7 +vmlal.s32 q8,d29,d1 +vmlal.s32 q8,d24,d6 +vmlal.s32 q8,d25,d0 +add r2,sp,#624 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q2,d18,d4 +vmlal.s32 q2,d12,d9 +vmlal.s32 q2,d13,d8 +vmlal.s32 q2,d19,d3 +vmlal.s32 q2,d22,d2 +vmlal.s32 q2,d23,d1 +vmlal.s32 q2,d24,d0 +add r2,sp,#640 +vst1.8 {d20-d21},[r2,: 128] +vmull.s32 q7,d18,d9 +vmlal.s32 q7,d26,d3 +vmlal.s32 q7,d19,d8 +vmlal.s32 q7,d27,d2 +vmlal.s32 q7,d22,d7 +vmlal.s32 q7,d28,d1 +vmlal.s32 q7,d23,d6 +vmlal.s32 q7,d29,d0 +add r2,sp,#656 +vst1.8 {d10-d11},[r2,: 128] +vmull.s32 q5,d18,d3 +vmlal.s32 q5,d19,d2 +vmlal.s32 q5,d22,d1 +vmlal.s32 q5,d23,d0 +vmlal.s32 q5,d12,d8 +add r2,sp,#672 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q4,d18,d8 +vmlal.s32 q4,d26,d2 +vmlal.s32 q4,d19,d7 +vmlal.s32 q4,d27,d1 +vmlal.s32 q4,d22,d6 +vmlal.s32 q4,d28,d0 +vmull.s32 q8,d18,d7 +vmlal.s32 q8,d26,d1 +vmlal.s32 q8,d19,d6 +vmlal.s32 q8,d27,d0 +add r2,sp,#576 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q7,d24,d21 +vmlal.s32 q7,d25,d20 +vmlal.s32 q4,d23,d21 +vmlal.s32 q4,d29,d20 +vmlal.s32 q8,d22,d21 +vmlal.s32 q8,d28,d20 +vmlal.s32 q5,d24,d20 +add r2,sp,#576 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q7,d18,d6 +vmlal.s32 q7,d26,d0 +add r2,sp,#656 +vld1.8 {d30-d31},[r2,: 128] +vmlal.s32 q2,d30,d21 +vmlal.s32 q7,d19,d21 +vmlal.s32 q7,d27,d20 +add r2,sp,#624 +vld1.8 {d26-d27},[r2,: 128] +vmlal.s32 q4,d25,d27 +vmlal.s32 q8,d29,d27 +vmlal.s32 q8,d25,d26 +vmlal.s32 q7,d28,d27 +vmlal.s32 q7,d29,d26 +add r2,sp,#608 +vld1.8 {d28-d29},[r2,: 128] +vmlal.s32 q4,d24,d29 +vmlal.s32 q8,d23,d29 +vmlal.s32 q8,d24,d28 +vmlal.s32 q7,d22,d29 +vmlal.s32 q7,d23,d28 +add r2,sp,#608 +vst1.8 {d8-d9},[r2,: 128] +add r2,sp,#560 +vld1.8 {d8-d9},[r2,: 128] +vmlal.s32 q7,d24,d9 +vmlal.s32 q7,d25,d31 +vmull.s32 q1,d18,d2 +vmlal.s32 q1,d19,d1 +vmlal.s32 q1,d22,d0 +vmlal.s32 q1,d24,d27 +vmlal.s32 q1,d23,d20 +vmlal.s32 q1,d12,d7 +vmlal.s32 q1,d13,d6 +vmull.s32 q6,d18,d1 +vmlal.s32 q6,d19,d0 +vmlal.s32 q6,d23,d27 +vmlal.s32 q6,d22,d20 +vmlal.s32 q6,d24,d26 +vmull.s32 q0,d18,d0 +vmlal.s32 q0,d22,d27 +vmlal.s32 q0,d23,d26 +vmlal.s32 q0,d24,d31 +vmlal.s32 q0,d19,d20 +add r2,sp,#640 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q2,d18,d7 +vmlal.s32 q2,d19,d6 +vmlal.s32 q5,d18,d6 +vmlal.s32 q5,d19,d21 +vmlal.s32 q1,d18,d21 +vmlal.s32 q1,d19,d29 +vmlal.s32 q0,d18,d28 +vmlal.s32 q0,d19,d9 +vmlal.s32 q6,d18,d29 +vmlal.s32 q6,d19,d28 +add r2,sp,#592 +vld1.8 {d18-d19},[r2,: 128] +add r2,sp,#512 +vld1.8 {d22-d23},[r2,: 128] +vmlal.s32 q5,d19,d7 +vmlal.s32 q0,d18,d21 +vmlal.s32 q0,d19,d29 +vmlal.s32 q6,d18,d6 +add r2,sp,#528 +vld1.8 {d6-d7},[r2,: 128] +vmlal.s32 q6,d19,d21 +add r2,sp,#576 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q0,d30,d8 +add r2,sp,#672 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q5,d30,d29 +add r2,sp,#608 +vld1.8 {d24-d25},[r2,: 128] +vmlal.s32 q1,d30,d28 +vadd.i64 q13,q0,q11 +vadd.i64 q14,q5,q11 +vmlal.s32 q6,d30,d9 +vshr.s64 q4,q13,#26 +vshr.s64 q13,q14,#26 +vadd.i64 q7,q7,q4 +vshl.i64 q4,q4,#26 +vadd.i64 q14,q7,q3 +vadd.i64 q9,q9,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q15,q9,q3 +vsub.i64 q0,q0,q4 +vshr.s64 q4,q14,#25 +vsub.i64 q5,q5,q13 +vshr.s64 q13,q15,#25 +vadd.i64 q6,q6,q4 +vshl.i64 q4,q4,#25 +vadd.i64 q14,q6,q11 +vadd.i64 q2,q2,q13 +vsub.i64 q4,q7,q4 +vshr.s64 q7,q14,#26 +vshl.i64 q13,q13,#25 +vadd.i64 q14,q2,q11 +vadd.i64 q8,q8,q7 +vshl.i64 q7,q7,#26 +vadd.i64 q15,q8,q3 +vsub.i64 q9,q9,q13 +vshr.s64 q13,q14,#26 +vsub.i64 q6,q6,q7 +vshr.s64 q7,q15,#25 +vadd.i64 q10,q10,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q14,q10,q3 +vadd.i64 q1,q1,q7 +add r2,r3,#240 +vshl.i64 q7,q7,#25 +add r4,r3,#144 +vadd.i64 q15,q1,q11 +add r2,r2,#8 +vsub.i64 q2,q2,q13 +add r4,r4,#8 +vshr.s64 q13,q14,#25 +vsub.i64 q7,q8,q7 +vshr.s64 q8,q15,#26 +vadd.i64 q14,q13,q13 +vadd.i64 q12,q12,q8 +vtrn.32 d12,d14 +vshl.i64 q8,q8,#26 +vtrn.32 d13,d15 +vadd.i64 q3,q12,q3 +vadd.i64 q0,q0,q14 +vst1.8 d12,[r2,: 64]! +vshl.i64 q7,q13,#4 +vst1.8 d13,[r4,: 64]! +vsub.i64 q1,q1,q8 +vshr.s64 q3,q3,#25 +vadd.i64 q0,q0,q7 +vadd.i64 q5,q5,q3 +vshl.i64 q3,q3,#25 +vadd.i64 q6,q5,q11 +vadd.i64 q0,q0,q13 +vshl.i64 q7,q13,#25 +vadd.i64 q8,q0,q11 +vsub.i64 q3,q12,q3 +vshr.s64 q6,q6,#26 +vsub.i64 q7,q10,q7 +vtrn.32 d2,d6 +vshr.s64 q8,q8,#26 +vtrn.32 d3,d7 +vadd.i64 q3,q9,q6 +vst1.8 d2,[r2,: 64] +vshl.i64 q6,q6,#26 +vst1.8 d3,[r4,: 64] +vadd.i64 q1,q4,q8 +vtrn.32 d4,d14 +vshl.i64 q4,q8,#26 +vtrn.32 d5,d15 +vsub.i64 q5,q5,q6 +add r2,r2,#16 +vsub.i64 q0,q0,q4 +vst1.8 d4,[r2,: 64] +add r4,r4,#16 +vst1.8 d5,[r4,: 64] +vtrn.32 d10,d6 +vtrn.32 d11,d7 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d0,d2 +vtrn.32 d1,d3 +vst1.8 d10,[r2,: 64] +vst1.8 d11,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d0,[r2,: 64] +vst1.8 d1,[r4,: 64] +ldr r2,[sp,#488] +ldr r4,[sp,#492] +subs r5,r2,#1 +bge ._mainloop +add r1,r3,#144 +add r2,r3,#336 +vld1.8 {d0-d1},[r1,: 128]! +vld1.8 {d2-d3},[r1,: 128]! +vld1.8 {d4},[r1,: 64] +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 {d2-d3},[r2,: 128]! +vst1.8 d4,[r2,: 64] +ldr r1,=0 +._invertloop: +add r2,r3,#144 +ldr r4,=0 +ldr r5,=2 +cmp r1,#1 +ldreq r5,=1 +addeq r2,r3,#336 +addeq r4,r3,#48 +cmp r1,#2 +ldreq r5,=1 +addeq r2,r3,#48 +cmp r1,#3 +ldreq r5,=5 +addeq r4,r3,#336 +cmp r1,#4 +ldreq r5,=10 +cmp r1,#5 +ldreq r5,=20 +cmp r1,#6 +ldreq r5,=10 +addeq r2,r3,#336 +addeq r4,r3,#336 +cmp r1,#7 +ldreq r5,=50 +cmp r1,#8 +ldreq r5,=100 +cmp r1,#9 +ldreq r5,=50 +addeq r2,r3,#336 +cmp r1,#10 +ldreq r5,=5 +addeq r2,r3,#48 +cmp r1,#11 +ldreq r5,=0 +addeq r2,r3,#96 +add r6,r3,#144 +add r7,r3,#288 +vld1.8 {d0-d1},[r6,: 128]! +vld1.8 {d2-d3},[r6,: 128]! +vld1.8 {d4},[r6,: 64] +vst1.8 {d0-d1},[r7,: 128]! +vst1.8 {d2-d3},[r7,: 128]! +vst1.8 d4,[r7,: 64] +cmp r5,#0 +beq ._skipsquaringloop +._squaringloop: +add r6,r3,#288 +add r7,r3,#288 +add r8,r3,#288 +vmov.i32 q0,#19 +vmov.i32 q1,#0 +vmov.i32 q2,#1 +vzip.i32 q1,q2 +vld1.8 {d4-d5},[r7,: 128]! +vld1.8 {d6-d7},[r7,: 128]! +vld1.8 {d9},[r7,: 64] +vld1.8 {d10-d11},[r6,: 128]! +add r7,sp,#416 +vld1.8 {d12-d13},[r6,: 128]! +vmul.i32 q7,q2,q0 +vld1.8 {d8},[r6,: 64] +vext.32 d17,d11,d10,#1 +vmul.i32 q9,q3,q0 +vext.32 d16,d10,d8,#1 +vshl.u32 q10,q5,q1 +vext.32 d22,d14,d4,#1 +vext.32 d24,d18,d6,#1 +vshl.u32 q13,q6,q1 +vshl.u32 d28,d8,d2 +vrev64.i32 d22,d22 +vmul.i32 d1,d9,d1 +vrev64.i32 d24,d24 +vext.32 d29,d8,d13,#1 +vext.32 d0,d1,d9,#1 +vrev64.i32 d0,d0 +vext.32 d2,d9,d1,#1 +vext.32 d23,d15,d5,#1 +vmull.s32 q4,d20,d4 +vrev64.i32 d23,d23 +vmlal.s32 q4,d21,d1 +vrev64.i32 d2,d2 +vmlal.s32 q4,d26,d19 +vext.32 d3,d5,d15,#1 +vmlal.s32 q4,d27,d18 +vrev64.i32 d3,d3 +vmlal.s32 q4,d28,d15 +vext.32 d14,d12,d11,#1 +vmull.s32 q5,d16,d23 +vext.32 d15,d13,d12,#1 +vmlal.s32 q5,d17,d4 +vst1.8 d8,[r7,: 64]! +vmlal.s32 q5,d14,d1 +vext.32 d12,d9,d8,#0 +vmlal.s32 q5,d15,d19 +vmov.i64 d13,#0 +vmlal.s32 q5,d29,d18 +vext.32 d25,d19,d7,#1 +vmlal.s32 q6,d20,d5 +vrev64.i32 d25,d25 +vmlal.s32 q6,d21,d4 +vst1.8 d11,[r7,: 64]! +vmlal.s32 q6,d26,d1 +vext.32 d9,d10,d10,#0 +vmlal.s32 q6,d27,d19 +vmov.i64 d8,#0 +vmlal.s32 q6,d28,d18 +vmlal.s32 q4,d16,d24 +vmlal.s32 q4,d17,d5 +vmlal.s32 q4,d14,d4 +vst1.8 d12,[r7,: 64]! +vmlal.s32 q4,d15,d1 +vext.32 d10,d13,d12,#0 +vmlal.s32 q4,d29,d19 +vmov.i64 d11,#0 +vmlal.s32 q5,d20,d6 +vmlal.s32 q5,d21,d5 +vmlal.s32 q5,d26,d4 +vext.32 d13,d8,d8,#0 +vmlal.s32 q5,d27,d1 +vmov.i64 d12,#0 +vmlal.s32 q5,d28,d19 +vst1.8 d9,[r7,: 64]! +vmlal.s32 q6,d16,d25 +vmlal.s32 q6,d17,d6 +vst1.8 d10,[r7,: 64] +vmlal.s32 q6,d14,d5 +vext.32 d8,d11,d10,#0 +vmlal.s32 q6,d15,d4 +vmov.i64 d9,#0 +vmlal.s32 q6,d29,d1 +vmlal.s32 q4,d20,d7 +vmlal.s32 q4,d21,d6 +vmlal.s32 q4,d26,d5 +vext.32 d11,d12,d12,#0 +vmlal.s32 q4,d27,d4 +vmov.i64 d10,#0 +vmlal.s32 q4,d28,d1 +vmlal.s32 q5,d16,d0 +sub r6,r7,#32 +vmlal.s32 q5,d17,d7 +vmlal.s32 q5,d14,d6 +vext.32 d30,d9,d8,#0 +vmlal.s32 q5,d15,d5 +vld1.8 {d31},[r6,: 64]! +vmlal.s32 q5,d29,d4 +vmlal.s32 q15,d20,d0 +vext.32 d0,d6,d18,#1 +vmlal.s32 q15,d21,d25 +vrev64.i32 d0,d0 +vmlal.s32 q15,d26,d24 +vext.32 d1,d7,d19,#1 +vext.32 d7,d10,d10,#0 +vmlal.s32 q15,d27,d23 +vrev64.i32 d1,d1 +vld1.8 {d6},[r6,: 64] +vmlal.s32 q15,d28,d22 +vmlal.s32 q3,d16,d4 +add r6,r6,#24 +vmlal.s32 q3,d17,d2 +vext.32 d4,d31,d30,#0 +vmov d17,d11 +vmlal.s32 q3,d14,d1 +vext.32 d11,d13,d13,#0 +vext.32 d13,d30,d30,#0 +vmlal.s32 q3,d15,d0 +vext.32 d1,d8,d8,#0 +vmlal.s32 q3,d29,d3 +vld1.8 {d5},[r6,: 64] +sub r6,r6,#16 +vext.32 d10,d6,d6,#0 +vmov.i32 q1,#0xffffffff +vshl.i64 q4,q1,#25 +add r7,sp,#512 +vld1.8 {d14-d15},[r7,: 128] +vadd.i64 q9,q2,q7 +vshl.i64 q1,q1,#26 +vshr.s64 q10,q9,#26 +vld1.8 {d0},[r6,: 64]! +vadd.i64 q5,q5,q10 +vand q9,q9,q1 +vld1.8 {d16},[r6,: 64]! +add r6,sp,#528 +vld1.8 {d20-d21},[r6,: 128] +vadd.i64 q11,q5,q10 +vsub.i64 q2,q2,q9 +vshr.s64 q9,q11,#25 +vext.32 d12,d5,d4,#0 +vand q11,q11,q4 +vadd.i64 q0,q0,q9 +vmov d19,d7 +vadd.i64 q3,q0,q7 +vsub.i64 q5,q5,q11 +vshr.s64 q11,q3,#26 +vext.32 d18,d11,d10,#0 +vand q3,q3,q1 +vadd.i64 q8,q8,q11 +vadd.i64 q11,q8,q10 +vsub.i64 q0,q0,q3 +vshr.s64 q3,q11,#25 +vand q11,q11,q4 +vadd.i64 q3,q6,q3 +vadd.i64 q6,q3,q7 +vsub.i64 q8,q8,q11 +vshr.s64 q11,q6,#26 +vand q6,q6,q1 +vadd.i64 q9,q9,q11 +vadd.i64 d25,d19,d21 +vsub.i64 q3,q3,q6 +vshr.s64 d23,d25,#25 +vand q4,q12,q4 +vadd.i64 d21,d23,d23 +vshl.i64 d25,d23,#4 +vadd.i64 d21,d21,d23 +vadd.i64 d25,d25,d21 +vadd.i64 d4,d4,d25 +vzip.i32 q0,q8 +vadd.i64 d12,d4,d14 +add r6,r8,#8 +vst1.8 d0,[r6,: 64] +vsub.i64 d19,d19,d9 +add r6,r6,#16 +vst1.8 d16,[r6,: 64] +vshr.s64 d22,d12,#26 +vand q0,q6,q1 +vadd.i64 d10,d10,d22 +vzip.i32 q3,q9 +vsub.i64 d4,d4,d0 +sub r6,r6,#8 +vst1.8 d6,[r6,: 64] +add r6,r6,#16 +vst1.8 d18,[r6,: 64] +vzip.i32 q2,q5 +sub r6,r6,#32 +vst1.8 d4,[r6,: 64] +subs r5,r5,#1 +bhi ._squaringloop +._skipsquaringloop: +mov r2,r2 +add r5,r3,#288 +add r6,r3,#144 +vmov.i32 q0,#19 +vmov.i32 q1,#0 +vmov.i32 q2,#1 +vzip.i32 q1,q2 +vld1.8 {d4-d5},[r5,: 128]! +vld1.8 {d6-d7},[r5,: 128]! +vld1.8 {d9},[r5,: 64] +vld1.8 {d10-d11},[r2,: 128]! +add r5,sp,#416 +vld1.8 {d12-d13},[r2,: 128]! +vmul.i32 q7,q2,q0 +vld1.8 {d8},[r2,: 64] +vext.32 d17,d11,d10,#1 +vmul.i32 q9,q3,q0 +vext.32 d16,d10,d8,#1 +vshl.u32 q10,q5,q1 +vext.32 d22,d14,d4,#1 +vext.32 d24,d18,d6,#1 +vshl.u32 q13,q6,q1 +vshl.u32 d28,d8,d2 +vrev64.i32 d22,d22 +vmul.i32 d1,d9,d1 +vrev64.i32 d24,d24 +vext.32 d29,d8,d13,#1 +vext.32 d0,d1,d9,#1 +vrev64.i32 d0,d0 +vext.32 d2,d9,d1,#1 +vext.32 d23,d15,d5,#1 +vmull.s32 q4,d20,d4 +vrev64.i32 d23,d23 +vmlal.s32 q4,d21,d1 +vrev64.i32 d2,d2 +vmlal.s32 q4,d26,d19 +vext.32 d3,d5,d15,#1 +vmlal.s32 q4,d27,d18 +vrev64.i32 d3,d3 +vmlal.s32 q4,d28,d15 +vext.32 d14,d12,d11,#1 +vmull.s32 q5,d16,d23 +vext.32 d15,d13,d12,#1 +vmlal.s32 q5,d17,d4 +vst1.8 d8,[r5,: 64]! +vmlal.s32 q5,d14,d1 +vext.32 d12,d9,d8,#0 +vmlal.s32 q5,d15,d19 +vmov.i64 d13,#0 +vmlal.s32 q5,d29,d18 +vext.32 d25,d19,d7,#1 +vmlal.s32 q6,d20,d5 +vrev64.i32 d25,d25 +vmlal.s32 q6,d21,d4 +vst1.8 d11,[r5,: 64]! +vmlal.s32 q6,d26,d1 +vext.32 d9,d10,d10,#0 +vmlal.s32 q6,d27,d19 +vmov.i64 d8,#0 +vmlal.s32 q6,d28,d18 +vmlal.s32 q4,d16,d24 +vmlal.s32 q4,d17,d5 +vmlal.s32 q4,d14,d4 +vst1.8 d12,[r5,: 64]! +vmlal.s32 q4,d15,d1 +vext.32 d10,d13,d12,#0 +vmlal.s32 q4,d29,d19 +vmov.i64 d11,#0 +vmlal.s32 q5,d20,d6 +vmlal.s32 q5,d21,d5 +vmlal.s32 q5,d26,d4 +vext.32 d13,d8,d8,#0 +vmlal.s32 q5,d27,d1 +vmov.i64 d12,#0 +vmlal.s32 q5,d28,d19 +vst1.8 d9,[r5,: 64]! +vmlal.s32 q6,d16,d25 +vmlal.s32 q6,d17,d6 +vst1.8 d10,[r5,: 64] +vmlal.s32 q6,d14,d5 +vext.32 d8,d11,d10,#0 +vmlal.s32 q6,d15,d4 +vmov.i64 d9,#0 +vmlal.s32 q6,d29,d1 +vmlal.s32 q4,d20,d7 +vmlal.s32 q4,d21,d6 +vmlal.s32 q4,d26,d5 +vext.32 d11,d12,d12,#0 +vmlal.s32 q4,d27,d4 +vmov.i64 d10,#0 +vmlal.s32 q4,d28,d1 +vmlal.s32 q5,d16,d0 +sub r2,r5,#32 +vmlal.s32 q5,d17,d7 +vmlal.s32 q5,d14,d6 +vext.32 d30,d9,d8,#0 +vmlal.s32 q5,d15,d5 +vld1.8 {d31},[r2,: 64]! +vmlal.s32 q5,d29,d4 +vmlal.s32 q15,d20,d0 +vext.32 d0,d6,d18,#1 +vmlal.s32 q15,d21,d25 +vrev64.i32 d0,d0 +vmlal.s32 q15,d26,d24 +vext.32 d1,d7,d19,#1 +vext.32 d7,d10,d10,#0 +vmlal.s32 q15,d27,d23 +vrev64.i32 d1,d1 +vld1.8 {d6},[r2,: 64] +vmlal.s32 q15,d28,d22 +vmlal.s32 q3,d16,d4 +add r2,r2,#24 +vmlal.s32 q3,d17,d2 +vext.32 d4,d31,d30,#0 +vmov d17,d11 +vmlal.s32 q3,d14,d1 +vext.32 d11,d13,d13,#0 +vext.32 d13,d30,d30,#0 +vmlal.s32 q3,d15,d0 +vext.32 d1,d8,d8,#0 +vmlal.s32 q3,d29,d3 +vld1.8 {d5},[r2,: 64] +sub r2,r2,#16 +vext.32 d10,d6,d6,#0 +vmov.i32 q1,#0xffffffff +vshl.i64 q4,q1,#25 +add r5,sp,#512 +vld1.8 {d14-d15},[r5,: 128] +vadd.i64 q9,q2,q7 +vshl.i64 q1,q1,#26 +vshr.s64 q10,q9,#26 +vld1.8 {d0},[r2,: 64]! +vadd.i64 q5,q5,q10 +vand q9,q9,q1 +vld1.8 {d16},[r2,: 64]! +add r2,sp,#528 +vld1.8 {d20-d21},[r2,: 128] +vadd.i64 q11,q5,q10 +vsub.i64 q2,q2,q9 +vshr.s64 q9,q11,#25 +vext.32 d12,d5,d4,#0 +vand q11,q11,q4 +vadd.i64 q0,q0,q9 +vmov d19,d7 +vadd.i64 q3,q0,q7 +vsub.i64 q5,q5,q11 +vshr.s64 q11,q3,#26 +vext.32 d18,d11,d10,#0 +vand q3,q3,q1 +vadd.i64 q8,q8,q11 +vadd.i64 q11,q8,q10 +vsub.i64 q0,q0,q3 +vshr.s64 q3,q11,#25 +vand q11,q11,q4 +vadd.i64 q3,q6,q3 +vadd.i64 q6,q3,q7 +vsub.i64 q8,q8,q11 +vshr.s64 q11,q6,#26 +vand q6,q6,q1 +vadd.i64 q9,q9,q11 +vadd.i64 d25,d19,d21 +vsub.i64 q3,q3,q6 +vshr.s64 d23,d25,#25 +vand q4,q12,q4 +vadd.i64 d21,d23,d23 +vshl.i64 d25,d23,#4 +vadd.i64 d21,d21,d23 +vadd.i64 d25,d25,d21 +vadd.i64 d4,d4,d25 +vzip.i32 q0,q8 +vadd.i64 d12,d4,d14 +add r2,r6,#8 +vst1.8 d0,[r2,: 64] +vsub.i64 d19,d19,d9 +add r2,r2,#16 +vst1.8 d16,[r2,: 64] +vshr.s64 d22,d12,#26 +vand q0,q6,q1 +vadd.i64 d10,d10,d22 +vzip.i32 q3,q9 +vsub.i64 d4,d4,d0 +sub r2,r2,#8 +vst1.8 d6,[r2,: 64] +add r2,r2,#16 +vst1.8 d18,[r2,: 64] +vzip.i32 q2,q5 +sub r2,r2,#32 +vst1.8 d4,[r2,: 64] +cmp r4,#0 +beq ._skippostcopy +add r2,r3,#144 +mov r4,r4 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4},[r2,: 64] +vst1.8 {d0-d1},[r4,: 128]! +vst1.8 {d2-d3},[r4,: 128]! +vst1.8 d4,[r4,: 64] +._skippostcopy: +cmp r1,#1 +bne ._skipfinalcopy +add r2,r3,#288 +add r4,r3,#144 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4},[r2,: 64] +vst1.8 {d0-d1},[r4,: 128]! +vst1.8 {d2-d3},[r4,: 128]! +vst1.8 d4,[r4,: 64] +._skipfinalcopy: +add r1,r1,#1 +cmp r1,#12 +blo ._invertloop +add r1,r3,#144 +ldr r2,[r1],#4 +ldr r3,[r1],#4 +ldr r4,[r1],#4 +ldr r5,[r1],#4 +ldr r6,[r1],#4 +ldr r7,[r1],#4 +ldr r8,[r1],#4 +ldr r9,[r1],#4 +ldr r10,[r1],#4 +ldr r1,[r1] +add r11,r1,r1,LSL #4 +add r11,r11,r1,LSL #1 +add r11,r11,#16777216 +mov r11,r11,ASR #25 +add r11,r11,r2 +mov r11,r11,ASR #26 +add r11,r11,r3 +mov r11,r11,ASR #25 +add r11,r11,r4 +mov r11,r11,ASR #26 +add r11,r11,r5 +mov r11,r11,ASR #25 +add r11,r11,r6 +mov r11,r11,ASR #26 +add r11,r11,r7 +mov r11,r11,ASR #25 +add r11,r11,r8 +mov r11,r11,ASR #26 +add r11,r11,r9 +mov r11,r11,ASR #25 +add r11,r11,r10 +mov r11,r11,ASR #26 +add r11,r11,r1 +mov r11,r11,ASR #25 +add r2,r2,r11 +add r2,r2,r11,LSL #1 +add r2,r2,r11,LSL #4 +mov r11,r2,ASR #26 +add r3,r3,r11 +sub r2,r2,r11,LSL #26 +mov r11,r3,ASR #25 +add r4,r4,r11 +sub r3,r3,r11,LSL #25 +mov r11,r4,ASR #26 +add r5,r5,r11 +sub r4,r4,r11,LSL #26 +mov r11,r5,ASR #25 +add r6,r6,r11 +sub r5,r5,r11,LSL #25 +mov r11,r6,ASR #26 +add r7,r7,r11 +sub r6,r6,r11,LSL #26 +mov r11,r7,ASR #25 +add r8,r8,r11 +sub r7,r7,r11,LSL #25 +mov r11,r8,ASR #26 +add r9,r9,r11 +sub r8,r8,r11,LSL #26 +mov r11,r9,ASR #25 +add r10,r10,r11 +sub r9,r9,r11,LSL #25 +mov r11,r10,ASR #26 +add r1,r1,r11 +sub r10,r10,r11,LSL #26 +mov r11,r1,ASR #25 +sub r1,r1,r11,LSL #25 +add r2,r2,r3,LSL #26 +mov r3,r3,LSR #6 +add r3,r3,r4,LSL #19 +mov r4,r4,LSR #13 +add r4,r4,r5,LSL #13 +mov r5,r5,LSR #19 +add r5,r5,r6,LSL #6 +add r6,r7,r8,LSL #25 +mov r7,r8,LSR #7 +add r7,r7,r9,LSL #19 +mov r8,r9,LSR #13 +add r8,r8,r10,LSL #12 +mov r9,r10,LSR #20 +add r1,r9,r1,LSL #6 +str r2,[r0],#4 +str r3,[r0],#4 +str r4,[r0],#4 +str r5,[r0],#4 +str r6,[r0],#4 +str r7,[r0],#4 +str r8,[r0],#4 +str r1,[r0] +ldrd r4,[sp,#0] +ldrd r6,[sp,#8] +ldrd r8,[sp,#16] +ldrd r10,[sp,#24] +ldr r12,[sp,#480] +ldr r14,[sp,#484] +ldr r0,=0 +mov sp,r12 +vpop {q4,q5,q6,q7} +bx lr diff --git a/src/crypto/curve25519/asm/x25519-asm-x86_64.S b/src/crypto/curve25519/asm/x25519-asm-x86_64.S new file mode 100644 index 0000000..7e86a23 --- /dev/null +++ b/src/crypto/curve25519/asm/x25519-asm-x86_64.S @@ -0,0 +1,1931 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This file is adapted from crypto_scalarmult/curve25519/amd64-51/ in + * SUPERCOP 20141124 (http://bench.cr.yp.to/supercop.html). That code is public + * domain licensed but the standard ISC license is included above to keep + * licensing simple. */ + +.data +.p2align 4 + +#if defined(__APPLE__) +/* OS X's C ABI prefixes functions with underscore. */ +#define C_ABI(x) _ ## x +#define HIDDEN .private_extern +#else +#define C_ABI(x) x +#define HIDDEN .hidden +#endif + +x25519_x86_64_REDMASK51: .quad 0x0007FFFFFFFFFFFF +x25519_x86_64_121666_213: .quad 996687872 +x25519_x86_64_2P0: .quad 0xFFFFFFFFFFFDA +x25519_x86_64_2P1234: .quad 0xFFFFFFFFFFFFE +x25519_x86_64_4P0: .quad 0x1FFFFFFFFFFFB4 +x25519_x86_64_4P1234: .quad 0x1FFFFFFFFFFFFC +x25519_x86_64_MU0: .quad 0xED9CE5A30A2C131B +x25519_x86_64_MU1: .quad 0x2106215D086329A7 +x25519_x86_64_MU2: .quad 0xFFFFFFFFFFFFFFEB +x25519_x86_64_MU3: .quad 0xFFFFFFFFFFFFFFFF +x25519_x86_64_MU4: .quad 0x000000000000000F +x25519_x86_64_ORDER0: .quad 0x5812631A5CF5D3ED +x25519_x86_64_ORDER1: .quad 0x14DEF9DEA2F79CD6 +x25519_x86_64_ORDER2: .quad 0x0000000000000000 +x25519_x86_64_ORDER3: .quad 0x1000000000000000 +x25519_x86_64_EC2D0: .quad 1859910466990425 +x25519_x86_64_EC2D1: .quad 932731440258426 +x25519_x86_64_EC2D2: .quad 1072319116312658 +x25519_x86_64_EC2D3: .quad 1815898335770999 +x25519_x86_64_EC2D4: .quad 633789495995903 +x25519_x86_64__38: .quad 38 + +.text +.p2align 5 + +.globl C_ABI(x25519_x86_64_freeze) +HIDDEN C_ABI(x25519_x86_64_freeze) +C_ABI(x25519_x86_64_freeze): +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq %r13,16(%rsp) +movq %r14,24(%rsp) +movq %r15,32(%rsp) +movq %rbx,40(%rsp) +movq %rbp,48(%rsp) +movq 0(%rdi),%rsi +movq 8(%rdi),%rdx +movq 16(%rdi),%rcx +movq 24(%rdi),%r8 +movq 32(%rdi),%r9 +movq x25519_x86_64_REDMASK51(%rip),%rax +mov %rax,%r10 +sub $18,%r10 +mov $3,%r11 +._reduceloop: +mov %rsi,%r12 +shr $51,%r12 +and %rax,%rsi +add %r12,%rdx +mov %rdx,%r12 +shr $51,%r12 +and %rax,%rdx +add %r12,%rcx +mov %rcx,%r12 +shr $51,%r12 +and %rax,%rcx +add %r12,%r8 +mov %r8,%r12 +shr $51,%r12 +and %rax,%r8 +add %r12,%r9 +mov %r9,%r12 +shr $51,%r12 +and %rax,%r9 +imulq $19,%r12,%r12 +add %r12,%rsi +sub $1,%r11 +ja ._reduceloop +mov $1,%r12 +cmp %r10,%rsi +cmovl %r11,%r12 +cmp %rax,%rdx +cmovne %r11,%r12 +cmp %rax,%rcx +cmovne %r11,%r12 +cmp %rax,%r8 +cmovne %r11,%r12 +cmp %rax,%r9 +cmovne %r11,%r12 +neg %r12 +and %r12,%rax +and %r12,%r10 +sub %r10,%rsi +sub %rax,%rdx +sub %rax,%rcx +sub %rax,%r8 +sub %rax,%r9 +movq %rsi,0(%rdi) +movq %rdx,8(%rdi) +movq %rcx,16(%rdi) +movq %r8,24(%rdi) +movq %r9,32(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +movq 16(%rsp),%r13 +movq 24(%rsp),%r14 +movq 32(%rsp),%r15 +movq 40(%rsp),%rbx +movq 48(%rsp),%rbp +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret + +.p2align 5 +.globl C_ABI(x25519_x86_64_mul) +HIDDEN C_ABI(x25519_x86_64_mul) +C_ABI(x25519_x86_64_mul): +mov %rsp,%r11 +and $31,%r11 +add $96,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq %r13,16(%rsp) +movq %r14,24(%rsp) +movq %r15,32(%rsp) +movq %rbx,40(%rsp) +movq %rbp,48(%rsp) +movq %rdi,56(%rsp) +mov %rdx,%rcx +movq 24(%rsi),%rdx +imulq $19,%rdx,%rax +movq %rax,64(%rsp) +mulq 16(%rcx) +mov %rax,%r8 +mov %rdx,%r9 +movq 32(%rsi),%rdx +imulq $19,%rdx,%rax +movq %rax,72(%rsp) +mulq 8(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 0(%rsi),%rax +mulq 0(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 0(%rsi),%rax +mulq 8(%rcx) +mov %rax,%r10 +mov %rdx,%r11 +movq 0(%rsi),%rax +mulq 16(%rcx) +mov %rax,%r12 +mov %rdx,%r13 +movq 0(%rsi),%rax +mulq 24(%rcx) +mov %rax,%r14 +mov %rdx,%r15 +movq 0(%rsi),%rax +mulq 32(%rcx) +mov %rax,%rbx +mov %rdx,%rbp +movq 8(%rsi),%rax +mulq 0(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 8(%rsi),%rax +mulq 8(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 8(%rsi),%rax +mulq 16(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq 8(%rsi),%rax +mulq 24(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 8(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 32(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 16(%rsi),%rax +mulq 0(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 16(%rsi),%rax +mulq 8(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq 16(%rsi),%rax +mulq 16(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 16(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 24(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 16(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 32(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 24(%rsi),%rax +mulq 0(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq 24(%rsi),%rax +mulq 8(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 64(%rsp),%rax +mulq 24(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 64(%rsp),%rax +mulq 32(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 32(%rsi),%rax +mulq 0(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 72(%rsp),%rax +mulq 16(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 72(%rsp),%rax +mulq 24(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 72(%rsp),%rax +mulq 32(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq x25519_x86_64_REDMASK51(%rip),%rsi +shld $13,%r8,%r9 +and %rsi,%r8 +shld $13,%r10,%r11 +and %rsi,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rsi,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rsi,%r14 +add %r13,%r14 +shld $13,%rbx,%rbp +and %rsi,%rbx +add %r15,%rbx +imulq $19,%rbp,%rdx +add %rdx,%r8 +mov %r8,%rdx +shr $51,%rdx +add %r10,%rdx +mov %rdx,%rcx +shr $51,%rdx +and %rsi,%r8 +add %r12,%rdx +mov %rdx,%r9 +shr $51,%rdx +and %rsi,%rcx +add %r14,%rdx +mov %rdx,%rax +shr $51,%rdx +and %rsi,%r9 +add %rbx,%rdx +mov %rdx,%r10 +shr $51,%rdx +and %rsi,%rax +imulq $19,%rdx,%rdx +add %rdx,%r8 +and %rsi,%r10 +movq %r8,0(%rdi) +movq %rcx,8(%rdi) +movq %r9,16(%rdi) +movq %rax,24(%rdi) +movq %r10,32(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +movq 16(%rsp),%r13 +movq 24(%rsp),%r14 +movq 32(%rsp),%r15 +movq 40(%rsp),%rbx +movq 48(%rsp),%rbp +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret + +.p2align 5 +.globl C_ABI(x25519_x86_64_square) +HIDDEN C_ABI(x25519_x86_64_square) +C_ABI(x25519_x86_64_square): +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq %r13,16(%rsp) +movq %r14,24(%rsp) +movq %r15,32(%rsp) +movq %rbx,40(%rsp) +movq %rbp,48(%rsp) +movq 0(%rsi),%rax +mulq 0(%rsi) +mov %rax,%rcx +mov %rdx,%r8 +movq 0(%rsi),%rax +shl $1,%rax +mulq 8(%rsi) +mov %rax,%r9 +mov %rdx,%r10 +movq 0(%rsi),%rax +shl $1,%rax +mulq 16(%rsi) +mov %rax,%r11 +mov %rdx,%r12 +movq 0(%rsi),%rax +shl $1,%rax +mulq 24(%rsi) +mov %rax,%r13 +mov %rdx,%r14 +movq 0(%rsi),%rax +shl $1,%rax +mulq 32(%rsi) +mov %rax,%r15 +mov %rdx,%rbx +movq 8(%rsi),%rax +mulq 8(%rsi) +add %rax,%r11 +adc %rdx,%r12 +movq 8(%rsi),%rax +shl $1,%rax +mulq 16(%rsi) +add %rax,%r13 +adc %rdx,%r14 +movq 8(%rsi),%rax +shl $1,%rax +mulq 24(%rsi) +add %rax,%r15 +adc %rdx,%rbx +movq 8(%rsi),%rdx +imulq $38,%rdx,%rax +mulq 32(%rsi) +add %rax,%rcx +adc %rdx,%r8 +movq 16(%rsi),%rax +mulq 16(%rsi) +add %rax,%r15 +adc %rdx,%rbx +movq 16(%rsi),%rdx +imulq $38,%rdx,%rax +mulq 24(%rsi) +add %rax,%rcx +adc %rdx,%r8 +movq 16(%rsi),%rdx +imulq $38,%rdx,%rax +mulq 32(%rsi) +add %rax,%r9 +adc %rdx,%r10 +movq 24(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 24(%rsi) +add %rax,%r9 +adc %rdx,%r10 +movq 24(%rsi),%rdx +imulq $38,%rdx,%rax +mulq 32(%rsi) +add %rax,%r11 +adc %rdx,%r12 +movq 32(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 32(%rsi) +add %rax,%r13 +adc %rdx,%r14 +movq x25519_x86_64_REDMASK51(%rip),%rsi +shld $13,%rcx,%r8 +and %rsi,%rcx +shld $13,%r9,%r10 +and %rsi,%r9 +add %r8,%r9 +shld $13,%r11,%r12 +and %rsi,%r11 +add %r10,%r11 +shld $13,%r13,%r14 +and %rsi,%r13 +add %r12,%r13 +shld $13,%r15,%rbx +and %rsi,%r15 +add %r14,%r15 +imulq $19,%rbx,%rdx +add %rdx,%rcx +mov %rcx,%rdx +shr $51,%rdx +add %r9,%rdx +and %rsi,%rcx +mov %rdx,%r8 +shr $51,%rdx +add %r11,%rdx +and %rsi,%r8 +mov %rdx,%r9 +shr $51,%rdx +add %r13,%rdx +and %rsi,%r9 +mov %rdx,%rax +shr $51,%rdx +add %r15,%rdx +and %rsi,%rax +mov %rdx,%r10 +shr $51,%rdx +imulq $19,%rdx,%rdx +add %rdx,%rcx +and %rsi,%r10 +movq %rcx,0(%rdi) +movq %r8,8(%rdi) +movq %r9,16(%rdi) +movq %rax,24(%rdi) +movq %r10,32(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +movq 16(%rsp),%r13 +movq 24(%rsp),%r14 +movq 32(%rsp),%r15 +movq 40(%rsp),%rbx +movq 48(%rsp),%rbp +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret + +.p2align 5 +.globl C_ABI(x25519_x86_64_ladderstep) +HIDDEN C_ABI(x25519_x86_64_ladderstep) +C_ABI(x25519_x86_64_ladderstep): +mov %rsp,%r11 +and $31,%r11 +add $352,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq %r13,16(%rsp) +movq %r14,24(%rsp) +movq %r15,32(%rsp) +movq %rbx,40(%rsp) +movq %rbp,48(%rsp) +movq 40(%rdi),%rsi +movq 48(%rdi),%rdx +movq 56(%rdi),%rcx +movq 64(%rdi),%r8 +movq 72(%rdi),%r9 +mov %rsi,%rax +mov %rdx,%r10 +mov %rcx,%r11 +mov %r8,%r12 +mov %r9,%r13 +add x25519_x86_64_2P0(%rip),%rax +add x25519_x86_64_2P1234(%rip),%r10 +add x25519_x86_64_2P1234(%rip),%r11 +add x25519_x86_64_2P1234(%rip),%r12 +add x25519_x86_64_2P1234(%rip),%r13 +addq 80(%rdi),%rsi +addq 88(%rdi),%rdx +addq 96(%rdi),%rcx +addq 104(%rdi),%r8 +addq 112(%rdi),%r9 +subq 80(%rdi),%rax +subq 88(%rdi),%r10 +subq 96(%rdi),%r11 +subq 104(%rdi),%r12 +subq 112(%rdi),%r13 +movq %rsi,56(%rsp) +movq %rdx,64(%rsp) +movq %rcx,72(%rsp) +movq %r8,80(%rsp) +movq %r9,88(%rsp) +movq %rax,96(%rsp) +movq %r10,104(%rsp) +movq %r11,112(%rsp) +movq %r12,120(%rsp) +movq %r13,128(%rsp) +movq 96(%rsp),%rax +mulq 96(%rsp) +mov %rax,%rsi +mov %rdx,%rcx +movq 96(%rsp),%rax +shl $1,%rax +mulq 104(%rsp) +mov %rax,%r8 +mov %rdx,%r9 +movq 96(%rsp),%rax +shl $1,%rax +mulq 112(%rsp) +mov %rax,%r10 +mov %rdx,%r11 +movq 96(%rsp),%rax +shl $1,%rax +mulq 120(%rsp) +mov %rax,%r12 +mov %rdx,%r13 +movq 96(%rsp),%rax +shl $1,%rax +mulq 128(%rsp) +mov %rax,%r14 +mov %rdx,%r15 +movq 104(%rsp),%rax +mulq 104(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 104(%rsp),%rax +shl $1,%rax +mulq 112(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 104(%rsp),%rax +shl $1,%rax +mulq 120(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 104(%rsp),%rdx +imulq $38,%rdx,%rax +mulq 128(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 112(%rsp),%rax +mulq 112(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 112(%rsp),%rdx +imulq $38,%rdx,%rax +mulq 120(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 112(%rsp),%rdx +imulq $38,%rdx,%rax +mulq 128(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 120(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 120(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 120(%rsp),%rdx +imulq $38,%rdx,%rax +mulq 128(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 128(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 128(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq x25519_x86_64_REDMASK51(%rip),%rdx +shld $13,%rsi,%rcx +and %rdx,%rsi +shld $13,%r8,%r9 +and %rdx,%r8 +add %rcx,%r8 +shld $13,%r10,%r11 +and %rdx,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rdx,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rdx,%r14 +add %r13,%r14 +imulq $19,%r15,%rcx +add %rcx,%rsi +mov %rsi,%rcx +shr $51,%rcx +add %r8,%rcx +and %rdx,%rsi +mov %rcx,%r8 +shr $51,%rcx +add %r10,%rcx +and %rdx,%r8 +mov %rcx,%r9 +shr $51,%rcx +add %r12,%rcx +and %rdx,%r9 +mov %rcx,%rax +shr $51,%rcx +add %r14,%rcx +and %rdx,%rax +mov %rcx,%r10 +shr $51,%rcx +imulq $19,%rcx,%rcx +add %rcx,%rsi +and %rdx,%r10 +movq %rsi,136(%rsp) +movq %r8,144(%rsp) +movq %r9,152(%rsp) +movq %rax,160(%rsp) +movq %r10,168(%rsp) +movq 56(%rsp),%rax +mulq 56(%rsp) +mov %rax,%rsi +mov %rdx,%rcx +movq 56(%rsp),%rax +shl $1,%rax +mulq 64(%rsp) +mov %rax,%r8 +mov %rdx,%r9 +movq 56(%rsp),%rax +shl $1,%rax +mulq 72(%rsp) +mov %rax,%r10 +mov %rdx,%r11 +movq 56(%rsp),%rax +shl $1,%rax +mulq 80(%rsp) +mov %rax,%r12 +mov %rdx,%r13 +movq 56(%rsp),%rax +shl $1,%rax +mulq 88(%rsp) +mov %rax,%r14 +mov %rdx,%r15 +movq 64(%rsp),%rax +mulq 64(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 64(%rsp),%rax +shl $1,%rax +mulq 72(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 64(%rsp),%rax +shl $1,%rax +mulq 80(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 64(%rsp),%rdx +imulq $38,%rdx,%rax +mulq 88(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 72(%rsp),%rax +mulq 72(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 72(%rsp),%rdx +imulq $38,%rdx,%rax +mulq 80(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 72(%rsp),%rdx +imulq $38,%rdx,%rax +mulq 88(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 80(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 80(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 80(%rsp),%rdx +imulq $38,%rdx,%rax +mulq 88(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 88(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 88(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq x25519_x86_64_REDMASK51(%rip),%rdx +shld $13,%rsi,%rcx +and %rdx,%rsi +shld $13,%r8,%r9 +and %rdx,%r8 +add %rcx,%r8 +shld $13,%r10,%r11 +and %rdx,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rdx,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rdx,%r14 +add %r13,%r14 +imulq $19,%r15,%rcx +add %rcx,%rsi +mov %rsi,%rcx +shr $51,%rcx +add %r8,%rcx +and %rdx,%rsi +mov %rcx,%r8 +shr $51,%rcx +add %r10,%rcx +and %rdx,%r8 +mov %rcx,%r9 +shr $51,%rcx +add %r12,%rcx +and %rdx,%r9 +mov %rcx,%rax +shr $51,%rcx +add %r14,%rcx +and %rdx,%rax +mov %rcx,%r10 +shr $51,%rcx +imulq $19,%rcx,%rcx +add %rcx,%rsi +and %rdx,%r10 +movq %rsi,176(%rsp) +movq %r8,184(%rsp) +movq %r9,192(%rsp) +movq %rax,200(%rsp) +movq %r10,208(%rsp) +mov %rsi,%rsi +mov %r8,%rdx +mov %r9,%rcx +mov %rax,%r8 +mov %r10,%r9 +add x25519_x86_64_2P0(%rip),%rsi +add x25519_x86_64_2P1234(%rip),%rdx +add x25519_x86_64_2P1234(%rip),%rcx +add x25519_x86_64_2P1234(%rip),%r8 +add x25519_x86_64_2P1234(%rip),%r9 +subq 136(%rsp),%rsi +subq 144(%rsp),%rdx +subq 152(%rsp),%rcx +subq 160(%rsp),%r8 +subq 168(%rsp),%r9 +movq %rsi,216(%rsp) +movq %rdx,224(%rsp) +movq %rcx,232(%rsp) +movq %r8,240(%rsp) +movq %r9,248(%rsp) +movq 120(%rdi),%rsi +movq 128(%rdi),%rdx +movq 136(%rdi),%rcx +movq 144(%rdi),%r8 +movq 152(%rdi),%r9 +mov %rsi,%rax +mov %rdx,%r10 +mov %rcx,%r11 +mov %r8,%r12 +mov %r9,%r13 +add x25519_x86_64_2P0(%rip),%rax +add x25519_x86_64_2P1234(%rip),%r10 +add x25519_x86_64_2P1234(%rip),%r11 +add x25519_x86_64_2P1234(%rip),%r12 +add x25519_x86_64_2P1234(%rip),%r13 +addq 160(%rdi),%rsi +addq 168(%rdi),%rdx +addq 176(%rdi),%rcx +addq 184(%rdi),%r8 +addq 192(%rdi),%r9 +subq 160(%rdi),%rax +subq 168(%rdi),%r10 +subq 176(%rdi),%r11 +subq 184(%rdi),%r12 +subq 192(%rdi),%r13 +movq %rsi,256(%rsp) +movq %rdx,264(%rsp) +movq %rcx,272(%rsp) +movq %r8,280(%rsp) +movq %r9,288(%rsp) +movq %rax,296(%rsp) +movq %r10,304(%rsp) +movq %r11,312(%rsp) +movq %r12,320(%rsp) +movq %r13,328(%rsp) +movq 280(%rsp),%rsi +imulq $19,%rsi,%rax +movq %rax,336(%rsp) +mulq 112(%rsp) +mov %rax,%rsi +mov %rdx,%rcx +movq 288(%rsp),%rdx +imulq $19,%rdx,%rax +movq %rax,344(%rsp) +mulq 104(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 256(%rsp),%rax +mulq 96(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 256(%rsp),%rax +mulq 104(%rsp) +mov %rax,%r8 +mov %rdx,%r9 +movq 256(%rsp),%rax +mulq 112(%rsp) +mov %rax,%r10 +mov %rdx,%r11 +movq 256(%rsp),%rax +mulq 120(%rsp) +mov %rax,%r12 +mov %rdx,%r13 +movq 256(%rsp),%rax +mulq 128(%rsp) +mov %rax,%r14 +mov %rdx,%r15 +movq 264(%rsp),%rax +mulq 96(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 264(%rsp),%rax +mulq 104(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 264(%rsp),%rax +mulq 112(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 264(%rsp),%rax +mulq 120(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 264(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 128(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 272(%rsp),%rax +mulq 96(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 272(%rsp),%rax +mulq 104(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 272(%rsp),%rax +mulq 112(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 272(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 120(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 272(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 128(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 280(%rsp),%rax +mulq 96(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 280(%rsp),%rax +mulq 104(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 336(%rsp),%rax +mulq 120(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 336(%rsp),%rax +mulq 128(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 288(%rsp),%rax +mulq 96(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 344(%rsp),%rax +mulq 112(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 344(%rsp),%rax +mulq 120(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 344(%rsp),%rax +mulq 128(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq x25519_x86_64_REDMASK51(%rip),%rdx +shld $13,%rsi,%rcx +and %rdx,%rsi +shld $13,%r8,%r9 +and %rdx,%r8 +add %rcx,%r8 +shld $13,%r10,%r11 +and %rdx,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rdx,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rdx,%r14 +add %r13,%r14 +imulq $19,%r15,%rcx +add %rcx,%rsi +mov %rsi,%rcx +shr $51,%rcx +add %r8,%rcx +mov %rcx,%r8 +shr $51,%rcx +and %rdx,%rsi +add %r10,%rcx +mov %rcx,%r9 +shr $51,%rcx +and %rdx,%r8 +add %r12,%rcx +mov %rcx,%rax +shr $51,%rcx +and %rdx,%r9 +add %r14,%rcx +mov %rcx,%r10 +shr $51,%rcx +and %rdx,%rax +imulq $19,%rcx,%rcx +add %rcx,%rsi +and %rdx,%r10 +movq %rsi,96(%rsp) +movq %r8,104(%rsp) +movq %r9,112(%rsp) +movq %rax,120(%rsp) +movq %r10,128(%rsp) +movq 320(%rsp),%rsi +imulq $19,%rsi,%rax +movq %rax,256(%rsp) +mulq 72(%rsp) +mov %rax,%rsi +mov %rdx,%rcx +movq 328(%rsp),%rdx +imulq $19,%rdx,%rax +movq %rax,264(%rsp) +mulq 64(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 296(%rsp),%rax +mulq 56(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 296(%rsp),%rax +mulq 64(%rsp) +mov %rax,%r8 +mov %rdx,%r9 +movq 296(%rsp),%rax +mulq 72(%rsp) +mov %rax,%r10 +mov %rdx,%r11 +movq 296(%rsp),%rax +mulq 80(%rsp) +mov %rax,%r12 +mov %rdx,%r13 +movq 296(%rsp),%rax +mulq 88(%rsp) +mov %rax,%r14 +mov %rdx,%r15 +movq 304(%rsp),%rax +mulq 56(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 304(%rsp),%rax +mulq 64(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 304(%rsp),%rax +mulq 72(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 304(%rsp),%rax +mulq 80(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 304(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 88(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 312(%rsp),%rax +mulq 56(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 312(%rsp),%rax +mulq 64(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 312(%rsp),%rax +mulq 72(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 312(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 80(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 312(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 88(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 320(%rsp),%rax +mulq 56(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 320(%rsp),%rax +mulq 64(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 256(%rsp),%rax +mulq 80(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 256(%rsp),%rax +mulq 88(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 328(%rsp),%rax +mulq 56(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 264(%rsp),%rax +mulq 72(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 264(%rsp),%rax +mulq 80(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 264(%rsp),%rax +mulq 88(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq x25519_x86_64_REDMASK51(%rip),%rdx +shld $13,%rsi,%rcx +and %rdx,%rsi +shld $13,%r8,%r9 +and %rdx,%r8 +add %rcx,%r8 +shld $13,%r10,%r11 +and %rdx,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rdx,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rdx,%r14 +add %r13,%r14 +imulq $19,%r15,%rcx +add %rcx,%rsi +mov %rsi,%rcx +shr $51,%rcx +add %r8,%rcx +mov %rcx,%r8 +shr $51,%rcx +and %rdx,%rsi +add %r10,%rcx +mov %rcx,%r9 +shr $51,%rcx +and %rdx,%r8 +add %r12,%rcx +mov %rcx,%rax +shr $51,%rcx +and %rdx,%r9 +add %r14,%rcx +mov %rcx,%r10 +shr $51,%rcx +and %rdx,%rax +imulq $19,%rcx,%rcx +add %rcx,%rsi +and %rdx,%r10 +mov %rsi,%rdx +mov %r8,%rcx +mov %r9,%r11 +mov %rax,%r12 +mov %r10,%r13 +add x25519_x86_64_2P0(%rip),%rdx +add x25519_x86_64_2P1234(%rip),%rcx +add x25519_x86_64_2P1234(%rip),%r11 +add x25519_x86_64_2P1234(%rip),%r12 +add x25519_x86_64_2P1234(%rip),%r13 +addq 96(%rsp),%rsi +addq 104(%rsp),%r8 +addq 112(%rsp),%r9 +addq 120(%rsp),%rax +addq 128(%rsp),%r10 +subq 96(%rsp),%rdx +subq 104(%rsp),%rcx +subq 112(%rsp),%r11 +subq 120(%rsp),%r12 +subq 128(%rsp),%r13 +movq %rsi,120(%rdi) +movq %r8,128(%rdi) +movq %r9,136(%rdi) +movq %rax,144(%rdi) +movq %r10,152(%rdi) +movq %rdx,160(%rdi) +movq %rcx,168(%rdi) +movq %r11,176(%rdi) +movq %r12,184(%rdi) +movq %r13,192(%rdi) +movq 120(%rdi),%rax +mulq 120(%rdi) +mov %rax,%rsi +mov %rdx,%rcx +movq 120(%rdi),%rax +shl $1,%rax +mulq 128(%rdi) +mov %rax,%r8 +mov %rdx,%r9 +movq 120(%rdi),%rax +shl $1,%rax +mulq 136(%rdi) +mov %rax,%r10 +mov %rdx,%r11 +movq 120(%rdi),%rax +shl $1,%rax +mulq 144(%rdi) +mov %rax,%r12 +mov %rdx,%r13 +movq 120(%rdi),%rax +shl $1,%rax +mulq 152(%rdi) +mov %rax,%r14 +mov %rdx,%r15 +movq 128(%rdi),%rax +mulq 128(%rdi) +add %rax,%r10 +adc %rdx,%r11 +movq 128(%rdi),%rax +shl $1,%rax +mulq 136(%rdi) +add %rax,%r12 +adc %rdx,%r13 +movq 128(%rdi),%rax +shl $1,%rax +mulq 144(%rdi) +add %rax,%r14 +adc %rdx,%r15 +movq 128(%rdi),%rdx +imulq $38,%rdx,%rax +mulq 152(%rdi) +add %rax,%rsi +adc %rdx,%rcx +movq 136(%rdi),%rax +mulq 136(%rdi) +add %rax,%r14 +adc %rdx,%r15 +movq 136(%rdi),%rdx +imulq $38,%rdx,%rax +mulq 144(%rdi) +add %rax,%rsi +adc %rdx,%rcx +movq 136(%rdi),%rdx +imulq $38,%rdx,%rax +mulq 152(%rdi) +add %rax,%r8 +adc %rdx,%r9 +movq 144(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 144(%rdi) +add %rax,%r8 +adc %rdx,%r9 +movq 144(%rdi),%rdx +imulq $38,%rdx,%rax +mulq 152(%rdi) +add %rax,%r10 +adc %rdx,%r11 +movq 152(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 152(%rdi) +add %rax,%r12 +adc %rdx,%r13 +movq x25519_x86_64_REDMASK51(%rip),%rdx +shld $13,%rsi,%rcx +and %rdx,%rsi +shld $13,%r8,%r9 +and %rdx,%r8 +add %rcx,%r8 +shld $13,%r10,%r11 +and %rdx,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rdx,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rdx,%r14 +add %r13,%r14 +imulq $19,%r15,%rcx +add %rcx,%rsi +mov %rsi,%rcx +shr $51,%rcx +add %r8,%rcx +and %rdx,%rsi +mov %rcx,%r8 +shr $51,%rcx +add %r10,%rcx +and %rdx,%r8 +mov %rcx,%r9 +shr $51,%rcx +add %r12,%rcx +and %rdx,%r9 +mov %rcx,%rax +shr $51,%rcx +add %r14,%rcx +and %rdx,%rax +mov %rcx,%r10 +shr $51,%rcx +imulq $19,%rcx,%rcx +add %rcx,%rsi +and %rdx,%r10 +movq %rsi,120(%rdi) +movq %r8,128(%rdi) +movq %r9,136(%rdi) +movq %rax,144(%rdi) +movq %r10,152(%rdi) +movq 160(%rdi),%rax +mulq 160(%rdi) +mov %rax,%rsi +mov %rdx,%rcx +movq 160(%rdi),%rax +shl $1,%rax +mulq 168(%rdi) +mov %rax,%r8 +mov %rdx,%r9 +movq 160(%rdi),%rax +shl $1,%rax +mulq 176(%rdi) +mov %rax,%r10 +mov %rdx,%r11 +movq 160(%rdi),%rax +shl $1,%rax +mulq 184(%rdi) +mov %rax,%r12 +mov %rdx,%r13 +movq 160(%rdi),%rax +shl $1,%rax +mulq 192(%rdi) +mov %rax,%r14 +mov %rdx,%r15 +movq 168(%rdi),%rax +mulq 168(%rdi) +add %rax,%r10 +adc %rdx,%r11 +movq 168(%rdi),%rax +shl $1,%rax +mulq 176(%rdi) +add %rax,%r12 +adc %rdx,%r13 +movq 168(%rdi),%rax +shl $1,%rax +mulq 184(%rdi) +add %rax,%r14 +adc %rdx,%r15 +movq 168(%rdi),%rdx +imulq $38,%rdx,%rax +mulq 192(%rdi) +add %rax,%rsi +adc %rdx,%rcx +movq 176(%rdi),%rax +mulq 176(%rdi) +add %rax,%r14 +adc %rdx,%r15 +movq 176(%rdi),%rdx +imulq $38,%rdx,%rax +mulq 184(%rdi) +add %rax,%rsi +adc %rdx,%rcx +movq 176(%rdi),%rdx +imulq $38,%rdx,%rax +mulq 192(%rdi) +add %rax,%r8 +adc %rdx,%r9 +movq 184(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 184(%rdi) +add %rax,%r8 +adc %rdx,%r9 +movq 184(%rdi),%rdx +imulq $38,%rdx,%rax +mulq 192(%rdi) +add %rax,%r10 +adc %rdx,%r11 +movq 192(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 192(%rdi) +add %rax,%r12 +adc %rdx,%r13 +movq x25519_x86_64_REDMASK51(%rip),%rdx +shld $13,%rsi,%rcx +and %rdx,%rsi +shld $13,%r8,%r9 +and %rdx,%r8 +add %rcx,%r8 +shld $13,%r10,%r11 +and %rdx,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rdx,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rdx,%r14 +add %r13,%r14 +imulq $19,%r15,%rcx +add %rcx,%rsi +mov %rsi,%rcx +shr $51,%rcx +add %r8,%rcx +and %rdx,%rsi +mov %rcx,%r8 +shr $51,%rcx +add %r10,%rcx +and %rdx,%r8 +mov %rcx,%r9 +shr $51,%rcx +add %r12,%rcx +and %rdx,%r9 +mov %rcx,%rax +shr $51,%rcx +add %r14,%rcx +and %rdx,%rax +mov %rcx,%r10 +shr $51,%rcx +imulq $19,%rcx,%rcx +add %rcx,%rsi +and %rdx,%r10 +movq %rsi,160(%rdi) +movq %r8,168(%rdi) +movq %r9,176(%rdi) +movq %rax,184(%rdi) +movq %r10,192(%rdi) +movq 184(%rdi),%rsi +imulq $19,%rsi,%rax +movq %rax,56(%rsp) +mulq 16(%rdi) +mov %rax,%rsi +mov %rdx,%rcx +movq 192(%rdi),%rdx +imulq $19,%rdx,%rax +movq %rax,64(%rsp) +mulq 8(%rdi) +add %rax,%rsi +adc %rdx,%rcx +movq 160(%rdi),%rax +mulq 0(%rdi) +add %rax,%rsi +adc %rdx,%rcx +movq 160(%rdi),%rax +mulq 8(%rdi) +mov %rax,%r8 +mov %rdx,%r9 +movq 160(%rdi),%rax +mulq 16(%rdi) +mov %rax,%r10 +mov %rdx,%r11 +movq 160(%rdi),%rax +mulq 24(%rdi) +mov %rax,%r12 +mov %rdx,%r13 +movq 160(%rdi),%rax +mulq 32(%rdi) +mov %rax,%r14 +mov %rdx,%r15 +movq 168(%rdi),%rax +mulq 0(%rdi) +add %rax,%r8 +adc %rdx,%r9 +movq 168(%rdi),%rax +mulq 8(%rdi) +add %rax,%r10 +adc %rdx,%r11 +movq 168(%rdi),%rax +mulq 16(%rdi) +add %rax,%r12 +adc %rdx,%r13 +movq 168(%rdi),%rax +mulq 24(%rdi) +add %rax,%r14 +adc %rdx,%r15 +movq 168(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 32(%rdi) +add %rax,%rsi +adc %rdx,%rcx +movq 176(%rdi),%rax +mulq 0(%rdi) +add %rax,%r10 +adc %rdx,%r11 +movq 176(%rdi),%rax +mulq 8(%rdi) +add %rax,%r12 +adc %rdx,%r13 +movq 176(%rdi),%rax +mulq 16(%rdi) +add %rax,%r14 +adc %rdx,%r15 +movq 176(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 24(%rdi) +add %rax,%rsi +adc %rdx,%rcx +movq 176(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 32(%rdi) +add %rax,%r8 +adc %rdx,%r9 +movq 184(%rdi),%rax +mulq 0(%rdi) +add %rax,%r12 +adc %rdx,%r13 +movq 184(%rdi),%rax +mulq 8(%rdi) +add %rax,%r14 +adc %rdx,%r15 +movq 56(%rsp),%rax +mulq 24(%rdi) +add %rax,%r8 +adc %rdx,%r9 +movq 56(%rsp),%rax +mulq 32(%rdi) +add %rax,%r10 +adc %rdx,%r11 +movq 192(%rdi),%rax +mulq 0(%rdi) +add %rax,%r14 +adc %rdx,%r15 +movq 64(%rsp),%rax +mulq 16(%rdi) +add %rax,%r8 +adc %rdx,%r9 +movq 64(%rsp),%rax +mulq 24(%rdi) +add %rax,%r10 +adc %rdx,%r11 +movq 64(%rsp),%rax +mulq 32(%rdi) +add %rax,%r12 +adc %rdx,%r13 +movq x25519_x86_64_REDMASK51(%rip),%rdx +shld $13,%rsi,%rcx +and %rdx,%rsi +shld $13,%r8,%r9 +and %rdx,%r8 +add %rcx,%r8 +shld $13,%r10,%r11 +and %rdx,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rdx,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rdx,%r14 +add %r13,%r14 +imulq $19,%r15,%rcx +add %rcx,%rsi +mov %rsi,%rcx +shr $51,%rcx +add %r8,%rcx +mov %rcx,%r8 +shr $51,%rcx +and %rdx,%rsi +add %r10,%rcx +mov %rcx,%r9 +shr $51,%rcx +and %rdx,%r8 +add %r12,%rcx +mov %rcx,%rax +shr $51,%rcx +and %rdx,%r9 +add %r14,%rcx +mov %rcx,%r10 +shr $51,%rcx +and %rdx,%rax +imulq $19,%rcx,%rcx +add %rcx,%rsi +and %rdx,%r10 +movq %rsi,160(%rdi) +movq %r8,168(%rdi) +movq %r9,176(%rdi) +movq %rax,184(%rdi) +movq %r10,192(%rdi) +movq 200(%rsp),%rsi +imulq $19,%rsi,%rax +movq %rax,56(%rsp) +mulq 152(%rsp) +mov %rax,%rsi +mov %rdx,%rcx +movq 208(%rsp),%rdx +imulq $19,%rdx,%rax +movq %rax,64(%rsp) +mulq 144(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 176(%rsp),%rax +mulq 136(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 176(%rsp),%rax +mulq 144(%rsp) +mov %rax,%r8 +mov %rdx,%r9 +movq 176(%rsp),%rax +mulq 152(%rsp) +mov %rax,%r10 +mov %rdx,%r11 +movq 176(%rsp),%rax +mulq 160(%rsp) +mov %rax,%r12 +mov %rdx,%r13 +movq 176(%rsp),%rax +mulq 168(%rsp) +mov %rax,%r14 +mov %rdx,%r15 +movq 184(%rsp),%rax +mulq 136(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 184(%rsp),%rax +mulq 144(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 184(%rsp),%rax +mulq 152(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 184(%rsp),%rax +mulq 160(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 184(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 168(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 192(%rsp),%rax +mulq 136(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 192(%rsp),%rax +mulq 144(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 192(%rsp),%rax +mulq 152(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 192(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 160(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 192(%rsp),%rdx +imulq $19,%rdx,%rax +mulq 168(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 200(%rsp),%rax +mulq 136(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 200(%rsp),%rax +mulq 144(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 56(%rsp),%rax +mulq 160(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 56(%rsp),%rax +mulq 168(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 208(%rsp),%rax +mulq 136(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 64(%rsp),%rax +mulq 152(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 64(%rsp),%rax +mulq 160(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 64(%rsp),%rax +mulq 168(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq x25519_x86_64_REDMASK51(%rip),%rdx +shld $13,%rsi,%rcx +and %rdx,%rsi +shld $13,%r8,%r9 +and %rdx,%r8 +add %rcx,%r8 +shld $13,%r10,%r11 +and %rdx,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rdx,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rdx,%r14 +add %r13,%r14 +imulq $19,%r15,%rcx +add %rcx,%rsi +mov %rsi,%rcx +shr $51,%rcx +add %r8,%rcx +mov %rcx,%r8 +shr $51,%rcx +and %rdx,%rsi +add %r10,%rcx +mov %rcx,%r9 +shr $51,%rcx +and %rdx,%r8 +add %r12,%rcx +mov %rcx,%rax +shr $51,%rcx +and %rdx,%r9 +add %r14,%rcx +mov %rcx,%r10 +shr $51,%rcx +and %rdx,%rax +imulq $19,%rcx,%rcx +add %rcx,%rsi +and %rdx,%r10 +movq %rsi,40(%rdi) +movq %r8,48(%rdi) +movq %r9,56(%rdi) +movq %rax,64(%rdi) +movq %r10,72(%rdi) +movq 216(%rsp),%rax +mulq x25519_x86_64_121666_213(%rip) +shr $13,%rax +mov %rax,%rsi +mov %rdx,%rcx +movq 224(%rsp),%rax +mulq x25519_x86_64_121666_213(%rip) +shr $13,%rax +add %rax,%rcx +mov %rdx,%r8 +movq 232(%rsp),%rax +mulq x25519_x86_64_121666_213(%rip) +shr $13,%rax +add %rax,%r8 +mov %rdx,%r9 +movq 240(%rsp),%rax +mulq x25519_x86_64_121666_213(%rip) +shr $13,%rax +add %rax,%r9 +mov %rdx,%r10 +movq 248(%rsp),%rax +mulq x25519_x86_64_121666_213(%rip) +shr $13,%rax +add %rax,%r10 +imulq $19,%rdx,%rdx +add %rdx,%rsi +addq 136(%rsp),%rsi +addq 144(%rsp),%rcx +addq 152(%rsp),%r8 +addq 160(%rsp),%r9 +addq 168(%rsp),%r10 +movq %rsi,80(%rdi) +movq %rcx,88(%rdi) +movq %r8,96(%rdi) +movq %r9,104(%rdi) +movq %r10,112(%rdi) +movq 104(%rdi),%rsi +imulq $19,%rsi,%rax +movq %rax,56(%rsp) +mulq 232(%rsp) +mov %rax,%rsi +mov %rdx,%rcx +movq 112(%rdi),%rdx +imulq $19,%rdx,%rax +movq %rax,64(%rsp) +mulq 224(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 80(%rdi),%rax +mulq 216(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 80(%rdi),%rax +mulq 224(%rsp) +mov %rax,%r8 +mov %rdx,%r9 +movq 80(%rdi),%rax +mulq 232(%rsp) +mov %rax,%r10 +mov %rdx,%r11 +movq 80(%rdi),%rax +mulq 240(%rsp) +mov %rax,%r12 +mov %rdx,%r13 +movq 80(%rdi),%rax +mulq 248(%rsp) +mov %rax,%r14 +mov %rdx,%r15 +movq 88(%rdi),%rax +mulq 216(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 88(%rdi),%rax +mulq 224(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 88(%rdi),%rax +mulq 232(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 88(%rdi),%rax +mulq 240(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 88(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 248(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 96(%rdi),%rax +mulq 216(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 96(%rdi),%rax +mulq 224(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 96(%rdi),%rax +mulq 232(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 96(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 240(%rsp) +add %rax,%rsi +adc %rdx,%rcx +movq 96(%rdi),%rdx +imulq $19,%rdx,%rax +mulq 248(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 104(%rdi),%rax +mulq 216(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq 104(%rdi),%rax +mulq 224(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 56(%rsp),%rax +mulq 240(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 56(%rsp),%rax +mulq 248(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 112(%rdi),%rax +mulq 216(%rsp) +add %rax,%r14 +adc %rdx,%r15 +movq 64(%rsp),%rax +mulq 232(%rsp) +add %rax,%r8 +adc %rdx,%r9 +movq 64(%rsp),%rax +mulq 240(%rsp) +add %rax,%r10 +adc %rdx,%r11 +movq 64(%rsp),%rax +mulq 248(%rsp) +add %rax,%r12 +adc %rdx,%r13 +movq x25519_x86_64_REDMASK51(%rip),%rdx +shld $13,%rsi,%rcx +and %rdx,%rsi +shld $13,%r8,%r9 +and %rdx,%r8 +add %rcx,%r8 +shld $13,%r10,%r11 +and %rdx,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rdx,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rdx,%r14 +add %r13,%r14 +imulq $19,%r15,%rcx +add %rcx,%rsi +mov %rsi,%rcx +shr $51,%rcx +add %r8,%rcx +mov %rcx,%r8 +shr $51,%rcx +and %rdx,%rsi +add %r10,%rcx +mov %rcx,%r9 +shr $51,%rcx +and %rdx,%r8 +add %r12,%rcx +mov %rcx,%rax +shr $51,%rcx +and %rdx,%r9 +add %r14,%rcx +mov %rcx,%r10 +shr $51,%rcx +and %rdx,%rax +imulq $19,%rcx,%rcx +add %rcx,%rsi +and %rdx,%r10 +movq %rsi,80(%rdi) +movq %r8,88(%rdi) +movq %r9,96(%rdi) +movq %rax,104(%rdi) +movq %r10,112(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +movq 16(%rsp),%r13 +movq 24(%rsp),%r14 +movq 32(%rsp),%r15 +movq 40(%rsp),%rbx +movq 48(%rsp),%rbp +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret + +.p2align 5 +.globl C_ABI(x25519_x86_64_work_cswap) +HIDDEN C_ABI(x25519_x86_64_work_cswap) +C_ABI(x25519_x86_64_work_cswap): +mov %rsp,%r11 +and $31,%r11 +add $0,%r11 +sub %r11,%rsp +cmp $1,%rsi +movq 0(%rdi),%rsi +movq 80(%rdi),%rdx +movq 8(%rdi),%rcx +movq 88(%rdi),%r8 +mov %rsi,%r9 +cmove %rdx,%rsi +cmove %r9,%rdx +mov %rcx,%r9 +cmove %r8,%rcx +cmove %r9,%r8 +movq %rsi,0(%rdi) +movq %rdx,80(%rdi) +movq %rcx,8(%rdi) +movq %r8,88(%rdi) +movq 16(%rdi),%rsi +movq 96(%rdi),%rdx +movq 24(%rdi),%rcx +movq 104(%rdi),%r8 +mov %rsi,%r9 +cmove %rdx,%rsi +cmove %r9,%rdx +mov %rcx,%r9 +cmove %r8,%rcx +cmove %r9,%r8 +movq %rsi,16(%rdi) +movq %rdx,96(%rdi) +movq %rcx,24(%rdi) +movq %r8,104(%rdi) +movq 32(%rdi),%rsi +movq 112(%rdi),%rdx +movq 40(%rdi),%rcx +movq 120(%rdi),%r8 +mov %rsi,%r9 +cmove %rdx,%rsi +cmove %r9,%rdx +mov %rcx,%r9 +cmove %r8,%rcx +cmove %r9,%r8 +movq %rsi,32(%rdi) +movq %rdx,112(%rdi) +movq %rcx,40(%rdi) +movq %r8,120(%rdi) +movq 48(%rdi),%rsi +movq 128(%rdi),%rdx +movq 56(%rdi),%rcx +movq 136(%rdi),%r8 +mov %rsi,%r9 +cmove %rdx,%rsi +cmove %r9,%rdx +mov %rcx,%r9 +cmove %r8,%rcx +cmove %r9,%r8 +movq %rsi,48(%rdi) +movq %rdx,128(%rdi) +movq %rcx,56(%rdi) +movq %r8,136(%rdi) +movq 64(%rdi),%rsi +movq 144(%rdi),%rdx +movq 72(%rdi),%rcx +movq 152(%rdi),%r8 +mov %rsi,%r9 +cmove %rdx,%rsi +cmove %r9,%rdx +mov %rcx,%r9 +cmove %r8,%rcx +cmove %r9,%r8 +movq %rsi,64(%rdi) +movq %rdx,144(%rdi) +movq %rcx,72(%rdi) +movq %r8,152(%rdi) +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/src/crypto/curve25519/curve25519.c b/src/crypto/curve25519/curve25519.c new file mode 100644 index 0000000..272db6c --- /dev/null +++ b/src/crypto/curve25519/curve25519.c @@ -0,0 +1,4898 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP + * 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as + * public domain but this file has the ISC license just to keep licencing + * simple. + * + * The field functions are shared by Ed25519 and X25519 where possible. */ + +#include <openssl/curve25519.h> + +#include <string.h> + +#include <openssl/cpu.h> +#include <openssl/mem.h> +#include <openssl/rand.h> +#include <openssl/sha.h> + +#include "internal.h" + + +/* fe means field element. Here the field is \Z/(2^255-19). An element t, + * entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 + * t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on + * context. */ +typedef int32_t fe[10]; + +static uint64_t load_3(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + return result; +} + +static uint64_t load_4(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + result |= ((uint64_t)in[3]) << 24; + return result; +} + +static void fe_frombytes(fe h, const uint8_t *s) { + /* Ignores top bit of h. */ + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = (load_3(s + 29) & 8388607) << 2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* Preconditions: + * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + * + * Write p=2^255-19; q=floor(h/p). + * Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). + * + * Proof: + * Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. + * Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. + * + * Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). + * Then 0<y<1. + * + * Write r=h-pq. + * Have 0<=r<=p-1=2^255-20. + * Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1. + * + * Write x=r+19(2^-255)r+y. + * Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q. + * + * Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1)) + * so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q. */ +static void fe_tobytes(uint8_t *s, const fe h) { + int32_t h0 = h[0]; + int32_t h1 = h[1]; + int32_t h2 = h[2]; + int32_t h3 = h[3]; + int32_t h4 = h[4]; + int32_t h5 = h[5]; + int32_t h6 = h[6]; + int32_t h7 = h[7]; + int32_t h8 = h[8]; + int32_t h9 = h[9]; + int32_t q; + int32_t carry0; + int32_t carry1; + int32_t carry2; + int32_t carry3; + int32_t carry4; + int32_t carry5; + int32_t carry6; + int32_t carry7; + int32_t carry8; + int32_t carry9; + + q = (19 * h9 + (((int32_t) 1) << 24)) >> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + + carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; + carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; + carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; + carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; + carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; + carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; + carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; + carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; + carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; + carry9 = h9 >> 25; h9 -= carry9 << 25; + /* h10 = carry9 */ + + /* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + * Have h0+...+2^230 h9 between 0 and 2^255-1; + * evidently 2^255 h10-2^255 q = 0. + * Goal: Output h0+...+2^230 h9. */ + + s[0] = h0 >> 0; + s[1] = h0 >> 8; + s[2] = h0 >> 16; + s[3] = (h0 >> 24) | (h1 << 2); + s[4] = h1 >> 6; + s[5] = h1 >> 14; + s[6] = (h1 >> 22) | (h2 << 3); + s[7] = h2 >> 5; + s[8] = h2 >> 13; + s[9] = (h2 >> 21) | (h3 << 5); + s[10] = h3 >> 3; + s[11] = h3 >> 11; + s[12] = (h3 >> 19) | (h4 << 6); + s[13] = h4 >> 2; + s[14] = h4 >> 10; + s[15] = h4 >> 18; + s[16] = h5 >> 0; + s[17] = h5 >> 8; + s[18] = h5 >> 16; + s[19] = (h5 >> 24) | (h6 << 1); + s[20] = h6 >> 7; + s[21] = h6 >> 15; + s[22] = (h6 >> 23) | (h7 << 3); + s[23] = h7 >> 5; + s[24] = h7 >> 13; + s[25] = (h7 >> 21) | (h8 << 4); + s[26] = h8 >> 4; + s[27] = h8 >> 12; + s[28] = (h8 >> 20) | (h9 << 6); + s[29] = h9 >> 2; + s[30] = h9 >> 10; + s[31] = h9 >> 18; +} + +/* h = f */ +static void fe_copy(fe h, const fe f) { + memmove(h, f, sizeof(int32_t) * 10); +} + +/* h = 0 */ +static void fe_0(fe h) { memset(h, 0, sizeof(int32_t) * 10); } + +/* h = 1 */ +static void fe_1(fe h) { + memset(h, 0, sizeof(int32_t) * 10); + h[0] = 1; +} + +/* h = f + g + * Can overlap h with f or g. + * + * Preconditions: + * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + * Postconditions: + * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ +static void fe_add(fe h, const fe f, const fe g) { + unsigned i; + for (i = 0; i < 10; i++) { + h[i] = f[i] + g[i]; + } +} + +/* h = f - g + * Can overlap h with f or g. + * + * Preconditions: + * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + * Postconditions: + * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ +static void fe_sub(fe h, const fe f, const fe g) { + unsigned i; + for (i = 0; i < 10; i++) { + h[i] = f[i] - g[i]; + } +} + +/* h = f * g + * Can overlap h with f or g. + * + * Preconditions: + * |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + * Postconditions: + * |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + * + * Notes on implementation strategy: + * + * Using schoolbook multiplication. + * Karatsuba would save a little in some cost models. + * + * Most multiplications by 2 and 19 are 32-bit precomputations; + * cheaper than 64-bit postcomputations. + * + * There is one remaining multiplication by 19 in the carry chain; + * one *19 precomputation can be merged into this, + * but the resulting data flow is considerably less clean. + * + * There are 12 carries below. + * 10 of them are 2-way parallelizable and vectorizable. + * Can get away with 11 carries, but then data flow is much deeper. + * + * With tighter constraints on inputs can squeeze carries into int32. */ +static void fe_mul(fe h, const fe f, const fe g) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ + int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + int32_t g3_19 = 19 * g3; + int32_t g4_19 = 19 * g4; + int32_t g5_19 = 19 * g5; + int32_t g6_19 = 19 * g6; + int32_t g7_19 = 19 * g7; + int32_t g8_19 = 19 * g8; + int32_t g9_19 = 19 * g9; + int32_t f1_2 = 2 * f1; + int32_t f3_2 = 2 * f3; + int32_t f5_2 = 2 * f5; + int32_t f7_2 = 2 * f7; + int32_t f9_2 = 2 * f9; + int64_t f0g0 = f0 * (int64_t) g0; + int64_t f0g1 = f0 * (int64_t) g1; + int64_t f0g2 = f0 * (int64_t) g2; + int64_t f0g3 = f0 * (int64_t) g3; + int64_t f0g4 = f0 * (int64_t) g4; + int64_t f0g5 = f0 * (int64_t) g5; + int64_t f0g6 = f0 * (int64_t) g6; + int64_t f0g7 = f0 * (int64_t) g7; + int64_t f0g8 = f0 * (int64_t) g8; + int64_t f0g9 = f0 * (int64_t) g9; + int64_t f1g0 = f1 * (int64_t) g0; + int64_t f1g1_2 = f1_2 * (int64_t) g1; + int64_t f1g2 = f1 * (int64_t) g2; + int64_t f1g3_2 = f1_2 * (int64_t) g3; + int64_t f1g4 = f1 * (int64_t) g4; + int64_t f1g5_2 = f1_2 * (int64_t) g5; + int64_t f1g6 = f1 * (int64_t) g6; + int64_t f1g7_2 = f1_2 * (int64_t) g7; + int64_t f1g8 = f1 * (int64_t) g8; + int64_t f1g9_38 = f1_2 * (int64_t) g9_19; + int64_t f2g0 = f2 * (int64_t) g0; + int64_t f2g1 = f2 * (int64_t) g1; + int64_t f2g2 = f2 * (int64_t) g2; + int64_t f2g3 = f2 * (int64_t) g3; + int64_t f2g4 = f2 * (int64_t) g4; + int64_t f2g5 = f2 * (int64_t) g5; + int64_t f2g6 = f2 * (int64_t) g6; + int64_t f2g7 = f2 * (int64_t) g7; + int64_t f2g8_19 = f2 * (int64_t) g8_19; + int64_t f2g9_19 = f2 * (int64_t) g9_19; + int64_t f3g0 = f3 * (int64_t) g0; + int64_t f3g1_2 = f3_2 * (int64_t) g1; + int64_t f3g2 = f3 * (int64_t) g2; + int64_t f3g3_2 = f3_2 * (int64_t) g3; + int64_t f3g4 = f3 * (int64_t) g4; + int64_t f3g5_2 = f3_2 * (int64_t) g5; + int64_t f3g6 = f3 * (int64_t) g6; + int64_t f3g7_38 = f3_2 * (int64_t) g7_19; + int64_t f3g8_19 = f3 * (int64_t) g8_19; + int64_t f3g9_38 = f3_2 * (int64_t) g9_19; + int64_t f4g0 = f4 * (int64_t) g0; + int64_t f4g1 = f4 * (int64_t) g1; + int64_t f4g2 = f4 * (int64_t) g2; + int64_t f4g3 = f4 * (int64_t) g3; + int64_t f4g4 = f4 * (int64_t) g4; + int64_t f4g5 = f4 * (int64_t) g5; + int64_t f4g6_19 = f4 * (int64_t) g6_19; + int64_t f4g7_19 = f4 * (int64_t) g7_19; + int64_t f4g8_19 = f4 * (int64_t) g8_19; + int64_t f4g9_19 = f4 * (int64_t) g9_19; + int64_t f5g0 = f5 * (int64_t) g0; + int64_t f5g1_2 = f5_2 * (int64_t) g1; + int64_t f5g2 = f5 * (int64_t) g2; + int64_t f5g3_2 = f5_2 * (int64_t) g3; + int64_t f5g4 = f5 * (int64_t) g4; + int64_t f5g5_38 = f5_2 * (int64_t) g5_19; + int64_t f5g6_19 = f5 * (int64_t) g6_19; + int64_t f5g7_38 = f5_2 * (int64_t) g7_19; + int64_t f5g8_19 = f5 * (int64_t) g8_19; + int64_t f5g9_38 = f5_2 * (int64_t) g9_19; + int64_t f6g0 = f6 * (int64_t) g0; + int64_t f6g1 = f6 * (int64_t) g1; + int64_t f6g2 = f6 * (int64_t) g2; + int64_t f6g3 = f6 * (int64_t) g3; + int64_t f6g4_19 = f6 * (int64_t) g4_19; + int64_t f6g5_19 = f6 * (int64_t) g5_19; + int64_t f6g6_19 = f6 * (int64_t) g6_19; + int64_t f6g7_19 = f6 * (int64_t) g7_19; + int64_t f6g8_19 = f6 * (int64_t) g8_19; + int64_t f6g9_19 = f6 * (int64_t) g9_19; + int64_t f7g0 = f7 * (int64_t) g0; + int64_t f7g1_2 = f7_2 * (int64_t) g1; + int64_t f7g2 = f7 * (int64_t) g2; + int64_t f7g3_38 = f7_2 * (int64_t) g3_19; + int64_t f7g4_19 = f7 * (int64_t) g4_19; + int64_t f7g5_38 = f7_2 * (int64_t) g5_19; + int64_t f7g6_19 = f7 * (int64_t) g6_19; + int64_t f7g7_38 = f7_2 * (int64_t) g7_19; + int64_t f7g8_19 = f7 * (int64_t) g8_19; + int64_t f7g9_38 = f7_2 * (int64_t) g9_19; + int64_t f8g0 = f8 * (int64_t) g0; + int64_t f8g1 = f8 * (int64_t) g1; + int64_t f8g2_19 = f8 * (int64_t) g2_19; + int64_t f8g3_19 = f8 * (int64_t) g3_19; + int64_t f8g4_19 = f8 * (int64_t) g4_19; + int64_t f8g5_19 = f8 * (int64_t) g5_19; + int64_t f8g6_19 = f8 * (int64_t) g6_19; + int64_t f8g7_19 = f8 * (int64_t) g7_19; + int64_t f8g8_19 = f8 * (int64_t) g8_19; + int64_t f8g9_19 = f8 * (int64_t) g9_19; + int64_t f9g0 = f9 * (int64_t) g0; + int64_t f9g1_38 = f9_2 * (int64_t) g1_19; + int64_t f9g2_19 = f9 * (int64_t) g2_19; + int64_t f9g3_38 = f9_2 * (int64_t) g3_19; + int64_t f9g4_19 = f9 * (int64_t) g4_19; + int64_t f9g5_38 = f9_2 * (int64_t) g5_19; + int64_t f9g6_19 = f9 * (int64_t) g6_19; + int64_t f9g7_38 = f9_2 * (int64_t) g7_19; + int64_t f9g8_19 = f9 * (int64_t) g8_19; + int64_t f9g9_38 = f9_2 * (int64_t) g9_19; + int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38; + int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19; + int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38; + int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19; + int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38; + int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19; + int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38; + int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19; + int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38; + int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + /* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) + * i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 + * |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) + * i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */ + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.71*2^59 */ + /* |h5| <= 1.71*2^59 */ + + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.41*2^60 */ + /* |h6| <= 1.41*2^60 */ + + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.71*2^59 */ + /* |h7| <= 1.71*2^59 */ + + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.72*2^34 */ + /* |h8| <= 1.41*2^60 */ + + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.71*2^59 */ + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.1*2^39 */ + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* h = f * f + * Can overlap h with f. + * + * Preconditions: + * |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + * Postconditions: + * |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + * + * See fe_mul.c for discussion of implementation strategy. */ +static void fe_sq(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; + int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; + int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; + int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; + int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; + int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; + int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; + int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; + int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; + int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +static void fe_invert(fe out, const fe z) { + fe t0; + fe t1; + fe t2; + fe t3; + int i; + + fe_sq(t0, z); + for (i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } + fe_sq(t1, t0); + for (i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t2, t0); + for (i = 1; i < 1; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t1, t2); + fe_sq(t2, t1); + for (i = 1; i < 5; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t2, t1); + for (i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } + fe_mul(t2, t2, t1); + fe_sq(t3, t2); + for (i = 1; i < 20; ++i) { + fe_sq(t3, t3); + } + fe_mul(t2, t3, t2); + fe_sq(t2, t2); + for (i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t2, t1); + for (i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } + fe_mul(t2, t2, t1); + fe_sq(t3, t2); + for (i = 1; i < 100; ++i) { + fe_sq(t3, t3); + } + fe_mul(t2, t3, t2); + fe_sq(t2, t2); + for (i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + for (i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } + fe_mul(out, t1, t0); +} + +/* h = -f + * + * Preconditions: + * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + * Postconditions: + * |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */ +static void fe_neg(fe h, const fe f) { + unsigned i; + for (i = 0; i < 10; i++) { + h[i] = -f[i]; + } +} + +/* Replace (f,g) with (g,g) if b == 1; + * replace (f,g) with (f,g) if b == 0. + * + * Preconditions: b in {0,1}. */ +static void fe_cmov(fe f, const fe g, unsigned b) { + b = 0-b; + unsigned i; + for (i = 0; i < 10; i++) { + int32_t x = f[i] ^ g[i]; + x &= b; + f[i] ^= x; + } +} + +/* return 0 if f == 0 + * return 1 if f != 0 + * + * Preconditions: + * |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ +static int fe_isnonzero(const fe f) { + uint8_t s[32]; + fe_tobytes(s, f); + + static const uint8_t zero[32] = {0}; + return CRYPTO_memcmp(s, zero, sizeof(zero)) != 0; +} + +/* return 1 if f is in {1,3,5,...,q-2} + * return 0 if f is in {0,2,4,...,q-1} + * + * Preconditions: + * |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ +static int fe_isnegative(const fe f) { + uint8_t s[32]; + fe_tobytes(s, f); + return s[0] & 1; +} + +/* h = 2 * f * f + * Can overlap h with f. + * + * Preconditions: + * |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + * Postconditions: + * |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + * + * See fe_mul.c for discussion of implementation strategy. */ +static void fe_sq2(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; + int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; + int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; + int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; + int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; + int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; + int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; + int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; + int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; + int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +static void fe_pow22523(fe out, const fe z) { + fe t0; + fe t1; + fe t2; + int i; + + fe_sq(t0, z); + for (i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } + fe_sq(t1, t0); + for (i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t0, t0); + for (i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + for (i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + for (i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, t1, t0); + fe_sq(t2, t1); + for (i = 1; i < 20; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + for (i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + for (i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, t1, t0); + fe_sq(t2, t1); + for (i = 1; i < 100; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + for (i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } + fe_mul(t0, t1, t0); + fe_sq(t0, t0); + for (i = 1; i < 2; ++i) { + fe_sq(t0, t0); + } + fe_mul(out, t0, z); +} + +/* ge means group element. + + * Here the group is the set of pairs (x,y) of field elements (see fe.h) + * satisfying -x^2 + y^2 = 1 + d x^2y^2 + * where d = -121665/121666. + * + * Representations: + * ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z + * ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT + * ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T + * ge_precomp (Duif): (y+x,y-x,2dxy) */ + +typedef struct { + fe X; + fe Y; + fe Z; +} ge_p2; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p3; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p1p1; + +typedef struct { + fe yplusx; + fe yminusx; + fe xy2d; +} ge_precomp; + +typedef struct { + fe YplusX; + fe YminusX; + fe Z; + fe T2d; +} ge_cached; + +static void ge_tobytes(uint8_t *s, const ge_p2 *h) { + fe recip; + fe x; + fe y; + + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; +} + +static void ge_p3_tobytes(uint8_t *s, const ge_p3 *h) { + fe recip; + fe x; + fe y; + + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; +} + +static const fe d = {-10913610, 13857413, -15372611, 6949391, 114729, + -8787816, -6275908, -3247719, -18696448, -12055116}; + +static const fe sqrtm1 = {-32595792, -7943725, 9377950, 3500415, 12389472, + -272473, -25146209, -2005654, 326686, 11406482}; + +static int ge_frombytes_negate_vartime(ge_p3 *h, const uint8_t *s) { + fe u; + fe v; + fe v3; + fe vxx; + fe check; + + fe_frombytes(h->Y, s); + fe_1(h->Z); + fe_sq(u, h->Y); + fe_mul(v, u, d); + fe_sub(u, u, h->Z); /* u = y^2-1 */ + fe_add(v, v, h->Z); /* v = dy^2+1 */ + + fe_sq(v3, v); + fe_mul(v3, v3, v); /* v3 = v^3 */ + fe_sq(h->X, v3); + fe_mul(h->X, h->X, v); + fe_mul(h->X, h->X, u); /* x = uv^7 */ + + fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ + fe_mul(h->X, h->X, v3); + fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe_sq(vxx, h->X); + fe_mul(vxx, vxx, v); + fe_sub(check, vxx, u); /* vx^2-u */ + if (fe_isnonzero(check)) { + fe_add(check, vxx, u); /* vx^2+u */ + if (fe_isnonzero(check)) { + return -1; + } + fe_mul(h->X, h->X, sqrtm1); + } + + if (fe_isnegative(h->X) == (s[31] >> 7)) { + fe_neg(h->X, h->X); + } + + fe_mul(h->T, h->X, h->Y); + return 0; +} + +static void ge_p2_0(ge_p2 *h) { + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); +} + +static void ge_p3_0(ge_p3 *h) { + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); + fe_0(h->T); +} + +static void ge_precomp_0(ge_precomp *h) { + fe_1(h->yplusx); + fe_1(h->yminusx); + fe_0(h->xy2d); +} + +/* r = p */ +static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { + fe_copy(r->X, p->X); + fe_copy(r->Y, p->Y); + fe_copy(r->Z, p->Z); +} + +static const fe d2 = {-21827239, -5839606, -30745221, 13898782, 229458, + 15978800, -12551817, -6495438, 29715968, 9444199}; + +/* r = p */ +static void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { + fe_add(r->YplusX, p->Y, p->X); + fe_sub(r->YminusX, p->Y, p->X); + fe_copy(r->Z, p->Z); + fe_mul(r->T2d, p->T, d2); +} + +/* r = p */ +static void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); +} + +/* r = p */ +static void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); + fe_mul(r->T, p->X, p->Y); +} + +/* r = 2 * p */ +static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { + fe t0; + + fe_sq(r->X, p->X); + fe_sq(r->Z, p->Y); + fe_sq2(r->T, p->Z); + fe_add(r->Y, p->X, p->Y); + fe_sq(t0, r->Y); + fe_add(r->Y, r->Z, r->X); + fe_sub(r->Z, r->Z, r->X); + fe_sub(r->X, t0, r->Y); + fe_sub(r->T, r->T, r->Z); +} + +/* r = 2 * p */ +static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { + ge_p2 q; + ge_p3_to_p2(&q, p); + ge_p2_dbl(r, &q); +} + +/* r = p + q */ +static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yplusx); + fe_mul(r->Y, r->Y, q->yminusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); +} + +/* r = p - q */ +static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yminusx); + fe_mul(r->Y, r->Y, q->yplusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); +} + +/* r = p + q */ +static void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YplusX); + fe_mul(r->Y, r->Y, q->YminusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); +} + +/* r = p - q */ +static void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YminusX); + fe_mul(r->Y, r->Y, q->YplusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); +} + +static uint8_t equal(signed char b, signed char c) { + uint8_t ub = b; + uint8_t uc = c; + uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */ + uint32_t y = x; /* 0: yes; 1..255: no */ + y -= 1; /* 4294967295: yes; 0..254: no */ + y >>= 31; /* 1: yes; 0: no */ + return y; +} + +static void cmov(ge_precomp *t, ge_precomp *u, uint8_t b) { + fe_cmov(t->yplusx, u->yplusx, b); + fe_cmov(t->yminusx, u->yminusx, b); + fe_cmov(t->xy2d, u->xy2d, b); +} + +#if defined(OPENSSL_SMALL) + +/* This block of code replaces the standard base-point table with a much smaller + * one. The standard table is 30,720 bytes while this one is just 960. + * + * This table contains 15 pairs of group elements, (x, y), where each field + * element is serialised with |fe_tobytes|. If |i| is the index of the group + * element then consider i+1 as a four-bit number: (i₀, i₁, i₂, i₃) (where i₀ + * is the most significant bit). The value of the group element is then: + * (i₀×2^192 + i₁×2^128 + i₂×2^64 + i₃)G, where G is the generator. */ +static const uint8_t kSmallPrecomp[15 * 2 * 32] = { + 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, + 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, + 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21, 0x58, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, + 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, + 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62, + 0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, + 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, + 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03, 0xa2, 0xfb, 0xcc, 0x61, + 0x67, 0x06, 0x70, 0x1a, 0xc4, 0x78, 0x3a, 0xff, 0x32, 0x62, 0xdd, 0x2c, + 0xab, 0x50, 0x19, 0x3b, 0xf2, 0x9b, 0x7d, 0xb8, 0xfd, 0x4f, 0x29, 0x9c, + 0xa7, 0x91, 0xba, 0x0e, 0x46, 0x5e, 0x51, 0xfe, 0x1d, 0xbf, 0xe5, 0xe5, + 0x9b, 0x95, 0x0d, 0x67, 0xf8, 0xd1, 0xb5, 0x5a, 0xa1, 0x93, 0x2c, 0xc3, + 0xde, 0x0e, 0x97, 0x85, 0x2d, 0x7f, 0xea, 0xab, 0x3e, 0x47, 0x30, 0x18, + 0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, + 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, + 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c, 0x6b, 0xa6, 0xf5, 0x4b, + 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, + 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, + 0xe6, 0x99, 0x2c, 0x5f, 0x9a, 0x96, 0x0c, 0x68, 0x29, 0xfd, 0xe2, 0xfb, + 0xe6, 0xbc, 0xec, 0x31, 0x08, 0xec, 0xe6, 0xb0, 0x53, 0x60, 0xc3, 0x8c, + 0xbe, 0xc1, 0xb3, 0x8a, 0x8f, 0xe4, 0x88, 0x2b, 0x55, 0xe5, 0x64, 0x6e, + 0x9b, 0xd0, 0xaf, 0x7b, 0x64, 0x2a, 0x35, 0x25, 0x10, 0x52, 0xc5, 0x9e, + 0x58, 0x11, 0x39, 0x36, 0x45, 0x51, 0xb8, 0x39, 0x93, 0xfc, 0x9d, 0x6a, + 0xbe, 0x58, 0xcb, 0xa4, 0x0f, 0x51, 0x3c, 0x38, 0x05, 0xca, 0xab, 0x43, + 0x63, 0x0e, 0xf3, 0x8b, 0x41, 0xa6, 0xf8, 0x9b, 0x53, 0x70, 0x80, 0x53, + 0x86, 0x5e, 0x8f, 0xe3, 0xc3, 0x0d, 0x18, 0xc8, 0x4b, 0x34, 0x1f, 0xd8, + 0x1d, 0xbc, 0xf2, 0x6d, 0x34, 0x3a, 0xbe, 0xdf, 0xd9, 0xf6, 0xf3, 0x89, + 0xa1, 0xe1, 0x94, 0x9f, 0x5d, 0x4c, 0x5d, 0xe9, 0xa1, 0x49, 0x92, 0xef, + 0x0e, 0x53, 0x81, 0x89, 0x58, 0x87, 0xa6, 0x37, 0xf1, 0xdd, 0x62, 0x60, + 0x63, 0x5a, 0x9d, 0x1b, 0x8c, 0xc6, 0x7d, 0x52, 0xea, 0x70, 0x09, 0x6a, + 0xe1, 0x32, 0xf3, 0x73, 0x21, 0x1f, 0x07, 0x7b, 0x7c, 0x9b, 0x49, 0xd8, + 0xc0, 0xf3, 0x25, 0x72, 0x6f, 0x9d, 0xed, 0x31, 0x67, 0x36, 0x36, 0x54, + 0x40, 0x92, 0x71, 0xe6, 0x11, 0x28, 0x11, 0xad, 0x93, 0x32, 0x85, 0x7b, + 0x3e, 0xb7, 0x3b, 0x49, 0x13, 0x1c, 0x07, 0xb0, 0x2e, 0x93, 0xaa, 0xfd, + 0xfd, 0x28, 0x47, 0x3d, 0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, + 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, + 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b, + 0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, + 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, + 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61, 0x38, 0x68, 0xb0, 0x07, + 0xa3, 0xfc, 0xcc, 0x85, 0x10, 0x7f, 0x4c, 0x65, 0x65, 0xb3, 0xfa, 0xfa, + 0xa5, 0x53, 0x6f, 0xdb, 0x74, 0x4c, 0x56, 0x46, 0x03, 0xe2, 0xd5, 0x7a, + 0x29, 0x1c, 0xc6, 0x02, 0xbc, 0x59, 0xf2, 0x04, 0x75, 0x63, 0xc0, 0x84, + 0x2f, 0x60, 0x1c, 0x67, 0x76, 0xfd, 0x63, 0x86, 0xf3, 0xfa, 0xbf, 0xdc, + 0xd2, 0x2d, 0x90, 0x91, 0xbd, 0x33, 0xa9, 0xe5, 0x66, 0x0c, 0xda, 0x42, + 0x27, 0xca, 0xf4, 0x66, 0xc2, 0xec, 0x92, 0x14, 0x57, 0x06, 0x63, 0xd0, + 0x4d, 0x15, 0x06, 0xeb, 0x69, 0x58, 0x4f, 0x77, 0xc5, 0x8b, 0xc7, 0xf0, + 0x8e, 0xed, 0x64, 0xa0, 0xb3, 0x3c, 0x66, 0x71, 0xc6, 0x2d, 0xda, 0x0a, + 0x0d, 0xfe, 0x70, 0x27, 0x64, 0xf8, 0x27, 0xfa, 0xf6, 0x5f, 0x30, 0xa5, + 0x0d, 0x6c, 0xda, 0xf2, 0x62, 0x5e, 0x78, 0x47, 0xd3, 0x66, 0x00, 0x1c, + 0xfd, 0x56, 0x1f, 0x5d, 0x3f, 0x6f, 0xf4, 0x4c, 0xd8, 0xfd, 0x0e, 0x27, + 0xc9, 0x5c, 0x2b, 0xbc, 0xc0, 0xa4, 0xe7, 0x23, 0x29, 0x02, 0x9f, 0x31, + 0xd6, 0xe9, 0xd7, 0x96, 0xf4, 0xe0, 0x5e, 0x0b, 0x0e, 0x13, 0xee, 0x3c, + 0x09, 0xed, 0xf2, 0x3d, 0x76, 0x91, 0xc3, 0xa4, 0x97, 0xae, 0xd4, 0x87, + 0xd0, 0x5d, 0xf6, 0x18, 0x47, 0x1f, 0x1d, 0x67, 0xf2, 0xcf, 0x63, 0xa0, + 0x91, 0x27, 0xf8, 0x93, 0x45, 0x75, 0x23, 0x3f, 0xd1, 0xf1, 0xad, 0x23, + 0xdd, 0x64, 0x93, 0x96, 0x41, 0x70, 0x7f, 0xf7, 0xf5, 0xa9, 0x89, 0xa2, + 0x34, 0xb0, 0x8d, 0x1b, 0xae, 0x19, 0x15, 0x49, 0x58, 0x23, 0x6d, 0x87, + 0x15, 0x4f, 0x81, 0x76, 0xfb, 0x23, 0xb5, 0xea, 0xcf, 0xac, 0x54, 0x8d, + 0x4e, 0x42, 0x2f, 0xeb, 0x0f, 0x63, 0xdb, 0x68, 0x37, 0xa8, 0xcf, 0x8b, + 0xab, 0xf5, 0xa4, 0x6e, 0x96, 0x2a, 0xb2, 0xd6, 0xbe, 0x9e, 0xbd, 0x0d, + 0xb4, 0x42, 0xa9, 0xcf, 0x01, 0x83, 0x8a, 0x17, 0x47, 0x76, 0xc4, 0xc6, + 0x83, 0x04, 0x95, 0x0b, 0xfc, 0x11, 0xc9, 0x62, 0xb8, 0x0c, 0x76, 0x84, + 0xd9, 0xb9, 0x37, 0xfa, 0xfc, 0x7c, 0xc2, 0x6d, 0x58, 0x3e, 0xb3, 0x04, + 0xbb, 0x8c, 0x8f, 0x48, 0xbc, 0x91, 0x27, 0xcc, 0xf9, 0xb7, 0x22, 0x19, + 0x83, 0x2e, 0x09, 0xb5, 0x72, 0xd9, 0x54, 0x1c, 0x4d, 0xa1, 0xea, 0x0b, + 0xf1, 0xc6, 0x08, 0x72, 0x46, 0x87, 0x7a, 0x6e, 0x80, 0x56, 0x0a, 0x8a, + 0xc0, 0xdd, 0x11, 0x6b, 0xd6, 0xdd, 0x47, 0xdf, 0x10, 0xd9, 0xd8, 0xea, + 0x7c, 0xb0, 0x8f, 0x03, 0x00, 0x2e, 0xc1, 0x8f, 0x44, 0xa8, 0xd3, 0x30, + 0x06, 0x89, 0xa2, 0xf9, 0x34, 0xad, 0xdc, 0x03, 0x85, 0xed, 0x51, 0xa7, + 0x82, 0x9c, 0xe7, 0x5d, 0x52, 0x93, 0x0c, 0x32, 0x9a, 0x5b, 0xe1, 0xaa, + 0xca, 0xb8, 0x02, 0x6d, 0x3a, 0xd4, 0xb1, 0x3a, 0xf0, 0x5f, 0xbe, 0xb5, + 0x0d, 0x10, 0x6b, 0x38, 0x32, 0xac, 0x76, 0x80, 0xbd, 0xca, 0x94, 0x71, + 0x7a, 0xf2, 0xc9, 0x35, 0x2a, 0xde, 0x9f, 0x42, 0x49, 0x18, 0x01, 0xab, + 0xbc, 0xef, 0x7c, 0x64, 0x3f, 0x58, 0x3d, 0x92, 0x59, 0xdb, 0x13, 0xdb, + 0x58, 0x6e, 0x0a, 0xe0, 0xb7, 0x91, 0x4a, 0x08, 0x20, 0xd6, 0x2e, 0x3c, + 0x45, 0xc9, 0x8b, 0x17, 0x79, 0xe7, 0xc7, 0x90, 0x99, 0x3a, 0x18, 0x25, +}; + +static void ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) { + /* kSmallPrecomp is first expanded into matching |ge_precomp| elements. */ + ge_precomp multiples[15]; + + unsigned i; + for (i = 0; i < 15; i++) { + const uint8_t *bytes = &kSmallPrecomp[i*(2 * 32)]; + fe x, y; + fe_frombytes(x, bytes); + fe_frombytes(y, bytes + 32); + + ge_precomp *out = &multiples[i]; + fe_add(out->yplusx, y, x); + fe_sub(out->yminusx, y, x); + fe_mul(out->xy2d, x, y); + fe_mul(out->xy2d, out->xy2d, d2); + } + + /* See the comment above |kSmallPrecomp| about the structure of the + * precomputed elements. This loop does 64 additions and 64 doublings to + * calculate the result. */ + ge_p3_0(h); + + for (i = 63; i < 64; i--) { + unsigned j; + signed char index = 0; + + for (j = 0; j < 4; j++) { + const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7)); + index |= (bit << j); + } + + ge_precomp e; + ge_precomp_0(&e); + + for (j = 1; j < 16; j++) { + cmov(&e, &multiples[j-1], equal(index, j)); + } + + ge_cached cached; + ge_p1p1 r; + ge_p3_to_cached(&cached, h); + ge_add(&r, h, &cached); + ge_p1p1_to_p3(h, &r); + + ge_madd(&r, h, &e); + ge_p1p1_to_p3(h, &r); + } +} + +#else + +/* base[i][j] = (j+1)*256^i*B */ +static ge_precomp base[32][8] = { + { + { + {25967493, -14356035, 29566456, 3660896, -12694345, 4014787, + 27544626, -11754271, -6079156, 2047605}, + {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, + 5043384, 19500929, -15469378}, + {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, + 29287919, 11864899, -24514362, -4438546}, + }, + { + {-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, + -11717903, -3814571, -358445, -10211303}, + {-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, + -15616551, 11189268, -26829678, -5319081}, + {26966642, 11152617, 32442495, 15396054, 14353839, -12752335, + -3128826, -9541118, -15472047, -4166697}, + }, + { + {15636291, -9688557, 24204773, -7912398, 616977, -16685262, + 27787600, -14772189, 28944400, -1550024}, + {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, + 16354577, -11775962, 7689662, 11199574}, + {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, + 7512774, 10017326, -17749093, -9920357}, + }, + { + {-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, + -28926210, 15006023, 3284568, -6276540}, + {23599295, -8306047, -11193664, -7687416, 13236774, 10506355, + 7464579, 9656445, 13059162, 10374397}, + {7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, + -3839045, -641708, -101325}, + }, + { + {10861363, 11473154, 27284546, 1981175, -30064349, 12577861, + 32867885, 14515107, -15438304, 10819380}, + {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, + 12483688, -12668491, 5581306}, + {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, + 28542350, 13850243, -23678021, -15815942}, + }, + { + {-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, + -19188627, -15224819, -9818940, -12085777}, + {-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, + -15689887, 1762328, 14866737}, + {-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, + -28236412, 3959421, 27914454, 4383652}, + }, + { + {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, + 5230134, -23952439, -15175766}, + {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, + 20654025, 16520125, 30598449, 7715701}, + {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, + -31400660, 1370708, 29794553, -1409300}, + }, + { + {14499471, -2729599, -33191113, -4254652, 28494862, 14271267, + 30290735, 10876454, -33154098, 2381726}, + {-7195431, -2655363, -14730155, 462251, -27724326, 3941372, + -6236617, 3696005, -32300832, 15351955}, + {27431194, 8222322, 16448760, -3907995, -18707002, 11938355, + -32961401, -2970515, 29551813, 10109425}, + }, + }, + { + { + {-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, + -2378284, -1627556, 10092783, -4764171}, + {27939166, 14210322, 4677035, 16277044, -22964462, -12398139, + -32508754, 12005538, -17810127, 12803510}, + {17228999, -15661624, -1233527, 300140, -1224870, -11714777, + 30364213, -9038194, 18016357, 4397660}, + }, + { + {-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, + -26619106, 14544525, -17477504, 982639}, + {29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, + -4120128, -21047696, 9934963}, + {5793303, 16271923, -24131614, -10116404, 29188560, 1206517, + -14747930, 4559895, -30123922, -10897950}, + }, + { + {-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, + 24191034, 4541697, -13338309, 5500568}, + {12650548, -1497113, 9052871, 11355358, -17680037, -8400164, + -17430592, 12264343, 10874051, 13524335}, + {25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, + 5080568, -22528059, 5376628}, + }, + { + {-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, + -22321305, -9447443, 4535768, 1569007}, + {-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, + -30494562, 3044290, 31848280, 12543772}, + {-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, + -27377195, -2062731, 7718482, 14474653}, + }, + { + {2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, + -7236665, 24316168, -5253567}, + {13741529, 10911568, -33233417, -8603737, -20177830, -1033297, + 33040651, -13424532, -20729456, 8321686}, + {21060490, -2212744, 15712757, -4336099, 1639040, 10656336, + 23845965, -11874838, -9984458, 608372}, + }, + { + {-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, + 1123968, -6780577, 27229399, 23887}, + {-23244140, -294205, -11744728, 14712571, -29465699, -2029617, + 12797024, -6440308, -1633405, 16678954}, + {-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, + -1508144, -4795045, -17169265, 4904953}, + }, + { + {24059557, 14617003, 19037157, -15039908, 19766093, -14906429, + 5169211, 16191880, 2128236, -4326833}, + {-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, + -29806336, 916033, -6882542, -2986532}, + {-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, + 285431, 2763829, 15736322, 4143876}, + }, + { + {2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, + -14594663, 23527084, -16458268}, + {33431127, -11130478, -17838966, -15626900, 8909499, 8376530, + -32625340, 4087881, -15188911, -14416214}, + {1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, + 4357868, -4774191, -16323038}, + }, + }, + { + { + {6721966, 13833823, -23523388, -1551314, 26354293, -11863321, + 23365147, -3949732, 7390890, 2759800}, + {4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, + -4264057, 1244380, -12919645}, + {-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, + 9208236, 15886429, 16489664}, + }, + { + {1996075, 10375649, 14346367, 13311202, -6874135, -16438411, + -13693198, 398369, -30606455, -712933}, + {-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, + 13348553, 12076947, -30836462, 5113182}, + {-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, + -30341101, -7336386, 13847711, 5387222}, + }, + { + {-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, + 8763061, 3617786, -19600662, 10370991}, + {20246567, -14369378, 22358229, -543712, 18507283, -10413996, + 14554437, -8746092, 32232924, 16763880}, + {9648505, 10094563, 26416693, 14745928, -30374318, -6472621, + 11094161, 15689506, 3140038, -16510092}, + }, + { + {-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, + -27224800, 9448613, -28774454, 366295}, + {19153450, 11523972, -11096490, -6503142, -24647631, 5420647, + 28344573, 8041113, 719605, 11671788}, + {8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, + -15266516, 27000813, -10195553}, + }, + { + {-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, + 5336097, 6750977, -14521026}, + {11836410, -3979488, 26297894, 16080799, 23455045, 15735944, + 1695823, -8819122, 8169720, 16220347}, + {-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, + -11144307, -2627664, -5990708, -14166033}, + }, + { + {-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, + 27884329, 2847284, 2655861, 1738395}, + {-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, + 21651608, -3239336, -19087449, -11005278}, + {1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, + 5821408, 10478196, 8544890}, + }, + { + {32173121, -16129311, 24896207, 3921497, 22579056, -3410854, + 19270449, 12217473, 17789017, -3395995}, + {-30552961, -2228401, -15578829, -10147201, 13243889, 517024, + 15479401, -3853233, 30460520, 1052596}, + {-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, + 27491595, -4612359, 3179268, -9478891}, + }, + { + {31947069, -14366651, -4640583, -15339921, -15125977, -6039709, + -14756777, -16411740, 19072640, -9511060}, + {11685058, 11822410, 3158003, -13952594, 33402194, -4165066, + 5977896, -5215017, 473099, 5040608}, + {-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, + 28326862, 1721092, -19558642, -3131606}, + }, + }, + { + { + {7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, + 8076149, -27868496, 11538389}, + {-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, + 8754525, 7446702, -5676054, 5797016}, + {-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, + 2014099, -9050574, -2369172, -5877341}, + }, + { + {-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, + 1192730, -3714199, 15123619, 10811505}, + {14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, + 15776356, -28886779, -11974553}, + {-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, + -20654173, -16484855, 4714547, -9600655}, + }, + { + {15200332, 8368572, 19679101, 15970074, -31872674, 1959451, + 24611599, -4543832, -11745876, 12340220}, + {12876937, -10480056, 33134381, 6590940, -6307776, 14872440, + 9613953, 8241152, 15370987, 9608631}, + {-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, + 15866074, -28210621, -8814099}, + }, + { + {26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, + 858697, 20571223, 8420556}, + {14620715, 13067227, -15447274, 8264467, 14106269, 15080814, + 33531827, 12516406, -21574435, -12476749}, + {236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, + 7256740, 8791136, 15069930}, + }, + { + {1276410, -9371918, 22949635, -16322807, -23493039, -5702186, + 14711875, 4874229, -30663140, -2331391}, + {5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, + -7912378, -33069337, 9234253}, + {20590503, -9018988, 31529744, -7352666, -2706834, 10650548, + 31559055, -11609587, 18979186, 13396066}, + }, + { + {24474287, 4968103, 22267082, 4407354, 24063882, -8325180, + -18816887, 13594782, 33514650, 7021958}, + {-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, + -25948728, -3916677, -21480480, 12868082}, + {-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, + -21446107, 2244500, -12455797, -8089383}, + }, + { + {-30595528, 13793479, -5852820, 319136, -25723172, -6263899, + 33086546, 8957937, -15233648, 5540521}, + {-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, + -23710744, -1568984, -16128528, -14962807}, + {23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, + 892185, -11513277, -15205948}, + }, + { + {9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, + 4763127, -19179614, 5867134}, + {-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, + 27846559, 5931263, -29749703, -16108455}, + {27461885, -2977536, 22380810, 1815854, -23033753, -3031938, + 7283490, -15148073, -19526700, 7734629}, + }, + }, + { + { + {-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, + 7585295, -3176626, 18549497, 15302069}, + {-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, + 10458790, -6418461, -8872242, 8424746}, + {24687205, 8613276, -30667046, -3233545, 1863892, -1830544, + 19206234, 7134917, -11284482, -828919}, + }, + { + {11334899, -9218022, 8025293, 12707519, 17523892, -10476071, + 10243738, -14685461, -5066034, 16498837}, + {8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, + -14124238, 6536641, 10543906}, + {-28946384, 15479763, -17466835, 568876, -1497683, 11223454, + -2669190, -16625574, -27235709, 8876771}, + }, + { + {-25742899, -12566864, -15649966, -846607, -33026686, -796288, + -33481822, 15824474, -604426, -9039817}, + {10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, + -4890037, 1657394, 3084098}, + {10477963, -7470260, 12119566, -13250805, 29016247, -5365589, + 31280319, 14396151, -30233575, 15272409}, + }, + { + {-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, + -25173957, -12636138, -25014757, 1950504}, + {-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, + -8384306, -8767532, 15341279, 8373727}, + {28685821, 7759505, -14378516, -12002860, -31971820, 4079242, + 298136, -10232602, -2878207, 15190420}, + }, + { + {-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, + 8669718, 2742393, -26033313, -6875003}, + {-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, + 9291594, -16247779, -12154742, 6048605}, + {-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, + 13934231, 5128323, 11213262, 9168384}, + }, + { + {-26280513, 11007847, 19408960, -940758, -18592965, -4328580, + -5088060, -11105150, 20470157, -16398701}, + {-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, + -22783952, 14461608, 14042978, 5230683}, + {29969567, -2741594, -16711867, -8552442, 9175486, -2468974, + 21556951, 3506042, -5933891, -12449708}, + }, + { + {-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, + -21284170, 8971513, -28539189, 15326563}, + {-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, + -15523050, 15300988, -20514118, 9168260}, + {-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, + -28948358, 9601605, 33087103, -9011387}, + }, + { + {-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, + -27444329, -15000531, -5996870, 15664672}, + {23294591, -16632613, -22650781, -8470978, 27844204, 11461195, + 13099750, -2460356, 18151676, 13417686}, + {-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, + 1661597, -12551441, 15271676, -15452665}, + }, + }, + { + { + {11433042, -13228665, 8239631, -5279517, -1985436, -725718, + -18698764, 2167544, -6921301, -13440182}, + {-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, + -9917708, -8638997, 12215110, 12028277}, + {14098400, 6555944, 23007258, 5757252, -15427832, -12950502, + 30123440, 4617780, -16900089, -655628}, + }, + { + {-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, + -15819999, 10154009, 23973261, -12684474}, + {-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, + 18341390, -11419951, 32013174, -10103539}, + {-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, + 21911214, 6354752, 4425632, -837822}, + }, + { + {-10433389, -14612966, 22229858, -3091047, -13191166, 776729, + -17415375, -12020462, 4725005, 14044970}, + {19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, + -1411784, -19522291, -16109756}, + {-24864089, 12986008, -10898878, -5558584, -11312371, -148526, + 19541418, 8180106, 9282262, 10282508}, + }, + { + {-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, + 15522535, 8372215, 5542595, -10702683}, + {-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, + -2781891, 6993761, -18093885, 10114655}, + {-20107055, -929418, 31422704, 10427861, -7110749, 6150669, + -29091755, -11529146, 25953725, -106158}, + }, + { + {-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, + 19390020, 6094296, -3315279, 12831125}, + {-15998678, 7578152, 5310217, 14408357, -33548620, -224739, + 31575954, 6326196, 7381791, -2421839}, + {-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, + 6295303, 8082724, -15362489, 12339664}, + }, + { + {27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, + 15768922, 25091167, 14856294}, + {-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, + -12695493, -22182473, -9012899}, + {-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, + -27260765, 13866390, 30146206, 9142070}, + }, + { + {3924129, -15307516, -13817122, -10054960, 12291820, -668366, + -27702774, 9326384, -8237858, 4171294}, + {-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, + 26396185, 3731949, 345228, -5462949}, + {-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, + 2031539, -12391231, -16253183, -13582083}, + }, + { + {31016211, -16722429, 26371392, -14451233, -5027349, 14854137, + 17477601, 3842657, 28012650, -16405420}, + {-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, + -9189873, 16292057, -8867157, 3507940}, + {29439664, 3537914, 23333589, 6997794, -17555561, -11018068, + -15209202, -15051267, -9164929, 6580396}, + }, + }, + { + { + {-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, + 17860444, -9273846, -2095802, 9304567}, + {20714564, -4336911, 29088195, 7406487, 11426967, -5095705, + 14792667, -14608617, 5289421, -477127}, + {-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, + 17271490, 12349094, 26939669, -3752294}, + }, + { + {-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, + -27283495, -12348559, -3698806, 117887}, + {22263325, -6560050, 3984570, -11174646, -15114008, -566785, + 28311253, 5358056, -23319780, 541964}, + {16259219, 3261970, 2309254, -15534474, -16885711, -4581916, + 24134070, -16705829, -13337066, -13552195}, + }, + { + {9378160, -13140186, -22845982, -12745264, 28198281, -7244098, + -2399684, -717351, 690426, 14876244}, + {24977353, -314384, -8223969, -13465086, 28432343, -1176353, + -13068804, -12297348, -22380984, 6618999}, + {-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, + 8044829, -13817328, 32239829, -5652762}, + }, + { + {-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, + -10350059, 32779359, 5095274}, + {-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, + -24601656, 14506724, 21639561, -2630236}, + {-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, + -1289502, -6863535, 17874574, 558605}, + }, + { + {-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, + 33499487, 5080151, 2085892, 5119761}, + {-22205145, -2519528, -16381601, 414691, -25019550, 2170430, + 30634760, -8363614, -31999993, -5759884}, + {-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, + 27534430, -7192145, -22351378, 12961482}, + }, + { + {-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, + 16533930, 8206996, -30194652, -5159638}, + {-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, + 7031275, 7589640, 8945490}, + {-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, + 7251489, -11182180, 24099109, -14456170}, + }, + { + {5019558, -7907470, 4244127, -14714356, -26933272, 6453165, + -19118182, -13289025, -6231896, -10280736}, + {10853594, 10721687, 26480089, 5861829, -22995819, 1972175, + -1866647, -10557898, -3363451, -6441124}, + {-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, + -2008168, -13866408, 7421392}, + }, + { + {8139927, -6546497, 32257646, -5890546, 30375719, 1886181, + -21175108, 15441252, 28826358, -4123029}, + {6267086, 9695052, 7709135, -16603597, -32869068, -1886135, + 14795160, -7840124, 13746021, -1742048}, + {28584902, 7787108, -6732942, -15050729, 22846041, -7571236, + -3181936, -363524, 4771362, -8419958}, + }, + }, + { + { + {24949256, 6376279, -27466481, -8174608, -18646154, -9930606, + 33543569, -12141695, 3569627, 11342593}, + {26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, + 4608608, 7325975, -14801071}, + {-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, + -27400540, 10258390, -17646694, -8186692}, + }, + { + {11431204, 15823007, 26570245, 14329124, 18029990, 4796082, + -31446179, 15580664, 9280358, -3973687}, + {-160783, -10326257, -22855316, -4304997, -20861367, -13621002, + -32810901, -11181622, -15545091, 4387441}, + {-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, + -24513992, 8548137, 20617071, -7482001}, + }, + { + {-938825, -3930586, -8714311, 16124718, 24603125, -6225393, + -13775352, -11875822, 24345683, 10325460}, + {-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, + 16318175, -1010689, 4766743, 3552007}, + {-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, + 14481909, 10988822, -3994762}, + }, + { + {15564307, -14311570, 3101243, 5684148, 30446780, -8051356, + 12677127, -6505343, -8295852, 13296005}, + {-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, + 31521204, 9614054, -30000824, 12074674}, + {4771191, -135239, 14290749, -13089852, 27992298, 14998318, + -1413936, -1556716, 29832613, -16391035}, + }, + { + {7064884, -7541174, -19161962, -5067537, -18891269, -2912736, + 25825242, 5293297, -27122660, 13101590}, + {-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, + 32512469, -5317593, -30356070, -4190957}, + {-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, + 14413974, 9515896, 19568978, 9628812}, + }, + { + {33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, + -6106839, -6291786, 3437740}, + {-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, + -22961733, 70104, 7463304, 4176122}, + {-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, + -32719404, -5322751, 24216882, 5944158}, + }, + { + {8894125, 7450974, -2664149, -9765752, -28080517, -12389115, + 19345746, 14680796, 11632993, 5847885}, + {26942781, -2315317, 9129564, -4906607, 26024105, 11769399, + -11518837, 6367194, -9727230, 4782140}, + {19916461, -4828410, -22910704, -11414391, 25606324, -5972441, + 33253853, 8220911, 6358847, -1873857}, + }, + { + {801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, + -4480480, -13538503, 1387155}, + {19646058, 5720633, -11416706, 12814209, 11607948, 12749789, + 14147075, 15156355, -21866831, 11835260}, + {19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, + 15467869, -26560550, 5052483}, + }, + }, + { + { + {-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, + -12618185, 12228557, -7003677}, + {32944382, 14922211, -22844894, 5188528, 21913450, -8719943, + 4001465, 13238564, -6114803, 8653815}, + {22865569, -4652735, 27603668, -12545395, 14348958, 8234005, + 24808405, 5719875, 28483275, 2841751}, + }, + { + {-16420968, -1113305, -327719, -12107856, 21886282, -15552774, + -1887966, -315658, 19932058, -12739203}, + {-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, + 3999228, 13239134, -4777469, -13910208}, + {1382174, -11694719, 17266790, 9194690, -13324356, 9720081, + 20403944, 11284705, -14013818, 3093230}, + }, + { + {16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, + 16271225, -24049421, -6691850}, + {-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, + 24123614, 15193618, -21652117, -16739389}, + {-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, + 31870908, 14690798, 17361620, 11864968}, + }, + { + {-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, + -12331205, -7486601, -25578460, -16240689}, + {14668462, -12270235, 26039039, 15305210, 25515617, 4542480, + 10453892, 6577524, 9145645, -6443880}, + {5974874, 3053895, -9433049, -10385191, -31865124, 3225009, + -7972642, 3936128, -5652273, -3050304}, + }, + { + {30625386, -4729400, -25555961, -12792866, -20484575, 7695099, + 17097188, -16303496, -27999779, 1803632}, + {-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, + 14911344, 12196514, -21405489, 7047412}, + {20093277, 9920966, -11138194, -5343857, 13161587, 12044805, + -32856851, 4124601, -32343828, -10257566}, + }, + { + {-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, + 4752377, -8714640, -21679658, 2288038}, + {-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, + 29457502, 14625692, -24819617, 12570232}, + {-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, + -21159943, -3498680, -11974704, 4724943}, + }, + { + {17960970, -11775534, -4140968, -9702530, -8876562, -1410617, + -12907383, -8659932, -29576300, 1903856}, + {23134274, -14279132, -10681997, -1611936, 20684485, 15770816, + -12989750, 3190296, 26955097, 14109738}, + {15308788, 5320727, -30113809, -14318877, 22902008, 7767164, + 29425325, -11277562, 31960942, 11934971}, + }, + { + {-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, + 20638173, 4875028, 10491392, 1379718}, + {-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, + 33518459, 16176658, 21432314, 12180697}, + {-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, + 1465425, 12689540, -10301319, -13872883}, + }, + }, + { + { + {5414091, -15386041, -21007664, 9643570, 12834970, 1186149, + -2622916, -1342231, 26128231, 6032912}, + {-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, + 3604025, 8316894, -25875034, -10437358}, + {3296484, 6223048, 24680646, -12246460, -23052020, 5903205, + -8862297, -4639164, 12376617, 3188849}, + }, + { + {29190488, -14659046, 27549113, -1183516, 3520066, -10697301, + 32049515, -7309113, -16109234, -9852307}, + {-14744486, -9309156, 735818, -598978, -20407687, -5057904, + 25246078, -15795669, 18640741, -960977}, + {-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, + -31638386, -494430, 10530747, 1053335}, + }, + { + {-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, + -31462369, -2948985, 24018831, 15026644}, + {-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, + 25310643, 13003497, -2314791, -15145616}, + {-27419985, -603321, -8043984, -1669117, -26092265, 13987819, + -27297622, 187899, -23166419, -2531735}, + }, + { + {-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, + 9716667, 16266922, -5070217, 726099}, + {29370922, -6053998, 7334071, -15342259, 9385287, 2247707, + -13661962, -4839461, 30007388, -15823341}, + {-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, + 730663, 9835848, 4555336}, + }, + { + {-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, + 17693930, 544696, -11985298, 12422646}, + {31117226, -12215734, -13502838, 6561947, -9876867, -12757670, + -5118685, -4096706, 29120153, 13924425}, + {-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, + -9383939, -11317700, 7240931, -237388}, + }, + { + {-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, + 1222336, 4389483, 3293637, -15551743}, + {-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, + -24319580, 7733547, 12796905, -6335822}, + {-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, + -28253339, 3647836, 3222231, -11160462}, + }, + { + {18606113, 1693100, -25448386, -15170272, 4112353, 10045021, + 23603893, -2048234, -7550776, 2484985}, + {9255317, -3131197, -12156162, -1004256, 13098013, -9214866, + 16377220, -2102812, -19802075, -3034702}, + {-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, + -31718148, 9936966, -30097688, -10618797}, + }, + { + {21878590, -5001297, 4338336, 13643897, -3036865, 13160960, + 19708896, 5415497, -7360503, -4109293}, + {27736861, 10103576, 12500508, 8502413, -3413016, -9633558, + 10436918, -1550276, -23659143, -8132100}, + {19492550, -12104365, -29681976, -852630, -3208171, 12403437, + 30066266, 8367329, 13243957, 8709688}, + }, + }, + { + { + {12015105, 2801261, 28198131, 10151021, 24818120, -4743133, + -11194191, -5645734, 5150968, 7274186}, + {2831366, -12492146, 1478975, 6122054, 23825128, -12733586, + 31097299, 6083058, 31021603, -9793610}, + {-2529932, -2229646, 445613, 10720828, -13849527, -11505937, + -23507731, 16354465, 15067285, -14147707}, + }, + { + {7840942, 14037873, -33364863, 15934016, -728213, -3642706, + 21403988, 1057586, -19379462, -12403220}, + {915865, -16469274, 15608285, -8789130, -24357026, 6060030, + -17371319, 8410997, -7220461, 16527025}, + {32922597, -556987, 20336074, -16184568, 10903705, -5384487, + 16957574, 52992, 23834301, 6588044}, + }, + { + {32752030, 11232950, 3381995, -8714866, 22652988, -10744103, + 17159699, 16689107, -20314580, -1305992}, + {-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, + 7924251, -2752281, 1976123, -7249027}, + {21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, + -3371252, 12331345, -8237197}, + }, + { + {8651614, -4477032, -16085636, -4996994, 13002507, 2950805, + 29054427, -5106970, 10008136, -4667901}, + {31486080, 15114593, -14261250, 12951354, 14369431, -7387845, + 16347321, -13662089, 8684155, -10532952}, + {19443825, 11385320, 24468943, -9659068, -23919258, 2187569, + -26263207, -6086921, 31316348, 14219878}, + }, + { + {-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, + 27146014, 6992409, 29126555, 9207390}, + {32382935, 1110093, 18477781, 11028262, -27411763, -7548111, + -4980517, 10843782, -7957600, -14435730}, + {2814918, 7836403, 27519878, -7868156, -20894015, -11553689, + -21494559, 8550130, 28346258, 1994730}, + }, + { + {-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, + -19516951, 7174894, 22628102, 8115180}, + {-30405132, 955511, -11133838, -15078069, -32447087, -13278079, + -25651578, 3317160, -9943017, 930272}, + {-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, + 24091212, -1388970, -22765376, -10650715}, + }, + { + {-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, + -14839018, -16554220, -1867018, 8398970}, + {-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, + 22981545, -6291273, 18009408, -15772772}, + {-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, + 29551787, -3727419, 19288549, 1325865}, + }, + { + {15100157, -15835752, -23923978, -1005098, -26450192, 15509408, + 12376730, -3479146, 33166107, -8042750}, + {20909231, 13023121, -9209752, 16251778, -5778415, -8094914, + 12412151, 10018715, 2213263, -13878373}, + {32529814, -11074689, 30361439, -16689753, -9135940, 1513226, + 22922121, 6382134, -5766928, 8371348}, + }, + }, + { + { + {9923462, 11271500, 12616794, 3544722, -29998368, -1721626, + 12891687, -8193132, -26442943, 10486144}, + {-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, + 2610596, -23921530, -11455195}, + {5408411, -1136691, -4969122, 10561668, 24145918, 14240566, + 31319731, -4235541, 19985175, -3436086}, + }, + { + {-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, + -17577068, 8849297, 65030, 8370684}, + {-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, + -19442942, 6922164, 12743482, -9800518}, + {-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, + 23783145, 11038569, 18800704, 255233}, + }, + { + {-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, + 9066957, 19258688, -14753793}, + {-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, + -31934921, 2209390, -1524053, 2055794}, + {580882, 16705327, 5468415, -2683018, -30926419, -14696000, + -7203346, -8994389, -30021019, 7394435}, + }, + { + {23838809, 1822728, -15738443, 15242727, 8318092, -3733104, + -21672180, -3492205, -4821741, 14799921}, + {13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, + 13496856, -9056018, 7402518}, + {2286874, -4435931, -20042458, -2008336, -13696227, 5038122, + 11006906, -15760352, 8205061, 1607563}, + }, + { + {14414086, -8002132, 3331830, -3208217, 22249151, -5594188, + 18364661, -2906958, 30019587, -9029278}, + {-27688051, 1585953, -10775053, 931069, -29120221, -11002319, + -14410829, 12029093, 9944378, 8024}, + {4368715, -3709630, 29874200, -15022983, -20230386, -11410704, + -16114594, -999085, -8142388, 5640030}, + }, + { + {10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, + -16694564, 15219798, -14327783}, + {27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, + -1173195, -18342183, 9742717}, + {6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, + 7406442, 12420155, 1994844}, + }, + { + {14012521, -5024720, -18384453, -9578469, -26485342, -3936439, + -13033478, -10909803, 24319929, -6446333}, + {16412690, -4507367, 10772641, 15929391, -17068788, -4658621, + 10555945, -10484049, -30102368, -4739048}, + {22397382, -7767684, -9293161, -12792868, 17166287, -9755136, + -27333065, 6199366, 21880021, -12250760}, + }, + { + {-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, + 16557151, 8890729, 8840445, 4957760}, + {-15447727, 709327, -6919446, -10870178, -29777922, 6522332, + -21720181, 12130072, -14796503, 5005757}, + {-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, + 10183197, -13239326, -16395286, -2176112}, + }, + }, + { + { + {-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, + -32013908, -3057104, 22208662, 2000468}, + {3065073, -1412761, -25598674, -361432, -17683065, -5703415, + -8164212, 11248527, -3691214, -7414184}, + {10379208, -6045554, 8877319, 1473647, -29291284, -12507580, + 16690915, 2553332, -3132688, 16400289}, + }, + { + {15716668, 1254266, -18472690, 7446274, -8448918, 6344164, + -22097271, -7285580, 26894937, 9132066}, + {24158887, 12938817, 11085297, -8177598, -28063478, -4457083, + -30576463, 64452, -6817084, -2692882}, + {13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, + -3418511, -4688006, 2364226}, + }, + { + {16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, + -11697457, 15445875, -7798101}, + {29004207, -7867081, 28661402, -640412, -12794003, -7943086, + 31863255, -4135540, -278050, -15759279}, + {-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, + 10343412, -6976290, -29828287, -10815811}, + }, + { + {27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, + 15372179, 17293797, 960709}, + {20263915, 11434237, -5765435, 11236810, 13505955, -10857102, + -16111345, 6493122, -19384511, 7639714}, + {-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, + 18006287, -16043750, 29994677, -15808121}, + }, + { + {9769828, 5202651, -24157398, -13631392, -28051003, -11561624, + -24613141, -13860782, -31184575, 709464}, + {12286395, 13076066, -21775189, -1176622, -25003198, 4057652, + -32018128, -8890874, 16102007, 13205847}, + {13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, + 8525972, 10151379, 10394400}, + }, + { + {4024660, -16137551, 22436262, 12276534, -9099015, -2686099, + 19698229, 11743039, -33302334, 8934414}, + {-15879800, -4525240, -8580747, -2934061, 14634845, -698278, + -9449077, 3137094, -11536886, 11721158}, + {17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, + 8835153, -9205489, -1280045}, + }, + { + {-461409, -7830014, 20614118, 16688288, -7514766, -4807119, + 22300304, 505429, 6108462, -6183415}, + {-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, + 29880583, -13483331, -26898490, -7867459}, + {-31975283, 5726539, 26934134, 10237677, -3173717, -605053, + 24199304, 3795095, 7592688, -14992079}, + }, + { + {21594432, -14964228, 17466408, -4077222, 32537084, 2739898, + 6407723, 12018833, -28256052, 4298412}, + {-20650503, -11961496, -27236275, 570498, 3767144, -1717540, + 13891942, -1569194, 13717174, 10805743}, + {-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, + -796431, 14860609, -26938930, -5863836}, + }, + }, + { + { + {12962541, 5311799, -10060768, 11658280, 18855286, -7954201, + 13286263, -12808704, -4381056, 9882022}, + {18512079, 11319350, -20123124, 15090309, 18818594, 5271736, + -22727904, 3666879, -23967430, -3299429}, + {-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, + -10084880, -6661110, -2403099, 5276065}, + }, + { + {30169808, -5317648, 26306206, -11750859, 27814964, 7069267, + 7152851, 3684982, 1449224, 13082861}, + {10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, + 15056736, -21016438, -8202000}, + {-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, + -26171976, 6482814, -10300080, -11060101}, + }, + { + {32869458, -5408545, 25609743, 15678670, -10687769, -15471071, + 26112421, 2521008, -22664288, 6904815}, + {29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, + 3841096, -29003639, -6657642}, + {10340844, -6630377, -18656632, -2278430, 12621151, -13339055, + 30878497, -11824370, -25584551, 5181966}, + }, + { + {25940115, -12658025, 17324188, -10307374, -8671468, 15029094, + 24396252, -16450922, -2322852, -12388574}, + {-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, + 12641087, 20603771, -6561742}, + {-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, + 1925523, 11914390, 4662781, 7820689}, + }, + { + {12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, + 12172924, 16136752, 15264020}, + {-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, + 10658213, 6671822, 19012087, 3772772}, + {3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, + -15762884, 20527771, 12988982}, + }, + { + {-14822485, -5797269, -3707987, 12689773, -898983, -10914866, + -24183046, -10564943, 3299665, -12424953}, + {-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, + 6461331, -25583147, 8991218}, + {-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, + -32948145, 7417950, -30242287, 1507265}, + }, + { + {29692663, 6829891, -10498800, 4334896, 20945975, -11906496, + -28887608, 8209391, 14606362, -10647073}, + {-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, + 9761487, 4170404, -2085325}, + {-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, + 22186522, 16002000, -14276837, -8400798}, + }, + { + {-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, + -7113572, -9620092, 13240845, 10965870}, + {-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, + 4498947, 14147411, 29514390, 4302863}, + {-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, + -5061276, -2144373, 17846988, -13971927}, + }, + }, + { + { + {-2244452, -754728, -4597030, -1066309, -6247172, 1455299, + -21647728, -9214789, -5222701, 12650267}, + {-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, + 13770293, -19134326, 10958663}, + {22470984, 12369526, 23446014, -5441109, -21520802, -9698723, + -11772496, -11574455, -25083830, 4271862}, + }, + { + {-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, + 75375, -4278529, -32526221, 8469673}, + {15854970, 4148314, -8893890, 7259002, 11666551, 13824734, + -30531198, 2697372, 24154791, -9460943}, + {15446137, -15806644, 29759747, 14019369, 30811221, -9610191, + -31582008, 12840104, 24913809, 9815020}, + }, + { + {-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, + -9103676, 13438769, 18735128, 9466238}, + {11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, + -10896103, -22728655, 16199064}, + {14576810, 379472, -26786533, -8317236, -29426508, -10812974, + -102766, 1876699, 30801119, 2164795}, + }, + { + {15995086, 3199873, 13672555, 13712240, -19378835, -4647646, + -13081610, -15496269, -13492807, 1268052}, + {-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, + -3470338, -12600221, -17055369, 3565904}, + {29210088, -9419337, -5919792, -4952785, 10834811, -13327726, + -16512102, -10820713, -27162222, -14030531}, + }, + { + {-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, + -29183421, -3769423, 2244111, -14001979}, + {-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, + -25673088, -16180800, 13491506, 4641841}, + {10813417, 643330, -19188515, -728916, 30292062, -16600078, + 27548447, -7721242, 14476989, -12767431}, + }, + { + {10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, + -1644259, -27912810, 12651324}, + {-31185513, -813383, 22271204, 11835308, 10201545, 15351028, + 17099662, 3988035, 21721536, -3148940}, + {10202177, -6545839, -31373232, -9574638, -32150642, -8119683, + -12906320, 3852694, 13216206, 14842320}, + }, + { + {-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, + -31500847, 13765824, -27434397, 9900184}, + {14465505, -13833331, -32133984, -14738873, -27443187, 12990492, + 33046193, 15796406, -7051866, -8040114}, + {30924417, -8279620, 6359016, -12816335, 16508377, 9071735, + -25488601, 15413635, 9524356, -7018878}, + }, + { + {12274201, -13175547, 32627641, -1785326, 6736625, 13267305, + 5237659, -5109483, 15663516, 4035784}, + {-2951309, 8903985, 17349946, 601635, -16432815, -4612556, + -13732739, -15889334, -22258478, 4659091}, + {-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, + 5736189, 15026997, -2178256, -13455585}, + }, + }, + { + { + {-8858980, -2219056, 28571666, -10155518, -474467, -10105698, + -3801496, 278095, 23440562, -290208}, + {10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, + 11551483, -16571960, -7442864}, + {17932739, -12437276, -24039557, 10749060, 11316803, 7535897, + 22503767, 5561594, -3646624, 3898661}, + }, + { + {7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, + 7152530, 21831162, 1245233}, + {26958459, -14658026, 4314586, 8346991, -5677764, 11960072, + -32589295, -620035, -30402091, -16716212}, + {-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, + 6280834, 14587357, -22338025, 13987525}, + }, + { + {-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, + -4300898, -5124639, -7469781, -2858068}, + {9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, + 6439245, -14581012, 4091397}, + {-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, + -19622683, 12092163, 29077877, -14741988}, + }, + { + {5269168, -6859726, -13230211, -8020715, 25932563, 1763552, + -5606110, -5505881, -20017847, 2357889}, + {32264008, -15407652, -5387735, -1160093, -2091322, -3946900, + 23104804, -12869908, 5727338, 189038}, + {14609123, -8954470, -6000566, -16622781, -14577387, -7743898, + -26745169, 10942115, -25888931, -14884697}, + }, + { + {20513500, 5557931, -15604613, 7829531, 26413943, -2019404, + -21378968, 7471781, 13913677, -5137875}, + {-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, + -8940970, 14059180, 12878652, 8511905}, + {-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, + -30223418, 6812974, 5568676, -3127656}, + }, + { + {11630004, 12144454, 2116339, 13606037, 27378885, 15676917, + -17408753, -13504373, -14395196, 8070818}, + {27117696, -10007378, -31282771, -5570088, 1127282, 12772488, + -29845906, 10483306, -11552749, -1028714}, + {10637467, -5688064, 5674781, 1072708, -26343588, -6982302, + -1683975, 9177853, -27493162, 15431203}, + }, + { + {20525145, 10892566, -12742472, 12779443, -29493034, 16150075, + -28240519, 14943142, -15056790, -7935931}, + {-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, + -3239766, -3356550, 9594024}, + {-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, + -6492290, 13352335, -10977084}, + }, + { + {-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, + -29783850, -7752482, -13215537, -319204}, + {20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, + 15077870, -22750759, 14523817}, + {27406042, -6041657, 27423596, -4497394, 4996214, 10002360, + -28842031, -4545494, -30172742, -4805667}, + }, + }, + { + { + {11374242, 12660715, 17861383, -12540833, 10935568, 1099227, + -13886076, -9091740, -27727044, 11358504}, + {-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, + 32676003, 11149336, -26123651, 4985768}, + {-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, + 13794114, -19414307, -15621255}, + }, + { + {6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, + 6970005, -1691065, -9004790}, + {1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, + -5475723, -16796596, -5031438}, + {-22273315, -13524424, -64685, -4334223, -18605636, -10921968, + -20571065, -7007978, -99853, -10237333}, + }, + { + {17747465, 10039260, 19368299, -4050591, -20630635, -16041286, + 31992683, -15857976, -29260363, -5511971}, + {31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, + -3744247, 4882242, -10626905}, + {29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, + 3272828, -5190932, -4162409}, + }, + { + {12501286, 4044383, -8612957, -13392385, -32430052, 5136599, + -19230378, -3529697, 330070, -3659409}, + {6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, + -8573892, -271295, 12071499}, + {-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, + -32769618, 1936675, -5159697, 3829363}, + }, + { + {28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, + -6567787, 26333140, 14267664}, + {-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, + 10004786, -8709488, -21761224, 8930324}, + {-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, + 1541940, 4757911, -26491501, -16408940}, + }, + { + {13537262, -7759490, -20604840, 10961927, -5922820, -13218065, + -13156584, 6217254, -15943699, 13814990}, + {-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, + 9257833, -1956526, -1776914}, + {-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, + -29171540, 12361135, -18685978, 4578290}, + }, + { + {24579768, 3711570, 1342322, -11180126, -27005135, 14124956, + -22544529, 14074919, 21964432, 8235257}, + {-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, + -2981514, -1669206, 13006806, 2355433}, + {-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, + 27202044, 1719366, 1141648, -12796236}, + }, + { + {-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, + 13475066, -3133972, 32674895, 13715045}, + {11423335, -5468059, 32344216, 8962751, 24989809, 9241752, + -13265253, 16086212, -28740881, -15642093}, + {-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, + -11709148, 7791794, -27245943, 4383347}, + }, + }, + { + { + {-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, + -4862407, -4906449, 27193557, 6245191}, + {-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, + 3260492, 22510453, 8577507}, + {-12632451, 11257346, -32692994, 13548177, -721004, 10879011, + 31168030, 13952092, -29571492, -3635906}, + }, + { + {3877321, -9572739, 32416692, 5405324, -11004407, -13656635, + 3759769, 11935320, 5611860, 8164018}, + {-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, + 32003002, -8832289, 5773085, -8422109}, + {-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, + 12376320, 31632953, 190926}, + }, + { + {-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, + -8288749, 4508564, -25341555, -3627528}, + {8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, + -14786005, -1672488, 827625}, + {-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, + -1800575, -14108036, -24878478, 1541286}, + }, + { + {2901347, -1117687, 3880376, -10059388, -17620940, -3612781, + -21802117, -3567481, 20456845, -1885033}, + {27019610, 12299467, -13658288, -1603234, -12861660, -4861471, + -19540150, -5016058, 29439641, 15138866}, + {21536104, -6626420, -32447818, -10690208, -22408077, 5175814, + -5420040, -16361163, 7779328, 109896}, + }, + { + {30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, + 12180118, 23177719, -554075}, + {26572847, 3405927, -31701700, 12890905, -19265668, 5335866, + -6493768, 2378492, 4439158, -13279347}, + {-22716706, 3489070, -9225266, -332753, 18875722, -1140095, + 14819434, -12731527, -17717757, -5461437}, + }, + { + {-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, + -820954, 2177225, 8550082, -15114165}, + {-18473302, 16596775, -381660, 15663611, 22860960, 15585581, + -27844109, -3582739, -23260460, -8428588}, + {-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, + -22725137, 15860482, -21902570, 1494193}, + }, + { + {-19562091, -14087393, -25583872, -9299552, 13127842, 759709, + 21923482, 16529112, 8742704, 12967017}, + {-28464899, 1553205, 32536856, -10473729, -24691605, -406174, + -8914625, -2933896, -29903758, 15553883}, + {21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, + 14513274, 19375923, -12647961}, + }, + { + {8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, + -6222716, 2862653, 9455043}, + {29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, + -2990080, 15511449, 4789663}, + {-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, + -5754762, 108893, 23513200, 16652362}, + }, + }, + { + { + {-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, + -6650416, -12936300, -18319198, 10212860}, + {2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, + 2600940, -9988298, -12506466}, + {-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, + 11344424, 864440, -2499677, -16710063}, + }, + { + {-26432803, 6148329, -17184412, -14474154, 18782929, -275997, + -22561534, 211300, 2719757, 4940997}, + {-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, + 21690126, 8518463, 26699843, 5276295}, + {-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, + 149635, -15452774, 7159369}, + }, + { + {9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, + 8312176, 22477218, -8403385}, + {18155857, -16504990, 19744716, 9006923, 15154154, -10538976, + 24256460, -4864995, -22548173, 9334109}, + {2986088, -4911893, 10776628, -3473844, 10620590, -7083203, + -21413845, 14253545, -22587149, 536906}, + }, + { + {4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, + 10589625, 10838060, -15420424}, + {-19342404, 867880, 9277171, -3218459, -14431572, -1986443, + 19295826, -15796950, 6378260, 699185}, + {7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, + 15693155, -5045064, -13373962}, + }, + { + {-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, + 31730678, -10962840, -3918636, -9669325}, + {10188286, -15770834, -7336361, 13427543, 22223443, 14896287, + 30743455, 7116568, -21786507, 5427593}, + {696102, 13206899, 27047647, -10632082, 15285305, -9853179, + 10798490, -4578720, 19236243, 12477404}, + }, + { + {-11229439, 11243796, -17054270, -8040865, -788228, -8167967, + -3897669, 11180504, -23169516, 7733644}, + {17800790, -14036179, -27000429, -11766671, 23887827, 3149671, + 23466177, -10538171, 10322027, 15313801}, + {26246234, 11968874, 32263343, -5468728, 6830755, -13323031, + -15794704, -101982, -24449242, 10890804}, + }, + { + {-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, + -14982212, 16484931, 25180797, -5334884}, + {-586574, 10376444, -32586414, -11286356, 19801893, 10997610, + 2276632, 9482883, 316878, 13820577}, + {-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, + 30756178, -7515054, 30696930, -3712849}, + }, + { + {32988917, -9603412, 12499366, 7910787, -10617257, -11931514, + -7342816, -9985397, -32349517, 7392473}, + {-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, + -30409476, -9134995, 25112947, -2926644}, + {-2504044, -436966, 25621774, -5678772, 15085042, -5479877, + -24884878, -13526194, 5537438, -13914319}, + }, + }, + { + { + {-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, + -14876251, -1729667, 31234590, 6090599}, + {-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, + 15878753, -6970405, -9034768}, + {-27757857, 247744, -15194774, -9002551, 23288161, -10011936, + -23869595, 6503646, 20650474, 1804084}, + }, + { + {-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, + -10329713, 27842616, -202328}, + {-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, + 5031932, -11375082, 12714369}, + {20807691, -7270825, 29286141, 11421711, -27876523, -13868230, + -21227475, 1035546, -19733229, 12796920}, + }, + { + {12076899, -14301286, -8785001, -11848922, -25012791, 16400684, + -17591495, -12899438, 3480665, -15182815}, + {-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, + -24363064, -15921875, -33374054, 2771025}, + {-21389266, 421932, 26597266, 6860826, 22486084, -6737172, + -17137485, -4210226, -24552282, 15673397}, + }, + { + {-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, + -20271184, 4733254, 3727144, -12934448}, + {6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, + 7975683, 31123697, -10958981}, + {30069250, -11435332, 30434654, 2958439, 18399564, -976289, + 12296869, 9204260, -16432438, 9648165}, + }, + { + {32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, + 5248604, -26008332, -11377501}, + {17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, + 15298639, 2662509, -16297073}, + {-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, + 32087529, -1222777, 32247248, -14389861}, + }, + { + {14312628, 1221556, 17395390, -8700143, -4945741, -8684635, + -28197744, -9637817, -16027623, -13378845}, + {-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, + 9803137, 17597934, 2346211}, + {18510800, 15337574, 26171504, 981392, -22241552, 7827556, + -23491134, -11323352, 3059833, -11782870}, + }, + { + {10141598, 6082907, 17829293, -1947643, 9830092, 13613136, + -25556636, -5544586, -33502212, 3592096}, + {33114168, -15889352, -26525686, -13343397, 33076705, 8716171, + 1151462, 1521897, -982665, -6837803}, + {-32939165, -4255815, 23947181, -324178, -33072974, -12305637, + -16637686, 3891704, 26353178, 693168}, + }, + { + {30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, + -400668, 31375464, 14369965}, + {-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, + 32732230, -13108839, 17901441, 16011505}, + {18171223, -11934626, -12500402, 15197122, -11038147, -15230035, + -19172240, -16046376, 8764035, 12309598}, + }, + }, + { + { + {5975908, -5243188, -19459362, -9681747, -11541277, 14015782, + -23665757, 1228319, 17544096, -10593782}, + {5811932, -1715293, 3442887, -2269310, -18367348, -8359541, + -18044043, -15410127, -5565381, 12348900}, + {-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, + -24849353, 8141295, -10632534, -585479}, + }, + { + {-12675304, 694026, -5076145, 13300344, 14015258, -14451394, + -9698672, -11329050, 30944593, 1130208}, + {8247766, -6710942, -26562381, -7709309, -14401939, -14648910, + 4652152, 2488540, 23550156, -271232}, + {17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, + -5908146, -408818, -137719}, + }, + { + {16091085, -16253926, 18599252, 7340678, 2137637, -1221657, + -3364161, 14550936, 3260525, -7166271}, + {-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, + -23028869, -13204905, -12748722, 2701326}, + {-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, + -10018363, 9276971, 11329923, 1862132}, + }, + { + {14763076, -15903608, -30918270, 3689867, 3511892, 10313526, + -21951088, 12219231, -9037963, -940300}, + {8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, + -2909717, -15438168, 11595570}, + {15214962, 3537601, -26238722, -14058872, 4418657, -15230761, + 13947276, 10730794, -13489462, -4363670}, + }, + { + {-2538306, 7682793, 32759013, 263109, -29984731, -7955452, + -22332124, -10188635, 977108, 699994}, + {-12466472, 4195084, -9211532, 550904, -15565337, 12917920, + 19118110, -439841, -30534533, -14337913}, + {31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, + -10051775, 12493932, -5409317}, + }, + { + {-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, + 27218280, 2607121, 29375955, 6024730}, + {842132, -2794693, -4763381, -8722815, 26332018, -12405641, + 11831880, 6985184, -9940361, 2854096}, + {-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, + 960770, 12121869, 16648078}, + }, + { + {-15218652, 14667096, -13336229, 2013717, 30598287, -464137, + -31504922, -7882064, 20237806, 2838411}, + {-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, + 12544294, -13470457, 1068881, -12499905}, + {-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, + -8486907, -2630053, 12521378, 4845654}, + }, + { + {-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, + 3409348, -873400, -6482306, -12885870}, + {-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, + 10477734, -1240216, -3113227, 13974498}, + {12966261, 15550616, -32038948, -1615346, 21025980, -629444, + 5642325, 7188737, 18895762, 12629579}, + }, + }, + { + { + {14741879, -14946887, 22177208, -11721237, 1279741, 8058600, + 11758140, 789443, 32195181, 3895677}, + {10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, + -3566119, -8982069, 4429647}, + {-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, + -7135870, -11642895, 18047436, -15281743}, + }, + { + {-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, + 10993114, -12850837, -17620701, -9408468}, + {21987233, 700364, -24505048, 14972008, -7774265, -5718395, + 32155026, 2581431, -29958985, 8773375}, + {-25568350, 454463, -13211935, 16126715, 25240068, 8594567, + 20656846, 12017935, -7874389, -13920155}, + }, + { + {6028182, 6263078, -31011806, -11301710, -818919, 2461772, + -31841174, -5468042, -1721788, -2776725}, + {-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, + -4166698, 28408820, 6816612}, + {-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, + 20613181, 13982702, -10339570, 5067943}, + }, + { + {-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, + -19719286, 12746132, 5331210, -10105944}, + {30528811, 3601899, -1957090, 4619785, -27361822, -15436388, + 24180793, -12570394, 27679908, -1648928}, + {9402404, -13957065, 32834043, 10838634, -26580150, -13237195, + 26653274, -8685565, 22611444, -12715406}, + }, + { + {22190590, 1118029, 22736441, 15130463, -30460692, -5991321, + 19189625, -4648942, 4854859, 6622139}, + {-8310738, -2953450, -8262579, -3388049, -10401731, -271929, + 13424426, -3567227, 26404409, 13001963}, + {-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, + -26064365, -11621720, -15405155, 11020693}, + }, + { + {1866042, -7949489, -7898649, -10301010, 12483315, 13477547, + 3175636, -12424163, 28761762, 1406734}, + {-448555, -1777666, 13018551, 3194501, -9580420, -11161737, + 24760585, -4347088, 25577411, -13378680}, + {-24290378, 4759345, -690653, -1852816, 2066747, 10693769, + -29595790, 9884936, -9368926, 4745410}, + }, + { + {-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, + -15462008, -11311852, 10931924, -11931931}, + {-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, + -22853429, 10856641, -20470770, 13434654}, + {22759489, -10073434, -16766264, -1871422, 13637442, -10168091, + 1765144, -12654326, 28445307, -5364710}, + }, + { + {29875063, 12493613, 2795536, -3786330, 1710620, 15181182, + -10195717, -8788675, 9074234, 1167180}, + {-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, + -18716888, -9535498, 3843903, 9367684}, + {-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, + 8601684, -139197, 4242895}, + }, + }, + { + { + {22092954, -13191123, -2042793, -11968512, 32186753, -11517388, + -6574341, 2470660, -27417366, 16625501}, + {-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, + 2602725, -27351616, 14247413}, + {6314175, -10264892, -32772502, 15957557, -10157730, 168750, + -8618807, 14290061, 27108877, -1180880}, + }, + { + {-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, + 33547976, -11058889, -27148451, 981874}, + {22833440, 9293594, -32649448, -13618667, -9136966, 14756819, + -22928859, -13970780, -10479804, -16197962}, + {-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, + 22680049, 13906969, -15933690, 3797899}, + }, + { + {21721356, -4212746, -12206123, 9310182, -3882239, -13653110, + 23740224, -2709232, 20491983, -8042152}, + {9209270, -15135055, -13256557, -6167798, -731016, 15289673, + 25947805, 15286587, 30997318, -6703063}, + {7392032, 16618386, 23946583, -8039892, -13265164, -1533858, + -14197445, -2321576, 17649998, -250080}, + }, + { + {-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, + -15241566, -9525724, -2233253, 7662146}, + {-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, + 7335080, -8472199, -3174674, 3440183}, + {-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, + 40450, -4431835, 4862400, 1133}, + }, + { + {-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, + 7258061, 311861, -30594991, -7379421}, + {-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, + 16527196, 18278453, 15405622}, + {-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, + -13313598, 843523, -21875062, 13626197}, + }, + { + {2281448, -13487055, -10915418, -2609910, 1879358, 16164207, + -10783882, 3953792, 13340839, 15928663}, + {31727126, -7179855, -18437503, -8283652, 2875793, -16390330, + -25269894, -7014826, -23452306, 5964753}, + {4100420, -5959452, -17179337, 6017714, -18705837, 12227141, + -26684835, 11344144, 2538215, -7570755}, + }, + { + {-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, + -20474983, 1485421, -629256, -15958862}, + {-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, + -20205425, -13191288, 11659922, -11115118}, + {26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, + -10170080, 33100372, -1306171}, + }, + { + {15121113, -5201871, -10389905, 15427821, -27509937, -15992507, + 21670947, 4486675, -5931810, -14466380}, + {16166486, -9483733, -11104130, 6023908, -31926798, -1364923, + 2340060, -16254968, -10735770, -10039824}, + {28042865, -3557089, -12126526, 12259706, -3717498, -6945899, + 6766453, -8689599, 18036436, 5803270}, + }, + }, + { + { + {-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, + 4598332, -6159431, -14117438}, + {-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, + 696309, 50292, -20095739, 11763584}, + {-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, + -12613632, -19773211, -10713562}, + }, + { + {30464590, -11262872, -4127476, -12734478, 19835327, -7105613, + -24396175, 2075773, -17020157, 992471}, + {18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, + 8080033, -11574335, -10601610}, + {19598397, 10334610, 12555054, 2555664, 18821899, -10339780, + 21873263, 16014234, 26224780, 16452269}, + }, + { + {-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, + -7618186, -20533829, 3698650}, + {14187449, 3448569, -10636236, -10810935, -22663880, -3433596, + 7268410, -10890444, 27394301, 12015369}, + {19695761, 16087646, 28032085, 12999827, 6817792, 11427614, + 20244189, -1312777, -13259127, -3402461}, + }, + { + {30860103, 12735208, -1888245, -4699734, -16974906, 2256940, + -8166013, 12298312, -8550524, -10393462}, + {-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, + -5789354, -15118654, -4976164, 12651793}, + {-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, + -13118820, -16517902, 9768698, -2533218}, + }, + { + {-24719459, 1894651, -287698, -4704085, 15348719, -8156530, + 32767513, 12765450, 4940095, 10678226}, + {18860224, 15980149, -18987240, -1562570, -26233012, -11071856, + -7843882, 13944024, -24372348, 16582019}, + {-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, + -11704054, 15444560, -11003761, 7989037}, + }, + { + {31490452, 5568061, -2412803, 2182383, -32336847, 4531686, + -32078269, 6200206, -19686113, -14800171}, + {-17308668, -15879940, -31522777, -2831, -32887382, 16375549, + 8680158, -16371713, 28550068, -6857132}, + {-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, + -30039981, 4364038, 1155602, 5988841}, + }, + { + {21890435, -13272907, -12624011, 12154349, -7831873, 15300496, + 23148983, -4470481, 24618407, 8283181}, + {-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, + 3070187, -7025928, 1466169, 10740210}, + {-1509399, -15488185, -13503385, -10655916, 32799044, 909394, + -13938903, -5779719, -32164649, -15327040}, + }, + { + {3960823, -14267803, -28026090, -15918051, -19404858, 13146868, + 15567327, 951507, -3260321, -573935}, + {24740841, 5052253, -30094131, 8961361, 25877428, 6165135, + -24368180, 14397372, -7380369, -6144105}, + {-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, + -15441463, -14453128, -1625486, -6494814}, + }, + }, + { + { + {793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, + -4885251, -9906200, -621852}, + {5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, + 1468826, -6171428, -15186581}, + {-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, + -30404353, -9871238, -1558923, -9863646}, + }, + { + {10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, + 14783338, -30581476, -15757844}, + {10566929, 12612572, -31944212, 11118703, -12633376, 12362879, + 21752402, 8822496, 24003793, 14264025}, + {27713862, -7355973, -11008240, 9227530, 27050101, 2504721, + 23886875, -13117525, 13958495, -5732453}, + }, + { + {-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, + -31889399, -10041781, 7340521, -15410068}, + {4646514, -8011124, -22766023, -11532654, 23184553, 8566613, + 31366726, -1381061, -15066784, -10375192}, + {-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, + 27584817, 3093888, -8843694, 3849921}, + }, + { + {-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, + 32477045, -9017955, 5002294, -15550259}, + {-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, + 16489530, 13378448, -25845716, 12741426}, + {-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, + 24306472, 15852464, 28834118, -7646072}, + }, + { + {-17335748, -9107057, -24531279, 9434953, -8472084, -583362, + -13090771, 455841, 20461858, 5491305}, + {13669248, -16095482, -12481974, -10203039, -14569770, -11893198, + -24995986, 11293807, -28588204, -9421832}, + {28497928, 6272777, -33022994, 14470570, 8906179, -1225630, + 18504674, -14165166, 29867745, -8795943}, + }, + { + {-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, + -6367600, -13175392, 22853429, -4012011}, + {24191378, 16712145, -13931797, 15217831, 14542237, 1646131, + 18603514, -11037887, 12876623, -2112447}, + {17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, + 608397, 16031844, 3723494}, + }, + { + {-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, + 17558842, -7872890, 23896954, -4314245}, + {-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, + 7229064, -9919646, -8826859}, + {28816045, 298879, -28165016, -15920938, 19000928, -1665890, + -12680833, -2949325, -18051778, -2082915}, + }, + { + {16000882, -344896, 3493092, -11447198, -29504595, -13159789, + 12577740, 16041268, -19715240, 7847707}, + {10151868, 10572098, 27312476, 7922682, 14825339, 4723128, + -32855931, -6519018, -10020567, 3852848}, + {-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, + 16514493, -15932110, 29330899, -15076224}, + }, + }, + { + { + {-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, + 3303702, 15490, -27548796, 12314391}, + {15683520, -6003043, 18109120, -9980648, 15337968, -5997823, + -16717435, 15921866, 16103996, -3731215}, + {-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, + -19273607, 5402699, -29815713, -9841101}, + }, + { + {23190676, 2384583, -32714340, 3462154, -29903655, -1529132, + -11266856, 8911517, -25205859, 2739713}, + {21374101, -3554250, -33524649, 9874411, 15377179, 11831242, + -33529904, 6134907, 4931255, 11987849}, + {-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, + 13861388, -30076310, 10117930}, + }, + { + {-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, + -6325503, 6704079, 12890019, 15728940}, + {-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, + -10428139, 12885167, 8311031}, + {-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, + 26423267, 4384730, 1888765, -5435404}, + }, + { + {-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, + -32251644, -12707869, -19464434, -3340243}, + {-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, + 14845197, 17151279, -9854116}, + {-24830458, -12733720, -15165978, 10367250, -29530908, -265356, + 22825805, -7087279, -16866484, 16176525}, + }, + { + {-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, + -10363426, -28746253, -10197509}, + {-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, + 23632037, -1940610, 32808310, 1099883}, + {15030977, 5768825, -27451236, -2887299, -6427378, -15361371, + -15277896, -6809350, 2051441, -15225865}, + }, + { + {-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, + -14154188, -22686354, 16633660}, + {4577086, -16752288, 13249841, -15304328, 19958763, -14537274, + 18559670, -10759549, 8402478, -9864273}, + {-28406330, -1051581, -26790155, -907698, -17212414, -11030789, + 9453451, -14980072, 17983010, 9967138}, + }, + { + {-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, + 7806337, 17507396, 3651560}, + {-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, + 26556809, -5574557, -18553322, -11357135}, + {2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, + 8459447, -5605463, -7621941}, + }, + { + {-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, + -849066, 17258084, -7977739}, + {18164541, -10595176, -17154882, -1542417, 19237078, -9745295, + 23357533, -15217008, 26908270, 12150756}, + {-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, + -5537701, -32302074, 16215819}, + }, + }, + { + { + {-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, + 32574489, 12532905, -7503072, -8675347}, + {-27343522, -16515468, -27151524, -10722951, 946346, 16291093, + 254968, 7168080, 21676107, -1943028}, + {21260961, -8424752, -16831886, -11920822, -23677961, 3968121, + -3651949, -6215466, -3556191, -7913075}, + }, + { + {16544754, 13250366, -16804428, 15546242, -4583003, 12757258, + -2462308, -8680336, -18907032, -9662799}, + {-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, + 26820651, 16690659, 25459437, -4564609}, + {-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, + 9142795, -2391602, -6432418, -1644817}, + }, + { + {-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, + -27457225, -16344658, 6335692, 7249989}, + {-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, + -30272269, 2682242, 25993170, -12478523}, + {4364628, 5930691, 32304656, -10044554, -8054781, 15091131, + 22857016, -10598955, 31820368, 15075278}, + }, + { + {31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, + -9650886, -17970238, 12833045}, + {19073683, 14851414, -24403169, -11860168, 7625278, 11091125, + -19619190, 2074449, -9413939, 14905377}, + {24483667, -11935567, -2518866, -11547418, -1553130, 15355506, + -25282080, 9253129, 27628530, -7555480}, + }, + { + {17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, + -9157582, -14110875, 15297016}, + {510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, + -11864220, 8683221, 2921426}, + {18606791, 11874196, 27155355, -5281482, -24031742, 6265446, + -25178240, -1278924, 4674690, 13890525}, + }, + { + {13609624, 13069022, -27372361, -13055908, 24360586, 9592974, + 14977157, 9835105, 4389687, 288396}, + {9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, + 8317628, 23388070, 16052080}, + {12720016, 11937594, -31970060, -5028689, 26900120, 8561328, + -20155687, -11632979, -14754271, -10812892}, + }, + { + {15961858, 14150409, 26716931, -665832, -22794328, 13603569, + 11829573, 7467844, -28822128, 929275}, + {11038231, -11582396, -27310482, -7316562, -10498527, -16307831, + -23479533, -9371869, -21393143, 2465074}, + {20017163, -4323226, 27915242, 1529148, 12396362, 15675764, + 13817261, -9658066, 2463391, -4622140}, + }, + { + {-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, + 9583558, 12851107, 4003896, 12673717}, + {-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, + 14741514, -9103726, 7903886, 2348101}, + {24536016, -16515207, 12715592, -3862155, 1511293, 10047386, + -3842346, -7129159, -28377538, 10048127}, + }, + }, + { + { + {-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, + 18873298, -7297090, -32297756, 15221632}, + {-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, + -21343950, 2095755, 29769758, 6593415}, + {-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, + -6118678, 30958054, 8292160}, + }, + { + {31429822, -13959116, 29173532, 15632448, 12174511, -2760094, + 32808831, 3977186, 26143136, -3148876}, + {22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, + -1674433, -3758243, -2304625}, + {-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, + -1612713, -1535569, -16664475, 8194478}, + }, + { + {27338066, -7507420, -7414224, 10140405, -19026427, -6589889, + 27277191, 8855376, 28572286, 3005164}, + {26287124, 4821776, 25476601, -4145903, -3764513, -15788984, + -18008582, 1182479, -26094821, -13079595}, + {-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, + -21876275, -13982627, 32208683, -1198248}, + }, + { + {-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, + -27315504, -10497842, -27672585, -11539858}, + {15941029, -9405932, -21367050, 8062055, 31876073, -238629, + -15278393, -1444429, 15397331, -4130193}, + {8934485, -13485467, -23286397, -13423241, -32446090, 14047986, + 31170398, -1441021, -27505566, 15087184}, + }, + { + {-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, + -15502406, 11461896, 16788528, -5868942}, + {-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, + -3770287, -10323320, 31322514, -11615635}, + {21426655, -5650218, -13648287, -5347537, -28812189, -4920970, + -18275391, -14621414, 13040862, -12112948}, + }, + { + {11293895, 12478086, -27136401, 15083750, -29307421, 14748872, + 14555558, -13417103, 1613711, 4896935}, + {-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, + 2825960, -4897045, -23971776, -11267415}, + {-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, + 20615400, 12405433, -23753030, -8436416}, + }, + { + {-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, + 4378436, 2432030, 23097949, -566018}, + {4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, + 10103221, -18512313, 2424778}, + {366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, + 1344109, -3642553, 12412659}, + }, + { + {-24001791, 7690286, 14929416, -168257, -32210835, -13412986, + 24162697, -15326504, -3141501, 11179385}, + {18289522, -14724954, 8056945, 16430056, -21729724, 7842514, + -6001441, -1486897, -18684645, -11443503}, + {476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, + 13403813, 11052904, 5219329}, + }, + }, + { + { + {20678546, -8375738, -32671898, 8849123, -5009758, 14574752, + 31186971, -3973730, 9014762, -8579056}, + {-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, + -33102500, 9160280, 8473550, -3256838}, + {24900749, 14435722, 17209120, -15292541, -22592275, 9878983, + -7689309, -16335821, -24568481, 11788948}, + }, + { + {-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, + -20037437, 10410733, -24568470, -1458691}, + {-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, + 11871841, -12505194, -18513325, 8464118}, + {-23400612, 8348507, -14585951, -861714, -3950205, -6373419, + 14325289, 8628612, 33313881, -8370517}, + }, + { + {-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, + -24805667, -10236854, -8940735, -5818269}, + {-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, + 15989197, -12838188, 28358192, -4253904}, + {-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, + -16637684, 4072016, -5351664, 5596589}, + }, + { + {-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, + 29266239, 2557221, 1768301, 15373193}, + {-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, + -4504991, -24660491, 3442910}, + {-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, + 22597931, 7176455, -18585478, 13365930}, + }, + { + {-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, + -8570186, -9689599, -3031667}, + {25008904, -10771599, -4305031, -9638010, 16265036, 15721635, + 683793, -11823784, 15723479, -15163481}, + {-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, + 11879682, 5400171, 519526, -1235876}, + }, + { + {22258397, -16332233, -7869817, 14613016, -22520255, -2950923, + -20353881, 7315967, 16648397, 7605640}, + {-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, + 23994942, -5281555, -9468848, 4763278}, + {-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, + 31088447, -7764523, -11356529, 728112}, + }, + { + {26047220, -11751471, -6900323, -16521798, 24092068, 9158119, + -4273545, -12555558, -29365436, -5498272}, + {17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, + 12327945, 10750447, 10014012}, + {-10312768, 3936952, 9156313, -8897683, 16498692, -994647, + -27481051, -666732, 3424691, 7540221}, + }, + { + {30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, + -16317219, -9244265, 15258046}, + {13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, + 2711395, 1062915, -5136345}, + {-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, + -6066489, 12194497, 32960380, 1459310}, + }, + }, + { + { + {19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, + -6101885, 18638003, -11174937}, + {31395534, 15098109, 26581030, 8030562, -16527914, -5007134, + 9012486, -7584354, -6643087, -5442636}, + {-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, + 9677543, -32294889, -6456008}, + }, + { + {-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, + -7839692, -7852844, -8138429}, + {-15236356, -15433509, 7766470, 746860, 26346930, -10221762, + -27333451, 10754588, -9431476, 5203576}, + {31834314, 14135496, -770007, 5159118, 20917671, -16768096, + -7467973, -7337524, 31809243, 7347066}, + }, + { + {-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, + 19797970, -12211255, 15192876, -2087490}, + {-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, + 10609330, 12694420, 33473243, -13382104}, + {33184999, 11180355, 15832085, -11385430, -1633671, 225884, + 15089336, -11023903, -6135662, 14480053}, + }, + { + {31308717, -5619998, 31030840, -1897099, 15674547, -6582883, + 5496208, 13685227, 27595050, 8737275}, + {-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, + -31008351, -12610604, 26498114, 66511}, + {22644454, -8761729, -16671776, 4884562, -3105614, -13559366, + 30540766, -4286747, -13327787, -7515095}, + }, + { + {-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, + 8205540, 13585437, -17127465, 15115439}, + {23711543, -672915, 31206561, -8362711, 6164647, -9709987, + -33535882, -1426096, 8236921, 16492939}, + {-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, + 19574902, 10071562, 6708380, -6222424}, + }, + { + {2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, + 9328700, 29955601, -11678310}, + {3096359, 9271816, -21620864, -15521844, -14847996, -7592937, + -25892142, -12635595, -9917575, 6216608}, + {-32615849, 338663, -25195611, 2510422, -29213566, -13820213, + 24822830, -6146567, -26767480, 7525079}, + }, + { + {-23066649, -13985623, 16133487, -7896178, -3389565, 778788, + -910336, -2782495, -19386633, 11994101}, + {21691500, -13624626, -641331, -14367021, 3285881, -3483596, + -25064666, 9718258, -7477437, 13381418}, + {18445390, -4202236, 14979846, 11622458, -1727110, -3582980, + 23111648, -6375247, 28535282, 15779576}, + }, + { + {30098053, 3089662, -9234387, 16662135, -21306940, 11308411, + -14068454, 12021730, 9955285, -16303356}, + {9734894, -14576830, -7473633, -9138735, 2060392, 11313496, + -18426029, 9924399, 20194861, 13380996}, + {-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, + -1984914, 15707771, 26342023, 10146099}, + }, + }, + { + { + {-26016874, -219943, 21339191, -41388, 19745256, -2878700, + -29637280, 2227040, 21612326, -545728}, + {-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, + 25764461, 12243797, -20856566, 11649658}, + {-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, + 6114064, 33514190, 2333242}, + }, + { + {-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, + -6679750, -12670638, 24350578, -13450001}, + {-4116307, -11271533, -23886186, 4843615, -30088339, 690623, + -31536088, -10406836, 8317860, 12352766}, + {18200138, -14475911, -33087759, -2696619, -23702521, -9102511, + -23552096, -2287550, 20712163, 6719373}, + }, + { + {26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, + -3763210, 26224235, -3297458}, + {-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, + 21728352, 9493610, 18620611, -16428628}, + {-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, + -5269471, -9725556, -30701573, -16479657}, + }, + { + {-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, + 12248509, -5240639, 13735342, 1934062}, + {25089769, 6742589, 17081145, -13406266, 21909293, -16067981, + -15136294, -3765346, -21277997, 5473616}, + {31883677, -7961101, 1083432, -11572403, 22828471, 13290673, + -7125085, 12469656, 29111212, -5451014}, + }, + { + {24244947, -15050407, -26262976, 2791540, -14997599, 16666678, + 24367466, 6388839, -10295587, 452383}, + {-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, + -24236251, -5915248, 15766062, 8407814}, + {-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, + -8917023, -4388953, -8067909, 2276718}, + }, + { + {30157918, 12924066, -17712050, 9245753, 19895028, 3368142, + -23827587, 5096219, 22740376, -7303417}, + {2041139, -14256350, 7783687, 13876377, -25946985, -13352459, + 24051124, 13742383, -15637599, 13295222}, + {33338237, -8505733, 12532113, 7977527, 9106186, -1715251, + -17720195, -4612972, -4451357, -14669444}, + }, + { + {-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, + -2469266, -4141880, 7770569, 9620597}, + {23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, + -1694323, -33502340, -14767970}, + {1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, + 1220118, 30494170, -11440799}, + }, + { + {-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, + -26739026, 926050, -1684339, -13333647}, + {13908495, -3549272, 30919928, -6273825, -21521863, 7989039, + 9021034, 9078865, 3353509, 4033511}, + {-29663431, -15113610, 32259991, -344482, 24295849, -12912123, + 23161163, 8839127, 27485041, 7356032}, + }, + }, + { + { + {9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, + 2625015, 28431036, -16771834}, + {-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, + -22545972, 14150565, 15970762, 4099461}, + {29262576, 16756590, 26350592, -8793563, 8529671, -11208050, + 13617293, -9937143, 11465739, 8317062}, + }, + { + {-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, + 14898637, 3848455, 20969334, -5157516}, + {-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, + -21610826, -3649888, 11177095, 14989547}, + {-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, + 13515641, 2581286, -28487508, 9930240}, + }, + { + {-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, + 18345767, -13403753, 16291481, -5314038}, + {-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, + 6957617, 4368891, 9788741}, + {16660756, 7281060, -10830758, 12911820, 20108584, -8101676, + -21722536, -8613148, 16250552, -11111103}, + }, + { + {-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, + 10604807, -30190403, 4782747}, + {-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, + -9981571, 4383045, 22546403, 437323}, + {31665577, -12180464, -16186830, 1491339, -18368625, 3294682, + 27343084, 2786261, -30633590, -14097016}, + }, + { + {-14467279, -683715, -33374107, 7448552, 19294360, 14334329, + -19690631, 2355319, -19284671, -6114373}, + {15121312, -15796162, 6377020, -6031361, -10798111, -12957845, + 18952177, 15496498, -29380133, 11754228}, + {-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, + 7141596, 11724556, 22761615, -10134141}, + }, + { + {16918416, 11729663, -18083579, 3022987, -31015732, -13339659, + -28741185, -12227393, 32851222, 11717399}, + {11166634, 7338049, -6722523, 4531520, -29468672, -7302055, + 31474879, 3483633, -1193175, -4030831}, + {-185635, 9921305, 31456609, -13536438, -12013818, 13348923, + 33142652, 6546660, -19985279, -3948376}, + }, + { + {-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, + -8537131, -12833048, -30772034, -15486313}, + {-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, + -31135347, -16049879, 10928917, 3011958}, + {-6957757, -15594337, 31696059, 334240, 29576716, 14796075, + -30831056, -12805180, 18008031, 10258577}, + }, + { + {-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, + -1853465, 1367120, 25127874, 6671743}, + {29701166, -14373934, -10878120, 9279288, -17568, 13127210, + 21382910, 11042292, 25838796, 4642684}, + {-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, + 30468147, -13900640, 18423289, 4177476}, + }, + }, +}; + +static uint8_t negative(signed char b) { + uint32_t x = b; + x >>= 31; /* 1: yes; 0: no */ + return x; +} + +static void table_select(ge_precomp *t, int pos, signed char b) { + ge_precomp minust; + uint8_t bnegative = negative(b); + uint8_t babs = b - (((-bnegative) & b) << 1); + + ge_precomp_0(t); + cmov(t, &base[pos][0], equal(babs, 1)); + cmov(t, &base[pos][1], equal(babs, 2)); + cmov(t, &base[pos][2], equal(babs, 3)); + cmov(t, &base[pos][3], equal(babs, 4)); + cmov(t, &base[pos][4], equal(babs, 5)); + cmov(t, &base[pos][5], equal(babs, 6)); + cmov(t, &base[pos][6], equal(babs, 7)); + cmov(t, &base[pos][7], equal(babs, 8)); + fe_copy(minust.yplusx, t->yminusx); + fe_copy(minust.yminusx, t->yplusx); + fe_neg(minust.xy2d, t->xy2d); + cmov(t, &minust, bnegative); +} + +/* h = a * B + * where a = a[0]+256*a[1]+...+256^31 a[31] + * B is the Ed25519 base point (x,4/5) with x positive. + * + * Preconditions: + * a[31] <= 127 */ +static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) { + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + ge_p3_0(h); + for (i = 1; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + ge_p1p1_to_p3(h, &r); + } + + ge_p3_dbl(&r, h); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p3(h, &r); + + for (i = 0; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + ge_p1p1_to_p3(h, &r); + } +} + +#endif + +static void slide(signed char *r, const uint8_t *a) { + int i; + int b; + int k; + + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + for (i = 0; i < 256; ++i) { + if (r[i]) { + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (r[i + b]) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + for (k = i + b; k < 256; ++k) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else { + break; + } + } + } + } + } +} + +static ge_precomp Bi[8] = { + { + {25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, + -11754271, -6079156, 2047605}, + {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, + 5043384, 19500929, -15469378}, + {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, + 11864899, -24514362, -4438546}, + }, + { + {15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, + -14772189, 28944400, -1550024}, + {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, + -11775962, 7689662, 11199574}, + {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, + 10017326, -17749093, -9920357}, + }, + { + {10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, + 14515107, -15438304, 10819380}, + {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, + 12483688, -12668491, 5581306}, + {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, + 13850243, -23678021, -15815942}, + }, + { + {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, + 5230134, -23952439, -15175766}, + {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, + 16520125, 30598449, 7715701}, + {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, + 1370708, 29794553, -1409300}, + }, + { + {-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, + -1361450, -13062696, 13821877}, + {-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, + -7212327, 18853322, -14220951}, + {4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, + -10431137, 2207753, -3209784}, + }, + { + {-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, + -663000, -31111463, -16132436}, + {25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, + 15725684, 171356, 6466918}, + {23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, + -14088058, -30714912, 16193877}, + }, + { + {-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, + 4729455, -18074513, 9256800}, + {-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, + 9761698, -19827198, 630305}, + {-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, + -15960994, -2449256, -14291300}, + }, + { + {-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, + 15033784, 25105118, -7894876}, + {-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, + 1573892, -2625887, 2198790, -15804619}, + {-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, + -16236442, -32461234, -12290683}, + }, +}; + +/* r = a * A + b * B + * where a = a[0]+256*a[1]+...+256^31 a[31]. + * and b = b[0]+256*b[1]+...+256^31 b[31]. + * B is the Ed25519 base point (x,4/5) with x positive. */ +void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a, + const ge_p3 *A, const uint8_t *b) { + signed char aslide[256]; + signed char bslide[256]; + ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + + slide(aslide, a); + slide(bslide, b); + + ge_p3_to_cached(&Ai[0], A); + ge_p3_dbl(&t, A); + ge_p1p1_to_p3(&A2, &t); + ge_add(&t, &A2, &Ai[0]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[1], &u); + ge_add(&t, &A2, &Ai[1]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[2], &u); + ge_add(&t, &A2, &Ai[2]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[3], &u); + ge_add(&t, &A2, &Ai[3]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[4], &u); + ge_add(&t, &A2, &Ai[4]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[5], &u); + ge_add(&t, &A2, &Ai[5]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[6], &u); + ge_add(&t, &A2, &Ai[6]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[7], &u); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) { + break; + } + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + if (bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } + + ge_p1p1_to_p2(r, &t); + } +} + +/* The set of scalars is \Z/l + * where l = 2^252 + 27742317777372353535851937790883648493. */ + +/* Input: + * s[0]+256*s[1]+...+256^63*s[63] = s + * + * Output: + * s[0]+256*s[1]+...+256^31*s[31] = s mod l + * where l = 2^252 + 27742317777372353535851937790883648493. + * Overwrites s in place. */ +static void sc_reduce(uint8_t *s) { + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +/* Input: + * a[0]+256*a[1]+...+256^31*a[31] = a + * b[0]+256*b[1]+...+256^31*b[31] = b + * c[0]+256*c[1]+...+256^31*c[31] = c + * + * Output: + * s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l + * where l = 2^252 + 27742317777372353535851937790883648493. */ +static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, + const uint8_t *c) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry18 = (s18 + (1 << 20)) >> 21; + s19 += carry18; + s18 -= carry18 << 21; + carry20 = (s20 + (1 << 20)) >> 21; + s21 += carry20; + s20 -= carry20 << 21; + carry22 = (s22 + (1 << 20)) >> 21; + s23 += carry22; + s22 -= carry22 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + carry17 = (s17 + (1 << 20)) >> 21; + s18 += carry17; + s17 -= carry17 << 21; + carry19 = (s19 + (1 << 20)) >> 21; + s20 += carry19; + s19 -= carry19 << 21; + carry21 = (s21 + (1 << 20)) >> 21; + s22 += carry21; + s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) { + uint8_t seed[32]; + RAND_bytes(seed, 32); + + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(seed, 32, az); + + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + ge_p3 A; + ge_scalarmult_base(&A, az); + ge_p3_tobytes(out_public_key, &A); + + memcpy(out_private_key, seed, 32); + memmove(out_private_key + 32, out_public_key, 32); +} + +int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, + const uint8_t private_key[64]) { + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(private_key, 32, az); + + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, az + 32, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t nonce[SHA512_DIGEST_LENGTH]; + SHA512_Final(nonce, &hash_ctx); + + sc_reduce(nonce); + ge_p3 R; + ge_scalarmult_base(&R, nonce); + ge_p3_tobytes(out_sig, &R); + + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, out_sig, 32); + SHA512_Update(&hash_ctx, private_key + 32, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t hram[SHA512_DIGEST_LENGTH]; + SHA512_Final(hram, &hash_ctx); + + sc_reduce(hram); + sc_muladd(out_sig + 32, hram, az, nonce); + + return 1; +} + +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], const uint8_t public_key[32]) { + ge_p3 A; + if ((signature[63] & 224) != 0 || + ge_frombytes_negate_vartime(&A, public_key) != 0) { + return 0; + } + + uint8_t pkcopy[32]; + memcpy(pkcopy, public_key, 32); + uint8_t rcopy[32]; + memcpy(rcopy, signature, 32); + uint8_t scopy[32]; + memcpy(scopy, signature + 32, 32); + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, signature, 32); + SHA512_Update(&hash_ctx, public_key, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t h[SHA512_DIGEST_LENGTH]; + SHA512_Final(h, &hash_ctx); + + sc_reduce(h); + + ge_p2 R; + ge_double_scalarmult_vartime(&R, h, &A, scopy); + + uint8_t rcheck[32]; + ge_tobytes(rcheck, &R); + + return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0; +} + + +#if defined(BORINGSSL_X25519_X86_64) + +static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]) { + x25519_x86_64(out, scalar, point); +} + +#else + +/* Replace (f,g) with (g,f) if b == 1; + * replace (f,g) with (f,g) if b == 0. + * + * Preconditions: b in {0,1}. */ +static void fe_cswap(fe f, fe g, unsigned int b) { + b = 0-b; + unsigned i; + for (i = 0; i < 10; i++) { + int32_t x = f[i] ^ g[i]; + x &= b; + f[i] ^= x; + g[i] ^= x; + } +} + +/* h = f * 121666 + * Can overlap h with f. + * + * Preconditions: + * |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + * + * Postconditions: + * |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */ +static void fe_mul121666(fe h, fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int64_t h0 = f0 * (int64_t) 121666; + int64_t h1 = f1 * (int64_t) 121666; + int64_t h2 = f2 * (int64_t) 121666; + int64_t h3 = f3 * (int64_t) 121666; + int64_t h4 = f4 * (int64_t) 121666; + int64_t h5 = f5 * (int64_t) 121666; + int64_t h6 = f6 * (int64_t) 121666; + int64_t h7 = f7 * (int64_t) 121666; + int64_t h8 = f8 * (int64_t) 121666; + int64_t h9 = f9 * (int64_t) 121666; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +static void x25519_scalar_mult_generic(uint8_t out[32], + const uint8_t scalar[32], + const uint8_t point[32]) { + fe x1, x2, z2, x3, z3, tmp0, tmp1; + + uint8_t e[32]; + memcpy(e, scalar, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + fe_frombytes(x1, point); + fe_1(x2); + fe_0(z2); + fe_copy(x3, x1); + fe_1(z3); + + unsigned swap = 0; + int pos; + for (pos = 254; pos >= 0; --pos) { + unsigned b = 1 & (e[pos / 8] >> (pos & 7)); + swap ^= b; + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + swap = b; + fe_sub(tmp0, x3, z3); + fe_sub(tmp1, x2, z2); + fe_add(x2, x2, z2); + fe_add(z2, x3, z3); + fe_mul(z3, tmp0, x2); + fe_mul(z2, z2, tmp1); + fe_sq(tmp0, tmp1); + fe_sq(tmp1, x2); + fe_add(x3, z3, z2); + fe_sub(z2, z3, z2); + fe_mul(x2, tmp1, tmp0); + fe_sub(tmp1, tmp1, tmp0); + fe_sq(z2, z2); + fe_mul121666(z3, tmp1); + fe_sq(x3, x3); + fe_add(tmp0, tmp0, z3); + fe_mul(z3, x1, z2); + fe_mul(z2, tmp1, tmp0); + } + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + + fe_invert(z2, z2); + fe_mul(x2, x2, z2); + fe_tobytes(out, x2); +} + +static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]) { +#if defined(BORINGSSL_X25519_NEON) + if (CRYPTO_is_NEON_capable()) { + x25519_NEON(out, scalar, point); + return; + } +#endif + + x25519_scalar_mult_generic(out, scalar, point); +} + +#endif /* BORINGSSL_X25519_X86_64 */ + + +void X25519_keypair(uint8_t out_public_value[32], uint8_t out_private_key[32]) { + RAND_bytes(out_private_key, 32); + X25519_public_from_private(out_public_value, out_private_key); +} + +int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32], + const uint8_t peer_public_value[32]) { + static const uint8_t kZeros[32] = {0}; + x25519_scalar_mult(out_shared_key, private_key, peer_public_value); + /* The all-zero output results when the input is a point of small order. */ + return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0; +} + +#if defined(BORINGSSL_X25519_X86_64) + +/* When |BORINGSSL_X25519_X86_64| is set, base point multiplication is done with + * the Montgomery ladder because it's faster. Otherwise it's done using the + * Ed25519 tables. */ + +void X25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]) { + static const uint8_t kMongomeryBasePoint[32] = {9}; + x25519_scalar_mult(out_public_value, private_key, kMongomeryBasePoint); +} + +#else + +void X25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]) { +#if defined(BORINGSSL_X25519_NEON) + if (CRYPTO_is_NEON_capable()) { + static const uint8_t kMongomeryBasePoint[32] = {9}; + x25519_NEON(out_public_value, private_key, kMongomeryBasePoint); + return; + } +#endif + + uint8_t e[32]; + memcpy(e, private_key, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + ge_p3 A; + ge_scalarmult_base(&A, e); + + /* We only need the u-coordinate of the curve25519 point. The map is + * u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */ + fe zplusy, zminusy, zminusy_inv; + fe_add(zplusy, A.Z, A.Y); + fe_sub(zminusy, A.Z, A.Y); + fe_invert(zminusy_inv, zminusy); + fe_mul(zplusy, zplusy, zminusy_inv); + fe_tobytes(out_public_value, zplusy); +} + +#endif /* BORINGSSL_X25519_X86_64 */ diff --git a/src/crypto/curve25519/ed25519_test.cc b/src/crypto/curve25519/ed25519_test.cc new file mode 100644 index 0000000..1b6a0b6 --- /dev/null +++ b/src/crypto/curve25519/ed25519_test.cc @@ -0,0 +1,63 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <stdint.h> +#include <string.h> + +#include <openssl/curve25519.h> + +#include "../test/file_test.h" + + +static bool TestSignature(FileTest *t, void *arg) { + std::vector<uint8_t> private_key, public_key, message, expected_signature; + if (!t->GetBytes(&private_key, "PRIV") || + private_key.size() != 64 || + !t->GetBytes(&public_key, "PUB") || + public_key.size() != 32 || + !t->GetBytes(&message, "MESSAGE") || + !t->GetBytes(&expected_signature, "SIG") || + expected_signature.size() != 64) { + return false; + } + + uint8_t signature[64]; + if (!ED25519_sign(signature, message.data(), message.size(), + private_key.data())) { + t->PrintLine("ED25519_sign failed"); + return false; + } + + if (!t->ExpectBytesEqual(expected_signature.data(), expected_signature.size(), + signature, sizeof(signature))) { + return false; + } + + if (!ED25519_verify(message.data(), message.size(), signature, + public_key.data())) { + t->PrintLine("ED25519_verify failed"); + return false; + } + + return true; +} + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "%s <test input.txt>\n", argv[0]); + return 1; + } + + return FileTestMain(TestSignature, nullptr, argv[1]); +} diff --git a/src/crypto/curve25519/ed25519_tests.txt b/src/crypto/curve25519/ed25519_tests.txt new file mode 100644 index 0000000..4d43417 --- /dev/null +++ b/src/crypto/curve25519/ed25519_tests.txt @@ -0,0 +1,2577 @@ +# The contents of this file were generated from +# http://ed25519.cr.yp.to/python/sign.input using the following Python script: +# +# import sys +# +# isFirst = True +# +# for line in sys.stdin.readlines(): +# (private, public, message, sig_and_message, _) = line.split(':') +# +# if not isFirst: +# print +# print "PRIV:", private +# print "PUB:", public +# print "MESSAGE:", message +# print "SIG:", sig_and_message[:128] +# isFirst = False + +PRIV: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a +PUB: d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a +MESSAGE: +SIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b + +PRIV: 4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c +PUB: 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c +MESSAGE: 72 +SIG: 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00 + +PRIV: c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025 +PUB: fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025 +MESSAGE: af82 +SIG: 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a + +PRIV: 0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057 +PUB: e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057 +MESSAGE: cbc77b +SIG: d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00c + +PRIV: 6df9340c138cc188b5fe4464ebaa3f7fc206a2d55c3434707e74c9fc04e20ebbc0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7 +PUB: c0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7 +MESSAGE: 5f4c8989 +SIG: 124f6fc6b0d100842769e71bd530664d888df8507df6c56dedfdb509aeb93416e26b918d38aa06305df3095697c18b2aa832eaa52edc0ae49fbae5a85e150c07 + +PRIV: b780381a65edf8b78f6945e8dbec7941ac049fd4c61040cf0c324357975a293ce253af0766804b869bb1595be9765b534886bbaab8305bf50dbc7f899bfb5f01 +PUB: e253af0766804b869bb1595be9765b534886bbaab8305bf50dbc7f899bfb5f01 +MESSAGE: 18b6bec097 +SIG: b2fc46ad47af464478c199e1f8be169f1be6327c7f9a0a6689371ca94caf04064a01b22aff1520abd58951341603faed768cf78ce97ae7b038abfe456aa17c09 + +PRIV: 78ae9effe6f245e924a7be63041146ebc670dbd3060cba67fbc6216febc44546fbcfbfa40505d7f2be444a33d185cc54e16d615260e1640b2b5087b83ee3643d +PUB: fbcfbfa40505d7f2be444a33d185cc54e16d615260e1640b2b5087b83ee3643d +MESSAGE: 89010d855972 +SIG: 6ed629fc1d9ce9e1468755ff636d5a3f40a5d9c91afd93b79d241830f7e5fa29854b8f20cc6eecbb248dbd8d16d14e99752194e4904d09c74d639518839d2300 + +PRIV: 691865bfc82a1e4b574eecde4c7519093faf0cf867380234e3664645c61c5f7998a5e3a36e67aaba89888bf093de1ad963e774013b3902bfab356d8b90178a63 +PUB: 98a5e3a36e67aaba89888bf093de1ad963e774013b3902bfab356d8b90178a63 +MESSAGE: b4a8f381e70e7a +SIG: 6e0af2fe55ae377a6b7a7278edfb419bd321e06d0df5e27037db8812e7e3529810fa5552f6c0020985ca17a0e02e036d7b222a24f99b77b75fdd16cb05568107 + +PRIV: 3b26516fb3dc88eb181b9ed73f0bcd52bcd6b4c788e4bcaf46057fd078bee073f81fb54a825fced95eb033afcd64314075abfb0abd20a970892503436f34b863 +PUB: f81fb54a825fced95eb033afcd64314075abfb0abd20a970892503436f34b863 +MESSAGE: 4284abc51bb67235 +SIG: d6addec5afb0528ac17bb178d3e7f2887f9adbb1ad16e110545ef3bc57f9de2314a5c8388f723b8907be0f3ac90c6259bbe885ecc17645df3db7d488f805fa08 + +PRIV: edc6f5fbdd1cee4d101c063530a30490b221be68c036f5b07d0f953b745df192c1a49c66e617f9ef5ec66bc4c6564ca33de2a5fb5e1464062e6d6c6219155efd +PUB: c1a49c66e617f9ef5ec66bc4c6564ca33de2a5fb5e1464062e6d6c6219155efd +MESSAGE: 672bf8965d04bc5146 +SIG: 2c76a04af2391c147082e33faacdbe56642a1e134bd388620b852b901a6bc16ff6c9cc9404c41dea12ed281da067a1513866f9d964f8bdd24953856c50042901 + +PRIV: 4e7d21fb3b1897571a445833be0f9fd41cd62be3aa04040f8934e1fcbdcacd4531b2524b8348f7ab1dfafa675cc538e9a84e3fe5819e27c12ad8bbc1a36e4dff +PUB: 31b2524b8348f7ab1dfafa675cc538e9a84e3fe5819e27c12ad8bbc1a36e4dff +MESSAGE: 33d7a786aded8c1bf691 +SIG: 28e4598c415ae9de01f03f9f3fab4e919e8bf537dd2b0cdf6e79b9e6559c9409d9151a4c40f083193937627c369488259e99da5a9f0a87497fa6696a5dd6ce08 + +PRIV: a980f892db13c99a3e8971e965b2ff3d41eafd54093bc9f34d1fd22d84115bb644b57ee30cdb55829d0a5d4f046baef078f1e97a7f21b62d75f8e96ea139c35f +PUB: 44b57ee30cdb55829d0a5d4f046baef078f1e97a7f21b62d75f8e96ea139c35f +MESSAGE: 3486f68848a65a0eb5507d +SIG: 77d389e599630d934076329583cd4105a649a9292abc44cd28c40000c8e2f5ac7660a81c85b72af8452d7d25c070861dae91601c7803d656531650dd4e5c4100 + +PRIV: 5b5a619f8ce1c66d7ce26e5a2ae7b0c04febcd346d286c929e19d0d5973bfef96fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257 +PUB: 6fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257 +MESSAGE: 5a8d9d0a22357e6655f9c785 +SIG: 0f9ad9793033a2fa06614b277d37381e6d94f65ac2a5a94558d09ed6ce922258c1a567952e863ac94297aec3c0d0c8ddf71084e504860bb6ba27449b55adc40e + +PRIV: 940c89fe40a81dafbdb2416d14ae469119869744410c3303bfaa0241dac57800a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd +PUB: a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd +MESSAGE: b87d3813e03f58cf19fd0b6395 +SIG: d8bb64aad8c9955a115a793addd24f7f2b077648714f49c4694ec995b330d09d640df310f447fd7b6cb5c14f9fe9f490bcf8cfadbfd2169c8ac20d3b8af49a0c + +PRIV: 9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291 +PUB: cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291 +MESSAGE: 55c7fa434f5ed8cdec2b7aeac173 +SIG: 6ee3fe81e23c60eb2312b2006b3b25e6838e02106623f844c44edb8dafd66ab0671087fd195df5b8f58a1d6e52af42908053d55c7321010092748795ef94cf06 + +PRIV: d5aeee41eeb0e9d1bf8337f939587ebe296161e6bf5209f591ec939e1440c300fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5 +PUB: fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5 +MESSAGE: 0a688e79be24f866286d4646b5d81c +SIG: f68d04847e5b249737899c014d31c805c5007a62c0a10d50bb1538c5f35503951fbc1e08682f2cc0c92efe8f4985dec61dcbd54d4b94a22547d24451271c8b00 + +PRIV: 0a47d10452ae2febec518a1c7c362890c3fc1a49d34b03b6467d35c904a8362d34e5a8508c4743746962c066e4badea2201b8ab484de5c4f94476ccd2143955b +PUB: 34e5a8508c4743746962c066e4badea2201b8ab484de5c4f94476ccd2143955b +MESSAGE: c942fa7ac6b23ab7ff612fdc8e68ef39 +SIG: 2a3d27dc40d0a8127949a3b7f908b3688f63b7f14f651aacd715940bdbe27a0809aac142f47ab0e1e44fa490ba87ce5392f33a891539caf1ef4c367cae54500c + +PRIV: f8148f7506b775ef46fdc8e8c756516812d47d6cfbfa318c27c9a22641e56f170445e456dacc7d5b0bbed23c8200cdb74bdcb03e4c7b73f0a2b9b46eac5d4372 +PUB: 0445e456dacc7d5b0bbed23c8200cdb74bdcb03e4c7b73f0a2b9b46eac5d4372 +MESSAGE: 7368724a5b0efb57d28d97622dbde725af +SIG: 3653ccb21219202b8436fb41a32ba2618c4a133431e6e63463ceb3b6106c4d56e1d2ba165ba76eaad3dc39bffb130f1de3d8e6427db5b71938db4e272bc3e20b + +PRIV: 77f88691c4eff23ebb7364947092951a5ff3f10785b417e918823a552dab7c7574d29127f199d86a8676aec33b4ce3f225ccb191f52c191ccd1e8cca65213a6b +PUB: 74d29127f199d86a8676aec33b4ce3f225ccb191f52c191ccd1e8cca65213a6b +MESSAGE: bd8e05033f3a8bcdcbf4beceb70901c82e31 +SIG: fbe929d743a03c17910575492f3092ee2a2bf14a60a3fcacec74a58c7334510fc262db582791322d6c8c41f1700adb80027ecabc14270b703444ae3ee7623e0a + +PRIV: ab6f7aee6a0837b334ba5eb1b2ad7fcecfab7e323cab187fe2e0a95d80eff1325b96dca497875bf9664c5e75facf3f9bc54bae913d66ca15ee85f1491ca24d2c +PUB: 5b96dca497875bf9664c5e75facf3f9bc54bae913d66ca15ee85f1491ca24d2c +MESSAGE: 8171456f8b907189b1d779e26bc5afbb08c67a +SIG: 73bca64e9dd0db88138eedfafcea8f5436cfb74bfb0e7733cf349baa0c49775c56d5934e1d38e36f39b7c5beb0a836510c45126f8ec4b6810519905b0ca07c09 + +PRIV: 8d135de7c8411bbdbd1b31e5dc678f2ac7109e792b60f38cd24936e8a898c32d1ca281938529896535a7714e3584085b86ef9fec723f42819fc8dd5d8c00817f +PUB: 1ca281938529896535a7714e3584085b86ef9fec723f42819fc8dd5d8c00817f +MESSAGE: 8ba6a4c9a15a244a9c26bb2a59b1026f21348b49 +SIG: a1adc2bc6a2d980662677e7fdff6424de7dba50f5795ca90fdf3e96e256f3285cac71d3360482e993d0294ba4ec7440c61affdf35fe83e6e04263937db93f105 + +PRIV: 0e765d720e705f9366c1ab8c3fa84c9a44370c06969f803296884b2846a652a47fae45dd0a05971026d410bc497af5be7d0827a82a145c203f625dfcb8b03ba8 +PUB: 7fae45dd0a05971026d410bc497af5be7d0827a82a145c203f625dfcb8b03ba8 +MESSAGE: 1d566a6232bbaab3e6d8804bb518a498ed0f904986 +SIG: bb61cf84de61862207c6a455258bc4db4e15eea0317ff88718b882a06b5cf6ec6fd20c5a269e5d5c805bafbcc579e2590af414c7c227273c102a10070cdfe80f + +PRIV: db36e326d676c2d19cc8fe0c14b709202ecfc761d27089eb6ea4b1bb021ecfa748359b850d23f0715d94bb8bb75e7e14322eaf14f06f28a805403fbda002fc85 +PUB: 48359b850d23f0715d94bb8bb75e7e14322eaf14f06f28a805403fbda002fc85 +MESSAGE: 1b0afb0ac4ba9ab7b7172cddc9eb42bba1a64bce47d4 +SIG: b6dcd09989dfbac54322a3ce87876e1d62134da998c79d24b50bd7a6a797d86a0e14dc9d7491d6c14a673c652cfbec9f962a38c945da3b2f0879d0b68a921300 + +PRIV: c89955e0f7741d905df0730b3dc2b0ce1a13134e44fef3d40d60c020ef19df77fdb30673402faf1c8033714f3517e47cc0f91fe70cf3836d6c23636e3fd2287c +PUB: fdb30673402faf1c8033714f3517e47cc0f91fe70cf3836d6c23636e3fd2287c +MESSAGE: 507c94c8820d2a5793cbf3442b3d71936f35fe3afef316 +SIG: 7ef66e5e86f2360848e0014e94880ae2920ad8a3185a46b35d1e07dea8fa8ae4f6b843ba174d99fa7986654a0891c12a794455669375bf92af4cc2770b579e0c + +PRIV: 4e62627fc221142478aee7f00781f817f662e3b75db29bb14ab47cf8e84104d6b1d39801892027d58a8c64335163195893bfc1b61dbeca3260497e1f30371107 +PUB: b1d39801892027d58a8c64335163195893bfc1b61dbeca3260497e1f30371107 +MESSAGE: d3d615a8472d9962bb70c5b5466a3d983a4811046e2a0ef5 +SIG: 836afa764d9c48aa4770a4388b654e97b3c16f082967febca27f2fc47ddfd9244b03cfc729698acf5109704346b60b230f255430089ddc56912399d1122de70a + +PRIV: 6b83d7da8908c3e7205b39864b56e5f3e17196a3fc9c2f5805aad0f5554c142dd0c846f97fe28585c0ee159015d64c56311c886eddcc185d296dbb165d2625d6 +PUB: d0c846f97fe28585c0ee159015d64c56311c886eddcc185d296dbb165d2625d6 +MESSAGE: 6ada80b6fa84f7034920789e8536b82d5e4678059aed27f71c +SIG: 16e462a29a6dd498685a3718b3eed00cc1598601ee47820486032d6b9acc9bf89f57684e08d8c0f05589cda2882a05dc4c63f9d0431d6552710812433003bc08 + +PRIV: 19a91fe23a4e9e33ecc474878f57c64cf154b394203487a7035e1ad9cd697b0d2bf32ba142ba4622d8f3e29ecd85eea07b9c47be9d64412c9b510b27dd218b23 +PUB: 2bf32ba142ba4622d8f3e29ecd85eea07b9c47be9d64412c9b510b27dd218b23 +MESSAGE: 82cb53c4d5a013bae5070759ec06c3c6955ab7a4050958ec328c +SIG: 881f5b8c5a030df0f75b6634b070dd27bd1ee3c08738ae349338b3ee6469bbf9760b13578a237d5182535ede121283027a90b5f865d63a6537dca07b44049a0f + +PRIV: 1d5b8cb6215c18141666baeefcf5d69dad5bea9a3493dddaa357a4397a13d4de94d23d977c33e49e5e4992c68f25ec99a27c41ce6b91f2bfa0cd8292fe962835 +PUB: 94d23d977c33e49e5e4992c68f25ec99a27c41ce6b91f2bfa0cd8292fe962835 +MESSAGE: a9a8cbb0ad585124e522abbfb40533bdd6f49347b55b18e8558cb0 +SIG: 3acd39bec8c3cd2b44299722b5850a0400c1443590fd4861d59aae7496acb3df73fc3fdf7969ae5f50ba47dddc435246e5fd376f6b891cd4c2caf5d614b6170c + +PRIV: 6a91b3227c472299089bdce9356e726a40efd840f11002708b7ee55b64105ac29d084aa8b97a6b9bafa496dbc6f76f3306a116c9d917e681520a0f914369427e +PUB: 9d084aa8b97a6b9bafa496dbc6f76f3306a116c9d917e681520a0f914369427e +MESSAGE: 5cb6f9aa59b80eca14f6a68fb40cf07b794e75171fba96262c1c6adc +SIG: f5875423781b66216cb5e8998de5d9ffc29d1d67107054ace3374503a9c3ef811577f269de81296744bd706f1ac478caf09b54cdf871b3f802bd57f9a6cb9101 + +PRIV: 93eaa854d791f05372ce72b94fc6503b2ff8ae6819e6a21afe825e27ada9e4fb16cee8a3f2631834c88b670897ff0b08ce90cc147b4593b3f1f403727f7e7ad5 +PUB: 16cee8a3f2631834c88b670897ff0b08ce90cc147b4593b3f1f403727f7e7ad5 +MESSAGE: 32fe27994124202153b5c70d3813fdee9c2aa6e7dc743d4d535f1840a5 +SIG: d834197c1a3080614e0a5fa0aaaa808824f21c38d692e6ffbd200f7dfb3c8f44402a7382180b98ad0afc8eec1a02acecf3cb7fde627b9f18111f260ab1db9a07 + +PRIV: 941cac69fb7b1815c57bb987c4d6c2ad2c35d5f9a3182a79d4ba13eab253a8ad23be323c562dfd71ce65f5bba56a74a3a6dfc36b573d2f94f635c7f9b4fd5a5b +PUB: 23be323c562dfd71ce65f5bba56a74a3a6dfc36b573d2f94f635c7f9b4fd5a5b +MESSAGE: bb3172795710fe00054d3b5dfef8a11623582da68bf8e46d72d27cece2aa +SIG: 0f8fad1e6bde771b4f5420eac75c378bae6db5ac6650cd2bc210c1823b432b48e016b10595458ffab92f7a8989b293ceb8dfed6c243a2038fc06652aaaf16f02 + +PRIV: 1acdbb793b0384934627470d795c3d1dd4d79cea59ef983f295b9b59179cbb283f60c7541afa76c019cf5aa82dcdb088ed9e4ed9780514aefb379dabc844f31a +PUB: 3f60c7541afa76c019cf5aa82dcdb088ed9e4ed9780514aefb379dabc844f31a +MESSAGE: 7cf34f75c3dac9a804d0fcd09eba9b29c9484e8a018fa9e073042df88e3c56 +SIG: be71ef4806cb041d885effd9e6b0fbb73d65d7cdec47a89c8a994892f4e55a568c4cc78d61f901e80dbb628b86a23ccd594e712b57fa94c2d67ec26634878507 + +PRIV: 8ed7a797b9cea8a8370d419136bcdf683b759d2e3c6947f17e13e2485aa9d420b49f3a78b1c6a7fca8f3466f33bc0e929f01fba04306c2a7465f46c3759316d9 +PUB: b49f3a78b1c6a7fca8f3466f33bc0e929f01fba04306c2a7465f46c3759316d9 +MESSAGE: a750c232933dc14b1184d86d8b4ce72e16d69744ba69818b6ac33b1d823bb2c3 +SIG: 04266c033b91c1322ceb3446c901ffcf3cc40c4034e887c9597ca1893ba7330becbbd8b48142ef35c012c6ba51a66df9308cb6268ad6b1e4b03e70102495790b + +PRIV: f2ab396fe8906e3e5633e99cabcd5b09df0859b516230b1e0450b580b65f616c8ea074245159a116aa7122a25ec16b891d625a68f33660423908f6bdc44f8c1b +PUB: 8ea074245159a116aa7122a25ec16b891d625a68f33660423908f6bdc44f8c1b +MESSAGE: 5a44e34b746c5fd1898d552ab354d28fb4713856d7697dd63eb9bd6b99c280e187 +SIG: a06a23d982d81ab883aae230adbc368a6a9977f003cebb00d4c2e4018490191a84d3a282fdbfb2fc88046e62de43e15fb575336b3c8b77d19ce6a009ce51f50c + +PRIV: 550a41c013f79bab8f06e43ad1836d51312736a9713806fafe6645219eaa1f9daf6b7145474dc9954b9af93a9cdb34449d5b7c651c824d24e230b90033ce59c0 +PUB: af6b7145474dc9954b9af93a9cdb34449d5b7c651c824d24e230b90033ce59c0 +MESSAGE: 8bc4185e50e57d5f87f47515fe2b1837d585f0aae9e1ca383b3ec908884bb900ff27 +SIG: 16dc1e2b9fa909eefdc277ba16ebe207b8da5e91143cde78c5047a89f681c33c4e4e3428d5c928095903a811ec002d52a39ed7f8b3fe1927200c6dd0b9ab3e04 + +PRIV: 19ac3e272438c72ddf7b881964867cb3b31ff4c793bb7ea154613c1db068cb7ef85b80e050a1b9620db138bfc9e100327e25c257c59217b601f1f6ac9a413d3f +PUB: f85b80e050a1b9620db138bfc9e100327e25c257c59217b601f1f6ac9a413d3f +MESSAGE: 95872d5f789f95484e30cbb0e114028953b16f5c6a8d9f65c003a83543beaa46b38645 +SIG: ea855d781cbea4682e350173cb89e8619ccfddb97cdce16f9a2f6f6892f46dbe68e04b12b8d88689a7a31670cdff409af98a93b49a34537b6aa009d2eb8b4701 + +PRIV: ca267de96c93c238fafb1279812059ab93ac03059657fd994f8fa5a09239c821017370c879090a81c7f272c2fc80e3aac2bc603fcb379afc98691160ab745b26 +PUB: 017370c879090a81c7f272c2fc80e3aac2bc603fcb379afc98691160ab745b26 +MESSAGE: e05f71e4e49a72ec550c44a3b85aca8f20ff26c3ee94a80f1b431c7d154ec9603ee02531 +SIG: ac957f82335aa7141e96b59d63e3ccee95c3a2c47d026540c2af42dc9533d5fd81827d1679ad187aeaf37834915e75b147a9286806c8017516ba43dd051a5e0c + +PRIV: 3dff5e899475e7e91dd261322fab09980c52970de1da6e2e201660cc4fce7032f30162bac98447c4042fac05da448034629be2c6a58d30dfd578ba9fb5e3930b +PUB: f30162bac98447c4042fac05da448034629be2c6a58d30dfd578ba9fb5e3930b +MESSAGE: 938f0e77621bf3ea52c7c4911c5157c2d8a2a858093ef16aa9b107e69d98037ba139a3c382 +SIG: 5efe7a92ff9623089b3e3b78f352115366e26ba3fb1a416209bc029e9cadccd9f4affa333555a8f3a35a9d0f7c34b292cae77ec96fa3adfcaadee2d9ced8f805 + +PRIV: 9a6b847864e70cfe8ba6ab22fa0ca308c0cc8bec7141fbcaa3b81f5d1e1cfcfc34ad0fbdb2566507a81c2b1f8aa8f53dccaa64cc87ada91b903e900d07eee930 +PUB: 34ad0fbdb2566507a81c2b1f8aa8f53dccaa64cc87ada91b903e900d07eee930 +MESSAGE: 838367471183c71f7e717724f89d401c3ad9863fd9cc7aa3cf33d3c529860cb581f3093d87da +SIG: 2ab255169c489c54c732232e37c87349d486b1eba20509dbabe7fed329ef08fd75ba1cd145e67b2ea26cb5cc51cab343eeb085fe1fd7b0ec4c6afcd9b979f905 + +PRIV: 575be07afca5d063c238cd9b8028772cc49cda34471432a2e166e096e2219efc94e5eb4d5024f49d7ebf79817c8de11497dc2b55622a51ae123ffc749dbb16e0 +PUB: 94e5eb4d5024f49d7ebf79817c8de11497dc2b55622a51ae123ffc749dbb16e0 +MESSAGE: 33e5918b66d33d55fe717ca34383eae78f0af82889caf6696e1ac9d95d1ffb32cba755f9e3503e +SIG: 58271d44236f3b98c58fd7ae0d2f49ef2b6e3affdb225aa3ba555f0e11cc53c23ad19baf24346590d05d7d5390582082cf94d39cad6530ab93d13efb39279506 + +PRIV: 15ffb45514d43444d61fcb105e30e135fd268523dda20b82758b1794231104411772c5abc2d23fd2f9d1c3257be7bc3c1cd79cee40844b749b3a7743d2f964b8 +PUB: 1772c5abc2d23fd2f9d1c3257be7bc3c1cd79cee40844b749b3a7743d2f964b8 +MESSAGE: da9c5559d0ea51d255b6bd9d7638b876472f942b330fc0e2b30aea68d77368fce4948272991d257e +SIG: 6828cd7624e793b8a4ceb96d3c2a975bf773e5ff6645f353614058621e58835289e7f31f42dfe6af6d736f2644511e320c0fa698582a79778d18730ed3e8cb08 + +PRIV: fe0568642943b2e1afbfd1f10fe8df87a4236bea40dce742072cb21886eec1fa299ebd1f13177dbdb66a912bbf712038fdf73b06c3ac020c7b19126755d47f61 +PUB: 299ebd1f13177dbdb66a912bbf712038fdf73b06c3ac020c7b19126755d47f61 +MESSAGE: c59d0862ec1c9746abcc3cf83c9eeba2c7082a036a8cb57ce487e763492796d47e6e063a0c1feccc2d +SIG: d59e6dfcc6d7e3e2c58dec81e985d245e681acf6594a23c59214f7bed8015d813c7682b60b3583440311e72a8665ba2c96dec23ce826e160127e18132b030404 + +PRIV: 5ecb16c2df27c8cf58e436a9d3affbd58e9538a92659a0f97c4c4f994635a8cada768b20c437dd3aa5f84bb6a077ffa34ab68501c5352b5cc3fdce7fe6c2398d +PUB: da768b20c437dd3aa5f84bb6a077ffa34ab68501c5352b5cc3fdce7fe6c2398d +MESSAGE: 56f1329d9a6be25a6159c72f12688dc8314e85dd9e7e4dc05bbecb7729e023c86f8e0937353f27c7ede9 +SIG: 1c723a20c6772426a670e4d5c4a97c6ebe9147f71bb0a415631e44406e290322e4ca977d348fe7856a8edc235d0fe95f7ed91aefddf28a77e2c7dbfd8f552f0a + +PRIV: d599d637b3c30a82a9984e2f758497d144de6f06b9fba04dd40fd949039d7c846791d8ce50a44689fc178727c5c3a1c959fbeed74ef7d8e7bd3c1ab4da31c51f +PUB: 6791d8ce50a44689fc178727c5c3a1c959fbeed74ef7d8e7bd3c1ab4da31c51f +MESSAGE: a7c04e8ba75d0a03d8b166ad7a1d77e1b91c7aaf7befdd99311fc3c54a684ddd971d5b3211c3eeaff1e54e +SIG: ebf10d9ac7c96108140e7def6fe9533d727646ff5b3af273c1df95762a66f32b65a09634d013f54b5dd6011f91bc336ca8b355ce33f8cfbec2535a4c427f8205 + +PRIV: 30ab8232fa7018f0ce6c39bd8f782fe2e159758bb0f2f4386c7f28cfd2c85898ecfb6a2bd42f31b61250ba5de7e46b4719afdfbc660db71a7bd1df7b0a3abe37 +PUB: ecfb6a2bd42f31b61250ba5de7e46b4719afdfbc660db71a7bd1df7b0a3abe37 +MESSAGE: 63b80b7956acbecf0c35e9ab06b914b0c7014fe1a4bbc0217240c1a33095d707953ed77b15d211adaf9b97dc +SIG: 9af885344cc7239498f712df80bc01b80638291ed4a1d28baa5545017a72e2f65649ccf9603da6eb5bfab9f5543a6ca4a7af3866153c76bf66bf95def615b00c + +PRIV: 0ddcdc872c7b748d40efe96c2881ae189d87f56148ed8af3ebbbc80324e38bdd588ddadcbcedf40df0e9697d8bb277c7bb1498fa1d26ce0a835a760b92ca7c85 +PUB: 588ddadcbcedf40df0e9697d8bb277c7bb1498fa1d26ce0a835a760b92ca7c85 +MESSAGE: 65641cd402add8bf3d1d67dbeb6d41debfbef67e4317c35b0a6d5bbbae0e034de7d670ba1413d056f2d6f1de12 +SIG: c179c09456e235fe24105afa6e8ec04637f8f943817cd098ba95387f9653b2add181a31447d92d1a1ddf1ceb0db62118de9dffb7dcd2424057cbdff5d41d0403 + +PRIV: 89f0d68299ba0a5a83f248ae0c169f8e3849a9b47bd4549884305c9912b46603aba3e795aab2012acceadd7b3bd9daeeed6ff5258bdcd7c93699c2a3836e3832 +PUB: aba3e795aab2012acceadd7b3bd9daeeed6ff5258bdcd7c93699c2a3836e3832 +MESSAGE: 4f1846dd7ad50e545d4cfbffbb1dc2ff145dc123754d08af4e44ecc0bc8c91411388bc7653e2d893d1eac2107d05 +SIG: 2c691fa8d487ce20d5d2fa41559116e0bbf4397cf5240e152556183541d66cf753582401a4388d390339dbef4d384743caa346f55f8daba68ba7b9131a8a6e0b + +PRIV: 0a3c1844e2db070fb24e3c95cb1cc6714ef84e2ccd2b9dd2f1460ebf7ecf13b172e409937e0610eb5c20b326dc6ea1bbbc0406701c5cd67d1fbde09192b07c01 +PUB: 72e409937e0610eb5c20b326dc6ea1bbbc0406701c5cd67d1fbde09192b07c01 +MESSAGE: 4c8274d0ed1f74e2c86c08d955bde55b2d54327e82062a1f71f70d536fdc8722cdead7d22aaead2bfaa1ad00b82957 +SIG: 87f7fdf46095201e877a588fe3e5aaf476bd63138d8a878b89d6ac60631b3458b9d41a3c61a588e1db8d29a5968981b018776c588780922f5aa732ba6379dd05 + +PRIV: c8d7a8818b98dfdb20839c871cb5c48e9e9470ca3ad35ba2613a5d3199c8ab2390d2efbba4d43e6b2b992ca16083dbcfa2b322383907b0ee75f3e95845d3c47f +PUB: 90d2efbba4d43e6b2b992ca16083dbcfa2b322383907b0ee75f3e95845d3c47f +MESSAGE: 783e33c3acbdbb36e819f544a7781d83fc283d3309f5d3d12c8dcd6b0b3d0e89e38cfd3b4d0885661ca547fb9764abff +SIG: fa2e994421aef1d5856674813d05cbd2cf84ef5eb424af6ecd0dc6fdbdc2fe605fe985883312ecf34f59bfb2f1c9149e5b9cc9ecda05b2731130f3ed28ddae0b + +PRIV: b482703612d0c586f76cfcb21cfd2103c957251504a8c0ac4c86c9c6f3e429fffd711dc7dd3b1dfb9df9704be3e6b26f587fe7dd7ba456a91ba43fe51aec09ad +PUB: fd711dc7dd3b1dfb9df9704be3e6b26f587fe7dd7ba456a91ba43fe51aec09ad +MESSAGE: 29d77acfd99c7a0070a88feb6247a2bce9984fe3e6fbf19d4045042a21ab26cbd771e184a9a75f316b648c6920db92b87b +SIG: 58832bdeb26feafc31b46277cf3fb5d7a17dfb7ccd9b1f58ecbe6feb979666828f239ba4d75219260ecac0acf40f0e5e2590f4caa16bbbcd8a155d347967a607 + +PRIV: 84e50dd9a0f197e3893c38dbd91fafc344c1776d3a400e2f0f0ee7aa829eb8a22c50f870ee48b36b0ac2f8a5f336fb090b113050dbcc25e078200a6e16153eea +PUB: 2c50f870ee48b36b0ac2f8a5f336fb090b113050dbcc25e078200a6e16153eea +MESSAGE: f3992cde6493e671f1e129ddca8038b0abdb77bb9035f9f8be54bd5d68c1aeff724ff47d29344391dc536166b8671cbbf123 +SIG: 69e6a4491a63837316e86a5f4ba7cd0d731ecc58f1d0a264c67c89befdd8d3829d8de13b33cc0bf513931715c7809657e2bfb960e5c764c971d733746093e500 + +PRIV: b322d46577a2a991a4d1698287832a39c487ef776b4bff037a05c7f1812bdeeceb2bcadfd3eec2986baff32b98e7c4dbf03ff95d8ad5ff9aa9506e5472ff845f +PUB: eb2bcadfd3eec2986baff32b98e7c4dbf03ff95d8ad5ff9aa9506e5472ff845f +MESSAGE: 19f1bf5dcf1750c611f1c4a2865200504d82298edd72671f62a7b1471ac3d4a30f7de9e5da4108c52a4ce70a3e114a52a3b3c5 +SIG: c7b55137317ca21e33489ff6a9bfab97c855dc6f85684a70a9125a261b56d5e6f149c5774d734f2d8debfc77b721896a8267c23768e9badb910eef83ec258802 + +PRIV: 960cab5034b9838d098d2dcbf4364bec16d388f6376d73a6273b70f82bbc98c05e3c19f2415acf729f829a4ebd5c40e1a6bc9fbca95703a9376087ed0937e51a +PUB: 5e3c19f2415acf729f829a4ebd5c40e1a6bc9fbca95703a9376087ed0937e51a +MESSAGE: f8b21962447b0a8f2e4279de411bea128e0be44b6915e6cda88341a68a0d818357db938eac73e0af6d31206b3948f8c48a447308 +SIG: 27d4c3a1811ef9d4360b3bdd133c2ccc30d02c2f248215776cb07ee4177f9b13fc42dd70a6c2fed8f225c7663c7f182e7ee8eccff20dc7b0e1d5834ec5b1ea01 + +PRIV: eb77b2638f23eebc82efe45ee9e5a0326637401e663ed029699b21e6443fb48e9ef27608961ac711de71a6e2d4d4663ea3ecd42fb7e4e8627c39622df4af0bbc +PUB: 9ef27608961ac711de71a6e2d4d4663ea3ecd42fb7e4e8627c39622df4af0bbc +MESSAGE: 99e3d00934003ebafc3e9fdb687b0f5ff9d5782a4b1f56b9700046c077915602c3134e22fc90ed7e690fddd4433e2034dcb2dc99ab +SIG: 18dc56d7bd9acd4f4daa78540b4ac8ff7aa9815f45a0bba370731a14eaabe96df8b5f37dbf8eae4cb15a64b244651e59d6a3d6761d9e3c50f2d0cbb09c05ec06 + +PRIV: b625aa89d3f7308715427b6c39bbac58effd3a0fb7316f7a22b99ee5922f2dc965a99c3e16fea894ec33c6b20d9105e2a04e2764a4769d9bbd4d8bacfeab4a2e +PUB: 65a99c3e16fea894ec33c6b20d9105e2a04e2764a4769d9bbd4d8bacfeab4a2e +MESSAGE: e07241dbd3adbe610bbe4d005dd46732a4c25086ecb8ec29cd7bca116e1bf9f53bfbf3e11fa49018d39ff1154a06668ef7df5c678e6a +SIG: 01bb901d83b8b682d3614af46a807ba2691358feb775325d3423f549ff0aa5757e4e1a74e9c70f9721d8f354b319d4f4a1d91445c870fd0ffb94fed64664730d + +PRIV: b1c9f8bd03fe82e78f5c0fb06450f27dacdf716434db268275df3e1dc177af427fc88b1f7b3f11c629be671c21621f5c10672fafc8492da885742059ee6774cf +PUB: 7fc88b1f7b3f11c629be671c21621f5c10672fafc8492da885742059ee6774cf +MESSAGE: 331da7a9c1f87b2ac91ee3b86d06c29163c05ed6f8d8a9725b471b7db0d6acec7f0f702487163f5eda020ca5b493f399e1c8d308c3c0c2 +SIG: 4b229951ef262f16978f7914bc672e7226c5f8379d2778c5a2dc0a2650869f7acfbd0bcd30fdb0619bb44fc1ae5939b87cc318133009c20395b6c7eb98107701 + +PRIV: 6d8cdb2e075f3a2f86137214cb236ceb89a6728bb4a200806bf3557fb78fac6957a04c7a5113cddfe49a4c124691d46c1f9cdc8f343f9dcb72a1330aeca71fda +PUB: 57a04c7a5113cddfe49a4c124691d46c1f9cdc8f343f9dcb72a1330aeca71fda +MESSAGE: 7f318dbd121c08bfddfeff4f6aff4e45793251f8abf658403358238984360054f2a862c5bb83ed89025d2014a7a0cee50da3cb0e76bbb6bf +SIG: a6cbc947f9c87d1455cf1a708528c090f11ecee4855d1dbaadf47454a4de55fa4ce84b36d73a5b5f8f59298ccf21992df492ef34163d87753b7e9d32f2c3660b + +PRIV: 47adc6d6bf571ee9570ca0f75b604ac43e303e4ab339ca9b53cacc5be45b2ccba3f527a1c1f17dfeed92277347c9f98ab475de1755b0ab546b8a15d01b9bd0be +PUB: a3f527a1c1f17dfeed92277347c9f98ab475de1755b0ab546b8a15d01b9bd0be +MESSAGE: ce497c5ff5a77990b7d8f8699eb1f5d8c0582f70cb7ac5c54d9d924913278bc654d37ea227590e15202217fc98dac4c0f3be2183d133315739 +SIG: 4e8c318343c306adbba60c92b75cb0569b9219d8a86e5d57752ed235fc109a43c2cf4e942cacf297279fbb28675347e08027722a4eb7395e00a17495d32edf0b + +PRIV: 3c19b50b0fe47961719c381d0d8da9b9869d312f13e3298b97fb22f0af29cbbe0f7eda091499625e2bae8536ea35cda5483bd16a9c7e416b341d6f2c83343612 +PUB: 0f7eda091499625e2bae8536ea35cda5483bd16a9c7e416b341d6f2c83343612 +MESSAGE: 8ddcd63043f55ec3bfc83dceae69d8f8b32f4cdb6e2aebd94b4314f8fe7287dcb62732c9052e7557fe63534338efb5b6254c5d41d2690cf5144f +SIG: efbd41f26a5d62685516f882b6ec74e0d5a71830d203c231248f26e99a9c6578ec900d68cdb8fa7216ad0d24f9ecbc9ffa655351666582f626645395a31fa704 + +PRIV: 34e1e9d539107eb86b393a5ccea1496d35bc7d5e9a8c5159d957e4e5852b3eb00ecb2601d5f7047428e9f909883a12420085f04ee2a88b6d95d3d7f2c932bd76 +PUB: 0ecb2601d5f7047428e9f909883a12420085f04ee2a88b6d95d3d7f2c932bd76 +MESSAGE: a6d4d0542cfe0d240a90507debacabce7cbbd48732353f4fad82c7bb7dbd9df8e7d9a16980a45186d8786c5ef65445bcc5b2ad5f660ffc7c8eaac0 +SIG: 32d22904d3e7012d6f5a441b0b4228064a5cf95b723a66b048a087ecd55920c31c204c3f2006891a85dd1932e3f1d614cfd633b5e63291c6d8166f3011431e09 + +PRIV: 49dd473ede6aa3c866824a40ada4996c239a20d84c9365e4f0a4554f8031b9cf788de540544d3feb0c919240b390729be487e94b64ad973eb65b4669ecf23501 +PUB: 788de540544d3feb0c919240b390729be487e94b64ad973eb65b4669ecf23501 +MESSAGE: 3a53594f3fba03029318f512b084a071ebd60baec7f55b028dc73bfc9c74e0ca496bf819dd92ab61cd8b74be3c0d6dcd128efc5ed3342cba124f726c +SIG: d2fde02791e720852507faa7c3789040d9ef86646321f313ac557f4002491542dd67d05c6990cdb0d495501fbc5d5188bfbb84dc1bf6098bee0603a47fc2690f + +PRIV: 331c64da482b6b551373c36481a02d8136ecadbb01ab114b4470bf41607ac57152a00d96a3148b4726692d9eff89160ea9f99a5cc4389f361fed0bb16a42d521 +PUB: 52a00d96a3148b4726692d9eff89160ea9f99a5cc4389f361fed0bb16a42d521 +MESSAGE: 20e1d05a0d5b32cc8150b8116cef39659dd5fb443ab15600f78e5b49c45326d9323f2850a63c3808859495ae273f58a51e9de9a145d774b40ba9d753d3 +SIG: 22c99aa946ead39ac7997562810c01c20b46bd610645bd2d56dcdcbaacc5452c74fbf4b8b1813b0e94c30d808ce5498e61d4f7ccbb4cc5f04dfc6140825a9600 + +PRIV: 5c0b96f2af8712122cf743c8f8dc77b6cd5570a7de13297bb3dde1886213cce20510eaf57d7301b0e1d527039bf4c6e292300a3a61b4765434f3203c100351b1 +PUB: 0510eaf57d7301b0e1d527039bf4c6e292300a3a61b4765434f3203c100351b1 +MESSAGE: 54e0caa8e63919ca614b2bfd308ccfe50c9ea888e1ee4446d682cb5034627f97b05392c04e835556c31c52816a48e4fb196693206b8afb4408662b3cb575 +SIG: 06e5d8436ac7705b3a90f1631cdd38ec1a3fa49778a9b9f2fa5ebea4e7d560ada7dd26ff42fafa8ba420323742761aca6904940dc21bbef63ff72daab45d430b + +PRIV: de84f2435f78dedb87da18194ff6a336f08111150def901c1ac418146eb7b54ad3a92bbaa4d63af79c2226a7236e6427428df8b362427f873023b22d2f5e03f2 +PUB: d3a92bbaa4d63af79c2226a7236e6427428df8b362427f873023b22d2f5e03f2 +MESSAGE: 205135ec7f417c858072d5233fb36482d4906abd60a74a498c347ff248dfa2722ca74e879de33169fadc7cd44d6c94a17d16e1e630824ba3e0df22ed68eaab +SIG: 471ebc973cfdaceec07279307368b73be35bc6f8d8312b70150567369096706dc471126c3576f9f0eb550df5ac6a525181110029dd1fc11174d1aaced48d630f + +PRIV: ba4d6e67b2ce67a1e44326494044f37a442f3b81725bc1f9341462718b55ee20f73fa076f84b6db675a5fda5ad67e351a41e8e7f29add16809ca010387e9c6cc +PUB: f73fa076f84b6db675a5fda5ad67e351a41e8e7f29add16809ca010387e9c6cc +MESSAGE: 4bafdac9099d4057ed6dd08bcaee8756e9a40f2cb9598020eb95019528409bbea38b384a59f119f57297bfb2fa142fc7bb1d90dbddde772bcde48c5670d5fa13 +SIG: 57b9d2a711207f837421bae7dd48eaa18eab1a9a70a0f1305806fee17b458f3a0964b302d1834d3e0ac9e8496f000b77f0083b41f8a957e632fbc7840eee6a06 + +PRIV: 0d131c45aea6f3a4e1b9a2cf60c55104587efaa846b222bf0a7b74ce7a3f63b63c6729dbe93b499c4e614a2f21beb729438d498e1ac8d14cbad9717a5dbd97cd +PUB: 3c6729dbe93b499c4e614a2f21beb729438d498e1ac8d14cbad9717a5dbd97cd +MESSAGE: b4291d08b88fb2f7b8f99d0dce40079fcbab718bbd8f4e8eabc3c1428b6a071fb2a3c8eba1cacccfa871b365c708bef2685bc13e6b80bc14a5f249170ffc56d014 +SIG: a9c5ee86fb06d9e46b379c32dda7c92c9c13db274dc24116fbdd878696045488cc75a52fff67d1a5113d06e333ac67ff664b3f2a405fa1d14dd5bbb97409b606 + +PRIV: a75e3b6b4170e444781be4eeac3e0fdaa4b4356f705486bcb071a325ae071fba993d38a7d72f0aee15ff6f4fdc37ca7724fd1373a3766b275dbc77e647980e0a +PUB: 993d38a7d72f0aee15ff6f4fdc37ca7724fd1373a3766b275dbc77e647980e0a +MESSAGE: 4037866f6548b01cc6bcf3a940e3945aa2d188b4b7f182aa77ec4d6b0428ab5b84d85df192a5a38ada089d76fa26bf67736a7041a5eb8f0c5719eb396693c45160f8 +SIG: a5db4d3d3329abe3697959e6b5947ea8601b03ef8e1d6fe202144931272ca0a09b5eb0f390572ea7ef03c6131e9de5f16bf0b034244f7e104ff5311bbf663a0d + +PRIV: bcbcf561ecc05a41c7d7e55e696d32ce39b4d03c1f5f3f3a8927fe5e62e844b24ddf53fad6a7a9ed30f3afecca136fd7843b72c243090891ae4021a32cadff1a +PUB: 4ddf53fad6a7a9ed30f3afecca136fd7843b72c243090891ae4021a32cadff1a +MESSAGE: 6f6716b6784740980aebc3248807e31c1286ac7b681c00b66c88ff7a336d441fa5c3eb256d20cf6d1ac92ccfe4be6dcc41b1aff846d360c243001cabdfbf1a9b240455 +SIG: 9ff15115f6661f3211d7a40764967629ba6a5263951bdc3c6a4c90d070f7be00024b80d83b6bc27587fcff5f5ccc0eb3cde1497cf56895147a063f61f08adf0b + +PRIV: 210532805fa9cc9be916d213cac374e3cd6fc2602a544d0c1ce29d30105d69ab10699e499be99e2b11b98f6f86b67cdc4ccf69f3c53ce094875647d2d0d0ecc5 +PUB: 10699e499be99e2b11b98f6f86b67cdc4ccf69f3c53ce094875647d2d0d0ecc5 +MESSAGE: 9fc4d28cfd25e6c0c5e724e19ca39d71e53bf4aa2796c54c3351f108fc70f2611a62e0ab90af6ade5216788e9eb2a873059b1e79d7d59debd68f2d4d80ffe31bf74b928c +SIG: 4c2d31d5bbc42e026dc1e079ecc4dd072c5d2cce65e3db8d8a1dd9057faa0371727f727231a0f060fa27097533b6db3b8f6252f2793d75662caadf5f0fcc710e + +PRIV: 185d64b69479e0ba0a5844a10ad84125ba11c4b40d63eda2c57afc7e019c8e0ca5764f6398a5ae2266a38f9714533c4bbd8d07826f63e204cbac374b0acef1bd +PUB: a5764f6398a5ae2266a38f9714533c4bbd8d07826f63e204cbac374b0acef1bd +MESSAGE: 4a0824fe70d4315413d0a0cafbf4f5fe117d5e07e1c3a4effb9d0ae91490234878ccf6792a91f68c6a520de16071f08abe35dc5ea428f1957b663371ce24c609dd55b8f493 +SIG: 43e0387da5ba09a190f6e7b2680578d889769bcc445e5ef571b492871c155c5b9f620bfacfbf2df1fd87444604b71b2e237baaa7ee2093ede4a601edf883e307 + +PRIV: cfa9d9164b3c4f6f722635d2066cd7ea5e5533d2c74f8add669c371faa47642641169a66f9a63f285782a6c2db81cc3f70b3ada21a68c84745c88a74c3b0a2de +PUB: 41169a66f9a63f285782a6c2db81cc3f70b3ada21a68c84745c88a74c3b0a2de +MESSAGE: 757621b1675db7cacef7f2782587ff3af51a3ef2f4bcf9279c4ce94002e1f00424bf0eb621982cc85cb4d171e564a0c2f6e3567a1aae2cddb7e9b25f47dc20a51050542969ca +SIG: 01d7c9b5701af71e2f4877ffc9b7b5305f52816d4458e37e41c7719fac1d76a01fff3f50fe1a5875ccc3fb70001c947a33fc8b207de13572ccdb8ba98933ab01 + +PRIV: 1acb4a256c2f8993ca24de1e0014606d668b5e756032d269f1d24d351c8eea4acbbdcd8cbc885ab43a057e5f9579f1161954159e7b562ea26cd9a43c88d3f96d +PUB: cbbdcd8cbc885ab43a057e5f9579f1161954159e7b562ea26cd9a43c88d3f96d +MESSAGE: c46a6d61aa0aed1c1d8547a70b89b7196475d5a4870881b1ecd0f0cb9c745f8a2adc8024e2dc55b53aa5d383a81aabc1a47e8d07d00b7f0b56ceddbfb1f424bb5c02184678a666 +SIG: 05aa76f7fe51892303d78914715995e7d768ff7714ce270f175e56af17ae018d3fa939f5f620de82bcd1549687b205c7871203e624238c4e309fab7f92fbaa05 + +PRIV: ace3c46424823622979fc3a84a7da69c1d527d8312e8fb018375bd3a96c29c18937cf34136d9e1cce0de11b12c70cbfb7455448421e92c82e7c40934bff8c676 +PUB: 937cf34136d9e1cce0de11b12c70cbfb7455448421e92c82e7c40934bff8c676 +MESSAGE: a9f137bc9021bf105aee25be21cd9ee5b3547cf10cc5f98476fb588bd70e2d6d6b0834e842e4ee94303cf96b09c1715381b36e14a491b80f895ea421b8ec2b1d3c187e02935c5526 +SIG: feb8896dd3fe6001ffea171b37b788a69f7f850193a63406f56376dd263d099aef80ece67e2c43f40eca462c6b71e79406b18db74ae5d49844e3b132bc2a1307 + +PRIV: 88f681934e33c35c07dc6e5a832942ae3d59903ccde2f76ccb7587cea7ec41b66a4e8aa5adb63d22fd7b14a26fdb03b7c8aa6ccd5a196f2c54b0465adb5092e1 +PUB: 6a4e8aa5adb63d22fd7b14a26fdb03b7c8aa6ccd5a196f2c54b0465adb5092e1 +MESSAGE: 6e8bac1f853b81fef94707e18cc61c6f0a9cbc2a41d078dcc83fc0229c7f8dbe6dbdd90854b1f1ae2b9f2b120b86a8786b4e78ce23ab86baaf88754af0f3d88881dae0bc5261bfd038 +SIG: 45b27bf1b9eac06b62b686f6d546563b2dfe5b175dbef32bf78c35a16c958a9d4f26d291de9bb2066c0a286113cc09172d40a36d4cbd951708860226eb30cd05 + +PRIV: 48050a6e0158f6ad253412e4497cff62d5ee555edffe59e4dc401522813295ce975e010abb9a3e56659137b0506057f283982f886ca172c7bc2c500ed9bd26c1 +PUB: 975e010abb9a3e56659137b0506057f283982f886ca172c7bc2c500ed9bd26c1 +MESSAGE: ed6eec29fb7049dff707f0a4426ebc8f5b350e95870b9d6198c8139e9c3e1e409937d1a858a0dea482a5cb1a854ed3b5a9397acb63bff6b64039ef2eb1159e99858310bbbd86125c3e0e +SIG: 7216ab60c35168187d0fce4753c86e80058d540b76bf95843a5898841060a99a44de6f439625a3f6365f59c377bf45909bbfef5c50b25f3194e5fbd34ea5e706 + +PRIV: 18d13d0c00e8e3386a5cfb30a9e79fe88b1861ed2d1201eb170038e194770403a4afc833401876090d9b880c41267d68cbbeeaa38afb20884e27328f3b7f535e +PUB: a4afc833401876090d9b880c41267d68cbbeeaa38afb20884e27328f3b7f535e +MESSAGE: 910f6c272dd97931ac47310d244cadb43251365e02ba9f6a5b3c3226be9d7d3a74a2ba4906e8e71a4bf3d3556ebdfc666cd6b12f20c4a00834b88fbb244575199286b0b9344cf334aff007 +SIG: 033988154c5d79d2510be83e778015dfe2fb85b8111f7ec139918b5400e3d656ee80a9f5c9072b5b467a5cc5a57cc8ad1062b5bff10862d9d369dde2cc966701 + +PRIV: 4adc8c28646a93a817293a14d29b48e2c6d712a68993547a5c5e4d1452acbc3a7f40473628f23fc0dff0021afd487740d4916a9122e6c97d36433e5ebf04f88c +PUB: 7f40473628f23fc0dff0021afd487740d4916a9122e6c97d36433e5ebf04f88c +MESSAGE: 09fb5501f1688f80a0ab9e22d778ae130acaf74d7f5185b4da198c6b9edac4302e2b753e578766e17d4056dc40d95cf4ca8bcc6565795e97d68bcda79fa77c493397716356164caab5d19cfd +SIG: 6d3b4e90ec408311f9b15b9253d3d95c5d152620c260d56302555a8804a5104ba5e8d29ee108e764a64219297298ab7674bbca784dee28773b34e185a386c208 + +PRIV: f26e1c84697a4908151b447dcf6c7c7a38b04081db9e7c7738e6fec900bed0c1a86e1422c1235ff8e1aa083470d5e42288cb007ab50e795dd0b4ff87394966c4 +PUB: a86e1422c1235ff8e1aa083470d5e42288cb007ab50e795dd0b4ff87394966c4 +MESSAGE: 54ed47606a1487c2f900cefb6e899dbaf6c31cc88ebe3558b83b93f6d422c31e888e48e520eeaedd7e554a9cd40c2c519d533b6144cee484c389e976b1e4022b50e7dbb87ead7e541a2004daf7 +SIG: 44f3344b9566c9dfd22d6198e1cbf95d9e28f2982fc7f166ab25dda30c46f768c558e0394fb9ab3e1d4db4cf487c17641a13f3f48939e0c64827a75103c57406 + +PRIV: cc0c33f3a86f5a17d30c186ce0f3b740bafa5fe3c7090f143541e2b2c1e534bc967a71c7cf9b82cc78cbe109104d8b438a8d1fd71d260d029046a9a4526866ff +PUB: 967a71c7cf9b82cc78cbe109104d8b438a8d1fd71d260d029046a9a4526866ff +MESSAGE: 1944e5e155d75e0d0be92e1be14cec370ad13791f2bfd40f271214e94fcf213c71bc20d7ce0c7584421ac4efc451883cc3f4956f21f73a4216720438bc38ff2cfdf3709905a50a9d94b1d9e7932b +SIG: e277b3dd655c33ff75fa920af1fcc859401e6c7a6ef4c6bfbfac5069638f19ca115baf13c09c82af793facb6abd0cd58e8481b08c1b68ad7a2665c4a614a2806 + +PRIV: f0bc979375a7073068dba7f6c094db6598b4e45df7d549583c22fded8048fa2eb42b6c57a78f1d90090a7181ab2ae09f426cbc2be96eb2cf27abc70d7d32a4b3 +PUB: b42b6c57a78f1d90090a7181ab2ae09f426cbc2be96eb2cf27abc70d7d32a4b3 +MESSAGE: 27ab3049b5c6351f6cfe38b13a059f5037257ee3d65d6079656856edc876ea081fd8a9480466f8839478088466f51ecbfaf2d65def25f0c4dd8d08588202812232f57945df8a6fa161ed8c0343b583 +SIG: 19dbc3027f9fae707deb76f588f9fd07aa8eae29bd4e1d04c2c984388286b3b122248a6c03ed67eca35df4db3dc1e4237f267892518497d9552a21de19b5140f + +PRIV: 3022975f298c0ad5ddbe90954f20e63ae0c0d2704cf13c221f5b3720af4dba32b845bce38e26ab027b8247463d437a71bbddca2a2381d81fad4c297df9140bd5 +PUB: b845bce38e26ab027b8247463d437a71bbddca2a2381d81fad4c297df9140bd5 +MESSAGE: 9aa19a595d989378cdc06891887ef5f9c246e5f83c0b658710673e4e7db760c76354c4f5d1e90db04a23b4fb434c69384593d010e312b11d299c9f97482de887cecfe82ea723bca79a1bd64d03ef19ee +SIG: ae14a860fad0051b3eb72b3721a82f7b9546b2867261e2b7b638979e2561bdeb89b600768f82450a66c8b0481283fa21cb6c53bde350effb68a7d1114bfdb203 + +PRIV: 0f710b6c481f71449589753312ef64932b4652ebe0e07597f7da1c4f3dcffb806973ff2932ccddfc1d16c4c0da50c8b29fe6452d1ee84d52064ebf3d628d403e +PUB: 6973ff2932ccddfc1d16c4c0da50c8b29fe6452d1ee84d52064ebf3d628d403e +MESSAGE: 85d85744ad55e9ef9a65ca91e85c8a4f80e4c58f8e4e9354e833986098b7d9fe9fdc0dedb0d75d2539fba00034fc0c2e84344d1edaa09d4f63d5546d67803dd6b54ddcc0b1d3f2582dd75289e31de42e69 +SIG: 02a8d26aee11420fb4f09d1163e14b867df7c6f6c8f8dc7a78034659f0401cad0aa90397efdd0704b798db1936503026e2a1adc297e27974d4be312a3753f804 + +PRIV: 7a05f121f60112dd16fee8c91bc2a11479f4b67ee33456042c8de167fc588017b3b05be989cea7197505d4b54335e5e1d77a4b52ba7282604bbc1cf6c4e87a6c +PUB: b3b05be989cea7197505d4b54335e5e1d77a4b52ba7282604bbc1cf6c4e87a6c +MESSAGE: d9c59e8cc4ede537be2122ab492a5b915a9b0a114b2ade356fc0457ef98722d5f567b86211e28369d14168ec4a3c804076e154adc70a668cf64a20d13cf190d115cd688d036e46938251df4964dc3517b10c +SIG: d30ce8a322b450a2fb1afd329cec8559ccf112bd83965f9ec4736270a0914e061196bf5209778c9f8ccf39c4668bbf0e1363f81afe45dd74e80d5875ddbf6f01 + +PRIV: bf381f8dfb5d0c6d64e416ac23e0d0fcb86ebb899b1d146abd911b92a7808eb6863fad8d1f1bc630a15f6fe8ecefe6b4497b60b21ae8830da46742045fef156f +PUB: 863fad8d1f1bc630a15f6fe8ecefe6b4497b60b21ae8830da46742045fef156f +MESSAGE: 8654f2f5c6dcd2cfcbb6ed8d2bc5fb5fec53e3effb0de65aac507fa56c897732395aa09946d3b6586a92edd6dc99315e1ba74c6a0247c4ba7760b948eb3c0932d9fe1f0e9fea6eb61a548a9ab48ffdf1547329 +SIG: 99b75378738fcac8067669e8509b5d2607e1ef76af9004e13fe5d3932df60b168216f58565340fa4d638055a89044ee7d45e2bd082a53382289a34700648980e + +PRIV: 36983241a0a8e60ce02a61b3fafab15a7313a5a270d015b9c9ec070dc42deeda6647984d42b9a5b3b1afa3b7f8f49d4c2b05e38984e99cea8fd68235d2ae4627 +PUB: 6647984d42b9a5b3b1afa3b7f8f49d4c2b05e38984e99cea8fd68235d2ae4627 +MESSAGE: cebb9e404451818253c0392a4554ee7323c5d5b8b226775700b806ed5b91337916ea7ecbc3d4103fc65e5372ae7e5f9ba2d8f5aee24ccf6e631ae20c4af9b5f728cdf89e8189def1a5b3d35347aa203525ea1d2e +SIG: ee37df8af422f91f85dfe43efe79f62378068ccdbaf3916eecbc3adfed0508bdebaf5ce06b3bc279f78087f0db8db3c6823edfb32c12217830be723d8872b30c + +PRIV: d06899f93a408dacb41c969718346f1e289bb5ea65e283ff79c705a074517c3546bf2a08a076c47d7f11b733f8141c355363ed85d7def26ba6a0ce15ac5f2be8 +PUB: 46bf2a08a076c47d7f11b733f8141c355363ed85d7def26ba6a0ce15ac5f2be8 +MESSAGE: 0864c39ac4fda8eb9048597bd40be0401021fd2dd3a3390a8facce984b260a13fa2c7cfc00d192fadf134a0ad5a181ee89eff0c795eaa0fbfe2f3b26115d07168db42ed21a51303b1958e4a42dc065b22ce48f17a6 +SIG: 6f89de92a66bc5f4144339124950bdf588144cb372f6736245351c9476becc59a258f9a933ffff2bef4b46cd1057395225799fd09dede6823db0e325dbc8140d + +PRIV: eebca7966970ee9f2cc4d74c6f1d8e0ebff7c45aebad349fb9f86df628dfff0e89101e0309f767e64ae9c98c4a5d8d2328fb3ef262d082f49b64ca209e1990f6 +PUB: 89101e0309f767e64ae9c98c4a5d8d2328fb3ef262d082f49b64ca209e1990f6 +MESSAGE: 0fac790adb9f59e5cb0ddcb2b667172f2a21034d93bcaddf188606fa9e776db33a8fcc6bd7f5567883fc0de351aa9afaa36d2075b1ba853bada849b8661d5c8154e7b0afea656dd15e01a9c5ba21589b02f8fc5481c2 +SIG: 7d447ee5328c9fe7f11936cc42998754a56cd1d2a6951af4fee7c4a8eb319d4923707c793c55d79067f822d5b16bb5776e38dffabc67237a916a81a63339b003 + +PRIV: 3820b6b15939d0afe18c9cb3d9a2a08f167dd458eb6c7e3f1558b0c6db4c689080b85c6559fea8b400e1999cc5bfed507ad7fc294cd9ba0ce2dd2584a91089b0 +PUB: 80b85c6559fea8b400e1999cc5bfed507ad7fc294cd9ba0ce2dd2584a91089b0 +MESSAGE: 3e5ad92d44b40e8614d8087c9c743de0c0861a07f1f5146d71cac2f3740024e841cc2d46027cf5d261d3ee7c1875b39551017b5fb1468114fc3e098a899cdbd558b39f098e156b6e9801ebcdd65fed56dbfcaf2c8c787b +SIG: 823ee2c0c8d87faa0ec0141e9ce08b51e57c839792d1fbd97a967207fd415849ebfb5dadb5a1dc2c0a8b7fc63fc354857b8c90c44720e13f45cd01e7aa23140c + +PRIV: 0d20fa4a37ff30c4dcc3e44ea7ac501137e5807e9781330ac310982cc3d39dbd67bb0a01bc8617b491eff1a326c1c70f7d0c5b95a5ad48241aedce1c6f0883cf +PUB: 67bb0a01bc8617b491eff1a326c1c70f7d0c5b95a5ad48241aedce1c6f0883cf +MESSAGE: 35e0f4b4a517f9c7aa4514f03e6d65f19b27c62cc069f6bf07dd6378bd6afe2b766560006cbd5730a00919ed11191fb0c8dac56e153fc1cea4bdce5046cccb717759a4083e1c16f740763264cc804de0d0e1a4b5a23067af +SIG: deab12ed82ba94b469ca98b66fa20444b4b7881c4f0f853409c9a1504a5b2b6d7860f26ada6bf73459b9cdb573c8017121338efa60f4148086d7a3a8ed59bb07 + +PRIV: bee161881d819b370d240d509ba46b06fb828e20310d9f6b309780703e98927b10854380de89162bfb9f7835a2716a3a6e0265671b250b389d01c3bcc03736b8 +PUB: 10854380de89162bfb9f7835a2716a3a6e0265671b250b389d01c3bcc03736b8 +MESSAGE: 5a6fe599b6b09b05c0ba6a622df3a92b3d376d24d04ea85ebe767bc2ec4d14e83e6937dc0b914b4809fdb607906841a6fd1dcdf61aaea8f9bb81b2ccaa32df412989ae53646680a71a211c8440eab0f1aec5e4fc00e6a2c96d +SIG: b07d072eb3831fae8a06effa9201797496dce126b8e11fef2fa07f664dc5cf3d4bf9c38a8b3c09fb5f14fa2deb219e7d852fdd27c7ba32d309942f2746dfe404 + +PRIV: 70150e9516164a3d7b7e8b6f255b65cac9f07459b32d11bb94b3d277208abc992328bec8e40351047882e8b43bc1ab085386fa47987e46ea87608814c5da713c +PUB: 2328bec8e40351047882e8b43bc1ab085386fa47987e46ea87608814c5da713c +MESSAGE: 77be8eceaab431a13c2a28d0d1556489d8c392fd7ae41157f7caf082cb54e45f08626be0076be844d38fde901a5eab0e8832d69dac22fb8507fb8ec4faf7c88fd26da308461afe385987972b5e760a34a5e18b9a82b4aaa529b7 +SIG: eda3f5033ea7953a0d583c6457522e84ad78445304d48e577d4d69e8641febe15248d8d90ce0944a8f801d39099bc77494bac4ce2a20b38369c6adfb71e03d0f + +PRIV: 3f87fcfdb421422a9c5fb98268313c15128c78844ef9eb3b3713fa77b6718903533ec59228374bd03a4699e3a8896b86182fcf8fc3085fdb8f5c4671524d6fe0 +PUB: 533ec59228374bd03a4699e3a8896b86182fcf8fc3085fdb8f5c4671524d6fe0 +MESSAGE: c00fed2d689468bcbacccd446e8d8f299e2a86925e62e59709afaf4857469ff1e006d00fa3e18a3615f8f06b6ebdff785dde58851d2c239038a0c344dce985bd1fc8deb4779ae5f8932e2f9ed5990b6472dbe4e6fef6917657e0b5 +SIG: f6519d7edb6134111974033f03b8d89e9c76caec8965a8e17cd45fff19de2615d73eccdb4a6664a8f0e23adf98988e96251bf26eb7a4ccaac1079f0a772f9b05 + +PRIV: 44ceef044ff998d4abeaaf374eb41d086718b63097b1e35f89634c14897132eae83c86677d03ed3a5e8c95f41f0b325ff4333702f2ff6936f57ff30aa31485c7 +PUB: e83c86677d03ed3a5e8c95f41f0b325ff4333702f2ff6936f57ff30aa31485c7 +MESSAGE: 8d3e2dec4644c7b51633b13e6375ca42ff9138465f43d7800c7313199f67c9cf1b520b1820bd630ecf1c992e2767b38eb5bbc441a4ab8d317db441db35a0fe3abe7a9e4541881c2d7b1a2612306959815d1da41267d9649dd4494ace +SIG: 554552d6b790d421d06b0a67f8e002ad7a1ed01c06cf00cbeaec2a268bda29f1183f0ceafc625fa5fdb847dc86fae1a20406e459d4a0177cb515220a568e0800 + +PRIV: 98ef2a44d4c8476dff05aa78dcf9c6dc086cb2f622a06745d60cbf223faaba6642fdb1daa39f0159119beec1bedf6f0394b26a2a29bd1fde081eccdadecc226a +PUB: 42fdb1daa39f0159119beec1bedf6f0394b26a2a29bd1fde081eccdadecc226a +MESSAGE: c8b5fcfc3c18c7d95957b668e91c731d50c7fcea4f9575bbf784625870e238df546e2cb1a19d2808dd5b230d3871fdec16100ee1fbf9b722fa3744a750a3b396b05f9c21b8c0f61ead57a78c5ecf72b579cfe88a3f404c8acf524f9ab9 +SIG: ab5e8724a3e6ff76058cfb214d574e04d05574ecdd4ffe8c07c7af396e882687c5d79ef1e62fbb4c5f1bd06b9bd897826edde0d111d918e8ef961ff2a00d7700 + +PRIV: 93a8c792a239c931917c114824a0174f8bc4ebbf98af8c7e321e0f5bea4015ec9b2eaa8a9c2c25ff4f6e13bb12bae5d06fda0eb1105fafae5880ff168740bb74 +PUB: 9b2eaa8a9c2c25ff4f6e13bb12bae5d06fda0eb1105fafae5880ff168740bb74 +MESSAGE: 901bf4e041caf16e04f2ffde8d6fe97e93d0900f6bc0fc09a9a0179d137b4b7788e57eb92766a9c634f35adb5c2988af1e86208f461998f59cfec99204b484fbcad3951e7ee4405523705d9739b44307db03f713fda78db421ef3121b3ba +SIG: cfe32c4435d911d772dc0727e78d689d0164c5069597cb441b22c1d26236479f1afd7089121b9ab4f61bbb1fae1ab42f7635a92a53784d7170916b703aa5cc09 + +PRIV: 7001fa0c4404c28aa5b5fcff30a961f21a22f5b85a9e382e07aea8a8924d0ec1daebb63c4d8f40ceba8ec35e3dd946a6b75bc74fcb29ade7b55eee3cc3aea5ca +PUB: daebb63c4d8f40ceba8ec35e3dd946a6b75bc74fcb29ade7b55eee3cc3aea5ca +MESSAGE: 44f48cfb02f08777a57873855f96be4c0291323f2739b275d90757a15472e5750436e0107408fe3026c00625689983f990eba9becbfce403ccd56356ad2741fd21445dfb23d76112e578b3395cf9d960955f1da8f399ca286f21390e25a59a +SIG: 64eac9ce87460618636b41fd2decc1673bfc48c5f479dfacb51e86686407374b1d10bf65d6d7474214d7770c9e5c7f806c80d53d48b720870e5e78f32e3a7e05 + +PRIV: 3adce3a3d3fbc977dd4b300a74749f13a3b04a5d73a2cd75a994e3195efebdac6ff19b1f18d64851d5c74845c6407f0bf596a52e385e020127e83e54cff5ac19 +PUB: 6ff19b1f18d64851d5c74845c6407f0bf596a52e385e020127e83e54cff5ac19 +MESSAGE: fe6c1a31068e332d12aab37d99406568deaa36bdb277cee55304633bd0a267a850e203bb3fabe5110bcc1ca4316698ab1cf00f0b0f1d97ef2180887f0ec0991e8c1111f0c0e1d2b712433ad2b3071bd66e1d81f7fa47bb4bb31ac0f059bb3cb8 +SIG: 7dda89f85b40539f5ad8c6de4953f7094a715b63dda30ec7cf65a785ceae5fc688707ee00be682cecbe7ee37d8fc39ee6d83c64409681708a0898a183b288a06 + +PRIV: 14803c1f23a47fcdd35e5d146e20ca630cd712c047d5330b652e31857acbc9e836f2d5bd6d8324fa6e9db7f7d854ebe48c0e6299998122e9d44b8adbef54f093 +PUB: 36f2d5bd6d8324fa6e9db7f7d854ebe48c0e6299998122e9d44b8adbef54f093 +MESSAGE: 555983679d026e5354b4cc055ae1bc14653c7281ec722372f3feb778e841da821b3d0b8ee7a9a9129ea06824be8379fbbdcb0748f423721ccb172a1bafa1d5ae9fc1c51e93d41dd551c3086079b620286c1c40c1223bbcbb76722e92ca21d8410a +SIG: 07a7de6ce97664b3ea0928e1385c3309be08a47cbf4daa9186a1b948c86fbba39c4efcfcb7a0a3866bc94c6788ffe6be0d4972e56d0c3292d1cc6e25447b9904 + +PRIV: 1a61154d3472cd96b328ee674beb4fc86763a969fb410494e0678414e31a46a67576d93ac85d0fc61f258c55cf90bd87a635099c0e810ed0b937258d13b42559 +PUB: 7576d93ac85d0fc61f258c55cf90bd87a635099c0e810ed0b937258d13b42559 +MESSAGE: 64c565efbcb8b9528ed47253f3c6a4035db781d6f0976b5e5ba8447d4ed54b04105293ef4c000d8b2e1b5b75e727e5d2a077743b50d183b491764801a2504d16ee6d7d8ac4fe40e6bfc2a8129c7285a5ac691c35e642ed162cf7fbc64516733a23b3 +SIG: ada1666c9c3b8284b8a21c4f2618ef0808a646f3f10941e470f738e1785e2de9fdd9c8cb526f945c7a8c6994f151b7d066581b1d755307947c62befc8ab7070f + +PRIV: f215d34fe2d757cff9cf5c05430994de587987ce45cb0459f61ec6c825c622591ed506485b09a6450be7c9337d9fe87ef99c96f8bd11cd631ca160d0fd73067e +PUB: 1ed506485b09a6450be7c9337d9fe87ef99c96f8bd11cd631ca160d0fd73067e +MESSAGE: fbed2a7df418ec0e8036312ec239fcee6ef97dc8c2df1f2e14adee287808b788a6072143b851d975c8e8a0299df846b19113e38cee83da71ea8e9bd6f57bdcd3557523f4feb616caa595aea01eb0b3d490b99b525ea4fbb9258bc7fbb0deea8f568cb2 +SIG: cbef65b6f3fd580969fc3340cfae4f7c99df1340cce54626183144ef468871634b0a5c0033534108e1c67c0dc99d3014f01084e98c95e1014b309b1dbb2e6704 + +PRIV: 8c9f95083075a43fe426d19f1e87719b40043de88eb0ee971f70e10c7694ce4ee91d167aa3ebc23e70aab45dabe905e416262f910e2a955dd8619efc74c24e85 +PUB: e91d167aa3ebc23e70aab45dabe905e416262f910e2a955dd8619efc74c24e85 +MESSAGE: b69d70e860f55c427ef2a71df36e05bbc43bb2e06463aa5de34419c6a614eea6695335a87526c1226488d842891d0574df343c9c1e17aed6958ecee87474221eb77a599ecb059344c0d052c0002a66e5a6013185af69a01ba5dbc660d36cae235f67fe0e +SIG: cac555222dafec76a0b47b9d2c586b3b3b9b3b9c8364beb3cae1e8dd7f1ae9dd74f22b8dd4ad2b290f81351a415a99f030f10778be4cda85d1d353331e70f109 + +PRIV: d7eb1fba424feed100777eedb4874bf20810ad686b67e31d27ecf610609a33f5a25acb11a6c825713a085fa754692886a87d07fb9be1a53eb961728bb66c9060 +PUB: a25acb11a6c825713a085fa754692886a87d07fb9be1a53eb961728bb66c9060 +MESSAGE: a1d0f81e3d59089cc2b19e07d2fce43db4cf171faa642f3b0bbde77ae3d53af5c02bf8fc12ffb4e57f7c8a015d6c2d178944fae9f7c8fc969d4b77bea51876ae99d59e94ad2456e0ed72c52cf4e5340da17c44dbff86457a519b6fffe269066290d629fe69 +SIG: 2bf719682b07cc5ecc0480f37e9d123ff6f44c26e6958e59f080466f9cd373a16500daf123dc3f1334774bfc9fa84503b16dbf21a815c1ada6ebef4920461702 + +PRIV: 4f6aeb35fce14fbcbb9aa8a4f6451bf95b98df047fa8c43f1ead3b404d3f928fbf66a9edd09481db8444a176c8ce0578d2934f0cdc9734e86fcaac05bf3330f1 +PUB: bf66a9edd09481db8444a176c8ce0578d2934f0cdc9734e86fcaac05bf3330f1 +MESSAGE: 2dfbb3f59e19ea17d44a5bde4ad227a1a351dda17af840ee0a75da21a5cca89b6d1c567c333e9cc910e2157e05e86ad5d931145064594c47baeea8663a34649c43e90eb95ca10f7d51597b378a722f1f704adf9f22e9f885b89d1f938006a2efcdb42aaff5e3 +SIG: 6adb07e364f2a455cb05867abc511acd9d658977f0cacafc92828e7b724f6bbf98bf0bfb29f4e5e6c74738d4fdd816d9252407ae4f3afc574c4f00614824e203 + +PRIV: ef4a6762b400975204ccc13abb47344015454906850ff14940cbb83aa22414aeeaca450996f50cfaf2bd7f9d7fa7087f09ad49664206a80bc2e5bbbb85bb668e +PUB: eaca450996f50cfaf2bd7f9d7fa7087f09ad49664206a80bc2e5bbbb85bb668e +MESSAGE: a4b63eaed5a64a94f2cad212ce2ae71092fd3ea744f5bd89562b2fc2a6c9e4d7aa27add56264a5a55016610be6c19ff7d4989e9504740853012715a79ece9e12c301b3317c7d9b6730db862a4a1d28058e0f8b5ddd9738c7c62ea572cfe59eae08e2b8b6593b58 +SIG: 02697d44cad862f1daf5708205f450d408525b10c01ffd06cfee80374f3db16fa9a49c19a9844b345f2f9559ea74aab173baa078c54370a5166700c6dafb780a + +PRIV: 55017e5f61f0c5bafbcde6f849f42a31e5e7a878c1d3f9126fc569fd417ea9f266914f74ed932fc881ff0166683f675a7c28a926fddd6469cdb3f28e6dec42cc +PUB: 66914f74ed932fc881ff0166683f675a7c28a926fddd6469cdb3f28e6dec42cc +MESSAGE: 2fc84a0998fa6e168a866410bb68105df249a28cfc76604be94fd7dffff2fc1dedd220199465575e8df860190f16aca4084169be16c6ba32eb67042ffd4f230316a26b2624a42f8f90ad57f6916486fa91fd94ed68aded4e632430ef719446979bfaf345409c387f +SIG: b1a5e7c49b8fc6b4331e0416ce7e4ed59edd56300b802e0d72abca4a6fcb876c03bf331579124ae0d3fe43f7898bc87e93fc2da3970fc8638957d18c6613c808 + +PRIV: 0553fba866942341217cf278ac57cb21acd09d9916cc6af0ac46941ea139d545840c66e57c2d4f52a4a2796d2a53c5709b96a628c2e063fe6efd47f283ef5e82 +PUB: 840c66e57c2d4f52a4a2796d2a53c5709b96a628c2e063fe6efd47f283ef5e82 +MESSAGE: c1fae6262a0e98a6b1235fcb62283b7f0a097f9d002416d318fefc60c5a1584f900ad0ab26ccfae0d6d84aa9aa2df16d4c117ea2724676cb866d4870a872fc829a7c2a5d21ba83340adb339a34c5184c7f5ead0f077289b33677ed6a1ba34be1994e25763bd1d9faec +SIG: bc3364c152ee5c808ac340f49ea2cc404e93517121220cce6f7c30a22500e41bcdb6e820480f8fccdd22ff9ad96da532802f431e94240fb83d4bceaa09b92b0d + +PRIV: 7a5ac602de19f3c21040bcddbff42f6aee6f95c1b093868f48e50482dbf4f9c7fbb6c7531cda21e7d17ea903c4d14be6c68b4ca803a16bd87120f5aaf7dce1d4 +PUB: fbb6c7531cda21e7d17ea903c4d14be6c68b4ca803a16bd87120f5aaf7dce1d4 +MESSAGE: bd1685419279eb81e4cf3c909031f0f09c5ffae7e2ce6ba9d96c2bce87b8ba0dd763231001e532c7ddd62103abf701288e19dd8f5302e8f5d31b64cc339bd8b7a95550c8a116fd486948772bd5af8dfd46001c59767b0d6bdce383a7078992d1022fbcaf90710687b9aa +SIG: 84101dd4b5e8ca3ed98c1e8a06e11d7e424b0d12ca714ee7374b64c29d51a2021cc77ac75389d9b0a646a447623d7d04d1241866b0ca6edd1b7ac015666b700d + +PRIV: 50414cf549bcc55b5b6b75ea3782b2ea7c087b6a0106175e469ca2cc764aeb01d0f30c12e997f96e7aeecd1bff6a012ec388ebf8f3f4af664804d1638e4c346a +PUB: d0f30c12e997f96e7aeecd1bff6a012ec388ebf8f3f4af664804d1638e4c346a +MESSAGE: 75ad77e8c54b0b05fb2d162e7cadb8a7528081b863f76a441b374469413e5714edf54f800496af0157c17e425583414d4361f2134171c0b87c22ce6820a4850ab49d99a9badce9e36110e7f3060118b3590f82b43771e9fbb081afe62227e024d98de6cdec028d7c49490d +SIG: b309800160de43a63a89a0acb8a6050059589b3eaecac20b256fece438042f69415d8a56883ee3836d3134a7fc1de64fa8c8cecc3ce27589f606058820857a0c + +PRIV: 93cb00d8fe9c9777a683631f39ba0f48761482cf1c366bd863cf71510153255587e94a1ea5258d61180cb828590ff1418a87d01e702686ba8abc2692c8dc3c91 +PUB: 87e94a1ea5258d61180cb828590ff1418a87d01e702686ba8abc2692c8dc3c91 +MESSAGE: 88d8538d31867813d88fef7228d49a7e950d738396f116dda1025f7913547c5d1dc5677a6de4b4a5880507b361780b61b43f7795263db22ff341645f2f5914fd6088c2811211ed4756ac019a6035d66e3170c1d82bfaa30596b396b3260cc1d10d413dd47ebe6daa0c30dc42 +SIG: 09824fa2dfbc4d6ef76a9e4145961116769130553b3edffa50d04f39b8b79facbd237acf71354a53a6e5fee754e823b0b290f9619320a13d561269a221639f03 + +PRIV: 2b4cae380e95ce694c26ac7957447347f98e31b4bf02d744e131529071e2301de6fc705a79c98e115b4e28d3aa1506b74ee74276c5fc1109a7f4d89c6fafb889 +PUB: e6fc705a79c98e115b4e28d3aa1506b74ee74276c5fc1109a7f4d89c6fafb889 +MESSAGE: e0b8250e27b7c0291dbc47a6da6f1268987afdf0a1e90be69bcbc4370865217830d5208693be7b7045099a22ea27f952eb3f79a9a0f1b5a87b19367790788d34c219c2e2a6b834020fb4fd149dc56b544fddbb42071a162fc7cb33c146cac05a31b183e9daadc616f3af449b17 +SIG: 555e45656ba9cfbf5155d0e52576e5197abbbc9dd233993eec2a1ee7f6a86409c0b71b0a661978ff5e0acdc9463dc449906f474f8e79bb86168bf70741e34b02 + +PRIV: b56491e54999bb5a1715ebfa2feb14a545a3a43c2fdfd4be0c95fc11819ad695cd42bf414f9bfc72ec069882a800557cdf31bc3464fb102c310e6dbd3ae20863 +PUB: cd42bf414f9bfc72ec069882a800557cdf31bc3464fb102c310e6dbd3ae20863 +MESSAGE: eb4418ba30683ec7959bdb1ec7b263f83e81f054ddcdbe0a6738ca7763e246935bac419026c22bfbdd1236336cc16107c53513e3ddf34e120846962c3bdd54f5ad5749597208f15a8bb56667baa895f08340db89b85c435e770931928d8abc99262f839aedd9be2aa138c9259adf +SIG: e3be3e71a89852df3cffd72d68207869dd3eceb49b1f029493eccbb932444ebe8c8c6db5f0a5a67e2194408df9841913a5ac1a606896419a668f4f47c56c2b08 + +PRIV: 6579c247dd2cd02ba2f7d7a950a330752681e92c0dc62984bbea279ea521c3810b087bea1a1b3d15805cb604f4bb8d68edde274faf521fe6df50c55f8ad4a70d +PUB: 0b087bea1a1b3d15805cb604f4bb8d68edde274faf521fe6df50c55f8ad4a70d +MESSAGE: df7c552ffc89374b9571a6024a8d0471d7eb6be8dfca6f4166b581b65479015a0568129074cc04d6342c758ca18f7987dec536b7033d5f9681504340e20986f027b8cf1f263be76db3525d173422950ea8dceddc585640918aa9d25ca89cba701c2020153873f46108c772cb388d55 +SIG: eccaf801ae0a912e21c6b83a5f0e4e88d4b2713459ff93449fc0b21a9f416050113cbae4e814d20c0a798f76d2f9d326ed83959ea02abdc1ab350a467123f709 + +PRIV: 18fba60c5026f3c9dd7aedc04209d5260361de400e190aeb60169e05a3367c9fdfff347f3dd255530bf7fb34d02ba486d112bb46e950e2ef80e517014cc95734 +PUB: dfff347f3dd255530bf7fb34d02ba486d112bb46e950e2ef80e517014cc95734 +MESSAGE: 34f08a804d7829cc3914f000ce1a3288acce2149c8a02086b9f67afccd83a178b0bcfd4970c056997da7dc3d47562f16663cedc52f82d710850cf4050379efdac23bee17c330a383ad137f788473b2b0723603b6deb1fdbf6c523fc948a0ccc4ff100fb946d874c1f990436ae8c4f3b2 +SIG: 4bc011e40f0f59c618f6bbe230b6f7bc2f50e3617c7faab7f4c21cb84f77eba994cb7c2a1bf10b01bb20084497fdf0a6ab5d9bcd22c4a2c5a78f79926825940f + +PRIV: 073cc15b0536285933b2be39253cf4fd696b81610f5dd3adac2e9cbf338ef2f600b551d371544375dac5c4e96cd1f0215207e8e166a1fe49d5b0a51ac18443ec +PUB: 00b551d371544375dac5c4e96cd1f0215207e8e166a1fe49d5b0a51ac18443ec +MESSAGE: c285362bc8ef628f7aedf654231ee51acdf2cf69a886b942bb9bfed8155105d9209ded2af24f169ad5fcd451370f5827a85111c7a52e032c5038617c0c0170e2a6c231dc401d12062edb186036114e38793b79089077581b9783f40007103ef17472491c00e7138aecc5084d3c85010470 +SIG: 3aa52a83062a8f28a5d6b7607f484b66cc374896b766123126333c579581316c742806f627b5bc55cad705cc1d4782b044080c8ac840f38c0c50d35e345c7803 + +PRIV: fd894a1e8232203b289505d5c68c68791ffc0e54f2a87530fbba5b3a3f2caf00e95ab565945c7ae5d533df5d0cccc7e9abbc838e20a0b61c930f5d41d81a6fe7 +PUB: e95ab565945c7ae5d533df5d0cccc7e9abbc838e20a0b61c930f5d41d81a6fe7 +MESSAGE: 2669624a94f2c44a05b7dc3ebf93e58a4bf3a01c273657e7e7878976f6b6ea737fa3f22cc8365b8b220c007d5b642726a408fe2fab69ebb3bd072b349f4dc3377ee7cc752934254215d23989bd3cd02ce999adec9784993f4c19940815f39c9e229247f5205c36cba44e714266369289b4a7 +SIG: f51102219e8804be713e556df4e4afa2f8866fe86541a1c2a0934d24c3c9beb280a70dd8d527fe8b7e0b948214d5f2f9638619914b72d55dc198b0229a848708 + +PRIV: 18ef464e28f87ffcfa4d3a9c09a22910951b8c719fdacdb56de62c4b406df00cc5064c9d43ee2da75b06bb09c77267dbd0d39128f1cdc6bfa451a03e93af4a70 +PUB: c5064c9d43ee2da75b06bb09c77267dbd0d39128f1cdc6bfa451a03e93af4a70 +MESSAGE: 9c825707d9358365ab9d38f7e728d628aa722a4f1a20a38e47c999fff8fc32417fbe072f96eb6a0e11e4da9b6de9615445280e93c77a3634d3d2c6879856c248f9800f60a0d38dc1cea8b7f31f286cb0374827b4c6ba144a6694f2b908ead68d18340124cb59cf1701863bd4f3efc709f3627a +SIG: d1e7f16e8e597d428adea65591d551b54b667aff2020c464f7f4e53c4773f70433249a3c71b4d11c89c3faa892809227b9f29ef4f7f5d020d4674d4021359405 + +PRIV: c911bdf2f9e7cc5fff35c96e15cc12eafd05ab0db31f649f7408acd0cada76e0de44696cd6bd2cbe9b11a0ef18b88164801a969d5e06ed453eb4008cce9a5725 +PUB: de44696cd6bd2cbe9b11a0ef18b88164801a969d5e06ed453eb4008cce9a5725 +MESSAGE: 76c471241d17192984b00362696e4d9d4d2b7f839c2064117e50a1598f3a1172b16c55e5396866084752024f3a7eb68bb3ffdb80979a0af6d0f6af26b6f0bc0c0384433bcfd44c75eb654a8a8225cb9c4a7fb3c824c3af6125fd46db287e70492d154632cb8f62432659d958d6281d04a54f5f5f +SIG: d584b5da371ae4f5c9859b25f70dc56c1b7b4e02d1ae6636283b1b7b11217afdcdf65d1b49ca2c8ef17966e9bc65f10c310b77bb5df7aff5ec1b379a2ce55d0d + +PRIV: d3703299c41db36d77dd3a49541f3fb21d0b2bad1f6e074affd96f1c40d0f927862c5ef616a5f066fd87758a56ab45056fea4bd33f008be24f7b540e095e148e +PUB: 862c5ef616a5f066fd87758a56ab45056fea4bd33f008be24f7b540e095e148e +MESSAGE: ac92edbe22257bb06d94aa950e62d18ca2ac0a8fc106000d2231f8a13b8d7a209ccd8cc49a6cd68a7f36c02fb8f728d15595167f0ba8cfe95c8a1e435f327513014ac428b75d4f72e7c834dd70e1a448f1847d3498475f74e3d9334dc7dcc4fed72bf6c7fe3b1d4f53d429616f1df44f19733158b6 +SIG: df28277121eac44630084cce75917ae9f6bec65af5572dc30719bde661cf696b85b8672dd4983cab30bd05cc3a119d7db9babd522d7b3a6bcf3886ecd25e080f + +PRIV: d411cd33576d0efe9ec413ccdaabd4fcbafec01a3af4b3cbe34f8b05ef8b59bae870344df98dd3a8702c4519bf9e8b35a9d189e746f7203dbbf9bbfab22d6f63 +PUB: e870344df98dd3a8702c4519bf9e8b35a9d189e746f7203dbbf9bbfab22d6f63 +MESSAGE: 11d2c2a7f0190988126696431b4bbcd90ab7b56a32da6404ae446aa762a4ddc66094971538eeb85bde0470a510be0d6d85780ee730a9854138728ae6816162268da852858eaed4ec74c7ac62e6e7096dc002df0bdf5fa40da565b41d181a3f0ad0c5e0b976743e315d9db8ed4160abe69c13a2b3f09a +SIG: 83460d15461d6717710bafd6a47a1eaa900a80f2bf8b8aae2468773614ee84bd628c9717476368ef3640cf760acac83ad60232a76963b7d52588b11dc004d70d + +PRIV: e10a2f1380c3e4720e8a8707a9bcb25a0f58270d7059cd7626c7153447edfb87a3c717acab366a40b51187bbf35b2d15e97cfeacd7349c06ef1c91ac93e90656 +PUB: a3c717acab366a40b51187bbf35b2d15e97cfeacd7349c06ef1c91ac93e90656 +MESSAGE: 135212a9cf00d0a05220be7323bfa4a5ba7fc5465514007702121a9c92e46bd473062f00841af83cb7bc4b2cd58dc4d5b151244cc8293e795796835ed36822c6e09893ec991b38ada4b21a06e691afa887db4e9d7b1d2afc65ba8d2f5e6926ff53d2d44d55fa095f3fad62545c714f0f3f59e4bfe91af8 +SIG: 094bf6f953ca0eb77df45129b7bf10d192cf6ddeae94ad6202b8eacfbec119e5291578fe64a084ae600fe07efdb8a782610dbdb0b49eb5f2a46c432355552f01 + +PRIV: b2e697b3d3efec976ef3369530c792717bdbb428d9ed0c11ec0ea9b2e5f39f82c4d2e4b3c236d6c9b8c74fa384612c4710d83aa16ad7ef01fbb7421d4fb3f0f6 +PUB: c4d2e4b3c236d6c9b8c74fa384612c4710d83aa16ad7ef01fbb7421d4fb3f0f6 +MESSAGE: 7b436232ac2111a84059510c48362588fcb7383426be5e6f62f372e4f7cca83c81c2357f9b54f4a15291065b6d41aad1ea93cffa776b9acaa58afe2b51644b97af9a3e53f84e40aa6d86051e6914cd039d4170a9a526dd69955ff507c33f74e2176591fb0b3cd7f00ee418f2c258a9981cccee72f01c8430 +SIG: 5047fa38197b8328e78dd8a10e966afb7bd3d43608280f1c257d25ca43bc1c06e94a5747ab6215ece54cdeff8c56567d70d2f91f9ec8c260aa1080a6ab5a7a02 + +PRIV: 19a679a7a905a1e2b3038e6e418b3da97c3089c7cd351ea07bc8d1af64eacc4619f08361f469b4ae1e0ceb94f47a7de7317410a92dd013b16ae0d0532fa4b3ef +PUB: 19f08361f469b4ae1e0ceb94f47a7de7317410a92dd013b16ae0d0532fa4b3ef +MESSAGE: 980c7b4d2939061ac7b9ba441117a19485661781a4083067c55acf93026c082a93cc124f095e1b4f2c3f6c135412a5096228e8a071e8b4b668ba9d9644ea9f4dabfc54a9856c3e965e6363395ab709037dda229baf927cd01f9af5e039afc42f3cec634f5d832d2ab7c7cad3ad7b8cf27ebdac698431ad8236 +SIG: 4347b7b4f7c3c4dd315b8384a0b0caeed84bdabe24b2915f12512dfd04770fc996a1bfb729afef9edd611447081a5330617eaea1c1dab1bf13cea8997204910c + +PRIV: f03b8363ee5b0eef7018a49bc02adf731da54ee50a7f03b88a29a2082b189c4331287ef5a2e64104ab7790b312f35c7ad4af6beb0d7ceb8a58f36a54ce272c3e +PUB: 31287ef5a2e64104ab7790b312f35c7ad4af6beb0d7ceb8a58f36a54ce272c3e +MESSAGE: 24191b5464b35ac7bcf4a375f033efba8943b09b9ff0fc403ca7aae702a3cbf396c5131bc008132cf5f12910d586dc1db9c084574a96babee95642f922371c0382ec0402a26feb142e4146bbd3360c2b36834fe45af5e2868d4d56fdd504cebf0c2d7f5791b4429417c8b65a98e0b15c466c137f410524fce737 +SIG: e8fa967e6afadf6a877d87e5f5c52bb634b75a7804199a2bc9d027b63a35654d9ddd06830455641dbfb49edce42e20e7d4104a071c2cbbec23018c297ced9908 + +PRIV: 11086b0d11e415ab1ce02aaf8f0621b54430f6fb135c74f40d38e8c64737064b7166dfbc691eb8c201114ba0d1a2c7b87f7a1fd8d0b36058b0d7dcabe1ae30da +PUB: 7166dfbc691eb8c201114ba0d1a2c7b87f7a1fd8d0b36058b0d7dcabe1ae30da +MESSAGE: 4b5b2936c5e360a38455503721078f8adb404a7ee7ecc14801dc87a67a152b769569fbeac0afa25a2070a1686b900ac1633d499808cdb2e81ce3916d5a3c04d19c5bb2699a662b8aba4af94d390bac7ccc8ec910ed2acdf86ebb71adb601877885eef3c91662fc30738e352cc74353ccf8d8edeefacc042c10a0e5 +SIG: e907459d5adcd0d0c36418581f19d0eebda7138ebd9faa0b262201f458c856310bb77f4c7de922495dcfe8b248eda2ad0df6a73f47bbfb894baa7d8869875802 + +PRIV: efce7667a8ef91228caed14eb477a345e5e8239234080848760ed0970713fa869193055a84df1eacca28ce2a08c2a07a50f04c024ecf1fe4a47d2efbaf63ed58 +PUB: 9193055a84df1eacca28ce2a08c2a07a50f04c024ecf1fe4a47d2efbaf63ed58 +MESSAGE: aa1bc80d7bcc1d94a23a57cedf5027482477dc46b86890bc0e5ac29ae6c91bbc43130348797305f75543580a8a069b348a7bd8fc3e015230b7c1940c7f80a82b12900910dbcf0630da03f081d44c7f955d4a1172f56ecc7c5ac646696bffdf4eb6d88bdd9cc3843528b72583abb3bad02e56ef7646eed5139551cdeb +SIG: e5a63124db1696b64140b6e9612fa9587b3eef710109398d44ba0ca63c0ebad06f0a6c8994ea34b3a2af91a89bf41ae614d7727d716fd42f8b92e1ac64fdbf03 + +PRIV: 88fccaa96ad884d1165be71dd0c4f5f8f4421c60fbfa498bfee9b967462443bdc75cb0e0237b45b8656eea9f3d1a9d4acd01a103aa269bb24fd54122fd81f2ac +PUB: c75cb0e0237b45b8656eea9f3d1a9d4acd01a103aa269bb24fd54122fd81f2ac +MESSAGE: 9d0eac98556bfa8672c35705d1d61ac4d0fca19dc0d993015877857d27fd80f74acace666c563485d81e53603a6aef40875fa551cc105f2cc10b39694679cdf4a6b073bc88645fc51a36da179d3d1e3c7722454c5e73577c61aa7d148c4ba50ea46c56a1c3b3b3c470f93100494e08bc5514ac763a85483c42c7cdc27c +SIG: 27d3a197cc9994212063bce8d799e77b6853b7355ebe369bcf1889a418a82caa3a7987a663f621defe86b3ac4ad44faeed16c9116ace28fccf915557fa779903 + +PRIV: 670b30626fe367d8b45f43733d6f25b37eccbcb551963f0ac8b666b48041c72d65aa4c6d4ba0ab34bc75b39f09527ca6f2425f52415cdffdf2dff273f8ea612c +PUB: 65aa4c6d4ba0ab34bc75b39f09527ca6f2425f52415cdffdf2dff273f8ea612c +MESSAGE: d00bcca7e184d10e1f1fe420b50639e1d5deba52a751236e68c59bb4bff9802f5fc165ed42fd6d534670a7c6fb60e4307d947915a248bf2f93465c2cb44d8f453d2c015afbc8ed58818ea51726a25177930e9ea192ef4514f4bb0eb4e0f5d4ae3c46e357c81187f7ed174733fff959c3f9fae6486cfa1356a95699211de5 +SIG: 1b6b4377d2b98e0f9d24ae8dfe30e2396e2004380d3431488e5843cf8d2d7a0070ab21f8a3b51ce84d2f4ba209f739f922bebf798096693f5622873d79ae6f04 + +PRIV: 813c4daed67a190d68bb635d73af6da74f32fdf7c48cca6e59262946b8e8c71fa2095457d7697020e2b884d95a96578c2a900a7666ac0dc7bd38f1931d7945d8 +PUB: a2095457d7697020e2b884d95a96578c2a900a7666ac0dc7bd38f1931d7945d8 +MESSAGE: ce54cb0450e689a0dbef785308b3177472fcd6d38203e58a0590b31fa253f9ea590be5368a922de88b63450102684443fb8189e601282003323b89c81e92eaef2b5ddc4a55c53fa3cfad4160248b3c286ff80d31d161b7b8dee713552b56f1507fb72eadfa89054e9d1600ac874c4b0a961004eb6d0d4bfd2ecb9c734f00ba +SIG: b446574ff6a4bd2b572e487c4ab443ca641075168aa4e1092f71f30bdb068ce46a395efee1ee660b9fac26d54109722c15cdb791bfb87fff63c6596ad4f2270c + +PRIV: 8400962bb769f63868cae5a3fec8db6a9c8d3f1c846c8dceeb642b6946efa8e398be21001993a7eb1a1277ff74c15504183d25fdfcc05f0d4dea892f6e301890 +PUB: 98be21001993a7eb1a1277ff74c15504183d25fdfcc05f0d4dea892f6e301890 +MESSAGE: f7e67d982a2ff93ecda4087152b4864c943b1ba7021f5407043ccb4253d348c27b9283acb26c194fd1cbb79e6afc32ff686b55b0b3617218dcf39316b4b66b3c8c0d67267a86db8adf3750801bcf9327d4c25441b96197832b4cde0eac3ff22892a2f0bc17c2c213c02377a333e308ed271658049383b7e2e57b6b8b125512e0 +SIG: 0ad71b0025f3d9a50db338414d6d670e7799b7270a8444f6ae7f12ae7eb71bd03ffd3c4f36631f69fdcc4061468ff582ede495243ef1361a3b3295fa813ba205 + +PRIV: 6288722035d1ea699bc7cfdf18d89625423180b683fa74639f4f30f15359cc85e17faa019572861a064e1bc571256dea1468f3a48590a89138aaa85925080cd7 +PUB: e17faa019572861a064e1bc571256dea1468f3a48590a89138aaa85925080cd7 +MESSAGE: 8b6caacac51d8949fb86acbcb1b99d859ff67c64147bc1216909dcab07ee6ef09f403863327394689dc34abc778fcb5c1f5091acf5a08f9d842211d1ae2eb40be9bb8d6679077471547a6c71ff77b519d4b7108e32bc46251c60dee8e332b6229316e6d57c22ab826ff1bc33f2b0213807c19280af110fd26ee27468201cff49cb +SIG: 9dec92b6e89adbe8f4e1b5e93ac4fcf957de7d1970a226770ec4eda647c8e3b3dffb2731a39e16e4a0119d3662a937e560522491ec7a1696be04c076b12e3501 + +PRIV: 13038a3a65ef32759a9cd903acb554b252de00e7cdb77bbed1970b20680ee17bb6a308e67f9b46c66499456ab5cd135cb2fe84a32eb045358626604da4122c8f +PUB: b6a308e67f9b46c66499456ab5cd135cb2fe84a32eb045358626604da4122c8f +MESSAGE: ddf00b4033a2a088022dabe93356432f50ddc6c6e1a659dc1a93124a4c2ffffd182765a2f56c43ea0bfd8de8015060889ae6941c3f3e255d4421a1c36201be846a2738a71f120cad598ca8527d70ff8d5a0993b55cb5153517110a41962daff42250158f2096d1ddaf7186e50298cbe51fcb429cbea411293f8a7bd9cf069fa237e4 +SIG: 5261558ecc3c98ff36351f42f504cad4a32ffda5a744560960b4c106e4492f02e20478887afee4f770f05597a7e388caceae805ae351e0e45e8e578e6a6ff20c + +PRIV: b9de5b063d3ca3a773f114941b2e4227c07511c0f5c06017b9c8845018f234325295243c8646e096674dda15979b322b9dd0faf27d024a0ed5771334e1179ed2 +PUB: 5295243c8646e096674dda15979b322b9dd0faf27d024a0ed5771334e1179ed2 +MESSAGE: 9493cc23896b84096046ae1053afe39499e9424254b366fe143f4da321e2dc9e4784208e12a542d899828dde7eff625a7f12416990c2841ffb095bf94c0c610e5a663918b689031ccd6b519349d04de1c212ca2a9d7abf52e1b4fd467bb665b6919ef8f91617e205565bf56647e5f8d508ea200a84467f8fa122e74bc3b9979f1174e5 +SIG: 92ba760d14d1415cfaf218ca847014088ae51ad821113a6f8630356f7ba85c005e2330f1066d0df464806052a4174610050462f3e013d702e7c77185a032580b + +PRIV: 8ff0297cc08842b5e67552ec2843e04353a34d74ef89b8565d97205b74ca133a0f7ef98c5ba4af984dfb77bc4e537b2b39e6273bb3e7b95fe1b7e6781952bd4a +PUB: 0f7ef98c5ba4af984dfb77bc4e537b2b39e6273bb3e7b95fe1b7e6781952bd4a +MESSAGE: 2bdc3a486c5e4ea62dcfec8a9d4fcf9ea9490dbcc715615d58490a72ce833fa22387ca50a0052508cf0aff1ca727f0fed46ffa7d3c8e23c5bb01d47e90ff06d3858a557d9926481579daf4384aea50e96ec615d2a3bf3c1122f1f24dd6ed98a5de421883589c213998ca5432373e68bbbe89428ca9885d0593d5e6215116b8266386452b +SIG: 0783737f706e6ff36614f850074fca1f485f24fcde2a28af544f37abd69b7a581defd8c771b031e108d19d788c74c5f20bb3f1c21cd92be317bacd8f650b4905 + +PRIV: 050d553d282dca3269c83c181768ec067b81c9fe0c94f2a0ebbb0c942d0fcd7c63e230b003c53a5672e832ff7f24430be223e497de840233f595a3e200c7127e +PUB: 63e230b003c53a5672e832ff7f24430be223e497de840233f595a3e200c7127e +MESSAGE: 15e13b8c01004f6aa5b236dbb281677f746d81e548e0aa80f0e414521521d856cd694e7c9152bb5e43776b60f6b560ed1ad3e4b390dbf3e46ef9257443f39c149e0240a02d021e1e3d7d046b26fd004eee7ca16a8059e126c74cb3f2194db47bf60465ecef5c704d2e2c75e2e50060ea2a31cb72b7b3c6b1b5ec72ab38004085281a22fe86 +SIG: 3f0e83765b31bbe8e1fb92e9678d6cde571a03ba7f1dcc1128461f708525457f4e0e2353aa2b598c063ff1bffdac916b5a2200655156904b0585577a1628560d + +PRIV: 69497cd7b4e868cfa0328d92bd6052d772b2767395c14595b279851a9cdd31aa5d276d626e230d18e7bcd61141cb93c90ef0f79e01321212d838ec71457b1aac +PUB: 5d276d626e230d18e7bcd61141cb93c90ef0f79e01321212d838ec71457b1aac +MESSAGE: 53cd080a0c61f1a093d3b3a74571c296303f363b4107edbe880b7aa9dfe44ab5d5dc5f74be9c8d876f04d754653491ab51b135fc953f71287b62ff41b67c742bd3445671a9d4f2dc174ca1b0335f78627a0dd4b30650504178039e7393638510ffe84091b57298d3ac9001c367c1452fbcb33dc54a5dc316fb2a5270764a2ac820a0b63fbdc6 +SIG: beafa58340960908e8d86e40329e3a4523fc7be770addb86e34c3772f84cd9fb338d1f3b65bfcdb09f35c6da36d1a3adf8f91f1ffd5782cc830206433a08410d + +PRIV: 2165a486b612bbff529cd00346964a3cb8cdcffa51dc3d524dd5adc5ac936d687ebc839a465e14f5892476e4a13b3988f83b3cd27ef79e193f86fa16f34a1ce1 +PUB: 7ebc839a465e14f5892476e4a13b3988f83b3cd27ef79e193f86fa16f34a1ce1 +MESSAGE: b728da7a36167c6085bd2d962cf63959facd95c9ad4542028afba90ec9c6c0760bdae935429c3feb3933e2f00042c672ad2cd7348d92bc33f81751e294ae9171b945b193144ef8acb9a1bd9abf0475ce0d0ac789b200c32e9c9a2736b168369ce5f97b1e8d2e7900e1a759178441f1fc430564ae129bae7857740511a668f32c0a3b077a9d8b19 +SIG: 7ec6fba56ba52460a1b4f2738689c1883dda9aaffc8bde17cb6029bdce3a0ebe2fffda55939b70bbd07fdbf6fc5cda87fed8ba58575f894a366e45e5705eea09 + +PRIV: 1c64ad63dd147034598e128f7406ec0530746ea1c5b72ecf79e888065486fa1bbaa6bcc1c3d8d3b11ffc1587adddc58bfd96c2b992b6c6f59fcc50ccbcdd0eb9 +PUB: baa6bcc1c3d8d3b11ffc1587adddc58bfd96c2b992b6c6f59fcc50ccbcdd0eb9 +MESSAGE: 9ebd8e337893bb053ef2b9e3269df54848494f03cd63576b33e64b1080be4be015264a403fb9602bbf90ca19b241a9b66863909b9008ce1b2ffcf236efa4c2668f0f47db9ff5fa157d9cb605412be7dd8b07ea878cccae6bf50f935b86d19e1b648b69e528553a56d8afb78221ad53307b7a4ec8d2fd4861b55dc5dae8e93ef387fbbe0b4ce7f788 +SIG: 7477e54158f13b7128c0a110ca6b65f42514fb70cd5cf28a8b1cc6110ea06fcf94290da13f85a11c2351d3bbccbb4c64e0215d6d0f0099e7f27bc94e949b150b + +PRIV: 55abbc5dac4128134dc8c6018a213ed4b60fcc8e90cbd41db2d21eda5373e936251afaa2646926b2a371f2a09d5865b98c9a5eb6ca047cd0d8ee36e5e0416974 +PUB: 251afaa2646926b2a371f2a09d5865b98c9a5eb6ca047cd0d8ee36e5e0416974 +MESSAGE: 47010e1398ad55fabe371dd8648f768d90df4b965a3b396100b303b40a17518bed6d86b09f734ab7c10b5f3a01b53deec5f8534b70c79f3f29b284fdec486f22f44c22ccd5c6463594415267baa611f70b1b316caa1b68b5e0e99b31c5bb0ce13679a23c31a63999698164cbf37d103ba92490188be59937f123043ec786efe3d411f9b0623a6ad972 +SIG: f6a61c2e661a9eb7bde182e38ec99af985f61698a5d7fa430d16e3f1a93709b75522320de48afcc595ab209122ae0ce132cdf4b0391746e7ff341177570c8108 + +PRIV: f2dcf4a1a0d46ddb2d72f8fdd80bbec5b7dea5913da4966c2f4d12c261f0bf98d39570a25ca59f2257f93f96600df4f63e684bf63ae8dffd914e4629c3d5095f +PUB: d39570a25ca59f2257f93f96600df4f63e684bf63ae8dffd914e4629c3d5095f +MESSAGE: 3b00e808fca4c11651d853d6b90f952ccf5647e102d4ee0ad7a5d181d5b4258c523cd39e3d9825298d84c8cba09f43dbba119988222c76059caf17b4bf9931c45e617448aeade151181497b24552367e52bc45ac79088806d3368207aafefd3057845dce819d5aaaa77b218e2aed3da76d40c1f07699f8172e4a5c803f7a2aceb9a47a8952e1b2f053f2 +SIG: 42882a811dad2d851885e4cbe9044708d91a86f15dfa1d66c3eb304314531f3015208c711b9bdbc5fb233951e569b59d34e415eec4b37ffd374d412c9a360d0c + +PRIV: 2246bfb06155859e10a748ff8f5919ad5d1daab756f01057b790d07474775f4ffa6349b62dc8c6a2feeef6ffc33ae085c649795c1c9d9898e75c13ae1625db34 +PUB: fa6349b62dc8c6a2feeef6ffc33ae085c649795c1c9d9898e75c13ae1625db34 +MESSAGE: 63ee1c7bbb15cebe1c22532d481682754bdaf58b8bc997ae30a34c9d23c33f1690c346ab0a7365ff62457424b6105f8421eca0ce3c630acfeb9a1cc416390edf4920e22b2367e9fb5d2ab25bee56da03ea55e3f57882d48b89229314d734cb83c79f4e17ee64bae6f7addbe9b525fcd03a91409a2dde907751db8cc97e08d0ea89c4d18718d26d0b897b64 +SIG: 2be4915a352f7785483046d8ae9625b8b63257af57c073691256ee076d6e1b972a101f551c705d3f96157c33b56ea049be4af4dc561cbe3c1ec5072d7f134e07 + +PRIV: c088a3dd2cb8bd5d684db8538dc22473b6f014f64fe86af168b4bb01b90a1dd0aad615a9c28759f03d373abe666691dead8b84f9b8b50a67f8f0aa4a701580d1 +PUB: aad615a9c28759f03d373abe666691dead8b84f9b8b50a67f8f0aa4a701580d1 +MESSAGE: 74906ae05a5af8e9968b6feb498569d6345a24f9711befb136e6c3b5ed49339e59a7938b4ba1a118f169b9ace0f7842a26a645f14c0ad22ebbcda93e67e4c348efc3d9ecbb1419e6262d0436a58ea82c2202389065ccf67c4f550e45b5f6a12a6c011b2e0a30101d5c62328bbf99c8c95563a6e33bdd9cce72b1f720139c2fd3e04913146ae5bac5288e0e3e +SIG: 3bb459d1ac575a180c1728d8b8924970492a0c8d2a378c29d1d41785c8379a58e2ba3606785e1c5da29e5527552bc6dc89a2b69c27fe51ed253a9f3b565b2700 + +PRIV: 45667d1e7b5910979c4a328317968371c864d564a661c5cce557c9ecc61bab9eedcdf5e1a170e00c8c687e7e9c18f9893b5fe495cd2977ceb7f446c0149aa9d3 +PUB: edcdf5e1a170e00c8c687e7e9c18f9893b5fe495cd2977ceb7f446c0149aa9d3 +MESSAGE: cd66cec476c87c8dbf47ec91dac48fb5b42db1282a573e0a5cf0b91768986608e1d7ebd05f5251bcf8b47a17093229acefbd44beb21c0c0c928dd3cd3f8966ecce6910331c508ea76baf904d8c21f6c17c2c58d00afd3259b8bf794c146b12b995cddd1c4289c5be3168ebd616b384c281ce1b38a10e1807808853c681a640a009b4d2acd7934f8c6d07578161 +SIG: 6de668f1ca6f292814625289a0808020c87c89ac94f5b0508e557bdf8000a5ca808f021c9679b50ee2f320064c95a464a8439379828c3b76cfa766455e128c0b + +PRIV: 24897428ae6546d85b3190ebe3f1f7bf7c712528ac851a588b07d5c8f94eecd15f348fe3ea5b2c023d0af7ede60e55f91aa55199699da15a11c3791d68d710bd +PUB: 5f348fe3ea5b2c023d0af7ede60e55f91aa55199699da15a11c3791d68d710bd +MESSAGE: 5201d9725f1dffa1863fa4d84c301861141acdfb64be1fbfdd5b9386db20ef394099eebcfdfecc62c6268607a84d55c55cd0efdc372ecf3067343e7b0731c2685461e24b953f99949e59ba3e67ed0f0848313793962a292c459814c5e28690ec1f45171f1abab86fdd14568b00caf48581115ee5ea83b000282fbbf0c0b2a1116039a35cfa3f201422207a3d4948 +SIG: 1b5e75def49f51d6b2de008c71fc1a909bd42ca813298dce4eeef717815d7a6c078c2f3d9a3fce1ab5b3ad8ef8d45cdf2eb4901c32eea2d5e018dcf2833cad0c + +PRIV: 7b04aca7cf926216cb960a3890786339d0a615967680190123fda3b60c6aeb11cdbc3e70e4e8fd13d0cce2852a3b9372c3a6160cd6deaba90f9b3022f70c91f9 +PUB: cdbc3e70e4e8fd13d0cce2852a3b9372c3a6160cd6deaba90f9b3022f70c91f9 +MESSAGE: 1cb09624b1f14a0260c7f56d8c60b5fe45837114232551ef5966386e0c2b441b75cfdb8df2185785d22cf526fa9df7fd45d9d83881b66c1feee0913e238121eedbb7ab504da0bee8998016684535031991f11bfcd9b95690aad2d19bd6a9de1844ed1362302df4217230b25c0552ce277534c650cae526577f25d8b1fe9f9febca2c814670d4805b21adef852daf94 +SIG: 25d2d361751d52b4fe66ea18e4b9866bde3d121a7312fd9e28a1e295e087e3176c94c874a2e81600f24c4654f43d1b67d47b64822648590ce5ce44f3b5ddc502 + +PRIV: ea73bf64a1a97877c3c3e7ca4644b71aaa66314c8f1b66bafaebd5edfb888bcdcaac93902e5764ade47294edd51faa14620940c668b5c1c392a6928325d4c3fd +PUB: caac93902e5764ade47294edd51faa14620940c668b5c1c392a6928325d4c3fd +MESSAGE: 362eec68b912852786bb4f9afff9ecf7cb28c9de6b18422a8ca940b0d7e6dcb83aa44be0afb5f1806d43f0e31d71f922f853615a26e287a27f08a04fbce3d45a0c6c311d4b7cb17e425bbeb0a6b410b5d6dbb7ac11df9850a131a691e3b60b0b214ebe044106e982433287595267b031b5d4a09262ded8934fdfdf964d868ef9a2c842f804eafddefcb71d9f16a59bf8 +SIG: bd86cb9c70a055279a86a9e64870988b8a7345c3cd2948a0fabcfb38abce3c420b4d5521618e11d2de827d9de569f6bc3be66aad40636cdaa64760ded3b7c209 + +PRIV: b8123c116b33bad0dcbc2c4dc06a3d66850dab360cdb5a033c14895c4ee31bfbbdca151ba32c6bb31531b05fdf86c6d78c8cd1935611d5ff111a0f00635b1885 +PUB: bdca151ba32c6bb31531b05fdf86c6d78c8cd1935611d5ff111a0f00635b1885 +MESSAGE: 7970f6666634548c848bb52338817b26a4d0ca68df3d28afff207c2d028067a18e4c9543025f5b0228aa691e5088513151a94494e15d1f54210328e0df159b352c30aaa7a844f18a9f4c395dcbb3fb9fcfbed1103e0706fbf9c35fe2666848fa35dc2cf5227ebee89e7d3bcfae2721b25fdec3d3174ea7ce267a55dd61d58201e96bda303cf418edf6e32fb92f5dc1a0b1 +SIG: 9cf13eba3dcc37b8fc70ccb2327436b9f08855e726aa7ed82bd5cb7df45fdf9ec1f96afad193f47572d770444b65b74a37cc034fc514cb3f91b2d8ada5b02006 + +PRIV: b18e1d0045995ec3d010c387ccfeb984d783af8fbb0f40fa7db126d889f6dadd77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb +PUB: 77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb +MESSAGE: 916c7d1d268fc0e77c1bef238432573c39be577bbea0998936add2b50a653171ce18a542b0b7f96c1691a3be6031522894a8634183eda38798a0c5d5d79fbd01dd04a8646d71873b77b221998a81922d8105f892316369d5224c9983372d2313c6b1f4556ea26ba49d46e8b561e0fc76633ac9766e68e21fba7edca93c4c7460376d7f3ac22ff372c18f613f2ae2e856af40 +SIG: 6bd710a368c1249923fc7a1610747403040f0cc30815a00f9ff548a896bbda0b4eb2ca19ebcf917f0f34200a9edbad3901b64ab09cc5ef7b9bcc3c40c0ff7509 + +PRIV: 93649c63910b35718e48c590d261c48e4ef8336613f6aa077b462676b3ba882906a685898b855212ebc289915d105a4320d620d85771b8c6b15bf10a1be6e9b8 +PUB: 06a685898b855212ebc289915d105a4320d620d85771b8c6b15bf10a1be6e9b8 +MESSAGE: 2cd1a951056c9ebae1399b6bd2d82c0ae277856290d06920ac56cac8fb42435101c72aa9c08dd2d12426325562c2f0a49cd821b11b939aafa593b4095c021bcb4827b107b9664d68282888bc4a44af3e3bdc861be6af309044c3daab57b77023dc902d47ebc326f9bdd02dbc02cd540ff81b2ddf7cf679a41193dfe5f8c8ca1aaefc41ef740280d9823e30a354717c8431f5d8 +SIG: 6274f2d4f431d5affefa35e7cf584a599017193da99094ca908b75acb608d1bf981857be93a7dafb0fadb3ff0906f48a5ee950456f782c2d605b14095ba0ff0f + +PRIV: 1c15cbeb89362d69476a2aa4a5f3ef2089cf87286349e0dfe0e72d9e3e5a66c713a882a1064182582c211847e19b4dac59722c9ffd34826d96f33113400fac7a +PUB: 13a882a1064182582c211847e19b4dac59722c9ffd34826d96f33113400fac7a +MESSAGE: 091c9b9b116ae83d23d01a6295211785d446b6228dd687ddf79bd0d5a4daa8c79d2cbfc37365f1f285e361738123e34e2bcbfc664ce1253a11d9e4a7982e58cf9468e1017ea14d2cc6d0865d40fde8cb560241e96ac1617c791f0ca7c6410cadf328611b18aef333d8350ac497f0a4ae2d03fdf0e23e426d34f4514780d1474e113583541f3c043672057172618cb2059eaaed56 +SIG: 5998b2808adfdeeaebe2c3eac026d3f825f9c7f2af97ca324fbd57aac1bedff78a8ee621d037ee3ad2a712e9a009c58ea3e6f2a828f74b86da275a44a4b1e50b + +PRIV: 11241ffdf34ae8ab875475e94c6cc3291f0b8820dc85e20f32fc53b24ae6897809c045e4bd5137314c0ec1d031faf914910c45a4676f5a3cd8f581bcccb03c97 +PUB: 09c045e4bd5137314c0ec1d031faf914910c45a4676f5a3cd8f581bcccb03c97 +MESSAGE: 3b89deccb7023e4b2b7aff2c3951870af413a9b04dd86ac78b7c8fd887492d8dde49d8fda149edd54781ae2b508030d14416a9a38bed2b9aebbbb20250b3c931acd4e32fbeeec5a26501beab7268d144fce8951a101c4b5178166fbb5927b1dfb1e1ce90d1d123068e3f472c888fdb01fdf70e7f8de9b0adb284b7119f55354316f84ed090030f9c2662061ca48447cc0aef964126 +SIG: 72ce9f91be2e66cfc90f952595946ffc90bfce53087d49e5dd7c087f3faa8f18f2356de971e4429d985a99194b4f92ced3ef47cd7114379e0b3267a9f8b1e706 + +PRIV: 3bdb162465eaceff98d69c86f70039c517d168aefe6bb101b4f769a86b17c972d76cb7be74328289fd1c64be747cca5bb30295dfaccd0f2e43f51703fd5d3683 +PUB: d76cb7be74328289fd1c64be747cca5bb30295dfaccd0f2e43f51703fd5d3683 +MESSAGE: fbf368feaeba87918b1b8c7b8a26832be6e7fc1cbdb8902519281a0654ec73de0bb07101a9d603f745d4ec2357aee9870cb19a56cb44fbd9c91fc34752612fbd83d6fc1a16bf8a85a215d0148e4af37d298467e5cc486b131352ce092182ce8284159a3812b30bacbff595863811bf9a30a9da494565c3ac1814430018ea0eeed39cdbca27f93140e46949db570bfa2ed4f4073f8833 +SIG: 6f1362a402063791f950984f544928e616a4ef79bbeb6854e9615aab9cdbaec483fb9a04bf22de5d97a15bda2d390483c7f61dbee07bb5141fc173b1aa47650d + +PRIV: d5efe51d5cd8e108bd922fc0ea126190a94628ffa53c433a518022792ddc78ef426b01cc61ff5e0e724da1d3b297f5325c18c62f64d5eb48d4a5216a8e9a4073 +PUB: 426b01cc61ff5e0e724da1d3b297f5325c18c62f64d5eb48d4a5216a8e9a4073 +MESSAGE: 9d17bcfe2dfc742f411cb53a94f359c001abf096c741f34af48679f281e7ce6bbd9e87709fc0728a563db2b9cf8ea4fbdcc344c1848e653ce970c6ce29de2ccd520300649adcddfc753971f846aac1ba42ae4528952d94980aa7c6cfa2142907647f894ae974a74d59035a73ef56a10b6612624809520190ace661c3a47095e0322efd781d50d1163598f2da32f31bc9c4f913d1b14861 +SIG: 2306f58fcd4cff2222d81b05a475532b8b19dc67e6d78ddb4205a3b7621cc5aef0b393d5d24dd96c88ccbc53a3208da323be4587d5ec067c820f0723aa44e90e + +PRIV: 18af89025ebfa76bd557cfb2dff148245214641fd5bda159f73da04b08e87c880c584459b9ebcccad587b272160bc60b27f4f772b4321de7723afef577edc7b4 +PUB: 0c584459b9ebcccad587b272160bc60b27f4f772b4321de7723afef577edc7b4 +MESSAGE: e82f46652ab914af535d8fb720b557ac95018d9f2a3fcce85771bb40ab14cb9a986e096f3afe5bee829dfd8b97335c536ac971a21655af16a2f8fdba183a4e18564c21492956537a419abbbbb02a4bbdc01481f5c6e658ecf3c34f011ad846f5edcd4939195df85e41303fb9a88fdfbd704396f7559a327318b952b3e60ce8ddde56378579232faf950c78e7f0b17c3b8dece36b788a8473 +SIG: 26bb0882297c2c08a752d3981145dcde55893a11df77f8aa4c19d0b9ed6e5220ed12e9fac3af13d0f0c71568f4a547d30114a6599a236806c4beee6765284408 + +PRIV: 0c93d99815fff8fe22b9e45aa02b3e6445ce1d6bf5a65dce3da107aa1055940e4d27a47b0fc80800d84d244eebb1deb4436d97633a83e67125ad52ea01685057 +PUB: 4d27a47b0fc80800d84d244eebb1deb4436d97633a83e67125ad52ea01685057 +MESSAGE: 11e877de58c134eaf4c9f1b53c3dc451d3c055f16b09622725b279768512fe10a7adb0765b689ec21d5b6efaa19f1b9d36254df0a9367f441b26bdb90b28cbc403e5074082fa1fed58e140dac97aeaf483e2c13f3cc560abffaba05b763feedb51e60698151cf56efdf1d37d6ce0564486210f052e937f2ea26f63efa5d247ff188329bb1aa83ce3f4f35a3d7dec14599e5feb7b6d5fe4296a +SIG: 7dc4467abcf6431adb7ccfe868eac8cd8a615a0ff65f6a9e338375b1aae3c49a126c9eba79426d1641c6b97c3e92c194e5ee4431efa2439fd450f2cd018c8700 + +PRIV: 989e99945635192c023cc5186fc25bbaef47240775d15a56195d88cd07c3748eca0beafdf731d89301f7723c5bb7e5a1c3ff3eab27c97d711bcd76e42054bee4 +PUB: ca0beafdf731d89301f7723c5bb7e5a1c3ff3eab27c97d711bcd76e42054bee4 +MESSAGE: c48414f5c757d03c523ef3f3b8510771b0ff3b4b97de279625d349ec185a29927a66b9593ba19338c2f5e4131f1ac07ea46d2c1b6e4ab5229280b2e2bb9d140d1ef7af7b1692bf2d097b80f811adcfa95d5cbf9eee92a1641c552b4be4a0d734f0afd470b9d7f4e45778951e21fc534f200a128b96adb8373f10cecec2dac2996a062fb3c294315965a9d5d7b077c4b013c64a38429769d23eab +SIG: aef756bfb8a7266e17d15f3f11ee50ed25be420e95a0742271ebd12294e2cb96ead083b8ff0b829d2edeb14da86e402ef25e6d4a5a7958c184ed10c176cb570b + +PRIV: 6bdbbe06d9f4219eea6403a357b25e561992fae0f0f614561dd86d23de415a43ed52dd1cce32d9b485e0940746421d36b9fde6cdf0211545b634044d4b3cb8f1 +PUB: ed52dd1cce32d9b485e0940746421d36b9fde6cdf0211545b634044d4b3cb8f1 +MESSAGE: 582ada13d69293e49bbd461032dfea1ca2025b52e013a33a0387fcfc5f7c0b8ec955982607fc901e1b7f636a9d371e1f91fe476bdd44856e275d67efa14238164354c231124c84de8f5b89d5a58ea6744b4d3b3d7906905233cce694a64d696f5a7024fc9033b1ce390899a3b441a48e53c7c9b30ba12e7d61f35f15e658c7cc4407e2f689ea8a55d01bf5dbacb11954754f920f09dbd48409bbb5 +SIG: 950206605b0f417c90843e2c8d8e66c828bb10b99b36eeeee8caf2e0e5484d93fe02bf533405f4bb74a50e5585fa0daef4821f0301d01b46321baa31e1f08d03 + +PRIV: d761c8c5a9601b9145b7d051249b004107e452e563100c6c788038c9ee8adad7e6488775d6407efc7b2bca890a7fc62266fc54cdac893343b4f59a196d948898 +PUB: e6488775d6407efc7b2bca890a7fc62266fc54cdac893343b4f59a196d948898 +MESSAGE: 84ead5eabd2fd4b7c79a9a928ab8ee0a16a5fd667a057f8a254663d56daae156d1a49affb2996137b9d8b340e635732f9d2b4c60218442541e72d2b00e1ee7a73c3f67caa499fa9d070b57d076dcde96b0764723c3c659c7a00c1b78b15ccc2223890b51067fc81e23e9458ab0683ba626a53d0c3793a58a9857bb44b3bd85bb6ce53a85694e7f53cc1bd46d50eda37d81f5381b513d1f38339d291b +SIG: 7ab78b64e6db359a2dc8302e1092ed66fa736b536253a1cd90fdb8c10efd78300225e191963599ba549cc859209df0ff61cd069b03d254e6e7d76c798440f907 + +PRIV: c5e0c7a7bb8b7ca07bf0a05ea67eff6deebfe3714ee3e1a227f4dc8e242a2fa05135efcd9052bec57a4431caabe82680eec0a33afd59b30203b280ba12be485c +PUB: 5135efcd9052bec57a4431caabe82680eec0a33afd59b30203b280ba12be485c +MESSAGE: 3770a6786652c4b78a043edce07f3e204d81997c42afc22331f75a5494a826d7cb69ab4314a473721058a1839981d5b7022d0cd8670377daf3320476d25b9f559561d66ee0a709fe17361e2a52898f5753c4fb43bd0c98b368f512adc09cd927c6622676926d8c2d91a14aca32f226f70036c1c858bcffc2b59f54c1c37bf81eb52ecb3f00da602c94361b52a5afddbfd7e05036e377503050333be512 +SIG: 2e7fdeb3484d0a5e8dce94448979496b0642cabc3733a51f8c3c5c51c19ae319018da91091c2385f2f4e9a59edbca2abd0d085ee40d3f0d42061a5a9832a370c + +PRIV: 11bb4748d2547e6196be823c9be7aa18150c204b12ca8d73c1bd46b11a54b475efeb42da28d764966403dd300d9f9451b258ab1c80df06fe5943153f5301cccb +PUB: efeb42da28d764966403dd300d9f9451b258ab1c80df06fe5943153f5301cccb +MESSAGE: f4b765b258ba35b427525c7f10a46f0bccd357ec1ad52a5b139417a9d3894c512d89eb88e681b1f30aac4c115ccf36545e83f37834c82e8300cc1eb289af4375968c29c0ffefb40e156c20c0432669ac8dc0a83c13b1e855a84ad0133c40c82c87ee1e7dd4084d741c80de8a7a9f7759e843a562099c4d7df875352039ff4d3824651386c97759ff7dba52064e6d3112e080819aee8ce723a1a2aa464d8a +SIG: 44c58da49d2365d27029d1eebb3bebf7c032d858aa07e0756b1c26a5412d22691176031341ad37d7bb7843289eb39db491584c1b2a1da2e4a2649c2293826606 + +PRIV: 7452a00156d794edebff4adb1f7a7eec26217fef67c3d268352b2b5460a7dc255f4dc338cfbd384b5f1c14c226701446b52b1e3e2a3cba1a40ee2825080d1de6 +PUB: 5f4dc338cfbd384b5f1c14c226701446b52b1e3e2a3cba1a40ee2825080d1de6 +MESSAGE: 8c4ee2867656e33f5269414d77b42d8e4750dba93c418bacca10938cc3b570c6603d52c2344488607b2f934f6d269fcb2ad966219b1ab11472f42c672ce20592490ec5baf6a2d2fc8a3ee35374b1902fdefc7870b1b626fa46b12b6cee241f601a9b3fe4c50812e573e6752ce2c7644e3367a6a6b77758d8e4934b58af23abae8fecac25edd734030ee7cf39907e3eed8186a19a807103a9fc49d38f4c8460 +SIG: a8f9fa24a3dea1022e73f0d88b1c37d06d0f0b20bbff0ecdb4a40c86d7e475617c03570a7419d74ba0f1327096bf19f0d0cf9f51d483112f26922378682f4807 + +PRIV: 880ef106733f04e76195eba280b3fadda0f25dcf96a6a99c8ccf842c68afdae570cee33d41c728ce7b141931e6e8524567d7601eb79f67fdcd07b9d682c650f0 +PUB: 70cee33d41c728ce7b141931e6e8524567d7601eb79f67fdcd07b9d682c650f0 +MESSAGE: f4f38d077f2b03da821bd36fde673d666e52f4832e1c0dcfeef049328acb7bd71ad2bfc49c123516e196c470df0847b3848a45a2c69bea03e2afa7e58205b63b523814fc8e242f059c69ff7e40f97be8125b70a54fdaf35aeafac79114a7b419e6bb9e70bf07adb559819600dc25e51b4b700d27ca5472a0e7cbbfd14e099faa3a72002da538cbe45d621ef0d5252ba29d83f8b3ec8389c9ceb6c6b2e8d8a20f +SIG: ff6caedd8a468aa07d4c6e7131bbda76182ba958649376e711f44c7bbacba6077bea878ba5949cdeeef05cfd4983b0057d275ea3e18c32659468c30c47ac8f0b + +PRIV: a2d88f37ecc2b2c05dd6cb3159962c5f646a9815b2fb37791fc7b606e2913ed558dd67d7a15d4ca0341a4c869566cad8c4ee16e583a10b4824173b08290d92d1 +PUB: 58dd67d7a15d4ca0341a4c869566cad8c4ee16e583a10b4824173b08290d92d1 +MESSAGE: d1b87e9e886dfbbdc8ca8ab9010ecf9bbaf23f72ab3cbe769db1d43c2a474a81651c464e9fb92734634641c9485a0239b3110771e7f75e05252e4d8f4c0aa1ba08626d7e96317c20acde2ad99b23bdadfd6f17468eb402ec5eefa57b47caf972b3dd21d89f0e2989ff87d51ed2e2d639c1644e698cbe0221b8e179f3cfb04a20cb2470216a6882fb4ff799e11536cf64219f0c075176bc7cf0f6c5b7925fcd6155 +SIG: ccf2400cd673e1effd20161d7b68a5fb87c1e99d3635d78c2da1b509fac33346c069163a6c46c7826a48bbbd03b05e6e2351fa62bf89bf7ccf9a9024bd157d07 + +PRIV: 42aafd0ae26df1e7aa0276860d752783af97280439bb23eae46e3f84caac78dedaa2350adb55dba9df7d7af5101998fe515d311c3cba3eeab9138233190c3b4e +PUB: daa2350adb55dba9df7d7af5101998fe515d311c3cba3eeab9138233190c3b4e +MESSAGE: 72131b80ad599b6f5ff698547d16e7499d71275e4e9b30526a5aac0b0c8b14fa4a540cfb1145fc004418bcd318c1a70e6269a3fb69baed86f363f5b8f97f569c20d4f4990e7bb4d0c39921268d636ed0554bd62acfcacd3b8e030217aafac3044c037e0f94da18c6b9a0932c3c5875d3a93fbdadcf67964eec9ec2be69b48f020f6c9874de5f8a5167b5ee024a2c2efd0cdcd2acd8c1f787814141e30b38b163175b +SIG: 116143650b6c133d617859db2429c2913579790b2197d7b7b1b4962b328721032ceeca58b2d56439e233bb84dc525e284ff8df2bde1db4986fafd21b3d7d6a0a + +PRIV: b69c33b11ba67841c3d4e6f9234e35370a28b47662ac560b27c078b66ab1b0219df68e9acf67379261744db5d1e377892f2b692ed5a38b37073c04de5d226737 +PUB: 9df68e9acf67379261744db5d1e377892f2b692ed5a38b37073c04de5d226737 +MESSAGE: f9ea126d3ab21961aa2433900a3982b83e0ef86d52d13440afa4817f9b822fb582cc3932bf450d4677c9188181fe7526ad6fe5abc61d0ae759f215013c0b2b41064cb6278ba7e39e2f4c10d6cc9605b3869e169d7da42e88eb857870fe6118bb02bc08c8055f0c189b62f79fb146b4c543aa30cc0cd57f037e9ef7a63711f66e6f2878931702202702614277d513f0850b758549336b30cf40ab8bd460e60e12deed04 +SIG: 24368fee5bd848b4c661a3be4f310cfc436e79ec4a78501b81095fe51614231b6ca1ab1269996ad2e98e299781af8e29804b24fe5679ca3ba650c5c4cc58ce01 + +PRIV: 7b63613f6dae01cdcd5e6b37686971cd8d8a99542f6329a12854a9d8ff8105ac72ec43faf34d8730177d1f0743c74c20bf72c2394b8a7d471ffe2a04ab00811c +PUB: 72ec43faf34d8730177d1f0743c74c20bf72c2394b8a7d471ffe2a04ab00811c +MESSAGE: 1816488f1fc83e1ed5911637dd42ba2077657dfe1ae422ad0aee59df9dd56a2763c2dd0ef61a12bb825b0dac1eda5fbb691c5ed58f3fb325050b4563a4042099982fffa5d6ed742d95823da8e1787cf746ef63b3fbb0e88a6c0beae4f7318366936b4917f507336068b194680900a7bf4a6fb69a5c387b97e31bc7f9be53c2a89e3651ce1de41b10e921b206ebf32e5621ef8081616dcd7a2059437efad014bb8e2c8221 +SIG: 76f50b2b9c2ad97bfb9499ee41928ac072da5e8bc71d0212550942332b62e70c8bfe1c722542394688decd917aec8f95353e1d72624b70ebed5d17f6c5497702 + +PRIV: 3558d3a74395bdcba560e2c45a91960cec6cb3edbcd30e722f7f055210f37b51534f43eba403a84f25967c152d93a0175ec8293e6f4375319eadf957401fbbd2 +PUB: 534f43eba403a84f25967c152d93a0175ec8293e6f4375319eadf957401fbbd2 +MESSAGE: be75444f9ce6be1d83af622a8c478d510127db56f1de6eb8a5126522b09fdc6ca0862cec0b8b2aafa31c17a2cc477da533d276a1ae4f8e0759d6afa0b17411b5170b52f20547c72f3e88d48cb456fe625b62feb0f81317edf1ec09ece534b9f500d4e1b1bda2db21982aa95094226ee9f5b0a65da83f91121c96b3b4010ae7826c9e80636cba00f70c3c8a279b01b95294cb850f91709f4376662a580b15ac2981afe9f854 +SIG: b365b5561a13a54517cf90d88b35eb0967d6d58414b8c1547e693159e01378563654c50fb42323f09dd78ffe28056ddfa54febf44891e8a741b6a1687d728605 + +PRIV: a35b92f244063a19bb5e3ed4d699ed2069607116d2bd08113f0d8373613f35b77ec93601864ee4995a4f7abcd3dfc101e9e7f369e63de1ae68a07aa7f075b329 +PUB: 7ec93601864ee4995a4f7abcd3dfc101e9e7f369e63de1ae68a07aa7f075b329 +MESSAGE: 65cd36dae0168d69974f95f09dd9a59db799f911e1a15b85a00893b8c9a3d48a2f58ac126bfaa0a606c05d94701d273abf7d68817f2c71b1c541795c4f6095e26c9dff803f032f75663fd1698edd97ff3a0e72e1b7c9948b08bacb5f7de502b2fea67ca2fef190d60eae92d15158da444a49d2e9d5a573e8e177e8bbf7e6c49f907136e71d2a66cb07636d48768ff417c8beccf4323181fefb3124e434049ea45dd5019e40b4 +SIG: a23dbe3757e478dbc84d3db3a933b0428cedb6b01b86d8d73f3959878dae6f0588f505cd4d39f2ab4677b64805d629652a22529825c3a91d043749fc71f03706 + +PRIV: 72d4a564ca15499b5e4e75d8ac0f28217d32114a0c649a7c8eaadd0cc78c520bc766bd73837c4faa5215502f1efc90c003f711bbef55170091028a34493408a9 +PUB: c766bd73837c4faa5215502f1efc90c003f711bbef55170091028a34493408a9 +MESSAGE: 6c7e7b62eb244a45d78436e2970dcd6c0f7db82297a86140ea58dd22c2195adbc956d4c4ec05354b21efe24cfcfe10e17622368848180d2c4680cc215e8ceea6cce222161f1e092239253b9746f7887df2425ab5a880bdba98153be786dc838cbeca016b1d06524bd6bfba809a8bb37adab15d42415f86ec0358365ea87b8150b05441d9d49846871485caae6de359736c27189736d8f1765f3e5c5f6b92168396390bee94cfbd +SIG: 8fc4f179330b642dd86ca9362651b83b006d8375ccef811d3c6706f91594651df2769953723046ccb9bfe66a667e0d11fc3ea2d8226234fdd5164765260f7b05 + +PRIV: 2e5aaab298e66c2dc1d77ea7421ff895255f9d900db0450d63f9f79c1a7013cf0381f3f19045719b9e8ceb562f0e965dc07b09f371a963a281c749c2532f654a +PUB: 0381f3f19045719b9e8ceb562f0e965dc07b09f371a963a281c749c2532f654a +MESSAGE: 3df0e54c711e3132d7ae953deb7b66869ee531ee40b63ce693206cdb2f4bda0a2569e913ac3e6532c5d9648efd4627780fb8a31d107e033f054d19ed8b7c49dc407d2e949de25f99307221d35843f6d5eb7de5cdf41b91dbbf34cb6c9c530021014b56abc44ac2300313615608a7b4a235e99c14cef8050887032209488b9eaeaa82c09405fc75bec94dd42d6ff1b599a63ee5742f3364093ac92cabab3035822aa867ae56dcc99d +SIG: 7c7430305b361a9e35b2780c4d4408071b2130931d39830ec8d313aafbc83a65dae19cb747d9d1c4ce3f359cc824ea8c92f66a42b8614e7848b884ac8aa4ae02 + +PRIV: b636a02448003543db864b40b5d8d6dd9ad611624c9b0fc6890c51ea5592c7901ef360495968e56e6d3fe740b1c84c4e4490ed682deb4305afd596efb280223b +PUB: 1ef360495968e56e6d3fe740b1c84c4e4490ed682deb4305afd596efb280223b +MESSAGE: 4aa85aac25034f614ed44f7adcdbeeec25fcc2a9eea32ab6a8699506f7a1cad3bc892e9dce934e75b0a8cd14642b778599286cfd8f50a9e4f2edf9f9d6291a2e2979cf1806b93ed8c9a78fae199b2854a03ec406ab3f720835ee263fbbc91cb4ef0758d775fc784c7d5b251ac8937919a9e67be88c9e44cf2ec7f560269aa0f1113d91b84401db15a3c48c7dacff4939ee01babb982fb95625c6c3ad78749060551bfde8cce4fb8a29 +SIG: d4ba80300d5cb51353c03f28c44fd0a424ffe1e40d78ed7bb1133e8fe4e187505293b20a391da962c6a8ac0acec9c67226af3b6195dabe39b3662294da3e0e09 + +PRIV: 5ca0543c71f568a00eedf50a9520f4c15b526e3fb0da816c29ea3d50b2f62a12d4a2933ce19454e331b5280100209a6ce8e569f993c2acab51dbe864c5cb2563 +PUB: d4a2933ce19454e331b5280100209a6ce8e569f993c2acab51dbe864c5cb2563 +MESSAGE: 4ef8496978d28c10abd54a26356ee55921ceb350dd4b742c4161fbeba8a1601f8ad0484b21a8cf5a294fac00ec8a6f59e3362e47bfae1e28a2e6d017c5caa75fb0f48482808037ca21476954d778ff1a0586da3ef69d6cef6d2d8df4ae7a85442a1e46c998cf407a6ad4c5463a43c248f3b6937fdbc845b60c6d85e0563cc16ba9675d364f525f669aaac95f428bb58205099f9e4a6dbbd0151fb65babe123e5393ad64026935cb488aa +SIG: 436823eeff3edce5d8587d68e5473ef3d8dc9465b558b6e8e7cd3137eccc80b4c4e806edf13619d8e717e69f48d7061b68de02c8209be1f7ac26ba8edf606d02 + +PRIV: 5f87117da9bbb6091c94da6b230b7d8f6de0ed2a076413b92eacdc43abbc6897aa786a146226832aa73c434b0edc2d41d2558f820ab8f87e09e6cda91072b9b6 +PUB: aa786a146226832aa73c434b0edc2d41d2558f820ab8f87e09e6cda91072b9b6 +MESSAGE: 2297c40a2e8365bae4c5f0630c50b13bdd9ad9770a5d9a9451d00874b023d25ecd468b96571b2f16dcb1b0d3d756c1f044fcddd1c51f27727a0369c9cf25bd6aa59551b5b07cf8f807d92b159198639704740fe6eda0f26dba7e75d4530b2800f03fb6aa677d84df75d68d4fbb64ad21001e3fc87b609b9c251e8ccb12bbca927447e2054e07688eb8a20521a52249e7b943bed60e6a93c01e3eb621f0460c18a690b6f6b66edc6e8743a6 +SIG: 0f19e6ea0c05f38185c01c2d6477995daf5065ba9d80173fa6bb23a774dc88b3aae879d8a62471d2d304cc3dc66278a7abcb0bb0771cd278e11e7b932e9f9b0f + +PRIV: b53a644c92ba2dc7108b16833f09ad5917846437225a773d32d79c97733c0a58515818c69c0e0a1706b04143842f3e9e271448fbaf3a899119c32f42566ffd33 +PUB: 515818c69c0e0a1706b04143842f3e9e271448fbaf3a899119c32f42566ffd33 +MESSAGE: 13036daaee45fcfde0c53e06d05aa9c01ea94a67e86c6c538ccb283b368daf7078d3fbab580c76ecf82b4e9660f068dcbb500b80595017c5be3c448fbd8a17d97c5643197890e167b35345bf65e75b82c8d65229f2f60aae2772581bc99c49d416bc3d78746ef830f1af944f4a6715ab4ffb01591bac2857f1a9c9d1700888780006a31607338f7af7bedf6efe0b57299ac915526fe5e1e101298708c6e61b84220afe95b53f895987456152 +SIG: 13d2cbac7976ad27f0bf669ad588efb2c91bab8507d57fb16bfea9caff2b0964e75625c4d808d7bbb78c5b464edffe4949ecfbc8b95ff6fdb1bdca2742068100 + +PRIV: d27c9eafcf88151990bb5b2fa8443e709b5fd8d78d233803322dc86d93d9329508e0eff529776714686196d817fdf71eb5b6e8326516ef489bfe186ac5c5bf6d +PUB: 08e0eff529776714686196d817fdf71eb5b6e8326516ef489bfe186ac5c5bf6d +MESSAGE: 77c35bda32a5967d8b302fa7a47583ceab89c9a609a667b753155fa6996f8631d0ebedfe0ac364c77e85ba37311f0de57a0dc2c1e9e400d58b424a322e1d5771e0a9fd9502ad0232ce544f07d8c66e7c3147f8607ac6189bb69066f2fad631185f457f467eba33228ecc40e894a77b571698a9bfac841a54eac5219da99c6a9125c469a22fe81f3b951433896f19ce39b373fd7e5c7b650a5ef2365ae7510b0da5e49d7c07073cf166a98387e8 +SIG: c254e371445633137442eefe40ad4a82e69b1ebf48a685a2bc6ffbac126d228487b2e3537c97ef7410342091962e50c0cb85de7b39ceb41ac4078d40f3407106 + +PRIV: 70213d3a79c65d6dbba542a3679635003a682af5fa58de6b0d65bfa24184901c4402fb92cc1249dd1ae1690f03b3ec4f1e9bdab0de5bfd289f10296830fd403e +PUB: 4402fb92cc1249dd1ae1690f03b3ec4f1e9bdab0de5bfd289f10296830fd403e +MESSAGE: cd6e1cd9c90f566de043d75d7244ecfdb38e8bde2f9a6cd5a4fdac72b5ede6af62d981918c5e610a38789274fa10e527f85fad209b76ca1c281ad5890f9c96d35de522f1ddccb539b8798a0067acdd45b6e344a5d9a97731f545ffa4b17b875c67b48e9d4c4ba72c98a4505583fdbf1e12f22b5a7a494746cc9b6c1b571906c67fcc883a9c15a3806875b659e5816b4276c3190e25cc1ac3de47bf99c49965388f54f3ef8eb569906c6008e5fbbd +SIG: 5b6ce2774d400ecea8a808f5fd0a797ffc6116752376cd7bfa3b2cca3a84d5593f5c03ad3eec1d89532275c47b7ce2a0e9c59cc4028a8a65e5bb9097ea71c208 + +PRIV: 5d540b3b14f0c0175c047eaf026c9070659ef13e9d28e0c5c516a428269b14eb1d2d4d551a57c6fb2b04181049d4039d575cf80c0bc6ec7033067f27309344de +PUB: 1d2d4d551a57c6fb2b04181049d4039d575cf80c0bc6ec7033067f27309344de +MESSAGE: e4c9e8706898cad4ac68d73c130efa04a54f8ca25919ea6bfaa54c8c720ced854c5e9509102c7b885aeddffbd1b7f2c5922583677ac9eea9a108c7e83e8871aed5a084f5440b0f391ad7ffc6bab4574af1b96770f4370e8e988e85ecb1a8d6034fc3d7f49f7422023b9dab5d0c16beab5f5d37b0a4d7de197ad87cd4ff8ce78eb12e1daf739d8b47ab380abe9093356db5b59717751a49e1948472fdacc259ffffc8c1dbae592607d4ec71cc6a8f6b +SIG: 32527da755312889935dd5ee91b1bb117a5d377dd23ef5b7e15baffae9a54391a3fd234bdce073e098c58d05bf195b4c3cc63972383ba4b51072971aebcb620d + +PRIV: ca41769caf1717b4e45c93c121dc82a534fbc6ec0986662c3222d71492bd1176af3f89f6187dbcf9217750c67ef89ed47b039f9eb062ffec9df64ab52b0b45cb +PUB: af3f89f6187dbcf9217750c67ef89ed47b039f9eb062ffec9df64ab52b0b45cb +MESSAGE: 9de8476c5813848ab1451537841cc178002181a2182af305b12e5f7c3b1d56b22cf46ae6276d1826ec0a8c9a7d9f68083b7225bbfaefce82b3b64594052a7700f309233a79fffdfccc5c21400c91cc0e418d5141d486b5219901d6dd2447c1f7b7cf5a0879e70e1dd658d0f2ecf31ebeee11a5c74440c63b9d8b45318c3465d7ff03365edd0385edf80d4fded51f0f7533ee4099f19e93bc9d08dadcd13485db239522ffc81e2c051f8796d62e979fcf +SIG: 5cda872f7ed6d7c90218ac10bee8e214f3b34d15d25c39255ec9e6b0177aa3cb7368d11cb8ed6ff5cf0c04281d06bc4272b8bc09c23f6f4cd5a810ddc7b9c103 + +PRIV: fedd63ffd4cfbf618894962e121a9025eea318a80a1adf169d6490445d2e02a0542f2244bdb7d84b87e628a8e6a12f17bf74a9a6d0ea46c595dbfdc680c04b26 +PUB: 542f2244bdb7d84b87e628a8e6a12f17bf74a9a6d0ea46c595dbfdc680c04b26 +MESSAGE: 2e2ae584641be03dd48f9c618077aeaa18212a4241f0c0194ed23e370d741a3ae11a5fec3b040c16eafa4ac8d18abaa7ce8f286967337189f0495ffdd61995cde31dd8dfc3df5700b57a7a29980e9c823fee85d61451176729e72787c6109b47359b93dfd62e1e5a2d642c057242dae500a94ca1a93bc57be1ade76fe4501c0f6377ed0e9246179aecdd9946b671e8190e1ed23f966e96409b948222d8ea5839de904fc51348073b8f40edbd9b4a4b2275 +SIG: ed59d9e23dec3494b0fbc5d10cd02bab86b3eb35abbf9e4d4a926479f134583a44ce72dc4122aca377a4072b7156462b74e8df46b686698636836ef203179c07 + +PRIV: 38f2184eaa553656ee2902706bcec4acb5af25157ca0f6a2d48de85285fa3bc07ff03fb4c82e9c15d659df424b3e73ed1d78006f3e0b79eb64d98c13aec6ba37 +PUB: 7ff03fb4c82e9c15d659df424b3e73ed1d78006f3e0b79eb64d98c13aec6ba37 +MESSAGE: c2df77c9e479f61983b6c7483ef93fb85a103b213923926523065ebff2257e85427e05cdc27582ef6c16be353a3b250372d6370eecb6c8962917eb656f2641690189d172a111051557abc2494e32cab65ed0633affe92408b55c4ed8af65e2c5e7aab887a3cc8d28c52e9e1336d0b7bb3fe2cd843e7fa1680342f8a4aafa02c4ab252f08c3d46d5f00fd01484263ee635284f6db26d6298de5b0dd238da40a8d2a93376da0302783a0e3be23d9e7f990d25b +SIG: 4a6413c2c87f2b3856a8decbce493adeae0c69c94134707fb0f18f3049fd3e3d051abdb9d4bee253c6107c02d57ad7cc9f3101db660afac2b7981938e9564f01 + +PRIV: 8bfca48462d2536f74b84f6af59f5d8582ff8f7ec28745d672e72eb72e79d3e99d10d275c3d3fe459f7fe2901bce389191cc8483c0f51140d9c62b08fade81bb +PUB: 9d10d275c3d3fe459f7fe2901bce389191cc8483c0f51140d9c62b08fade81bb +MESSAGE: 81ee4cb9c45da691dacd7dd09aff59737267bb55c3ade1ba32c17b7d0d2d0c6079c39d5fd5b29ba5f9c1762097709843eee5612bd20bc8185bf64d5c934184e13624e6f877a2a5dda15c0df62afbb97057cc91cac9a18406a0e0109cc39b2e3f812e227a4062d5ef81c92c22a7dc797c845d71eb6ea9e42ec8417fba90a96d2bb1439418330b4bb2f99c6d63d304a0e506dca9653e5de0dd56e309db1a76a0faabab163774f000088cef3d1b7a6cf661d2e1d9 +SIG: 44d77e439ef6ca5eb940c60ff8732ddc16269ea023bb2613bd447eba7fd69851226c4819ce8d44985a49f3f41ac7af33c47ffe5f89304a3256e445f8d686e307 + +PRIV: d7480d4272bcb1557b1bbee04915c126a52ca6d6a8bb5314a0e1a52b59bfc99c99c839d36d8f5b8652618ed7b0fe9ec3d94efff4c453c540631476a5979bbbe0 +PUB: 99c839d36d8f5b8652618ed7b0fe9ec3d94efff4c453c540631476a5979bbbe0 +MESSAGE: 615cc19f942017365ba8bfa256ceccc85ee289a1c34bb1442acc0716c7fc2caeb76a9de19adec106371e47a30d2e1239ce1f7dca25526d604bdd647659d942bcbac368911349c3b946a97da10a42dbcf3c73416d2e6ba22bd29d9f705672e9e338944cef01ad21f009742e07bcd888ca31e1ee953e8c1b1fd954b7dcf1a0b1d5a069065a66cb721adc020f4efe1abdd16742746939285780d753137ae0140bb410fb6ce33676c27aeec593a88cbc73afd9f40511 +SIG: e04dc8442d352173e931818e290858de85688a4649ea3e3c3ae74edaa54ad01b64622ad8a090b6ad60adfd01881882828d39078bb5b2714fd3ea8397a342fd04 + +PRIV: 3c2d3650735b41ef9006bb45e4be2e0aa5cde851aeac421ee9c1b492d87aa18a3e46ddce298844fcafa00a1b47eaf3de70596df1bbee3c809d1be7dd94080e34 +PUB: 3e46ddce298844fcafa00a1b47eaf3de70596df1bbee3c809d1be7dd94080e34 +MESSAGE: 1425d8d218da1a10a80b6a9c3c2750efe41657984abd5100f451ba949db01046b7126be8402334ed57528bac05622553a86b726722695a8fb331d8565417c4ff0f251a320ad06dedbb750def35d521c3c4cd571a45ada8450653d5e81fe0beb53aaae787b3eb653c2381ed55aaf2590ee5ed8b6626f1c4b0430a54f39658624e6635fefc98fee8fc3e1cc7ff3dd420de9da11a62fcae0e0cb454fc6f7df03954291d26202f1b188b657b3bae07389449b75e67422f +SIG: 3f2af01ad5377ac39040d41a41e36e7b93fa7235b841791f432ecd7f91a3b21ab7196c883ad5a7db446f6c06672460f3f63ef863d9432be9caeabb79e87e2208 + +PRIV: 74965996268cdc4c09220bd31ce07b217a03826ee981fa89f3a2359ced095ef14096d027c1c5ee4cbfc04b9d534174029fdb50cf5610d3021ef933b4caf33985 +PUB: 4096d027c1c5ee4cbfc04b9d534174029fdb50cf5610d3021ef933b4caf33985 +MESSAGE: 45b2f064615bf774fce97f51c464685d7b3e4fefff9231240a719b3b0621cd4ad83305675cd6eaaebff791000b0b1fa31d82d8181b7fe57c5e00cec56ff9022e9ce8db66356e408e3ee262fe627789e65535ef1a63e8fec933be3dee34d2facdb8928cc456abf2f3e8cab47eff1ca42e8b0e48d2c73e7bcc5de3f1056fc523dfef6b0023f32889ed394eeda032abf6bcaadaa7f3ee74118760ab6d91df528bdc5807972c85fa7cb56e387d7332e779e52d0dd7db0cfb +SIG: 8c6628344317a63aca6f78cfaea965b3aa5522ce914195141c08870a1b8dacf34b79c7abc693cd9e5ebe1a2e86f0332d2048db3cbdef01687962d6df249e3800 + +PRIV: 0abf069c08b2691c3a26f79dc8ed05cb71d220ff78f3a5c5780ae9da18e456439ef3b5cc016cc82dbdda705766aa448bd61fa1aaf1170efe9149daa9fe64a1ae +PUB: 9ef3b5cc016cc82dbdda705766aa448bd61fa1aaf1170efe9149daa9fe64a1ae +MESSAGE: 0d055291b2e861eae19ea0fb2069d8c9eef4f1347f3576d78411ae7c0b1c1caf31fde736dc8accacb662df76b620b62ce90b9f92c83309128621d057cf845805949088e938ddbc3d41c5e5541fec8298687ad2f79acda01aa215d25821436eac9d268716d4cd6050260cb4ef6aada4835e073a845821ff211ae2baadceb6e57f06f88345edbf93bfdf54fb74123b57c0fb4a79608d8db6740889e15733507799f7a1fd3017bcd77b28a2bb6c91ecd154e9c5a5ffa0eb62 +SIG: c7566fb3b4d8def667e040f276d3ed98d36dff460126a75b4cc2100386bb01c642f6d8de7e649be6e0818b08d77ce60f4ee5e7717a50884bdee02034ecf1cd0c + +PRIV: f3fd5ec5e230b6dad1ac3d3aebadc7863ff89de2a1317f424d15989a3efb0afdf99e5d5eeeaed1205cfb5c2cc4e5e9f6b4e7f64129f860104ca6244eb9feb564 +PUB: f99e5d5eeeaed1205cfb5c2cc4e5e9f6b4e7f64129f860104ca6244eb9feb564 +MESSAGE: 71f28973ed3df05945fa0bdb23e9beca651d3ee6bf9fa45ffdc6061e42fa2e8d76235f0e9e2daa65e52631fc3bead33da055bb492e4758e598a030a33b3c40b34371459b233ccc043cccc3a3cbce549e20e0b2b43305b64aec661aadba6556b17d76e3bbed62c4a4eac4f88603996752d2363c8d4a2789d128f6e959945c68c30146d194ccb6839ec65344601652c18b0074e2bc7668311697d960c7066597924d704d02a0193fafbfdf571ee0dfe414dc2f52896912bc32 +SIG: 44b0124663adb0c73aed49f73403461fcb19111b0ba17aa996566f477e37d524b0e1f107612fc52a7c767b181fbf4d629bddc08f30584dec6124c5d39d423102 + +PRIV: 738f1310a4e08f917a0a5c1fbaf4ef72f95ee62fcded50868a3daf98856a448d42272c2c8b08470ee5dd8af8849c01b7508d3a3c65b0330e695c841d5dccb2f5 +PUB: 42272c2c8b08470ee5dd8af8849c01b7508d3a3c65b0330e695c841d5dccb2f5 +MESSAGE: f0e7ef6782d04c6943b19eb66ff6226b736e3b0940c09bb126bfc4c4ca7a5e7016c286b7bfd73aa6a79a96031bc81cb5da68cec71a6a0d39780cbe6a0cd4774d3aa06a881610444a8c9d19102294e5f635187aa6f48d11912c7094b38833028d570cb110db60625bb1bdc37affa25ea3c8f8dbfc2514f4365c62b2989a66d27c80384e74ae5fba8c1c2af9c72c4971e64fa6a1dc2517b31ea57ccb0815a7fe2da0f146caa08431d25d151662d9d26e95229d0c62823664123c +SIG: ce1e3577b6a21016b9dd0b517baa0ccb107bc199b8bbaef68f950c8ed58013c853b4d338eedc675079ab1390462ffefa6a959b043f8b5651c6ca375ce0b4a403 + +PRIV: 8841d22aded69c131ef5ee0a10ab0a9b77cb754ede8d257a5372726e2b499c6e715ecca63681bc6e9e31d18848902f4d96feaf43b95d008642903b1763bc9fb8 +PUB: 715ecca63681bc6e9e31d18848902f4d96feaf43b95d008642903b1763bc9fb8 +MESSAGE: 087ca6be2a950c024b3e7467fe00a7d364555d5dc6770f5ebd260642525bd3c0f965db36d7b229a57421eec64e4d991cdde59123034470553f4eb0be81ad2936c8ca26bcab4e5d79040e29798728601684a468323cf3baae4d948d0a1fd905effe16dc44642088df53f6388bc480edf4aa207d0ed161eda345712b4c00cb05fcf635ec2588785bfb8a27cdc28996a1db3e6787023393c075d83c9038fed7899c55fec307de3249c14bda49e8b895860942c36d640bb893779142 +SIG: bb2bab7003f1311be9b8c883fc4fd528adfd51a9c99db3dca8da0fca958da19a10eb22332667b1a0065d3dbc0d06269a1259b6a890484aa2143a52695f145b0a + +PRIV: c02135e7b65aac72f63c32bf5bef5b68c7f3b8ed56208e59e4752070e9d07095dcf600f244037a75203ae11ac316e8dbe9986f0dce23473939334bf5cea48b0d +PUB: dcf600f244037a75203ae11ac316e8dbe9986f0dce23473939334bf5cea48b0d +MESSAGE: 86d9491350d2566e708ed356185d610c73465b2a5c7012919958af2cf76af995230d360de400b7137170dd0835f10fcbec224ee4e42c7d1cebb7f580fea8ed6223163bacdd1923a572cbb6dc26ca8b17ade68c6d2808c4ca1eca28eae9a145f68d4079d8d59d140e958228e7e99520e342dbd7457a9159740f48bdc27b93bdabeba465cbf0c8df5ef2c0f9386eebe656f5d749d5f9147f525266910d7b80396a90be5cc188a9a945f93e753fc99bafa18ee0a6dff79bf8484898ef +SIG: dd5cbae479eb5e229574c21ec3bed911113a57a1916d3313457515d55cc5b6e6ebc52c93f821d13988dbba8df5096d55ff9c39e7f9d561cb58930c96a7a5d60b + +PRIV: 154a47eba1b8c38362ea61faeb0c0ad7e61e412a3cba4688af0db2a487208b1c16de2c894a50cbd4ca90419a4ca64942cb14bd335c5d3f4a53e239c280bda725 +PUB: 16de2c894a50cbd4ca90419a4ca64942cb14bd335c5d3f4a53e239c280bda725 +MESSAGE: bf607e8b6e14d9c8acd96815af0c035ac73c4104c93786ccc1c9f859395dd781900320ebf356aa991cdc9f503fcee9f83675888a7d592002d2a54a573a96994b3fa865538c617ed8ad1ff62018288a674f449be0aab5222f74c4fd475ed6a8dfb27f45287b22b2b6c3bd15179f267d157d7d8a4159679be85b25c2bb2ba850aaed9ae3ae571be4f75836329cf36f412c1c80f1413b7661eab4a8e11b6024244fc62323ff02e38aceb1737bd474bf1e98015dbc788b027bbe217cf4e7 +SIG: f4b6eb1a8d950e887fd2f30f70a23b41871495bfa5b8a4ad3996cd9bf51eb742e07f4c4d2da4b01ab087367a50e2b65b3cef514e40d837540b8c89966485910f + +PRIV: d3028431ce2eef73bd940ab84ca29f13fb26436aa25e1b7bf26cb33f17fdf81763df203e2860bac4d352e722c1c91fe3776e1cbcae8553a4f19890260bf0e457 +PUB: 63df203e2860bac4d352e722c1c91fe3776e1cbcae8553a4f19890260bf0e457 +MESSAGE: 086335d61275d168eaac0540477f50d4b15f9e50b9be693921ed54a9941bc40643cda62e1d805d0250a81146bd5fe2d39e81444d21e2b21b031c111306cacbf52717f6fb4cd3416f1215f8dddcedd2f0096b0fcfa0a6cc2cde7a2bab7f1e32790b5361df3671424cc722f231bf71895bcdcb7b22ee074e8fb4a9678504e735366c172f07637b7a93149bb21f38883378a1db273fc23239e35337f9ce566d8ddf3b3133cad7f2ce81edb503ce1d27c5a657160b78dca9aeaea379be9c85 +SIG: ce9729a96c3ed28943b27839c73382ecd572960c1f9e90c5eff9dd499ff48f17d25edd1268effe41ee6a81ce48d84de513df9c41442621b2f5491e346be18c04 + +PRIV: ee8985dc27504440a8758d4c53e4225215797a00cd8631d59bd93bc66f373d5ecd647bb065693d486589156a9fa261437534dc86f46f72d0a800399a7af010f7 +PUB: cd647bb065693d486589156a9fa261437534dc86f46f72d0a800399a7af010f7 +MESSAGE: f2220485addfebce02a833aca33381d1df917ed609950ed24f85e3b02b2b994b4d939784e332f41064c8b4a2630ab36961742aa1cffdcb08c144eeaedeafd48b5dbe96bf24350e14fd68286bc08eeaef8bc6ad9e195d1484afcd30afa8ced4848126d56c81b43c27a5dbbdec1a50c11062ce21c61d860c25a862fbb75c3bd51c8dc07636668669bbf751eacaccb3b51d2c0d4140316cfce2eb18d2908cecd5a188679bc5f5de290f548e7ebc57d41b589a24ce88ee48d97e8d0c7c769960 +SIG: 5bd60ad5e9bad9932ca9c75f231a76889ae7a8b864b91d1fcba5c5d4bfa1d92838adb974842a0710779b3e3094044909e92c7cf046ce519f4c68e8f19ec03c02 + +PRIV: 80dfe2bf7387bad4654eb076f8dae9595163e40127f5df492dad7df04c7221c4d1783ceeb9cf8e4d07764c473fa4061b8274397103f2076d703249d758b8fbd5 +PUB: d1783ceeb9cf8e4d07764c473fa4061b8274397103f2076d703249d758b8fbd5 +MESSAGE: aa09d784bb09dc999931ebb4c00e424cefeca104818d8eaf0661f09728ad025ef47393210571f17404e9aa6d8cbd5fd88cd7dfb8e2e8a108c05de206f3408234a3b463dbe71a07d05587324524b7326ee79d3348ddbed7871b86fcb488031dc9ea93f6b8d7fda6239348a562444faf1e72d31af35443e9df53e762f3e56b48668f9784b3368ab278a48ef4546a26cfad0d0a5161698f26ee8d34fc2b3d6dfb93b009ac296f6afe487ee335eac9f02cfcae5fcbd1a16ba4e71be1b112562fc2 +SIG: 27279e3cdcb03ef557a5defc2f6c58128a6dc3f8b0385958014e709c1f61b0ae6b403576f0e454d5e4c64c173138ee4bbd5fe7b60d06c5abe23fe99ee3b46a00 + +PRIV: da1f868542cd7cce7a5ca3fa3c24081b4d2344b21a157f0264a347132d19659dcb3a25a53f272ea813804468d6500e96a1eaf822705b7790a8ac3e98cc4e524b +PUB: cb3a25a53f272ea813804468d6500e96a1eaf822705b7790a8ac3e98cc4e524b +MESSAGE: c6987ef380d5d0e74196443aaa3a32356cbc02636c5a4b6d62a8114b2111bc1abddd9e44b3672c18b58d4ef591af4562e020049f8e1274688e1f8e5296d2f9252e7fc84cd1d0c58e98f0f160530aa22c871eef652e71974ce91b4a65fc25fd09fa1b6c32086e98ec708d9abcb1d9cc8e1a089ed8db2206ee9570236ad69b3de6821862fd2c70cd83a32a68b0486229553d928de48d03a104e87381964abea76683976d527c84163a12eee0a55986cf1431e9c86cba8182ca94689bacd165fbce +SIG: 75c517ade4f08d7746305743d1a776c3c55eb5eedfdfcb5eb1d5634a1bdaf7a4b8d24187d6c8850e3ced6567a03c4c59389a4cf47114ce5473160f230546e60d + +PRIV: f13daec0ef33ddd133c7d244d10fd27ddb23705280ff5f1815f0f656d836fe842dc7f1367de672c51e005c74f876f982593996873acba079292734c209c2b111 +PUB: 2dc7f1367de672c51e005c74f876f982593996873acba079292734c209c2b111 +MESSAGE: ec02ff1804b2b309af3158b66272a14a3aad83c41a719846f7088ca9792af575c78913c432759f0b9a748bdc5568496e41658cc1cdb8da6c91d07c3ec2f4af504249b996aa00c0071cdfa793f82d0ec5d267262f518fc029b88e20b6201fb9e05abd3f9524c5da2fa8978ff2efd48120cf00822d1bee90df816125d8edc0cfb5de66d16be63896a412a62b031b7118ac13fe2c9faa6b1a3342f9ccf7884166cf489a84de26b5ce5b21856a3af289bc6622c0aab9f2142d393f5d4b236779dbb066 +SIG: db771833f7fdbacdab2b5cc80eed50afdf13783b7fe5e903d5dbb4c2e535316a6eef4c34f004d2b9a4e2700bd6e2acdd564c3c80cc68a303f5fb091cb4340f0a + +PRIV: 42dc16c57fb6f128945fa101e05bbf548ef7d97726b692fe404069cc57ccefa00a1ba5df523996f954b34ddcfabad3f3dee21a5fa7a4ce322d216bd8ccaf438c +PUB: 0a1ba5df523996f954b34ddcfabad3f3dee21a5fa7a4ce322d216bd8ccaf438c +MESSAGE: f2714c23a3a6fc11ad15c980b7350fc84217877661188055ff750d82c49c5fef7bc8e6aac574a1b79a3f26d16969c0f406eeab3e9e12850a55709745e30dffa62a69dfb2b64b3c1bd2bc3586e26d4eea714d2a7b71cf79fb8ffbf2aaad00ca3e4f2b6f503cc1fef2eab3656fb44f8d62a8db8ab58f394693949eea57fafecf005f6ebf1287dba4d2d623c02ea171f567e526add20709ebcab962f83d98ef668ebd01ef20488b3665e3a446fbfb13d34050942c749bb2dffc766367fd452e68e5b0c6 +SIG: c75977e83bcfe9df7292a860ed972555b5c24416fd4b7ee3285388fa5b1447608e4a347813cfe093512a7651e422e9867db7b97c0b0867f0b8c7b7f4f02c310d + +PRIV: 90b455c6bb9cec83e137357065339d030525d0ea7f5b923a2d5972c3c12aa37b5cef038c16bfa4b4c923a0fe70cd7f25c8bc837fdf5a7efb9d95f21b96be925a +PUB: 5cef038c16bfa4b4c923a0fe70cd7f25c8bc837fdf5a7efb9d95f21b96be925a +MESSAGE: c62cfdb9d21eee6be47f30727aaee51f0703789a431d32228533350217a93a18900669c95956f3f2ae90dc745a71e18340d058d16b4c6fe33b64af8dad973fe5dc02e8520705c7a8bb3ccbe1838c6c249337f9b6a4c0e1f8a4e5d103196fa79998923d0422e9d079a72cc2a8f86d659031a607d4cca0b947b3abeeeef64c28da420d05de665a5510fe55f77598ecad7faa0ac284800b53829394c4ae90be66678ff04ab46da265ae06402d8c83cad84d61a051de0260559888e779f74b72a5d71c132f +SIG: c9345eec2c4a0aec732386494a69a3fce8b8a1be366bbed1659f131fe97cc037fb1b7c1b68b0f3023945d20090a0cd2c1553a47faec4d66fd816ce121168f309 + +PRIV: dc185c2ba0b378dfe5dda510c32feff535ca2e8a02434b326e0158bc878e884833d6cc05a434e419280d5864a1af209a2c676814b70f72f8141ac7e0573ee63e +PUB: 33d6cc05a434e419280d5864a1af209a2c676814b70f72f8141ac7e0573ee63e +MESSAGE: e276b11912cca5a84bba650c172aef3a4d5f91ac722913bb891a3ab0424ab07ea709cb8bba3a3d11f82f51c2af0162a82f7219ce27b35a30507d536a930817e40f85a22a5a432b94d192c3c8911777cfdb7fe937a67502770d6d75753d3ae88229e08f1ed23b4328d862ac61863c063ea9848f8ab96a0213d7b936c48fe754836c98487859d199b3d940392716a1d569e6c0cb1ba918932cf88525e256c8abb11aaf0b454655d5db55713cebba287ae202651ac872bfc80feaa7e00d47c0be38e658f7c5 +SIG: f1e44514d2ecbcc8d1a7e84bf584ce731835e9894f88974f098d456b60718f575ef4d8062f2182504250cf83bb2af2a79b1f58a6a97bd98da467132d7bec2f05 + +PRIV: 90721c43bc366f24bf4e8c993e138024682f1029dba35abeb0d60c7fa710021c7c63a2f13b7b220a0bb752e3800753b8b6b32669378ce131bb77a9a8d230e9ae +PUB: 7c63a2f13b7b220a0bb752e3800753b8b6b32669378ce131bb77a9a8d230e9ae +MESSAGE: 651c9617cac958c7edd4a5f3fedfb83dc971abfbb69a31e898cca8472ef068034a6d2376ee0e72d0a9bfee275796c3795adac8ebe1d12b66ec268f6b75fa3941154f99e223faf2cbab5b92e2b3ba7b79be7700ef9dba69253cce5356b0c4e74703cfcafdb5546850b46232675c90c02d5e426d33d60cebf0c7930182379dbb007f536163c8ddbbd3157bb2da62340133f00ae2682ec6baa6416b5a01521cc10e04695295f2e5b94c05f00383ffe954830797f6df823172532f98165fe314ab325929af8385 +SIG: d2064a6d6c99c6c3f152d2d435f24e34b5459b082ef11e944a77ff54ddf9862737ecb2ac8d54207d36c51ad41f36490a111ba80e126bfecb09def6accbdf880e + +PRIV: 9cec246758e412e7378b4579eafe9fac5a25d5405f9270b5d7e543414ec3d5da975a9e6a152caebb2f9dd0deb76dd922b6dc77055dda03fbae9e7c685d073aa1 +PUB: 975a9e6a152caebb2f9dd0deb76dd922b6dc77055dda03fbae9e7c685d073aa1 +MESSAGE: 17ec9bd47add6ccfbd787af0d9013e9cc979aaf850e09426d3b28edfd71296eb31ff8b21c5fe7be050f536324c3ec48850e0b508a36bb4cb7e754b327183a1b394d88a7941d1ce8dac62a5d8291874d78485e51f29ed05865a206e52ecb12c5d107d4ff96f25d3c5d181d2c4ba6463600db1cca32857fcf597cbdfb2fda2708a8aba281b43c3d28c4a4e7983361509f61a1074e6f0ad6101c7b567ee4078e9839c47f46531b729ff0efeef7c9d1a8d833d9c0f42812a34187c3a778c165c09d6459c9c7ceaa2 +SIG: 9bad1e3b1279ef658f4d071644c63ae2b7a780357e9dc426f1650ec0634dfc520f8eda9dc8f10aa7324c5942d2347ff8802bd90e95fcec313352cdae64f32a04 + +PRIV: d1403f63202e080525843bde255eeb6b6783c1caae9d6ed00ba60805bed1941f238aea3ad6d6f27783e70516bbfcca4770366b50ed0fe6a4e966b53af121a721 +PUB: 238aea3ad6d6f27783e70516bbfcca4770366b50ed0fe6a4e966b53af121a721 +MESSAGE: c4f17d442fba4ca0df8dc1d0628d7d7f36b60b5758d7c13b80b8f97a62124d96a23b279565495a8accab5997115b13a4ba220a73957eb7930520acbbfb6f54cf68726b6450c6ffa9470b055ea262914e2bc612633f1ac3d0618a23dff188a733d76bcbcc460f52ab61e19938f9c8caaa792c208d1f6c754728905fda51d881a347a53da744d3baadc0a76c474c558680269095f9084a74471d5c09ffc29141b5bfaf4954dfacbca663d037b17ebf9559882233e5ca5a8bf75cca4fc9c5a4109f32e145f3853b17 +SIG: 8e60e73c063816795e29f5d64ece1159f1b5d5021a6f8f655e261a4d0026f5b94ff2923250499d995298480512e4126276aa4a226d015a95827b3ce692e23302 + +PRIV: bdf6bdc31ab0b5313784483abeca6ea5e9cdc68f81b21f350d09c3907bb9b6a103627712b755e5069fb9ab8f9e899724029a7f268af9398821eeec9360c9285b +PUB: 03627712b755e5069fb9ab8f9e899724029a7f268af9398821eeec9360c9285b +MESSAGE: 90a66aafa5642a98e79f0d88147080167b11e4466518f195cddd8940d12ee4918d31a6d4cb77d0bf5af29983bbe5085610a79daf0c75a78ccbcffbbdab2189c394ae24e265bd8c55fd3f4098e1b175577549518e7a4dcf7452086dd1278dd58ea4c0aa690e917951ef39fcff60cbfa1e90910bab5374928d4722f702bf5ad6028ffda6541fa5ba1a3779ec78b0a95fe3850c748b6c8f42f330ec79541a52a1cf57db72df4f92ce7f748aeef1af33bc5ae0a82c89dff216f23aec168a7dbb510aa632daabcc971b3f +SIG: 38fac603ed246f833f1c0fd4585698b0a71305eff0d14a0049b3cef073bd036dd451b3dabadaaeaea2aeaf83d395746f4e86866ada971cbe482edb0419332f0e + +PRIV: 57b3b14ace1cd0cd603e6328bd219ee7d9d094487fa668f28aeec02b43c909a724e6b6395f97ea0e237186d469b71923d2113adf403beeeb4a2d27909aaf3eda +PUB: 24e6b6395f97ea0e237186d469b71923d2113adf403beeeb4a2d27909aaf3eda +MESSAGE: b2e0dedd802eed996dbd5836bf8688b0d1201bf5442ff9bbd351aeefe1a0c21fea2b5c9fe5edee47e921099b05aedaa80367c1ce08821d783a5b64cf059c0f4335083986a5a6ecff8c84fd40e0ba5dd5e5d2f01112a84ce5cf8e0db78beb182d9139c0b0f3e0060a3fa73869e96423f170df9af1cb9c35566d87dff542223f6d439bdb54729d366aff637b0f36a5d14b15d612bd03076cc4d04c1f25b3ba84e0d1fe474e5718d1a17d5a488465662ee4c3f664b4c9274b649d78cea4e85243f3713239048a908ce3e1 +SIG: fc79fdc6d090887a61e43c6b9187b657d2e4d9cbafd6e7caeb7ebdea842825b78fb949d2c49a0cf38b6c73296d82c8ddeb1fe2d40aaddd7964da68acf8c66f0e + +PRIV: 018a2c3deea50ab506751f9c2adaadfd9e2192121609931684eb265e193e7f89af410bdddefc644ef12c9899ff71b9e1d0dfa3d69d8c2cd676c1916b34591cfd +PUB: af410bdddefc644ef12c9899ff71b9e1d0dfa3d69d8c2cd676c1916b34591cfd +MESSAGE: cf7813efac12ad1c7c7322ccbe54aa0e9a8ba4fd4345b06e4ce7a35c8b1cd5e3f7f0688533849ba2cf4c75b6f20926a1194a72df0e1b1b34456a2133112d006722fe811d5e40c4121159ded88990c0ac2bfd34f35af4f07cc402e9a381a675d03fec7ec438c4ad9d929aec8f242def023c993c9e8ba18c7428e88fde68a4711e506d7969f63c8e0bc83ff0de4e1336106c05e09d5922400e8a81bf54885667899785882b70f20dd8fb1e75f5855b765a256da4341bf23ea0ffa18aadda381816946001045669c8d04df0 +SIG: 7a44e6a31932dee6dc2d8394e29a6551d13e6c6ffdfa218fa5b998668d8439db5e05379fbfa0da5b563ed966435ae2c54e3ad16e1a9fca1f5a157a080704ab03 + +PRIV: bea445e9b6d3f21235912cd6c42ec0577297ca20a10357880c2b846dd8e2cc77024174966221699ea4b0a37e517ff9b16598ae4d4e83bfa3ca50bc616841f595 +PUB: 024174966221699ea4b0a37e517ff9b16598ae4d4e83bfa3ca50bc616841f595 +MESSAGE: 4743c7c099ab815927b3674d0054b6de59af2811abc2cf7fde08f62929185adc238fadd5e75ae3ba0036ff565a79405b424f6552331e2789d9709ac1ecbd839aa1e91c854817597958cc4bd91d07377507c2c8d3c006cfeb6c0a6c5a50eee115e21153dd198ea0a3aff62b7075d5a461788783f050e659c572963d7a59e5afaa2b9c501f43c6ac08ab4797c4566d22b93cdf65a99a2a1d638e79f72b5f4631fe5e9e5f968f6db7a1880df51d8febc14942672f8ea6fc3a72814a44d66d148420a69000f68c330de5b80fc6 +SIG: 6964b9c5903e74e99328acef036558eecd3369150a52e2cbad4bbb97d461b3dfc6b3e8455813a4f4bdca46302e02e683ecea1820171c538e54c3de6c954aa407 + +PRIV: 6447540ed7be0a11c2a8de793d83c6e244983db18d78ec9d75f1729c92e0fdf1391212c8edc4d334a5bec860ef0f5ebb5ec44e8bb51c0f6741998959b2b379fc +PUB: 391212c8edc4d334a5bec860ef0f5ebb5ec44e8bb51c0f6741998959b2b379fc +MESSAGE: a4381c7638c48799e9b5c43f67fc3aa3cbb5ec4234f37e70ccccced1627a57683d1e53f4e0883d8b462bf83f1308630368c89b491533ddb8c9a5b9e8155002fdd581a9a5be0e430b9086a6beac4720210f87b14e862d97e5cc69286786a7586723f231ef0e3e1b932dbba3a18a0cb221cb07f80e6a8e1300056c13e702b23bfb3250ec7cc864d5c7ec5786240709c56024ea6be5f7b15a4fa5555e39a744a1dc557df5b948db220b3d5745746691dacb4421641cdcc12e7ec0450293f19ec57b09cff135847aabe446a61332 +SIG: 3ab5f88e2f7276b5b6583dffba5639993a905dbf9b88ceeaaaae3335800e4a5f10f83da6d6225a8dbe99ae80075009dd508786b3975113db478e14ba101bee0f + +PRIV: 0c587a811add88b994458c3c808ac4e3a83afab26d4cff5c961b9df0b5c8334406783b0cdcc5028c5638bd748f0bc76f7e94d1aa2015ca948738a3500460aca0 +PUB: 06783b0cdcc5028c5638bd748f0bc76f7e94d1aa2015ca948738a3500460aca0 +MESSAGE: f56dc6b76076325b2126ed11d1f09decef9d15c31d0e90cdb1a27e089cc56329f6ec3f665eb6739ec5678b3f37ee1fb37deb9e240092b7a88fd25525acd55e294eb1046f9b1b69a847eb9ceb7b1593b9f6978ef618c15de4e059ecc3bfda3297a19c2df202adf72155cf21eabd03948df15198e8a68b0884f93ad5e36eb0983cca30e45a8b4b5fb8136fdea8a3341dd7877540a557debf7530cc33aeeef6271c3f0af6d09787e815f2f1dd25ce4d2fd09ffa9f53081b469c500da4d44180c04eb1869329cbf2d823187e831c24 +SIG: 33b4f4274f20008a721d1e8d054a2b4e95327e38bb07b33c4bee7e1ce020a442fb2627eda3b7ac93cd3ab0b12b99935a1a9233111604da4acffb5315b907120b + +PRIV: 66cf401a2142fcf4a8018046cf4140bca18d76ef6266e7a024757df172a5d65367d48dfd23743cc2ca40e4dfd6b8cc5d84be82dd2b1120cc476e6af6f25ecc98 +PUB: 67d48dfd23743cc2ca40e4dfd6b8cc5d84be82dd2b1120cc476e6af6f25ecc98 +MESSAGE: daa8efb3fd41f12fbc55bd60464157a26d718632d882aedb6bf98e47dd2337879e0b46452e062e6dfbff3e7bca7289e4ef6b3f41d4b03bdc2c842afe97f3029883ed45f6054dde9690649abb2b8dc28f5fe8cecf80fc1ea411bfc40bbf4fd20b218cf47ea8ee118d4d5aefa5c1bfa08a8fb1b30d6de0977cd15e50292c501f2e71ce2740ff828b8432da5a594bab5223760b64792ed3a69dd75e2829234943656513df1a17a2a067a9a8eaa64e19569f46939d34b99271ae50a47d7dbca3620c81255b0e1fd1f3cec851f1b11b35 +SIG: d6b0e80e60bc1b29ab8f74808fc460847795ccb887bac0ecaa8e135297a85097712b24b0a1fbaf7a67c5d530a47d0643fc8702c059d215fb112dbe475e5bca0d + +PRIV: 5dbf885aa598e895571f5f65090b72323e9d70b0f58110687afbbc383afedcacfa17eba76e3bc3ea6dab3a5b120dc5ecb9ae6f00138f7d36dda9268bc4722174 +PUB: fa17eba76e3bc3ea6dab3a5b120dc5ecb9ae6f00138f7d36dda9268bc4722174 +MESSAGE: 1e0b6cf15ce03337179c02d65408df5be9200c3782b6004af94ea4decb257999d6fdff301d11d00c98c372fac0d026cb56dfefe3def7eb99ac68d6968e17124d8446f53e8d2d3dd890d37a23c7e0b83a484b3c93bddf6c118e0281959d27bd87d37e843d5785f4a40771398494e6c4322fbb675c1d479321032148f7fe52564ddf7ae7ac269d0cd2e552fec589aeae0fb93fe3eeaef0856096cf4f6b3497e7235cc8494d810a0b46c5eac87f187e505bb7764f8045c9541983f7b025698009a23d9df0bd1a473cbee4cf5e9488ecbc +SIG: e1429dab2e42cd035b7fc602efd6baf94706f16eaf2f8b5fed329239e875605fb172f5dd9ae2bc2eb42eb474567e292f5206e82e694bca0d6d433b867634cb0d + +PRIV: 84b3aedd4797a565c351de7dfa0700b9ff7c4d7291c8808d8a8ae505cdd22590d7ad72caa7c22209ec4678d11d5590a6cb28a07117fe5aef57b50751583201a5 +PUB: d7ad72caa7c22209ec4678d11d5590a6cb28a07117fe5aef57b50751583201a5 +MESSAGE: 532567ffa53b5c0fcd29c39499d2e78ecd20e63123499240e775088b394dc65c8baaa0fe8f6aa7e70181f9e10add8b4a8beb0b2ec38a43309f100cd4be91c6f48e79dc0aee93a15c9403773b354a8d42ed48d8f276230fa6de5ada501ee0a653b4458f0ecf6d5b3c33e2141c662f6ea055f741e54586917d2e0c4eb2b56621f9665fef3246f0bd800b533e3bc615c4021f8d0e2ad233a11e7736c493acc31faee76a097dc40db9efc22446eacf1cc18f51fd10236a2f942d0a53c3ce209108b5938c0a9e536b89ef0ad6b405a10f22c3 +SIG: 9220f0edaaaee1b876350dbe9266061767b86296c351d4cac99d07cd612c6efb24f8f9b0b975f95c42c5b6afedc892f87efedd39d5160294c27658bdcf42850b + +PRIV: 6950bfcf480b98ea18a2d5ae5ba6e7668f4c283ff2711357740ffe32cf25819a8e4c6f233f7b86321c9d6799bac28aafcd2503d7aa0a7bded8722727fbbcaeb8 +PUB: 8e4c6f233f7b86321c9d6799bac28aafcd2503d7aa0a7bded8722727fbbcaeb8 +MESSAGE: a401b922aba57ee0c6ac1c8f1b48296a8562eef137526893886a08306e2203667788618b939864467a31f16edce152a42c25546b640ea8bed189a4f89886a37f106911eae1f50081bf795e70c6504437d2a80cb839479ecbb87c129bcc5fe31d716ef978c206d7f08a793466594f4d75e215bb6374596f8e7d00eea724780943e89bd3863c951bbd24efee23c97c2c797c7fafbf8f2c8b43f37a5f881129a09573fa7a034a285e80dc4ba4bc9564a4dcedeb33167e0b30c5a00b9a109a2231cfa0012b29b2b3450b892eccef0808e503f8 +SIG: 94de5df7a25ecd70205d40bc9499fc7cd7136568060a419a93be6e318664bb6dfce60e2d4e633f7ec148fe4f834ed277c1fec4c4e2a86f44c4589c817888db00 + +PRIV: 61b260f5b848b271ef48e5a56d297432d89f2ab85bd538fa668870d0560220e56086fe8735f399f1af2e395e0fdfb5629ebcb04b6ed4a54a9e47052c6e8191d4 +PUB: 6086fe8735f399f1af2e395e0fdfb5629ebcb04b6ed4a54a9e47052c6e8191d4 +MESSAGE: 2826295d79945f675476bc4d45ef800d80b1f0398e4be60e3de4571ed108df989f032de6c2345d9948d677927ea0b8cf1a5ca36fd5f23c25dc0d2ab5bd565a54af46fd97d338d770e3a7b47efb54c07a1664707771eb4e37d9d70ba779251dcdcd3bf6d1248adec53f787259c4d594d5fd4ced8e3db7621d4965d48298178124931a3d0cd269b2d53b7cd261b96d370c5d9693c8ad133ed58945ee3540e10625d924aeba9bdafc656100aab276fa996b1db477bf85ea559081d5b4c7307dc1595654aca82f7b6d2ddaf7357c15a4d7d8b908 +SIG: 9828fec8ff5cf85a98f450770b5bdb4b80daca44379d8f53c91c348e22df64ac48f2b6e2a7b3b642bc8193a194316229e69447ed241cd423d83b6fe7b2d44b00 + +PRIV: 936dc1cef6a310747f350088055a39aa762d9a4b52c8c8e4c682794380c2725c03b31800412df4d56f1532c05828c0b72528a67a781bef4c06c1fb6ff2ce324b +PUB: 03b31800412df4d56f1532c05828c0b72528a67a781bef4c06c1fb6ff2ce324b +MESSAGE: eb58fe86c4ef349c29ae6fb04f10850e38c6823dbe64a09a5bf1e0ce600d394efa6fb96ed6a8f2c9d4bec05e6a5ebd5a1bf4d0c51db934e57b79e5c6a879d975197dbb10475f65c7f8a8c6a77a420384b5062a2740f1401740ee0f5e043aad7a2a2b4260c5d907f705edaf65b0e375dfc7b00bd660db6147f2ebe870a0ee18dc2ba3c92b0b76fae2b90932cdb6c149e46f3feecf4c26f0441f3a9e006678aecff8ccaecaeda73a18a68ac988b62e83a9bb5188aede38df77a9a164abbdd9d58e52a6caf7222389f198e85fbf966236dcdbd4c1 +SIG: 3f994b8ef528f6421c6a6a22e977ade5cee887263de38b719acd12d469bfd8c3f68e7ac07d2fae80a2092778df0b463537ad3a0551997a3d5b51f832d9c8230b + +PRIV: f89eed09dec551361fa46f375973d4fbfa5c5c12f1b5e5abf45cfa05ff31a3403e0efdca3919fa10d4a849cef1de428851bd08efd248594fd89cdeb9deee43b0 +PUB: 3e0efdca3919fa10d4a849cef1de428851bd08efd248594fd89cdeb9deee43b0 +MESSAGE: 4cf9773da05fd322fc147be900ef5cf256c88afdad4b08c230dfc8981fb69f476f7d45ef7c9006bc10032ba53436ac22843e0d76289cf68f9818fa64031d4b40955059aa69110915889f5e22732a1343912581ab3b11a3bae7a471359508596575f888160beef966e5708f0e3147eacfcec1caa3ef240c5e0a14c186546c8eeb64658350b1affc0cfd2ac213af670afca7bbc9dddd28a465b586e69c388cd73478d68efb322bdf86d9213011e711b2b95fefa7bb9b5939761706aa7121024906420bddf1d8800a4338d938fa137cf27e9ffc51c6 +SIG: 897e6f2797c3f326d2cdb1d2673d360631f063304580ff5b4eb43d39ad6851834c9cf891d9f0905bf8de075f7635dfca601adc0f14e7b2c76f7571bfa468ed0c + +PRIV: 400796ef60c5cf4084dee1801c4a1975e482e70aef961cd42e2fd5a3fa1a0fbef47da38128f2d012cc5797571d479c83e7d8a3409802f9a7d976c27067cbbe43 +PUB: f47da38128f2d012cc5797571d479c83e7d8a3409802f9a7d976c27067cbbe43 +MESSAGE: c473325e785b27df4471eefb9ebebd6461d570800181100ff36caf3c38f67c1921b157ec8e6126f955aebd90ea3fe5385f8042cd704b27cc1d6978c0e2a296695f5ef97b7c2e16ae4ff4d063c688d7f46e964e1f0a00503f357345977683d6e4c3423d56bdb6ce864b6987e085e83e70c7c1a14e0e413f592a72a71e017d505b64c24f1a1a6b813e064e6e0cf8bd4571d0ff2f267a6a13e0cd430463b6ca3b88f0cd40b0fb83d5bedf6f7d47e170e87d0a750093693eda232a6daf98125727b9588ecb894ae373bae3a445a106306469a4c2cd77ff +SIG: 84d3aa3f361844396754d80d9fa05b8b2fa4abf3a0f36b639bee9cfb5c8530a3a9cc34677f92a913c41e800f2e8041f7666d07ed85f16a57d817b1241fc5ee04 + +PRIV: 6703a6232c5e2e65e0ab3b92e2aaf9f5fbd33fb46988047d6f4d0ff5387fa029047cffca8b7b11ac6eacc0eaa0c5b73c75b9c637956973af9d97b2dd5b605d6f +PUB: 047cffca8b7b11ac6eacc0eaa0c5b73c75b9c637956973af9d97b2dd5b605d6f +MESSAGE: a26b30a769197932a3a62854968d760151612366778dc994576a2e0e0355496b46200e506948a0d102b6651b2e7334ca6c6eaef8bca44b425970a0b37d6bde0da9d3c1b9f51cbb25bc335cd6fa928a74f2c0dc2c6e99d37a12863a474d4df43aad35415ffcaa24d8c29f914572ab2abec3892db49e679c5ea220c2f519a7d033ac1a2c5a467869e30eda3d2635ca863431473f958d552bdc5582352c290d0ce4fa9cfd0ad42799c227ec90b7c9e5db9f5a7b6d569212eed94d323326805f2b3a0010d6c11eb4107c8283037652f50dc067b6dc81f4db +SIG: cae96879e5b603be866609d4a053bfa12a51378e99b2a2812e4789267d8f32f473243f8af74b9be73f47dea50f0d165ebf49458b73e53d88580c191a182d1904 + +PRIV: e0e72f8f178633626733bcbda2ad2a50e653890f15359b6c22fc7345ad333109d13cee540d84b5667d516fe7ec7239bf8da91546ee791f84edd8ffcf3a083e76 +PUB: d13cee540d84b5667d516fe7ec7239bf8da91546ee791f84edd8ffcf3a083e76 +MESSAGE: 791fd613c1095292c8a4a2c86b47ae026155b8465b607dbb416477ef79a297c9d7758ce34af9dcbf1c68474f30909fbe74b7ba429632f2403aad832b486b72c23054ad42f7653a9ddb456cc791f348886a7ae5dcec7c0ba815f7a93a10fe331e903b970f7b5028be49d14bc5620d63792672b98b9488c67ae16646693e112047f0ac8921ff561c92dd0596d32df0a6e507ac1b07de516c98428d570a37db9bcd7c7e61c6948ab3fe91250dd1d5bd671275df9a972f22c2ba36804747aec1ea2416c1f41ab87befde31629b2d43317ce41cda03626286c0 +SIG: 14552171b95245ac0f0e5a6e7a2f541721068db650c6dada04c28cab7c49195f6436712144cb31913c562e30c39d8a8549fb64ffea81c7445143b5f23286da05 + +PRIV: 544dafd9960d829756c6d4b3eadd44375fe78051876bf978a381b0decaaa8096ae4f6425c1b67ccb77f9aacfea28eaef769c8cacee035205cdcd787e8d07629d +PUB: ae4f6425c1b67ccb77f9aacfea28eaef769c8cacee035205cdcd787e8d07629d +MESSAGE: 447fe7344cad1fae09d6a7d05f09d503c1b3d3d5dfa584810c35bc41e4955693706154e2d751b2f1b525e1a14547ba7f8b232088a6fc922702d93a11cd82949c27bed645dc351fb4c1242cf41d01575412e792aed214531d94fd66e03dd32e972fd77f6947a353e1ae5e00f5a6ca77992472f096b6e7475fe534e913a77bcb0d681fdfb3a7a0dcb56d274df4aa109d4a8a37794a9276f50006696ff12ca4d0254039df0fb3f72a960da05c9872f2e33ee81d1cf7a6f48bbce0aa18c7c0f06ba55e67689e0af587b500eab79cc7f9640bca104b7fbf31f08e +SIG: a2ae117c8de4ca6d6fe75e466023bd550c26fedd3e74ca13adb625f272e175f14d5df550ace7d82288efefabf96311a123bee23889ad3711bff2b8087946bf0e + +PRIV: bfbcd867027a199978d53e359d70318fc78c7cc7bb5c7996ba797c8554f3f0f07c5ae3bab9201199dfbe74b7d1ec157125bdbaa4520f501da3f248579dc6c22d +PUB: 7c5ae3bab9201199dfbe74b7d1ec157125bdbaa4520f501da3f248579dc6c22d +MESSAGE: 117fae13e78777b6219f020214c1b87c57046d1c09ce82ee2b5629898d9b0de74a15cfe99f80548ba913d7036c56285a4cba493b52d2cb70d6365ace3da12b1f34a2778af36ef52ab82ede04cacaf2793f5f89831e3b205a9ee4c1d6fbdab4ba4d9fae65dd79a5fe76b4b39a3092cc7148d211e85ee82ab463d34dcee9061d9c21ded2051bbd50b413f0e21a0e48d1ffa8dcae240b3495be25d93151b57aa271ab99aa708ca28080cab4804fcefa929f5f1ef3f4c6c0fbfb40bef7ea1b509b36ba1260323512379d7bc3fdbb5d3faac9b00e21f12ea1ca2e29 +SIG: e48615b65633e61993b0aaa1fafb74b9629c384fd592bd735fa1f62c5cad11291fcd8c2e91a50bfe0b03b43502fff3a5c382b9c2821907efc34da5ba054af00e + +PRIV: df2df8a9d66d5638cdee09324e7b10f8ed29ab91387e3147b7dc03f7cd8005085c042e157fb7fb12d4d4fef2847141ecfb57c1253e14eaf3004d6513f52fe625 +PUB: 5c042e157fb7fb12d4d4fef2847141ecfb57c1253e14eaf3004d6513f52fe625 +MESSAGE: 21576615c9346a63dccf0c50ecbd7c6d72ad452cfed43ea73202cc7a98576056b9664b54622905a1e7221720730ac685d3bd3977ec3959d446bfa941e725b6fe16afe5432c4b4bdee7aa0fd8030948ed6fcba7c0bdb40c2e517da97456e74e1f93d5ed676de0f4a8b0aea449404bd15b6da79dc1b813965fe5572410d76f5b5eac663050570311dc9842b6fbf8806aec03151715cacf7f21802e8bf5e98a89c0d7d0d098b73c6efc09962e36b4e030c1a64b5d349f5f2042c74428671e4a2c7fea0caee2422d85c4fcddfed32213859a69955d4e3ebb7e1b2022 +SIG: 9a1074531ed43d07bffc7f2b6c13b8838fc75cba02c7d1ec7ba38bca3cef20dc9badf3a3064a2c93b1842441420b6a8d421a960d70dfb7c70eec295f21f83f0a + +PRIV: e8ee065f9907f1efa2daecb23a0425f353094da02bc2c931f0a587efc0d13de1c72651b7fb7ac0337a172977496fd7f2a72aea889385835e563c6b6053a32dc1 +PUB: c72651b7fb7ac0337a172977496fd7f2a72aea889385835e563c6b6053a32dc1 +MESSAGE: a2f0c1373473a305d8f1d99138b06b9a9694ffaa8a88222de9f729bee1305175dfb17001cc77f67b6d40c90c1a28fb226c11286db4a13e45e69211242bcdd01cb6e2c454e76c0cab881b4d2d9d3ab100a5d61d1725d866e4fdb66d93d77f5b308693b9b5a333e57fa25d1e5d2e38df6e4e9ec84159bbee1ffea926836a0101c91483bd5bc88a6f1cc4d4e7f008ad08453a0123429dd335781c7cbf8d685a8999ed1177607004a13c4cb5ea4908c542607d3f2cd6690cf1f2a7455bbd38f538f07a103964317efbcee37eb46931c027cf153ef86e43d78281ebd710 +SIG: a510dff42d4559a19a7bf0fe0bea53d3e1f22dfa6be55039895e12a5d07da5f2e37713ccb2eb216011628f6983f871fee286e66fff4be7582c961a1ed7568404 + +PRIV: c72e67d8c3fec004ff618718a9099eb8ad7b06ff3b8c542a7e8b9847313475e14eb002d3cceb188c6658fec51cb479a65264ac555c75cdc2249cf1ce3defc16d +PUB: 4eb002d3cceb188c6658fec51cb479a65264ac555c75cdc2249cf1ce3defc16d +MESSAGE: a8f34135c0132ec95b64b0cbf51d66900143370406791fbb55f2b8ca953cc74a46e08b002fa2da21b951b8871f7a29bc6d38790afc66a329c397d9f9250bae0e30ae3426e08d8ead0179a3b313c908839192f289a3f3b6e960b4c5cebef0a09daa9c7a15c19d4ebc6fc2ac3cd02232e832b234edd7965d687bfeb758f70fa7963841b7859bb97c971bd557bc8769524ac4c6eeb3579793334b522d176bc62f86b4d5c0d4017036d2b6bd4e4384416ef8263139691a8606170d73c93d6417dcc1a08a537c9ed4400471a46f52907b46b10a8b6889dbb4647a8bbc7149 +SIG: 2d7bab8ebda7fca5bb3c25f51dc51b73e6ff6a3bb1b52acc7811a7d2595cd6fdaf730494418e2f57efdc5617b066fd7b6207680d94fb8c43d3d4740b41cb6901 + +PRIV: 696450b557ec3c94cf1af1326475634aa81def3814ff30a02ba7f2044b59c0fe8584773c566b0eed3f43281705b575a434e47d6cf6b251b89803fef53534cb29 +PUB: 8584773c566b0eed3f43281705b575a434e47d6cf6b251b89803fef53534cb29 +MESSAGE: cc257829f30a5f90dfdbc247d42e388738b76c41ef8a82a5e0225ddf1e386d77080b3b9df86c54b85cdf2c32f367aba0c3b6bf888a5a6903529b6aeb4d5407a10180149114130228fc4356ccf366b77be89796a9e71a0c693f31e584a4f143097ba370363b67b2f2e2fd8d6fe8b4e8dbf0d7dcc1a8360041158aa2aff7e2a325b8e518f193a28bae05e3d52b26621af402026d7f250e86dcee301a58b631eadf4527e958f02a61587f0bb516cefac009fe51052fff53336dbd94e7266d3b43caba8a1b38e5d871c2a24a4c412fff3f7a9a52a8ab23bac9791b2b5a669a +SIG: ce8b0a5779f4f5f401e84d65927a0c28df829e95d09bfa97111b8700078ff894cf7277e34a716144d55306fc9e2f64cd287583cc8003be0e8faf26af7640140e + +PRIV: a8dd35f054fb6ff6f0ab094a0d3d1c262832181df35ccd5192545ebd6a9cf529ca412338d3814b886d964b71925e1aabb3ffd07834dbe7dc512568882b53e4a3 +PUB: ca412338d3814b886d964b71925e1aabb3ffd07834dbe7dc512568882b53e4a3 +MESSAGE: 55a7ad9132d63ac161e7adb132b9189fdd84c361c1e4f5419a6df73df4d7aeb29a8dc4bf01490d4f484e2d12077517f5fc7ad0bdeda20a6cb0227942290b08c3fe33ab9b2135bc38a6579a54bd982f7d1417ce867117aea918dbd3dd476e7eb5b5d3c3e48a864a2f942a31501aa2b29b53b80513c95d6a411844f0dedf16a29ac267d331e53bdc2539bfcf32dc9b5d640f1231e2cafb0ae94bb5189426863364262efb47b5b5ccdbbc93324216a799b6f50d3704f15ed59af6cc7d910cf062d1be632dca5df213d487d8564f2b2bd7d818bba27c364013d92d7f72625462 +SIG: fa709fbc8382af83d11812618dfaca452eab83e4c53fe9e5858467d07b6767e17975c1e06393d6dde15a34d9473d1cf4d6d8c2d57394520080fac4e43448be07 + +PRIV: ae1d2c6b171be24c2e413d364dcda97fa476aaf9123d3366b0be03a142fe6e7dd437f57542c681dd543487408ec7a44bd42a5fd545ce2f4c8297d67bb0b3aa7b +PUB: d437f57542c681dd543487408ec7a44bd42a5fd545ce2f4c8297d67bb0b3aa7b +MESSAGE: 9e6c2fc76e30f17cd8b498845da44f22d55bec150c6130b411c6339d14b39969ab1033be687569a991a06f70b2a8a6931a777b0e4be6723cd75e5aa7532813ef50b3d37271640fa2fb287c0355257641ea935c851c0b6ac68be72c88dfc5856fb53543fb377b0dbf64808afcc4274aa456855ad28f61267a419bc72166b9ca73cd3bb79bf7dd259baa75911440974b68e8ba95a78cbbe1cb6ad807a33a1cce2f406ff7bcbd058b44a311b38ab4d4e61416c4a74d883d6a6a794abd9cf1c039028bf1b20e3d4990aae86f32bf06cd8349a7a884cce0165e36a0640e987b9d51 +SIG: 909008f3fcfff43988aee1314b15b1822caaa8dab120bd452af494e08335b44a94c313c4b145eadd5166eaac034e29b7e6ac7941d5961fc49d260e1c4820b00e + +PRIV: 0265a7944baccfebf417b87ae1e6df2ff2a544ffb58225a08e092be03f02609763d327615ea0139be0740b618aff1acfa818d4b0c2cfeaf0da93cdd5245fb5a9 +PUB: 63d327615ea0139be0740b618aff1acfa818d4b0c2cfeaf0da93cdd5245fb5a9 +MESSAGE: 874ed712a2c41c26a2d9527c55233fde0a4ffb86af8e8a1dd0a820502c5a26932bf87ee0de72a8874ef2eebf83384d443f7a5f46a1233b4fb514a2469981824894f325bf86aa0fe1217153d40f3556c43a8ea9269444e149fb70e9415ae0766c565d93d1d6368f9a23a0ad76f9a09dbf79634aa97178677734d04ef1a5b3f87ce1ee9fc5a9ac4e7a72c9d7d31ec89e28a845d2e1103c15d6410ce3c723b0cc2209f698aa9fa288bbbecfd9e5f89cdcb09d3c215feb47a58b71ea70e2abead67f1b08ea6f561fb93ef05232eedabfc1c7702ab039bc465cf57e207f1093fc8208 +SIG: b6c445b7eddca5935c61708d44ea5906bd19cc54224eae3c8e46ce99f5cbbd341f26623938f5fe04070b1b02e71fbb7c78a90c0dda66cb143fab02e6a0bae306 + +PRIV: 6bce4dfd53bfa5506f2f554d2d994a0dc40cafcdec7e1be050006e5c5a4b38a1c890023728d8397070291771e65e034d34d4aae5e247653e4ff4c074591da702 +PUB: c890023728d8397070291771e65e034d34d4aae5e247653e4ff4c074591da702 +MESSAGE: 3239190747ee33d40bf870ac9ad49d88ee320f63c05257e8ab2c60306597ce76d1f1e792ab6a65caa544fbec20892fd4960594f31b3763ef07d4982eae4a2dbf3377dcc1e3f95e46ed39b7f0222f04bb5c3b434c8f9f310de9f122a29f8241e81e206549ae628d2b8ad768972c98847c1188ad04c835356378bef79cd126869405b129fdbdc3bc489cbd1399505dadef7617b5be5da173d3e80e5838c99e349276242729e0219bd7476ae5c4f81a12878fb483a6c0e9b0df2962eb0bf00157782cf768a1b71c010169ee8522def0024ad7e45775a290639c53aaf48198c42de75c +SIG: 99ae6782ff27646c27f61e23636ae1881521cfa5ed256f70bce7ce00b68280ce8e0c82aa765afb8b5a1ff2fe42c57441e458e443dc8b123477ae33d884888c0b + +PRIV: 17861a8d4154acd4fa9c8fc947c1886c11290be222872ff4f8cd25939e4d136143773f4449065eaebaf8937baf758560b0c4d2de46977839b3b873d5d7d5fd8f +PUB: 43773f4449065eaebaf8937baf758560b0c4d2de46977839b3b873d5d7d5fd8f +MESSAGE: 184df5ea3215ebe180390b0ff042ba2381155a038dc732f76a01c7e70f82d1ccc9de9a0596b3fee447209c992684f643df21f4cf9d179262790e8623e42472dc351997e6da189c07e1e8882c07f86c6337ec0113912cf92215c8de1982b8fc57bfabc55a3e8736f73610429d97feb51d794f505d0c5a0b3abd48ef7f55a628f90b8567a1c15ea9d190d7bf4ec2bc9334ada6cb92808dfc2064836fcfa46b96fd7a5d6f4b054dab09b73595feb89ed005b9ec9d3188121de69696d64e7c7bbdfc1c469faf148c38a7785970afe1acd06a92c99478fe44974e3bb2095e4467e9b2e996 +SIG: a5ee024ccdbdd4c21a24709ec53dccb7ee17626dd00a093d0884f5b45c4c9d1691840151c33c8aa07b69b34e16f61647ebe793ae4daa70cff48e6ab42ffdbc00 + +PRIV: 0a84baa54f11cf17090fec61f3f9401508a3a03887aca1a7939394b1ee40a925309a73c62d23d740f2e93c18587ac15e7ec480d25ac0794e10f8cd461cc2b130 +PUB: 309a73c62d23d740f2e93c18587ac15e7ec480d25ac0794e10f8cd461cc2b130 +MESSAGE: fe70017b14678b0d3ad03e183d6f53314378379ab3da65b3511257b3d54086e86f2031139021391af9d72085ff7c3dc8c1e2d91e53333855423d0f785e2cc5f8b7799fcf1b70e6becb788e53e9020f2995ddb0c383a1f81038fc3d543ce0a38c9c288a9bc4077f4277dcc6c5642263fcfe19688005a603f57675d2434f3ed1f46d32f14eaeb073e83ee7086da2fb67659d3fb68c62320b7727b3b8ea006576bc2c7e6b5f1ecefa8b92e70c92c88951d0c12d91de801c38b7ca5a0a04b4c3429aba86386e96e06afd20d4c5c2fe2b9b4273eb05201a79273abdbeb37ed1830d226b6bdb +SIG: 4d870bd53af8f13f214d9934ec903ac48284092cd9b162a44ccec851fa942de715ccda07b7991d712723e7a4d5b4f0374ab85ac3867e0b53ebc46b530f9fed05 + +PRIV: 38379423dafdbf25e19d7231bddd80b4cefcfe2aed932584dfa0cc3c9f9232de597e81dcee9448b77de6829e7921c8a390535d89a0849430aed66364ee140d8b +PUB: 597e81dcee9448b77de6829e7921c8a390535d89a0849430aed66364ee140d8b +MESSAGE: 36125ca66668802906237e63a2fe5ae610f11a7cf92520d19e6690a3adfafd5d07a784bc1a0e185273d11d340d5eff901597dedf450c4699d43f3fb168d557f6c9c03077c3cdc370d34832ccdf2a8e3d75796490ed0242899d25ddf44bfc66f329cf4c45168703c31bc9202d890f3969ffd3ac35a12818dca751ceb8808fe81efa26a5e0d200c5ec1d94a5097ea74b6498fe288f30c48d727e9d3d35c8e12d85420702556f2861484ffd09b4f12265cc9abafeb82cf590028895a7d050ff57ccf5f28022d016ab4094b062e48b66fd36d1e19626e5215efa40fb7e3b7062f81e954830c9 +SIG: d8b50a88aed6f2a96d082213adf8b2519f6a0bbd30dd3cb0f3fd3ce1c643fc029946cd43462ed22513f1d65fca24bde3818166baa86daa798792afafe0c1a10a + +PRIV: f925d274aaf1fe1a21656237385e97f7783e78090c5d4217fece7057c80f426d3b0fc370be3a4b19a88ab998c59504ffb59a87606338e673df5b3fab4d9bfb8d +PUB: 3b0fc370be3a4b19a88ab998c59504ffb59a87606338e673df5b3fab4d9bfb8d +MESSAGE: 143caafa5f62b13e43dffa49d420fa99f771b1926d40d6cb2bbb427f27b6c266eb3deb2d8bbbd47b8214ad40251cb1907ad65eb94193e54ad85c6700b4189e80f1cc0154c63ed151a8bbbd30e01637ca58e70aa3ee52ef75d0873078a405014f786eb2d77b7f4422f927823e475e05b24245f9068a67f14f4f3cfb1eb30bfede7b3262230ced9e31361db19636b2c12fdf1b9c14510acd5bc18c0ddf7635e003503e6f71e1c365cdfb4c65ee75b4de0694af87076374d631e6c4b8e240fa51dab5e1f80ca2a06c49f42ea09e0475defb184d9cde9f58f959e64092aac8f2027e468126f2fb +SIG: 79549a317d10a0be322a94a151ad11e77efc4836cc8006a85081273d7602a638963a9caf19c3edf1e25fad1e9d68701a71dea727da6a5c5bcac9339589224b05 + +PRIV: 971f806be6f07d41be8830ff8dae704b08638ad6cff722d8432538127b769625af6ac98dce2078a6c73f6097bab63f205caf6953afa284d042bd50a4fce96cb4 +PUB: af6ac98dce2078a6c73f6097bab63f205caf6953afa284d042bd50a4fce96cb4 +MESSAGE: 013455d049aa54ed995fbd94e6369955495395e4438822259b1060e9a34779042a1a69211f6ea2077399dd234806ba0b353cd79a57e1c49b250ab27106dcde576ecfa115eae461febb12d2da25ffcf17b715f8d95c2f0c425d5a81f700115b70d49e1cfe49fcaa14fa205e28ec85247f1a6e7128bf3bb3060dc08464bda6538540d0ac472093e5a0720fde2f3dc4788e0e9b0dbfe2a2b5f1a0f3f80de984025b15c65af77f671e1c5e2840444de5c7eda025e6dc1a3ff16e26cc54cdeed56be73f9b01ab2b1bc16c8ef58a5b76dd47287807e5c50f0d7c0a5b8120dfde645a012c5cf11491bc +SIG: 2037a0a7674b84ff27d0b22f62b4bac65e2dc0f5fdc899feb7800f25c29981dee641c5a50f8b9410970b49d2d53658c89ee16961dccf5391a6918f2a84eada0b + +PRIV: 2bb0652f8fff6901991148c68a3267877271006ae9589149bb206850cdf52fb0c03b77be983e74a234c1986496b292e139992eb7529e70b3afad7ae4fdcf8a66 +PUB: c03b77be983e74a234c1986496b292e139992eb7529e70b3afad7ae4fdcf8a66 +MESSAGE: b923ca67e396d8656fa3dbce8289a38bd3c128cefb30efc1862bb944b4507805419824ce2b83d690ef4cf107492817143bf64c024989af1a7d2e1f5ac97874f86bb0d3773ff840f514d9a1394a3959b011d3a6b816a3fae5de17b2a9ff349863d27fbbb50cca734108751000d6358ca0647a93eb49e2e7af06287d48f2c09d5c1c73e4d8f77ea2bcaa7356795b26728719bed5ffdb821578bd5d66bf92edaf8b238b2bbd7d1e2c30a787f901a33d0a76669a9c3c7f2b552ccb8349c7ded5e1a46170cf28e359e2fdd54b05a562f528c68a56974df82d466637c8e53246a7217e4386801e0e3266 +SIG: 4e158deaaec3d88941296af2d27341012b0241d4e0f46e435e375c9875e89f5e32c057b527bc3411af096a77bfceb45b983efe455e3f03155d6bc7b0acc8e60c + +PRIV: db9b812cb3c7c03b977f487d3d65ccd9cd2f3dee11602067dbfb72b589ff3f79ffa038ad8c3b378ce75d65844d08e3d6a92d194a1b7862e9d9720d20679b2944 +PUB: ffa038ad8c3b378ce75d65844d08e3d6a92d194a1b7862e9d9720d20679b2944 +MESSAGE: a70092c7697cd4a209567c38ba7fb71aa8f15e5827a20876923943fd6adc659c9867ac6f58a61dc7cec3d362411682000c1a9ad1295eb8b70f242d86b5865eb76b87e3f2c6941d2612ee3bcde8f19765566733152ef54e95690943285f78b375f4036585d4739deedeef6d946db61ca458ef4f650da963c385e29dfdee415fe495845f55197a870f8cdeb5a010ba6bbb32bf1a588cc774d4890184c4b2924a5b8073313bce226585f1adfc229c90bc6cc9d212e62f05d33bedac961d77cf8c2620e451de817f8c1bb16a2c59ff804b635a73a8cf8c181b3f9401c3b643d18a2f706ea9cae47071a6 +SIG: a628a77421b2abab576eed35d2ee3d14561b21fa14a6e2fac263c3eadd79f2fc0669f9429b910b8422b4b29ac026a42e98d181be3507c5ed7c748a1fdcf1d807 + +PRIV: ce379bbe2fa8abcba51c7a7543de5b7180771b3c44bc6b41892e7b88979bab907f3cff89f41babf4fa64cba33a5bb17f413bbf2a1e112b50a8e9b1f821d849bf +PUB: 7f3cff89f41babf4fa64cba33a5bb17f413bbf2a1e112b50a8e9b1f821d849bf +MESSAGE: 001a74f095c814d3beed67a8d15fc18efe235dc3f6457812a4039b7a46fe9a0e9de81a7a4e5fbab5ebe9e1e4801bd11b45c9f7ad0636a09bff42164be5749a04c02f0ab61f0ecfdfef799b827da6a274c8d3b39f2e3805a6791287eedb2314d3f842b558b9b489afe1ed37bbbcfc5e60a431d5ac60b39e946d903d6bf6b140e12c7e07f9ed7ac46a3999c6245c8ab1bdb21879a317a3dcd257a5c4f349b7f59e4e43d62d9f1cd16f518f1ca6cad37e2cb20f2598c4134291c6b8a98aae5247e26eefb76aa38c9c8231c17e9dbf271cec80fba5b4a834bd9be81ea841637aa9cdd4c4bf26d7ad24ca3c +SIG: da98dfb189385b2c853b6cf375738046a8f27ef27974abcecea1db02989b951fe433a6ce1e225b3fa82032fe060a7d3f6c183fd1157f791a064b407650571600 + +PRIV: 2b2ee809d647023e7b77fc541f44875a35fa941d37f7c5b21fd34934d23919352c29d53e1bf2c7879d73d20ba88ca07a0b216d7f6d05d93663a65c3d9e10633a +PUB: 2c29d53e1bf2c7879d73d20ba88ca07a0b216d7f6d05d93663a65c3d9e10633a +MESSAGE: c4147d64ebfda41a1be5977262958104e940c3876bcd5b6956acfdec32c660914d62623c210663cb2cbe6249d7f5274991c60e950e8e2809049953c69581d2469f4fe982c7434fedd9d4e00ae08896d62cc1fb984dd233150cc2483e159cff4097df8c036bb633003abbfbe18c8fa79b5a22270838123fc9be39b8892c80384a385028c1a81ec58c8f21060e78afd2c04bfd2d30ca3977c6edad518cc1e2004cdc14bf3d15f5f528e5af277fa182275870e5c012f5f82fb1afd04edde4578ddd2160a1a3dbc050e80bdd811bc88ead79bf93f010cd0fd4433d0bc348dacfd0947cceda62bfa49711d013 +SIG: 12d90685775572c9eabc9be2574ca9ae66f0e652e578b21736cd6e654f7c6b1545883d56bf760ccfc3cf87544e0004c798061257e130030cb997a788369a9a05 + +PRIV: 4ea18d6b4af8053b885ec188be48deb86ffb2a69a4cec86637bbd7b41b807c46e5986059976233ed77382c3d9959f34e317962696553e86ed1e5902c4bedd167 +PUB: e5986059976233ed77382c3d9959f34e317962696553e86ed1e5902c4bedd167 +MESSAGE: e9c89a1a1119373206ce40ede3b89a82f89462a1dee9e789e9845eec21f571c0faefd430ad338e4a72c047a39a4259580387fb9aacaddc36a2b51e7b60a87ca1321ff806794cd6dd4549a4df45c2dae3e539c4d7d06b6e6e9f466ffca2fa4978ce3dc792e44a6283880cd138a75a226f985da41ffdc0e32a5a85c85fe9a43ae78fcfe57f4dd7540a6dd3924a49ab39eb69950d421151d96b1e4fd3935890f634cd52a73a755f5c2fb72f9cd5a2e67ea930915e133b47cf6b7c10a9d889c6af6b5f1f4f51094d27fbba228ac2268b344027fd49e426343cc0134399b4b510aaea50234df42c37fa1c4f4d0e +SIG: 27570c002a487d000ca3928b83cb4319722c46dfb4cca260de790ec0e3c1932688f87362952818b54f51bc7aeeb263f960bc0da8964bf312ef93e81f06c80b04 + +PRIV: fc1b75d17d3807217351d2aa40d9b04f525b89ed3f5fcdb311bec2aec5cb7ece55e484e774a4392a9d6eeff835a8fbb232cf6276a89c74fc0d1bb2045a8b21be +PUB: 55e484e774a4392a9d6eeff835a8fbb232cf6276a89c74fc0d1bb2045a8b21be +MESSAGE: d031bd11da308097e3beb6ffdb2600ee6a193ca6d8324501c972b1a25166fa7a369f5bc882ea45612cf02580254d21b40b0363237e835dae2656c1b7f4736e88be53d6b119c07f5729bbd82f67de03588322879243c5990a7e61f56907b24171a57cbb0bbefba2316277af9326f9cbf3538bcbf6780be41825a2ca774b41bdb1cd5c608851ec2339eb2f4feeddaa891a6326b29d97d7fbf311e3bb749c5d4c058dcc14f452f9334991e271c16d6508c818633927f429804ca7a38170f1b9f6bd73ed675e11e8c0d321fac912730b4ba2f7c428534adcaa4dad314c55807e6c642d494c6b2f0e8cd129775cc0 +SIG: 9a68d151fea3909893359e60b96b68b2a3e2946f2b47b875398a1e39eb01463d35eae7d976f833a762b51f2726ee0dccad5ce3600564fd9dd58c23807fdffd05 + +PRIV: 0d0bf4d42ef810b179eb841771de6dbde76361caf894e42a14b1e09787ea3e067171510b43fc17efa80b15e320b1b0a408332542e0d36e4ab9a649cd941b5aed +PUB: 7171510b43fc17efa80b15e320b1b0a408332542e0d36e4ab9a649cd941b5aed +MESSAGE: 8e2179975d0a8e5a69fe875a3cb1e79aec49c3853e30dd0320fe3ebfb638b82f89ad1643036b37e56e0b55e0a9e22a4e283d7a27485ce9102db6787d6628b77913e10896774e495c26e8bab26e7f9a94d29aaa36aec9c26ad3f50e5d8c0b7698bb5f01b876d0d65fcf5e9e32cd7b89829ed05b0b8f63a93858985bc9569fce429fd37a211abed650f585c3b55900443b6c5d6e8a48ba67deeed07b76e969fc88430fce2709c0bb5ce926ab7f44e0cd79f4ec359ef76748883fcc3d026edd06c8b9cba54b990d30aa41f1448a10893fb0539280c599d42361433a34cdafd8ebdd92efb9c38a36daf4c74060c696 +SIG: 24446bdf03416a4d08614466fb851db50e91a623cacd1b0b35660f3cf933200e15308708da3499a5ad25f0f0306b7942762e20a765b7ca9b901c750b3a95320a + +PRIV: 57b5194d26abe4ab2116c0f03d23dbe116d48825a25e77d64648b43692ae25bf499c02dbad2a4eab3b6ff1aba3944b91c3f273a382c548a6f3a19c83f0a86724 +PUB: 499c02dbad2a4eab3b6ff1aba3944b91c3f273a382c548a6f3a19c83f0a86724 +MESSAGE: b4813c9d13215fe9f63a78ff7ac95173eb810b4613f0f48d6876b2bd3b2c72bc7d98cb1ac32bc41ca47f09896f79204ecfb8264ce8f3c3e76dc124da8ddc6e0dfc1e13b5a529f20c82613fb9a82e5f5d77326a861faedabc7325c59af33dae6744025e649774fc4f79134bf9f6e3d5875dd91bc8a14cc36a66283d01d8d108c13327eca53057ba50bf210c19f139de6494982646198a1246c271b0a368c10aab95cd8961235d742df4545be68bd010dc0db23b673e623609e420ee76b1056c520f9ce8fbe8ee1863df97d17b7174636c3a2b612295091948810d1d4b8a5843760a2887dc55ef512af041ec54fad3 +SIG: 4c7345960c8fd48a7dead71dbd61908468efa865a135568c8f9ca0055483468617a7e335840f57c6cd8f2c9805cd47a9d7cdfde53da8ef4f1adbb6f698aaf100 + +PRIV: 068d27b21e2acfcc19c3e9673dd44142d98aacae894930e20ca067439e749a79e22ddd396f955bb90e284776aa76e921e50699d0ca8914a9b7b841eb5ff47d6d +PUB: e22ddd396f955bb90e284776aa76e921e50699d0ca8914a9b7b841eb5ff47d6d +MESSAGE: 1c6815423d1a2c5ebe8828d1646527c17b2006e547f016b5350f010d79b13df4fb8c6ed57ba9c26c3cb0e0a64178b650a3ea5444a4fad5b20a3eb8caa702634011cf7892a0727b6e8150b0770429a37a8a0bb3a7edb891a7c90240bc0360b14e6dd770a990b31b31f33ddbf653988f82742e5eec31b27368eb0e4f1ecf4d676f49214a520d1e5b2bbb59ac2e13267e07a0cbacbed9f94d7473ed697828b0928fcc616ee02e51fcd8db4d8f7533b7b139a05e06f9e0eae32993e3025aef0590b3fbb4292a3ac40765e8584ead00266acdcbdde1457a03b7d57bd5c9e64fb06b64a50f35f0a1ec34b6ddbde767b96ffd +SIG: 0c173c488ad001cbb9c43d7b30a7c071a2fdb08cf7f37daf71d7ae7128dc0d43f0f095b2929c54b773ed4a1f0bf0dc4f364f0601e8d5ae062f5b78c05bfbc702 + +PRIV: a34d52563159e0723e9f3fd133bd96e20adae623f8c798013bc36b441489bdc21fb658e645de6d3efdb083a73fbd592fcd4b800e03c7bd681aeae6576bfbbe2f +PUB: 1fb658e645de6d3efdb083a73fbd592fcd4b800e03c7bd681aeae6576bfbbe2f +MESSAGE: 1d215f85c089f35f307a746c66c7c1e41d6ba37730d759e6e5622d6c6a198e40f63d37873b715df7518b3c6bb5e95a467726b97c9a0f8f5dfcdbfd1e0de357661ddeab555042b945fd899fad6d382d7917da9e12dfbda0d69900b3975165a73d0ac9de01fd3048b8fe5f0b90be67e03dc22f653a0a13eb4b0b753f3f3bbf787369ebd8bf5e00eb78bf0b3515a91e68b1d5fc6920bf4f4259f8a730efc7f1016d501ef6fb7cb8366fc8e716cfa50ea8b203cca1a316707e0b0fc57eafce82d62f7ff3ae04ac8fd041b55b19a352a69e6d4b79d0e650175168e34fa3358eac816cecf2c8dd1bf2a589113e91bb818f91f8 +SIG: 5fab5a7140d47873684305aa6353d3862f5fc13e54a40c9563cceac8f74008c6c445631fa864e0f1c345b5954f80056aeba25662b78827b5e8e3a9437813720f + +PRIV: 58dfe768bf52118494b29975154cf452bd9746dc7de1d6bcd18ee6a05acfd8580f1476c6cc2a1b4764af75805e77341f14a0d8b09c6a5b2ea287fd517c3fa6b9 +PUB: 0f1476c6cc2a1b4764af75805e77341f14a0d8b09c6a5b2ea287fd517c3fa6b9 +MESSAGE: 609794201c4f6faf488790d61dbff3f41b328c5b0695cbe9aa8a136d72b4977b21b500f216e9f32168ada8c13bff25327647e30d8a244d74d88303abc90b7f71aa07ca04d17bc8a0167d6e63fb88baa1dab81d50f1e91f46f5af77f2e8408b826336a35052efffdf4af79596af1bb2259f83c1bc109cfdc3dd50fd96d310f27ea4c6c7690f21815ea92bd79389680cfe3ed40c80181190688d24222d9a1ed52ce6a16b41dbd9107eb6d2e3594e4494d75dd7c089e3b26ffd00d1003c92c4c39ae5382ef9291491a880ca4ec3ac2b86e66719b92b6f7cea2cb0bbb1cf624d0d1abeae556e5f73909dd546277037ec972fd4 +SIG: 977137a38af44f4b262abff7e07282433c58926d562fbc6180bde6cd9497861fb6d955cf383d999fa1037b8b1754ce888c9ffc1560a451d0e9db8d74d2940604 + +PRIV: 5a63ef9bd7dbf0e89fef155983659e8a0a6ca002bc42fad5a45af8e0281923f4e632f4dc994231cc1790c21afadaa977a589b0eb0da19fcb2792911b15ecf8af +PUB: e632f4dc994231cc1790c21afadaa977a589b0eb0da19fcb2792911b15ecf8af +MESSAGE: 796bc8361c6e8eec39838b24f53971e820f82361e0510eb4def1db2512387d6bf35bbdfa318879209435d6887b1410b3ebc1455f91f985e0fab1ce1c505c455576bca03539d048ad3a0ed1f11c73bac6809e2ea147975bee27c65261aca117df0fae7008e2c3c130bec5533ab89351c2140c9d1a62bdf688629787f954e1c610cbb75edb86209d7c357cd06ef41931dd5dfd1c7d407fa4ee1ef29393beab5713173802cce2d56229cfa76b601662c4d9a84a4936c52abb1981378b717eb55cb604a68d34f03b219f32226ca0e669348a2d8d2453930eb6e9c2bf66fa4e92c75136e148cdb034130d3f646382e1c71579ac70 +SIG: 75461f99650c0368058113a15ba16bd2337b2e633da38112878c4834fac9ba2e307c866c02af79bea33659614cbb4465c57ec3effd4c478ae38a34a05cf1ed07 + +PRIV: 8b2f06141e401163f90f674b04dc90dcb6dd3386419339662ecb0dffadf2500b54da934a659119198553fd4566b660d8d610adc3290cb84829c894148cf3f67e +PUB: 54da934a659119198553fd4566b660d8d610adc3290cb84829c894148cf3f67e +MESSAGE: 1deb25d43458690323a7d26a26695090993474f467c6fde5ddb34da945be3cea2f6b75652ae21cbc4fd22763a1b45583e1c3e88bbb5fea2049b7336c91159988c01526824ca3bef16b362b9202b8b9754185bd61bea8f539aadf4a1ab135fbc31d2a8e33178073106cbbc02d4cd0d3c8feaa8eb733084356251795afbd78ac3c4f8a3ba19aed755c646f35569c7a6c675b6d6918e834969aca03f71a2e72ccb17003bb75b62e852aaf58b3baea89bcd64a32eb14a6b9e10de48971e53d0e9ac99a78f42de0382ef0e80ed3cfa343f35e4a9983b9aeed986d3a57f47e5e46d40e9d677302809a2d37e4ec011f051b4d031ed600 +SIG: d68e3750dc56432397401c98ff1529db9ed48fea246dd4ed383ec74c1a463aeb784c87b1fda8bbce970fc97aa9807ddbe95d41fb022ea68c1e311654fa1da207 + +PRIV: dc649fbb1bee0a44814d6d9e9080d5d90c1fc173ab5fefed826a74723a774e0a0214c89f3867ad2e8870e50f8c2a6254986d9c220e3338411300cd9c6404d4b1 +PUB: 0214c89f3867ad2e8870e50f8c2a6254986d9c220e3338411300cd9c6404d4b1 +MESSAGE: 328700a8ae581c1edc4e2c00c78bf4606097f9bd75aade205a243c5fd7434d6222da937e2881a2e3c574356d4d5679301da99e11cf749c27921c8caa2ab2a564d87c5df8ecf1a72b680184824f6986022e3fc98bd2a21c3455abf1154954fb30c89882947b02f35af7b1bfad05237d242e2b74832fc536196f2e59d1acd0c1db6f1943d0f6043bbd6a769083ed66ba0e05a50feb0acf72b6c16ba9af039afb7fe2a4aaeb4d06181c5a1878689e67a3f5d0ad39e794d6239a7e0a12ce820c5be60fd5f1dd79702f49d02b79755fe873f5785c72f74625cd7e2428262597d31482c2c0508801fd96319d61b91ba253a5e722f414cf +SIG: 0e0c5e4e184375da4ef7e2a2e4888050cd84e2fe21d08e84a852db2be3fbc372c472de0954dcd1dc11aec493c569f40fc6f77f03ee524fb06ec40faa1d6cc10f + +PRIV: 39b8062da43e64e1676765d62c7fb8e0a99c4fd417d6f7e3319bb13044205f3b6227cefe88ea4fb27b37b5f797778bd72fdafeadccd9aeb67ad437ce08fba6a8 +PUB: 6227cefe88ea4fb27b37b5f797778bd72fdafeadccd9aeb67ad437ce08fba6a8 +MESSAGE: 740af679e3069fad059fa4825fa41c59fbd484aa649303c27c4f7a94711c5b713b2a6b8987859e2271a6a71eb0b4a15abde4f5168f6cb9dbdc6a27a2a13d52c9720896a1f4ce3a5345ee793b6cc3ad80d7d58163d5455b9cbd073e2b7adbff95590c7172271bd91fefdbd01657ee1750651036cdc3560b444ca2184bf4f3ea89fc973aab6fb4a8ee5704bbe5a71c99fa3b5ef0d0396249758297699ae202b819690dc7ac4692770346907845e2210d5363adeec03f0fc7761b7e0ec0fea1bcf6b04fc54b3e4c40d19b8fa649ac8479e8f80730c0c94e9f4a1ad506f2bcab0c49540f6decaa77b3d657dc38a02b28a977ece482545a +SIG: c5f626490c0ef4e1efc3edeb0cbc3f7de267057fb7b6eb8f0c813584965bc5c421feedf54241cae001ec6d5e25c9b1fba0385e5dbd95a06ec1d8ae519144960d + +PRIV: 52f4675d8ccd0eb909df0a516648db26fa033ba41d43fc3845896d456e14265ff39e7dafc97b0a84dcbf7fa14a9403ee1fa92b85e5a7e5d05f031b44ddf1f794 +PUB: f39e7dafc97b0a84dcbf7fa14a9403ee1fa92b85e5a7e5d05f031b44ddf1f794 +MESSAGE: 74427110857cb4af0a3342c2b52997bce1a0db6405c74e9651c5b85979acb071e567fe70412c4e0d8c9fa421914f6a62f2ae420b7b2f4cf80c90574221222288b65867eaa66e7e0a0557a26c549f9a7a4e70838ba4074b4cd7a9d758b378b88dd49441df802a444dcbc30624933b59922f33c20f019fe78ee24b8fba79a682f388505ac9c97f4eb87c611880026b4c23306b865173f5d716abc6cd9a9906db3430136f754129c443b20c42be2fbcbcd44034d714f58a4ba8e756607a02b608ef49648f2ad0cea99e7ab30a8dd7814004f725f49301d7b304dcda625c296d928cb581736ab739c86b469241a8259351fd37b4780a9993 +SIG: 4bf668827a720af68898a06ea7b44545a34ca896ecf311feea47e0686d911fadaa03118997153c65361fea15de9bb891b8909872045508ffad0cd9eab21a9702 + +PRIV: bad73c9fda4ceb9da6c701c2a6e2efc0467afa0a74f8750c52cf1fd4c8e7489abb0f027a9035376e1aa3206c3d774475e351f5767ef86ef48a72c037c24cce62 +PUB: bb0f027a9035376e1aa3206c3d774475e351f5767ef86ef48a72c037c24cce62 +MESSAGE: 74b966cb780771aee63d734df3756702d1d5fdeddf32136c6358b836318a4f984fe71e7716adddbd649eba44cd4282e0055d8c1ed2d35123d66e5a98f1c0838ded563b9a20eb8007538fc7b0713e7e485e3c28f6ebc421a29dce2524db7f29205761036ada62e5b0b7d5b7f294ff17f338232fa5fd42b6f7253304092d848f50735248595da0f7ef28e568e9916bfc56d7ed0d811b59d5d891ae43e1b198071306bf525c678c6343998005fbb7869d1c40f8cac807fe2ef03f3d5b933f58978ef2906fccf7444a2936e63d928c690926c9c994ed3d666263e956fdfea27764bc5f74125bc46bc102dd3e5ff93b5e123e4b38bdef697e15 +SIG: 197d6b6cc88a98c06dfca0c01225edfe38a0b2289f29f8a44ec0816a952d585e2d59b5b08de100c0606296ccf5e92a99e093623144b8b22db87d929225546005 + +PRIV: 707327a431dba77639b3966b2bc095f8eedf57f7a200e3b0077ce420389c92feee2496910864189fdaa3c7757eb3cda9ab1e70fc9e7f71a38a0bfc845931c95a +PUB: ee2496910864189fdaa3c7757eb3cda9ab1e70fc9e7f71a38a0bfc845931c95a +MESSAGE: 32ef31b64eee700fca2ab21a267f8d9d3bdc689c7538fe959bf713fa995db2c0ad36dde430a8417d437b72c74e26dbe31d93701d4617fe51825cff7a544fc9f44e4345e14b4b11e15f26ffc2af8035f3f970e4dda44c0ebc0363c2b56fde218663bf78839092538fc2f39153d4eb29da0c1a08aa966601cc68ca96e993b01b173a261b2ef327650382f568fe944855b0f4fd9d15e752ac74dcfd37b3786fffcef23339c21e9270dce8891dd5eeeba9608fdc7b6fbcc99fa1b5903daa0968e1b691d19d06f215ded047ef9d76610f5de220f5041b313faf9e96c9fd7db54b5225726af435f9cbd9fd87ab40ce8f2c6940b55f0faae87850ca +SIG: fb99029feca387a5d765961e361d7172b98b7e0f11290bb1e5b57b51bc2123d0bce29020392a4fec9ae6a72c4c386cea1857cb8f9c50aa9a76d7f1687fcf2900 + +PRIV: 6aa5c9f008f990473ba4a6286a416614026661f11e1a24efa81ac35852d1d070605ac9b4dbdd5033d6c828bfafa93c0039440aa11ca724ae834043e07bd032d5 +PUB: 605ac9b4dbdd5033d6c828bfafa93c0039440aa11ca724ae834043e07bd032d5 +MESSAGE: b5165d3963f6e6f9ea5657e9f07ff3a321eb338f9a8c3d3c42306b2b278978b31c623a631be3b04c41edfdeddf538e1b765bc8785401c1af29d0467a64411c497395d755dca03ae3272f4bc1fb1918dcc1ed6f04d6498404a8ce1409d447f570a4359522cc54629202ebe507ab693843141bd5ea0573b20f321a483ff383a46897f5926fe0b8afc25572707b63eeed283532928a4144196497942c572ac547605139256b0aa0eaf04db1a256012ed453b173ee19ad6e9b1af3f45ff3044a641f8c8eb0ac7bb45abbded47286b2a069d3908694ee06f2fbd0ef605a7911026ea9ea3c4913f38c04d8b69565a7027867ab3092d05f4cfb18fc7c +SIG: 9756303b90655e935251032ab19cfc95ca1c2a2c3ea28b033bd47066cbd4c7d8982a8b9886f1b9cd02e88a65564da8dcc34f308ba9f10144ba469c2efa49e004 + +PRIV: 8efb8b79742be21e6d31de678bc81450ba8621082cd6f0003e22861e2291c48133381e356c4fd386a3f7b969afd9f5c00d2067b698b3f1f00f3784202d3084cf +PUB: 33381e356c4fd386a3f7b969afd9f5c00d2067b698b3f1f00f3784202d3084cf +MESSAGE: 6b750325d3a0f08a147700b51a9b3725571094818ed69d1f761013eb86f323f73c49f5e439877c2783b336d1f1a674ef3e431fc1ae0180082df5fca69f848139fe6ab6739a0592ebd6d4705c7f0136b22189a11d60d4d3c9bc80fe7d7c00952d5742f9c0c2121fe792df133f221db991fc960ee64b9d32e0178e542bce8efa8d03ac8026cd77ba8bf0b24215b9faed2eaec920e925d5ec46fff6bde725e91c8280e4ada232a5433ae9680ebb53eb55553147c93370574854896154514299c093219a111dca4e637ad5001338c6d4d5ee9098c65832f7af835bcb622128423036c79a5737738a7539f8d4a6b8b221b56d1401aeb74d4571bc009d +SIG: 923005cb4848402aa8f9d5da74030b009444924c214ad600ddbab4c153a6ff022b53cf6364cd7ee99bef34fe144da964edfc38a0ba633312650ebf0e55a06009 + +PRIV: ed046d688b2b0a1bc3daf2119dd321a607b16d2a2d1d963add1209c665b5ccba8734f1ffcbd71cfde290017ea6253e580d59e65b541b46521f5e5ec1451eaec6 +PUB: 8734f1ffcbd71cfde290017ea6253e580d59e65b541b46521f5e5ec1451eaec6 +MESSAGE: b9cc90fd8de2a141f95116db3b04be83e98522597ec2174964245180b9a473767d6d470a217db5ff5a1ab777e1e28a0b16975e2bacb873020444b47ed8326421b90ebb503688f090c11b3b13617c5c5052c297a41e2893775e34d59ada49d994c0e4a9f5220e9f0315a67705a3ec08af0dc724b5cf67ff34fada8ba7109ed2b5a8907bb403fb1a838b4b059f18c792d7bfec05dee0c9cbbf1753409d7db3aceaf47b4c61398497b0eca6c1f8ac08a7ea1eb9c40bc4e92e888212f7d9ee14fdb73158160944ff9bcdfef1a7469cc70f9474e5f24dfffea585f09eaaab4be2afebbe8e6cf86d35680dc5d1b92913e848256ec736316fd0a2142063b0 +SIG: 721bfd4776cfba13330fd37269e979c1d7b6ce54a51b82f456e137378e582f192a12089da5aba76a7b161813dce56b72892a35330c94f7ff21d09cf09e553504 + +PRIV: 76ac8e570a39b3a0232c45497537fb2155acec3617865ed1df210f00b49d1b8d312a3ad899ae6a25507ae6e4524e10b63a6e7ae53d9cffd39cf28521d93533d6 +PUB: 312a3ad899ae6a25507ae6e4524e10b63a6e7ae53d9cffd39cf28521d93533d6 +MESSAGE: 53ced9db2b479e59d3ed643f7cc3784c24b8bd4c63206c72e23fa850028899a41ce1a8bdc003f12b7c29972c9a08bcd231fe0e1a0fef0bafbfa4e0e027d72004075ba37d490eb9964e783bb98f9e503e9c1fd3d23fb0017cc7c7a9f86d171f041e2355d8c5e6229d34c7eeacb6358cf3060d5d265bae2004a558878659a30dfed5f2ec788b4e14397b5d00c29db5d4ebf16639a8df292a3d24f6983cbca760d903e976f5b698642ba1fed49e79c38f4bb3946efccc9d6aefad336d558f78e4f205422e10384a4e531e75807efb389d2af4cab43825fb87f196a9080769fe7585782970a6918affe10d20d629b705845597418d699de3f1de854f94bd +SIG: cf03f525913c44303b2f80079393c21c1158146ecf99636f5d97adfdd9f35839804c23804cbf1e553cfd4b73f689a9143aec298f8276e1e4ee0891f1ba75de04 + +PRIV: f64a66ba0f0819f3001416c220bf52d860130a19764aa8ab38d15b2aa75ac0228125253cd337e00d45b45079b585349561e5f542a81f6d2fcfd985c10feab2af +PUB: 8125253cd337e00d45b45079b585349561e5f542a81f6d2fcfd985c10feab2af +MESSAGE: 8072862ed0ab35921db5ec2cba8e6aedb0441fdf47491006c01e6456ad70fae3c4152dcfbfdbb8f0fddec5e96b12bf67989ba96793f4861a11b63909ce8d19b8ca64a544b31ce051fbc88e062806d9965cbd2967b01614e86b532fbf59843218dc9c19c80315f044731719371092a3da38878bc4cf77de972e860466b8fc45e465dc3d0ebf94bdea60ef0b9891ced41b997b11b31ee4167db60c9cfc8b85beacfe223cc1829213774085d7c06d2b2e632cc21cd9660df47c4fa918bdd596ddf622dcb652642b67527ba8ed15a819a8e21f48d7ee70247f5200e37c259dffd17eec8c232f970cb03182fe3964132993f6ecb7c4db18ccef390c9eb3639e +SIG: 4de6f5250822d7c9d5bb98582500b5c085f541ebdc450ed1acaf83684827ed1dc77147aae4b19e14a7dc5bbe1f1e4f5771d8a6e4f2351739afb08c806d558701 + +PRIV: 8439b1d60aa48460135eb1002cc112792995079a77e6e8ab020b9abaca8920b4eadc3e0c5bddbc3052c3b2f8b0a94566c2b2c879ed17034ac0e6a45f2b3e32d2 +PUB: eadc3e0c5bddbc3052c3b2f8b0a94566c2b2c879ed17034ac0e6a45f2b3e32d2 +MESSAGE: 5419f6d24eb46635d4a7f8eab803cfd0d04de092afbd86f2a6961a8d1eb8c0d197ba55ee08c991822a5aa702bae0337abd5ca7faa15e1f1ae369946e9b81216c0f5fc22bbd4433c3de93c5caa2741683bbd0e1a78df28dda19174101876334d40339659f021ae766162c6cc5421b79cf9d5c090ed4af07ec84493035bd0b2421b533684295bbe76a70fec596ef8c89c5c9dda3c33b7735d2d2f20b28f1a5402e72d04ba291dd59f14af08adf56eeb086d769c6bec3451891372345fd6bd02dcf95e803af0353150e182e323aaf683e036d9a135d2e6f98cb4d327e2ce7d54247f3592ed067b4ce7627174f996f28165c9c11f07e5ee9cee63851c6b68ea2 +SIG: 62da81e16440821b593b6ee6540e15d1aea75d23e0a1bbfedc808c9548f87e8bbf36915a39a74716f645cca5714d170af907576d4f3705e543d2adddc5ff2303 + +PRIV: 3a046397f0afc072bc7f907c74d38fd1b9afdf27e14a3534768b0dd2df3a1c2299cd70ef3be342493393872f54c47deaa081021892d11a3268f3145ed4f3abe5 +PUB: 99cd70ef3be342493393872f54c47deaa081021892d11a3268f3145ed4f3abe5 +MESSAGE: f08ddef46cc6c34179820c9861375172fddf774f8dc3f7d64aa432da8e5fae644c0a8a9e6908517d505debd612868ac6daf95cd7e1699750022ccd4b88dbae2bbf73546ee4b835d319a842dae8b9ed683323f31e5cc57919bc9dbe3bcfffb2ada48072697ff4a7d310c91adbca81faf26a0eb7bb0c404ac9d8dfec63e9c64e2f420c07d323b7c0dc3b73507283aeb1cee51db4e1a83a692c7c1ea398f6f30940fab85e2138d4b85aa4e231e5424f5b064ed026f0ccb99d1c85a9eb15f5934a11359d411cf94ae8ffa3361a224f46bab852d184a248b4c31fe3a7e7f5134c051031a9f328a7be4a7cbbb1d8d863a400fd2d58daa44f1b9d8e9ddf961ce6322f +SIG: 5024ce60257965687080c5b1fc7d1301c32aa6fcc835497d9cb23a74a6ca2724f55353c1b757827ca5440c9ef8f8c1050913e20aabec35c497b56041b5deb209 + +PRIV: 124f7416a80453e4cf1cd7b5e050a9761418258bf7d27beb7f23238c4540be2d0da34ab173990150df7399b6bcddba93c6dbcbf4d176941cb5071e8734c5dc92 +PUB: 0da34ab173990150df7399b6bcddba93c6dbcbf4d176941cb5071e8734c5dc92 +MESSAGE: 9dcb9873ff054db11d0a9b19de6885ffba7f0e681cf7fb8f6cd950c48328d1f919ca46054eeee6c9e57843ebdda7b24bc3503c4d612abb1a314f39f58221d2b54dc755acca7969740e7fa8b1a9523b8c7379fd395253f4e6cd054ee24b75613c3581d49e19246a7b3be1cecb334be44f3d626fe3b7b269e628d44580c20636eba2642f2744b959e65757d0ee601843f188e95d17253fef567068a5405a3a9e677fea3d7d55f7ead19a3f30c5f985671b55fa120cb9d05f471b6e1e8d779a2c803a19e6d0d7cd507887ed647c2a95483f933991ed45ae301a2b0e954a5703d248c78810aa0b199cc2bebb2f1d71cc40487dbd42eee0f745f7d285685b1fb31b15 +SIG: b0572104aa69e529e3465a6fd28f404a4ec20276a993b1725eb8c5f650b4a216f1871b24e368cc46cd1ee0174cda1b5e4ae2200aa9fc44522d975a9c51814908 + +PRIV: 25d13b3837601b07a975693e5a33d5337c34c1127fe4c27490612aaf7f642e9a3a07cd68ee2692d51cfad1a80e7763b18a043c74f4e1b01edc55ba9a9e07795a +PUB: 3a07cd68ee2692d51cfad1a80e7763b18a043c74f4e1b01edc55ba9a9e07795a +MESSAGE: 115b3220b45ca8f36c7ff5b53887d47e669b78dac13b98cc7aaca5c2e19fce81ec8617ca410e11c9a9118a668453b329ffb718eaec739172f0a849a0848192a5bdea18ab4f60d8d1a0d338952d77b2cc13efe83c76e8dd58803b1d8b3c9729ef102b20835b7de872bef3010f15a4caddf07cf7bdd222d84b174bc21527cffb1b7ffde81e281d30cb7bce25ea3dffb6ea1fbb06cb70569a95ed1a07e97ca42de70aa218159efd608fa9b0896e0b58518a322f251d133e58c8fc1428ab0a170ed845c75fb403f1ffb97d2d2a6d4f277911d326c1cabbb8516cbc17908ab81ff8d79af44611ea1d05879c1ec81d06936e0f4a0aef6d5748e181d30ec25236597a973d +SIG: 20cbf08392fea6a99cf446a95c199caa0c0f9813cc217b8d228e2ed90bab95ea92cd73ac95834764d33e42243c80a7603491c8d3e49ac715fd8a5b9e4789bb03 + +PRIV: 7b3a76decaea60c41e95b05877a7da82064c27278c8d7df5f0bb95f0ad2d0435f80db5c28721b1c611bd87eb145a98bbf383b068045df2458d1a6fda099f7fc2 +PUB: f80db5c28721b1c611bd87eb145a98bbf383b068045df2458d1a6fda099f7fc2 +MESSAGE: 375fadaedd9cac49b64e1574028046069f4c83654c8a7011abdb64db16b47fa311798172f9072217b0a6a43e5df6ffcc1154bcec1c68e1d35ec05880d012ce76e4cebf301bb2ec983d00b4a0540c937ff1c6df9441c61bdb3be8e0c7c11a35d49b6f55c381269a0e768efbd453447fe48b75ac39646ca82eca7d149304423491871c10dbcfc5973a57fab8371c30cbc4e90becc0b67152226ee177b4ff368ec879b391eb95e36dcbb07b2c16ba395545d4529f727b1a11ef65d120976b7ccc86af4bd204cb9489c921e43ba5e850cfe59899f1c1ec4aa5c92b6dac6914b1952b53dcb540b409231381568987bb2236bc40895df3f17eab7c0274f2244f958612e88e +SIG: 2cd26fb3c4f7440a72affe93564f6f6559adb15cc7a2ba10879fb7d67e47d4ebd02fe4823698a5fbd4a907fd69184c255a170e5f1747fce968102dc219b50d02 + +PRIV: 5ff8d4052608eb033a5e94b603ce384d8452f60a26498b9112567f3410c18666c4900de24d9af2482763109926af7c481380fabcda9440c1a53ea1cdc27e6568 +PUB: c4900de24d9af2482763109926af7c481380fabcda9440c1a53ea1cdc27e6568 +MESSAGE: 138c60557c2e9008afc03d45bec71f961149a0835926751c8ff3935c7d652d83e1b0b1da7d5bbe0b8e171a4e49aae06fd8a9deff78dcde4d25b1aa899998a0f99e1df6f9337a3ea2f24b76c317a7014db4e5283191795a70d8821d217846490f958701d39dc2c8ce47d928938874d87b3558989bc77af820979a351eef9594aa5b94f3341eded4ea20b08c3e7c5610d43267818dfac0a87ddf527fbce8512bbf85b66c9bb5d62f0fe84048f23b19604a5c8d82b1f25a8da02731feb2ecae489b8475f7bd326ddf1a08189e46c08cf50538c2a363e2f4eb2c01a204c7ffbc0b981adc0fd997aafdf2a222ee84c309f6e95ec7de4fa85d4768d5c003165028225e22e09e +SIG: b737d4e5be27deb6d87729c636dff7a406c013f313c38cf683fe14f75a3b3005d9535d7e5815c8f8b37c51d6927111c979f7d9d81a347aa9cc09ed4e6c18e90f + +PRIV: eedefc1757e3a7e5ed3946dbedc396a362f683d2c51b0b9f60765d4bfc5134dea9872bc2192fc02b189ceed403ab9f270a032a835fdebfaf1c9d6934ed8304bc +PUB: a9872bc2192fc02b189ceed403ab9f270a032a835fdebfaf1c9d6934ed8304bc +MESSAGE: b194db73f994cbdc3cbe630ba72c47c2249bc0592ab547942b1d1b882b44f5b3855e568bdddf92ef05022d88fcfc294e76b64a00e9c74355373763e49a4ebc47243d48a9ad588994a518f80f8615c2b31da587a53e529d435a8697350dfcde02d20cce7d5eeefe3f5ab2aac601259cda38538a1b8301f9832e75ab90f8a932f267eac181003965d5266f206180c6c380ece803577ccb46176bf607159486f24259747e2ca6fb1912db7b78a973b2846387c1208030ee1f400d0c5b5e8bde9635ae55638ba17c734de8638bb85dfcd76629a7f9f40d6ab954d55bf8575fc9c9a595097e0893db5a7b8a6c455ecbd3d22d725e19de2941f467f9eb93d66a0e2bbdbf92ed1c +SIG: d5bea8ea9a5fe9ed6d2bf839930c0c6cd5039e988f551fdedb5437e1c1af0ed7b3897c035711c3c51926be8d1b32024d5cd582f5f8369ad84d18b12502652f07 + +PRIV: 09d22bbaa5956cfacbbf9fd5510975128686c40c6ea96b89ef4c0f0c649bcd7fe559ea8acbdc61b6709a7d83ae15849a6c78b203923dd0a299239ee4886930ba +PUB: e559ea8acbdc61b6709a7d83ae15849a6c78b203923dd0a299239ee4886930ba +MESSAGE: 1c26a0f3a1a5b2d7d5b297af8a6a689d7c62a25267e197d23becd2f2b816c4de92fbdaffb941c3fc8db7a84335a84cfbc92cb3ac806ed58df16b6b8e119a48df4f27c71e931a5938e7d002734885e13a258a15b6e1136efba72f1d096b689f7618f49c968063e8f991fa0b55601e430eee13492a1b09413eb23813591a7a9f070cc396ca9d1facdd4f4ce37c40f7245f55035e10fad6b85b5f01a1daacc0df94069f7de8f6467f96d1fb98648e8a0520a8cd723c98e9dc2dd4b2934d8228f0ae1a415bd3a7cda38d7a9983ce1af6f8c970a2a591635fe12b917536ef815eaf1a3138d70ce70a794264d7c986d9ee3290445f15a9248f2765271e5a992196ae331abd4164bf +SIG: e65275c4328a70ad62408ed7fb1728be87a73a814fee8ebd94f2665c71bc66ab0c1b07a600b30bc081a74c536857c20610384be268d9af3e3ecddd3eb0c14c0c + +PRIV: 77826ed351a3f09254ae5692885d774cb3f24410a4809fd90f8a00da9aee99033eac8f41ee73e6ef136821f7957a1c27e15638d0e3916e6caac6fb7beb7bcfb0 +PUB: 3eac8f41ee73e6ef136821f7957a1c27e15638d0e3916e6caac6fb7beb7bcfb0 +MESSAGE: 1ff06c0b3999cecb1900a47d267beafbb35d93d14cb2c8925e3e3fe5d967586925ee4baa41998edd0103205810aad5c0bbdc77874476810246d13089a64db576424fae0bed9664a42a491147d1ee3b9c3b1ba4875be15462392540f9978d9a4630ba4c525499751a45efc299ec7d73b17f9ad275ee71a687e72690d7320242d2dc2bd4d5c5cf0f17a465185dcf60f8efff53903f20b0c2ab2192d44368f2f2fb36048af071f7aa857b14ad1d11461205bebe17e02be2e3ccb6092821885c4e0d4811be3f45b1fea088453e022432f562562b43a355cb56270cedb6c2c42dbf9be850e77192fdc65cfd36834be988dbe9a93e2518c138b090fb9da827cb1c91c8fe52fe7c57f7 +SIG: 977adccdb829b40bbd8e53856a783db346a39dff62041a2972d29009f1c9ff81b8ad54cb901e497c1d3021b50b6c69ee73558fd7be05d625f5727f9af2ce8702 + +PRIV: 99a99531c3cd6e3e9c900a9eeb26267e72f09d11b651a897ebb79be016f64c6e9bf9f8b48a2728e02608fc19899d219656839d1cc1e9a8984df674ec26662f41 +PUB: 9bf9f8b48a2728e02608fc19899d219656839d1cc1e9a8984df674ec26662f41 +MESSAGE: 7a89c0c1952fdc4298dcaea854efc134656be147e9e8e82fc9a449059d80570f75676b81c4a94f76a968200cdeb0988c73f59afc72ad4c3103e19fe63b7e95e140b5cb2efc7b97a6ffbb6c298ddace3be6d2ed3d598b8bdf0c2fe6c97602142a76e978514c196c1b9a88efdc1925fc506155cff9a2f21ab634e2b93e96928a5d8f7ce4cb7326d9689469242ba9c6a01b77496badef87578f5a17284e900a72df141c6199b0e71ab5da4375037617ec6196d4f4e23ae2916a72d0fce796022305ac9fbbbbe4705b340e42b78e1c02bb1001860cdcaf71ed89255dd56cc0b31c59d4596dcef84e22234be562bd801e94111d83a78064c90f9d82fce91f68abb03c73b6bd8d7e02d4 +SIG: 0e89da5d949cf2bf40c7e17c2d0f9ceabc88a092eb4d49cfbfeab7c8bff43245c67b9e2e92f9bcb9b34b3fcf8b01fa2ea7a9649f814c3aa98b3dd04540c31d09 + +PRIV: aa58403e763bac405db065eb11eb6be3e3b6cf00ec4a222b52bff4b6e3d156ac167f9b9a4665f93f5d7d3016ace6fbd13420b2e51e72bde59eedf26993b66cae +PUB: 167f9b9a4665f93f5d7d3016ace6fbd13420b2e51e72bde59eedf26993b66cae +MESSAGE: 3baa0998ff02b32b90b51f9a840c7b5c5870cfb1810a9b0f77b55909d47ad335147a991c29fbebfc592e9307175c1964129a2d5efc6215807453bcd726969781222bcad1c99a49748b9ee667c4d0c82889e2f50064c115dbd8fb483d72ab0ccadf76bddb2dc727dbc3fa5c4624c283d8921c8aa4425110dcdd69c05e5ed59b359625eeaaec1e27eafe9d9a5ce736c3f9c527ea547818b9bca6811be4cc15058a6f5b683303b80c90c94a83b8b15869713a66b1e0f656331b286d1ef7698834ab3e138417aad6bb3ab3bd9fc78761a482dfc654f3f8628c8d9fc16018898f1641e8622bd272e38d41706cb9cebe6ee5e173576bf61bb1188cf2f39c62220bba88fcb4de4898b25b04 +SIG: 64b598ca5b8f9ae742e46ee0d8c1aaf31458b50c25d267a677e44be5b755f14d51801a30399bfcc38d14071aa0ae93da825a581ab6c20725a0a910b4735dfa0b + +PRIV: 1044ee3708c0b0e909a8cb2ba2cd0af8d28a5de01d962e826087fb232df7b2d246d241ea0c702c1889d44655824629b67284d4e644a48fa45455d27ac5f62529 +PUB: 46d241ea0c702c1889d44655824629b67284d4e644a48fa45455d27ac5f62529 +MESSAGE: b8a445455fb66e17e3143d35204c9ea93474eebeef93963ee5c1d377ca217acd4ca63e5755da08fbffdbd4352bf165193896c8d6f76bb4cd3bc2d3a476a4e320824a1210ce74d0014d747f111eec310c5c89ed4d0850e811f80a8bb28dcaf6f411df83e2c1dfd90c4ad23561454eb5d756b63b4ea7f37dc5d466c16ef70d11190c4f5316fe2aa8597440e88bbebaeb35ea5f04f07b0339264158ef909ad5163bfc248cd724133e274f812695f290e57176a96b9393d07bb310299f5d2a6b6dd1dabcb51bf29c5afa7ebb0701c6c84767ac137793091fe0ed6e47d780628a32c84f83e00e9c16742a523ecb63c24f4a338ed299a06194924f44c5a5d3c937ff9b0945982ad24a2d1c79 +SIG: 7d6bed7f87d090abe013c31e1203903bac9c93445d06c7b53d31d15f970d88647a7ed2c3a63050ba19d68043aadd18bd861de1ac4715b8e828b2b16f8a92b001 + +PRIV: 95dd1a5e658fa6c8d42507b3e5b8edb5baeca62deb00fc5d4dca8e1ab5835e593a5323dd1e07f323bb6d83e9c2db92a29f62e2e003ee0deacd7e2e4e030d8d27 +PUB: 3a5323dd1e07f323bb6d83e9c2db92a29f62e2e003ee0deacd7e2e4e030d8d27 +MESSAGE: 9b7afd48c474604c26367531556840c388668b0f3840063dfc9869ad5b901274b931293d04f3c8e8f7f8eab815a641d7c351284e8bb0437ac551bb29438964e6a7c7ba772344b333f9eda5a77568c8931ddcaf21e32e07b10bf4820fb859bcf87b81c4bff426f24a4d468f2e9aeda8f17d939709970db11df76247e98a39eb8b38f5949f349f2ae05ab48c018517c48fa0205dc7f1566453e105e48c52eb455c0c40802f797b3eefb1e2f3b1f84315aed5b0711c6499a691b74b91f12ef70f76c4c05c1aa1a993e2f3e528ab343dd2368162f4036a61a13a88045dcdefa85d68532275bcf5b8f5f00efdea999a95783175d9ee95a925d48a544934d8c6b262225b6ebea35415dd44df1f +SIG: d02a7523dcbd29576ba809b531037774df41734a41175813119c6a6a788cd9b8ad780865678667699ae66d010919a966a051c08163df67a977ee6e220d0dc30f + +PRIV: 1abc0b9aa01dc57ca53efe7380962b1a88d50a964f5cd98640982c74393f29268d4fd14394d7c1405700306983fbf76ea9f171b15a6b56612a1feb1cbdae5dd5 +PUB: 8d4fd14394d7c1405700306983fbf76ea9f171b15a6b56612a1feb1cbdae5dd5 +MESSAGE: da2dd940d5e1db6e80bf7e2b782e7e745cd4fd252e981517975887dd05ac77ed837d082961575efedf301fdf24b70718b991b8d92bdd2e6bee17c8aa4bc694a727bcfc78fd85195c42caf883a2c38d161cadd79cfda9a39110e1264d30bd4c5c4a5876777f233b071b1b0b408935f0468954cc744af8063b004ede56cd981c4dd5608abffeaec9e58f3fafaa671467804b7fa2558f4f95174201f183d80a5914065fed53115b41ebc338f78df050053b8a4e75ea7c6fdc354dad27bfd8a2e66fcd7ae2f587d24be0d4a33da30a220e51bc05fa4e412b959fd95d89ea6ec0162516c096a9433a9e7cf599c928bd5305c2173bf7493ed0c1c603cd03f082cce44237a79ffd8be9a672c2ebaa +SIG: f738af2d3e290b3d23d9aff7414bfc5ffa47235dc053687a8ba5c8541b8511f781566cdaa130e0677db55fa8be9d81a092cb58923a8628494d2f62d95c167100 + +PRIV: cbffce2c9bd3e23e406e5f66e632dcfa726654d29a955cec983173235fa359d049653edd64a55f7cd40eaf3f8e72eb96dbcdee398f34817f2c95867949710b14 +PUB: 49653edd64a55f7cd40eaf3f8e72eb96dbcdee398f34817f2c95867949710b14 +MESSAGE: 1ffde6826e4f0c24a7961f191e74cc0bbc928e3f1aec3efab32765c2501cbc1620e7ee6f61fccfb00cfca9fb98143b529bcc8c3d0fdf89ee7c342f101815fabf7deaf9f302a288fe175826d590d99ee6fd92da74f9596b783c0e7d47d711a32f39ea4165e5212431441b498c6b70db3b09d1f4e4a14a6bae39da5088bb85b3285ce9df2f90681af2c74dece439aeb91e1c1b0712eddbee8d72569828f37cb720c509d02aec476070484e9b16ec7179947ac96caf0e1be8b6b74f372d7235fe6e3999df733bccd482dfe2e631f56b582667dce5e3121763adfacf3b18cf2095f7394dee4927fc2bea6b5824d90cd59e854ec5872b4551b02efaba5ad54a9b7a8f6de5d7cda5825b325b076ded +SIG: e7ced4fa2a7dff73f1068bbad0ec9a1109043c97a62effa148876f0969ed4dc608e28bce797af3b82532c94dec4d6811b7f563679129facf17bb73d69375eb05 + +PRIV: 9f91231497484cab39b9e20f861181d397908577bbb2968242d071bca4813ffb8824bc6cd6a6f15a5f41668f2b3bae8fc4967383078d08b51d6d1b2b93a1071f +PUB: 8824bc6cd6a6f15a5f41668f2b3bae8fc4967383078d08b51d6d1b2b93a1071f +MESSAGE: 21d4fbc98163c3fb6e09f775c2ab7b18b18792340bafedacb49605622e3c08aa3b2b8d0e0902f361aa1c0f652e2732b10a0c5c6a05098996b588267cc8951a78b5d431e7222bbb508eeef1b5e8b8d01d3991e18dddc6ca8d222ef177ce62938d1810eecf06f4738b28f440946ccad2a12e39d38611bed3a39f93419a179ec2b1b52d5fe5c80c23b84d8803755f5146092cc199b4bdcea5bcf2037bd53ff6346694155f027d8ce2baffe30a5666596c00783aaeade9c77fc8637942ece017d6484c2899b1918d3a480bd5157678d4772d271f9b99768ee1bcc46b2489ae87cd030f47d1333c7672cb902cb4f5fe746e853de57940ba2264d3e629644d653a5b7af78ce64a993f36250f8cb7cb45 +SIG: 0a1c706dd8a13077ab18386c65fa97cf9dfc43542d1846ecbddeb7b3c93f3c66f3ccd0447aacdd4dad8fbf736c4ff9dbdb62bfc14d8883e385bce9bac56a350c + +PRIV: 1e2bd5487c5f5ced461f604dccb4e78eb91608f0b821f5afc4e3e534f7960392ef825475cf2051a2017ae532f077d96774347d2767ea7b45f9c1b860ab993506 +PUB: ef825475cf2051a2017ae532f077d96774347d2767ea7b45f9c1b860ab993506 +MESSAGE: 1dbbbb13cdad88854b809ceded273343d306a8deabf3ff02c9cec6f002b8e9e10ef5d1b0f5711f33267aa91c171b61e960f740457b81d751a473f44f750a080cab80af7ccca7dffcfac9ee4c39dc85cbdf51259ccd3470d9bad3ad30f4ee5dbd4fac6bd5c6c4df7311a470044695a7e1a7e18572207588afa57eebcd4d575b6d424457ee92465ce1863e3c677cf875fdb98d4078ebe7144260807052577144cb8e0359aa42ad155d79dae3deb99c4632c191c799cbfe587d954787068d663bdfc0fab1334f1876bf498c4db5c53db7b0204ed5a521c62f09eaca8d0189f3b394143f29c421cb5c8d07bd751baf4cbe3bf4be1701df4b2207dfb2904d84f4dbda51cba576d5a5bb16efe698edd608 +SIG: 4d33c96a2e3a5db7391adf65c1cc3565fe76eeafd0b5c7abb0b492a0b51e1fa33639946a243b2ddef357552298ce0aa95eac6fbfe660988271877eb2a7da1806 + +PRIV: f78db14d6d1a643dd7735baf2635321244e7ec8ca72c5c38c98c809db9cb5a555414f75f52f3864afb0c79c2c5c1d06b4bce400fbddf17fe9cfb2a8bac47a0dd +PUB: 5414f75f52f3864afb0c79c2c5c1d06b4bce400fbddf17fe9cfb2a8bac47a0dd +MESSAGE: 05caf1b8edc3b173fbc1ed29b95e2bf06d814ba2407d4b31c728d04ec273d25394423ac7d4fff2ca36ee90273093c756e2bd13c96d4a3dc7f5be1759fcd328eb66c5882b58fa4588e5b2a3713a4154a2340d0b06ad019601b0e028e497f898256b028af95cd8168df5e58a57cd1ebfc0a0c91ced61dbb480aca7df8dca91eb16e98007cd2cd1a2045b0e4477d12d5a4072f365426567c9d61577f3485c8f46605e7f475ef04a3948f60dba8c5508d14bfddb9b11dd044ef2d84c16b9a9038d8e78eda43b91297df35f4361a383b41d49677a687d5b344ad1ab0fc73017b3bebf32306fb3fd7b3d5071f3ab5f6e49aa15540cad6503bea7784cf9421801ce1385839893362a97fae121300d6783af0f +SIG: d7cbd4181f67712007b7f0e18452e0a024464d9dc9b5ff9cf669d1b91169d7573262f83336b97c861bfab3fcf669223ce8caf319f21d23f1fa331a2d89b6ca0b + +PRIV: 7dfa328e90a1b849c219e3da832df9ed77448234f0d89ea5d17a3d64e7883dafe30ce6fd5f5800389a70cd117364f59945afb180f229927360b06b4835f8dc91 +PUB: e30ce6fd5f5800389a70cd117364f59945afb180f229927360b06b4835f8dc91 +MESSAGE: e5e495d663f47236714532687a24308f942ca9c33e088f7f106a5a723518cacbbef4a68c939a6950b2dc2589f82d354e575272d42b1383d315ab8a20aa0cdc9d4df678ab3b26612b5dca66e71f9f3fa7d9e731dc481e2bc7127cea3b6203ca6cd8162e90886a73dc46c83ddefc4b9e2d53d29dd387c624e08bd8d53be928a40a9aa8ae8b1c8d0fb6a7bd6dce5f62315b7a2181f627f256bbe7e2a95bf464e6132204c174209629840235b2c39913301a4b40325d118d384bc7ac028cd4f12702e161191b149e4209058a55122bbb8b22b24683ba4f8e2e6ccfc08dc8c8b1bcfb6d60bd8f062196933df319ab16906d085730eba1720d4b02c67daf38cce6aba38e25d68ef95b2f521913a1d77d5eb650 +SIG: 1c61d53b872f8cde598609682c79f6c5df007c513a71cfb3a06dcb82d85c4b00ccc40b00e59f595393088b4cd0432855c67a207da71f87e72c409b3e50279507 + +PRIV: 6ce13d3c2ec71fed83131a69d5d030314ab49e6565ef68163fff09ac5d9b47e79c7b1118fab91e0e7b192a23d95fb877cb7936cc6c8a330592f48e6784edc292 +PUB: 9c7b1118fab91e0e7b192a23d95fb877cb7936cc6c8a330592f48e6784edc292 +MESSAGE: 10bbc311eb2a765e0167ff37618ff70e13f02d7b0617ae4ac06befbbe149c972a994f680ca4dc9a92ec7efa53997fad356b9ff4ebdee629541d1f4dea62ed0d2494f9ccfdf07a9310491f61c4b3e2700b4a3c668d678329a38c2eff9d8cba431fb959e7f7655bd0fbd77d53bbbc2eb8dc51dd718ed98728a181686be122b844d3da331e329d3959b5923f7734325a021026e2754e17a15108be801465ad958dbcf21df890cfe5d5b883ca43c61cedccbdb58b849ea75374f1e918e803e577a5dc7a1c17936eccfcd3481bd2b1eb075b83237ca6f3c07c19e9af9731267be82d4898eee96ebc900d48b059d51b0dd415b1c890660a88d25f5c5f35d8e45e523e0ce3336923ab43670e35c5057d56c758876 +SIG: 608b2bf6f6da05c2ac5bbfd795a2ac32c79c74153f9431dea59768ff4c225e3b693b645a506766b860850ee97ea43032b05b69e56767e8eb9d1918df9afba805 + +PRIV: d45ee69a5f1a7cfdd0343f8770d1c6bc026f067a70dbe839a86f2aa068c33f81fc8d9fb0e4f34793090755e0328096e01e281ea351b8d95cd9116e131a5ca54e +PUB: fc8d9fb0e4f34793090755e0328096e01e281ea351b8d95cd9116e131a5ca54e +MESSAGE: eb5ed8ab79cbfe61c25981b9d1d6b70f10b60194b4161fe17d11aff1767994aa0813e9ece2f4c5d531b99e8adf1888c30a63893eb451aaf55acd5a52ad8c401faa88d6eacf3e49470566114fd0c6a274e9544846b0ae9bfa124d7951eb26715e19253ff7edc8a70965776f23ce46031e034a200723ba3d11e11d353d7e7cd84aede267ff64bed418cb9f28c61cd0f63b6ce2ecae14b20bc6bdaed8c428bad18be4b7d66338364acd8042a8256f258a69969b8d3ca2eab3aea3706e5f21c3b1efcc254a824bb4e7ea7aba8827c8eb82786c665aa973821931ff990a63fd34a74a6d8c22a882b0b935152ccb36fcc76f4eca65d67c8680942f75dfad073439c0916065e83877f7ba209303f33548d9e40d4a6b +SIG: 156c51c5f915d89b8d1400350f8f217a5c02e2629ede9f4a30b6e71d1ea7a953cc6db31ba5c778c269920b649fb4221c6d38cf2cea2a7de3ad423e04faaa0607 + +PRIV: 8a76eaab3a21ec5a975c8b9e197a989e8e030899eb45d78968d0fb697b92e46d2d9c813d2d81e2730b0d17d8512bb8b5d33f436cabaa13e141ca1cb785014344 +PUB: 2d9c813d2d81e2730b0d17d8512bb8b5d33f436cabaa13e141ca1cb785014344 +MESSAGE: c6c78f2e2080461aed9f12b4f77c989b19716780fab60e6ecb9793b4bc7ed69e5f70fa6bdba16e9bd3194969eea6665abfd630deeefa3d717b6d254dd24bc97dde21f0f29f9ed34b8bd7a013380f4f82c984fdbd95af9805b744bcd952c5a71fbb57d11f411c18cc30bc3594f7ad8228cb6099394a1b6b0a818581bdf93cce58f3a4a23e55db3e69ca9d60cfb3a907fb68329e2ffb6c65f1e828d28127109c9e9fb70160f2ef82a2ee9f9bd170c51e13fd3fc1866b22c79fe6d5101217979dbe2724dcad8a9bc69acc42c112dc697bd271eea550e9e50406bfd28245b83b8f012d34db6dbdd55ae6e575745c153d6e7534901027eadc2fcc33a5287ddbca6d3aeab8972294dc6c712b9942547277340e7ad19e +SIG: fceecca4b014fecd90b921b0fa3b15aeaa4e62caa1fb22729c70269232c33cef0d0aeea66432c128afb9a3646bc7f03a12774da8758398c2a0dcce0bbbf6740a + +PRIV: 18a8f93648cdcf47133630af1e11c0ceea3de07327314c96580df775597d7a9c2912f41ab4c87e3937a03331802cba87716b4eea14b9fba6f546d0ac2c0973df +PUB: 2912f41ab4c87e3937a03331802cba87716b4eea14b9fba6f546d0ac2c0973df +MESSAGE: 592093ac7cd671d6070b0027edac1fb015cc205d78bb603f378eb9f8aa388ca830db3cb23420c7e852db0b55241eb88a02cc627aa94143be439aab4bf2634757470406e842f20eb10f0700e3c2da364f588a8000f23850c12ce976f326d2df1bac13e95020b412b175bf74bd7ebbacf3ae55c0daebb5c010bf804feee1d7d49fae050bea55996f53cfe1f15a0cf20727db4ee311c260bad9682d7b965e27a9491f471d4a473aff646c7d424d5a0bdcbb8a0233f4b3060dd04c98ec98dfd05ec7247884e2d8e152d4ae52b3d5865d9efd6706a60e088e1e7c9f624510abc7a2045a2c7a7588e2535e73191dd5cf05421563f556a13e8236670343cd5ba4d466e245c4ee3b5a41e70c9a0f5e6ea2c559ebe61ba81e +SIG: 3b77394cd69f8b45d00cfe3a79a7900628a56518b379ed8a11581fc3a376e5d66807df11e70904f696c741d21d139310fa1b89a93bdc4d2c3997991f5220ee00 + +PRIV: 206cd2b8114aae188d81862ccec4cb92c4ef5fc78c24435a19f9ed9b8a22f47e97a67ac2811f529456df532737d76bed7e387da83bd55459372fdfb27ffacff3 +PUB: 97a67ac2811f529456df532737d76bed7e387da83bd55459372fdfb27ffacff3 +MESSAGE: 480c4800f68c79f5dfc0c3666c0ac429b30fe0c5fe848750db2171380b80c8e9fec0a054b16d08674cefe2f64ec28bb6b0596b35235575f189bee259aca766c222ac0a46cf2af75774da4e34a0b54fc2ac49ec8bedf4887cd9b7be4fdb7f686902ddfab04627e26ea2dc3d97d62a4b1546180218ed8fa113334819b5275cc54afdee44309008596507971675e6d8b8a8edec4718f2d4bd735213cbbd18791faa8054174907a7ac17d7143a4757e493beeec4849d0b836f18bb2b3c9016f25af47fb96199251720549f15d149503d41095e25f26209daac39154485c3ded7cb1a8c3e83a52f5a06ec09cf83df00726b7968f64c0cbae299512fb438560f04b3b644346f938ac8e90486614cd844b54eae078bf678b3 +SIG: 73a40d9da08fb98ea25b67e721557a1a51225294d316b53149af895fa4d63cb4a3f56f688566ef6da42fd2941dffa06d497aa902165d50213a6214116299a90c + +PRIV: 59b144a708abec972729a04a6c13f0ea020b4ed4a48298023a568958c21215ecc4f4720092ed6179a082ae4d6145df3771786efca9bd9bb79c9f6667d2cb56b3 +PUB: c4f4720092ed6179a082ae4d6145df3771786efca9bd9bb79c9f6667d2cb56b3 +MESSAGE: 3857bd260b8aad9d073f06765d37fe893a3f53e23de866ddac33495a39ad33ee9e9d5c22502bc1c4b5470d0e3f3a585223fe4cb93cc4ad2b5ba6d78826a53fc0253dc580a2018cc9ff1cfedbd3ac0b53292deefbc14e589acf496cb5f7670130fdbb6cf38d208953c015a0474675b724bd109f7cb89c33016751fe7aa785d099d09ab20dd5258cd764ac8daf343ce4790ead0863af43121aa527a37a11628f47869668f8eac00d80b6bf9906663d7a2899c1cb678cd7b3eb3bc80226b8b13b6e46877f38f07c3d9c86d3368baac4a6f6b93ccebcec9811474b6a6a4da5c3a5966571eed05edcc0e3fe7cd15915c91f44eee8c149ae451f375518a79fb600a971a39b9433dfa19f91931b1932275747c262eedcbd27f1 +SIG: 1a80850fcbd6e643c6ba8eb684dbef7df015159228daedcf0604709186054db185aa7baacb09d6caad01638eff8e468735a60124de0c5376e94340e541a98007 + +PRIV: 8d1621eeab83270de857335c665bbf5726e3722225fd016e23bf90ab47aeec3dbecdbc024dae6a94ed4e29c80f2aff796aed8feb2c1b3790a8c72d7b048a2c61 +PUB: becdbc024dae6a94ed4e29c80f2aff796aed8feb2c1b3790a8c72d7b048a2c61 +MESSAGE: 97facddc82cccccf788c31b3305e93eba956f89613e6e53542b043267fee544c2b0a8ae8886a31b9d321a63c27623baefea840b2a8af5b2330193ffb5baf873c335528afeae2160163c851c5a2e58154a1b0569c2d1366c0710437623b0e08c686e54fc279ed4c45f3e856868375f78224c777b13d75de10d79173552425d15a561904155f2117b2f14713eb0b04648a3bdeb3302167d1973e788a06cb00d48ccb269fa71af8ba68eae55dbbfd9594d5c2b4dc13ae0321718561acdf67dc8cfcc25bc46bb66e096a1941d9335207d3f7d11e8904904fabe3a50a3883e7078047df252f38b67cd28a6ac45c7d7a1d2a1de8d45747cf09301e01cdafd0cd99a6e91b704d509fce692fbdef2f71a5ce0b35bc15c65f876824 +SIG: e08d6caa5f39327d6e6652ed74dd1a37844b979f5cce747a606f5679f4898bbb7643df7e931b54a2b40ebdefe83003f61ca0f11112f023c6a3e8cc18cafe5f0d + +PRIV: f2735d50ee3a9a65b58c8acf551663e98809ec406f73e3e7f4e73bc4ea923874df48a5b94a07af3c2c99b8388762243233c850dc175317d602638e5b86ab49ed +PUB: df48a5b94a07af3c2c99b8388762243233c850dc175317d602638e5b86ab49ed +MESSAGE: ae31e94e7197e4e4d0239348025ed6681e513ce1a6e0aa0e5b979373912150ef113e50ef0569c483f7568c4bbc4703c5dacaa80a0de4e738383fa1f10d6d4071a31b99e6485143972316c86522e37c6887a1c307b29b0dd6f9f1b438310af9d8d7346fb41f9b2dd2e80b14c45eb87d4ed48e37a5260b52257b3e99787a13c55392ba930c08e0240e960def0c29b8550745cf149dee53a5d174ec065d2d6677dee1fc42057062c34e27ea5dbcdb861b9f670c6032c7846cec8e87a7c9520e27967b0186ee71b77ed6d029bbdd70949cec4a709329fa37fee002490cc1bc4c2df6f763f9858f33d750c5b505a67e237063c0486f9456d3c620d9ac7c98f1381de0effe41c18259504a150d68a6a28b0a3eea803b855315c9e0 +SIG: 6942a7696417efaa591b95e11f02d763bef5279b932a8e2a7cbb9f583695c14ce5cc556bec66799b33cb592da4df2735f9eef2c3ceca4362164b6cc93da4e105 + +PRIV: cad9d21a01c7e1d15df2fbd79c516eb8c3401e9fe28467cc7b21679d4e331a3da7b55c15d6790b40536fcae5ad2892cd66b18689f499c1fdeea66d4a7df39424 +PUB: a7b55c15d6790b40536fcae5ad2892cd66b18689f499c1fdeea66d4a7df39424 +MESSAGE: 70702bf19c919f9836defd7b846fd9992d8b7eb2e106aeb71e60a31b4ea25a41b212dc7de7c91cbd613d58d0595db833cfe7e50584f25569602c7744fa675d156d0f63cd2b7c089c8a00686a437169826a12dc485b38c068a8007142e5163747011a07a415683622ab1e23ce577c732ba14f401fbc3043e0693a9205c19a92298a3d9b08fb7afafae0a9f016bc750ee631a5f5da5db6f9ba2692c74caaaeb4d097e90e3c02d2e3a7fb3aa000040b7c17b74564e646bea16bad611ebc0859a3828804ab4f5cfba417d254515ca3620a3ad683c46ca6267bb49539bb30e369087e67438e9489562750dccba3aa0b1b0a6c267032d20c2adb75e68df1123b5259bfe4eac6cadca6778138a37318adb30e8d669f3bc9692cc74b68 +SIG: 31927d01db9f2472f4df6f63c18ebd83c2b1aaf88d580e848854df8cba6395d3da7bd6bb9edc1fce1c7d7e1360558fcddfa93915be076efb8ea2dc5ea7b20d0a + +PRIV: d9be842255e9a16b0a51a8674218cee7cd9a8bdf343508397f4ddb05f3fa00827931bc6dfa3324943aab183d1285515919399ffe0b710677f0915d3a5be51e92 +PUB: 7931bc6dfa3324943aab183d1285515919399ffe0b710677f0915d3a5be51e92 +MESSAGE: ac6c55b134663e41f02a6dcb8549eaa1c013f59658d81d812f95b74009513723671945e1324f90f8a3f971369181b587bab45665f788d663ab78140c5a22c1c18d4afedc7448a748afe5bf2387003c1d65ab18482ef98922b470da80ad14c944951ce4aed37390cce79a8e01b24c7dfc1141c0eca2c7f773ed4b11806a34615513486e4ee11af08078a1b4054cf9880298608dd9b3faa1a242a452fe511604b3102c313d14cc27c6f0f8471d94555317eaa264cdf52c69e18f461e47903d21298716b172ee9cb178f08ff2d3c9c162121c2ed21d8734b2f0630d399146cbf76e028a143f2bf7bb50af0f57b9ba8021d264b00c6662f84c86cb6d5952b3d241f7dc3e700c96616cbcfb0d0e753ffd5d21ee320e65e97e25cb8609 +SIG: c93845658c9560d2c0e28f282adbd4652bafd3bb2edec17c94878f7b94d3c77afec906ed292a8dfbf5f8e7c118e8f2ca33dda7909d9b695b8ff5a1c0e97ac807 + +PRIV: cfc48cc6f65811fe7d7bba85d1cd84858fd6f7edd638f4f552363ee7685f69cad29c10694c5e8e3f3447ed78d34dbd74a2b301373ba871b5850c333dff7bf8d0 +PUB: d29c10694c5e8e3f3447ed78d34dbd74a2b301373ba871b5850c333dff7bf8d0 +MESSAGE: 8e7defb9d16d036bd642cf226e32773e605361c5ec4b951255788db0a042c63e5a4367d61524f10e6258991325a39ab6b03612260c3fe3df20b34202d34395bd4ed40bd61373df781a4c8bcfbd15301060f07437732333d8e49736322dee6b22438e787d8856b70c26ec57d6dade9c3c28e27220c5670e393544ed095937298dc3adc73865f777e90037bdef834716476d78f4e6cb4961a4c68a8a836338a9f5da179c4d5e93c3f70dd35eec709653dd8de37996b12056d4eefcb4b6b3c13ba984d832275c4386ebf4a8ff7f078be3d428c1e0d9b162381f06a5b7bb12704003d91f25d1d8fd43626ce70fff59d2927768a76bf7f9ef76ff95489f38edcd1c9e9b8a8b0ef66c32805776d5ae9fbd84a7af4fa6563ec70ac5733a44 +SIG: 80c5d51e96d1cac8efd3459825e79c1e9f65af701d1d29e1f95b036707113b77984b7b3350f04077333c957f8fbc7d9b040c362651417b9899027cd33edb1103 + +PRIV: 15c9f7c4d84a5a479041952e6a8cac24e76fd2d275c197e6b521929b43ba6c5d8633c1829d29091df71fd5c0ef640572e4b64974cd097dbebbcddeba041647c0 +PUB: 8633c1829d29091df71fd5c0ef640572e4b64974cd097dbebbcddeba041647c0 +MESSAGE: 11730dd45dda80d84d080d92e9bddaeea6878e4a0b3b512d9ea733808e1cef51d49048d6c78116a4bde3c64aceaa52beca86b331ab59e9185c70286a02bb5dd04f5c7f4e9c7e445e77458565f159c783dfd4d976a910e937789d2141d416ed3a7f608d26737a86b20b624e3c36af18d25c7d59b8d7427ec6c4d3d438d7ae0949dd7d748c1ffd6f28e8285d440422d22a3761202e9584f5cdb3504547aa4b685730c982cba213de08020a5e4e46a95fac4b481bea0b630abd030ddd335a20fe2cf7094aef4813956991913c6821f4b5410df4f133fe63e22c08092a0a65972722a27ae42011a807c327b417237c540114eecb9f0e96cda5dcf0246f1d2717f49b9cea9dc6a3da9b396f0270529226f5dcba6499918a6c289fe055fec8 +SIG: 1e36bea5a583767ebd80306cab233155b7b42814b43473cf45cdc5039c939744a9694b87220daf4ccd29f25cea405e7c08db2ef17f3f034dbb49cff60283e306 + +PRIV: 6d2d0d823f294746b9a5512e14e73c1d855b5e4bca65fe817729810cc5ef840d1b6480a6a90dfb472984855cef6f1ab31eb7b3f13c8ac00fa556d20b53e5ae17 +PUB: 1b6480a6a90dfb472984855cef6f1ab31eb7b3f13c8ac00fa556d20b53e5ae17 +MESSAGE: 8772721f72eaf7f73040c068a7c3753bffca7dc2d0930c6525f425e6005c25cd4c0ff5095c9c61a5d8a1967b8c86010c884e509e6b1670f79046e22979ebd354734090d3ada21435c1f8254f7b5222cd5564f064e977640366449f4e5008f870f9c4840565bf4fb5f574c9774ba2568e71a9ccd82ffc59b694f26e7de4ce2e3fd880a0eef387931333ede00dcb065e6d0f79591a2aa956df1948a265cb95750d8a233b15c288a05487c515663f93e740fb1570fbe4bd80c68e8d9297345a8a01cdbd88f4a39bed9c5ef09f144bce5de568bf3733bc53b2039a29cb3e194501adc1c10e86383aac8b0f85c67a6689bbe1470a392476313439ca88d98c021c0eaec25fb2f9a160ce5c786170be0238fb8785dd33bfa9059a6c3702d0de05 +SIG: b515f49eb32ad478692df88f07b7802c6e0e5327aa08a6366e4cb1d1e26f9e65fc81abebe2215d649100f27598273a412b624e842d8130403797e57dec975a0a + +PRIV: c0cf799af7395bf27bafa36cab437045e39c903bf807548319ce44f287494fbbafbf550ca290c905bdd92fc8831ebe3dfeb6daae4f56005253cc50951e50edc2 +PUB: afbf550ca290c905bdd92fc8831ebe3dfeb6daae4f56005253cc50951e50edc2 +MESSAGE: dbe65780e968de9e40ffb57cf59a60fd93b3f9a5e7d8ed5180adbc578ca1bc48bd9fb60a1324c9c2c1141479a0dcf0f1d07e84936526df42333c0d773e3fed9e4038de5b95ad905c92cbe040487bf55e10e1edb429a0ecc4e0e8d00a988a9cd53e2eb372f4fc4cd9537b269ba3a23cefbc8df6476e75434b81d93e8891bf417c82e363f3e4abf80a4f73aca84ac7df6337f536d63d939d92cba64be742221116069ef251abba0b00af01718bb580ddbeb79973ef10a68b4d0fa023d6ebd3079d6b32a1aa20a21e9202f27590c3f0c0cc253073c3f822aac459d39f50758b70c00710a3c98438416508522e512adaa0afd503a7ceb04fb94a4a932ce80cd5a7f11bb861263f58e5749d542a110de7c7689dfcb0c51afa9d54a58ff89f3f67 +SIG: 5bba01a4c7b25542d06912de70aa1e220423fdf8338a9e693395cb6f0dc1fbfd018e3c77e50aef90a9080f30f1f5792b2431078fe6e3e00464245e17cd8dc107 + +PRIV: cdaa50e8527dc7a50fb37e28fa8b9568c37e8567e0b499997b9aed676180c3b07c56e164510268c182b423747904f1d3a5809330f6e1b29266ec46e73be1550f +PUB: 7c56e164510268c182b423747904f1d3a5809330f6e1b29266ec46e73be1550f +MESSAGE: 94fcfbaaa303dece7b908f874cc5f095061f1754bb35780db666b63ab8290811bf1c521a7f8f785ea270dfb39d0d6ed95ab71955a11ffaeaa268e081ff3e4f2425b41880a987151e678e89111350942d820c3eec36212426663be175e5286b4ad1cc804e3e3a03b9fa3e82838ebbc2615a645f2ca1468ac4a1cdbe523761e83f4381b0c8550ae5e8c8cd1fda57191436e27cb883bc64be86a9dc6110ef3401d88a7debd1b701d9c257a6826cf01e9e2922e3ae577f2834275fb0ecda80ed8cf1801e0bc5e01e26a77c48bdf46a5c4894d22ab53e741827e24bed5f0750ffad05e53f1d5e61dfd316b191d9797ef713131a8b430abe3fac5f3c4a2ca021878b15adc8c5f542114260e687a9d199d230c4e0d3fc696993b59ccfa3ffa9d8d2fb +SIG: 137bd10a50ef609384fe668768fb871de741ca0f53ff8477d7ebfa90aafd5e2681fdf1b89250463c15db8e17a58825fe9427de089c34de13cd07bba18d4aa40d + +PRIV: 0fdea9bee6288f947e0adbdda4dfb2baa03891af25024a5e138ac77984d0050770abd86430d7e8d63209c8b373ec4e4b79e989e6725facefbade3c7574d23cd0 +PUB: 70abd86430d7e8d63209c8b373ec4e4b79e989e6725facefbade3c7574d23cd0 +MESSAGE: cf72c1a180a2bc37d8478d9a7a39acf03bf2a50790f7902f81121222d31d3ec916f4f24cef9d7c41dc021b0e8487bb892e47305e54520303e89b30b263dac4a9ba375d46c40fcf400535c959d2b746a7fc970cf65b472e84b5f1d0ebadcfa1aed6fc47facce16a366a3b1d6e516813c1960975f8f2b43042fb4eeaabe63c6f65db45ddb7db888a19a9d7ba6ca479fcd70c5d1e970f12c14f4d24fb7e2f357bd3a94aa1b868ccc0847f2eef21853e253bafbf07c4e6176a1ef077167841ebbe5629337157f39f75c71d21e7e96c51a1b16fa8dc60f0b1279fcda2641fc8591e3c492f15bf83caf1d95b2cd91332f1b4202fe72862ca2ea2ef92c11db831d82f8fc3d41fe29a76c211a758e2f71bd89d2c6610f201429f348d56e10e3b7af53e27 +SIG: 80c42dd5df03b285a86ac95ce6669f786a978a813a9d7b8c6a23de76fbd09bdb66c5dd1cc9f1a176cba388d5051764a32fa27f0028ba4898068bd01a3ee17208 + +PRIV: 03d5e466f8298ab5438a30976d1322a7215a642dd5fb4c3f8519409a7522f0924b3ed4db080e2a452e16912c14504424920a60975604e4f379258d1c8b193d6f +PUB: 4b3ed4db080e2a452e16912c14504424920a60975604e4f379258d1c8b193d6f +MESSAGE: 1b47b70013cb53e1f8f4971e0f39563ce87edbc2cedd99e5a35585df8b00a852f7b9c97c7e4a5465fc5605ae8c5c36570a99201a7ad6031287ef0c7b2ba6e57b056d0fc8d6ca43bf6cbdab098934b403197b525d22d45e6b29c78f8d6183e41ffe197dae25ba22b06669ae05badd7e1da6932a7d054cbab3f54e5146223ad8671231bc16fe62679bd2817a6b80e653998c4949f81ff53b6173163e11da3e6d3c76d84c713225b4173d6bf06a85b6988a48be4359cb515503ca563f4353f8e7d45e4d94462c89a04a00f1b3b0ca6422d5db029c507d464834a20c78a713661d84edffc496d69282619894437b4487954cbea2aa7261e6a62b6851154a5d25fb6b4f09c59473d385ce03e91ba865eab66c58c0abb0b7a78e4be927e55460ccd70d82 +SIG: 6d7e4658f26f337c98e03f13542e2f39440ff7bf8d88f3f6dfa4d64948cd96b79051492fc28f65f2cc0d23a0c4d5e2307bb1c47e11e53b371f091b69f80dbd05 + +PRIV: 76cc18a1dafffa100586c06a7b40f79c35fe558c339c2999a5f43875cfade03e4b9da8d2f137dc6c857a99a5998dd89dd5f05971a21e8c776670eb47bc1270a5 +PUB: 4b9da8d2f137dc6c857a99a5998dd89dd5f05971a21e8c776670eb47bc1270a5 +MESSAGE: 4522b1d82373f7a318221e7e57617503ddf44fd53997522a1d963c85b708d0b245de372ad52ec7f54f6213d271f7c91d5a1d36d134db389df0b081a06bc0c7a4875f724092793172c9115641c6d054f1d992e0fae4df58695f0ea3449d7a4b3a8857e19803fe49b6d52c9ff3746a574a2756956579f9fb809a0edec92c55e95ffefa3d05f165822f464a21999f29691f6744ac5a3ee49017880645e837edebfd2e0f24997f041145a72e2376ada283186ca2b836362977195baee30a3acc81b243f3ee376a2c4764c783667a4b1177e7951d3e3c7be4f1bd7ae8c60fd5fb0fd91f0c1c14d0d2327e8f20d92c0dfcc53870e9d99fdbf9dd9a17e882509ae7baa8653e39edc8ee569000d624cb93a0754a798d1f811f6a0ef5501a17bcf25fd0f91626 +SIG: db74751c66e6b1866044dd9ae99f19e6334f179e79d8b8e0c8cd71d22cefb9eab7e3e7a9c2da225f2a9d93a313d1cbf1b7fe2597b8d702bf3017a6a6bc7b7b06 + +PRIV: 71ad980d58ad8e7d33306689358936a372d5190b24ec7f9bde749cb81150efdafd35a75fe5abc20104691a24a4659440b55aeaea902ac3be274af27aa8312869 +PUB: fd35a75fe5abc20104691a24a4659440b55aeaea902ac3be274af27aa8312869 +MESSAGE: e87ae073ff5dcc5485a19940e4e3ff263a0618a9025ad4032dfb36d171ce881f71c18a49210eb45819806142e2f00db3041835bf2c3bccf1dba02b8b5a5bdaf8fea316c0623dd48a564ec166f037d587c8c01684e5e5c0ba9dba4d23b49a0309244e282a51408622edb05704747e0cdeec976893777071098972c113a8ab639c31f1613233ee460eea8a8c10e1e6e152214529878cf1adaeaf78cf19bac71361815bf57955498fab4f0f2b7586c86f9f4c2ddf8972f9b9e0eb636d84bcc14385b2d038be55a963702efe225a50bdd0c4da92a2a6a09100ea04a211d396458dceb4487116837d139eb0f122538ed3986ad0af4da2dffc89f3269ca88538086e691e5beae9581e7c63d8e612da2c47f74dde1d94951eadb0df60c3897d2a3095c506093b +SIG: 81670b1029e481e9ff3c171f05c16861c846ee79cdf2e21e3bf952bcfac97565f2b1dcedf69d2e7eb35caf5662e8bc671fbb96756a63a596264d1b7f4af97e06 + +PRIV: 61594e24e75f996b4fb6b3e563f6a4f9915cfa65ddb199b01fed7f8ed7824ecb8627d2141579cd2521aa076800ac354b9e3a47d71cedc8547434268225e33005 +PUB: 8627d2141579cd2521aa076800ac354b9e3a47d71cedc8547434268225e33005 +MESSAGE: bc01b08c7caa236100a012a726477d0ec389dbfadac73d5106424c5d1f3d1cef1695cfd93a7062ec8bf1067047854920162f651357bedf1cd5a92ec29bdb5dff716e8f6025515a9549ba36cdc35ced7c5c0c368e6cd92f2f10ae146a20728c374bba509641ce88cb42fff0cedfd9fd67f310f9d01a3f3690eb21db17bce67ae35c4cd24c209f09f044759d8d5a7d248e2bd966524ba8c0c28974726b43bd05de843433cc400598922974623d9acbfdc761c4c04375a952ce54caffaa96acff6d9dc278742af476e1865cb8c20d13d1c1900863bca231e44c6b0d47cb41d510f7958f48f304d03da033484a3e1f273faf6983375b7d3be03d8a0a002def6365beb2fa8ccf1a94987adcd33d0da1177fc5159b6e56d004301e921dbc12ec0a73f413cf2c48 +SIG: 6302b3ff2710be306c92b9aae30d23c3d4beff394e63201e6ad11713345c4fcb5cc8d3dd10adfb82bb11a189ce7ec3e4222727624fc17881c14788d2710e1608 + +PRIV: 54e6bbfbf8c06ff2c066318c2ebf03d506547bf43c2d7a5d4df305a3032b71383b71aa1def666d9188f403f82ed30454aba5bc9f470f6eb988da187c92523284 +PUB: 3b71aa1def666d9188f403f82ed30454aba5bc9f470f6eb988da187c92523284 +MESSAGE: 0318d7cb4805af9821dd3f914b0e076fea04a7d2db3a59a00affead3325a2be40c1f87f53276a8552604f228b976e288b9be906a7bd25b2ffab8a8af5d0f6e08786fd034e2fe1eb7ee033979860dd1e5327287e9e615f5dc5a960f17026b56842fc8d44cad002edc8501cfb956001502e4ddc81a7700d9c0be88eb4aaa64a6cbc39de82f13c11086de1a4270d3af97284bac1caef1d3edaa1071666bd83b2ede3962d98b9d93497ddfd8e97dab3089950cf30ed11db77ad1437a0af5889d8efc44e612420e3907267df3acff4bd3fb6e8ca5badf8e72f9de39528653058524456a81da5f84982afac34bef5f71e91f8f90938a6f5f1f287716de56a0946d261e87bc775ce189e41a77baede7320a3c608fc971e55d0a773c4d848d428637f11b4e4460390c +SIG: 3df4d09079f830e3f982283681ba37b50f3c73de2c5d22a291358ebb1fb854e510f63f9a48e9fff7fd8311302ea3e969394e6d49c9e3182054942f6a744cee03 + +PRIV: 6862061be0de9dfd998118204b2b98db3ce7d7e819dbc10794af0ab2b06e84349c5f7c2265dde1b25e4f27ec71580d52dc89f2c3a712bc1ad5d6d69e711e08d4 +PUB: 9c5f7c2265dde1b25e4f27ec71580d52dc89f2c3a712bc1ad5d6d69e711e08d4 +MESSAGE: 1740dde8434a0d689925679b0c180300cdbd0cf6a89ad8fde34653316cee4c571a4105c9e9e0284238fef2c38a09157c5db94340571b390adfb69ff4c0dc5053253a679d42cc1f1bf1ff429229ea0a5044c6f79564e0dd287f53f015b83187d9ad27d91039af062c437b1575a0eab6aeb8aa0d27b27665d6dea9041ff9963a3118b3298a8544e3fd69ac6877e3e4052fe4422bf03560b2c57ec531ee8b5ff53c28dbde35bb45c35077636e6f841b59d7eb77bc7791b6093858a3a80a3aa6d778dbf53db9d06119c50b71c791c0495c576d1b59d396873ed871485352c8299a359da5ee9d7f36ed1455f89851a30851bea719685aecd08f25562609dd106630735277e1d6519bb1687de8b8c68b9671452edbb3491da264cdfa0017c512d2769759cb925fb664 +SIG: 965edb34e8ab8bc3204a3201d22186372de4242600297cfdb57aa1df074ec50ddf10105e9d4c89a266c34db7772aa94cba946429e68ba62bf9a0ac90f5f05b02 + +PRIV: b2250bbcb268d2477c8312b1900fd99982baa29a68974fbf8778a1228dc9755044aa8df1181674b05ade980f7eddbaf3bd7422a920287cb2d2db59a063eebf74 +PUB: 44aa8df1181674b05ade980f7eddbaf3bd7422a920287cb2d2db59a063eebf74 +MESSAGE: 7ef0ae1336a6fab37f99da5fa7d0dec7409c072623ead84f241d53d0596b461705fb1b3c537d36b89e8960febb4cdc0d427ce2fc1be58dbbce151e35acd8b6ace40a19822914a4bd8c4af632f136418ac49b184d55193ebcc32d0d798709b1a8fe294fba8a1fe72d976b4400d4a393242311b0f8cc994e89475b0038ae5d8914938e8f6e87c6f50b9d656c45d7b14231efed97f3c90668913670bf5be2efd5c270c7cbaf01e8572e9800978dfe2e10a2fc0440b855629bf9cd409ea941cb69226cac771b15ea77c0326848806ff8d2e201e6e26cd5f45430dadcff8f59c321c1c9c6a29b94882935447d3e6c2e8804b1161576bdf0320fe53c307d9cde426077a7677cde3c1bc83e18e60a0c4ee6dccd877c213a8e4cca640ee04929804570ae1f96157c04357a +SIG: f2b8d92ed51ebd1000bf9dd3411a9fa9e7aee54c4c86e24ad0f9ad5c55643a12d680019ca03f216bd4bd32c9ce1cd8a528c3ffaa5d5b1dc91a4be56f0e2c5e06 + +PRIV: b809361f55cfe8137fbda880fc62cbe44c216e141893346302b336045de21878fd23e42ff06644ead347abcc1b3e03b0e88593b61254981dd8ae59454e61b3e0 +PUB: fd23e42ff06644ead347abcc1b3e03b0e88593b61254981dd8ae59454e61b3e0 +MESSAGE: 17ace197d083aaf1726f53e5ef81b5a8c09222f260ee5f1f5404ab78d900d489688449b843bad3c498aac6d80b4639b76e6e81c55276a6f9c7cecd70b71aaaf2018ef76c0e30154aae86a5c86d4e8d0e4ec68cc427060bd56514f7238086bbef5bfca1f5671b18041838fd013572443dba48fbdd95ca740b0daa4327164a1e34677249708f77bd793e7caa6638b5dc9fbe6f0dfd4120209097209c93cedfaf21b6bf59ca6e99e6209639444f0e827bbcc0a61c3a237ca22a283213223ab658e712c7556238d3a5fe31722d65f5706ef6d64d73232d3043220f14e5cfd3c2c83a83d68e20274b6f96b29de040cec8475030b6a8a87d29808dd381795c3d22acf5dc193b720d95a752d9f123c209ffba004e48dd06dd8c9e172bc9e087d80bc5216c0b0b6e77031241 +SIG: b5b5950d3772d2eef88e1b0f5df5ffae2f2103885e71446d346fbb5daef94967a6b7b6e4be885110065876c665b7812de46ad31ec3bfcbeaee13ed0c1e0b300e + +PRIV: eeef8074c2eb9a1cee2f2d3bb05325546a9fb7cbe44b599461fc5885f5fd9cac9b892941a0573b7a1673ef480f081168d9b7496a81f9177dc427ca1f84cbbf7d +PUB: 9b892941a0573b7a1673ef480f081168d9b7496a81f9177dc427ca1f84cbbf7d +MESSAGE: 9ae39feade905affcbedd2e72a6f2429b3d1108e5bc1a9dbaf490a6299bccd94acc413adacc918b14afa85c78bc168cc00740c3da0e08183915f79b7fe3868ce2a7e886b32ad45009805bfb81b8c07b3b1022420c0f009b889d7fc22fd1997ae34198438ca94778575122fcaaf96e6502c33a75a129a2d0dbb073d93820d9c96683db318990be3fef4cafc890afbd9b1504c7439a08a065e7814ee4f9b6f57ee16baed3f0e3aa35dd23d3528a458919ad77048b4e2e6172346be249a50af02bc6c853304c208ae0ba02771262a0d8a465f71fa0635e53eb2ef0a847d56a0bcd7dd3fe077c92bcdca3069a4a682a2859928315ce3eb445c6072a71492ee82e172a20be0b648b756e6c775376f0c7c3df8e64288089c2f81ce9593c6e08bb1cc1b27fcbd392fc7952c55 +SIG: 6f7101984fd6892e2144b7d45619830caeb6713bfab4eebbe217c5becd249bd9d752eb76e9fa995e7c71ff7df86bb260cdda173ff5deec6af204b7dde011de09 + +PRIV: 61faeb15f857f6557862c8b8c7ef41f80545520996fcc1127b8c2491822201ae60a290c0fc425a0874673d94f9bb1400f9dacde9954f9f5b05dd48ab747a3950 +PUB: 60a290c0fc425a0874673d94f9bb1400f9dacde9954f9f5b05dd48ab747a3950 +MESSAGE: 253b566eccb563bd6e480c69739b8e372519a3437254e0e5029cac86c71638f2df2a6cf9e56db2569934deba90db75547e3671747df64d6f2aaf3c110fa67a7094ccbe4cc5355f0d43235136ee26dbe37f4225d3bbfe245595280585fb548f894e86c516102580291fa7a02859557fb98eb588870828b0990ae9d74f3831da58946bc7a5ce1ba498b4e8be8989a3b50d7e8789f56b8b4fecbc2a33bfa3ef591a0fbcd932fa93e19f3a812ae5e4e3b4b242be7705a5874af73be310b0058266a378f23c1348524715b0ccc18d6634b23636c316ba6a1dd2fd5092c06716a717b54d0eb9fc7f636f85bbf225a2cf035b4b7cfddd75351682c0576c6b3ba5a1c0b25ec594e7709dd09a0079772ff3acc67fb6c1b37bb3742b726e77e80561d9ab73160b73362581da5b9c7f +SIG: 31f90f50b2dc705f1d92f12ca9975d76f1b2826ada3cc185b0ed6c83860777bd8c489b59855a91f64839d49ba467985abb376c47a4908b271b8f77c58d01fd04 + +PRIV: e6b9cd4da07cb34f30391cf68f0d87c7cfcf68f810ffa40f9739c95deb037f71569ede0f04630b43a04c5a66b6a5636b766c75965984a7477e15491960fdd864 +PUB: 569ede0f04630b43a04c5a66b6a5636b766c75965984a7477e15491960fdd864 +MESSAGE: 69def0523afda696f8448f9c1143abc26533e68695a090df0d9e43d0c0eff43583e6f709d2043c815fbb3f96ba2b0dc3be6fecad5dd38148788e4a0385a9fe7a921fcb8ccee0e4d3aed4bc3d216d84b414f9580b02820c03d92e675e685c4b5851f363bb4df97b417c3fd90022eeafa20dfbe82964f2ff073d255758fbe567c76b2c35e2b09f8a8d7afa32c6f5ad01bc3ebf6e210606db038ecb6820ce1ea4dd529fc1adfbc2a138565ac6d0f4a4109bdd47b8aa6ef4b8bede454680d1dbdb75fe1eb2e548d5de7cb6d792fef3aa0d8480a6030b30f104d7e76b58e9f476ebf2cc832923b50c50c111c3515fc518852323426ca778a596d3195da8585d8c3aa92083313a6e6585b70c98b185b472798a61cde77e62ec272f14b0d9eb4f22f9c7c05817da6fdefe7879a584 +SIG: 1e375c94bd809ca0cdd02f89ecec4e437732dd20a0a84b254eae889d8070e682d113b0be22e41e6cdc3be877680e7eeb7f0995e6622dc0b434fb0949dd994b0c + +PRIV: 4d9044f17b5a0977dc5aa9916a924300a244a1ef7f060277ad4978351ea64291ab9c0692a606b2567c19c30f9faa3b4cfe72fb237077767b76d3b2ae1490a6d4 +PUB: ab9c0692a606b2567c19c30f9faa3b4cfe72fb237077767b76d3b2ae1490a6d4 +MESSAGE: 7c8c7189af67327af1c6dd2c30e975f190e3b38d008b4585167e0d450740d46734587f6d208784245cc5cb062a2a277f17ebb2746f9bdf4a8237ca479ab0a430177e19ed7dd3622576b14cdc08282214fe5ee4d76b43c16ac90864c51be8aed45d7b980df7917f290fdf795846465f27fcb7e5730637944f0577c92f32375e995bc0cda9d7196f2c0c1ac8b80d12a0439963ebd2254c347703575816e7964c13d44d629280c312ea265344de38f3b18d9150f8f924afb44b6bfb9eda513d59e65e2ef18666e6c2a21c4018665befe92cae581d3cb14e23e97d830002cb90931ae0210068af394ebe351be5b817f3674bfbf40049030e4fe505d34a1d502a2c50d8e638e926c230676b7edefb6bec77b1c0ce609325287ba5fdd7a9976987bd07fc6a4344956ebf818f08586c +SIG: 6fa48aea4d5b9af65af964cdb709443a11fa84f7d44acddab16e04a6fcefb27ae33c05b36da13c23de517d6e6ac574a03ea630ba4fbb958131129aa7f1354c01 + +PRIV: 75ad76bb4c0c229a5adc79e444b13f88a96459862c8cf0ba498d0c996af94a7af074dd2b9c1c309105ec951bb5812a91ddb54023b3809ab379c56af0461af617 +PUB: f074dd2b9c1c309105ec951bb5812a91ddb54023b3809ab379c56af0461af617 +MESSAGE: 0ca8c1c74128d74e9d0a7bf8964291d074917f2f9920efb911520567642a50a615abcbd00aed4abbfef1a983cce333e1d0df3e6404fb9043c6803914cd5fffbc66a0790c7878a24089a571f895662a1d18be3f01ff97fb3323334b6f5baf96551448e4090d033c464294d09133b151d5b5c6321b50e2241de0ef6f882889ccf4ad3540d5a1e3f7548fb13be71c16516606e79d0449c2a08e5dc23148843c84e97ed24069161c8e75208f33e95b3e10d1d49a2faef9d986ab62809f62ad39c7cc871f375a4f5a6faf104d7e11b890cfb0589902685216ec07cb8e8e9e7a7c43635e23212b69ca3b7ed54f0b97949e3d9a6662f8e4b3ab09cd495294c331c047d86ee785ff658bcd7fcf9c480605ce05e810068d60fc9b26b5f063eb9000d2657a5094284ac80f1375d0b66d6f5f +SIG: 0c4643a8be6dc22f4beb6bcc70c6172ec7608378653cb4e99f3ae795eadf4e982a297609ca7938f5df632b095628cb75062d3d51fc0f3323bfa7b22ec4d47205 + +PRIV: adc6e9b2e103b62c24ad4346410e83a1a0bd253e4abf77911850c6d9666e09f9fce316e33c910821beeddd634bedc58ee57999a76ece384605283b99b543b78b +PUB: fce316e33c910821beeddd634bedc58ee57999a76ece384605283b99b543b78b +MESSAGE: 8cccd98ebbf2439ffdfac41687638faa444e1ca4b63d13e898eaa8355492f28813ab813fd01510e112be106b2045d30f63335d248904d521de181abac03e3d2cb2d16c44b3b012a0c51f9901aef9056c724d7a2c6b2acb0a07555940e4c6e21154890611adeb6489f461d3e5ecd1af5a4d2b0adaf41747436eb414757a8fe4775674e3c6e5de4569d6fc6c788e10905eba32c270a393e6f721a765294e2ac99a9b6e534d3df08d1db97d602ac3195cb0b77f5bd4acaf737fadd6991f0688abc74918047574eac28289739a664e0e0e20574a2c25fde49d14539db1cedd4a9204a70acff0a62c8f25cd768ffab15c4db316840a4d1bc92e212670be07c5bdcf537590607dfbbbb4d9f98b89da0b4df7d88f3eca4814d16bfa20c8d2fa94f9f259f2ee2d3a83c9e4171b1a262c4b99 +SIG: cb017d6d2682c9854366259aa35f30d491cfaa930998c297dbddc6aded5b3d401cf76d80d8a2764de131718b6e0c481d7196bc72579716b0c0f6ff053e68c50c + +PRIV: 37fc1beda4060b6c57883ddba0776c2bcf5ac28a651326021cca97723730fbb07bd7bf1c99dc82e06f08bb454d8fb288a57927e07ff1b12af15ee2c12fbb6b3d +PUB: 7bd7bf1c99dc82e06f08bb454d8fb288a57927e07ff1b12af15ee2c12fbb6b3d +MESSAGE: 3dfcac0265a024a83cb932674489a163aac314bf3d969f27596e451733b99deba5eeb779210baf95bf545a1ae6b8a915860693ee890f939320e06a844483d18c6a1bcd03c638bb7d1fe2a82eb448a311b1302ea6428f54a39f45a4d560be1557a2b254c45c137f45cc68356836e21bed0b7f73a518ce09db0be393927c339bf2a4b5987539404ce650284de12e3b553b262efe23848332ccfdc35e791a0ab43f139c71ed0fcb2d173bb377ee46b1a9dca9277e77df855f2830251e31e26acd86763c8d7eac22c882fc174f2b5e75ca6ad1ade03f942bb2a13bf541906159158c68363c7480c5b27a99320f8283a2699d4369c071c50dbd90b7792e4772efbc0b195bce84cc4dcfff7072a48968db69f9feddd0f9ced659eb5db7167f35f988cec114887dcbfdf27d02d300b3e1abec +SIG: a01dd65fada27039f168b123419d8abfbda48c572ece24fda06e1a5ec31e084f4ee1cbf9961e88ed51e189fcb7f5f235de1e5b28d08f2bfca190b0f019ecc207 + +PRIV: 8d42f4ddd2bbd2b827b0a0d31d8f758ebd13a1b9b3712228948ca610bb8858e5b7354898794f9db0a8af6eeafcdbdf011d3fbef0212ad938a4a4ad27ab16ebbf +PUB: b7354898794f9db0a8af6eeafcdbdf011d3fbef0212ad938a4a4ad27ab16ebbf +MESSAGE: e3a2bebc0496d8974a8f4061880369314ed9e440c1b77e26fe5071ce694ffd2136db0c4d5e880e6000083a75c90d3cf72b9cf5a2b1a9002c2701a2ff59b0699a8f42d79dd8a5fb71a8125453d91fb80080a3f0a16584282f17ec7dfdc2e5c69c4d9bdf484d55944dae273f211cfb76ad37da45871365439af35eea1fbecd4ca679b59b5e01bacf49c7f4e5efaa406ba1daeb085482af5ded89dc6885ffbe3d14d2931b83897e28ad06e5564e2789baea81bd932aa279fe8e324b9a8ef111c2abe2f137d4bb50d8ab76cebc0bd982a23919751ad4d49e88eb14173d3310289a872317e4a451e88d54320891870f15b2d53324430877a9fb5b49bb929f211c5b89764dd9c3a595a1451e9f85a238540002566e53a99ed1e6ddc9b4853f455edb4cf1980d56bbdc1313a36e76ea9cbb048a +SIG: 70764be39c6dca0f067abe1eca490fda951fd4e9499695266e270b9b05eae706ca8d1ca6a92d7c488ec6ad8ba11457a42a5e31702a9c2bce892dc40535c09f01 + +PRIV: b62de5a1acfe4ca2d1f0c132afcbdae66fb29a02f297fbc2407fadbbf2454200b63b2d0bf355f7b6d0bac07403411c40afbbb2f707503b3fc2cee8a1c7d0a838 +PUB: b63b2d0bf355f7b6d0bac07403411c40afbbb2f707503b3fc2cee8a1c7d0a838 +MESSAGE: e659e51d7b193c4b8e2b3ed73a9d7557ed2bab6153883ab723592f730a914567142b3fa435db3219f83a542dc7a4bd805af666ea865b853146f8e3a9fe870711f90d12b0693492af2a1edf99a16458f781f1266ec437a5296a822ca9d69ce844b5c59097a2a56f3eb8fd273a636116db774300922d45b744657a692f5e8bfbcb06d2422818aeb51e7cda68acfbeda16e7c79580dcccde24e8e3d601b16e063b43a6d0d1407552f7504f5be19882e4ffe32344f5f473e73a8f6ed37b0d8d9e5e0a0dc9828395bcbd8f3a4e3124869249d058be0e045de0b1e12b1c83ba0aa227c95b82bf742c3eac0152b33e6d19be8b33a35bf705daab10622a90aed022ea6e439ed50a9308437929924ba3ab111ad0caa6feb0a6eb165824ebdb0866571efc07e5222ed8686b14d9270bf76b945d52014 +SIG: 5cdb00e98de73eab480be42f8a8a6163809a0d37101b6a5a4eed6a0c92030d09a5562c729080ce6f6594c8fafb1f594772db7a90a9e7da15896e82f70569390d + +PRIV: 9732059d7bf0200f5f30412430336be4ef1e3cae62938ad08729ce3ba714cfd40de8425f5e30b2b8aebb8072009a30cf0411c3c8238f4e4208760c56c33e434f +PUB: 0de8425f5e30b2b8aebb8072009a30cf0411c3c8238f4e4208760c56c33e434f +MESSAGE: 1a13e7ab603b48eb896fe17173fb31950b0dcd5a35ffdbe1371c7a5bfba593317589d9652d88797729180b8d0e515abfe6548f160421e537d5c94aef2b34c7ebb097420003bc0f361b423e7e14630a803c118202540049f68c9cf46fae0368d162e400d77bb4523cf6c753b975c245bc99ed2f413a9d06c2da6ce0cc0987b6406b809e8eb319033d2de9131dee3b1b7b5c95d653ced8fccf998da1768511eca4d3c5f735adab96503b3551803e4922635095ef811be4c08a6cbac917cbe6cd91a4ae5a330ccec0e8e815371217a3de62f2d2d61466219833f33447132f4d43350c58cbaf422475edb128c56d80a495726b1fdbc56551eb72d0f4fec26ba8bff5eed6774b85039a5292834b5d1cc1b09ba0a3954d29323673f5e71276a12ac4c579355bf1ecca48e6a716b9fcecdc565c51b9 +SIG: fba1749b641dd4df34664bc43c00468c7d75e84afad72de473fd1e9c87da15ea604fc2549a1a867fa80850e9c2a59cd99053886760a8d9764b84dd672676720d + +PRIV: 9c7f6f379e3857007e2ac6324cbbced57ac9eee4477813f83a81fc8cefa964d5a54ba396d687634d3eccf41c5782494f5f10a521a1e5d388523d80eeba5b0b2b +PUB: a54ba396d687634d3eccf41c5782494f5f10a521a1e5d388523d80eeba5b0b2b +MESSAGE: 3f2d3072fe7383e541551ea9abdbaeae6a464ae6b9f0ba786a441b2d08da5bcada3c5424dc6931d6b39523e2de0a0c2e4e6b5b8cda925e5eac938416a2c51bf13d49531d7ec7114b1c82feaf90f3f87591e397d02702f8ec1b30d99f5be7d2203e4fe4db2ea47e7b4589d8ac506248d7347466edbc96ea32bf3a6ea7502dd60c9e84902715ab2c6ca68f5b00e1d909d83aa6ab662d8aea870ecd861fec69f2eec0ae677d2995b0ed688faa8ef78244e0d1195697b07122ceaa11f5a6ea58fbdfa2e2ec2df9d18693ae96d47127556e91f0864982c13419b04a63f208e730d26951882aefe001bca3408bd9862748c6cc876c28cac3bb2eb3395818c2091e0fbd7a0b4468c6b0d00cd008c11c3c3ad01080a1f5a40ae2e4b0c3a071efc8e1d1ba6ace6d4df0ff19829b0c680b3aeb759177ed34 +SIG: 65685f9ca5982e15a22ba3c83a0348348482dfae57cea178f0780c057baebe4af632f984540a26019a7fb34253c9ece7ff308ada233ce0686347ab5b21ce570b + +PRIV: a478f35abb73727b6be6ee5e56eec323c9517882fd6919360ebbbf5d5cb8b83a7a6e266a54d135dda0009ccda8a94a4712ae5cb14761e8436e97c4b7814d8e8c +PUB: 7a6e266a54d135dda0009ccda8a94a4712ae5cb14761e8436e97c4b7814d8e8c +MESSAGE: 0173a34050b43748061ff8f5a3d7c43b6360847786e8bb75e536fb47b645b214f221ba24d83d28bc025024663e534f90f6e83a93d8bddeda2cd8808155652a908c437c2db6f3ed4912f57ca5b97928a73be964af59df4439854bb006fc295a87b7b72239c7fadfec40715509d98579daadfb8d524b4cec6620705efd4104c297144aea722974e12c5ecee5391ef2d93ac2b124e4ac496147c8b70363585d7078ccc53e2ae593350bc25548a0542526ab00afe477a0f4b27397c72bc74a8a8ab156e62b8bb47c3fbb4b34913e459687476bf33142c614702107ffe2cc01e25fa30275e1e2e63cea9168e4a47c02de097d4d853b27675c5bb330b94a974ead85e2bdee8ee17cbb5653346658df2f91f6bd739491dd71988b3a976a3e2e7a9d137410f4acba9feb5f11798c9a43b6adce14365a7c6d +SIG: 9d16fd40b9f8dd9b4a1a8c6d703b9fccbb940b1e0ae77a5970374af0cf726f4479fd30d7dff5cf53494d9a296ab6b9e46ea6c136b4db2c71c21b97c1c8254d0a + +PRIV: ffe825148c0959b3a68de86ad8e8af7fa5e078f363dc124213c90020da0c9089139152a0bd22962dd919ae3e0b1620e03c033c2ad0a3979ec6bcd1705e23d598 +PUB: 139152a0bd22962dd919ae3e0b1620e03c033c2ad0a3979ec6bcd1705e23d598 +MESSAGE: f125780d0cd088530f0c87b70bd42ebab56adb5ad4345f929ae5deae07fb55322153a8f023d38843bf5d6a93fe993eee71bc2ee563b25a50918f03efdb5dbf7269add69ded3e66953895620d9b6cf46ba2348f8d66d7f092235e378c1e3edfebeb78084bc8dea013f9933aae14a041948276d01f1cb5834b0e590e13d931d19292bb1d8041ff2fe2e1171a2e0b9a059821d0924dde7f3b1bb59813f5e3c63520aafb8801ba62c7097d4d8cf437a568a7f0087c6ea0fce6e568c4883f1cd12c749d06a6feb278f1086a8b04769921f78a9959062ab06f98ee80c2c7854ffa760f86a89ee1a51266053d195e61bb1dbd18dd89ff394e408ace0f641a395d56118ea72b7d8adf78b1655ecece7e8250e8a3a91cb8fca0d9ce0baf8980a387c5ed4318663280e5b4531f3187c47eaea7c329728ddd0e40 +SIG: fe4e89ee31786c0a3d3de3649bb93f0b8aef1caf5a832ec5e4067810705adddf539b8f4e05ad08cf3479e45b42c96528f6d59a4625703ddbf15b63093965d80d + +PRIV: 49aff421a7cd12722aa84c48c1fb1c5f8d9e277d0a99ecbc9348c3aaa74be42288d2c26266f493bc67578ca0b1f51160cf0fdb6a09a906db9faa686f11f8208d +PUB: 88d2c26266f493bc67578ca0b1f51160cf0fdb6a09a906db9faa686f11f8208d +MESSAGE: 70a1ac144b75fda75586a79c36fd39cce5f5cae2e6375852d3b62a9630336a293ea6d2ac6e5b57da21ef364a595bb0750f5bf4d2b320676423870e4b8e0869601f16680619048c4ede276da69f205a70176e25ea04bd089763e709ba343fc8831e52044eabf9441e6997f8ba1aeb9ef0f491170667a7f5fc9627cbd0551b76be27283a4b0c5f667846688226a115ee8020df08042b19b59fe551316a6cb6916860b9ecd74154b4051038a17352372ec14d3c957d2ef50ff786189a8aeb9c08f45eeb5eb8b040339974aa9798c425d7becb228c447a6d0b3cef271893e0f7076e223a7e87c6a3d270a033bc97a4565edce0aa91ffc3f7801775a6f29b230245bd71fa034353de372395d1bfcbdebba081330f7c076be99c2cf4867f15b78d52f46fc7391c9cb95e5d64643baffe72a8e3a650667fbb3e +SIG: 749181284df05dbe5974b91782a1a76ea08642cb0f0c98db586c575c210cdc8b651bd34b757ae38e4b6be9465235bd0eca430e26c3eede561c6e824dfa200e0a + +PRIV: 703a6e2b62d0090c61d8659b6a963e03c9d62c1b38f7d70e5f9ff05590cd0360370c21de6ef2fab534ada999869c90bc9b92ccbf249b79d39d95441d1ede210a +PUB: 370c21de6ef2fab534ada999869c90bc9b92ccbf249b79d39d95441d1ede210a +MESSAGE: d42a1756e84df4b4e9773f86f7674a2cd78e71e40aa8f644e6702dfbc2c2c5ca90fc242e9cb0099cc8f2c2d3136baafc0ff695482fdacdef9f565610b6e1900722f435c6385b35e9f6c436ca037e03f64e2233dffa58db3b91cc1daa0bb0c54c8a43e469d2cff7fa2bf8f5d1d877931089c82ed89aba42f2ee2b86e445cfd09f4cd78b35191bf467e784eef75dc987e046d37d4d4e8e9bbe14af80d03a1f40898384b9d3279fac9c57fd9c7eecbe19a5acc15033b84e07fd0e409bdbd5a57f65641183a6c0a8ec426d1f1d223166ff0a1900b2e92b7d85835d019d17775e5093ccd126f90f63cb7d15cbeb531324219cd64ded6714b21a65371af07210dfdf0e4e58ddc7d59f4cfa65c421d814ee2c9bf6dbf64873d579b09ee5dcedd733063e039ac9a5f9ca4c2525a4cc8e984da7185e2d64fad81c8a +SIG: e5fd64da028800c6ceed068a5e596f1621c70a8cb138b31b32647eb4b07bd2ecc5942c18844f367033f67398e314ba2c7ccf299c069787777025d845f2aad60e + +PRIV: 76849c188e3edd0ff5f8fb874dc0456645518445e41a7d6833e616c3c48c9868d670e2ea07db60c22ab79a93ebf49d22a6245ee3af07b3be584eda694c37729e +PUB: d670e2ea07db60c22ab79a93ebf49d22a6245ee3af07b3be584eda694c37729e +MESSAGE: 1eccb0bc8eca3ab5bee68c5f8caa34536766c705f50827db7ac375d4fe30b58ffb7e2fe490cc71a8ff86c006d6174d05793ab8a55dd51b06de417bc0ac452cdc7cfb0bb00362b6765d20db23eb1848027064a1d9091d3b10ed776f28b76768bdfc08f0bc511f76faeba76cfc4cb5c83dc9ebe8a8d79edca923eccd524009cafedc90e3ad87d1392e1fccf4e60ccab95dc0ab54bf44245a007a96d46634b1b2965b829c3d7daa765972b54a7b365b6f34d77d7176acd8d894f6b417091b6c00edb7a4e81379988bfcecb692e9c3c4310a7e240e5c1063cde113f22a684a50a112ff47d3898812efb92637072b86163ad89316d221195acbfad0a03a1fbc2d967fe83f84c8459fccd490b9c5b3e55d27e9484e943c417f2128d73701da28f49fd3683f33a39cdee234bd305b9491e2f3eb621be3dd1dbbb31b +SIG: 7141399d51daa6eb4519bf3f01b233920fa908fefa612f0cd7d5af8a9a3c44190e3f6384a8d14d37c97030ef5018cf8aee8aeb1569a73d84862a59b7df72fe09 + +PRIV: 83ae48ad70da0bb3cdf87481ee2c0c8571c2ca986712f8bc2329e9a3e33383c5b785309000df95f5a04f7d89c4113301057adaeeb29bcd28d99371b537bba2f6 +PUB: b785309000df95f5a04f7d89c4113301057adaeeb29bcd28d99371b537bba2f6 +MESSAGE: b7521d3f71c679fa7037fe7488a641f6b97c49454acc8e36b903d8f9ebb54d89cb56efd19e04ba6a7c8f48a7d3ec9decd3f1cd0faf6e978118e6adce9c6c6be63c6a6a1ae21651828479a46bc9a0f7943040f940a0d470c8e577c5d575cb53c1bf3ab1feb050dcb6fef0ba4447f299fdb9f27ecb0714ecfefd74bad7b122a462c24a209848a03389074578c5bdc36396d809b0f14018da64917e6bf87ef405c8f3e333ff9c3baf6339667620794bb4743f0514b5de7d7fdd947a7e3501ee88efad159e33a1072fbb99c7c71e9d13a502d5a07c4f817eeb7f0c5319aa41a96d5ff4f15a73c29b571fe211090e172c8db518624612a5c371a9d7cef6de35ebef96e88e1a78af3bd5dd35251ab54d73718f3e70d2d59021531dc73184f0fc69c2e92965844ec27c1c02af5e9a3469de355db2256e0ec2a4eba30a +SIG: 43332351d3fb7b45fcf37c607d442ea80dbda2cb69c2884f424e65ea3a331ed8472d4368405cb736b2d6685ad782e239fe833ed789a2923185166f608342ee05 + +PRIV: 39e56a65623a0aebade0da12ce1df378bc924073f73a549effaebc465d1a78e283da8ad50bad09eb3e94c725df3cc3a119736adc859ca1a10503f48ff2fec596 +PUB: 83da8ad50bad09eb3e94c725df3cc3a119736adc859ca1a10503f48ff2fec596 +MESSAGE: a96dc2ea3fa1351492a4619d9194681f8ec400a97158244482653838ccb7e156a82d564368f83a6ee1be46bc34b817200e8464c3d12b5ef2c50b19565b881c4c3d4563fb947eb47c3ee9c1ee7853269874455bfacba305f307d1ac5309eeae5c07fa5c4d428edbc8b9528c4415243a9ef580aff8fcfb12000a71fceee89de97f90279529bcc822ed3cb34c82ba5fec15f4945663636d67b5feceacc31d25f98aea07f7800d5a1034251cb91dd0963ec2c1a54773a4d96c18357f8d101de58e932f8c6cdde8e3cfcef5a7443fdba7b78320403c0196844724a612183e34bdd808ce7b958861ca37115730eaede1fd0baabe976efefd0365fdf926776c536f47ff80de5c18291bb7e9f1b913ffd1d94468b789752fae6ca897c0cca53ef1e731d00c8bdbe8929ea6b1dce1f31a20688d37b0f3a2b4153b306bdba1 +SIG: 398e8260011f57d8ac8c58d5457bc652c7414aaf6fb2f426b7899056605c0afc28392423b2b571f5e6c3c7f6d60245e53ebd03bdc5ad3c1ad8738cb32214d00f + +PRIV: 4b9921852f409a323ae38175e8d76a211fc4d9c654178eea3baa7a767a6fda064c723e436b6bd97f44af52503b21cc50d5f6ad6cfc8288345dde8054e995582e +PUB: 4c723e436b6bd97f44af52503b21cc50d5f6ad6cfc8288345dde8054e995582e +MESSAGE: 3f33d8fb83e68741090a37bedd745cf141aaaed8c92ffa742a52561777885805ace14246ab98a8cb598c9ce3de9b29bae5fa04b1cf828de11aff80a7ef8a3a38aede4f3c3563a25d049badcad5ed7e47fdbba6e111307eebe9ef4906bc989728b76e84afe808e6653b271e21104aa665f1898dd2aab23090e22b4e344a2616fbd8ee4ad8ed8108395eba817fbd14fec5c17dcf56b8220856b2b833e091407d5089b35ddf34b86ff7dc9fde52b21ef12176ef3370b7f3a0a8cb1b058a51aefff3d279d80f51a68bfb592587b45c5c63a7e4d625b887de486a118316c3b6a238575f92ac5b1c94c3f5dbbd96686000d6d39cccd558d420e4d447a8cbc4bc7b8c6a03af0f0034fb3518d93800f0f713e4b13732e16ada51801d7e559cf839d1058f64955698311399345416850dddcc5601a684fd09e6afd3944f5e19 +SIG: cbf1f1642df950eb71fd09590d34c265922c58bd8026bba3fc0e594a6bb1f2b90da3dc1d5f6b6d5b405a896d1dbb71b8685c4dfc444acaffe65ab8331789f507 + +PRIV: 1bff652a2c8309a393ac11da3aa97fb078bb284ed5e1b8ccc983652ef8556cd0aaabdc091fc3682354201744e9b73fd2a6cfb281914bf2c70ec3dc1dec7216b0 +PUB: aaabdc091fc3682354201744e9b73fd2a6cfb281914bf2c70ec3dc1dec7216b0 +MESSAGE: 48d02698a97bdcb3ef078dcfcf5750005f1702d300e7e89bc436e381113401f852b8b4acff60ffbd4ab46d202168d98b8735e79cb350e35b070ff6bdcafd954b551969b6b1a70c9131ebd40d96140291d8d2b091540a8b18d8e5465915c25dbc6b5c9a687942533c372c8b4e95a953677169b950edd3464375cd43132ff9bd541ee22bd418ce23195f65d8b289f633ec8d71e1a801b06c3c827f627e723d2199100ce73e8e4a4440e778317a474910793b47b10ffb55db7f281c7d7a033bd80048b82673b87cf95e99422ba628688f3c971890ca15d12f572fa1977a17307069da304ead3026eb01042668890d17008cd1e92c46cbe9c857e7193de3aba3911e4f86fe0a1698ab7cdb9251a8424b2848b96ad81ea239d365fdea92ea5c0473d0a6bb1e371356bdfad2d0350336d3e1947c936fd0c25195445011731b +SIG: 93c9c33493fc64172d51e16a0a1cd729a0d99e3cb864e89a42987f39dd8cd26545fdfe37581911e803677da4c55b0a683ddf62b728f8f30685ae58f628ebe609 + +PRIV: 002fdd1f7641793ab064bb7aa848f762e7ec6e332ffc26eeacda141ae33b178377d1d8ebacd13f4e2f8a40e28c4a63bc9ce3bfb69716334bcb28a33eb134086c +PUB: 77d1d8ebacd13f4e2f8a40e28c4a63bc9ce3bfb69716334bcb28a33eb134086c +MESSAGE: 5ac1dfc324f43e6cb79a87ab0470fa857b51fb944982e19074ca44b1e40082c1d07b92efa7ea55ad42b7c027e0b9e33756d95a2c1796a7c2066811dc41858377d4b835c1688d638884cd2ad8970b74c1a54aadd27064163928a77988b24403aa85af82ceab6b728e554761af7175aeb99215b7421e4474c04d213e01ff03e3529b11077cdf28964b8c49c5649e3a46fa0a09dcd59dcad58b9b922a83210acd5e65065531400234f5e40cddcf9804968e3e9ac6f5c44af65001e158067fc3a660502d13fa8874fa93332138d9606bc41b4cee7edc39d753dae12a873941bb357f7e92a4498847d6605456cb8c0b425a47d7d3ca37e54e903a41e6450a35ebe5237c6f0c1bbbc1fd71fb7cd893d189850295c199b7d88af26bc8548975fda1099ffefee42a52f3428ddff35e0173d3339562507ac5d2c45bbd2c19cfe89b +SIG: 0df3aa0d0999ad3dc580378f52d152700d5b3b057f56a66f92112e441e1cb9123c66f18712c87efe22d2573777296241216904d7cdd7d5ea433928bd2872fa0c + +PRIV: 25b0f0bb3dcb422a6f3c6c220eaadb11dbfe489c2d455b276cefe8cba057f9f3fe03c9c4394adc74b13f47654bead8bc855958b4194fdab2097ac1b157933c05 +PUB: fe03c9c4394adc74b13f47654bead8bc855958b4194fdab2097ac1b157933c05 +MESSAGE: 54d99f969efa8870fc20fa9a962bb372619c324439728af3139c2a07e8c1b29c1e4eedc2d40ba722f63ce37670362af6f5202add668c4fb4d62fa8bacbc7d07ff3bd38c15a01064259cc34134861632967460541a99b8d5182bf59347b5a59879aa3b091a1f3e04135bd6301be5226d4895e5e9c2b15e48e5ecdf44129e6122853a606fc118466fa720b5ab165635c3bde04d74289274fa03547accbde780e1fa0bf2c56f8436a53e73878a424a29aa9de385dba419ae6a5d12e004276152b58d325b302400a55333c38cde4908ae1d0121cbeca950809c543314277c1485e68d9f9c0a962d1b1e0dda1d4a52b56f8308a80b92acc9f4ebc3ed45d91a129da8675621af676703def3b84113183b2e3a8c56157f243f13980f3d1756fea7668c91503d35c839a2120c79ec954fb546d7b542f987289534ffdef62d47fd5ec +SIG: da50d5242bf51c3951780cafd926d67bdf5640d5d3bb08433831d56e48e2592a1c375968bb4d2fbea56145abf2d82991363b1565fa1effe214011a686e39950e + +PRIV: bf5ba5d6a49dd5ef7b4d5d7d3e4ecc505c01f6ccee4c54b5ef7b40af6a4541401be034f813017b900d8990af45fad5b5214b573bd303ef7a75ef4b8c5c5b9842 +PUB: 1be034f813017b900d8990af45fad5b5214b573bd303ef7a75ef4b8c5c5b9842 +MESSAGE: 16152c2e037b1c0d3219ced8e0674aee6b57834b55106c5344625322da638ecea2fc9a424a05ee9512d48fcf75dd8bd4691b3c10c28ec98ee1afa5b863d1c36795ed18105db3a9aabd9d2b4c1747adbaf1a56ffcc0c533c1c0faef331cdb79d961fa39f880a1b8b1164741822efb15a7259a465bef212855751fab66a897bfa211abe0ea2f2e1cd8a11d80e142cde1263eec267a3138ae1fcf4099db0ab53d64f336f4bcd7a363f6db112c0a2453051a0006f813aaf4ae948a2090619374fa58052409c28ef76225687df3cb2d1b0bfb43b09f47f1232f790e6d8dea759e57942099f4c4bd3390f28afc2098244961465c643fc8b29766af2bcbc5440b86e83608cfc937be98bb4827fd5e6b689adc2e26513db531076a6564396255a09975b7034dac06461b255642e3a7ed75fa9fc265011f5f6250382a84ac268d63ba64 +SIG: 279cace6fdaf3945e3837df474b28646143747632bede93e7a66f5ca291d2c24978512ca0cb8827c8c322685bd605503a5ec94dbae61bbdcae1e49650602bc07 + +PRIV: 65de297b70cbe80980500af0561a24db50001000125f4490366d8300d3128592ba8e2ad929bdcea538741042b57f2067d3153707a453770db9f3c4ca75504d24 +PUB: ba8e2ad929bdcea538741042b57f2067d3153707a453770db9f3c4ca75504d24 +MESSAGE: 131d8f4c2c94b153565b86592e770c987a443461b39aa2408b29e213ab057affc598b583739d6603a83fef0afc514721db0e76f9bd1b72b98c565cc8881af5747c0ba6f58c53dd2377da6c0d3aa805620cc4e75d52aabcba1f9b2849e08bd1b6b92e6f06615b814519606a02dc65a8609f5b29e9c2af5a894f7116ef28cfd1e7b76b64061732f7a5a3f8aa4c2e569e627a3f9749aa597be49d6b94436c352dd5fa7b83c92d2610faa32095ca302152d91a3c9776750e758ee8e9e402c6f5385eaa5df23850e54beb1be437a416c7115ed6aa6de13b55482532787e0bee34b83f3084406765635497c931b62a0518f1fbc2b891dc7262c7c6b67eda594fa530d74c9329bad5be94c287fbcde53aa80272b83322613d9368e5904076fdbcc88b2c0e59c10b02c448e00d1b3e7a9c9640feffb9523a8a60e1d83f04a4b8df69153b +SIG: 7a9b736b01cc92a3349f1a3c32dbd91959825394ff443c567405e899c8185ce8fad9500e1fce89d95a6253c00477435acf04bff993de1b00495def0834ee1f07 + +PRIV: 0826e7333324e7ec8c764292f6015d4670e9b8d7c4a89e8d909e8ef435d18d15ffb2348ca8a018058be71d1512f376f91e8b0d552581254e107602217395e662 +PUB: ffb2348ca8a018058be71d1512f376f91e8b0d552581254e107602217395e662 +MESSAGE: 7f9e3e2f03c9df3d21b990f5a4af8295734afe783accc34fb1e9b8e95a0fd837af7e05c13cda0de8fadac9205265a0792b52563bdc2fee766348befcc56b88bbb95f154414fb186ec436aa62ea6fcabb11c017a9d2d15f67e595980e04c9313bc94fbc8c1134c2f40332bc7e311ac1ce11b505f8572ada7fbe196fba822d9a914492fa7185e9f3bea4687200a524c673a1cdf87eb3a140dcdb6a8875613488a2b00adf7175341c1c257635fa1a53a3e21d60c228399eea0991f112c60f653d7148e2c5ceb98f940831f070db1084d79156cc82c46bc9b8e884f3fa81be2da4cdda46bcaa24cc461f76ee647bb0f0f8c15ac5daa795b945e6f85bb310362e48d8095c782c61c52b481b4b002ad06ea74b8d306eff71abf21db710a8913cbe48332be0a0b3f31e0c7a6eba85ce33f357c7aeccd30bfb1a6574408b66fe404d31c3c5 +SIG: 4bac7fabec8724d81ab09ae130874d70b5213492104372f601ae5abb10532799373c4dad215876441f474e2c006be37c3c8f5f6f017d0870414fd276a8f42808 + +PRIV: 00ad6227977b5f38ccda994d928bba9086d2daeb013f8690db986648b90c1d4591a4ea005752b92cbebf99a8a5cbecd240ae3f016c44ad141b2e57ddc773dc8e +PUB: 91a4ea005752b92cbebf99a8a5cbecd240ae3f016c44ad141b2e57ddc773dc8e +MESSAGE: cb5bc5b98b2efce43543e91df041e0dbb53ed8f67bf0f197c52b2211e7a45e2e1ec818c1a80e10abf6a43535f5b79d974d8ae28a2295c0a6521763b607d5103c6aef3b2786bd5afd7563695660684337bc3090739fb1cd53a9d644139b6d4caec75bda7f2521fbfe676ab45b98cb317aa7ca79fc54a3d7c578466a6aa64e434e923465a7f211aa0c61681bb8486e90206a25250d3fdae6fb03299721e99e2a914910d91760089b5d281e131e6c836bc2de08f7e02c48d323c647e9536c00ec1039201c0362618c7d47aa8e7b9715ffc439987ae1d31154a6198c5aa11c128f4082f556c99baf103ecadc3b2f3b2ec5b469623bc03a53caf3814b16300aedbda538d676d1f607102639db2a62c446707ce6469bd873a0468225be88b0aef5d4020459b94b32fe2b0133e92e7ba54dd2a5397ed85f966ab39ed0730cca8e7dacb8a336 +SIG: dc501db79fd782bc88cae792557d5d273f9ba560c7d90037fe84ac879d684f612a77452c4443e95c07b8be192c35769b17bbdfca42280de796d92119d833670d + +PRIV: 1521c6dbd6f724de73eaf7b56264f01035c04e01c1f3eb3cbe83efd26c439ada2f61a26ffb68ba4f6e141529dc2617e8531c7151404808093b4fa7fedaea255d +PUB: 2f61a26ffb68ba4f6e141529dc2617e8531c7151404808093b4fa7fedaea255d +MESSAGE: 3e3c7c490788e4b1d42f5cbcae3a9930bf617ebdff447f7be2ac2ba7cd5bcfc015760963e6fe5b956fb7cdb35bd5a17f5429ca664f437f08753a741c2bc8692b71a9115c582a25b2f74d329854d60b7817c079b3523aaff8793c2f72fff8cd10592c54e738df1d6452fb72da131c6731ea5c953c62ea177ac1f4735e5154477387109afae15f3ed6eeb08606e28c81d4386f03b9376924b6ef8d221ee29547f82a7ede48e1dc17723e3d42171eeaf96ac84bedc2a01dd86f4d085734fd69f91b5263e439083ff0318536adff4147308e3aafd1b58bb74f6fb0214a46fdcd3524f18df5a719ce57319e791b4ea606b499bfa57a60e707f94e18f1fed22f91bc79e6364a843f9cbf93825c465e9cae9072bc9d3ec4471f21ab2f7e99a633f587aac3db78ae9666a89a18008dd61d60218554411a65740ffd1ae3adc06595e3b7876407b6 +SIG: a817ed23ec398a128601c1832dc6af7643bf3a5f517bcc579450fdb4759028f4966164125f6ebd0d6bf86ff298a39c766d0c21fdb0cbfdf81cd0eb1f03cd8a08 + +PRIV: 17e5f0a8f34751babc5c723ecf339306992f39ea065ac140fcbc397d2dd32c4b4f1e23cc0f2f69c88ef9162ab5f8c59fb3b8ab2096b77e782c63c07c8c4f2b60 +PUB: 4f1e23cc0f2f69c88ef9162ab5f8c59fb3b8ab2096b77e782c63c07c8c4f2b60 +MESSAGE: c0fad790024019bd6fc08a7a92f5f2ac35cf6432e2eaa53d482f6e1204935336cb3ae65a63c24d0ec6539a10ee18760f2f520537774cdec6e96b55536011daa8f8bcb9cdaf6df5b34648448ac7d7cb7c6bd80d67fbf330f8765297766046a925ab52411d1604c3ed6a85173040125658a32cf4c854ef2813df2be6f3830e5eee5a6163a83ca8849f612991a31e9f88028e50bf8535e11755fad029d94cf25959f6695d09c1ba4315d40f7cf51b3f8166d02faba7511ecd8b1dded5f10cd6843455cff707ed225396c61d0820d20ada70d0c3619ff679422061c9f7c76e97d5a37af61fd62212d2dafc647ebbb979e61d9070ec03609a07f5fc57d119ae64b7a6ef92a5afae660a30ed48d702cc3128c633b4f19060a0578101729ee979f790f45bdbb5fe1a8a62f01a61a31d61af07030450fa0417323e9407bc76e73130e7c69d62e6a7 +SIG: efe2cb63fe7b4fc98946dc82fb6998e741ed9ce6b9c1a93bb45bc0a7d8396d7405282b43fe363ba5b23589f8e1fae130e157ce888cd72d053d0cc19d257a4300 + +PRIV: 0cd7aa7d605e44d5ffb97966b2cb93c189e4c5a85db87fad7ab8d62463c59b594889855fe4116b4913927f47f2273bf559c3b394a983631a25ae597033185e46 +PUB: 4889855fe4116b4913927f47f2273bf559c3b394a983631a25ae597033185e46 +MESSAGE: 28a55dda6cd0844b6577c9d6da073a4dc35cbc98ac158ab54cf88fd20cc87e83c4bba2d74d82ce0f4854ec4db513de400465aaa5eee790bc84f16337072d3a91cde40d6e0df1ba0cc0645f5d5cbbb642381d7b9e211d25267a8acf77d1edb69c3a630f5b133d24f046a81bf22ff03b31d8447e12c3f7b77114a70cbd20bbd08b0b3827a6bbcf90409e344447a7fbc59bdd97d729071f8d71dcc33e6ef2cbab1d411edf13734db1dd9703276f5eb2d6aa2cb8952dd6712bfae809ce08c3aa502b8135713fac0a9c25b1d45b6a5831e02421bba65b81a596efa24b0576bd1dc7fdfb49be762875e81bd540722bc06140b9aa2ef7b84a801e41ded68d4546ac4873d9e7ced649b64fadaf0b5c4b6eb8d036315233f4326ca01e03393050cd027c24f67303fb846bd2c6b3dba06bed0d59a36289d24bd648f7db0b3a81346612593e3ddd18c557 +SIG: bf9115fd3d02706e398d4bf3b02a82674ff3041508fd39d29f867e501634b9261f516a794f98738d7c7013a3f2f858ffdd08047fb6bf3dddfb4b4f4cbeef3003 + +PRIV: 33371d9e892f9875052ac8e325ba505e7477c1ace24ba7822643d43d0acef3de35929bded27c249c87d8b8d82f59260a575327b546c3a167c69f5992d5b8e006 +PUB: 35929bded27c249c87d8b8d82f59260a575327b546c3a167c69f5992d5b8e006 +MESSAGE: 27a32efba28204be59b7ff5fe488ca158a91d5986091ecc4458b49e090dd37cbfede7c0f46186fabcbdff78d2844155808efffd873ed9c9261526e04e4f7050b8d7bd267a0fe3d5a449378d54a4febbd2f26824338e2aaaf35a32ff0f62504bda5c2e44abc63159f336cf25e6bb40ddb7d8825dff18fd51fc01951eaedcd33707007e1203ca58b4f7d242f8166a907e099932c001bfb1ec9a61e0ef2da4e8446af208201315d69681710d425d2400c387d7b9df321a4aec602b9c656c3e2310bff8756d18b802134b15604f4edc111149a9879e31241dd34f702f4c349617b13529769a772f5e52a89c098e0dca5920667893a250061b17991626eb9319298685be46b6a8b68422444fa5a36bcf3a687e2eccb9322c87dc80165da898930850b98fc863cada1aa99c6d61c451b9ccf4874c7f0e75b0a0c602f044812c71765adaf02025395b0 +SIG: 985ca446ddc007827cc8f2852cbd8115ef8c5975e9d7ce96d74dfed859aa14a4c15254006bea5e08359efe2625d715e0897ee5a16f151203be5010418637de05 + +PRIV: beedb8073df58f8c1bffbdbd77ec7decb2c82a9babecefc0331507bdc2c2a7e7b27e908b805e296fc30d2e474b060cd50c0f6f520b3671712183bd89d4e733e9 +PUB: b27e908b805e296fc30d2e474b060cd50c0f6f520b3671712183bd89d4e733e9 +MESSAGE: 35ca57f0f915e5209d54ea4b871ffb585354df1b4a4a1796fbe4d6227d3e1aba5171ed0391a79e83e24d82fdafd15c17b28bf6c94d618c74d65264e58faaacd2902872fdd0efa22e8d2d7ce8e3b8197f0c3615b0a385235fa9fd8e4564ee6e6b1650b4cfb94d872c805c32d4f3a18f966461d3adbb605fa525884f8eb197627396ba4d995d78ac02948a0eaabb58519b9a8e2e7985cd1de2c71d8918d96a0168660ce17cddf364e3ec0d4bd90f2104751a1927ee1d23f3e7a69840ed040b00e5f6e4866ec58813149cc382aebf6162608c79574d553f47230e924a0ef1ebf55d8e1a52abb62a2d7ac86027c7c03cc83fa1949da29e2f3037ab986fd2fffe650e3149babae5a50b1ee9696f3babec72e29697c82422814d272085500fd837fe3c7a973ef4c169af12dd7f02700620bb045bdbf84623f326350570b3cadbc9aea4200b28287e17ab +SIG: 8c890cccadc7760e1e82e43c44b3dc0b685a48b479ae13cc0a6b0557d0fb1cbabba63d2a96843412ea8d36c50acbf52b92cfb2dce49dc48af6ddcf8ee47a8608 + +PRIV: 9184ef618816832592bc8eb35f4ffd4ff98dfbf7776c90f2aad212ce7e03351e687b7726010d9bde2c90e573cd2a2a702ff28c4a2af70afc7315c94d575601e5 +PUB: 687b7726010d9bde2c90e573cd2a2a702ff28c4a2af70afc7315c94d575601e5 +MESSAGE: 729eb7e54a9d00c58617af18c345b8dc6e5b4e0f57de2f3c02e54a2ec8f1425ec2e240775b5ab0c10f84ac8bafda4584f7e21c655faecd8030a98906bd68398f26b5d58d92b6cf045e9bd9743c74c9a342ec61ce57f37b981eac4d8bf034608866e985bb68686a68b4a2af88b992a2a6d2dc8ce88bfb0a36cf28bbab7024abfa2bea53313b66c906f4f7cf66970f540095bd0104aa4924dd82e15413c22679f847e48cd0c7ec1f677e005fec0177fbd5c559fc39add613991fbaeae4d24d39d309ef74647f8192cc4c62d0642028c76a1b951f6bc9639deb91ecc08be6043f2109705a42c7eae712649d91d96ccbbfb63d8d0dd6dd112160f61361ecdc6793929ca9aef9ab56944a6fa4a7df1e279eaf58ce8323a9cf62c94279fff7440fbc936baa61489c999330badcb9fc0e184bc5093f330cbb242f71fb378738fea10511dd438364d7f76bcc +SIG: b3c24e75132c563475422d5ea412b5c1e8e6e5ea1c08ead1393c412da134c9a1638284ea7e2ca032fe3d3e32a9066a8c8839903f6ef46e966bb5e492d8c2aa00 + +PRIV: 354e13152ee1fe748a1252204c6527bdc1b1eb2eb53678150e6359924708d812d45ff6c5fb83e7bb9669aa8960deb7dbc665c988439b6c9ef672c6811dc8bcf6 +PUB: d45ff6c5fb83e7bb9669aa8960deb7dbc665c988439b6c9ef672c6811dc8bcf6 +MESSAGE: 8e5fccf66b1ba6169cb685733d9d0e0190361c90bcab95c163285a97fe356d2bdcde3c9380268805a384d063da09ccd9969cc3ff7431e60a8e9f869cd62faa0e356151b280bc526e577c2c538c9a724dc48bf88b70321d7e1eeedb3c4af706748c942e67bdabdb41bec2977b1523069e31e29b76300288f88a51b384b80cc2526f1679340ddec3881f5cd28b0378d9cd0a812b68dd3f68f7a23e1b54bee7466ac765cf38df04d67441dfa498c4bffc52045fa6d2dbcdbfa33dfaa77644ffccef0decdb6790c70a0d734ec287cc338cb5a909c0055189301169c4f7702c05c0911a27b16ef9ed934fa6a0ca7b13e413523422535647968030edc40cd73e7d6b345b7581f438316d68e3cd292b846d3f4f7c4862bc7e6b3fb89a27f6f60cd7db2e34ec9aae1013fe37acff8ad888cb9a593ef5e621eae5186c58b31dcfde22870e336d33f440f6b8d49a +SIG: de2b46e65f3decef34332e500f2e11306fbdcf1be85a1c1ee68ba3045dcec2c7be608d22927da1f44c0e2083ae622cf3c29d893887994efcfa2ca594f5051f03 + +PRIV: 7ff62d4b3c4d99d342d4bb401d726b21e99f4ef592149fc311b68761f5567ff67fdfdb9eca29d3f01d9486d7e112ce03aa37b91326a4283b9c03999c5eda099a +PUB: 7fdfdb9eca29d3f01d9486d7e112ce03aa37b91326a4283b9c03999c5eda099a +MESSAGE: 99c44c796572a4823fc6c3807730839173774c05dbfc1492ed0d00509a95a1de37274b3135ed0456a1718e576597dc13f2a2ab37a45c06cbb4a2d22afad4d5f3d90ab3d8da4dcdaa06d44f2219088401c5dceee26055c4782f78d7d63a380608e1bef89eeef338c2f0897da106fafce2fb2ebc5db669c7c172c9cfe77d3109d239fe5d005c8ee751511b5a88317c729b0d8b70b52f6bd3cda2fe865c77f36e4f1b635f336e036bd718bec90ee78a802811510c4058c1ba364017253aa842922e1dd7d7a0f0fc9c69e43fc4eaeffaaf1ae5fa5d2d73b43079617baba030923fe5b13d2c1c4fe6fac3f2db74e2020a734b6121a0302fce820ba0580ce6135348fdf0632e0008df03ee112168f5cfa0037a26a1f69b1f1317edf2a3ab367455a77e00691215d7aa3133c2159d3da2b134cf04f0defbf07a6064011e64dd14d4f8f064356655428804c2771a +SIG: 058f79927fbf6178724815c7b11c63baaa90bcc15d7272be082f8a9141861c816433055f6cf6491424853f9ec78bb91ace913a93411b4e5ed58bc4ba5715c60a + +PRIV: 6cabadd03f8a2e6ebab96a74f80e18164e4d1b6baa678f5a82e25604af989aaf2a4a3179564194e00100c18bc35351d8b135bbae5b32b28fce1d7b6766ca4b32 +PUB: 2a4a3179564194e00100c18bc35351d8b135bbae5b32b28fce1d7b6766ca4b32 +MESSAGE: 279f78cf3b9ccfc6e1b01e1a82f50ed172e9a8e1e702bb15661dd7dc3a456ff7a7a7fdfb081db3867079630c7f70fd753292ec60ecbf50632e9aa45b996505c66e6dc3c6ae892e21b6a8705e4bbae8f16a3378554b31fdb0139dcd15c96a8a7e4b88756a86d18db5dc74fd7691197dd88e2c7d5df52b049344cdc477c9cd7e89eda99ccfb1d00814d0152b9654df3279372ca5f18b1c946f2894a76b079ddb1c3cd61fbb969aeec9193a6b88fb7d136c07f9821e5c1074b4e93bcaf6fa14d0d1d7e1707589d77ec1337206e53a1f06cc26672ff95c13d5ff444766931ba30a0afdcdadd2098e9c41fd87a3f23cd16dbb0efbf8092ce33e327f42610990e1cee6cb8e54951aa081e69765ae4009aeed758e768de50c23d9a22b4a06dc4d19fc8cbd0cdef4c983461755d0a3b5d6a9c12253e09568339ff7e5f78c5fdf7ec89f9186a621a8c0eed11b67022e +SIG: 4e65c6c1d493045e8a9250e397c1d1d30ffed24db66a8961aa458f8f0fcb760c39fe8657d7ab8f84000b96d519717cff71f926522c1efec7f8b2624eae55f60c + +PRIV: 0fa0c32c3ae34be51b92f91945405981a8e202488558a8e220c288c7d6a5532dd6aee62bd91fc9453635ffcc02b2f38dcab13285140380580ccdff0865df0492 +PUB: d6aee62bd91fc9453635ffcc02b2f38dcab13285140380580ccdff0865df0492 +MESSAGE: 53f44be0e5997ff07264cb64ba1359e2801def8755e64a2362bddaf597e672d021d34fface6d97e0f2b1f6ae625fd33d3c4f6e9ff7d0c73f1da8defb23f324975e921bb2473258177a16612567edf7d5760f3f3e3a6d26aaabc5fde4e2043f73fa70f128020933b1ba3b6bd69498e9503ea670f1ed880d3651f2e4c59e79cabc86e9b703394294112d5d8e213c317423b525a6df70106a9d658a262028b5f45100cb77d1150d8fe461eed434f241015f3276ad7b09a291b4a7f35e3c30051cbf13b1d4a7fa0c81a50f939e7c49673afdc87883c9e3e61f5a1df03755470fda74bf23ea88676b258a97a280d5f90b52b714b596035bae08c8d0fe6d94f8949559b1f27d7116cf59dd3cfbf18202a09c13f5c4fbc8d97225492887d32870c2297e34debd9876d6d01ac27a16b088b079079f2b20feb02537cda314c43cb2dca371b9df37ed11ec97e1a7a6993a +SIG: 7e9ab85ee94fe4b35dcb545329a0ef25923de5c9dc23e7df1a7e77ab0dcfb89e03f4e785ca6429cb2b0df50da6230f733f00f33a45c4e576cd40bdb84f1ae001 + +PRIV: 7b06f88026fa86f39fce2426f67cc5996bedd0cfc4b5ebb1b5e3edbb47e080aa3f1469ee6a2e7867e2e9012d402cf5a4861497c01df879a1deb1c539830b58de +PUB: 3f1469ee6a2e7867e2e9012d402cf5a4861497c01df879a1deb1c539830b58de +MESSAGE: 71175d4e21721297d9176d817f4e785d9600d923f987fe0b26fd79d33a5ea5d1e818b71f0f92b8c73afddabdcc27f6d16e26aafa874cfd77a00e06c36b041487582bb933760f88b419127345776ea418f83522254fed33819bc5c95f8f8404cc144ebf1486c88515409d3433aaf519d9920f5256e629419e9a95580a35b069b8d25533dfcbc98ad36404a951808e01378c03266326d120046975fde07daef3266caacd821c1403499d7fdf17c033c8d8c3f28f162b5f09dfdaca06285f00c6cb986dfdf5151aa6639608b5b13e78d65a4368585b16138754fbd113835a686cd066c2b89bb0953c24d50e77bf0fc457c1e0fcf5d44da8db9a88f062be3b688d5cdcff1d1c00e81ec9d413882295b341fee8fa427dc109adeb5f284eec202f1bef115bf96b1782d3ccdeb682b69bf92d170c007d5df80e1ed962f677dc24a145a1e4e829e8dec0104e5f78365944 +SIG: 42f133e34e3eb7032a133ed781537ec62e44a5ce8381e5e0bf9e13a914a4b2c757811d6d3b1e86672424ea4230d10f7c610abb7069e61e319b4066a2bd7bc900 + +PRIV: c3f5e149968a24f4de9119531975f443015ccca305d7119ed4749e8bf6d94fc739aaccdb948a4038538a4588322f806bb129b5876c4bec51271afe4f49690045 +PUB: 39aaccdb948a4038538a4588322f806bb129b5876c4bec51271afe4f49690045 +MESSAGE: c46370e37f2e0cadcf93402f1f0cb048f52881ba750b7a43f56ab11ce348732fb57e7f9aaf8dfcbe455e14e983c248d026a27e7f148d5db5a53f94635702b895127771047a876d14107386c5e0ff8933345bbd7a936d990d33efa28c2ec4e4864ffd2ff576f7c88f954cfc1c459e883bb712dae3cdf6632066f1f4d13a509615b3360cadc5a307f23e52a51b40a6feebe0b18d0e9ee4e348f33cd81a8def222f6a59b12861d335bd9af85cc004be46f1d3a424f4870ae9dc587e5a4ade136b9370649348c33ac3bf1febeebffea37085ed59cac9d9e696470b234609e9a10a9d431ff91e69cb5135fd117ff58a36539744ebe70cea6973c00c7a4d57b62f4a7136d731b8e46ff18ec0ed69070031905075d8541d568cfce6eeb76242b7819a7b6a93552111bb88f165527cfa6966d39fcbe0a7dea008e39c7a3e577ab307cd1d0ea326833d52654e172955f3fcd4 +SIG: 5fa2b531677b00b85b0a313cbd479f55f4ab3ec5cfce5e454d2b74176ccc3399c899f9d6b51ed4c1e76185ac9fe730c4b4014044f7041185bc3c85722eb2ea02 + +PRIV: 42305c9302f45ea6f87e26e2208fd94b3c4ad037b1b6c83cf6677aa1096a013c3b97b1f11ce45ba46ffbb25b76bfc5ad7b77f90cc69ed76115dea4029469d587 +PUB: 3b97b1f11ce45ba46ffbb25b76bfc5ad7b77f90cc69ed76115dea4029469d587 +MESSAGE: d110828d449198d675e74e8e39439fd15e75bf2cc1f430abfb245836885bafc420f754b89d2fbbf6dd3490792e7a4f766073cfe3b302d089831ace869e2730fde45c2121ec3ef217aa9c43fa7cc7e9ed0a01ad9f1d2fc3613638ca9fc193c98b37455bf5dbf8f38b64708dfdca6c21f0975f1017c5da5f6434bda9f033cec2a631ab50318e017b170b240bf01eb8b36c7e1cb59e7736ac34444208132a8f59e4f313d65d849c6a4fdf13e20ecaee3823e589a171b39b2489497b06e6ff58c2c9f1dc5d3aa3bd10e6443e22d42d07b783f79fd43a46e1cde314b663a95f7246dea131fcd46d1dc333c5454f86b2c4e2e424dea405cc2230d4dcd39a2eab2f92845cf6a7994192063f1202749ef52dcb96f2b79ed6a98118ca0b99ba2285490860eb4c61ab78b9ddc6acc7ad883fa5e96f9d029171223abf7573e36230e0a81f6c1311151473ee264f4b842e923dcb3b +SIG: 18d05e5d01668e83f40fa3bbee28b388acf318d1b0b5ad668c672f345c8eda14c2f884cd2a9039459ce0810bc5b580fe70d3964a43edb49e73a6ff914bbf040c + +PRIV: c57a43dcd7bab8516009546918d71ad459b7345efdca8d4f19929875c839d7222083b444236b9ab31d4e00c89d55c6260fee71ac1a47c4b5ba227404d382b82d +PUB: 2083b444236b9ab31d4e00c89d55c6260fee71ac1a47c4b5ba227404d382b82d +MESSAGE: a4f6d9c281cf81a28a0b9e77499aa24bde96cc1264374491c008294ee0af6f6e4bbb686396f59068d358e30fe9992db0c6f16680a1c71e27a4a907ac607d39bdc3258c7956482fb37996f4beb3e5051b8148019a1c256e2ee999ebc8ce64c54e07fedb4fbd8953ebd93b7d69ce5a0082edd6209d12d3619b4fd2eae916461f72a4ce727157251a19209bbff9fbdbd289436f3fcacc6b4e1318521a47839cba4b14f7d7a21e7b5d6b6a753d5804afcd2b1eb7779b92abab8afa8aa4fa51caec0b85dcd0fc2a0676036d3f56630a831ffeb502861dd89161c708a9c006c73c930ce5b94756426ff18aa112fb4eb9a68500b48d4eedbd4167b6ffd0a11d49443a173ce9d949436748fc0634f06bb08b8f3423f4463dba7b4d199b64df578117f0a2645f0b2a1e2ada27d286f76733f25b82ed1d48a5c3898d4ad621e50ed9060daad40a39532e4d1bf162ce36804d5d4e2d +SIG: 1edef9bc036971f1fa88edf45393c802e6c1a1631c8a06871a09a320821dce40beca97e53a0361a955a4c6d60b8ca8e400c81340911ccb4f56284041cdbb1804 + +PRIV: 2dddb6b8fd04fa90ece1a709f8418f2e5d0c9c43afe7cfce19e6ad15a73476f78059de6a7c4776489ecc2e7d707ffce30285bf30a23f78d72db49cfd6ed0d492 +PUB: 8059de6a7c4776489ecc2e7d707ffce30285bf30a23f78d72db49cfd6ed0d492 +MESSAGE: 474baa590a4cd72d5424e51d8257b3d44325bc4c5063a0033c86ebbe99ed7212184c19944d082a115379dd4cece973faa0bca6485bd25f3744a719e70aa0291e1b5a96e637c140616a98263357c76b6eb0083fe51414e386870d0fdc7dd9abe4ff6fb5bbf1e7b15dac3e08e2615f655c3104ceb32a4cc2c9e9c43cf282d346ac253ccc46b635ae040973b49735720ffb890469a567c5824e0c00d7ccd5509a718092a906461c4d6163eaf422418f5fc6e009fc3f529ac61a2f89bb8e0ed45d940c4c2331ff8d8e1d6d58d417d8fc2656a02e8701aee75aed918724eebe4a2cf4744c5c401e217023df68a6f6a0228bd05a679a697d8de7036b9ed269090d3c65486afb91e27954eb15b964665ede7ad008f12fb3a9d0e69c13b4254f43819e0818a4195f68b8a38ae81f3fcb1879c95ab4cd0ffc38e381089260cca967ace5a085b457ab5eb363852101377570f9ac9e38 +SIG: c634ea7bf72e895a2e796e2834201415b8b45e05e045559284eb9052c0e84f62a5a9f0c9764f7576788c7228b19ef517c195497325a48a9344b147c12fd75509 + +PRIV: 5547f1004baedfce5cfc0850b05302374aad24f6163994ecd751df3af3c106207ce620787385ee1951ac49a77352ee0d6f8c5cd47df74e9e3216a6324fc7cf7f +PUB: 7ce620787385ee1951ac49a77352ee0d6f8c5cd47df74e9e3216a6324fc7cf7f +MESSAGE: a6c17eeb5b8066c2cd9a89667317a945a0c7c96996e77ae854c509c6cd0631e922ad04503af87a3c4628adafed7600d071c078a22e7f64bda08a362b38b26ca15006d38acf532d0dedea4177a2d33f06956d80e963848ec791b2762fa99449b4f1a1ed9b3f2580be3ac7d7f52fb14421d6222ba76f807750c6cbb0b16f0895fc73d9dfc587e1a9e5d1e58375fbab705b8f0c1fd7df8b3ad446f2f08459e7ed1af59556fbc966dc249c1cf604f3e677c8a09d4363608774bf3811bef0642748c55c516c7a580fa3499050acb30eed870d0d91174cb623e98c3ad121cf81f04e57d49b008424a98a31eeaaf5f38e000f903d48d215ed52f862d636a5a73607de85760167267efe30f8a26ebc5aa0c09f5b258d3361ca69d1d7ee07b59648179ab2170ec50c07f6616f216872529421a6334a4a1ed3d2671ef47bc9a92afb58314e832db8a9003408a0487503fe4f67770dd4b6 +SIG: 29df3ad589009c667baa5e72dabb4e53cb7876de4e7efe5cc21ead7fa878db57f97c1103ddb39a861eb88653c1d4ec3b4306e4584b47b8bc90423119e7e4af00 + +PRIV: 3dd7203c237aefe9e38a201ff341490179905f9f100828da18fcbe58768b5760f067d7b2ff3a957e8373a7d42ef0832bcda84ebf287249a184a212a94c99ea5b +PUB: f067d7b2ff3a957e8373a7d42ef0832bcda84ebf287249a184a212a94c99ea5b +MESSAGE: db28ed31ac04b0c2decee7a6b24fc9a082cc262ca7ccf2a247d6372ec3e9120ecedb4542ea593fea30335c5ab9dd318a3b4fd5834299cf3f53d9ef46137b273c390ec3c26a0b4470d0d94b77d82cae4b24587837b167bb7f8166710baeb3ee70af797316cb7d05fa57e468ae3f0bd449404d8528808b41fcca62f5e0a2aa5d8f3acab008cc5f6e5ab02777bdcde87f0a10ef06a4bb37fe02c94815cf76bfb8f5cdd865cc26dcb5cf492edfd547b535e2e6a6d8540956dcba62cfea19a9474406e934337e454270e01036ac45793b6b8aceda187a08d56a2ce4e98f42ea375b101a6b9fcb4231d171aa463eeb43586a4b82a387bcddaf71a80fd5c1f7292efc2bd8e70c11eaa817106061b6c461c4883d613cc06c7e2a03f73d90fc55cdc07265eefd36be72270383d6c676cae37c93691f1ae3d927b3a1cd963e4229757ae5231eea73a9f71515628305410ac2593b325cc631 +SIG: 4c036935a96abc0d050d907bedbe9946fb97439f039c742e051ccf09add7df44d17da98c2ca01bdc2424da1e4debf347f8fff48ac8030d2cc07f9575c044be04 + +PRIV: 282775df9ebbd7c5a65f3a2b096e36ee64a8f8ea719da77758739e4e7476111da2b49646033a13937cad6b0e914e3cec54989c252ca5643d076555d8c55e56e0 +PUB: a2b49646033a13937cad6b0e914e3cec54989c252ca5643d076555d8c55e56e0 +MESSAGE: 14cc50c2973ea9d0187a73f71cb9f1ce07e739e049ec2b27e6613c10c26b73a2a966e01ac3be8b505aeaad1485c1c2a3c6c2b00f81b9e5f927b73bfd498601a7622e8544837aad02e72bf72196dc246902e58af253ad7e025e3666d3bfc46b5b02f0eb4a37c9554992abc8651de12fd813177379bb0ce172cd8aaf937f979642bc2ed7c7a430cb14c3cd3101b9f6b91ee3f542acdf017f8c2116297f4564768f4db95dad8a9bcdc8da4d8fb13ef6e2da0b1316d3c8c2f3ed836b35fe2fd33effb409e3bc1b0f85225d2a1de3bfc2d20563946475c4d7ca9fddbaf59ad8f8961d287ae7dd803e7af1fa612329b1bdc04e225600ae731bc01ae0925aed62ac50d46086f3646cf47b072f0d3b044b36f85cec729a8bb2b92883ca4dfb34a8ee8a0273b31af50982bb6131bfa11d55504b1f6f1a0a00438ca26d8ab4f48bcddc9d5a38851abede4151d5b70d720732a00abea2c8b979 +SIG: 15763973859402907d8dcb86adc24a2a168ba3abf2246173d6348afed51ef60b0c0edeff4e10bcef4c6e5778c8bc1f5e9ee0237373445b455155d23de127a202 + +PRIV: 4730a5cf9772d7d6665ba787bea4c95252e6ecd63ec62390547bf100c0a46375f9f094f7cc1d40f1926b5b22dce465784468b20ab349bc6d4fdf78d0042bbc5b +PUB: f9f094f7cc1d40f1926b5b22dce465784468b20ab349bc6d4fdf78d0042bbc5b +MESSAGE: e7476d2e668420e1b0fadfbaa54286fa7fa890a87b8280e26078152295e1e6e55d1241435cc430a8693bb10cde4643f59cbfcc256f45f5090c909a14c7fc49d37bfc25af11e8f4c83f4c32d4aabf43b20fa382bb6622a1848f8ffc4dff3408bb4ec7c67a35b4cdaee5e279c0fc0a66093a9f36a60fdd65e6334a804e845c8530b6fda363b5640337d027243ccfb3c177f43e717896e46ead7f72ca06aa0ff1e77247121baf48be9a445f729ca1390fc46151cbd33fcbd7373f27a6ba55c92cbf6945b09b44b9a4e5800d403070ae66048997b2197f02181a097e563f9b9acc841139258a258bc610d3bd891637356b2edc8c184c35c65af91aaf7b1c16d74a5f5f862548139254ecf550631d5f8849afdb5b64cf366ff2633a93f3a18c39b5150245fb5f33c9e4e2d94af6963a70b88f9e7e519f8fa2a0f2e3749de883d0e6f052a949d0fc7153a8693f6d801d7352eb2f7a465c0e +SIG: 552c7347bdfe131646ce0932d82a36d2c1b76d7c30ee890e0592e19f9d18b9a56f48d7a9b68c017da6b550c943af4a907baf317e419fbbc96f6cf4bfad42de00 + +PRIV: 2770aadd1d123e9547832dfb2a837eba089179ef4f23abc4a53f2a714e423ee23c5fbb07530dd3a20ff35a500e3708926310fed8a899690232b42c15bd86e5dc +PUB: 3c5fbb07530dd3a20ff35a500e3708926310fed8a899690232b42c15bd86e5dc +MESSAGE: a5cc2055eba3cf6f0c6332c1f2ab5854870913b03ff7093bc94f335add44332231d9869f027d82efd5f1227144ab56e3222dc3ddccf062d9c1b0c1024d9b416dfa3ee8a7027923003465e0ffaefb75b9f29dc6bcf213adc5e318fd8ba93a7aa5bfb495de9d7c5e1a196cd3a2d7721f8ba785aa9052a1811c7fcc8f93932765059cab9c9b718945895ef26f3ac048d4cabf91a9e6aa83ac14d43156827837914eb763a23cba53f60f150f4b70203ec1833ff105849457a8da7327661fb23a554164e05fcf0146b10674964be6f6aa0acc94c41ad57180e5180d199bd9102f55d740e81789b15671bbd0670e6de5d97e1ae626d8a0ebc32c8fd9d24737274e47d2dd5941a272e72a598928ad109cde937bf248d57f5d2942983c51e2a89f8f054d5c48dfad8fcf1ffa97f7de6a3a43ca15fc6720efaec69f0836d84223f9776d111ec2bbc69b2dfd58be8ca12c072164b718cd7c246d64 +SIG: f267715e9a84c7314f2d5869ef4ab8d2149a13f7e8e1c728c423906293b49ce6283454dd1c7b04741df2eabedc4d6ab1397dc95a679df04d2c17d66c79bb7601 + +PRIV: 4fdab7c1600e70114b11f533242376af7614b4d5da046ac4bedea21d8a361598a25c9a94d6e4ecd95a4bd6805f762eb1c457a8d45d243238b1839cbba8f441cc +PUB: a25c9a94d6e4ecd95a4bd6805f762eb1c457a8d45d243238b1839cbba8f441cc +MESSAGE: da405890d11a872c119dab5efcbff61e931f38eccca457edc626d3ea29ed4fe3154fafec1444da74343c06ad90ac9d17b511bcb73bb49d90bafb7c7ea800bd58411df1275c3cae71b700a5dab491a4261678587956aa4a219e1ac6dd3fb2cb8c46197218e726dc7ed234526a6b01c0d72cb93ab3f4f38a08e5940b3f61a72ad2789a0532000fac1d2d2e3ad632ac8b62bb3ff5b99d53597bf4d44b19674924df9b3db3d0253f74627ccab30031c85e291c58b5fa9167522a46746fc307036745d4f9817786e5d300e6c5d503125fea01dec3e3fedbf3861ca2627a0518fb2b24e5a7a014178719e9b345f7b249ce3a413280c8deb674f59a25be92a8ab6400c7c52b0728ae34e22b2ec200c1cbaba2ccd8af29249d17af60c36007a722fc80258a7bebab1cdaad7462a8b7588c2f7e27c6d07afcf60117fed11bd6859e75e3b4fcee3981881e95dd116827dd4b369af069d3c8f2676f8a +SIG: 5075c090cfbeb6b01802af7f4da5aa4f434d5ee2f3530eebb75c85e08621f83edc08aa96693894a4277633ba81e19e9e55af5c495daa5e1a6f8cbb79c01c7207 + +PRIV: 264504604e70d72dc4474dbb34913e9c0f806dfe18c7879a41762a9e4390ec61eb2b518ce7dc71c91f3665581651fd03af84c46bf1fed2433222353bc7ec511d +PUB: eb2b518ce7dc71c91f3665581651fd03af84c46bf1fed2433222353bc7ec511d +MESSAGE: 901d70e67ed242f2ec1dda813d4c052cfb31fd00cfe5446bf3b93fdb950f952d94ef9c99d1c264a6b13c3554a264beb97ed20e6b5d66ad84db5d8f1de35c496f947a23270954051f8e4dbe0d3ef9ab3003dd47b859356cecb81c50affa68c15dadb5f864d5e1bb4d3bada6f3aba1c83c438d79a94bfb50b43879e9cef08a2bfb22fad943dbf7683779746e31c486f01fd644905048b112ee258042153f46d1c7772a0624bcd6941e9062cfda75dc8712533f4057335c298038cbca29ebdb560a295a88339692808eb3481fd9735ea414f620c143b2133f57bb64e44778a8ca70918202d157426102e1dfc0a8f7b1ae487b74f02792633154dfe74caa1b7088fda22fa8b9bc354c585f1567706e2955493870f54169e0d7691159df43897961d24a852ea970c514948f3b48f71ee586e72ec78db820f253e08db84f6f312c4333bd0b732fe75883507783e9a1fd4fbab8e5870f9bf7ad58aa +SIG: eea439a00f7e459b402b835150a779eed171ab971bd1b58dcc7f9386dadd583de8dc69e267121dde41f0f9493d450b16219cdf3c22f09482ce402fe17ca49e08 + +PRIV: 2ca7447a3668b748b1fd3d52d2080d30e34d397bb2846caf8f659ac168788ca5ab331cd40a31d0173c0c8c1c17002532807bf89e3edb6d34c2dd8294632b9fbc +PUB: ab331cd40a31d0173c0c8c1c17002532807bf89e3edb6d34c2dd8294632b9fbc +MESSAGE: a82bcd9424bffda0f2f5e9eae17835dbe468f61b785aab82934737a91c5f602cb7c617cdffe87cad726a4972e15a7b8ee147f062d2a5a4d89706b571fa8aa2b95981c78abeaaae86203fa2c0e07297406ea8c27111a86dbe1d5a7c3b7ae930904d9890f6d4abebd1412a73ad5feea64acf065d3e63b5cbe20cf20bbd2d8b94f9053ed5f66633482530124446605918de66455e8cf4b101a127233c4e27d5d55bf95bd3195d0340d43531fc75faf8dded5275bf89750de838fd10c31745be4ca41fa871cb0f9b016706a1a7e3c44bb90ac7a8ad51e272389292fd6c98ad7a069e76e3f5f3e0cc770b9e9b35a765d0d93712d7cdabd17e5d01dd8183af4ad9365db0a0fa41381fce60a081df1c5ab0f8c18f95a7a8b582dfff7f149ea579df0623b33b7508f0c663f01e3a2dcd9dfbee51cc615220fdaffdab51bdae42cb9f7fa9e3b7c69cc8ada5ccd642529ba514fdc54fcf2720b8f5d08b95 +SIG: f93ada15ae9cd2b54f26f86f0c28392aed5eb6b6b44d01a4e33a54e7da37c38e8d53366f73fd85be642e4ec81236d163f0d025e76c8bbdd65d43df49f09c1f01 + +PRIV: 494ea9bcce26885b7d17d1fc114448f239f0ce46e5f247b4c999fa86296924726901e5efae57536ba5fdd96b59657359065f25d391a1aa8cdc0d38bb5d53c139 +PUB: 6901e5efae57536ba5fdd96b59657359065f25d391a1aa8cdc0d38bb5d53c139 +MESSAGE: 3badbfa5f5a8aa2cce0a60e686cdce654d24452f98fd54872e7395b39464380a0e185557ea134d095730864f4254d3dd946970c10c804fcc0899dfa024205be0f80b1c75449523324fe6a0751e47b4ff4822b8c33e9eaf1d1d96e0de3d4acd89696b7fcc03d49f92f82b9725700b350db1a87615369545561b8599f5ea920a310a8bafc0e8d7468cbf6f3820e943594afdd5166e4e3309dddd7694ef67e694f34fc62724ff96ac3364176f34e8a02b4cf569db5b8f77d58512aedabf0bcd1c2df12db3a9473f948c5c3243309aae46c49efd088b60f31a8a72ad7e5a35acc5d89fa66807eb5d3ba9cdf08d4753cb85089ee36f5c96b432b6928352afad58012225d6157f9e3611426df921b6d1d8374628a63031e9ffb90e42ffbba021f174f68503155430152c9155dc98ffa26c4fab065e1f8e4622c2f28a8cb043110b617441140f8e20adc16f799d1d5096b1f50532be5042d21b81ea46c7 +SIG: 548a093a680361b7dc56f14503b55eeec3b3f4fd4ca99d6aedce0830f7f4ae2f7328539b34c48fc9760922333dae9c7c017e7db73b8faa6c06be05e347992b06 + +PRIV: 00d735ebaee75dd579a40dfd82508274d01a1572df99b811d5b01190d82192e4ba02517c0fdd3e2614b3f7bf99ed9b492b80edf0495d230f881730ea45bc17c4 +PUB: ba02517c0fdd3e2614b3f7bf99ed9b492b80edf0495d230f881730ea45bc17c4 +MESSAGE: 59c0b69af95d074c88fdc8f063bfdc31b5f4a9bc9cecdffa8128e01e7c1937dde5eb0570b51b7b5d0a67a3555b4cdce2bca7a31a4fe8e1d03ab32b4035e6dadbf1532059ee01d3d9a7633a0e706a1154cab22a07cd74c06a3cb601244cf3cf35a35c3100ba47f31372a2da65dcff0d7a80a1055d8aa99212e899aad7f02e949e6fee4d3c9cefa85069eaff1f6ad06fc300c871ab82b2bedb934d20875c2a263242cdb7f9be192a8710b24c7ea98d43daec8baa5553c678a38f0e0adf7d3ff2dcc799a1dbad6eab1c3d9458a9db922f02e75cfab9d65c7336dae71895d5bb15cac203f2b38b9996c410f8655ad22d3c091c20b7f926d45e780128f19747462abc5c58932fbb9e0bc62d53868802f1b083f183b8a1f9434986d5cf97c04e2f3e145730cba98779c7fed0cab1c05d5e4653c6c3f6736260bc78ee4372862ffe9e90371d762c7432781f35ced884a4baca05653ef25f25a6f3d5628308 +SIG: dcdc54611937d2bd06cacd9818b3be15ce7425427a75f50d197a337a3b8ba6714ef48866f243bd5ac7415e914517a2c1c5a953f432b99db0e620d64f74eb8505 + +PRIV: 8c34b905440b61911d1d8137c53d46a1a76d4609af973e18eb4c5709295627bbb69a8b2fdf5c20e734c2ffb294bc8ae1011d664f11afe7fbc471925cf72fa99d +PUB: b69a8b2fdf5c20e734c2ffb294bc8ae1011d664f11afe7fbc471925cf72fa99d +MESSAGE: 30b57a389b48a0beb1a48432bff6b314bded79c4a1763a5acb57cea1bfb4c6d016cf090f5bd05bbd114e33ae7c17782dfa264f46c45f8c599c603016fe9ff05b6b5a99e92fe713a4cd5c41b292ed2bb2e9cf33a440542e821ec82cbf665c3f02e3dc337d7fdb58e31b27cb2954541468814698510df18c85c81fad12db11ec6b966f4930da5646b991db97445097da30dab61cda53a41083cb96add19de6c5eec323bca9d3530e38c00b35af7360077601be6ac97f3030f930a27b90fe8b6911bae389065adc15e1882300e2a003274d23182d5efd5ba4b9130c07bd5c65fecb8b5cb7eb38836b318befdfd77de4d6ca0181f77ae5740891683225f549dd8426145c97c5818c319f7ab2d868e1a41ceab64c085116069897bf2ca3667652406155ed0646431b6de1ccc03b4279ae4d326679265dce82048e7298e1f87fcec0768ac0f5d8ff84f7210be54d411af8edea7217f4e59413121e148c60da +SIG: 3e0b72073dc9375eedcca6c4fc1cd315938a050c92716bd2284f4629a962beec0b7d7cf16ab923d58f5b90d3901a8e5c75c8f17dab9998e007d8c49511973d0e + +PRIV: 77a83e18c9f000eeff7deeac959ecba2206c0aa39d2f0e2aed5729482a7a022962b1b316135596bfbca6037ed847c61fb7f09fa36ce90abb7789b86f768b59dd +PUB: 62b1b316135596bfbca6037ed847c61fb7f09fa36ce90abb7789b86f768b59dd +MESSAGE: f3d5fa2acaefd858f1df26e03059cdcbc2468ad74afc993d0db9c4cde4113f8d55c7da71d38ba06520531c61fddb5f33d5f0353be2376e580711be45c0a30b1fa01b55e228c6fa35e3f95b67909fc7df3fd464d93d661a926f9d11f7550c17fbcc3496526e8f10e0c8916677b2be5b319b688f21e81aaa9482e5c93e64ce8c437b9c1e14fefed70a3fee568811dc31cadab3d5b220254465336dc4d97a3bd096b5e065e0cfbe82849e2c1905aca486533f0da7a61f1e9a55b8e2a83262deeb59f2b13d3a8aef5700845b83b25ae2183c0ddac0ce42f8d25674cb0d0d220a6de7c1858bb07d59a3372344d944602aa451d2b937db0fe6feca0beba81721fc361ea7509e2b6d397e1c191b56f54ab436d0d27ab4c061bd661ad1a4452387e8735754d07fa7ef4d4548b172582425b299046e6301b5ba6b914418f149cf722e10bde2e0d41700f12c8429fc897b7819da92292240cd45565458c9a7b29c12 +SIG: 1eaad8420ac12c99ac1ff4476678e3cbbe94da6a797f174664d5ee0f641433fb1e7cb2f5613e10805df8654cd8e0d45d96230932bc7f20b04eae836435134309 + +PRIV: 73b03373ef1fd849005ecd6270dd9906f19f4439e40376cdbc520902bc976812663719e08ba3ba1666f6069a3f54991866b18cc6be41991b02eb3026ff9e155f +PUB: 663719e08ba3ba1666f6069a3f54991866b18cc6be41991b02eb3026ff9e155f +MESSAGE: d5c2deaba795c30aba321bc7de6996f0d90e4d05c747fb4dae8f3451895def6e16e72f38eace756f36635f8fb0b72a3a0c1f54663817a94d4fd346f835ab0e657f001a6f2cecb86d0825bd02639254f7f7f38ca99dbb86c64a633f73baf933aae3563281f4005e2d0e7cec9fbde8e588a957e211068be65b3d3d35bf4e8d5bb3478333df9ced9b2abaf48697994a145e9321499fc5ee560f4fbb6849e1ae8eb3d1de0083a21a03f6a6b28176f0130d3895e50e75e3d7d0947a7bc2c5b9ff69895d27791442ba8d0f2180712b567f712ea912f3b0d92c19342e0106ff1d87b46ad33af300b90855ba9769d366e79425d98e4de19905a04577707cbe625b84691781cd26bf62260b4a8bd605f77af6f970e1b3a112e8918344bd0d8d2e41dfd2ce9895b0246e50887aa3a577ff73be4b6ae60feb0ca36f6a5f8171ed209e5c566529c0940d9b4bd744ccee56e54a9a0c6e4da520dd315c2872b02db563703e +SIG: a40abe98fc69da8a1ff9ff5c2cca93632e975980ee8b82c3c376022d6524ab736d01b072f2b681b5f1cd3ea067012ed6d074e949c42327a366caa9e4750a3c08 + +PRIV: eab179e41ed5c889ffe6aabdc054faf1307c395e46e313e17a14fe01023ffa3086f34746d3f7a01ddbe322f1aca56d22856d38733a3a6900bb08e776450ec803 +PUB: 86f34746d3f7a01ddbe322f1aca56d22856d38733a3a6900bb08e776450ec803 +MESSAGE: 971095cebe5031530224387c5c31966e389b8566390054cf45264b44e18964b7be52c33c4ffb259af16283438fa15dd66bc7791b7533ef10cb0beab524a6437626f4cc74512851adcc2fb129055a482c61107383fb7c5241831d5551634eef0dc0b8f9053a00971aa8fa1ae0898e4b481b6707e97c0f942040b339d92fc17bbade74675af243d8b2dafb15b1db55d12415b85f3037291930ab61600ba3431f8eb425be4491614728af101e81c091f348bc5ffd1bde6ae6cad5c15b3aa7358078cc4effb54a86e7f0e0c55e4cfe0a54605ed443fdf2aaba016585da617e77341d52889d75dd540d39fe8b7993ed705cfddea0cb0d5a731d6bfcdb816afaff47e963eedebdf241af5593353d6d401a34f029a8cdeb1904cc2caa4f9635cc2ba6b7b1a29da625ffc383be2f5a8f1fa4f39b2d4b4f4c2d8838ce258a04d4a120493fdf07f68c0ffd1c16b768a35c55fea2cac696b5c20efc10865cde8a64627dcd +SIG: 143cb28027c2f82e375e5f340e7fe6e60ce7bd51000b49c74168af85e26ed2ed630ed2672090164cc54b052da694ebdd21a21b3053f4dcfd7895ea5f6c8aa80d + +PRIV: fbf146ebd51075570ec51ac410ae9f391db75b610ada6362b4dbd949656cfb66be7c2f5b21d746c8ea3245ce6f268e9da74e00fa85c9c475260c68fa1af6361f +PUB: be7c2f5b21d746c8ea3245ce6f268e9da74e00fa85c9c475260c68fa1af6361f +MESSAGE: cd7ad4f17fcff73acc402dc102d09079b29aaf2a0f4b27cf6beeb1e2b23d19ab47deb3ae1becd68861ea279c46691738f4fff47c43047c4f8b56b6bbcc3fde0723d44120dcd307a6310dc4f366b8f3cd52db19b8266a487f7872391c45fe0d3248a7abf2c20022d3769547f683067dcc363cd22fd7cda3cadc15804056f0e2aa2b795008c598be7a961805e6df291ba3041c47ff5640275f46e6ae82092d21abcbcfba11e730216008822de3ce462400596da79f7ae5d1df8389112ad98868fa94fb0546bfe6a67aa8d28c4d32072d2eadd6256255f18c2382e662dfa922a680e06a43622c4871d27d1807f7b2703070c83db8dd929c06038b2183cb8e2b9ec4c778d7ecf9e9ffac77fa7737b055feac2e7982aeeec0b72f1bbca2424e1a844bbac79cb2e7400f81dc449d0560b521a7c16bb4167e6696586058a9b8ed2e5116690b77f2a17e5c0b16a83dcbd2e24552293e258b32ba7f844944379342698627 +SIG: 6768006fe0f201b217dd10eb05d4b82adcfeb2ecfc8373c3308f4150394811eb60491881a2e53d1289d96478e18a64c34b2a19832cdccfd96a2e4a0c469fdc0b + +PRIV: dff0eb6b426dea2fd33c1d3fc24df9b31b486facb7edb8502954a3e8da99d9fdc245085ece69fb9aa560d0c27fdb634f7a840d41d8463660fbe82483b0f3cc3a +PUB: c245085ece69fb9aa560d0c27fdb634f7a840d41d8463660fbe82483b0f3cc3a +MESSAGE: e7c9e313d86160f4c74aa0ae07369ee22b27f81b3f69097affae28dae48483fb52a5c062306b59610f5cdbff6332b1960cd6f2b8f7b41578c20f0bc9637a0fdfc739d61f699a573f1c1a0b49294506cf4487965e5bb07bbf81803cb3d5cb3829c66c4bee7fc800ede216150934d277dea50edb097b992f11bb669fdf140bf6ae9fec46c3ea32f888fde9d154ea84f01c51265a7d3fef6eefc1ccdbffd1e2c897f05546a3b1ca11d9517cd667c660ec3960f7a8e5e80202a78d3a388b92f5c1dee14ae6acf8e17c841c9557c35a2eeced6e6af6372148e483ccd06c8fe344924e1019fb91cbf7941b9a176a073415867210670410c5dbd0ac4a50e6c0a509ddfdc555f60d696d41c77db8e6c84d5181f872755e64a721b061fcd68c463db4d32c9e01ea501267de22879d7fc12c8ca0379edb45abaa6e64dda2af6d40ccf24fbebad7b5a8d3e52007945ecd3ddc1e3efeb522581ac80e98c863ba0c590a3ed95cd1 +SIG: 6b48b10f545ddb7a89cd5829f4e5b20146cf6bc96e550d06f65de8bdae7ccdded26cd630f86c9266bccf88e924033e04f83a54f8290d7f734cf8673cca8f9703 + +PRIV: 9f32958c7679b90fd5036056a75ec2eb2f56ec1effc7c012461dc89a3a1674201d7269dcb6d1f584e662d4ce251de0aba290ef78b97d448afb1e5333f1976d26 +PUB: 1d7269dcb6d1f584e662d4ce251de0aba290ef78b97d448afb1e5333f1976d26 +MESSAGE: a56ba86c71360504087e745c41627092ad6b49a71e9daa5640e1044bf04d4f071ad728779e95d1e2460584e6f0773545da82d4814c9189a120f12f3e3819813e5b240d0f26436f70ee353b4d20cea54a1460b5b8f1008d6f95f3aa2d8f1e908fced50d624e3a096938b9353854b96da463a2798a5a312ec790842c10c446e3350c764bf5c972593b9987bf23256daa8894d47f22e85b97607e66fc08a12c789c4746080368d321bb9015a1155b65523ad8e99bb989b44eac756b0734acd7c6357c70b59743246d1652d91b0f9896965141345b9945cf34980452f3502974edb76b9c785fb0f4395266b055f3b5db8aab68e9d7102a1cd9ee3d142504f0e88b282e603a738e051d98de05d1fcc65b5f7e99c4111cc0aec489abd0ecad311bfc13e7d1653b9c31e81c998037f959d5cd980835aa0e0b09bcbed634391151da02bc01a36c9a5800afb984163a7bb815edbc0226eda0595c724ca9b3f8a71178f0d20a5a +SIG: 9881a5763bdb259a3fefbba3d957162d6c70b804fa94ab613406a6ec42505b8789465ca1a9a33e1895988842270c55e5bdd5483f6b17b31781b593507a6c1808 + +PRIV: f86d6f766f88b00717b7d6327eb26cf3ceeba5385184426f9cfd8295e2421ff2cb1d250504754183704dbe21c323d66f9f9011758f6d8dab6f597b199662145b +PUB: cb1d250504754183704dbe21c323d66f9f9011758f6d8dab6f597b199662145b +MESSAGE: da8423a6b7a18f20aa1f90ed2331b17b24067c40175bc25d8109e21d87ac00528eb3b2f66a2b52dc7ef2f8cecb75c76099cfa23db8da897043ba1cce31e2dfea46075f5e073203eaeb3d62c84c107b6dab33a14eaf149aa61850c15f5a58d88a15aba9196f9e495e8dbecbcf7e8444f5dd72a08a099d7f6209990b562974ea829ef11d29a920e3a799d0d92cb50d50f817631ab09de97c31e9a05f4d78d649fcd93a83752078ab3bb0e16c564d4fb07ca923c0374ba5bf1eea7e73668e135031feafcbb47cbc2ae30ec16a39b9c337e0a62eecdd80c0b7a04924ac3972da4fa9299c14b5a53d37b08bf02268b3bac9ea9355090eeb04ad87bee0593ba4e4443dda38a97afbf2db9952df63f178f3b4c52bcc132be8d9e26881213abdeb7e1c44c4061548909f0520f0dd7520fc408ea28c2cebc0f53063a2d30570e05350e52b390dd9b67662984847be9ad9b4cd50b069ffd29dd9c62ef14701f8d012a4a70c8431cc +SIG: ec61c0b292203a8f1d87235ede92b74723c8d23408423773ae50b1e9bc4464e03e446da9dce4c39f6dd159bea26c009ed00120bc36d4a247dc0d24bcefcc110c + +PRIV: a5b34cefab9479df8389d7e6f6c146aa8affb0bec837f78af64624a145cc344e7b0f4f24d9972bc6fe83826c52716ad1e0d7d19f123858cb3e99fa636ac9631a +PUB: 7b0f4f24d9972bc6fe83826c52716ad1e0d7d19f123858cb3e99fa636ac9631a +MESSAGE: e21e98af6c2bac70557eb0e864da2c2b4d6c0a39a059d3477251f6178a39676f4749e7fbea623f148a43a8b0fe0610506fa658abd2f5fa39198f2636b724db22d1aebc2ab07b2b6dbffdee8cece81e1af1493ec1964e16bf86ab258ca0feb77e3c8717e44038abe152c14be15660bf93b2d48d92c4ed7074d2494210621bcf204fba88c654d5ffe01e1a53d08f70bb237089dc807216ff6a85dbec3102237d42590778acf6c1dc566d5a2bb9a63bc21c329c272e5965baeeb0fe891de3cc8cbfa8e541a8881df68942e7ff8dc656bd08575f6aaf924a176d663b1a1f43574d11768c701b269561e55438dbebfd443d2115cb933d1cde4a915b54c325c27f499ef02bd012ff1f9a36390922887600fe712bcdc23eb5974a305372ad52951f83f0e58cc49e289841621917f1fcb0235147240dae4cf3b99b6ac6d8de94efe7c4436714508bcd0114c56068ff1b7c16d51bd906437874d6549ab5d8087896872ec8a09d7412 +SIG: 2fbd899d72b6d39e4f45b8b62cbbd5f3c0acb1ad8540913fa585877e91ccfef7bee50a4b0f9fedf5cc1e0d1953ad399c8389a93391e1b7c929af6d6f3b796c08 + +PRIV: ad75c9ce299c4d59393367d77a4c9f8df8dcec765c6dbd25b527fb7669913604b9910548fe6312a119c9993eebcfb9dc90030ffb0e4de2b7ccd23cbeb4fef71b +PUB: b9910548fe6312a119c9993eebcfb9dc90030ffb0e4de2b7ccd23cbeb4fef71b +MESSAGE: 62fc5ab67deb1fee9ab6cca3b88a1df1e589f0fd4a88f4aa7738948761fe84372c5b18e4655220c1d84d52acad32e229a5c756c20fc62fe4b4b4e5fd7077ae4ed5397aa796f2307ceedb6505b39297856f4aeb5e70938e36ee24a0ac7d9868306f6b53910623b7dc89a6672ad738576ed5d88831dd338321c8902bc2061f65e94d452fdfa0dc665cefb92308e52301bd4627006b363d06b775a395914d8c863e95a00d6893f3376134c429f56478145e4456f7a12d65bb2b8965d728cb2ddbb708f7125c237095a92195d92fa727a372f3545ae701f3808fee802c8967a76e8a940e55fb2d810bfb47ada156f0eda1829b159cf05c7f36cf3847d7b21de84c3dc0fe658347f79396a01139a508b60022db1c0e5aeef47e445e66f783e62c96597bdb16f209c08a9132c7573136170ee3ebf24261265a89fb4f10333375e20b33ab7403464f5249461c6853c5fddb9f58af816892910393a7077b799fdc3489720998feea86 +SIG: 6b7ef27bcfbf2b714985033764fccff555e3f5bc44610d6c8c62117cb3831a07f4a8bddb0eaed1d46b0289b15de1aa4dcc17d71be96a09e66ba4dc4627c78705 + +PRIV: 1ced574529b9b416977e92eb39448a8717cac2934a243a5c44fb44b73ccc16da85e167d5f062fee82014f3c8b1beaed8eefb2c22d8649c424b86b21b11eb8bda +PUB: 85e167d5f062fee82014f3c8b1beaed8eefb2c22d8649c424b86b21b11eb8bda +MESSAGE: 1b3b953cce6d15303c61ca707609f70e7250f6c0deba56a8ce522b5986689651cdb848b842b2229661b8eeabfb8570749ed6c2b10a8fbf515053b5ea7d7a9228349e4646f9505e198029fec9ce0f38e4e0ca73625842d64caf8ced070a6e29c743586aa3db6d82993ac71fd38b783162d8fe04ffd0fa5cbc381d0e219c91937df6c973912fc02fda5377312468274c4bee6dca7f79c8b544861ed5babcf5c50e1473491be01708ac7c9ff58f1e40f855497ce9d7cc47b9410f2edd00f6496740243b8d03b2f5fa742b9c630867f77ac42f2b62c14e5ebddc7b647a05fff43670745f2851eff4909f5d27d57ae87f61e965ee60fdf97724c59267f2610b7ad5de919856d64d7c212659ce8656149b6a6d29d8f92b312be50b6e2a431d36ae022b00a6fe360e3af65432899c43be0427e36d21cfec81f21aa53b33db5ed2c37da8f96ac3e7dc67a1de37546cf7de1008c7e1adbe0f34fa7eb2434d94e6a13f4cf86a98d497622f +SIG: e0303aefe08a77738dcc657afbb9b835ed279613a53c73fdc5ddbfb350e5cff4d6c9bb43dc07c95bf4e23b64c40f8804c7169952e3c8d59a7197241bfed0740f + +PRIV: f0790d93e2d3b84f61ef4c807147aba410e415e72b71b0d61d01026fed99da3defdf649fb033cf328e0b287796f8a25e9c6e2e871b33c2c21a4028a8a25a4b28 +PUB: efdf649fb033cf328e0b287796f8a25e9c6e2e871b33c2c21a4028a8a25a4b28 +MESSAGE: 7973e9f32d74805992eb65da0d637335e50eff0ce68ea2d1f3a02de704492b9cfbe7e7ba96fdb42bb821a513d73fc60402e92c855deaed73ffeaf70952029062c833e14ec1b14f144e2207f6a0e727e5a7e3cbab27d5972970f69518a15b093e740cc0ce11bf5248f0826b8a98bde8bf2c7082c97aff158d08371118c89021cc3974ae8f76d86673c3f824b62c79c4b41f40eaa8943738f03300f68cbe175468eb235a9ff0e6537f8714e97e8f08ca444e41191063b5fabd156e85dcf66606b81dad4a95065584b3e0658c20a706eaf4a0777da4d2e0cd2a0fca60109c2b4403db3f03cd4781c1fbb0272202bcb11687808c50cb98f64b7f3fd3d43333bb5a061b9e377090abb1e0a885cb26b73c163e63ff6451ff2f4ec8249c7e152bd03973a1e964e2b5b235281a938399a112a24529e383a560dc50bb1b622ad74ef35658dcb10ffe022568ac3ffae5b465a8ed7643e8561b352ee9944a35d882c712b187788a0abae5a22f +SIG: 08773a6a78762cbb1e25fcbb29139941bdf16f4e09a1fa08fc701f32f933edd74c0ae983c12a0a5b020b6bcf44bb719dde8ed0781a8298265640e1608c98b301 + +PRIV: 4cb9df7ce6fae9d62ba09e8eb70e4c969bdeafcb5ec7d7024326e6603b0621bf018069dd0eb44055a35cd8c77c37ca9fb1ad2417271385e134b2f4e81f52033c +PUB: 018069dd0eb44055a35cd8c77c37ca9fb1ad2417271385e134b2f4e81f52033c +MESSAGE: 14627d6ea0e7895460759476dc74c42800ceef994327518151490d9df23067914e44788a12768ccb25471b9c3ba9d14fb436dcba38429b3a0456877763c49175d0e082683e07a9058f3685c6279307b2303d1221b9c29793d8a4877f6df51587384dadf751c5f7bfbd207d519622c37b51ceeee2c20d8269f8cb88d3fe43d6d434d5bbd0e203c1532d97ba552147227496c87f67b50bb76193add0144df1c176657585408362ca2ed04ad62acf1c25e341dfd1498d85b4b1349a8b0b9b02c43523c55853419bfed37d5a2cdf17dfbf1a3bd7759d6ae180f9d27dcd9a8933e29a7c0a30771eea7c2e0fa242925d2336dce585629057d844323964f6d3d11ff0b3f829a3be8c9f0468a6823d8e70ab5a2da21e15fa8b041a29812222e9c30b2bd9a12d1fdee6f87876e8ce81009637a8bb2236129a47ca74289ee4aad429ffe29f47430241ca8cc3848b7200fd6e1470651a9a0a6f72c9033e831df051408a6260f65cbaf6e012b18e +SIG: e33c07836c537d6bfbd0f4592d6e35b163499ba78dc7ffcec565d04f9a7db781943e29e6ce76763e9baddf57437fd9c6b03239a6e6850e4502a356c2e12c3705 + +PRIV: a136e009d53e5ef59d0946bc175663a86bc0fcd29eadd95cfc9d266037b1e4fb9c1806ec0454f58314eb8397d64287dee386640d8491aba364607688841715a0 +PUB: 9c1806ec0454f58314eb8397d64287dee386640d8491aba364607688841715a0 +MESSAGE: a49d1c3d49e13c2eda56868a8824aa9f8d2bf72f21955ebafd07b3bdc8e924de20936cee513d8a64a47173a3bd659eff1accff8244b26aae1a0c27fa891bf4d85e8fb1b76a6cab1e7f74c89ee07bb40d714326f09b3fd40632fad208ea816f9072028c14b5b54ecc1c5b7fc809e7e0786e2f11495e76017eb62aa4563f3d00ee84348d9838cd17649f6929a6d206f60e6fc82e0c3464b27e0e6abd22f4469bdfd4cb54f77e329b80f71bf42129ec13c9dfe192adfaa42ee3ddeeda385816fbad5f411938c63b560f4ecd94534be7d98725cd94c99ce492f0f069ba0ec08f877a7812ef27ae19d7a77be63f66bcf8d6cf3a1a61fc9cfef104c7462a21ca7f03afb5bb1ac8c75124b554e8d044b810d95ff8c9dd09a34484d8c4b6c95f95c3c22823f52ce844293724d5259191f1ba0929e2acdbb8b9a7a8adf0c52e78acdfdf057b0985881afbed4dbebdebbdae0a2b63bd4e90f96afdcbbd78f506309f9bdb650013cb73faed73904e +SIG: bc094ba91c115dee15d753361a75f3f03d6af45c92157e95dbe8d32194b6c5ce72b9dc66f73df12dca0b639f3e791d478616a1f8d7359a42c8eae0dda16b1606 + +PRIV: ff0f1c57dd884fbeea6e2917282b79ba67f8a6851267b9f4636dafda33bd2b5bfef6378ad12a7c252fa6eb742b05064b41530ff019dc680ab544c027ea2836e7 +PUB: fef6378ad12a7c252fa6eb742b05064b41530ff019dc680ab544c027ea2836e7 +MESSAGE: 522a5e5eff5b5e98fad6878a9d72df6eb318622610a1e1a48183f5590ecef5a6df671b28be91c88cdf7ae2881147fe6c37c28b43f64cf981c455c59e765ce94e1b6491631deaeef6d1da9ebca88643c77f83eae2cfdd2d97f604fe45081d1be5c4ae2d875996b8b6fecd707d3fa219a93ba0488e55247b405e330cfb97d31a1361c9b2084bdb13fb0c058925db8c3c649c9a3e937b533cc6310fa3b16126fb3cc9bb2b35c5c8300015488a30fadca3c8871fa70dfdc7055bf8e631f20c9b2528311e324a7c4edd5462079f3441c9ecf55fa999e731372344fdc0d413e417aaa001a1b2d3d9bc000fec1b02bd7a88a812d9d8a66f9464764c070c93041eefb17ce74eff6d4aff75f0cbf6a789a9ecde74abe33130fca0da853aa7c3313ada3f0ae2f595c6796a93685e729dd18a669d6381825ab3f36a391e7525b2a807a52fa5ec2a030a8cf3b77337ac41fceb580e845eed655a48b547238c2e8137c92f8c27e585caad3106eee3814a +SIG: d5008486726cce330a29dd7e4d7474d735798201afd1206feb869a112e5b43523c06976761be3cf9b2716378273c94f93572a7d2b8982634e0755c632b449008 + +PRIV: 0bc6af64de5709d3dbc28f7ef6d3fe28b6de529f08f5857ccb910695de454f56fb491fc900237bdc7e9a119f27150cd911935cd3628749ff40ef41f3955bc8ac +PUB: fb491fc900237bdc7e9a119f27150cd911935cd3628749ff40ef41f3955bc8ac +MESSAGE: ac7886e4f4172a22c95e8eea37437b375d72accedcee6cc6e816763301a2d8ef4d6f31a2c1d635818b7026a395ce0dafd71c5180893af76b7ea056c972d680eca01dcbdbae6b26f1c5f33fc988b824fbbe00cacc316469a3bae07aa7c8885af7f65f42e75cef94dbb9aab4825143c85070e7716b7612f64ef0b0166011d23eb5654aa098b02d8d71e57c8fa17bff2fe97dc8193177eadc09fb192d80aa92afa98720d4614817ff3c39d3acce18906fa3de09618931d0d7a60c4429cbfa20cf165c947929ac293ae6c06e7e8f25f1264291e3e1c98f5d93e6ecc2389bc60dbbf4a621b132c552a99c95d26d8d1af61138b570a0de4b497ebe8051c7273a98e6e7876d0b327503af3cb2cc4091ce1925cb2f2957f4ec56ee90f8a09dd57d6e83067a356a4cfe65b1b7a4465da2ab133b0efb5e7d4dbb811bcbbde712afbf0f7dd3f326222284b8c74eac7ad6257fa8c632b7da2559a6266e91e0ef90dbb0aa968f75376b693fcaa5da342221 +SIG: dbc7134d1cd6b0813b53352714b6df939498e91cf37c324337d9c088a1b998347d26185b430900412929e4f63e910379fc42e355a4e98f6fee27dafad1957206 + +PRIV: 2f5e83bd5b412e71ae3e9084cd369efcc79bf6037c4b174dfd6a11fb0f5da218a22a6da29a5ef6240c49d8896e3a0f1a4281a266c77d383ee6f9d25ffacbb872 +PUB: a22a6da29a5ef6240c49d8896e3a0f1a4281a266c77d383ee6f9d25ffacbb872 +MESSAGE: b766273f060ef3b2ae3340454a391b426bc2e97264f8674553eb00dd6ecfdd59b611d8d662929fec710d0e462020e12cdbf9c1ec8858e85671acf8b7b14424ce92079d7d801e2ad9acac036bc8d2dfaa72aa839bff30c0aa7e414a882c00b645ff9d31bcf5a54382def4d0142efa4f06e823257ff132ee968cdc6738c53f53b84c8df76e9f78dd5056cf3d4d5a80a8f84e3edec48520f2cb4583e708539355ef7aa86fb5a0e87a94dcf14f30a2cca568f139d9ce59eaf459a5c5916cc8f20b26aaf6c7c029379aedb05a07fe585ccac60307c1f58ca9f859157d06d06baa394aace79d51b8cb38cfa2598141e245624e5ab9b9d68731173348905315bf1a5ad61d1e8adaeb810e4e8a86d7c13537b0be860ab2ed35b73399b8808aa91d750f77943f8a8b7e89fdb50728aa3dbbd8a41a6e00756f438c9b9e9d55872df5a9068add8a972b7e43edad9ced2237ca1367be4b7cdb66a54ea12eef129471158610eaf28f99f7f686557dcdf644ea +SIG: 9f80922bc8db32d0cc43f9936affebe7b2bc35a5d82277cd187b5d50dc7fc4c4832fffa34e9543806b485c04548e7c75429425e14d55d91fc1052efd8667430b + +PRIV: 722a2da50e42c11a61c9afac7be1a2fed2267d650f8f7d8e5bc706b807c1b91dfd0b964562f823721e649c3fedb432a76f91e0aead7c61d35f95ed7726d78589 +PUB: fd0b964562f823721e649c3fedb432a76f91e0aead7c61d35f95ed7726d78589 +MESSAGE: 173e8bb885e1f9081404acac999041d2ecfcb73f945e0db36e631d7cd1ab999eb717f34bf07874bf3d34e2530eb6085f4a9f88ae1b0f7d80f221456a8e9a8890b91a50192deaaacc0a1a615a87841e2c5a9e057957af6e48e78cc86198e32e7aa24dcf6cffa329bc72606d65b11682c8ba736cce22a05785df1146331e41609cf9ca711cf464958297138b58a9073f3bbf06ad8a85d135de66652104d88b49d27ad41e59bcc44c7fab68f53f0502e293ffcabaaf755927dfdffbfde3b35c080b5de4c8b785f4da64ef357bc0d1466a6a96560c3c4f3e3c0b563a003f5f95f237171bce1a001771a04ede7cdd9b8ca770fd36ef90e9fe0000a8d7685fd153cc7282de95920a8f8f0898d00bf0c6c933fe5bb9653ff146c4e2acd1a2e0c23c1244844dacf8652716302c2032f9c114679ed26b3ee3ab4a7b18bc4e3071f0977db57cd0ac68c0727a09b4f125fb64af2850b26c8a484263334e2da902d744737044e79ab1cf5b2f93a022b63d40cd +SIG: c2695a57172aaa31bd0890f231ca8eeec0287a87172669a899ad0891cea4c47579b50420e791cdec8c182c8a0e8dde21b2480b0cfd8111e28e5603347a352d04 + +PRIV: 5fe9c3960ed5bd374cc94d42357e6a24dc7e3060788f726365defacf13cd12da0ce7b155c8b20ebdaacdc2aa23627e34b1f9ace980650a2530c7607d04814eb4 +PUB: 0ce7b155c8b20ebdaacdc2aa23627e34b1f9ace980650a2530c7607d04814eb4 +MESSAGE: c9490d83d9c3a9370f06c91af001685a02fe49b5ca667733fff189eee853ec1667a6c1b6c787e9244812d2d532866ab74dfc870d6f14033b6bcd39852a3900f8f08cd95a74cb8cbe02b8b8b51e993a06adfebd7fc9854ae5d29f4df9642871d0c5e470d903cfbcbd5adb3275628f28a80bf8c0f0376687dae673bf7a8547e80d4a9855ae2572fc2b205dc8a198016ddc9b50995f5b39f368f540504a551803d6dd5f874828e5541ded052894d9e2dc5e6aa351087e790c0dd5d9c4decb217e4db81c98a184b264e6daeac0f11e074cae2bfc899f54b419c65dcc22664a915fbfffac35cee0f286eb7b144933db933e16c4bcb650d537722489de236373fd8d65fc86118b6def37ca4608bc6ce927b65436ffda7f02bfbf88b045ae7d2c2b45a0b30c8f2a04df953221088c555fe9a5df260982a3d64df194ee952fa9a98c31b96493db6180d13d67c36716f95f8c0bd7a039ad990667ca34a83ac1a18c37dd7c7736aa6b9b6fc2b1ac0ce119ef77 +SIG: 379f9c54c413af0d192e9bc736b29da9d521e7ba7841d309f9bcc1e742ec4308fe9f7ba51e0b22aed487cb4aa3913b9bebfb3aacd38f4039f9bbbebe1ad80002 + +PRIV: ec2fa541ac14b414149c3825eaa7001b795aa1957d4040dda92573904afa7ee471b363b2408404d7beecdef1e1f511bb6084658b532f7ea63d4e3f5f01c61d31 +PUB: 71b363b2408404d7beecdef1e1f511bb6084658b532f7ea63d4e3f5f01c61d31 +MESSAGE: 2749fc7c4a729e0e0ad71b5b74eb9f9c534ebd02ffc9df4374d813bdd1ae4eb87f1350d5fdc563934515771763e6c33b50e64e0cd114573031d2186b6eca4fc802cddc7cc51d92a61345a17f6ac38cc74d84707a5156be9202dee3444652e79bae7f0d31bd17567961f65dd01a8e4bee38331938ce4b2b550691b99a4bc3c072d186df4b3344a5c8fbfbb9fd2f355f6107e410c3d0c798b68d3fb9c6f7ab5fe27e70871e86767698fe35b77ead4e435a9402cc9ed6a2657b059be0a21003c048bbf5e0ebd93cbb2e71e923cf5c728d1758cd817ad74b454a887126d653b95a7f25e5293b768c9fc5a9c35a2372e3741bc90fd66301427b10824bb4b1e9110bfba84c21a40eb8fed4497e91dc3ffd0438c514c0a8cb4cac6ad0256bf11d5aa7a9c7c00b669b015b0bf81425a21413e2ffb6edc0bd78e385c44fd74558e511c2c25fee1fec18d3990b8690300fa711e93d9854668f0187065e76e7113ae763c30ddd86720b5546a6c3c6f1c43bc67b14 +SIG: 84d18d56f964e3776759bba92c510c2b6d574555c3cddade212da90374554991e7d77e278d63e34693e1958078cc3685f8c41c1f5342e351899638ef61211401 + +PRIV: 6132692a5ef27bf476b1e991e6c431a8c764f1aebd470282db3321bb7cb09c207a2d166184f9e5f73bea454486b041ceb5fc2314a7bd59cb718e79f0ec989d84 +PUB: 7a2d166184f9e5f73bea454486b041ceb5fc2314a7bd59cb718e79f0ec989d84 +MESSAGE: a9c0861665d8c2de06f9301da70afb27b3024b744c6b38b24259294c97b1d1cb4f0dcf7575a8ed454e2f0980f50313a77363415183fe9677a9eb1e06cb6d34a467cb7b0758d6f55c564b5ba15603e202b18856d89e72a23ab07d8853ff77da7aff1caebd7959f2c710ef31f5078a9f2cdae92641a1cc5f74d0c143ec42afbaa5f378a9e10d5bf74587fa5f49c156233247dafd3929acde888dc684337e40cdc5932e7eb73ffcc90b85c0ad460416691aefbd7efd07b657c350946a0e366b37a6c8089aba5c5fe3bbca064afbe9d47fbc83914af1cb43c2b2efa98e0a43be32ba823202001def36817251b65f9b0506cef6683642a46ed612f8ca81ee97bb04d317b517343ade2b77126d1f02a87b7604c8653b6748cf5488fa6d43df809faa19e69292d38c5d397dd8e20c7af7c5334ec977f5010a0f7cb5b89479ca06db4d12627f067d6c42186a6b1f8742f36ae709ba720e3cd898116666d81b190b9b9d2a72202cb690a03f3310429a71dc048cde +SIG: eb677f3347e1a1ea929efdf62bf9105a6c8f4993033b4f6d03cb0dbf9c742b270704e383ab7c0676bdb1ad0ce9b16673083c9602ec10ae1dd98e8748b336440b + +PRIV: f219b2101164aa9723bde3a7346f68a35061c01f9782072580ba32df903ba891f66b920d5aa1a6085495a1480539beba01ffe60e6a6388d1b2e8eda23355810e +PUB: f66b920d5aa1a6085495a1480539beba01ffe60e6a6388d1b2e8eda23355810e +MESSAGE: 015577d3e4a0ec1ab25930106343ff35ab4f1e0a8a2d844aadbb70e5fc5348ccb679c2295c51d702aaae7f6273ce70297b26cb7a253a3db94332e86a15b4a64491232791f7a8b082ee2834af30400e804647a532e9c454d2a0a7320130ab6d4d860073a34667ac25b7e5e2747ba9f5c94594fb68377ae260369c40713b4e32f23195bf91d3d7f1a2719bf408aad8d8a347b112e84b118817cb06513344021763035272a7db728a0ccdaa949c61715d0764140b3e8c01d20ff1593c7f2d55c4e82a1c0cb1ea58442bf80a741bca91f58ab0581b498ee9fe3c92ca654148ef75313543d1aff382befe1a93b02190ce0102175158e2071d02bacad8dbe9fb940fcb610c105ad52c80feb1ec4e524f4c0ec7983e9ce696fa4fcf4bf0514b8f0432b17d5448fc426fea2b01ac7b26c2aed769927534da22576fc1bba726e9d65be01b59f60a648ace2fc3e5e275789fa637cbbd84be3d6ac24457a6292cd656c7b569a52ffea7916b8d04b4f4a75be7ac95142f +SIG: 17f0127ca3bafa5f4ee959cd60f772be87a0034961517e39a0a1d0f4b9e26db1336e60c82b352c4cbacdbbd11771c3774f8cc5a1a795d6e4f4ebd51def36770b + +PRIV: fc180035aec0f5ede7bda93bf77ade7a81ed06de07ee2e3aa8576be81608610a4f215e948cae243ee3143b80282ad792c780d2a6b75060ca1d290ca1a8e3151f +PUB: 4f215e948cae243ee3143b80282ad792c780d2a6b75060ca1d290ca1a8e3151f +MESSAGE: b5e8b01625664b222339e0f05f93a990ba48b56ae65439a17520932df011721e284dbe36f98631c066510098a68d7b692a3863e99d58db76ca5667c8043cb10bd7abbaf506529fbb23a5166be038affdb9a234c4f4fcf43bddd6b8d2ce772dd653ed115c095e232b269dd4888d2368cb1c66be29dd383fca67f66765b296564e37555f0c0e484504c591f006ea8533a12583ad2e48318ff6f324ecaf804b1bae04aa896743e67ef61ca383d58e42acfc6410de30776e3ba262373b9e1441943955101a4e768231ad9c6529eff6118dde5df02f94b8d6df2d99f27863b517243a579e7aaff311ea3a0282e47ca876fabc2280fce7adc984dd0b30885b1650f1471dfcb0522d49fec7d042f32a93bc368f076006ea01ec1c7412bf66f62dc88de2c0b74701a5614e855e9fa728fb1f1171385f96afbde70dea02e9aa94dc21848c26302b50ae91f9693a1864e4e095ae03cdc22ad28a0eb7db596779246712fab5f5da327efec3e79612de0a6ccaa536759b8e +SIG: a43a71c3a19c35660dae6f31a254b8c0ea3593fc8fca74d13640012b9e9473d4afe070db01e7fb399bf4ca6070e062180011285a67dd6858b761e46c6bd32004 + +PRIV: a2836a65427912122d25dcdfc99d7046fe9b53d5c1bb23617f11890e94ca93ed8c12bda214c8abb2286acffbf8112425040aab9f4d8bb7870b98da0159e882f1 +PUB: 8c12bda214c8abb2286acffbf8112425040aab9f4d8bb7870b98da0159e882f1 +MESSAGE: 813d6061c56eae0ff53041c0244aa5e29e13ec0f3fb428d4beb8a99e04bca8c41bddb0db945f487efe38f2fc14a628fafa2462f860e4e34250eb4e93f139ab1b74a2614519e41ee2403be427930ab8bc82ec89ceafb60905bd4ddbbd13bdb19654314fc92373140b962e2258e038d71b9ec66b84ef8319e03551cb707e747f6c40ad476fbefdce71f3a7b67a1af1869bc6440686e7e0855e4f369d1d88b8099fba54714678627bba1aff41e7707bc97eddf890b0c08dce3e9800d24c6f61092ce28d481b5dea5c096c55d72f8946009131fb968e2bc8a054d825adab76740dcf0d758c8bf54ff38659e71b32bfe2e615aaabb0f5293085649cf60b9847bc62011ce3878af628984a5840a4ad5dae3702db367da0f8a165fed0517eb5c442b0145330241b97eeca733ba6688b9c129a61cd1236aff0e27bcf98c28b0fbeea55a3d7c7193d644b2749f986bd46af8938e8faaeafbd9cec3612ab005bd7c3eeafe9a31279ca6102560666ba16136ff1452f850adb +SIG: e6a9a6b436559a4320c45c0c2c4a2aedecb90d416d52c82680ac7330d062aebef3e9ac9f2c5ffa455c9be113013a2b282e5600fd306435ada83b1e48ba2a3605 + +PRIV: f051af426d0c3282fafc8bf912ade1c24211a95ad200e1eef549320e1cb1a252fa87955e0ea13dde49d83dc22e63a2bdf1076725c2cc7f93c76511f28e7944f2 +PUB: fa87955e0ea13dde49d83dc22e63a2bdf1076725c2cc7f93c76511f28e7944f2 +MESSAGE: b48d9f84762b3bcc66e96d76a616fa8fe8e01695251f47cfc1b7b17d60dc9f90d576ef64ee7d388504e2c9079638165a889696471c989a876f8f13b63b58d531fea4dd1229fc631668a047bfae2da281feae1b6de3ebe280abe0a82ee00fbfdc22ce2d10e06a0492ff1404dfc094c40b203bf55721dd787ed4e91d5517aaf58d3bdd35d44a65ae6ba75619b339b650518cefcc17493de27a3b5d41788f87edbde72610f181bf06e208e0eb7cdfe881d91a2d6cc77aa19c0fcf330fedb44675d800eb8cff9505d8887544a503cbe373c4847b19e8f3995726efd6649858595c57ccaf0cbc9eb25de83ba046bc9f1838ac7b8953dd81b81ac0f68d0e9338cb55402552afb6bc16949351b926d151a82efc695e8d7da0dd55099366789718ccbf36030bd2c3c109399be26cdb8b9e2a155f3b2cb1bfa71ab69a23625a4ac118fe91cb2c19788cf52a71d730d576b421d96982a51a2991daec440cda7e6cc3282b8312714278b819bfe2387eb96aa91d40173034f428 +SIG: b8f713578a64466719aceb432fce302a87cf066bf3e102a350616921a840964bfc7e685d8fd17455ac3eb4861edcb8979d35e3a4bd82a078cd707721d733400e + +PRIV: a103e92672c65f81ea5da1fff1a4038788479e941d503a756f4a755201a57c1dee63a5b69641217acbaf3339da829ec071b9931e5987153514d30140837a7af4 +PUB: ee63a5b69641217acbaf3339da829ec071b9931e5987153514d30140837a7af4 +MESSAGE: b1984e9eec085d524c1eb3b95c89c84ae085be5dc65c326e19025e1210a1d50edbbba5d1370cf15d68d687eb113233e0fba50f9433c7d358773950c67931db8296bbcbecec888e87e71a2f7579fad2fa162b85fb97473c456b9a5ce2956676969c7bf4c45679085b62f2c224fc7f458794273f6d12c5f3e0d06951824d1cca3e2f904559ed28e2868b366d79d94dc98667b9b5924268f3e39b1291e5abe4a758f77019dacbb22bd8196e0a83a5677658836e96ca5635055a1e63d65d036a68d87ac2fd283fdda390319909c5cc7680368848873d597f298e0c6172308030ffd452bb1363617b316ed7cd949a165dc8abb53f991aef3f3e9502c5dfe4756b7c6bfdfe89f5e00febdd6afb0402818f11cf8d1d5864fe9da1b86e39aa935831506cf2400ea7ed75bd9533b23e202fe875d7d9638c89d11cb2d6e6021ae6bd27c7754810d35cd3a61494f27b16fc794e2cd2f0d3453ada933865db78c579571f8fc5c5c6be8eaffce6a852e5b3b1c524c49313d427abcb +SIG: 2aa2035c2ce5b5e6ae161e168f3ad0d6592bcf2c4a049d3ed342fceb56be9c7cb372027573ae0178e8878ebefca7b030327b8aad41857de58cb78e1a00cbac05 + +PRIV: d47c1b4b9e50cbb71fd07d096d91d87213d44b024373044761c4822f9d9df880f4e1cb86c8ca2cfee43e58594a8778436d3ea519704e00c1bbe48bbb1c9454f8 +PUB: f4e1cb86c8ca2cfee43e58594a8778436d3ea519704e00c1bbe48bbb1c9454f8 +MESSAGE: 88d7009d51de3d337eef0f215ea66ab830ec5a9e6823761c3b92ad93ea341db92ece67f4ef4ceb84194ae6926c3d014b2d59781f02e0b32f9a611222cb9a5850c6957cb8079ae64e0832a1f05e5d1a3c572f9d08f1437f76bb3b83b52967c3d48c3576848891c9658d4959eb80656d26cdba0810037c8a18318ff122f8aa8985c773cb317efa2f557f1c3896bcb162df5d87681bb787e7813aa2dea3b0c564d646a92861f444ca1407efbac3d12432cbb70a1d0eaffb11741d3718fedee2b83036189a6fc45a52f74fa487c18fd264a7945f6c9e44b011f5d86613f1939b19f4f4fdf53234057be3f005ad64eebf3c8ffb58cb40956c4336df01d4424b706a0e561d601708d12485e21bcb6d799d8d1d044b400064ec0944501406e70253947006cabbdb2dd6bd8cee4497653d9113a44d4de9b68d4c526fca0b9b0c18fe50fb917fdd9a914fb816108a73a6b3fff9e654e69c9cfe02b05c6c1b9d15c4e65cf31018b8100d784633ee1888eee3572aafa6f189ea22d0 +SIG: 627e7ca7e34ed6331d62b9541c1ea9a9292be7b0a65d805e266b5122272a82db7d765acc7e2a290d685804922f91ed04a3c382c03ff21a1768f584413c4e5f00 + +PRIV: fc0c32c5eb6c71ea08dc2b300cbcef18fdde3ea20f68f21733237b4ddaab900e47c37d8a080857eb8777a6c0a9a5c927303faf5c320953b5de48e462e12d0062 +PUB: 47c37d8a080857eb8777a6c0a9a5c927303faf5c320953b5de48e462e12d0062 +MESSAGE: a7b1e2db6bdd96b3d51475603537a76b42b04d7ebd24fe515a887658e4a352e22109335639a59e2534811f4753b70209d0e4698e9d926088826c14689681ea00fa3a2fcaa0047ced3ef287e6172502b215e56497614d86b4cb26bcd77a2e172509360ee58893d01c0d0fb4d4abfe4dbd8d2a2f54190fa2f731c1ceac6829c3ddc9bfb2ffd70c57ba0c2b22d2326fbfe7390db8809f73547ff47b86c36f2bf7454e678c4f1c0fa870bd0e30bbf3278ec8d0c5e9b64aff0af64babc19b70f4cf9a41cb8f95d3cde24f456ba3571c8f021d38e591dec05cb5d1ca7b48f9da4bd734b069a9fd106500c1f408ab7fe8e4a6e6f3ed64da0ed24b01e33df8475f95fa9ed71d04dd30b3cd823755a3401bf5afae10ee7e18ec6fe637c3793fd434b48d7145130447e00299101052558b506554ec9c399f62941c3f414cbc352caa345b930adecfaddac91ee53d1451a65e06201026325de07c931f69bba868a7c87ee23c604ec6794332917dfe2c5b69669b659706917f71eddf96 +SIG: 6887c6e2b98a82af5ee3dfa7ca2cb25d9c10745620a82956acba85cb57c8ec24279fa42f092359a1b6bbeafba050f14b6288209e6ef7bc1e0a2b872c1138f305 + +PRIV: a8d73d639a23cc6a967ef31bcabb5d063e53e1eab8fcc7cab9bc3a17fde9c2f88daa9f4c8b1a44691bf44521f2f7ca45dc7fc61f6a4ce6f98faa41c2a74977d1 +PUB: 8daa9f4c8b1a44691bf44521f2f7ca45dc7fc61f6a4ce6f98faa41c2a74977d1 +MESSAGE: fd1fac3d53313b11acd29f5a83ac11896dab2530fa47865b2295c0d99dd67c36ed8e5fa549150c794c5549efb5c1d69114d5d607b23285b7212afaab57846a54ae67b9e880e07b6586607cecf6d4eed516a3a75511fe367d88eb871e6d71b7d6aa1367a01421b1088fc2d75e44954b73625c52da8a3a183c60be9da6050f59a453caa53520593671728d431877bfaac913a765fb6a56b75290b2a8aaac34afb9217ba1b0d5850ba0fdabf80969def0feee794ceb60614e3368e63ef20e4c32d341ec9b0328ea9fe139207ed7a626ff08943b415233db7cfcc845c9b63121d4ed52ec3748ab6a1f36b2103c7dc7e9303acea4ba8af7a3e07184fb491e891ede84f0dc41cadc3973028e879acd2031afc29a16092868e2c7f539fc1b792edab195a25ab9830661346b39ef53915de4af52c421eaf172e9da76a08c283a52df907f705d7e8599c5baae0c2af380c1bb46f93484a03f28374324b278992b50b7afa02552cafa503f034f8d866e9b720271dd68ccb685a85fffd1 +SIG: c4dcef1a2453939b364b340250c3129431431d5ba3f47670ab07ce680c69bf28b678627c76a6360fc40dc109aa7dea371b825e46134f624572182acf3957e70f + +PRIV: 79c7dcb7d59a8df6b2b2ba0413059d89680995c20e916da01b8f067dc60cdeb4298743c73918bd556b28f8d4824a09b814752a7aeae7ee04875c53f4d6b108d9 +PUB: 298743c73918bd556b28f8d4824a09b814752a7aeae7ee04875c53f4d6b108d9 +MESSAGE: 5fe202f5b33b7788810d2508a13b3114d69b8596e6eacda05a04a2eb597fa3279c208b5a5b65daacb699f144e1d660e78e139b578331abec5c3c35334454f03e832c8d6e2984df5d450ecb5d33582a78808a9c78f26ebcd1244ef52e3fa6dca115c1f0cb56e38eae0e5b39f5fd863dffd0b2fb5b958f2d739db312fc667a17b031c4c9f8c5a2ad577984cc4146c437580efd2152173fe0d5782cc2ae9831a8d9a04177256018ff7631e0b0d8a99cb28f008b320421e27a74c31359188663456d85e098c1ebd281701097b6ae5a871e5ccc02058a501416cb91c12cef5be6f1914370e563f1a1b2aa41f4b8ee84cd32a1d509e529787d14a445438d807ecd620e2fa26de0da6426864784d4a28f54103e609283b99ee9b2b699c980bbb7882c3ea68ddc90802ac232f2c8e84291987bf3c5240921b59cfa214969317673d0be7f34b1ca0e15ea73c7175401ce550be106b49e62f8db68695e740e0f3a3556a19f3c8e6b91ac1cc23e863fcd0f0d9eb7047aa631e0d2eb9bcc6b +SIG: 7b7cbe44c771e4371bae13b0722babcc1064155732962f407cba2acd35381d42210bece822f4681121fd4dab745a1f3077922fba1a78045b712902baccac660e + +PRIV: b9ced0412593fefed95e94ac965e5b23ff9d4b0e797db02bf497994d3b793e60c1629a723189959337f5535201e5d395ba0a03ea8c17660d0f8b6f6e6404bb12 +PUB: c1629a723189959337f5535201e5d395ba0a03ea8c17660d0f8b6f6e6404bb12 +MESSAGE: 555bb39c1899d57cabe428064c2d925f5fc4cf7059b95fb89a8e9e3a7e426c6c922d9e4d76984ea2383cabb4f2befd89c1f20eaa8a00dbe787cfa70ae2ae6aa90331cbbe580fa5a02184ed05e6c8e89d576af28aeeaf7c4e2500f358a00971a0a75920e854849bf332142975404f598c32e96982043d992bcd1a4fe819bb5634ad03467afc4ce05073f88ba1ba4ae8653a04665cf3f71690fe13343885bc5ebc0e5e62d882f43b7c68900ac9438bf4a81ce90169ec129ee63e2c675a1a5a67e27cc798c48cc23f51078f463b3b7cc14e3bcfd2e9b82c75240934cbdc50c4308f282f193122995606f40135100a291c55afdf8934eb8b61d81421674124dec3b88f9a73110a9e616f5b826b9d343f3ac0e9d7bdf4fd8b648b40f0098b3897a3a1cd65a64570059b8bc5c6743883074c88623c1f5a88c58969e21c692aca236833d3470b3eb09815e1138e9d0650c390eee977422193b00918be8a97cc6199b451b05b5730d1d13358cf74610678f7ac7f7895cc2efc456e03873b +SIG: f1b797ded8a6942b12626848340fb719fcddafd98f33e2992d357bfdd35933c7ac561e5b2f939464338c5666854ca885c4d046eb2c54e48a1b5ed266ad34de05 + +PRIV: 81da168f02d46bb87cda845da43f8a6cba2c016878d6f49c6f061a60f155a04aaff86e98093ca4c71b1b804c5fe451cfdf868250dea30345fa4b89bb09b6a53b +PUB: aff86e98093ca4c71b1b804c5fe451cfdf868250dea30345fa4b89bb09b6a53b +MESSAGE: 6bc6726a34a64aae76ab08c92b179e54ff5d2e65eb2c6c659ae8703cc245cbc2cf45a12b22c468ae61fd9a6627ad0626c9b1e5af412cb483eaee1db11b29f0a510c13e38020e09ae0eee762537a3e9d1a0c7b033d097fdc1f4f82629a9de9ef38da1cf96a940357d5f2e0e7e8dbc29db728a1e6aad876e5e053113d06420272b87cf0c40dfe03a544de96c7aea13ba0029b57b48d99dcc6a650492d78c4cdd1b28e1a115a7e3e7a7cb21333d4ff80858dfb67782c16354b8716596560d7d8e389eb15a052a0bf5d16eb54fb3e4973ad4984e72a187f5347d5b262c32b1647e42b6a53837096cc78c2a05ce1c6e12493a03f1a667584cb97f4fcd57ee944c65b7eed25f7ae0f3f6cede173fdfacf5af1db143730d18096664914ba4cfc6966f392022781c66a9417ca2680b51f63e4fba424ecfdbc6a2f01787d0e7484f8a8ab390aeaa6d1f7ed325d82feaa1692a4984fae43da87329b045da8f0a4f56b695aa935de152ce0385153720979a2b7006d405fcb0fba09e23b85fd19b +SIG: 4aaca947e3f22cc8b8588ee030ace8f6b5f5711c2974f20cc18c3b655b07a5bc1366b59a1708032d12cae01ab794f8cbcc1a330874a75035db1d69422d2fc00c + +PRIV: af2e60da0f29bb1614fc3f193cc353331986b73f3f9a0aec9421b9473d6a4b6ac8bfe2835822199c6127b806fabeef0cb9ff59f3c81ff0cb89c556f55106af6a +PUB: c8bfe2835822199c6127b806fabeef0cb9ff59f3c81ff0cb89c556f55106af6a +MESSAGE: 7dbb77b88bda94f344416a06b096566c6e8b393931a8243a6cab75c361fde7dc536aec40cded83296a89e8c3bef7d787cfc49401a7b9183f138d5000619ff073c05e2f841d6008358f10a2da7dcfac3d4d70c20d2ec34c7b6d5cd1a734d6bbb11c5fd8d2bce32ac810ef82b4188aa8ea3cfc3032233dc0e2600e9db6e18bc22b10044a31c15baceaf5554de89d2a3466807f244414d080ff2963956c6e83c8e144ed0066088b476ddcb564403447d9159f9089aba2b4d5575c4d8ae66fc8690e7349ed40832e6369c024563ec493bfcc0fc9ac787ac841397fe133167283d80c42f006a99d39e82979da3fa9334bd9ede0d14b41b7466bcebbe8171bc804a645d3723274a1b92bf82fd993358744de92441903d436fd47f23d40052a3829367f202f0553b5e49b76c5e03fa6ce7c3cf5eeb21de967bec4dd355925384ebf96697e823762bac4d43a767c241a4cef724a970d00ff3a8ab3b83eed840075c74e90f306e330013260962161e9d0910de183622ce9a6b8d5144280550fc7 +SIG: 50f9f941a8da9f6240f76d2fa3b06dd6b2292ed32d1c05218097d34d8a19dfe553f76ae3c6b4a2ed20852128461540decf418f52d38e64037eec7771bd1afe00 + +PRIV: 605f90b53d8e4a3b48b97d745439f2a0807d83b8502e8e2979f03e8d376ac9feaa3fae4cfa6f6bfd14ba0afa36dcb1a2656f36541ad6b3e67f1794b06360a62f +PUB: aa3fae4cfa6f6bfd14ba0afa36dcb1a2656f36541ad6b3e67f1794b06360a62f +MESSAGE: 3bcdcac292ac9519024aaecee2b3e999ff5d3445e9f1eb60940f06b91275b6c5db2722ed4d82fe89605226530f3e6b0737b308cde8956184944f388a80042f6cba274c0f7d1192a0a96b0da6e2d6a61b76518fbee555773a414590a928b4cd545fccf58172f35857120eb96e75c5c8ac9ae3add367d51d34ac403446360ec10f553ea9f14fb2b8b78cba18c3e506b2f04097063a43b2d36431cce02caf11c5a4db8c821752e52985d5af1bfbf4c61572e3fadae3ad424acd81662ea5837a1143b9669391d7b9cfe230cffb3a7bb03f6591c25a4f01c0d2d4aca3e74db1997d3739c851f0327db919ff6e77f6c8a20fdd3e1594e92d01901ab9aef194fc893e70d78c8ae0f480001a515d4f9923ae6278e8927237d05db23e984c92a683882f57b1f1882a74a193ab6912ff241b9ffa662a0d47f29205f084dbde845baaeb5dd36ae6439a437642fa763b57e8dbe84e55813f0151e97e5b9de768b234b8db15c496d4bfcfa1388788972bb50ce030bc6e0ccf4fa7d00d343782f6ba8de0 +SIG: dd0212e63288cbe14a4569b4d891da3c7f92727c5e7f9a801cf9d6827085e7095b669d7d45f882ca5f0745dccd24d87a57181320191e5b7a47c3f7f2dccbd707 + +PRIV: 9e2c3d189838f4dd52ef0832886874c5ca493983ddadc07cbc570af2ee9d6209f68d3b81e73557ee1f08bd2d3f46a4718256a0f3cd8d2e03eb8fe882aab65c69 +PUB: f68d3b81e73557ee1f08bd2d3f46a4718256a0f3cd8d2e03eb8fe882aab65c69 +MESSAGE: 19485f5238ba82eadf5eff14ca75cd42e5d56fea69d5718cfb5b1d40d760899b450e66884558f3f25b7c3de9afc4738d7ac09da5dd4689bbfac07836f5e0be432b1ddcf1b1a075bc9815d0debc865d90bd5a0c5f5604d9b46ace816c57694ecc3d40d8f84df0ede2bc4d577775a027f725de0816f563fa88f88e077720ebb6ac02574604819824db7474d4d0b22cd1bc05768e0fb867ca1c1a7b90b34ab7a41afc66957266ac0c915934aaf31c0cf6927a4f03f23285e6f24afd5813849bb08c203ac2d0336dcbf80d77f6cf7120edfbcdf181db107ec8e00f32449c1d3f5c049a92694b4ea2c6ebe5e2b0f64b5ae50ad3374d246b3270057e724a27cf263b633ab65ecb7f5c266b8007618b10ac9ac83db0febc04fd863d9661ab6e58494766f71b9a867c5a7a4555f667c1af2e54588f162a41ce756407cc4161d607b6e0682980934caa1bef036f7330d9eef01ecc553583fee5994e533a46ca916f60f8b961ae01d20f7abf0df6141b604de733c636b42018cd5f1d1ef4f84cee40fc +SIG: 38a31b6b465084738262a26c065fe5d9e2886bf9dd35cde05df9bad0cc7db401c750aa19e66090bce25a3c721201e60502c8c10454346648af065eab0ee7d80f + +PRIV: 31010d1d67eb616348e84792b92d5dc128553cb52f6368159fe7b816cd0e7c37266543d96787ca901fcff06e6e434491ae0970880a5a187d535edb19db5cabeb +PUB: 266543d96787ca901fcff06e6e434491ae0970880a5a187d535edb19db5cabeb +MESSAGE: 39f89a5e7aa530b5463d498f8035b9909d55da527cdbd4de6d228379f089e608a9207a2c5b9c42051a60c8ca3fb97a1c06cd747d9d0739970ceb88ce526f971140ea2ec21f090ba075bf8975faa508b1cc10efa494dc172e6d3d3f3f75dc8e0e96f05c0cccb2f96e911cfa7a2c82c9845018bb1f9d75f82e3dfe1139347b2ac058b014ac93760c90f5567ab5c4eba04b49fb09ddadd305be511dfe05c96ebc86fd67b5d0ab57d85f4fe5e2f0fa9d88a68f0f6b6bc8bb944eb3c0b17557e55d5ea187d922a42813e69057c9b6a7f75e49921b7079e58f8a63719ee3e1ad10cf0e8a70c4f1540218b70494bd029ee02ff9727a7d85d377919ec4051479b70f7cd6767723fe42c1c7899c2b7c1f702dd6b4d13b672d488f34a0e969db79cc2cb2524a948a8de4c5b623ecd90d6e82d97033c125637d1cd8c84803d8fbc012846ffe484f6c02149258f9462fa1e99c307dd0062fe0b6f11eee40c2629ef7c0f6a5107259ea5b9ffb6f29f12c32f7b5228cabc986ab66450af9dcc3da09d0e0b9a4 +SIG: 7b1eb677c3e5e6a8b4ba69fcb7f6b1870e42a8d58958a35c674e2db82107481c4c7b37f0f689d39d9f51e181b17b1108c15a3e27b29df3a4315dcc4faf122205 + +PRIV: 8ff2398cd51f51d4c2c57869a2218b8486822031f400729f4ac4d5909c48bafea5a88704b68677be3d16c3dc0052cfee6e2b30e08609059d4cba52c6d96061fb +PUB: a5a88704b68677be3d16c3dc0052cfee6e2b30e08609059d4cba52c6d96061fb +MESSAGE: 993953e47a341188bc592942e1557af29546e4e9368e2f1a5ee9806e2baf66b6190191fc5d2b7e47de37ff054fb2bbb1f031684ada5d607adda3d65433122fa904e0456faa84109bbc517f8ad39660876382adcfed0f7620cf1164622eacd91eb37a8596462ebe9ebe26bdc1e32cc34ad46fb1cea420e73c31215408e6d35425f44a829b132f631a3f6dd4b873a000667e19eb22fffd5903aaa7d4c8fdf21953c3c6178f5f8cb2aa6bff92894ead835888df060a3c9043026e0e2cef275497e7d105df3b644a98f26bf00105c99413ee0af8851954d65ceb8d79ad3071b8bb87f0b19743d2556ffd9819830b6eebf7ecc7e045661f43570ce9fdbbe2d252406fa90d04236f222c429ec16b1287224ada1a532161ae8b481bcab8d47afb3ed0445b3060fd6759179856f4085c1e585fd7c1409799af693cf427bd1d3dc10b5ae3447a8d2a18dc3a12a6860b22175dd5eb53a0950432e2d7aefece8af0ade3d8567743de43690f2d253723c5d7e48bd30d2937593701cecde9154b7665cb611d7d +SIG: 417a647829c92898e520ff5311daa0a139cd8fffcb25a18e6d9b50cb52cbc35424c39ebbb5d5ac6a6d63f1f53c4df212f7025a8aaef8e36493c874c3ce341a0e + +PRIV: ef816c8f5ec34ef41f68831d90cd29e52de8973782d003ee4edada2ada2691d647f9b363a88a45053a05bb72160852bfe8f7dfefc2f37283de346752caf092cc +PUB: 47f9b363a88a45053a05bb72160852bfe8f7dfefc2f37283de346752caf092cc +MESSAGE: 9593c35cdec535bebb6965da68eab0b646bffcfbd04883bc4cef90d5d01f018c63c9b0ddfb3cef5e786284d5218caaaf060e9288952f16301ed8a4c1bcee256356a0c8bda359fbaa2782b10c86d18e20f7a0ec99b27a0b4dbefc0a262a3bf68fe81444dcae5f693eb0f16e6ee03f8fcbf3a3398146d20ec4d2657761fd0320fee7ea703c49a6a543bc9bba911e7925038710e8c36552d476d6027f58b2c52ba51ad65ea4f039c78f96b889102bb4bdd69b68e9c3d45b5176a2d82b0b95dc321016370dae30c3936515db0464c41774301c74e42d89b8bf4b9c19ed554b12febac0f60ddb3219ccc5603531dbf2eb5f293425d72ccefa0c7f144aba89347b296be87ff18994b4a0c70c930f059303b5dd4c8fe1e6bbc3cd68c6c0d84246dc6e6140a2abd1780b13f1594a6019d1778b7cbb3a3e3a34bfae7297f0b3edc376941c32352a4be314b84a9d8d6d7f1f38a0ad3798020aa2a331a402be9c704484744a730cbdedcb904b6fde708fbd14bfdc29efd461d1d0b5825de0bc79422b69a2722f +SIG: 65c5d10ea7bfdbb38d55364a9968f82b548224dff3363b2ddcf585163dea27dc63b0563eb1a8dfbee951d3c9b33fcd6bbf0921c3abb21786b229069bd9ca000a + +PRIV: 45eb0c4dfafa2a7690ef579c095456ceedcd32f0b6144d0c380f87fb744a0b1ffc85632c98384b5f9682aed9cd664cf1f48e588be2d568e5c734494df4c712b8 +PUB: fc85632c98384b5f9682aed9cd664cf1f48e588be2d568e5c734494df4c712b8 +MESSAGE: 6f66d847405a03d7bd6f8d2897dbdf04e76d7df2d9470a4996b7dd6db88500f8f4f83e960e219a2486e24545add13614550414d827c41a9b08318daf01b15214c64a4266cbf8a5717ada3e62c26729073e16ddbd66f2d520e1e09935de05e4db11c396d477010aec66aafb762e69238d0b9e76b452454bf9e451e76ac79e6990d41b932bc32917093783c91bc9cf0bbe3b514070a1e692ff34fd06b66ea11f39e10af933ee96d8e9b677cb03737e7964eeaa725f121207f9c1b26a96c616df7cb7caef47bda901368ff2ea586e422e65bf21a691bdd2c13e67fff58cfbfed81782049dafa0f727df88623f2f7e8f262daf939542a187b8720a9b6b2b09890e54876b28a43874abbe3bfa981f8138b772c5d51736885f86acac2215a0b010dfc2c6b150845d4f8296252586a3e115f303c3d8a582e20fd2d43f6c446e5d00280ec179823b7fb4c1b0feb94eb4ef1707f5184e3b52461a7562d1f307cb751cdbbf6eae49ffae91862358e74e9548822b8a049fec6bf4c7a99cabbe09206577b657e31f +SIG: 55851de8e1092f78944f6c6dd95bf07e2dbc8df7f57ad576829b978e3af58a7a8e94ed4dccbc0182467edf0bad4bae7ca84aa9a0c17c61a9e0ddff1d7525d704 + +PRIV: 709d2e199006f5369a7a0bdd34e74dc784be33880ea3c5dd10ed5c94451e797206f989202ba2cbc9c150be611262aca00c45f012f89fbaf89f8ceccba0b1934a +PUB: 06f989202ba2cbc9c150be611262aca00c45f012f89fbaf89f8ceccba0b1934a +MESSAGE: 62f003140fa09e0387d187a0ff96c4563df9f4e28c2282c0183ac3eede1312354921f780fca5361d3068d29949630b7530cd5914ace0468d014b6f53d839b82e38817dbf2d8392c3ce3424eab86a24d804c7acb1ce7acfe0a1cda4393924283105da4a7741196e027550047f85b7a0a01d454124efc0e299f0ef9ad14350543053482261528baa56e65999ac802c00a336267c635106b26403c19f391d53bd82861d6d48a4380b3043aa91d649536881204eccb0de20d43e5a3755b7f600916eccae42a0c9053b462d9417a13d67d778264a896e8eaf90baf66d29e5438a716781123a89fa9b8beef91d965af2f4a1a5bd5d2e2aaf46d5c94b7709cdd38d05feee4bfb76a359077c16bc4be9116e69001271cda565bc19bf47d4f986bd9c0d184cd8a3520ca1bdb4b505aaf7cb4ec9f94789779d30714e79116dd5019d59b28b17dad96f4e2155ad9c61274addc6b638109504e9ed19f4eda5377762648c4098224e3391043e4c2ad591654c9e7f974efdf0b0504b6fa5f646cecf44cd372412372505 +SIG: 629bf97b0c78ee6a9c8759fbea28224e27abbb6cbe4dea5bb797e6e0fe80c913f953e3a9b623352d13acf4ce6250fb029a1e198d72bd5e7402e60e9e48ca3501 + +PRIV: 5151617421aadc9c95a442b45e7ff6de06a2c733b85bd789fbad414ee3c91add14941d559761b30ab0a86d47e0f7d1896b33784527c80af41cb84810cbff9dbf +PUB: 14941d559761b30ab0a86d47e0f7d1896b33784527c80af41cb84810cbff9dbf +MESSAGE: 216e9d40bcdc3b2650188d121c9f8ef29e914facd022fe01b90ed11225f2eb93538e5fcee5ab8045e9199aa76a16bdd0616805660e247fecd7e22821b69b1f8e8a58ac3fb85691d75d5957a1daf53ff9ee6476d7c4bc541e6ad38e3a34ea90fc52a48b9399f92d17c9bb0d7fc3104c55d0efb4ea5b831ff9490b3f79f4d9d699594b741566f2b50a8fc78cc403fa40f5abb6638a32f449a8b3ef029c402f46931ad2bd3e8e683108714c989ae21689e9c444b9f55b81119bb5035bcf73e97ce43a2218c7bc3e430d1e814f34dee057265d3194b9f43875d8381f525f78576e64ce692584faa30fb743a12d1b77614d2e10a6b856b52be27cdb630ba1f0d3a6f8ea9844542e584ea0a2777527d0c52aca949aacda45ad83d16d5c83d663adb79cad6f3e39e990fe282a14c353aa2379d7f06adab74cea021b8983a57f1d0cf703292eb05ece89c53f3a1265610e0c1ea8ddd444d1ffd6bc3d03f0a6e4d0df5c5b8dc1f95d9f5558b118afe6bea0f6c2931363f03ab34e757d49364174f658efbbf38dc177 +SIG: fae4773b334460c77bf01ec6366c4fe61c0cab57d8a4b03909c619e11ee3461c13fa21576f63870e423dd04181e4a7013a7524f246fe33853c674162a7815104 + +PRIV: 38bed445556de74482bf5fec0506f9af330b151e50d4774dfe8591d7b7e0276b4c0f9c49a42f4047bfe6885551c5e4b856cf771a67af3f89dbf602f9db9220f3 +PUB: 4c0f9c49a42f4047bfe6885551c5e4b856cf771a67af3f89dbf602f9db9220f3 +MESSAGE: 0ff0031df0beeff3710c6b763f9b8ec81719bfa1528ce46519adf3d3412d93fb188fd497d5d17091c0f0345960dd0eb0c09fc4005173665d4d97f95c13828bc76b3492b87a4b64253c8b5fa47aa75fa3b86d5abeea8de5959a602289136f60a69b309e773b2255cde19ed2a2e199c33db11c16ade08a319750b851d92c692924fc9859be523431cbe78ec092db1129210ebbeaa7c2a2c000eeb105ca0301a48f3e45fdfb15b275cbab83ca5c99d737a585320e9e3b317179bd86467fa9694fcdb2ac6ad36ed7144843dbc34e423d35afd7d8972a1c43c199a191abd6ceba4936d395c995a3eb13cb057f88a9dc9490fe98845ee5d26a89fb642a2a516dc3056c54d3637213363a8628a42a395d942b954a89e8ef7a744d8ae5adac88c616efaa90e2077205a60baffede5c87bb14dead306229495f698f3e490616966b1636387d0d86183f945b24a9dcfccf4d36722cd12ebb6bd8e78325752afa2b1abd13c4bdbcadd170869136826242acfb721de5ff27ba8aa0c018b225ed3404803ce9fa2d508d8944 +SIG: f702d0d463282fc7fd5f8f9029b89c626cafd83450c3bb9dd8f6589f0c4b4b71f649ea212e5e33487c59c168ea3ad83150f1fcdfe8c53eba65adc2023c25830f + +PRIV: 055460b32dd04d7f4b2311a89807e073fd556565a4771857d882794130a2fe5d260f8fed4bba30b9e12ad8523fbb6f57f0a7a882550061f1da46fbd8ea442221 +PUB: 260f8fed4bba30b9e12ad8523fbb6f57f0a7a882550061f1da46fbd8ea442221 +MESSAGE: 7407f96ee3e79c69d36ce1f64e4f188655ea68b947e7e2be97b05ebc6d4439e950276ef3f0e6a03dd48b24f66929b49c1580eb468807e1e7a25eb9b94da340c53f984f8b81603efb61047bf3f14b686d9798003d2f68589a79ebfad54409c71c90ff67c11fbd76cc72c2d145f458e42f88b75d250eadcafe66bf37ffc837b62ff006685b7f85a9d875fc078c82e61fe35d1922527a551dab62f9e477499146bad912203e664c417c3679c02d872abac0032f8cc77f77bfe54d3326fdee9276a48ea4eb251350406882d08c830e7649fe6854558a7513ab2d8d2ac3e5ced8a808d2aee454779edabd1aa63bb19f718f470bdc8451cd9b294941e3497063b1e39b6ca184562fe838cbfeee922de24ddfcf9882c5e615b11bf904817fbd647139db80b4e8feb37f11e1852d7e876db9cb63c94d7ee34192f7200b5bc77a0311ae43b806ebd4c2896c53f58f7ebc1625cb20d7107ef9db0da28788523de991ef6c5866b18d8de83a954d3281e06dbf27c4f2382e08cd0e0f6ebae3f961b77fce5a95a9b0621b756f +SIG: 23f4f1627fbabd7891d7d8489631c7231d22de71864e262ab4da84ea8a13a60feac4dcfb1812f1200444b775f121d7266d755ce9b6a9ad796559c0a26b516d02 + +PRIV: e9f6d31b936942c526e0f9ec4f5a7ac25fa789e0c434bcd9199d720c743c84c432126d26e28231c5b585b13f43a01c6fe542946b07d3a91e57d281523f5cb45c +PUB: 32126d26e28231c5b585b13f43a01c6fe542946b07d3a91e57d281523f5cb45c +MESSAGE: e88133f3d17642d5c22779a85316ba0df34c792b4efee49ed7dd93ca3322ef47c72e5b2e4595c77800434b60719adf54e4c1a34c89fa1e27ee8d35a0921f9755ac4a77a6c1684ea0f5c8ee5f759ce59bfe8315800a67aa6c64ddfaac92eabe6c2c613779784b3affafcc620f2a6dc5cb8d8dc7d74aa4d79494678494e5e6394c433c14809ff40c9a592d0d694a81103b44531e1f48bc13965d15af8bf3340488f8cd58f09ae1a6616bf85ac9de7e0c6696aa2f1bec15e17a44da4a84edb4ec6d77247788ba0de3ae12a155cbedc0da2f568eef0b75a877ea5b0c2c0d4bf2c61d468a46faadfaece35fc263a9be9987f4f7f78f05c707784378c7b8f7daf9ac3a122aad39a1677966da9ef286c9e062c4f439ad0bddea26e54b2f7388e238b2a64928450d34564c5a447e7afbbedd1085f1f24c11ae084322d1a32cf8aa473941f00d56b1618213cab3900aa606463d9f800e926f9f42d4b082d8c5ec3a4a025b45f9aadc8bcbd17091b3da49e9453dc55e89b5b5fe6b31f5eddad10b6601572568d8e205d3251a +SIG: 7e3b1c4c716c808e90b974458915f3b2239c42077119fe270788fae520578bd7da6488044132e1bef23e3b23c34d9c1862744f28fcaecda6cac0fd72b93b6a0f + +PRIV: 6bf4caaabb96854a38a572f4ce6c7838f7e750118c73f2723582618e2307f83808126373d056f00e54b8d43d77c35f5f919833e90d8aafd6c8246d27917ad091 +PUB: 08126373d056f00e54b8d43d77c35f5f919833e90d8aafd6c8246d27917ad091 +MESSAGE: 4776e9d60085481fa537bf295bdabd8b1cf632a8cd40bce6bd325c129f977000e88468ebf2dc158ac0f207212db00fb60b8ec8bae229372e9a6b01530a7ed1bc9d389ec8913f59030d5b54af56ae1ccc28f37cc96a8e53204e92a677766adfaada99b0281f867f61ac9ff7d972ee3ed427d72faae75d4aec01b5ffc37061b6f0f7e5714c4cf30d5b731b0746065f19e4c8922dde642f80fe24a3c8dcb2e5f1c266e2af6c37decf55a2baa54f0d5cf0839370c3e0b4e77a4f36bbb3162014933a4a4ebcae8c60961ac6dcf134f30828d31402ae74e7e8513c9d2ad8ee46b7a9d53a1f87ebfce04f461bded1749b6fc4c4f25793525692d7a0e426c84e06082cc3e6abb51368370cbb106c7a0897f66d92c9739cff9f2706d6a2980ecea3ac4945f0f47e656bd9637777e853d2a839104327dc049ebc34f049d6c2f80eca99db7b418424acef752260d2d427949323997cd9617edf50d441d0088b1d47912e35cf542315265829f383f45860d3b45e735bb2f8586dcf58db4f2acfb4a68853a96eed7b89769d365613 +SIG: d2113f80d6cf928486a250a679d6e74b35ea9d26061fa94d769e1a8fbfa0a734227f55537e4ebff59336db141cf5d6d482a0711f1e9fc72ff70956a11b4fb909 + +PRIV: 5d9585736ab209b0abe8bf74aca4eea4f6d1650b532550a223e044580f8e20dee77729edfd2144b2b12078765417fa21f1594f09b269e9b6706802b4f3bdfe85 +PUB: e77729edfd2144b2b12078765417fa21f1594f09b269e9b6706802b4f3bdfe85 +MESSAGE: 08693591e6c58a5ead9c85fe8ec58508f81a3467636c2d34fcc1f466e5c6dafdc37c35cbee35589c6997e2b15448132744e5a1e131bb49bf5c2563f87ead3efe01e88cbf24cc1769c78cdfc167e378215b15859c7a28ece70e188fa330267d3fc57b4ace6c1520ec67875067fd33be86f4a1967afb3eb164c797cf28d8072aa69d82afa38374f8e5797c4c28471b7d69f5b9c7b4acdbc19f3c5c5d400808a982a47837aed1b3841d69890eeb31494e10e3e513d12d0ca686c7ce651778092703fef0dcc0214077dfb361251bdea4364dd41b97bceb0fb1475a50e4708f47f7878c74401e9771cc3fceace89169981aa77250850090d181d8358ebba65e290acb0352bece8c579832a601551816d1c05621ccbbee0fbe39ea2f195393199e69c234c2fb1c37e474840860ce609161fcfce2869574be0d38f95e20f4f8725247b9627b46e834905101ac12b934cbf87cb2d190d2f51490a82c4e810eddb81f956a9f36bda497bca506a49ee9cd47fda5b7f2b884a3648cadd12ab61898ada46ecc970f81dc9f876845db +SIG: e7b08e1d5809fdd8529443d65ada5dd655ea55b5415a011393be7071676486d358e8d2a460ebe075b0e701b24c9e3ab5f2b033592d4de3b7f37fd541f6920909 + +PRIV: 60b142f165114143ca30a604fef51c686436aa1b9afdb266b3e398ccb3c4d855eaf6c5a76ca99bf7306498888c3b7a1feae98bf8988d7f2e1547f8f53a4528aa +PUB: eaf6c5a76ca99bf7306498888c3b7a1feae98bf8988d7f2e1547f8f53a4528aa +MESSAGE: 1815dee1173b78264720d35b7cc2454a000a65fff214e2473e20bc83f3ecde9c04c1e0696ce6e55519dd2a75ce0464bf601adc381e793ecb9f8ce7ab87b6ca2a3e410f639069451978d14873d3390fab8623969713c3dfcd58d86d124073761ee09a652a48767f9646cb726ac454ac9a1bc5faed3026b703982bc2b1e0758210e1d62519230eb2b2f4a486bc55168560c4363df5ff5adfda11ac7ef51b18196c94337c07aef117990f770c0f1e8c0f88eb6ffc40e8ed7c3a80a632db1e7f63b63096e2ac49e57792b31143e2f4faabceae66b27471681c36fc1139007f9b548cdc6e3b8fbbdaba7a8adb843431238bb461ba24f6e09f62c72d6377b4048cb0134c25a5411a20bfcfc13e48d80e36bfb0da7e0185d33f1928636e15dee0e5df8992a16572b13ea8f7cf85cae32d529f66e8f6d2fb2ad0bbfe7199169b2567ba00c781b20a48e1d70df9fa3119cd7e5bbe58884b0b51218940fa815f85625fa203471cee8084780eb0b9356f9f3d4f6df740301d707ef1ffb3519e3f90b8064b98e70f375d071426881718 +SIG: a621f084ea1a36ef812a9755c9afbb53dadaae6b3a53fa8344ca40d3612a268a35fed0fd398ab75bcd639c547937c94155ab1a7a3467dd4bfddfacab1655e908 + +PRIV: 734ba47033c6140232dd4a7a14f1a7743eefe9070bad9662491630cc9d28c1f32fa5df3026d60742e2aff6b57842c7126846c8a7bbe9266efa7b3f2398c357ea +PUB: 2fa5df3026d60742e2aff6b57842c7126846c8a7bbe9266efa7b3f2398c357ea +MESSAGE: 5d3c659810c3fea52a6df3861e5cdc5b703cc1cef48558c61d8c51d0edea5a1479cfe5063d82ded9ca681e5748887c40ecfb9e1a9a8b7f8509d10776461c3923399693a78189089178d5aabd15f8c846642be47d6d4caf13824edcefb809868fa72ddf035c4de8ef0a9c832264f66f012761ce6955bc3c416e93e29188025ebbb13a553258c1d7c499c9a4aeb10bb36f61d1bb4cec5ae55d175722b9a9696df881951e35200b9653cf6ed4b3d15de087a9d1c319fce8582156bebf3fc91e0e610ff7a15308fd1d2c6069fbbb2947d3110731d245ae2963014bd76dea42db125cecc493c8e9091a76646577729aed4966fce9699fe12e367d665df9e95a9193e1133e143af92f82b66ac7764e5033178690521809a7107d8ae9b88e0ed1f35b1719901b930ad0e1cbce7fb30267b1155204f605f525e49de2988ea7f74be8815177fd976a1bcc126d9c9c135c5b4276d38019c34aefb7a0220f7f5aeff380aed627b070c2c9e21533bb35c08e394c85ae25e6862942599c65dbae5977a584a88180e0c8c71e5a8409e04ef7 +SIG: 9bd074d1d0bd28001baf7d2d4e82435df08c4264d8cbb1c381183c2f01223f79f94923ca178cac75564e16c7f56079088f7ed885de4d509fbc78f438fba3f607 + +PRIV: 45e34d0ef4c196fa6d572b6b1774b5218f7c3291304c13500df7070d90e8039e13a7304dff423359177abafa5e6508d26769ca99cf8af45c383f3ff634406003 +PUB: 13a7304dff423359177abafa5e6508d26769ca99cf8af45c383f3ff634406003 +MESSAGE: 3d9ed5c64b75e135df2f5e85300d90f21b363935e2817556fc9311751ba7535477dec8356ec385efb82b414062f35bb6d3edeafde305f9900a25e9813c9ee0237d46409650cdcdb5dfa2301a8e2647f8d3819d86f7b7e3070d33440f82c4054b1ab5edebeb27f95b3c4c6fdd468f21600f03b3494da200bab9293c38d02fc44048e52ff5fd0f7217a04d4ce912a180d1628f368280b6892672e8ff98d4629ac28b60c02a301e6c6026c1b9e9ef21cf0392df225008d5a0e0284b282631ad1710f811615697066c98296519948a7cfed5aeeb454ee7a61cc271bd3d499be17df09d3a0e790ee6b9bd99e1b919bed4a063b8d1a34f1afd2e952b9dfefd770969c8b2fc37977abb0fee6317253a23ecc97578168973334c8f91763ab97f29c49baeee7b35f3ae7f5cd3a4a6e697ef255a3c2ec0c752a3396f69f663ca1fc2b332dfe6c0faf78afe9c68d99571e8e896c5093085e9863a27648a9e58f3a9a84cbbfe2b41ca3633dd5cf6e82cb77cecacad8d78b353f48db42d99c36bcad170ea9e98abb2788c33a3c706268f3631 +SIG: b42c1f925f4baccd129efb109db354aca31c6898f4f451294749a26a6da1677bd3a5c04119e35f47319f20cfdfc08bb4528b21009e00bd41ebc0f46863bed10b + +PRIV: 888ce2ecceda9ca2b948ac1443c2aedd7595aacf36edaf27255bde7a6991dcc0016e572b4f98417c6ee297abd784ea48226ff4fbf0050a5ade8806e7046d3ba3 +PUB: 016e572b4f98417c6ee297abd784ea48226ff4fbf0050a5ade8806e7046d3ba3 +MESSAGE: 5c801a8e664e7660760a25a5e1431a62159fc3f3aa713780ae7cbce23b8564782799bf2be4817ee2921965bab7e1d44833824c1628d42dcee3e46ae42b2816d0a432a1ab0bd21fcf30adb63d8dd76569544343d0035c760522ca68bea72c404edda1e9095ec90f3325681c6de0f4c12d1afbcba2c7871a1b1e1f19c35b0bed9ec2a87c043d36d819396bd5d099e1aa090391297c733f65a8c5d2120c67635316fab25b4d4847a45fc3f76f2e2426dbee4629975062fce14e2189dba27fb1ded2453f001debfaa899c11660612d2ce2ad2f762ea5dee7e71e58adcdcefa79e8e8b27fc4ccf89aabf176b5d34f82dd15d889f9f087dc9ae8a42a72f3b83583616e170637cd1adf38aa6551cbacca3602bdc7ae210c4a446b3af8db2720e549bbedb8bed215ae00f19da29d8fb0b642d27b2d88575f0ee84f3d129eb774d20f537a1c0fdcf717bdebcfe47f8331a341864346fa6a1c6bbfd178819e387a0d5499a68e81cc9f82ad39e31e4dfe71952d5ea5cc8052a3ceed1751f59dc7ecc9742fad144e18dda8d0582e74e39ca8c4 +SIG: 99d83f148a236ebbef1cad88cb3c7694f4986c9250e21c3603a0d941bff199cf77d6ce99efdb20533188d68ad133de033a1fb3468abb706d2b8b4fbac08dfe03 + +PRIV: 617390857dc10cdf82b5c94261f58ce2d44aa2f57d298f08a2d6c74d28147daf89e0c3e0a0f130d1916e0e3849b7286fa2e3ac4c17bd1f716ee5a72f0257fb8d +PUB: 89e0c3e0a0f130d1916e0e3849b7286fa2e3ac4c17bd1f716ee5a72f0257fb8d +MESSAGE: 1fd9e7453eaffd7c9b54055622dde170dd58b71cb945de75351d5fceb1f536bde25158f03786155f953dc207a1708f90d95b15aca0aee3097fdcaae85e4ab1c2cdb705c53e6c2ed21a994b304a75caf2ce4fc7d61f561e74e297397e2cde5cc69056940343aa81375d0af18d17d2f34c0a71dcf1de3c4fc488a14c5fa6b3337a3174b1da7958fb00bd5955148221427c60dba04117c80d2488656dbd5343de891287b50ef4df9825eda76b4977f3acd4ab6d3102fa56878306cd76561491bcfdaa1da567e677f7f03bae5dbf4426c3c4a6c3d082f9178b2efdd2bd49eee97ef4dcf3f0f51bbdeffe5ae6601e28019518f827f02e51f6679b8715978bec3e69d577156dd719959371baf034219fbbd17a2369a8541490f6a02013e33e74f4769be37aefa4defb6bfb3f351c2a261482c2fbec49f85f8445456e8f5a474030cd72d095ef6a622030e1e43a0c5debb034731d2f5e8e4ba3990f077d0c162649d1fa3ea4fe1e81d74aa849e21b059d966cbad4c493ca10bafe7a69243e3c0a6ebfd13d697906303392ba65d4fe06b6a5 +SIG: 63e90a6afbbbb0ee696bfb56efd679d68a9851a8947640a97f41f68edfeadd216ed8698e2e43c820c9044caa7adaab5b76762b681831a9f760476a8443c43c06 + +PRIV: 877d017436369ec2453fed46e977d6acc3a7be60d31395ad6e7ea9e07480e4c94e65422fed334a55e8b673893eba7c181dd724dda002817b0bae28acdc3f7fc0 +PUB: 4e65422fed334a55e8b673893eba7c181dd724dda002817b0bae28acdc3f7fc0 +MESSAGE: 4ed3f5bdbd41d0e3b0a8a7fc3752eea496d6141678cbfe06757f61e1a168d761b6da83052f7994950d24626f004fbe9b8c9562e0c955fb3b5c08fd2d3d258393a349030c8e156205b40483038be1959f1cba490a87fe13899e4f3752063b68fe3e1c5071f7db0002f01494b4a3ee2e07992bdd200db4316629ee8a95ca347f0b28d6402a6da8b53e6b32581c3691e11ae9b6e0f0494894e649a92d03eb49c4d6833fa1f54f8dcd91d06936a6e62d491e2cea46dd07d9f02d3254b850bc9749f258a61ad3b9cc24b03287331b85a24143aaf8fcccac5f18bfc72dec75c0233516aa6e4589c78c665a186ed902091df97b0d04e83a2d74d789891aea2cacf813fffb5efaf78dbcd7af54ef55c77b1c4c8ace9e9278adc23d76c779d64b3bbbd1fb33b09836ea64a71e4711e89e8da0f709213342176ae22c6e7852c3973b60d9f98889b442aa48d7bfdfdef64c36c586c4fb2ad2e27ebe479f6d722f069fd6106b0d08975d5f721547c3b9c52f9fc5f45bb45b5b632188e80626518a79056bdc4ee1d2be6c6542a21fadea92c6dfb776 +SIG: 7688f3f2401eacaf2dd88e170ff1c4d7e94822a77f6b550b569e82152bbbb434057e01230b05ce58ee1dee5226b5c7cdbe5a8ade3b9465f59aed74145d14330c + +PRIV: 4f0b3607d70b0f2698327ef4f1982c5b4b94be78f50c76f43bd642f1f0ede39b942b43089fd031cec0f99e5e550d65307fb6c3e793449fb390ff730fffd7c74b +PUB: 942b43089fd031cec0f99e5e550d65307fb6c3e793449fb390ff730fffd7c74b +MESSAGE: 9f700a1d2560f69d9bc105bc83bff539e4258c0248602013a959b978a19cc273280d90c0178089578b50518e06ad1eab790ffe710c63d78887a95569144f3e58a8837f93dd516fcddd22bc97a7f14411d424b2e8e9aa7c280119ad94ce92533fc7fea6c66248644ac3e1beef2553a6f61e91b9379b0fe0c68b40681455b311f40df0c97f53fc954242c375e7708d61bad9f51296247274fa01a7328fa5009d9995f501ae8683552b11a49d2638116723b1319450a90138d278cd9512b80ca5792ed16c683bef92ec87884c9f07f137dc47a13146e511065c2e1b4b80efde88ae12e29431beb7aee365c16d80506b99afa6a1406edb061766875832dba473e519dd7018f402eb1bb3014b7cee4f02e980b1b17127e7d25dfe0c168c5344f1c90044f827707dca03070e4c43cc460047ff62870f075f34591816e4d07ee302e7b2c2ca9255a35e8adec03530e86a13b1bdfa1498813098f9ba59f8187abcafe21ba09d7c4aaa1ad10a2f28334ab53996147c2459c01b6a10839e0301123d91a35ced7af89afbac7d9cf8ac9a38ceebef83 +SIG: f396a11f2f03c61439684f79001bd4f346a348dcf1d3beb2d3bfe33ea73a5ad4eb97506acfbffb784e77548189cd599f8ccf17355dde80e75024ef2a78d5fa03 + +PRIV: b8a0010c784d8d002a31da11d022d30188a4197a1d5f14ea4c0dab29a2e406688bdc63e50bede13c91a41e4b4b7857b9e553f484e3c1ec167dc04c281ea86622 +PUB: 8bdc63e50bede13c91a41e4b4b7857b9e553f484e3c1ec167dc04c281ea86622 +MESSAGE: 5c6ccb298be216808b811e56d972f456b69ad39594eee354701ca6b3e38d1f41a359e5512af98a3a0873265fe5191f4f2ecaf66bee75a3ac0b71a4ddf2a759ebdddbd88a6a1c6fd0fcf7d7cb92a84e3307b4a4f98c710abf4f553dee74f652d2ac64bc30f72bf4354ef7e806a19071a051bcfcfb27e37fddd41eceaec1758e94695c670ef4c5a5902178329db9585c65ef0fa3cd62449bb20b1f13aecfdd1c6cf78c51f568ce9fb85259aad05b38c6b485f6b86076928ddb4e2036f45e7b9c6a7ff24ae1776030e2576825019ab463ebf7103a33072033eacbb5b503f53266afb82f9b2454b8dc057d84f30d9d2cb7c3a31a7dbdfba5b8e49231c231396c47ca042c8e48a1a5e3ec9afe4020595390f9990dfb874e0825ae9ae5e752af63af6fd3e787e75e8d8dc4c66302277ac01b30a18a56cb82c8a7ebdc915b7153255a1fedc492e49660262bb249780d173e1fd20d18c4f6b0b69aa2eca024bf3c80d7d5962cc4a129a7943b27f33cc799a36045541275a2cdb92a40e485ba8b737a04b43d29c3e25f76cb3d93a6b94461f88f5696 +SIG: b3f6cf4c0e0f9074ff2c2c47e163202f1e9d6ee117cf757633e4abe74423aa70008ada1509ec1dc117c1c230e9b23786f3d0f29b73aa284536e9580106a8a70c + +PRIV: efc86cbe40363abfbb2a4b1fcce5fd6084da96e7e814de71aadf9a618f30362522f295cee727d28d2b9317153e7d9412da1065c1b16ae2a251dd1fb431c62b01 +PUB: 22f295cee727d28d2b9317153e7d9412da1065c1b16ae2a251dd1fb431c62b01 +MESSAGE: 9e4fa45dc026710f6bef4ed0f07c544b0bb0d88fa79e7177d8448bc209d71cfe9743c10af0c9937d72e1819e5b531d661c58c63141ce8662c8839e664db79e16c54d113abb02a75bdf11b3453d071825bc415741e99483546b8e1e6819de53017092e4ef871f1ca0d3508f937828a4667db11ffff9416eebb94bf9b84d654603094834a99ca70b90f562a86823624dfe9cb2f9e88c173f13464d4ce255f222db50dd63ab42465734e75295c064b64cc3f15e6237e37f33d615f7c243e4ba308960cfd4393402525500bb7902970b3931d48b35666a2d4d2ab08fa12af366a004346c9dd93d39fb1b7340f104e51fedbb533605b5ff39cf6d59513f12856dcfa198d793b0fc875cdea0741f1455746d8a19c3e9d928f0021b01c25131811e48c3c75c6f41422a8810c6c81f35b454eeae8cd17cf3f2e6f0bcd9f290984f496578623ab8e2738d2d10840eb91d101cb4a23722b72e3dd185440c3b9f44d46a393a34c187a20d610bb698c50531741efe96323512329800772a408065a7ef8e4e4105eb1f5bf6d3fd6b217fd836d89f53b96f45 +SIG: f8818310228ca76111524ce94bfcb0246ea63508cee9306592b2f77548edefcf76bd1454508ea715042cec169cea5115ab54235cb1097b10702aa38378028e0c + +PRIV: 33556c60de2f2c9a9303b99add378592060505f8e49861085a4b15f072a7ef28231ec8cd845859f69961275119dbe4f715e5ec5aa98bb8741675b3c2d0c89fee +PUB: 231ec8cd845859f69961275119dbe4f715e5ec5aa98bb8741675b3c2d0c89fee +MESSAGE: 96af540ea2b1923f5fd0aad321ac032070c2d65ba13d164e75c3469758fcf31bb31655cb3a721f9cb34be2c90c77eb65be37f606d32a917a4cb9a709ac0705229930ef6eb6fdb0fa3c0fd3a90ce171674ee3ed06354bafc3c7075467a57445b80385640447902be39262894b1f64fea58287dc322d19875972a7c8be91d31f021c70eb682fdf11a10f8f582a126e064794838c69fdf64f5b6e8ba59d48b4384f8e9fb5c087cc7738295cd32344ba3b697ee6b6a8b78ee7a9575c97972a4d1bb18486f9037a0f3c6f471a90f86498dbc0df5232c07e8c01b690bee75302992a7a36fb4437c25a8bf5e34cf7d5b55572c700a079848d381364f9946a91eb1603ff3de5ebdd523bd92564818e237a53e8f522deaa2c29b897e961586e100ed0fc0ad70d160934e694027e5c957920bc0546e901be39a84535597e1f280c222267abe97f41205d8171820dd2faafc0699419321a9160f69b99fd41180945b62d2dd105cc7bbe821d28605e098edfa8b2309aeb0534e756377f59937c67463fd87c8b92ab58119cf4ce6c665af572fbae1de4a2cc71 +SIG: e06a7a414457bbbef2bac3775ccad087dacb1fa4bf938894e8c929118e09e678dd19938bc88f43ed0f7d31cc6a0e602c4e4d1fee33d41e74a119fa2d1e4e340f + +PRIV: 7a5c74314e1183334a4b6226b9a82d70fc2a124e3f87db6a2283ee05b68e34e0beae7d3dd97c67f6273bfaa066131fed8ace7f535fe6464e65791c7e5398576c +PUB: beae7d3dd97c67f6273bfaa066131fed8ace7f535fe6464e65791c7e5398576c +MESSAGE: 98bac6724755912992adc2a48b5442376f2d927997a040fb98efe544eb0c8e1866b9616e298d3360316ed976bd946a411fdd3a6b625c0c1a37af0f41cf6569a7884ab8467491a987df3ea7a0b7ebc4692569a34ce3a2ea3503495b2c02d49d7d7db579d13a82cf0cf7a9547a6eaebe68e7267d45a60b8d4772455228cca4036e282e1a1216f34cef7ea68f938270bdb04293c885d005f9f7e638a8b4ead2626c0945174ff2a3e2d6e15a4c0338c09e1260f0928ca9d3499824f3fedc4785da49c5c34a56855e241facc6347a399ddcac4399a8b158198c151461a3b189e58ec1f7efcf2ab2031fb17b6f035ba1f092e9eee2e92c2d6cc2032287f854b41e70fc61c8d11a2e4f0708f02eebd02e8c7e8c7b38a57bfa1a745f3a86c23909f6f89ab16ce7e1813c1d20147f31b4cf2ad0b606fb17e5ac1ab51ef4a7d8093cee9a655f471dc5b146bd1b93e540a3d3d3e2de8105911c10d6ab5ff79c2d06027f7a54561f2071414bd330a8785442251c810e232f83c367f0be7799a93f5238f7f17b5be829fd89123c04833af8b77e5a4363047ceca7 +SIG: c2ab1f6f5114a84f218502582c567b37a8bdbcdf6340fa4622873be89106f0a90b4829505f72129df0ab3d8513268774a34df3ad21ce254b464488addd6c9b04 + +PRIV: da8006adc492ca5dc86c2959437a75deb6120ff787d2ecb9c20c30b52c26bc41ff113bf0aa58d546f2385d444ecb7888f8caba43a174a89fd6065f2b7dc17bf0 +PUB: ff113bf0aa58d546f2385d444ecb7888f8caba43a174a89fd6065f2b7dc17bf0 +MESSAGE: 3eb4324dbc0149d2e7d6df632bb0cbe9a9f6dfa83e227fc07bde1b577b3611fb921c9f8313f068e6295d4913a8196be530f6a01f57c09c028491444b784720e909ea1fb69c1c1dd6304400327b7731b33cc46deb046cdab6ad1b53f1749a0c65cb9a7e376ffa02230f536584aea243c639103adbba764321649d7e0126f82e0b4fd9dcb86c731cbcc517f2016841e916bcd5fde871dc098cd913dc546284d1b2165c63e88f32a2789a500856371b50d22fb8c87d1a3caedcdfd01ee5f870a53c284181d632ec66d48b6bdd5646ac39c9e75338a520212062bc3466ef5c58765570b905f63a93d07f8f1baac3526b016da799f3e9e03a4f7f81355e0f7a76f30a42b807322051b71c626a7a296d75b9d9d1a23bcb13c9ef48a912dc057325d3bcfb3f9fadaf0c249b102aeb854aa3631e34f69ad90c2ab2ed33bacc40b9ed1037fae67cdf799d5a9b43785961127d62f8e0bc1589fd1a06fca2aea7cfc012cbf7b5b207ddc4e677d8ae4aec100045ce36c00b74d1d28250791236dc5dcc1ed313c8c246172666f75217437c6034acd64198cd96df2a +SIG: 1f5375dcb3ad2baaff956d8554ecb424176be9a6eb9ea54e814e0a73df2a5d848ada26ba8e1805cd51c5e16950c1ff7d4d2764daa6f4c7502fb865cbe55aaf0b + +PRIV: a284e26b97e538839c808d45bde6f012a354454aef81caa8c55914624f2b7d665ae46e34695efaf463a4208fc4e35b81f2c63593238a56f2444b850f058c3c5c +PUB: 5ae46e34695efaf463a4208fc4e35b81f2c63593238a56f2444b850f058c3c5c +MESSAGE: 9ebfe910b50a5cb719d95b961e5905f00ec7943b55468ab5956692017645b366071f8fbb77eb49ec73ea7d64511405b90de22db98c3eae39c4039c7a133430e8010bdd39a00fd1a528b113dae149cfad3ae340da27dcc507782ecd8929237517afe7463eca2473c7acf6f7aa04efc9f266ae7b6d63bb8cc2a438b344827f0713d1f1736f0cbb65b99353f20355fa0230d4fa707328a8662654e83ad0530a10f9a69e17c099e1e2b5db18e5f6f1dceda5883e8cab79701a5e9089562ed153ad08c674f097c28e4d16633e092969a8f0bdac54527c0ee03bc200e5be612e3d1eabd87091101b4962afa07b310806992f373076d76a58185118137c9d26ee2cd4c618c18283dd19f0e7a089ee37305b6b9518a78d8098436ef62be7d699808acecf67939d61b3e02937cd8c5f1e746d4274334bc9c37fdcba234c166fd712893f3a040832ec5425e57d80f11ef9ca5fbcd6c147fbbf5e2fae746e0ddb605867e3bd050483c3cd1329abe57a60bf88898dc7e80ede0f4517de8fc807e888b621a00f663084ff94b99996628f3b11690a60f0918cb5c9a7ef +SIG: bf110e2e9cecbc31fa3e0c2438cd1f4321f92cd287005a48528addf76cad8d88bb22719ef91b139562a1511838682674faa9ff7e7ade6c9d573f845036d18905 + +PRIV: cc97a96301ceed0f922731b685bad8ad4f06207be340f5a44fd187f29903ec20eb563a7bce12db97f1891d0f610bebd55101a3125ca8dbb50b25a6b5050d3784 +PUB: eb563a7bce12db97f1891d0f610bebd55101a3125ca8dbb50b25a6b5050d3784 +MESSAGE: b9ea3b3df7187ea415a3c335e0834e10f440915b2ad41c71f255d6950a4e9120e4d494fd9e672ce53206fdc417d865897b47ac1054e1ca1068195232d4297435e44e1224e66a912d9d7d182946ff5a9f085bb8ba19c54d16b586a9b30461b6773b93950311e1619886f5a5b3f111aaad094bae31c48f1941080968bd0277bb6fa92eebf324b192df5cc969516c78c7b2d12159b4d1c8eb03160c4cd1907f62ed4b854c569ecc481c08e636f44ed7c390e58b5937d2906b2817bc3769dad9da1b0f79391b55942063055da0d6f249a3e452baddaa032998d7f73398ccd0151bfc92c5e2fdfa9b14855e6b0d3746dce248e219672987252ec747df2747fd3fbd8b714c882d707ee302a904950c34754f85350e1aa3f8ea6293cf01f717cefb6b83a22126df5c4f5698aafd06a2244ad7d01f34017ca0ece6f21040048aba6ca4aeb04325b9402bcd43ab130a105788ac3d7b7da01ea9426dd0ea1933a8189933a6c0c6cd648ea316a7469a5fdc6e7c934d9186586097b55dd51ac487bb80ed11d4df8d33626bbce95e4f13bd49922f00c920223f4cbf93cb +SIG: ffbdd3244181cdf6034f4a450fdd95dee4971a933f8be022bb0a4106aef39af3055b721881c9b54d1e99b9409096fbe6dc2c9966e3679964bd7ef4c808cabf01 + +PRIV: 679e3e34773abe4ae25cae7d07ccd0eb3b0ec0a35d570257d62570de58ea251618acffce253b27259579ed9924f479cae312167bcd876edba88b5d1d73c43dbe +PUB: 18acffce253b27259579ed9924f479cae312167bcd876edba88b5d1d73c43dbe +MESSAGE: fb2b648ebb16688244f78b2ee9a273599d56b6198900d438a9e99c191425c72bec4f235847e18e47f57c3cb396655f778921f908580e8e83c96c108b20dd416678021bca259b98518fabb2d3532e4851d9d52add2542c0cb3efa3857a17e512438bc0ec4762e2f9baba429c03e99bec4038e6b0ca42bff5b233b24c333b4caead2de374a87b2ab5d80d6e49e4456329d51ae973bc83d7862f3d315e514481b12854a9dfc09e7d14f0d022c0ba3022578eba8f874deba4aa8c833f2b132861d4d51e50fe9aa4b787bd2f051aac50c375390cbbcfba2002b80ad00cdc12980f8ba8bcb7064afc04d5c4682c1029b10a6d45fe6ecd704245faf598c4659597c5d68a192cc1cd4fa45e84b549e8e5e67daa879ae5a520a6b5550519876a562ac49c6db0aa76ec69bb64dd6b5e1a3af2e131e722e7cdd05be34b5fcc6259aa124ccf814cf5b500d176be28ebc40bb21f03e24ccc131e0f41daa1ca02e6b00c9c53fad1248614e940d4b237760ab7569a767b7515dd2d623e57a2841b7d2441cf43049e4698d2f9c9eae7b2910f6ad65edf9cb2bdbd9b29f606e0d +SIG: 1a51022628ccbb88eae9b21773c3f830b7b6e5bc36c9903ce70fbcf459d6a1ed8a1dceff5b19269ebf5a6fd3d8958860f554461f0e9fc0e29af9b1fb1744a80b + +PRIV: 9bfa60923a43ed0c24e2f12f5b86a0716329f93d4d8d3e06238002893278c19afb1c00687781b55b893d6b2f4f49cf5f73d2903c316d1eee75991d983a1868c0 +PUB: fb1c00687781b55b893d6b2f4f49cf5f73d2903c316d1eee75991d983a1868c0 +MESSAGE: a99028b0f4a3aa5e79abef6c0df4a783ef470f1a29ba51eba00f6214e840fe19e5b6dc6021ab599bb2ee3699576015d79a7939af823535b630e3938c723f6e0b9229d46bb3379acdba587c238567e3d89bc3bd3519b727fc694fff1118bf22c8bc8bc82c4df7f5ad38de05fe9f762999ecaa795f3ae630a9a316d26dce9f1568ffa3f22b0295214020b3d3f5337c149568192218132a90709279c01d23baefa669e1c4e42038173f1319c212da144f1c4ea4c52c005cbc0b5bc283e74483a0dca69279deb17ae5b29cfafa7d0063f4e1bc93537efd937e58a8aca737228f937ff2a741890e96c5725da11b45c413a9bbb4180a419987bbf046bfd346295d62f081c76daf2b0e1eb4f6712feebe6f0a92e358e7ddb85896507c340a01f68d1b0f085778b7c44b014aa6673e501796959a17a688db0959058488a7112572f23cf9cdb53b5eb4b45f5953ba0c0c690f86bd75e89a047bebaf847c1dfc345a4f3c7d3beec98b84b0219003e819f5c2adb45f8717903d1f5bd5d71914c56fcabc7a290f9c41699c95584d6a3a16340cb17baa1fc5e5467af7ac3221 +SIG: 55f202efb2a57be8b4e4fd894dcc11a4fc5f8276618ef5cd34a4495adb016a298e6480a35cfc53edb25ff1499fc532a33061cc01a250458aa5e4f7f16f51440d + +PRIV: 6e3af45e66e22890c3f3c934f523a4d69427976e6e52625f8bad558993963219e097364e76ff9f2e1d167f6b20c1bc5830085e7ec993c138f8b1b2175637e741 +PUB: e097364e76ff9f2e1d167f6b20c1bc5830085e7ec993c138f8b1b2175637e741 +MESSAGE: 5cfc2f4b559f8205b39102087617f4d86c7ce6cb251e5f89601dfc88ed28e8d7a670ec0087d2ea5d893021c7044da2899a22d776fe90170e51c203250690d37a294555e74af9234cbf1ad8f22cee8974828a0d09e9554b71ee3bcf880ab98325f706272194eb2e80c701d441b5f8668561b88849f827af703ab0954105fd3c54b3f6ec5493596d0e3bc67818048310c4a3e0c556bc80675f201f9bb9c6538a41d99aa40c886fc431467218d819c23e78498aed0613fa6f973e2211df9fb87f44116f3fe4c26d6cb2fa334c87f78c08ca8c9b9041d83a1230677e0af788598a42e44cfdf6964a4ee80e38402ba67c73a581e552baa2282425cb2ca17ca92edfbf98299102fba761b9b71a5452141bb9c18dd95febc2a782de9ceec08bd2ee3f7f0c1bd8946dba99cf9ea086abafd37c9ca60213f0de17c61ff9c391c9818ed5cd8571778b7dcc13224962386fb8ca14f861e99f3b18edac8a5f130f7bfcd45d045d0ff34c81572a512363d6530f93813e5fb10e9cb8338a7f93800491006f4463e89f0ed4530e5f12df674f598904780ad0812b1e3521fcd0f83e +SIG: 26ba562e8a4065708207c25e239b780aee38794cf983a37acbb9d557a65ceed3c0da47d17f3e8b8f4eeb1b65a2c182ea6f29623b63bb0f1c72592683b126b901 + +PRIV: 5f1f271844d9ed5a6a6f209a21408daea470f6fd53ba6479d7407105b7de4d656085d7fb5a9b2ed806c1fd30a2afde760961f7a36b48f4875246e615a2bd9928 +PUB: 6085d7fb5a9b2ed806c1fd30a2afde760961f7a36b48f4875246e615a2bd9928 +MESSAGE: eed6b4475dc263bd2207fe9d41d48282b713f680f2e037384f18b4bf224347f5e4c4b060b808d412eaabcf733dc39a40c6bda0505ce71fa823bd1b1794847678dc034e7999c16369340bc60c64d09bb9187b2e326055a053f8e505ea4196861471622db0e46f0f8954d8a1f07332da4d8ac55712626009912f8a15a9cd63a74a03c92f246cb63cc73f92e51dad1bc9715b1ed3fe5f2e1b2959b9b71e0e37360eb29536cf797147fab10864d6146c36b82335a0ce931408479c7ede484ff73e2dbfffc6c9227e16d7a23f4d90f15584514c39594e17bfbb295de9d62adadb589dbbe0b06dc8dac5b3bf517b24c1837b39472a6dd38931ffbbff5b763638805b4e22321f7afe92cdf502fb63d109ddcd9e4051ad6f45598532be179523710851d3931e887d02c345c79c489fc106a4ae162f7df71ab90b751da7038a6df7616cfc11887e21068fb9e33be566402be504f3fc2742b881509bd4fe6a0fc722649883f8cb655598a15a1d4c229dd86b5caeb711a028defd431154bba46b48172a4d8cbd45bc90aaf874b6085fa284f5fed655ad6fa17d67b3b9a796fa3e +SIG: 319bb4deb2178112241b3fb8f46e105c3b8e4ef721eb200d762ef363e2716f2a89f80b5b9e89970890a09892ad6a58808b477e943b3cfa77774a3645bc745f03 + +PRIV: 048ac9ec3ecb30a3b1bfda9b3b79a48c0793b490879e3c8a5e23ee2babcd9b7c946c186feafc3580a58ddd526ff229c04720250f4cf6bde0271eef9b12b1c3f3 +PUB: 946c186feafc3580a58ddd526ff229c04720250f4cf6bde0271eef9b12b1c3f3 +MESSAGE: d68be8ef7b4c7a4289f2b18b16ade97f4e4fa16452976afb581693380cc54de38a07587f32e2d4549f26595fee2393bd062e9b00bae72498e4148c8b882a8840e15b585c82b5c0defb233518409916615deb3a55a5f84e6b3aab93844de3b1e4d86e09f889ac71c324eb12d0fbd861cc31229540e843a34f8d5be47c0ec0d23df43e06813fca309439904c167d1043c0dcd444b004be1ff27b7862b00eba9433b94b0fcdc67521da0c1d5358636c78f530431164dde20a1cf164f51e29b8e63eacdecc869b41392c667664d91680d9ac516af548f09e60564e814e36e0b563dbae55c627ffc14158a56d8eb3609e174381b21de4ba82344466dd577f4d1103c43c27fb83cb833d87afdf7412b4090909b1dde264daddce967f496bf6f17112bf351e417db5953b13b8f0fcccbf30f5bcf376861c12ef20eec89ed23cf384ee78dc6eb40fd5811a7b23927c13e7dc5da3a921b883a9b2b1155970fb0da7d2993dcdfd4343642a9d5a6347e43c193b5793e4453ac1537aa3d04dc9f774e840934881d78a39ba250438c507250eed2f6e07cc953f783d6b72b1cc619981 +SIG: 2ecf5b8a59a8e27d25890a2aa32f4a0673275d539b174afa7b2cebf2e76280dffc338ede85ac8f614039560e2806d9e1e3cf9cce2ceb7874ffe1a7e80cdef40b + +PRIV: 2f057d20b1678531611f48f003b7d22eba5dbbd7e2dd41b7c79d09071f85e993620fc4eaa34d787df675ccbf7e893204828db92ead17a1165ac7fa1ab42719d8 +PUB: 620fc4eaa34d787df675ccbf7e893204828db92ead17a1165ac7fa1ab42719d8 +MESSAGE: 6e35f6eaa2bfee06ea6f2b2f7ab15fa97c5180958af2e90af918adfb3db8323f447c7bf26dc534997c38b7fc977f642de288cdf253071cacf3564e3b8ed6dce57ddfba9ff783bad2e76df124828fc1031acfadf01a44d41b42161ad9060301c1af1928b9e5b73b9bd21cac60a842b504dc3cc311c522e3bb048bf221444f53ceb08e77e948590e94ed98f1b604cb9eadc93bbe7431c1149b23193ff93e8569f113e1684d8976ecae6f09e0103614be418a472ef55bb8890d72b341cdd7505b50a45522ab63ed791ce8f82feddd7a620a4f6fb1d2fb0ed0c4560d78446d83b3d1b1bb56b366d196020d0624b1fbdb75ce735dd43e8e8df163c44e236993dca341f5132d825d0a4e393a19d38f61e11e0cf392cb9b646ea23c58099824dd8d9fbe26a49e33b23df80607abf19715799c19acc722ed9bcf94a0c29ad24b78b0b035b3241c64cd86edeac810e66745694b5eb1625060edf2d949de0d34f522df2dc60ae694a193f3b82c1d6f83a0cbb840f46c49a3d7d1cf06deaf96c64f8f9e17bd9ad512ae6309c486d9e2a78dceeca473a0421dd1b643c78754271b53ce +SIG: 30df7b0b1c04fb1efa3517e928d6d57c2ca0d07f4e04ffb1f08b4792c5937dd271ccabdc00dce850afe50af5990f224e8420a681d95f9f7f515afec102efd10e + +PRIV: 3a3d27970fe2acb6951edd5ca90dda0fc6dd229c0a56df6eb11a9c54d242dbbf564f0dc3dc4720e68e44dd16711e049e6112000098fa62a1b98c288042f7c3bd +PUB: 564f0dc3dc4720e68e44dd16711e049e6112000098fa62a1b98c288042f7c3bd +MESSAGE: 4374f61c2cd88a3b8972249bfa79b36ab69e3ed484cc60e5d9541fa7686cf4eed1210c5d0dcf42dd25972501909193ca76ae6eb7f471d8bd0d5fb5a6b431bc3de0e0318d50514524de87c4b83005dfb41245fb1af79b84a97b83d3cac7ad7a53364e2e9b21c97b769bdc57f0703116168380f3cc883689eb4a7fa3b26dbe12bc28f8c40381af64df4b5361d174cf75acbd46428740b0d1322d32bbe94845215966ae588777a8c05336e352306d49278d328e496db65e9ecf6ce6405ed1c893490bc48c13a134e1fb6e80debe6d32fce6ef74783c8d77980a441a26aeb4fd83cc855352cedc188f5279ce211f744a40b23ce7ff24437a1dd3373ec5b290da1f94f43a07a3ffea5b5f67b52c196185bce9e9a858257fcd7a8ebaf9040ed091face5a155aa447fa15e12122d25e8fc36eaee2137c7b3aa30b7e3ff6cc86b6dcb9eaf49c9576f0f462008439cb1a3aba013e897a0faf994cb7d59ede5774bb144774f73ca30e6414a7cc7c74b20c51a1404ddc419ef7624593e9bcfb37c0a762eab68faca5863443e16edb759dbc8788732b9e4f59c11192c3fcc872af55f32d +SIG: 22eb8ea0507349b6a0ace25cf9180cb08e0357b04502905fbe69b4e21b2bd94e22cfbdb851ae716a5c253c70d5e2b24ea78f35bc213292543d94e14110b24106 + +PRIV: 06d498318da456242b9c3b9ab6d532a128fce044f53882682e9262149c165288413517aa63200a17173209a4b3e78ab9383cb4e39efd6794c46a2d13fafa99c0 +PUB: 413517aa63200a17173209a4b3e78ab9383cb4e39efd6794c46a2d13fafa99c0 +MESSAGE: 3fe30ecd55077a6e50df54bb1bf1248bea4063e3fa755f65fcd1159ee046efd0eb5f2fbb38b5c00947c97dc879b36b9e536192286086d0dc12053610386174a7c56f22a85b73ff208c5944f393236c32415809da036e73cad8fc3c30378064a76afa930a3baae9aa357061a8c5e8e756a9cecf94b72df43facd88fa49cb4948c6368318a6b1e5cff52e587ecdfaefdb69081f28c2d13bf8eab81dbaa5e3728c4317fb793dd196bca0fe54a6c242cf26e2d129ba0d82a2c3a45bc8d1dfd6f54f8da4f5189c91ac214fdabf4c597381b2e5c40cc71fa7051cf2ea93906a37d57df12d5c7e5cd77c907e442566315bae51a2222d62e3f42d1767882637d66a1d5305ab4010a0e49c57def69dcea839e1b76a41135ba952cc424950e8d3aac19e1d93de7757c15ff9997b3d2a8613cd9a164781d1be331799fa6109cef614305a1958f62903c8c9ea0b23ba706d49c54baccc1e63cb4bf14785fc7b062a9800349bdb0bb927260b677b60f10e62c8780f3ebb5eb6ff0360263d457ab52fd1125c9ce046a95d89d287350c804cfd4ff2b2ddd18a9e13519f20b4d1e051af624640f +SIG: 8250f76dc599c5128787e4f6d3da23173330ce3320dba959bd714cc8cc07c67945d63e75662c075e267460ab7bf561f24faae3b41dbf676899191e3b02b5af0a + +PRIV: 8e8e1db5b1102e22a95c47af3661469f000a33f13b8b87b115d2452a411f6f3956d7b3169a95c22998ec937925bd7cad13cc65808cd5d34a6c4da870eaf32364 +PUB: 56d7b3169a95c22998ec937925bd7cad13cc65808cd5d34a6c4da870eaf32364 +MESSAGE: b24634fbdd1b7661315d9dc153ba90d66a88622a4158f8bcff25ba9c29e65f297f8e60311800b7331b69fc20c9f85bb7c184bd4086b3a9f9a27102b62362bdb4fa5b201594250fc628fd2e0e0d1be03dcf818c6094c4c29121cb2bf6d908ed8aab427c3771c0c95f0ac1469a0810b603a470282e5980a60729197fe6c20ef681cd1b96932d2058f896ea7416422a7e541f224a5f04253080741c5d4e3eb039db6ba051b4ca5417ce8afdc70214ba4dcc85b623d11e681c6009aee4e6130a83edd0d2c99fb0647e11ede7301ae56b59904ef7025732cde038801ec7e8d90a9a1bba047fe628351b3b89d0bc5ae665a700891f09ebeec05591842adfcc25adc3c71c1ebc4a312e5471be67253b0e9428b0cae37645a0f7ecb89dd79fbd9be2875433667ae07d74a7983c4cea601e72e975c21df993e7fa22a9fabd45455d45e37031558e13a7a4f5f497ea78fb7399f8838c0fd5de4ebb66db290f43a4867d505309f1c1bc27e9fabcbba71302fc1204715ce3fcb0905bfa411c9d1c9ab4a39954e50b8e0cf736c10289563bdfa967553c36cd9e555bc8cc56be594847de9f26f9 +SIG: f6ee5e13cfaa362c8971d5a4a879a7e36966525ccd86c5a48cba08d913ece1a79c4cd146b8e9c65125fbadf17bac1cabcde8fd17cfd68fa1f9c44ea61c08a405 + +PRIV: 3884b8b79abfd3be6c13985eb859ab743f157cd9deb81b2fe97ea4d6173e46f5bd7fd9a8def13a542ed2f2fb048886885ba9b5ce59cb7019fb54667986eebc26 +PUB: bd7fd9a8def13a542ed2f2fb048886885ba9b5ce59cb7019fb54667986eebc26 +MESSAGE: 12adafe30eaf2b9c7203ca5d44b97ffed4bf6517a49988e4e676c8e314adbdbe23d8f2d3e2b081a7024fa525ab5aae26e60057c101e8f368d3addb9376c4682c1f4224d7f149a8474bb9a8f663ef210e9572ce829da388d8aae72a467141adc153473be3653baaa64b5b1e2e30683f6f06dac2784d5bbf0d082aab47305ed8a8efd0886ce63a179315225d1e4d4ffcf1f24ac2f464cf5ed3a8b6d3998454f1c02cdbf0a444ee2b59ddbe0a174a0d937fa62865088ac647499957d281c6949803a5fbdfdd0dd9e91b6976861f3c5f2126f39aac935be09f4b9715bd4f0d5c55df73a6b9f2c0ad26ce49d822bf85bfa2346f3165b03859a71c3d2a7b86db6e9f2e5d7b169a910eeb7ef38fbdfbbec43a9a25f04bc3acfd3b0691542ab6de9db6f03058f9584024f9918edecd90fbb85735d6dcec5bd593ae63e2cc96553599a310f8f2009ba95371196b4d5b80e7559637f22926778be5e1ccef5126e2443fa939c2a53dddb04961eefd34e538cd8d7f0bec2bff1ef0d3a4bdd358317637f42d595538c1122251a94e963d1f81e7b9aeb164f95da9a4ed7529b845ebc961b27b5c19 +SIG: f4206fcd34502441d54a73323f33a5dbb4c98557319f21246f260ffbbe5844886db567f4b63c47943dbb78fc35657d7c04d4feb042ff8536f672925c319efb09 + +PRIV: ecd519f287ad395052b0b30deac341d2a9df13d6567c891c813a0c9ca52e871e8ee94c588e0b343585fc6748fd1b54b5770c64e9937a56357a48d44ae2f51824 +PUB: 8ee94c588e0b343585fc6748fd1b54b5770c64e9937a56357a48d44ae2f51824 +MESSAGE: aa71be5f557e10c9fb5f091a3a274453947c07a0e25b26f9509224541dff76f4d96effd0d5a41d319bc9321a86667d55cf49432fb5c3e715388f3f106c9174b1610c8f3075d5931c290099385ce9249e235128e907c53390036fbf5da968f8d012336958de90c5e8e6b1016ad43fb57c8e288dafe14e90e64b63791e5cbe557e02df8ac9370642a71faf851075e5565f6f9a267f4f6b454ce4c5474810b804844dda38392939719793246aa47454b9b0e82e9803c09935d0027f3995cca9713069bb31027f7b2af12fe5feec7eeb06843d8296ec5682262a07dae747ed7bc821ec17018d899fd167b36a7e3773b427499d99dc583bbe4b429afa6a26593953f943e4673bdd0d2a844256131603cd0903256f334d4f8ec82de115b6ca5338c75c8baa44b4ba963c7c78510d8de9b2a5852f42f3463c685fb3a6da61a8e0892662d6a250fcaa6fef74d450fc457b9871d08bb5be3011294ac888fce215d535c3b1a43bb47efe3ad25da159191aed55195469c59093ffb24f65d60c4020bfbe647ff5db7ab8a01d5e487b0b1b64ef25da156db142e6ad872a4dc1ee9ba668465265379e +SIG: e8f51be73fc4e0235aa153a2e1b354e9c5d2d33a11ae0e333478de1d8e6c4456d2e250824c3246ca0e8d6ae3e16677a97344144108c13b959e1daf51cf0fe501 + +PRIV: 193f3c630f0c855b529f34a44e944970f4a6972e6c3859359c2e0c8762ba9eaf3256f2c82e7c801201210140569faf18507e60338c2cc4118bb1ce605b0ebe61 +PUB: 3256f2c82e7c801201210140569faf18507e60338c2cc4118bb1ce605b0ebe61 +MESSAGE: 98623f651698085bde02762e8c3321f14da1619b5c3f7c1a568e8c26ff0c62fdcc412475912eb8e8c4b0d30918b8ffeef3509315e58da359cdc2f26bebfb5703953be16b8f3beb1e54a1abee0aebe24e64dbe873402e156f37dfc168eaf8a114ce08a6795d3f64f5151e9a8b8275cc7b49a6b8d8a66b6d4b7632ef80740dc1c1b0a38d1a28f7c1b29fa44541c1aad354d4590c231dae687a2a8fed09e8c1ebbfcc38f347bf06d94577e49ad139f710ed8bb1fd07663c0320846fbb455ab837ef964ae7d4eceea45fd7bd8d509f821e6eb027494efd8dd8e992b88698eec2ebc5e03025be789c18013f201f77aa2d34f5686460e43fb489e08776f98bcde2ceeb9d4fafdffe0375604371ec32f46b81fec474382908e9d250a0ba2780a7d6df407bd2b1eb126748d72511b9b069eb1cd44270f29fe84b9a717751831d04c2818e408f22789376c61c2ca45e32e788ead3a7536bf09da8af4703902f5516a020d89263e93701a2565eef1270418925f35a288e327bab628ac2f0248cfbca3482e265d1621cc343c31f65493f064bad0d7602460715fa486f29426346af53e333b75f5905 +SIG: b12510ac5f2f6d33360cddc67291d6c270fd9ee62dc086b38d932d26473fe9a24efbd4248867ea7e915a30c5bfb3b8b19aa01aa2febf0dac6cfd6638a2ba7e0c + +PRIV: a88ad0048d38c44cebe735ea3802ca576e37121c7d4d760dfd88de1663064abb14dd8bb306803e5a758ed68ad21d07d88161d50f1c74713777da1209afbaea0b +PUB: 14dd8bb306803e5a758ed68ad21d07d88161d50f1c74713777da1209afbaea0b +MESSAGE: 2ce8bca26178913b1676e90ffefd945bc561982660e2a75d482ff30aaba1ba43f82d2e6b909ec10fc09789ff5cf32a5180b601ea80fadece6d7e7baeef481dc6979e2f658ae0f6d8e416b93298f7d34031bb76f716ed991a16d09a582e58ba4003ac17be8b4469e1a889b2fbb2289e98af1c6d5bbee77756713c0778b0dc446a1f6c48c4d40818ec799905f069bc95341657ca5d02b7a539a13a02cd0376a50e8343c0dc20346de5275b1dcd4ad7af725131ac75e954825d30eaa57a68bb98dfc41cafe5710556647b387d9b7fd4e47651e5138050798f6d40f4ee7120b58f74da94d73cacbfd393d1347388ee00b79b8dbfeb57814121bdda60c627dce147d4d568d79052e97b9a5f3eb5407cc46461a55e18a960d8094a5fea48b6937529cc4ec919cdbedf9185456dc00e8d98ad1537ee10a057f4eec4b81dc60392fc9188d3e561785965092e44317f2a48e36605fc583fc173b05db9dcbc7557d06487390fbbba77af3a014e1ac35139caa1c53a8d17347f178e1c54d0f52b40e91042c93e7e481d792e288fc27e4c2fcf111fe97d9e2337d2fc1c3098f06684a31d55ebf362c027 +SIG: 1341a148da4593c88ebc5a58821eef77f92186390ff633e76207084e7874ccf0eb1f9ec70a3a3f96b58934bcb061ff920124f7e580fa2b0b279583adf9232d0c + +PRIV: 3f59d6a018f50a822117e5b473609e30cd64920ca1c2750dcb09eaab807a3eac457d0e59c11f348f3bfbdd3f327de78c0a7577c0aeef42d4c1e56700d108808b +PUB: 457d0e59c11f348f3bfbdd3f327de78c0a7577c0aeef42d4c1e56700d108808b +MESSAGE: 7d103a6c6ba2d09087eef2254c1c903f067695a54c4515e4d13bc1fbfb54d6e7a167349c14809976da04a7e58d96b40aac3b2bdd14b9b50322bb11645f05e5e978bc7fbd02492ef88f87d668280fd708373207ff670fcda97df8485d5e46dc3bd04347f4d7527eab2718f7d93d132ba7758218894e75a7deabe693335ba0dc73bf26c288bfe9be8a736d75e5e0eaa7bbe8d0b77abdd5146e0fc9b30db9f07cf4bf36260a1f41410331f8b47c6b38338c6dc9e801ffe1d585f9b7fc31e9778bca3027c232c074cb18e5b72997005ffeee4bf37c8f874b1b246a6345415dacaca7075a60443ac3319236e23cf6b7544740807052114984b8d8f7e857dcc6faec8869cf96b997dfa9af9184ad623f1d90b8ca759b448eabfce18c17cfdf9a3e3312e63e5f084cea904c1c909913cc4b19d044a3720034973c7384949bd6f9ba9256f98cd394c566da83c31180109f16d10347b7e3e9dd6be3bd3c77ff1a7996a078dcf89dcdce2d1b615695f4cc9f8f4f2a08804641bca82662ce88faa53145b6a45955aec8cc2af81cccb5d7c64f9ece1c9983326484a1e5ece4ce36544d63735f7776f21a20 +SIG: d7425ea194a6715c452ec4f6d6c76e6dd374d3ca7ae7a11995d02b942d4a31870dd734c12fca89a8eb0213eb139c14a87a6a33e818603b2e313023fa58737d0e + +PRIV: a1212b34dbca63b7093612d05dab7b4cc8f7b676a934ad01f659851b3bb44e4eba2fccea9a080591be71268d7e951f250dedc00416e5f3f908db6cc571254925 +PUB: ba2fccea9a080591be71268d7e951f250dedc00416e5f3f908db6cc571254925 +MESSAGE: 07c37c46be3c68d05689577aa64a932b906446b29baf12f6174a6b42bbaefd1f1f373e0bccc473ddfcee1a7f21b96a6260ef0aa1f2d8b2959e71d12c953358a2774cc5e6f379a313e435ed69dfd6d4a59adee3cc7ec4bacbdbb3fee5430b73f6051a6096c60e9bc92cc8fa059fac2a93ef7007d64fbe50064964d5a0ad601175cd9caba453f9103b25485545d301f03c5f9f9478bdf9d414bf1dca3b1c1d9daa9971f9e617fbfaf5b02a7fbd5d4fb894c0975c54592b49a0fc85dd0853f30c51502d98fc1ab85a17cc58961aae9764570ba5cbdbc96dfceb8d11da53364b4025fe0b8ba8a353ad23686720169fe973432ffe291a4b11dedda0aac79a5e42620a64587d2059e787013b40ceec599208f66ed0ca6e1be9092ec27db216ee6dadfebc21705bc4a85aee577e57d239af586efeec22cf38d1cfb3cd74dd0d9a3381aa81e6a297e39b819137ad27d475e2bf54aa426dc29c4ca8176df343137a2d79d12ef9aa7be1cf6775e5d8a4430a85c33db61cd2f35187b4f6ea9ebdd753d1c4ef72471159ff07b77870906496249d4278e3f3ca6bcbf37a265b896539190f9a31f1e7b4b65cd1 +SIG: fa93ed6595bc958dc042ce1645167b79e8f6734c46f80f631fd5484908f5e51a22427ee686f564ff982f6ef4d2ca1f0ca5624910cdd63c11a3c2b16d40973c07 + +PRIV: d9682086fe7dda30b87111060193d847566ab94cfd9c97ab6b43e7a8d3f793828b0b1372d88733ef7233f6379790d1e46e1e07e9d3fb8b0be252ed04c5fa163d +PUB: 8b0b1372d88733ef7233f6379790d1e46e1e07e9d3fb8b0be252ed04c5fa163d +MESSAGE: e8814be124be3c63cc9adb03af493d442ff20d8b200b20cd249367f417f9a9d893fbbbe85a642be2701d1d1b3cd48a85cf58f159a197273143a578f42e8bcc8b6240f93271900538ffc187c0afc8dbcc492bcd679baaef3af5088434a94586f94b49970bba18f5ea0ebf0d27ee482aa83ad0dd0ee609df59d37f818b2c8d7c15f0f6f544dd4c7e7cb3a16724324f77d58948f8475a60d53e5bd510c17137c99e1cfa515af9bc85569d212a21190729f2817de8c46915e021df70ff6d60215f614fc21139904df3b292b749dc4dea02518b62d15862c92d2a4c996701cdecaed84ab628ee984fc111eecb59e48444efc0d456e2c852518441c3db7630ddd5156249a28730983838ae59ac4cc7110fd6de68101ea5b2ff69fd364e3c9448defefe175bcbe117cc11b4ff7549c33e1025b6b592048a8e31969e818dcc188bb19d7a2440a3baba4eb1b81c45679db46b31bcde7776757d9931ec2063fc6f1fcd761ecc57a7d030a85ea273ef1825b05092ab9645359a444ff7d166b575fac298308d9faa68463d1d0f7b7df8a51c6815d37159adc0b593224a818321d7219f09686cfc952259718dfc +SIG: 1793e497eb521ca74e35d14a63868cbe9499da2f21b4eb5260340fca3c1feca78dbe5b14ac10f3fa76fa2e71e4c91461aa75977e5e70792670ef7ff0e6a28708 + +PRIV: b52b249a7aeae0fbd94ffcf9a9fde10de61c3f4cbda14b289fe01f82707334ca735163bfcfd54f9d352e1c2f3c0170c95c1842ccc7421623ae0496980cee791c +PUB: 735163bfcfd54f9d352e1c2f3c0170c95c1842ccc7421623ae0496980cee791c +MESSAGE: 1d445e8ee36f6e1064ee1281e6b4a4cec50a91c2b667c8305d1e9a5f7b73a3445882581fb0c11e64f6ee92e811f9f2d6c59c6344be7691d116dda493cade51c0ce77372b61a7c4fbb633401333cbf71372ad2f044e992ac035f5879c053004f8223f237a24a409b7894f6ad518e046b8a84c3f4c6260e6169fd944d57fbcf9ba2775f2d60ed772c46ccd63c850b80d587c5208dfb1a25878c02dece3e602e9632fc3c2c79b25ab41034c6e26b869255357a686781dfe6e644beba9b627da1fcb5ec0be497cf188e1ef1af0601bf16b2911fd9ff34f0e97ac95a7fe2cf90ea6ced33ccb0ed1ef2d4160efb07c591a5cb16c70ca1694fb36f2ca19eba52be3d4ad895abcada4b36f0261d65f59e0cfd2a6148a8892ddbb45810db3bf4a9e26e92c15ea2618cfeeb462d8628f254f54d2af27113bab4f9a7d06791811942bdc32f845922d7b2ddba959140928f8c28d98b44e1d19b97fd39cc0f9a5236d349fc835ac492192462e40ac629bebffd2eba72d2788b244bb777ad0f7b7f96f23412399fc1d87a1d087ba089027eabbc05edafee43379e893291331b460bfa7332e0842ec2573393de95306 +SIG: 6f48a9f7f0fa192b66d12175a333612303e180b9fab18edabebcdf6674fdfcc53607089bf980ce35894c2f9babdc4438667ab3297a6248ec0269faa99c724807 + +PRIV: 782a93efe0ef06cb2534330efd0e9684e9969b5258123e490239bf24bf9f6523942fa1406ee2683e29377e49f7ba757cf50ef0723707d4403d2862257045de87 +PUB: 942fa1406ee2683e29377e49f7ba757cf50ef0723707d4403d2862257045de87 +MESSAGE: 46a4e319a670ac993994a53300c3f79144c2f7fec1116eeeb3621c76ac35da79dbff6e189ca9dbfc9abbda054847b2971b02facebbe926d469eb0a860389ac744162bf6fb13b42cb9bb8c9d72607138e7800121ee0cd633ed535c7ae5f4060bbdd271c9d110abff5e060ea6ee83890b1e92a9256d7b2ba982a3114bb6deffee2696f0a2f9c21aaa5b2defa11aab7076de6e57e86f284bb67f5a49ee685921032c95b74e7e3eac723f175af082c858e0dfa01728c38fbbb4c83581f81ace6c63c6bdaac5620eb9a568e7ebb7b72b3d1a164ef524e7b9f00799ab086715976c14d0df65f7b96bf9ebcda7feeef113422001a03a7633df5e49939a121db899d9b8ac2db4fad0c30cf0b8bdbc9e9802a797c8238e46511ff24068cadcff2448cc0bff92769223348d45d6b6f2c8f1593388c0bbbf44b6ddb50b98cd7f09c730f7de4d008156cb3cde0cab3ad0a58a83954e234a0a8a04b573c9a8e9b929ed38b8b228bf55a3c6e2c6b51f682652fbb708e74640e3313e17b4694d7fdf0111f90608c1b5af422dcdecad9ddb7f50d1bf5bc6378ccaffc3201e6c787b48c443ba240d9d50ff6c0e9df7f1a5b +SIG: 93e7405a4044510166c8ac264ce3b5ba6665d68bad458712dc93c2c390568d7402ef7d57f549b8a1042f7f69a679aa855f34f801d57d79895deb8deadb352308 + +PRIV: 6fe7bcf7a684423de1076fd76da783423373b381329efd6157424ec4b2655a947740e91afe45324f8bb990ca2a341279ddaf232c3bb415f178b6092fba195fec +PUB: 7740e91afe45324f8bb990ca2a341279ddaf232c3bb415f178b6092fba195fec +MESSAGE: 0baf0ad440612b4c5a136c3a42be1ca2b7c319862a44a9fd50c4ee73541c5e6457efa81825b6dd4a72194a2968688bd49e5a8f4c04dbafc2e7884c0c70c208d4e954cd1675da8e74c65c497cf9dc69424965bdcba5de52936f925f62e201f99505d3777beb3c2e08b2ec9a873e5a9c21fb4a2f3e861f3cf4d6b5dcd1c88bcd9163539ac62cd0659f4ef232c2ce57fc77f90285eb350169edc6a806ff50f61c7e0beeebecec63bfc9d3983f5bb4b261c746471fcbf2892c6108970b68db5e43c4504ddae2d0ffffa28b6759ae1128e16f66d492ad61e3722c960f88692be81a9f412890ffa346e702c867dfa259703b73f525074f3227c49cec1b645a103bd4471f33f9f1bac327d7917861d0ad91abee60222ea2a3c8cac052ae9a2cbd90855d733d5319133f9541bd0b61f0995268351e2863c1ca2ca51e3c976383f5c4c11ff410036fd51d5ac56b023ce9029c620f22557019ad9b4264ed4d71b434f4a4d17a7d5769fa1e14a69f7ae419ccf5947f8c7682697116c2405f5a1959c54b48f0872f596ed45964488ddec12bdb636d0b349e749eb66092ff4511fba59b5962cb93cc85515cc86ab0c6b2 +SIG: 9914cc50fef0935efb89b3d64e3c1c3412aed659b90166222c0d13ec1ce3a68ae6281b7efd9d4ec64b82e73e14479f03fbac8fa3abdb41ea4215c4a4d4949d09 + +PRIV: dda48a0d15a29eba9a76305d360e466e72d8040efe2e89c04b6461315a9b8bf44f5cc36a809416b58e15d24cc57968cb573b76ad90887a8ef36cde7eca400fcc +PUB: 4f5cc36a809416b58e15d24cc57968cb573b76ad90887a8ef36cde7eca400fcc +MESSAGE: f5ac19b81f2111a0db0ae30d1513ed343e7f57f7f77d65b8ac7ce3a601174baed9bfa136035976f516d5a870f45db1919f1eb1cbecbe88ec32d191e9248821a7e7681fe3abec11584bdb33de1b4ca94891eb66dcb8539ac41163736ccfd69abb83814dd38cd60381318728052a25cb665471058650ccc75756dbee688ab826ecad4ad5a7db57e8f65f1b64abff82dd53334b797ac40228dd817f239d3ee804a19aeac8cfe33eb657ec9ce923d6b388914cfba2e72bfc2bc3d6f985c0d97534db958eede57b16491ffb755c1a58d78ab377faec0d311818e899260e3ebd1ccd29246fa82d0b76622b2c4bc52f549fee72a30f554f331f36d2a74d999ec10a08294f002b4361e590279c2fb1bda4312ccb24d75282ce7c061a0ca5520c74f6f6333b18c4b541cb6c51e01575ba80512ffa7ce0accd22d14027c53aba1f7437835f1114d68e3acf3ff8de94c8e4ef6d3ab312c91d02970157508f54a5816f467a214e9b1284300289e65f365a610a8ea284666cfe5518e435bccd21627501c725f0b8eb5725e0e06e0cef5db201b48ec91ebf878dd57ce8dac7334848a1bc82c18b065955e4f59be3398594dc +SIG: ce71bc82d531d0f93b57bfdc2f7316cf404ee09af88f33bf806c7cad6b8ffa366236ba74e75c15096ddaa6e3a62a8f5eb1c8c3f6b6c94a6a349fc7c0cbfb190d + +PRIV: ec57b941adf3ca13e77a780577cfd0df5b49edc85351052da34e99f8a9bf32082859c071978a04b7f5407b6d22401a78efd0394bb966b9a04da6b5ef819de3fa +PUB: 2859c071978a04b7f5407b6d22401a78efd0394bb966b9a04da6b5ef819de3fa +MESSAGE: d2bcbd1bc361ab32c66d72fd48a8e227dc6b8d6b150848ba715ff47dd35c8e49381bb4e2933f42cd26b75b14d9c0039282b62b8556aaa11cd691e828382be306889fc9205137b169d3bf17b7f37693fce286039f03809d7d9d98c8fde46f1101942a279c516706f50191a9112f6a24630e1a26c321e46c9ccc85b6ef942f353a642b9e7ef998c0fce2d3a75b999eeb77f31f9b0813a97e3014c3a86e2558734621a3066dae35845031e35665f1922907dbb739786a8b7658ab60276f2d921d1a51230fc74d19e80184a4f10e9e834abc9a36c429726bc055dc8c063f0eca9c61a8a970bd4bb5f424ee4d04bfc295e3bb1f34becbd9920fe2e77fcf36763f32fc9cfd5e465979c167cabf5a1244b491fc06b8946419046ba516c5b233c414ddefb6da04f2e13daff7a9a0c02a518ede57ad9521de64eddf6f49a9670f632d3f7d42425207d053604fe39d13b9f52c8bc292b0076ea42a560056df25de51ad35881d08543224d7fa5d70b8603ef23ce06339d6cd09e22a95749e50dfbd3b8ad69fd30496b984d1c0a199c8594805f38ba44631a2c59eadc6554d19f9bc98366dfdec2a121d0e4814d2cd3f5871 +SIG: 118e1462126b45b8c6803523755c56dfc4e123e4acbb66ba0ba6fe3e053da4119f5719295e0c82ac64d7c5cb1ac898df263ddfd360f3008d91018b26f6a1730a + +PRIV: cbfd91d7695c1f270f69246ab3df90edb21401101ca7f8f26c6d00f4dcb7233e513879cf79d2f46df4b85a5c0949eb2116abf981735a303164cbd85adf20b752 +PUB: 513879cf79d2f46df4b85a5c0949eb2116abf981735a303164cbd85adf20b752 +MESSAGE: 264a933f7d0aecbac13eef644b0b53dd53a1280904100dbc1ab87b51148998f9da0b3a0a6337f5e3486c2b7e548d211259397aaa194ee4695bf98c2d5f4487699f7397e5d3a7e6d5f628fbd05497c556a50a4d05e2b712cdbc351068e42af19538901b8825310e343e1a17a1867dde0eb47ddab456d316f3521554937bf808ae4e4bc1c3c5b4756e4a165ad9e8827f5316f748cac6998ed2d2104f268407c135e62f26a922460eab6d851639a00e5f08b34765ea0244f475bbfeac183e3b5bd1aab798522798a08ec6bf2257d4692f5b03cdd0a2133de970603e3251475aad8d934af6b2bfc7a650b91bdec143f8ad254cfa506bbff28a03beb659ef5e5ddffe76e23230c4ccd46310b37dd91fa6aa68167f62a55c8a69f9ed1ec6cdb144dd81ab0bcbd62643420bcae67869f64c0b169f3cdf3c905895b7d35b6fafda25ccf23c3d10de32e7f271e300d39597da8f843722ef08364a5f7a105b9655172df7c82d7374f98264c9cdccb496f2e10fd8262fb1a9a9965b0b841ac0d0e9c1a3d9493ea7aa600205b8f900be0d7abb4d98a06583d2295c276318be28d421982dedd5bfc33b8865d94ef747d626af99 +SIG: f336137dfe6f42a6669b55f74b80b3035a040367f90656fcef0a644c52272ddc39273cd7726010ebcd8a30a05201ab70b8ff97d0288a2cb94cbc49020647390b + +PRIV: 51a4197ab7686f82f6003a0c32f39d0f2e47555f4e9f8deee75bcb1bd1ef69e506386df86b61f1f8f4dc45b73edaa841920968bbd131cc5ca1c5294eeed5c8ba +PUB: 06386df86b61f1f8f4dc45b73edaa841920968bbd131cc5ca1c5294eeed5c8ba +MESSAGE: 2aedb7e82f1fe4ce469ada48345d006d1b3bff40eb21867f51fce965640c409ec13ad4d52f891bd79066d6b4d944ca868d8986d242b57eccc4c4a488291b159c8de4392be4b86febaa75eac5d22d3c4f8d6bef79adb9b92b4914d5ea07c7f021e2c29f58d07be8a084100bc152d51ca897d7c131644d0895322e9440a8339e1aa390a7f4fcb51ddfb6df48aaf5676337d87ddd85b1d925e1a9c29fe0818f514ef72f747a674946476907a7ca99e9db8d209641057a7f44a317b90974bc86f9617a968a76a6b8387cf5853e608190c1a79f1e1d686e0de22db6cd9aeb8532c5c85cc90b5a018579f28e502a770a4ec675263d0dd781b4fa53c9dbf8098d57b33ae2afbaeb3e68266ad9aab7174ba68c6479883992670ccf3e5ac6a17e65e31e1fdc85e269c80935ef574f20d239568486e7d94a4f724ab7006098b24f3f61587691435c7f29ce4e5ca71b2b1874556433a358c8c5ef3c880843030c2d13d51b78c9bf1a8824e62e111844396f5af2e25c3126ef3626e26efafacf99830aa41212332f378a167233a0b42213afe36d83dc4582a79693b9d571a57712a08b8566d361ac902647afc886603e24283efb +SIG: 2c072969ff4719212a121938b506c602995b4d02a22e6198d6e87dd6ae076225ac70bb25ef8c0ee81eb6fe953df6b1815949e8ed0506cb012e873cd36cd09b0a + +PRIV: b1119c36118b7a065a195bfb8b79a5c287e09bd287c2daac5e6b01164c5d737f88f218ecba99e770ed214a8d01a92a10400acaf1f6eed420067e136ee2c0c670 +PUB: 88f218ecba99e770ed214a8d01a92a10400acaf1f6eed420067e136ee2c0c670 +MESSAGE: 8816b1eb206d5f6dcc2e4cc391d23209006de935e318152e93fc8c2cf08e26432bad9adb3203d898df0a2e7f1f83dc2f3ed3205bec8efcfd31adc1aca5755db9bd4efe54cc17073077de4a3fdd11996e84b6a052f034b41099226c9c272eae12528f16581b91b812850c207144dbff3e850cca848ec2b1dd164744d7b59337d7e3efef008162e680bd4a0899ced60b171f8cbeb48c5158df6cbfdb26240881bd58ebb8b6a079587279679cb5ad82f371b53c8013804c35596c887e436d23926f994e09d98fbb8ce2704174ef38b68262a7f1a712da0ef0dec639606814b3bdcaf253ff31c48e8a752c111bd7101031cc3d38efb0c9c7f19c59081584a0e015ee7c75b10a4c51ff543a30e52d5f94d8188c6b08e9df1e84a4e2c807170ac124a771b99465a0d38b1f1c6330403c82543582c5bb61b220de1b9e0ef69bdae26023181ba4cc077a5f0d425732ace132ae0c6ff0bb18baea83e8877afbe650fe0bd02093f00a7b5365728dcb66fbb881f592945058a5b350665af91c557a547250ad295e68b4fb72457cfb9d5ea1a7b2a39c9ab7d7ace0af5d51669cb6c2c4c07b2256d10e5ffc6b97c660006313c4eb8d +SIG: 24ec1e54fc7e722d37551d02cf135d33f5d3ff535773e02991ee85ffd3aa29997f9c464470197fee81dce110609f870b27c18dfbcfd9320548525e93148e2205 + +PRIV: cbb587514e0a34ffc34cbc04f28c9b4f6465f1eb225cca19b864876daef37d7f6b705d4677d2d849b6744b1ebed167dbcbf645924b1ff2e6360794bdd0e09788 +PUB: 6b705d4677d2d849b6744b1ebed167dbcbf645924b1ff2e6360794bdd0e09788 +MESSAGE: bdf7d17c706796efd3489559b527b1c0584b9022c9cbda3aac5146da340d9cea69f916037cd21b3eb1104348880fd5c5b7c65ff820f7499346016951cb715d8df2b41c88cd3c66105458b7b590c21c1ae2f6ea9ddea7470f25e02027d171e0e574a2bb21642f8f9da508e21d8e7335b5ace5935299407bd1b01bdd1423133ef045234e701f55549434ade94a60be1e1406ca5c758c36799ce1703084476e484fb1740530aee84266d07adfb4cc689f3265133a59cdf992fbb9a4b12defbe241ddbf65d12b2fbddfc05af0fb8de42080775bad29c6b0459841cbb648a9a95e48d6e36ac514480a3deb4b36554d8da620808ae9d47329710d20aaa6e5d7f547d81ad30f84c0e3d239cde5b169d9ddf294832d67a8060ba329c4ef39be94ac46434dd2185931d1231f9b6df878a5af0831e0e9d8a08d08069ded6a961ef7f39fad501ffd17d6d9b7c654653c1f58fcee1a6cd803d2aef166c78ef5514a3276d6998dc7c09a3fa982e427c785aa6a9e256f7ba72d5a6ba33eb46f1f9fe9be2bfc14109f64773c00c063b4d5cb4f4f8a0beca92a9a016c4f540feea9c3a31e313bbcbc2ff5eca9967857f5f8a909a29d7f20d +SIG: 1274d6f356eb641472b6b9e5b3ce65d2654e6cb87d3a83fb49d0f7da9c44be2b532604465f6089d680d2d94b0edd2b6b2b805c5e84c379efc059673d31007a09 + +PRIV: 8bde3ff61a16995ab9d539f6053219081bcaea1d458ec33684fc1c01fb565bfacd9d782a356e847b7a04c885a9b0907cc33ba97ad5390d4ea5fee5eb198d08b3 +PUB: cd9d782a356e847b7a04c885a9b0907cc33ba97ad5390d4ea5fee5eb198d08b3 +MESSAGE: a1f40ec5807e7a27069a43b1aebff583ef037028c02c859525eb8fa4c3ba95a901ff3aed78c4f87752fb795522f5bf715be7e3defac10fcf17e3fa5c54b20089a472333327252ec945718fb455e3f27ccfdef823d12d406e62a4aeba3cb9d1c61b2b17e49e200a8418f935f26eeb57602c7aa3b3a24f7e6238d3e08d2d609f2eada0332bc8cb12916cb03b0d4f9cd602002586d3e4cc7e0e0381c045ad2e1ee28298ae7fcf0c10f212808565296f158d2c32e8cb28156581af52bfc3470c3c9582138d2255e8426d648ca237d7aad2856f171638558241d8ae3f62ba92db596568edee3ec0ef370f83626aa0445af08f967863660e8fba5a41c8e8ede1c960514a14687a4a81e776ae0e8e777fb0f250d51a83b55f8c1ffdd78df3bdc97ff177afeca046c72d72af924ad0d0ab2bfc11b7f4abded51c3987a8bb94d640c8710e5fc9a4190e8a008363d7419cea17c40dea20ea5156029f3debf05241918f54af5039e2c4cf2ca2e139f60e45cc65595cdf54a67d92b6ac66fc0c5a290495ca57b07ef5750d05f57d87d0c228f7e4e15ad0ba0178730f951c697583481c66cbfcd48032544aa8d50908304bd81940308706 +SIG: 7464df0b67eb90b4b73ff082ad0d60ebfe0660dae97069b52c3727223bf70e29e48711a2bbb438f5f8d8a33bb9c48fe7b628fa8a542ff0b5ae36269d4007a505 + +PRIV: da59bbc523404f07646add7908294977e46645bc8a38bad2809641a23de3b15ab22c0f21aa1c2d45f4b2e56cc9b5e02f9e31a2eaa367ecb482f874cbd8e9fe34 +PUB: b22c0f21aa1c2d45f4b2e56cc9b5e02f9e31a2eaa367ecb482f874cbd8e9fe34 +MESSAGE: 097106c3624d774dde2551e0c27e19504e6518cc86369ab26ff810969e7de24abc68b4b53f11d945d49ef078eb4f6ba6bf257ff7b608afdcb30a5c59a756fd77a6c1247f6f2a41100d99fc5206af3bcc6de1d3e4968e28fba0123f6045a1b54d693a42bdfa071b2b914b3c3c0c29b2593d07e8bdc86ca42ac555b7dcd9439df9fbd4bbec730d6327bfae4fc41ed498b4f04a0eb14cee608283aaa6e6aa46676bc88aed5d9939037aad4915661af94bb5f6e653a2cac123287073270e0b13fda1dd4871af6a92f992f539df881712fefb038540d41191123b6b3b4b6ff87ffc929a6be53c6cef02f48f2f0cf2fe64a45fd66025cc2d7ee55ebe2316c000855661165e2a5ba41afc2097957b6fe4c55221204b6fc1f317dd3ba13cac39924026bdb66be4542268875631d277f210107a33767f6d9596e25742d7a90ea791ea4bc9ee84a67fd328b80f791ede96d89663e937f0b755baa9d52bda210cee1db339ff1d3c4b000b653b9bde338049af84364e2177f80dd51e2a1672ee555d6317589f6f1d5abe6c2877358bf94b0b808ff857363fbfbe32e97337e4b8a8c221a9e75962a8dc9b5a3d7ca5f9c9b61c73c1469a72bd +SIG: 1472459cbbae2cf21ce44a15bae9fc85dca40b8182da7d52cbf56ed538d18e03477c140a3ddd0efba43c96aa92f5f9bcdf3481286ce762a7e2bd1e779ba99b0d + +PRIV: 40ea82da41fd15b06ffeb99cd616dc6bc8c1b21477ea239466088e2849bf10165910e580bf412c31a87451d9ddf32b3ab713f9e4a22c590c641c14a5dfbbe0d7 +PUB: 5910e580bf412c31a87451d9ddf32b3ab713f9e4a22c590c641c14a5dfbbe0d7 +MESSAGE: a06c4e02b83ab7e191ad818cb8187b52a8da004fe838db333c4e02548db6bdf791444642e57fdbc8594e59d7023280bbae82986f399805434bb072c8a27a2dcd5aa62f065bc58b0621fcd365f6cdbf4d57d577d91150301fa48f182f87e8dca7ce45a7d64845ff434d1bab0534ccc83aa0974e88b38fc2508cefcbbc82135b73b384c80eccb8a09e2873cc07129021d81ce129a9df65e613410af950197dbf9afc28edc4e65c3e84da40d2ef841b886bc44719a5d59db2c6dc776401c895e2b3c83783d7817bba68baff59470d6015bba8d975f0eb712f3b8902912805523aa71c90499de689d31ae44e210b8446f2484727cc491b92a8e8b199d628e1df79a28c561e5a7d882e30787d08fb2d5196ba61196309b3bf0c5824a3548c700003fe9913befe12223150012685e90720e9ec6bc4db607425aec531c4fa36086d3b9be391a3f04635a8077a447a16a6fd89afbb9a72d0d355cb0b22d562f43f59d4e37128b3e2d906c8ae23d0aa599c70d3778a076c1a39728f1d6937bd48b978740850566138d34852b63075e89a8e2280edba6f4ee8f61511e9b768e95c78d197b693b109e88818b486a9dfdb74b4c5550acdfbd5 +SIG: d298fcc9a8ecb76a98d4a71dfb01d276ab2d9670a95bab34cf1d8364516d1ebdb23903460215307125afd09c758e981a452da95c0ac2c0b958c6917e6874190d + +PRIV: 28bb81a17d4584754d52818cd0f1f21baa777e695844a15122ac05344dddc027d5f61d519944d13b84bfa7cd67cb0bea4ef2281efa461f22ade4ba882d11b252 +PUB: d5f61d519944d13b84bfa7cd67cb0bea4ef2281efa461f22ade4ba882d11b252 +MESSAGE: 92e84c7a55b0bea03e17cfb65f7085ce3f445b1542bae997de5f092a24ff243380286d137091a598f35e6dae1a1c648f5a494c819dfb240652ff908381f32d70bc513100aca16fe7220295b1c71835f16d9310a9d27a04a980ace297d5af3f7cb7c78b24997ccb41f54ecbab507eb73ea6a3ed470e49590509f5d1e6032a2605db87f4a9b9ec91602583f14e2fe1bdb900ecb8971196b55c0d433489f26be9ca157cbd56572887ba859f39674a8e0ca08f2dbb0f27073551d0b1990685178b1ae9e7885499143d9d72c8571d11e0d85bf58df94e2a74d9b6846557f9125ca0944ce5718d2cbae1672ba02b847c17a6f6b445634d2f0175a75cf6883c62e5b521c57141f218b2fb0994b372a716c4a217434beab75740b8e91c622187d03c85da001e00247312a465225f5d6af232064a427d3018700ded774b9026777a5275fc04754606c86600297bf7b71aaff8b9a746677a3662f3750e81b50166f6237000051ffa15868defdf090057722ae229964a4ea085e0dbc04ce1997722c5bb65d2b47ecb746fd83a9f6a69c81545a9b502f5e76d3130c5afcb1c9af99d918740837ce89d7cd213fef2fd062ce8850f69659e4ad327 +SIG: 9ce45a07dbd28d3f6f1b35630a3fd56f1d548f84ffb1c6ae64b21498ae38e596916e77f79905e609fb1ae0da36138a80f242122167068092cc605796c5669e06 + +PRIV: 24bfd4fc45d5093585678101cf563ab8011fd6430de155f2a425f0633ee3b7cd9cf5c5fc0ccfaeb28a08ba67707b18dc84ea0698ffbdbc169a09c28123e6c2ac +PUB: 9cf5c5fc0ccfaeb28a08ba67707b18dc84ea0698ffbdbc169a09c28123e6c2ac +MESSAGE: ba54128f45be2001dbb060d5dcc47144997415d4294f6eba8dceba4f6cf2234683c4265f88032205296e9b27d68506232d57b688407648f87ceb342052bde9d0065542ff1715c942027e67482af4bc278ff71966fb3f62a2a5323cb1b4bae1e7b8fedcbc73ea05b4076421b0b4fae8bc3337416a17fe124e7ee465ebb38d8792306429d8279a1bd54c37bee8f9c85eebe3afd1f64489d4e53ac5f50657bb6ffb97120744b75d47c6226d5a9c9c264ee3e6a6ded05062ca1006669118454550010919c2633cf086950345e514af3843148e5c64352e69037dfe60d4a8eab3eb8cb54bd39af2f353d5ded2e2bc8b11c09f612e128c6efa41f6eb2c958087be34c6335a43005d11a9d3b5a529c2d1b0642f77afdd8c6b1d6fb2a9dcb65f42f4eca8ea9a054058be8613667610e3eed8d1df0739eca171954117989d1b12189ab57904aa960b0ca85541746385efa985be9d97b5a9029989a9c71498dfabdb813681f57e276b64db491b8f082a885145469a531b7f9f04ca0a2c2f8dff20ccb99c2861f54e5eafa962cc53eaf18d3d5e50d337af485f19975f05930700a8a7253f11f184130d0aee70969d96fe08f216951d9dced52388 +SIG: dc935b60fde44359af8f50ed7f919f483ce3f24e2320c55ba92f3e7617c19bfb54701903ff183b42cbedfef0875f42b12875d36a0aeec73ffd09509d92b28b0d + +PRIV: 2fc2f9b2050ad7d139273e93e2a0451c7b5cce57599aa6b08d3edc5bb07590c8ffe5a17880d718cc7988c2fd9825b03b93450ac1deb8fbd1f1bf3b8f87805954 +PUB: ffe5a17880d718cc7988c2fd9825b03b93450ac1deb8fbd1f1bf3b8f87805954 +MESSAGE: dc1297990cc027d56d1fee265c09bcf207a9583e6bab8d32478228e0bc305b9818154c338ceec34b04c4ade7ac61dcb09bfac8ade00d1f29de317060b8a4daf1987de409ca2c3fe4380088073ccf485e9a69516b5bbb4130f20be69b2dd6a9b465159cca1ac88b328b80c51b66af7f4c50f6228772f28734693ce4805a4163dff14b4d039811ee3fce65935444a6ea9a72d78b915c9c3b766c60b7e0329e43c9c57ede94b91525ce5a075a7297219772ef3c029649b586a95a73bbdf16d8fc20368de4ba44de1064be5826b376be31a86ca478a52efb98f1fa333157719bd6e0da80ed68d0efeafee5a13bcc3b457525258f1f7e031f7b403a461506927b1e6c7d4a0c8d84b5f3dd0eb8bdb13edc2b514a81d088eb077a52c8a831861feee8110e41a325dce206b2d67d25f90ef57e0fde709f3e5a39c04eed31e57c193b283e2da7279ee3f1eed482b3bbcd373902c1df811ac33e1de06429e8f8443f602019650bdc2ee8d7f650036a7a22b8fd88517511229c729a3269b3a3e8fc72b01b5a4b3e33f5272f3ad21629d08b1f717935e9e104add2f0f2033432bec82e2121d98c9c1a58e0daba25536a1be8e5088347f4a14e48d8e3 +SIG: 7aff162a3c0d28dff41715a974af07ecac2132fc18bc43a198fe664659050da19ae22758d52c9cbb94f1358bb02610a8a351c2116279e7245adf69675dfd360a + +PRIV: 8afe33a0c08aa3487a97df9f01f05b23277df0bb7e4ce39522aec3d17816e467d004370e6edc34b3e8818667216f5b226b0ff75a58484c8616e1a866444cab57 +PUB: d004370e6edc34b3e8818667216f5b226b0ff75a58484c8616e1a866444cab57 +MESSAGE: 86fb741f1b9708929195031aa1645fb709a8ae323fff85e5470194452e11b7b1279194b5e2427ce23e1d749c3ddf910b017e4f2dff86dbe482c91bd994e8493f2e6824bba3bc7d7a845f217ae9760b3cd00226d9ff2616d452751a90c3d0d3c36d4ab4b2520f67288171bd3a34b2eacae8d44c1e153dda1f90bcd3595dad37713b8d340156ea90a4e135951ba7169ac175578b81e97a541ab9bfb76328798d7d631c14df2ad613e9c6e1147a0e84062ddba035859d46bade5fadd9b32b43dad483c6b8023b32391e51ef1520c68c6191326c494423080c623dc4ad0aa074748d826c29644c38986a77002f0cab9068e6c9ec73cc2e0c584b80e0bc375721f7a8fc35317a5e240e8c66092fb6305b012c70e17aeaff13386d5e28d06430ca585b0c85b274e7fcbb63e3423a982579e5a64a0262c41908e55dbe43dac1e5cc1bb7298be428720a12e3b072559ec2675d457aaf8f13252e28aad63c1513f5f239564d363c8505ffa4e50f6648c1cb82bba852bff0acb030cbe73f059dd87bbd7318c5586e708618a4f4c9f3bec3f4f07c609eebb24ba878c6bf1e4f2d0fd1450ab94e31755217786fb15182760ffbe5a267cbe998a4ff90a2 +SIG: 63a8aeac025f2dde9a73286e56c2d62dcb79a241ba0b2e2dbaca8752ed2fc8cc7ab8e6600b67645fb5e818a4e82c29180a6b2c3f58d099cb635ce52bdc157004 + +PRIV: 6dc7ccf329378e8131b6defcd89370301068946336b0b762ac5ea51487dbd39e04e90d275e79df5f2b6ef4a31505aac05a69459baf2c581b3ce3db29f0f1fc14 +PUB: 04e90d275e79df5f2b6ef4a31505aac05a69459baf2c581b3ce3db29f0f1fc14 +MESSAGE: 20cebbe98401ac8934c3e65a5738cb0ec0cdc75fdb09dc96312894b187c0a46d2c38f4855be3eeccdcdcc56d926a8c08ce6e748e2a858f53532e7e5fc5f7014c8c6f86310cc26efef30ae525a5157940ab535ed8e403112b08e35e2bb3dd91a9ae8f772d2aff37d8c40d2b5cc887a6f15050a0f5bcf0360c3a9d12d5918655edc3c13c86ba6f4a2fa3bfcd405ed38f871cf7dff0f75daf2c321084ee9fa81211adb105b25c2288f0f2f7f93ef656b2de190122e7a4bfd4a1bd9893a8485b509ff0bc46cc961051c1db5a12490c7e741922ccc0a665496470276f69c7b77098c1e670af6b9f851252996875eb8035a817fa9be07f2be0bbb12025e0565414c817e9421ac700373893862f24cb165f9a271a64fd2305c6672c46767f8f075be5d2d4079bfadc3956288b0215605311b5bf32f0037b7c5ad502013e82ae3419d9d8f39c545b5888f47106c94d5fd6084d26034a99f5dcbf26a84eb4ee149c62a0410d8c707b1a9b071f74ed23932585072ce6cbd33d4d54ee917916f5dfc64d26a498018438b455739345dd60ae0f4750625915cc829ab6822d6f05f6d2bda0a7bf5601e9a2ed6de960371d17e6f43709c9678ca743adfbdb45 +SIG: 04509db003a1a6ed3fbcec21ac44ec10cc06d79f2714960882170316275df80423a1c1a112d881fc24d2812526079058aa8b608bfc6b5e57632240c636d6eb00 + +PRIV: ccae07d2a021fe3e6ee23836a711b97b04e0a441f169607572731cb08c269488a32265e5328a4f49cf06b467a98b9f9d5b997b85dfb7523ca6a0a1d627d32891 +PUB: a32265e5328a4f49cf06b467a98b9f9d5b997b85dfb7523ca6a0a1d627d32891 +MESSAGE: a4bf8297d0dc5e4c92bd00ad5b9c09b1238b503d619116ef74260378349a9282b41f3f4676a6215e3ce6d02238480a96043b2942b3feed12620b1fa97f7703b3eb683c1601bd2f51825c450df4fd1f33b0bf9c23c03223789e06e24cf136d3b557403a66981f4b777dcfe890d2ba96da4a4742aeeddd6a611d05fc215694a5d89a5de6760b1d9415155044c049cb02291a1514faa2e77d2ae33d44585bdac6365bf481d9c97833937eab636ed65742a0d5973b24d54089b2daf084d5414765105e4eca14aaadd1053338a8470505232e4ac633345c5cdee1e4653d1d93583af11854b1d9b65fc20281838c56df1148f35ccf9bfe2f3f80ab73f5b791cbed2d920644cf0316f0cb5d3662b9120647da56afbeb47a952953bc1a37de857e4b39fd92b632b85159f46cd05b6abc2338d4632d48e9a178860de8f65d9bc23f24507b7c5629e0bdaac067c476c9c3941d86f788944d744852a61da716f95f3b04f0783a562941bcdda439590fd186b2a8ebf19a5a7e4f4a3aaab7a87a434524fbc9799c9931eb8ce4e34e99b608cac94ab7e74495668df136185f487d9fbcb6605ad725345403ec57f3f6db364a87f38fea4b4c271552e9f2e4a1be +SIG: 0eec754105447f97d4a9cd246c7eede3fd069018f0d01a41dfabca3e90a741835ea4a9d682342267b250fc1c8c547c89632d9f689af536c7929004ded0d96f09 + +PRIV: db5d5f41fddd6768709747ab8239bb4f42a31d34b4fa88824d94bf78d314926403858ce6b2d24079eead66ca0dfe772ecda9af4d46bc9b5edfdc286b95fe9716 +PUB: 03858ce6b2d24079eead66ca0dfe772ecda9af4d46bc9b5edfdc286b95fe9716 +MESSAGE: 67ee03de45c3e7030db5246ee5b51bf298bba3e4d0934937fc12d9a629604c53c070e30d611999a9cddaf2d9acda6a9f67202b352369d48260eebce0e78e4d5ae54f677521f84a7be0017fab278b2b57275efc5fa57c617186fc1ba49edfbd3308634878d864f2da1583ca8d56ce9fae77c462039abc32d0539c0a60b7bbba5029e9329d275683d9c4ce77d0b908ade98b0e32b4420d9aee2cc10e4be922f9572582dd8967141c1d402e215f20aee0a890e2368e406dea11bd11177f2e038aa2f1a0dff51a128d955d5e5f8d5d0009aaa82440a96864d6c697f910d1df230f467f0e02a2e02bf9e45da95f255410cc5aab8d85f449a5de99aabd44fd763ec14629f3dbab1a247bffb7174648e43b9fb1eb0df5e4109b7a88e05512b20865bad39f9ea79d52f5188e7ca5194405bfb1a09727617f3f6c88192008edbc0c6585dbf261f149dffb593d42716e5a5777f5462beeb1e9a56a2c76e6cb735117cc1183a38d1e00b303d174aa9cf5c731b2c70edd79cc5dc96f4018f1d71d7198bbb7d134cd2ff8c15f9a04280db26a8fa9997eb86b133c022eda15d8ad5e77cc9f62615960bac2f9bbc3ebbd198f72c572b97156fa7fa229a98014e170 +SIG: 5b3d0da7102355486be4d69cfd65886c9d9c8738b293cafb23b2104bfdac8d7d01298eeb18fde3ded6491d41b419cc663752c4e67dbe8986833d20e4ef34180b + +PRIV: 7f048dfcc2650cda59491d4ce2b2533aecc89cc4b336885194b7ad917db5cd1408001b5d40958bcb270beea9baba3387e3a4b900fc42275657c6c691a2e264f2 +PUB: 08001b5d40958bcb270beea9baba3387e3a4b900fc42275657c6c691a2e264f2 +MESSAGE: 917519cdb33519680bcae04faa790771ce7d1397c345f1b03dd7625776f3f195809932618b1c64acd93ad000ead09654a33d14f748b46b67aae0ff12df3cc163280f47cedc16a8579034e49884296772ecbdbb71ca29c166233533c8de54012b412ca13cc258f7c5465d83422f524e4c05f806313478319fd143cf5088e69837697d3615d80a7fa7e7443fca65e753ac1b11d8eff3476636ae02d7a20f4b2388dad684002f5ce957caddd2053d0ed533132a81ca19bb080bd43be932028cb5f6b964f008b5b1c1c5993bc9b5485b22bbef701f0a26a3e675ea31122bbae91d864b54d895afdc79ca58d4fe449213353b149f3143b5144d747c5b4697479ae68528485384044aa2c99ba4b17b184e94982269bde2de0b17705d0bfc46d6906a90edefe89195de6bb8f3fb6a374186c7cd086d13d1b3525a3994dc8020e1a00554ac8a82d6047c5bff5e7f12450f4865da161e1a021fd9be8bd33a32bb54a4ddf874512e74b5cfd3fc3cd9ac11edd878433668e3fcc782b97b6d905adb0ebec42c9254ac90f35822c00f97ff3f0c7c39ed3c7cb3920f5608bb45838bb242a52a8637d7cecdcf489fa183b45451c6c9fcbbbf914f5f7e6b223bcb4675 +SIG: 583370971d24652ad213c42615911938fa9aa3d9b7196940e6eb08151200c7b6729d1eff8f4f0904074dab3ddda6af1e4e562b7d6220c1a562683beab268f80e + +PRIV: 9feb3df88c494a99849c6fca194201477a2fa7564e29fb06cb44c1154e8cea3ac35628ca6ee28ec1c239ddc5bba2a9e09e4846816b143c74dfa2aec1f62551b6 +PUB: c35628ca6ee28ec1c239ddc5bba2a9e09e4846816b143c74dfa2aec1f62551b6 +MESSAGE: 95fb7581bd25ffd442c3ae38a19bea7349c7b7683ba6767e148f0afc15373f67c16d471781202e6da8054ed7fb9ee204cc0f63c210a670a5f9ced4294588196330d31b8e8392bef6b48fe3c92078fae11284b4c3ba20d937e2719de7bf67c00669ad23e61384ebdf8c6e60735428c084fe217fdb4709ccb6083fc0ae4a05273eef739023d34bb73f662dacdf110b6dbd3e74fc1491e8c96596075fae5c36aabe2a0a53052bf77c4462438063aa7bc0c50ab920c9eb288671560ca5ba7af44a53db2e2ff43ca56069ea5517cb214e76faa53dbda100003c4f6175414041be74de22ce155d2281b6f4035be39841afdb96dd89aa808e6865bae62d6bedd919d3e86510b9fa5fedd1977c4131b2b86e0f48d7215eb13d5498ca5d2368f81895ed855a527124657ec9539efe3b2499a3b0b338262f26340e22554c79f4fad2b4e419c70bc1a2107d206456b6368781be4b5e2c54da42d336040fb7ba49c32d752321adcd92986e78bedb226ceac50292089bb579027f702217745afe06a5be136b3998a3604c9ff2acd6fa3f3f71633d3102fbf03047c5486f84c4dc2447d863796383d55f08c981fd4dd7dc1cb72b8ba4435af6abdd74e6f6e6798f1ae2 +SIG: a1c2607835bec1a1d87872fd8ee488d0ae9ed23d49fd6786fc4996725e49b3262118babb4834877c7f78fbeac02df40ab091b8b420dc9951381e3bcda0670502 + +PRIV: bff68955dd6ae0e8ba85ab0d0cdaf04a9f5befd5ef6014f49994a78363dc17f70ad9493af80b15f07a521ccd674fe9e5212a4a28c17c74f6605ffef78a4aed72 +PUB: 0ad9493af80b15f07a521ccd674fe9e5212a4a28c17c74f6605ffef78a4aed72 +MESSAGE: d8f5650aa3581c4d39bd1b8afc96c1ad7c4bf723426f9d7fabd1a5c8ac1d2fe54a971fac765e05af6e407d7269bab661b3432292a484f952c11095bbd20a15d77c41f8f3731a504d518ee10cd006c96ee57372de5bea348ec8ba159162170c63e970f1c7a3465a3d592e1d56c6540fbdb60228e340909646320c95f25698cd4896bdff58e2561e3b3d9a73b89747912a1cf467d63e41455fda77477f46fe6937bb0e79d92ccd52e82dba908a05a57c7ecf49554ab44c0b718e3bdd5fc0bf7070d9c58f860591c18bca8b3a9a148a06548e0f01602b1e6f686037c94ff732e155d52d5b0b44703b3d11163e3f56e3b9c1b86476e4dcbfc53fa05984e8c75dd21843cf96f9e494abbae7184aa42736633e3811aeff402b2fcb7d7f702e447241e22a58842fd6d0c03d33ff5b8c792200e173daa7b217e4b2f4433e6c020acce501b9323aa0241144434b08e9d2469139ff67342208900546200fd971a65dbd6db6c21e3ef9172abba1ea9ea2a249addf1a1eaa3ce11938b13e30913cd0dad491fcbb3285ea378b8ef9227f3fa80b586ecfeae137066f8448acdfb78d6d3e9ef4a6b362df4241ad9ae253b8e1597d656e000cea447a02fa4933328609bba0 +SIG: 9319eef740633ada1af0e137644c61fb3e11ba4b01d3c6f25392dc9367872a23be56310d312efcb91bdbab78a75e576ebe9081972415f562db41baf5e2338b07 + +PRIV: 1ba919c066bb56e640c3335968e1d1b5bcc093383e2d7cf8b5fff5c61ec47a77804c90bdc2b3618b01f075e041fa971b83c5b6cfa3b6b3974f3fa43599beacab +PUB: 804c90bdc2b3618b01f075e041fa971b83c5b6cfa3b6b3974f3fa43599beacab +MESSAGE: 87c5c75d8ad07d52acd781d1bb95f78c70e21c2dd66f7aa44234152f98234d128358a8aee98ea903a77b441db1447ae6ff3432ddd4570f7f58036122c1fdcc93cb21573739c19ccaa411508e08de2606f3d8f2db89df6a44a46133d57018462627e22f57ef36d1de024de3d4ae41b752df4821155934b447b2effe512487521be0356832a74ce0e2d8301b79f93175e8b6b961b1df637d8acadc884543c6864f8025ececec7c6e4fe0fecfc40dcd95e8d6ab93ce25595384436b598b73c74b03d49ed5002c0f858cfd9d0df61ede937cc41659d6708b96fc5aaadee109e2a68846baf2c246dfcf3d27c28bd1371e35fc9412631442ee75f38c6e4958070a74f6e6a220f75c7280eab4737d97e37882f3624811675f16caf60cb944bce92e75884c56483c61f26b6371b1b51237621a06543eb4abea7becc4fc31dbb5475b3deb9bb3c8992387104830c6072afe1af244bf681a40329c9b37772b09c5e88e78f7dffbc04549ffa13b4144ddfa538fc4b3300540ad830215e25f11446d289f33122c2c880de3da71c453d7e88f7ca4ea3d1255e82f4bc9e5533dc401c33040e16940b2cf9cf21feaca1c2c6c33337cf75e1884b483bf801536d304089115a0 +SIG: 503eb7ed6de1b776c952f255bbd4bcfb0e48bc70c2cc2f1f72bf6881479040c47524ec542ae13f6005ca5016b58b736a50898dd0569d4d38ad298630d68adb0b + +PRIV: 9b36247c17710e95261a7d702f57fe81f2971117a50c87920193b386d494ca9729ae39f273e35fb3f611da091600650efbc4fc4d1e7b4c76aced5a83f82634f3 +PUB: 29ae39f273e35fb3f611da091600650efbc4fc4d1e7b4c76aced5a83f82634f3 +MESSAGE: e8d9d53ba27e98edd55df3c6b245eacddc8a40e3efb007bc918ec5a869178a170bb4a635b7f8f742e37ad45d14a74344a6b522830a522106eb960daf192dc1e0fd70f16160e122516892d0e2abd0d4ae0f0d2e5adcc99ad55302e251b3e7a4d0cb33774a497049905c33de1fbbc1ad2b6c645295fe416b4d12b232efe0a33cd2ad8732eba1c3cb0eaeb0b2a57fa03ec567ca29210bf6ff9542a766f496fe68058aa983806cbe7ab10a47920bac8248818e54a41551c9a0959e8994cac60fc868ad48b5a24d5f24a7a5a3fd90b847e817ad3dd5d0d6f8de2d204f642483bd53585a92ef925415a9b38fbbf07fc0f35e707569cf488b205453ce5433eba6fde8781af72b52bfbcab85ead385d9d3175e21ad3373ad535cf0e357ed6b5383ef3829a9d5095b87dc9aadbe0ca7abadf33ec3b6ffd6eb94afdcc12e8d66a6fc05acf97368db0f69565dcd8fef4d1e49d7dd4ac053c218f5240c812d4ebba440dc54cacddb1c39329e5bd0c3c80dc3259a80f059f94679aa0794ca0115cc62af25e124cb8a9d4160eace6d22c7b1c44544f81142a19ebb02a9bda6429c50e783db4a07f0219e857c8d3c5655a582831c8eabc3f19b59ad8d2c714adeaf4039d5cf70 +SIG: 035970a672e93f87eb42cc396f6ea7e1b3dd5c5951572826d1075a15c2d7e454df195b51aae8dc61ef7ab895485f64e5989573d98a062e67ae7356fe5c9e3b0f + +PRIV: 6fede7396c462033189acd23d2f9d02b68898d35f3a01a798fc24d488de93a78b34062060b2c20076a98fea939b3b3a50451a5f49f8351c0ad7591dbbebb130f +PUB: b34062060b2c20076a98fea939b3b3a50451a5f49f8351c0ad7591dbbebb130f +MESSAGE: 5abcc14b9d8578de08321de0d415e3d40e9de31e1888137475ce62bc6fbee8fdd03b9d47c7b88bbceb804444490bf6a3ccb7a273261e24004ea67cefa3d5d173576d01e38f76c1e0e515083c97e79914acf2be4160ef9360bbe986b36e9ff93346b0e70691d934e47f8a503fa933ab2a50426947cda8e810c9ebe3b36982f09aee6092739fa2358b613c7f129db0dcbe368bee52f2f7f1dfe3d2434605b5afcf256071717d924fd0803bbd0dd1f9555ce834dac781df4cc7aa19e7f11da9fb99cb9e6b9e1e6fb4f7e8dcb2236c28aeb6cbc55a130e03c1b17a991cca1b794e6c13732d5b0a66f6eba860ecb98555aa4c218d112b116bce238295de142741f687be0b2487f58ffc5c12a0a519f1e23793242ef857ed398a20699d4351453fc2f092762abde34f4da2dbe0ce2aabaf6bc4c0159f3fe1aea16a036f7eaecd629538f3e0eed83c9a4dc1abc238f90daaf489fd61b34d937b6f4607a788baa82061943dbab26c1d384d8d49f99348800bf361f871f5d6cda18f689918cec31ad158f1863d13ffac5405c162c32de06e32994cc4106f95bb4fffdbefe7d629ec7797394609fdbfeadb46927370a11fb38471540f951b93c6eb238668dc006c21660ba2 +SIG: 88a83e2012d209ca03b8ebf6de5bb7ef4ccb5e3df5cac78954aa694930e4de82544ef5083c4892db9f05d77bf63f4fdfce15a4d1c3f85bae8077062bec0e7b07 + +PRIV: d559580134ab050aca446ea7750ef6b371d92d7645ec7635fe7851100bc4e51ede5020cd21a8b32339decbedff24664d9580326327aedf09c5ec6b3fe5405226 +PUB: de5020cd21a8b32339decbedff24664d9580326327aedf09c5ec6b3fe5405226 +MESSAGE: 6842e3190a110eee96c507d4bcb4c548c3a0ed7b1a8ed77dd93b38613b23c73e830b205e62651921ad8296b08d1e1008ad78f2996e3c7f38032e467cffecd77b8525e243cec021f85296afd545d7be1a62568bb0cfcdb90d614ed798bfb7efc655326816a61082251df01613aac88efcea1e0ea2961b8f921ebe1558dee83374a0113a78c55857ce2055bb2c48badbd3d8f4cb19734d00d0604b619073020d72a99a1923e6160a09946567fd4bda66442ef5a7360786d178dae44922f350ce2edc6af73d1bd80dc03ec3ca7005f4109d10c6d4f7d8fa61735110f8dbaedf91a0bad7d7fb5c04d706373c15c645063ff4b4fbd2d559b0afad432d4c496cd8abfea286fa675dc076726ec522b3a3c2f47aecc539f48a792169c4cc8cd41cd2cb6b63ddbc19373ac9691c2bc2f78f22603d5513715a16d4574e7acc4bea6dcd8ca7f19865a49d3664a210dfad290774b10b7188f255b3be4dc8fa86f8da3f73a4e7c929951df30fe66a17c8cee23e4f2ed2063f0b02ab40372cbe54b9a708df7c48a06566d39b19434c6c766987b3ebb00675f44c4b3c1e9f4504e7a9270589c0d0f4cb734235a58ef074cf9decf3601aeeca9f1d8e356cb2db5fce79cbc36143f34b +SIG: 6fcb1ac9290ab767d59b598c9a24ecdb6c05bb023ec36014a40d908ef0dc378a4528b3760d889a79174e21cae35df45d427ba6ea812bddca16e35a69b5e79f0a + +PRIV: 9d4ce975547876636fea25437c2880c9aa8ee6b270d1b2da197c8d7f95e7dcccbde4993c030477c35890aae82bb5087e914e64b94ffc64e2d7a5a7c919e2d902 +PUB: bde4993c030477c35890aae82bb5087e914e64b94ffc64e2d7a5a7c919e2d902 +MESSAGE: ea0fa32a4a288811301b9ee533fa351fdfbf6bc1d0555a7402767a3a9198558f74bba7031857995b9f326226f1dd5df107b06342203eb8d40c5f1dc95b4f3f88975aa24af8769e2670c46671bebb7a0f1b7568729aee477e8988af9c749f3202708171fd94b337ae67ed21a6c44174014b0b0eb5ba71c277978d488c24c4a7841309846b4e30a4fbbcfc45078d7e14014114b1ac64f7c33c9ac25ea5626c2c819fbaa2a4de8a2bf5f1365d6b70407e8094f99197ce1f0c35e11a98fbe372414ea2064a3a12d1cd5c8df8fc0e79f5b770b58f477f91976ca0139895120e246baab5a026f2d39c687dc0788334b5c626d52cdebe05eaf30864b413eebdc5581ef00d439276e52f479c9c05b116395826b60490b3ce700cc0027f61e46ca2f6fbc2c9de2e800806550afb06d4a08eac7a758e24582a4d6d428b433d365fc31d4444607afb64f15e370794005a3a2244e666d5d4c38ad2009c769a51cdbf738d235942f412d07feeb73b3657d0b0c91cb5940bad6a706e14edcdc34225b1c1f38b1abecb2adcaf819155a94fe190fd556822d559d9c470854d3a43bfb868dadd6e443d98ee87e4d8284f5cf3a6dafaf295b902836c640511e610ae7d0cb1b1d3d6079fe6 +SIG: be17444cd465a87a971df84eb102f9c7a626a7c4ff7aea51d32c81353d5dbc07393ca03db897d1ff09945c4d91d98c9d91acbdc7cc7f34144d4d69eb04d81f0c + +PRIV: 0273868232f5be48592cfa05134e8d5554ed1f9a57bc7e3982a330c57e5a7f3af172208782db66d466cbe4f4417f6fc477b7349f2a98db56c03a47227546bc5a +PUB: f172208782db66d466cbe4f4417f6fc477b7349f2a98db56c03a47227546bc5a +MESSAGE: f7a1d4614cc64a3bc48f00c6276304f34d4dfd15e0617b93ccef126c5c638c9d9953aabb7df42df4e0aaa7eac96a4b38c7ba758d860c90d05e3d14e479e545f319b0e5a85ad8f0991b43d6e49c24fa060e3e5df95c98d9451ab833e12aa97f404611bba359496265a6db11917d0da5c6a702d0b102de36dd0c98df5b54806ce626bb96374475f68a6060eb350a7d2aae3204b3dfdf9f1e31be81f7170f8a1b9385413ff8f6881e10c1e8da4c88afb50639ab44887aca2abeecedf110d2958c13fd3390d1b96a762d16ce196920ce85f6c415bed545b1445302a6f001eb8d00e97c751887868d481a0b1e4dfa04b6f761086ee8e697b019e017104bafb98fca242e334c6f18f1db5b6f295f05c559361c6831dabc42c2110703f9d1f64e12ddf26a8679854e9f8ef8479e1f12c35447aac02ea7f242e58632cf2fd063fe665070445b80f3dc6a3303bba96e05fa88eec201c5c2d00ca81b8da6969d0a4dd0483b3477d325a71facd6fa2209b48cb4f6525da73c9c05b2d9789b01448e1527e56a09a9bc6136d9837243c2077b925bbb933f8fb1daac963398c5802aeda3bbca8ae3b8f4a9a871f7ea8e2c0ce898c566217b5c06ff55ff9f4fe78398ae7973641eafb521 +SIG: 15e8d8dc7d5d25359d6a10d04ee41918a9c9df4c87be269fa832434d5301db022481bfa395a3e3466f9554ceee0532a8183a0d0550e7d1abe99fc694c6ff9301 + +PRIV: 336a83b55abf4c02e25e540329b5275843c2ecb8df69395b5a5e241bd0d8c10ddd60569844570c9f0a82643f446478b5ac6fc542214231a7ca656a92b5fdaa54 +PUB: dd60569844570c9f0a82643f446478b5ac6fc542214231a7ca656a92b5fdaa54 +MESSAGE: 9afee8ab482010e29264b406d9b49453d1ce6d550939072182863e4665284ab05d86258e0623b18754c4785238f697f075adfb9e1d31a42e85934ec071ddddecc2e6c2f61334a79526788b4952190716906dde17fba556eea4c8b59727514f6f5615a19ca36da358fae6a6c54f7f4b7a929e31ba7cc71bde7882fa9ffd87300136409caf3ca64eefea616aed58da5dfbf28b668ec1cccffcef6e2e14f8109e9cbf76cfa414f91ac00f48e93eada385dd3d5c16e1a39ea3dd55c761fca361b428f516c05e694fe5c3c345cd94457187a8e604b200a1a0f937ae89f4d6b5421dffcf7ca15f2e2c25378a4113233f7613f4570aa4b909a9135eae4c7b9ead458007ae17126a11d145258af9563db2f7e8925431878b0eeca8affc01ac5913bf5bac4fa3a857c54cc8906d6af77de6b9326b6506151099e87e99b1e819c6fbe082688f34b803d588e416d853169765d62f7e0bdf72c5cd66669a0335562336735e7efb734a2fada327f858bec602d0da08eba4479e7f6dc4def6e4ebdbb730ee91a33445cadc9df52c825ad36149cefbc51ab102033530814bafa7e87961b06367ff896f08ae334a9b1aad703da686706c11a04943ea75e12992dcf6106e372077cd0311029f +SIG: d263f56d59cb9b2896a947267c2ed78a945bac5abdbf3c14dc3ad092b2308cb9315c464942a0a20b2024511d766e85c936499a149cd0bbb209150a1643265200 + +PRIV: 88409172618b490393db27d960171cbc187eaf4dd8b320b3d2f824980043718fce2e7c5839ef5632a123dc373dc14b1f0505766e9675407604ca7cf54e8d44b2 +PUB: ce2e7c5839ef5632a123dc373dc14b1f0505766e9675407604ca7cf54e8d44b2 +MESSAGE: fb3e82f11bc286267e123817ad8864e077d9f7a8e7a163ac7eeaf93d55dd111de8083b66b53ce7bc771fc5071a2d7ac2f85d6fc6adcfcec446e16aa1046df37209ad7a29cf9665b439a54d6f8d942f89bdaa56f2f11260cc95993038b0e8fbdb3214f142e6c90b61a1d2b142076206af30ac35784a6dc15a1e79251a8c7731a1c53978038f8d76d70c6c1cdf529fbdb84d1507dcffdd42873dfa6a8fe6bd6f7fd29c80e4b2f933d2b6c9e62c9457e665472655059b63b618e2a9a8e5b9e41c3646173a892b8e6d4bcad6a62a6fccd3455890b58ec2681a95cc9776a9fce83c54a9ef312a331959c7ef3f79ee576eb7b79469c9234b1eaef609884708fe4bb0efac662da871ba61ddabb3fcbdeb8f635657dd9a5d7311e639a824858b9a9868d3f9384da612c7f2e771a46bd2624c99ea2b6ccbca996c1d9c375554f2a551619ce6d5e6e4d6b844a4dbea83ba732331fcf46572c1fb0e257ce1041b265df02e690a92814bbf3b5ecac69ee998766a02b0d2f908b3c15f952699616f2c07d589198989e6056c16319aab6cf8771902c078046a88b2570c13bc5edeba2ed1e3ba131daf94e6891862bb3de7d1063fe405307a5cd975693e9d58e17c690eeef4a2603cafc68c2b +SIG: 93b6e29d63945d5c427387d006c7f0b01956a95fc0436ed42b46d0f17b5bb193ea8c0ebbf3d6d13bb539e35c91f3f0f9fa3414a0223c9060bac83653c6fcd906 + +PRIV: e571189b5cd9e788302de3919d850c227dcbb615022e568bdaeb37ac5b2939c5edda890f42dd5fbc7316a5fadfbec38556f23f51b8efd2625437f6b5069f1ee5 +PUB: edda890f42dd5fbc7316a5fadfbec38556f23f51b8efd2625437f6b5069f1ee5 +MESSAGE: b62c867ad6227435bfa6dab830684e38d196e1f861aade0fd6a7699b6d60901fefb2d799c35c6f3d8bb94deee834403981866bab84946ae9476c75e9f1d3602b42cb2db437bff33a775822f0d6a257d4b75400eba5b8abb314b71fc6b46f8a34e861a9a62abf33de8482f63f9d7169e773a2dcebee03705dac117fd1499b68e7414f51ff9437f253a1d9901ec3b0bba86965a19383655487b58010f804909de1ffb2212c0252ddd9bf2a56ac46bd59c0c34dd59e46598b6babd4e5f3fffde55e48dab0398c22af9e26baddf77275e5f017b35a9b8f8435f9631936b391cb95d7adf35d1d8545a0fd066412d508967bbe9a20245a269e3be2777117e75fbac170dba352be69b254d353b3b2cb3b7e21b721aa9fe044f8916b4b2a6f8c28f8abe66ac92b91323ac73afd93dfbeeaeef26d19bd9f67e99d48cd2ad2d3e55e45d24d54b50f44a39b90e242ebe9b42bebdb230c470bdfde1bc7721c3120008477393dcc2e15fd22b251feb0e18b02883c078aee4fb760655a671dc7b8aadb9a562420a3c2efa2d342e1e0099d951b42242984f594e6914fe282b1ee128735984ef93a669e6ecba26c9fcb9f09f09256645617f1392d35908917cb8d29e0897c7503cddd5de1959686 +SIG: 7f797a31715d7c356f8f1f783700aa9974bb936d661661ad968c7cde1ac9e767be56a2dd49b9230e90110c67c0ed187cb7e75c3053ece844984d296f0d85cb07 + +PRIV: 371744ab63c115613929a343709bb019b7357dff72d2a149f1d0f71d3a201efee58abfad4a13859f0acb05d0e47d59638f7b1b4936100b988d61e6e70e22667d +PUB: e58abfad4a13859f0acb05d0e47d59638f7b1b4936100b988d61e6e70e22667d +MESSAGE: c219de1e8d7ad8df08c49377396fe7c1f2d57bd2170633a00d708faadee180ceba92849a7778506cbb366875bf9124701894cecdb3385147d0671843922a649aff7c435eb5a9c74927503072d0067978716dc80be1545a2dbf5a1c38536e12bd7720c1965d3803a4e8aa55765192a13b705ca1059ded0e806362fc5bbe6c76a1c9674bb853790f7e90af00753e00436da48cd082ead64fddb689890162082f8482924f33acd604640f69927352b43f64402d27a883fa6b72aa70d241dffaa1701a25cf1079358260793875f76a2978e9f9f9d68634eb3f5f01bde1ce49e5921252f949f082795e4eafed7be5b49a9f95edbb4a13532e3f3b3be62e2652231253a20c1d5477e8f4bc57ed76fa19eaf03a11bba429b6496ce76246170e043bc14f2d2f703d968f1deb09388715c37cb4752da8d464e348e0313c8993e24133a7c545284e3c9c907d01b260c4883f9cb3e3dc5b6f7fb6d75536365f2132eaeddab570e7273afac0bff5c9fc0b820f2078e0336052e1fe7bdec86674d0998ec78da1c3f34751f886727695f35eca1304b14734766ab05c1186306ded9db3eef65d3c0456cdae8181afee04b296c6722a88c7ef3088d26f7fe74bc89cf5285c688f027b7e68600486af +SIG: 5eae4ac72af0174ab256527b7cd337a0e5482e615af068db21dae35a64640742604df73fd4ca02ed9515a5608d73195230fadca7b426f02a2fbfd02061af3600 + +PRIV: 498b6ee6492d53231b3532d193578ba75d6a894e2e530034e21ab8ad8d2c0d1fd124665b28facd2d17946a04dfe3d129a4561a2b24eb326d84b62b422e44dbcf +PUB: d124665b28facd2d17946a04dfe3d129a4561a2b24eb326d84b62b422e44dbcf +MESSAGE: 0498a59b87cdae28695547e10863bce804d97de0ac8008f3d5fb652c1757419fdc9e0f9736f4c59a34f21cfc74599fa788fcc10c6730c7df8c3d2c1b6a786d1230b65585719d1cb5c490359b94435d6dd671f54d6e9a19b9b5aaad7e0f233f8797df997828d88cd92ef089ef7dbf1e95277894a2f7c2fd0c8e4dfdfa6d3d14589ff01916dbf9ddd811c2f5e01e94298990a145a6cfc26895614c7c963fef308a4e3856c32dd3e359bc56d2cca496ad199ff1a568d6430ac5cd208e0e2d07803ca523e0d813ad3733ab50bdcadcb988aee758ea50439bf38ee649997604f151c602c82900a8205d8f6f670c8684bf5abb5f75ff29a37eb9bf8105199fbbfb4707e162e64c715270f853e648b0aa26fea0f6db562896bf424a9ffcb292fae85b76cefb8bd5a4b3ce1fb39bd2a50d0c9e6d933e167ff629b8a494f2a9b774eb303c781ea02aff1a8afadc2465cc616968015ed6a5a33c3120b945ed5351981e32fb9fb96b2212dcf8fe9ac56e3cf41dc524f800631020b025919178ce074eef078d6842012a276efa628db54058d1eb5b5b705f1e1818d2df5164baabb0c61956ecdb8c706e562fc4fd64052870530ae425b221f89dd6f90dab882e763e7a7ffa141bbaa8bf7a3f21b0 +SIG: 112f5c6d3bcb3dd99346d32ad69cbfac3e653bef29c68a33f43231f66cea1d0a195427d6e10c0e77c5d55fe2794287ee32e5e22bafbbd8052ad3606b90f94505 + +PRIV: cefcfcd1cff4d8910749279131830b1da19dfc5245f78ca68b8c3c1b622b45511d394abd1b4ed1aedf966a60efd3ff882140a7e56b428374ecb443289a9c7f00 +PUB: 1d394abd1b4ed1aedf966a60efd3ff882140a7e56b428374ecb443289a9c7f00 +MESSAGE: 5ec94ed06fc1257ae9c183ce56271207aca37a23fdb4b0e74ac9307a1bb112e05ed5a5d047c93109e2e59477b03378346422de36714c2961bb9736a513ca3671c603a68c2be7317b1b52a076dae2aff7bc88cd5eea0aa268faaadae539c938bb4fd4b6069b1945eb6af0c9e6c8aa5ee4a4af37e90c67e248e8d27bd7f9589c4d30e905651baf45364fa049957ea5d9b7146ca68204e5e973d0f1c91a1c4bded66115028a71114f0f4f851bd115faeb954e3f71a01470b2481a0098d99f9d74898c8ba0287cc7834155214173d1fcbafcfe9b08250384439476055883833816c9524cfd5744aaa259db7ebd3a6aa20b5a6546dadefd140668eb0eccb5f668db9fc62983df980850c9d19882a17550d5dca3542cd36003a0d03cffb04575a3e8e1d07015c7b30eca9115cd2b72e46dfddf6a4dda1faa2dbdc89000d433f6ec9adc46146d939f32121b99b28983d98b9dde8c3f6e5779f2b0700cb023db13de656e0aed1da2d5c6ba2652343648ad420f6ab9e55a97482a1a22b3bc2ee598629abad9547edb5ff790990564bd871f81b24b12f2bf8dbdfe7a88375fad9ccbd9fc0ba1d3bba5e3c4813c18a0348aad83fb1b82689054d99b4600dd1760d0dcce44757467bec1946406d530 +SIG: 7d83ff66ec79307b1c0c093fda3968a96cf6044f5c802888584018845e7caf2a135ac6f1677e84d22e458e227e4f930209919bc11b12f7aaf2b8c94302d64200 + +PRIV: d107cf26f527db71a206e41d17955321013225bb20f93e12df3dc7399e720ca3186bf453c95dc0a2fd589a78e2c80040b3f6ddf9a6f8681d146036cf2146e8fc +PUB: 186bf453c95dc0a2fd589a78e2c80040b3f6ddf9a6f8681d146036cf2146e8fc +MESSAGE: 78eb9e13789928a74f360141728ede98389685c836b91fafbf1a7e8c19cfbe21bd3c3d6c6ed83c409ef693f1d735da3fa466497e19f38e30fba2a1023785459070e6e92c1cb7c9bd0c9ba61220157866c3bed2b01e6e6b9b8dd3f0c47c02f181346a0a9b9b5d3d7e18a94d6956855e16e8eaaaab71b10302f35bd8fb1f9b5847304160324926645b0582c2f2f1533a24281461514241db2850ef31c5763b2e3d4fb18fc6d8c1d7e52f7c13392c17e27019ff60008e431f1714370bc0efd9452a61f5c56488d91a185037f1f647f72fa785010d5d78f0a11587ccf66b8088e0e635fff3774193b2edeffd92d6e8a0321128ae64cdb862e631e2ee5ba0da44bbd589dc392b5a113b86a727a8ddb698a334cc668b39b1cde199b88837ca5f00f553f89c622834273641d39bc10c6a24e1eb42587542f03fc1627524ed6b749391f11028706c42364425b2caf20180e1b802c744b49b7bcd9bf7b15c23a0bf1c6965960d341554e1966b6ef82fcfbbe41d1e09d741e309254446777f13c29a67b8bdebc5f7f04d160d60e332e3d0441a0f2f7b192c3e2bdf6dadec2a424f88669806236ee04dea692bd8bb6f91ca0682ece349142575358b9b7be70600b3cb81e1456ba0799fdc01ffd68623 +SIG: 8071d97f324f10358f13ac8c61d424b4f300dd0419571c39e40d99aea5f03140e62ab4c97127ab33e98269966ae1d4557e459bf7f597b313f351a20122f0660e + +PRIV: af7ea8e41c8937a4ec475ad81371a171d3d0f9fd7519a04c751ed4ad8ff8fef915dfc71585bac71ef20f374987c555a3f2f07d6b9c787066c10d63cf06e02ab0 +PUB: 15dfc71585bac71ef20f374987c555a3f2f07d6b9c787066c10d63cf06e02ab0 +MESSAGE: 05f2263f0245ecb9faeb14e57aca436668308c8125df3116c4ee20501d0cde701b366e2b50a1c5edf484144ce16bfb1f7d26dc4275ea9732e264ba4d4a362b40275ba47377dbc332cb65e2f4c8853894aa878a4c175dc5b3b2a757ff3c8d7de660973b89dadf076e2e4fc76239b7bc752a229d44e000ceb667104cb0746bfcf59d69603ae7fc1bcf11d2e33f61dc497ec1b0bd5e4f1dbef435f2f291f30b00a85e833946c8b10484e4abd7d60bdbb1fe6dff5807a53bb89382153013b70ca08efc91b7e9fc5b5dbbb6af123b57be2e140fc471a45d89fa8284cc27e0a1fe771f55598bbdcf068d506dad0a592179ceca39ee9526f9e4fe47bf2bb14fb1486a677d4d7b99a520545676a0f1fa809049aa2414ae7b817d9a036e5c157886e8341d4e819c092a3b48b3606b03acb727c6c2217d0af30121546a94af6b49caa2a8c9b1786fa0c2a524ec7a023e924b5f8a89a53780c7f8781c5b8e869430caa0e6d0437967e3aed44f45c901cbcf1026fbbd4e3dd9a091ecf8b34f7dd5038e543dc7eb6ad5494efb145cf63ec0d355bb8e172f455d8a6b13dacaaddbc56e47de3cf762a1a738ef092f1436680467b5cd82e9e36e2d2b6842b3bd5dce77180ddaf0b643378e698599dd47f5cdbb +SIG: c0f1739167274bf91831c74beb645af790459b28bb3f21325365130f409acb66df1d223759a9758e08fd7253737484e285a6fb47404abe2eba5ef249fd025c0a + +PRIV: 0c57cbfcebde10ede02d1cb01df360d41f2e66a50443d58b5d4f0828c9a18bb7c4d761ba189971b9462c61bf46a765f88e2ecaa5bf2211220afb00ac657f7ce5 +PUB: c4d761ba189971b9462c61bf46a765f88e2ecaa5bf2211220afb00ac657f7ce5 +MESSAGE: 337703243ab5b4e4d3481ee8dd1f4494507174412658a93988b5c30403a7b7ed8522ceb46fa1ee02753a874ef0675d397c575da0b08caa8cee3393784d0f0db8459837af90b9056df4e38e417f3ad2eb1a100ef207ce2ca6c610018021661e307099f2b7c4ae875991140bdd3f0f99ad2c5d55aacb84cc1cdcd579e08072b6951fd45ed289ac9ff7f0986ac88a4fbb9dc9203d9baf180c90edf937258c9d0a6d48e220f72d250c7f2c777eaa7fb9fa11d50a5798772f9fd976b00599f1f0276f3a2e4d988ae92125467a8dedb7a16f9e3a56e8d00662b3eb67a35b9b60e73bd935077ee238df8f6e833b9a5523386826c1f2917b1c3ec98e0a5fde89c48b1d446da5d0c885fef0e374bff30a997c7bafd5e743c85d0c6aaa6ef10a061211a2327c6d84eb747a56e9bf60fcd5b553b798834d0c5ccadb9d4b54e7237d12c679c193a287bb2f511cd4ee2a2d8549b44b21c11fbe5723381c6c5f784687fd90cebc5b495af9e414f2961b06a1c8433b9aa3292bcff4241c227167f8d1de054ba33ad81da3eb3ec6e40a6e26854af349540171b75d75fb9a8d12937827fd594d317b7a8d9f1c2fcabda56375568c3e9e514c2efffc3878363dcfad9fd95436b022e8772a88cb71e803bf90381962 +SIG: 8af7bbe01b8ab93951d16fca05a9c967d1c52c974bea151ea72e4cebaa20cc783bb61d8d69385cac5bc6d72dbd162beef1fcb5dd0e0a08b48ca0b9f6d9a9880c + +PRIV: fe7172278364194bcfefb4783142b79f59d5fd978b1e47c314d78d4cb3f61c8a2e82cce47910c7e2a79bc1f419dc3c3df54f23291fc8193e8258ccd2fd38d548 +PUB: 2e82cce47910c7e2a79bc1f419dc3c3df54f23291fc8193e8258ccd2fd38d548 +MESSAGE: 23509451a059969f2b4bdfcee5388957e9456d1fc0cd857e4f4d3c25a4155d5ee91c2053d558062eea6827950de863bc9c3df9672cde8ba741744ebbddb45ec1f4284570fd0aacd07ea58c581be2afc95ae444e678edc2a02439f387cec982ea3a44814a8a302bb3bfe8228d58de039debdf7c2a7eddb4e71ca474f94f7e2bd89dc65b1610733c91fff89bd499f40154a6198fdf5ec7ad3722d925b292196c429499075be0c5b6da9c090c0791a7019eb5e7366be6ce58ab2f04fecd9127c42718047bf47030691521312c0877aa3f36cc5fbc9caae0fde3945d2a868ee2502a3833208eb850a163cfcbf6da9ee6ad9fe067fe241986fe4436d6ae4edc61561938e2a33f4a33db63f69d3f1a8850ed40028869164103488fb795cd82ca067fe1b4897caa49a7ca9a80f3a8151fd13bbb7ff350e8579f565dc1c4a9ca938d27b15b3f858ef45d3dd78b2c358635356315f55a97528ecfec5d11a5b721503107faa406c17034e601474b3b60cf48692e269261158fc353d4df4274381357790b7756087b00cc79e3b9d28a3f2439febf199e64a8b37c91b5a4334e3354e8faf3a361e856c54bdaa43bfdcd6ee6c9f9679588f6069950832348aacba2bfeebacaa2071ddc7d77898ef0f68793cd25 +SIG: f6c2a4296b9a3407c6d7a5679dae8666b503d1a17eacf71df493791b8ff0c0aa8eed36b327a29ab7828f46f22de868b628b1cfd501e8599fa31693b15f61080f + +PRIV: a951e4e6ba9f1f0b354831c986942448faede37e11b0f247da2706dceef73ac730362014974bf75c8495c2e271e713d57384384d0a5da88edeea79279c0c58ec +PUB: 30362014974bf75c8495c2e271e713d57384384d0a5da88edeea79279c0c58ec +MESSAGE: 20577dcac89174885eedb062489cd512fa72863ec5438e31e95878b75ce2772aee6290a0ba3c8f642c1d0ef55da8d5bc1484f83bb9876c7a8c0b6b609b94d112a06fc83ce8d2c1e08ed6c735e57b244aad6ecf7075363d565ba47865695c8423510909e0a3db4b61ed7aa67a7471331e83a0c58b8220a6245f65661549c1a12d4c0d50c326fb94917cbd07be51e83fe8bb3e46ca01b0a260daaf1d6abe3703d6a925113bb4d57ea1a48b4c7dbdaa03eea814a4b5f02e1dfb545cc623fe17a3bb18e4373f5f7ec2fb5217d23e4fed54a772e11323e730aad7efca8c464400e7679055fcc125a876ef7b8b9de186e229a7abf191d0c56d91815f67872e957bfbc7634aac403576a58f427bdbb30e8c4b6fc6c447741024ebb503a5a9025124a4887f825a43ee940f210a1bd5ae4f6732d60f95f2b83201c4c6dfe279412d7502a5211f8f48f800db30fc3776c4ed3a38bb4634822c98a6d6dd3233be60e42cca45a3163cc84e9e8da647c0711bc4c6ccd65aa1e972c07404d103e74bcc31a7e2c3eea5ac9257ab428947ab3dd3fb153d90694a4073373c4dd9ceb131154fe877473fd996f424f33e316e4eb02b8c7513be6998e516cbba54d94cd0a435e0ffcc2c0a8ef72b630ec24781066aa5efb9 +SIG: 0278c86a15208d9be5b1e1574761861b8af72ae08d40cdcbec354e65a9c3d0a06b5fcbb297d09bef397462395986c3093eeb22644c003c3078178cdf674e990a + +PRIV: 38a9b2d49ba8b82f301a5772cea0efc2218455c8b218b22cbaa2aad2d7ad3b359df5ea1f78f810a521774602bbba4942f0459238966c8bcd21900afbf3d84293 +PUB: 9df5ea1f78f810a521774602bbba4942f0459238966c8bcd21900afbf3d84293 +MESSAGE: 1778167c49b3a44d4a5ba838b7388553b1e13d36ea4f86d30242e1a822a3bbaff5cea63e2ae2a4635be236fef2b8135d14fb621c0bb773c9c17753f80926eb55d0f115bd09a885d844b818c9f04489a331bb5e032b8e58cda36949c5a8d08b55bb8de965e1f90d3b9cfeecfc6ad9a4ee5cb4047e9450acdc64640166a8c069ea849aebddac1ae4afec91ddd17fa5553fa87c56f7e51ec1cd6b5cc23351d057a4ce4a8923c8ae6ac7a8afdcc0881c0e74ebb024ef7296162cb93c68e50bbb074e651ac87dac9ea59d4c3fbf0fe379f3e97a24566ecae54303bcfb6f0cc9f15f6639430e66b19a427849fdfff833df02689e9de44006c903c559183459b9f4a97f54a0f2a28df7b0e9deeda8239d7b516977f5e7d6971b4502e9885f750af8d1a6669e25e77d5f327c77c87a86e0a1872bc96a76060f5f8a0c40cc973bfc7fe6ed9bca78f884e6a2828b94d489d32a0fd337e69db83fb8789afd4e8ef54c22a78c2587468b9ae071bae3b202d3183ad5f0f8e842e5a8de85bfff49e03c8381bca7fd4278ddccaf0134fb5593a395a77a5cbd434593bc4ad0ff4b8400ec674c4ecaf1d57754be0cb2fa9a6441a9abad7b42197ad82e50827e4a4245573a8f0ef87f58228a2867f4b3b834b6635037940a +SIG: e19e62ac539a9ca251d12d4c71055b0a3f581d19f2682e672404c78ac1f12bbefc91519276a5cbe16f520cf7a7f687a240f0329157c59f50026a58dcdc50fc08 + +PRIV: 9a1717873689a03c112dd6b4d76ae73b89b416a598ceec209e27961e7bb1ee8aeecad1e0e4b863291881a8c241db9ccfffe4e55d8b5a42f307b4436acd0649a6 +PUB: eecad1e0e4b863291881a8c241db9ccfffe4e55d8b5a42f307b4436acd0649a6 +MESSAGE: e26580470901a07ab0931aa23829802ce04da59fdc2f773bc567f1e65b4f2e2d4a1a6aec1f54158adfce9b099790b503a13d22097ae23ebccf923f3bb1986d6e49111a8cf0d4eb8236bfe0d7c9e93a5efc7feb8e6a9cd1b8d921efa21e449ff49e06c1ccfea31f93e033c3c2a54ddb0f653a09fbd18a70b56315f193e7be56e5168f59563821d4bc3bbb0eaa2048286bbeee5aa3f3e7536cf2b750fd322602bb3847ceca39b75474322d76b1de80fa2eadba152d6f8f020d4d931c53f0a2801224d35deb6ec13b014873e689903607de96d9b7a743a887d2f48daf2ed2eefb202abf6082796981123b966e936dcf3483e2d24d694ecb865fbeb6969f347027fb8b175d24a4c045c0bb4ab5e02ddcbe77d4756c46d137b094473a02307a108340acad9d03bae8403af199cb75cae3162f3815813cc68bf2a5e499e594921149f3bbd214da5137e756521559dc80d9a4b74a0f4943022c7cd5fca42315e0bceeae9069615ce67a04382412313a31d67b346c329ad82e742c0a6ce0a6a02454c113e52022f3cc03fda691ebdfe14c53c8ce5ca9b932ca1a386e3eb4e90a4dc6e8ad8533b5af1aaef5003128655ca64f67fcd97c6ac803002404900bc0fae98463bcc31409f9981748789ade2d07783bc32b +SIG: 1af8be095538965800d8eff6d723d028d65d0e9c6eb5e9d125bb3b1783f11ef7079a49a807e27ef1260be26a3b231d03b2ae151e49f6f189f15b1c83eab01c02 + +PRIV: 43bd924db8156008c6b3994a8130d427d514db8a613b84dfb0b8e0de6ac306761b3461c269d5b0062d5df6fa654a2586f647a0684218a06e5e2f7badfb394131 +PUB: 1b3461c269d5b0062d5df6fa654a2586f647a0684218a06e5e2f7badfb394131 +MESSAGE: 6184e6480c42e96cc877269b16371545ff9523c45ea88e76a1348c68ae7f318b088fe4610928239185b6b55bfa0f43644c4a4c97c56ed77d08b1f4aad2f4aa069994abeca96b7bf81b8064ea4350d8a8b02297a51308b61c57c8f1873c6f97007aca3180429e730a6643f28733547bcf7b9adfe327e85736bd04af7f1d9f4fb84a7f3affdf4e22b574ecb4bc8836b10b8453aeaa5c1bf132248b826cc5230f75e075fac9f037561136e00643d08253e7ad652f702c0d15b6d7d48aa6f8e9b5f5cc146e3f156fb2522751c3710041bd922f37a50377e028b0c4e4bc3465d7c84af6a5fb427acb3b41378b102bda46d8f6f203a5ffcf395d435e93458a0b0a4c2e7782fafe119f769f67058c6677f6d10d9cf5cb8748e1805798ed233f6f930eee0e5075bc58b97af9177fda75d53708beb04dc4f19a43e768074609f14065f48fdad5077ce109bacc357174a6b7956f6e7f32e38415be526370fa58c3c0b31f51e6cd4b2cf27f8bcbc21259d9e5c3b5c2946a9fc1b00d9d15c3b7d80bfd9d05db91d249d3e42d8956682044548d83bda8d5cc9212442f30b45cf4aead80cce9b3512c39c5c737d3f8d747afbab265af5eeef8ca9362ec76e943b0a0d7a39f3db11eca14458a7b592e5e4ff2275dd48b2853 +SIG: d2a05d88d9d543d94d57ec88ae55681750f20b9be9c1e918cdaf457767f2948dd629e94f068edcf3d9927e330234badc3a02fa5ad3d9d85e948cb0b0cb3cd70a + +PRIV: 8fb086206dd95a2621f598560ccb281f8273c8fc72e23611089baac89d3c3c7820276ef479f4d4523ab77420d424e8819c33c83779ed80c7f666e8f4403f94d7 +PUB: 20276ef479f4d4523ab77420d424e8819c33c83779ed80c7f666e8f4403f94d7 +MESSAGE: f02903ed4266e849a4485205954fffa8a108c323b7e3f84331043514e48556ab019497233a5a127bff3cd7c97086becef538b3f339d7d06e532dc7325e597ae357f816dea42a6a22c79d22074a2e1ad8023c424b7e096e5ad8897b05ef7d00d30a04aaf2981eddff2b347f1e27e20aabbe7e7a9544978e092b00cce420aba06187374ffbb37b4c22d75f04e57590f610a27347286c298312a6c9b1bdf24fbda8513c4f8356ccf757068ffc11bc65113783a5dde7722faf4ceb19fbb62f40702e2c6e6a8bb49ef40446450c4c59a2990944da4744f6ee770b930c246669813ce5a9f5a47dd80388981bfcc3a56b5be2c4c7e659a2e9182dec0aaafe9031aa3954d4fe7c431196a561a5b78eaba64f3db1b586c53b16f679a84921a642c260e4653a61de108ebde6f7053afa2cb3f3668ede121020dd1bace8418aebac3a5bd5142f105ac26fe49e5fb140c19b22d54a6291dfc954670247881646874defad814995519f6260e9774a8d185c37881b4f2543c4b63fbf1985016ab41c4d728cbc90b3ab876267bed41d0c0902f6b50e8fa906fc4788f7b820467306e0fe9e036a0a00f804f91c3ca718b95ff6d9e2204bc3161bf70fcc17b2964b56bc612e29402d96f50986514bc7d831d58e42793786d5806f +SIG: a9305e001600d597d05ef671699bf09f0dcc0c44475d3ca31e7ff1bffedc0c67daa1f3b76a035948c59cd87f82453a40950a1c9703c2e7d9280e7303966da301 + +PRIV: afa1b846c210b52300e97696f81b8ea774d1df12e612527c55747f29c1937396b609566bbd1947bd7afaceb14389e836227169215fab66851aa5d70d6e2e3b89 +PUB: b609566bbd1947bd7afaceb14389e836227169215fab66851aa5d70d6e2e3b89 +MESSAGE: 4cac1b1f4bd48284dcc9afc8b5955b64b436db704b0335d9755cc1f97477f8d323cb6410ef146ab8a9efb9526d8b62e3bbad1f7295f47ba9f0de958f8ec9b77ab42232437ed974856444cd22e20be35e91813bff4b016f810d0f61d89f6b614db33f34bd09985b593fe3e06e065b7bc6cd39d55c2cfbec7b6d59c0b37dd1d0d35135ab1d1b04f2f30c2f04f4ba2b36582738081cf59190f528363db944ed612931d1d514c6214f9ab92abb1833926183ac52fba2a4551e20e4c0ac959a49ddb167a381e0241d40c086e90e52aca017258975dbab2ba451ee539a718f076a58709c6697418d9c6f13e4d391368bf0e8bd8f2932dd95ceaf7aaca1241147d341a3acd08dc32905483572b89a80cc47231468ab8de359dd525a6257cf196c2ecb82fa8a78aa3a851c7c96ca25bf7ca3dcf3ca21453d0dfd3323d5a422dec84316102f684c359f226bb53779c0b9950939281ef79a58c011993eace085497afa4daf64c9687b0a11aa116cfa7b03936241a5567b646e7e42e9fb592405b8fa3c0a821fc3121b45b1753cec9a83947d211a45499bd63790b87f01472fe566d87696efedbb74ed00048c384ba7f027b3aa4298dc4110349fedf52a96cd05d08bd635771ed4510738d8f07a6021244d1903579a3ea739 +SIG: 98b0c6313cecaf7c82cbdeb3d0280641c61a060f65e563aa93ce18300a9b58272dc8680b485e8cd11cf80fdca868fab365378384a142727f2f844f87cfdf1905 + +PRIV: c85913a6877877131001623ccda9cdc12b9d4043b8a83793c44696632cd6421c9cc67c6948f7bf6e556d0849d3b8d203457a7b61549b36681d754f1dc0841e96 +PUB: 9cc67c6948f7bf6e556d0849d3b8d203457a7b61549b36681d754f1dc0841e96 +MESSAGE: 91b5009e83d0f6103399c2d3feec0084973a305bf4176ec782537560472db187a11b4dcb4b2ffb7f0644feb394b28e5bfe97247c4a4a231cf6e916bf99344ccda88a7f5d831d6de3d563dd102eaeb108c5bdce44e0632d17e6fa55b18067df2fa8d200a9869f6aff920c51d46a1ced2d903b1d9b6b075facbf91cd05eb41ad811a8ef40d9118261012c72b8979f15153dbb8561293da9f8b77c8ff14f75387536f0036d1713a72ce8c35b1062f2c6732aebf32936799b51c2cbcd6572413e7dfaab8641a02c150237381cf7a14e22c74c6c20009de7d3b7e69cd1b4584ac2c01babaf973c56b3814bb0089720e41968106cf26509d4aa546fcad5534af303ffca42b16ae6c93ee06bc3cace12e4ec718844bd30d2224cc486d106d1c456bfa165ea0120fab3df2c5ab3a523bbfa789deed44032ab0be86eb7cc09cdb7c07aa948dd5277c3df1d9d1843567dec84f9288e085b05ae4b8af2cea5d9a184d50bef85550c836613d5d3af5f9c2928e6a89660fa62719ebff773e46b77e34bc0470da4d2cdbc7071da758c4d39fe65201c88aaa8e6603d0bbe7c3e9b2d9e41b634682092f147341ad6d667f20c64e81a68d629467a54dd86e1ce12c560a6f9b64512d6f3886cbb9f37c37eb3985c8ac38dd6682f48fe1 +SIG: 01fccfdb1fb6888b0310a913170f7e366816daebe7650d72513d9506e66f7d62208a49ece0af1871497f4541ef605bde711c9e0a1205ef48f26c03dc1ad4af03 + +PRIV: fa1e11dc8364208d8e1cb66a361be7e84c5e368166587d4fdb06aced7f62e17c4d8e6f4b3415df6cedabfb295c1984fd419923c6ac41764e32d22daf372c50fc +PUB: 4d8e6f4b3415df6cedabfb295c1984fd419923c6ac41764e32d22daf372c50fc +MESSAGE: 294e63bacccb801bbf04c1f19d0aee16f5650a6e8eea6fe41110663ec01532bd4960a527f15eca4af2f4e6b7b0fc340cf97aa234e92cf7d69d50e4009c2496e3ed4d9aff000f9e185275b817d26a0bab69b7f7ee1ea30daec8bcee387ae46b4b299c27bdc06eea63f24dbee955a6c0969037eef91c34321e3c5c972fde993183b7d23f6e019c3e0cac7589ae4a1521af87ea42df8c22c2270ec23d6d140f9cf6d4d52fac1b9d6c8939ef8131cb62a035c5261538bcdfd6db419a55ef9fe5d7a5ac44579de700858d74a3434844f28342c565892722e27f407d7f17b74a5934be915b20c2400643235f8ab5795f324e33c50644a04033542cb3816d770fa899e7311c14301c1bd0f5aa60a2eb3165680c720e1efa8096fc25d2779275f1842b2db53b4da0ad3e59c07540c28460cec1fdd3cdb7a3478b91a9caf9ac891cdf3aeaeeca9a9656ac1307259922fca74c5cc69f7e25c6bf587973a4b7d3e3ac0635b0db22a0093a79076881c71736ee1d4d45f8ed2d29a0671a64e6ca2f7a5ef404b1edeb842034f571b699bc59e5a37df02054e8482bf1e7b77d8e8397da15d89d7355a5dce86b1683a9ac4e406c08a94a6eb00e5ae16d96722972e5c50c7bee4a84d0697bbe67ceb7ef295f06aaea5abba44466be0f67 +SIG: e857db087e28d6750bf54e53797251d8439989576c12da2d9c811a14877c3bd46c4efab861a10eebe7da04c0b0b445c7a390a50c13de36f3a3c7ae0157022c0e + +PRIV: 24a914ceb499e375e5c66777c1ed2043be56549d5e502a844710364042ba9acb20d21ee764b1f35f94568200d63bd5828aca8c5d3e9047d23f478b925295fa2e +PUB: 20d21ee764b1f35f94568200d63bd5828aca8c5d3e9047d23f478b925295fa2e +MESSAGE: 3ff9f66fa2646ec66a1bf933c2b4cc0fbf912b4d6db50534257f97d01e698d05485747de2544e9f5a4a4a075388cf4400ab89b0353ce86198202db3a903767b879a2af9daa155843111af15a2bc35efe41bcc92c8207e00113b04f1303007949ffb6ce8df4b0b34248fedf5d9cb2cee94b812ed58ece2a0ce0454cf14c20e49e09fe664d6e25762e87895932cd5cd32eb6a3abb38ee163078c133e93588791dbf6af499a31ea4453bbcc7a85e406c9848a664052f11113fbb4ffa760dee4c261e396942491119da29a33582f821d4125e0b4162f28beb066031a652d05749aa7244dd4f3d3bb15d268328d6a02fce2501815257f8ad5af4ecbe7cb8ae9661e344f9072318791f3e859091121e08aefca8982eaaf66259d9de4f46a31e716dc033d0f95d1fa936b6c6079b137dd1158d1def113018c73f8ebb9807e0f7415404ea9c78544ace7ce463cd1d1c57e31f4091bc091804cbcddad0e15a40ca91acbe1c6224ed13cafb4df2c84ac9f0c3c9b546007d9dd6e524c467072563d4ac0d700cc1bf30febb334313dae5761745ec0a5e9e8815025958f00fa2e58060d7e9a5f2b727f48699f929c8459930892573f784fef5692518b5ca268e2a73ebead6ebdeb7ec24eac92aa7dcb41b598bd6eff3632d069726291 +SIG: 3ae0cc7bca8d73be83a9b809b13338c12706aaef75c4d1a478178f9dc565514c7529e298043ea78d21a5a09dd04f10ae87441e5686a933c92c75548427ad3a03 + +PRIV: 5532e09b937ffd3d5f4c1d9f1ffcded26ee74d4da075264844690bd9c86139945093969f377bec3e35f59efda01ab4186c5d2a36740cf022675e01096b1a3f0a +PUB: 5093969f377bec3e35f59efda01ab4186c5d2a36740cf022675e01096b1a3f0a +MESSAGE: add4d7a9ce3f63d1f946e8679065545d8c7bf0a2cc3a4c00b8f142f0945ae362c4c9462a7576a4059d57861662884bd80b96d90d279a952eda952d37d4f95cf0d70da98f4fbaca39e169f9d945d41f872397bbdd5701454303d77d31e86348271da40a1b8f1e57c36fcd803e14fa17716c5631efa01d3a795dc20b2bde36ab73ff6a2d533bc15cce22328713c3c9ccd072c3e450d7f22c0c9f94919752cbfe45ee655d1b53676593cdb448704102631caaa976952eaa1f6c2e876564e420f0c646a0f88365f76415b4085f60a338b29c51633e540f0bf32d4087e7d0fb685be88c7595dc531c99b489584560ad8234b18e39a107cf5d842dabd421e77d26ea5e0f1405ce35fe792714eb4ee1a8017648ac1ae739a33d7b1e089105d1e5add27a62ce64154570340af9eb14e7fdfc2f9a2c2fcfcdac3cc4227763f4d629497479f849216e5d90ec16dfa36b72517f7b5486baee7fda4450c352cffbbae73926c843224f8ce44b38dae53f3ead21890b52a7801075291684fd5910ed86ad33e8a007f6c3f85c16b209293740184f5890874d431cd4e0ea4087c49c3471d789c813c6dc9a78699363a1d87197d3b92c0286689311823f4df22ce8035e75732cdea7f5621f67db0e2a4ca6616193221c0aa3d6de50d85282ee +SIG: d527ff0d4a219d61f418121206a54ae4985854a310482744486e4d130a7de97c319df8372c82828c936e6a8afd9c5de1828573d8261ae9365b8f237676182402 + +PRIV: eb36511009d37a9c46c4d1374d0bbd0d9981e78cee7d188c5aab983ec239e10cb1cc212b4521bbe7b19a7693878a558440eec36205d8439d040a46a9902fbf55 +PUB: b1cc212b4521bbe7b19a7693878a558440eec36205d8439d040a46a9902fbf55 +MESSAGE: ba2466e56c1df77f22b6f0241fc7952ae9bc24756419a9446dd2b49e2cb9df594e5b6c77a95aa5fbd9dc57fec83962c7751eebb4ba218253f916a922a5139663e3203e3be482be379ca151c463d9ada21446135f356994fa5449f084478f5bb4f5ba6145c5158eb7b1c43c32ebea25e09c900f01ef91e92f88c03c76504ace9646016ffc2789559d0f3cc9d00fb61bdc6af7d3940f302e588e04f79f7b3d4b91a5d193a4f8222bfeb69bf0347d98ad81ef99d130ebc7b36b0783394eea92a38ddd5e7480d2add4e4def53eb99c449bff94e4718b09f2ea9b1f2b886594a95c33a69e0333154e440ab34b7b6c1134d8179b6f0c56251a9ad8e1b6b0f9b8a5c97081a7f8fd05d0b0affc82dbddc8b0c0ab7e833f300626d4b973b3f60feac55571e89cda0f2b441ed2faa669a70d556cb48f9b1d1cbce32ede5d166b1143e264b11ea327681cb559edd13c364bd2baf1fd54bb781807bd59c868b0e4795a779e67f0bd0d14b5a6b9e440b57a5823328b59affbd027eda7dd785079c5f02b5e32890b038730986a39a5a9834a3fed868b6f45cbdd28acb2709aff556263864f9ae1e757b3278c288dbe2932825712773e431f7c29329857fdaea798ed93920893631402e6b13bab62b4855461edb94620f2d1751865f445c466 +SIG: 9f583724de552eae82f254ac6e2ed483ec1a07346266735c490920690c1e3fb2a9e9a34194ed6473733b300d4f23c9aec0da5a2022054ca43885a15a2984320e + +PRIV: 7dbc81902e4eaab3077540f559995c387403cac306d486e959c5eb59e431c0a8e03066139082f613448bdbc27fe53aa3f88994c31ddce002e36bbb2963df3ec8 +PUB: e03066139082f613448bdbc27fe53aa3f88994c31ddce002e36bbb2963df3ec8 +MESSAGE: dff798b1557b17085a0634371ded5ddf7a5acb996ef9035475e6826336f64ad8b84b882e30badec2b4a711998752f4a1574bc1f89d4325cf2b39861044dd03691e71d07768b5933a3052cc7c81d571a9de061dc19026c2f1e701f2dcf26a88d3401bc99fb81559dca76d8a31a92044a273587d622a08d1cce61c8f948a34ded1acb318881c9b49f6f37c30a65d495b02d5429e7ab4040d8bebeb78794ff736d1511031a6d67a22cdf341b980811c9d775fb19c6478f05ed98430103ea24c0f414d4cc07d860b72dc542ff22d83845a42f8ba45ca7ff3aab0b1e7de2b1094deac08d16eee01969f91bc16fec29ccc061c54db5345ba64842dacc99ee7729468d80a3f095583d8e8012408519d582cc3ff9a2eb7aebaa22db81ffc78ee90ef4ec589dcce87118dab31a6328e409ad5059a5132c82df3cefe2e4014e476f04c3a7018e45267ec5018ecd7bff1dda9267e90666b6b1417e89ddacb5085943befc7ad2f4df5f1ee0af9431aeeb6b24a5515b93dbcf68640f7daf8c961e567d7534900205c3df2184b6ac2da961c4c1d2bc49b4ea96b8154ffd4efffdc5e55a7119cb8af429e85105dffd41fe4a2ebba48168aa05fa7df27c4298735ff868f1496beb4b2ed0b8980c75ffd939ddd1a17e44a44fe3b02795339b08c8d +SIG: 5b7f652f08f229fda1b0bd759377b3fb726c1b9c9a10ef63426d352dd0869bd54d876c3092f1cd411c3757d3c6b6ea942aa70c3aaeb4217a4c7364d18e76e50f + +PRIV: 91b095c8a999e03f3ed749cd9f2faacc0076c3b477a87ab5ccd6631738767446dad174d359daecca9c6b389ba096452ab5ca91e6383c6d042a284ece16ba97b6 +PUB: dad174d359daecca9c6b389ba096452ab5ca91e6383c6d042a284ece16ba97b6 +MESSAGE: 9b0d8b00299852d68bbf497fe603961a485466a99a5484005db73d4e4bad814e8574efd54d648bd5c91ae8483c54b2f998b02e1abd6f401a25526843a5f2a23a97bd589d1f7e1ab14915b1e359a396d352c360ae6584325ae4bb7d624f61255c5c7bf0a67acab46c3b57b34534c0ee8431d260576606cbd84d8d1839e73da6fe4b0b8b78f0f958827c2f1d93ba7a346dcc75cb563dffde26f997598e8b5c2f1617c6fefc9be4b28b5401b0006413a251690d1203aaae4f6d8a3fb21f24009ab3bff13737a8a7e6646c02732d9ec5a4a510469e2d299e4cc1ad6480a482aa956f89ddcccc64a136fb15b876b6ecd88c7c86a4dfc60e666207c604167d163440ca9ab9cf87a5e0f7bbc5517de4dee876c037f8cc9d959c8ff5dbe944ff54cd91a771e29231f8b5f17d61de904c955fe2025dc52ed480fb3cc90f232459c607ef7e2adb52c7482becd67ad2149a4128f984038b58aa90176782393604aac74c18209a3d6a78630c01955a7cece5da8384da3baf63aa2ddf5963fae05ba3b81c6a03d86a00ef78edb4184fdc89b1d6bfeb310fd1b5fcce1e219524a3cfb2e972577f06b1dddeba00865dae4979000c008ad99f3b638cceb8e8c7a0f998d34d92143d81c0e1c096a925ceba65c43003ee18d494d003e9c61f77d65759 +SIG: 64ee9efdb0c2601a835f418520641e436c7dd47c333d9fc30cfbb9e390fe764530654708b40b03581899a9ac870efd766ffbb4637152f8ff277964fe35425209 + +PRIV: 8c568b310ace7d1f0edecefd603a884000544c792565d481c3d3e06e2d82ca965fa6e267c766736841411072d1983d1900acf01d48c3ce11770b26f78da979f7 +PUB: 5fa6e267c766736841411072d1983d1900acf01d48c3ce11770b26f78da979f7 +MESSAGE: b59f5fe9bb4ecff9289594721f2647047b0da5e0e4941bbe57c5b722b476723f0ac5970b4111f893bcaa411f28fceb4f585a2a7187018a904b70ef8fe1f6569a54d00ada37b69cb5e9c9d26c16a903518148e04a1b936a32329c94ee1a8fb6b591892c3aff00bf6e44dd0a762babe89d7060c17b90390d23bf9d360a293b8308383086916e1182b1ba4336f001b8d20deae9a029f7e85397a9ae5cf3ca10c7f3875588b8ffabb063c00ca26f580f69edc527a1accf4f41397b33766bcf6d55eb8de081a48c981d05c066617b80d8f6f5e60e59dd9b930bc4d04586403bb868df75933bdd86230e447036c175a10de9bb39953dcb1966a1f11912078e358f48c5b209a636c7f783f4d36a93ad2cc2e3244519078e99de1d5158b3961e0fc5a4f260c25f45f5e8585e601db08ba058d2909a1bf4995f4813460d369503c6873685ebcd3330a130b75f2365fb2a5a34ea63d958a2a867e90552d2cec8c390084be0c108b0fd2d83cb9284db5b842cbb5d0c3f6f1e2603c9c30c0f6a9b118e1a143a15e319fd1b607152b7cc0547497954c1f729199d0b23e53865403b0ad680e9b45369a6aa38d6685abd397f07fbca40627ecaf8d8d30133a6d9d5af009192751c9c45f77c0bc011268800bf552512730e69973c5bf362ab164894bf +SIG: debdd8e5d3112fd77b394aa0e36e9426bac91df126fa9c317cea7c9d45957cdd96a45ae3ad760413ee1205afd71a29f9c3cb586cd2d7cd1e93bc1652fc34dc04 + +PRIV: 3d09afcee3c432fdfb6bdcead54e3da5b1b4165c50d6d310b7fad787b444d680b0d9028c4d1487d293ed585a76bc94fffbafe2c65d980c494e141e4810a35cb9 +PUB: b0d9028c4d1487d293ed585a76bc94fffbafe2c65d980c494e141e4810a35cb9 +MESSAGE: 767165caae0e578f16537e1750be7de87a789a51ff2de11838f564e2580b2391362d2868a5a4708af15d2e2db7b9be39c16adcc1200b34e6b4d4027ddffc1a2a3595e29e855ec5261b20bd55c428b01309badb59e2ca3edb967fc2f4bac0729ddf54fb6c20057bdda9e7af7cbfc092fba865fd3275b9d3bcb0c346b951d170ac9aa650a86df49855d48a1b37ce56c9f27389f5c8b15f5c2c900c4f107c064f603e4f867ef2e9c10a1b74210e6b89bb011793aa85ded43b51b749ba7f70287b6bc1b89434db8b8c8b5d73b214b41e36b528005bfbfe002e21b1006fb9d24babd72106d093e3c7093b3138aea719d69479084647498cd6c9bbb744509cd7da8dd61a627100f03c21e750acb3fcf4631d7c0f618154d2e5fa6656fb76f74c24795047bbce4579eb110643fa98e1f776ca76d7a2b7b7b8678173c773f4be7e182fd24dd76291ac67d9f26a28c5e3cb025c6813a378b383224642b4aefad0c76a6579517b8f360797dd22613ee682b179381950fb71609a5fb5494d2d57dcb00f26d1e72956f4d6672830e05c01b3779677c07ea00953c6b8f0dc204c8dbdccb381bc01b89c5c261db189ab1f54e46bc3edc4de5ad4f0eb29c0a120e437cd8f37ac67d48c7f0e730278708f02b54aee62b72952bc1c0eb437ca8bd5655437 +SIG: 89739fe441ca0ced08a6eb5796e9bdda0e74fb473528fd4907edb659aab44d3343229046716368faf88e85c1644af66ff2dcaf0b17ac93ca13819f3f241dd300 + +PRIV: 41c1a2df9369cdc927164aa5adf7757136abe51395604266334cc5460ad5683e40557834cce8e043580a4272a8804d4f926e88cb10d1df0c5e28b9b67e1b63da +PUB: 40557834cce8e043580a4272a8804d4f926e88cb10d1df0c5e28b9b67e1b63da +MESSAGE: b64b14ba77d239e6f81abe060accef85f0442b650c44015efc43a0aa2ba10bf48d3018b1953ddfffbcda5bf3bbe0b6b3e4b0d9a32c6b725bbb231e0a2704471ee8bc1d594f5c54226f5dd9dfa163cfc1452c61f93e4f8139ab4ce4476f07ec933661eae91b6d500bf508ac63e4baaf1ffc8f0007d802e005f1b4fc1c88bee4d5e9e76384f5a7043bd660cce71f3b67f01f6ab844298531aac73a39d045370088855005a09c6d04238ea478dfacad1e6b22b2be4c46b0d59b1eba1f060bf7da5d1566cf1fdb5c543a33926af63f01a0db86e1a6711c473dc795ab283c8d93facfb5701fa2f2f6bb99f9b7e3749b071d58607be44a7089bcb503ec1495b5feedb399961fd3677d7493eaa3b3e9cc5e3642f40d47de9bfee7c20b0e519c4eb4a40f4da446ed6ac7aaca053e759c97dabe0a8ec2f58e7f2f9b2072762f9f794a6a4e36060b8872bd2c18d06a85c2c141a78293773ee8cfbf154b9930cd39da31b497e737a7750c90a13f5aaa147cd0dc4311f2e34941252ef198b0c1f50827e56c9f16f595aced6d2a69346531495a6499774d360766ca9be5ed8881c0db26ed7c5e6ff3a4f9b73cd8b654640dc96bf43bd426a0f28c9b25fa704d62ff0288fcceffaaebd3ea3097bcbbd778420ebc520a417730a1b5b3b8c96cda9f4e177d +SIG: b8b2752a097196c289849d78f811d9a62fc767278f0c46628b521f62ed2759d74462a175da22403f15020445cae06da3ed61cca6203b7006362a0e198963d20e + +PRIV: a00611489467122c4c164bfb6a616e6a619b9f83c4367206b85d3fbec38cd62c57ab58babb41dc0da0bcd506059aac9f46eca91cd35a61f1ba049a9ac227f3d9 +PUB: 57ab58babb41dc0da0bcd506059aac9f46eca91cd35a61f1ba049a9ac227f3d9 +MESSAGE: 34db02ed7512bf8c67d359e7203a2ea441e20e729766c15aa00fa249a3518fc29ef8905aa5b4670958c6a460d77b3a80efcb473859bbaff862223eee52fe58acfd3315f150f3c6c27ff48fca76552f98f6585b5e793308bf5976bad6ee327b4a7a313214b9ae04b9651b63cd8d9f5b3bec689e0fd000dd501770dd0e99b8f99eafa09c396a245a4a96e56896a29b24190b1ef11063f39b63ee3a586b07627dd3500c4e170b835dc0ec236fa5a35c44184707565c4a50662d8dbccfff7f9a7a68d021b4af64d532b7c3d2747418c2d717bb6aca6b58747ae4dd5641d826f79a8a315c38211a538a929e5b451f623f4fcbbcacdb86c8752ea13a617ab414ab653eb2e68d5420df7c6df92438168dcf9c066581dfe7b2c468194a23707de4659bd67eb634ff024741c5fc8698fd4dc41fe5dfc6299b7a08e6ffca37109c0210c8f94ea2d3ddc977ffc0b3794fe6ba4337c7aab434a68ac665484ea8243a84b79aa181ee6ab5aa37a32d879725edc018f8552181816d7d272ca8818a7b92e6ee4454d1f7828dd8afba1a790364b4ff28d84e028597353ebbef24837bc319e1ae8f2b0b6a851b489c3e170eef53e065f7032653cd6b46d8e57e4e111b789ba950c4230aba35e569e06615403407bce0369aaab4eafaef0cae109ac4cb838fb6c1 +SIG: c771ba0a3d3c4a7b064bd51ad05c9ff27fd326610fbfa09183039e5edf35472dded8fc2275bbcc5df1bf129860c01a2c1311da602fbaffc8b79c249c9cc95502 + +PRIV: de1634f3460e02898db53298d6d3821c60853adee2d7f3e8edd8b0239a48cfaf9dc1465b3383f37de00ea2d3c70f2c8fac815f0172029c3f579579c984a5895e +PUB: 9dc1465b3383f37de00ea2d3c70f2c8fac815f0172029c3f579579c984a5895e +MESSAGE: d10c3e4de7fa2989dba87537e00593d0eed4d75ee65846dab1498b4749d64f40e34b5911c5ce3b53a7e37d2d02bb0dae38ed962a4edc86c00207bee9a8e456eccae8bdf4d87a76746014201af6caffe10566f08d10daaf077160f011feaca25b9c1f6eca9fc53314a80547951754355525257d09a7fdad5bc321b72aa28d1e02d8696d4f9eb0ad3b2196f8bcfaeb1d6148287a3faefef91a7a3e0609c28ce59d0ca14d0b3050dd4f096b7bc2513988ba212128d5026daaa7188846db21c5c1d179ab9487c1a5bd346588127c20398d362d4c759cfab2a677750b9e45676a1e7e092ef02edbf278fb19a58e9bf6c9e996e24edad73f3ce31fa04b6d8533436bf80b4b2f805ed91e7fcda3bc2bab3b2bb157158af0ea8e3f0731dfad459d2e79b6d3715fe7bf1eafc5397593208857e57b7feb2f7387943a8e0913470c161aef4fe205d3637f23177ff26304a4f64eba3fe6f7f272d234a67206a388ddd0366e894eaa4bb05d73a475f1b34ca222bbce1685b1b56e034e43b3c40e81fff79682c19f32aa3f2a895c0709f9f74a4d59d3a49029ecfcb283082b067f1a0d9505750fd867321999484249efa725f52c94c7596206a911f3f505d63f0313254bd445f05be3996b58fe1819af87352e7f0a2ca320d9cc00a5fe77ad41640d50be8436 +SIG: d20506eb846923a0b16ff82fb2c3923b00c1b3bcc6e2f6482fba24807521e8e0223f692e62eac993f498f67102a04fd1acf9c7e3888d857c9a080b8af6361006 + +PRIV: c738ef5f0935281ba625fa4014d4a4d0be7e28fed779a9cf658e21dba43cebc195799faf706d195e544c76cafddf09d02d1beafc42c9d6c9ead4c1845587d39e +PUB: 95799faf706d195e544c76cafddf09d02d1beafc42c9d6c9ead4c1845587d39e +MESSAGE: 168d0bc5598be02f5443bfe7dfb8829985ca5d282af9cf1b1482602f243d486bd82ba039a0750909e9b3c7d4d5f8b8baf45718af0311854f4d1c7837f31d8ee68d3558e7e51e0c646a4a637596ee90057b01ed0a17daa3950b81ab47ae8b94c17d40746913c46ba1478bfca51b167628fc3ee1e22f2f19d6d8daf93df6540cedb7a859d1a2ba5911ba71766e8b7fce0c0e8663616d0180697d78ce3040d438131982f3f8112acca29ae53e539ff8c9ec4106d132f402018518308485f2aa6c9e8d1e62fed60cb249457db33c6fd1fe07445361f08194a2b5a057cb03cc754e5c7d4a7eea53a7f7d207cacca5e68cafa969a3521dbb810399a17f328ee767cf55926b2bd5f029549d3b464579c42655265398472e1c77cc8dd9aff187f7ac34dd456ace999a736ecca6d405d4922c779c600c47b84c9c1df5e5f8ed3b2811d351339113f8453cca4c4411688cb0388258ebbd1872b83610042249494ed560d4cda6a68455d957e806dd0bdd83004c4ca80774b8a0a1665866f17085014eadb3eae7382fa870deb29dd8c931b53019625740e28392f38575c0e2a9e504fc35bd95df56439a898230a2398cd2225c766ef36f12ae7e49b30a9c0aad469d5895bbf721cc0ff51d840c802d4a7eefba84fe5205a2c2f14011922dde561456f79e6161 +SIG: f44371e6c3391639d457ed14648184809411e80a3201f8811670e500fcad92f300aabf7fc68e440191e881d6c3474efd6d28f09dc44312fcfcb82701ba3c290a + +PRIV: 5fea38739c61ca83bf7b4ad175a2117627b971a634a305a84fa57fecb8035624ddd14b0fc06768d5104c50764bfd3b952352a34007c50d5ddd224ff51afcdf9c +PUB: ddd14b0fc06768d5104c50764bfd3b952352a34007c50d5ddd224ff51afcdf9c +MESSAGE: 1013c60a73953549e5ed105bdea150b91e60ec39200d43721304bfc8ec439d39609613c2d878044a9da01b26d86d6d65db93d91a137e9c4808a97d4ef286a903f3f1382cc6d1294216b9fafc013c86b9ff68b55a50ea3766e61dc1ce38348e91d62ce732c152d766b9335c68d6cad77be2b4a0cd50b9a1ec632ba55648a6e7e11a14c06853c02aec4809bd147a5ddd9fbc3be9f0c8158d84ab6795d771b42b1814a17a3c7a6ca0f4a8f7b3a0db1c73ba13b16400dfecbd03d216650e4d69704a707246444d5791fa273752f59cb5ae9fd416a5186613d66afdbd1ce691a87bd7d8b67190e9ac687062a080d2ec39fe76ed8335058251872839e85eb62f18ece187caba55b5f7d5edcade01cdc543cc677e50238b89c5635ad5c8fc220f5e0be1bc667d20989753a6d616fa69f8b12940b8ca9e2c48577132d8691b053779a152cbacff3b8b1bd7af692e56c73bbae4634776cfc213c99b9ae458df1befc8c877742664b0a0bb1f6915c8dae3b3f55dd75aba6a3bcc4176b4e3ba03d0c1c04c3c6408778b2b8e5a8a3eb52ed32a7428c00a98a589d8ca9390a210f4a7ac004fa1fe4c6da694f12276e320b41b0b59f75d264a396d450b631ab353f1612709e7a2e6a50d01cb110e53040546dd3b1e11d25732813aa76be5e81fcf7a5773f6815bbd +SIG: f4e274823f2c396f3a329486aa6410c5ff19266f0770fd04fb14a7602d2b69a4a2b00928e9e1d92389f8033359ed6fb2146467aa154cba597dec6a84173f8d07 + +PRIV: 60f9a14cce5d43fd9aab4ee8cc8379d575949152693bf29a6790b035e42a44debd4a70740d5acabe49f9a2152082fa2025330e6440437f1d047f313de490dca5 +PUB: bd4a70740d5acabe49f9a2152082fa2025330e6440437f1d047f313de490dca5 +MESSAGE: dd7f44f9eb728ab48de54ecde6b6184bd5ddd8707545a0129f2e905905b55d3e7fd57e28485d258148f6605e2377d5b267d2eaf4cd4b46e454962219868232b6f41f88a797f9cdd5c39ada51a641214fb9db2c2a9b5a5b16e303575318b625cca970b74348727902a1cf268bd16e107113161c8cbc99303c2b9f235541a7b31e433120feba14febe4bcb0f5b936c7edddd0ecfc72c8d38f64cdb6cfc2910bc29a521c50a51abcbc2aabf789de822cb04f5728fee153dd5501b2db59c59f50cab17c29216d66951019e145b36fd7e841bfbb0a328554b44dd7ef51468c3d5b7d3a1f7b9def58d8cf9d9bcafe92c86cf6d6119e98dba6f38ea57e322ddc9c2198d4bbc3b94ea1329db0d458e01c7081b33925a3e287f599a858c50c3a8f18cc2aa634df63e7f10e403adeab2f41db5578790c3b4f041a8b7a4f69cd6e06215df8201ae5b3e1d1d25a0a39bfc3d041a2f98213ef4141245792a76f06d4de25f6467a0e56f2f5cf69400d22117de7b46149554b70c75b9f99484a4f6f035ad3f10e3753cb14f4f398dcf6a64d10cf6c4fac07c91193cc0f54f0de58c6343e9caaa6b4f475ef91a59e083f9f211f5bc8e7e4516b45cf06bf50beb8fc4ab579d86d4a4190eeac748d06e0852c4b9ba8cfc50dd0a037a7bad7fad55af309a5f13d4c91ed3e0 +SIG: 72f54bb8bdd17e9e422cd339631dd39f57355015d4cbd15acab7542efd784a321c1f6125764c0d154045b32e70dc2e03fbfe1117468ac3e73127b5fac8d42102 + +PRIV: a39053c5c58bf31d462b27a620b0b37b8052c6b1c4102b6145663aa15e9787183642ac2a3280dce52ad8dfcfd3709436edc4e7e4ae1b452d9b220780b08679fa +PUB: 3642ac2a3280dce52ad8dfcfd3709436edc4e7e4ae1b452d9b220780b08679fa +MESSAGE: f65540d3abeb1ee5ea987062c1b579516d3c29c39cbc6b09d60e18fe274c2befe0f5fe7dbd57c2d5835229bb754ec4341394765776d6a9178c4e6a312cd74bdbaca0e88270628cd84100f472b075f93692830122f00f9bd91ac582836c8bfa714aa48e977003556e1b696df328ef584f413f8ab614760699c4d147c3eea1da0435835c9bf7ad54606f0213eb74a1b476141506ae2cd124cd51d66e7e7e579560576305c5fbe8430be3ebebaacba3f9989dd7d199f5a455a50cdb3755037e1a70674a4fef40b4a3aaf7bd3c95b1ab41bb206211c3a1276d3e37d8a3a5c3d5d0f36ef5b4f3de26b7f20f6b2900716dcc22ab734ebaf1e8d00020e5f019551653b9c2f70a4038dfb2f12d25d6d84e79073a6548fe15e4828fe5de83ac3d8d98b7daf92710482c37f7bd2431a8114c6137657bb177882d8a3c76babf1c671a7055365fe90866167a2d1dbc870be83b3601f09d4a317ae254cac9f98dcc7aead9224cd9c9d8a200abc80a2dd108af28fd46ad7080ae741b50054b9b9a9201efb7838bc4c5c2cc3d76ba0fcc49c46e792c26292b7d0312aff955a9f8edf0c696a70a614f3553ad3869bfde48d26a4d367b6cec057e62a4e548554b48b53ecda790ba7a0ab2e3de587bdc22b02f5947634d73099f547db22ec1bbf82343f9a2ca38bce4eb59be +SIG: f7383e966cb2309deedf860100183aaefac672ca16d5419cd6422ca70e16b3976f5f165afc2786117c868234ba1109ede031f8979b50e567358bd4f8bd958202 + +PRIV: e0c29df4de45c47539e0896b3a59bc3de6b802fd14dbdc9f25e717ac82c328f3a69002b0f5ef354ce3b2d6b8d8ba70ab778432b22f144dc9c2eb92d99d99dd2a +PUB: a69002b0f5ef354ce3b2d6b8d8ba70ab778432b22f144dc9c2eb92d99d99dd2a +MESSAGE: 6a37cb4c749c583590c8d849bce3fa657f10009190cad9be41ede19bf2fdb3c562a6101f27bd37f223cab13ced245a1cedf852f551f857aad9727f62c967c0a921df116f48a80a6040b3c723ab5cb594c4507a3d20cd60514e22164a82b74f19dcfdd83c57bc3652375517414af5d18e0a64ccab36699768d07cf40b7063a83e43d5f607964b1bf0840a45ad50abf83dbc849f40e5b4cfb6a3347b29fec50774046a4b50041032aa4d567e8564b3eed1642040682dd8ae7d7179286cf6e1853dc87d27c3e9e60fa47cf8cb2da0181d53eec40614b07331a4fb7028086d0b1ce2e1115b73a162c527bdd7cab5335b863d108be047bdbca112cc6e776bb453c317314388bb9653efb4444bf5cf1ec8da23b711ba71796c0ae02ba1dcc838455078c3897f07e9e13b76e49274c2e207506b00a0b558883aa122b667db9d670508606a3f54320636cd19f973917fb1875f4363e220f1e12398cc6afd79094743338456813a5826ad3f1aba7cd7beab1fe183859c0cc9ef40a5eab912caf515a8d4c3b93d641b7ab3e76b16c12971ace88ff33e5a1ed9b44e45db8f3085dbf070b256b0d7512ee1069432603d73095db8749ca547963bd71a8a684ab8516b146c4187176386afdf6cb1368a3dd8fcb2cfff77056aaf7823f800b266acce72bf643c6d0c28f0ab +SIG: bb3b8c5c27591fd8b9c5ba489d6b6ee5b0fb4a7b0de51f1639afc673d0e5f75e313aa7e1d0009081dbca7435b687ccd12f64f74a386e772b9e24781b925c8c0c + +PRIV: 198b5fd1c03827e0994ad5bfee9b5b7be9966c9c3a267e4d7430343767403c676682c6f1a866b49b2f8ee97f2e532fa91666bf38da1b4dd65543a1777794cbee +PUB: 6682c6f1a866b49b2f8ee97f2e532fa91666bf38da1b4dd65543a1777794cbee +MESSAGE: 3fdaa15c46f25143db972079d7013c7f69a136f45f3f6ba2ced8b828468eb3daa6b50b4f8d3380fec64a0343be116f6f83b6ee64cc4c1b1d08d54fd42029e4285cfc6c6dd5cd181ab533ffcd411f23a1003da94ec9340e2ec71199d678540d5182e139ffcbc505a170b8f07f4a7e694ca92f58320c0a078564ce9de99b0fa8e66b0d822e467a5aeb83567996a48b89db25cade6457794e5414d67e9d4ab7cd6cc2058bb7a513abd709f4caf24bb67ce1c03ab62dbdfe309ec7db0fa3ea7aae8236f259b922d4536115a63bc89acb2051d09e731cbb0df157d9d345bd9109973c2b594f148efc6f3377de5163b7f69869ffef853eaefeb402e23529594fbd65ca05fe4062c529d8e321abc05200cac1e839e87b1fd3fdf021d68cbb3a4142b69cc3af6f632edd65b83f5aa4cb17da5b6ba3fc03edb17c2a3cb5b04836e7660e63c8a0483e243983371dfa9839f9164ad4da0d5953655e3a9518e136da745737c79243c355fc125cbdcc76aec92216846c4574f4f7f298bcde54fd2444ad3025955c100315de5a4e27c333a00284b2f702fdd3de22ac6c240dbc14bf71e62d131b62f2db992473f2f913f60c916ecf57df5f3f021fb330834395b79472caff19fcfa0a271795c76d69b4db3f85b8d2e5c3441965484dcc39aba59b701274f7fc425246856069 +SIG: f454f35b18538f877e5d614a76b5276a27fc0b433f215dc4e963b3f047694c780c515c6ef6fe2db4b009009bc2733aec4fd46e615357cc0bcc9f1f7fc21e3c02 + +PRIV: 4392f7d4fbd68fe154e4ba38ad5207612a0648556056c39ac116ad468f89bd2dcbeaef41acac02bf1f780ce934aabd631364b369567be1be28e3906f9db120fa +PUB: cbeaef41acac02bf1f780ce934aabd631364b369567be1be28e3906f9db120fa +MESSAGE: cf1709dc9a0867ee908721b136cb93a84229e83b46204777ca8194d08b7a3ca9c912eb243e5bdabfeed352349d20be801b722af0892238e72edf190e6361f57572781ad3c2590b197357641c805383baa1d4972f76c65448532c110834a0baa8f48863e166b706653708cd4057d3a4f9fcb2ceb4120001277d38c43847d822822b777c2bb4da4015a1c24d416d5062a8718491d855aaa5dbf5579c164d8e524a9f2fa3f22eb09861ffe6ad659fe36eb40431222c22d7137a6cabca8db786e39d81f661afde4e39589b4db4d3c51ca53590a14e115d0afc3a877b839a9638bece80c32c19e51b7532024845f76cfe9bfb2ac05130f6758bf7fe993aa93aa272e4e6bd0c75c14099d43e652a223e5bcd64c362d4b8f4b95e016f9350c7fa74e653525d08011558b2c6e9bf4fdf9dbd5ef9b09bbc846afc2bcbc86c4ccc315f6d1ccd489b0cf8ed0d93f2f532a426265c590ba3a59023347d819d9b281ef85310b05316d46c8a8c0365d068a8708664ea4d77ac0cd150a65a56586babd34b74365bb8fe3e6187262284d64432e4c81ea4c0e57c1d71ae980c7f4d1d871032e188bbf9d1758cdc1dff989f2d1288fef4e205e99e7cbf2cc324b8c93046f476c59d3d0a59db6fe37382dc79c5ec16056ab3934a52f7d2880d0471a377b6a8ae84d56ac22d1d54551c +SIG: 86e7ccf06e79362d40cdb7fb75a98978bbd334a1db7590367d60849bd53e2fb1a4bdae590d1f47b5490d8702e7c1a87268b8ee9db612de7bdc2e38fa6deb7e05 + +PRIV: 0bea98abe7d63f158390ee668aa050e84a25d2893e49fc83f079f9bba6a55a7522192ec0d32ef9835665a61bc88bcf4e1604637921152c116af503365bf6be42 +PUB: 22192ec0d32ef9835665a61bc88bcf4e1604637921152c116af503365bf6be42 +MESSAGE: c178e38d4e83ed2be57ce1c3ab64253a8171e610008181fbfc6d752269f7f1c5a9ec62cb27f19ad99ce1f5116a363d96fdc5a42f358b6dbe7cabdfc9f60718e4012c1bb1f842c5560811ba8374a0637747ff92eac21ca65ddeaf43e9989b7de2d432520afee364ecfba4da669ad4893d0bf69f9f81e7df69657be22b92069745f216c242ccd46d02d35616e16c755e0e37f961a6f3637752534f6dfab8805ab759a032a4e7e4c81953325a2f686bb69a029ce4e03becb3605637c5a65b52e331c26c926ed4711a504d3733bb53c97b80eafe4e75ddd9f415362888c3d4d37bae0e63fa11bf755666437d72f58c91d7a2f8cb619b7620a070b26b18b4d50184c5818712110e36d3e2830f6a8576ba57f9cccb8fff4028bf8ef9cb814825bbca827d649547bf6f2bef931704ca7f6df15f780155ed46eaa7ca7d72e22434ca0483bfb2f7902dc787f617eb9bd41ed4520adfd430948c710805a73c1ba5492e96484c4baa7da24c7435c46a052bf3515d33e42dcef517caa45f36c879121078c688dd10d76656a119762b6a834136fa1f8a643224b9224c543cf0470b3f8ee017d620dbdcc84d985154e9d1ae80e5f14387b88a0f6a5c35905aa57fb3abeb0ea6eccddb004474633cc483b56b8a8e20e8f2e09e979aa09893087875c6b117b5f13847ad8fc05604c4 +SIG: 7eb3139b880fdf66376a2090818840049767c837f3ad0036b141667052b33609817ca5e240ed8cdf3ccf3aee29274534594db0b4ccc5c6e5bba3280b873f2901 + +PRIV: c25878b0d1e0925c8f5f04a1e5799080963c413a1399c118afb1687c797f483913ac2cad41908c255f671f93934ae5d7be325346725c8b40dc39ea80d70ddf34 +PUB: 13ac2cad41908c255f671f93934ae5d7be325346725c8b40dc39ea80d70ddf34 +MESSAGE: 6856cc7144b6bddcc4b58954d1a2e7101d6584b5d5e719a0aea0fbbdf221c2a2aacbacdc4020c5c8ce681ff7381acd607b0f5239692335700655be2d94c53d7b5148e92a2bc16338c2f4c1a7d1c595af622c240ce579a5e0f5b651bf562518cec8aa2ce4b4aadb1f2fda6cf6295bc37803b5377dab65c9b9a2949fdd49bf9ddc8f96d260ff951bf8e8ccf9827e6869c44bfd973358cefdb010db5e1fe5dbd9f5d2b2ca393c17d446f637059e692d7a91aadcc7689f5f9e1b3052175d9b6b208f9026787fdb66783f45372a24946b1bd1687bf0cfcc8174ebe4d32e43284fc78d7844de0fa22e2065e07528baabaf015cb34d629c3596ad040de31c5620eb266defa7533ac0401998e5673a754365047debfcf7e137a20d16cdd6a5521982f444cfc3429397c641bd7e74a770bb11fcb29483e337bae5169ee82da9a91adf3af67cd814c2825d29018ef035ea86f8de4c7563aaf66e0c75d17ca68f49f0758ec2d9c5179d01aaed7d4515e91a222b0b06fbde4f07a7d9df2de3bcae37ca2c8460c2a6b3749e9bda36d08e66bcc356b390434b4a18cfa45af557dca3d857ff3ad347cfb07e2358c2acfd5cd53b3b0ea2a41ee5c0802fd473db5f30526334da41eb4bc7518383898a0b7507ad4ca289d66c5e2eb75cf255dff312cb1e04eebeb47f2930b90d5e002eb0 +SIG: 06f55198b4191914b74306f38e381316eac40b5b5adb8a312464f67175ecf612e0147b1cef46c2518750a5606bb03bc6467bb9321514f69dcbebce8f69058002 + +PRIV: 0b2ec62763f687593135da1961ef29a288089696d944b265a5f96893cd2d8225c1e234fa8bc96d268e7aad028b03f0a911b697715db3a21c2fc7df48ecda8875 +PUB: c1e234fa8bc96d268e7aad028b03f0a911b697715db3a21c2fc7df48ecda8875 +MESSAGE: a83434c68693d5fced91bda10213fcd50c48920b90cee9b73a9c61081a0974933f4fdb0a67e671f8351b0ed5ec0fe7b5fb0c87586fe582ffb1bfa2db5fcedd3302428234b2bb0e726dedf45b13a70cd35ab3e299d13f34503508278c4458eea5b7351b05836bdad5b05f60e445fc65737ae27d2e52df9c39e5da0286392d08fff7ecb7066820fc90fc8a44d5616561c50b52714702302bca5874de85dba045045f9f0e604eb86d6d7fbd775f72ea493b2c4ef7c3be16db2ca7e4d8bd79eb20cfb5f0f6f05336b75cc86d219f3b8f2e91ba7d52b64fdd6a6664f04f2fbab758cdf984168691c32f53e8616b49f76ab7b192b900903082cc89656a9705804cc9b9288a3e42170984f8dc454e0864b9341672686a178c060050178a36c6d906b2ce070d8faaacd9a58c794a5ea4108b4a485c65811c2dca2ee7bb10bffff75d4586b990f43763a16fbc0b48ae1fafb08a9a36fa4326845dba5ba2fbd32bbf66505c5e8657ed0107e3e16144ef31fa6aae72e774097483f5480aa45540568fd08cba0d577768004f58ae9b95be374ed7f0299fe721275e476e0b9ab72dc06ea328384e39bf3ac331c625484312cd9b06b15a2954d33e7aaba6be2261886ca811db96b1143d06dd6e0f3cba7a1ae9b94eaf67771bb2d24e2f94de9c470fcde7bfdb32f410198b5aa9698e32 +SIG: ff701f34b3594de3b80045f429e5e32dd88d6051d4195f1685be783766e80119368f56b3749725b913f1223f87fb0fb24d9dfa0841d6a0e2eb1fddf775c2d205 + +PRIV: 8960d7bee8c6b39ca5934d7cddd16f16b3663e6e03e833c057e2181e4597cb6843409095d4f50f5eddbd5cd4d2012298cb41a40e99492d5a2db08be5377ea183 +PUB: 43409095d4f50f5eddbd5cd4d2012298cb41a40e99492d5a2db08be5377ea183 +MESSAGE: 308d84c7a5f786e563e5c1ea57aab5e555c00997749d15aee35439efa645da2c3967703115c6c63ed7f94785c5478f38467b86e7626e8fffa4d51a2dc45e6df2a35cec99555eabc9f7a93e2e2b689459b4e0c92b351562c417b1997113754ea59e4a91510728ff3071a2bbd1f465a687f67dae955615031a8ad551fe738a260bbc446b48dca1d979051ab5840832e19d473b666217a9183980d6b27e3d3c76d93665ba2393e6ab1a42c3904d4025932d601a202a59a4c49fdb77f0e02868247de5afdfaa1b894208ac00d77c6bb54c6b2a73a47657e44c85137963b57521af20976248eb261482147cdf7a145c3643e29e0588bfdae6a082904853ce5a10d24970ebdfb7f59d5efdd6a5e7e0d287971c846acd54d84dd45468a4110bab6ef8d9a5b4b2426788900b7e1adfe0624344f98fe59ef8a1e6c405b344eb97bb204773744b6a2d8c6e65d17cea07de03b7f0fe49f1a55c33d5f15ce55df7c9561b251c6ac807a92553e1ce917012dccfd69e7dbd038c7eeecae98623f18fbb650e2218a0bc0fff43a75a116448bb7362f527ee6bc8e10761cccf9bcfc0d000f2127b4cc19211d095a0bdaa4e4be4519e6c8445eab9b3144a45cab9996135bf7f75a78d22275900f4ce1f0a9eac136364103062893dad4390422b77e5f5d1d94d7029c6097b35ca64a7a476fcc7 +SIG: 7213dd4a79fd54dec0c548ef42e6cae015be77802bf515cd2582768f72f563ebb2da36af4aaeac56bbffc9932c2e24ec95daff00a5f7a0acab9c8bd3c23bb40c + +PRIV: ef6b9b51fd4f8586ca62658e042fc09a83b943033526ffc326c65eb3a5fb594b1d6eece805e0887821876b7ed6ed5b0714d646fbecda38764f94c8155e61d004 +PUB: 1d6eece805e0887821876b7ed6ed5b0714d646fbecda38764f94c8155e61d004 +MESSAGE: a8f3f19665de2390d5cc52b064b4851273677486d8f5563bb7c95fa94db3356161ee622221f10cbb1fa195aac7231ea716d74b46b37bc85a70dba3dfaa1675217b351199e74a971028f729b7ae2b74ae8c6b3a0679c3e3296802844ad5bba343f6f9f7c4661b4a29b44f17e89e114fb220e984cd980e94c3d2bf9873e0605c92301744a3035ef046bad2666b5c63ebecf93cc140291946c0fa170340ce395092deed79841352fbfee03a927eb458f2a633ed3271652f5b0f9960cdf9015d56fdabd89ee71e259af6eb514b4c1bd4a666f5b5a35c90f35b149457af2944dd0aa8d9b542283a7e5412b775e421d2126f89bebc3ca37f73071621f1321eee52e9690486a33cd7ff9c9967fb65ee4e907b6b852211473d21e9d91a93362ac761760e8c7bbea486c3d605f9e11b86136819a7ab3f32f13ffca16817fed197ff880b4d6d9a808f7f878763a045728df72faaa963e4cb1c09cc2b2da920280c8366b7d18bf8972df16cc23448fbe6b2e6e16cbbf0745129854053189637ce115d2398433c15d6f116a205334824af282fa758494c47868ea8f4dfadc705e861aad2eb8ef3dbbed2a4569e15834a760cce0cbbc84b289e779b988346b9069c744c97ab2bf42b086d2fb0a411f5ce99f0819a3086b4fe9d96c7c9908dce28df1ddd30f3501ddaf78110734f9dcdfec3 +SIG: 71d171071cd0fea1c6a9cfad1f7fd835e85ff906778bc6345a4dec4313ecc2bff755a717ebd912a5e02840ac073842f9bfcaa58913e260e3c73393d36685c70e + +PRIV: bad47cd4bd89849067cce1e63c3d91e9b787aea8584edb07f3451ef67e7bd79bab0ce9ba1d29bdfb85a0e66b76b5e2e05ff732569e4375ccd75098e9e71d17bf +PUB: ab0ce9ba1d29bdfb85a0e66b76b5e2e05ff732569e4375ccd75098e9e71d17bf +MESSAGE: b5a61e19e4863e0bb5f3fab6c4970d878596895521fa1e7f678cafa2de53322fd458a98aa6e35805429f651291b95bd9950e155f3ada0b609159a4abda5990c04bc2e764422fb49ef42f12529ff6f6a82029ff0185662e658f83c546eed09f06b5a68e857cdad0eb9ec4eecbfd88f34bc80990f8644a9bfdde1d9f3a90d557a8b828d5ce06a64e3b238582bb4cbeba30edc49e8122c55e95badcf502cc567869c09e9f46c6ff3f6878986b1de00b72a1858046fcd3a6e9cdaf5b073c56f2025063a2d178bd4c1e8cbc1e6e671aa97fb2cb4cc8a62c20be41c776372c8e7be63b482e6c63fa85d7cffbc1b2820bae1fc128343a1e20fcf1bc3502eee81358cc9a74c72af63530f96a25a604648ff570df1eb89d1fddbab28679ba2e9b41977e9a9c1caecdbfc361a1dd055ec51620a9bbdbbaf718c9cc136d2007710399536d13332485ec38879785e0c9ce9915a80251373990a59bce440326031ab1b458bfa5b8a4793da4ee11ab7af20de2a118c9ae521a417b68207fc885e109d8463e9f022787cc730db0b1faaed257bed901710885b74e994f54f6f2aeb64f0f60b59efbf2e3bb6515424603a113c0b8a31ba3c1e9a9b8118c87ec6949b75f49627ea7b1328889391104d4f4a3892cf00f26a73cda2a40f9b7157afc40667f4a04f647dbf93906b84c9a35164e1bc902 +SIG: e5724a1dd463a97d1222c518c4925d322202d10f04cd078e771e0fb3951dbc1493a234460754c3aae3df93008dbbfb310c99592bede735a4aeab0323a1210d0e + +PRIV: caba8e0533113a4be173408ba83c0db74260802f9186c391402655acde6015cb2d7bef6164c279fa1028a9788e3e8ee8ac15edcf92a5855062952310b4684547 +PUB: 2d7bef6164c279fa1028a9788e3e8ee8ac15edcf92a5855062952310b4684547 +MESSAGE: 2413a32bca5ce6e230e565eb858493d5d04e6d2e2a7ab1f89a3b423311676bfa93c67daafd1cfc7109e040bac52cbfe07c28280bb6acf6e3a31073dab2965378dd77f61fe9247135c1a631b79ad668c9ea1cd4112d8d3a064cc21df32aeac7dd718b091fb6915b8bc063bb5815c376e01476312a2e5433417a7a9315d65999b02ff464a474a597e53988773670eca46a6e26cf96e9488e9e6344bc783ddfb535e76bb3b9a603ff4c59c7dbe2d8b6198d5b24490b4ea96c95959ffbf3d8218e760daf20e01e2f36c84bb097115abddee92bed82d16b15a9e192e9893ac638461df507207b0cf595884d8a99fb9c7045f9bff7b73f00ca3fd595a5cec292adb458bd9463be1204d01678d2f4389b8720115fa597c402b4ff694b71ce4f3d330d5e2f3c3ad6d96a9b3439230fc53a44794cda595557c406ca1589bc7be81e2d79636033253fa7bdd600c67fc55936bd96ce0428c3eb97bad1de0a5fbb9b675157de5f18bc62a7c22c9483e2802e679b5b8f89db0fc37f7c7150ad5ac8722ceb999b2435e6997217092336ef1c8a2292dab9a46ff8a9e10d3355765cac9d6598770f4f01ea639125fd031609dd1a507d96280c7d01a3ee987e9b210ec8744cd48c74f8afee961e8ef221f826a1fe6e7df0cb15ad7c7ef4a91f9d0f4c2e1bdea635d275fac8c4bc0601f490dbdbc734 +SIG: ec35ec32c8a4008827e178492b3b8bee22a4954fc6b25f4f225dd7ed23698900de8156756a8edc35c51d10f82b830a2a659676eac911f960244766e0c3c60705 + +PRIV: 9bf3fbc7308b46f6036bade0c3ca199fac662b07f103bf75181d52ba6a58be052f6ac6fc33bc060c1dc3cb9d1a2b9115845addb16c4b84be37ed33adb3b3d3a8 +PUB: 2f6ac6fc33bc060c1dc3cb9d1a2b9115845addb16c4b84be37ed33adb3b3d3a8 +MESSAGE: d65e36a6a38195ecb91de3c848b51f639245fa2baba8a6f85947159dec0ed3fae80c5a0f8c66ff24793c89c0c687543bc633547a1f37f730d97012ebbdc7ac339c4890c0856bbfe2ba29b25a7aa6b089c033fecb76db62dd3c00f6421b9e76dd0ea366eb2d4a052ee6cc736e3819191d5ad7a66d2be042cc6539e5f35652b155a727f3888d93f93a9102598f7538a9ab7c777eec79426a6075d6f38d64c485520f6413ff4d358a8a9cbdab01adf4db02adaea26494d1f5d617637f277f8b0e6e7e61e2eeccdd337de2baf0ca264c14c8cb8368000b9c714385f413737d6816e212cae2aecfffc32fd16d46c3ecee6ab074c0d768bdfe99b86cbbc8df9c47cd586d465871268d4a9d1c877236ab78f8859c114e251cabc4be0f8bc25d148c5f543e290745d11803e49f5b53193fe39969c039b3f249b32f2b8598b6acf4ed64d5752bb772ff4ee00ce0f85ecbb4cfc4ce07daf2809868c2903b781e12a274105f06181029e47f2bfb21f49480aa1e444715c0b9ff07ead88975d93585d2ff424832a9783d94906a60f877ae1c85ff15317badca1e61317433c7ce96279b678ec9d174dd0870080b234154f626a53462cfd547842eab8705605b8ee885729ee78d1833aa43f55ac22731989fdeda7dc5fa9c01985f2661e6c7326d346e6db27e6f921fae7c93a2170e10dd0c460bdc +SIG: 0c3136e01f9bcd99e10d3d124b0cdb0772bec18a864be81bd1daa44d818c3d470dfaa8ab6e9a761cf03f93ef9cc78291096ed6d10c08fa2fba3bac04dde20f0c + +PRIV: 64e89304a335e903cb36c0bdf1a6412ef368468006b73d3d2d61cb030cc5f8d1a180ef3a661c3c479d5f69807c902748e35e7f725121e37a5d91b8bec88d83a6 +PUB: a180ef3a661c3c479d5f69807c902748e35e7f725121e37a5d91b8bec88d83a6 +MESSAGE: 2f51074d981bdafafb02a40fe826c45f3171c1b3184d8c260b82b8411fc625cb02ccfe755dc29dc7895bf759e61b2450da1a656a38d4f70d2ee748c518c6420306e5f01ec7a0ffe0e9dceb93f6c077b12662881584f98ce6ab945f87fc6d123c45d6cdfd8237a1ce3635b623a79d020df44c74b89ac14a321fbf33a8c0a2559fea1c2b156076b813908f842ebe4c2b949089e52b1ae40dc6e4b2abbc439a0bf72369679aab6f4c00018be147f7c0a67b9679ee88a53819c49f7b675e30a8b5af39661ee8db21010411294968f88e5d604d0d88d76a7e4864fad3a56f5f624ba1b34ea9cb720850aad3bd4f0a882a7d25fbec2bb7ca86da616da96c1562c6d6a1abcc641e1b58b2c178e1c3bc8a3b36ec9e144dd2e75b0bc8c08ccb0d6e3427b0322b3d6ab93f3f60b9cc5b61dad02385a14949f9b87a8e3af1e0e0fab7a9a928c753fc6110444af7ccaf8027ed641b9ed87fa5d8e1f76cae465d57a70dad9ebfdd3ce7576ac4de89d98f42e282ad87ad6a5042577cbbbc4d951e2a8676fedc8cb1b1bdf76c3a38846385a85aa24706c20a8b38465fe2ae0e41f78e614b8e9642fe2471a9015747db976e0c7848c23ff3f417cb05a8d5ef40130adf855c998a62104d7e2fb7c0f9aa2a496075623ced2c0f7eec10147ff9608a8a042ef98117459b93837fd1b8d5ef03978eada74cac +SIG: 92eb4454814001ecfc18025d6421f64645a5bcbb5cb8fd85c14d772617c503e8be7d3bcf117f5e6801d1c3b96f9090a66ddc67f8cf8ff0f1c125b16b15e2ce07 + +PRIV: 6f634387ca2c0cb167a740d6afd89e2a28f5307184e81cba3c037046a5ede23c011f2a9a111c38f3490cad1685be78eceedc6fac4a3221301c69c84b1ec7b3a7 +PUB: 011f2a9a111c38f3490cad1685be78eceedc6fac4a3221301c69c84b1ec7b3a7 +MESSAGE: 865c20a94ac3f2e3bd5cb85bec9d33726671fe01f9c537017d59c8d5106e43360bf76fc06186705980c8a87ba3633a4a170426ecc0defb6db2670f5f592533774cda50052ae597d48deacc2637063bfd519f2e79bac81775beccb1ab2f5b39712e2e829469b75a2d2dbd08aa6d24723404b25eb948a4834c55246c8079a82ec64354e8c2388f8c5a616b3cdc371e6263fabc9f6099219e861585fe82a67d610dd1eb5c81c96b5cb354a689fd8aac8db76c433f0cb0b31cf1d855b6a30a3d2a212e9b4f7d7afe619951f98d2f1ba2c101085ba81f49b36037cd6457a7eaa8f4f3bedf68d09fc9fa25a9d754db65360285412d1a6da53788905fcf4efa8a80cd86ca48b845633d8c31c2ae06f16c4c6bbbe9cd1afb59e101be50e03535dd8a65e45bba46d45cb14badfc8e93ab5267f4e492ab1f9a95e61fcab81cbf2bd867a3ec7b4baa189a0f08567075596129dcf9ff1c502d3279e8aa6ce56eaf134582a9e430a5aa8ca10c3da8bc793d0256ad19aea7149f0ea7ea95facfac1c5cfd29d7a3fe1a417975739e14da8edc819900472ca8c69716328e8a299f974edff741aabc1c074a761b3ec8761dda2e7eed7af33ef00409849d415497c5ed5dfaa2259a31d076398170b2d9d210208b4a4c7db8c626d1c533562a1f95489f9819e4985fc4e1d1a707be5e82b005481d86377f424e +SIG: fd17c618cdbb5d459ea2aca886f0512c623251284aae3a83eb5d7f60da1d9b2ba083c455a5e2583a3cba736e7b961ba19c1cc8dd90745da82a15dfc662e8e10d + +PRIV: 4b2e1ae60fa5d383baba54edc168b9b05e0d05ee9c181321dbfddd198395915436c020b18552345619ef8837eb8d5494840e85f46809343b4d6f406125da557d +PUB: 36c020b18552345619ef8837eb8d5494840e85f46809343b4d6f406125da557d +MESSAGE: fab98b2bbf86aeb05086812a4b0049a1042abb76df9cd2908755706303efedb1ad21e8bc8d7562349e1e98ce0d752f4b3d99e677368bd08c78fe7425ec3b560e383bd42af6499886c35add80a5828b61d6644d7dc443ba2c06f9bad2eccb983d24458f6ada1b10bb5b77172c5cdd56d273d1e41010b25cf48a7d58d7255702ac12f2a6fe2918466395f460d15236d035ae9410ca86c4605128299faaf09015f1adee7768ee1a8f8ca06d10dd7f95c46fa10253065f9d6f90295908809fd779571be29e0ae66e0bcbdeb7913d2bbb76ac302f3452c55ef199a48eceb0e3596c7b4c0386dae7101ea244a33c4cdc830672df83655b35338052307b94d223cab1af69e07f78e58cbb0cb3c5351e3a6b0c4a927f7562c598d2d3df90569f61db1a3cb0140b56ea02cf7745fbeec2028673d67f1ec5f7daf9715f754a9d8ed46a7a63ef722ee0d5899331b63c974fa880429435767f96254ef46c9968f3fedaafeaf3e8f45634b54f5e0a5fc2d2373ab9e98d9acfe3697e642a18e0dfd9fbc2f094866d401f0a4ca2a456edf6a1a77b9c296c3922067eb3d5a5ca0a77f430e4c8611d8f05a1baac1635ef7ba83dfc69d301949856be4d2c8ab61de29cf39250c5794cbf5750cda95d0468afa2b7f23dba4ef5f5295a3bf4140018b7ed061884444f5bb1b7d239312dd739999536c684456ea06b +SIG: 2220119e83d69a6a3eed95fa166d1d1128a3f232ca1b78bc94b4d476c4779443614b8772aa2232cb0720a055eb71d8407f3ab19baa1d962c052c84c0bd589608 + +PRIV: b216cebf878024c20dfc86ce4b37bdc47aa28f29203b5b44925065d993a259fec36edbb6254a913f08fe259e238780638f72ec0b3007264bcc60a9e81ee9298f +PUB: c36edbb6254a913f08fe259e238780638f72ec0b3007264bcc60a9e81ee9298f +MESSAGE: 9c8717cc86fe02480bfd9e922bd76bffee2170c4cb1b13df834ac01d45006086297f1b8a26f2ba674d33e1d162f19367feba97352b7df2e75b309d4b6f8b07cc0eb6777e81e268e02d07f2a08f8f39d5a8320bfc01fc8c9227d2cf05e12891ff4de885a1c93371a0910ba53392aff9ba2eed9a2055977ec4157bd65b34df79372f4d50edbc48924353cfa1692319d88a7a5bb726254c209291e9b1d2c1a6c8236398109c59ed42a0ac9e7633c520734eccfea4fea95a47a8f0a068b4275000439cc97c57871e105cc0790e9dcc9c25d5af7063ffd05c4f3780e7bca4c456d0170da709fc6cb3faa72bdcf562908ae9340aef4d0c8b91f0fbccbcf1cd898b1c716f4f1474c3aa316242abdf6368e57a247ff2fd5ce23d187f694f11e38dfbfbc3d9db20903b4ebb449b9049ee020f6e2f508e8b2b165bad7464dbdd178cbd423233765d371e7ae1c3e878cdb5b824b20cb309867c0e473c067e6744008527b6bc076d077f4867622aeed1c253dbde7c6a76c7015962fb73391698600bb318ffa7b0136ee4ccb07daaf01f40ff9c194f98681f9faef8b6f9e99f95df0080da8966a8ba7a9474c537b92df9799e2fd16f788dad7a7bcc745226e1e6371f52ebcdbd144044ddfe632dfc0a43d3a450923170ebc7ae219e50e078a511bc12ef14cd14b5309f38abd65db2b2a7af2243b229c9fd2e +SIG: b7389ee78dd9763f9d2892912edcbe3e8a236b8bdc25f44b9cfdc8c47cd58168ab56eb0402a5bd752ac8f4978d2ea2b65d2fa85265966b9f57227ef4a59ae009 + +PRIV: afcecea92439e44a43ed61b673043dcbc4e360f2f30cd07896cda20cb988d4e3d231f69235a2e3a1dd5f6c2a9aaf20c03454b9a29f4e3a29ab94689d0d723e50 +PUB: d231f69235a2e3a1dd5f6c2a9aaf20c03454b9a29f4e3a29ab94689d0d723e50 +MESSAGE: 0b05f89ebb3397947687afbef0ede87cf3810676277037521d952a3bbbbdc8565988a095d8d4f6f59be572d3d821dd789977ef77a2fd7110ceeed9f3756ed8e188267b97a30ef8957c78aea3a2963deca61860545e0c40824881ebb1db10f607e10ddbddce400ea236ba4745aa99a05641976766789ed0da7db55fdab459ebd4b441a6282f7cfd5a20ea06effa335955e5fd29181671bc92c00052f7f75c39277c9a43b787ac9fb1516e996232a509774d1dc21d8c0513f7844b0a5b5f18957581f99044a14223ccda8a284de12fd424265fe57b270215f8fa9ff2bea517934e4800a47d346fb6c361cfbabeffabd9c4164f45156e245c977edb473642c3940be5ad6fd1a7119a7b18e98d6dc843e0d254c93d0146d18e5c62ede1490f89a605eb454f974778cfae20932e95477bd03bcdb97d5bcb76335942e92ee668f231e69c570ac5446d0f774066737fdf49f10ceb1b52d6d8a4639846a3373a7c6f3b4b3159fe2e7af7eee2f0df172d94d255d017651da3009005e5eac3176c09389ee40d70383bd37117eca083598a1801f592d057186e568e247c252be4b14f723ab7ddb97ae9768c2682fd63acc300779fe04e2b88874751346c9e0f97a2a216772ff9625c33bd7e29fed8003a08dbd33b5d17899c943c25e95ad754fb632e047c112af7f7ceba72362e1a3ddd2935aaf7f818a27c +SIG: a65545cf3df456b28d83a6d94c036a19d0d29fb065edc27e5e93a1f40279897e1c6f25959a725ababc87cf2ae727f3467b79570e902711917191d9cb0d2d660c + +PRIV: b834c6e0facbff580dd3b23753959a4c2154c219521b3d27035d071f6599bd02d1c384715e3b3d02c13e090605534c7db740da2aa560f53200a3ced8beae8cf8 +PUB: d1c384715e3b3d02c13e090605534c7db740da2aa560f53200a3ced8beae8cf8 +MESSAGE: 6cf147b1605528a36be75716a14b420bcf067c03f1cfe9c4402f14987fbfc9d3ecc3ccf4f8d2d03a55900b8dc79af3b6e77436f69b1417ad4b68fd44e5e333ed90ea7943fbd1122609ec8ff6bb25e42e9914f5920fc72c4d013b6a9685c996fbd8352aafb184c22d9e47871a5280e4ab7dd6a5cfd10a5994a200f670e0b622a9394d4793d0a420e7d8806cb127c7ac690d45a2e94166cea672bcd982b0e9baad56312d2570ddde7e0b9e7f47136f0481d00f66a2aaca4d1b09d7ce6c5a98a76b68cd97d5793968d667073f8217f9054735340f9b149c0dce845b099e88d0709680f0f77603ff0a2331c558fc36d5f24da9a62d69af5190d21b5c857a1e08f014c6d456468665a7f845c66f9111f9c098c68940efcd87b657070cb9164bc9743aceb7439a0d01c0062a11af2e11349397f5d152872b13c5ab32f51cc58f1475ec82ac671561dcbd343cfb3c5f78d0fc73053c6004b0a4ca3f2043ff4b0c54275c4fcb9cadc6baabe57b1d5acd531e972ef9335136cd1d65512ba1f5b6ccc4b66b4250aafa2967dd4211a2742e0f177d8f4063899f61815cbe6d8fbfcdf74812bd40cc10084e46a99ac128058eaf16a49a24b6ae228ecf0109c52dfc06e37d6a333bcb24aba312164c6c0290485d251280538ce9541c0916640e36d6929dcd9588eb99577f5f6d82bcbb198826267e49f5daff2c0d +SIG: 0f19b7066d5792328a9800d9d4f8f67d5b089b541226a167dacd439fa485b0025a5dc7f2c7e23fc4a5c6869e7619d356399700c93650e89cd25b90fb9925e304 + +PRIV: 2269a5d8f7ac2cd9048f5f49e349e5c435a159b319fe3b30bfac8d0d505943f41c817943dc39c24b01da38a487b175482460c609e4726349a9aa7aea9bc0fb34 +PUB: 1c817943dc39c24b01da38a487b175482460c609e4726349a9aa7aea9bc0fb34 +MESSAGE: 7153d4d9e641aa61920db0ff4bd537a6d6130a396554cc94537698f9cad16b99eebefa5f2776f2feaff6bd9a6904120c67e0883f6b96bbbb195e95aec753b699bab3d03944c13c72fc84e3f2cbf6296f645549111c93fae1a759bfcd16fc09e60bb9785535ad27da244ef2f857f2de99a6e92188890e452c7f5b9e3a4b968e11743b6fc7faf1275e5360a5468941797894d770fa7da364a337302239fe83ae0b0d084aa12acdc63462524e0eb10fefe81ba96f71f275f3449a3f8db21d58749a38853d39b0ad8e69891bd204dfca8f6c239dc9a0ac27f54db4238d4706df11d607369dc7f704da1d39f2e82af8c283d220c12431f56d803069b4acb77081c031ae3319fc77fca7845097fd727ad0d080895bba23e873d2def8cdc216c3eed61b08761bb9ebce0282cf502aaf6ce7e8c058637958c3ea1b72fe6e8df8d37ac055db6992587fabbdc467f52475644f918863af620492f34680f2056cbcab75e2323626c094759c0e0e99ef19759527250646ad760120ba386699d53934f956b8bbc7395bb496ceb2dd223c7b501b92d36a95f8f0a02eb5ba4dddf166b9b95b4a59e72a30c63cf21e6085751923d54b30281e52a09618e6f023ba0a21675e7f989b8991588c96c2b56a78f5d2945a7baeb6a0c1bbd5d95af3ee830f5809c794a15ab4b5f89dd2be2dfdcd8fe0520fda2b3f02a1ac0155 +SIG: be0fb3308a076a61a4a92a97f6ac55327190e1341d6dd410d86b41bdaf2d3374093ef720bdb77feb7014e0f77d3b809623c7ca53e2ae4b097113e96db77a2d08 + +PRIV: e965b3f257356685c98b42b964a253fc495399cc94b099c2445fc81c759c68e5689f5410c8e0f4d37bc07c85d7cce6c9b63601f9bdafecaa448a5eed64afc8c6 +PUB: 689f5410c8e0f4d37bc07c85d7cce6c9b63601f9bdafecaa448a5eed64afc8c6 +MESSAGE: 6f20a9ad27e30dac76b30d4c19a5bd6dfd6d049213f4becdd963d72b8b2dad687b003808201d50f7dd6e599ef58ceb6068c545ed99b9e763f9b0ec1db5fcbd7d490a121ecec6bba1eb5edbd6de85364707c55e300c8b16bb2530f70898136689c988591d5391d9cc347d7931061a9b7696e2c9f35bc0d304a81c2cf954d9c3a88a22e1d67bbe0a85308477f62918c25db504e4762f0e3b4246007908ac701779006b77d72510edc69e17d0f6394c77e5551875a446f81233415d0a91a0460b51c413d644e850f8557281c46699e53b22a7c73b068ea38652cff3b0a7b8ba30971eab18fdbbd8739ee1ee0cd5cbfb7d5d41757b6331271fb7809751e203513c9970f66d91bc0ce062f4fcb28be0a699867b79594c6458a0d307acac91f413c4615877dc53e1b018da5cfce1b63f40be1e55274c4374cdfc21524499a683a231adef779d1921440e5d3fdbd5033dc983cfc931abe638c35d5a95869e9fe3d93eb90bd1861f855ce1f608b7bcad6b5e1bd97edc95ed5ddcbcb715d919f5ff77df2da438f7a3a98286dbd5b6e043fc7372f69704f09d865530f4f0edd3300f185b6d73d8716d32d32b1c9ac2ddf4f902d3f216d35a33f368095ded10be94bb53d6f256560fac2f4af0edf5c5c702143777126e7de32d07493932662129ba0e7fc7cfb36fd2ca531646e8cd2211854fc510af3b1e8cafde7a +SIG: 8d2bc4e1cd256aad8a151dec010dc93a5e5cca58298dec49cbc9c4717b5cfb5460d430be726b0f302cbd926beea19aa3c93aeb452a44f6007af49adf2f05bb04 + +PRIV: bc3b1e0bf8d69ea5b4cbbf10bb33fc955adcbe13fc20af8a10872ce9df39d6bdaccd2628155919bbc7f9d86f91dafec35c711a78c79ad360eddb88fa8a180b2d +PUB: accd2628155919bbc7f9d86f91dafec35c711a78c79ad360eddb88fa8a180b2d +MESSAGE: 4c73e04abe0819de1f84d70541eb1bb61c4f42920e1f2d1d9e6281a8a2e8b3eb45537d83969027f99ef0ea27ca085b13f9db480f00c02f3fd7429dd567708953bbf3b9e8e2c6ac4d321ff8f9e4a3154723085a54e9c9573cc7350c09f8973f948b08730373597a5fd0349821ae0a3cd6c84992b189128f3490987e1e9ad4f6574ca538fdfd83284c1eb0953f24c08f74932d4364dbbef922542440dae80424a92eaef27c1889bd08c44f9df03a3af30dffb48fae445e625f4d9265cf387a1da35fe4c231504535db72ea81a186805f856ebe6a6a65241432530fe6c960c5f9be6c22957060304e9dd8efbc1e482e7ddbd8af03bf2382899c986d916611e4f27ae52f817ef01b6a141fe4f685d94dc8cd52830043934587704c1e642e8fe56be6d6b85bf4a6feb2b6858f1f007f99d39ea04c9fe5fa7ef1b91f495ed0e7fa4213dd68cea42b6729f95031907e27c44098094386fabfb04ab9b4de3d6861de462312c59b27c76f7b6a4fc71ea0d5daf6b7320521a67e5cb37504976ad73dae2d649feb75e2eadd3401a7f2f36e16dfbfbdb2af5716cba1bce20cd47ce1c1d7be00697001fbbeb4915aa6e5393b5ab20e0f31f5119149a2cb4c4d452c8156113ac7824f84f09aeb81202e8dd3dac0aa89399b5a38b1e218301960a37d52632eeaefe3687455464288eb17d9e19a3a72ed9de32c17be79a3b9 +SIG: 6ef7f0e91f2cc6715f8e5a98574b4400c261a643e0545ff26747f8e1739899d76640b6451c43c1d03a4775b54fcf9bce18ed3fccad338b7764024fdfa2de8201 + +PRIV: 10718fa6e2d7f6ed38fd66cb6dbfa087e8f1e8a8a24fab58d79d7954b8720c3e870d4f666d06fda9f9511b58602eec050d754ea6d8e79cdd19f601c477df1aa0 +PUB: 870d4f666d06fda9f9511b58602eec050d754ea6d8e79cdd19f601c477df1aa0 +MESSAGE: 41259b6eef13d6ffe33cdde799b995c40be782cf978440b66be51c440582abd42f526696bb3cb92265b1ed0e4bba764cae2839830a252635dc80ce5f73d521b3d6ff03ac30e198ad20567e75a34fa825ebf9841508da84cd674236ca7b43de3564c94ab079408fd94137ce3f90a5dd5d3ac39a05ec86715a8f025e4539a7640ab88836f4efbabd5e1652c49ea21613acfe343a880ee5a42f2f9134ef4e3716b16d134a9c4c71c39b3c1a857d3c89439783eef1edd71bf4492d05fd18673a5242ff4187b9de47ad4968da49dba5a6092e95ea27ddfc7448dcf5972d9d228d63e5291ba6e6fbd07e3241f9366ca4976bb04b22d01f0dbae794fa9c1d9029f88a83602b0e0ec55e22c37b201125cadb5341ef73f6da1abbe2b1c475f0750345b1be4259d8c28531ffe7788667c410dac339918c869b00ab80f20bf7990d366f9b3d5e8eb2f48d7ed0e64b85dc9fe3bb998b1eecd1231e902d2d152e09da2d2592bdb32c8cd2e2c489496b2980c03dbb09ec7f8a4ea2c7020f2a0faa657cd6ced48d6da27864cf5e97eea9b3c2f0f34abf8d87bd2adeb60c7272fc4306d955bdc8023d7d3dc2f3dafe9ebe8a8d138965a7f6ce93517cd2099663f67c34552176ddb595ac6ea5609febcf24c7d69d412709e578670a21ac8afccb8bf2b18ff3af7de21dc71d50d60d37b6ed729db04beff7d34b2920d87551ce15 +SIG: e1659186f1f76fe43ac8a11703360fbeff53b5e57b5974aaa08e2575579c27084cf6802e7c206347314475b603197494e7d61fe4b1ee7b78e18d94469352df0c + +PRIV: c1d4724c6cb1bc6723b2b43034278b3c5b48fed7f8a3cc2318033e7552047351c27e392e7c3664b9061ea76d2575dd7c41eaf1da3a65f3a986e0a57f6c40c17e +PUB: c27e392e7c3664b9061ea76d2575dd7c41eaf1da3a65f3a986e0a57f6c40c17e +MESSAGE: deee99d7a77d4300c17aec1ab323c571c6e9e73a43491a3c7888b76fc03ec43d07af42a05a2aa322d00c8560acef314106b10b9bd12654357ffa26f2390050da63d668c9e2df548f87639e096a35853f82e761fd711d2a265438f5d4db5e32775708150da6cb686a2b4ca211d7f00dc0abcb2ca150e791116a10a5efcff3514dab8ed80a7092c3a015152cb25d9f86ec0d1ca67ddab44d64eeb1f931bfab2ab188956c743db4814808c5cde1b0745b3edd340eb03ffcc80a78f3db310f4f5c20009fc0279c2c1bcb3cedf990bd0e20c6f9fb7515ad6e933b07e99da6ac32b97141187ef63bdb1062e37220a4dcd419d6244cdcc34ea41d0bcbc3138b1d54aefc0190e30b187db073aa7d6cfe04bd3fd2ac00313e3ddd64a181935ca4b8b2a85d36bc27d97b7626767b93ee38def8b6b2c8da9b00263614342faa9d3e738d2713c45ffbeef8c84bcdbc8da4309c8445530f5c617dc866251f548950a14f075aa3117f96e41f899dbe7340b1d90a1352d3b8fb41b79f16a82bc2e4a193b8a7232400996b73b1fc00b2ec1c667577f82824d39fb7f6e7692dcd97b1d8ce94083ca197e9a5d40fadff0b9ac57e9de761c156e6d31d52c332d513e9f58697dcbdd80a5e42c551702c3de7beccc3db845b1a04c8cbd41695ea7428abba89e0dce3e3d9e70230ae9147c2b88559dc695d6809a51ccbc1dd9e089c585f +SIG: d37a6ec82ed45ca9b4855de9cb942564e883ff70a79b8e712d5f604ec8974de5363ac849cbab28e7aeeff28ed3f2d14b608b3146c2efe0735ad815c7d75a1a01 + +PRIV: 37c070d4a53b13be760635110d1bd4f01920225afabec576faaec910f2926d1a0aa85f2ab1dff895d1fad0c119f2bf57126aab601c528d37698e97702d35f525 +PUB: 0aa85f2ab1dff895d1fad0c119f2bf57126aab601c528d37698e97702d35f525 +MESSAGE: 10c646447f81ad94d015d86d0d98b2452dca60a47ab35264035e33a0942b954e3e23b91d8123b8593c6af7c8d3ecd290e0e5ee36fd4e53b7be633a6cf027a5ac3f0f679eb1bdd210a38ea6e48b0558e303010af474e7f6df2a4e457699fc38e36938b05ffcaa1b694e32f3d1b2cc5d00cf256f12184c873e519089ec1df15b0dc76e7bfe90780df58136fe597fce894ca563e08efa0f2d4d208bede9a874882873d251baf019fe46d1d6504b3bcd243b795351f34d2e7606aa975528ee50d59efb6ee6992a89b2426956c2ca4247e0df0129852983e9767a8eed1bc7335ffca8d0289f04807f67ca7da971f58db8b9bc9fdbe4f83cfe9a00f1ca584798bc71d851ff7cd6c51b8990aaba4d38b416b92240dfb70ee3c12b5e731057762ef90823fbf683ca06d05c20d3ae2b97a83ebe70ae17afff9d16609d546d8d3c74bc281884894f3d49e083f10ae7c11c1dca0effefcfa6e0f1535081fac3a2819fd2e3265527182ae9d391b232bb7542e68455cd267760db652d19e22fb2ed11cd1305ba8d98c1ebf2d1969b24d64f3e319af74e092006d2a3ff744872a20ebf18d17748ab7110805096ea136bce2f968b205e650b803c531d06775ae5ceea28bb92e9a0edec8951ce2009a88ee1b64d9b9e89f69051203384210a102a44d2d6703173b68507dceadd3bf6510df2a5cefd9c80e4f385b2f9e6215813ed32 +SIG: 9da60cc4a64d07dee1346bd3d3010995ce2738208ab35b34c2a8fd1787ae3a1e207fe784525154fae4f5794cd8503045fea85cf77fd92f6a70cd0c5a52c0810e + +PRIV: 1126496a582ce58d3d618dd8a3933547aa7a8a30fb54063b8dfdd31671c6c73de10229c623fa8ad8982c3e4c36ff52df0f219b57915b6e980e5fe72ea0962e22 +PUB: e10229c623fa8ad8982c3e4c36ff52df0f219b57915b6e980e5fe72ea0962e22 +MESSAGE: 6a4b52d730ddab829b2a179590cbd4c372498e9f439977c0a10dc13c0ae1736eaaff063371434fd0da80360ec5890607d2fae1c9a2e1ab0b7f3d667f5b1b9c418f18b10c9e6fd669d3ebec168efef44163e577a2ebd0f2cb768f80c23188e86069e4d10f410306cedd7a341a61e0f4f3bc25041bc2f922ed073e1e2f1b709c579d10630f33071754d707894a1c62190de18882c564dc4c01dc545dd8966404ed78fa3267a9469f63b6120abb65f9b3ba3eee28d79c2eb4e7020cc6987dfc5c29672f8c0fa3e690d584fe000c64f352610179621bfd5ff3eb30d18f1a0250416db93b1c1e93cf8a3646517560d1cc8fff822b51ef27b200e987b592390753453ef138bd3d29db7cb1b5f45e4795b89c53f49704192752237c6ab274849f9594ee9777f6efe70483129d067f97199d9ae36090703864f7ca4750a6f3b6ff83824c910484394d1e2eceba18446fe4e994ce07433a740ddd05f0e396d482894e6f14acf7b97bae6c7eb88703039fa785d60a3af78b13243a4f88dde1d998617f2e3fa7eafc2f435dd4ac1ea9c238407aa09b4eea8ed434927b406674ac270458cfb3bf29c347f94559613179b9502192321b88e9af0a90e9a4ab9eddaae382e3734d1415ebe32499c34e6fdeaf15b0d9787985e08dfe495460c54f6743d81ff16881e5e30c51f4b092373783f12423c3e1ae8591130a269980caa1cb5c +SIG: b30eb56ca9b120bf849a3a9d56af033de8a590c9e1240c1e36dbc6cf0a71b78a11ec143fb9959a8f25b57711d6a90a67e01be3a4da2b69394869bb8d64b87e0f + +PRIV: 9c167aff3b1b788f133d422de8ca9a64316409f9e35bfe22032ec417ae9abc6defb534f0d47c068e77b28a906d95ad8d213a4d4fc1c70542f01e596d57b5f019 +PUB: efb534f0d47c068e77b28a906d95ad8d213a4d4fc1c70542f01e596d57b5f019 +MESSAGE: 68ac0fc2b607ba38e377fae845c808c8f9fa614eb1f31158a9620a937d3e301e85acaa69144bc349a39dfb582041c4a197ae99b4d4d59b7a2ca3d16228b5591cbf57c18a781efd19193c47b16c6023a3a8ba3d668f05a37f1e83b0d7febdd10f63e48ef7a20e015b1c6725d4c300a986c60e3a115469c8e52ba05b51c05d0af40d89fd9ed76f36950aee3c7819898a903cfe0361a91c69100b495141e86ee79d63d17403fb1a1629ef63cb7e9d2720cbfff0002b190bcdc26794124dd38d42bcaa7175405eb0bbcf8e37d65d05a37195b479371fa2bbbb167d91cee88235dd72ea88fc73ce3ce43d33b715f25f192ec215dac124899c5e7586e86340d8cbe53735defbe02e4cc9fde69fb9794d1db72b98c0f19766ee5138bbfa78909aa299b4913c499deaf54b4841d5044829984936700dcf92f36542b2fc7e86441b9925f5d0b78c17a85cfcfcb20b0fd751349c27463abde4d27df74265288713f96dea013b945521808b4996b1b2dc0338b6d236efd6d2b27dafda46ec5fa32b965e8bb5e8bb61bd966edeb774681e0ea8c17b8c99fa7d660f0f66c9bc6d95cbd7dc094724098eb05191b53a3df6566b9c90e0d7dff2943848b61a20d48c22b6d3c958e293d709c8f48110230ff51918562877daf6d920c85a82e07c451fe7ae9759c0a77e97bb298b5d0592a41d08f67a4ed5a1bb41e937b6a68aeb38fd5be9 +SIG: c9ae67fd6415dcbab292fab394ca6c3b7d90ca244dc6a7764e74fd202bf4b2905bd2030e6beb914c3c238db371b1cba6d9261aa392ec871a4b8b12fe9c1c970e + +PRIV: e9948805eb341b2867479c668fd3532c309941c0ad4cb2e54231756e6a1bdecb5447a8e34d6a640002d8d60bcf1ddc711e4c465c94c34b50bdef358960ff81f1 +PUB: 5447a8e34d6a640002d8d60bcf1ddc711e4c465c94c34b50bdef358960ff81f1 +MESSAGE: 91cffd7eb1cf6bd4756bce6a30af9dfba26ddd1cce0394c194a3e39cc3d1cbc221b7eb70bea18d29c267457176a3c9e53c18e47d10a67c464505197702e6b2470d38869db5174b158f9992e4435d02246f540258dedd3ce33df582555a681fb76ecaccb1c2989b177e3b7e454aaa529de59bf5a03123d571df2e7f7cb830805c58b74a653bac0e5a888e08dc2236d6cd496aa06d0d67cf3b335e218c49dedad82fc1be9ef20cac61905c30eb132d739b16ca8a8c906619c0e0d8b33985327e36f3d4b8fda387c186cc50443104db761f7ff9301270204a713e58902101fad000ce931647c577fdec148dca95cdc08918ebed037c60332fadf088f036083ebc92e173b7ddcc30c493f27e69cd17a20d30b78f83a72e4f5a747d86d96c5e1bb7a438166204013e2164d6aabc0d562f54015c365c80445607145e5692ee34f6353077fab7452d88ce3eb01d2b3797dc91b341a3a726301516baae18e851f74dfbdf0866bb2376867de55231e362c472c52116544cd4f81e93571c4ec820e7e653f4e21be0a942576c9de91e7d1251683d859de448f822dcf3d2cf55ede2f9c71b6063d1373061f8f5936b698d1384e65459ea2bc26ec96775ef425207432dda0ac1fe28526c5e4559349c3d8df9918230f4044683cc2c1b858d141ab8d0805bb9336067522aa89c810f3eaa7ac2d8dd28c3751225a19ecec8bcca52439946 +SIG: d3dc62d6ce9c766f2abaf9a7fbe09d6bdb07a4747b56080db09beb4a4e804a70d7ddf4119475c7be834f31956f4a71dad029cdf2363dd0365ce22dc27f078003 + +PRIV: b01753efa73bb3de7aa778be7afcbff66a5d3e2c2f8b5aa2b048844050996965d0cc6cf109c999fbf6d16f471fafd0232b0a68d4c46406ec7545dbaba8194158 +PUB: d0cc6cf109c999fbf6d16f471fafd0232b0a68d4c46406ec7545dbaba8194158 +MESSAGE: 684e612f27eead0d34844cc81ba911c28aaf6d66e71229e8cc3462f7c7a050daa30cb74471150f07dad459b5a91358476c0598255d8a642dd7c0802811bd88e4cac597efe41ebd96cd0f3b5ce72db4be1a3dbd6b84f5446e3da600d3b1d2b460a009bd31cacd98a91518ce33e9a703d404288736ccc43103fc69e67974f31652fa3dadef3337f6c897a3d201303c8f03597b4a87c98f291ccd58a3f1e898332aa5993b47fcb5ddaa1c0868b643742d0e4a4b9cd427038b3b74999bc89ac3484c0ca13f25aae8e78ae1ccee6218accab81a4f694f5324a347629d49b55e4037504a9acc8df58c6841dddcd4fc4347f7b6f1fd9de0564577e6f329ed951a0a6b9124ff63e22eb36d3a8863bc1bf69cea24c605967e7d8948953f27d5c4c75f0849f872a3e3d16d422fa5a11e1b9a74df6f38b90f277d81fce8437a14d99d2bef189d7cac83ddc61377ed348b3c4fc09ec2b9005925d04a71e26d641667bdf549294331c6ea01cd5c0bd1b6a7ecfda20b0f1929582b74697cb262c3927d6b223f4b5f3043aa6eb4571a78e9da11c2b36f64552580caa7b5fa6b90f929e0162e608d1240d7242cd2f47025c03debe059b1dc94770232bc6765148480bb1d9f50da1ee6448cf9c88b19dd459932c06ed811c4a64a12d5938bd1c757bcfaeaee8933fe5fff21763de740482bcf1ba59afdc8fcf873c3d507bb394e32e45f736519 +SIG: 16b7421227ae09130685cbb1a0c60aa57a5e1afe1bbe6bacea0c281bcc8998e6824a772c3208a6b6b4d236695505c9be82700cf93a783985a39e16e377a7410e + +PRIV: 4f4b20d899366f2f23ee628f229b236cf80f43ba183177c97ee34829546f1742c94576641f4a893cdfcee7b39fc21929b86b349976d7b0a46d39a588bcfe4357 +PUB: c94576641f4a893cdfcee7b39fc21929b86b349976d7b0a46d39a588bcfe4357 +MESSAGE: db8ef02e3033e6b96a56cab05082fb4695f4a1c916250dd75173f430a10c9468817709d37623346ae8245b42bda0da6b60462ccfdfc75a9ab994e66c9ab9fecdd8599610910affe4f10215cb280bf8f9f2700a444796dae93e06c6bea7d8b4fe1301baa79ccec769368feb2442c7de84f095e6b3bff63d388cbafb2b9809dc38e9b12ebd039c0a57f4d522e91ec8d1f2b8d23a4a0ae059af85393bb0a15f749110f6774a1fd731a6ec213e4ff435daab546d31ed9ec3b6d8cc2edacebf4facc5566556eea92e5b3f2542239b25e28012dd4ef40072eebf83ed2a255181f3a442189d68c6c609f4dfdf3db7d67d087a2fcd6d2dc50bbfed8bfbbfcb74d3c41f02a87865b13b8efcf5c3581257be0aa913f60c370527bde11a475c136a17c5eefeb03f5bff28693ed841e8ed1f7c29102f5599dd444009bcea6a92d5574152458e0caf8a36aa72b5dc4908a6461c9b741453005c8fbcc68113ae184208ee14b835480c6efafed18a76000b38e5858290f4d51f52f096cbe490e1eb5cacb226ec495a55a7fa457843d57fab67f8be7e209334785bdd665d7b63e4daf57b6e78928b603c8c0f9bc85464733b61273ef9e2b8a0cd7c3bf8ee0a6872e34d5a27a625e35eaf7ff5440b8b141af704df70c9c18623bd11209513192505105cd7bcfa5f0d919da706948fbe1f761f315846aa3b4813dd9ba3d81b9204e5409c0382b6eb +SIG: 0f80ff5d17488fe26f93c543b04ed959b5f0643fc61c7f2c3bc60132ba9c6210c8b250ea5e84d07b01de68bc174414eeeb31fdc2ba6823e231e312a91ededd02 diff --git a/src/crypto/curve25519/internal.h b/src/crypto/curve25519/internal.h new file mode 100644 index 0000000..27994b7 --- /dev/null +++ b/src/crypto/curve25519/internal.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CURVE25519_INTERNAL_H +#define OPENSSL_HEADER_CURVE25519_INTERNAL_H + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_SMALL) && \ + !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_ASM) +#define BORINGSSL_X25519_X86_64 + +void x25519_x86_64(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]); +#endif + + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) +#define BORINGSSL_X25519_NEON + +/* x25519_NEON is defined in asm/x25519-arm.S. */ +void x25519_NEON(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]); +#endif + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_CURVE25519_INTERNAL_H */ diff --git a/src/crypto/curve25519/x25519-x86_64.c b/src/crypto/curve25519/x25519-x86_64.c new file mode 100644 index 0000000..9776c75 --- /dev/null +++ b/src/crypto/curve25519/x25519-x86_64.c @@ -0,0 +1,225 @@ +#include <openssl/curve25519.h> + +#include <string.h> + +#include "internal.h" + + +#if defined(BORINGSSL_X25519_X86_64) + +typedef struct { uint64_t v[5]; } fe25519; + +/* These functions are defined in asm/x25519-x86_64.S */ +void x25519_x86_64_work_cswap(fe25519 *, uint64_t); +void x25519_x86_64_mul(fe25519 *out, const fe25519 *a, const fe25519 *b); +void x25519_x86_64_square(fe25519 *out, const fe25519 *a); +void x25519_x86_64_freeze(fe25519 *); +void x25519_x86_64_ladderstep(fe25519 *work); + +static void fe25519_setint(fe25519 *r, unsigned v) { + r->v[0] = v; + r->v[1] = 0; + r->v[2] = 0; + r->v[3] = 0; + r->v[4] = 0; +} + +/* Assumes input x being reduced below 2^255 */ +static void fe25519_pack(unsigned char r[32], const fe25519 *x) { + fe25519 t; + t = *x; + x25519_x86_64_freeze(&t); + + r[0] = (uint8_t)(t.v[0] & 0xff); + r[1] = (uint8_t)((t.v[0] >> 8) & 0xff); + r[2] = (uint8_t)((t.v[0] >> 16) & 0xff); + r[3] = (uint8_t)((t.v[0] >> 24) & 0xff); + r[4] = (uint8_t)((t.v[0] >> 32) & 0xff); + r[5] = (uint8_t)((t.v[0] >> 40) & 0xff); + r[6] = (uint8_t)((t.v[0] >> 48)); + + r[6] ^= (uint8_t)((t.v[1] << 3) & 0xf8); + r[7] = (uint8_t)((t.v[1] >> 5) & 0xff); + r[8] = (uint8_t)((t.v[1] >> 13) & 0xff); + r[9] = (uint8_t)((t.v[1] >> 21) & 0xff); + r[10] = (uint8_t)((t.v[1] >> 29) & 0xff); + r[11] = (uint8_t)((t.v[1] >> 37) & 0xff); + r[12] = (uint8_t)((t.v[1] >> 45)); + + r[12] ^= (uint8_t)((t.v[2] << 6) & 0xc0); + r[13] = (uint8_t)((t.v[2] >> 2) & 0xff); + r[14] = (uint8_t)((t.v[2] >> 10) & 0xff); + r[15] = (uint8_t)((t.v[2] >> 18) & 0xff); + r[16] = (uint8_t)((t.v[2] >> 26) & 0xff); + r[17] = (uint8_t)((t.v[2] >> 34) & 0xff); + r[18] = (uint8_t)((t.v[2] >> 42) & 0xff); + r[19] = (uint8_t)((t.v[2] >> 50)); + + r[19] ^= (uint8_t)((t.v[3] << 1) & 0xfe); + r[20] = (uint8_t)((t.v[3] >> 7) & 0xff); + r[21] = (uint8_t)((t.v[3] >> 15) & 0xff); + r[22] = (uint8_t)((t.v[3] >> 23) & 0xff); + r[23] = (uint8_t)((t.v[3] >> 31) & 0xff); + r[24] = (uint8_t)((t.v[3] >> 39) & 0xff); + r[25] = (uint8_t)((t.v[3] >> 47)); + + r[25] ^= (uint8_t)((t.v[4] << 4) & 0xf0); + r[26] = (uint8_t)((t.v[4] >> 4) & 0xff); + r[27] = (uint8_t)((t.v[4] >> 12) & 0xff); + r[28] = (uint8_t)((t.v[4] >> 20) & 0xff); + r[29] = (uint8_t)((t.v[4] >> 28) & 0xff); + r[30] = (uint8_t)((t.v[4] >> 36) & 0xff); + r[31] = (uint8_t)((t.v[4] >> 44)); +} + +static void fe25519_unpack(fe25519 *r, const uint8_t x[32]) { + r->v[0] = x[0]; + r->v[0] += (uint64_t)x[1] << 8; + r->v[0] += (uint64_t)x[2] << 16; + r->v[0] += (uint64_t)x[3] << 24; + r->v[0] += (uint64_t)x[4] << 32; + r->v[0] += (uint64_t)x[5] << 40; + r->v[0] += ((uint64_t)x[6] & 7) << 48; + + r->v[1] = x[6] >> 3; + r->v[1] += (uint64_t)x[7] << 5; + r->v[1] += (uint64_t)x[8] << 13; + r->v[1] += (uint64_t)x[9] << 21; + r->v[1] += (uint64_t)x[10] << 29; + r->v[1] += (uint64_t)x[11] << 37; + r->v[1] += ((uint64_t)x[12] & 63) << 45; + + r->v[2] = x[12] >> 6; + r->v[2] += (uint64_t)x[13] << 2; + r->v[2] += (uint64_t)x[14] << 10; + r->v[2] += (uint64_t)x[15] << 18; + r->v[2] += (uint64_t)x[16] << 26; + r->v[2] += (uint64_t)x[17] << 34; + r->v[2] += (uint64_t)x[18] << 42; + r->v[2] += ((uint64_t)x[19] & 1) << 50; + + r->v[3] = x[19] >> 1; + r->v[3] += (uint64_t)x[20] << 7; + r->v[3] += (uint64_t)x[21] << 15; + r->v[3] += (uint64_t)x[22] << 23; + r->v[3] += (uint64_t)x[23] << 31; + r->v[3] += (uint64_t)x[24] << 39; + r->v[3] += ((uint64_t)x[25] & 15) << 47; + + r->v[4] = x[25] >> 4; + r->v[4] += (uint64_t)x[26] << 4; + r->v[4] += (uint64_t)x[27] << 12; + r->v[4] += (uint64_t)x[28] << 20; + r->v[4] += (uint64_t)x[29] << 28; + r->v[4] += (uint64_t)x[30] << 36; + r->v[4] += ((uint64_t)x[31] & 127) << 44; +} + +static void fe25519_invert(fe25519 *r, const fe25519 *x) { + fe25519 z2; + fe25519 z9; + fe25519 z11; + fe25519 z2_5_0; + fe25519 z2_10_0; + fe25519 z2_20_0; + fe25519 z2_50_0; + fe25519 z2_100_0; + fe25519 t; + int i; + + /* 2 */ x25519_x86_64_square(&z2, x); + /* 4 */ x25519_x86_64_square(&t, &z2); + /* 8 */ x25519_x86_64_square(&t, &t); + /* 9 */ x25519_x86_64_mul(&z9, &t, x); + /* 11 */ x25519_x86_64_mul(&z11, &z9, &z2); + /* 22 */ x25519_x86_64_square(&t, &z11); + /* 2^5 - 2^0 = 31 */ x25519_x86_64_mul(&z2_5_0, &t, &z9); + + /* 2^6 - 2^1 */ x25519_x86_64_square(&t, &z2_5_0); + /* 2^20 - 2^10 */ for (i = 1; i < 5; i++) { x25519_x86_64_square(&t, &t); } + /* 2^10 - 2^0 */ x25519_x86_64_mul(&z2_10_0, &t, &z2_5_0); + + /* 2^11 - 2^1 */ x25519_x86_64_square(&t, &z2_10_0); + /* 2^20 - 2^10 */ for (i = 1; i < 10; i++) { x25519_x86_64_square(&t, &t); } + /* 2^20 - 2^0 */ x25519_x86_64_mul(&z2_20_0, &t, &z2_10_0); + + /* 2^21 - 2^1 */ x25519_x86_64_square(&t, &z2_20_0); + /* 2^40 - 2^20 */ for (i = 1; i < 20; i++) { x25519_x86_64_square(&t, &t); } + /* 2^40 - 2^0 */ x25519_x86_64_mul(&t, &t, &z2_20_0); + + /* 2^41 - 2^1 */ x25519_x86_64_square(&t, &t); + /* 2^50 - 2^10 */ for (i = 1; i < 10; i++) { x25519_x86_64_square(&t, &t); } + /* 2^50 - 2^0 */ x25519_x86_64_mul(&z2_50_0, &t, &z2_10_0); + + /* 2^51 - 2^1 */ x25519_x86_64_square(&t, &z2_50_0); + /* 2^100 - 2^50 */ for (i = 1; i < 50; i++) { x25519_x86_64_square(&t, &t); } + /* 2^100 - 2^0 */ x25519_x86_64_mul(&z2_100_0, &t, &z2_50_0); + + /* 2^101 - 2^1 */ x25519_x86_64_square(&t, &z2_100_0); + /* 2^200 - 2^100 */ for (i = 1; i < 100; i++) { + x25519_x86_64_square(&t, &t); + } + /* 2^200 - 2^0 */ x25519_x86_64_mul(&t, &t, &z2_100_0); + + /* 2^201 - 2^1 */ x25519_x86_64_square(&t, &t); + /* 2^250 - 2^50 */ for (i = 1; i < 50; i++) { x25519_x86_64_square(&t, &t); } + /* 2^250 - 2^0 */ x25519_x86_64_mul(&t, &t, &z2_50_0); + + /* 2^251 - 2^1 */ x25519_x86_64_square(&t, &t); + /* 2^252 - 2^2 */ x25519_x86_64_square(&t, &t); + /* 2^253 - 2^3 */ x25519_x86_64_square(&t, &t); + + /* 2^254 - 2^4 */ x25519_x86_64_square(&t, &t); + + /* 2^255 - 2^5 */ x25519_x86_64_square(&t, &t); + /* 2^255 - 21 */ x25519_x86_64_mul(r, &t, &z11); +} + +static void mladder(fe25519 *xr, fe25519 *zr, const uint8_t s[32]) { + fe25519 work[5]; + + work[0] = *xr; + fe25519_setint(work + 1, 1); + fe25519_setint(work + 2, 0); + work[3] = *xr; + fe25519_setint(work + 4, 1); + + int i, j; + uint8_t prevbit = 0; + + j = 6; + for (i = 31; i >= 0; i--) { + while (j >= 0) { + const uint8_t bit = 1 & (s[i] >> j); + const uint64_t swap = bit ^ prevbit; + prevbit = bit; + x25519_x86_64_work_cswap(work + 1, swap); + x25519_x86_64_ladderstep(work); + j -= 1; + } + j = 7; + } + + *xr = work[1]; + *zr = work[2]; +} + +void x25519_x86_64(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]) { + uint8_t e[32]; + memcpy(e, scalar, sizeof(e)); + + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + fe25519 t; + fe25519 z; + fe25519_unpack(&t, point); + mladder(&t, &z, e); + fe25519_invert(&z, &z); + x25519_x86_64_mul(&t, &t, &z); + fe25519_pack(out, &t); +} + +#endif /* BORINGSSL_X25519_X86_64 */ diff --git a/src/crypto/curve25519/x25519_test.cc b/src/crypto/curve25519/x25519_test.cc new file mode 100644 index 0000000..85ee4a2 --- /dev/null +++ b/src/crypto/curve25519/x25519_test.cc @@ -0,0 +1,128 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#include <openssl/curve25519.h> + + +static bool TestX25519() { + /* Taken from + * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */ + static const uint8_t kScalar1[32] = { + 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15, + 0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc, + 0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4, + }; + static const uint8_t kPoint1[32] = { + 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1, + 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, + 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c, + }; + + uint8_t out[32]; + X25519(out, kScalar1, kPoint1); + + static const uint8_t kExpected1[32] = { + 0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea, + 0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c, + 0x71, 0xf7, 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2, 0x85, 0x52, + }; + if (memcmp(kExpected1, out, sizeof(out)) != 0) { + fprintf(stderr, "X25519 test one failed.\n"); + return false; + } + + static const uint8_t kScalar2[32] = { + 0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, 0x5a, 0xd2, 0x26, + 0x91, 0x95, 0x7d, 0x6a, 0xf5, 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea, + 0x01, 0xd4, 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d, + }; + static const uint8_t kPoint2[32] = { + 0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7, 0x95, + 0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0, + 0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93, + }; + + X25519(out, kScalar2, kPoint2); + + static const uint8_t kExpected2[32] = { + 0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d, 0x7a, 0xad, 0xe4, + 0x5c, 0xb4, 0xb8, 0x73, 0xf8, 0x8b, 0x59, 0x5a, 0x68, 0x79, 0x9f, + 0xa1, 0x52, 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac, 0x79, 0x57, + }; + if (memcmp(kExpected2, out, sizeof(out)) != 0) { + fprintf(stderr, "X25519 test two failed.\n"); + return false; + } + + return true; +} + +static bool TestX25519SmallOrder() { + static const uint8_t kSmallOrderPoint[32] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, + 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, + }; + + uint8_t out[32], private_key[32]; + memset(private_key, 0x11, sizeof(private_key)); + + if (X25519(out, private_key, kSmallOrderPoint)) { + fprintf(stderr, "X25519 returned success with a small-order input.\n"); + return false; + } + + return true; +} + +static bool TestX25519Iterated() { + /* Taken from + * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */ + uint8_t scalar[32] = {9}, point[32] = {9}, out[32]; + + unsigned i; + for (i = 0; i < 1000; i++) { + X25519(out, scalar, point); + memcpy(point, scalar, sizeof(point)); + memcpy(scalar, out, sizeof(scalar)); + } + + static const uint8_t kExpected[32] = { + 0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55, 0x28, 0x00, 0xef, + 0x56, 0x6f, 0x2f, 0x4d, 0x3c, 0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60, + 0xe3, 0x87, 0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51, + }; + + if (memcmp(kExpected, scalar, sizeof(kExpected)) != 0) { + fprintf(stderr, "Iterated X25519 test failed\n"); + return false; + } + + return true; +} + +int main(int argc, char **argv) { + if (!TestX25519() || + !TestX25519Iterated() || + !TestX25519SmallOrder()) { + return 1; + } + + printf("PASS\n"); + return 0; +} diff --git a/src/crypto/des/internal.h b/src/crypto/des/internal.h index 91559ff..00b4558 100644 --- a/src/crypto/des/internal.h +++ b/src/crypto/des/internal.h @@ -202,24 +202,7 @@ how to use xors :-) I got it to its final state. #define ITERATIONS 16 #define HALF_ITERATIONS 8 -#if defined(_MSC_VER) -#define ROTATE(a, n) (_lrotr(a, n)) -#elif defined(__ICC) -#define ROTATE(a, n) (_rotr(a, n)) -#elif defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM) && \ - !defined(__STRICT_ANSI__) && \ - (defined(OPENSSL_X86) || defined(OPENSSL_X86_64)) -#define ROTATE(a, n) \ - ({ \ - unsigned int ret; \ - asm("rorl %1,%0" : "=r"(ret) : "I"(n), "0"(a) : "cc"); \ - ret; \ - }) -#endif - -#ifndef ROTATE #define ROTATE(a, n) (((a) >> (n)) + ((a) << (32 - (n)))) -#endif #if defined(__cplusplus) diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c index a88520d..bf6196c 100644 --- a/src/crypto/dh/dh.c +++ b/src/crypto/dh/dh.c @@ -85,11 +85,7 @@ DH *DH_new(void) { CRYPTO_MUTEX_init(&dh->method_mont_p_lock); dh->references = 1; - if (!CRYPTO_new_ex_data(&g_ex_data_class, dh, &dh->ex_data)) { - CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock); - OPENSSL_free(dh); - return NULL; - } + CRYPTO_new_ex_data(&dh->ex_data); return dh; } @@ -239,11 +235,16 @@ int DH_generate_key(DH *dh) { int ok = 0; int generate_new_key = 0; unsigned l; - BN_CTX *ctx; + BN_CTX *ctx = NULL; BN_MONT_CTX *mont = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; BIGNUM local_priv; + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); + goto err; + } + ctx = BN_CTX_new(); if (ctx == NULL) { goto err; @@ -443,11 +444,11 @@ DH *DHparams_dup(const DH *dh) { return ret; } -int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int index; - if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func, - dup_func, free_func)) { + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func, + free_func)) { return -1; } return index; diff --git a/src/crypto/dh/dh_test.cc b/src/crypto/dh/dh_test.cc index 16a5ae0..c117bd4 100644 --- a/src/crypto/dh/dh_test.cc +++ b/src/crypto/dh/dh_test.cc @@ -68,7 +68,6 @@ #include "internal.h" #include "../test/scoped_types.h" -#include "../test/stl_compat.h" static bool RunBasicTests(); @@ -167,7 +166,7 @@ static bool RunBasicTests() { printf("\n"); std::vector<uint8_t> key1(DH_size(a.get())); - int ret = DH_compute_key(bssl::vector_data(&key1), b->pub_key, a.get()); + int ret = DH_compute_key(key1.data(), b->pub_key, a.get()); if (ret < 0) { return false; } @@ -180,7 +179,7 @@ static bool RunBasicTests() { printf("\n"); std::vector<uint8_t> key2(DH_size(b.get())); - ret = DH_compute_key(bssl::vector_data(&key2), a->pub_key, b.get()); + ret = DH_compute_key(key2.data(), a->pub_key, b.get()); if (ret < 0) { return false; } @@ -458,17 +457,17 @@ static bool RunRFC5114Tests() { std::vector<uint8_t> Z2(DH_size(dhB.get())); /* Work out shared secrets using both sides and compare * with expected values. */ - int ret1 = DH_compute_key(bssl::vector_data(&Z1), dhB->pub_key, dhA.get()); - int ret2 = DH_compute_key(bssl::vector_data(&Z2), dhA->pub_key, dhB.get()); + int ret1 = DH_compute_key(Z1.data(), dhB->pub_key, dhA.get()); + int ret2 = DH_compute_key(Z2.data(), dhA->pub_key, dhB.get()); if (ret1 < 0 || ret2 < 0) { fprintf(stderr, "DH_compute_key error RFC5114 set %u\n", i + 1); return false; } if (static_cast<size_t>(ret1) != td->Z_len || - memcmp(bssl::vector_data(&Z1), td->Z, td->Z_len) != 0 || + memcmp(Z1.data(), td->Z, td->Z_len) != 0 || static_cast<size_t>(ret2) != td->Z_len || - memcmp(bssl::vector_data(&Z2), td->Z, td->Z_len) != 0) { + memcmp(Z2.data(), td->Z, td->Z_len) != 0) { fprintf(stderr, "Test failed RFC5114 set %u\n", i + 1); return false; } diff --git a/src/crypto/dh/params.c b/src/crypto/dh/params.c index 6b30036..7e8102a 100644 --- a/src/crypto/dh/params.c +++ b/src/crypto/dh/params.c @@ -55,182 +55,169 @@ #include <openssl/bn.h> #include "internal.h" +#include "../bn/internal.h" -#if BN_BITS2 == 32 -#define TOBN(lo, hi) lo, hi -#elif BN_BITS2 == 64 -#define TOBN(lo, hi) ((BN_ULONG)hi << 32 | lo) -#else -#error "unsupported BN_BITS2" -#endif - static const BN_ULONG dh1024_160_p[] = { - TOBN(0x2E4A4371, 0xDF1FB2BC), TOBN(0x6D4DA708, 0xE68CFDA7), - TOBN(0x365C1A65, 0x45BF37DF), TOBN(0x0DC8B4BD, 0xA151AF5F), - TOBN(0xF55BCCC0, 0xFAA31A4F), TOBN(0xE5644738, 0x4EFFD6FA), - TOBN(0x219A7372, 0x98488E9C), TOBN(0x90C4BD70, 0xACCBDD7D), - TOBN(0xD49B83BF, 0x24975C3C), TOBN(0xA9061123, 0x13ECB4AE), - TOBN(0x2EE652C0, 0x9838EF1E), TOBN(0x75A23D18, 0x6073E286), - TOBN(0x52D23B61, 0x9A6A9DCA), TOBN(0xFB06A3C6, 0x52C99FBC), - TOBN(0xAE5D54EC, 0xDE92DE5E), TOBN(0xA080E01D, 0xB10B8F96), + TOBN(0xDF1FB2BC, 0x2E4A4371), TOBN(0xE68CFDA7, 0x6D4DA708), + TOBN(0x45BF37DF, 0x365C1A65), TOBN(0xA151AF5F, 0x0DC8B4BD), + TOBN(0xFAA31A4F, 0xF55BCCC0), TOBN(0x4EFFD6FA, 0xE5644738), + TOBN(0x98488E9C, 0x219A7372), TOBN(0xACCBDD7D, 0x90C4BD70), + TOBN(0x24975C3C, 0xD49B83BF), TOBN(0x13ECB4AE, 0xA9061123), + TOBN(0x9838EF1E, 0x2EE652C0), TOBN(0x6073E286, 0x75A23D18), + TOBN(0x9A6A9DCA, 0x52D23B61), TOBN(0x52C99FBC, 0xFB06A3C6), + TOBN(0xDE92DE5E, 0xAE5D54EC), TOBN(0xB10B8F96, 0xA080E01D), }; static const BN_ULONG dh1024_160_g[] = { - TOBN(0x22B3B2E5, 0x855E6EEB), TOBN(0xF97C2A24, 0x858F4DCE), - TOBN(0x18D08BC8, 0x2D779D59), TOBN(0x8E73AFA3, 0xD662A4D1), - TOBN(0x69B6A28A, 0x1DBF0A01), TOBN(0x7A091F53, 0xA6A24C08), - TOBN(0x63F80A76, 0x909D0D22), TOBN(0xB9A92EE1, 0xD7FBD7D3), - TOBN(0x9E2749F4, 0x5E91547F), TOBN(0xB01B886A, 0x160217B4), - TOBN(0x5504F213, 0x777E690F), TOBN(0x5C41564B, 0x266FEA1E), - TOBN(0x14266D31, 0xD6406CFF), TOBN(0x58AC507F, 0xF8104DD2), - TOBN(0xEFB99905, 0x6765A442), TOBN(0xC3FD3412, 0xA4D1CBD5), + TOBN(0x855E6EEB, 0x22B3B2E5), TOBN(0x858F4DCE, 0xF97C2A24), + TOBN(0x2D779D59, 0x18D08BC8), TOBN(0xD662A4D1, 0x8E73AFA3), + TOBN(0x1DBF0A01, 0x69B6A28A), TOBN(0xA6A24C08, 0x7A091F53), + TOBN(0x909D0D22, 0x63F80A76), TOBN(0xD7FBD7D3, 0xB9A92EE1), + TOBN(0x5E91547F, 0x9E2749F4), TOBN(0x160217B4, 0xB01B886A), + TOBN(0x777E690F, 0x5504F213), TOBN(0x266FEA1E, 0x5C41564B), + TOBN(0xD6406CFF, 0x14266D31), TOBN(0xF8104DD2, 0x58AC507F), + TOBN(0x6765A442, 0xEFB99905), TOBN(0xA4D1CBD5, 0xC3FD3412), }; static const BN_ULONG dh1024_160_q[] = { - TOBN(0x49462353, 0x64B7CB9D), TOBN(0x8ABA4E7D, 0x81A8DF27), 0xF518AA87, + TOBN(0x64B7CB9D, 0x49462353), TOBN(0x81A8DF27, 0x8ABA4E7D), 0xF518AA87, }; static const BN_ULONG dh2048_224_p[] = { - TOBN(0x0C10E64F, 0x0AC4DFFE), TOBN(0x4E71B81C, 0xCF9DE538), - TOBN(0xFFA31F71, 0x7EF363E2), TOBN(0x6B8E75B9, 0xE3FB73C1), - TOBN(0x4BA80A29, 0xC9B53DCF), TOBN(0x16E79763, 0x23F10B0E), - TOBN(0x13042E9B, 0xC52172E4), TOBN(0xC928B2B9, 0xBE60E69C), - TOBN(0xB9E587E8, 0x80CD86A1), TOBN(0x98C641A4, 0x315D75E1), - TOBN(0x44328387, 0xCDF93ACC), TOBN(0xDC0A486D, 0x15987D9A), - TOBN(0x1FD5A074, 0x7310F712), TOBN(0xDE31EFDC, 0x278273C7), - TOBN(0x415D9330, 0x1602E714), TOBN(0xBC8985DB, 0x81286130), - TOBN(0x70918836, 0xB3BF8A31), TOBN(0xB9C49708, 0x6A00E0A0), - TOBN(0x8BBC27BE, 0xC6BA0B2C), TOBN(0xED34DBF6, 0xC9F98D11), - TOBN(0xB6C12207, 0x7AD5B7D0), TOBN(0x55B7394B, 0xD91E8FEF), - TOBN(0xEFDA4DF8, 0x9037C9ED), TOBN(0xAD6AC212, 0x6D3F8152), - TOBN(0x1274A0A6, 0x1DE6B85A), TOBN(0x309C180E, 0xEB3D688A), - TOBN(0x7BA1DF15, 0xAF9A3C40), TOBN(0xF95A56DB, 0xE6FA141D), - TOBN(0xB61D0A75, 0xB54B1597), TOBN(0x683B9FD1, 0xA20D64E5), - TOBN(0x9559C51F, 0xD660FAA7), TOBN(0x9123A9D0, 0xAD107E1E), + TOBN(0x0AC4DFFE, 0x0C10E64F), TOBN(0xCF9DE538, 0x4E71B81C), + TOBN(0x7EF363E2, 0xFFA31F71), TOBN(0xE3FB73C1, 0x6B8E75B9), + TOBN(0xC9B53DCF, 0x4BA80A29), TOBN(0x23F10B0E, 0x16E79763), + TOBN(0xC52172E4, 0x13042E9B), TOBN(0xBE60E69C, 0xC928B2B9), + TOBN(0x80CD86A1, 0xB9E587E8), TOBN(0x315D75E1, 0x98C641A4), + TOBN(0xCDF93ACC, 0x44328387), TOBN(0x15987D9A, 0xDC0A486D), + TOBN(0x7310F712, 0x1FD5A074), TOBN(0x278273C7, 0xDE31EFDC), + TOBN(0x1602E714, 0x415D9330), TOBN(0x81286130, 0xBC8985DB), + TOBN(0xB3BF8A31, 0x70918836), TOBN(0x6A00E0A0, 0xB9C49708), + TOBN(0xC6BA0B2C, 0x8BBC27BE), TOBN(0xC9F98D11, 0xED34DBF6), + TOBN(0x7AD5B7D0, 0xB6C12207), TOBN(0xD91E8FEF, 0x55B7394B), + TOBN(0x9037C9ED, 0xEFDA4DF8), TOBN(0x6D3F8152, 0xAD6AC212), + TOBN(0x1DE6B85A, 0x1274A0A6), TOBN(0xEB3D688A, 0x309C180E), + TOBN(0xAF9A3C40, 0x7BA1DF15), TOBN(0xE6FA141D, 0xF95A56DB), + TOBN(0xB54B1597, 0xB61D0A75), TOBN(0xA20D64E5, 0x683B9FD1), + TOBN(0xD660FAA7, 0x9559C51F), TOBN(0xAD107E1E, 0x9123A9D0), }; static const BN_ULONG dh2048_224_g[] = { - TOBN(0x191F2BFA, 0x84B890D3), TOBN(0x2A7065B3, 0x81BC087F), - TOBN(0xF6EC0179, 0x19C418E1), TOBN(0x71CFFF4C, 0x7B5A0F1C), - TOBN(0x9B6AA4BD, 0xEDFE72FE), TOBN(0x94B30269, 0x81E1BCFE), - TOBN(0x8D6C0191, 0x566AFBB4), TOBN(0x409D13CD, 0xB539CCE3), - TOBN(0x5F2FF381, 0x6AA21E7F), TOBN(0x770589EF, 0xD9E263E4), - TOBN(0xD19963DD, 0x10E183ED), TOBN(0x150B8EEB, 0xB70A8137), - TOBN(0x28C8F8AC, 0x051AE3D4), TOBN(0x0C1AB15B, 0xBB77A86F), - TOBN(0x16A330EF, 0x6E3025E3), TOBN(0xD6F83456, 0x19529A45), - TOBN(0x118E98D1, 0xF180EB34), TOBN(0x50717CBE, 0xB5F6C6B2), - TOBN(0xDA7460CD, 0x09939D54), TOBN(0x22EA1ED4, 0xE2471504), - TOBN(0x521BC98A, 0xB8A762D0), TOBN(0x5AC1348B, 0xF4D02727), - TOBN(0x1999024A, 0xC1766910), TOBN(0xA8D66AD7, 0xBE5E9001), - TOBN(0x620A8652, 0xC57DB17C), TOBN(0x00C29F52, 0xAB739D77), - TOBN(0xA70C4AFA, 0xDD921F01), TOBN(0x10B9A6F0, 0xA6824A4E), - TOBN(0xCFE4FFE3, 0x74866A08), TOBN(0x89998CAF, 0x6CDEBE7B), - TOBN(0x8FFDAC50, 0x9DF30B5C), TOBN(0x4F2D9AE3, 0xAC4032EF), + TOBN(0x84B890D3, 0x191F2BFA), TOBN(0x81BC087F, 0x2A7065B3), + TOBN(0x19C418E1, 0xF6EC0179), TOBN(0x7B5A0F1C, 0x71CFFF4C), + TOBN(0xEDFE72FE, 0x9B6AA4BD), TOBN(0x81E1BCFE, 0x94B30269), + TOBN(0x566AFBB4, 0x8D6C0191), TOBN(0xB539CCE3, 0x409D13CD), + TOBN(0x6AA21E7F, 0x5F2FF381), TOBN(0xD9E263E4, 0x770589EF), + TOBN(0x10E183ED, 0xD19963DD), TOBN(0xB70A8137, 0x150B8EEB), + TOBN(0x051AE3D4, 0x28C8F8AC), TOBN(0xBB77A86F, 0x0C1AB15B), + TOBN(0x6E3025E3, 0x16A330EF), TOBN(0x19529A45, 0xD6F83456), + TOBN(0xF180EB34, 0x118E98D1), TOBN(0xB5F6C6B2, 0x50717CBE), + TOBN(0x09939D54, 0xDA7460CD), TOBN(0xE2471504, 0x22EA1ED4), + TOBN(0xB8A762D0, 0x521BC98A), TOBN(0xF4D02727, 0x5AC1348B), + TOBN(0xC1766910, 0x1999024A), TOBN(0xBE5E9001, 0xA8D66AD7), + TOBN(0xC57DB17C, 0x620A8652), TOBN(0xAB739D77, 0x00C29F52), + TOBN(0xDD921F01, 0xA70C4AFA), TOBN(0xA6824A4E, 0x10B9A6F0), + TOBN(0x74866A08, 0xCFE4FFE3), TOBN(0x6CDEBE7B, 0x89998CAF), + TOBN(0x9DF30B5C, 0x8FFDAC50), TOBN(0xAC4032EF, 0x4F2D9AE3), }; static const BN_ULONG dh2048_224_q[] = { - TOBN(0xB36371EB, 0xBF389A99), TOBN(0x4738CEBC, 0x1F80535A), - TOBN(0x99717710, 0xC58D93FE), 0x801C0D34, + TOBN(0xBF389A99, 0xB36371EB), TOBN(0x1F80535A, 0x4738CEBC), + TOBN(0xC58D93FE, 0x99717710), 0x801C0D34, }; static const BN_ULONG dh2048_256_p[] = { - TOBN(0x1E1A1597, 0xDB094AE9), TOBN(0xD7EF09CA, 0x693877FA), - TOBN(0x6E11715F, 0x6116D227), TOBN(0xC198AF12, 0xA4B54330), - TOBN(0xD7014103, 0x75F26375), TOBN(0x54E710C3, 0xC3A3960A), - TOBN(0xBD0BE621, 0xDED4010A), TOBN(0x89962856, 0xC0B857F6), - TOBN(0x71506026, 0xB3CA3F79), TOBN(0xE6B486F6, 0x1CCACB83), - TOBN(0x14056425, 0x67E144E5), TOBN(0xA41825D9, 0xF6A167B5), - TOBN(0x96524D8E, 0x3AD83477), TOBN(0x51BFA4AB, 0xF13C6D9A), - TOBN(0x35488A0E, 0x2D525267), TOBN(0xCAA6B790, 0xB63ACAE1), - TOBN(0x81B23F76, 0x4FDB70C5), TOBN(0x12307F5C, 0xBC39A0BF), - TOBN(0xB1E59BB8, 0xB941F54E), TOBN(0xD45F9088, 0x6C5BFC11), - TOBN(0x4275BF7B, 0x22E0B1EF), TOBN(0x5B4758C0, 0x91F9E672), - TOBN(0x6BCF67ED, 0x5A8A9D30), TOBN(0x97517ABD, 0x209E0C64), - TOBN(0x830E9A7C, 0x3BF4296D), TOBN(0x34096FAA, 0x16C3D911), - TOBN(0x61B2AA30, 0xFAF7DF45), TOBN(0xD61957D4, 0xE00DF8F1), - TOBN(0x435E3B00, 0x5D2CEED4), TOBN(0x660DD0F2, 0x8CEEF608), - TOBN(0x65195999, 0xFFBBD19C), TOBN(0xB4B6663C, 0x87A8E61D), + TOBN(0xDB094AE9, 0x1E1A1597), TOBN(0x693877FA, 0xD7EF09CA), + TOBN(0x6116D227, 0x6E11715F), TOBN(0xA4B54330, 0xC198AF12), + TOBN(0x75F26375, 0xD7014103), TOBN(0xC3A3960A, 0x54E710C3), + TOBN(0xDED4010A, 0xBD0BE621), TOBN(0xC0B857F6, 0x89962856), + TOBN(0xB3CA3F79, 0x71506026), TOBN(0x1CCACB83, 0xE6B486F6), + TOBN(0x67E144E5, 0x14056425), TOBN(0xF6A167B5, 0xA41825D9), + TOBN(0x3AD83477, 0x96524D8E), TOBN(0xF13C6D9A, 0x51BFA4AB), + TOBN(0x2D525267, 0x35488A0E), TOBN(0xB63ACAE1, 0xCAA6B790), + TOBN(0x4FDB70C5, 0x81B23F76), TOBN(0xBC39A0BF, 0x12307F5C), + TOBN(0xB941F54E, 0xB1E59BB8), TOBN(0x6C5BFC11, 0xD45F9088), + TOBN(0x22E0B1EF, 0x4275BF7B), TOBN(0x91F9E672, 0x5B4758C0), + TOBN(0x5A8A9D30, 0x6BCF67ED), TOBN(0x209E0C64, 0x97517ABD), + TOBN(0x3BF4296D, 0x830E9A7C), TOBN(0x16C3D911, 0x34096FAA), + TOBN(0xFAF7DF45, 0x61B2AA30), TOBN(0xE00DF8F1, 0xD61957D4), + TOBN(0x5D2CEED4, 0x435E3B00), TOBN(0x8CEEF608, 0x660DD0F2), + TOBN(0xFFBBD19C, 0x65195999), TOBN(0x87A8E61D, 0xB4B6663C), }; static const BN_ULONG dh2048_256_g[] = { - TOBN(0x6CC41659, 0x664B4C0F), TOBN(0xEF98C582, 0x5E2327CF), - TOBN(0xD4795451, 0xD647D148), TOBN(0x90F00EF8, 0x2F630784), - TOBN(0x1DB246C3, 0x184B523D), TOBN(0xCDC67EB6, 0xC7891428), - TOBN(0x0DF92B52, 0x7FD02837), TOBN(0x64E0EC37, 0xB3353BBB), - TOBN(0x57CD0915, 0xECD06E15), TOBN(0xDF016199, 0xB7D2BBD2), - TOBN(0x052588B9, 0xC8484B1E), TOBN(0x13D3FE14, 0xDB2A3B73), - TOBN(0xD182EA0A, 0xD052B985), TOBN(0xE83B9C80, 0xA4BD1BFF), - TOBN(0xFB3F2E55, 0xDFC967C1), TOBN(0x767164E1, 0xB5045AF2), - TOBN(0x6F2F9193, 0x1D14348F), TOBN(0x428EBC83, 0x64E67982), - TOBN(0x82D6ED38, 0x8AC376D2), TOBN(0xAAB8A862, 0x777DE62A), - TOBN(0xE9EC144B, 0xDDF463E5), TOBN(0xC77A57F2, 0x0196F931), - TOBN(0x41000A65, 0xA55AE313), TOBN(0xC28CBB18, 0x901228F8), - TOBN(0x7E8C6F62, 0xBC3773BF), TOBN(0x0C6B47B1, 0xBE3A6C1B), - TOBN(0xAC0BB555, 0xFF4FED4A), TOBN(0x77BE463F, 0x10DBC150), - TOBN(0x1A0BA125, 0x07F4793A), TOBN(0x21EF2054, 0x4CA7B18F), - TOBN(0x60EDBD48, 0x2E775066), TOBN(0x73134D0B, 0x3FB32C9B), + TOBN(0x664B4C0F, 0x6CC41659), TOBN(0x5E2327CF, 0xEF98C582), + TOBN(0xD647D148, 0xD4795451), TOBN(0x2F630784, 0x90F00EF8), + TOBN(0x184B523D, 0x1DB246C3), TOBN(0xC7891428, 0xCDC67EB6), + TOBN(0x7FD02837, 0x0DF92B52), TOBN(0xB3353BBB, 0x64E0EC37), + TOBN(0xECD06E15, 0x57CD0915), TOBN(0xB7D2BBD2, 0xDF016199), + TOBN(0xC8484B1E, 0x052588B9), TOBN(0xDB2A3B73, 0x13D3FE14), + TOBN(0xD052B985, 0xD182EA0A), TOBN(0xA4BD1BFF, 0xE83B9C80), + TOBN(0xDFC967C1, 0xFB3F2E55), TOBN(0xB5045AF2, 0x767164E1), + TOBN(0x1D14348F, 0x6F2F9193), TOBN(0x64E67982, 0x428EBC83), + TOBN(0x8AC376D2, 0x82D6ED38), TOBN(0x777DE62A, 0xAAB8A862), + TOBN(0xDDF463E5, 0xE9EC144B), TOBN(0x0196F931, 0xC77A57F2), + TOBN(0xA55AE313, 0x41000A65), TOBN(0x901228F8, 0xC28CBB18), + TOBN(0xBC3773BF, 0x7E8C6F62), TOBN(0xBE3A6C1B, 0x0C6B47B1), + TOBN(0xFF4FED4A, 0xAC0BB555), TOBN(0x10DBC150, 0x77BE463F), + TOBN(0x07F4793A, 0x1A0BA125), TOBN(0x4CA7B18F, 0x21EF2054), + TOBN(0x2E775066, 0x60EDBD48), TOBN(0x3FB32C9B, 0x73134D0B), }; static const BN_ULONG dh2048_256_q[] = { - TOBN(0x64F5FBD3, 0xA308B0FE), TOBN(0x1EB3750B, 0x99B1A47D), - TOBN(0x40129DA2, 0xB4479976), TOBN(0xA709A097, 0x8CF83642), + TOBN(0xA308B0FE, 0x64F5FBD3), TOBN(0x99B1A47D, 0x1EB3750B), + TOBN(0xB4479976, 0x40129DA2), TOBN(0x8CF83642, 0xA709A097), }; /* dh1024_safe_prime_1 is hard-coded in Apache httpd 2.2, * modules/ssl/ssl_engine_dh.c. */ static const BN_ULONG dh1024_safe_prime_1[] = { - TOBN(0x24218EB3, 0xE7393E0F), TOBN(0xE2BD68B0, 0x7DE0F4D6), - TOBN(0x88AEAA74, 0x07DD62DB), TOBN(0x9DDD3305, 0x10EA9FCC), - TOBN(0x74087D15, 0xA7DBCA78), TOBN(0x78045B07, 0xDAE88600), - TOBN(0x1AAD3B72, 0x33168A46), TOBN(0x7BEDDCFD, 0xFF590137), - TOBN(0x7A635E81, 0xFE324A46), TOBN(0x420B2A29, 0x5AC179BA), - TOBN(0x177E16D5, 0x13B4B4D7), TOBN(0x639C72FB, 0x849F912E), - TOBN(0x98BCE951, 0xB88174CB), TOBN(0xA45F520B, 0x0C84D239), - TOBN(0x4AFD0AD5, 0x36D693D3), TOBN(0xCBBBDC19, 0xD67DE440), + TOBN(0xE7393E0F, 0x24218EB3), TOBN(0x7DE0F4D6, 0xE2BD68B0), + TOBN(0x07DD62DB, 0x88AEAA74), TOBN(0x10EA9FCC, 0x9DDD3305), + TOBN(0xA7DBCA78, 0x74087D15), TOBN(0xDAE88600, 0x78045B07), + TOBN(0x33168A46, 0x1AAD3B72), TOBN(0xFF590137, 0x7BEDDCFD), + TOBN(0xFE324A46, 0x7A635E81), TOBN(0x5AC179BA, 0x420B2A29), + TOBN(0x13B4B4D7, 0x177E16D5), TOBN(0x849F912E, 0x639C72FB), + TOBN(0xB88174CB, 0x98BCE951), TOBN(0x0C84D239, 0xA45F520B), + TOBN(0x36D693D3, 0x4AFD0AD5), TOBN(0xD67DE440, 0xCBBBDC19), }; /* dh1024_safe_prime_2 is hard-coded in nginx, * src/event/ngx_event_openssl.c. */ static const BN_ULONG dh1024_safe_prime_2[] = { - TOBN(0xCFE16B9B, 0x071DF045), TOBN(0x146757DA, 0x88D0F65D), - TOBN(0x58FAFD49, 0x4A63AB1E), TOBN(0xEF9EA027, 0x35D8CECE), - TOBN(0x70CC9A50, 0x25ECE662), TOBN(0x81DC2CA7, 0xF29BA5DF), - TOBN(0xF7D36CC8, 0x8F68B076), TOBN(0xA757E304, 0x60E91A92), - TOBN(0x9BE67780, 0x87A2BC04), TOBN(0xA5FDF1D2, 0xBEECA565), - TOBN(0x922614C5, 0x5CCBBAA8), TOBN(0xE710800C, 0x6C030276), - TOBN(0x0FB3504C, 0x08EED4EB), TOBN(0x68B42D4B, 0xD958A3F5), - TOBN(0x80E9CFDB, 0x7C43FCF5), TOBN(0xD8467490, 0xBBBC2DCA), + TOBN(0x071DF045, 0xCFE16B9B), TOBN(0x88D0F65D, 0x146757DA), + TOBN(0x4A63AB1E, 0x58FAFD49), TOBN(0x35D8CECE, 0xEF9EA027), + TOBN(0x25ECE662, 0x70CC9A50), TOBN(0xF29BA5DF, 0x81DC2CA7), + TOBN(0x8F68B076, 0xF7D36CC8), TOBN(0x60E91A92, 0xA757E304), + TOBN(0x87A2BC04, 0x9BE67780), TOBN(0xBEECA565, 0xA5FDF1D2), + TOBN(0x5CCBBAA8, 0x922614C5), TOBN(0x6C030276, 0xE710800C), + TOBN(0x08EED4EB, 0x0FB3504C), TOBN(0xD958A3F5, 0x68B42D4B), + TOBN(0x7C43FCF5, 0x80E9CFDB), TOBN(0xBBBC2DCA, 0xD8467490), }; /* dh1024_safe_prime_3 is offered as a parameter by several high-traffic sites, * including mozilla.org, as of Jan 2015. */ static const BN_ULONG dh1024_safe_prime_3[] = { - TOBN(0x349E721B, 0x671746AE), TOBN(0xD75E93B2, 0x258A0655), - TOBN(0x25592EB6, 0xD425E6FB), TOBN(0xBF7CDD9A, 0x0C46AB04), - TOBN(0x28968680, 0x0AD0BC99), TOBN(0xD0B7EB49, 0xF53907FB), - TOBN(0xEBC85C1D, 0x202EABB3), TOBN(0x364D8C71, 0x3129C693), - TOBN(0x2D46F195, 0x53728351), TOBN(0x8C76CC85, 0xDF326DD6), - TOBN(0x9188E24E, 0xF898B3F9), TOBN(0x2855DFD2, 0x95EFB13C), - TOBN(0x7B2241FE, 0x1F5DAC48), TOBN(0x99A13D9F, 0x117B6BF7), - TOBN(0x3A3468C7, 0x0F97CDDA), TOBN(0x74A8297B, 0xC9BBF5F7)}; + TOBN(0x671746AE, 0x349E721B), TOBN(0x258A0655, 0xD75E93B2), + TOBN(0xD425E6FB, 0x25592EB6), TOBN(0x0C46AB04, 0xBF7CDD9A), + TOBN(0x0AD0BC99, 0x28968680), TOBN(0xF53907FB, 0xD0B7EB49), + TOBN(0x202EABB3, 0xEBC85C1D), TOBN(0x3129C693, 0x364D8C71), + TOBN(0x53728351, 0x2D46F195), TOBN(0xDF326DD6, 0x8C76CC85), + TOBN(0xF898B3F9, 0x9188E24E), TOBN(0x95EFB13C, 0x2855DFD2), + TOBN(0x1F5DAC48, 0x7B2241FE), TOBN(0x117B6BF7, 0x99A13D9F), + TOBN(0x0F97CDDA, 0x3A3468C7), TOBN(0xC9BBF5F7, 0x74A8297B)}; /* dh1024_safe_prime_4 is hard-coded in Apache httpd 2.0, * modules/ssl/ssl_engine_dh.c. */ static const BN_ULONG dh1024_safe_prime_4[] = { - TOBN(0x0DD5C86B, 0x5085E21F), TOBN(0xD823C650, 0x871538DF), - TOBN(0x262E56A8, 0x125136F7), TOBN(0x839EB5DB, 0x974E9EF1), - TOBN(0x1B13A63C, 0xEA9BAD99), TOBN(0x3D76E05E, 0x6044CF02), - TOBN(0x1BAC9B5C, 0x611EBBBE), TOBN(0x4E5327DF, 0x3E371D79), - TOBN(0x061CBC05, 0x000E6EDD), TOBN(0x20129B48, 0x2F971F3C), - TOBN(0x3048D5A2, 0xA6EF09C4), TOBN(0xCBD523A6, 0xFA15A259), - TOBN(0x4A79A770, 0x2A206490), TOBN(0x51BB055E, 0x91B78182), - TOBN(0xBDD4798E, 0x7CF180C3), TOBN(0x495BE32C, 0xE6969D3D)}; + TOBN(0x5085E21F, 0x0DD5C86B), TOBN(0x871538DF, 0xD823C650), + TOBN(0x125136F7, 0x262E56A8), TOBN(0x974E9EF1, 0x839EB5DB), + TOBN(0xEA9BAD99, 0x1B13A63C), TOBN(0x6044CF02, 0x3D76E05E), + TOBN(0x611EBBBE, 0x1BAC9B5C), TOBN(0x3E371D79, 0x4E5327DF), + TOBN(0x000E6EDD, 0x061CBC05), TOBN(0x2F971F3C, 0x20129B48), + TOBN(0xA6EF09C4, 0x3048D5A2), TOBN(0xFA15A259, 0xCBD523A6), + TOBN(0x2A206490, 0x4A79A770), TOBN(0x91B78182, 0x51BB055E), + TOBN(0x7CF180C3, 0xBDD4798E), TOBN(0xE6969D3D, 0x495BE32C)}; static const BN_ULONG bn_two_data[] = {2}; -#define STATIC_BIGNUM(x) \ - { \ - (BN_ULONG *) x, sizeof(x) / sizeof(BN_ULONG), \ - sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \ - } - struct standard_parameters { BIGNUM p, q, g; }; @@ -260,7 +247,7 @@ static const BIGNUM dh1024_safe_prime[] = { STATIC_BIGNUM(dh1024_safe_prime_4) }; -BIGNUM bn_two = STATIC_BIGNUM(bn_two_data); +static BIGNUM bn_two = STATIC_BIGNUM(bn_two_data); static DH *get_standard_parameters(const struct standard_parameters *params, const ENGINE *engine) { diff --git a/src/crypto/digest/md32_common.h b/src/crypto/digest/md32_common.h index d213476..9db8c54 100644 --- a/src/crypto/digest/md32_common.h +++ b/src/crypto/digest/md32_common.h @@ -51,12 +51,12 @@ #include <openssl/base.h> +#include <assert.h> #if defined(__cplusplus) extern "C" { #endif -#define asm __asm__ /* This is a generic 32-bit "collector" for message digest algorithms. It * collects input character stream into chunks of 32-bit values and invokes the @@ -74,14 +74,15 @@ extern "C" { * * typedef struct <name>_state_st { * uint32_t h[<chaining length> / sizeof(uint32_t)]; - * uint32_t Nl,Nh; - * uint32_t data[HASH_CBLOCK / sizeof(uint32_t)]; - * unsigned int num + * uint32_t Nl, Nh; + * uint8_t data[HASH_CBLOCK]; + * unsigned num; * ... * } <NAME>_CTX; * * <chaining length> is the output length of the hash in bytes, before - * any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and SHA-512). + * any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and + * SHA-512). * * |HASH_UPDATE| must be defined as the name of the "Update" function to * generate. @@ -133,220 +134,189 @@ extern "C" { #error "HASH_BLOCK_DATA_ORDER must be defined!" #endif -/* - * Engage compiler specific rotate intrinsic function if available. - */ -#undef ROTATE -# if defined(_MSC_VER) -# define ROTATE(a,n) _lrotl(a,n) -# elif defined(__ICC) -# define ROTATE(a,n) _rotl(a,n) -# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) - /* - * Some GNU C inline assembler templates. Note that these are - * rotates by *constant* number of bits! But that's exactly - * what we need here... - * <appro@fy.chalmers.se> - */ -# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) -# define ROTATE(a,n) ({ register uint32_t ret; \ - asm ( \ - "roll %1,%0" \ - : "=r"(ret) \ - : "I"(n), "0"((uint32_t)(a)) \ - : "cc"); \ - ret; \ - }) -# endif /* OPENSSL_X86 || OPENSSL_X86_64 */ -# endif /* COMPILER */ - -#ifndef ROTATE -#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#ifndef HASH_MAKE_STRING +#error "HASH_MAKE_STRING must be defined!" #endif #if defined(DATA_ORDER_IS_BIG_ENDIAN) -#ifndef PEDANTIC -# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) -# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) - /* - * This gives ~30-40% performance improvement in SHA-256 compiled - * with gcc [on P4]. Well, first macro to be frank. We can pull - * this trick on x86* platforms only, because these CPUs can fetch - * unaligned data without raising an exception. - */ -# define HOST_c2l(c,l) ({ uint32_t r=*((const uint32_t *)(c)); \ - asm ("bswapl %0":"=r"(r):"0"(r)); \ - (c)+=4; (l)=r; }) -# define HOST_l2c(l,c) ({ uint32_t r=(l); \ - asm ("bswapl %0":"=r"(r):"0"(r)); \ - *((uint32_t *)(c))=r; (c)+=4; r; }) -# elif defined(__aarch64__) -# if defined(__BYTE_ORDER__) -# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ -# define HOST_c2l(c,l) ({ uint32_t r; \ - asm ("rev %w0,%w1" \ - :"=r"(r) \ - :"r"(*((const uint32_t *)(c))));\ - (c)+=4; (l)=r; }) -# define HOST_l2c(l,c) ({ uint32_t r; \ - asm ("rev %w0,%w1" \ - :"=r"(r) \ - :"r"((uint32_t)(l))); \ - *((uint32_t *)(c))=r; (c)+=4; r; }) -# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ -# define HOST_c2l(c,l) (void)((l)=*((const uint32_t *)(c)), (c)+=4) -# define HOST_l2c(l,c) (*((uint32_t *)(c))=(l), (c)+=4, (l)) -# endif -# endif -# endif -# endif -#endif +#if !defined(PEDANTIC) && defined(__GNUC__) && __GNUC__ >= 2 && \ + !defined(OPENSSL_NO_ASM) +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +/* The first macro gives a ~30-40% performance improvement in SHA-256 compiled + * with gcc on P4. This can only be done on x86, where unaligned data fetches + * are possible. */ +#define HOST_c2l(c, l) \ + (void)({ \ + uint32_t r = *((const uint32_t *)(c)); \ + __asm__("bswapl %0" : "=r"(r) : "0"(r)); \ + (c) += 4; \ + (l) = r; \ + }) +#define HOST_l2c(l, c) \ + (void)({ \ + uint32_t r = (l); \ + __asm__("bswapl %0" : "=r"(r) : "0"(r)); \ + *((uint32_t *)(c)) = r; \ + (c) += 4; \ + r; \ + }) +#elif defined(__aarch64__) && defined(__BYTE_ORDER__) +#if defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define HOST_c2l(c, l) \ + (void)({ \ + uint32_t r; \ + __asm__("rev %w0, %w1" : "=r"(r) : "r"(*((const uint32_t *)(c)))); \ + (c) += 4; \ + (l) = r; \ + }) +#define HOST_l2c(l, c) \ + (void)({ \ + uint32_t r; \ + __asm__("rev %w0, %w1" : "=r"(r) : "r"((uint32_t)(l))); \ + *((uint32_t *)(c)) = r; \ + (c) += 4; \ + r; \ + }) +#elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4) +#define HOST_l2c(l, c) (*((uint32_t *)(c)) = (l), (c) += 4, (l)) +#endif /* __aarch64__ && __BYTE_ORDER__ */ +#endif /* ARCH */ +#endif /* !PEDANTIC && GNUC && !NO_ASM */ #ifndef HOST_c2l -#define HOST_c2l(c,l) (void)(l =(((uint32_t)(*((c)++)))<<24), \ - l|=(((uint32_t)(*((c)++)))<<16), \ - l|=(((uint32_t)(*((c)++)))<< 8), \ - l|=(((uint32_t)(*((c)++))) )) +#define HOST_c2l(c, l) \ + (void)(l = (((uint32_t)(*((c)++))) << 24), \ + l |= (((uint32_t)(*((c)++))) << 16), \ + l |= (((uint32_t)(*((c)++))) << 8), l |= (((uint32_t)(*((c)++))))) #endif + #ifndef HOST_l2c -#define HOST_l2c(l,c) (*((c)++)=(uint8_t)(((l)>>24)&0xff), \ - *((c)++)=(uint8_t)(((l)>>16)&0xff), \ - *((c)++)=(uint8_t)(((l)>> 8)&0xff), \ - *((c)++)=(uint8_t)(((l) )&0xff), \ - l) +#define HOST_l2c(l, c) \ + (void)(*((c)++) = (uint8_t)(((l) >> 24) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 16) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 8) & 0xff), \ + *((c)++) = (uint8_t)(((l)) & 0xff)) #endif #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) - /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ -# define HOST_c2l(c,l) (void)((l)=*((const uint32_t *)(c)), (c)+=4) -# define HOST_l2c(l,c) (*((uint32_t *)(c))=(l), (c)+=4, l) -#endif +/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ +#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4) +#define HOST_l2c(l, c) (void)(*((uint32_t *)(c)) = (l), (c) += 4, l) +#endif /* OPENSSL_X86 || OPENSSL_X86_64 */ #ifndef HOST_c2l -#define HOST_c2l(c,l) (void)(l =(((uint32_t)(*((c)++))) ), \ - l|=(((uint32_t)(*((c)++)))<< 8), \ - l|=(((uint32_t)(*((c)++)))<<16), \ - l|=(((uint32_t)(*((c)++)))<<24)) -#endif -#ifndef HOST_l2c -#define HOST_l2c(l,c) (*((c)++)=(uint8_t)(((l) )&0xff), \ - *((c)++)=(uint8_t)(((l)>> 8)&0xff), \ - *((c)++)=(uint8_t)(((l)>>16)&0xff), \ - *((c)++)=(uint8_t)(((l)>>24)&0xff), \ - l) +#define HOST_c2l(c, l) \ + (void)(l = (((uint32_t)(*((c)++)))), l |= (((uint32_t)(*((c)++))) << 8), \ + l |= (((uint32_t)(*((c)++))) << 16), \ + l |= (((uint32_t)(*((c)++))) << 24)) #endif +#ifndef HOST_l2c +#define HOST_l2c(l, c) \ + (void)(*((c)++) = (uint8_t)(((l)) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 8) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 16) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 24) & 0xff)) #endif -int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len) - { - const uint8_t *data=data_; - uint8_t *p; - uint32_t l; - size_t n; - - if (len==0) return 1; - - l=(c->Nl+(((uint32_t)len)<<3))&0xffffffffUL; - /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to - * Wei Dai <weidai@eskimo.com> for pointing it out. */ - if (l < c->Nl) /* overflow */ - c->Nh++; - c->Nh+=(uint32_t)(len>>29); /* might cause compiler warning on 16-bit */ - c->Nl=l; - - n = c->num; - if (n != 0) - { - p=(uint8_t *)c->data; - - if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK) - { - memcpy (p+n,data,HASH_CBLOCK-n); - HASH_BLOCK_DATA_ORDER (c->h,p,1); - n = HASH_CBLOCK-n; - data += n; - len -= n; - c->num = 0; - memset (p,0,HASH_CBLOCK); /* keep it zeroed */ - } - else - { - memcpy (p+n,data,len); - c->num += (unsigned int)len; - return 1; - } - } - - n = len/HASH_CBLOCK; - if (n > 0) - { - HASH_BLOCK_DATA_ORDER (c->h,data,n); - n *= HASH_CBLOCK; - data += n; - len -= n; - } - - if (len != 0) - { - p = (uint8_t *)c->data; - c->num = (unsigned int)len; - memcpy (p,data,len); - } - return 1; - } - - -void HASH_TRANSFORM (HASH_CTX *c, const uint8_t *data) - { - HASH_BLOCK_DATA_ORDER (c->h,data,1); - } - - -int HASH_FINAL (uint8_t *md, HASH_CTX *c) - { - uint8_t *p = (uint8_t *)c->data; - size_t n = c->num; - - p[n] = 0x80; /* there is always room for one */ - n++; - - if (n > (HASH_CBLOCK-8)) - { - memset (p+n,0,HASH_CBLOCK-n); - n=0; - HASH_BLOCK_DATA_ORDER (c->h,p,1); - } - memset (p+n,0,HASH_CBLOCK-8-n); - - p += HASH_CBLOCK-8; -#if defined(DATA_ORDER_IS_BIG_ENDIAN) - (void)HOST_l2c(c->Nh,p); - (void)HOST_l2c(c->Nl,p); +#endif /* DATA_ORDER */ + +int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) { + const uint8_t *data = data_; + + if (len == 0) { + return 1; + } + + uint32_t l = c->Nl + (((uint32_t)len) << 3); + if (l < c->Nl) { + /* Handle carries. */ + c->Nh++; + } + c->Nh += (uint32_t)(len >> 29); + c->Nl = l; + + size_t n = c->num; + if (n != 0) { + if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + memcpy(c->data + n, data, HASH_CBLOCK - n); + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + n = HASH_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + /* Keep |c->data| zeroed when unused. */ + memset(c->data, 0, HASH_CBLOCK); + } else { + memcpy(c->data + n, data, len); + c->num += (unsigned)len; + return 1; + } + } + + n = len / HASH_CBLOCK; + if (n > 0) { + HASH_BLOCK_DATA_ORDER(c->h, data, n); + n *= HASH_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + c->num = (unsigned)len; + memcpy(c->data, data, len); + } + return 1; +} + + +void HASH_TRANSFORM(HASH_CTX *c, const uint8_t *data) { + HASH_BLOCK_DATA_ORDER(c->h, data, 1); +} + + +int HASH_FINAL(uint8_t *md, HASH_CTX *c) { + /* |c->data| always has room for at least one byte. A full block would have + * been consumed. */ + size_t n = c->num; + assert(n < HASH_CBLOCK); + c->data[n] = 0x80; + n++; + + /* Fill the block with zeros if there isn't room for a 64-bit length. */ + if (n > (HASH_CBLOCK - 8)) { + memset(c->data + n, 0, HASH_CBLOCK - n); + n = 0; + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + } + memset(c->data + n, 0, HASH_CBLOCK - 8 - n); + + /* Append a 64-bit length to the block and process it. */ + uint8_t *p = c->data + HASH_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + HOST_l2c(c->Nh, p); + HOST_l2c(c->Nl, p); #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) - (void)HOST_l2c(c->Nl,p); - (void)HOST_l2c(c->Nh,p); -#endif - p -= HASH_CBLOCK; - HASH_BLOCK_DATA_ORDER (c->h,p,1); - c->num=0; - memset (p,0,HASH_CBLOCK); - -#ifndef HASH_MAKE_STRING -#error "HASH_MAKE_STRING must be defined!" -#else - HASH_MAKE_STRING(c,md); + HOST_l2c(c->Nl, p); + HOST_l2c(c->Nh, p); #endif + assert(p == c->data + HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + c->num = 0; + memset(c->data, 0, HASH_CBLOCK); - return 1; - } + HASH_MAKE_STRING(c, md); + return 1; +} #if defined(__cplusplus) -} /* extern C */ +} /* extern C */ #endif -#endif /* OPENSSL_HEADER_MD32_COMMON_H */ +#endif /* OPENSSL_HEADER_MD32_COMMON_H */ diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c index ceffd1a..ebe55e8 100644 --- a/src/crypto/dsa/dsa.c +++ b/src/crypto/dsa/dsa.c @@ -98,12 +98,7 @@ DSA *DSA_new(void) { dsa->references = 1; CRYPTO_MUTEX_init(&dsa->method_mont_p_lock); - - if (!CRYPTO_new_ex_data(&g_ex_data_class, dsa, &dsa->ex_data)) { - CRYPTO_MUTEX_cleanup(&dsa->method_mont_p_lock); - OPENSSL_free(dsa); - return NULL; - } + CRYPTO_new_ex_data(&dsa->ex_data); return dsa; } @@ -541,10 +536,6 @@ redo: goto err; } - ret = DSA_SIG_new(); - if (ret == NULL) { - goto err; - } /* Redo if r or s is zero as required by FIPS 186-3: this is * very unlikely. */ if (BN_is_zero(r) || BN_is_zero(s)) { @@ -554,11 +545,15 @@ redo: } goto redo; } + ret = DSA_SIG_new(); + if (ret == NULL) { + goto err; + } ret->r = r; ret->s = s; err: - if (!ret) { + if (ret == NULL) { OPENSSL_PUT_ERROR(DSA, reason); BN_free(r); BN_free(s); @@ -864,11 +859,11 @@ err: return ret; } -int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int index; - if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func, - dup_func, free_func)) { + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func, + free_func)) { return -1; } return index; diff --git a/src/crypto/ec/asm/p256-x86_64-asm.pl b/src/crypto/ec/asm/p256-x86_64-asm.pl index e203d46..361a84b 100644 --- a/src/crypto/ec/asm/p256-x86_64-asm.pl +++ b/src/crypto/ec/asm/p256-x86_64-asm.pl @@ -67,10 +67,6 @@ $code.=<<___; .Lpoly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 -# 2^512 mod P precomputed for NIST P256 polynomial -.LRR: -.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd - .LOne: .long 1,1,1,1,1,1,1,1 .LTwo: @@ -91,7 +87,6 @@ my ($r_ptr,$a_ptr,$b_ptr)=("%rdi","%rsi","%rdx"); $code.=<<___; -.globl ecp_nistz256_mul_by_2 .type ecp_nistz256_mul_by_2,\@function,2 .align 64 ecp_nistz256_mul_by_2: @@ -134,224 +129,6 @@ ecp_nistz256_mul_by_2: .size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 ################################################################################ -# void ecp_nistz256_div_by_2(uint64_t res[4], uint64_t a[4]); -.globl ecp_nistz256_div_by_2 -.type ecp_nistz256_div_by_2,\@function,2 -.align 32 -ecp_nistz256_div_by_2: - push %r12 - push %r13 - - mov 8*0($a_ptr), $a0 - mov 8*1($a_ptr), $a1 - mov 8*2($a_ptr), $a2 - mov $a0, $t0 - mov 8*3($a_ptr), $a3 - lea .Lpoly(%rip), $a_ptr - - mov $a1, $t1 - xor $t4, $t4 - add 8*0($a_ptr), $a0 - mov $a2, $t2 - adc 8*1($a_ptr), $a1 - adc 8*2($a_ptr), $a2 - mov $a3, $t3 - adc 8*3($a_ptr), $a3 - adc \$0, $t4 - xor $a_ptr, $a_ptr # borrow $a_ptr - test \$1, $t0 - - cmovz $t0, $a0 - cmovz $t1, $a1 - cmovz $t2, $a2 - cmovz $t3, $a3 - cmovz $a_ptr, $t4 - - mov $a1, $t0 # a0:a3>>1 - shr \$1, $a0 - shl \$63, $t0 - mov $a2, $t1 - shr \$1, $a1 - or $t0, $a0 - shl \$63, $t1 - mov $a3, $t2 - shr \$1, $a2 - or $t1, $a1 - shl \$63, $t2 - shr \$1, $a3 - shl \$63, $t4 - or $t2, $a2 - or $t4, $a3 - - mov $a0, 8*0($r_ptr) - mov $a1, 8*1($r_ptr) - mov $a2, 8*2($r_ptr) - mov $a3, 8*3($r_ptr) - - pop %r13 - pop %r12 - ret -.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 - -################################################################################ -# void ecp_nistz256_mul_by_3(uint64_t res[4], uint64_t a[4]); -.globl ecp_nistz256_mul_by_3 -.type ecp_nistz256_mul_by_3,\@function,2 -.align 32 -ecp_nistz256_mul_by_3: - push %r12 - push %r13 - - mov 8*0($a_ptr), $a0 - xor $t4, $t4 - mov 8*1($a_ptr), $a1 - add $a0, $a0 # a0:a3+a0:a3 - mov 8*2($a_ptr), $a2 - adc $a1, $a1 - mov 8*3($a_ptr), $a3 - mov $a0, $t0 - adc $a2, $a2 - adc $a3, $a3 - mov $a1, $t1 - adc \$0, $t4 - - sub \$-1, $a0 - mov $a2, $t2 - sbb .Lpoly+8*1(%rip), $a1 - sbb \$0, $a2 - mov $a3, $t3 - sbb .Lpoly+8*3(%rip), $a3 - test $t4, $t4 - - cmovz $t0, $a0 - cmovz $t1, $a1 - cmovz $t2, $a2 - cmovz $t3, $a3 - - xor $t4, $t4 - add 8*0($a_ptr), $a0 # a0:a3+=a_ptr[0:3] - adc 8*1($a_ptr), $a1 - mov $a0, $t0 - adc 8*2($a_ptr), $a2 - adc 8*3($a_ptr), $a3 - mov $a1, $t1 - adc \$0, $t4 - - sub \$-1, $a0 - mov $a2, $t2 - sbb .Lpoly+8*1(%rip), $a1 - sbb \$0, $a2 - mov $a3, $t3 - sbb .Lpoly+8*3(%rip), $a3 - test $t4, $t4 - - cmovz $t0, $a0 - cmovz $t1, $a1 - mov $a0, 8*0($r_ptr) - cmovz $t2, $a2 - mov $a1, 8*1($r_ptr) - cmovz $t3, $a3 - mov $a2, 8*2($r_ptr) - mov $a3, 8*3($r_ptr) - - pop %r13 - pop %r12 - ret -.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 - -################################################################################ -# void ecp_nistz256_add(uint64_t res[4], uint64_t a[4], uint64_t b[4]); -.globl ecp_nistz256_add -.type ecp_nistz256_add,\@function,3 -.align 32 -ecp_nistz256_add: - push %r12 - push %r13 - - mov 8*0($a_ptr), $a0 - xor $t4, $t4 - mov 8*1($a_ptr), $a1 - mov 8*2($a_ptr), $a2 - mov 8*3($a_ptr), $a3 - lea .Lpoly(%rip), $a_ptr - - add 8*0($b_ptr), $a0 - adc 8*1($b_ptr), $a1 - mov $a0, $t0 - adc 8*2($b_ptr), $a2 - adc 8*3($b_ptr), $a3 - mov $a1, $t1 - adc \$0, $t4 - - sub 8*0($a_ptr), $a0 - mov $a2, $t2 - sbb 8*1($a_ptr), $a1 - sbb 8*2($a_ptr), $a2 - mov $a3, $t3 - sbb 8*3($a_ptr), $a3 - test $t4, $t4 - - cmovz $t0, $a0 - cmovz $t1, $a1 - mov $a0, 8*0($r_ptr) - cmovz $t2, $a2 - mov $a1, 8*1($r_ptr) - cmovz $t3, $a3 - mov $a2, 8*2($r_ptr) - mov $a3, 8*3($r_ptr) - - pop %r13 - pop %r12 - ret -.size ecp_nistz256_add,.-ecp_nistz256_add - -################################################################################ -# void ecp_nistz256_sub(uint64_t res[4], uint64_t a[4], uint64_t b[4]); -.globl ecp_nistz256_sub -.type ecp_nistz256_sub,\@function,3 -.align 32 -ecp_nistz256_sub: - push %r12 - push %r13 - - mov 8*0($a_ptr), $a0 - xor $t4, $t4 - mov 8*1($a_ptr), $a1 - mov 8*2($a_ptr), $a2 - mov 8*3($a_ptr), $a3 - lea .Lpoly(%rip), $a_ptr - - sub 8*0($b_ptr), $a0 - sbb 8*1($b_ptr), $a1 - mov $a0, $t0 - sbb 8*2($b_ptr), $a2 - sbb 8*3($b_ptr), $a3 - mov $a1, $t1 - sbb \$0, $t4 - - add 8*0($a_ptr), $a0 - mov $a2, $t2 - adc 8*1($a_ptr), $a1 - adc 8*2($a_ptr), $a2 - mov $a3, $t3 - adc 8*3($a_ptr), $a3 - test $t4, $t4 - - cmovz $t0, $a0 - cmovz $t1, $a1 - mov $a0, 8*0($r_ptr) - cmovz $t2, $a2 - mov $a1, 8*1($r_ptr) - cmovz $t3, $a3 - mov $a2, 8*2($r_ptr) - mov $a3, 8*3($r_ptr) - - pop %r13 - pop %r12 - ret -.size ecp_nistz256_sub,.-ecp_nistz256_sub - -################################################################################ # void ecp_nistz256_neg(uint64_t res[4], uint64_t a[4]); .globl ecp_nistz256_neg .type ecp_nistz256_neg,\@function,2 @@ -406,24 +183,6 @@ my ($poly1,$poly3)=($acc6,$acc7); $code.=<<___; ################################################################################ -# void ecp_nistz256_to_mont( -# uint64_t res[4], -# uint64_t in[4]); -.globl ecp_nistz256_to_mont -.type ecp_nistz256_to_mont,\@function,2 -.align 32 -ecp_nistz256_to_mont: -___ -$code.=<<___ if ($addx); - mov \$0x80100, %ecx - and OPENSSL_ia32cap_P+8(%rip), %ecx -___ -$code.=<<___; - lea .LRR(%rip), $b_org - jmp .Lmul_mont -.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont - -################################################################################ # void ecp_nistz256_mul_mont( # uint64_t res[4], # uint64_t a[4], diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c index 4891daa..827cc57 100644 --- a/src/crypto/ec/ec.c +++ b/src/crypto/ec/ec.c @@ -525,8 +525,6 @@ void EC_GROUP_free(EC_GROUP *group) { group->meth->group_finish(group); } - ec_pre_comp_free(group->pre_comp); - EC_POINT_free(group->generator); BN_free(&group->order); BN_free(&group->cofactor); @@ -547,8 +545,6 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) { return 1; } - ec_pre_comp_free(dest->pre_comp); - dest->pre_comp = ec_pre_comp_dup(src->pre_comp); dest->mont_data = src->mont_data; if (src->generator != NULL) { @@ -617,12 +613,16 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) { return group->generator; } +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) { + assert(!BN_is_zero(&group->order)); + return &group->order; +} + int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { - if (!BN_copy(order, &group->order)) { + if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) { return 0; } - - return !BN_is_zero(order); + return 1; } int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, @@ -645,21 +645,6 @@ unsigned EC_GROUP_get_degree(const EC_GROUP *group) { return ec_GFp_simple_group_get_degree(group); } -int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { - if (group->meth->precompute_mult != NULL) { - return group->meth->precompute_mult(group, ctx); - } - - return 1; /* nothing to do, so report success */ -} - -int EC_GROUP_have_precompute_mult(const EC_GROUP *group) { - if (group->pre_comp != NULL) { - return 1; - } - return 0; -} - EC_POINT *EC_POINT_new(const EC_GROUP *group) { EC_POINT *ret; @@ -856,39 +841,23 @@ int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { } int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, - const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) { - /* just a convenient interface to EC_POINTs_mul() */ - - const EC_POINT *points[1]; - const BIGNUM *scalars[1]; - - points[0] = point; - scalars[0] = p_scalar; - - return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), - points, scalars, ctx); -} - -int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *ctx) { - if (group->meth != r->meth) { - OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) { + /* Previously, this function set |r| to the point at infinity if there was + * nothing to multiply. But, nobody should be calling this function with + * nothing to multiply in the first place. */ + if ((g_scalar == NULL && p_scalar == NULL) || + ((p == NULL) != (p_scalar == NULL))) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } - size_t i; - for (i = 0; i < num; i++) { - if (points[i]->meth != r->meth) { - break; - } - } - if (i != num) { + if (group->meth != r->meth || + (p != NULL && group->meth != p->meth)) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->mul(group, r, scalar, num, points, scalars, ctx); + return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx); } int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, diff --git a/src/crypto/ec/ec_asn1.c b/src/crypto/ec/ec_asn1.c index 7c4be07..a085be5 100644 --- a/src/crypto/ec/ec_asn1.c +++ b/src/crypto/ec/ec_asn1.c @@ -329,6 +329,11 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **inp, long len) { goto err; } + if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(ret->group)) >= 0) { + OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); + goto err; + } + EC_POINT_free(ret->pub_key); ret->pub_key = EC_POINT_new(ret->group); if (ret->pub_key == NULL) { diff --git a/src/crypto/ec/ec_key.c b/src/crypto/ec/ec_key.c index 0defa98..d3bf4c6 100644 --- a/src/crypto/ec/ec_key.c +++ b/src/crypto/ec/ec_key.c @@ -104,24 +104,18 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) { ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; ret->references = 1; - if (!CRYPTO_new_ex_data(&g_ex_data_class, ret, &ret->ex_data)) { - goto err1; - } + CRYPTO_new_ex_data(&ret->ex_data); if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) { - goto err2; + CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data); + if (ret->ecdsa_meth) { + METHOD_unref(ret->ecdsa_meth); + } + OPENSSL_free(ret); + return NULL; } return ret; - -err2: - CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data); -err1: - if (ret->ecdsa_meth) { - METHOD_unref(ret->ecdsa_meth); - } - OPENSSL_free(ret); - return NULL; } EC_KEY *EC_KEY_new_by_curve_name(int nid) { @@ -249,7 +243,15 @@ int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) { /* TODO(fork): duplicating the group seems wasteful but see * |EC_KEY_set_conv_form|. */ key->group = EC_GROUP_dup(group); - return (key->group == NULL) ? 0 : 1; + if (key->group == NULL) { + return 0; + } + /* XXX: |BN_cmp| is not constant time. */ + if (key->priv_key != NULL && + BN_cmp(key->priv_key, EC_GROUP_get0_order(group)) >= 0) { + return 0; + } + return 1; } const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) { @@ -257,6 +259,12 @@ const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) { } int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) { + /* XXX: |BN_cmp| is not constant time. */ + if (key->group != NULL && + BN_cmp(priv_key, EC_GROUP_get0_order(key->group)) >= 0) { + OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); + return 0; + } BN_clear_free(key->priv_key); key->priv_key = BN_dup(priv_key); return (key->priv_key == NULL) ? 0 : 1; @@ -286,17 +294,9 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) { key->conv_form = cform; } -int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) { - if (key->group == NULL) { - return 0; - } - return EC_GROUP_precompute_mult(key->group, ctx); -} - int EC_KEY_check_key(const EC_KEY *eckey) { int ok = 0; BN_CTX *ctx = NULL; - const BIGNUM *order = NULL; EC_POINT *point = NULL; if (!eckey || !eckey->group || !eckey->pub_key) { @@ -310,10 +310,8 @@ int EC_KEY_check_key(const EC_KEY *eckey) { } ctx = BN_CTX_new(); - point = EC_POINT_new(eckey->group); - if (ctx == NULL || - point == NULL) { + if (ctx == NULL) { goto err; } @@ -322,19 +320,11 @@ int EC_KEY_check_key(const EC_KEY *eckey) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); goto err; } - /* testing whether pub_key * order is the point at infinity */ /* TODO(fork): can this be skipped if the cofactor is one or if we're about * to check the private key, below? */ - order = &eckey->group->order; - if (BN_is_zero(order)) { - OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); - goto err; - } - if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { - OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); - goto err; - } - if (!EC_POINT_is_at_infinity(eckey->group, point)) { + if (eckey->group->meth->check_pub_key_order != NULL && + !eckey->group->meth->check_pub_key_order(eckey->group, eckey->pub_key, + ctx)) { OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); goto err; } @@ -342,11 +332,14 @@ int EC_KEY_check_key(const EC_KEY *eckey) { * check if generator * priv_key == pub_key */ if (eckey->priv_key) { - if (BN_cmp(eckey->priv_key, order) >= 0) { + /* XXX: |BN_cmp| is not constant time. */ + if (BN_cmp(eckey->priv_key, EC_GROUP_get0_order(eckey->group)) >= 0) { OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); goto err; } - if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) { + point = EC_POINT_new(eckey->group); + if (point == NULL || + !EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) { OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); goto err; } @@ -415,8 +408,7 @@ err: int EC_KEY_generate_key(EC_KEY *eckey) { int ok = 0; - BN_CTX *ctx = NULL; - BIGNUM *priv_key = NULL, *order = NULL; + BIGNUM *priv_key = NULL; EC_POINT *pub_key = NULL; if (!eckey || !eckey->group) { @@ -424,14 +416,6 @@ int EC_KEY_generate_key(EC_KEY *eckey) { return 0; } - order = BN_new(); - ctx = BN_CTX_new(); - - if (order == NULL || - ctx == NULL) { - goto err; - } - if (eckey->priv_key == NULL) { priv_key = BN_new(); if (priv_key == NULL) { @@ -441,10 +425,7 @@ int EC_KEY_generate_key(EC_KEY *eckey) { priv_key = eckey->priv_key; } - if (!EC_GROUP_get_order(eckey->group, order, ctx)) { - goto err; - } - + const BIGNUM *order = EC_GROUP_get0_order(eckey->group); do { if (!BN_rand_range(priv_key, order)) { goto err; @@ -460,7 +441,7 @@ int EC_KEY_generate_key(EC_KEY *eckey) { pub_key = eckey->pub_key; } - if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) { + if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, NULL)) { goto err; } @@ -470,23 +451,21 @@ int EC_KEY_generate_key(EC_KEY *eckey) { ok = 1; err: - BN_free(order); if (eckey->pub_key == NULL) { EC_POINT_free(pub_key); } if (eckey->priv_key == NULL) { BN_free(priv_key); } - BN_CTX_free(ctx); return ok; } -int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int index; - if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func, - dup_func, free_func)) { + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func, + free_func)) { return -1; } return index; diff --git a/src/crypto/ec/ec_montgomery.c b/src/crypto/ec/ec_montgomery.c index 3715e0c..1d4113d 100644 --- a/src/crypto/ec/ec_montgomery.c +++ b/src/crypto/ec/ec_montgomery.c @@ -74,24 +74,6 @@ #include "internal.h" -const EC_METHOD *EC_GFp_mont_method(void) { - static const EC_METHOD ret = {ec_GFp_mont_group_init, - ec_GFp_mont_group_finish, - ec_GFp_mont_group_clear_finish, - ec_GFp_mont_group_copy, - ec_GFp_mont_group_set_curve, - ec_GFp_simple_point_get_affine_coordinates, - ec_wNAF_mul /* XXX: Not constant time. */, - ec_wNAF_precompute_mult, - ec_GFp_mont_field_mul, - ec_GFp_mont_field_sqr, - ec_GFp_mont_field_encode, - ec_GFp_mont_field_decode, - ec_GFp_mont_field_set_to_one}; - - return &ret; -} - int ec_GFp_mont_group_init(EC_GROUP *group) { int ok; @@ -256,3 +238,43 @@ int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, } return 1; } + +static int ec_GFp_mont_check_pub_key_order(const EC_GROUP *group, + const EC_POINT* pub_key, + BN_CTX *ctx) { + EC_POINT *point = EC_POINT_new(group); + int ret = 0; + + if (point == NULL || + !ec_wNAF_mul(group, point, NULL, pub_key, EC_GROUP_get0_order(group), + ctx) || + !EC_POINT_is_at_infinity(group, point)) { + goto err; + } + + ret = 1; + +err: + EC_POINT_free(point); + return ret; +} + +const EC_METHOD *EC_GFp_mont_method(void) { + static const EC_METHOD ret = { + ec_GFp_mont_group_init, + ec_GFp_mont_group_finish, + ec_GFp_mont_group_clear_finish, + ec_GFp_mont_group_copy, + ec_GFp_mont_group_set_curve, + ec_GFp_simple_point_get_affine_coordinates, + ec_wNAF_mul /* XXX: Not constant time. */, + ec_GFp_mont_check_pub_key_order, + ec_GFp_mont_field_mul, + ec_GFp_mont_field_sqr, + ec_GFp_mont_field_encode, + ec_GFp_mont_field_decode, + ec_GFp_mont_field_set_to_one, + }; + + return &ret; +} diff --git a/src/crypto/ec/ec_test.cc b/src/crypto/ec/ec_test.cc index 3f45bd0..2088e72 100644 --- a/src/crypto/ec/ec_test.cc +++ b/src/crypto/ec/ec_test.cc @@ -23,7 +23,6 @@ #include <openssl/mem.h> #include "../test/scoped_types.h" -#include "../test/stl_compat.h" // kECKeyWithoutPublic is an ECPrivateKey with the optional publicKey field @@ -80,7 +79,7 @@ static ScopedEC_KEY DecodeECPrivateKey(const uint8_t *in, size_t in_len) { static bool EncodeECPrivateKey(std::vector<uint8_t> *out, EC_KEY *key) { int len = i2d_ECPrivateKey(key, NULL); out->resize(len); - uint8_t *outp = bssl::vector_data(out); + uint8_t *outp = out->data(); return i2d_ECPrivateKey(key, &outp) == len; } diff --git a/src/crypto/ec/internal.h b/src/crypto/ec/internal.h index b6b5d52..bcc0e37 100644 --- a/src/crypto/ec/internal.h +++ b/src/crypto/ec/internal.h @@ -95,13 +95,22 @@ struct ec_method_st { int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *, BIGNUM *x, BIGNUM *y, BN_CTX *); - /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, - * EC_POINT_have_precompute_mult - * (default implementations are used if the 'mul' pointer is 0): */ - int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); - int (*precompute_mult)(EC_GROUP *group, BN_CTX *); + /* Computes |r = g_scalar*generator + p_scalar*p| if |g_scalar| and |p_scalar| + * are both non-null. Computes |r = g_scalar*generator| if |p_scalar| is null. + * Computes |r = p_scalar*p| if g_scalar is null. At least one of |g_scalar| + * and |p_scalar| must be non-null, and |p| must be non-null if |p_scalar| is + * non-null. */ + int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx); + + /* |check_pub_key_order| checks that the public key is in the proper subgroup + * by checking that |pub_key*group->order| is the point at infinity. This may + * be NULL for |EC_METHOD|s specialized for prime-order curves (i.e. with + * cofactor one), as this check is not necessary for such curves (See section + * A.3 of the NSA's "Suite B Implementer's Guide to FIPS 186-3 + * (ECDSA)"). */ + int (*check_pub_key_order)(const EC_GROUP *group, const EC_POINT *pub_key, + BN_CTX *ctx); /* internal functions */ @@ -121,10 +130,6 @@ struct ec_method_st { const EC_METHOD* EC_GFp_mont_method(void); -struct ec_pre_comp_st; -void ec_pre_comp_free(struct ec_pre_comp_st *pre_comp); -void *ec_pre_comp_dup(struct ec_pre_comp_st *pre_comp); - struct ec_group_st { const EC_METHOD *meth; @@ -133,7 +138,6 @@ struct ec_group_st { int curve_name; /* optional NID for named curve */ - struct ec_pre_comp_st *pre_comp; const BN_MONT_CTX *mont_data; /* data for ECDSA inverse */ /* The following members are handled by the method functions, @@ -170,10 +174,8 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src); * a built-in group. */ const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group); -int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *); +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx); /* method functions in simple.c */ int ec_GFp_simple_group_init(EC_GROUP *); diff --git a/src/crypto/ec/oct.c b/src/crypto/ec/oct.c index 365dc3d..e39337d 100644 --- a/src/crypto/ec/oct.c +++ b/src/crypto/ec/oct.c @@ -90,18 +90,10 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group, } if (EC_POINT_is_at_infinity(group, point)) { - /* encodes to a single 0 octet */ - if (buf != NULL) { - if (len < 1) { - OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); - return 0; - } - buf[0] = 0; - } - return 1; + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + goto err; } - /* ret := required output buffer length */ field_len = BN_num_bytes(&group->field); ret = @@ -117,7 +109,7 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group, if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { - return 0; + goto err; } } @@ -193,25 +185,13 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, form = buf[0]; y_bit = form & 1; form = form & ~1U; - if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) && - (form != POINT_CONVERSION_UNCOMPRESSED)) { - OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); - return 0; - } - if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { + if ((form != POINT_CONVERSION_COMPRESSED && + form != POINT_CONVERSION_UNCOMPRESSED) || + (form == POINT_CONVERSION_UNCOMPRESSED && y_bit)) { OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); return 0; } - if (form == 0) { - if (len != 1) { - OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); - return 0; - } - - return EC_POINT_set_to_infinity(group, point); - } - field_len = BN_num_bytes(&group->field); enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; @@ -261,12 +241,6 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, } } - /* test required by X9.62 */ - if (!EC_POINT_is_on_curve(group, point, ctx)) { - OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); - goto err; - } - ret = 1; err: diff --git a/src/crypto/ec/p224-64.c b/src/crypto/ec/p224-64.c index bcc4158..e026fc4 100644 --- a/src/crypto/ec/p224-64.c +++ b/src/crypto/ec/p224-64.c @@ -106,7 +106,7 @@ static const felem_bytearray nistp224_curve_params[5] = { * The reason for this is so that we can clock bits into four different * locations when doing simple scalar multiplies against the base point, * and then another four locations using the second 16 elements. */ -static const felem gmul[2][16][3] = { +static const felem g_pre_comp[2][16][3] = { {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf}, {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723}, @@ -937,8 +937,7 @@ static char get_bit(const felem_bytearray in, unsigned i) { static void batch_mul(felem x_out, felem y_out, felem z_out, const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar, - const int mixed, const felem pre_comp[][17][3], - const felem g_pre_comp[2][16][3]) { + const int mixed, const felem pre_comp[][17][3]) { int i, skip; unsigned num; unsigned gen_mul = (g_scalar != NULL); @@ -1122,12 +1121,16 @@ static void make_points_affine(size_t num, felem points[/*num*/][3], (void (*)(void *, const void *))felem_contract); } -/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values - * Result is stored in r (r can equal one of the inputs). */ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx) { + const BIGNUM *g_scalar, const EC_POINT *p_, + const BIGNUM *p_scalar_, BN_CTX *ctx) { + /* TODO: This function used to take |points| and |scalars| as arrays of + * |num| elements. The code below should be simplified to work in terms of + * |p_| and |p_scalar_|. */ + size_t num = p_ != NULL ? 1 : 0; + const EC_POINT **points = p_ != NULL ? &p_ : NULL; + BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL; + int ret = 0; int j; unsigned i; @@ -1140,11 +1143,8 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, felem *tmp_felems = NULL; felem_bytearray tmp; unsigned num_bytes; - int have_pre_comp = 0; size_t num_points = num; felem x_in, y_in, z_in, x_out, y_out, z_out; - const felem(*g_pre_comp)[16][3] = NULL; - EC_POINT *generator = NULL; const EC_POINT *p = NULL; const BIGNUM *p_scalar = NULL; @@ -1164,35 +1164,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, goto err; } - if (scalar != NULL) { - /* try to use the standard precomputation */ - g_pre_comp = &gmul[0]; - generator = EC_POINT_new(group); - if (generator == NULL) { - goto err; - } - /* get the generator from precomputation */ - if (!felem_to_BN(x, g_pre_comp[0][1][0]) || - !felem_to_BN(y, g_pre_comp[0][1][1]) || - !felem_to_BN(z, g_pre_comp[0][1][2])) { - OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); - goto err; - } - if (!ec_point_set_Jprojective_coordinates_GFp(group, generator, x, y, z, - ctx)) { - goto err; - } - - if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { - /* precomputation matches generator */ - have_pre_comp = 1; - } else { - /* we don't have valid precomputation: - * treat the generator as a random point */ - num_points = num_points + 1; - } - } - if (num_points > 0) { if (num_points >= 3) { /* unless we precompute multiples for just one or two points, @@ -1200,7 +1171,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, mixed = 1; } secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); - pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem)); + pre_comp = OPENSSL_malloc(num_points * sizeof(felem[17][3])); if (mixed) { tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem)); } @@ -1219,7 +1190,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, if (i == num) { /* the generator */ p = EC_GROUP_get0_generator(group); - p_scalar = scalar; + p_scalar = g_scalar; } else { /* the i^th point */ p = points[i]; @@ -1227,7 +1198,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, } if (p_scalar != NULL && p != NULL) { - /* reduce scalar to 0 <= scalar < 2^224 */ + /* reduce g_scalar to 0 <= g_scalar < 2^224 */ if (BN_num_bits(p_scalar) > 224 || BN_is_negative(p_scalar)) { /* this is an unusual input, and we don't guarantee * constant-timeness */ @@ -1272,31 +1243,25 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, } } - /* the scalar for the generator */ - if (scalar != NULL && have_pre_comp) { + if (g_scalar != NULL) { memset(g_secret, 0, sizeof(g_secret)); - /* reduce scalar to 0 <= scalar < 2^224 */ - if (BN_num_bits(scalar) > 224 || BN_is_negative(scalar)) { + /* reduce g_scalar to 0 <= g_scalar < 2^224 */ + if (BN_num_bits(g_scalar) > 224 || BN_is_negative(g_scalar)) { /* this is an unusual input, and we don't guarantee constant-timeness */ - if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { + if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) { OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); goto err; } num_bytes = BN_bn2bin(tmp_scalar, tmp); } else { - num_bytes = BN_bn2bin(scalar, tmp); + num_bytes = BN_bn2bin(g_scalar, tmp); } flip_endian(g_secret, tmp, num_bytes); - /* do the multiplication with generator precomputation */ - batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, - num_points, g_secret, mixed, (const felem(*)[17][3])pre_comp, - g_pre_comp); - } else { - /* do the multiplication without generator precomputation */ - batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, - num_points, NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); } + batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, + num_points, g_scalar != NULL ? g_secret : NULL, mixed, + (const felem(*)[17][3])pre_comp); /* reduce the output to its unique minimal representation */ felem_contract(x_in, x_out); @@ -1312,7 +1277,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, err: BN_CTX_end(ctx); - EC_POINT_free(generator); BN_CTX_free(new_ctx); OPENSSL_free(secrets); OPENSSL_free(pre_comp); @@ -1328,7 +1292,7 @@ const EC_METHOD *EC_GFp_nistp224_method(void) { ec_GFp_nistp224_group_set_curve, ec_GFp_nistp224_point_get_affine_coordinates, ec_GFp_nistp224_points_mul, - 0 /* precompute_mult */, + 0 /* check_pub_key_order */, ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr, 0 /* field_encode */, diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c index 2adcd6b..32852dd 100644 --- a/src/crypto/ec/p256-64.c +++ b/src/crypto/ec/p256-64.c @@ -1312,8 +1312,8 @@ static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3, * * Tables for other points have table[i] = iG for i in 0 .. 16. */ -/* gmul is the table of precomputed base points */ -static const smallfelem gmul[2][16][3] = { +/* g_pre_comp is the table of precomputed base points */ +static const smallfelem g_pre_comp[2][16][3] = { {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2, 0x6b17d1f2e12c4247}, @@ -1505,8 +1505,7 @@ static char get_bit(const felem_bytearray in, int i) { static void batch_mul(felem x_out, felem y_out, felem z_out, const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar, - const int mixed, const smallfelem pre_comp[][17][3], - const smallfelem g_pre_comp[2][16][3]) { + const int mixed, const smallfelem pre_comp[][17][3]) { int i, skip; unsigned num, gen_mul = (g_scalar != NULL); felem nq[3], ftmp; @@ -1598,11 +1597,6 @@ static void batch_mul(felem x_out, felem y_out, felem z_out, felem_assign(z_out, nq[2]); } -/* Precomputation for the group generator. */ -typedef struct { - smallfelem g_pre_comp[2][16][3]; -} NISTP256_PRE_COMP; - /******************************************************************************/ /* * OPENSSL EC_METHOD FUNCTIONS @@ -1707,12 +1701,16 @@ static void make_points_affine(size_t num, smallfelem points[][3], (void (*)(void *, const void *))smallfelem_assign); } -/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL - * values Result is stored in r (r can equal one of the inputs). */ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx) { + const BIGNUM *g_scalar, const EC_POINT *p_, + const BIGNUM *p_scalar_, BN_CTX *ctx) { + /* TODO: This function used to take |points| and |scalars| as arrays of + * |num| elements. The code below should be simplified to work in terms of |p| + * and |p_scalar|. */ + size_t num = p_ != NULL ? 1 : 0; + const EC_POINT **points = p_ != NULL ? &p_ : NULL; + BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL; + int ret = 0; int j; int mixed = 0; @@ -1724,12 +1722,9 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, smallfelem *tmp_smallfelems = NULL; felem_bytearray tmp; unsigned i, num_bytes; - int have_pre_comp = 0; size_t num_points = num; smallfelem x_in, y_in, z_in; felem x_out, y_out, z_out; - const smallfelem(*g_pre_comp)[16][3] = NULL; - EC_POINT *generator = NULL; const EC_POINT *p = NULL; const BIGNUM *p_scalar = NULL; @@ -1748,34 +1743,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, goto err; } - if (scalar != NULL) { - /* try to use the standard precomputation */ - g_pre_comp = &gmul[0]; - generator = EC_POINT_new(group); - if (generator == NULL) { - goto err; - } - /* get the generator from precomputation */ - if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) || - !smallfelem_to_BN(y, g_pre_comp[0][1][1]) || - !smallfelem_to_BN(z, g_pre_comp[0][1][2])) { - OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); - goto err; - } - if (!ec_point_set_Jprojective_coordinates_GFp(group, generator, x, y, z, - ctx)) { - goto err; - } - if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { - /* precomputation matches generator */ - have_pre_comp = 1; - } else { - /* we don't have valid precomputation: treat the generator as a - * random point. */ - num_points++; - } - } - if (num_points > 0) { if (num_points >= 3) { /* unless we precompute multiples for just one or two points, @@ -1783,7 +1750,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, mixed = 1; } secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); - pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem)); + pre_comp = OPENSSL_malloc(num_points * sizeof(smallfelem[17][3])); if (mixed) { tmp_smallfelems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem)); @@ -1802,14 +1769,14 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, if (i == num) { /* we didn't have a valid precomputation, so we pick the generator. */ p = EC_GROUP_get0_generator(group); - p_scalar = scalar; + p_scalar = g_scalar; } else { /* the i^th point */ p = points[i]; p_scalar = scalars[i]; } if (p_scalar != NULL && p != NULL) { - /* reduce scalar to 0 <= scalar < 2^256 */ + /* reduce g_scalar to 0 <= g_scalar < 2^256 */ if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) { /* this is an unusual input, and we don't guarantee * constant-timeness. */ @@ -1851,32 +1818,25 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, } } - /* the scalar for the generator */ - if (scalar != NULL && have_pre_comp) { + if (g_scalar != NULL) { memset(g_secret, 0, sizeof(g_secret)); - /* reduce scalar to 0 <= scalar < 2^256 */ - if (BN_num_bits(scalar) > 256 || BN_is_negative(scalar)) { + /* reduce g_scalar to 0 <= g_scalar < 2^256 */ + if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) { /* this is an unusual input, and we don't guarantee * constant-timeness. */ - if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { + if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) { OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); goto err; } num_bytes = BN_bn2bin(tmp_scalar, tmp); } else { - num_bytes = BN_bn2bin(scalar, tmp); + num_bytes = BN_bn2bin(g_scalar, tmp); } flip_endian(g_secret, tmp, num_bytes); - /* do the multiplication with generator precomputation */ - batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, - num_points, g_secret, mixed, (const smallfelem(*)[17][3])pre_comp, - g_pre_comp); - } else { - /* do the multiplication without generator precomputation */ - batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, - num_points, NULL, mixed, (const smallfelem(*)[17][3])pre_comp, - NULL); } + batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, + num_points, g_scalar != NULL ? g_secret : NULL, mixed, + (const smallfelem(*)[17][3])pre_comp); /* reduce the output to its unique minimal representation */ felem_contract(x_in, x_out); @@ -1892,7 +1852,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, err: BN_CTX_end(ctx); - EC_POINT_free(generator); BN_CTX_free(new_ctx); OPENSSL_free(secrets); OPENSSL_free(pre_comp); @@ -1908,7 +1867,7 @@ const EC_METHOD *EC_GFp_nistp256_method(void) { ec_GFp_simple_group_copy, ec_GFp_nistp256_group_set_curve, ec_GFp_nistp256_point_get_affine_coordinates, ec_GFp_nistp256_points_mul, - 0 /* precompute_mult */, + 0 /* check_pub_key_order */, ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr, 0 /* field_encode */, 0 /* field_decode */, 0 /* field_set_to_one */ }; diff --git a/src/crypto/ec/p256-x86_64.c b/src/crypto/ec/p256-x86_64.c index 09816ad..2f7023d 100644 --- a/src/crypto/ec/p256-x86_64.c +++ b/src/crypto/ec/p256-x86_64.c @@ -22,6 +22,7 @@ #include <openssl/ec.h> +#include <assert.h> #include <stdint.h> #include <string.h> @@ -37,18 +38,13 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ !defined(OPENSSL_SMALL) -#if BN_BITS2 != 64 -#define TOBN(hi, lo) lo, hi -#else -#define TOBN(hi, lo) ((BN_ULONG)hi << 32 | lo) -#endif #if defined(__GNUC__) -#define ALIGN32 __attribute((aligned(32))) +#define ALIGN(x) __attribute((aligned(x))) #elif defined(_MSC_VER) -#define ALIGN32 __declspec(align(32)) +#define ALIGN(x) __declspec(align(x)) #else -#define ALIGN32 +#define ALIGN(x) #endif #define ALIGNPTR(p, N) ((uint8_t *)p + N - (size_t)p % N) @@ -69,21 +65,6 @@ typedef P256_POINT_AFFINE PRECOMP256_ROW[64]; /* Functions implemented in assembly */ -/* Modular mul by 2: res = 2*a mod P */ -void ecp_nistz256_mul_by_2(BN_ULONG res[P256_LIMBS], - const BN_ULONG a[P256_LIMBS]); -/* Modular div by 2: res = a/2 mod P */ -void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS], - const BN_ULONG a[P256_LIMBS]); -/* Modular mul by 3: res = 3*a mod P */ -void ecp_nistz256_mul_by_3(BN_ULONG res[P256_LIMBS], - const BN_ULONG a[P256_LIMBS]); -/* Modular add: res = a+b mod P */ -void ecp_nistz256_add(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS], - const BN_ULONG b[P256_LIMBS]); -/* Modular sub: res = a-b mod P */ -void ecp_nistz256_sub(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS], - const BN_ULONG b[P256_LIMBS]); /* Modular neg: res = -a mod P */ void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]); /* Montgomery mul: res = a*b*2^-256 mod P */ @@ -96,9 +77,6 @@ void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS], /* Convert a number from Montgomery domain, by multiplying with 1 */ void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS], const BN_ULONG in[P256_LIMBS]); -/* Convert a number to Montgomery domain, by multiplying with 2^512 mod P*/ -void ecp_nistz256_to_mont(BN_ULONG res[P256_LIMBS], - const BN_ULONG in[P256_LIMBS]); /* Functions that perform constant time access to the precomputed tables */ void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT *in_t, int index); void ecp_nistz256_select_w7(P256_POINT_AFFINE *val, @@ -153,48 +131,6 @@ static void copy_conditional(BN_ULONG dst[P256_LIMBS], } } -static BN_ULONG is_zero(BN_ULONG in) { - in |= (0 - in); - in = ~in; - in &= BN_MASK2; - in >>= BN_BITS2 - 1; - return in; -} - -static BN_ULONG is_equal(const BN_ULONG a[P256_LIMBS], - const BN_ULONG b[P256_LIMBS]) { - BN_ULONG res; - - res = a[0] ^ b[0]; - res |= a[1] ^ b[1]; - res |= a[2] ^ b[2]; - res |= a[3] ^ b[3]; - if (P256_LIMBS == 8) { - res |= a[4] ^ b[4]; - res |= a[5] ^ b[5]; - res |= a[6] ^ b[6]; - res |= a[7] ^ b[7]; - } - - return is_zero(res); -} - -static BN_ULONG is_one(const BN_ULONG a[P256_LIMBS]) { - BN_ULONG res; - - res = a[0] ^ ONE[0]; - res |= a[1] ^ ONE[1]; - res |= a[2] ^ ONE[2]; - res |= a[3] ^ ONE[3]; - if (P256_LIMBS == 8) { - res |= a[4] ^ ONE[4]; - res |= a[5] ^ ONE[5]; - res |= a[6] ^ ONE[6]; - } - - return is_zero(res); -} - void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a); void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a, const P256_POINT *b); @@ -296,113 +232,117 @@ static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS], return 1; } -/* r = sum(scalar[i]*point[i]) */ -static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, - const BIGNUM **scalar, - const EC_POINT **point, int num, - BN_CTX *ctx) { +/* r = p * p_scalar */ +static int ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, + const EC_POINT *p, const BIGNUM *p_scalar, + BN_CTX *ctx) { + assert(p != NULL); + assert(p_scalar != NULL); + static const unsigned kWindowSize = 5; static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1; - void *table_storage = OPENSSL_malloc(num * 16 * sizeof(P256_POINT) + 64); - uint8_t(*p_str)[33] = OPENSSL_malloc(num * 33 * sizeof(uint8_t)); - const BIGNUM **scalars = OPENSSL_malloc(num * sizeof(BIGNUM *)); - - if (table_storage == NULL || - p_str == NULL || - scalars == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - goto err; - } + /* A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should + * add no more than 63 bytes of overhead. Thus, |table| should require + * ~1599 ((96 * 16) + 63) bytes of stack space. */ + ALIGN(64) P256_POINT table[16]; + uint8_t p_str[33]; - P256_POINT(*table)[16] = (void *)ALIGNPTR(table_storage, 64); - int i; - for (i = 0; i < num; i++) { - P256_POINT *row = table[i]; + int ret = 0; + BN_CTX *new_ctx = NULL; + int ctx_started = 0; - if (BN_num_bits(scalar[i]) > 256 || BN_is_negative(scalar[i])) { - BIGNUM *mod = BN_CTX_get(ctx); - if (mod == NULL) { + if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) { + if (ctx == NULL) { + new_ctx = BN_CTX_new(); + if (new_ctx == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); goto err; } - - if (!BN_nnmod(mod, scalar[i], &group->order, ctx)) { - OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); - goto err; - } - scalars[i] = mod; - } else { - scalars[i] = scalar[i]; + ctx = new_ctx; } - - int j; - for (j = 0; j < scalars[i]->top * BN_BYTES; j += BN_BYTES) { - BN_ULONG d = scalars[i]->d[j / BN_BYTES]; - - p_str[i][j + 0] = d & 0xff; - p_str[i][j + 1] = (d >> 8) & 0xff; - p_str[i][j + 2] = (d >> 16) & 0xff; - p_str[i][j + 3] = (d >>= 24) & 0xff; - if (BN_BYTES == 8) { - d >>= 8; - p_str[i][j + 4] = d & 0xff; - p_str[i][j + 5] = (d >> 8) & 0xff; - p_str[i][j + 6] = (d >> 16) & 0xff; - p_str[i][j + 7] = (d >> 24) & 0xff; - } + BN_CTX_start(ctx); + ctx_started = 1; + BIGNUM *mod = BN_CTX_get(ctx); + if (mod == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!BN_nnmod(mod, p_scalar, &group->order, ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; } + p_scalar = mod; + } - for (; j < 33; j++) { - p_str[i][j] = 0; + int j; + for (j = 0; j < p_scalar->top * BN_BYTES; j += BN_BYTES) { + BN_ULONG d = p_scalar->d[j / BN_BYTES]; + + p_str[j + 0] = d & 0xff; + p_str[j + 1] = (d >> 8) & 0xff; + p_str[j + 2] = (d >> 16) & 0xff; + p_str[j + 3] = (d >>= 24) & 0xff; + if (BN_BYTES == 8) { + d >>= 8; + p_str[j + 4] = d & 0xff; + p_str[j + 5] = (d >> 8) & 0xff; + p_str[j + 6] = (d >> 16) & 0xff; + p_str[j + 7] = (d >> 24) & 0xff; } + } - /* table[0] is implicitly (0,0,0) (the point at infinity), therefore it is - * not stored. All other values are actually stored with an offset of -1 in - * table. */ + for (; j < 33; j++) { + p_str[j] = 0; + } - if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &point[i]->X) || - !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &point[i]->Y) || - !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &point[i]->Z)) { - OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE); - goto err; - } + /* table[0] is implicitly (0,0,0) (the point at infinity), therefore it is + * not stored. All other values are actually stored with an offset of -1 in + * table. */ + P256_POINT *row = table; - ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]); - ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]); - ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]); - ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]); - ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]); - ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]); - ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]); - ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]); - ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]); - ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]); - ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]); - ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]); - ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]); - ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]); - ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]); + if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &p->X) || + !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &p->Y) || + !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &p->Z)) { + OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE); + goto err; } + ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]); + ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]); + ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]); + ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]); + ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]); + ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]); + ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]); + BN_ULONG tmp[P256_LIMBS]; - ALIGN32 P256_POINT h; + ALIGN(32) P256_POINT h; unsigned index = 255; - unsigned wvalue = p_str[0][(index - 1) / 8]; + unsigned wvalue = p_str[(index - 1) / 8]; wvalue = (wvalue >> ((index - 1) % 8)) & kMask; - ecp_nistz256_select_w5(r, table[0], booth_recode_w5(wvalue) >> 1); + ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1); while (index >= 5) { - for (i = (index == 255 ? 1 : 0); i < num; i++) { + if (index != 255) { unsigned off = (index - 1) / 8; - wvalue = p_str[i][off] | p_str[i][off + 1] << 8; + wvalue = p_str[off] | p_str[off + 1] << 8; wvalue = (wvalue >> ((index - 1) % 8)) & kMask; wvalue = booth_recode_w5(wvalue); - ecp_nistz256_select_w5(&h, table[i], wvalue >> 1); + ecp_nistz256_select_w5(&h, table, wvalue >> 1); ecp_nistz256_neg(tmp, h.Y); copy_conditional(h.Y, tmp, (wvalue & 1)); @@ -420,217 +360,166 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, } /* Final window */ - for (i = 0; i < num; i++) { - wvalue = p_str[i][0]; - wvalue = (wvalue << 1) & kMask; + wvalue = p_str[0]; + wvalue = (wvalue << 1) & kMask; - wvalue = booth_recode_w5(wvalue); + wvalue = booth_recode_w5(wvalue); - ecp_nistz256_select_w5(&h, table[i], wvalue >> 1); + ecp_nistz256_select_w5(&h, table, wvalue >> 1); - ecp_nistz256_neg(tmp, h.Y); - copy_conditional(h.Y, tmp, wvalue & 1); + ecp_nistz256_neg(tmp, h.Y); + copy_conditional(h.Y, tmp, wvalue & 1); - ecp_nistz256_point_add(r, r, &h); - } + ecp_nistz256_point_add(r, r, &h); -err: - OPENSSL_free(table_storage); - OPENSSL_free(p_str); - OPENSSL_free((BIGNUM**) scalars); -} - -/* Coordinates of G, for which we have precomputed tables */ -const static BN_ULONG def_xG[P256_LIMBS] = { - TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601), - TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6), -}; - -const static BN_ULONG def_yG[P256_LIMBS] = { - TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c), - TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85) -}; + ret = 1; -/* ecp_nistz256_is_affine_G returns one if |generator| is the standard, P-256 - * generator. */ -static int ecp_nistz256_is_affine_G(const EC_POINT *generator) { - return (generator->X.top == P256_LIMBS) && (generator->Y.top == P256_LIMBS) && - (generator->Z.top == (P256_LIMBS - P256_LIMBS / 8)) && - is_equal(generator->X.d, def_xG) && is_equal(generator->Y.d, def_yG) && - is_one(generator->Z.d); +err: + if (ctx_started) { + BN_CTX_end(ctx); + } + BN_CTX_free(new_ctx); + return ret; } -/* r = scalar*G + sum(scalars[i]*points[i]) */ static int ecp_nistz256_points_mul( - const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, - const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) { + const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *p_, const BIGNUM *p_scalar, BN_CTX *ctx) { + assert((p_ != NULL) == (p_scalar != NULL)); + static const unsigned kWindowSize = 7; static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1; - int ret = 0, no_precomp_for_generator = 0, p_is_infinity = 0; - ALIGN32 union { + ALIGN(32) union { P256_POINT p; P256_POINT_AFFINE a; } t, p; - if (scalar == NULL && num == 0) { - return EC_POINT_set_to_infinity(group, r); - } + int ret = 0; + BN_CTX *new_ctx = NULL; + int ctx_started = 0; /* Need 256 bits for space for all coordinates. */ - bn_wexpand(&r->X, P256_LIMBS); - bn_wexpand(&r->Y, P256_LIMBS); - bn_wexpand(&r->Z, P256_LIMBS); + if (bn_wexpand(&r->X, P256_LIMBS) == NULL || + bn_wexpand(&r->Y, P256_LIMBS) == NULL || + bn_wexpand(&r->Z, P256_LIMBS) == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + goto err; + } r->X.top = P256_LIMBS; r->Y.top = P256_LIMBS; r->Z.top = P256_LIMBS; - const EC_POINT *generator = NULL; - if (scalar) { - generator = EC_GROUP_get0_generator(group); - if (generator == NULL) { - OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR); - goto err; - } - - if (ecp_nistz256_is_affine_G(generator)) { - if (BN_num_bits(scalar) > 256 || BN_is_negative(scalar)) { - BIGNUM *tmp_scalar = BN_CTX_get(ctx); - if (tmp_scalar == NULL) { + if (g_scalar != NULL) { + if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) { + if (ctx == NULL) { + new_ctx = BN_CTX_new(); + if (new_ctx == NULL) { goto err; } - - if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { - OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); - goto err; - } - scalar = tmp_scalar; + ctx = new_ctx; } - - uint8_t p_str[33] = {0}; - int i; - for (i = 0; i < scalar->top * BN_BYTES; i += BN_BYTES) { - BN_ULONG d = scalar->d[i / BN_BYTES]; - - p_str[i + 0] = d & 0xff; - p_str[i + 1] = (d >> 8) & 0xff; - p_str[i + 2] = (d >> 16) & 0xff; - p_str[i + 3] = (d >>= 24) & 0xff; - if (BN_BYTES == 8) { - d >>= 8; - p_str[i + 4] = d & 0xff; - p_str[i + 5] = (d >> 8) & 0xff; - p_str[i + 6] = (d >> 16) & 0xff; - p_str[i + 7] = (d >> 24) & 0xff; - } + BN_CTX_start(ctx); + ctx_started = 1; + BIGNUM *tmp_scalar = BN_CTX_get(ctx); + if (tmp_scalar == NULL) { + goto err; } - for (; i < (int) sizeof(p_str); i++) { - p_str[i] = 0; + if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; } + g_scalar = tmp_scalar; + } - /* First window */ - unsigned wvalue = (p_str[0] << 1) & kMask; - unsigned index = kWindowSize; - - wvalue = booth_recode_w7(wvalue); + uint8_t p_str[33] = {0}; + int i; + for (i = 0; i < g_scalar->top * BN_BYTES; i += BN_BYTES) { + BN_ULONG d = g_scalar->d[i / BN_BYTES]; - const PRECOMP256_ROW *const precomputed_table = - (const PRECOMP256_ROW *)ecp_nistz256_precomputed; - ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1); + p_str[i + 0] = d & 0xff; + p_str[i + 1] = (d >> 8) & 0xff; + p_str[i + 2] = (d >> 16) & 0xff; + p_str[i + 3] = (d >>= 24) & 0xff; + if (BN_BYTES == 8) { + d >>= 8; + p_str[i + 4] = d & 0xff; + p_str[i + 5] = (d >> 8) & 0xff; + p_str[i + 6] = (d >> 16) & 0xff; + p_str[i + 7] = (d >> 24) & 0xff; + } + } - ecp_nistz256_neg(p.p.Z, p.p.Y); - copy_conditional(p.p.Y, p.p.Z, wvalue & 1); + for (; i < (int) sizeof(p_str); i++) { + p_str[i] = 0; + } - memcpy(p.p.Z, ONE, sizeof(ONE)); + /* First window */ + unsigned wvalue = (p_str[0] << 1) & kMask; + unsigned index = kWindowSize; - for (i = 1; i < 37; i++) { - unsigned off = (index - 1) / 8; - wvalue = p_str[off] | p_str[off + 1] << 8; - wvalue = (wvalue >> ((index - 1) % 8)) & kMask; - index += kWindowSize; + wvalue = booth_recode_w7(wvalue); - wvalue = booth_recode_w7(wvalue); + const PRECOMP256_ROW *const precomputed_table = + (const PRECOMP256_ROW *)ecp_nistz256_precomputed; + ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1); - ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1); + ecp_nistz256_neg(p.p.Z, p.p.Y); + copy_conditional(p.p.Y, p.p.Z, wvalue & 1); - ecp_nistz256_neg(t.p.Z, t.a.Y); - copy_conditional(t.a.Y, t.p.Z, wvalue & 1); + memcpy(p.p.Z, ONE, sizeof(ONE)); - ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); - } - } else { - p_is_infinity = 1; - no_precomp_for_generator = 1; - } - } else { - p_is_infinity = 1; - } + for (i = 1; i < 37; i++) { + unsigned off = (index - 1) / 8; + wvalue = p_str[off] | p_str[off + 1] << 8; + wvalue = (wvalue >> ((index - 1) % 8)) & kMask; + index += kWindowSize; - if (no_precomp_for_generator) { - /* Without a precomputed table for the generator, it has to be handled like - * a normal point. */ - const BIGNUM **new_scalars; - const EC_POINT **new_points; + wvalue = booth_recode_w7(wvalue); - /* Bound |num| so that all the possible overflows in the following can be - * excluded. */ - if (0xffffff < num) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - return 0; - } + ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1); - new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *)); - if (new_scalars == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - return 0; - } + ecp_nistz256_neg(t.p.Z, t.a.Y); + copy_conditional(t.a.Y, t.p.Z, wvalue & 1); - new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *)); - if (new_points == NULL) { - OPENSSL_free((BIGNUM**) new_scalars); - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - return 0; + ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); } - - memcpy((BIGNUM**) new_scalars, scalars, num * sizeof(BIGNUM *)); - new_scalars[num] = scalar; - memcpy((EC_POINT**) new_points, points, num * sizeof(EC_POINT *)); - new_points[num] = generator; - - scalars = new_scalars; - points = new_points; - num++; } - if (num) { + const int p_is_infinity = g_scalar == NULL; + if (p_scalar != NULL) { P256_POINT *out = &t.p; if (p_is_infinity) { out = &p.p; } - ecp_nistz256_windowed_mul(group, out, scalars, points, num, ctx); + if (!ecp_nistz256_windowed_mul(group, out, p_, p_scalar, ctx)) { + goto err; + } if (!p_is_infinity) { ecp_nistz256_point_add(&p.p, &p.p, out); } } - if (no_precomp_for_generator) { - OPENSSL_free((BIGNUM **) scalars); - OPENSSL_free((EC_POINT **) points); - } - memcpy(r->X.d, p.p.X, sizeof(p.p.X)); memcpy(r->Y.d, p.p.Y, sizeof(p.p.Y)); memcpy(r->Z.d, p.p.Z, sizeof(p.p.Z)); + + /* Not constant-time, but we're only operating on the public output. */ bn_correct_top(&r->X); bn_correct_top(&r->Y); bn_correct_top(&r->Z); + r->Z_is_one = BN_is_one(&r->Z); ret = 1; err: + if (ctx_started) { + BN_CTX_end(ctx); + } + BN_CTX_free(new_ctx); return ret; } @@ -659,7 +548,10 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point, ecp_nistz256_mul_mont(x_aff, z_inv2, point_x); if (x != NULL) { - bn_wexpand(x, P256_LIMBS); + if (bn_wexpand(x, P256_LIMBS) == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } x->top = P256_LIMBS; ecp_nistz256_from_mont(x->d, x_aff); bn_correct_top(x); @@ -668,7 +560,10 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point, if (y != NULL) { ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2); ecp_nistz256_mul_mont(y_aff, z_inv3, point_y); - bn_wexpand(y, P256_LIMBS); + if (bn_wexpand(y, P256_LIMBS) == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } y->top = P256_LIMBS; ecp_nistz256_from_mont(y->d, y_aff); bn_correct_top(y); @@ -686,7 +581,7 @@ const EC_METHOD *EC_GFp_nistz256_method(void) { ec_GFp_mont_group_set_curve, ecp_nistz256_get_affine, ecp_nistz256_points_mul, - 0, /* precompute_mult */ + 0 /* check_pub_key_order */, ec_GFp_mont_field_mul, ec_GFp_mont_field_sqr, ec_GFp_mont_field_encode, diff --git a/src/crypto/ec/simple.c b/src/crypto/ec/simple.c index 7e611eb..cef0e94 100644 --- a/src/crypto/ec/simple.c +++ b/src/crypto/ec/simple.c @@ -76,25 +76,6 @@ #include "internal.h" -const EC_METHOD *EC_GFp_simple_method(void) { - static const EC_METHOD ret = {ec_GFp_simple_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_simple_group_copy, - ec_GFp_simple_group_set_curve, - ec_GFp_simple_point_get_affine_coordinates, - 0 /* mul */, - 0 /* precompute_mult */, - ec_GFp_simple_field_mul, - ec_GFp_simple_field_sqr, - 0 /* field_encode */, - 0 /* field_decode */, - 0 /* field_set_to_one */}; - - return &ret; -} - - /* Most method functions in this file are designed to work with non-trivial * representations of field elements if necessary (see ecp_mont.c): while * standard modular addition and subtraction are used, the field_mul and diff --git a/src/crypto/ec/wnaf.c b/src/crypto/ec/wnaf.c index 4aaffd9..ba2257c 100644 --- a/src/crypto/ec/wnaf.c +++ b/src/crypto/ec/wnaf.c @@ -80,65 +80,8 @@ /* This file implements the wNAF-based interleaving multi-exponentation method * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>); - * for multiplication with precomputation, we use wNAF splitting - * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>). * */ -/* structure for precomputed multiples of the generator */ -typedef struct ec_pre_comp_st { - size_t blocksize; /* block size for wNAF splitting */ - size_t numblocks; /* max. number of blocks for which we have precomputation */ - size_t w; /* window size */ - EC_POINT **points; /* array with pre-calculated multiples of generator: - * 'num' pointers to EC_POINT objects followed by a NULL */ - size_t num; /* numblocks * 2^(w-1) */ - CRYPTO_refcount_t references; -} EC_PRE_COMP; - -static EC_PRE_COMP *ec_pre_comp_new(void) { - EC_PRE_COMP *ret = NULL; - - ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP)); - if (!ret) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - return ret; - } - ret->blocksize = 8; /* default */ - ret->numblocks = 0; - ret->w = 4; /* default */ - ret->points = NULL; - ret->num = 0; - ret->references = 1; - return ret; -} - -void *ec_pre_comp_dup(EC_PRE_COMP *pre_comp) { - if (pre_comp == NULL) { - return NULL; - } - - CRYPTO_refcount_inc(&pre_comp->references); - return pre_comp; -} - -void ec_pre_comp_free(EC_PRE_COMP *pre_comp) { - if (pre_comp == NULL || - !CRYPTO_refcount_dec_and_test_zero(&pre_comp->references)) { - return; - } - - if (pre_comp->points) { - EC_POINT **p; - - for (p = pre_comp->points; *p != NULL; p++) { - EC_POINT_free(*p); - } - OPENSSL_free(pre_comp->points); - } - OPENSSL_free(pre_comp); -} - - /* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. * This is an array r[] of values that are either zero or odd with an * absolute value less than 2^w satisfying @@ -281,21 +224,12 @@ err: ? 2 \ : 1)) -/* Compute - * \sum scalars[i]*points[i], - * also including - * scalar*generator - * in the addition if scalar != NULL - */ -int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *ctx) { +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) { BN_CTX *new_ctx = NULL; const EC_POINT *generator = NULL; EC_POINT *tmp = NULL; - size_t totalnum; - size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */ - size_t pre_points_per_block = 0; + size_t total_num; size_t i, j; int k; int r_is_inverted = 0; @@ -307,30 +241,9 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num_val; EC_POINT **val = NULL; /* precomputation */ EC_POINT **v; - EC_POINT ***val_sub = - NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */ - const EC_PRE_COMP *pre_comp = NULL; - int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like - * other scalars, - * i.e. precomputation is not available */ + EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' */ int ret = 0; - if (group->meth != r->meth) { - OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - - if ((scalar == NULL) && (num == 0)) { - return EC_POINT_set_to_infinity(group, r); - } - - for (i = 0; i < num; i++) { - if (group->meth != points[i]->meth) { - OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - } - if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { @@ -338,52 +251,31 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } } - if (scalar != NULL) { + /* TODO: This function used to take |points| and |scalars| as arrays of + * |num| elements. The code below should be simplified to work in terms of |p| + * and |p_scalar|. */ + size_t num = p != NULL ? 1 : 0; + const EC_POINT **points = p != NULL ? &p : NULL; + const BIGNUM **scalars = p != NULL ? &p_scalar : NULL; + + total_num = num; + + if (g_scalar != NULL) { generator = EC_GROUP_get0_generator(group); if (generator == NULL) { OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR); goto err; } - /* look if we can use precomputed multiples of generator */ - - pre_comp = group->pre_comp; - - if (pre_comp && pre_comp->numblocks && - (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) { - blocksize = pre_comp->blocksize; - - /* determine maximum number of blocks that wNAF splitting may yield - * (NB: maximum wNAF length is bit length plus one) */ - numblocks = (BN_num_bits(scalar) / blocksize) + 1; - - /* we cannot use more blocks than we have precomputation for */ - if (numblocks > pre_comp->numblocks) { - numblocks = pre_comp->numblocks; - } - - pre_points_per_block = (size_t)1 << (pre_comp->w - 1); - - /* check that pre_comp looks sane */ - if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) { - OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - goto err; - } - } else { - /* can't use precomputation */ - pre_comp = NULL; - numblocks = 1; - num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */ - } + ++total_num; /* treat 'g_scalar' like 'num'-th element of 'scalars' */ } - totalnum = num + numblocks; - wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]); - wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]); - wNAF = OPENSSL_malloc((totalnum + 1) * + wsize = OPENSSL_malloc(total_num * sizeof wsize[0]); + wNAF_len = OPENSSL_malloc(total_num * sizeof wNAF_len[0]); + wNAF = OPENSSL_malloc((total_num + 1) * sizeof wNAF[0]); /* includes space for pivot */ - val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]); + val_sub = OPENSSL_malloc(total_num * sizeof val_sub[0]); /* Ensure wNAF is initialised in case we end up going to err. */ if (wNAF) { @@ -398,15 +290,15 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, /* num_val will be the total number of temporarily precomputed points */ num_val = 0; - for (i = 0; i < num + num_scalar; i++) { + for (i = 0; i < total_num; i++) { size_t bits; - bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); + bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(g_scalar); wsize[i] = EC_window_bits_for_scalar_size(bits); num_val += (size_t)1 << (wsize[i] - 1); wNAF[i + 1] = NULL; /* make sure we always have a pivot */ wNAF[i] = - compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]); + compute_wNAF((i < num ? scalars[i] : g_scalar), wsize[i], &wNAF_len[i]); if (wNAF[i] == NULL) { goto err; } @@ -415,110 +307,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } } - if (numblocks) { - /* we go here iff scalar != NULL */ - - if (pre_comp == NULL) { - if (num_scalar != 1) { - OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - goto err; - } - /* we have already generated a wNAF for 'scalar' */ - } else { - signed char *tmp_wNAF = NULL; - size_t tmp_len = 0; - - if (num_scalar != 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - goto err; - } - - /* use the window size for which we have precomputation */ - wsize[num] = pre_comp->w; - tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len); - if (!tmp_wNAF) { - goto err; - } - - if (tmp_len <= max_len) { - /* One of the other wNAFs is at least as long - * as the wNAF belonging to the generator, - * so wNAF splitting will not buy us anything. */ - - numblocks = 1; /* don't use wNAF splitting */ - totalnum = num + numblocks; - wNAF[num] = tmp_wNAF; - wNAF[num + 1] = NULL; - wNAF_len[num] = tmp_len; - /* pre_comp->points starts with the points that we need here: */ - val_sub[num] = pre_comp->points; - } else { - /* don't include tmp_wNAF directly into wNAF array - * - use wNAF splitting and include the blocks */ - - signed char *pp; - EC_POINT **tmp_points; - - if (tmp_len < numblocks * blocksize) { - /* possibly we can do with fewer blocks than estimated */ - numblocks = (tmp_len + blocksize - 1) / blocksize; - if (numblocks > pre_comp->numblocks) { - OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - OPENSSL_free(tmp_wNAF); - goto err; - } - totalnum = num + numblocks; - } - - /* split wNAF in 'numblocks' parts */ - pp = tmp_wNAF; - tmp_points = pre_comp->points; - - for (i = num; i < totalnum; i++) { - if (i < totalnum - 1) { - wNAF_len[i] = blocksize; - if (tmp_len < blocksize) { - OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - OPENSSL_free(tmp_wNAF); - goto err; - } - tmp_len -= blocksize; - } else { - /* last block gets whatever is left - * (this could be more or less than 'blocksize'!) */ - wNAF_len[i] = tmp_len; - } - - wNAF[i + 1] = NULL; - wNAF[i] = OPENSSL_malloc(wNAF_len[i]); - if (wNAF[i] == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - OPENSSL_free(tmp_wNAF); - goto err; - } - memcpy(wNAF[i], pp, wNAF_len[i]); - if (wNAF_len[i] > max_len) { - max_len = wNAF_len[i]; - } - - if (*tmp_points == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - OPENSSL_free(tmp_wNAF); - goto err; - } - val_sub[i] = tmp_points; - tmp_points += pre_points_per_block; - pp += blocksize; - } - OPENSSL_free(tmp_wNAF); - } - } - } - - /* All points we precompute now go into a single array 'val'. - * 'val_sub[i]' is a pointer to the subarray for the i-th point, - * or to a subarray of 'pre_comp->points' if we already have precomputation. - */ + /* All points we precompute now go into a single array 'val'. 'val_sub[i]' is + * a pointer to the subarray for the i-th point. */ val = OPENSSL_malloc((num_val + 1) * sizeof val[0]); if (val == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); @@ -528,7 +318,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, /* allocate points for precomputation */ v = val; - for (i = 0; i < num + num_scalar; i++) { + for (i = 0; i < total_num; i++) { val_sub[i] = v; for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) { *v = EC_POINT_new(group); @@ -553,7 +343,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * val_sub[i][2] := 5 * points[i] * ... */ - for (i = 0; i < num + num_scalar; i++) { + for (i = 0; i < total_num; i++) { if (i < num) { if (!EC_POINT_copy(val_sub[i][0], points[i])) { goto err; @@ -587,7 +377,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, goto err; } - for (i = 0; i < totalnum; i++) { + for (i = 0; i < total_num; i++) { if (wNAF_len[i] > (size_t)k) { int digit = wNAF[i][k]; int is_neg; @@ -657,192 +447,3 @@ err: OPENSSL_free(val_sub); return ret; } - - -/* ec_wNAF_precompute_mult() - * creates an EC_PRE_COMP object with preprecomputed multiples of the generator - * for use with wNAF splitting as implemented in ec_wNAF_mul(). - * - * 'pre_comp->points' is an array of multiples of the generator - * of the following form: - * points[0] = generator; - * points[1] = 3 * generator; - * ... - * points[2^(w-1)-1] = (2^(w-1)-1) * generator; - * points[2^(w-1)] = 2^blocksize * generator; - * points[2^(w-1)+1] = 3 * 2^blocksize * generator; - * ... - * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * - *generator - * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * - *generator - * ... - * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * - *generator - * points[2^(w-1)*numblocks] = NULL - */ -int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { - const EC_POINT *generator; - EC_POINT *tmp_point = NULL, *base = NULL, **var; - BN_CTX *new_ctx = NULL; - BIGNUM *order; - size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; - EC_POINT **points = NULL; - EC_PRE_COMP *pre_comp; - int ret = 0; - - /* if there is an old EC_PRE_COMP object, throw it away */ - ec_pre_comp_free(group->pre_comp); - group->pre_comp = NULL; - - generator = EC_GROUP_get0_generator(group); - if (generator == NULL) { - OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR); - return 0; - } - - pre_comp = ec_pre_comp_new(); - if (pre_comp == NULL) { - return 0; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) { - goto err; - } - } - - BN_CTX_start(ctx); - order = BN_CTX_get(ctx); - if (order == NULL) { - goto err; - } - - if (!EC_GROUP_get_order(group, order, ctx)) { - goto err; - } - if (BN_is_zero(order)) { - OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_ORDER); - goto err; - } - - bits = BN_num_bits(order); - /* The following parameters mean we precompute (approximately) - * one point per bit. - * - * TBD: The combination 8, 4 is perfect for 160 bits; for other - * bit lengths, other parameter combinations might provide better - * efficiency. - */ - blocksize = 8; - w = 4; - if (EC_window_bits_for_scalar_size(bits) > w) { - /* let's not make the window too small ... */ - w = EC_window_bits_for_scalar_size(bits); - } - - numblocks = (bits + blocksize - 1) / - blocksize; /* max. number of blocks to use for wNAF splitting */ - - pre_points_per_block = (size_t)1 << (w - 1); - num = pre_points_per_block * - numblocks; /* number of points to compute and store */ - - points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1)); - if (!points) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - goto err; - } - - var = points; - var[num] = NULL; /* pivot */ - for (i = 0; i < num; i++) { - if ((var[i] = EC_POINT_new(group)) == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EC_POINT_copy(base, generator)) { - goto err; - } - - /* do the precomputation */ - for (i = 0; i < numblocks; i++) { - size_t j; - - if (!EC_POINT_dbl(group, tmp_point, base, ctx)) { - goto err; - } - - if (!EC_POINT_copy(*var++, base)) { - goto err; - } - - for (j = 1; j < pre_points_per_block; j++, var++) { - /* calculate odd multiples of the current base point */ - if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) { - goto err; - } - } - - if (i < numblocks - 1) { - /* get the next base (multiply current one by 2^blocksize) */ - size_t k; - - if (blocksize <= 2) { - OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (!EC_POINT_dbl(group, base, tmp_point, ctx)) { - goto err; - } - for (k = 2; k < blocksize; k++) { - if (!EC_POINT_dbl(group, base, base, ctx)) { - goto err; - } - } - } - } - - if (!EC_POINTs_make_affine(group, num, points, ctx)) { - goto err; - } - - pre_comp->blocksize = blocksize; - pre_comp->numblocks = numblocks; - pre_comp->w = w; - pre_comp->points = points; - points = NULL; - pre_comp->num = num; - - group->pre_comp = pre_comp; - pre_comp = NULL; - - ret = 1; - -err: - if (ctx != NULL) { - BN_CTX_end(ctx); - } - BN_CTX_free(new_ctx); - ec_pre_comp_free(pre_comp); - if (points) { - EC_POINT **p; - - for (p = points; *p != NULL; p++) { - EC_POINT_free(*p); - } - OPENSSL_free(points); - } - EC_POINT_free(tmp_point); - EC_POINT_free(base); - return ret; -} diff --git a/src/crypto/ecdsa/ecdsa.c b/src/crypto/ecdsa/ecdsa.c index a718cf8..16760ed 100644 --- a/src/crypto/ecdsa/ecdsa.c +++ b/src/crypto/ecdsa/ecdsa.c @@ -143,7 +143,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, const ECDSA_SIG *sig, EC_KEY *eckey) { int ret = 0; BN_CTX *ctx; - BIGNUM *order, *u1, *u2, *m, *X; + BIGNUM *u1, *u2, *m, *X; EC_POINT *point = NULL; const EC_GROUP *group; const EC_POINT *pub_key; @@ -167,21 +167,16 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, return 0; } BN_CTX_start(ctx); - order = BN_CTX_get(ctx); u1 = BN_CTX_get(ctx); u2 = BN_CTX_get(ctx); m = BN_CTX_get(ctx); X = BN_CTX_get(ctx); - if (order == NULL || u1 == NULL || u2 == NULL || m == NULL || X == NULL) { + if (u1 == NULL || u2 == NULL || m == NULL || X == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); goto err; } - if (!EC_GROUP_get_order(group, order, ctx)) { - OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); - goto err; - } - + const BIGNUM *order = EC_GROUP_get0_order(group); if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { @@ -229,7 +224,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, ret = (BN_ucmp(u1, sig->r) == 0); err: - BN_CTX_end(ctx); + BN_CTX_end(ctx);
BN_CTX_free(ctx); EC_POINT_free(point); return ret; @@ -239,7 +234,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp, const uint8_t *digest, size_t digest_len) { BN_CTX *ctx = NULL; - BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; + BIGNUM *k = NULL, *r = NULL, *X = NULL; EC_POINT *tmp_point = NULL; const EC_GROUP *group; int ret = 0; @@ -260,9 +255,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, k = BN_new(); /* this value is later returned in *kinvp */ r = BN_new(); /* this value is later returned in *rp */ - order = BN_new(); X = BN_new(); - if (!k || !r || !order || !X) { + if (k == NULL || r == NULL || X == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -271,10 +265,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); goto err; } - if (!EC_GROUP_get_order(group, order, ctx)) { - OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); - goto err; - } + + const BIGNUM *order = EC_GROUP_get0_order(group); do { /* If possible, we'll include the private key and message digest in the k @@ -360,7 +352,6 @@ err: if (ctx_in == NULL) { BN_CTX_free(ctx); } - BN_free(order); EC_POINT_free(tmp_point); BN_clear_free(X); return ret; @@ -374,7 +365,7 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) { int ok = 0; - BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; + BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL; const BIGNUM *ckinv; BN_CTX *ctx = NULL; const EC_GROUP *group; @@ -401,16 +392,15 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len, } s = ret->s; - if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || - (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { + if ((ctx = BN_CTX_new()) == NULL || + (tmp = BN_new()) == NULL || + (m = BN_new()) == NULL) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); goto err; } - if (!EC_GROUP_get_order(group, order, ctx)) { - OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); - goto err; - } + const BIGNUM *order = EC_GROUP_get0_order(group); + if (!digest_to_bn(m, digest, digest_len, order)) { goto err; } @@ -464,7 +454,6 @@ err: BN_CTX_free(ctx); BN_clear_free(m); BN_clear_free(tmp); - BN_free(order); BN_clear_free(kinv); return ret; } diff --git a/src/crypto/ecdsa/ecdsa_asn1.c b/src/crypto/ecdsa/ecdsa_asn1.c index f2d7c36..3fee191 100644 --- a/src/crypto/ecdsa/ecdsa_asn1.c +++ b/src/crypto/ecdsa/ecdsa_asn1.c @@ -78,17 +78,7 @@ size_t ECDSA_size(const EC_KEY *key) { return 0; } - BIGNUM *order = BN_new(); - if (order == NULL) { - return 0; - } - if (!EC_GROUP_get_order(group, order, NULL)) { - BN_clear_free(order); - return 0; - } - - group_order_size = BN_num_bytes(order); - BN_clear_free(order); + group_order_size = BN_num_bytes(EC_GROUP_get0_order(group)); } return ECDSA_SIG_max_len(group_order_size); diff --git a/src/crypto/ecdsa/ecdsa_test.cc b/src/crypto/ecdsa/ecdsa_test.cc index b916509..a0c8fbd 100644 --- a/src/crypto/ecdsa/ecdsa_test.cc +++ b/src/crypto/ecdsa/ecdsa_test.cc @@ -63,7 +63,6 @@ #include <openssl/rand.h> #include "../test/scoped_types.h" -#include "../test/stl_compat.h" enum Api { kEncodedApi, @@ -118,9 +117,8 @@ static bool TestTamperedSig(FILE *out, Api api, const uint8_t *digest, size_t buf_len = 2 * bn_len; std::vector<uint8_t> raw_buf(buf_len); // Pad the bignums with leading zeroes. - if (!BN_bn2bin_padded(bssl::vector_data(&raw_buf), bn_len, ecdsa_sig->r) || - !BN_bn2bin_padded(bssl::vector_data(&raw_buf) + bn_len, bn_len, - ecdsa_sig->s)) { + if (!BN_bn2bin_padded(raw_buf.data(), bn_len, ecdsa_sig->r) || + !BN_bn2bin_padded(raw_buf.data() + bn_len, bn_len, ecdsa_sig->s)) { return false; } @@ -129,18 +127,16 @@ static bool TestTamperedSig(FILE *out, Api api, const uint8_t *digest, uint8_t dirt = raw_buf[11] ? raw_buf[11] : 1; raw_buf[offset] ^= dirt; // Now read the BIGNUMs back in from raw_buf. - if (BN_bin2bn(bssl::vector_data(&raw_buf), bn_len, ecdsa_sig->r) == NULL || - BN_bin2bn(bssl::vector_data(&raw_buf) + bn_len, bn_len, - ecdsa_sig->s) == NULL || + if (BN_bin2bn(raw_buf.data(), bn_len, ecdsa_sig->r) == NULL || + BN_bin2bn(raw_buf.data() + bn_len, bn_len, ecdsa_sig->s) == NULL || !VerifyECDSASig(api, digest, digest_len, ecdsa_sig, eckey, 0)) { return false; } // Sanity check: Undo the modification and verify signature. raw_buf[offset] ^= dirt; - if (BN_bin2bn(bssl::vector_data(&raw_buf), bn_len, ecdsa_sig->r) == NULL || - BN_bin2bn(bssl::vector_data(&raw_buf) + bn_len, bn_len, - ecdsa_sig->s) == NULL || + if (BN_bin2bn(raw_buf.data(), bn_len, ecdsa_sig->r) == NULL || + BN_bin2bn(raw_buf.data() + bn_len, bn_len, ecdsa_sig->s) == NULL || !VerifyECDSASig(api, digest, digest_len, ecdsa_sig, eckey, 1)) { return false; } @@ -180,12 +176,8 @@ static bool TestBuiltin(FILE *out) { fprintf(out, " failed\n"); return false; } - ScopedBIGNUM order(BN_new()); - if (!order || !EC_GROUP_get_order(group.get(), order.get(), NULL)) { - fprintf(out, " failed\n"); - return false; - } - if (BN_num_bits(order.get()) < 160) { + const BIGNUM *order = EC_GROUP_get0_order(group.get()); + if (BN_num_bits(order) < 160) { // Too small to test. fprintf(out, " skipped\n"); continue; @@ -221,8 +213,7 @@ static bool TestBuiltin(FILE *out) { // Create a signature. unsigned sig_len = ECDSA_size(eckey.get()); std::vector<uint8_t> signature(sig_len); - if (!ECDSA_sign(0, digest, 20, bssl::vector_data(&signature), &sig_len, - eckey.get())) { + if (!ECDSA_sign(0, digest, 20, signature.data(), &sig_len, eckey.get())) { fprintf(out, " failed\n"); return false; } @@ -230,32 +221,32 @@ static bool TestBuiltin(FILE *out) { fprintf(out, "."); fflush(out); // Verify the signature. - if (!ECDSA_verify(0, digest, 20, bssl::vector_data(&signature), - signature.size(), eckey.get())) { + if (!ECDSA_verify(0, digest, 20, signature.data(), signature.size(), + eckey.get())) { fprintf(out, " failed\n"); return false; } fprintf(out, "."); fflush(out); // Verify the signature with the wrong key. - if (ECDSA_verify(0, digest, 20, bssl::vector_data(&signature), - signature.size(), wrong_eckey.get())) { + if (ECDSA_verify(0, digest, 20, signature.data(), signature.size(), + wrong_eckey.get())) { fprintf(out, " failed\n"); return false; } fprintf(out, "."); fflush(out); // Verify the signature using the wrong digest. - if (ECDSA_verify(0, wrong_digest, 20, bssl::vector_data(&signature), - signature.size(), eckey.get())) { + if (ECDSA_verify(0, wrong_digest, 20, signature.data(), signature.size(), + eckey.get())) { fprintf(out, " failed\n"); return false; } fprintf(out, "."); fflush(out); // Verify a truncated signature. - if (ECDSA_verify(0, digest, 20, bssl::vector_data(&signature), - signature.size() - 1, eckey.get())) { + if (ECDSA_verify(0, digest, 20, signature.data(), signature.size() - 1, + eckey.get())) { fprintf(out, " failed\n"); return false; } @@ -263,10 +254,10 @@ static bool TestBuiltin(FILE *out) { fflush(out); // Verify a tampered signature. ScopedECDSA_SIG ecdsa_sig(ECDSA_SIG_from_bytes( - bssl::vector_data(&signature), signature.size())); + signature.data(), signature.size())); if (!ecdsa_sig || !TestTamperedSig(out, kEncodedApi, digest, 20, ecdsa_sig.get(), - eckey.get(), order.get())) { + eckey.get(), order)) { fprintf(out, " failed\n"); return false; } @@ -305,7 +296,7 @@ static bool TestBuiltin(FILE *out) { fflush(out); // Verify a tampered signature. if (!TestTamperedSig(out, kRawApi, digest, 20, ecdsa_sig.get(), eckey.get(), - order.get())) { + order)) { fprintf(out, " failed\n"); return false; } @@ -327,8 +318,8 @@ static bool TestECDSA_SIG_max_len(size_t order_len) { return false; } std::vector<uint8_t> bytes(order_len, 0xff); - if (!BN_bin2bn(bssl::vector_data(&bytes), bytes.size(), sig->r) || - !BN_bin2bn(bssl::vector_data(&bytes), bytes.size(), sig->s)) { + if (!BN_bin2bn(bytes.data(), bytes.size(), sig->r) || + !BN_bin2bn(bytes.data(), bytes.size(), sig->s)) { return false; } /* Serialize it. */ diff --git a/src/crypto/err/asn1.errordata b/src/crypto/err/asn1.errordata index 55342a0..b1b0437 100644 --- a/src/crypto/err/asn1.errordata +++ b/src/crypto/err/asn1.errordata @@ -48,41 +48,40 @@ ASN1,146,INVALID_TIME_FORMAT ASN1,147,INVALID_UNIVERSALSTRING_LENGTH ASN1,148,INVALID_UTF8STRING ASN1,149,LIST_ERROR -ASN1,150,MALLOC_FAILURE -ASN1,151,MISSING_ASN1_EOS -ASN1,152,MISSING_EOC -ASN1,153,MISSING_SECOND_NUMBER -ASN1,154,MISSING_VALUE -ASN1,155,MSTRING_NOT_UNIVERSAL -ASN1,156,MSTRING_WRONG_TAG -ASN1,157,NESTED_ASN1_ERROR -ASN1,158,NESTED_ASN1_STRING -ASN1,159,NON_HEX_CHARACTERS -ASN1,160,NOT_ASCII_FORMAT -ASN1,161,NOT_ENOUGH_DATA -ASN1,162,NO_MATCHING_CHOICE_TYPE -ASN1,163,NULL_IS_WRONG_LENGTH -ASN1,164,OBJECT_NOT_ASCII_FORMAT -ASN1,165,ODD_NUMBER_OF_CHARS -ASN1,166,SECOND_NUMBER_TOO_LARGE -ASN1,167,SEQUENCE_LENGTH_MISMATCH -ASN1,168,SEQUENCE_NOT_CONSTRUCTED -ASN1,169,SEQUENCE_OR_SET_NEEDS_CONFIG -ASN1,170,SHORT_LINE -ASN1,171,STREAMING_NOT_SUPPORTED -ASN1,172,STRING_TOO_LONG -ASN1,173,STRING_TOO_SHORT -ASN1,174,TAG_VALUE_TOO_HIGH -ASN1,175,TIME_NOT_ASCII_FORMAT -ASN1,176,TOO_LONG -ASN1,177,TYPE_NOT_CONSTRUCTED -ASN1,178,TYPE_NOT_PRIMITIVE -ASN1,179,UNEXPECTED_EOC -ASN1,180,UNIVERSALSTRING_IS_WRONG_LENGTH -ASN1,181,UNKNOWN_FORMAT -ASN1,182,UNKNOWN_TAG -ASN1,183,UNSUPPORTED_ANY_DEFINED_BY_TYPE -ASN1,184,UNSUPPORTED_PUBLIC_KEY_TYPE -ASN1,185,UNSUPPORTED_TYPE -ASN1,186,WRONG_TAG -ASN1,187,WRONG_TYPE +ASN1,150,MISSING_ASN1_EOS +ASN1,151,MISSING_EOC +ASN1,152,MISSING_SECOND_NUMBER +ASN1,153,MISSING_VALUE +ASN1,154,MSTRING_NOT_UNIVERSAL +ASN1,155,MSTRING_WRONG_TAG +ASN1,156,NESTED_ASN1_ERROR +ASN1,157,NESTED_ASN1_STRING +ASN1,158,NON_HEX_CHARACTERS +ASN1,159,NOT_ASCII_FORMAT +ASN1,160,NOT_ENOUGH_DATA +ASN1,161,NO_MATCHING_CHOICE_TYPE +ASN1,162,NULL_IS_WRONG_LENGTH +ASN1,163,OBJECT_NOT_ASCII_FORMAT +ASN1,164,ODD_NUMBER_OF_CHARS +ASN1,165,SECOND_NUMBER_TOO_LARGE +ASN1,166,SEQUENCE_LENGTH_MISMATCH +ASN1,167,SEQUENCE_NOT_CONSTRUCTED +ASN1,168,SEQUENCE_OR_SET_NEEDS_CONFIG +ASN1,169,SHORT_LINE +ASN1,170,STREAMING_NOT_SUPPORTED +ASN1,171,STRING_TOO_LONG +ASN1,172,STRING_TOO_SHORT +ASN1,173,TAG_VALUE_TOO_HIGH +ASN1,174,TIME_NOT_ASCII_FORMAT +ASN1,175,TOO_LONG +ASN1,176,TYPE_NOT_CONSTRUCTED +ASN1,177,TYPE_NOT_PRIMITIVE +ASN1,178,UNEXPECTED_EOC +ASN1,179,UNIVERSALSTRING_IS_WRONG_LENGTH +ASN1,180,UNKNOWN_FORMAT +ASN1,181,UNKNOWN_TAG +ASN1,182,UNSUPPORTED_ANY_DEFINED_BY_TYPE +ASN1,183,UNSUPPORTED_PUBLIC_KEY_TYPE +ASN1,184,UNSUPPORTED_TYPE +ASN1,185,WRONG_TAG +ASN1,186,WRONG_TYPE diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata index 0b30b13..3766bb9 100644 --- a/src/crypto/err/ssl.errordata +++ b/src/crypto/err/ssl.errordata @@ -7,137 +7,111 @@ SSL,105,BAD_DH_P_LENGTH SSL,106,BAD_DIGEST_LENGTH SSL,107,BAD_ECC_CERT SSL,108,BAD_ECPOINT -SSL,109,BAD_HANDSHAKE_LENGTH -SSL,110,BAD_HANDSHAKE_RECORD -SSL,111,BAD_HELLO_REQUEST -SSL,112,BAD_LENGTH -SSL,113,BAD_PACKET_LENGTH -SSL,114,BAD_RSA_ENCRYPT -SSL,115,BAD_SIGNATURE -SSL,116,BAD_SRTP_MKI_VALUE -SSL,117,BAD_SRTP_PROTECTION_PROFILE_LIST -SSL,118,BAD_SSL_FILETYPE -SSL,119,BAD_WRITE_RETRY -SSL,120,BIO_NOT_SET -SSL,121,BN_LIB -SSL,272,BUFFER_TOO_SMALL -SSL,122,CANNOT_SERIALIZE_PUBLIC_KEY -SSL,123,CA_DN_LENGTH_MISMATCH -SSL,124,CA_DN_TOO_LONG -SSL,125,CCS_RECEIVED_EARLY -SSL,126,CERTIFICATE_VERIFY_FAILED -SSL,127,CERT_CB_ERROR -SSL,128,CERT_LENGTH_MISMATCH -SSL,129,CHANNEL_ID_NOT_P256 -SSL,130,CHANNEL_ID_SIGNATURE_INVALID -SSL,131,CIPHER_CODE_WRONG_LENGTH -SSL,132,CIPHER_OR_HASH_UNAVAILABLE -SSL,133,CLIENTHELLO_PARSE_FAILED -SSL,134,CLIENTHELLO_TLSEXT -SSL,135,CONNECTION_REJECTED -SSL,136,CONNECTION_TYPE_NOT_SET -SSL,137,COOKIE_MISMATCH -SSL,284,CUSTOM_EXTENSION_CONTENTS_TOO_LARGE -SSL,285,CUSTOM_EXTENSION_ERROR -SSL,138,D2I_ECDSA_SIG -SSL,139,DATA_BETWEEN_CCS_AND_FINISHED -SSL,140,DATA_LENGTH_TOO_LONG -SSL,141,DECODE_ERROR -SSL,142,DECRYPTION_FAILED -SSL,143,DECRYPTION_FAILED_OR_BAD_RECORD_MAC -SSL,144,DH_PUBLIC_VALUE_LENGTH_IS_WRONG -SSL,145,DIGEST_CHECK_FAILED -SSL,146,DTLS_MESSAGE_TOO_BIG -SSL,147,ECC_CERT_NOT_FOR_SIGNING -SSL,148,EMPTY_SRTP_PROTECTION_PROFILE_LIST -SSL,276,EMS_STATE_INCONSISTENT -SSL,149,ENCRYPTED_LENGTH_TOO_LONG -SSL,281,ERROR_ADDING_EXTENSION -SSL,150,ERROR_IN_RECEIVED_CIPHER_LIST -SSL,282,ERROR_PARSING_EXTENSION -SSL,151,EVP_DIGESTSIGNFINAL_FAILED -SSL,152,EVP_DIGESTSIGNINIT_FAILED -SSL,153,EXCESSIVE_MESSAGE_SIZE -SSL,154,EXTRA_DATA_IN_MESSAGE -SSL,271,FRAGMENT_MISMATCH -SSL,155,GOT_A_FIN_BEFORE_A_CCS -SSL,156,GOT_CHANNEL_ID_BEFORE_A_CCS -SSL,157,GOT_NEXT_PROTO_BEFORE_A_CCS -SSL,158,GOT_NEXT_PROTO_WITHOUT_EXTENSION -SSL,159,HANDSHAKE_FAILURE_ON_CLIENT_HELLO -SSL,160,HANDSHAKE_RECORD_BEFORE_CCS -SSL,161,HTTPS_PROXY_REQUEST -SSL,162,HTTP_REQUEST -SSL,163,INAPPROPRIATE_FALLBACK -SSL,164,INVALID_COMMAND -SSL,165,INVALID_MESSAGE -SSL,166,INVALID_SSL_SESSION -SSL,167,INVALID_TICKET_KEYS_LENGTH -SSL,168,LENGTH_MISMATCH -SSL,169,LIBRARY_HAS_NO_CIPHERS -SSL,170,MISSING_DH_KEY -SSL,171,MISSING_ECDSA_SIGNING_CERT -SSL,283,MISSING_EXTENSION -SSL,172,MISSING_RSA_CERTIFICATE -SSL,173,MISSING_RSA_ENCRYPTING_CERT -SSL,174,MISSING_RSA_SIGNING_CERT -SSL,175,MISSING_TMP_DH_KEY -SSL,176,MISSING_TMP_ECDH_KEY -SSL,177,MIXED_SPECIAL_OPERATOR_WITH_GROUPS -SSL,178,MTU_TOO_SMALL -SSL,286,NEGOTIATED_BOTH_NPN_AND_ALPN -SSL,179,NESTED_GROUP -SSL,180,NO_CERTIFICATES_RETURNED -SSL,181,NO_CERTIFICATE_ASSIGNED -SSL,182,NO_CERTIFICATE_SET -SSL,183,NO_CIPHERS_AVAILABLE -SSL,184,NO_CIPHERS_PASSED -SSL,185,NO_CIPHERS_SPECIFIED -SSL,186,NO_CIPHER_MATCH -SSL,187,NO_COMPRESSION_SPECIFIED -SSL,188,NO_METHOD_SPECIFIED -SSL,189,NO_P256_SUPPORT -SSL,190,NO_PRIVATE_KEY_ASSIGNED -SSL,191,NO_RENEGOTIATION -SSL,192,NO_REQUIRED_DIGEST -SSL,193,NO_SHARED_CIPHER -SSL,194,NO_SHARED_SIGATURE_ALGORITHMS -SSL,195,NO_SRTP_PROFILES -SSL,196,NULL_SSL_CTX -SSL,197,NULL_SSL_METHOD_PASSED -SSL,198,OLD_SESSION_CIPHER_NOT_RETURNED -SSL,273,OLD_SESSION_VERSION_NOT_RETURNED -SSL,274,OUTPUT_ALIASES_INPUT -SSL,199,PACKET_LENGTH_TOO_LONG -SSL,200,PARSE_TLSEXT -SSL,201,PATH_TOO_LONG -SSL,202,PEER_DID_NOT_RETURN_A_CERTIFICATE -SSL,203,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE -SSL,204,PROTOCOL_IS_SHUTDOWN -SSL,205,PSK_IDENTITY_NOT_FOUND -SSL,206,PSK_NO_CLIENT_CB -SSL,207,PSK_NO_SERVER_CB -SSL,208,READ_BIO_NOT_SET -SSL,209,READ_TIMEOUT_EXPIRED -SSL,210,RECORD_LENGTH_MISMATCH -SSL,211,RECORD_TOO_LARGE -SSL,212,RENEGOTIATE_EXT_TOO_LONG -SSL,213,RENEGOTIATION_ENCODING_ERR -SSL,214,RENEGOTIATION_MISMATCH -SSL,215,REQUIRED_CIPHER_MISSING -SSL,275,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION -SSL,277,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION -SSL,216,SCSV_RECEIVED_WHEN_RENEGOTIATING -SSL,217,SERVERHELLO_TLSEXT -SSL,218,SESSION_ID_CONTEXT_UNINITIALIZED -SSL,219,SESSION_MAY_NOT_BE_CREATED -SSL,220,SIGNATURE_ALGORITHMS_ERROR -SSL,280,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER -SSL,221,SRTP_COULD_NOT_ALLOCATE_PROFILES -SSL,222,SRTP_PROTECTION_PROFILE_LIST_TOO_LONG -SSL,223,SRTP_UNKNOWN_PROTECTION_PROFILE -SSL,224,SSL3_EXT_INVALID_SERVERNAME -SSL,225,SSL3_EXT_INVALID_SERVERNAME_TYPE +SSL,109,BAD_HANDSHAKE_RECORD +SSL,110,BAD_HELLO_REQUEST +SSL,111,BAD_LENGTH +SSL,112,BAD_PACKET_LENGTH +SSL,113,BAD_RSA_ENCRYPT +SSL,114,BAD_SIGNATURE +SSL,115,BAD_SRTP_MKI_VALUE +SSL,116,BAD_SRTP_PROTECTION_PROFILE_LIST +SSL,117,BAD_SSL_FILETYPE +SSL,118,BAD_WRITE_RETRY +SSL,119,BIO_NOT_SET +SSL,120,BN_LIB +SSL,121,BUFFER_TOO_SMALL +SSL,122,CA_DN_LENGTH_MISMATCH +SSL,123,CA_DN_TOO_LONG +SSL,124,CCS_RECEIVED_EARLY +SSL,125,CERTIFICATE_VERIFY_FAILED +SSL,126,CERT_CB_ERROR +SSL,127,CERT_LENGTH_MISMATCH +SSL,128,CHANNEL_ID_NOT_P256 +SSL,129,CHANNEL_ID_SIGNATURE_INVALID +SSL,130,CIPHER_OR_HASH_UNAVAILABLE +SSL,131,CLIENTHELLO_PARSE_FAILED +SSL,132,CLIENTHELLO_TLSEXT +SSL,133,CONNECTION_REJECTED +SSL,134,CONNECTION_TYPE_NOT_SET +SSL,135,CUSTOM_EXTENSION_ERROR +SSL,136,DATA_LENGTH_TOO_LONG +SSL,137,DECODE_ERROR +SSL,138,DECRYPTION_FAILED +SSL,139,DECRYPTION_FAILED_OR_BAD_RECORD_MAC +SSL,140,DH_PUBLIC_VALUE_LENGTH_IS_WRONG +SSL,141,DH_P_TOO_LONG +SSL,142,DIGEST_CHECK_FAILED +SSL,143,DTLS_MESSAGE_TOO_BIG +SSL,144,ECC_CERT_NOT_FOR_SIGNING +SSL,145,EMS_STATE_INCONSISTENT +SSL,146,ENCRYPTED_LENGTH_TOO_LONG +SSL,147,ERROR_ADDING_EXTENSION +SSL,148,ERROR_IN_RECEIVED_CIPHER_LIST +SSL,149,ERROR_PARSING_EXTENSION +SSL,150,EXCESSIVE_MESSAGE_SIZE +SSL,151,EXTRA_DATA_IN_MESSAGE +SSL,152,FRAGMENT_MISMATCH +SSL,153,GOT_NEXT_PROTO_WITHOUT_EXTENSION +SSL,154,HANDSHAKE_FAILURE_ON_CLIENT_HELLO +SSL,155,HTTPS_PROXY_REQUEST +SSL,156,HTTP_REQUEST +SSL,157,INAPPROPRIATE_FALLBACK +SSL,158,INVALID_COMMAND +SSL,159,INVALID_MESSAGE +SSL,160,INVALID_SSL_SESSION +SSL,161,INVALID_TICKET_KEYS_LENGTH +SSL,162,LENGTH_MISMATCH +SSL,163,LIBRARY_HAS_NO_CIPHERS +SSL,164,MISSING_EXTENSION +SSL,165,MISSING_RSA_CERTIFICATE +SSL,166,MISSING_TMP_DH_KEY +SSL,167,MISSING_TMP_ECDH_KEY +SSL,168,MIXED_SPECIAL_OPERATOR_WITH_GROUPS +SSL,169,MTU_TOO_SMALL +SSL,170,NEGOTIATED_BOTH_NPN_AND_ALPN +SSL,171,NESTED_GROUP +SSL,172,NO_CERTIFICATES_RETURNED +SSL,173,NO_CERTIFICATE_ASSIGNED +SSL,174,NO_CERTIFICATE_SET +SSL,175,NO_CIPHERS_AVAILABLE +SSL,176,NO_CIPHERS_PASSED +SSL,177,NO_CIPHER_MATCH +SSL,178,NO_COMPRESSION_SPECIFIED +SSL,179,NO_METHOD_SPECIFIED +SSL,180,NO_P256_SUPPORT +SSL,181,NO_PRIVATE_KEY_ASSIGNED +SSL,182,NO_RENEGOTIATION +SSL,183,NO_REQUIRED_DIGEST +SSL,184,NO_SHARED_CIPHER +SSL,185,NULL_SSL_CTX +SSL,186,NULL_SSL_METHOD_PASSED +SSL,187,OLD_SESSION_CIPHER_NOT_RETURNED +SSL,188,OLD_SESSION_VERSION_NOT_RETURNED +SSL,189,OUTPUT_ALIASES_INPUT +SSL,190,PARSE_TLSEXT +SSL,191,PATH_TOO_LONG +SSL,192,PEER_DID_NOT_RETURN_A_CERTIFICATE +SSL,193,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE +SSL,194,PROTOCOL_IS_SHUTDOWN +SSL,195,PSK_IDENTITY_NOT_FOUND +SSL,196,PSK_NO_CLIENT_CB +SSL,197,PSK_NO_SERVER_CB +SSL,198,READ_TIMEOUT_EXPIRED +SSL,199,RECORD_LENGTH_MISMATCH +SSL,200,RECORD_TOO_LARGE +SSL,201,RENEGOTIATION_ENCODING_ERR +SSL,202,RENEGOTIATION_MISMATCH +SSL,203,REQUIRED_CIPHER_MISSING +SSL,204,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION +SSL,205,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION +SSL,206,SCSV_RECEIVED_WHEN_RENEGOTIATING +SSL,207,SERVERHELLO_TLSEXT +SSL,208,SESSION_ID_CONTEXT_UNINITIALIZED +SSL,209,SESSION_MAY_NOT_BE_CREATED +SSL,210,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER +SSL,211,SRTP_COULD_NOT_ALLOCATE_PROFILES +SSL,212,SRTP_UNKNOWN_PROTECTION_PROFILE +SSL,213,SSL3_EXT_INVALID_SERVERNAME SSL,1042,SSLV3_ALERT_BAD_CERTIFICATE SSL,1020,SSLV3_ALERT_BAD_RECORD_MAC SSL,1045,SSLV3_ALERT_CERTIFICATE_EXPIRED @@ -150,12 +124,9 @@ SSL,1047,SSLV3_ALERT_ILLEGAL_PARAMETER SSL,1041,SSLV3_ALERT_NO_CERTIFICATE SSL,1010,SSLV3_ALERT_UNEXPECTED_MESSAGE SSL,1043,SSLV3_ALERT_UNSUPPORTED_CERTIFICATE -SSL,226,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION -SSL,227,SSL_HANDSHAKE_FAILURE -SSL,228,SSL_SESSION_ID_CALLBACK_FAILED -SSL,229,SSL_SESSION_ID_CONFLICT -SSL,230,SSL_SESSION_ID_CONTEXT_TOO_LONG -SSL,231,SSL_SESSION_ID_HAS_BAD_LENGTH +SSL,214,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION +SSL,215,SSL_HANDSHAKE_FAILURE +SSL,216,SSL_SESSION_ID_CONTEXT_TOO_LONG SSL,1049,TLSV1_ALERT_ACCESS_DENIED SSL,1050,TLSV1_ALERT_DECODE_ERROR SSL,1021,TLSV1_ALERT_DECRYPTION_FAILED @@ -174,44 +145,36 @@ SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE SSL,1112,TLSV1_UNRECOGNIZED_NAME SSL,1110,TLSV1_UNSUPPORTED_EXTENSION -SSL,232,TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER -SSL,233,TLS_ILLEGAL_EXPORTER_LABEL -SSL,234,TLS_INVALID_ECPOINTFORMAT_LIST -SSL,235,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST -SSL,236,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG -SSL,237,TOO_MANY_EMPTY_FRAGMENTS -SSL,278,TOO_MANY_WARNING_ALERTS -SSL,238,UNABLE_TO_FIND_ECDH_PARAMETERS -SSL,239,UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS -SSL,279,UNEXPECTED_EXTENSION -SSL,240,UNEXPECTED_GROUP_CLOSE -SSL,241,UNEXPECTED_MESSAGE -SSL,242,UNEXPECTED_OPERATOR_IN_GROUP -SSL,243,UNEXPECTED_RECORD -SSL,244,UNINITIALIZED -SSL,245,UNKNOWN_ALERT_TYPE -SSL,246,UNKNOWN_CERTIFICATE_TYPE -SSL,247,UNKNOWN_CIPHER_RETURNED -SSL,248,UNKNOWN_CIPHER_TYPE -SSL,249,UNKNOWN_DIGEST -SSL,250,UNKNOWN_KEY_EXCHANGE_TYPE -SSL,251,UNKNOWN_PROTOCOL -SSL,252,UNKNOWN_SSL_VERSION -SSL,253,UNKNOWN_STATE -SSL,254,UNPROCESSED_HANDSHAKE_DATA -SSL,255,UNSAFE_LEGACY_RENEGOTIATION_DISABLED -SSL,256,UNSUPPORTED_CIPHER -SSL,257,UNSUPPORTED_COMPRESSION_ALGORITHM -SSL,258,UNSUPPORTED_ELLIPTIC_CURVE -SSL,259,UNSUPPORTED_PROTOCOL -SSL,260,UNSUPPORTED_SSL_VERSION -SSL,261,USE_SRTP_NOT_NEGOTIATED -SSL,262,WRONG_CERTIFICATE_TYPE -SSL,263,WRONG_CIPHER_RETURNED -SSL,264,WRONG_CURVE -SSL,265,WRONG_MESSAGE_TYPE -SSL,266,WRONG_SIGNATURE_TYPE -SSL,267,WRONG_SSL_VERSION -SSL,268,WRONG_VERSION_NUMBER -SSL,269,X509_LIB -SSL,270,X509_VERIFICATION_SETUP_PROBLEMS +SSL,217,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST +SSL,218,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG +SSL,219,TOO_MANY_EMPTY_FRAGMENTS +SSL,220,TOO_MANY_WARNING_ALERTS +SSL,221,UNABLE_TO_FIND_ECDH_PARAMETERS +SSL,222,UNEXPECTED_EXTENSION +SSL,223,UNEXPECTED_MESSAGE +SSL,224,UNEXPECTED_OPERATOR_IN_GROUP +SSL,225,UNEXPECTED_RECORD +SSL,226,UNINITIALIZED +SSL,227,UNKNOWN_ALERT_TYPE +SSL,228,UNKNOWN_CERTIFICATE_TYPE +SSL,229,UNKNOWN_CIPHER_RETURNED +SSL,230,UNKNOWN_CIPHER_TYPE +SSL,231,UNKNOWN_DIGEST +SSL,232,UNKNOWN_KEY_EXCHANGE_TYPE +SSL,233,UNKNOWN_PROTOCOL +SSL,234,UNKNOWN_SSL_VERSION +SSL,235,UNKNOWN_STATE +SSL,236,UNSAFE_LEGACY_RENEGOTIATION_DISABLED +SSL,237,UNSUPPORTED_CIPHER +SSL,238,UNSUPPORTED_COMPRESSION_ALGORITHM +SSL,239,UNSUPPORTED_ELLIPTIC_CURVE +SSL,240,UNSUPPORTED_PROTOCOL +SSL,241,WRONG_CERTIFICATE_TYPE +SSL,242,WRONG_CIPHER_RETURNED +SSL,243,WRONG_CURVE +SSL,244,WRONG_MESSAGE_TYPE +SSL,245,WRONG_SIGNATURE_TYPE +SSL,246,WRONG_SSL_VERSION +SSL,247,WRONG_VERSION_NUMBER +SSL,248,X509_LIB +SSL,249,X509_VERIFICATION_SETUP_PROBLEMS diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c index 5822379..afe5c38 100644 --- a/src/crypto/evp/evp.c +++ b/src/crypto/evp/evp.c @@ -60,7 +60,6 @@ #include <string.h> #include <openssl/bio.h> -#include <openssl/dh.h> #include <openssl/dsa.h> #include <openssl/ec.h> #include <openssl/err.h> @@ -73,10 +72,6 @@ #include "../internal.h" -extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth; - EVP_PKEY *EVP_PKEY_new(void) { EVP_PKEY *ret; @@ -235,15 +230,22 @@ int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key); } -RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) { +RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_RSA) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); return NULL; } - RSA_up_ref(pkey->pkey.rsa); return pkey->pkey.rsa; } +RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) { + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa != NULL) { + RSA_up_ref(rsa); + } + return rsa; +} + int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { if (EVP_PKEY_assign_DSA(pkey, key)) { DSA_up_ref(key); @@ -256,15 +258,22 @@ int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key); } -DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) { +DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_DSA) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); return NULL; } - DSA_up_ref(pkey->pkey.dsa); return pkey->pkey.dsa; } +DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) { + DSA *dsa = EVP_PKEY_get0_DSA(pkey); + if (dsa != NULL) { + DSA_up_ref(dsa); + } + return dsa; +} + int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { if (EVP_PKEY_assign_EC_KEY(pkey, key)) { EC_KEY_up_ref(key); @@ -277,34 +286,20 @@ int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key); } -EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) { +EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_EC) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); return NULL; } - EC_KEY_up_ref(pkey->pkey.ec); return pkey->pkey.ec; } -int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) { - if (EVP_PKEY_assign_DH(pkey, key)) { - DH_up_ref(key); - return 1; - } - return 0; -} - -int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) { - return EVP_PKEY_assign(pkey, EVP_PKEY_DH, key); -} - -DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_DH) { - OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY); - return NULL; +EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) { + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + if (ec_key != NULL) { + EC_KEY_up_ref(ec_key); } - DH_up_ref(pkey->pkey.dh); - return pkey->pkey.dh; + return ec_key; } int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c index a8e71fe..9e038cd 100644 --- a/src/crypto/evp/evp_ctx.c +++ b/src/crypto/evp/evp_ctx.c @@ -66,9 +66,6 @@ #include "internal.h" -extern const EVP_PKEY_METHOD rsa_pkey_meth; -extern const EVP_PKEY_METHOD ec_pkey_meth; - static const EVP_PKEY_METHOD *const evp_methods[] = { &rsa_pkey_meth, &ec_pkey_meth, diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc index bd70040..fe7a002 100644 --- a/src/crypto/evp/evp_extra_test.cc +++ b/src/crypto/evp/evp_extra_test.cc @@ -16,6 +16,7 @@ #include <stdio.h> #include <stdlib.h> +#include <utility> #include <vector> #include <openssl/bytestring.h> @@ -233,6 +234,85 @@ static const uint8_t kExamplePSSCert[] = { 0x8c, 0x16, }; +// kBadPSSCert is an example RSA-PSS certificate with bad parameters. +static const uint8_t kBadPSSCert[] = { + 0x30, 0x82, 0x03, 0x76, 0x30, 0x82, 0x02, 0x3a, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0xd7, 0x30, 0x64, 0xbc, 0x9f, 0x12, 0xfe, 0xc3, + 0x30, 0x3e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0a, 0x30, 0x31, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x04, + 0x02, 0x02, 0x00, 0xde, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x35, 0x31, 0x31, 0x30, 0x34, 0x31, 0x36, 0x30, 0x32, 0x33, + 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x32, 0x30, 0x34, 0x31, 0x36, + 0x30, 0x32, 0x33, 0x35, 0x5a, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xda, 0x33, 0xb5, 0x87, + 0xa9, 0x50, 0x80, 0x18, 0x02, 0x00, 0xfb, 0x32, 0xf5, 0x29, 0x6b, 0xef, + 0x01, 0x24, 0xeb, 0x86, 0x5a, 0xbe, 0xd5, 0xe3, 0xdd, 0x3b, 0xbc, 0x2c, + 0xad, 0x65, 0xf6, 0x2a, 0x26, 0x28, 0x4d, 0x8a, 0xc9, 0x61, 0x39, 0xf1, + 0x84, 0xb9, 0xe7, 0xd3, 0x0a, 0xc7, 0xa8, 0x0a, 0x6d, 0xef, 0xd9, 0xcb, + 0x20, 0x11, 0xbb, 0x71, 0xf4, 0xa1, 0xc9, 0x9a, 0x85, 0x1c, 0xe6, 0x3f, + 0x23, 0x39, 0x58, 0x3c, 0xc5, 0x6d, 0xfa, 0x03, 0xe8, 0xdb, 0xdd, 0xe0, + 0xc3, 0xde, 0x85, 0x76, 0xce, 0x49, 0x06, 0xc8, 0xe1, 0x8e, 0x4c, 0x86, + 0x9c, 0xec, 0xab, 0xf4, 0xe5, 0x27, 0xb4, 0x5a, 0xaf, 0xc4, 0x36, 0xd3, + 0x20, 0x81, 0x54, 0xee, 0x8f, 0x48, 0x77, 0x10, 0xf8, 0x79, 0xd6, 0xaa, + 0x8d, 0x1b, 0xfe, 0x7d, 0xe8, 0x15, 0x13, 0xe0, 0x7b, 0xf6, 0x90, 0xe4, + 0xe2, 0xcd, 0x2e, 0x8e, 0xc9, 0x3a, 0x75, 0x42, 0xed, 0x0a, 0x0f, 0x51, + 0xb2, 0xdd, 0x2e, 0x70, 0x61, 0x68, 0xd7, 0xd9, 0xab, 0xf9, 0xbe, 0xe4, + 0x75, 0xb7, 0xe7, 0xf2, 0x96, 0x7b, 0xd9, 0x93, 0x43, 0x24, 0xfb, 0x9e, + 0x55, 0xda, 0xd4, 0x01, 0x6c, 0x3d, 0xa2, 0x59, 0x7a, 0xd5, 0x47, 0x18, + 0x7e, 0x4e, 0xf9, 0x5d, 0xda, 0xcb, 0x93, 0xa2, 0x65, 0x2f, 0x8d, 0x46, + 0xad, 0x81, 0xdc, 0xf0, 0xa9, 0x5f, 0x5d, 0xfe, 0x37, 0x80, 0x64, 0x2a, + 0x41, 0xfa, 0xe9, 0x1e, 0x48, 0x38, 0x22, 0x1d, 0x9c, 0x23, 0xa5, 0xad, + 0xda, 0x78, 0x45, 0x18, 0x0c, 0xeb, 0x95, 0xca, 0x2b, 0xcc, 0xb9, 0x62, + 0x40, 0x85, 0x09, 0x44, 0x88, 0x4c, 0xf2, 0x1e, 0x08, 0x80, 0x37, 0xe9, + 0x06, 0x96, 0x8f, 0x75, 0x54, 0x0b, 0xa9, 0x2d, 0xa9, 0x15, 0xb5, 0xda, + 0xe5, 0xe4, 0x23, 0xaa, 0x2c, 0x89, 0xc1, 0xa9, 0x36, 0xbc, 0x9f, 0x02, + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78, + 0xa0, 0x65, 0x2d, 0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6, + 0xe1, 0x5f, 0x7b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78, 0xa0, 0x65, 0x2d, + 0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6, 0xe1, 0x5f, 0x7b, + 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, + 0x01, 0xff, 0x30, 0x31, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0a, 0x30, 0x24, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x0d, 0x30, 0x0b, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0xa2, + 0x04, 0x02, 0x02, 0x00, 0xde, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0xc1, + 0xb6, 0x6f, 0x74, 0x94, 0x6c, 0x60, 0x75, 0xd8, 0xdc, 0xe1, 0x7b, 0xbf, + 0x9d, 0xb5, 0xd7, 0x14, 0x75, 0x6c, 0xdb, 0x35, 0x5c, 0x1e, 0xff, 0xe6, + 0xa8, 0xe6, 0x68, 0x42, 0x41, 0x81, 0xf6, 0xbf, 0xc1, 0x56, 0x02, 0xdb, + 0xc6, 0x11, 0xeb, 0x15, 0x9d, 0xa9, 0x1c, 0x61, 0x25, 0x6d, 0x46, 0x0f, + 0x7e, 0x27, 0xdd, 0x4b, 0xdc, 0xed, 0x07, 0xbd, 0xde, 0xd5, 0xde, 0x09, + 0xf8, 0xfd, 0xbd, 0xa3, 0x4c, 0x81, 0xa9, 0xf7, 0x78, 0xff, 0x01, 0x80, + 0x73, 0xf2, 0x40, 0xf2, 0xa8, 0x27, 0xe8, 0x00, 0x04, 0x3b, 0xf5, 0xe7, + 0xa6, 0x58, 0x45, 0x79, 0x34, 0x49, 0x42, 0xd2, 0xd9, 0x56, 0x5e, 0xf9, + 0x0a, 0x41, 0xd7, 0x81, 0x41, 0x94, 0x77, 0x78, 0x7e, 0x00, 0x3b, 0xca, + 0xb5, 0xc0, 0x6e, 0x5b, 0xd7, 0x52, 0x52, 0x77, 0x1a, 0x52, 0xb8, 0x0d, + 0x29, 0x1f, 0x2e, 0xfe, 0x1f, 0xf6, 0xb0, 0xc1, 0xb7, 0xf1, 0x15, 0x98, + 0x0f, 0x30, 0x5d, 0x74, 0x2f, 0xfa, 0xe9, 0x84, 0xda, 0xde, 0xbe, 0xca, + 0x91, 0x55, 0x1f, 0x5b, 0xbc, 0xaa, 0x45, 0x07, 0xc4, 0x2e, 0x21, 0x8a, + 0x75, 0xc9, 0xbe, 0x6e, 0x39, 0x53, 0x10, 0xcb, 0x2f, 0x4b, 0xe1, 0x21, + 0x1e, 0xea, 0x7d, 0x0b, 0x36, 0xe9, 0xa0, 0x2c, 0x76, 0x17, 0x1f, 0x69, + 0x34, 0xfb, 0x45, 0x63, 0x7c, 0x84, 0x39, 0xb4, 0x21, 0x98, 0xbd, 0x49, + 0xca, 0x80, 0x91, 0x5a, 0xa0, 0x44, 0xef, 0x91, 0xb3, 0x14, 0xf6, 0xd1, + 0x6a, 0x2b, 0xb1, 0xe5, 0x4a, 0x44, 0x92, 0x7b, 0x3e, 0x8b, 0x7b, 0x6b, + 0x90, 0x6b, 0x2c, 0x67, 0x3b, 0x0e, 0xb9, 0x5a, 0x87, 0x35, 0x33, 0x59, + 0x94, 0x2f, 0x7e, 0xf6, 0x13, 0xc7, 0x22, 0x87, 0x3d, 0x50, 0xc9, 0x80, + 0x40, 0xda, 0x35, 0xbc, 0x62, 0x16, 0xdc, 0xd5, 0x95, 0xa1, 0xe1, 0x9b, + 0x68, 0x9f, +}; + // kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8 // PrivateKeyInfo. static const uint8_t kExampleRSAKeyPKCS8[] = { @@ -342,6 +422,22 @@ static const uint8_t kExampleBadECKeyDER2[] = { 0x07, }; +// kInvalidPrivateKey is an invalid private key. See +// https://rt.openssl.org/Ticket/Display.html?id=4131. +static const uint8_t kInvalidPrivateKey[] = { + 0x30, 0x39, 0x02, 0x01, 0x02, 0x30, 0x09, 0x06, 0x01, 0x38, 0x08, + 0x04, 0x69, 0x30, 0x30, 0x80, 0x30, 0x19, 0x01, 0x02, 0x9f, 0xf8, + 0x8b, 0x29, 0x80, 0x30, 0xb0, 0x1b, 0x06, 0x09, 0x22, 0xbe, 0x08, + 0x04, 0xe9, 0x30, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x3a, 0x01, 0x80, + 0x09, 0x30, 0x80, 0x06, 0x01, 0x02, 0x30, 0x80, 0x30, 0x01, 0x3b, + 0x02, 0x00, 0x00, 0x04, 0x20, 0x30, 0x82, 0x04, 0xe9, 0x30, 0xc3, + 0xe8, 0x30, 0x01, 0x05, 0x30, 0x80, 0x30, 0x01, 0x3b, 0x01, 0x04, + 0x02, 0x02, 0xff, 0x00, 0x30, 0x29, 0x02, 0x11, 0x03, 0x29, 0x29, + 0x02, 0x00, 0x99, 0x30, 0x80, 0x06, 0x21, 0x02, 0x24, 0x04, 0xe8, + 0x30, 0x01, 0x01, 0x04, 0x30, 0x80, 0x1b, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x30, 0x01, 0xaa, 0x02, 0x86, 0xc0, 0x30, 0xdf, 0xe9, 0x80, +}; + static ScopedEVP_PKEY LoadExampleRSAKey() { ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER))); @@ -376,16 +472,17 @@ static bool TestEVP_DigestSignInit(void) { std::vector<uint8_t> sig; sig.resize(sig_len); - if (!EVP_DigestSignFinal(md_ctx.get(), bssl::vector_data(&sig), &sig_len)) { + if (!EVP_DigestSignFinal(md_ctx.get(), sig.data(), &sig_len)) { return false; } sig.resize(sig_len); // Ensure that the signature round-trips. md_ctx.Reset(); - if (!EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) || + if (!EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL, + pkey.get()) || !EVP_DigestVerifyUpdate(md_ctx.get(), kMsg, sizeof(kMsg)) || - !EVP_DigestVerifyFinal(md_ctx.get(), bssl::vector_data(&sig), sig_len)) { + !EVP_DigestVerifyFinal(md_ctx.get(), sig.data(), sig_len)) { return false; } @@ -432,7 +529,7 @@ static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) { std::vector<uint8_t> sig; sig.resize(sig_len); - if (!EVP_DigestSignFinal(md_ctx, bssl::vector_data(&sig), &sig_len)) { + if (!EVP_DigestSignFinal(md_ctx, sig.data(), &sig_len)) { return false; } sig.resize(sig_len); @@ -442,8 +539,7 @@ static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) { if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx_verify.get(), algor.get(), pkey) || !EVP_DigestVerifyUpdate(md_ctx_verify.get(), kMsg, sizeof(kMsg)) || - !EVP_DigestVerifyFinal(md_ctx_verify.get(), bssl::vector_data(&sig), - sig_len)) { + !EVP_DigestVerifyFinal(md_ctx_verify.get(), sig.data(), sig_len)) { return false; } @@ -477,16 +573,52 @@ static bool TestEVP_DigestSignAlgorithm(void) { return true; } -static bool TestEVP_DigestVerifyInitFromAlgorithm(void) { - CBS cert, cert_body, tbs_cert, algorithm, signature; - CBS_init(&cert, kExamplePSSCert, sizeof(kExamplePSSCert)); - if (!CBS_get_asn1(&cert, &cert_body, CBS_ASN1_SEQUENCE) || - CBS_len(&cert) != 0 || +static bool ParseCertificate(CBS *out_tbs_cert, + ScopedEVP_PKEY *out_pubkey, + ScopedX509_ALGOR *out_algor, + CBS *out_signature, + const CBS *in_) { + CBS in = *in_; + CBS cert_body, tbs_cert, algorithm, signature; + if (!CBS_get_asn1(&in, &cert_body, CBS_ASN1_SEQUENCE) || + CBS_len(&in) != 0 || !CBS_get_any_asn1_element(&cert_body, &tbs_cert, NULL, NULL) || !CBS_get_asn1_element(&cert_body, &algorithm, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) || CBS_len(&cert_body) != 0) { - fprintf(stderr, "Failed to parse certificate\n"); + return false; + } + + CBS tbs_cert_copy = tbs_cert; + CBS tbs_cert_body, discard, spki; + if (!CBS_get_asn1(&tbs_cert_copy, &tbs_cert_body, CBS_ASN1_SEQUENCE) || + CBS_len(&tbs_cert_copy) != 0 || + !CBS_get_optional_asn1( + &tbs_cert_body, &discard, NULL, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + !CBS_get_asn1(&tbs_cert_body, &discard /* serialNumber */, + CBS_ASN1_INTEGER) || + !CBS_get_asn1(&tbs_cert_body, &discard /* signature */, + CBS_ASN1_SEQUENCE) || + !CBS_get_any_asn1_element(&tbs_cert_body, &discard /* issuer */, + NULL, NULL) || + !CBS_get_asn1(&tbs_cert_body, &discard /* validity */, + CBS_ASN1_SEQUENCE) || + !CBS_get_any_asn1_element(&tbs_cert_body, &discard /* subject */, + NULL, NULL) || + !CBS_get_asn1_element(&tbs_cert_body, &spki, CBS_ASN1_SEQUENCE)) { + return false; + } + + const uint8_t *derp = CBS_data(&spki); + ScopedEVP_PKEY pubkey(d2i_PUBKEY(NULL, &derp, CBS_len(&spki))); + if (!pubkey || derp != CBS_data(&spki) + CBS_len(&spki)) { + return false; + } + + derp = CBS_data(&algorithm); + ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm))); + if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) { return false; } @@ -494,21 +626,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) { // leading phase byte is just a zero. uint8_t padding; if (!CBS_get_u8(&signature, &padding) || padding != 0) { - fprintf(stderr, "Invalid signature padding\n"); return false; } - const uint8_t *derp = CBS_data(&algorithm); - ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm))); - if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) { - fprintf(stderr, "Failed to parse algorithm\n"); + *out_tbs_cert = tbs_cert; + *out_pubkey = std::move(pubkey); + *out_algor = std::move(algor); + *out_signature = signature; + return true; +} + +static bool TestEVP_DigestVerifyInitFromAlgorithm(void) { + CBS in, tbs_cert, signature; + ScopedEVP_PKEY pkey; + ScopedX509_ALGOR algor; + CBS_init(&in, kExamplePSSCert, sizeof(kExamplePSSCert)); + if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) { + fprintf(stderr, "Failed to parse certificate\n"); return false; } - ScopedEVP_PKEY pkey = LoadExampleRSAKey(); ScopedEVP_MD_CTX md_ctx; - if (!pkey || - !EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(), + if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(), pkey.get()) || !EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_cert), CBS_len(&tbs_cert)) || @@ -519,8 +658,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) { return true; } -static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len, - int expected_id) { +static bool TestBadPSSParameters(void) { + CBS in, tbs_cert, signature; + ScopedEVP_PKEY pkey; + ScopedX509_ALGOR algor; + CBS_init(&in, kBadPSSCert, sizeof(kBadPSSCert)); + if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) { + fprintf(stderr, "Failed to parse certificate\n"); + return false; + } + + ScopedEVP_MD_CTX md_ctx; + if (EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(), + pkey.get())) { + fprintf(stderr, "Unexpectedly processed bad signature parameters\n"); + return false; + } + ERR_clear_error(); + return true; +} + +static bool TestValidPrivateKey(const uint8_t *input, size_t input_len, + int expected_id) { const uint8_t *p = input; ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, input_len)); if (!pkey || p != input + input_len) { @@ -536,6 +695,42 @@ static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len, return true; } +static bool Testd2i_AutoPrivateKey() { + if (!TestValidPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), + EVP_PKEY_RSA)) { + fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n"); + return false; + } + + if (!TestValidPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8), + EVP_PKEY_RSA)) { + fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n"); + return false; + } + + if (!TestValidPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER), + EVP_PKEY_EC)) { + fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n"); + return false; + } + + if (!TestValidPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER), + EVP_PKEY_DSA)) { + fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n"); + return false; + } + + const uint8_t *p = kInvalidPrivateKey; + ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey))); + if (pkey) { + fprintf(stderr, "Parsed invalid private key\n"); + return false; + } + ERR_clear_error(); + + return true; +} + // TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format. static bool TestEVP_PKCS82PKEY(void) { const uint8_t *derp = kExampleBadECKeyDER; @@ -602,7 +797,7 @@ static bool Testd2i_PrivateKey(void) { // Copy the input into a |malloc|'d vector to flag memory errors. std::vector<uint8_t> copy(kExampleBadECKeyDER2, kExampleBadECKeyDER2 + sizeof(kExampleBadECKeyDER2)); - derp = bssl::vector_data(©); + derp = copy.data(); pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp, copy.size())); if (pkey) { fprintf(stderr, "Imported invalid EC key #2.\n"); @@ -641,30 +836,14 @@ int main(void) { return 1; } - if (!Testd2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), - EVP_PKEY_RSA)) { - fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n"); - ERR_print_errors_fp(stderr); - return 1; - } - - if (!Testd2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8), - EVP_PKEY_RSA)) { - fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n"); + if (!TestBadPSSParameters()) { + fprintf(stderr, "TestBadPSSParameters failed\n"); ERR_print_errors_fp(stderr); return 1; } - if (!Testd2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER), - EVP_PKEY_EC)) { - fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n"); - ERR_print_errors_fp(stderr); - return 1; - } - - if (!Testd2i_AutoPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER), - EVP_PKEY_DSA)) { - fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n"); + if (!Testd2i_AutoPrivateKey()) { + fprintf(stderr, "Testd2i_AutoPrivateKey failed\n"); ERR_print_errors_fp(stderr); return 1; } diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc index c7ac908..7fedc15 100644 --- a/src/crypto/evp/evp_test.cc +++ b/src/crypto/evp/evp_test.cc @@ -78,7 +78,6 @@ #include "../test/file_test.h" #include "../test/scoped_types.h" -#include "../test/stl_compat.h" // evp_test dispatches between multiple test types. PrivateKey tests take a key @@ -179,8 +178,8 @@ static bool TestEVP(FileTest *t, void *arg) { } if (t->GetType() == "Verify") { - if (!EVP_PKEY_verify(ctx.get(), bssl::vector_data(&output), output.size(), - bssl::vector_data(&input), input.size())) { + if (!EVP_PKEY_verify(ctx.get(), output.data(), output.size(), input.data(), + input.size())) { // ECDSA sometimes doesn't push an error code. Push one on the error queue // so it's distinguishable from other errors. OPENSSL_PUT_ERROR(USER, ERR_R_EVP_LIB); @@ -191,18 +190,15 @@ static bool TestEVP(FileTest *t, void *arg) { size_t len; std::vector<uint8_t> actual; - if (!key_op(ctx.get(), nullptr, &len, bssl::vector_data(&input), - input.size())) { + if (!key_op(ctx.get(), nullptr, &len, input.data(), input.size())) { return false; } actual.resize(len); - if (!key_op(ctx.get(), bssl::vector_data(&actual), &len, - bssl::vector_data(&input), input.size())) { + if (!key_op(ctx.get(), actual.data(), &len, input.data(), input.size())) { return false; } actual.resize(len); - if (!t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), - bssl::vector_data(&actual), len)) { + if (!t->ExpectBytesEqual(output.data(), output.size(), actual.data(), len)) { return false; } return true; diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h index 60881e3..aa52d53 100644 --- a/src/crypto/evp/internal.h +++ b/src/crypto/evp/internal.h @@ -263,6 +263,13 @@ struct evp_pkey_method_st { int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); } /* EVP_PKEY_METHOD */; +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth; + +extern const EVP_PKEY_METHOD rsa_pkey_meth; +extern const EVP_PKEY_METHOD ec_pkey_meth; + #if defined(__cplusplus) } /* extern C */ diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c index c583e0f..f40b976 100644 --- a/src/crypto/evp/p_ec_asn1.c +++ b/src/crypto/evp/p_ec_asn1.c @@ -337,23 +337,12 @@ static int int_ec_size(const EVP_PKEY *pkey) { } static int ec_bits(const EVP_PKEY *pkey) { - BIGNUM *order = BN_new(); - const EC_GROUP *group; - int ret; - - if (!order) { + const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec); + if (group == NULL) { ERR_clear_error(); return 0; } - group = EC_KEY_get0_group(pkey->pkey.ec); - if (!EC_GROUP_get_order(group, order, NULL)) { - ERR_clear_error(); - return 0; - } - - ret = BN_num_bits(order); - BN_free(order); - return ret; + return BN_num_bits(EC_GROUP_get0_order(group)); } static int ec_missing_parameters(const EVP_PKEY *pkey) { @@ -387,7 +376,6 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { const char *ecstr; size_t buf_len = 0, i; int ret = 0, reason = ERR_R_BIO_LIB; - BIGNUM *order = NULL; BN_CTX *ctx = NULL; const EC_GROUP *group; const EC_POINT *public_key; @@ -458,9 +446,8 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { if (!BIO_indent(bp, off, 128)) { goto err; } - order = BN_new(); - if (order == NULL || !EC_GROUP_get_order(group, order, NULL) || - BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) { + const BIGNUM *order = EC_GROUP_get0_order(group); + if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) { goto err; } @@ -482,7 +469,6 @@ err: OPENSSL_PUT_ERROR(EVP, reason); } OPENSSL_free(pub_key_bytes); - BN_free(order); BN_CTX_free(ctx); OPENSSL_free(buffer); return ret; diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c index cfecbfd..895d351 100644 --- a/src/crypto/evp/p_rsa.c +++ b/src/crypto/evp/p_rsa.c @@ -456,8 +456,6 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } OPENSSL_free(rctx->oaep_label); if (p2 && p1 > 0) { - /* TODO(fork): this seems wrong. Shouldn't it take a copy of the - * buffer? */ rctx->oaep_label = p2; rctx->oaep_labellen = p1; } else { diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c index f60625b..db38d5c 100644 --- a/src/crypto/evp/p_rsa_asn1.c +++ b/src/crypto/evp/p_rsa_asn1.c @@ -303,7 +303,7 @@ static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) { const uint8_t *p; int plen; - if (alg == NULL || + if (alg == NULL || alg->parameter == NULL || OBJ_obj2nid(alg->algorithm) != NID_mgf1 || alg->parameter->type != V_ASN1_SEQUENCE) { return NULL; diff --git a/src/crypto/ex_data.c b/src/crypto/ex_data.c index f562f17..8fa1240 100644 --- a/src/crypto/ex_data.c +++ b/src/crypto/ex_data.c @@ -124,14 +124,12 @@ struct crypto_ex_data_func_st { long argl; /* Arbitary long */ void *argp; /* Arbitary void pointer */ - CRYPTO_EX_new *new_func; CRYPTO_EX_free *free_func; CRYPTO_EX_dup *dup_func; }; int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index, - long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, + long argl, void *argp, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { CRYPTO_EX_DATA_FUNCS *funcs; int ret = 0; @@ -144,7 +142,6 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index, funcs->argl = argl; funcs->argp = argp; - funcs->new_func = new_func; funcs->dup_func = dup_func; funcs->free_func = free_func; @@ -230,46 +227,24 @@ static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out, return 1; } -int CRYPTO_new_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj, - CRYPTO_EX_DATA *ad) { - STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers; - size_t i; - +void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad) { ad->sk = NULL; - - if (!get_func_pointers(&func_pointers, ex_data_class)) { - return 0; - } - - for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) { - CRYPTO_EX_DATA_FUNCS *func_pointer = - sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i); - if (func_pointer->new_func) { - func_pointer->new_func(obj, NULL, ad, i + ex_data_class->num_reserved, - func_pointer->argl, func_pointer->argp); - } - } - - sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers); - - return 1; } int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from) { - STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers; - size_t i; - - if (!from->sk) { + if (from->sk == NULL) { /* In this case, |from| is blank, which is also the initial state of |to|, * so there's nothing to do. */ return 1; } + STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers; if (!get_func_pointers(&func_pointers, ex_data_class)) { return 0; } + size_t i; for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) { CRYPTO_EX_DATA_FUNCS *func_pointer = sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i); @@ -288,13 +263,18 @@ int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to, void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj, CRYPTO_EX_DATA *ad) { - STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers; - size_t i; + if (ad->sk == NULL) { + /* Nothing to do. */ + return; + } + STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers; if (!get_func_pointers(&func_pointers, ex_data_class)) { + /* TODO(davidben): This leaks memory on malloc error. */ return; } + size_t i; for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) { CRYPTO_EX_DATA_FUNCS *func_pointer = sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i); diff --git a/src/crypto/header_removed.h b/src/crypto/header_removed.h deleted file mode 100644 index 49ee31a..0000000 --- a/src/crypto/header_removed.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright (c) 2014, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -/* This header is linked to under the names of several headers that have been - * removed. It's possible to put a #error in here in order to catch that an - * clean up older code. */ diff --git a/src/crypto/hmac/hmac.c b/src/crypto/hmac/hmac.c index d37a249..be2dcce 100644 --- a/src/crypto/hmac/hmac.c +++ b/src/crypto/hmac/hmac.c @@ -129,7 +129,7 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, return 0; } } else { - assert(key_len >= 0 && key_len <= sizeof(key_block)); + assert(key_len <= sizeof(key_block)); memcpy(key_block, key, key_len); key_block_len = (unsigned)key_len; } diff --git a/src/crypto/hmac/hmac_test.cc b/src/crypto/hmac/hmac_test.cc index d438b70..da390ef 100644 --- a/src/crypto/hmac/hmac_test.cc +++ b/src/crypto/hmac/hmac_test.cc @@ -66,7 +66,6 @@ #include "../test/file_test.h" #include "../test/scoped_types.h" -#include "../test/stl_compat.h" static const EVP_MD *GetDigest(const std::string &name) { @@ -107,33 +106,28 @@ static bool TestHMAC(FileTest *t, void *arg) { // Test using the one-shot API. uint8_t mac[EVP_MAX_MD_SIZE]; unsigned mac_len; - if (nullptr == HMAC(digest, bssl::vector_data(&key), key.size(), - bssl::vector_data(&input), input.size(), mac, - &mac_len) || - !t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), mac, - mac_len)) { + if (nullptr == HMAC(digest, key.data(), key.size(), input.data(), + input.size(), mac, &mac_len) || + !t->ExpectBytesEqual(output.data(), output.size(), mac, mac_len)) { t->PrintLine("One-shot API failed."); return false; } // Test using HMAC_CTX. ScopedHMAC_CTX ctx; - if (!HMAC_Init_ex(ctx.get(), bssl::vector_data(&key), key.size(), digest, - nullptr) || - !HMAC_Update(ctx.get(), bssl::vector_data(&input), input.size()) || + if (!HMAC_Init_ex(ctx.get(), key.data(), key.size(), digest, nullptr) || + !HMAC_Update(ctx.get(), input.data(), input.size()) || !HMAC_Final(ctx.get(), mac, &mac_len) || - !t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), mac, - mac_len)) { + !t->ExpectBytesEqual(output.data(), output.size(), mac, mac_len)) { t->PrintLine("HMAC_CTX failed."); return false; } // Test that an HMAC_CTX may be reset with the same key. if (!HMAC_Init_ex(ctx.get(), nullptr, 0, digest, nullptr) || - !HMAC_Update(ctx.get(), bssl::vector_data(&input), input.size()) || + !HMAC_Update(ctx.get(), input.data(), input.size()) || !HMAC_Final(ctx.get(), mac, &mac_len) || - !t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), mac, - mac_len)) { + !t->ExpectBytesEqual(output.data(), output.size(), mac, mac_len)) { t->PrintLine("HMAC_CTX with reset failed."); return false; } @@ -150,8 +144,7 @@ static bool TestHMAC(FileTest *t, void *arg) { } } if (!HMAC_Final(ctx.get(), mac, &mac_len) || - !t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), mac, - mac_len)) { + !t->ExpectBytesEqual(output.data(), output.size(), mac, mac_len)) { t->PrintLine("HMAC_CTX streaming failed."); return false; } diff --git a/src/crypto/internal.h b/src/crypto/internal.h index 713659d..bf45349 100644 --- a/src/crypto/internal.h +++ b/src/crypto/internal.h @@ -168,18 +168,6 @@ extern "C" { #endif -#if defined(_MSC_VER) -#define OPENSSL_U64(x) x##UI64 -#else - -#if defined(OPENSSL_64_BIT) -#define OPENSSL_U64(x) x##UL -#else -#define OPENSSL_U64(x) x##ULL -#endif - -#endif /* defined(_MSC_VER) */ - #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \ defined(OPENSSL_AARCH64) /* OPENSSL_cpuid_setup initializes OPENSSL_ia32cap_P. */ @@ -509,8 +497,7 @@ typedef struct { * zero otherwise. */ OPENSSL_EXPORT int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index, long argl, - void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, + void *argp, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); /* CRYPTO_set_ex_data sets an extra data pointer on a given object. Each class @@ -522,11 +509,8 @@ OPENSSL_EXPORT int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val); * function. */ OPENSSL_EXPORT void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index); -/* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA| which is - * embedded inside of |obj| which is of class |ex_data_class|. Returns one on - * success and zero otherwise. */ -OPENSSL_EXPORT int CRYPTO_new_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, - void *obj, CRYPTO_EX_DATA *ad); +/* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA|. */ +OPENSSL_EXPORT void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad); /* CRYPTO_dup_ex_data duplicates |from| into a freshly allocated * |CRYPTO_EX_DATA|, |to|. Both of which are inside objects of the given diff --git a/src/crypto/md4/md4.c b/src/crypto/md4/md4.c index 0a8ea1d..86a540b 100644 --- a/src/crypto/md4/md4.c +++ b/src/crypto/md4/md4.c @@ -84,13 +84,13 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num); do { \ uint32_t ll; \ ll = (c)->h[0]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[1]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[2]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[3]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ } while (0) #define HASH_BLOCK_DATA_ORDER md4_block_data_order @@ -103,6 +103,8 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num); #define G(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) #define H(b, c, d) ((b) ^ (c) ^ (d)) +#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + #define R0(a, b, c, d, k, s, t) \ { \ a += ((k) + (t)+F((b), (c), (d))); \ diff --git a/src/crypto/md5/md5.c b/src/crypto/md5/md5.c index f27e62d..66483b8 100644 --- a/src/crypto/md5/md5.c +++ b/src/crypto/md5/md5.c @@ -106,13 +106,13 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num); do { \ uint32_t ll; \ ll = (c)->h[0]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[1]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[2]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[3]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ } while (0) #define HASH_BLOCK_DATA_ORDER md5_block_data_order @@ -127,6 +127,8 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num); #define H(b,c,d) ((b) ^ (c) ^ (d)) #define I(b,c,d) (((~(d)) | (b)) ^ (c)) +#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + #define R0(a,b,c,d,k,s,t) { \ a+=((k)+(t)+F((b),(c),(d))); \ a=ROTATE(a,s); \ diff --git a/src/crypto/modes/asm/ghash-armv4.pl b/src/crypto/modes/asm/ghash-armv4.pl index df33be5..d328822 100644 --- a/src/crypto/modes/asm/ghash-armv4.pl +++ b/src/crypto/modes/asm/ghash-armv4.pl @@ -140,7 +140,7 @@ $code=<<___; .text .code 32 -#ifdef __APPLE__ +#ifdef __clang__ #define ldrplb ldrbpl #define ldrneb ldrbne #endif diff --git a/src/crypto/modes/gcm.c b/src/crypto/modes/gcm.c index 8aac741..65451a6 100644 --- a/src/crypto/modes/gcm.c +++ b/src/crypto/modes/gcm.c @@ -55,7 +55,6 @@ #include <openssl/cpu.h> #include "internal.h" -#include "../internal.h" #if !defined(OPENSSL_NO_ASM) && \ @@ -76,7 +75,7 @@ #define REDUCE1BIT(V) \ do { \ if (sizeof(size_t) == 8) { \ - uint64_t T = OPENSSL_U64(0xe100000000000000) & (0 - (V.lo & 1)); \ + uint64_t T = UINT64_C(0xe100000000000000) & (0 - (V.lo & 1)); \ V.lo = (V.hi << 63) | (V.lo >> 1); \ V.hi = (V.hi >> 1) ^ T; \ } else { \ @@ -586,7 +585,7 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) { } alen += len; - if (alen > (OPENSSL_U64(1) << 61) || (sizeof(len) == 8 && alen < len)) { + if (alen > (UINT64_C(1) << 61) || (sizeof(len) == 8 && alen < len)) { return 0; } ctx->len.u[0] = alen; @@ -653,7 +652,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key, #endif mlen += len; - if (mlen > ((OPENSSL_U64(1) << 36) - 32) || + if (mlen > ((UINT64_C(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) { return 0; } @@ -813,7 +812,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key, #endif mlen += len; - if (mlen > ((OPENSSL_U64(1) << 36) - 32) || + if (mlen > ((UINT64_C(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) { return 0; } @@ -978,7 +977,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key, #endif mlen += len; - if (mlen > ((OPENSSL_U64(1) << 36) - 32) || + if (mlen > ((UINT64_C(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) { return 0; } @@ -1087,7 +1086,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key, #endif mlen += len; - if (mlen > ((OPENSSL_U64(1) << 36) - 32) || + if (mlen > ((UINT64_C(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) { return 0; } diff --git a/src/crypto/obj/obj_dat.h b/src/crypto/obj/obj_dat.h index 517dc49..bf44c6d 100644 --- a/src/crypto/obj/obj_dat.h +++ b/src/crypto/obj/obj_dat.h @@ -58,9 +58,9 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -#define NUM_NID 948 -#define NUM_SN 940 -#define NUM_LN 940 +#define NUM_NID 949 +#define NUM_SN 941 +#define NUM_LN 941 #define NUM_OBJ 882 static const unsigned char lvalues[6176]={ @@ -2482,6 +2482,7 @@ static const ASN1_OBJECT kObjects[NUM_NID]={ NID_dhSinglePass_cofactorDH_sha512kdf_scheme,6,&(lvalues[6169]),0}, {"dh-std-kdf","dh-std-kdf",NID_dh_std_kdf,0,NULL,0}, {"dh-cofactor-kdf","dh-cofactor-kdf",NID_dh_cofactor_kdf,0,NULL,0}, +{"X25519","x25519",NID_x25519,0,NULL,0}, }; static const unsigned int kNIDsInShortNameOrder[NUM_SN]={ @@ -2668,6 +2669,7 @@ static const unsigned int kNIDsInShortNameOrder[NUM_SN]={ 143, /* "SXNetID" */ 458, /* "UID" */ 0, /* "UNDEF" */ +948, /* "X25519" */ 11, /* "X500" */ 378, /* "X500algorithms" */ 12, /* "X509" */ @@ -4364,6 +4366,7 @@ static const unsigned int kNIDsInLongNameOrder[NUM_LN]={ 742, /* "wap-wsg-idm-ecid-wtls9" */ 804, /* "whirlpool" */ 868, /* "x121Address" */ +948, /* "x25519" */ 503, /* "x500UniqueIdentifier" */ 158, /* "x509Certificate" */ 160, /* "x509Crl" */ diff --git a/src/crypto/obj/obj_mac.num b/src/crypto/obj/obj_mac.num index e143ece..a0e09b8 100644 --- a/src/crypto/obj/obj_mac.num +++ b/src/crypto/obj/obj_mac.num @@ -945,3 +945,4 @@ dhSinglePass_cofactorDH_sha384kdf_scheme 944 dhSinglePass_cofactorDH_sha512kdf_scheme 945 dh_std_kdf 946 dh_cofactor_kdf 947 +x25519 948 diff --git a/src/crypto/obj/objects.txt b/src/crypto/obj/objects.txt index 2757c4f..93cf53a 100644 --- a/src/crypto/obj/objects.txt +++ b/src/crypto/obj/objects.txt @@ -1330,3 +1330,6 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme # NIDs for use with lookup tables. : dh-std-kdf : dh-cofactor-kdf + +# NID for X25519 (no corresponding OID). + : X25519 : x25519 diff --git a/src/crypto/pem/pem_all.c b/src/crypto/pem/pem_all.c index 24ecc62..c9f8b6e 100644 --- a/src/crypto/pem/pem_all.c +++ b/src/crypto/pem/pem_all.c @@ -247,12 +247,6 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, return pkey_get_eckey(pktmp, key); /* will free pktmp */ } -/* TODO(fork): remove this code? */ -/* IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters) */ - - - - IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey) @@ -274,8 +268,4 @@ EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) -/* TODO(fork): remove this code? */ -/* IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) */ - - IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/src/crypto/pem/pem_lib.c b/src/crypto/pem/pem_lib.c index 5915696..12d9674 100644 --- a/src/crypto/pem/pem_lib.c +++ b/src/crypto/pem/pem_lib.c @@ -188,10 +188,6 @@ static int check_pem(const char *nm, const char *name) } return 0; } - /* If reading DH parameters handle X9.42 DH format too */ - if(!strcmp(nm,PEM_STRING_DHXPARAMS) && - !strcmp(name,PEM_STRING_DHPARAMS)) return 1; - /* Permit older strings */ if(!strcmp(nm,PEM_STRING_X509_OLD) && diff --git a/src/crypto/pem/pem_pkey.c b/src/crypto/pem/pem_pkey.c index c462727..cd334b4 100644 --- a/src/crypto/pem/pem_pkey.c +++ b/src/crypto/pem/pem_pkey.c @@ -280,11 +280,7 @@ DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) return NULL; p = data; - /* TODO(fork): remove? */ - /*if (!strcmp(nm, PEM_STRING_DHXPARAMS)) - ret = d2i_DHxparams(x, &p, len); - else */ - ret = d2i_DHparams(x, &p, len); + ret = d2i_DHparams(x, &p, len); if (ret == NULL) OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); diff --git a/src/crypto/pkcs8/pkcs8.c b/src/crypto/pkcs8/pkcs8.c index c097881..31a34a7 100644 --- a/src/crypto/pkcs8/pkcs8.c +++ b/src/crypto/pkcs8/pkcs8.c @@ -773,13 +773,14 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth, goto err; } - if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data) { + if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data || + CBS_len(&ai) > LONG_MAX) { OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); goto err; } inp = CBS_data(&ai); - algor = d2i_X509_ALGOR(NULL, &inp, CBS_len(&ai)); + algor = d2i_X509_ALGOR(NULL, &inp, (long)CBS_len(&ai)); if (algor == NULL) { goto err; } @@ -822,9 +823,14 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth, goto err; } + if (CBS_len(&wrapped_contents) > LONG_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + /* encrypted isn't actually an X.509 signature, but it has the same * structure as one and so |X509_SIG| is reused to store it. */ - encrypted = d2i_X509_SIG(NULL, &inp, CBS_len(&wrapped_contents)); + encrypted = d2i_X509_SIG(NULL, &inp, (long)CBS_len(&wrapped_contents)); if (encrypted == NULL) { OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); goto err; @@ -861,8 +867,12 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth, } if (OBJ_cbs2nid(&cert_type) == NID_x509Certificate) { + if (CBS_len(&cert) > LONG_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } const uint8_t *inp = CBS_data(&cert); - X509 *x509 = d2i_X509(NULL, &inp, CBS_len(&cert)); + X509 *x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert)); if (!x509) { OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); goto err; diff --git a/src/crypto/poly1305/poly1305_test.cc b/src/crypto/poly1305/poly1305_test.cc index 0526075..3a72668 100644 --- a/src/crypto/poly1305/poly1305_test.cc +++ b/src/crypto/poly1305/poly1305_test.cc @@ -21,7 +21,6 @@ #include <openssl/poly1305.h> #include "../test/file_test.h" -#include "../test/stl_compat.h" // |CRYPTO_poly1305_finish| requires a 16-byte-aligned output. @@ -46,22 +45,22 @@ static bool TestPoly1305(FileTest *t, void *arg) { // Test single-shot operation. poly1305_state state; - CRYPTO_poly1305_init(&state, bssl::vector_data(&key)); - CRYPTO_poly1305_update(&state, bssl::vector_data(&in), in.size()); + CRYPTO_poly1305_init(&state, key.data()); + CRYPTO_poly1305_update(&state, in.data(), in.size()); ALIGNED uint8_t out[16]; CRYPTO_poly1305_finish(&state, out); - if (!t->ExpectBytesEqual(out, 16, bssl::vector_data(&mac), mac.size())) { + if (!t->ExpectBytesEqual(out, 16, mac.data(), mac.size())) { t->PrintLine("Single-shot Poly1305 failed."); return false; } // Test streaming byte-by-byte. - CRYPTO_poly1305_init(&state, bssl::vector_data(&key)); + CRYPTO_poly1305_init(&state, key.data()); for (size_t i = 0; i < in.size(); i++) { CRYPTO_poly1305_update(&state, &in[i], 1); } CRYPTO_poly1305_finish(&state, out); - if (!t->ExpectBytesEqual(out, 16, bssl::vector_data(&mac), mac.size())) { + if (!t->ExpectBytesEqual(out, 16, mac.data(), mac.size())) { t->PrintLine("Streaming Poly1305 failed."); return false; } diff --git a/src/crypto/rand/rand.c b/src/crypto/rand/rand.c index 8b11728..892b4ba 100644 --- a/src/crypto/rand/rand.c +++ b/src/crypto/rand/rand.c @@ -192,7 +192,12 @@ int RAND_pseudo_bytes(uint8_t *buf, size_t len) { return RAND_bytes(buf, len); } -void RAND_seed(const void *buf, int num) {} +void RAND_seed(const void *buf, int num) { + /* OpenSSH calls |RAND_seed| before jailing on the assumption that any needed + * file descriptors etc will be opened. */ + uint8_t unused; + RAND_bytes(&unused, sizeof(unused)); +} int RAND_load_file(const char *path, long num) { if (num < 0) { /* read the "whole file" */ diff --git a/src/crypto/rand/urandom.c b/src/crypto/rand/urandom.c index 1cc5260..5bf5c73 100644 --- a/src/crypto/rand/urandom.c +++ b/src/crypto/rand/urandom.c @@ -83,11 +83,15 @@ static void init_once(void) { int flags = fcntl(fd, F_GETFD); if (flags == -1) { - abort(); - } - flags |= FD_CLOEXEC; - if (fcntl(fd, F_SETFD, flags) == -1) { - abort(); + /* Native Client doesn't implement |fcntl|. */ + if (errno != ENOSYS) { + abort(); + } + } else { + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) { + abort(); + } } urandom_fd = fd; } diff --git a/src/crypto/rc4/CMakeLists.txt b/src/crypto/rc4/CMakeLists.txt index a208e96..151773a 100644 --- a/src/crypto/rc4/CMakeLists.txt +++ b/src/crypto/rc4/CMakeLists.txt @@ -5,7 +5,6 @@ if (${ARCH} STREQUAL "x86_64") RC4_ARCH_SOURCES rc4-x86_64.${ASM_EXT} - rc4-md5-x86_64.${ASM_EXT} ) endif() @@ -27,5 +26,4 @@ add_library( ) perlasm(rc4-x86_64.${ASM_EXT} asm/rc4-x86_64.pl) -perlasm(rc4-md5-x86_64.${ASM_EXT} asm/rc4-md5-x86_64.pl) perlasm(rc4-586.${ASM_EXT} asm/rc4-586.pl) diff --git a/src/crypto/rc4/asm/rc4-md5-x86_64.pl b/src/crypto/rc4/asm/rc4-md5-x86_64.pl deleted file mode 100644 index 272fa91..0000000 --- a/src/crypto/rc4/asm/rc4-md5-x86_64.pl +++ /dev/null @@ -1,632 +0,0 @@ -#!/usr/bin/env perl -# -# ==================================================================== -# Written by Andy Polyakov <appro@openssl.org> 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/. -# ==================================================================== - -# June 2011 -# -# This is RC4+MD5 "stitch" implementation. The idea, as spelled in -# http://download.intel.com/design/intarch/papers/323686.pdf, is that -# since both algorithms exhibit instruction-level parallelism, ILP, -# below theoretical maximum, interleaving them would allow to utilize -# processor resources better and achieve better performance. RC4 -# instruction sequence is virtually identical to rc4-x86_64.pl, which -# is heavily based on submission by Maxim Perminov, Maxim Locktyukhin -# and Jim Guilford of Intel. MD5 is fresh implementation aiming to -# minimize register usage, which was used as "main thread" with RC4 -# weaved into it, one RC4 round per one MD5 round. In addition to the -# stiched subroutine the script can generate standalone replacement -# md5_block_asm_data_order and RC4. Below are performance numbers in -# cycles per processed byte, less is better, for these the standalone -# subroutines, sum of them, and stitched one: -# -# RC4 MD5 RC4+MD5 stitch gain -# Opteron 6.5(*) 5.4 11.9 7.0 +70%(*) -# Core2 6.5 5.8 12.3 7.7 +60% -# Westmere 4.3 5.2 9.5 7.0 +36% -# Sandy Bridge 4.2 5.5 9.7 6.8 +43% -# Atom 9.3 6.5 15.8 11.1 +42% -# -# (*) rc4-x86_64.pl delivers 5.3 on Opteron, so real improvement -# is +53%... - -my ($rc4,$md5)=(1,1); # what to generate? -my $D="#" if (!$md5); # if set to "#", MD5 is stitched into RC4(), - # but its result is discarded. Idea here is - # to be able to use 'openssl speed rc4' for - # benchmarking the stitched subroutine... - -my $flavour = shift; -my $output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } - -my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; -( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or -( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or -die "can't locate x86_64-xlate.pl"; - -open OUT,"| \"$^X\" $xlate $flavour $output"; -*STDOUT=*OUT; - -my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs); - -if ($rc4 && !$md5) { - ($dat,$len,$in0,$out) = ("%rdi","%rsi","%rdx","%rcx"); - $func="RC4"; $nargs=4; -} elsif ($md5 && !$rc4) { - ($ctx,$inp,$len) = ("%rdi","%rsi","%rdx"); - $func="md5_block_asm_data_order"; $nargs=3; -} else { - ($dat,$in0,$out,$ctx,$inp,$len) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9"); - $func="rc4_md5_enc"; $nargs=6; - # void rc4_md5_enc( - # RC4_KEY *key, # - # const void *in0, # RC4 input - # void *out, # RC4 output - # MD5_CTX *ctx, # - # const void *inp, # MD5 input - # size_t len); # number of 64-byte blocks -} - -my @K=( 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee, - 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501, - 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be, - 0x6b901122,0xfd987193,0xa679438e,0x49b40821, - - 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa, - 0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8, - 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed, - 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a, - - 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c, - 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70, - 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05, - 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665, - - 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039, - 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1, - 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1, - 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 ); - -my @V=("%r8d","%r9d","%r10d","%r11d"); # MD5 registers -my $tmp="%r12d"; - -my @XX=("%rbp","%rsi"); # RC4 registers -my @TX=("%rax","%rbx"); -my $YY="%rcx"; -my $TY="%rdx"; - -my $MOD=32; # 16, 32 or 64 - -$code.=<<___; -.text -.align 16 - -.globl $func -.type $func,\@function,$nargs -$func: - cmp \$0,$len - je .Labort - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 - sub \$40,%rsp -.Lbody: -___ -if ($rc4) { -$code.=<<___; -$D#md5# mov $ctx,%r11 # reassign arguments - mov $len,%r12 - mov $in0,%r13 - mov $out,%r14 -$D#md5# mov $inp,%r15 -___ - $ctx="%r11" if ($md5); # reassign arguments - $len="%r12"; - $in0="%r13"; - $out="%r14"; - $inp="%r15" if ($md5); - $inp=$in0 if (!$md5); -$code.=<<___; - xor $XX[0],$XX[0] - xor $YY,$YY - - lea 8($dat),$dat - mov -8($dat),$XX[0]#b - mov -4($dat),$YY#b - - inc $XX[0]#b - sub $in0,$out - movl ($dat,$XX[0],4),$TX[0]#d -___ -$code.=<<___ if (!$md5); - xor $TX[1],$TX[1] - test \$-128,$len - jz .Loop1 - sub $XX[0],$TX[1] - and \$`$MOD-1`,$TX[1] - jz .Loop${MOD}_is_hot - sub $TX[1],$len -.Loop${MOD}_warmup: - add $TX[0]#b,$YY#b - movl ($dat,$YY,4),$TY#d - movl $TX[0]#d,($dat,$YY,4) - movl $TY#d,($dat,$XX[0],4) - add $TY#b,$TX[0]#b - inc $XX[0]#b - movl ($dat,$TX[0],4),$TY#d - movl ($dat,$XX[0],4),$TX[0]#d - xorb ($in0),$TY#b - movb $TY#b,($out,$in0) - lea 1($in0),$in0 - dec $TX[1] - jnz .Loop${MOD}_warmup - - mov $YY,$TX[1] - xor $YY,$YY - mov $TX[1]#b,$YY#b - -.Loop${MOD}_is_hot: - mov $len,32(%rsp) # save original $len - shr \$6,$len # number of 64-byte blocks -___ - if ($D && !$md5) { # stitch in dummy MD5 - $md5=1; - $ctx="%r11"; - $inp="%r15"; - $code.=<<___; - mov %rsp,$ctx - mov $in0,$inp -___ - } -} -$code.=<<___; -#rc4# add $TX[0]#b,$YY#b -#rc4# lea ($dat,$XX[0],4),$XX[1] - shl \$6,$len - add $inp,$len # pointer to the end of input - mov $len,16(%rsp) - -#md5# mov $ctx,24(%rsp) # save pointer to MD5_CTX -#md5# mov 0*4($ctx),$V[0] # load current hash value from MD5_CTX -#md5# mov 1*4($ctx),$V[1] -#md5# mov 2*4($ctx),$V[2] -#md5# mov 3*4($ctx),$V[3] - jmp .Loop - -.align 16 -.Loop: -#md5# mov $V[0],0*4(%rsp) # put aside current hash value -#md5# mov $V[1],1*4(%rsp) -#md5# mov $V[2],2*4(%rsp) -#md5# mov $V[3],$tmp # forward reference -#md5# mov $V[3],3*4(%rsp) -___ - -sub R0 { - my ($i,$a,$b,$c,$d)=@_; - my @rot0=(7,12,17,22); - my $j=$i%16; - my $k=$i%$MOD; - my $xmm="%xmm".($j&1); - $code.=" movdqu ($in0),%xmm2\n" if ($rc4 && $j==15); - $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1); - $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1); - $code.=<<___; -#rc4# movl ($dat,$YY,4),$TY#d -#md5# xor $c,$tmp -#rc4# movl $TX[0]#d,($dat,$YY,4) -#md5# and $b,$tmp -#md5# add 4*`$j`($inp),$a -#rc4# add $TY#b,$TX[0]#b -#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d -#md5# add \$$K[$i],$a -#md5# xor $d,$tmp -#rc4# movz $TX[0]#b,$TX[0]#d -#rc4# movl $TY#d,4*$k($XX[1]) -#md5# add $tmp,$a -#rc4# add $TX[1]#b,$YY#b -#md5# rol \$$rot0[$j%4],$a -#md5# mov `$j==15?"$b":"$c"`,$tmp # forward reference -#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n -#md5# add $b,$a -___ - $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1); - mov $YY,$XX[1] - xor $YY,$YY # keyword to partial register - mov $XX[1]#b,$YY#b - lea ($dat,$XX[0],4),$XX[1] -___ - $code.=<<___ if ($rc4 && $j==15); - psllq \$8,%xmm1 - pxor %xmm0,%xmm2 - pxor %xmm1,%xmm2 -___ -} -sub R1 { - my ($i,$a,$b,$c,$d)=@_; - my @rot1=(5,9,14,20); - my $j=$i%16; - my $k=$i%$MOD; - my $xmm="%xmm".($j&1); - $code.=" movdqu 16($in0),%xmm3\n" if ($rc4 && $j==15); - $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1); - $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1); - $code.=<<___; -#rc4# movl ($dat,$YY,4),$TY#d -#md5# xor $b,$tmp -#rc4# movl $TX[0]#d,($dat,$YY,4) -#md5# and $d,$tmp -#md5# add 4*`((1+5*$j)%16)`($inp),$a -#rc4# add $TY#b,$TX[0]#b -#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d -#md5# add \$$K[$i],$a -#md5# xor $c,$tmp -#rc4# movz $TX[0]#b,$TX[0]#d -#rc4# movl $TY#d,4*$k($XX[1]) -#md5# add $tmp,$a -#rc4# add $TX[1]#b,$YY#b -#md5# rol \$$rot1[$j%4],$a -#md5# mov `$j==15?"$c":"$b"`,$tmp # forward reference -#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n -#md5# add $b,$a -___ - $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1); - mov $YY,$XX[1] - xor $YY,$YY # keyword to partial register - mov $XX[1]#b,$YY#b - lea ($dat,$XX[0],4),$XX[1] -___ - $code.=<<___ if ($rc4 && $j==15); - psllq \$8,%xmm1 - pxor %xmm0,%xmm3 - pxor %xmm1,%xmm3 -___ -} -sub R2 { - my ($i,$a,$b,$c,$d)=@_; - my @rot2=(4,11,16,23); - my $j=$i%16; - my $k=$i%$MOD; - my $xmm="%xmm".($j&1); - $code.=" movdqu 32($in0),%xmm4\n" if ($rc4 && $j==15); - $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1); - $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1); - $code.=<<___; -#rc4# movl ($dat,$YY,4),$TY#d -#md5# xor $c,$tmp -#rc4# movl $TX[0]#d,($dat,$YY,4) -#md5# xor $b,$tmp -#md5# add 4*`((5+3*$j)%16)`($inp),$a -#rc4# add $TY#b,$TX[0]#b -#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d -#md5# add \$$K[$i],$a -#rc4# movz $TX[0]#b,$TX[0]#d -#md5# add $tmp,$a -#rc4# movl $TY#d,4*$k($XX[1]) -#rc4# add $TX[1]#b,$YY#b -#md5# rol \$$rot2[$j%4],$a -#md5# mov `$j==15?"\\\$-1":"$c"`,$tmp # forward reference -#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n -#md5# add $b,$a -___ - $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1); - mov $YY,$XX[1] - xor $YY,$YY # keyword to partial register - mov $XX[1]#b,$YY#b - lea ($dat,$XX[0],4),$XX[1] -___ - $code.=<<___ if ($rc4 && $j==15); - psllq \$8,%xmm1 - pxor %xmm0,%xmm4 - pxor %xmm1,%xmm4 -___ -} -sub R3 { - my ($i,$a,$b,$c,$d)=@_; - my @rot3=(6,10,15,21); - my $j=$i%16; - my $k=$i%$MOD; - my $xmm="%xmm".($j&1); - $code.=" movdqu 48($in0),%xmm5\n" if ($rc4 && $j==15); - $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1); - $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1); - $code.=<<___; -#rc4# movl ($dat,$YY,4),$TY#d -#md5# xor $d,$tmp -#rc4# movl $TX[0]#d,($dat,$YY,4) -#md5# or $b,$tmp -#md5# add 4*`((7*$j)%16)`($inp),$a -#rc4# add $TY#b,$TX[0]#b -#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d -#md5# add \$$K[$i],$a -#rc4# movz $TX[0]#b,$TX[0]#d -#md5# xor $c,$tmp -#rc4# movl $TY#d,4*$k($XX[1]) -#md5# add $tmp,$a -#rc4# add $TX[1]#b,$YY#b -#md5# rol \$$rot3[$j%4],$a -#md5# mov \$-1,$tmp # forward reference -#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n -#md5# add $b,$a -___ - $code.=<<___ if ($rc4 && $j==15); - mov $XX[0],$XX[1] - xor $XX[0],$XX[0] # keyword to partial register - mov $XX[1]#b,$XX[0]#b - mov $YY,$XX[1] - xor $YY,$YY # keyword to partial register - mov $XX[1]#b,$YY#b - lea ($dat,$XX[0],4),$XX[1] - psllq \$8,%xmm1 - pxor %xmm0,%xmm5 - pxor %xmm1,%xmm5 -___ -} - -my $i=0; -for(;$i<16;$i++) { R0($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); } -for(;$i<32;$i++) { R1($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); } -for(;$i<48;$i++) { R2($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); } -for(;$i<64;$i++) { R3($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); } - -$code.=<<___; -#md5# add 0*4(%rsp),$V[0] # accumulate hash value -#md5# add 1*4(%rsp),$V[1] -#md5# add 2*4(%rsp),$V[2] -#md5# add 3*4(%rsp),$V[3] - -#rc4# movdqu %xmm2,($out,$in0) # write RC4 output -#rc4# movdqu %xmm3,16($out,$in0) -#rc4# movdqu %xmm4,32($out,$in0) -#rc4# movdqu %xmm5,48($out,$in0) -#md5# lea 64($inp),$inp -#rc4# lea 64($in0),$in0 - cmp 16(%rsp),$inp # are we done? - jb .Loop - -#md5# mov 24(%rsp),$len # restore pointer to MD5_CTX -#rc4# sub $TX[0]#b,$YY#b # correct $YY -#md5# mov $V[0],0*4($len) # write MD5_CTX -#md5# mov $V[1],1*4($len) -#md5# mov $V[2],2*4($len) -#md5# mov $V[3],3*4($len) -___ -$code.=<<___ if ($rc4 && (!$md5 || $D)); - mov 32(%rsp),$len # restore original $len - and \$63,$len # remaining bytes - jnz .Loop1 - jmp .Ldone - -.align 16 -.Loop1: - add $TX[0]#b,$YY#b - movl ($dat,$YY,4),$TY#d - movl $TX[0]#d,($dat,$YY,4) - movl $TY#d,($dat,$XX[0],4) - add $TY#b,$TX[0]#b - inc $XX[0]#b - movl ($dat,$TX[0],4),$TY#d - movl ($dat,$XX[0],4),$TX[0]#d - xorb ($in0),$TY#b - movb $TY#b,($out,$in0) - lea 1($in0),$in0 - dec $len - jnz .Loop1 - -.Ldone: -___ -$code.=<<___; -#rc4# sub \$1,$XX[0]#b -#rc4# movl $XX[0]#d,-8($dat) -#rc4# movl $YY#d,-4($dat) - - mov 40(%rsp),%r15 - mov 48(%rsp),%r14 - mov 56(%rsp),%r13 - mov 64(%rsp),%r12 - mov 72(%rsp),%rbp - mov 80(%rsp),%rbx - lea 88(%rsp),%rsp -.Lepilogue: -.Labort: - ret -.size $func,.-$func -___ - -if ($rc4 && $D) { # sole purpose of this section is to provide - # option to use the generated module as drop-in - # replacement for rc4-x86_64.pl for debugging - # and testing purposes... -my ($idx,$ido)=("%r8","%r9"); -my ($dat,$len,$inp)=("%rdi","%rsi","%rdx"); - -$code.=<<___; -.globl RC4_set_key -.type RC4_set_key,\@function,3 -.align 16 -RC4_set_key: - lea 8($dat),$dat - lea ($inp,$len),$inp - neg $len - mov $len,%rcx - xor %eax,%eax - xor $ido,$ido - xor %r10,%r10 - xor %r11,%r11 - jmp .Lw1stloop - -.align 16 -.Lw1stloop: - mov %eax,($dat,%rax,4) - add \$1,%al - jnc .Lw1stloop - - xor $ido,$ido - xor $idx,$idx -.align 16 -.Lw2ndloop: - mov ($dat,$ido,4),%r10d - add ($inp,$len,1),$idx#b - add %r10b,$idx#b - add \$1,$len - mov ($dat,$idx,4),%r11d - cmovz %rcx,$len - mov %r10d,($dat,$idx,4) - mov %r11d,($dat,$ido,4) - add \$1,$ido#b - jnc .Lw2ndloop - - xor %eax,%eax - mov %eax,-8($dat) - mov %eax,-4($dat) - ret -.size RC4_set_key,.-RC4_set_key - -.globl RC4_options -.type RC4_options,\@abi-omnipotent -.align 16 -RC4_options: - lea .Lopts(%rip),%rax - ret -.align 64 -.Lopts: -.asciz "rc4(64x,int)" -.align 64 -.size RC4_options,.-RC4_options -___ -} -# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, -# CONTEXT *context,DISPATCHER_CONTEXT *disp) -if ($win64) { -my $rec="%rcx"; -my $frame="%rdx"; -my $context="%r8"; -my $disp="%r9"; - -$code.=<<___; -.extern __imp_RtlVirtualUnwind -.type se_handler,\@abi-omnipotent -.align 16 -se_handler: - push %rsi - push %rdi - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 - pushfq - sub \$64,%rsp - - mov 120($context),%rax # pull context->Rax - mov 248($context),%rbx # pull context->Rip - - lea .Lbody(%rip),%r10 - cmp %r10,%rbx # context->Rip<.Lbody - jb .Lin_prologue - - mov 152($context),%rax # pull context->Rsp - - lea .Lepilogue(%rip),%r10 - cmp %r10,%rbx # context->Rip>=.Lepilogue - jae .Lin_prologue - - mov 40(%rax),%r15 - mov 48(%rax),%r14 - mov 56(%rax),%r13 - mov 64(%rax),%r12 - mov 72(%rax),%rbp - mov 80(%rax),%rbx - lea 88(%rax),%rax - - mov %rbx,144($context) # restore context->Rbx - mov %rbp,160($context) # restore context->Rbp - mov %r12,216($context) # restore context->R12 - mov %r13,224($context) # restore context->R12 - mov %r14,232($context) # restore context->R14 - mov %r15,240($context) # restore context->R15 - -.Lin_prologue: - mov 8(%rax),%rdi - mov 16(%rax),%rsi - mov %rax,152($context) # restore context->Rsp - mov %rsi,168($context) # restore context->Rsi - mov %rdi,176($context) # restore context->Rdi - - mov 40($disp),%rdi # disp->ContextRecord - mov $context,%rsi # context - mov \$154,%ecx # sizeof(CONTEXT) - .long 0xa548f3fc # cld; rep movsq - - mov $disp,%rsi - xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER - mov 8(%rsi),%rdx # arg2, disp->ImageBase - mov 0(%rsi),%r8 # arg3, disp->ControlPc - mov 16(%rsi),%r9 # arg4, disp->FunctionEntry - mov 40(%rsi),%r10 # disp->ContextRecord - lea 56(%rsi),%r11 # &disp->HandlerData - lea 24(%rsi),%r12 # &disp->EstablisherFrame - mov %r10,32(%rsp) # arg5 - mov %r11,40(%rsp) # arg6 - mov %r12,48(%rsp) # arg7 - mov %rcx,56(%rsp) # arg8, (NULL) - call *__imp_RtlVirtualUnwind(%rip) - - mov \$1,%eax # ExceptionContinueSearch - add \$64,%rsp - popfq - pop %r15 - pop %r14 - pop %r13 - pop %r12 - pop %rbp - pop %rbx - pop %rdi - pop %rsi - ret -.size se_handler,.-se_handler - -.section .pdata -.align 4 - .rva .LSEH_begin_$func - .rva .LSEH_end_$func - .rva .LSEH_info_$func - -.section .xdata -.align 8 -.LSEH_info_$func: - .byte 9,0,0,0 - .rva se_handler -___ -} - -sub reg_part { -my ($reg,$conv)=@_; - if ($reg =~ /%r[0-9]+/) { $reg .= $conv; } - elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; } - elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; } - elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; } - return $reg; -} - -$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem; -$code =~ s/\`([^\`]*)\`/eval $1/gem; -$code =~ s/pinsrw\s+\$0,/movd /gm; - -$code =~ s/#md5#//gm if ($md5); -$code =~ s/#rc4#//gm if ($rc4); - -print $code; - -close STDOUT; diff --git a/src/crypto/rsa/padding.c b/src/crypto/rsa/padding.c index 5a42e24..032df2e 100644 --- a/src/crypto/rsa/padding.c +++ b/src/crypto/rsa/padding.c @@ -56,6 +56,7 @@ #include <openssl/rsa.h> #include <assert.h> +#include <limits.h> #include <string.h> #include <openssl/digest.h> @@ -65,20 +66,21 @@ #include <openssl/sha.h> #include "internal.h" +#include "../internal.h" /* TODO(fork): don't the check functions have to be constant time? */ -int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned tlen, - const uint8_t *from, unsigned flen) { +int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned to_len, + const uint8_t *from, unsigned from_len) { unsigned j; uint8_t *p; - if (tlen < RSA_PKCS1_PADDING_SIZE) { + if (to_len < RSA_PKCS1_PADDING_SIZE) { OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } - if (flen > tlen - RSA_PKCS1_PADDING_SIZE) { + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } @@ -89,20 +91,20 @@ int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned tlen, *(p++) = 1; /* Private Key BT (Block Type) */ /* pad out with 0xff data */ - j = tlen - 3 - flen; + j = to_len - 3 - from_len; memset(p, 0xff, j); p += j; *(p++) = 0; - memcpy(p, from, (unsigned int)flen); + memcpy(p, from, (unsigned int)from_len); return 1; } -int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen, - const uint8_t *from, unsigned flen) { +int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned to_len, + const uint8_t *from, unsigned from_len) { unsigned i, j; const uint8_t *p; - if (flen < 2) { + if (from_len < 2) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL); return -1; } @@ -114,7 +116,7 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen, } /* scan over padding data */ - j = flen - 2; /* one for leading 00, one for type. */ + j = from_len - 2; /* one for leading 00, one for type. */ for (i = 0; i < j; i++) { /* should decrypt to 0xff */ if (*p != 0xff) { @@ -140,7 +142,7 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen, } i++; /* Skip over the '\0' */ j -= i; - if (j > tlen) { + if (j > to_len) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); return -1; } @@ -149,17 +151,17 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen, return j; } -int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen, - const uint8_t *from, unsigned flen) { +int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned to_len, + const uint8_t *from, unsigned from_len) { unsigned i, j; uint8_t *p; - if (tlen < RSA_PKCS1_PADDING_SIZE) { + if (to_len < RSA_PKCS1_PADDING_SIZE) { OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } - if (flen > tlen - RSA_PKCS1_PADDING_SIZE) { + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } @@ -170,7 +172,7 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen, *(p++) = 2; /* Public Key BT (Block Type) */ /* pad out with non-zero random data */ - j = tlen - 3 - flen; + j = to_len - 3 - from_len; if (!RAND_bytes(p, j)) { return 0; @@ -187,116 +189,89 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen, *(p++) = 0; - memcpy(p, from, (unsigned int)flen); + memcpy(p, from, (unsigned int)from_len); return 1; } -/* constant_time_byte_eq returns 1 if |x| == |y| and 0 otherwise. */ -static int constant_time_byte_eq(unsigned char a, unsigned char b) { - unsigned char z = ~(a ^ b); - z &= z >> 4; - z &= z >> 2; - z &= z >> 1; - - return z; -} - -/* constant_time_select returns |x| if |v| is 1 and |y| if |v| is 0. - * Its behavior is undefined if |v| takes any other value. */ -static int constant_time_select(int v, int x, int y) { - return ((~(v - 1)) & x) | ((v - 1) & y); -} - -/* constant_time_le returns 1 if |x| <= |y| and 0 otherwise. - * |x| and |y| must be positive. */ -static int constant_time_le(int x, int y) { - return ((x - y - 1) >> (sizeof(int) * 8 - 1)) & 1; -} - -int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len, - size_t *out_index) { - size_t i; - int first_byte_is_zero, second_byte_is_two, looking_for_index; - int valid_index, zero_index = 0; +int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned to_len, + const uint8_t *from, unsigned from_len) { + if (from_len == 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + return -1; + } /* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography * Standard", section 7.2.2. */ if (from_len < RSA_PKCS1_PADDING_SIZE) { /* |from| is zero-padded to the size of the RSA modulus, a public value, so * this can be rejected in non-constant time. */ - *out_index = 0; - return 0; + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; } - first_byte_is_zero = constant_time_byte_eq(from[0], 0); - second_byte_is_two = constant_time_byte_eq(from[1], 2); + unsigned first_byte_is_zero = constant_time_eq(from[0], 0); + unsigned second_byte_is_two = constant_time_eq(from[1], 2); - looking_for_index = 1; + unsigned i, zero_index = 0, looking_for_index = ~0u; for (i = 2; i < from_len; i++) { - int equals0 = constant_time_byte_eq(from[i], 0); - zero_index = - constant_time_select(looking_for_index & equals0, i, zero_index); + unsigned equals0 = constant_time_is_zero(from[i]); + zero_index = constant_time_select(looking_for_index & equals0, (unsigned)i, + zero_index); looking_for_index = constant_time_select(equals0, 0, looking_for_index); } /* The input must begin with 00 02. */ - valid_index = first_byte_is_zero; + unsigned valid_index = first_byte_is_zero; valid_index &= second_byte_is_two; /* We must have found the end of PS. */ valid_index &= ~looking_for_index; /* PS must be at least 8 bytes long, and it starts two bytes into |from|. */ - valid_index &= constant_time_le(2 + 8, zero_index); + valid_index &= constant_time_ge(zero_index, 2 + 8); /* Skip the zero byte. */ zero_index++; - *out_index = constant_time_select(valid_index, zero_index, 0); - return valid_index; -} - -int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen, - const uint8_t *from, unsigned flen) { - size_t msg_index, msg_len; - - if (flen == 0) { - OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + /* NOTE: Although this logic attempts to be constant time, the API contracts + * of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it + * impossible to completely avoid Bleichenbacher's attack. Consumers should + * use |RSA_unpad_key_pkcs1|. */ + if (!valid_index) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); return -1; } - /* NOTE: Although |RSA_message_index_PKCS1_type_2| itself is constant time, - * the API contracts of this function and |RSA_decrypt| with - * |RSA_PKCS1_PADDING| make it impossible to completely avoid Bleichenbacher's - * attack. */ - if (!RSA_message_index_PKCS1_type_2(from, flen, &msg_index)) { + const unsigned msg_len = from_len - zero_index; + if (msg_len > to_len) { + /* This shouldn't happen because this function is always called with + * |to_len| as the key size and |from_len| is bounded by the key size. */ OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); return -1; } - msg_len = flen - msg_index; - if (msg_len > tlen) { - /* This shouldn't happen because this function is always called with |tlen| - * the key size and |flen| is bounded by the key size. */ - OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + if (msg_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); return -1; } - memcpy(to, &from[msg_index], msg_len); - return msg_len; + + memcpy(to, &from[zero_index], msg_len); + return (int)msg_len; } -int RSA_padding_add_none(uint8_t *to, unsigned tlen, const uint8_t *from, unsigned flen) { - if (flen > tlen) { +int RSA_padding_add_none(uint8_t *to, unsigned to_len, const uint8_t *from, + unsigned from_len) { + if (from_len > to_len) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } - if (flen < tlen) { + if (from_len < to_len) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE); return 0; } - memcpy(to, from, (unsigned int)flen); + memcpy(to, from, (unsigned int)from_len); return 1; } @@ -319,7 +294,8 @@ int PKCS1_MGF1(uint8_t *mask, unsigned len, const uint8_t *seed, cnt[2] = (uint8_t)((i >> 8)) & 255; cnt[3] = (uint8_t)(i & 255); if (!EVP_DigestInit_ex(&c, dgst, NULL) || - !EVP_DigestUpdate(&c, seed, seedlen) || !EVP_DigestUpdate(&c, cnt, 4)) { + !EVP_DigestUpdate(&c, seed, seedlen) || + !EVP_DigestUpdate(&c, cnt, 4)) { goto err; } @@ -343,9 +319,9 @@ err: return ret; } -int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen, - const uint8_t *from, unsigned flen, - const uint8_t *param, unsigned plen, +int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len, + const uint8_t *from, unsigned from_len, + const uint8_t *param, unsigned param_len, const EVP_MD *md, const EVP_MD *mgf1md) { unsigned i, emlen, mdlen; uint8_t *db, *seed; @@ -361,13 +337,13 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen, mdlen = EVP_MD_size(md); - if (tlen < 2 * mdlen + 2) { + if (to_len < 2 * mdlen + 2) { OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } - emlen = tlen - 1; - if (flen > emlen - 2 * mdlen - 1) { + emlen = to_len - 1; + if (from_len > emlen - 2 * mdlen - 1) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } @@ -381,12 +357,12 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen, seed = to + 1; db = to + mdlen + 1; - if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) { + if (!EVP_Digest((void *)param, param_len, db, NULL, md, NULL)) { return 0; } - memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); - db[emlen - flen - mdlen - 1] = 0x01; - memcpy(db + emlen - flen - mdlen, from, flen); + memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1); + db[emlen - from_len - mdlen - 1] = 0x01; + memcpy(db + emlen - from_len - mdlen, from, from_len); if (!RAND_bytes(seed, mdlen)) { return 0; } @@ -417,14 +393,13 @@ out: return ret; } -int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen, - const uint8_t *from, unsigned flen, - const uint8_t *param, unsigned plen, +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len, + const uint8_t *from, unsigned from_len, + const uint8_t *param, unsigned param_len, const EVP_MD *md, const EVP_MD *mgf1md) { - unsigned i, dblen, mlen = -1, mdlen; + unsigned i, dblen, mlen = -1, mdlen, bad, looking_for_one_byte, one_index = 0; const uint8_t *maskeddb, *maskedseed; uint8_t *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE]; - int bad, looking_for_one_byte, one_index = 0; if (md == NULL) { md = EVP_sha1(); @@ -438,13 +413,13 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen, /* The encoded message is one byte smaller than the modulus to ensure that it * doesn't end up greater than the modulus. Thus there's an extra "+1" here * compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. */ - if (flen < 1 + 2*mdlen + 1) { - /* 'flen' is the length of the modulus, i.e. does not depend on the + if (from_len < 1 + 2*mdlen + 1) { + /* 'from_len' is the length of the modulus, i.e. does not depend on the * particular ciphertext. */ goto decoding_err; } - dblen = flen - mdlen - 1; + dblen = from_len - mdlen - 1; db = OPENSSL_malloc(dblen); if (db == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); @@ -468,19 +443,19 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen, db[i] ^= maskeddb[i]; } - if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) { + if (!EVP_Digest((void *)param, param_len, phash, NULL, md, NULL)) { goto err; } - bad = CRYPTO_memcmp(db, phash, mdlen); - bad |= from[0]; + bad = ~constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen)); + bad |= ~constant_time_is_zero(from[0]); - looking_for_one_byte = 1; + looking_for_one_byte = ~0u; for (i = mdlen; i < dblen; i++) { - int equals1 = constant_time_byte_eq(db[i], 1); - int equals0 = constant_time_byte_eq(db[i], 0); - one_index = - constant_time_select(looking_for_one_byte & equals1, i, one_index); + unsigned equals1 = constant_time_eq(db[i], 1); + unsigned equals0 = constant_time_eq(db[i], 0); + one_index = constant_time_select(looking_for_one_byte & equals1, i, + one_index); looking_for_one_byte = constant_time_select(equals1, 0, looking_for_one_byte); bad |= looking_for_one_byte & ~equals0; @@ -494,7 +469,7 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen, one_index++; mlen = dblen - one_index; - if (tlen < mlen) { + if (to_len < mlen) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); mlen = -1; } else { diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c index 49ab27b..6c28ad7 100644 --- a/src/crypto/rsa/rsa.c +++ b/src/crypto/rsa/rsa.c @@ -96,13 +96,7 @@ RSA *RSA_new_method(const ENGINE *engine) { rsa->references = 1; rsa->flags = rsa->meth->flags; CRYPTO_MUTEX_init(&rsa->lock); - - if (!CRYPTO_new_ex_data(&g_ex_data_class, rsa, &rsa->ex_data)) { - CRYPTO_MUTEX_cleanup(&rsa->lock); - METHOD_unref(rsa->meth); - OPENSSL_free(rsa); - return NULL; - } + CRYPTO_new_ex_data(&rsa->ex_data); if (rsa->meth->init && !rsa->meth->init(rsa)) { CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data); @@ -308,11 +302,11 @@ int RSA_supports_digest(const RSA *rsa, const EVP_MD *md) { return 1; } -int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int index; - if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func, - dup_func, free_func)) { + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func, + free_func)) { return -1; } return index; diff --git a/src/crypto/rsa/rsa_asn1.c b/src/crypto/rsa/rsa_asn1.c index 6144e74..b73a0e1 100644 --- a/src/crypto/rsa/rsa_asn1.c +++ b/src/crypto/rsa/rsa_asn1.c @@ -108,6 +108,14 @@ static RSA *parse_public_key(CBS *cbs, int buggy) { RSA_free(ret); return NULL; } + + if (!BN_is_odd(ret->e) || + BN_num_bits(ret->e) < 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + RSA_free(ret); + return NULL; + } + return ret; } diff --git a/src/crypto/rsa/rsa_impl.c b/src/crypto/rsa/rsa_impl.c index bee7f22..b1cfaa6 100644 --- a/src/crypto/rsa/rsa_impl.c +++ b/src/crypto/rsa/rsa_impl.c @@ -636,7 +636,7 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { BIGNUM *p = NULL, *q = NULL; /* Make sure BN_mod_inverse in Montgomery intialization uses the - * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) */ + * BN_FLG_CONSTTIME flag. */ BN_init(&local_p); p = &local_p; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); diff --git a/src/crypto/rsa/rsa_test.cc b/src/crypto/rsa/rsa_test.cc index 57b360c..5545161 100644 --- a/src/crypto/rsa/rsa_test.cc +++ b/src/crypto/rsa/rsa_test.cc @@ -495,6 +495,34 @@ static const uint8_t kEstonianRSAKey[] = { 0x02, 0x03, 0x01, 0x00, 0x01, }; +// kExponent1RSAKey is an RSAPublicKey encoded with an exponent of 1. See +// https://crbug.com/541257 +static const uint8_t kExponent1RSAKey[] = { + 0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcf, 0x86, 0x9a, + 0x7d, 0x5c, 0x9f, 0xbd, 0x33, 0xbb, 0xc2, 0xb1, 0x06, 0xa8, 0x3e, 0xc5, + 0x18, 0xf3, 0x01, 0x04, 0xdd, 0x7a, 0x38, 0x0e, 0x8e, 0x8d, 0x10, 0xaa, + 0xf8, 0x64, 0x49, 0x82, 0xa6, 0x16, 0x9d, 0xd9, 0xae, 0x5e, 0x7f, 0x9b, + 0x53, 0xcb, 0xbb, 0x29, 0xda, 0x98, 0x47, 0x26, 0x88, 0x2e, 0x1d, 0x64, + 0xb3, 0xbc, 0x7e, 0x96, 0x3a, 0xa7, 0xd6, 0x87, 0xf6, 0xf5, 0x3f, 0xa7, + 0x3b, 0xd3, 0xc5, 0xd5, 0x61, 0x3c, 0x63, 0x05, 0xf9, 0xbc, 0x64, 0x1d, + 0x71, 0x65, 0xf5, 0xc8, 0xe8, 0x64, 0x41, 0x35, 0x88, 0x81, 0x6b, 0x2a, + 0x24, 0xbb, 0xdd, 0x9f, 0x75, 0x4f, 0xea, 0x35, 0xe5, 0x32, 0x76, 0x5a, + 0x8b, 0x7a, 0xb5, 0x92, 0x65, 0x34, 0xb7, 0x88, 0x42, 0x5d, 0x41, 0x0b, + 0xd1, 0x00, 0x2d, 0x43, 0x47, 0x55, 0x60, 0x3c, 0x0e, 0x60, 0x04, 0x5c, + 0x88, 0x13, 0xc7, 0x42, 0x55, 0x16, 0x31, 0x32, 0x81, 0xba, 0xde, 0xa9, + 0x56, 0xeb, 0xdb, 0x66, 0x7f, 0x31, 0xba, 0xe8, 0x87, 0x1a, 0xcc, 0xad, + 0x90, 0x86, 0x4b, 0xa7, 0x6d, 0xd5, 0xc1, 0xb7, 0xe7, 0x67, 0x56, 0x41, + 0xf7, 0x03, 0xb3, 0x09, 0x61, 0x63, 0xb5, 0xb0, 0x19, 0x7b, 0xc5, 0x91, + 0xc8, 0x96, 0x5b, 0x6a, 0x80, 0xa1, 0x53, 0x0f, 0x9a, 0x47, 0xb5, 0x9a, + 0x44, 0x53, 0xbd, 0x93, 0xe3, 0xe4, 0xce, 0x0c, 0x17, 0x11, 0x51, 0x1d, + 0xfd, 0x6c, 0x74, 0xe4, 0xec, 0x2a, 0xce, 0x57, 0x27, 0xcc, 0x83, 0x98, + 0x08, 0x32, 0x2c, 0xd5, 0x75, 0xa9, 0x27, 0xfe, 0xaa, 0x5e, 0x48, 0xc9, + 0x46, 0x9a, 0x29, 0x3f, 0xe6, 0x01, 0x4d, 0x97, 0x4a, 0x70, 0xd1, 0x5d, + 0xf8, 0xc0, 0x0b, 0x23, 0xcb, 0xbe, 0xf5, 0x70, 0x0b, 0xc2, 0xf2, 0xc0, + 0x33, 0x9c, 0xc4, 0x8b, 0x39, 0x7e, 0x3d, 0xc6, 0x23, 0x39, 0x9a, 0x98, + 0xdd, 0x02, 0x01, 0x01, +}; + static bool TestRSA(const uint8_t *der, size_t der_len, const uint8_t *oaep_ciphertext, size_t oaep_ciphertext_len) { @@ -845,6 +873,19 @@ static bool TestASN1() { return true; } +static bool TestBadExponent() { + ScopedRSA rsa(RSA_public_key_from_bytes(kExponent1RSAKey, + sizeof(kExponent1RSAKey))); + + if (rsa) { + fprintf(stderr, "kExponent1RSAKey parsed but should have failed.\n"); + return false; + } + + ERR_clear_error(); + return true; +} + int main(int argc, char *argv[]) { CRYPTO_library_init(); @@ -867,7 +908,8 @@ int main(int argc, char *argv[]) { kSixPrimeEncryptedMessage, sizeof(kSixPrimeEncryptedMessage)) || !TestMultiPrimeKeygen() || - !TestASN1()) { + !TestASN1() || + !TestBadExponent()) { return 1; } diff --git a/src/crypto/sha/asm/sha1-586.pl b/src/crypto/sha/asm/sha1-586.pl index 09fd3fc..3514273 100644 --- a/src/crypto/sha/asm/sha1-586.pl +++ b/src/crypto/sha/asm/sha1-586.pl @@ -121,9 +121,7 @@ for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); } # In upstream, this is controlled by shelling out to the compiler to check # versions, but BoringSSL is intended to be used with pre-generated perlasm # output, so this isn't useful anyway. -# -# TODO(davidben): Enable this after testing. $ymm goes up to 1. -$ymm = 0; +$ymm = 1; $ymm = 0 unless ($xmm); diff --git a/src/crypto/sha/asm/sha1-x86_64.pl b/src/crypto/sha/asm/sha1-x86_64.pl index 59b1607..4895f92 100644 --- a/src/crypto/sha/asm/sha1-x86_64.pl +++ b/src/crypto/sha/asm/sha1-x86_64.pl @@ -96,8 +96,10 @@ die "can't locate x86_64-xlate.pl"; # versions, but BoringSSL is intended to be used with pre-generated perlasm # output, so this isn't useful anyway. # -# TODO(davidben): Enable this after testing. $avx goes up to 2. -$avx = 0; +# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. Is it +# necessary to disable AVX2 code when SHA Extensions code is disabled? Upstream +# did not tie them together until after $shaext was added. +$avx = 1; # TODO(davidben): Consider enabling the Intel SHA Extensions code once it's # been tested. diff --git a/src/crypto/sha/asm/sha256-586.pl b/src/crypto/sha/asm/sha256-586.pl index 1866d5a..fa8f264 100644 --- a/src/crypto/sha/asm/sha256-586.pl +++ b/src/crypto/sha/asm/sha256-586.pl @@ -72,8 +72,8 @@ for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); } # versions, but BoringSSL is intended to be used with pre-generated perlasm # output, so this isn't useful anyway. # -# TODO(davidben): Enable this after testing. $avx goes up to 2. -$avx = 0; +# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. +$avx = 1; $avx = 0 unless ($xmm); diff --git a/src/crypto/sha/asm/sha512-x86_64.pl b/src/crypto/sha/asm/sha512-x86_64.pl index 9a0d0c4..2bc33c6 100644 --- a/src/crypto/sha/asm/sha512-x86_64.pl +++ b/src/crypto/sha/asm/sha512-x86_64.pl @@ -113,8 +113,10 @@ die "can't locate x86_64-xlate.pl"; # versions, but BoringSSL is intended to be used with pre-generated perlasm # output, so this isn't useful anyway. # -# TODO(davidben): Enable this after testing. $avx goes up to 2. -$avx = 0; +# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. Is it +# necessary to disable AVX2 code when SHA Extensions code is disabled? Upstream +# did not tie them together until after $shaext was added. +$avx = 1; # TODO(davidben): Consider enabling the Intel SHA Extensions code once it's # been tested. diff --git a/src/crypto/sha/sha1.c b/src/crypto/sha/sha1.c index 568706b..74e841c 100644 --- a/src/crypto/sha/sha1.c +++ b/src/crypto/sha/sha1.c @@ -102,21 +102,22 @@ uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) { do { \ uint32_t ll; \ ll = (c)->h[0]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[1]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[2]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[3]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ ll = (c)->h[4]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ } while (0) #define HASH_UPDATE SHA1_Update #define HASH_TRANSFORM SHA1_Transform #define HASH_FINAL SHA1_Final #define HASH_BLOCK_DATA_ORDER sha1_block_data_order +#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) #define Xupdate(a, ix, ia, ib, ic, id) \ ((a) = (ia ^ ib ^ ic ^ id), ix = (a) = ROTATE((a), 1)) diff --git a/src/crypto/sha/sha256.c b/src/crypto/sha/sha256.c index 3681308..0ddacba 100644 --- a/src/crypto/sha/sha256.c +++ b/src/crypto/sha/sha256.c @@ -155,13 +155,13 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) { case SHA224_DIGEST_LENGTH: \ for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) { \ ll = (c)->h[nn]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ } \ break; \ case SHA256_DIGEST_LENGTH: \ for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) { \ ll = (c)->h[nn]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ } \ break; \ default: \ @@ -170,7 +170,7 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) { } \ for (nn = 0; nn < (c)->md_len / 4; nn++) { \ ll = (c)->h[nn]; \ - (void) HOST_l2c(ll, (s)); \ + HOST_l2c(ll, (s)); \ } \ break; \ } \ @@ -204,6 +204,8 @@ static const uint32_t K256[64] = { 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL}; +#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + /* FIPS specification refers to right rotations, while our ROTATE macro * is left one. This is why you might notice that rotation coefficients * differ from those observed in FIPS document by 32-N... */ diff --git a/src/crypto/sha/sha512.c b/src/crypto/sha/sha512.c index beb0f8c..6ad8d40 100644 --- a/src/crypto/sha/sha512.c +++ b/src/crypto/sha/sha512.c @@ -60,8 +60,6 @@ #include <openssl/mem.h> -#include "../internal.h" - /* IMPLEMENTATION NOTES. * @@ -87,14 +85,14 @@ #endif int SHA384_Init(SHA512_CTX *sha) { - sha->h[0] = OPENSSL_U64(0xcbbb9d5dc1059ed8); - sha->h[1] = OPENSSL_U64(0x629a292a367cd507); - sha->h[2] = OPENSSL_U64(0x9159015a3070dd17); - sha->h[3] = OPENSSL_U64(0x152fecd8f70e5939); - sha->h[4] = OPENSSL_U64(0x67332667ffc00b31); - sha->h[5] = OPENSSL_U64(0x8eb44a8768581511); - sha->h[6] = OPENSSL_U64(0xdb0c2e0d64f98fa7); - sha->h[7] = OPENSSL_U64(0x47b5481dbefa4fa4); + sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8); + sha->h[1] = UINT64_C(0x629a292a367cd507); + sha->h[2] = UINT64_C(0x9159015a3070dd17); + sha->h[3] = UINT64_C(0x152fecd8f70e5939); + sha->h[4] = UINT64_C(0x67332667ffc00b31); + sha->h[5] = UINT64_C(0x8eb44a8768581511); + sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7); + sha->h[7] = UINT64_C(0x47b5481dbefa4fa4); sha->Nl = 0; sha->Nh = 0; @@ -105,14 +103,14 @@ int SHA384_Init(SHA512_CTX *sha) { int SHA512_Init(SHA512_CTX *sha) { - sha->h[0] = OPENSSL_U64(0x6a09e667f3bcc908); - sha->h[1] = OPENSSL_U64(0xbb67ae8584caa73b); - sha->h[2] = OPENSSL_U64(0x3c6ef372fe94f82b); - sha->h[3] = OPENSSL_U64(0xa54ff53a5f1d36f1); - sha->h[4] = OPENSSL_U64(0x510e527fade682d1); - sha->h[5] = OPENSSL_U64(0x9b05688c2b3e6c1f); - sha->h[6] = OPENSSL_U64(0x1f83d9abfb41bd6b); - sha->h[7] = OPENSSL_U64(0x5be0cd19137e2179); + sha->h[0] = UINT64_C(0x6a09e667f3bcc908); + sha->h[1] = UINT64_C(0xbb67ae8584caa73b); + sha->h[2] = UINT64_C(0x3c6ef372fe94f82b); + sha->h[3] = UINT64_C(0xa54ff53a5f1d36f1); + sha->h[4] = UINT64_C(0x510e527fade682d1); + sha->h[5] = UINT64_C(0x9b05688c2b3e6c1f); + sha->h[6] = UINT64_C(0x1f83d9abfb41bd6b); + sha->h[7] = UINT64_C(0x5be0cd19137e2179); sha->Nl = 0; sha->Nh = 0; @@ -185,7 +183,7 @@ int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) { return 1; } - l = (c->Nl + (((uint64_t)len) << 3)) & OPENSSL_U64(0xffffffffffffffff); + l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff); if (l < c->Nl) { c->Nh++; } @@ -316,77 +314,91 @@ int SHA512_Final(uint8_t *md, SHA512_CTX *sha) { #ifndef SHA512_ASM static const uint64_t K512[80] = { - 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, - 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, - 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, - 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, - 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, - 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, - 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275, - 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, - 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, - 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, - 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, - 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, - 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, - 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001, - 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, - 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, - 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, - 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, - 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, - 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, - 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, - 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207, - 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, - 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, - 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, - 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, - 0x5fcb6fab3ad6faec, 0x6c44198c4a475817}; + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817), +}; #if defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM) #if defined(__x86_64) || defined(__x86_64__) -#define ROTR(a, n) \ - ({ \ - uint64_t ret; \ - asm("rorq %1,%0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \ - ret; \ +#define ROTR(a, n) \ + ({ \ + uint64_t ret; \ + __asm__("rorq %1, %0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \ + ret; \ }) -#define PULL64(x) \ - ({ \ - uint64_t ret = *((const uint64_t *)(&(x))); \ - asm("bswapq %0" : "=r"(ret) : "0"(ret)); \ - ret; \ +#define PULL64(x) \ + ({ \ + uint64_t ret = *((const uint64_t *)(&(x))); \ + __asm__("bswapq %0" : "=r"(ret) : "0"(ret)); \ + ret; \ }) #elif(defined(__i386) || defined(__i386__)) -#define PULL64(x) \ - ({ \ - const unsigned int *p = (const unsigned int *)(&(x)); \ - unsigned int hi = p[0], lo = p[1]; \ - asm("bswapl %0; bswapl %1;" : "=r"(lo), "=r"(hi) : "0"(lo), "1"(hi)); \ - ((uint64_t)hi) << 32 | lo; \ +#define PULL64(x) \ + ({ \ + const unsigned int *p = (const unsigned int *)(&(x)); \ + unsigned int hi = p[0], lo = p[1]; \ + __asm__("bswapl %0; bswapl %1;" : "=r"(lo), "=r"(hi) : "0"(lo), "1"(hi)); \ + ((uint64_t)hi) << 32 | lo; \ }) #elif(defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) -#define ROTR(a, n) \ - ({ \ - uint64_t ret; \ - asm("rotrdi %0,%1,%2" : "=r"(ret) : "r"(a), "K"(n)); \ - ret; \ +#define ROTR(a, n) \ + ({ \ + uint64_t ret; \ + __asm__("rotrdi %0, %1, %2" : "=r"(ret) : "r"(a), "K"(n)); \ + ret; \ }) #elif defined(__aarch64__) -#define ROTR(a, n) \ - ({ \ - uint64_t ret; \ - asm("ror %0,%1,%2" : "=r"(ret) : "r"(a), "I"(n)); \ - ret; \ +#define ROTR(a, n) \ + ({ \ + uint64_t ret; \ + __asm__("ror %0, %1, %2" : "=r"(ret) : "r"(a), "I"(n)); \ + ret; \ }) #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -#define PULL64(x) \ - ({ \ - uint64_t ret; \ - asm("rev %0,%1" : "=r"(ret) : "r"(*((const uint64_t *)(&(x))))); \ - ret; \ +#define PULL64(x) \ + ({ \ + uint64_t ret; \ + __asm__("rev %0, %1" : "=r"(ret) : "r"(*((const uint64_t *)(&(x))))); \ + ret; \ }) #endif #endif diff --git a/src/crypto/test/file_test.cc b/src/crypto/test/file_test.cc index 6723350..4752f04 100644 --- a/src/crypto/test/file_test.cc +++ b/src/crypto/test/file_test.cc @@ -22,8 +22,6 @@ #include <openssl/err.h> -#include "stl_compat.h" - FileTest::FileTest(const char *path) { file_ = fopen(path, "r"); diff --git a/src/crypto/test/scoped_types.h b/src/crypto/test/scoped_types.h index 2ce4526..590f926 100644 --- a/src/crypto/test/scoped_types.h +++ b/src/crypto/test/scoped_types.h @@ -18,6 +18,8 @@ #include <stdint.h> #include <stdio.h> +#include <memory> + #include <openssl/aead.h> #include <openssl/bio.h> #include <openssl/bn.h> @@ -34,8 +36,6 @@ #include <openssl/stack.h> #include <openssl/x509.h> -#include "stl_compat.h" - template<typename T, void (*func)(T*)> struct OpenSSLDeleter { @@ -66,11 +66,11 @@ struct FileCloser { }; template<typename T, void (*func)(T*)> -using ScopedOpenSSLType = bssl::unique_ptr<T, OpenSSLDeleter<T, func>>; +using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>; template<typename StackType, typename T, void (*func)(T*)> using ScopedOpenSSLStack = - bssl::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>; + std::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>; template<typename T, typename CleanupRet, void (*init_func)(T*), CleanupRet (*cleanup_func)(T*)> @@ -129,9 +129,9 @@ using ScopedEVP_MD_CTX = ScopedOpenSSLContext<EVP_MD_CTX, int, EVP_MD_CTX_init, using ScopedHMAC_CTX = ScopedOpenSSLContext<HMAC_CTX, void, HMAC_CTX_init, HMAC_CTX_cleanup>; -using ScopedOpenSSLBytes = bssl::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>; -using ScopedOpenSSLString = bssl::unique_ptr<char, OpenSSLFree<char>>; +using ScopedOpenSSLBytes = std::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>; +using ScopedOpenSSLString = std::unique_ptr<char, OpenSSLFree<char>>; -using ScopedFILE = bssl::unique_ptr<FILE, FileCloser>; +using ScopedFILE = std::unique_ptr<FILE, FileCloser>; #endif // OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H diff --git a/src/crypto/test/stl_compat.h b/src/crypto/test/stl_compat.h deleted file mode 100644 index 1997a45..0000000 --- a/src/crypto/test/stl_compat.h +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright (c) 2015, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#ifndef OPENSSL_HEADER_CRYPTO_TEST_STL_COMPAT_H -#define OPENSSL_HEADER_CRYPTO_TEST_STL_COMPAT_H - -#include <assert.h> - -#include <vector> - - -// This header contains re-implementations of library functions from C++11. They -// will be replaced with their standard counterparts once Chromium has C++11 -// library support in its toolchain. - -namespace bssl { - -// vector_data is a reimplementation of |std::vector::data| from C++11. -template <class T> -static T *vector_data(std::vector<T> *out) { - return out->empty() ? nullptr : &(*out)[0]; -} - -template <class T> -static const T *vector_data(const std::vector<T> *out) { - return out->empty() ? nullptr : &(*out)[0]; -} - -// remove_reference is a reimplementation of |std::remove_reference| from C++11. -template <class T> -struct remove_reference { - using type = T; -}; - -template <class T> -struct remove_reference<T&> { - using type = T; -}; - -template <class T> -struct remove_reference<T&&> { - using type = T; -}; - -// move is a reimplementation of |std::move| from C++11. -template <class T> -typename remove_reference<T>::type &&move(T &&t) { - return static_cast<typename remove_reference<T>::type&&>(t); -} - -// default_delete is a partial reimplementation of |std::default_delete| from -// C++11. -template <class T> -struct default_delete { - void operator()(T *t) const { - enum { type_must_be_complete = sizeof(T) }; - delete t; - } -}; - -// nullptr_t is |std::nullptr_t| from C++11. -using nullptr_t = decltype(nullptr); - -// unique_ptr is a partial reimplementation of |std::unique_ptr| from C++11. It -// intentionally does not support stateful deleters to avoid having to bother -// with the empty member optimization. -template <class T, class Deleter = default_delete<T>> -class unique_ptr { - public: - unique_ptr() : ptr_(nullptr) {} - unique_ptr(nullptr_t) : ptr_(nullptr) {} - unique_ptr(T *ptr) : ptr_(ptr) {} - unique_ptr(const unique_ptr &u) = delete; - - unique_ptr(unique_ptr &&u) : ptr_(nullptr) { - reset(u.release()); - } - - ~unique_ptr() { - reset(); - } - - unique_ptr &operator=(nullptr_t) { - reset(); - return *this; - } - - unique_ptr &operator=(unique_ptr &&u) { - reset(u.release()); - return *this; - } - - unique_ptr& operator=(const unique_ptr &u) = delete; - - explicit operator bool() const { - return ptr_ != nullptr; - } - - T &operator*() const { - assert(ptr_ != nullptr); - return *ptr_; - } - - T *operator->() const { - assert(ptr_ != nullptr); - return ptr_; - } - - T *get() const { - return ptr_; - } - - T *release() { - T *ptr = ptr_; - ptr_ = nullptr; - return ptr; - } - - void reset(T *ptr = nullptr) { - if (ptr_ != nullptr) { - Deleter()(ptr_); - } - ptr_ = ptr; - } - - private: - T *ptr_; -}; - -} // namespace bssl - - -#endif // OPENSSL_HEADER_CRYPTO_TEST_STL_COMPAT_H diff --git a/src/crypto/thread_pthread.c b/src/crypto/thread_pthread.c index 59c4b8d..68aaab5 100644 --- a/src/crypto/thread_pthread.c +++ b/src/crypto/thread_pthread.c @@ -17,6 +17,7 @@ #if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_THREADS) #include <pthread.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -74,7 +75,11 @@ void CRYPTO_STATIC_MUTEX_unlock(struct CRYPTO_STATIC_MUTEX *lock) { } void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { - pthread_once(once, init); + if (pthread_once(once, init) != 0) { + fprintf(stderr, + "pthread_once failed. Did you link against a threading library?\n"); + abort(); + } } static pthread_mutex_t g_destructors_lock = PTHREAD_MUTEX_INITIALIZER; diff --git a/src/crypto/x509/by_dir.c b/src/crypto/x509/by_dir.c index 3393dfa..ae50ae1 100644 --- a/src/crypto/x509/by_dir.c +++ b/src/crypto/x509/by_dir.c @@ -98,7 +98,7 @@ static void free_dir(X509_LOOKUP *lu); static int add_cert_dir(BY_DIR *ctx,const char *dir,int type); static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name, X509_OBJECT *ret); -X509_LOOKUP_METHOD x509_dir_lookup= +static X509_LOOKUP_METHOD x509_dir_lookup= { "Load certs from files in a directory", new_dir, /* new */ diff --git a/src/crypto/x509/by_file.c b/src/crypto/x509/by_file.c index f1d6194..3460b57 100644 --- a/src/crypto/x509/by_file.c +++ b/src/crypto/x509/by_file.c @@ -68,7 +68,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); -X509_LOOKUP_METHOD x509_file_lookup= +static X509_LOOKUP_METHOD x509_file_lookup= { "Load file into cache", NULL, /* new */ diff --git a/src/crypto/x509/pkcs7.c b/src/crypto/x509/pkcs7.c index 2087f94..9e6a52f 100644 --- a/src/crypto/x509/pkcs7.c +++ b/src/crypto/x509/pkcs7.c @@ -15,6 +15,7 @@ #include <openssl/x509.h> #include <assert.h> +#include <limits.h> #include <openssl/bytestring.h> #include <openssl/err.h> @@ -114,8 +115,11 @@ int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) { goto err; } + if (CBS_len(&cert) > LONG_MAX) { + goto err; + } inp = CBS_data(&cert); - x509 = d2i_X509(NULL, &inp, CBS_len(&cert)); + x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert)); if (!x509) { goto err; } @@ -181,8 +185,11 @@ int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) { goto err; } + if (CBS_len(&crl_data) > LONG_MAX) { + goto err; + } inp = CBS_data(&crl_data); - crl = d2i_X509_CRL(NULL, &inp, CBS_len(&crl_data)); + crl = d2i_X509_CRL(NULL, &inp, (long)CBS_len(&crl_data)); if (!crl) { goto err; } diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c index 695793e..c62a6f5 100644 --- a/src/crypto/x509/x509_vfy.c +++ b/src/crypto/x509/x509_vfy.c @@ -141,7 +141,6 @@ static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *crl_path); static int internal_verify(X509_STORE_CTX *ctx); -const char X509_version[]="X.509"; static int null_callback(int ok, X509_STORE_CTX *e) @@ -205,22 +204,26 @@ int X509_verify_cert(X509_STORE_CTX *ctx) OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); return -1; } + if (ctx->chain != NULL) + { + /* This X509_STORE_CTX has already been used to verify a + * cert. We cannot do another one. */ + OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } cb=ctx->verify_cb; /* first we make sure the chain we are going to build is * present and that the first entry is in place */ - if (ctx->chain == NULL) + ctx->chain = sk_X509_new_null(); + if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) { - if ( ((ctx->chain=sk_X509_new_null()) == NULL) || - (!sk_X509_push(ctx->chain,ctx->cert))) - { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - goto end; - } - X509_up_ref(ctx->cert); - ctx->last_untrusted=1; + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto end; } + X509_up_ref(ctx->cert); + ctx->last_untrusted = 1; /* We use a temporary STACK so we can chop and hack at it */ if (ctx->untrusted != NULL @@ -2093,14 +2096,14 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, return NULL; } -int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { /* This function is (usually) called only once, by * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */ int index; if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, - new_func, dup_func, free_func)) + dup_func, free_func)) { return -1; } @@ -2267,19 +2270,13 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain) { int ret = 1; - int ex_data_allocated = 0; memset(ctx, 0, sizeof(X509_STORE_CTX)); ctx->ctx=store; ctx->cert=x509; ctx->untrusted=chain; - if(!CRYPTO_new_ex_data(&g_ex_data_class, ctx, - &ctx->ex_data)) - { - goto err; - } - ex_data_allocated = 1; + CRYPTO_new_ex_data(&ctx->ex_data); ctx->param = X509_VERIFY_PARAM_new(); if (!ctx->param) @@ -2363,10 +2360,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, return 1; err: - if (ex_data_allocated) - { - CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data); - } + CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data); if (ctx->param != NULL) { X509_VERIFY_PARAM_free(ctx->param); diff --git a/src/crypto/x509/x509name.c b/src/crypto/x509/x509name.c index 7bb3aa1..8b10fa2 100644 --- a/src/crypto/x509/x509name.c +++ b/src/crypto/x509/x509name.c @@ -291,19 +291,13 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type, unsigned char *bytes, int len) { - const ASN1_OBJECT *obj; - X509_NAME_ENTRY *nentry; - - obj=OBJ_nid2obj(nid); + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); if (obj == NULL) { OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); - return(NULL); + return NULL; } - nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len); - /* TODO(fork): remove this? */ - /* ASN1_OBJECT_free(obj); */ - return nentry; + return X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len); } X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, diff --git a/src/crypto/x509/x_all.c b/src/crypto/x509/x_all.c index d7f2d29..62b3f40 100644 --- a/src/crypto/x509/x_all.c +++ b/src/crypto/x509/x_all.c @@ -93,14 +93,6 @@ int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) x->sig_alg, x->signature, x->cert_info, ctx); } -/* TODO(fork) -int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert) - { - return OCSP_REQ_CTX_nbio_d2i(rctx, - (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509)); - } -*/ - int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) { return(ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO),x->sig_alg, NULL, @@ -127,14 +119,6 @@ int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx); } -/* TODO(fork) -int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl) - { - return OCSP_REQ_CTX_nbio_d2i(rctx, - (ASN1_VALUE **)pcrl, ASN1_ITEM_rptr(X509_CRL)); - } -*/ - int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) { return(ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,NULL, @@ -191,31 +175,6 @@ int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); } -/* TODO(fork) */ -#if 0 -#ifndef OPENSSL_NO_FP_API -PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) - { - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); - } - -int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) - { - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); - } -#endif - -PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) - { - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); - } - -int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) - { - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); - } -#endif - #ifndef OPENSSL_NO_FP_API X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) { @@ -425,15 +384,6 @@ int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *m return(ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME),type,(char *)data,md,len)); } -#if 0 /* TODO(fork): remove */ -int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, const EVP_MD *type, - unsigned char *md, unsigned int *len) - { - return(ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL),type, - (char *)data,md,len)); - } -#endif - #ifndef OPENSSL_NO_FP_API X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) { diff --git a/src/crypto/x509/x_name.c b/src/crypto/x509/x_name.c index 762756b..a1dcd16 100644 --- a/src/crypto/x509/x_name.c +++ b/src/crypto/x509/x_name.c @@ -120,7 +120,7 @@ ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) * to the external form. */ -const ASN1_EXTERN_FUNCS x509_name_ff = { +static const ASN1_EXTERN_FUNCS x509_name_ff = { NULL, x509_name_ex_new, x509_name_ex_free, diff --git a/src/crypto/x509/x_x509.c b/src/crypto/x509/x_x509.c index b8f318a..7bbe4f3 100644 --- a/src/crypto/x509/x_x509.c +++ b/src/crypto/x509/x_x509.c @@ -104,7 +104,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ret->akid = NULL; ret->aux = NULL; ret->crldp = NULL; - CRYPTO_new_ex_data(&g_ex_data_class, ret, &ret->ex_data); + CRYPTO_new_ex_data(&ret->ex_data); break; case ASN1_OP_D2I_POST: @@ -146,12 +146,12 @@ X509 *X509_up_ref(X509 *x) return x; } -int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int index; if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, - new_func, dup_func, free_func)) + dup_func, free_func)) { return -1; } diff --git a/src/crypto/x509v3/ext_dat.h b/src/crypto/x509v3/ext_dat.h index 8b2c123..f1fb8ef 100644 --- a/src/crypto/x509v3/ext_dat.h +++ b/src/crypto/x509v3/ext_dat.h @@ -55,17 +55,17 @@ /* This file contains a table of "standard" extensions */ -extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; -extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; -extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; -extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; -extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; -extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; -extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; -extern X509V3_EXT_METHOD v3_crl_hold, v3_pci; -extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; -extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; -extern X509V3_EXT_METHOD v3_addr, v3_asid; +extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; +extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; +extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; +extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; +extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; +extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; +extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; +extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci; +extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; +extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; +extern const X509V3_EXT_METHOD v3_addr, v3_asid; /* This table will be searched using OBJ_bsearch so it *must* kept in * order of the ext_nid values. diff --git a/src/decrepit/cast/cast.c b/src/decrepit/cast/cast.c index 68bcbe3..94b0710 100644 --- a/src/decrepit/cast/cast.c +++ b/src/decrepit/cast/cast.c @@ -62,6 +62,7 @@ #pragma warning(pop) #endif +#include "internal.h" #include "../macros.h" @@ -80,15 +81,6 @@ void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, const CAST_KEY *ks, l2n(d[1], out); } -extern const uint32_t CAST_S_table0[256]; -extern const uint32_t CAST_S_table1[256]; -extern const uint32_t CAST_S_table2[256]; -extern const uint32_t CAST_S_table3[256]; -extern const uint32_t CAST_S_table4[256]; -extern const uint32_t CAST_S_table5[256]; -extern const uint32_t CAST_S_table6[256]; -extern const uint32_t CAST_S_table7[256]; - #if defined(OPENSSL_WINDOWS) && defined(_MSC_VER) #define ROTL(a, n) (_lrotl(a, n)) #else diff --git a/src/decrepit/cast/cast_tables.c b/src/decrepit/cast/cast_tables.c index a00acd8..6808aa8 100644 --- a/src/decrepit/cast/cast_tables.c +++ b/src/decrepit/cast/cast_tables.c @@ -56,6 +56,9 @@ #include <openssl/base.h> +#include "internal.h" + + const uint32_t CAST_S_table0[256] = { 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, diff --git a/src/decrepit/cast/internal.h b/src/decrepit/cast/internal.h new file mode 100644 index 0000000..15e2222 --- /dev/null +++ b/src/decrepit/cast/internal.h @@ -0,0 +1,81 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_CAST_INTERNAL_H +#define OPENSSL_HEADER_CAST_INTERNAL_H + +#include <openssl/base.h> + +#if defined(__cplusplus) +extern "C" { +#endif + + +extern const uint32_t CAST_S_table0[256]; +extern const uint32_t CAST_S_table1[256]; +extern const uint32_t CAST_S_table2[256]; +extern const uint32_t CAST_S_table3[256]; +extern const uint32_t CAST_S_table4[256]; +extern const uint32_t CAST_S_table5[256]; +extern const uint32_t CAST_S_table6[256]; +extern const uint32_t CAST_S_table7[256]; + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_CAST_INTERNAL_H */ diff --git a/src/decrepit/xts/xts.c b/src/decrepit/xts/xts.c index 632e0f8..10a696d 100644 --- a/src/decrepit/xts/xts.c +++ b/src/decrepit/xts/xts.c @@ -56,12 +56,6 @@ #include "../crypto/modes/internal.h" -#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || defined(OPENSSL_AARCH64) -#define STRICT_ALIGNMENT 0 -#else -#define STRICT_ALIGNMENT 1 -#endif - typedef struct xts128_context { void *key1, *key2; block128_f block1, block2; @@ -70,10 +64,6 @@ typedef struct xts128_context { static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const uint8_t iv[16], const uint8_t *inp, uint8_t *out, size_t len, int enc) { - const union { - long one; - char little; - } is_endian = {1}; union { uint64_t u[2]; uint32_t d[4]; @@ -90,22 +80,22 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, if (!enc && (len % 16)) len -= 16; while (len >= 16) { -#if defined(STRICT_ALIGNMENT) +#if STRICT_ALIGNMENT memcpy(scratch.c, inp, 16); scratch.u[0] ^= tweak.u[0]; scratch.u[1] ^= tweak.u[1]; #else - scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak.u[0]; - scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak.u[1]; + scratch.u[0] = ((uint64_t *)inp)[0] ^ tweak.u[0]; + scratch.u[1] = ((uint64_t *)inp)[1] ^ tweak.u[1]; #endif (*ctx->block1)(scratch.c, scratch.c, ctx->key1); -#if defined(STRICT_ALIGNMENT) +#if STRICT_ALIGNMENT scratch.u[0] ^= tweak.u[0]; scratch.u[1] ^= tweak.u[1]; memcpy(out, scratch.c, 16); #else - ((unint64_t *)out)[0] = scratch.u[0] ^= tweak.u[0]; - ((unint64_t *)out)[1] = scratch.u[1] ^= tweak.u[1]; + ((uint64_t *)out)[0] = scratch.u[0] ^= tweak.u[0]; + ((uint64_t *)out)[1] = scratch.u[1] ^= tweak.u[1]; #endif inp += 16; out += 16; @@ -113,26 +103,12 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, if (len == 0) return 1; - if (is_endian.little) { - unsigned int carry, res; + unsigned int carry, res; - res = 0x87 & (((int)tweak.d[3]) >> 31); - carry = (unsigned int)(tweak.u[0] >> 63); - tweak.u[0] = (tweak.u[0] << 1) ^ res; - tweak.u[1] = (tweak.u[1] << 1) | carry; - } else { - size_t c; - - for (c = 0, i = 0; i < 16; ++i) { - /* - * + substitutes for |, because c is 1 bit - */ - c += ((size_t)tweak.c[i]) << 1; - tweak.c[i] = (uint8_t)c; - c = c >> 8; - } - tweak.c[0] ^= (uint8_t)(0x87 & (0 - c)); - } + res = 0x87 & (((int)tweak.d[3]) >> 31); + carry = (unsigned int)(tweak.u[0] >> 63); + tweak.u[0] = (tweak.u[0] << 1) ^ res; + tweak.u[1] = (tweak.u[1] << 1) | carry; } if (enc) { for (i = 0; i < len; ++i) { @@ -152,33 +128,19 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, uint8_t c[16]; } tweak1; - if (is_endian.little) { - unsigned int carry, res; - - res = 0x87 & (((int)tweak.d[3]) >> 31); - carry = (unsigned int)(tweak.u[0] >> 63); - tweak1.u[0] = (tweak.u[0] << 1) ^ res; - tweak1.u[1] = (tweak.u[1] << 1) | carry; - } else { - size_t c; + unsigned int carry, res; - for (c = 0, i = 0; i < 16; ++i) { - /* - * + substitutes for |, because c is 1 bit - */ - c += ((size_t)tweak.c[i]) << 1; - tweak1.c[i] = (uint8_t)c; - c = c >> 8; - } - tweak1.c[0] ^= (uint8_t)(0x87 & (0 - c)); - } -#if defined(STRICT_ALIGNMENT) + res = 0x87 & (((int)tweak.d[3]) >> 31); + carry = (unsigned int)(tweak.u[0] >> 63); + tweak1.u[0] = (tweak.u[0] << 1) ^ res; + tweak1.u[1] = (tweak.u[1] << 1) | carry; +#if STRICT_ALIGNMENT memcpy(scratch.c, inp, 16); scratch.u[0] ^= tweak1.u[0]; scratch.u[1] ^= tweak1.u[1]; #else - scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak1.u[0]; - scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak1.u[1]; + scratch.u[0] = ((uint64_t *)inp)[0] ^ tweak1.u[0]; + scratch.u[1] = ((uint64_t *)inp)[1] ^ tweak1.u[1]; #endif (*ctx->block1)(scratch.c, scratch.c, ctx->key1); scratch.u[0] ^= tweak1.u[0]; @@ -192,13 +154,13 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, scratch.u[0] ^= tweak.u[0]; scratch.u[1] ^= tweak.u[1]; (*ctx->block1)(scratch.c, scratch.c, ctx->key1); -#if defined(STRICT_ALIGNMENT) +#if STRICT_ALIGNMENT scratch.u[0] ^= tweak.u[0]; scratch.u[1] ^= tweak.u[1]; memcpy(out, scratch.c, 16); #else - ((unint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0]; - ((unint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1]; + ((uint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0]; + ((uint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1]; #endif } @@ -286,7 +248,7 @@ static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { } static const EVP_CIPHER aes_256_xts = { - NID_aes_256_xts, 1 /* block_size */, 32 /* key_size */, + NID_aes_256_xts, 1 /* block_size */, 64 /* key_size (2 AES keys) */, 16 /* iv_len */, sizeof(EVP_AES_XTS_CTX), EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY, diff --git a/src/include/openssl/aead.h b/src/include/openssl/aead.h index 4f822e8..092d2f6 100644 --- a/src/include/openssl/aead.h +++ b/src/include/openssl/aead.h @@ -98,23 +98,15 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void); /* EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode. */ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void); +/* EVP_aead_chacha20_poly1305 is the AEAD built from ChaCha20 and + * Poly1305 as described in RFC 7539. */ +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void); + /* EVP_aead_chacha20_poly1305_old is an AEAD built from ChaCha20 and * Poly1305 that is used in the experimental ChaCha20-Poly1305 TLS cipher * suites. */ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void); -/* EVP_aead_chacha20_poly1305 is currently an alias for - * |EVP_aead_chacha20_poly1305_old|. In the future, the RFC 7539 version will - * take this name. */ -OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void); - -/* EVP_aead_chacha20_poly1305_rfc7539 is the AEAD built from ChaCha20 and - * Poly1305 as described in RFC 7539. - * - * WARNING: this function is not ready yet. It will be renamed in the future to - * drop the “_rfc7539” suffix. */ -OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void); - /* EVP_aead_aes_128_key_wrap is AES-128 Key Wrap mode. This should never be * used except to interoperate with existing systems that use this mode. * @@ -339,6 +331,14 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, size_t *out_len); +/* Deprecated functions. */ + +/* EVP_aead_chacha20_poly1305_rfc7539 calls |EVP_aead_chacha20_poly1305|. + * + * TODO(davidben): Remove this. */ +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void); + + #if defined(__cplusplus) } /* extern C */ #endif diff --git a/src/include/openssl/asn1.h b/src/include/openssl/asn1.h index 08886d1..63bde18 100644 --- a/src/include/openssl/asn1.h +++ b/src/include/openssl/asn1.h @@ -1126,43 +1126,42 @@ OPENSSL_EXPORT int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_f #define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 147 #define ASN1_R_INVALID_UTF8STRING 148 #define ASN1_R_LIST_ERROR 149 -#define ASN1_R_MALLOC_FAILURE 150 -#define ASN1_R_MISSING_ASN1_EOS 151 -#define ASN1_R_MISSING_EOC 152 -#define ASN1_R_MISSING_SECOND_NUMBER 153 -#define ASN1_R_MISSING_VALUE 154 -#define ASN1_R_MSTRING_NOT_UNIVERSAL 155 -#define ASN1_R_MSTRING_WRONG_TAG 156 -#define ASN1_R_NESTED_ASN1_ERROR 157 -#define ASN1_R_NESTED_ASN1_STRING 158 -#define ASN1_R_NON_HEX_CHARACTERS 159 -#define ASN1_R_NOT_ASCII_FORMAT 160 -#define ASN1_R_NOT_ENOUGH_DATA 161 -#define ASN1_R_NO_MATCHING_CHOICE_TYPE 162 -#define ASN1_R_NULL_IS_WRONG_LENGTH 163 -#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 164 -#define ASN1_R_ODD_NUMBER_OF_CHARS 165 -#define ASN1_R_SECOND_NUMBER_TOO_LARGE 166 -#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 167 -#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 168 -#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 169 -#define ASN1_R_SHORT_LINE 170 -#define ASN1_R_STREAMING_NOT_SUPPORTED 171 -#define ASN1_R_STRING_TOO_LONG 172 -#define ASN1_R_STRING_TOO_SHORT 173 -#define ASN1_R_TAG_VALUE_TOO_HIGH 174 -#define ASN1_R_TIME_NOT_ASCII_FORMAT 175 -#define ASN1_R_TOO_LONG 176 -#define ASN1_R_TYPE_NOT_CONSTRUCTED 177 -#define ASN1_R_TYPE_NOT_PRIMITIVE 178 -#define ASN1_R_UNEXPECTED_EOC 179 -#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 180 -#define ASN1_R_UNKNOWN_FORMAT 181 -#define ASN1_R_UNKNOWN_TAG 182 -#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 183 -#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 184 -#define ASN1_R_UNSUPPORTED_TYPE 185 -#define ASN1_R_WRONG_TAG 186 -#define ASN1_R_WRONG_TYPE 187 +#define ASN1_R_MISSING_ASN1_EOS 150 +#define ASN1_R_MISSING_EOC 151 +#define ASN1_R_MISSING_SECOND_NUMBER 152 +#define ASN1_R_MISSING_VALUE 153 +#define ASN1_R_MSTRING_NOT_UNIVERSAL 154 +#define ASN1_R_MSTRING_WRONG_TAG 155 +#define ASN1_R_NESTED_ASN1_ERROR 156 +#define ASN1_R_NESTED_ASN1_STRING 157 +#define ASN1_R_NON_HEX_CHARACTERS 158 +#define ASN1_R_NOT_ASCII_FORMAT 159 +#define ASN1_R_NOT_ENOUGH_DATA 160 +#define ASN1_R_NO_MATCHING_CHOICE_TYPE 161 +#define ASN1_R_NULL_IS_WRONG_LENGTH 162 +#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 163 +#define ASN1_R_ODD_NUMBER_OF_CHARS 164 +#define ASN1_R_SECOND_NUMBER_TOO_LARGE 165 +#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 166 +#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 167 +#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 168 +#define ASN1_R_SHORT_LINE 169 +#define ASN1_R_STREAMING_NOT_SUPPORTED 170 +#define ASN1_R_STRING_TOO_LONG 171 +#define ASN1_R_STRING_TOO_SHORT 172 +#define ASN1_R_TAG_VALUE_TOO_HIGH 173 +#define ASN1_R_TIME_NOT_ASCII_FORMAT 174 +#define ASN1_R_TOO_LONG 175 +#define ASN1_R_TYPE_NOT_CONSTRUCTED 176 +#define ASN1_R_TYPE_NOT_PRIMITIVE 177 +#define ASN1_R_UNEXPECTED_EOC 178 +#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 179 +#define ASN1_R_UNKNOWN_FORMAT 180 +#define ASN1_R_UNKNOWN_TAG 181 +#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 182 +#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 183 +#define ASN1_R_UNSUPPORTED_TYPE 184 +#define ASN1_R_WRONG_TAG 185 +#define ASN1_R_WRONG_TYPE 186 #endif diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h index 01115c8..6e971e4 100644 --- a/src/include/openssl/bn.h +++ b/src/include/openssl/bn.h @@ -253,6 +253,9 @@ OPENSSL_EXPORT size_t BN_bn2bin(const BIGNUM *in, uint8_t *out); * returns 0. Otherwise, it returns 1. */ OPENSSL_EXPORT int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in); +/* BN_bn2cbb_padded behaves like |BN_bn2bin_padded| but writes to a |CBB|. */ +OPENSSL_EXPORT int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in); + /* BN_bn2hex returns an allocated string that contains a NUL-terminated, hex * representation of |bn|. If |bn| is negative, the first char in the resulting * string will be '-'. Returns NULL on allocation failure. */ @@ -836,11 +839,7 @@ struct bignum_st { struct bn_mont_ctx_st { BIGNUM RR; /* used to convert to montgomery form */ BIGNUM N; /* The modulus */ - BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 - * (Ni is only stored for bignum algorithm) */ - BN_ULONG n0[2]; /* least significant word(s) of Ni; - (type changed with 0.9.9, was "BN_ULONG n0;" before) */ - int ri; /* number of bits in R */ + BN_ULONG n0[2]; /* least significant words of (R*Ri-1)/N */ }; OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l); diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h index 906e7e8..9193e11 100644 --- a/src/include/openssl/bytestring.h +++ b/src/include/openssl/bytestring.h @@ -238,13 +238,13 @@ struct cbb_buffer_st { struct cbb_st { struct cbb_buffer_st *base; - /* offset is the offset from the start of |base->buf| to the position of any - * pending length-prefix. */ - size_t offset; /* child points to a child CBB if a length-prefix is pending. */ CBB *child; - /* pending_len_len contains the number of bytes in a pending length-prefix, - * or zero if no length-prefix is pending. */ + /* offset is the number of bytes from the start of |base->buf| to this |CBB|'s + * pending length prefix. */ + size_t offset; + /* pending_len_len contains the number of bytes in this |CBB|'s pending + * length-prefix, or zero if no length-prefix is pending. */ uint8_t pending_len_len; char pending_is_asn1; /* is_top_level is true iff this is a top-level |CBB| (as opposed to a child @@ -292,12 +292,18 @@ OPENSSL_EXPORT int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len); * on error. */ OPENSSL_EXPORT int CBB_flush(CBB *cbb); -/* CBB_len returns the number of bytes written to |cbb|'s top-level |CBB|. It - * may be compared before and after an operation to determine how many bytes - * were written. +/* CBB_data returns a pointer to the bytes written to |cbb|. It does not flush + * |cbb|. The pointer is valid until the next operation to |cbb|. + * + * To avoid unfinalized length prefixes, it is a fatal error to call this on a + * CBB with any active children. */ +OPENSSL_EXPORT const uint8_t *CBB_data(const CBB *cbb); + +/* CBB_len returns the number of bytes written to |cbb|. It does not flush + * |cbb|. * - * It is a fatal error to call this on a CBB with any active children. This does - * not flush |cbb|. */ + * To avoid unfinalized length prefixes, it is a fatal error to call this on a + * CBB with any active children. */ OPENSSL_EXPORT size_t CBB_len(const CBB *cbb); /* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The @@ -332,6 +338,17 @@ OPENSSL_EXPORT int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len); * otherwise. */ OPENSSL_EXPORT int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len); +/* CBB_reserve ensures |cbb| has room for |len| additional bytes and sets + * |*out_data| to point to the beginning of that space. It returns one on + * success and zero otherwise. The caller may write up to |len| bytes to + * |*out_data| and call |CBB_did_write| to complete the write. |*out_data| is + * valid until the next operation on |cbb| or an ancestor |CBB|. */ +OPENSSL_EXPORT int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len); + +/* CBB_did_write advances |cbb| by |len| bytes, assuming the space has been + * written to by the caller. It returns one on success and zero on error. */ +OPENSSL_EXPORT int CBB_did_write(CBB *cbb, size_t len); + /* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on * success and zero otherwise. */ OPENSSL_EXPORT int CBB_add_u8(CBB *cbb, uint8_t value); diff --git a/src/include/openssl/cpu.h b/src/include/openssl/cpu.h index 19e11d0..e946304 100644 --- a/src/include/openssl/cpu.h +++ b/src/include/openssl/cpu.h @@ -102,10 +102,20 @@ extern uint32_t OPENSSL_ia32cap_P[4]; #if !defined(OPENSSL_STATIC_ARMCAP) -/* CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. Note - * that |OPENSSL_armcap_P| also exists and contains the same information in a - * form that's easier for assembly to use. */ -OPENSSL_EXPORT char CRYPTO_is_NEON_capable(void); +/* CRYPTO_is_NEON_capable_at_runtime returns true if the current CPU has a NEON + * unit. Note that |OPENSSL_armcap_P| also exists and contains the same + * information in a form that's easier for assembly to use. */ +OPENSSL_EXPORT char CRYPTO_is_NEON_capable_at_runtime(void); + +/* CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. If + * this is known statically then it returns one immediately. */ +static inline int CRYPTO_is_NEON_capable(void) { +#if defined(__ARM_NEON__) + return 1; +#else + return CRYPTO_is_NEON_capable_at_runtime(); +#endif +} /* CRYPTO_set_NEON_capable sets the return value of |CRYPTO_is_NEON_capable|. * By default, unless the code was compiled with |-mfpu=neon|, NEON is assumed diff --git a/src/include/openssl/curve25519.h b/src/include/openssl/curve25519.h new file mode 100644 index 0000000..30c6470 --- /dev/null +++ b/src/include/openssl/curve25519.h @@ -0,0 +1,92 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CURVE25519_H +#define OPENSSL_HEADER_CURVE25519_H + +#include <openssl/base.h> + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* Curve25519. + * + * Curve25519 is an elliptic curve. See + * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11. */ + + +/* X25519. + * + * Curve25519 is an elliptic curve. The same name is also sometimes used for + * the Diffie-Hellman primitive built from it but “X25519” is a more precise + * name for that, which is the one used here. See http://cr.yp.to/ecdh.html and + * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11. */ + +/* X25519_keypair sets |out_public_value| and |out_private_key| to a freshly + * generated, public–private key pair. */ +OPENSSL_EXPORT void X25519_keypair(uint8_t out_public_value[32], + uint8_t out_private_key[32]); + +/* X25519 writes a shared key to |out_shared_key| that is calculated from the + * given private key and the peer's public value. It returns one on success and + * zero on error. + * + * Don't use the shared key directly, rather use a KDF and also include the two + * public values as inputs. */ +OPENSSL_EXPORT int X25519(uint8_t out_shared_key[32], + const uint8_t private_key[32], + const uint8_t peers_public_value[32]); + +/* X25519_public_from_private calculates a Diffie-Hellman public value from the + * given private key and writes it to |out_public_value|. */ +OPENSSL_EXPORT void X25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]); + + +/* Ed25519. + * + * Ed25519 is a signature scheme using a twisted-Edwards curve that is + * birationally equivalent to curve25519. */ + +#define ED25519_PRIVATE_KEY_LEN 64 +#define ED25519_PUBLIC_KEY_LEN 32 +#define ED25519_SIGNATURE_LEN 64 + +/* ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly + * generated, public–private key pair. */ +OPENSSL_EXPORT void ED25519_keypair(uint8_t out_public_key[32], + uint8_t out_private_key[64]); + +/* ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from + * |message| using |private_key|. It returns one on success or zero on + * error. */ +OPENSSL_EXPORT int ED25519_sign(uint8_t out_sig[64], const uint8_t *message, + size_t message_len, + const uint8_t private_key[64]); + +/* ED25519_verify returns one iff |signature| is a valid signature, by + * |public_key| of |message_len| bytes from |message|. It returns zero + * otherwise. */ +OPENSSL_EXPORT int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], + const uint8_t public_key[32]); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_CURVE25519_H */ diff --git a/src/include/openssl/dh.h b/src/include/openssl/dh.h index d781789..2c49fc8 100644 --- a/src/include/openssl/dh.h +++ b/src/include/openssl/dh.h @@ -193,7 +193,7 @@ OPENSSL_EXPORT int i2d_DHparams(const DH *in, unsigned char **outp); * See |ex_data.h| for details. */ OPENSSL_EXPORT int DH_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); OPENSSL_EXPORT int DH_set_ex_data(DH *d, int idx, void *arg); diff --git a/src/include/openssl/dsa.h b/src/include/openssl/dsa.h index bd16395..2045fe7 100644 --- a/src/include/openssl/dsa.h +++ b/src/include/openssl/dsa.h @@ -302,7 +302,7 @@ OPENSSL_EXPORT DH *DSA_dup_DH(const DSA *dsa); * See |ex_data.h| for details. */ OPENSSL_EXPORT int DSA_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); OPENSSL_EXPORT int DSA_set_ex_data(DSA *d, int idx, void *arg); diff --git a/src/include/openssl/ec.h b/src/include/openssl/ec.h index ac36a32..667be3b 100644 --- a/src/include/openssl/ec.h +++ b/src/include/openssl/ec.h @@ -120,10 +120,9 @@ OPENSSL_EXPORT int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, * in |group| that specifies the generator for the group. */ OPENSSL_EXPORT const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); -/* EC_GROUP_get_order sets |*order| to the order of |group|, if it's not - * NULL. It returns one on success and zero otherwise. |ctx| is ignored. */ -OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, - BN_CTX *ctx); +/* EC_GROUP_get0_order returns a pointer to the internal |BIGNUM| object in + * |group| that specifies the order of the group. */ +OPENSSL_EXPORT const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); /* EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group| using * |ctx|, if it's not NULL. It returns one on success and zero otherwise. */ @@ -146,15 +145,6 @@ OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group); * element of the field underlying |group|. */ OPENSSL_EXPORT unsigned EC_GROUP_get_degree(const EC_GROUP *group); -/* EC_GROUP_precompute_mult precomputes multiplies of the generator in order to - * speed up operations that involve calculating generator multiples. It returns - * one on sucess and zero otherwise. If |ctx| is not NULL, it may be used. */ -OPENSSL_EXPORT int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); - -/* EC_GROUP_have_precompute_mult returns one if |group| contains precomputed - * generator multiples. */ -OPENSSL_EXPORT int EC_GROUP_have_precompute_mult(const EC_GROUP *group); - /* Points on elliptic curves. */ @@ -278,13 +268,6 @@ OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); -/* EC_POINTs_mul sets r = generator*n + sum(p[i]*m[i]). It returns one on - * success and zero otherwise. If |ctx| is not NULL, it may be used. */ -OPENSSL_EXPORT int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *n, size_t num, - const EC_POINT *p[], const BIGNUM *m[], - BN_CTX *ctx); - /* Deprecated functions. */ @@ -299,6 +282,12 @@ OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +/* EC_GROUP_get_order sets |*order| to the order of |group|, if it's not + * NULL. It returns one on success and zero otherwise. |ctx| is ignored. Use + * |EC_GROUP_get0_order| instead. */ +OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, + BN_CTX *ctx); + /* EC_GROUP_set_generator sets the generator for |group| to |generator|, which * must have the given order and cofactor. This should only be used with * |EC_GROUP| objects returned by |EC_GROUP_new_curve_GFp|. */ diff --git a/src/include/openssl/ec_key.h b/src/include/openssl/ec_key.h index 1cd4e6e..afd95d6 100644 --- a/src/include/openssl/ec_key.h +++ b/src/include/openssl/ec_key.h @@ -154,12 +154,6 @@ OPENSSL_EXPORT point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); OPENSSL_EXPORT void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform); -/* EC_KEY_precompute_mult precomputes multiplies of the generator of the - * underlying group in order to speed up operations that calculate generator - * multiples. If |ctx| is not NULL, it may be used. It returns one on success - * and zero otherwise. */ -OPENSSL_EXPORT int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); - /* EC_KEY_check_key performs several checks on |key| (possibly including an * expensive check that the public key is in the primary subgroup). It returns * one if all checks pass and zero otherwise. If it returns zero then detail @@ -232,7 +226,7 @@ OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); * These functions are wrappers. See |ex_data.h| for details. */ OPENSSL_EXPORT int EC_KEY_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); OPENSSL_EXPORT int EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg); diff --git a/src/include/openssl/evp.h b/src/include/openssl/evp.h index 6f594e5..be2ea33 100644 --- a/src/include/openssl/evp.h +++ b/src/include/openssl/evp.h @@ -143,31 +143,30 @@ OPENSSL_EXPORT int EVP_PKEY_type(int nid); * The following functions get and set the underlying public key in an * |EVP_PKEY| object. The |set1| functions take an additional reference to the * underlying key and return one on success or zero on error. The |assign| - * functions adopt the caller's reference. The getters return a fresh reference - * to the underlying object. */ + * functions adopt the caller's reference. The |get1| functions return a fresh + * reference to the underlying object or NULL if |pkey| is not of the correct + * type. The |get0| functions behave the same but return a non-owning + * pointer. */ OPENSSL_EXPORT int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key); OPENSSL_EXPORT int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key); +OPENSSL_EXPORT RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); OPENSSL_EXPORT RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); OPENSSL_EXPORT int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key); OPENSSL_EXPORT int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key); +OPENSSL_EXPORT DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); OPENSSL_EXPORT DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); OPENSSL_EXPORT int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); OPENSSL_EXPORT int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); +OPENSSL_EXPORT EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); -OPENSSL_EXPORT int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key); -OPENSSL_EXPORT int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key); -OPENSSL_EXPORT DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey); - #define EVP_PKEY_NONE NID_undef #define EVP_PKEY_RSA NID_rsaEncryption #define EVP_PKEY_RSA2 NID_rsa #define EVP_PKEY_DSA NID_dsa -#define EVP_PKEY_DH NID_dhKeyAgreement -#define EVP_PKEY_DHX NID_dhpublicnumber #define EVP_PKEY_EC NID_X9_62_id_ecPublicKey /* EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of @@ -643,6 +642,10 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, /* Deprecated functions. */ +/* EVP_PKEY_DH is defined for compatibility, but it is impossible to create an + * |EVP_PKEY| of that type. */ +#define EVP_PKEY_DH NID_dhKeyAgreement + /* OpenSSL_add_all_algorithms does nothing. */ OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void); diff --git a/src/include/openssl/ex_data.h b/src/include/openssl/ex_data.h index c0d3773..e78e070 100644 --- a/src/include/openssl/ex_data.h +++ b/src/include/openssl/ex_data.h @@ -121,8 +121,8 @@ extern "C" { /* ex_data is a mechanism for associating arbitrary extra data with objects. * For each type of object that supports ex_data, different users can be * assigned indexes in which to store their data. Each index has callback - * functions that are called when a new object of that type is created, freed - * and duplicated. */ + * functions that are called when an object of that type is freed or + * duplicated. */ typedef struct crypto_ex_data_st CRYPTO_EX_DATA; @@ -142,7 +142,7 @@ typedef struct crypto_ex_data_st CRYPTO_EX_DATA; * * TODO(fork): this should follow the standard calling convention. */ OPENSSL_EXPORT int TYPE_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); @@ -160,27 +160,19 @@ OPENSSL_EXPORT void *TYPE_get_ex_data(const TYPE *t, int index); /* Callback types. */ -/* CRYPTO_EX_new is the type of a callback function that is called whenever a - * new object of a given class is created. For example, if this callback has - * been passed to |SSL_get_ex_new_index| then it'll be called each time an SSL* - * is created. +/* CRYPTO_EX_free is a callback function that is called when an object of the + * class with extra data pointers is being destroyed. For example, if this + * callback has been passed to |SSL_get_ex_new_index| then it may be called each + * time an |SSL*| is destroyed. * - * The callback is passed the new object (i.e. the SSL*) in |parent|. The + * The callback is passed the new object (i.e. the |SSL*|) in |parent|. The * arguments |argl| and |argp| contain opaque values that were given to * |CRYPTO_get_ex_new_index|. The callback should return one on success, but * the value is ignored. * - * TODO(fork): the |ptr| argument is always NULL, no? */ -typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad, - int index, long argl, void *argp); - -/* CRYPTO_EX_free is a callback function that is called when an object of the - * class is being destroyed. See |CRYPTO_EX_new| for a discussion of the - * arguments. - * - * If |CRYPTO_get_ex_new_index| was called after the creation of objects of the - * class that this applies to then, when those those objects are destroyed, - * this callback will be called with a NULL value for |ptr|. */ + * This callback may be called with a NULL value for |ptr| if |parent| has no + * value set for this index. However, the callbacks may also be skipped entirely + * if no extra data pointers are set on |parent| at all. */ typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int index, long argl, void *argp); @@ -190,9 +182,9 @@ typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, * original object. When the callback returns, |*from_d| will be set as the * data for this index in |to|. * - * If |CRYPTO_get_ex_new_index| was called after the creation of objects of the - * class that this applies to then, when those those objects are copies, this - * callback will be called with a NULL value for |*from_d|. */ + * This callback may be called with a NULL value for |*from_d| if |from| has no + * value set for this index. However, the callbacks may also be skipped entirely + * if no extra data pointers are set on |from| at all. */ typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, void **from_d, int index, long argl, void *argp); @@ -202,6 +194,13 @@ typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, /* CRYPTO_cleanup_all_ex_data does nothing. */ OPENSSL_EXPORT void CRYPTO_cleanup_all_ex_data(void); + +/* Private structures. */ + +/* CRYPTO_EX_unused is a placeholder for an unused callback. It is aliased to + * int to ensure non-NULL callers fail to compile rather than fail silently. */ +typedef int CRYPTO_EX_unused; + struct crypto_ex_data_st { STACK_OF(void) *sk; }; diff --git a/src/include/openssl/md4.h b/src/include/openssl/md4.h index e363b73..93c7af8 100644 --- a/src/include/openssl/md4.h +++ b/src/include/openssl/md4.h @@ -90,8 +90,8 @@ OPENSSL_EXPORT void MD4_Transform(MD4_CTX *md4, const uint8_t *block); struct md4_state_st { uint32_t h[4]; uint32_t Nl, Nh; - uint32_t data[16]; - unsigned int num; + uint8_t data[MD4_CBLOCK]; + unsigned num; }; diff --git a/src/include/openssl/md5.h b/src/include/openssl/md5.h index 87c3ba4..55162f0 100644 --- a/src/include/openssl/md5.h +++ b/src/include/openssl/md5.h @@ -95,8 +95,8 @@ OPENSSL_EXPORT void MD5_Transform(MD5_CTX *md5, const uint8_t *block); struct md5_state_st { uint32_t h[4]; uint32_t Nl, Nh; - uint32_t data[16]; - unsigned int num; + uint8_t data[MD5_CBLOCK]; + unsigned num; }; diff --git a/src/include/openssl/obj_mac.h b/src/include/openssl/obj_mac.h index 55e1cba..b636adc 100644 --- a/src/include/openssl/obj_mac.h +++ b/src/include/openssl/obj_mac.h @@ -4138,3 +4138,7 @@ #define SN_dh_cofactor_kdf "dh-cofactor-kdf" #define NID_dh_cofactor_kdf 947 +#define SN_x25519 "X25519" +#define LN_x25519 "x25519" +#define NID_x25519 948 + diff --git a/src/include/openssl/pem.h b/src/include/openssl/pem.h index db763d5..a6687a6 100644 --- a/src/include/openssl/pem.h +++ b/src/include/openssl/pem.h @@ -125,11 +125,9 @@ extern "C" { #define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" #define PEM_STRING_PKCS8INF "PRIVATE KEY" #define PEM_STRING_DHPARAMS "DH PARAMETERS" -#define PEM_STRING_DHXPARAMS "X9.42 DH PARAMETERS" #define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" #define PEM_STRING_DSAPARAMS "DSA PARAMETERS" #define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" -#define PEM_STRING_ECPARAMETERS "EC PARAMETERS" #define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" #define PEM_STRING_PARAMETERS "PARAMETERS" #define PEM_STRING_CMS "CMS" @@ -454,13 +452,11 @@ DECLARE_PEM_rw_const(DSAparams, DSA) #endif -DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) DECLARE_PEM_rw_const(DHparams, DH) -DECLARE_PEM_write_const(DHxparams, DH) DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) diff --git a/src/include/openssl/rand.h b/src/include/openssl/rand.h index de1bd8d..3a8e357 100644 --- a/src/include/openssl/rand.h +++ b/src/include/openssl/rand.h @@ -68,7 +68,8 @@ OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd); /* RAND_pseudo_bytes is a wrapper around |RAND_bytes|. */ OPENSSL_EXPORT int RAND_pseudo_bytes(uint8_t *buf, size_t len); -/* RAND_seed does nothing. */ +/* RAND_seed reads a single byte of random data to ensure that any file + * descriptors etc are opened. */ OPENSSL_EXPORT void RAND_seed(const void *buf, int num); /* RAND_load_file returns a nonnegative number. */ diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h index e624f7c..304c555 100644 --- a/src/include/openssl/rsa.h +++ b/src/include/openssl/rsa.h @@ -124,8 +124,8 @@ OPENSSL_EXPORT int RSA_generate_multi_prime_key(RSA *rsa, int bits, * It returns 1 on success or zero on error. * * The |padding| argument must be one of the |RSA_*_PADDING| values. If in - * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_OAEP_PADDING| - * is the most secure. */ + * doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but + * |RSA_PKCS1_PADDING| is most common. */ OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); @@ -137,8 +137,14 @@ OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, * It returns 1 on success or zero on error. * * The |padding| argument must be one of the |RSA_*_PADDING| values. If in - * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_OAEP_PADDING| - * is the most secure. */ + * doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. + * + * Passing |RSA_PKCS1_PADDING| into this function is deprecated and insecure. If + * implementing a protocol using RSAES-PKCS1-V1_5, use |RSA_NO_PADDING| and then + * check padding in constant-time combined with a swap to a random session key + * or other mitigation. See "Chosen Ciphertext Attacks Against Protocols Based + * on the RSA Encryption Standard PKCS #1", Daniel Bleichenbacher, Advances in + * Cryptology (Crypto '98). */ OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); @@ -147,8 +153,8 @@ OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, * |rsa| and writes the encrypted data to |to|. The |to| buffer must have at * least |RSA_size| bytes of space. It returns the number of bytes written, or * -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| - * values. If in doubt, |RSA_PKCS1_PADDING| is the most common but - * |RSA_PKCS1_OAEP_PADDING| is the most secure. + * values. If in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but + * |RSA_PKCS1_PADDING| is most common. * * WARNING: this function is dangerous because it breaks the usual return value * convention. Use |RSA_encrypt| instead. */ @@ -156,37 +162,25 @@ OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding); /* RSA_private_decrypt decrypts |flen| bytes from |from| with the public key in - * |rsa| and writes the plaintext to |to|. The |to| buffer must have at - * least |RSA_size| bytes of space. It returns the number of bytes written, or - * -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| - * values. If in doubt, |RSA_PKCS1_PADDING| is the most common but - * |RSA_PKCS1_OAEP_PADDING| is the most secure. + * |rsa| and writes the plaintext to |to|. The |to| buffer must have at least + * |RSA_size| bytes of space. It returns the number of bytes written, or -1 on + * error. The |padding| argument must be one of the |RSA_*_PADDING| values. If + * in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. Passing + * |RSA_PKCS1_PADDING| into this function is deprecated and insecure. See + * |RSA_decrypt|. * * WARNING: this function is dangerous because it breaks the usual return value * convention. Use |RSA_decrypt| instead. */ OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding); -/* RSA_message_index_PKCS1_type_2 performs the first step of a PKCS #1 padding - * check for decryption. If the |from_len| bytes pointed to at |from| are a - * valid PKCS #1 message, it returns one and sets |*out_index| to the start of - * the unpadded message. The unpadded message is a suffix of the input and has - * length |from_len - *out_index|. Otherwise, it returns zero and sets - * |*out_index| to zero. This function runs in time independent of the input - * data and is intended to be used directly to avoid Bleichenbacher's attack. - * - * WARNING: This function behaves differently from the usual OpenSSL convention - * in that it does NOT put an error on the queue in the error case. */ -OPENSSL_EXPORT int RSA_message_index_PKCS1_type_2(const uint8_t *from, - size_t from_len, - size_t *out_index); - /* Signing / Verification */ -/* RSA_sign signs |in_len| bytes of digest from |in| with |rsa| and writes, at - * most, |RSA_size(rsa)| bytes to |out|. On successful return, the actual - * number of bytes written is written to |*out_len|. +/* RSA_sign signs |in_len| bytes of digest from |in| with |rsa| using + * RSASSA-PKCS1-v1_5. It writes, at most, |RSA_size(rsa)| bytes to |out|. On + * successful return, the actual number of bytes written is written to + * |*out_len|. * * The |hash_nid| argument identifies the hash function used to calculate |in| * and is embedded in the resulting signature. For example, it might be @@ -204,13 +198,14 @@ OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *in, * It returns 1 on success or zero on error. * * The |padding| argument must be one of the |RSA_*_PADDING| values. If in - * doubt, |RSA_PKCS1_PADDING| is the most common. */ + * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_PSS_PADDING| + * (via the |EVP_PKEY| interface) is preferred for new protocols. */ OPENSSL_EXPORT int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); -/* RSA_verify verifies that |sig_len| bytes from |sig| are a valid, PKCS#1 - * signature of |msg_len| bytes at |msg| by |rsa|. +/* RSA_verify verifies that |sig_len| bytes from |sig| are a valid, + * RSASSA-PKCS1-v1_5 signature of |msg_len| bytes at |msg| by |rsa|. * * The |hash_nid| argument identifies the hash function used to calculate |in| * and is embedded in the resulting signature in order to prevent hash @@ -231,7 +226,8 @@ OPENSSL_EXPORT int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, * It returns 1 on success or zero on error. * * The |padding| argument must be one of the |RSA_*_PADDING| values. If in - * doubt, |RSA_PKCS1_PADDING| is the most common. */ + * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_PSS_PADDING| + * (via the |EVP_PKEY| interface) is preferred for new protocols. */ OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); @@ -240,7 +236,9 @@ OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, * |rsa| and writes the encrypted data to |to|. The |to| buffer must have at * least |RSA_size| bytes of space. It returns the number of bytes written, or * -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| - * values. If in doubt, |RSA_PKCS1_PADDING| is the most common. + * values. If in doubt, |RSA_PKCS1_PADDING| is the most common but + * |RSA_PKCS1_PSS_PADDING| (via the |EVP_PKEY| interface) is preferred for new + * protocols. * * WARNING: this function is dangerous because it breaks the usual return value * convention. Use |RSA_sign_raw| instead. */ @@ -251,7 +249,9 @@ OPENSSL_EXPORT int RSA_private_encrypt(size_t flen, const uint8_t *from, * public key in |rsa| and writes the plaintext to |to|. The |to| buffer must * have at least |RSA_size| bytes of space. It returns the number of bytes * written, or -1 on error. The |padding| argument must be one of the - * |RSA_*_PADDING| values. If in doubt, |RSA_PKCS1_PADDING| is the most common. + * |RSA_*_PADDING| values. If in doubt, |RSA_PKCS1_PADDING| is the most common + * but |RSA_PKCS1_PSS_PADDING| (via the |EVP_PKEY| interface) is preferred for + * new protocols. * * WARNING: this function is dangerous because it breaks the usual return value * convention. Use |RSA_verify_raw| instead. */ @@ -386,7 +386,7 @@ OPENSSL_EXPORT int RSA_private_key_to_bytes(uint8_t **out_bytes, * See |ex_data.h| for details. */ OPENSSL_EXPORT int RSA_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); OPENSSL_EXPORT int RSA_set_ex_data(RSA *r, int idx, void *arg); diff --git a/src/include/openssl/sha.h b/src/include/openssl/sha.h index f4253ec..48a52e8f 100644 --- a/src/include/openssl/sha.h +++ b/src/include/openssl/sha.h @@ -98,7 +98,7 @@ OPENSSL_EXPORT uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out); OPENSSL_EXPORT void SHA1_Transform(SHA_CTX *sha, const uint8_t *block); struct sha_state_st { -#if !defined(ANDROID) +#if defined(OPENSSL_WINDOWS) uint32_t h[5]; #else /* wpa_supplicant accesses |h0|..|h4| so we must support those names @@ -115,8 +115,8 @@ struct sha_state_st { }; #endif uint32_t Nl, Nh; - uint32_t data[16]; - unsigned int num; + uint8_t data[SHA_CBLOCK]; + unsigned num; }; @@ -176,8 +176,8 @@ OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, const uint8_t *data); struct sha256_state_st { uint32_t h[8]; uint32_t Nl, Nh; - uint32_t data[16]; - unsigned int num, md_len; + uint8_t data[SHA256_CBLOCK]; + unsigned num, md_len; }; @@ -245,7 +245,7 @@ struct sha512_state_st { uint64_t d[16]; uint8_t p[128]; } u; - unsigned int num, md_len; + unsigned num, md_len; }; diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h index 38d838d..dcfee91 100644 --- a/src/include/openssl/ssl.h +++ b/src/include/openssl/ssl.h @@ -542,23 +542,6 @@ OPENSSL_EXPORT int SSL_version(const SSL *ssl); * * Options configure protocol behavior. */ -/* SSL_OP_LEGACY_SERVER_CONNECT allows initial connections to servers that don't - * support the renegotiation_info extension (RFC 5746). It is on by default. */ -#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L - -/* SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER allows for record sizes |SSL3_RT_MAX_EXTRA| - * bytes above the maximum record size. */ -#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L - -/* SSL_OP_TLS_D5_BUG accepts an RSAClientKeyExchange in TLS encoded as in SSL3 - * (i.e. without a length prefix). */ -#define SSL_OP_TLS_D5_BUG 0x00000100L - -/* SSL_OP_ALL enables the above bug workarounds that are enabled by many - * consumers. - * TODO(davidben): Determine which of the remaining may be removed now. */ -#define SSL_OP_ALL 0x00000BFFL - /* SSL_OP_NO_QUERY_MTU, in DTLS, disables querying the MTU from the underlying * |BIO|. Instead, the MTU is configured with |SSL_set_mtu|. */ #define SSL_OP_NO_QUERY_MTU 0x00001000L @@ -877,15 +860,16 @@ OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); * input DER-encoded structures. They return one on success and zero on * failure. */ -OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, - const uint8_t *d); +OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der); OPENSSL_EXPORT int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, - int len); + size_t der_len); OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, - const uint8_t *d, long len); + const uint8_t *der, + size_t der_len); OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, - const uint8_t *d, long len); + const uint8_t *der, size_t der_len); OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der, @@ -1051,8 +1035,18 @@ OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher); /* SSL_CIPHER_is_AES128GCM returns one if |cipher| uses 128-bit AES-GCM. */ OPENSSL_EXPORT int SSL_CIPHER_is_AES128GCM(const SSL_CIPHER *cipher); +/* SSL_CIPHER_is_AES128CBC returns one if |cipher| uses 128-bit AES in CBC + * mode. */ +OPENSSL_EXPORT int SSL_CIPHER_is_AES128CBC(const SSL_CIPHER *cipher); + +/* SSL_CIPHER_is_AES256CBC returns one if |cipher| uses 256-bit AES in CBC + * mode. */ +OPENSSL_EXPORT int SSL_CIPHER_is_AES256CBC(const SSL_CIPHER *cipher); + /* SSL_CIPHER_is_CHACHA20POLY1305 returns one if |cipher| uses - * CHACHA20_POLY1305. */ + * CHACHA20_POLY1305. Note this includes both the + * draft-ietf-tls-chacha20-poly1305-04 and draft-agl-tls-chacha20poly1305-04 + * versions. */ OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher); /* SSL_CIPHER_is_NULL returns one if |cipher| does not encrypt. */ @@ -1067,6 +1061,9 @@ OPENSSL_EXPORT int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher); /* SSL_CIPHER_is_ECDSA returns one if |cipher| uses ECDSA. */ OPENSSL_EXPORT int SSL_CIPHER_is_ECDSA(const SSL_CIPHER *cipher); +/* SSL_CIPHER_is_ECDHE returns one if |cipher| uses ECDHE. */ +OPENSSL_EXPORT int SSL_CIPHER_is_ECDHE(const SSL_CIPHER *cipher); + /* SSL_CIPHER_get_min_version returns the minimum protocol version required * for |cipher|. */ OPENSSL_EXPORT uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher); @@ -1157,10 +1154,9 @@ OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, * |kEDH|, |EDH|, |kEECDH|, and |EECDH| are legacy aliases for |kDHE|, |DHE|, * |kECDHE|, and |ECDHE|, respectively. * - * |MEDIUM| and |HIGH| match ciphers historically labeled by OpenSSL as - * 'medium' and 'high', respectively. + * |MEDIUM| and |HIGH| match RC4-based ciphers and all others, respectively. * - * |FIPS| matches ciphers historically FIPS-approved in OpenSSL. + * |FIPS| is an alias for |HIGH|. * * |SSLv3| and |TLSv1| match ciphers available in TLS 1.1 or earlier. * |TLSv1_2| matches ciphers new in TLS 1.2. This is confusing and should not @@ -1800,48 +1796,6 @@ OPENSSL_EXPORT int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves, size_t curves_len); -/* SSL_CTX_set_tmp_ecdh configures |ctx| to use the curve from |ecdh| as the - * curve for ephemeral ECDH keys. For historical reasons, this API expects an - * |EC_KEY|, but only the curve is used. It returns one on success and zero on - * error. If unset, an appropriate curve will be chosen based on curve - * preferences. (This is recommended.) */ -OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key); - -/* SSL_set_tmp_ecdh configures |ssl| to use the curve from |ecdh| as the curve - * for ephemeral ECDH keys. For historical reasons, this API expects an - * |EC_KEY|, but only the curve is used. It returns one on success and zero on - * error. If unset, an appropriate curve will be chosen based on curve - * preferences. (This is recommended.) */ -OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key); - -/* SSL_CTX_set_tmp_ecdh_callback configures |ctx| to use |callback| to determine - * the curve for ephemeral ECDH keys. |callback| should ignore |is_export| and - * |keylength| and return an |EC_KEY| of the selected curve or NULL on - * error. Only the curve is used, so the |EC_KEY| needn't have a generated - * keypair. - * - * If the callback is unset, an appropriate curve will be chosen based on curve - * preferences. (This is recommended.) - * - * WARNING: The caller does not take ownership of the resulting |EC_KEY|, so - * |callback| must save and release the object elsewhere. */ -OPENSSL_EXPORT void SSL_CTX_set_tmp_ecdh_callback( - SSL_CTX *ctx, EC_KEY *(*callback)(SSL *ssl, int is_export, int keylength)); - -/* SSL_set_tmp_ecdh_callback configures |ssl| to use |callback| to determine the - * curve for ephemeral ECDH keys. |callback| should ignore |is_export| and - * |keylength| and return an |EC_KEY| of the selected curve or NULL on - * error. Only the curve is used, so the |EC_KEY| needn't have a generated - * keypair. - * - * If the callback is unset, an appropriate curve will be chosen based on curve - * preferences. (This is recommended.) - * - * WARNING: The caller does not take ownership of the resulting |EC_KEY|, so - * |callback| must save and release the object elsewhere. */ -OPENSSL_EXPORT void SSL_set_tmp_ecdh_callback( - SSL *ssl, EC_KEY *(*callback)(SSL *ssl, int is_export, int keylength)); - /* SSL_get_curve_name returns a human-readable name for the elliptic curve * specified by the given TLS curve id, or NULL if the curve if unknown. */ OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id); @@ -2421,6 +2375,8 @@ DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE) #define SRTP_AES128_F8_SHA1_32 0x0004 #define SRTP_NULL_SHA1_80 0x0005 #define SRTP_NULL_SHA1_32 0x0006 +#define SRTP_AEAD_AES_128_GCM 0x0007 +#define SRTP_AEAD_AES_256_GCM 0x0008 /* SSL_CTX_set_srtp_profiles enables SRTP for all SSL objects created from * |ctx|. |profile| contains a colon-separated list of profile names. It returns @@ -2597,7 +2553,7 @@ OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value); OPENSSL_EXPORT int SSL_set_ex_data(SSL *ssl, int idx, void *data); OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl, int idx); OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); @@ -2606,14 +2562,14 @@ OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx); OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data); OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); @@ -2674,13 +2630,15 @@ OPENSSL_EXPORT void SSL_set_msg_callback( /* SSL_set_msg_callback_arg sets the |arg| parameter of the message callback. */ OPENSSL_EXPORT void SSL_set_msg_callback_arg(SSL *ssl, void *arg); -/* SSL_CTX_set_keylog_bio sets configures all SSL objects attached to |ctx| to - * log session material to |keylog_bio|. This is intended for debugging use - * with tools like Wireshark. |ctx| takes ownership of |keylog_bio|. +/* SSL_CTX_set_keylog_callback configures a callback to log key material. This + * is intended for debugging use with tools like Wireshark. The |cb| function + * should log |line| followed by a newline, synchronizing with any concurrent + * access to the log. * * The format is described in * https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. */ -OPENSSL_EXPORT void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio); +OPENSSL_EXPORT void SSL_CTX_set_keylog_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, const char *line)); enum ssl_renegotiate_mode_t { ssl_renegotiate_never = 0, @@ -2748,20 +2706,6 @@ OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment); -/* OPENSSL_get_big_buffer_use_count returns the total number of invalid TLS - * records that were accepted because of |SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER|. - * - * TODO(davidben): Remove this when (hopefully!) the quirk is demonstrated to be - * unnecessary. */ -OPENSSL_EXPORT uint64_t OPENSSL_get_big_buffer_use_count(void); - -/* OPENSSL_get_d5_bug_use_count returns the total number of invalid RSA - * ClientKeyExchanges that were accepted because of |SSL_OP_TLS_D5_BUG|. - * - * TODO(davidben): Remove this when (hopefully!) the quirk is demonstrated to be - * unnecessary. */ -OPENSSL_EXPORT uint64_t OPENSSL_get_d5_bug_use_count(void); - /* ssl_early_callback_ctx is passed to certain callbacks that are called very * early on during the server handshake. At this point, much of the SSL* hasn't * been filled out and only the ClientHello can be depended on. */ @@ -2932,7 +2876,7 @@ OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject); * freed with |OPENSSL_free|, or NULL on error. * * The description includes a trailing newline and has the form: - * AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 + * AES128-SHA Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 * * Consider |SSL_CIPHER_get_name| or |SSL_CIPHER_get_rfc_name| instead. */ OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, @@ -3177,9 +3121,12 @@ DECLARE_STACK_OF(SSL_COMP) #define SSL_MODE_RELEASE_BUFFERS 0 #define SSL_MODE_SEND_CLIENTHELLO_TIME 0 #define SSL_MODE_SEND_SERVERHELLO_TIME 0 +#define SSL_OP_ALL 0 #define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0 #define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0 #define SSL_OP_EPHEMERAL_RSA 0 +#define SSL_OP_LEGACY_SERVER_CONNECT 0 +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0 #define SSL_OP_MICROSOFT_SESS_ID_BUG 0 #define SSL_OP_MSIE_SSLV2_RSA_PADDING 0 #define SSL_OP_NETSCAPE_CA_DN_BUG 0 @@ -3196,6 +3143,7 @@ DECLARE_STACK_OF(SSL_COMP) #define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0 #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0 #define SSL_OP_TLS_BLOCK_PADDING_BUG 0 +#define SSL_OP_TLS_D5_BUG 0 #define SSL_OP_TLS_ROLLBACK_BUG 0 #define SSL_VERIFY_CLIENT_ONCE 0 @@ -3347,6 +3295,14 @@ OPENSSL_EXPORT const char *SSL_state_string(const SSL *ssl); * Use |SSL_CTX_set_quiet_shutdown| instead. */ OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode); +/* SSL_CTX_set_tmp_ecdh calls |SSL_CTX_set1_curves| with a one-element list + * containing |ec_key|'s curve. */ +OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key); + +/* SSL_set_tmp_ecdh calls |SSL_set1_curves| with a one-element list containing + * |ec_key|'s curve. */ +OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key); + /* Private structures. * @@ -3363,22 +3319,20 @@ struct ssl_cipher_st { /* id is the cipher suite value bitwise OR-d with 0x03000000. */ uint32_t id; - /* The following are internal fields. See ssl/internal.h for their values. */ - + /* algorithm_* are internal fields. See ssl/internal.h for their values. */ uint32_t algorithm_mkey; uint32_t algorithm_auth; uint32_t algorithm_enc; uint32_t algorithm_mac; - uint32_t algorithm_ssl; - uint32_t algo_strength; uint32_t algorithm_prf; - - /* strength_bits is the strength of the cipher in bits. */ - int strength_bits; - /* alg_bits is the number of bits of key material used by the algorithm. */ - int alg_bits; }; +typedef struct ssl_ecdh_method_st SSL_ECDH_METHOD; +typedef struct ssl_ecdh_ctx_st { + const SSL_ECDH_METHOD *method; + void *data; +} SSL_ECDH_CTX; + #define SSL_MAX_SSL_SESSION_ID_LENGTH 32 #define SSL_MAX_SID_CTX_LENGTH 32 #define SSL_MAX_MASTER_KEY_LENGTH 48 @@ -3729,9 +3683,9 @@ struct ssl_ctx_st { uint8_t *ocsp_response; size_t ocsp_response_length; - /* If not NULL, session key material will be logged to this BIO for debugging - * purposes. The format matches NSS's and is readable by Wireshark. */ - BIO *keylog_bio; + /* keylog_callback, if not NULL, is the key logging callback. See + * |SSL_CTX_set_keylog_callback|. */ + void (*keylog_callback)(const SSL *ssl, const char *line); /* current_time_cb, if not NULL, is the function to use to get the current * time. It sets |*out_clock| to the current time. */ @@ -3951,12 +3905,9 @@ struct ssl_st { typedef struct ssl3_record_st { /* type is the record type. */ uint8_t type; - /* length is the number of unconsumed bytes of |data|. */ + /* length is the number of unconsumed bytes in the record. */ uint16_t length; - /* off is the number of consumed bytes of |data|. */ - uint16_t off; - /* data is a non-owning pointer to the record contents. The total length of - * the buffer is |off| + |length|. */ + /* data is a non-owning pointer to the first unconsumed byte of the record. */ uint8_t *data; } SSL3_RECORD; @@ -3971,26 +3922,13 @@ typedef struct ssl3_buffer_st { uint16_t cap; } SSL3_BUFFER; -/* TODO(davidben): This flag can probably be merged into s3->change_cipher_spec - * to something tri-state. (Normal / Expect CCS / Between CCS and Finished). */ -#define SSL3_FLAGS_EXPECT_CCS 0x0080 - typedef struct ssl3_state_st { - long flags; - uint8_t read_sequence[8]; - int read_mac_secret_size; - uint8_t read_mac_secret[EVP_MAX_MD_SIZE]; uint8_t write_sequence[8]; - int write_mac_secret_size; - uint8_t write_mac_secret[EVP_MAX_MD_SIZE]; uint8_t server_random[SSL3_RANDOM_SIZE]; uint8_t client_random[SSL3_RANDOM_SIZE]; - /* flags for countermeasure against known-IV weakness */ - int need_record_splitting; - /* have_version is true if the connection's final version is known. Otherwise * the version has not been negotiated yet. */ char have_version; @@ -4006,10 +3944,9 @@ typedef struct ssl3_state_st { SSL3_RECORD rrec; /* each decoded record goes in here */ - /* storage for Handshake protocol data received but not yet processed by - * ssl3_read_bytes: */ - uint8_t handshake_fragment[4]; - unsigned int handshake_fragment_len; + /* hello_request_len is the number of bytes of HelloRequest received, possibly + * split over multiple records. */ + uint8_t hello_request_len; /* partial write - check the numbers match */ unsigned int wnum; /* number of bytes sent so far */ @@ -4027,10 +3964,6 @@ typedef struct ssl3_state_st { * the handshake hash for TLS 1.1 and below. */ EVP_MD_CTX handshake_md5; - /* this is set whenerver we see a change_cipher_spec message come in when we - * are not looking for one */ - int change_cipher_spec; - int warn_alert; int fatal_alert; /* we allow one fatal and one warning alert to be outstanding, send close @@ -4053,10 +3986,9 @@ typedef struct ssl3_state_st { * pending handshake state here so it can be managed separately from * established connection state in case of renegotiations. */ struct { - /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ - uint8_t finish_md[EVP_MAX_MD_SIZE * 2]; + uint8_t finish_md[EVP_MAX_MD_SIZE]; int finish_md_len; - uint8_t peer_finish_md[EVP_MAX_MD_SIZE * 2]; + uint8_t peer_finish_md[EVP_MAX_MD_SIZE]; int peer_finish_md_len; unsigned long message_size; @@ -4064,9 +3996,6 @@ typedef struct ssl3_state_st { /* used to hold the new cipher we are going to use */ const SSL_CIPHER *new_cipher; - DH *dh; - - EC_KEY *ecdh; /* holds short lived ECDH key */ /* used when SSL_ST_FLUSH_DATA is entered */ int next_state; @@ -4167,11 +4096,12 @@ typedef struct ssl3_state_st { * |TLSEXT_hash_none|. */ uint8_t server_key_exchange_hash; - /* peer_dh_tmp, on a client, is the server's DHE public key. */ - DH *peer_dh_tmp; + /* ecdh_ctx is the current ECDH instance. */ + SSL_ECDH_CTX ecdh_ctx; - /* peer_ecdh_tmp, on a client, is the server's ECDHE public key. */ - EC_KEY *peer_ecdh_tmp; + /* peer_key is the peer's ECDH key. */ + uint8_t *peer_key; + uint16_t peer_key_len; } tmp; /* Connection binding to prevent renegotiation attacks */ @@ -4367,184 +4297,147 @@ OPENSSL_EXPORT int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); #define SSL_R_BAD_DIGEST_LENGTH 106 #define SSL_R_BAD_ECC_CERT 107 #define SSL_R_BAD_ECPOINT 108 -#define SSL_R_BAD_HANDSHAKE_LENGTH 109 -#define SSL_R_BAD_HANDSHAKE_RECORD 110 -#define SSL_R_BAD_HELLO_REQUEST 111 -#define SSL_R_BAD_LENGTH 112 -#define SSL_R_BAD_PACKET_LENGTH 113 -#define SSL_R_BAD_RSA_ENCRYPT 114 -#define SSL_R_BAD_SIGNATURE 115 -#define SSL_R_BAD_SRTP_MKI_VALUE 116 -#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 117 -#define SSL_R_BAD_SSL_FILETYPE 118 -#define SSL_R_BAD_WRITE_RETRY 119 -#define SSL_R_BIO_NOT_SET 120 -#define SSL_R_BN_LIB 121 -#define SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY 122 -#define SSL_R_CA_DN_LENGTH_MISMATCH 123 -#define SSL_R_CA_DN_TOO_LONG 124 -#define SSL_R_CCS_RECEIVED_EARLY 125 -#define SSL_R_CERTIFICATE_VERIFY_FAILED 126 -#define SSL_R_CERT_CB_ERROR 127 -#define SSL_R_CERT_LENGTH_MISMATCH 128 -#define SSL_R_CHANNEL_ID_NOT_P256 129 -#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 130 -#define SSL_R_CIPHER_CODE_WRONG_LENGTH 131 -#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 132 -#define SSL_R_CLIENTHELLO_PARSE_FAILED 133 -#define SSL_R_CLIENTHELLO_TLSEXT 134 -#define SSL_R_CONNECTION_REJECTED 135 -#define SSL_R_CONNECTION_TYPE_NOT_SET 136 -#define SSL_R_COOKIE_MISMATCH 137 -#define SSL_R_D2I_ECDSA_SIG 138 -#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 139 -#define SSL_R_DATA_LENGTH_TOO_LONG 140 -#define SSL_R_DECODE_ERROR 141 -#define SSL_R_DECRYPTION_FAILED 142 -#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 143 -#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 144 -#define SSL_R_DIGEST_CHECK_FAILED 145 -#define SSL_R_DTLS_MESSAGE_TOO_BIG 146 -#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 147 -#define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 148 -#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 149 -#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 150 -#define SSL_R_EVP_DIGESTSIGNFINAL_FAILED 151 -#define SSL_R_EVP_DIGESTSIGNINIT_FAILED 152 -#define SSL_R_EXCESSIVE_MESSAGE_SIZE 153 -#define SSL_R_EXTRA_DATA_IN_MESSAGE 154 -#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 155 -#define SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS 156 -#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 157 -#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 158 -#define SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO 159 -#define SSL_R_HANDSHAKE_RECORD_BEFORE_CCS 160 -#define SSL_R_HTTPS_PROXY_REQUEST 161 -#define SSL_R_HTTP_REQUEST 162 -#define SSL_R_INAPPROPRIATE_FALLBACK 163 -#define SSL_R_INVALID_COMMAND 164 -#define SSL_R_INVALID_MESSAGE 165 -#define SSL_R_INVALID_SSL_SESSION 166 -#define SSL_R_INVALID_TICKET_KEYS_LENGTH 167 -#define SSL_R_LENGTH_MISMATCH 168 -#define SSL_R_LIBRARY_HAS_NO_CIPHERS 169 -#define SSL_R_MISSING_DH_KEY 170 -#define SSL_R_MISSING_ECDSA_SIGNING_CERT 171 -#define SSL_R_MISSING_RSA_CERTIFICATE 172 -#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 173 -#define SSL_R_MISSING_RSA_SIGNING_CERT 174 -#define SSL_R_MISSING_TMP_DH_KEY 175 -#define SSL_R_MISSING_TMP_ECDH_KEY 176 -#define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 177 -#define SSL_R_MTU_TOO_SMALL 178 -#define SSL_R_NESTED_GROUP 179 -#define SSL_R_NO_CERTIFICATES_RETURNED 180 -#define SSL_R_NO_CERTIFICATE_ASSIGNED 181 -#define SSL_R_NO_CERTIFICATE_SET 182 -#define SSL_R_NO_CIPHERS_AVAILABLE 183 -#define SSL_R_NO_CIPHERS_PASSED 184 -#define SSL_R_NO_CIPHERS_SPECIFIED 185 -#define SSL_R_NO_CIPHER_MATCH 186 -#define SSL_R_NO_COMPRESSION_SPECIFIED 187 -#define SSL_R_NO_METHOD_SPECIFIED 188 -#define SSL_R_NO_P256_SUPPORT 189 -#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 -#define SSL_R_NO_RENEGOTIATION 191 -#define SSL_R_NO_REQUIRED_DIGEST 192 -#define SSL_R_NO_SHARED_CIPHER 193 -#define SSL_R_NO_SHARED_SIGATURE_ALGORITHMS 194 -#define SSL_R_NO_SRTP_PROFILES 195 -#define SSL_R_NULL_SSL_CTX 196 -#define SSL_R_NULL_SSL_METHOD_PASSED 197 -#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 198 -#define SSL_R_PACKET_LENGTH_TOO_LONG 199 -#define SSL_R_PARSE_TLSEXT 200 -#define SSL_R_PATH_TOO_LONG 201 -#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 202 -#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 203 -#define SSL_R_PROTOCOL_IS_SHUTDOWN 204 -#define SSL_R_PSK_IDENTITY_NOT_FOUND 205 -#define SSL_R_PSK_NO_CLIENT_CB 206 -#define SSL_R_PSK_NO_SERVER_CB 207 -#define SSL_R_READ_BIO_NOT_SET 208 -#define SSL_R_READ_TIMEOUT_EXPIRED 209 -#define SSL_R_RECORD_LENGTH_MISMATCH 210 -#define SSL_R_RECORD_TOO_LARGE 211 -#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 212 -#define SSL_R_RENEGOTIATION_ENCODING_ERR 213 -#define SSL_R_RENEGOTIATION_MISMATCH 214 -#define SSL_R_REQUIRED_CIPHER_MISSING 215 -#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 216 -#define SSL_R_SERVERHELLO_TLSEXT 217 -#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 218 -#define SSL_R_SESSION_MAY_NOT_BE_CREATED 219 -#define SSL_R_SIGNATURE_ALGORITHMS_ERROR 220 -#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 221 -#define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 222 -#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 223 -#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 224 -#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 225 -#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 226 -#define SSL_R_SSL_HANDSHAKE_FAILURE 227 -#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 228 -#define SSL_R_SSL_SESSION_ID_CONFLICT 229 -#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 230 -#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 231 -#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 -#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 233 -#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 234 -#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 235 -#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 236 -#define SSL_R_TOO_MANY_EMPTY_FRAGMENTS 237 -#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 238 -#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 -#define SSL_R_UNEXPECTED_GROUP_CLOSE 240 -#define SSL_R_UNEXPECTED_MESSAGE 241 -#define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 242 -#define SSL_R_UNEXPECTED_RECORD 243 -#define SSL_R_UNINITIALIZED 244 -#define SSL_R_UNKNOWN_ALERT_TYPE 245 -#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 246 -#define SSL_R_UNKNOWN_CIPHER_RETURNED 247 -#define SSL_R_UNKNOWN_CIPHER_TYPE 248 -#define SSL_R_UNKNOWN_DIGEST 249 -#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 -#define SSL_R_UNKNOWN_PROTOCOL 251 -#define SSL_R_UNKNOWN_SSL_VERSION 252 -#define SSL_R_UNKNOWN_STATE 253 -#define SSL_R_UNPROCESSED_HANDSHAKE_DATA 254 -#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 255 -#define SSL_R_UNSUPPORTED_CIPHER 256 -#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 -#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 258 -#define SSL_R_UNSUPPORTED_PROTOCOL 259 -#define SSL_R_UNSUPPORTED_SSL_VERSION 260 -#define SSL_R_USE_SRTP_NOT_NEGOTIATED 261 -#define SSL_R_WRONG_CERTIFICATE_TYPE 262 -#define SSL_R_WRONG_CIPHER_RETURNED 263 -#define SSL_R_WRONG_CURVE 264 -#define SSL_R_WRONG_MESSAGE_TYPE 265 -#define SSL_R_WRONG_SIGNATURE_TYPE 266 -#define SSL_R_WRONG_SSL_VERSION 267 -#define SSL_R_WRONG_VERSION_NUMBER 268 -#define SSL_R_X509_LIB 269 -#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 270 -#define SSL_R_FRAGMENT_MISMATCH 271 -#define SSL_R_BUFFER_TOO_SMALL 272 -#define SSL_R_OLD_SESSION_VERSION_NOT_RETURNED 273 -#define SSL_R_OUTPUT_ALIASES_INPUT 274 -#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 275 -#define SSL_R_EMS_STATE_INCONSISTENT 276 -#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 277 -#define SSL_R_TOO_MANY_WARNING_ALERTS 278 -#define SSL_R_UNEXPECTED_EXTENSION 279 -#define SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER 280 -#define SSL_R_ERROR_ADDING_EXTENSION 281 -#define SSL_R_ERROR_PARSING_EXTENSION 282 -#define SSL_R_MISSING_EXTENSION 283 -#define SSL_R_CUSTOM_EXTENSION_CONTENTS_TOO_LARGE 284 -#define SSL_R_CUSTOM_EXTENSION_ERROR 285 -#define SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN 286 +#define SSL_R_BAD_HANDSHAKE_RECORD 109 +#define SSL_R_BAD_HELLO_REQUEST 110 +#define SSL_R_BAD_LENGTH 111 +#define SSL_R_BAD_PACKET_LENGTH 112 +#define SSL_R_BAD_RSA_ENCRYPT 113 +#define SSL_R_BAD_SIGNATURE 114 +#define SSL_R_BAD_SRTP_MKI_VALUE 115 +#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 116 +#define SSL_R_BAD_SSL_FILETYPE 117 +#define SSL_R_BAD_WRITE_RETRY 118 +#define SSL_R_BIO_NOT_SET 119 +#define SSL_R_BN_LIB 120 +#define SSL_R_BUFFER_TOO_SMALL 121 +#define SSL_R_CA_DN_LENGTH_MISMATCH 122 +#define SSL_R_CA_DN_TOO_LONG 123 +#define SSL_R_CCS_RECEIVED_EARLY 124 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 125 +#define SSL_R_CERT_CB_ERROR 126 +#define SSL_R_CERT_LENGTH_MISMATCH 127 +#define SSL_R_CHANNEL_ID_NOT_P256 128 +#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 129 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 130 +#define SSL_R_CLIENTHELLO_PARSE_FAILED 131 +#define SSL_R_CLIENTHELLO_TLSEXT 132 +#define SSL_R_CONNECTION_REJECTED 133 +#define SSL_R_CONNECTION_TYPE_NOT_SET 134 +#define SSL_R_CUSTOM_EXTENSION_ERROR 135 +#define SSL_R_DATA_LENGTH_TOO_LONG 136 +#define SSL_R_DECODE_ERROR 137 +#define SSL_R_DECRYPTION_FAILED 138 +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 139 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 140 +#define SSL_R_DH_P_TOO_LONG 141 +#define SSL_R_DIGEST_CHECK_FAILED 142 +#define SSL_R_DTLS_MESSAGE_TOO_BIG 143 +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 144 +#define SSL_R_EMS_STATE_INCONSISTENT 145 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 146 +#define SSL_R_ERROR_ADDING_EXTENSION 147 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 148 +#define SSL_R_ERROR_PARSING_EXTENSION 149 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 150 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 151 +#define SSL_R_FRAGMENT_MISMATCH 152 +#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 153 +#define SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO 154 +#define SSL_R_HTTPS_PROXY_REQUEST 155 +#define SSL_R_HTTP_REQUEST 156 +#define SSL_R_INAPPROPRIATE_FALLBACK 157 +#define SSL_R_INVALID_COMMAND 158 +#define SSL_R_INVALID_MESSAGE 159 +#define SSL_R_INVALID_SSL_SESSION 160 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 161 +#define SSL_R_LENGTH_MISMATCH 162 +#define SSL_R_LIBRARY_HAS_NO_CIPHERS 163 +#define SSL_R_MISSING_EXTENSION 164 +#define SSL_R_MISSING_RSA_CERTIFICATE 165 +#define SSL_R_MISSING_TMP_DH_KEY 166 +#define SSL_R_MISSING_TMP_ECDH_KEY 167 +#define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 168 +#define SSL_R_MTU_TOO_SMALL 169 +#define SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN 170 +#define SSL_R_NESTED_GROUP 171 +#define SSL_R_NO_CERTIFICATES_RETURNED 172 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 173 +#define SSL_R_NO_CERTIFICATE_SET 174 +#define SSL_R_NO_CIPHERS_AVAILABLE 175 +#define SSL_R_NO_CIPHERS_PASSED 176 +#define SSL_R_NO_CIPHER_MATCH 177 +#define SSL_R_NO_COMPRESSION_SPECIFIED 178 +#define SSL_R_NO_METHOD_SPECIFIED 179 +#define SSL_R_NO_P256_SUPPORT 180 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 181 +#define SSL_R_NO_RENEGOTIATION 182 +#define SSL_R_NO_REQUIRED_DIGEST 183 +#define SSL_R_NO_SHARED_CIPHER 184 +#define SSL_R_NULL_SSL_CTX 185 +#define SSL_R_NULL_SSL_METHOD_PASSED 186 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 187 +#define SSL_R_OLD_SESSION_VERSION_NOT_RETURNED 188 +#define SSL_R_OUTPUT_ALIASES_INPUT 189 +#define SSL_R_PARSE_TLSEXT 190 +#define SSL_R_PATH_TOO_LONG 191 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 192 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 193 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 194 +#define SSL_R_PSK_IDENTITY_NOT_FOUND 195 +#define SSL_R_PSK_NO_CLIENT_CB 196 +#define SSL_R_PSK_NO_SERVER_CB 197 +#define SSL_R_READ_TIMEOUT_EXPIRED 198 +#define SSL_R_RECORD_LENGTH_MISMATCH 199 +#define SSL_R_RECORD_TOO_LARGE 200 +#define SSL_R_RENEGOTIATION_ENCODING_ERR 201 +#define SSL_R_RENEGOTIATION_MISMATCH 202 +#define SSL_R_REQUIRED_CIPHER_MISSING 203 +#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 204 +#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 205 +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 206 +#define SSL_R_SERVERHELLO_TLSEXT 207 +#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 208 +#define SSL_R_SESSION_MAY_NOT_BE_CREATED 209 +#define SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER 210 +#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 211 +#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 212 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 213 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 214 +#define SSL_R_SSL_HANDSHAKE_FAILURE 215 +#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 216 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 217 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 218 +#define SSL_R_TOO_MANY_EMPTY_FRAGMENTS 219 +#define SSL_R_TOO_MANY_WARNING_ALERTS 220 +#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 221 +#define SSL_R_UNEXPECTED_EXTENSION 222 +#define SSL_R_UNEXPECTED_MESSAGE 223 +#define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 224 +#define SSL_R_UNEXPECTED_RECORD 225 +#define SSL_R_UNINITIALIZED 226 +#define SSL_R_UNKNOWN_ALERT_TYPE 227 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 228 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 229 +#define SSL_R_UNKNOWN_CIPHER_TYPE 230 +#define SSL_R_UNKNOWN_DIGEST 231 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 232 +#define SSL_R_UNKNOWN_PROTOCOL 233 +#define SSL_R_UNKNOWN_SSL_VERSION 234 +#define SSL_R_UNKNOWN_STATE 235 +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 236 +#define SSL_R_UNSUPPORTED_CIPHER 237 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 238 +#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 239 +#define SSL_R_UNSUPPORTED_PROTOCOL 240 +#define SSL_R_WRONG_CERTIFICATE_TYPE 241 +#define SSL_R_WRONG_CIPHER_RETURNED 242 +#define SSL_R_WRONG_CURVE 243 +#define SSL_R_WRONG_MESSAGE_TYPE 244 +#define SSL_R_WRONG_SIGNATURE_TYPE 245 +#define SSL_R_WRONG_SSL_VERSION 246 +#define SSL_R_WRONG_VERSION_NUMBER 247 +#define SSL_R_X509_LIB 248 +#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 249 #define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000 #define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 #define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 diff --git a/src/include/openssl/ssl3.h b/src/include/openssl/ssl3.h index 0d013d5..957b740 100644 --- a/src/include/openssl/ssl3.h +++ b/src/include/openssl/ssl3.h @@ -231,8 +231,6 @@ extern "C" { #define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 -#define SSL3_RT_MAX_EXTRA (16384) - /* Maximum plaintext length: defined by SSL/TLS standards */ #define SSL3_RT_MAX_PLAIN_LENGTH 16384 /* Maximum compression overhead: defined by SSL/TLS standards */ diff --git a/src/include/openssl/stack.h b/src/include/openssl/stack.h index b600b43..16b9f4f 100644 --- a/src/include/openssl/stack.h +++ b/src/include/openssl/stack.h @@ -134,9 +134,6 @@ typedef struct stack_st { * STACK_OF:GENERAL_NAME * STACK_OF:GENERAL_NAMES * STACK_OF:GENERAL_SUBTREE - * STACK_OF:MIME_HEADER - * STACK_OF:PKCS7_RECIP_INFO - * STACK_OF:PKCS7_SIGNER_INFO * STACK_OF:POLICYINFO * STACK_OF:POLICYQUALINFO * STACK_OF:POLICY_MAPPING diff --git a/src/include/openssl/stack_macros.h b/src/include/openssl/stack_macros.h index 08097af..809424c 100644 --- a/src/include/openssl/stack_macros.h +++ b/src/include/openssl/stack_macros.h @@ -1430,262 +1430,6 @@ copy_func), \ CHECKED_CAST(void (*)(void *), void (*)(GENERAL_SUBTREE *), free_func))) -/* MIME_HEADER */ -#define sk_MIME_HEADER_new(comp) \ - ((STACK_OF(MIME_HEADER) *)sk_new(CHECKED_CAST( \ - stack_cmp_func, int (*)(const MIME_HEADER **a, const MIME_HEADER **b), \ - comp))) - -#define sk_MIME_HEADER_new_null() ((STACK_OF(MIME_HEADER) *)sk_new_null()) - -#define sk_MIME_HEADER_num(sk) \ - sk_num(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk)) - -#define sk_MIME_HEADER_zero(sk) \ - sk_zero(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk)); - -#define sk_MIME_HEADER_value(sk, i) \ - ((MIME_HEADER *)sk_value( \ - CHECKED_CAST(_STACK *, const STACK_OF(MIME_HEADER) *, sk), (i))) - -#define sk_MIME_HEADER_set(sk, i, p) \ - ((MIME_HEADER *)sk_set(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \ - (i), CHECKED_CAST(void *, MIME_HEADER *, p))) - -#define sk_MIME_HEADER_free(sk) \ - sk_free(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk)) - -#define sk_MIME_HEADER_pop_free(sk, free_func) \ - sk_pop_free( \ - CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \ - CHECKED_CAST(void (*)(void *), void (*)(MIME_HEADER *), free_func)) - -#define sk_MIME_HEADER_insert(sk, p, where) \ - sk_insert(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \ - CHECKED_CAST(void *, MIME_HEADER *, p), (where)) - -#define sk_MIME_HEADER_delete(sk, where) \ - ((MIME_HEADER *)sk_delete( \ - CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), (where))) - -#define sk_MIME_HEADER_delete_ptr(sk, p) \ - ((MIME_HEADER *)sk_delete_ptr( \ - CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \ - CHECKED_CAST(void *, MIME_HEADER *, p))) - -#define sk_MIME_HEADER_find(sk, out_index, p) \ - sk_find(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), (out_index), \ - CHECKED_CAST(void *, MIME_HEADER *, p)) - -#define sk_MIME_HEADER_shift(sk) \ - ((MIME_HEADER *)sk_shift(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk))) - -#define sk_MIME_HEADER_push(sk, p) \ - sk_push(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \ - CHECKED_CAST(void *, MIME_HEADER *, p)) - -#define sk_MIME_HEADER_pop(sk) \ - ((MIME_HEADER *)sk_pop(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk))) - -#define sk_MIME_HEADER_dup(sk) \ - ((STACK_OF(MIME_HEADER) *)sk_dup( \ - CHECKED_CAST(_STACK *, const STACK_OF(MIME_HEADER) *, sk))) - -#define sk_MIME_HEADER_sort(sk) \ - sk_sort(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk)) - -#define sk_MIME_HEADER_is_sorted(sk) \ - sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(MIME_HEADER) *, sk)) - -#define sk_MIME_HEADER_set_cmp_func(sk, comp) \ - ((int (*)(const MIME_HEADER **a, const MIME_HEADER **b))sk_set_cmp_func( \ - CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \ - CHECKED_CAST(stack_cmp_func, \ - int (*)(const MIME_HEADER **a, const MIME_HEADER **b), \ - comp))) - -#define sk_MIME_HEADER_deep_copy(sk, copy_func, free_func) \ - ((STACK_OF(MIME_HEADER) *)sk_deep_copy( \ - CHECKED_CAST(const _STACK *, const STACK_OF(MIME_HEADER) *, sk), \ - CHECKED_CAST(void *(*)(void *), MIME_HEADER *(*)(MIME_HEADER *), \ - copy_func), \ - CHECKED_CAST(void (*)(void *), void (*)(MIME_HEADER *), free_func))) - -/* PKCS7_RECIP_INFO */ -#define sk_PKCS7_RECIP_INFO_new(comp) \ - ((STACK_OF(PKCS7_RECIP_INFO) *)sk_new(CHECKED_CAST( \ - stack_cmp_func, \ - int (*)(const PKCS7_RECIP_INFO **a, const PKCS7_RECIP_INFO **b), comp))) - -#define sk_PKCS7_RECIP_INFO_new_null() \ - ((STACK_OF(PKCS7_RECIP_INFO) *)sk_new_null()) - -#define sk_PKCS7_RECIP_INFO_num(sk) \ - sk_num(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)) - -#define sk_PKCS7_RECIP_INFO_zero(sk) \ - sk_zero(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)); - -#define sk_PKCS7_RECIP_INFO_value(sk, i) \ - ((PKCS7_RECIP_INFO *)sk_value( \ - CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk), (i))) - -#define sk_PKCS7_RECIP_INFO_set(sk, i, p) \ - ((PKCS7_RECIP_INFO *)sk_set( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), (i), \ - CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p))) - -#define sk_PKCS7_RECIP_INFO_free(sk) \ - sk_free(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)) - -#define sk_PKCS7_RECIP_INFO_pop_free(sk, free_func) \ - sk_pop_free( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \ - CHECKED_CAST(void (*)(void *), void (*)(PKCS7_RECIP_INFO *), free_func)) - -#define sk_PKCS7_RECIP_INFO_insert(sk, p, where) \ - sk_insert(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \ - CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p), (where)) - -#define sk_PKCS7_RECIP_INFO_delete(sk, where) \ - ((PKCS7_RECIP_INFO *)sk_delete( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), (where))) - -#define sk_PKCS7_RECIP_INFO_delete_ptr(sk, p) \ - ((PKCS7_RECIP_INFO *)sk_delete_ptr( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \ - CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p))) - -#define sk_PKCS7_RECIP_INFO_find(sk, out_index, p) \ - sk_find(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \ - (out_index), CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p)) - -#define sk_PKCS7_RECIP_INFO_shift(sk) \ - ((PKCS7_RECIP_INFO *)sk_shift( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))) - -#define sk_PKCS7_RECIP_INFO_push(sk, p) \ - sk_push(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \ - CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p)) - -#define sk_PKCS7_RECIP_INFO_pop(sk) \ - ((PKCS7_RECIP_INFO *)sk_pop( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))) - -#define sk_PKCS7_RECIP_INFO_dup(sk) \ - ((STACK_OF(PKCS7_RECIP_INFO) *)sk_dup( \ - CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk))) - -#define sk_PKCS7_RECIP_INFO_sort(sk) \ - sk_sort(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)) - -#define sk_PKCS7_RECIP_INFO_is_sorted(sk) \ - sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk)) - -#define sk_PKCS7_RECIP_INFO_set_cmp_func(sk, comp) \ - ((int (*)(const PKCS7_RECIP_INFO **a, const PKCS7_RECIP_INFO **b)) \ - sk_set_cmp_func( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \ - CHECKED_CAST(stack_cmp_func, int (*)(const PKCS7_RECIP_INFO **a, \ - const PKCS7_RECIP_INFO **b), \ - comp))) - -#define sk_PKCS7_RECIP_INFO_deep_copy(sk, copy_func, free_func) \ - ((STACK_OF(PKCS7_RECIP_INFO) *)sk_deep_copy( \ - CHECKED_CAST(const _STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk), \ - CHECKED_CAST(void *(*)(void *), \ - PKCS7_RECIP_INFO *(*)(PKCS7_RECIP_INFO *), copy_func), \ - CHECKED_CAST(void (*)(void *), void (*)(PKCS7_RECIP_INFO *), \ - free_func))) - -/* PKCS7_SIGNER_INFO */ -#define sk_PKCS7_SIGNER_INFO_new(comp) \ - ((STACK_OF(PKCS7_SIGNER_INFO) *)sk_new(CHECKED_CAST( \ - stack_cmp_func, \ - int (*)(const PKCS7_SIGNER_INFO **a, const PKCS7_SIGNER_INFO **b), \ - comp))) - -#define sk_PKCS7_SIGNER_INFO_new_null() \ - ((STACK_OF(PKCS7_SIGNER_INFO) *)sk_new_null()) - -#define sk_PKCS7_SIGNER_INFO_num(sk) \ - sk_num(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk)) - -#define sk_PKCS7_SIGNER_INFO_zero(sk) \ - sk_zero(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk)); - -#define sk_PKCS7_SIGNER_INFO_value(sk, i) \ - ((PKCS7_SIGNER_INFO *)sk_value( \ - CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_SIGNER_INFO) *, sk), (i))) - -#define sk_PKCS7_SIGNER_INFO_set(sk, i, p) \ - ((PKCS7_SIGNER_INFO *)sk_set( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), (i), \ - CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p))) - -#define sk_PKCS7_SIGNER_INFO_free(sk) \ - sk_free(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk)) - -#define sk_PKCS7_SIGNER_INFO_pop_free(sk, free_func) \ - sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \ - CHECKED_CAST(void (*)(void *), void (*)(PKCS7_SIGNER_INFO *), \ - free_func)) - -#define sk_PKCS7_SIGNER_INFO_insert(sk, p, where) \ - sk_insert(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \ - CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p), (where)) - -#define sk_PKCS7_SIGNER_INFO_delete(sk, where) \ - ((PKCS7_SIGNER_INFO *)sk_delete( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), (where))) - -#define sk_PKCS7_SIGNER_INFO_delete_ptr(sk, p) \ - ((PKCS7_SIGNER_INFO *)sk_delete_ptr( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \ - CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p))) - -#define sk_PKCS7_SIGNER_INFO_find(sk, out_index, p) \ - sk_find(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \ - (out_index), CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p)) - -#define sk_PKCS7_SIGNER_INFO_shift(sk) \ - ((PKCS7_SIGNER_INFO *)sk_shift( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk))) - -#define sk_PKCS7_SIGNER_INFO_push(sk, p) \ - sk_push(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \ - CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p)) - -#define sk_PKCS7_SIGNER_INFO_pop(sk) \ - ((PKCS7_SIGNER_INFO *)sk_pop( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk))) - -#define sk_PKCS7_SIGNER_INFO_dup(sk) \ - ((STACK_OF(PKCS7_SIGNER_INFO) *)sk_dup( \ - CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_SIGNER_INFO) *, sk))) - -#define sk_PKCS7_SIGNER_INFO_sort(sk) \ - sk_sort(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk)) - -#define sk_PKCS7_SIGNER_INFO_is_sorted(sk) \ - sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_SIGNER_INFO) *, sk)) - -#define sk_PKCS7_SIGNER_INFO_set_cmp_func(sk, comp) \ - ((int (*)(const PKCS7_SIGNER_INFO **a, const PKCS7_SIGNER_INFO **b)) \ - sk_set_cmp_func( \ - CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \ - CHECKED_CAST(stack_cmp_func, int (*)(const PKCS7_SIGNER_INFO **a, \ - const PKCS7_SIGNER_INFO **b), \ - comp))) - -#define sk_PKCS7_SIGNER_INFO_deep_copy(sk, copy_func, free_func) \ - ((STACK_OF(PKCS7_SIGNER_INFO) *)sk_deep_copy( \ - CHECKED_CAST(const _STACK *, const STACK_OF(PKCS7_SIGNER_INFO) *, sk), \ - CHECKED_CAST(void *(*)(void *), \ - PKCS7_SIGNER_INFO *(*)(PKCS7_SIGNER_INFO *), copy_func), \ - CHECKED_CAST(void (*)(void *), void (*)(PKCS7_SIGNER_INFO *), \ - free_func))) - /* POLICYINFO */ #define sk_POLICYINFO_new(comp) \ ((STACK_OF(POLICYINFO) *)sk_new(CHECKED_CAST( \ diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h index 92210f6..92d2752 100644 --- a/src/include/openssl/tls1.h +++ b/src/include/openssl/tls1.h @@ -430,12 +430,14 @@ extern "C" { #define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD 0x0300CC13 #define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD 0x0300CC14 -/* TODO(davidben): Remove these once WebRTC is no longer using them, so they - * may point to the future RFC 7539 variant. */ +#define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA8 +#define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA9 +#define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0x0300CCAC + +/* TODO(davidben): Remove this. Historically, the CK names for CHACHA20_POLY1305 + * were missing 'WITH' and 'SHA256'. */ #define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 \ - TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD -#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 \ - TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD + TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 /* XXX * Inconsistency alert: @@ -597,14 +599,25 @@ extern "C" { #define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" #define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" +/* For convenience, the old and new CHACHA20_POLY1305 ciphers have the same + * name. In cipher strings, both will be selected. This is temporary and will be + * removed when the pre-standard construction is removed. */ #define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD \ "ECDHE-RSA-CHACHA20-POLY1305" #define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD \ "ECDHE-ECDSA-CHACHA20-POLY1305" -/* TODO(davidben): Remove this once QUIC has switched to the '_OLD' name. */ +#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-RSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-ECDSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-PSK-CHACHA20-POLY1305" + +/* TODO(davidben): Remove this. Historically, the TXT names for CHACHA20_POLY1305 + * were missing 'SHA256'. */ #define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 \ - TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD + TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 #define TLS_CT_RSA_SIGN 1 #define TLS_CT_DSS_SIGN 2 diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h index da569e8..a5aaf31 100644 --- a/src/include/openssl/x509.h +++ b/src/include/openssl/x509.h @@ -618,12 +618,10 @@ OPENSSL_EXPORT int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *si OPENSSL_EXPORT int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); OPENSSL_EXPORT int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); -/* int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); */ OPENSSL_EXPORT int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); OPENSSL_EXPORT int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); OPENSSL_EXPORT int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); OPENSSL_EXPORT int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); -/* int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); */ OPENSSL_EXPORT int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); OPENSSL_EXPORT int X509_pubkey_digest(const X509 *data,const EVP_MD *type, @@ -787,7 +785,7 @@ DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR) * |x|. */ OPENSSL_EXPORT X509 *X509_up_ref(X509 *x); -OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg); OPENSSL_EXPORT void *X509_get_ex_data(X509 *r, int idx); diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h index c11820b..b39ef49 100644 --- a/src/include/openssl/x509_vfy.h +++ b/src/include/openssl/x509_vfy.h @@ -498,7 +498,7 @@ OPENSSL_EXPORT int X509_STORE_load_locations (X509_STORE *ctx, OPENSSL_EXPORT int X509_STORE_set_default_paths(X509_STORE *ctx); #endif -OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); OPENSSL_EXPORT int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data); OPENSSL_EXPORT void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx); diff --git a/src/ssl/CMakeLists.txt b/src/ssl/CMakeLists.txt index a5ad126..c82cb9b 100644 --- a/src/ssl/CMakeLists.txt +++ b/src/ssl/CMakeLists.txt @@ -26,6 +26,7 @@ add_library( ssl_buffer.c ssl_cert.c ssl_cipher.c + ssl_ecdh.c ssl_file.c ssl_lib.c ssl_rsa.c diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.c index a940af6..ee4cbc9 100644 --- a/src/ssl/d1_both.c +++ b/src/ssl/d1_both.c @@ -301,8 +301,9 @@ static int dtls1_write_change_cipher_spec(SSL *ssl, } static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS}; - int ret = dtls1_write_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec, - sizeof(kChangeCipherSpec), use_epoch); + int ret = + dtls1_write_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec, + sizeof(kChangeCipherSpec), use_epoch); if (ret <= 0) { return ret; } @@ -410,17 +411,17 @@ err: /* dtls1_is_next_message_complete returns one if the next handshake message is * complete and zero otherwise. */ -static int dtls1_is_next_message_complete(SSL *s) { - pitem *item = pqueue_peek(s->d1->buffered_messages); +static int dtls1_is_next_message_complete(SSL *ssl) { + pitem *item = pqueue_peek(ssl->d1->buffered_messages); if (item == NULL) { return 0; } hm_fragment *frag = (hm_fragment *)item->data; - assert(s->d1->handshake_read_seq <= frag->msg_header.seq); + assert(ssl->d1->handshake_read_seq <= frag->msg_header.seq); - return s->d1->handshake_read_seq == frag->msg_header.seq && - frag->reassembly == NULL; + return ssl->d1->handshake_read_seq == frag->msg_header.seq && + frag->reassembly == NULL; } /* dtls1_discard_fragment_body discards a handshake fragment body of length @@ -428,11 +429,11 @@ static int dtls1_is_next_message_complete(SSL *s) { * * TODO(davidben): This function will go away when ssl_read_bytes is gone from * the DTLS side. */ -static int dtls1_discard_fragment_body(SSL *s, size_t frag_len) { +static int dtls1_discard_fragment_body(SSL *ssl, size_t frag_len) { uint8_t discard[256]; while (frag_len > 0) { size_t chunk = frag_len < sizeof(discard) ? frag_len : sizeof(discard); - int ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, discard, chunk, 0); + int ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, discard, chunk, 0); if (ret != (int) chunk) { return 0; } @@ -446,12 +447,12 @@ static int dtls1_discard_fragment_body(SSL *s, size_t frag_len) { * queue. Otherwise, it checks |msg_hdr| is consistent with the existing one. It * returns NULL on failure. The caller does not take ownership of the result. */ static hm_fragment *dtls1_get_buffered_message( - SSL *s, const struct hm_header_st *msg_hdr) { + SSL *ssl, const struct hm_header_st *msg_hdr) { uint8_t seq64be[8]; memset(seq64be, 0, sizeof(seq64be)); seq64be[6] = (uint8_t)(msg_hdr->seq >> 8); seq64be[7] = (uint8_t)msg_hdr->seq; - pitem *item = pqueue_find(s->d1->buffered_messages, seq64be); + pitem *item = pqueue_find(ssl->d1->buffered_messages, seq64be); hm_fragment *frag; if (item == NULL) { @@ -467,7 +468,7 @@ static hm_fragment *dtls1_get_buffered_message( dtls1_hm_fragment_free(frag); return NULL; } - item = pqueue_insert(s->d1->buffered_messages, item); + item = pqueue_insert(ssl->d1->buffered_messages, item); /* |pqueue_insert| fails iff a duplicate item is inserted, but |item| cannot * be a duplicate. */ assert(item != NULL); @@ -479,7 +480,7 @@ static hm_fragment *dtls1_get_buffered_message( /* The new fragment must be compatible with the previous fragments from * this message. */ OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); return NULL; } } @@ -487,29 +488,29 @@ static hm_fragment *dtls1_get_buffered_message( } /* dtls1_max_handshake_message_len returns the maximum number of bytes - * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but may + * permitted in a DTLS handshake message for |ssl|. The minimum is 16KB, but may * be greater if the maximum certificate list size requires it. */ -static size_t dtls1_max_handshake_message_len(const SSL *s) { +static size_t dtls1_max_handshake_message_len(const SSL *ssl) { size_t max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; - if (max_len < s->max_cert_list) { - return s->max_cert_list; + if (max_len < ssl->max_cert_list) { + return ssl->max_cert_list; } return max_len; } /* dtls1_process_fragment reads a handshake fragment and processes it. It * returns one if a fragment was successfully processed and 0 or -1 on error. */ -static int dtls1_process_fragment(SSL *s) { +static int dtls1_process_fragment(SSL *ssl) { /* Read handshake message header. */ uint8_t header[DTLS1_HM_HEADER_LENGTH]; - int ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, header, + int ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, header, DTLS1_HM_HEADER_LENGTH, 0); if (ret <= 0) { return ret; } if (ret != DTLS1_HM_HEADER_LENGTH) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); return -1; } @@ -518,30 +519,30 @@ static int dtls1_process_fragment(SSL *s) { dtls1_get_message_header(header, &msg_hdr); /* TODO(davidben): dtls1_read_bytes is the wrong abstraction for DTLS. There - * should be no need to reach into |s->s3->rrec.length|. */ + * should be no need to reach into |ssl->s3->rrec.length|. */ const size_t frag_off = msg_hdr.frag_off; const size_t frag_len = msg_hdr.frag_len; const size_t msg_len = msg_hdr.msg_len; if (frag_off > msg_len || frag_off + frag_len < frag_off || frag_off + frag_len > msg_len || - msg_len > dtls1_max_handshake_message_len(s) || - frag_len > s->s3->rrec.length) { + msg_len > dtls1_max_handshake_message_len(ssl) || + frag_len > ssl->s3->rrec.length) { OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); return -1; } - if (msg_hdr.seq < s->d1->handshake_read_seq || - msg_hdr.seq > (unsigned)s->d1->handshake_read_seq + + if (msg_hdr.seq < ssl->d1->handshake_read_seq || + msg_hdr.seq > (unsigned)ssl->d1->handshake_read_seq + kHandshakeBufferSize) { /* Ignore fragments from the past, or ones too far in the future. */ - if (!dtls1_discard_fragment_body(s, frag_len)) { + if (!dtls1_discard_fragment_body(ssl, frag_len)) { return -1; } return 1; } - hm_fragment *frag = dtls1_get_buffered_message(s, &msg_hdr); + hm_fragment *frag = dtls1_get_buffered_message(ssl, &msg_hdr); if (frag == NULL) { return -1; } @@ -549,7 +550,7 @@ static int dtls1_process_fragment(SSL *s) { if (frag->reassembly == NULL) { /* The message is already assembled. */ - if (!dtls1_discard_fragment_body(s, frag_len)) { + if (!dtls1_discard_fragment_body(ssl, frag_len)) { return -1; } return 1; @@ -557,11 +558,11 @@ static int dtls1_process_fragment(SSL *s) { assert(msg_len > 0); /* Read the body of the fragment. */ - ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, frag->fragment + frag_off, + ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, frag->fragment + frag_off, frag_len, 0); if (ret != (int) frag_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return -1; } dtls1_hm_fragment_mark(frag, frag_off, frag_off + frag_len); @@ -572,7 +573,7 @@ static int dtls1_process_fragment(SSL *s) { /* dtls1_get_message reads a handshake message of message type |msg_type| (any * if |msg_type| == -1), maximum acceptable body length |max|. Read an entire * handshake message. Handshake messages arrive in fragments. */ -long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max, +long dtls1_get_message(SSL *ssl, int st1, int stn, int msg_type, long max, enum ssl_hash_message_t hash_message, int *ok) { pitem *item = NULL; hm_fragment *frag = NULL; @@ -580,26 +581,26 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max, /* s3->tmp is used to store messages that are unexpected, caused * by the absence of an optional handshake message */ - if (s->s3->tmp.reuse_message) { + if (ssl->s3->tmp.reuse_message) { /* A ssl_dont_hash_message call cannot be combined with reuse_message; the * ssl_dont_hash_message would have to have been applied to the previous * call. */ assert(hash_message == ssl_hash_message); - s->s3->tmp.reuse_message = 0; - if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) { + ssl->s3->tmp.reuse_message = 0; + if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) { al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } *ok = 1; - s->init_msg = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - s->init_num = (int)s->s3->tmp.message_size; - return s->init_num; + ssl->init_msg = (uint8_t *)ssl->init_buf->data + DTLS1_HM_HEADER_LENGTH; + ssl->init_num = (int)ssl->s3->tmp.message_size; + return ssl->init_num; } /* Process fragments until one is found. */ - while (!dtls1_is_next_message_complete(s)) { - int ret = dtls1_process_fragment(s); + while (!dtls1_is_next_message_complete(ssl)) { + int ret = dtls1_process_fragment(ssl); if (ret <= 0) { *ok = 0; return ret; @@ -607,10 +608,10 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max, } /* Read out the next complete handshake message. */ - item = pqueue_pop(s->d1->buffered_messages); + item = pqueue_pop(ssl->d1->buffered_messages); assert(item != NULL); frag = (hm_fragment *)item->data; - assert(s->d1->handshake_read_seq == frag->msg_header.seq); + assert(ssl->d1->handshake_read_seq == frag->msg_header.seq); assert(frag->reassembly == NULL); if (frag->msg_header.msg_len > (size_t)max) { @@ -622,10 +623,10 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max, size_t len; CBB cbb; CBB_zero(&cbb); - if (!BUF_MEM_grow(s->init_buf, - (size_t)frag->msg_header.msg_len + - DTLS1_HM_HEADER_LENGTH) || - !CBB_init_fixed(&cbb, (uint8_t *)s->init_buf->data, s->init_buf->max) || + if (!BUF_MEM_grow(ssl->init_buf, (size_t)frag->msg_header.msg_len + + DTLS1_HM_HEADER_LENGTH) || + !CBB_init_fixed(&cbb, (uint8_t *)ssl->init_buf->data, + ssl->init_buf->max) || !CBB_add_u8(&cbb, frag->msg_header.type) || !CBB_add_u24(&cbb, frag->msg_header.msg_len) || !CBB_add_u16(&cbb, frag->msg_header.seq) || @@ -639,38 +640,38 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max, } assert(len == (size_t)frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH); - s->d1->handshake_read_seq++; + ssl->d1->handshake_read_seq++; /* TODO(davidben): This function has a lot of implicit outputs. Simplify the * |ssl_get_message| API. */ - s->s3->tmp.message_type = frag->msg_header.type; - s->s3->tmp.message_size = frag->msg_header.msg_len; - s->init_msg = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - s->init_num = frag->msg_header.msg_len; + ssl->s3->tmp.message_type = frag->msg_header.type; + ssl->s3->tmp.message_size = frag->msg_header.msg_len; + ssl->init_msg = (uint8_t *)ssl->init_buf->data + DTLS1_HM_HEADER_LENGTH; + ssl->init_num = frag->msg_header.msg_len; - if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) { + if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) { al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } - if (hash_message == ssl_hash_message && !ssl3_hash_current_message(s)) { + if (hash_message == ssl_hash_message && !ssl3_hash_current_message(ssl)) { goto err; } - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - s->init_num + DTLS1_HM_HEADER_LENGTH, s, - s->msg_callback_arg); + if (ssl->msg_callback) { + ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, ssl->init_buf->data, + ssl->init_num + DTLS1_HM_HEADER_LENGTH, ssl, + ssl->msg_callback_arg); } pitem_free(item); dtls1_hm_fragment_free(frag); - s->state = stn; + ssl->state = stn; *ok = 1; - return s->init_num; + return ssl->init_num; f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: pitem_free(item); dtls1_hm_fragment_free(frag); @@ -678,25 +679,25 @@ err: return -1; } -int dtls1_read_failed(SSL *s, int code) { +int dtls1_read_failed(SSL *ssl, int code) { if (code > 0) { assert(0); return 1; } - if (!dtls1_is_timer_expired(s)) { + if (!dtls1_is_timer_expired(ssl)) { /* not a timeout, none of our business, let higher layers handle this. In * fact, it's probably an error */ return code; } - if (!SSL_in_init(s)) { + if (!SSL_in_init(ssl)) { /* done, no need to send a retransmit */ - BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); + BIO_set_flags(SSL_get_rbio(ssl), BIO_FLAGS_READ); return code; } - return DTLSv1_handle_timeout(s); + return DTLSv1_handle_timeout(ssl); } static uint16_t dtls1_get_queue_priority(uint16_t seq, int is_ccs) { @@ -713,47 +714,47 @@ static uint16_t dtls1_get_queue_priority(uint16_t seq, int is_ccs) { return seq * 2 - is_ccs; } -static int dtls1_retransmit_message(SSL *s, hm_fragment *frag) { +static int dtls1_retransmit_message(SSL *ssl, hm_fragment *frag) { /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1 * (negotiated cipher) exist. */ - assert(s->d1->w_epoch == 0 || s->d1->w_epoch == 1); - assert(frag->msg_header.epoch <= s->d1->w_epoch); + assert(ssl->d1->w_epoch == 0 || ssl->d1->w_epoch == 1); + assert(frag->msg_header.epoch <= ssl->d1->w_epoch); enum dtls1_use_epoch_t use_epoch = dtls1_use_current_epoch; - if (s->d1->w_epoch == 1 && frag->msg_header.epoch == 0) { + if (ssl->d1->w_epoch == 1 && frag->msg_header.epoch == 0) { use_epoch = dtls1_use_previous_epoch; } /* TODO(davidben): This cannot handle non-blocking writes. */ int ret; if (frag->msg_header.is_ccs) { - ret = dtls1_write_change_cipher_spec(s, use_epoch); + ret = dtls1_write_change_cipher_spec(ssl, use_epoch); } else { /* Restore the message body. * TODO(davidben): Make this less stateful. */ - memcpy(s->init_buf->data, frag->fragment, + memcpy(ssl->init_buf->data, frag->fragment, frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH); - s->init_num = frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH; + ssl->init_num = frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH; - dtls1_set_message_header(s, frag->msg_header.type, + dtls1_set_message_header(ssl, frag->msg_header.type, frag->msg_header.msg_len, frag->msg_header.seq, 0, frag->msg_header.frag_len); - ret = dtls1_do_handshake_write(s, use_epoch); + ret = dtls1_do_handshake_write(ssl, use_epoch); } /* TODO(davidben): Check return value? */ - (void)BIO_flush(SSL_get_wbio(s)); + (void)BIO_flush(SSL_get_wbio(ssl)); return ret; } -int dtls1_retransmit_buffered_messages(SSL *s) { - pqueue sent = s->d1->sent_messages; +int dtls1_retransmit_buffered_messages(SSL *ssl) { + pqueue sent = ssl->d1->sent_messages; piterator iter = pqueue_iterator(sent); pitem *item; for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) { hm_fragment *frag = (hm_fragment *)item->data; - if (dtls1_retransmit_message(s, frag) <= 0) { + if (dtls1_retransmit_message(ssl, frag) <= 0) { return -1; } } @@ -789,28 +790,28 @@ static int dtls1_buffer_change_cipher_spec(SSL *ssl, uint16_t seq) { return 1; } -int dtls1_buffer_message(SSL *s) { +int dtls1_buffer_message(SSL *ssl) { /* this function is called immediately after a message has * been serialized */ - assert(s->init_off == 0); + assert(ssl->init_off == 0); - hm_fragment *frag = dtls1_hm_fragment_new(s->init_num, 0); + hm_fragment *frag = dtls1_hm_fragment_new(ssl->init_num, 0); if (!frag) { return 0; } - memcpy(frag->fragment, s->init_buf->data, s->init_num); + memcpy(frag->fragment, ssl->init_buf->data, ssl->init_num); - assert(s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH == - (unsigned int)s->init_num); + assert(ssl->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH == + (unsigned int)ssl->init_num); - frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; - frag->msg_header.seq = s->d1->w_msg_hdr.seq; - frag->msg_header.type = s->d1->w_msg_hdr.type; + frag->msg_header.msg_len = ssl->d1->w_msg_hdr.msg_len; + frag->msg_header.seq = ssl->d1->w_msg_hdr.seq; + frag->msg_header.type = ssl->d1->w_msg_hdr.type; frag->msg_header.frag_off = 0; - frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.frag_len = ssl->d1->w_msg_hdr.msg_len; frag->msg_header.is_ccs = 0; - frag->msg_header.epoch = s->d1->w_epoch; + frag->msg_header.epoch = ssl->d1->w_epoch; uint16_t priority = dtls1_get_queue_priority(frag->msg_header.seq, 0 /* handshake */); @@ -825,37 +826,37 @@ int dtls1_buffer_message(SSL *s) { return 0; } - pqueue_insert(s->d1->sent_messages, item); + pqueue_insert(ssl->d1->sent_messages, item); return 1; } -int dtls1_send_change_cipher_spec(SSL *s, int a, int b) { - if (s->state == a) { +int dtls1_send_change_cipher_spec(SSL *ssl, int a, int b) { + if (ssl->state == a) { /* Buffer the message to handle retransmits. */ - s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; - dtls1_buffer_change_cipher_spec(s, s->d1->handshake_write_seq); - s->state = b; + ssl->d1->handshake_write_seq = ssl->d1->next_handshake_write_seq; + dtls1_buffer_change_cipher_spec(ssl, ssl->d1->handshake_write_seq); + ssl->state = b; } - return dtls1_write_change_cipher_spec(s, dtls1_use_current_epoch); + return dtls1_write_change_cipher_spec(ssl, dtls1_use_current_epoch); } /* call this function when the buffered messages are no longer needed */ -void dtls1_clear_record_buffer(SSL *s) { +void dtls1_clear_record_buffer(SSL *ssl) { pitem *item; - for (item = pqueue_pop(s->d1->sent_messages); item != NULL; - item = pqueue_pop(s->d1->sent_messages)) { + for (item = pqueue_pop(ssl->d1->sent_messages); item != NULL; + item = pqueue_pop(ssl->d1->sent_messages)) { dtls1_hm_fragment_free((hm_fragment *)item->data); pitem_free(item); } } /* don't actually do the writing, wait till the MTU has been retrieved */ -void dtls1_set_message_header(SSL *s, uint8_t mt, unsigned long len, +void dtls1_set_message_header(SSL *ssl, uint8_t mt, unsigned long len, unsigned short seq_num, unsigned long frag_off, unsigned long frag_len) { - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + struct hm_header_st *msg_hdr = &ssl->d1->w_msg_hdr; msg_hdr->type = mt; msg_hdr->msg_len = len; diff --git a/src/ssl/d1_clnt.c b/src/ssl/d1_clnt.c index b86655c..ad5eb50 100644 --- a/src/ssl/d1_clnt.c +++ b/src/ssl/d1_clnt.c @@ -131,354 +131,362 @@ #include "internal.h" -static int dtls1_get_hello_verify(SSL *s); +static int dtls1_get_hello_verify(SSL *ssl); -int dtls1_connect(SSL *s) { +int dtls1_connect(SSL *ssl) { BUF_MEM *buf = NULL; void (*cb)(const SSL *ssl, int type, int value) = NULL; int ret = -1; int new_state, state, skip = 0; - assert(s->handshake_func == dtls1_connect); - assert(!s->server); - assert(SSL_IS_DTLS(s)); + assert(ssl->handshake_func == dtls1_connect); + assert(!ssl->server); + assert(SSL_IS_DTLS(ssl)); ERR_clear_error(); ERR_clear_system_error(); - if (s->info_callback != NULL) { - cb = s->info_callback; - } else if (s->ctx->info_callback != NULL) { - cb = s->ctx->info_callback; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; } - s->in_handshake++; + ssl->in_handshake++; for (;;) { - state = s->state; + state = ssl->state; - switch (s->state) { + switch (ssl->state) { case SSL_ST_CONNECT: if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_START, 1); + cb(ssl, SSL_CB_HANDSHAKE_START, 1); } - if (s->init_buf == NULL) { + if (ssl->init_buf == NULL) { buf = BUF_MEM_new(); if (buf == NULL || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { ret = -1; goto end; } - s->init_buf = buf; + ssl->init_buf = buf; buf = NULL; } - if (!ssl_init_wbio_buffer(s, 0)) { + if (!ssl_init_wbio_buffer(ssl, 0)) { ret = -1; goto end; } /* don't push the buffering BIO quite yet */ - s->state = SSL3_ST_CW_CLNT_HELLO_A; - s->init_num = 0; - s->d1->send_cookie = 0; - s->hit = 0; + ssl->state = SSL3_ST_CW_CLNT_HELLO_A; + ssl->init_num = 0; + ssl->d1->send_cookie = 0; + ssl->hit = 0; break; case SSL3_ST_CW_CLNT_HELLO_A: case SSL3_ST_CW_CLNT_HELLO_B: - s->shutdown = 0; - dtls1_start_timer(s); - ret = ssl3_send_client_hello(s); + ssl->shutdown = 0; + dtls1_start_timer(ssl); + ret = ssl3_send_client_hello(ssl); if (ret <= 0) { goto end; } - if (s->d1->send_cookie) { - s->state = SSL3_ST_CW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; + if (ssl->d1->send_cookie) { + ssl->state = SSL3_ST_CW_FLUSH; + ssl->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; } else { - s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; + ssl->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; } - s->init_num = 0; + ssl->init_num = 0; /* turn on buffering for the next lot of output */ - if (s->bbio != s->wbio) { - s->wbio = BIO_push(s->bbio, s->wbio); + if (ssl->bbio != ssl->wbio) { + ssl->wbio = BIO_push(ssl->bbio, ssl->wbio); } break; case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: - ret = dtls1_get_hello_verify(s); + ret = dtls1_get_hello_verify(ssl); if (ret <= 0) { goto end; } - if (s->d1->send_cookie) { + if (ssl->d1->send_cookie) { /* start again, with a cookie */ - dtls1_stop_timer(s); - s->state = SSL3_ST_CW_CLNT_HELLO_A; + dtls1_stop_timer(ssl); + ssl->state = SSL3_ST_CW_CLNT_HELLO_A; } else { - s->state = SSL3_ST_CR_SRVR_HELLO_A; + ssl->state = SSL3_ST_CR_SRVR_HELLO_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_CR_SRVR_HELLO_A: case SSL3_ST_CR_SRVR_HELLO_B: - ret = ssl3_get_server_hello(s); + ret = ssl3_get_server_hello(ssl); if (ret <= 0) { goto end; } - if (s->hit) { - s->state = SSL3_ST_CR_FINISHED_A; - if (s->tlsext_ticket_expected) { + if (ssl->hit) { + ssl->state = SSL3_ST_CR_CHANGE; + if (ssl->tlsext_ticket_expected) { /* receive renewed session ticket */ - s->state = SSL3_ST_CR_SESSION_TICKET_A; + ssl->state = SSL3_ST_CR_SESSION_TICKET_A; } } else { - s->state = SSL3_ST_CR_CERT_A; + ssl->state = SSL3_ST_CR_CERT_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_CR_CERT_A: case SSL3_ST_CR_CERT_B: - if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { - ret = ssl3_get_server_certificate(s); + if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) { + ret = ssl3_get_server_certificate(ssl); if (ret <= 0) { goto end; } - if (s->s3->tmp.certificate_status_expected) { - s->state = SSL3_ST_CR_CERT_STATUS_A; + if (ssl->s3->tmp.certificate_status_expected) { + ssl->state = SSL3_ST_CR_CERT_STATUS_A; } else { - s->state = SSL3_ST_VERIFY_SERVER_CERT; + ssl->state = SSL3_ST_VERIFY_SERVER_CERT; } } else { skip = 1; - s->state = SSL3_ST_CR_KEY_EXCH_A; + ssl->state = SSL3_ST_CR_KEY_EXCH_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_VERIFY_SERVER_CERT: - ret = ssl3_verify_server_cert(s); + ret = ssl3_verify_server_cert(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CR_KEY_EXCH_A; - s->init_num = 0; + ssl->state = SSL3_ST_CR_KEY_EXCH_A; + ssl->init_num = 0; break; case SSL3_ST_CR_KEY_EXCH_A: case SSL3_ST_CR_KEY_EXCH_B: - ret = ssl3_get_server_key_exchange(s); + ret = ssl3_get_server_key_exchange(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CR_CERT_REQ_A; - s->init_num = 0; + ssl->state = SSL3_ST_CR_CERT_REQ_A; + ssl->init_num = 0; break; case SSL3_ST_CR_CERT_REQ_A: case SSL3_ST_CR_CERT_REQ_B: - ret = ssl3_get_certificate_request(s); + ret = ssl3_get_certificate_request(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CR_SRVR_DONE_A; - s->init_num = 0; + ssl->state = SSL3_ST_CR_SRVR_DONE_A; + ssl->init_num = 0; break; case SSL3_ST_CR_SRVR_DONE_A: case SSL3_ST_CR_SRVR_DONE_B: - ret = ssl3_get_server_done(s); + ret = ssl3_get_server_done(ssl); if (ret <= 0) { goto end; } - dtls1_stop_timer(s); - if (s->s3->tmp.cert_req) { - s->s3->tmp.next_state = SSL3_ST_CW_CERT_A; + dtls1_stop_timer(ssl); + if (ssl->s3->tmp.cert_req) { + ssl->s3->tmp.next_state = SSL3_ST_CW_CERT_A; } else { - s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; + ssl->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; } - s->init_num = 0; - s->state = s->s3->tmp.next_state; + ssl->init_num = 0; + ssl->state = ssl->s3->tmp.next_state; break; case SSL3_ST_CW_CERT_A: case SSL3_ST_CW_CERT_B: case SSL3_ST_CW_CERT_C: case SSL3_ST_CW_CERT_D: - dtls1_start_timer(s); - ret = ssl3_send_client_certificate(s); + dtls1_start_timer(ssl); + ret = ssl3_send_client_certificate(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; + ssl->state = SSL3_ST_CW_KEY_EXCH_A; + ssl->init_num = 0; break; case SSL3_ST_CW_KEY_EXCH_A: case SSL3_ST_CW_KEY_EXCH_B: - dtls1_start_timer(s); - ret = ssl3_send_client_key_exchange(s); + dtls1_start_timer(ssl); + ret = ssl3_send_client_key_exchange(ssl); if (ret <= 0) { goto end; } /* For TLS, cert_req is set to 2, so a cert chain * of nothing is sent, but no verify packet is sent */ - if (s->s3->tmp.cert_req == 1) { - s->state = SSL3_ST_CW_CERT_VRFY_A; + if (ssl->s3->tmp.cert_req == 1) { + ssl->state = SSL3_ST_CW_CERT_VRFY_A; } else { - s->state = SSL3_ST_CW_CHANGE_A; - s->s3->change_cipher_spec = 0; + ssl->state = SSL3_ST_CW_CHANGE_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_CW_CERT_VRFY_A: case SSL3_ST_CW_CERT_VRFY_B: case SSL3_ST_CW_CERT_VRFY_C: - dtls1_start_timer(s); - ret = ssl3_send_cert_verify(s); + dtls1_start_timer(ssl); + ret = ssl3_send_cert_verify(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CW_CHANGE_A; - s->init_num = 0; - s->s3->change_cipher_spec = 0; + ssl->state = SSL3_ST_CW_CHANGE_A; + ssl->init_num = 0; break; case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_B: - if (!s->hit) { - dtls1_start_timer(s); + if (!ssl->hit) { + dtls1_start_timer(ssl); } - ret = dtls1_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A, + ret = dtls1_send_change_cipher_spec(ssl, SSL3_ST_CW_CHANGE_A, SSL3_ST_CW_CHANGE_B); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CW_FINISHED_A; - s->init_num = 0; + ssl->state = SSL3_ST_CW_FINISHED_A; + ssl->init_num = 0; - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->enc_method->setup_key_block(s) || - !s->enc_method->change_cipher_state( - s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { + ssl->session->cipher = ssl->s3->tmp.new_cipher; + if (!ssl->enc_method->setup_key_block(ssl) || + !ssl->enc_method->change_cipher_state( + ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { ret = -1; goto end; } - - dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); break; case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B: - if (!s->hit) { - dtls1_start_timer(s); + if (!ssl->hit) { + dtls1_start_timer(ssl); } ret = - ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B, - s->enc_method->client_finished_label, - s->enc_method->client_finished_label_len); + ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B, + ssl->enc_method->client_finished_label, + ssl->enc_method->client_finished_label_len); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CW_FLUSH; + ssl->state = SSL3_ST_CW_FLUSH; - if (s->hit) { - s->s3->tmp.next_state = SSL_ST_OK; + if (ssl->hit) { + ssl->s3->tmp.next_state = SSL_ST_OK; } else { /* Allow NewSessionTicket if ticket expected */ - if (s->tlsext_ticket_expected) { - s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; + if (ssl->tlsext_ticket_expected) { + ssl->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; } else { - s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; + ssl->s3->tmp.next_state = SSL3_ST_CR_CHANGE; } } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_CR_SESSION_TICKET_A: case SSL3_ST_CR_SESSION_TICKET_B: - ret = ssl3_get_new_session_ticket(s); + ret = ssl3_get_new_session_ticket(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CR_FINISHED_A; - s->init_num = 0; + ssl->state = SSL3_ST_CR_CHANGE; + ssl->init_num = 0; break; case SSL3_ST_CR_CERT_STATUS_A: case SSL3_ST_CR_CERT_STATUS_B: - ret = ssl3_get_cert_status(s); + ret = ssl3_get_cert_status(ssl); + if (ret <= 0) { + goto end; + } + ssl->state = SSL3_ST_VERIFY_SERVER_CERT; + ssl->init_num = 0; + break; + + case SSL3_ST_CR_CHANGE: + ret = ssl->method->ssl_read_change_cipher_spec(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_VERIFY_SERVER_CERT; - s->init_num = 0; + + if (!ssl3_do_change_cipher_spec(ssl)) { + ret = -1; + goto end; + } + ssl->state = SSL3_ST_CR_FINISHED_A; break; case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_B: - s->d1->change_cipher_spec_ok = 1; ret = - ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); + ssl3_get_finished(ssl, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); if (ret <= 0) { goto end; } - dtls1_stop_timer(s); + dtls1_stop_timer(ssl); - if (s->hit) { - s->state = SSL3_ST_CW_CHANGE_A; + if (ssl->hit) { + ssl->state = SSL3_ST_CW_CHANGE_A; } else { - s->state = SSL_ST_OK; + ssl->state = SSL_ST_OK; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_CW_FLUSH: - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { + ssl->rwstate = SSL_WRITING; + if (BIO_flush(ssl->wbio) <= 0) { ret = -1; goto end; } - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; + ssl->rwstate = SSL_NOTHING; + ssl->state = ssl->s3->tmp.next_state; break; case SSL_ST_OK: /* clean a few things up */ - ssl3_cleanup_key_block(s); + ssl3_cleanup_key_block(ssl); /* Remove write buffering now. */ - ssl_free_wbio_buffer(s); + ssl_free_wbio_buffer(ssl); - s->init_num = 0; - s->s3->initial_handshake_complete = 1; + ssl->init_num = 0; + ssl->s3->initial_handshake_complete = 1; - ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + ssl_update_cache(ssl, SSL_SESS_CACHE_CLIENT); ret = 1; if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_DONE, 1); + cb(ssl, SSL_CB_HANDSHAKE_DONE, 1); } /* done with handshaking */ - s->d1->handshake_read_seq = 0; - s->d1->next_handshake_write_seq = 0; + ssl->d1->handshake_read_seq = 0; + ssl->d1->next_handshake_write_seq = 0; goto end; default: @@ -488,36 +496,36 @@ int dtls1_connect(SSL *s) { } /* did we do anything? */ - if (!s->s3->tmp.reuse_message && !skip) { - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; + if (!ssl->s3->tmp.reuse_message && !skip) { + if ((cb != NULL) && (ssl->state != state)) { + new_state = ssl->state; + ssl->state = state; + cb(ssl, SSL_CB_CONNECT_LOOP, 1); + ssl->state = new_state; } } skip = 0; } end: - s->in_handshake--; + ssl->in_handshake--; BUF_MEM_free(buf); if (cb != NULL) { - cb(s, SSL_CB_CONNECT_EXIT, ret); + cb(ssl, SSL_CB_CONNECT_EXIT, ret); } return ret; } -static int dtls1_get_hello_verify(SSL *s) { +static int dtls1_get_hello_verify(SSL *ssl) { long n; int al, ok = 0; CBS hello_verify_request, cookie; uint16_t server_version; - n = s->method->ssl_get_message( - s, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, - -1, + n = ssl->method->ssl_get_message( + ssl, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, + DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, -1, /* Use the same maximum size as ssl3_get_server_hello. */ 20000, ssl_hash_message, &ok); @@ -525,13 +533,13 @@ static int dtls1_get_hello_verify(SSL *s) { return n; } - if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { - s->d1->send_cookie = 0; - s->s3->tmp.reuse_message = 1; + if (ssl->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { + ssl->d1->send_cookie = 0; + ssl->s3->tmp.reuse_message = 1; return 1; } - CBS_init(&hello_verify_request, s->init_msg, n); + CBS_init(&hello_verify_request, ssl->init_msg, n); if (!CBS_get_u16(&hello_verify_request, &server_version) || !CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) || @@ -541,18 +549,18 @@ static int dtls1_get_hello_verify(SSL *s) { goto f_err; } - if (CBS_len(&cookie) > sizeof(s->d1->cookie)) { + if (CBS_len(&cookie) > sizeof(ssl->d1->cookie)) { al = SSL_AD_ILLEGAL_PARAMETER; goto f_err; } - memcpy(s->d1->cookie, CBS_data(&cookie), CBS_len(&cookie)); - s->d1->cookie_len = CBS_len(&cookie); + memcpy(ssl->d1->cookie, CBS_data(&cookie), CBS_len(&cookie)); + ssl->d1->cookie_len = CBS_len(&cookie); - s->d1->send_cookie = 1; + ssl->d1->send_cookie = 1; return 1; f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); return -1; } diff --git a/src/ssl/d1_lib.c b/src/ssl/d1_lib.c index 787ad9a..7f08b06 100644 --- a/src/ssl/d1_lib.c +++ b/src/ssl/d1_lib.c @@ -84,15 +84,15 @@ static void get_current_time(const SSL *ssl, struct timeval *out_clock); -int dtls1_new(SSL *s) { +int dtls1_new(SSL *ssl) { DTLS1_STATE *d1; - if (!ssl3_new(s)) { + if (!ssl3_new(ssl)) { return 0; } d1 = OPENSSL_malloc(sizeof *d1); if (d1 == NULL) { - ssl3_free(s); + ssl3_free(ssl); return 0; } memset(d1, 0, sizeof *d1); @@ -104,52 +104,52 @@ int dtls1_new(SSL *s) { pqueue_free(d1->buffered_messages); pqueue_free(d1->sent_messages); OPENSSL_free(d1); - ssl3_free(s); + ssl3_free(ssl); return 0; } - s->d1 = d1; + ssl->d1 = d1; /* Set the version to the highest version for DTLS. This controls the initial - * state of |s->enc_method| and what the API reports as the version prior to + * state of |ssl->enc_method| and what the API reports as the version prior to * negotiation. * * TODO(davidben): This is fragile and confusing. */ - s->version = DTLS1_2_VERSION; + ssl->version = DTLS1_2_VERSION; return 1; } -static void dtls1_clear_queues(SSL *s) { +static void dtls1_clear_queues(SSL *ssl) { pitem *item = NULL; hm_fragment *frag = NULL; - while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { + while ((item = pqueue_pop(ssl->d1->buffered_messages)) != NULL) { frag = (hm_fragment *)item->data; dtls1_hm_fragment_free(frag); pitem_free(item); } - while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { + while ((item = pqueue_pop(ssl->d1->sent_messages)) != NULL) { frag = (hm_fragment *)item->data; dtls1_hm_fragment_free(frag); pitem_free(item); } } -void dtls1_free(SSL *s) { - ssl3_free(s); +void dtls1_free(SSL *ssl) { + ssl3_free(ssl); - if (s == NULL || s->d1 == NULL) { + if (ssl == NULL || ssl->d1 == NULL) { return; } - dtls1_clear_queues(s); + dtls1_clear_queues(ssl); - pqueue_free(s->d1->buffered_messages); - pqueue_free(s->d1->sent_messages); + pqueue_free(ssl->d1->buffered_messages); + pqueue_free(ssl->d1->sent_messages); - OPENSSL_free(s->d1); - s->d1 = NULL; + OPENSSL_free(ssl->d1); + ssl->d1 = NULL; } int dtls1_supports_cipher(const SSL_CIPHER *cipher) { @@ -158,19 +158,19 @@ int dtls1_supports_cipher(const SSL_CIPHER *cipher) { return cipher->algorithm_enc != SSL_RC4 && cipher->algorithm_enc != SSL_eNULL; } -void dtls1_start_timer(SSL *s) { +void dtls1_start_timer(SSL *ssl) { /* If timer is not set, initialize duration with 1 second */ - if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { - s->d1->timeout_duration = 1; + if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { + ssl->d1->timeout_duration = 1; } /* Set timeout to current time */ - get_current_time(s, &s->d1->next_timeout); + get_current_time(ssl, &ssl->d1->next_timeout); /* Add duration to current time */ - s->d1->next_timeout.tv_sec += s->d1->timeout_duration; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, - &s->d1->next_timeout); + ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration; + BIO_ctrl(SSL_get_rbio(ssl), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &ssl->d1->next_timeout); } int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) { @@ -213,11 +213,11 @@ int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) { return 1; } -int dtls1_is_timer_expired(SSL *s) { +int dtls1_is_timer_expired(SSL *ssl) { struct timeval timeleft; /* Get time left until timeout, return false if no timer running */ - if (!DTLSv1_get_timeout(s, &timeleft)) { + if (!DTLSv1_get_timeout(ssl, &timeleft)) { return 0; } @@ -230,39 +230,39 @@ int dtls1_is_timer_expired(SSL *s) { return 1; } -void dtls1_double_timeout(SSL *s) { - s->d1->timeout_duration *= 2; - if (s->d1->timeout_duration > 60) { - s->d1->timeout_duration = 60; +void dtls1_double_timeout(SSL *ssl) { + ssl->d1->timeout_duration *= 2; + if (ssl->d1->timeout_duration > 60) { + ssl->d1->timeout_duration = 60; } - dtls1_start_timer(s); + dtls1_start_timer(ssl); } -void dtls1_stop_timer(SSL *s) { +void dtls1_stop_timer(SSL *ssl) { /* Reset everything */ - s->d1->num_timeouts = 0; - memset(&s->d1->next_timeout, 0, sizeof(struct timeval)); - s->d1->timeout_duration = 1; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, - &s->d1->next_timeout); + ssl->d1->num_timeouts = 0; + memset(&ssl->d1->next_timeout, 0, sizeof(struct timeval)); + ssl->d1->timeout_duration = 1; + BIO_ctrl(SSL_get_rbio(ssl), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &ssl->d1->next_timeout); /* Clear retransmission buffer */ - dtls1_clear_record_buffer(s); + dtls1_clear_record_buffer(ssl); } -int dtls1_check_timeout_num(SSL *s) { - s->d1->num_timeouts++; +int dtls1_check_timeout_num(SSL *ssl) { + ssl->d1->num_timeouts++; /* Reduce MTU after 2 unsuccessful retransmissions */ - if (s->d1->num_timeouts > DTLS1_MTU_TIMEOUTS && - !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { - long mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, + if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS && + !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + long mtu = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) { - s->d1->mtu = (unsigned)mtu; + ssl->d1->mtu = (unsigned)mtu; } } - if (s->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) { + if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) { /* fail the connection, enough alerts have been sent */ OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED); return -1; @@ -307,21 +307,22 @@ static void get_current_time(const SSL *ssl, struct timeval *out_clock) { #endif } -int dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) { - uint8_t *message = (uint8_t *)s->init_buf->data; - const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; +int dtls1_set_handshake_header(SSL *ssl, int htype, unsigned long len) { + uint8_t *message = (uint8_t *)ssl->init_buf->data; + const struct hm_header_st *msg_hdr = &ssl->d1->w_msg_hdr; uint8_t serialised_header[DTLS1_HM_HEADER_LENGTH]; uint8_t *p = serialised_header; - s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; - s->d1->next_handshake_write_seq++; + ssl->d1->handshake_write_seq = ssl->d1->next_handshake_write_seq; + ssl->d1->next_handshake_write_seq++; - dtls1_set_message_header(s, htype, len, s->d1->handshake_write_seq, 0, len); - s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH; - s->init_off = 0; + dtls1_set_message_header(ssl, htype, len, ssl->d1->handshake_write_seq, 0, + len); + ssl->init_num = (int)len + DTLS1_HM_HEADER_LENGTH; + ssl->init_off = 0; /* Buffer the message to handle re-xmits */ - dtls1_buffer_message(s); + dtls1_buffer_message(ssl); /* Add the new message to the handshake hash. Serialize the message * header as if it were a single fragment. */ @@ -330,11 +331,11 @@ int dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) { s2n(msg_hdr->seq, p); l2n3(0, p); l2n3(msg_hdr->msg_len, p); - return ssl3_update_handshake_hash(s, serialised_header, + return ssl3_update_handshake_hash(ssl, serialised_header, sizeof(serialised_header)) && - ssl3_update_handshake_hash(s, message + DTLS1_HM_HEADER_LENGTH, len); + ssl3_update_handshake_hash(ssl, message + DTLS1_HM_HEADER_LENGTH, len); } -int dtls1_handshake_write(SSL *s) { - return dtls1_do_handshake_write(s, dtls1_use_current_epoch); +int dtls1_handshake_write(SSL *ssl) { + return dtls1_do_handshake_write(ssl, dtls1_use_current_epoch); } diff --git a/src/ssl/d1_meth.c b/src/ssl/d1_meth.c index 4dc3404..49a2595 100644 --- a/src/ssl/d1_meth.c +++ b/src/ssl/d1_meth.c @@ -67,6 +67,7 @@ static const SSL_PROTOCOL_METHOD DTLS_protocol_method = { dtls1_connect, dtls1_get_message, dtls1_read_app_data, + dtls1_read_change_cipher_spec, dtls1_read_close_notify, dtls1_write_app_data, dtls1_dispatch_alert, diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.c index 8cabdd4..f2ade3a 100644 --- a/src/ssl/d1_pkt.c +++ b/src/ssl/d1_pkt.c @@ -124,7 +124,7 @@ #include "internal.h" -static int do_dtls1_write(SSL *s, int type, const uint8_t *buf, +static int do_dtls1_write(SSL *ssl, int type, const uint8_t *buf, unsigned int len, enum dtls1_use_epoch_t use_epoch); /* dtls1_get_record reads a new input record. On success, it places it in @@ -164,7 +164,6 @@ again: SSL3_RECORD *rr = &ssl->s3->rrec; rr->type = type; rr->length = (uint16_t)len; - rr->off = 0; rr->data = out; return 1; @@ -190,6 +189,29 @@ int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) { return dtls1_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek); } +int dtls1_read_change_cipher_spec(SSL *ssl) { + uint8_t byte; + int ret = dtls1_read_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, + 1 /* len */, 0 /* no peek */); + if (ret <= 0) { + return ret; + } + assert(ret == 1); + + if (ssl->s3->rrec.length != 0 || byte != SSL3_MT_CCS) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return -1; + } + + if (ssl->msg_callback != NULL) { + ssl->msg_callback(0, ssl->version, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1, + ssl, ssl->msg_callback_arg); + } + + return 1; +} + void dtls1_read_close_notify(SSL *ssl) { /* Bidirectional shutdown doesn't make sense for an unordered transport. DTLS * alerts also aren't delivered reliably, so we may even time out because the @@ -201,44 +223,31 @@ void dtls1_read_close_notify(SSL *ssl) { /* Return up to 'len' payload bytes received in 'type' records. * 'type' is one of the following: * - * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) - * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - SSL3_RT_HANDSHAKE (when dtls1_get_message calls us) + * - SSL3_RT_CHANGE_CIPHER_SPEC (when dtls1_read_change_cipher_spec calls us) + * - SSL3_RT_APPLICATION_DATA (when dtls1_read_app_data calls us) * - * If we don't have stored data to work from, read a SSL/TLS record first - * (possibly multiple records if we still don't have anything to return). + * If we don't have stored data to work from, read a DTLS record first (possibly + * multiple records if we still don't have anything to return). * * This function must handle any surprises the peer may have for us, such as - * Alert records (e.g. close_notify), ChangeCipherSpec records (not really - * a surprise, but handled as if it were), or renegotiation requests. - * Also if record payloads contain fragments too small to process, we store - * them until there is enough for the respective protocol (the record protocol - * may use arbitrary fragmentation and even interleaving): - * Change cipher spec protocol - * just 1 byte needed, no need for keeping anything stored - * Alert protocol - * 2 bytes needed (AlertLevel, AlertDescription) - * Handshake protocol - * 4 bytes needed (HandshakeType, uint24 length) -- we just have - * to detect unexpected Client Hello and Hello Request messages - * here, anything else is handled by higher layers - * Application data protocol - * none of our business - */ -int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) { + * Alert records (e.g. close_notify) and out of records. */ +int dtls1_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek) { int al, i, ret; unsigned int n; SSL3_RECORD *rr; void (*cb)(const SSL *ssl, int type, int value) = NULL; - if ((type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) || + if ((type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE && + type != SSL3_RT_CHANGE_CIPHER_SPEC) || (peek && type != SSL3_RT_APPLICATION_DATA)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } - if (!s->in_handshake && SSL_in_init(s)) { + if (!ssl->in_handshake && SSL_in_init(ssl)) { /* type == SSL3_RT_APPLICATION_DATA */ - i = s->handshake_func(s); + i = ssl->handshake_func(ssl); if (i < 0) { return i; } @@ -249,24 +258,24 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) { } start: - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; - /* s->s3->rrec.type - is the type of record - * s->s3->rrec.data - data - * s->s3->rrec.off - offset into 'data' for next read - * s->s3->rrec.length - number of bytes. */ - rr = &s->s3->rrec; + /* ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data - data + * ssl->s3->rrec.off - offset into 'data' for next read + * ssl->s3->rrec.length - number of bytes. */ + rr = &ssl->s3->rrec; /* Check for timeout */ - if (DTLSv1_handle_timeout(s) > 0) { + if (DTLSv1_handle_timeout(ssl) > 0) { goto start; } /* get new packet if necessary */ if (rr->length == 0) { - ret = dtls1_get_record(s); + ret = dtls1_get_record(ssl); if (ret <= 0) { - ret = dtls1_read_failed(s, ret); + ret = dtls1_read_failed(ssl, ret); /* anything other than a timeout is an error */ if (ret <= 0) { return ret; @@ -278,31 +287,20 @@ start: /* we now have a packet which can be read and processed */ - /* |change_cipher_spec is set when we receive a ChangeCipherSpec and reset by - * ssl3_get_finished. */ - if (s->s3->change_cipher_spec && rr->type != SSL3_RT_HANDSHAKE && - rr->type != SSL3_RT_ALERT) { - /* We now have an unexpected record between CCS and Finished. Most likely - * the packets were reordered on their way. DTLS is unreliable, so drop the - * packet and expect the peer to retransmit. */ - rr->length = 0; - goto start; - } - /* If the other end has shut down, throw anything we read away (even in * 'peek' mode) */ - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) { rr->length = 0; - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; return 0; } - if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ - /* make sure that we are not getting application data when we - * are doing a handshake for the first time */ - if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && - (s->aead_read_ctx == NULL)) { + if (type == rr->type) { + /* Make sure that we are not getting application data when we + * are doing a handshake for the first time. */ + if (SSL_in_init(ssl) && (type == SSL3_RT_APPLICATION_DATA) && + (ssl->aead_read_ctx == NULL)) { /* TODO(davidben): Is this check redundant with the handshake_func * check? */ al = SSL_AD_UNEXPECTED_MESSAGE; @@ -325,14 +323,13 @@ start: n = (unsigned int)len; } - memcpy(buf, &(rr->data[rr->off]), n); + memcpy(buf, rr->data, n); if (!peek) { rr->length -= n; - rr->off += n; + rr->data += n; if (rr->length == 0) { - rr->off = 0; /* The record has been consumed, so we may now clear the buffer. */ - ssl_read_buffer_discard(s); + ssl_read_buffer_discard(ssl); } } @@ -351,41 +348,42 @@ start: goto f_err; } - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_ALERT, &rr->data[rr->off], 2, s, - s->msg_callback_arg); + if (ssl->msg_callback) { + ssl->msg_callback(0, ssl->version, SSL3_RT_ALERT, rr->data, 2, ssl, + ssl->msg_callback_arg); } - const uint8_t alert_level = rr->data[rr->off++]; - const uint8_t alert_descr = rr->data[rr->off++]; + const uint8_t alert_level = rr->data[0]; + const uint8_t alert_descr = rr->data[1]; rr->length -= 2; + rr->data += 2; - if (s->info_callback != NULL) { - cb = s->info_callback; - } else if (s->ctx->info_callback != NULL) { - cb = s->ctx->info_callback; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; } if (cb != NULL) { uint16_t alert = (alert_level << 8) | alert_descr; - cb(s, SSL_CB_READ_ALERT, alert); + cb(ssl, SSL_CB_READ_ALERT, alert); } if (alert_level == SSL3_AL_WARNING) { - s->s3->warn_alert = alert_descr; + ssl->s3->warn_alert = alert_descr; if (alert_descr == SSL_AD_CLOSE_NOTIFY) { - s->shutdown |= SSL_RECEIVED_SHUTDOWN; + ssl->shutdown |= SSL_RECEIVED_SHUTDOWN; return 0; } } else if (alert_level == SSL3_AL_FATAL) { char tmp[16]; - s->rwstate = SSL_NOTHING; - s->s3->fatal_alert = alert_descr; + ssl->rwstate = SSL_NOTHING; + ssl->s3->fatal_alert = alert_descr; OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr); BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); ERR_add_error_data(2, "SSL alert number ", tmp); - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->ctx, s->session); + ssl->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(ssl->ctx, ssl->session); return 0; } else { al = SSL_AD_ILLEGAL_PARAMETER; @@ -396,89 +394,74 @@ start: goto start; } - if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { - /* 'Change Cipher Spec' is just a single byte, so we know exactly what the - * record payload has to look like */ - if (rr->length != 1 || rr->off != 0 || rr->data[0] != SSL3_MT_CCS) { - al = SSL_AD_ILLEGAL_PARAMETER; - OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto f_err; - } - + /* Cross-epoch records are discarded, but we may receive out-of-order + * application data between ChangeCipherSpec and Finished or a ChangeCipherSpec + * before the appropriate point in the handshake. Those must be silently + * discarded. + * + * However, only allow the out-of-order records in the correct epoch. + * Application data must come in the encrypted epoch, and ChangeCipherSpec in + * the unencrypted epoch (we never renegotiate). Other cases fall through and + * fail with a fatal error. */ + if ((rr->type == SSL3_RT_APPLICATION_DATA && ssl->aead_read_ctx != NULL) || + (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC && ssl->aead_read_ctx == NULL)) { rr->length = 0; + goto start; + } - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, - s->msg_callback_arg); - } - - /* We can't process a CCS now, because previous handshake - * messages are still missing, so just drop it. - */ - if (!s->d1->change_cipher_spec_ok) { + if (rr->type == SSL3_RT_HANDSHAKE) { + if (type != SSL3_RT_APPLICATION_DATA) { + /* Out-of-order handshake record while looking for ChangeCipherSpec. Drop + * it silently. */ + assert(type == SSL3_RT_CHANGE_CIPHER_SPEC); + rr->length = 0; goto start; } - s->d1->change_cipher_spec_ok = 0; - - s->s3->change_cipher_spec = 1; - if (!ssl3_do_change_cipher_spec(s)) { - goto err; - } - - /* do this whenever CCS is processed */ - dtls1_reset_seq_numbers(s, SSL3_CC_READ); - - goto start; - } - - /* Unexpected handshake message. It may be a retransmitted Finished (the only - * post-CCS message). Otherwise, it's a pre-CCS handshake message from an - * unsupported renegotiation attempt. */ - if (rr->type == SSL3_RT_HANDSHAKE && !s->in_handshake) { + /* Parse the first fragment header to determine if this is a pre-CCS or + * post-CCS handshake record. DTLS resets handshake message numbers on each + * handshake, so renegotiations and retransmissions are ambiguous. */ if (rr->length < DTLS1_HM_HEADER_LENGTH) { al = SSL_AD_DECODE_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD); goto f_err; } struct hm_header_st msg_hdr; - dtls1_get_message_header(&rr->data[rr->off], &msg_hdr); + dtls1_get_message_header(rr->data, &msg_hdr); - /* Ignore a stray Finished from the previous handshake. */ if (msg_hdr.type == SSL3_MT_FINISHED) { if (msg_hdr.frag_off == 0) { /* Retransmit our last flight of messages. If the peer sends the second * Finished, they may not have received ours. Only do this for the * first fragment, in case the Finished was fragmented. */ - if (dtls1_check_timeout_num(s) < 0) { + if (dtls1_check_timeout_num(ssl) < 0) { return -1; } - dtls1_retransmit_buffered_messages(s); + dtls1_retransmit_buffered_messages(ssl); } rr->length = 0; goto start; } - } - /* We already handled these. */ - assert(rr->type != SSL3_RT_CHANGE_CIPHER_SPEC && rr->type != SSL3_RT_ALERT); + /* Otherwise, this is a pre-CCS handshake message from an unsupported + * renegotiation attempt. Fall through to the error path. */ + } al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); -err: + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); return -1; } -int dtls1_write_app_data(SSL *s, const void *buf_, int len) { +int dtls1_write_app_data(SSL *ssl, const void *buf_, int len) { int i; - if (SSL_in_init(s) && !s->in_handshake) { - i = s->handshake_func(s); + if (SSL_in_init(ssl) && !ssl->in_handshake) { + i = ssl->handshake_func(ssl); if (i < 0) { return i; } @@ -493,33 +476,33 @@ int dtls1_write_app_data(SSL *s, const void *buf_, int len) { return -1; } - i = dtls1_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf_, len, + i = dtls1_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf_, len, dtls1_use_current_epoch); return i; } /* Call this to write data in records of type 'type' It will return <= 0 if not * all data has been sent or non-blocking IO. */ -int dtls1_write_bytes(SSL *s, int type, const void *buf, int len, +int dtls1_write_bytes(SSL *ssl, int type, const void *buf, int len, enum dtls1_use_epoch_t use_epoch) { int i; assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); - s->rwstate = SSL_NOTHING; - i = do_dtls1_write(s, type, buf, len, use_epoch); + ssl->rwstate = SSL_NOTHING; + i = do_dtls1_write(ssl, type, buf, len, use_epoch); return i; } -static int do_dtls1_write(SSL *s, int type, const uint8_t *buf, +static int do_dtls1_write(SSL *ssl, int type, const uint8_t *buf, unsigned int len, enum dtls1_use_epoch_t use_epoch) { /* There should never be a pending write buffer in DTLS. One can't write half * a datagram, so the write buffer is always dropped in * |ssl_write_buffer_flush|. */ - assert(!ssl_write_buffer_is_pending(s)); + assert(!ssl_write_buffer_is_pending(ssl)); /* If we have an alert to send, lets send it */ - if (s->s3->alert_dispatch) { - int ret = s->method->ssl_dispatch_alert(s); + if (ssl->s3->alert_dispatch) { + int ret = ssl->method->ssl_dispatch_alert(ssl); if (ret <= 0) { return ret; } @@ -535,78 +518,61 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf, return 0; } - size_t max_out = len + ssl_max_seal_overhead(s); + size_t max_out = len + ssl_max_seal_overhead(ssl); uint8_t *out; size_t ciphertext_len; - if (!ssl_write_buffer_init(s, &out, max_out) || - !dtls_seal_record(s, out, &ciphertext_len, max_out, type, buf, len, + if (!ssl_write_buffer_init(ssl, &out, max_out) || + !dtls_seal_record(ssl, out, &ciphertext_len, max_out, type, buf, len, use_epoch)) { - ssl_write_buffer_clear(s); + ssl_write_buffer_clear(ssl); return -1; } - ssl_write_buffer_set_len(s, ciphertext_len); + ssl_write_buffer_set_len(ssl, ciphertext_len); - int ret = ssl_write_buffer_flush(s); + int ret = ssl_write_buffer_flush(ssl); if (ret <= 0) { return ret; } return (int)len; } -int dtls1_dispatch_alert(SSL *s) { +int dtls1_dispatch_alert(SSL *ssl) { int i, j; void (*cb)(const SSL *ssl, int type, int value) = NULL; uint8_t buf[DTLS1_AL_HEADER_LENGTH]; uint8_t *ptr = &buf[0]; - s->s3->alert_dispatch = 0; + ssl->s3->alert_dispatch = 0; memset(buf, 0x00, sizeof(buf)); - *ptr++ = s->s3->send_alert[0]; - *ptr++ = s->s3->send_alert[1]; + *ptr++ = ssl->s3->send_alert[0]; + *ptr++ = ssl->s3->send_alert[1]; - i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), + i = do_dtls1_write(ssl, SSL3_RT_ALERT, &buf[0], sizeof(buf), dtls1_use_current_epoch); if (i <= 0) { - s->s3->alert_dispatch = 1; + ssl->s3->alert_dispatch = 1; } else { - if (s->s3->send_alert[0] == SSL3_AL_FATAL) { - (void)BIO_flush(s->wbio); + if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { + (void)BIO_flush(ssl->wbio); } - if (s->msg_callback) { - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s, - s->msg_callback_arg); + if (ssl->msg_callback) { + ssl->msg_callback(1, ssl->version, SSL3_RT_ALERT, ssl->s3->send_alert, 2, + ssl, ssl->msg_callback_arg); } - if (s->info_callback != NULL) { - cb = s->info_callback; - } else if (s->ctx->info_callback != NULL) { - cb = s->ctx->info_callback; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; } if (cb != NULL) { - j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; - cb(s, SSL_CB_WRITE_ALERT, j); + j = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; + cb(ssl, SSL_CB_WRITE_ALERT, j); } } return i; } - -void dtls1_reset_seq_numbers(SSL *s, int rw) { - uint8_t *seq; - unsigned int seq_bytes = sizeof(s->s3->read_sequence); - - if (rw & SSL3_CC_READ) { - seq = s->s3->read_sequence; - s->d1->r_epoch++; - memset(&s->d1->bitmap, 0, sizeof(DTLS1_BITMAP)); - } else { - seq = s->s3->write_sequence; - memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence)); - s->d1->w_epoch++; - } - - memset(seq, 0x00, seq_bytes); -} diff --git a/src/ssl/d1_srtp.c b/src/ssl/d1_srtp.c index 115bd70..5dba8ef 100644 --- a/src/ssl/d1_srtp.c +++ b/src/ssl/d1_srtp.c @@ -133,6 +133,12 @@ const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = { { "SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32, }, + { + "SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, + }, + { + "SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, + }, {0, 0}, }; diff --git a/src/ssl/d1_srvr.c b/src/ssl/d1_srvr.c index f1e8826..3ba9411 100644 --- a/src/ssl/d1_srvr.c +++ b/src/ssl/d1_srvr.c @@ -130,131 +130,131 @@ #include "internal.h" -int dtls1_accept(SSL *s) { +int dtls1_accept(SSL *ssl) { BUF_MEM *buf = NULL; void (*cb)(const SSL *ssl, int type, int value) = NULL; uint32_t alg_a; int ret = -1; int new_state, state, skip = 0; - assert(s->handshake_func == dtls1_accept); - assert(s->server); - assert(SSL_IS_DTLS(s)); + assert(ssl->handshake_func == dtls1_accept); + assert(ssl->server); + assert(SSL_IS_DTLS(ssl)); ERR_clear_error(); ERR_clear_system_error(); - if (s->info_callback != NULL) { - cb = s->info_callback; - } else if (s->ctx->info_callback != NULL) { - cb = s->ctx->info_callback; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; } - s->in_handshake++; + ssl->in_handshake++; for (;;) { - state = s->state; + state = ssl->state; - switch (s->state) { + switch (ssl->state) { case SSL_ST_ACCEPT: if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_START, 1); + cb(ssl, SSL_CB_HANDSHAKE_START, 1); } - if (s->init_buf == NULL) { + if (ssl->init_buf == NULL) { buf = BUF_MEM_new(); if (buf == NULL || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { ret = -1; goto end; } - s->init_buf = buf; + ssl->init_buf = buf; buf = NULL; } - s->init_num = 0; + ssl->init_num = 0; - if (!ssl_init_wbio_buffer(s, 1)) { + if (!ssl_init_wbio_buffer(ssl, 1)) { ret = -1; goto end; } - if (!ssl3_init_handshake_buffer(s)) { + if (!ssl3_init_handshake_buffer(ssl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); ret = -1; goto end; } - s->state = SSL3_ST_SR_CLNT_HELLO_A; + ssl->state = SSL3_ST_SR_CLNT_HELLO_A; break; case SSL3_ST_SR_CLNT_HELLO_A: case SSL3_ST_SR_CLNT_HELLO_B: case SSL3_ST_SR_CLNT_HELLO_C: case SSL3_ST_SR_CLNT_HELLO_D: - s->shutdown = 0; - ret = ssl3_get_client_hello(s); + ssl->shutdown = 0; + ret = ssl3_get_client_hello(ssl); if (ret <= 0) { goto end; } - dtls1_stop_timer(s); - s->state = SSL3_ST_SW_SRVR_HELLO_A; - s->init_num = 0; + dtls1_stop_timer(ssl); + ssl->state = SSL3_ST_SW_SRVR_HELLO_A; + ssl->init_num = 0; break; case SSL3_ST_SW_SRVR_HELLO_A: case SSL3_ST_SW_SRVR_HELLO_B: - dtls1_start_timer(s); - ret = ssl3_send_server_hello(s); + dtls1_start_timer(ssl); + ret = ssl3_send_server_hello(ssl); if (ret <= 0) { goto end; } - if (s->hit) { - if (s->tlsext_ticket_expected) { - s->state = SSL3_ST_SW_SESSION_TICKET_A; + if (ssl->hit) { + if (ssl->tlsext_ticket_expected) { + ssl->state = SSL3_ST_SW_SESSION_TICKET_A; } else { - s->state = SSL3_ST_SW_CHANGE_A; + ssl->state = SSL3_ST_SW_CHANGE_A; } } else { - s->state = SSL3_ST_SW_CERT_A; + ssl->state = SSL3_ST_SW_CERT_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: - if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { - dtls1_start_timer(s); - ret = ssl3_send_server_certificate(s); + if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) { + dtls1_start_timer(ssl); + ret = ssl3_send_server_certificate(ssl); if (ret <= 0) { goto end; } - if (s->s3->tmp.certificate_status_expected) { - s->state = SSL3_ST_SW_CERT_STATUS_A; + if (ssl->s3->tmp.certificate_status_expected) { + ssl->state = SSL3_ST_SW_CERT_STATUS_A; } else { - s->state = SSL3_ST_SW_KEY_EXCH_A; + ssl->state = SSL3_ST_SW_KEY_EXCH_A; } } else { skip = 1; - s->state = SSL3_ST_SW_KEY_EXCH_A; + ssl->state = SSL3_ST_SW_KEY_EXCH_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_SW_CERT_STATUS_A: case SSL3_ST_SW_CERT_STATUS_B: - ret = ssl3_send_certificate_status(s); + ret = ssl3_send_certificate_status(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_KEY_EXCH_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_KEY_EXCH_A; + ssl->init_num = 0; break; case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: case SSL3_ST_SW_KEY_EXCH_C: - alg_a = s->s3->tmp.new_cipher->algorithm_auth; + alg_a = ssl->s3->tmp.new_cipher->algorithm_auth; /* Send a ServerKeyExchange message if: * - The key exchange is ephemeral or anonymous @@ -264,10 +264,10 @@ int dtls1_accept(SSL *s) { * TODO(davidben): This logic is currently duplicated * in s3_srvr.c. Fix this. In the meantime, keep them * in sync. */ - if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher) || - ((alg_a & SSL_aPSK) && s->psk_identity_hint)) { - dtls1_start_timer(s); - ret = ssl3_send_server_key_exchange(s); + if (ssl_cipher_requires_server_key_exchange(ssl->s3->tmp.new_cipher) || + ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) { + dtls1_start_timer(ssl); + ret = ssl3_send_server_key_exchange(ssl); if (ret <= 0) { goto end; } @@ -275,176 +275,187 @@ int dtls1_accept(SSL *s) { skip = 1; } - s->state = SSL3_ST_SW_CERT_REQ_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_CERT_REQ_A; + ssl->init_num = 0; break; case SSL3_ST_SW_CERT_REQ_A: case SSL3_ST_SW_CERT_REQ_B: - if (s->s3->tmp.cert_request) { - dtls1_start_timer(s); - ret = ssl3_send_certificate_request(s); + if (ssl->s3->tmp.cert_request) { + dtls1_start_timer(ssl); + ret = ssl3_send_certificate_request(ssl); if (ret <= 0) { goto end; } } else { skip = 1; } - s->state = SSL3_ST_SW_SRVR_DONE_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_SRVR_DONE_A; + ssl->init_num = 0; break; case SSL3_ST_SW_SRVR_DONE_A: case SSL3_ST_SW_SRVR_DONE_B: - dtls1_start_timer(s); - ret = ssl3_send_server_done(s); + dtls1_start_timer(ssl); + ret = ssl3_send_server_done(ssl); if (ret <= 0) { goto end; } - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; + ssl->s3->tmp.next_state = SSL3_ST_SR_CERT_A; + ssl->state = SSL3_ST_SW_FLUSH; + ssl->init_num = 0; break; case SSL3_ST_SW_FLUSH: - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { + ssl->rwstate = SSL_WRITING; + if (BIO_flush(ssl->wbio) <= 0) { ret = -1; goto end; } - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; + ssl->rwstate = SSL_NOTHING; + ssl->state = ssl->s3->tmp.next_state; break; case SSL3_ST_SR_CERT_A: case SSL3_ST_SR_CERT_B: - if (s->s3->tmp.cert_request) { - ret = ssl3_get_client_certificate(s); + if (ssl->s3->tmp.cert_request) { + ret = ssl3_get_client_certificate(ssl); if (ret <= 0) { goto end; } } - s->init_num = 0; - s->state = SSL3_ST_SR_KEY_EXCH_A; + ssl->init_num = 0; + ssl->state = SSL3_ST_SR_KEY_EXCH_A; break; case SSL3_ST_SR_KEY_EXCH_A: case SSL3_ST_SR_KEY_EXCH_B: case SSL3_ST_SR_KEY_EXCH_C: - ret = ssl3_get_client_key_exchange(s); + ret = ssl3_get_client_key_exchange(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; + ssl->state = SSL3_ST_SR_CERT_VRFY_A; + ssl->init_num = 0; break; case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: - ret = ssl3_get_cert_verify(s); + ret = ssl3_get_cert_verify(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SR_FINISHED_A; - s->init_num = 0; + ssl->state = SSL3_ST_SR_CHANGE; + ssl->init_num = 0; + break; + + case SSL3_ST_SR_CHANGE: + ret = ssl->method->ssl_read_change_cipher_spec(ssl); + if (ret <= 0) { + goto end; + } + + if (!ssl3_do_change_cipher_spec(ssl)) { + ret = -1; + goto end; + } + + ssl->state = SSL3_ST_SR_FINISHED_A; break; case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: - s->d1->change_cipher_spec_ok = 1; - ret = - ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); + ret = ssl3_get_finished(ssl, SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); if (ret <= 0) { goto end; } - dtls1_stop_timer(s); - if (s->hit) { - s->state = SSL_ST_OK; - } else if (s->tlsext_ticket_expected) { - s->state = SSL3_ST_SW_SESSION_TICKET_A; + dtls1_stop_timer(ssl); + if (ssl->hit) { + ssl->state = SSL_ST_OK; + } else if (ssl->tlsext_ticket_expected) { + ssl->state = SSL3_ST_SW_SESSION_TICKET_A; } else { - s->state = SSL3_ST_SW_CHANGE_A; + ssl->state = SSL3_ST_SW_CHANGE_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_SW_SESSION_TICKET_A: case SSL3_ST_SW_SESSION_TICKET_B: - ret = ssl3_send_new_session_ticket(s); + ret = ssl3_send_new_session_ticket(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_CHANGE_A; + ssl->init_num = 0; break; case SSL3_ST_SW_CHANGE_A: case SSL3_ST_SW_CHANGE_B: - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->enc_method->setup_key_block(s)) { + ssl->session->cipher = ssl->s3->tmp.new_cipher; + if (!ssl->enc_method->setup_key_block(ssl)) { ret = -1; goto end; } - ret = dtls1_send_change_cipher_spec(s, SSL3_ST_SW_CHANGE_A, + ret = dtls1_send_change_cipher_spec(ssl, SSL3_ST_SW_CHANGE_A, SSL3_ST_SW_CHANGE_B); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_FINISHED_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_FINISHED_A; + ssl->init_num = 0; - if (!s->enc_method->change_cipher_state( - s, SSL3_CHANGE_CIPHER_SERVER_WRITE)) { + if (!ssl->enc_method->change_cipher_state( + ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) { ret = -1; goto end; } - - dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); break; case SSL3_ST_SW_FINISHED_A: case SSL3_ST_SW_FINISHED_B: - ret = - ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A, SSL3_ST_SW_FINISHED_B, - s->enc_method->server_finished_label, - s->enc_method->server_finished_label_len); + ret = ssl3_send_finished(ssl, SSL3_ST_SW_FINISHED_A, + SSL3_ST_SW_FINISHED_B, + ssl->enc_method->server_finished_label, + ssl->enc_method->server_finished_label_len); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_FLUSH; - if (s->hit) { - s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; + ssl->state = SSL3_ST_SW_FLUSH; + if (ssl->hit) { + ssl->s3->tmp.next_state = SSL3_ST_SR_CHANGE; } else { - s->s3->tmp.next_state = SSL_ST_OK; + ssl->s3->tmp.next_state = SSL_ST_OK; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL_ST_OK: - ssl3_cleanup_key_block(s); + ssl3_cleanup_key_block(ssl); /* remove buffering on output */ - ssl_free_wbio_buffer(s); + ssl_free_wbio_buffer(ssl); - s->init_num = 0; - s->s3->initial_handshake_complete = 1; + ssl->init_num = 0; + ssl->s3->initial_handshake_complete = 1; - ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + ssl_update_cache(ssl, SSL_SESS_CACHE_SERVER); if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_DONE, 1); + cb(ssl, SSL_CB_HANDSHAKE_DONE, 1); } ret = 1; /* done handshaking, next message is client hello */ - s->d1->handshake_read_seq = 0; + ssl->d1->handshake_read_seq = 0; /* next message is server hello */ - s->d1->handshake_write_seq = 0; - s->d1->next_handshake_write_seq = 0; + ssl->d1->handshake_write_seq = 0; + ssl->d1->next_handshake_write_seq = 0; goto end; default: @@ -453,22 +464,22 @@ int dtls1_accept(SSL *s) { goto end; } - if (!s->s3->tmp.reuse_message && !skip) { - if (cb != NULL && s->state != state) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; + if (!ssl->s3->tmp.reuse_message && !skip) { + if (cb != NULL && ssl->state != state) { + new_state = ssl->state; + ssl->state = state; + cb(ssl, SSL_CB_ACCEPT_LOOP, 1); + ssl->state = new_state; } } skip = 0; } end: - s->in_handshake--; + ssl->in_handshake--; BUF_MEM_free(buf); if (cb != NULL) { - cb(s, SSL_CB_ACCEPT_EXIT, ret); + cb(ssl, SSL_CB_ACCEPT_EXIT, ret); } return ret; } diff --git a/src/ssl/internal.h b/src/ssl/internal.h index 520131e..5acb598 100644 --- a/src/ssl/internal.h +++ b/src/ssl/internal.h @@ -155,7 +155,7 @@ #include <winsock2.h> #pragma warning(pop) #else -#include <sys/types.h> +#include <sys/time.h> #endif @@ -183,6 +183,7 @@ #define SSL_AES256GCM 0x00000020L #define SSL_CHACHA20POLY1305_OLD 0x00000040L #define SSL_eNULL 0x00000080L +#define SSL_CHACHA20POLY1305 0x00000100L #define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM) @@ -194,15 +195,6 @@ /* SSL_AEAD is set for all AEADs. */ #define SSL_AEAD 0x00000010L -/* Bits for |algorithm_ssl| (protocol version). These denote the first protocol - * version which introduced the cipher. - * - * TODO(davidben): These are extremely confusing, both in code and in - * cipher rules. Try to remove them. */ -#define SSL_SSLV3 0x00000002L -#define SSL_TLSV1 SSL_SSLV3 -#define SSL_TLSV1_2 0x00000004L - /* Bits for |algorithm_prf| (handshake digest). */ #define SSL_HANDSHAKE_MAC_DEFAULT 0x1 #define SSL_HANDSHAKE_MAC_SHA256 0x2 @@ -212,11 +204,6 @@ * one, update the table in ssl_cipher.c. */ #define SSL_MAX_DIGEST 4 -/* Bits for |algo_strength|, cipher strength information. */ -#define SSL_MEDIUM 0x00000001L -#define SSL_HIGH 0x00000002L -#define SSL_FIPS 0x00000004L - /* ssl_cipher_get_evp_aead sets |*out_aead| to point to the correct EVP_AEAD * object for |cipher| protocol version |version|. It sets |*out_mac_secret_len| * and |*out_fixed_iv_len| to the MAC key length and fixed IV length, @@ -280,7 +267,7 @@ struct ssl_aead_ctx_st { EVP_AEAD_CTX ctx; /* fixed_nonce contains any bytes of the nonce that are fixed for all * records. */ - uint8_t fixed_nonce[8]; + uint8_t fixed_nonce[12]; uint8_t fixed_nonce_len, variable_nonce_len; /* variable_nonce_included_in_record is non-zero if the variable nonce * for a record is included as a prefix before the ciphertext. */ @@ -295,6 +282,9 @@ struct ssl_aead_ctx_st { /* omit_version_in_ad is non-zero if the version should be omitted * in the AEAD's ad parameter. */ char omit_version_in_ad; + /* xor_fixed_nonce is non-zero if the fixed nonce should be XOR'd into the + * variable nonce rather than prepended. */ + char xor_fixed_nonce; } /* SSL_AEAD_CTX */; /* SSL_AEAD_CTX_new creates a newly-allocated |SSL_AEAD_CTX| using the supplied @@ -517,13 +507,69 @@ int ssl3_init_handshake_hash(SSL *ssl); void ssl3_free_handshake_buffer(SSL *ssl); /* ssl3_free_handshake_hash releases the handshake hash. */ -void ssl3_free_handshake_hash(SSL *s); +void ssl3_free_handshake_hash(SSL *ssl); /* ssl3_update_handshake_hash adds |in| to the handshake buffer and handshake * hash, whichever is enabled. It returns one on success and zero on failure. */ int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len); +/* ECDH curves. */ + +#define SSL_CURVE_SECP256R1 23 +#define SSL_CURVE_SECP384R1 24 +#define SSL_CURVE_SECP521R1 25 +#define SSL_CURVE_ECDH_X25519 29 + +/* An SSL_ECDH_METHOD is an implementation of ECDH-like key exchanges for + * TLS. */ +struct ssl_ecdh_method_st { + int nid; + uint16_t curve_id; + const char name[8]; + + /* cleanup releases state in |ctx|. */ + void (*cleanup)(SSL_ECDH_CTX *ctx); + + /* generate_keypair generates a keypair and writes the public value to + * |out_public_key|. It returns one on success and zero on error. */ + int (*generate_keypair)(SSL_ECDH_CTX *ctx, CBB *out_public_key); + + /* compute_secret performs a key exchange against |peer_key| and, on + * success, returns one and sets |*out_secret| and |*out_secret_len| to + * a newly-allocated buffer containing the shared secret. The caller must + * release this buffer with |OPENSSL_free|. Otherwise, it returns zero and + * sets |*out_alert| to an alert to send to the peer. */ + int (*compute_secret)(SSL_ECDH_CTX *ctx, uint8_t **out_secret, + size_t *out_secret_len, uint8_t *out_alert, + const uint8_t *peer_key, size_t peer_key_len); +} /* SSL_ECDH_METHOD */; + +/* ssl_nid_to_curve_id looks up the curve corresponding to |nid|. On success, it + * sets |*out_curve_id| to the curve ID and returns one. Otherwise, it returns + * zero. */ +int ssl_nid_to_curve_id(uint16_t *out_curve_id, int nid); + +/* SSL_ECDH_CTX_init sets up |ctx| for use with curve |curve_id|. It returns one + * on success and zero on error. */ +int SSL_ECDH_CTX_init(SSL_ECDH_CTX *ctx, uint16_t curve_id); + +/* SSL_ECDH_CTX_init_for_dhe sets up |ctx| for use with legacy DHE-based ciphers + * where the server specifies a group. It takes ownership of |params|. */ +void SSL_ECDH_CTX_init_for_dhe(SSL_ECDH_CTX *ctx, DH *params); + +/* SSL_ECDH_CTX_cleanup releases memory associated with |ctx|. It is legal to + * call it in the zero state. */ +void SSL_ECDH_CTX_cleanup(SSL_ECDH_CTX *ctx); + +/* The following functions call the corresponding method of + * |SSL_ECDH_METHOD|. */ +int SSL_ECDH_CTX_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out_public_key); +int SSL_ECDH_CTX_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret, + size_t *out_secret_len, uint8_t *out_alert, + const uint8_t *peer_key, size_t peer_key_len); + + /* Transport buffers. */ /* ssl_read_buffer returns a pointer to contents of the read buffer. */ @@ -688,24 +734,15 @@ void ssl_write_buffer_clear(SSL *ssl); #define TLSEXT_CHANNEL_ID_SIZE 128 /* Check if an SSL structure is using DTLS */ -#define SSL_IS_DTLS(s) (s->method->is_dtls) +#define SSL_IS_DTLS(ssl) (ssl->method->is_dtls) /* See if we need explicit IV */ -#define SSL_USE_EXPLICIT_IV(s) \ - (s->enc_method->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) +#define SSL_USE_EXPLICIT_IV(ssl) \ + (ssl->enc_method->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) /* See if we use signature algorithms extension and signature algorithm before * signatures. */ -#define SSL_USE_SIGALGS(s) (s->enc_method->enc_flags & SSL_ENC_FLAG_SIGALGS) - -/* SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) | - * <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN) - * SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN) - * SSL_kDHE <- RSA_ENC | RSA_SIGN | DSA_SIGN - * SSL_aRSA <- RSA_ENC | RSA_SIGN - * SSL_aDSS <- DSA_SIGN */ +#define SSL_USE_SIGALGS(ssl) (ssl->enc_method->enc_flags & SSL_ENC_FLAG_SIGALGS) /* From RFC4492, used in encoding the curve type in ECParameters */ -#define EXPLICIT_PRIME_CURVE_TYPE 1 -#define EXPLICIT_CHAR2_CURVE_TYPE 2 #define NAMED_CURVE_TYPE 3 enum ssl_hash_message_t { @@ -740,14 +777,6 @@ typedef struct cert_st { DH *dh_tmp; DH *(*dh_tmp_cb)(SSL *ssl, int is_export, int keysize); - /* ecdh_nid, if not |NID_undef|, is the NID of the curve to use for ephemeral - * ECDH keys. If unset, |ecdh_tmp_cb| is consulted. */ - int ecdh_nid; - /* ecdh_tmp_cb is a callback for selecting the curve to use for ephemeral ECDH - * keys. If NULL, a curve is selected automatically. See - * |SSL_CTX_set_tmp_ecdh_callback|. */ - EC_KEY *(*ecdh_tmp_cb)(SSL *ssl, int is_export, int keysize); - /* peer_sigalgs are the algorithm/hash pairs that the peer supports. These * are taken from the contents of signature algorithms extension for a server * or from the CertificateRequest for a client. */ @@ -785,26 +814,27 @@ struct ssl_method_st { struct ssl_protocol_method_st { /* is_dtls is one if the protocol is DTLS and zero otherwise. */ char is_dtls; - int (*ssl_new)(SSL *s); - void (*ssl_free)(SSL *s); - int (*ssl_accept)(SSL *s); - int (*ssl_connect)(SSL *s); - long (*ssl_get_message)(SSL *s, int header_state, int body_state, + int (*ssl_new)(SSL *ssl); + void (*ssl_free)(SSL *ssl); + int (*ssl_accept)(SSL *ssl); + int (*ssl_connect)(SSL *ssl); + long (*ssl_get_message)(SSL *ssl, int header_state, int body_state, int msg_type, long max, enum ssl_hash_message_t hash_message, int *ok); - int (*ssl_read_app_data)(SSL *s, uint8_t *buf, int len, int peek); - void (*ssl_read_close_notify)(SSL *s); - int (*ssl_write_app_data)(SSL *s, const void *buf_, int len); - int (*ssl_dispatch_alert)(SSL *s); + int (*ssl_read_app_data)(SSL *ssl, uint8_t *buf, int len, int peek); + int (*ssl_read_change_cipher_spec)(SSL *ssl); + void (*ssl_read_close_notify)(SSL *ssl); + int (*ssl_write_app_data)(SSL *ssl, const void *buf_, int len); + int (*ssl_dispatch_alert)(SSL *ssl); /* supports_cipher returns one if |cipher| is supported by this protocol and * zero otherwise. */ int (*supports_cipher)(const SSL_CIPHER *cipher); /* Handshake header length */ unsigned int hhlen; /* Set the handshake header */ - int (*set_handshake_header)(SSL *s, int type, unsigned long len); + int (*set_handshake_header)(SSL *ssl, int type, unsigned long len); /* Write out handshake message */ - int (*do_write)(SSL *s); + int (*do_write)(SSL *ssl); }; /* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit @@ -828,12 +858,12 @@ struct ssl3_enc_method { unsigned int enc_flags; }; -#define SSL_HM_HEADER_LENGTH(s) s->method->hhlen -#define ssl_handshake_start(s) \ - (((uint8_t *)s->init_buf->data) + s->method->hhlen) -#define ssl_set_handshake_header(s, htype, len) \ - s->method->set_handshake_header(s, htype, len) -#define ssl_do_write(s) s->method->do_write(s) +#define SSL_HM_HEADER_LENGTH(ssl) ssl->method->hhlen +#define ssl_handshake_start(ssl) \ + (((uint8_t *)ssl->init_buf->data) + ssl->method->hhlen) +#define ssl_set_handshake_header(ssl, htype, len) \ + ssl->method->set_handshake_header(ssl, htype, len) +#define ssl_do_write(ssl) ssl->method->do_write(ssl) /* Values for enc_flags */ @@ -933,8 +963,6 @@ typedef struct dtls1_state_st { /* Timeout duration */ unsigned short timeout_duration; - - unsigned int change_cipher_spec_ok; } DTLS1_STATE; extern const SSL3_ENC_METHOD TLSv1_enc_data; @@ -943,8 +971,8 @@ extern const SSL3_ENC_METHOD TLSv1_2_enc_data; extern const SSL3_ENC_METHOD SSLv3_enc_data; extern const SRTP_PROTECTION_PROFILE kSRTPProfiles[]; -void ssl_clear_cipher_ctx(SSL *s); -int ssl_clear_bad_session(SSL *s); +void ssl_clear_cipher_ctx(SSL *ssl); +int ssl_clear_bad_session(SSL *ssl); CERT *ssl_cert_new(void); CERT *ssl_cert_dup(CERT *cert); void ssl_cert_clear_certs(CERT *c); @@ -967,14 +995,10 @@ enum ssl_session_result_t ssl_get_prev_session( SSL *ssl, SSL_SESSION **out_session, int *out_send_ticket, const struct ssl_early_callback_ctx *ctx); -STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs); -struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup( - struct ssl_cipher_preference_list_st *cipher_list); +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *ssl, const CBS *cbs); void ssl_cipher_preference_list_free( struct ssl_cipher_preference_list_st *cipher_list); -struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_from_ciphers( - STACK_OF(SSL_CIPHER) *ciphers); -struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *s); +struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *ssl); int ssl_cert_set0_chain(CERT *cert, STACK_OF(X509) *chain); int ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain); @@ -984,42 +1008,42 @@ void ssl_cert_set_cert_cb(CERT *cert, int (*cb)(SSL *ssl, void *arg), void *arg); int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain); -int ssl_add_cert_chain(SSL *s, unsigned long *l); +int ssl_add_cert_chain(SSL *ssl, unsigned long *l); void ssl_update_cache(SSL *ssl, int mode); /* ssl_get_compatible_server_ciphers determines the key exchange and * authentication cipher suite masks compatible with the server configuration - * and current ClientHello parameters of |s|. It sets |*out_mask_k| to the key + * and current ClientHello parameters of |ssl|. It sets |*out_mask_k| to the key * exchange mask and |*out_mask_a| to the authentication mask. */ -void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k, +void ssl_get_compatible_server_ciphers(SSL *ssl, uint32_t *out_mask_k, uint32_t *out_mask_a); -STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *ssl); int ssl_verify_alarm_type(long type); /* ssl_fill_hello_random fills a client_random or server_random field of length * |len|. It returns one on success and zero on failure. */ int ssl_fill_hello_random(uint8_t *out, size_t len, int is_server); -int ssl3_send_server_certificate(SSL *s); -int ssl3_send_new_session_ticket(SSL *s); -int ssl3_send_certificate_status(SSL *s); -int ssl3_get_finished(SSL *s, int state_a, int state_b); -int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b); -int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, +int ssl3_send_server_certificate(SSL *ssl); +int ssl3_send_new_session_ticket(SSL *ssl); +int ssl3_send_certificate_status(SSL *ssl); +int ssl3_get_finished(SSL *ssl, int state_a, int state_b); +int ssl3_send_change_cipher_spec(SSL *ssl, int state_a, int state_b); +int ssl3_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret, size_t secret_len, const char *label, size_t label_len, const uint8_t *seed1, size_t seed1_len, const uint8_t *seed2, size_t seed2_len); -void ssl3_cleanup_key_block(SSL *s); -int ssl3_do_write(SSL *s, int type); -int ssl3_send_alert(SSL *s, int level, int desc); -int ssl3_get_req_cert_type(SSL *s, uint8_t *p); -long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type, +void ssl3_cleanup_key_block(SSL *ssl); +int ssl3_do_write(SSL *ssl, int type); +int ssl3_send_alert(SSL *ssl, int level, int desc); +int ssl3_get_req_cert_type(SSL *ssl, uint8_t *p); +long ssl3_get_message(SSL *ssl, int header_state, int body_state, int msg_type, long max, enum ssl_hash_message_t hash_message, int *ok); /* ssl3_hash_current_message incorporates the current handshake message into the * handshake hash. It returns one on success and zero on allocation failure. */ -int ssl3_hash_current_message(SSL *s); +int ssl3_hash_current_message(SSL *ssl); /* ssl3_cert_verify_hash writes the CertificateVerify hash into the bytes * pointed to by |out| and writes the number of bytes to |*out_len|. |out| must @@ -1027,29 +1051,29 @@ int ssl3_hash_current_message(SSL *s); * for the hash function, otherwise the hash function depends on |pkey_type| * and is written to |*out_md|. It returns one on success and zero on * failure. */ -int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len, +int ssl3_cert_verify_hash(SSL *ssl, uint8_t *out, size_t *out_len, const EVP_MD **out_md, int pkey_type); -int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen); +int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen); int ssl3_supports_cipher(const SSL_CIPHER *cipher); -int ssl3_dispatch_alert(SSL *s); -int ssl3_expect_change_cipher_spec(SSL *s); +int ssl3_dispatch_alert(SSL *ssl); int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek); +int ssl3_read_change_cipher_spec(SSL *ssl); void ssl3_read_close_notify(SSL *ssl); -int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek); +int ssl3_read_bytes(SSL *ssl, int type, uint8_t *buf, int len, int peek); int ssl3_write_app_data(SSL *ssl, const void *buf, int len); -int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); -int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, uint8_t *p); -int ssl3_cert_verify_mac(SSL *s, int md_nid, uint8_t *p); -int ssl3_output_cert_chain(SSL *s); +int ssl3_write_bytes(SSL *ssl, int type, const void *buf, int len); +int ssl3_final_finish_mac(SSL *ssl, const char *sender, int slen, uint8_t *p); +int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p); +int ssl3_output_cert_chain(SSL *ssl); const SSL_CIPHER *ssl3_choose_cipher( SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, struct ssl_cipher_preference_list_st *srvr); -int ssl3_new(SSL *s); -void ssl3_free(SSL *s); -int ssl3_accept(SSL *s); -int ssl3_connect(SSL *s); +int ssl3_new(SSL *ssl); +void ssl3_free(SSL *ssl); +int ssl3_accept(SSL *ssl); +int ssl3_connect(SSL *ssl); /* ssl3_record_sequence_update increments the sequence number in |seq|. It * returns one on success and zero on wraparound. */ @@ -1057,102 +1081,102 @@ int ssl3_record_sequence_update(uint8_t *seq, size_t seq_len); int ssl3_do_change_cipher_spec(SSL *ssl); -int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len); -int ssl3_handshake_write(SSL *s); +int ssl3_set_handshake_header(SSL *ssl, int htype, unsigned long len); +int ssl3_handshake_write(SSL *ssl); -int dtls1_do_handshake_write(SSL *s, enum dtls1_use_epoch_t use_epoch); +int dtls1_do_handshake_write(SSL *ssl, enum dtls1_use_epoch_t use_epoch); int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek); +int dtls1_read_change_cipher_spec(SSL *ssl); void dtls1_read_close_notify(SSL *ssl); -int dtls1_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek); -void dtls1_set_message_header(SSL *s, uint8_t mt, unsigned long len, +int dtls1_read_bytes(SSL *ssl, int type, uint8_t *buf, int len, int peek); +void dtls1_set_message_header(SSL *ssl, uint8_t mt, unsigned long len, unsigned short seq_num, unsigned long frag_off, unsigned long frag_len); -int dtls1_write_app_data(SSL *s, const void *buf, int len); -int dtls1_write_bytes(SSL *s, int type, const void *buf, int len, +int dtls1_write_app_data(SSL *ssl, const void *buf, int len); +int dtls1_write_bytes(SSL *ssl, int type, const void *buf, int len, enum dtls1_use_epoch_t use_epoch); -int dtls1_send_change_cipher_spec(SSL *s, int a, int b); -int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen); -int dtls1_read_failed(SSL *s, int code); -int dtls1_buffer_message(SSL *s); -int dtls1_retransmit_buffered_messages(SSL *s); -void dtls1_clear_record_buffer(SSL *s); +int dtls1_send_change_cipher_spec(SSL *ssl, int a, int b); +int dtls1_send_finished(SSL *ssl, int a, int b, const char *sender, int slen); +int dtls1_read_failed(SSL *ssl, int code); +int dtls1_buffer_message(SSL *ssl); +int dtls1_retransmit_buffered_messages(SSL *ssl); +void dtls1_clear_record_buffer(SSL *ssl); void dtls1_get_message_header(uint8_t *data, struct hm_header_st *msg_hdr); -void dtls1_reset_seq_numbers(SSL *s, int rw); -int dtls1_check_timeout_num(SSL *s); -int dtls1_set_handshake_header(SSL *s, int type, unsigned long len); -int dtls1_handshake_write(SSL *s); +int dtls1_check_timeout_num(SSL *ssl); +int dtls1_set_handshake_header(SSL *ssl, int type, unsigned long len); +int dtls1_handshake_write(SSL *ssl); int dtls1_supports_cipher(const SSL_CIPHER *cipher); -void dtls1_start_timer(SSL *s); -void dtls1_stop_timer(SSL *s); -int dtls1_is_timer_expired(SSL *s); -void dtls1_double_timeout(SSL *s); +void dtls1_start_timer(SSL *ssl); +void dtls1_stop_timer(SSL *ssl); +int dtls1_is_timer_expired(SSL *ssl); +void dtls1_double_timeout(SSL *ssl); unsigned int dtls1_min_mtu(void); void dtls1_hm_fragment_free(hm_fragment *frag); /* some client-only functions */ int ssl3_send_client_hello(SSL *ssl); -int ssl3_get_server_hello(SSL *s); -int ssl3_get_certificate_request(SSL *s); -int ssl3_get_new_session_ticket(SSL *s); -int ssl3_get_cert_status(SSL *s); -int ssl3_get_server_done(SSL *s); -int ssl3_send_cert_verify(SSL *s); -int ssl3_send_client_certificate(SSL *s); -int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); -int ssl3_send_client_key_exchange(SSL *s); -int ssl3_get_server_key_exchange(SSL *s); -int ssl3_get_server_certificate(SSL *s); +int ssl3_get_server_hello(SSL *ssl); +int ssl3_get_certificate_request(SSL *ssl); +int ssl3_get_new_session_ticket(SSL *ssl); +int ssl3_get_cert_status(SSL *ssl); +int ssl3_get_server_done(SSL *ssl); +int ssl3_send_cert_verify(SSL *ssl); +int ssl3_send_client_certificate(SSL *ssl); +int ssl_do_client_cert_cb(SSL *ssl, X509 **px509, EVP_PKEY **ppkey); +int ssl3_send_client_key_exchange(SSL *ssl); +int ssl3_get_server_key_exchange(SSL *ssl); +int ssl3_get_server_certificate(SSL *ssl); int ssl3_send_next_proto(SSL *ssl); int ssl3_send_channel_id(SSL *ssl); -int ssl3_verify_server_cert(SSL *s); +int ssl3_verify_server_cert(SSL *ssl); /* some server-only functions */ -int ssl3_get_initial_bytes(SSL *s); -int ssl3_get_v2_client_hello(SSL *s); -int ssl3_get_client_hello(SSL *s); +int ssl3_get_initial_bytes(SSL *ssl); +int ssl3_get_v2_client_hello(SSL *ssl); +int ssl3_get_client_hello(SSL *ssl); int ssl3_send_server_hello(SSL *ssl); -int ssl3_send_server_key_exchange(SSL *s); -int ssl3_send_certificate_request(SSL *s); -int ssl3_send_server_done(SSL *s); -int ssl3_get_client_certificate(SSL *s); -int ssl3_get_client_key_exchange(SSL *s); -int ssl3_get_cert_verify(SSL *s); -int ssl3_get_next_proto(SSL *s); -int ssl3_get_channel_id(SSL *s); - -int dtls1_new(SSL *s); -int dtls1_accept(SSL *s); -int dtls1_connect(SSL *s); -void dtls1_free(SSL *s); - -long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, +int ssl3_send_server_key_exchange(SSL *ssl); +int ssl3_send_certificate_request(SSL *ssl); +int ssl3_send_server_done(SSL *ssl); +int ssl3_get_client_certificate(SSL *ssl); +int ssl3_get_client_key_exchange(SSL *ssl); +int ssl3_get_cert_verify(SSL *ssl); +int ssl3_get_next_proto(SSL *ssl); +int ssl3_get_channel_id(SSL *ssl); + +int dtls1_new(SSL *ssl); +int dtls1_accept(SSL *ssl); +int dtls1_connect(SSL *ssl); +void dtls1_free(SSL *ssl); + +long dtls1_get_message(SSL *ssl, int st1, int stn, int mt, long max, enum ssl_hash_message_t hash_message, int *ok); -int dtls1_dispatch_alert(SSL *s); +int dtls1_dispatch_alert(SSL *ssl); -int ssl_init_wbio_buffer(SSL *s, int push); -void ssl_free_wbio_buffer(SSL *s); +int ssl_init_wbio_buffer(SSL *ssl, int push); +void ssl_free_wbio_buffer(SSL *ssl); -/* tls1_prf computes the TLS PRF function for |s| as described in RFC 5246, +/* tls1_prf computes the TLS PRF function for |ssl| as described in RFC 5246, * section 5 and RFC 2246 section 5. It writes |out_len| bytes to |out|, using * |secret| as the secret and |label| as the label. |seed1| and |seed2| are * concatenated to form the seed parameter. It returns one on success and zero * on failure. */ -int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, +int tls1_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret, size_t secret_len, const char *label, size_t label_len, const uint8_t *seed1, size_t seed1_len, const uint8_t *seed2, size_t seed2_len); -int tls1_change_cipher_state(SSL *s, int which); -int tls1_setup_key_block(SSL *s); -int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len); -int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *p); -int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *p); -int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster, +int tls1_change_cipher_state(SSL *ssl, int which); +int tls1_setup_key_block(SSL *ssl); +int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len); +int tls1_final_finish_mac(SSL *ssl, const char *str, int slen, uint8_t *p); +int tls1_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p); +int tls1_generate_master_secret(SSL *ssl, uint8_t *out, const uint8_t *premaster, size_t premaster_len); -int tls1_export_keying_material(SSL *s, uint8_t *out, size_t out_len, +int tls1_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, const uint8_t *context, size_t context_len, int use_context); @@ -1160,24 +1184,16 @@ int tls1_alert_code(int code); int ssl3_alert_code(int code); char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx); -int tls1_ec_curve_id2nid(uint16_t curve_id); -int tls1_ec_nid2curve_id(uint16_t *out_curve_id, int nid); - -/* tls1_ec_curve_id2name returns a human-readable name for the - * curve specified by the TLS curve id in |curve_id|. If the - * curve is unknown, it returns NULL. */ -const char* tls1_ec_curve_id2name(uint16_t curve_id); -/* tls1_check_curve parses ECParameters out of |cbs|, modifying it. It - * checks the curve is one of our preferences and writes the - * NamedCurve value to |*out_curve_id|. It returns one on success and - * zero on error. */ -int tls1_check_curve(SSL *s, CBS *cbs, uint16_t *out_curve_id); +/* tls1_check_curve_id returns one if |curve_id| is consistent with both our + * and the peer's curve preferences. Note: if called as the client, only our + * preferences are checked; the peer (the server) does not send preferences. */ +int tls1_check_curve_id(SSL *ssl, uint16_t curve_id); -/* tls1_get_shared_curve returns the NID of the first preferred shared curve - * between client and server preferences. If none can be found, it returns - * NID_undef. */ -int tls1_get_shared_curve(SSL *s); +/* tls1_get_shared_curve sets |*out_curve_id| to the first preferred shared + * curve between client and server preferences and returns one. If none may be + * found, it returns zero. */ +int tls1_get_shared_curve(SSL *ssl, uint16_t *out_curve_id); /* tls1_set_curves converts the array of |ncurves| NIDs pointed to by |curves| * into a newly allocated array of TLS curve IDs. On success, the function @@ -1189,14 +1205,7 @@ int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len, /* tls1_check_ec_cert returns one if |x| is an ECC certificate with curve and * point format compatible with the client's preferences. Otherwise it returns * zero. */ -int tls1_check_ec_cert(SSL *s, X509 *x); - -/* tls1_check_ec_tmp_key returns one if the EC temporary key is compatible with - * client extensions and zero otherwise. */ -int tls1_check_ec_tmp_key(SSL *s); - -int tls1_shared_list(SSL *s, const uint8_t *l1, size_t l1len, const uint8_t *l2, - size_t l2len, int nmatch); +int tls1_check_ec_cert(SSL *ssl, X509 *x); /* ssl_add_clienthello_tlsext writes ClientHello extensions to |out|. It * returns one on success and zero on failure. The |header_len| argument is the @@ -1205,8 +1214,8 @@ int tls1_shared_list(SSL *s, const uint8_t *l1, size_t l1len, const uint8_t *l2, int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len); int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out); -int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs); -int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs); +int ssl_parse_clienthello_tlsext(SSL *ssl, CBS *cbs); +int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs); #define tlsext_tick_md EVP_sha256 @@ -1220,10 +1229,11 @@ int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session, size_t ticket_len, const uint8_t *session_id, size_t session_id_len); -/* tls12_get_sigandhash assembles the SignatureAndHashAlgorithm corresponding to - * |ssl|'s private key and |md|. The two-byte value is written to |p|. It +/* tls12_add_sigandhash assembles the SignatureAndHashAlgorithm corresponding to + * |ssl|'s private key and |md|. The two-byte value is written to |out|. It * returns one on success and zero on failure. */ -int tls12_get_sigandhash(SSL *ssl, uint8_t *p, const EVP_MD *md); +int tls12_add_sigandhash(SSL *ssl, CBB *out, const EVP_MD *md); + int tls12_get_sigid(int pkey_type); const EVP_MD *tls12_get_hash(uint8_t hash_alg); @@ -1232,50 +1242,50 @@ const EVP_MD *tls12_get_hash(uint8_t hash_alg); * one on success and zero on failure. */ int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len); -int tls1_record_handshake_hashes_for_channel_id(SSL *s); +int tls1_record_handshake_hashes_for_channel_id(SSL *ssl); -/* ssl_ctx_log_rsa_client_key_exchange logs |premaster| to |ctx|, if logging is - * enabled. It returns one on success and zero on failure. The entry is - * identified by the first 8 bytes of |encrypted_premaster|. */ -int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx, - const uint8_t *encrypted_premaster, - size_t encrypted_premaster_len, - const uint8_t *premaster, - size_t premaster_len); +/* ssl_log_rsa_client_key_exchange logs |premaster|, if logging is enabled for + * |ssl|. It returns one on success and zero on failure. The entry is identified + * by the first 8 bytes of |encrypted_premaster|. */ +int ssl_log_rsa_client_key_exchange(const SSL *ssl, + const uint8_t *encrypted_premaster, + size_t encrypted_premaster_len, + const uint8_t *premaster, + size_t premaster_len); -/* ssl_ctx_log_master_secret logs |master| to |ctx|, if logging is enabled. It +/* ssl_log_master_secret logs |master|, if logging is enabled for |ssl|. It * returns one on success and zero on failure. The entry is identified by * |client_random|. */ -int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random, - size_t client_random_len, const uint8_t *master, - size_t master_len); +int ssl_log_master_secret(const SSL *ssl, const uint8_t *client_random, + size_t client_random_len, const uint8_t *master, + size_t master_len); -/* ssl3_can_false_start returns one if |s| is allowed to False Start and zero +/* ssl3_can_false_start returns one if |ssl| is allowed to False Start and zero * otherwise. */ -int ssl3_can_false_start(const SSL *s); +int ssl3_can_false_start(const SSL *ssl); /* ssl3_get_enc_method returns the SSL3_ENC_METHOD corresponding to * |version|. */ const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version); /* ssl3_get_max_server_version returns the maximum SSL/TLS version number - * supported by |s| as a server, or zero if all versions are disabled. */ -uint16_t ssl3_get_max_server_version(const SSL *s); + * supported by |ssl| as a server, or zero if all versions are disabled. */ +uint16_t ssl3_get_max_server_version(const SSL *ssl); -/* ssl3_get_mutual_version selects the protocol version on |s| for a client +/* ssl3_get_mutual_version selects the protocol version on |ssl| for a client * which advertises |client_version|. If no suitable version exists, it returns * zero. */ -uint16_t ssl3_get_mutual_version(SSL *s, uint16_t client_version); +uint16_t ssl3_get_mutual_version(SSL *ssl, uint16_t client_version); /* ssl3_get_max_client_version returns the maximum protocol version configured * for the client. It is guaranteed that the set of allowed versions at or below * this maximum version is contiguous. If all versions are disabled, it returns * zero. */ -uint16_t ssl3_get_max_client_version(SSL *s); +uint16_t ssl3_get_max_client_version(SSL *ssl); /* ssl3_is_version_enabled returns one if |version| is an enabled protocol - * version for |s| and zero otherwise. */ -int ssl3_is_version_enabled(SSL *s, uint16_t version); + * version for |ssl| and zero otherwise. */ +int ssl3_is_version_enabled(SSL *ssl, uint16_t version); /* ssl3_version_from_wire maps |wire_version| to a protocol version. For * SSLv3/TLS, the version is returned as-is. For DTLS, the corresponding TLS @@ -1284,16 +1294,16 @@ int ssl3_is_version_enabled(SSL *s, uint16_t version); * * TODO(davidben): To normalize some DTLS-specific code, move away from using * the wire version except at API boundaries. */ -uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version); +uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version); -uint32_t ssl_get_algorithm_prf(SSL *s); -int tls1_parse_peer_sigalgs(SSL *s, const CBS *sigalgs); +uint32_t ssl_get_algorithm_prf(SSL *ssl); +int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *sigalgs); /* tls1_choose_signing_digest returns a digest for use with |ssl|'s private key * based on the peer's preferences the digests supported. */ const EVP_MD *tls1_choose_signing_digest(SSL *ssl); -size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs); +size_t tls12_get_psigalgs(SSL *ssl, const uint8_t **psigs); /* tls12_check_peer_sigalg checks that |hash| and |signature| are consistent * with |pkey| and |ssl|'s sent, supported signature algorithms and, if so, @@ -1301,6 +1311,6 @@ size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs); * returns 0 and writes an alert into |*out_alert|. */ int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert, uint8_t hash, uint8_t signature, EVP_PKEY *pkey); -void ssl_set_client_disabled(SSL *s); +void ssl_set_client_disabled(SSL *ssl); #endif /* OPENSSL_HEADER_SSL_INTERNAL_H */ diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c index 31e36c7..01a7e8c 100644 --- a/src/ssl/s3_both.c +++ b/src/ssl/s3_both.c @@ -130,127 +130,119 @@ #include "internal.h" -/* ssl3_do_write sends |s->init_buf| in records of type 'type' +/* ssl3_do_write sends |ssl->init_buf| in records of type 'type' * (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC). It returns -1 on error, 1 * on success or zero if the transmission is still incomplete. */ -int ssl3_do_write(SSL *s, int type) { +int ssl3_do_write(SSL *ssl, int type) { int n; - n = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], s->init_num); + n = ssl3_write_bytes(ssl, type, &ssl->init_buf->data[ssl->init_off], + ssl->init_num); if (n < 0) { return -1; } - if (n == s->init_num) { - if (s->msg_callback) { - s->msg_callback(1, s->version, type, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, - s->msg_callback_arg); + if (n == ssl->init_num) { + if (ssl->msg_callback) { + ssl->msg_callback(1, ssl->version, type, ssl->init_buf->data, + (size_t)(ssl->init_off + ssl->init_num), ssl, + ssl->msg_callback_arg); } return 1; } - s->init_off += n; - s->init_num -= n; + ssl->init_off += n; + ssl->init_num -= n; return 0; } -int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) { +int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen) { uint8_t *p; int n; - if (s->state == a) { - p = ssl_handshake_start(s); + if (ssl->state == a) { + p = ssl_handshake_start(ssl); - n = s->enc_method->final_finish_mac(s, sender, slen, s->s3->tmp.finish_md); + n = ssl->enc_method->final_finish_mac(ssl, sender, slen, + ssl->s3->tmp.finish_md); if (n == 0) { return 0; } - s->s3->tmp.finish_md_len = n; - memcpy(p, s->s3->tmp.finish_md, n); + ssl->s3->tmp.finish_md_len = n; + memcpy(p, ssl->s3->tmp.finish_md, n); /* Log the master secret, if logging is enabled. */ - if (!ssl_ctx_log_master_secret(s->ctx, s->s3->client_random, - SSL3_RANDOM_SIZE, s->session->master_key, - s->session->master_key_length)) { + if (!ssl_log_master_secret(ssl, ssl->s3->client_random, SSL3_RANDOM_SIZE, + ssl->session->master_key, + ssl->session->master_key_length)) { return 0; } /* Copy the finished so we can use it for renegotiation checks */ - if (s->server) { + if (ssl->server) { assert(n <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, n); - s->s3->previous_server_finished_len = n; + memcpy(ssl->s3->previous_server_finished, ssl->s3->tmp.finish_md, n); + ssl->s3->previous_server_finished_len = n; } else { assert(n <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, n); - s->s3->previous_client_finished_len = n; + memcpy(ssl->s3->previous_client_finished, ssl->s3->tmp.finish_md, n); + ssl->s3->previous_client_finished_len = n; } - if (!ssl_set_handshake_header(s, SSL3_MT_FINISHED, n)) { + if (!ssl_set_handshake_header(ssl, SSL3_MT_FINISHED, n)) { return 0; } - s->state = b; + ssl->state = b; } /* SSL3_ST_SEND_xxxxxx_HELLO_B */ - return ssl_do_write(s); + return ssl_do_write(ssl); } /* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen * so far. */ -static void ssl3_take_mac(SSL *s) { +static void ssl3_take_mac(SSL *ssl) { const char *sender; int slen; /* If no new cipher setup then return immediately: other functions will set * the appropriate error. */ - if (s->s3->tmp.new_cipher == NULL) { + if (ssl->s3->tmp.new_cipher == NULL) { return; } - if (s->state & SSL_ST_CONNECT) { - sender = s->enc_method->server_finished_label; - slen = s->enc_method->server_finished_label_len; + if (ssl->state & SSL_ST_CONNECT) { + sender = ssl->enc_method->server_finished_label; + slen = ssl->enc_method->server_finished_label_len; } else { - sender = s->enc_method->client_finished_label; - slen = s->enc_method->client_finished_label_len; + sender = ssl->enc_method->client_finished_label; + slen = ssl->enc_method->client_finished_label_len; } - s->s3->tmp.peer_finish_md_len = s->enc_method->final_finish_mac( - s, sender, slen, s->s3->tmp.peer_finish_md); + ssl->s3->tmp.peer_finish_md_len = ssl->enc_method->final_finish_mac( + ssl, sender, slen, ssl->s3->tmp.peer_finish_md); } -int ssl3_get_finished(SSL *s, int a, int b) { +int ssl3_get_finished(SSL *ssl, int a, int b) { int al, finished_len, ok; long message_len; uint8_t *p; - message_len = - s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, EVP_MAX_MD_SIZE, - ssl_dont_hash_message, &ok); + message_len = ssl->method->ssl_get_message( + ssl, a, b, SSL3_MT_FINISHED, EVP_MAX_MD_SIZE, ssl_dont_hash_message, &ok); if (!ok) { return message_len; } /* Snapshot the finished hash before incorporating the new message. */ - ssl3_take_mac(s); - if (!ssl3_hash_current_message(s)) { + ssl3_take_mac(ssl); + if (!ssl3_hash_current_message(ssl)) { goto err; } - /* If this occurs, we have missed a message. - * TODO(davidben): Is this check now redundant with SSL3_FLAGS_EXPECT_CCS? */ - if (!s->s3->change_cipher_spec) { - al = SSL_AD_UNEXPECTED_MESSAGE; - OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_A_FIN_BEFORE_A_CCS); - goto f_err; - } - s->s3->change_cipher_spec = 0; - - p = s->init_msg; - finished_len = s->s3->tmp.peer_finish_md_len; + p = ssl->init_msg; + finished_len = ssl->s3->tmp.peer_finish_md_len; if (finished_len != message_len) { al = SSL_AD_DECODE_ERROR; @@ -258,134 +250,137 @@ int ssl3_get_finished(SSL *s, int a, int b) { goto f_err; } - if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, finished_len) != 0) { + if (CRYPTO_memcmp(p, ssl->s3->tmp.peer_finish_md, finished_len) != 0) { al = SSL_AD_DECRYPT_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); goto f_err; } /* Copy the finished so we can use it for renegotiation checks */ - if (s->server) { + if (ssl->server) { assert(finished_len <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, finished_len); - s->s3->previous_client_finished_len = finished_len; + memcpy(ssl->s3->previous_client_finished, ssl->s3->tmp.peer_finish_md, + finished_len); + ssl->s3->previous_client_finished_len = finished_len; } else { assert(finished_len <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, finished_len); - s->s3->previous_server_finished_len = finished_len; + memcpy(ssl->s3->previous_server_finished, ssl->s3->tmp.peer_finish_md, + finished_len); + ssl->s3->previous_server_finished_len = finished_len; } return 1; f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: return 0; } /* for these 2 messages, we need to - * ssl->enc_read_ctx re-init - * ssl->s3->read_sequence zero - * ssl->s3->read_mac_secret re-init - * ssl->session->read_sym_enc assign - * ssl->session->read_compression assign - * ssl->session->read_hash assign */ -int ssl3_send_change_cipher_spec(SSL *s, int a, int b) { - if (s->state == a) { - *((uint8_t *)s->init_buf->data) = SSL3_MT_CCS; - s->init_num = 1; - s->init_off = 0; - - s->state = b; + * ssl->enc_read_ctx re-init + * ssl->s3->read_sequence zero + * ssl->s3->read_mac_secret re-init + * ssl->session->read_sym_enc assign + * ssl->session->read_compression assign + * ssl->session->read_hash assign */ +int ssl3_send_change_cipher_spec(SSL *ssl, int a, int b) { + if (ssl->state == a) { + *((uint8_t *)ssl->init_buf->data) = SSL3_MT_CCS; + ssl->init_num = 1; + ssl->init_off = 0; + + ssl->state = b; } /* SSL3_ST_CW_CHANGE_B */ - return ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); + return ssl3_do_write(ssl, SSL3_RT_CHANGE_CIPHER_SPEC); } -int ssl3_output_cert_chain(SSL *s) { +int ssl3_output_cert_chain(SSL *ssl) { uint8_t *p; - unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s); + unsigned long l = 3 + SSL_HM_HEADER_LENGTH(ssl); - if (!ssl_add_cert_chain(s, &l)) { + if (!ssl_add_cert_chain(ssl, &l)) { return 0; } - l -= 3 + SSL_HM_HEADER_LENGTH(s); - p = ssl_handshake_start(s); + l -= 3 + SSL_HM_HEADER_LENGTH(ssl); + p = ssl_handshake_start(ssl); l2n3(l, p); l += 3; - return ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l); + return ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE, l); } /* Obtain handshake message of message type |msg_type| (any if |msg_type| == -1), * maximum acceptable body length |max|. The first four bytes (msg_type and - * length) are read in state |header_state|, the body is read in state |body_state|. */ -long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type, + * length) are read in state |header_state|, the body is read in state + * |body_state|. */ +long ssl3_get_message(SSL *ssl, int header_state, int body_state, int msg_type, long max, enum ssl_hash_message_t hash_message, int *ok) { uint8_t *p; unsigned long l; long n; int al; - if (s->s3->tmp.reuse_message) { + if (ssl->s3->tmp.reuse_message) { /* A ssl_dont_hash_message call cannot be combined with reuse_message; the * ssl_dont_hash_message would have to have been applied to the previous * call. */ assert(hash_message == ssl_hash_message); - s->s3->tmp.reuse_message = 0; - if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) { + ssl->s3->tmp.reuse_message = 0; + if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) { al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } *ok = 1; - s->state = body_state; - s->init_msg = (uint8_t *)s->init_buf->data + 4; - s->init_num = (int)s->s3->tmp.message_size; - return s->init_num; + ssl->state = body_state; + ssl->init_msg = (uint8_t *)ssl->init_buf->data + 4; + ssl->init_num = (int)ssl->s3->tmp.message_size; + return ssl->init_num; } - p = (uint8_t *)s->init_buf->data; + p = (uint8_t *)ssl->init_buf->data; - if (s->state == header_state) { - assert(s->init_num < 4); + if (ssl->state == header_state) { + assert(ssl->init_num < 4); for (;;) { - while (s->init_num < 4) { - int bytes_read = ssl3_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], - 4 - s->init_num, 0); + while (ssl->init_num < 4) { + int bytes_read = ssl3_read_bytes( + ssl, SSL3_RT_HANDSHAKE, &p[ssl->init_num], 4 - ssl->init_num, 0); if (bytes_read <= 0) { *ok = 0; return bytes_read; } - s->init_num += bytes_read; + ssl->init_num += bytes_read; } static const uint8_t kHelloRequest[4] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0}; - if (s->server || memcmp(p, kHelloRequest, sizeof(kHelloRequest)) != 0) { + if (ssl->server || memcmp(p, kHelloRequest, sizeof(kHelloRequest)) != 0) { break; } /* The server may always send 'Hello Request' messages -- we are doing * a handshake anyway now, so ignore them if their format is correct. * Does not count for 'Finished' MAC. */ - s->init_num = 0; + ssl->init_num = 0; - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, 4, s, - s->msg_callback_arg); + if (ssl->msg_callback) { + ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, p, 4, ssl, + ssl->msg_callback_arg); } } - /* s->init_num == 4 */ + /* ssl->init_num == 4 */ if (msg_type >= 0 && *p != msg_type) { al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } - s->s3->tmp.message_type = *(p++); + ssl->s3->tmp.message_type = *(p++); n2l3(p, l); if (l > (unsigned long)max) { @@ -394,57 +389,57 @@ long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type, goto f_err; } - if (l && !BUF_MEM_grow_clean(s->init_buf, l + 4)) { + if (l && !BUF_MEM_grow_clean(ssl->init_buf, l + 4)) { OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); goto err; } - s->s3->tmp.message_size = l; - s->state = body_state; + ssl->s3->tmp.message_size = l; + ssl->state = body_state; - s->init_msg = (uint8_t *)s->init_buf->data + 4; - s->init_num = 0; + ssl->init_msg = (uint8_t *)ssl->init_buf->data + 4; + ssl->init_num = 0; } /* next state (body_state) */ - p = s->init_msg; - n = s->s3->tmp.message_size - s->init_num; + p = ssl->init_msg; + n = ssl->s3->tmp.message_size - ssl->init_num; while (n > 0) { - int bytes_read = ssl3_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], n, - 0); + int bytes_read = + ssl3_read_bytes(ssl, SSL3_RT_HANDSHAKE, &p[ssl->init_num], n, 0); if (bytes_read <= 0) { - s->rwstate = SSL_READING; + ssl->rwstate = SSL_READING; *ok = 0; return bytes_read; } - s->init_num += bytes_read; + ssl->init_num += bytes_read; n -= bytes_read; } /* Feed this message into MAC computation. */ - if (hash_message == ssl_hash_message && !ssl3_hash_current_message(s)) { + if (hash_message == ssl_hash_message && !ssl3_hash_current_message(ssl)) { goto err; } - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num + 4, s, s->msg_callback_arg); + if (ssl->msg_callback) { + ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, ssl->init_buf->data, + (size_t)ssl->init_num + 4, ssl, ssl->msg_callback_arg); } *ok = 1; - return s->init_num; + return ssl->init_num; f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: *ok = 0; return -1; } -int ssl3_hash_current_message(SSL *s) { +int ssl3_hash_current_message(SSL *ssl) { /* The handshake header (different size between DTLS and TLS) is included in * the hash. */ - size_t header_len = s->init_msg - (uint8_t *)s->init_buf->data; - return ssl3_update_handshake_hash(s, (uint8_t *)s->init_buf->data, - s->init_num + header_len); + size_t header_len = ssl->init_msg - (uint8_t *)ssl->init_buf->data; + return ssl3_update_handshake_hash(ssl, (uint8_t *)ssl->init_buf->data, + ssl->init_num + header_len); } /* ssl3_cert_verify_hash is documented as needing EVP_MAX_MD_SIZE because that @@ -452,19 +447,19 @@ int ssl3_hash_current_message(SSL *s) { OPENSSL_COMPILE_ASSERT(EVP_MAX_MD_SIZE > MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, combined_tls_hash_fits_in_max); -int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len, +int ssl3_cert_verify_hash(SSL *ssl, uint8_t *out, size_t *out_len, const EVP_MD **out_md, int pkey_type) { /* For TLS v1.2 send signature algorithm and signature using * agreed digest and cached handshake records. Otherwise, use * SHA1 or MD5 + SHA1 depending on key type. */ - if (SSL_USE_SIGALGS(s)) { + if (SSL_USE_SIGALGS(ssl)) { EVP_MD_CTX mctx; unsigned len; EVP_MD_CTX_init(&mctx); if (!EVP_DigestInit_ex(&mctx, *out_md, NULL) || - !EVP_DigestUpdate(&mctx, s->s3->handshake_buffer->data, - s->s3->handshake_buffer->length) || + !EVP_DigestUpdate(&mctx, ssl->s3->handshake_buffer->data, + ssl->s3->handshake_buffer->length) || !EVP_DigestFinal(&mctx, out, &len)) { OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); EVP_MD_CTX_cleanup(&mctx); @@ -472,15 +467,15 @@ int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len, } *out_len = len; } else if (pkey_type == EVP_PKEY_RSA) { - if (s->enc_method->cert_verify_mac(s, NID_md5, out) == 0 || - s->enc_method->cert_verify_mac(s, NID_sha1, out + MD5_DIGEST_LENGTH) == - 0) { + if (ssl->enc_method->cert_verify_mac(ssl, NID_md5, out) == 0 || + ssl->enc_method->cert_verify_mac(ssl, NID_sha1, + out + MD5_DIGEST_LENGTH) == 0) { return 0; } *out_len = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; *out_md = EVP_md5_sha1(); } else if (pkey_type == EVP_PKEY_EC) { - if (s->enc_method->cert_verify_mac(s, NID_sha1, out) == 0) { + if (ssl->enc_method->cert_verify_mac(ssl, NID_sha1, out) == 0) { return 0; } *out_len = SHA_DIGEST_LENGTH; diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c index 843403b..5f68037 100644 --- a/src/ssl/s3_clnt.c +++ b/src/ssl/s3_clnt.c @@ -172,37 +172,37 @@ #include "../crypto/dh/internal.h" -int ssl3_connect(SSL *s) { +int ssl3_connect(SSL *ssl) { BUF_MEM *buf = NULL; void (*cb)(const SSL *ssl, int type, int value) = NULL; int ret = -1; int new_state, state, skip = 0; - assert(s->handshake_func == ssl3_connect); - assert(!s->server); - assert(!SSL_IS_DTLS(s)); + assert(ssl->handshake_func == ssl3_connect); + assert(!ssl->server); + assert(!SSL_IS_DTLS(ssl)); ERR_clear_error(); ERR_clear_system_error(); - if (s->info_callback != NULL) { - cb = s->info_callback; - } else if (s->ctx->info_callback != NULL) { - cb = s->ctx->info_callback; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; } - s->in_handshake++; + ssl->in_handshake++; for (;;) { - state = s->state; + state = ssl->state; - switch (s->state) { + switch (ssl->state) { case SSL_ST_CONNECT: if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_START, 1); + cb(ssl, SSL_CB_HANDSHAKE_START, 1); } - if (s->init_buf == NULL) { + if (ssl->init_buf == NULL) { buf = BUF_MEM_new(); if (buf == NULL || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { @@ -210,124 +210,124 @@ int ssl3_connect(SSL *s) { goto end; } - s->init_buf = buf; + ssl->init_buf = buf; buf = NULL; } - if (!ssl_init_wbio_buffer(s, 0)) { + if (!ssl_init_wbio_buffer(ssl, 0)) { ret = -1; goto end; } /* don't push the buffering BIO quite yet */ - if (!ssl3_init_handshake_buffer(s)) { + if (!ssl3_init_handshake_buffer(ssl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); ret = -1; goto end; } - s->state = SSL3_ST_CW_CLNT_HELLO_A; - s->init_num = 0; + ssl->state = SSL3_ST_CW_CLNT_HELLO_A; + ssl->init_num = 0; break; case SSL3_ST_CW_CLNT_HELLO_A: case SSL3_ST_CW_CLNT_HELLO_B: - s->shutdown = 0; - ret = ssl3_send_client_hello(s); + ssl->shutdown = 0; + ret = ssl3_send_client_hello(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CR_SRVR_HELLO_A; - s->init_num = 0; + ssl->state = SSL3_ST_CR_SRVR_HELLO_A; + ssl->init_num = 0; /* turn on buffering for the next lot of output */ - if (s->bbio != s->wbio) { - s->wbio = BIO_push(s->bbio, s->wbio); + if (ssl->bbio != ssl->wbio) { + ssl->wbio = BIO_push(ssl->bbio, ssl->wbio); } break; case SSL3_ST_CR_SRVR_HELLO_A: case SSL3_ST_CR_SRVR_HELLO_B: - ret = ssl3_get_server_hello(s); + ret = ssl3_get_server_hello(ssl); if (ret <= 0) { goto end; } - if (s->hit) { - s->state = SSL3_ST_CR_CHANGE; - if (s->tlsext_ticket_expected) { + if (ssl->hit) { + ssl->state = SSL3_ST_CR_CHANGE; + if (ssl->tlsext_ticket_expected) { /* receive renewed session ticket */ - s->state = SSL3_ST_CR_SESSION_TICKET_A; + ssl->state = SSL3_ST_CR_SESSION_TICKET_A; } } else { - s->state = SSL3_ST_CR_CERT_A; + ssl->state = SSL3_ST_CR_CERT_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_CR_CERT_A: case SSL3_ST_CR_CERT_B: - if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { - ret = ssl3_get_server_certificate(s); + if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) { + ret = ssl3_get_server_certificate(ssl); if (ret <= 0) { goto end; } - if (s->s3->tmp.certificate_status_expected) { - s->state = SSL3_ST_CR_CERT_STATUS_A; + if (ssl->s3->tmp.certificate_status_expected) { + ssl->state = SSL3_ST_CR_CERT_STATUS_A; } else { - s->state = SSL3_ST_VERIFY_SERVER_CERT; + ssl->state = SSL3_ST_VERIFY_SERVER_CERT; } } else { skip = 1; - s->state = SSL3_ST_CR_KEY_EXCH_A; + ssl->state = SSL3_ST_CR_KEY_EXCH_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_VERIFY_SERVER_CERT: - ret = ssl3_verify_server_cert(s); + ret = ssl3_verify_server_cert(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CR_KEY_EXCH_A; - s->init_num = 0; + ssl->state = SSL3_ST_CR_KEY_EXCH_A; + ssl->init_num = 0; break; case SSL3_ST_CR_KEY_EXCH_A: case SSL3_ST_CR_KEY_EXCH_B: - ret = ssl3_get_server_key_exchange(s); + ret = ssl3_get_server_key_exchange(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CR_CERT_REQ_A; - s->init_num = 0; + ssl->state = SSL3_ST_CR_CERT_REQ_A; + ssl->init_num = 0; break; case SSL3_ST_CR_CERT_REQ_A: case SSL3_ST_CR_CERT_REQ_B: - ret = ssl3_get_certificate_request(s); + ret = ssl3_get_certificate_request(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CR_SRVR_DONE_A; - s->init_num = 0; + ssl->state = SSL3_ST_CR_SRVR_DONE_A; + ssl->init_num = 0; break; case SSL3_ST_CR_SRVR_DONE_A: case SSL3_ST_CR_SRVR_DONE_B: - ret = ssl3_get_server_done(s); + ret = ssl3_get_server_done(ssl); if (ret <= 0) { goto end; } - if (s->s3->tmp.cert_req) { - s->state = SSL3_ST_CW_CERT_A; + if (ssl->s3->tmp.cert_req) { + ssl->state = SSL3_ST_CW_CERT_A; } else { - s->state = SSL3_ST_CW_KEY_EXCH_A; + ssl->state = SSL3_ST_CW_KEY_EXCH_A; } - s->init_num = 0; + ssl->init_num = 0; break; @@ -335,65 +335,63 @@ int ssl3_connect(SSL *s) { case SSL3_ST_CW_CERT_B: case SSL3_ST_CW_CERT_C: case SSL3_ST_CW_CERT_D: - ret = ssl3_send_client_certificate(s); + ret = ssl3_send_client_certificate(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; + ssl->state = SSL3_ST_CW_KEY_EXCH_A; + ssl->init_num = 0; break; case SSL3_ST_CW_KEY_EXCH_A: case SSL3_ST_CW_KEY_EXCH_B: - ret = ssl3_send_client_key_exchange(s); + ret = ssl3_send_client_key_exchange(ssl); if (ret <= 0) { goto end; } /* For TLS, cert_req is set to 2, so a cert chain * of nothing is sent, but no verify packet is sent */ - if (s->s3->tmp.cert_req == 1) { - s->state = SSL3_ST_CW_CERT_VRFY_A; + if (ssl->s3->tmp.cert_req == 1) { + ssl->state = SSL3_ST_CW_CERT_VRFY_A; } else { - s->state = SSL3_ST_CW_CHANGE_A; - s->s3->change_cipher_spec = 0; + ssl->state = SSL3_ST_CW_CHANGE_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_CW_CERT_VRFY_A: case SSL3_ST_CW_CERT_VRFY_B: case SSL3_ST_CW_CERT_VRFY_C: - ret = ssl3_send_cert_verify(s); + ret = ssl3_send_cert_verify(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CW_CHANGE_A; - s->init_num = 0; - s->s3->change_cipher_spec = 0; + ssl->state = SSL3_ST_CW_CHANGE_A; + ssl->init_num = 0; break; case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_B: - ret = ssl3_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A, + ret = ssl3_send_change_cipher_spec(ssl, SSL3_ST_CW_CHANGE_A, SSL3_ST_CW_CHANGE_B); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CW_FINISHED_A; - if (s->s3->tlsext_channel_id_valid) { - s->state = SSL3_ST_CW_CHANNEL_ID_A; + ssl->state = SSL3_ST_CW_FINISHED_A; + if (ssl->s3->tlsext_channel_id_valid) { + ssl->state = SSL3_ST_CW_CHANNEL_ID_A; } - if (s->s3->next_proto_neg_seen) { - s->state = SSL3_ST_CW_NEXT_PROTO_A; + if (ssl->s3->next_proto_neg_seen) { + ssl->state = SSL3_ST_CW_NEXT_PROTO_A; } - s->init_num = 0; + ssl->init_num = 0; - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->enc_method->setup_key_block(s) || - !s->enc_method->change_cipher_state( - s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { + ssl->session->cipher = ssl->s3->tmp.new_cipher; + if (!ssl->enc_method->setup_key_block(ssl) || + !ssl->enc_method->change_cipher_state( + ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { ret = -1; goto end; } @@ -402,162 +400,165 @@ int ssl3_connect(SSL *s) { case SSL3_ST_CW_NEXT_PROTO_A: case SSL3_ST_CW_NEXT_PROTO_B: - ret = ssl3_send_next_proto(s); + ret = ssl3_send_next_proto(ssl); if (ret <= 0) { goto end; } - if (s->s3->tlsext_channel_id_valid) { - s->state = SSL3_ST_CW_CHANNEL_ID_A; + if (ssl->s3->tlsext_channel_id_valid) { + ssl->state = SSL3_ST_CW_CHANNEL_ID_A; } else { - s->state = SSL3_ST_CW_FINISHED_A; + ssl->state = SSL3_ST_CW_FINISHED_A; } break; case SSL3_ST_CW_CHANNEL_ID_A: case SSL3_ST_CW_CHANNEL_ID_B: - ret = ssl3_send_channel_id(s); + ret = ssl3_send_channel_id(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CW_FINISHED_A; + ssl->state = SSL3_ST_CW_FINISHED_A; break; case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B: - ret = - ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B, - s->enc_method->client_finished_label, - s->enc_method->client_finished_label_len); + ret = ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A, + SSL3_ST_CW_FINISHED_B, + ssl->enc_method->client_finished_label, + ssl->enc_method->client_finished_label_len); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CW_FLUSH; + ssl->state = SSL3_ST_CW_FLUSH; - if (s->hit) { - s->s3->tmp.next_state = SSL_ST_OK; + if (ssl->hit) { + ssl->s3->tmp.next_state = SSL_ST_OK; } else { /* This is a non-resumption handshake. If it involves ChannelID, then * record the handshake hashes at this point in the session so that * any resumption of this session with ChannelID can sign those * hashes. */ - ret = tls1_record_handshake_hashes_for_channel_id(s); + ret = tls1_record_handshake_hashes_for_channel_id(ssl); if (ret <= 0) { goto end; } - if ((SSL_get_mode(s) & SSL_MODE_ENABLE_FALSE_START) && - ssl3_can_false_start(s) && + if ((SSL_get_mode(ssl) & SSL_MODE_ENABLE_FALSE_START) && + ssl3_can_false_start(ssl) && /* No False Start on renegotiation (would complicate the state * machine). */ - !s->s3->initial_handshake_complete) { - s->s3->tmp.next_state = SSL3_ST_FALSE_START; + !ssl->s3->initial_handshake_complete) { + ssl->s3->tmp.next_state = SSL3_ST_FALSE_START; } else { /* Allow NewSessionTicket if ticket expected */ - if (s->tlsext_ticket_expected) { - s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; + if (ssl->tlsext_ticket_expected) { + ssl->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; } else { - s->s3->tmp.next_state = SSL3_ST_CR_CHANGE; + ssl->s3->tmp.next_state = SSL3_ST_CR_CHANGE; } } } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_CR_SESSION_TICKET_A: case SSL3_ST_CR_SESSION_TICKET_B: - ret = ssl3_get_new_session_ticket(s); + ret = ssl3_get_new_session_ticket(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_CR_CHANGE; - s->init_num = 0; + ssl->state = SSL3_ST_CR_CHANGE; + ssl->init_num = 0; break; case SSL3_ST_CR_CERT_STATUS_A: case SSL3_ST_CR_CERT_STATUS_B: - ret = ssl3_get_cert_status(s); + ret = ssl3_get_cert_status(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_VERIFY_SERVER_CERT; - s->init_num = 0; + ssl->state = SSL3_ST_VERIFY_SERVER_CERT; + ssl->init_num = 0; break; case SSL3_ST_CR_CHANGE: - /* At this point, the next message must be entirely behind a - * ChangeCipherSpec. */ - if (!ssl3_expect_change_cipher_spec(s)) { + ret = ssl->method->ssl_read_change_cipher_spec(ssl); + if (ret <= 0) { + goto end; + } + + if (!ssl3_do_change_cipher_spec(ssl)) { ret = -1; goto end; } - s->state = SSL3_ST_CR_FINISHED_A; + ssl->state = SSL3_ST_CR_FINISHED_A; break; case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_B: - ret = - ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); + ret = ssl3_get_finished(ssl, SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); if (ret <= 0) { goto end; } - if (s->hit) { - s->state = SSL3_ST_CW_CHANGE_A; + if (ssl->hit) { + ssl->state = SSL3_ST_CW_CHANGE_A; } else { - s->state = SSL_ST_OK; + ssl->state = SSL_ST_OK; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_CW_FLUSH: - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { + ssl->rwstate = SSL_WRITING; + if (BIO_flush(ssl->wbio) <= 0) { ret = -1; goto end; } - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; + ssl->rwstate = SSL_NOTHING; + ssl->state = ssl->s3->tmp.next_state; break; case SSL3_ST_FALSE_START: /* Allow NewSessionTicket if ticket expected */ - if (s->tlsext_ticket_expected) { - s->state = SSL3_ST_CR_SESSION_TICKET_A; + if (ssl->tlsext_ticket_expected) { + ssl->state = SSL3_ST_CR_SESSION_TICKET_A; } else { - s->state = SSL3_ST_CR_CHANGE; + ssl->state = SSL3_ST_CR_CHANGE; } - s->s3->tmp.in_false_start = 1; + ssl->s3->tmp.in_false_start = 1; - ssl_free_wbio_buffer(s); + ssl_free_wbio_buffer(ssl); ret = 1; goto end; case SSL_ST_OK: /* clean a few things up */ - ssl3_cleanup_key_block(s); + ssl3_cleanup_key_block(ssl); - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; + BUF_MEM_free(ssl->init_buf); + ssl->init_buf = NULL; /* Remove write buffering now. */ - ssl_free_wbio_buffer(s); + ssl_free_wbio_buffer(ssl); - const int is_initial_handshake = !s->s3->initial_handshake_complete; + const int is_initial_handshake = !ssl->s3->initial_handshake_complete; - s->init_num = 0; - s->s3->tmp.in_false_start = 0; - s->s3->initial_handshake_complete = 1; + ssl->init_num = 0; + ssl->s3->tmp.in_false_start = 0; + ssl->s3->initial_handshake_complete = 1; if (is_initial_handshake) { /* Renegotiations do not participate in session resumption. */ - ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + ssl_update_cache(ssl, SSL_SESS_CACHE_CLIENT); } ret = 1; - /* s->server=0; */ + /* ssl->server=0; */ if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_DONE, 1); + cb(ssl, SSL_CB_HANDSHAKE_DONE, 1); } goto end; @@ -568,22 +569,22 @@ int ssl3_connect(SSL *s) { goto end; } - if (!s->s3->tmp.reuse_message && !skip) { - if (cb != NULL && s->state != state) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; + if (!ssl->s3->tmp.reuse_message && !skip) { + if (cb != NULL && ssl->state != state) { + new_state = ssl->state; + ssl->state = state; + cb(ssl, SSL_CB_CONNECT_LOOP, 1); + ssl->state = new_state; } } skip = 0; } end: - s->in_handshake--; + ssl->in_handshake--; BUF_MEM_free(buf); if (cb != NULL) { - cb(s, SSL_CB_CONNECT_EXIT, ret); + cb(ssl, SSL_CB_CONNECT_EXIT, ret); } return ret; } @@ -735,17 +736,17 @@ err: return -1; } -int ssl3_get_server_hello(SSL *s) { +int ssl3_get_server_hello(SSL *ssl) { STACK_OF(SSL_CIPHER) *sk; const SSL_CIPHER *c; - CERT *ct = s->cert; + CERT *ct = ssl->cert; int al = SSL_AD_INTERNAL_ERROR, ok; long n; CBS server_hello, server_random, session_id; uint16_t server_version, cipher_suite; uint8_t compression_method; - n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A, + n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_SRVR_HELLO_A, SSL3_ST_CR_SRVR_HELLO_B, SSL3_MT_SERVER_HELLO, 20000, /* ?? */ ssl_hash_message, &ok); @@ -765,7 +766,7 @@ int ssl3_get_server_hello(SSL *s) { return n; } - CBS_init(&server_hello, s->init_msg, n); + CBS_init(&server_hello, ssl->init_msg, n); if (!CBS_get_u16(&server_hello, &server_version) || !CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE) || @@ -778,55 +779,56 @@ int ssl3_get_server_hello(SSL *s) { goto f_err; } - assert(s->s3->have_version == s->s3->initial_handshake_complete); - if (!s->s3->have_version) { - if (!ssl3_is_version_enabled(s, server_version)) { + assert(ssl->s3->have_version == ssl->s3->initial_handshake_complete); + if (!ssl->s3->have_version) { + if (!ssl3_is_version_enabled(ssl, server_version)) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL); - s->version = server_version; + ssl->version = server_version; /* Mark the version as fixed so the record-layer version is not clamped * to TLS 1.0. */ - s->s3->have_version = 1; + ssl->s3->have_version = 1; al = SSL_AD_PROTOCOL_VERSION; goto f_err; } - s->version = server_version; - s->enc_method = ssl3_get_enc_method(server_version); - assert(s->enc_method != NULL); - /* At this point, the connection's version is known and s->version is + ssl->version = server_version; + ssl->enc_method = ssl3_get_enc_method(server_version); + assert(ssl->enc_method != NULL); + /* At this point, the connection's version is known and ssl->version is * fixed. Begin enforcing the record-layer version. */ - s->s3->have_version = 1; - } else if (server_version != s->version) { + ssl->s3->have_version = 1; + } else if (server_version != ssl->version) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); al = SSL_AD_PROTOCOL_VERSION; goto f_err; } /* Copy over the server random. */ - memcpy(s->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE); - - assert(s->session == NULL || s->session->session_id_length > 0); - if (!s->s3->initial_handshake_complete && s->session != NULL && - CBS_mem_equal(&session_id, s->session->session_id, - s->session->session_id_length)) { - if (s->sid_ctx_length != s->session->sid_ctx_length || - memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) { + memcpy(ssl->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE); + + assert(ssl->session == NULL || ssl->session->session_id_length > 0); + if (!ssl->s3->initial_handshake_complete && ssl->session != NULL && + CBS_mem_equal(&session_id, ssl->session->session_id, + ssl->session->session_id_length)) { + if (ssl->sid_ctx_length != ssl->session->sid_ctx_length || + memcmp(ssl->session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length)) { /* actually a client application bug */ al = SSL_AD_ILLEGAL_PARAMETER; OPENSSL_PUT_ERROR(SSL, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); goto f_err; } - s->hit = 1; + ssl->hit = 1; } else { /* The session wasn't resumed. Create a fresh SSL_SESSION to * fill out. */ - s->hit = 0; - if (!ssl_get_new_session(s, 0 /* client */)) { + ssl->hit = 0; + if (!ssl_get_new_session(ssl, 0 /* client */)) { goto f_err; } /* Note: session_id could be empty. */ - s->session->session_id_length = CBS_len(&session_id); - memcpy(s->session->session_id, CBS_data(&session_id), CBS_len(&session_id)); + ssl->session->session_id_length = CBS_len(&session_id); + memcpy(ssl->session->session_id, CBS_data(&session_id), + CBS_len(&session_id)); } c = SSL_get_cipher_by_value(cipher_suite); @@ -838,15 +840,15 @@ int ssl3_get_server_hello(SSL *s) { } /* If the cipher is disabled then we didn't sent it in the ClientHello, so if * the server selected it, it's an error. */ - if ((c->algorithm_mkey & ct->mask_k) || - (c->algorithm_auth & ct->mask_a) || - SSL_CIPHER_get_min_version(c) > ssl3_version_from_wire(s, s->version)) { + if ((c->algorithm_mkey & ct->mask_k) || (c->algorithm_auth & ct->mask_a) || + SSL_CIPHER_get_min_version(c) > + ssl3_version_from_wire(ssl, ssl->version)) { al = SSL_AD_ILLEGAL_PARAMETER; OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); goto f_err; } - sk = ssl_get_ciphers_by_id(s); + sk = ssl_get_ciphers_by_id(ssl); if (!sk_SSL_CIPHER_find(sk, NULL, c)) { /* we did not say we would use this cipher */ al = SSL_AD_ILLEGAL_PARAMETER; @@ -854,30 +856,30 @@ int ssl3_get_server_hello(SSL *s) { goto f_err; } - if (s->hit) { - if (s->session->cipher != c) { + if (ssl->hit) { + if (ssl->session->cipher != c) { al = SSL_AD_ILLEGAL_PARAMETER; OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); goto f_err; } - if (s->session->ssl_version != s->version) { + if (ssl->session->ssl_version != ssl->version) { al = SSL_AD_ILLEGAL_PARAMETER; OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED); goto f_err; } } - s->s3->tmp.new_cipher = c; + ssl->s3->tmp.new_cipher = c; /* Now that the cipher is known, initialize the handshake hash. */ - if (!ssl3_init_handshake_hash(s)) { + if (!ssl3_init_handshake_hash(ssl)) { goto f_err; } /* If doing a full handshake with TLS 1.2, the server may request a client * certificate which requires hashing the handshake transcript under a * different hash. Otherwise, the handshake buffer may be released. */ - if (!SSL_USE_SIGALGS(s) || s->hit) { - ssl3_free_handshake_buffer(s); + if (!SSL_USE_SIGALGS(ssl) || ssl->hit) { + ssl3_free_handshake_buffer(ssl); } /* Only the NULL compression algorithm is supported. */ @@ -888,7 +890,7 @@ int ssl3_get_server_hello(SSL *s) { } /* TLS extensions */ - if (!ssl_parse_serverhello_tlsext(s, &server_hello)) { + if (!ssl_parse_serverhello_tlsext(ssl, &server_hello)) { OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); goto err; } @@ -901,10 +903,11 @@ int ssl3_get_server_hello(SSL *s) { goto f_err; } - if (s->hit && - s->s3->tmp.extended_master_secret != s->session->extended_master_secret) { + if (ssl->hit && + ssl->s3->tmp.extended_master_secret != + ssl->session->extended_master_secret) { al = SSL_AD_HANDSHAKE_FAILURE; - if (s->session->extended_master_secret) { + if (ssl->session->extended_master_secret) { OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); } else { OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION); @@ -915,16 +918,15 @@ int ssl3_get_server_hello(SSL *s) { return 1; f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: return -1; } -/* ssl3_check_certificate_for_cipher returns one if |leaf| is a suitable server - * certificate type for |cipher|. Otherwise, it returns zero and pushes an error - * on the error queue. */ -static int ssl3_check_certificate_for_cipher(X509 *leaf, - const SSL_CIPHER *cipher) { +/* ssl3_check_leaf_certificate returns one if |leaf| is a suitable leaf server + * certificate for |ssl|. Otherwise, it returns zero and pushes an error on the + * error queue. */ +static int ssl3_check_leaf_certificate(SSL *ssl, X509 *leaf) { int ret = 0; EVP_PKEY *pkey = X509_get_pubkey(leaf); if (pkey == NULL) { @@ -932,6 +934,7 @@ static int ssl3_check_certificate_for_cipher(X509 *leaf, } /* Check the certificate's type matches the cipher. */ + const SSL_CIPHER *cipher = ssl->s3->tmp.new_cipher; int expected_type = ssl_cipher_get_key_type(cipher); assert(expected_type != EVP_PKEY_NONE); if (pkey->type != expected_type) { @@ -939,9 +942,9 @@ static int ssl3_check_certificate_for_cipher(X509 *leaf, goto err; } - /* TODO(davidben): This behavior is preserved from upstream. Should key usages - * be checked in other cases as well? */ if (cipher->algorithm_auth & SSL_aECDSA) { + /* TODO(davidben): This behavior is preserved from upstream. Should key + * usages be checked in other cases as well? */ /* This call populates the ex_flags field correctly */ X509_check_purpose(leaf, -1, 0); if ((leaf->ex_flags & EXFLAG_KUSAGE) && @@ -949,6 +952,11 @@ static int ssl3_check_certificate_for_cipher(X509 *leaf, OPENSSL_PUT_ERROR(SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING); goto err; } + + if (!tls1_check_ec_cert(ssl, leaf)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT); + goto err; + } } ret = 1; @@ -958,7 +966,7 @@ err: return ret; } -int ssl3_get_server_certificate(SSL *s) { +int ssl3_get_server_certificate(SSL *ssl) { int al, ok, ret = -1; unsigned long n; X509 *x = NULL; @@ -967,15 +975,15 @@ int ssl3_get_server_certificate(SSL *s) { CBS cbs, certificate_list; const uint8_t *data; - n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B, - SSL3_MT_CERTIFICATE, (long)s->max_cert_list, + n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B, + SSL3_MT_CERTIFICATE, (long)ssl->max_cert_list, ssl_hash_message, &ok); if (!ok) { return n; } - CBS_init(&cbs, s->init_msg, n); + CBS_init(&cbs, ssl->init_msg, n); sk = sk_X509_new_null(); if (sk == NULL) { @@ -998,8 +1006,9 @@ int ssl3_get_server_certificate(SSL *s) { OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } + /* A u24 length cannot overflow a long. */ data = CBS_data(&certificate); - x = d2i_X509(NULL, &data, CBS_len(&certificate)); + x = d2i_X509(NULL, &data, (long)CBS_len(&certificate)); if (x == NULL) { al = SSL_AD_BAD_CERTIFICATE; OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); @@ -1018,27 +1027,27 @@ int ssl3_get_server_certificate(SSL *s) { } X509 *leaf = sk_X509_value(sk, 0); - if (!ssl3_check_certificate_for_cipher(leaf, s->s3->tmp.new_cipher)) { + if (!ssl3_check_leaf_certificate(ssl, leaf)) { al = SSL_AD_ILLEGAL_PARAMETER; goto f_err; } /* NOTE: Unlike the server half, the client's copy of |cert_chain| includes * the leaf. */ - sk_X509_pop_free(s->session->cert_chain, X509_free); - s->session->cert_chain = sk; + sk_X509_pop_free(ssl->session->cert_chain, X509_free); + ssl->session->cert_chain = sk; sk = NULL; - X509_free(s->session->peer); - s->session->peer = X509_up_ref(leaf); + X509_free(ssl->session->peer); + ssl->session->peer = X509_up_ref(leaf); - s->session->verify_result = s->verify_result; + ssl->session->verify_result = ssl->verify_result; ret = 1; if (0) { f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); } err: @@ -1048,53 +1057,51 @@ err: return ret; } -int ssl3_get_server_key_exchange(SSL *s) { +int ssl3_get_server_key_exchange(SSL *ssl) { EVP_MD_CTX md_ctx; int al, ok; long n, alg_k, alg_a; EVP_PKEY *pkey = NULL; const EVP_MD *md = NULL; - RSA *rsa = NULL; DH *dh = NULL; EC_KEY *ecdh = NULL; - BN_CTX *bn_ctx = NULL; EC_POINT *srvr_ecpoint = NULL; CBS server_key_exchange, server_key_exchange_orig, parameter; /* use same message size as in ssl3_get_certificate_request() as * ServerKeyExchange message may be skipped */ - n = s->method->ssl_get_message(s, SSL3_ST_CR_KEY_EXCH_A, - SSL3_ST_CR_KEY_EXCH_B, -1, s->max_cert_list, + n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_KEY_EXCH_A, + SSL3_ST_CR_KEY_EXCH_B, -1, ssl->max_cert_list, ssl_hash_message, &ok); if (!ok) { return n; } - if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { - if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher)) { + if (ssl->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { + if (ssl_cipher_requires_server_key_exchange(ssl->s3->tmp.new_cipher)) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); return -1; } /* In plain PSK ciphersuite, ServerKeyExchange may be omitted to send no * identity hint. */ - if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK) { + if (ssl->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK) { /* TODO(davidben): This should be reset in one place with the rest of the * handshake state. */ - OPENSSL_free(s->s3->tmp.peer_psk_identity_hint); - s->s3->tmp.peer_psk_identity_hint = NULL; + OPENSSL_free(ssl->s3->tmp.peer_psk_identity_hint); + ssl->s3->tmp.peer_psk_identity_hint = NULL; } - s->s3->tmp.reuse_message = 1; + ssl->s3->tmp.reuse_message = 1; return 1; } /* Retain a copy of the original CBS to compute the signature over. */ - CBS_init(&server_key_exchange, s->init_msg, n); + CBS_init(&server_key_exchange, ssl->init_msg, n); server_key_exchange_orig = server_key_exchange; - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; + alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey; + alg_a = ssl->s3->tmp.new_cipher->algorithm_auth; EVP_MD_CTX_init(&md_ctx); if (alg_a & SSL_aPSK) { @@ -1123,7 +1130,7 @@ int ssl3_get_server_key_exchange(SSL *s) { } /* Save the identity hint as a C string. */ - if (!CBS_strdup(&psk_identity_hint, &s->s3->tmp.peer_psk_identity_hint)) { + if (!CBS_strdup(&psk_identity_hint, &ssl->s3->tmp.peer_psk_identity_hint)) { al = SSL_AD_INTERNAL_ERROR; OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto f_err; @@ -1132,7 +1139,6 @@ int ssl3_get_server_key_exchange(SSL *s) { if (alg_k & SSL_kDHE) { CBS dh_p, dh_g, dh_Ys; - if (!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_p) || CBS_len(&dh_p) == 0 || !CBS_get_u16_length_prefixed(&server_key_exchange, &dh_g) || @@ -1146,84 +1152,69 @@ int ssl3_get_server_key_exchange(SSL *s) { dh = DH_new(); if (dh == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); goto err; } - if ((dh->p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL)) == NULL || - (dh->g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)) == NULL || - (dh->pub_key = BN_bin2bn(CBS_data(&dh_Ys), CBS_len(&dh_Ys), NULL)) == - NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB); + dh->p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL); + dh->g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL); + if (dh->p == NULL || dh->g == NULL) { goto err; } - s->session->key_exchange_info = DH_num_bits(dh); - if (s->session->key_exchange_info < 1024) { + ssl->session->key_exchange_info = DH_num_bits(dh); + if (ssl->session->key_exchange_info < 1024) { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DH_P_LENGTH); goto err; + } else if (ssl->session->key_exchange_info > 4096) { + /* Overly large DHE groups are prohibitively expensive, so enforce a limit + * to prevent a server from causing us to perform too expensive of a + * computation. */ + OPENSSL_PUT_ERROR(SSL, SSL_R_DH_P_TOO_LONG); + goto err; } - DH_free(s->s3->tmp.peer_dh_tmp); - s->s3->tmp.peer_dh_tmp = dh; + + SSL_ECDH_CTX_init_for_dhe(&ssl->s3->tmp.ecdh_ctx, dh); dh = NULL; + + /* Save the peer public key for later. */ + size_t peer_key_len; + if (!CBS_stow(&dh_Ys, &ssl->s3->tmp.peer_key, &peer_key_len)) { + goto err; + } + /* |dh_Ys| has a u16 length prefix, so this fits in a |uint16_t|. */ + assert(sizeof(ssl->s3->tmp.peer_key_len) == 2 && peer_key_len <= 0xffff); + ssl->s3->tmp.peer_key_len = (uint16_t)peer_key_len; } else if (alg_k & SSL_kECDHE) { + /* Parse the server parameters. */ + uint8_t curve_type; uint16_t curve_id; - int curve_nid = 0; - const EC_GROUP *group; CBS point; - - /* Extract elliptic curve parameters and the server's ephemeral ECDH public - * key. Check curve is one of our preferences, if not server has sent an - * invalid curve. */ - if (!tls1_check_curve(s, &server_key_exchange, &curve_id)) { + if (!CBS_get_u8(&server_key_exchange, &curve_type) || + curve_type != NAMED_CURVE_TYPE || + !CBS_get_u16(&server_key_exchange, &curve_id) || + !CBS_get_u8_length_prefixed(&server_key_exchange, &point)) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); - goto f_err; - } - - curve_nid = tls1_ec_curve_id2nid(curve_id); - if (curve_nid == 0) { - al = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } + ssl->session->key_exchange_info = curve_id; - ecdh = EC_KEY_new_by_curve_name(curve_nid); - s->session->key_exchange_info = curve_id; - if (ecdh == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB); - goto err; - } - - group = EC_KEY_get0_group(ecdh); - - /* Next, get the encoded ECPoint */ - if (!CBS_get_u8_length_prefixed(&server_key_exchange, &point)) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + /* Ensure the curve is consistent with preferences. */ + if (!tls1_check_curve_id(ssl, curve_id)) { + al = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); goto f_err; } - if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || - ((bn_ctx = BN_CTX_new()) == NULL)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + /* Initialize ECDH and save the peer public key for later. */ + size_t peer_key_len; + if (!SSL_ECDH_CTX_init(&ssl->s3->tmp.ecdh_ctx, curve_id) || + !CBS_stow(&point, &ssl->s3->tmp.peer_key, &peer_key_len)) { goto err; } - - if (!EC_POINT_oct2point(group, srvr_ecpoint, CBS_data(&point), - CBS_len(&point), bn_ctx)) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); - goto f_err; - } - EC_KEY_set_public_key(ecdh, srvr_ecpoint); - EC_KEY_free(s->s3->tmp.peer_ecdh_tmp); - s->s3->tmp.peer_ecdh_tmp = ecdh; - ecdh = NULL; - BN_CTX_free(bn_ctx); - bn_ctx = NULL; - EC_POINT_free(srvr_ecpoint); - srvr_ecpoint = NULL; + /* |point| has a u8 length prefix, so this fits in a |uint16_t|. */ + assert(sizeof(ssl->s3->tmp.peer_key_len) == 2 && peer_key_len <= 0xffff); + ssl->s3->tmp.peer_key_len = (uint16_t)peer_key_len; } else if (!(alg_k & SSL_kPSK)) { al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); @@ -1237,13 +1228,13 @@ int ssl3_get_server_key_exchange(SSL *s) { CBS_len(&server_key_exchange_orig) - CBS_len(&server_key_exchange)); /* ServerKeyExchange should be signed by the server's public key. */ - if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { - pkey = X509_get_pubkey(s->session->peer); + if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) { + pkey = X509_get_pubkey(ssl->session->peer); if (pkey == NULL) { goto err; } - if (SSL_USE_SIGALGS(s)) { + if (SSL_USE_SIGALGS(ssl)) { uint8_t hash, signature; if (!CBS_get_u8(&server_key_exchange, &hash) || !CBS_get_u8(&server_key_exchange, &signature)) { @@ -1251,10 +1242,10 @@ int ssl3_get_server_key_exchange(SSL *s) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } - if (!tls12_check_peer_sigalg(s, &md, &al, hash, signature, pkey)) { + if (!tls12_check_peer_sigalg(ssl, &md, &al, hash, signature, pkey)) { goto f_err; } - s->s3->tmp.server_key_exchange_hash = hash; + ssl->s3->tmp.server_key_exchange_hash = hash; } else if (pkey->type == EVP_PKEY_RSA) { md = EVP_md5_sha1(); } else { @@ -1271,9 +1262,9 @@ int ssl3_get_server_key_exchange(SSL *s) { } if (!EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) || - !EVP_DigestVerifyUpdate(&md_ctx, s->s3->client_random, + !EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->client_random, SSL3_RANDOM_SIZE) || - !EVP_DigestVerifyUpdate(&md_ctx, s->s3->server_random, + !EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->server_random, SSL3_RANDOM_SIZE) || !EVP_DigestVerifyUpdate(&md_ctx, CBS_data(¶meter), CBS_len(¶meter)) || @@ -1299,12 +1290,10 @@ int ssl3_get_server_key_exchange(SSL *s) { return 1; f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: EVP_PKEY_free(pkey); - RSA_free(rsa); DH_free(dh); - BN_CTX_free(bn_ctx); EC_POINT_free(srvr_ecpoint); EC_KEY_free(ecdh); EVP_MD_CTX_cleanup(&md_ctx); @@ -1315,7 +1304,7 @@ static int ca_dn_cmp(const X509_NAME **a, const X509_NAME **b) { return X509_NAME_cmp(*a, *b); } -int ssl3_get_certificate_request(SSL *s) { +int ssl3_get_certificate_request(SSL *ssl) { int ok, ret = 0; unsigned long n; X509_NAME *xn = NULL; @@ -1325,31 +1314,31 @@ int ssl3_get_certificate_request(SSL *s) { CBS certificate_authorities; const uint8_t *data; - n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_REQ_A, - SSL3_ST_CR_CERT_REQ_B, -1, s->max_cert_list, + n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_CERT_REQ_A, + SSL3_ST_CR_CERT_REQ_B, -1, ssl->max_cert_list, ssl_hash_message, &ok); if (!ok) { return n; } - s->s3->tmp.cert_req = 0; + ssl->s3->tmp.cert_req = 0; - if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) { - s->s3->tmp.reuse_message = 1; + if (ssl->s3->tmp.message_type == SSL3_MT_SERVER_DONE) { + ssl->s3->tmp.reuse_message = 1; /* If we get here we don't need the handshake buffer as we won't be doing * client auth. */ - ssl3_free_handshake_buffer(s); + ssl3_free_handshake_buffer(ssl); return 1; } - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE); goto err; } - CBS_init(&cbs, s->init_msg, n); + CBS_init(&cbs, ssl->init_msg, n); ca_sk = sk_X509_NAME_new(ca_dn_cmp); if (ca_sk == NULL) { @@ -1359,22 +1348,22 @@ int ssl3_get_certificate_request(SSL *s) { /* get the certificate types */ if (!CBS_get_u8_length_prefixed(&cbs, &certificate_types)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto err; } - if (!CBS_stow(&certificate_types, &s->s3->tmp.certificate_types, - &s->s3->tmp.num_certificate_types)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + if (!CBS_stow(&certificate_types, &ssl->s3->tmp.certificate_types, + &ssl->s3->tmp.num_certificate_types)) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); goto err; } - if (SSL_USE_SIGALGS(s)) { + if (SSL_USE_SIGALGS(ssl)) { CBS supported_signature_algorithms; if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms) || - !tls1_parse_peer_sigalgs(s, &supported_signature_algorithms)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + !tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto err; } @@ -1382,7 +1371,7 @@ int ssl3_get_certificate_request(SSL *s) { /* get the CA RDNs */ if (!CBS_get_u16_length_prefixed(&cbs, &certificate_authorities)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH); goto err; } @@ -1391,28 +1380,29 @@ int ssl3_get_certificate_request(SSL *s) { CBS distinguished_name; if (!CBS_get_u16_length_prefixed(&certificate_authorities, &distinguished_name)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG); goto err; } data = CBS_data(&distinguished_name); - xn = d2i_X509_NAME(NULL, &data, CBS_len(&distinguished_name)); + /* A u16 length cannot overflow a long. */ + xn = d2i_X509_NAME(NULL, &data, (long)CBS_len(&distinguished_name)); if (xn == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); goto err; } if (!CBS_skip(&distinguished_name, data - CBS_data(&distinguished_name))) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } if (CBS_len(&distinguished_name) != 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_LENGTH_MISMATCH); goto err; } @@ -1424,9 +1414,9 @@ int ssl3_get_certificate_request(SSL *s) { } /* we should setup a certificate to return.... */ - s->s3->tmp.cert_req = 1; - sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); - s->s3->tmp.ca_names = ca_sk; + ssl->s3->tmp.cert_req = 1; + sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free); + ssl->s3->tmp.ca_names = ca_sk; ca_sk = NULL; ret = 1; @@ -1436,10 +1426,10 @@ err: return ret; } -int ssl3_get_new_session_ticket(SSL *s) { +int ssl3_get_new_session_ticket(SSL *ssl) { int ok, al; - long n = s->method->ssl_get_message( - s, SSL3_ST_CR_SESSION_TICKET_A, SSL3_ST_CR_SESSION_TICKET_B, + long n = ssl->method->ssl_get_message( + ssl, SSL3_ST_CR_SESSION_TICKET_A, SSL3_ST_CR_SESSION_TICKET_B, SSL3_MT_NEWSESSION_TICKET, 16384, ssl_hash_message, &ok); if (!ok) { @@ -1448,7 +1438,7 @@ int ssl3_get_new_session_ticket(SSL *s) { CBS new_session_ticket, ticket; uint32_t ticket_lifetime_hint; - CBS_init(&new_session_ticket, s->init_msg, n); + CBS_init(&new_session_ticket, ssl->init_msg, n); if (!CBS_get_u32(&new_session_ticket, &ticket_lifetime_hint) || !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) || CBS_len(&new_session_ticket) != 0) { @@ -1462,17 +1452,17 @@ int ssl3_get_new_session_ticket(SSL *s) { * negotiating the extension. The value of |tlsext_ticket_expected| is * checked in |ssl_update_cache| so is cleared here to avoid an unnecessary * update. */ - s->tlsext_ticket_expected = 0; + ssl->tlsext_ticket_expected = 0; return 1; } - if (s->hit) { + if (ssl->hit) { /* The server is sending a new ticket for an existing session. Sessions are * immutable once established, so duplicate all but the ticket of the * existing session. */ uint8_t *bytes; size_t bytes_len; - if (!SSL_SESSION_to_bytes_for_ticket(s->session, &bytes, &bytes_len)) { + if (!SSL_SESSION_to_bytes_for_ticket(ssl->session, &bytes, &bytes_len)) { goto err; } SSL_SESSION *new_session = SSL_SESSION_from_bytes(bytes, bytes_len); @@ -1483,55 +1473,55 @@ int ssl3_get_new_session_ticket(SSL *s) { goto err; } - SSL_SESSION_free(s->session); - s->session = new_session; + SSL_SESSION_free(ssl->session); + ssl->session = new_session; } - if (!CBS_stow(&ticket, &s->session->tlsext_tick, - &s->session->tlsext_ticklen)) { + if (!CBS_stow(&ticket, &ssl->session->tlsext_tick, + &ssl->session->tlsext_ticklen)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } - s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; + ssl->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; /* Generate a session ID for this session based on the session ticket. We use * the session ID mechanism for detecting ticket resumption. This also fits in * with assumptions elsewhere in OpenSSL.*/ - if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), s->session->session_id, - &s->session->session_id_length, EVP_sha256(), NULL)) { + if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), ssl->session->session_id, + &ssl->session->session_id_length, EVP_sha256(), NULL)) { goto err; } return 1; f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: return -1; } -int ssl3_get_cert_status(SSL *s) { +int ssl3_get_cert_status(SSL *ssl) { int ok, al; long n; CBS certificate_status, ocsp_response; uint8_t status_type; - n = s->method->ssl_get_message( - s, SSL3_ST_CR_CERT_STATUS_A, SSL3_ST_CR_CERT_STATUS_B, + n = ssl->method->ssl_get_message( + ssl, SSL3_ST_CR_CERT_STATUS_A, SSL3_ST_CR_CERT_STATUS_B, -1, 16384, ssl_hash_message, &ok); if (!ok) { return n; } - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) { + if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) { /* A server may send status_request in ServerHello and then change * its mind about sending CertificateStatus. */ - s->s3->tmp.reuse_message = 1; + ssl->s3->tmp.reuse_message = 1; return 1; } - CBS_init(&certificate_status, s->init_msg, n); + CBS_init(&certificate_status, ssl->init_msg, n); if (!CBS_get_u8(&certificate_status, &status_type) || status_type != TLSEXT_STATUSTYPE_ocsp || !CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) || @@ -1542,8 +1532,8 @@ int ssl3_get_cert_status(SSL *s) { goto f_err; } - if (!CBS_stow(&ocsp_response, &s->session->ocsp_response, - &s->session->ocsp_response_length)) { + if (!CBS_stow(&ocsp_response, &ssl->session->ocsp_response, + &ssl->session->ocsp_response_length)) { al = SSL_AD_INTERNAL_ERROR; OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto f_err; @@ -1551,15 +1541,15 @@ int ssl3_get_cert_status(SSL *s) { return 1; f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); return -1; } -int ssl3_get_server_done(SSL *s) { +int ssl3_get_server_done(SSL *ssl) { int ok; long n; - n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_DONE_A, + n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_SRVR_DONE_A, SSL3_ST_CR_SRVR_DONE_B, SSL3_MT_SERVER_DONE, 30, /* should be very small, like 0 :-) */ ssl_hash_message, &ok); @@ -1570,7 +1560,7 @@ int ssl3_get_server_done(SSL *s) { if (n > 0) { /* should contain no data */ - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH); return -1; } @@ -1581,415 +1571,298 @@ int ssl3_get_server_done(SSL *s) { OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned), SIZE_T_IS_SMALLER_THAN_UNSIGNED); -int ssl3_send_client_key_exchange(SSL *s) { - uint8_t *p; - int n = 0; - uint32_t alg_k; - uint32_t alg_a; - uint8_t *q; - EVP_PKEY *pkey = NULL; - EC_KEY *clnt_ecdh = NULL; - const EC_POINT *srvr_ecpoint = NULL; - EVP_PKEY *srvr_pub_pkey = NULL; - uint8_t *encodedPoint = NULL; - int encoded_pt_len = 0; - BN_CTX *bn_ctx = NULL; - unsigned int psk_len = 0; - uint8_t psk[PSK_MAX_PSK_LEN]; +int ssl3_send_client_key_exchange(SSL *ssl) { + if (ssl->state == SSL3_ST_CW_KEY_EXCH_B) { + return ssl_do_write(ssl); + } + assert(ssl->state == SSL3_ST_CW_KEY_EXCH_A); + uint8_t *pms = NULL; size_t pms_len = 0; + CBB cbb; + if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl), + ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl))) { + goto err; + } - if (s->state == SSL3_ST_CW_KEY_EXCH_A) { - p = ssl_handshake_start(s); - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - - /* If using a PSK key exchange, prepare the pre-shared key. */ - if (alg_a & SSL_aPSK) { - char identity[PSK_MAX_IDENTITY_LEN + 1]; - size_t identity_len; - - if (s->psk_client_callback == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_CLIENT_CB); - goto err; - } - - memset(identity, 0, sizeof(identity)); - psk_len = - s->psk_client_callback(s, s->s3->tmp.peer_psk_identity_hint, identity, - sizeof(identity), psk, sizeof(psk)); - if (psk_len > PSK_MAX_PSK_LEN) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } else if (psk_len == 0) { - OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - goto err; - } + uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey; + uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth; - identity_len = OPENSSL_strnlen(identity, sizeof(identity)); - if (identity_len > PSK_MAX_IDENTITY_LEN) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } + /* If using a PSK key exchange, prepare the pre-shared key. */ + unsigned psk_len = 0; + uint8_t psk[PSK_MAX_PSK_LEN]; + if (alg_a & SSL_aPSK) { + if (ssl->psk_client_callback == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_CLIENT_CB); + goto err; + } - OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strdup(identity); - if (s->session->psk_identity == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } + char identity[PSK_MAX_IDENTITY_LEN + 1]; + memset(identity, 0, sizeof(identity)); + psk_len = ssl->psk_client_callback( + ssl, ssl->s3->tmp.peer_psk_identity_hint, identity, sizeof(identity), + psk, sizeof(psk)); + if (psk_len == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + assert(psk_len <= PSK_MAX_PSK_LEN); - /* Write out psk_identity. */ - s2n(identity_len, p); - memcpy(p, identity, identity_len); - p += identity_len; - n = 2 + identity_len; + OPENSSL_free(ssl->session->psk_identity); + ssl->session->psk_identity = BUF_strdup(identity); + if (ssl->session->psk_identity == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; } - /* Depending on the key exchange method, compute |pms| and |pms_len|. */ - if (alg_k & SSL_kRSA) { - RSA *rsa; - size_t enc_pms_len; + /* Write out psk_identity. */ + CBB child; + if (!CBB_add_u16_length_prefixed(&cbb, &child) || + !CBB_add_bytes(&child, (const uint8_t *)identity, + OPENSSL_strnlen(identity, sizeof(identity))) || + !CBB_flush(&cbb)) { + goto err; + } + } - pms_len = SSL_MAX_MASTER_KEY_LENGTH; - pms = OPENSSL_malloc(pms_len); - if (pms == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } + /* Depending on the key exchange method, compute |pms| and |pms_len|. */ + if (alg_k & SSL_kRSA) { + pms_len = SSL_MAX_MASTER_KEY_LENGTH; + pms = OPENSSL_malloc(pms_len); + if (pms == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } - pkey = X509_get_pubkey(s->session->peer); - if (pkey == NULL || - pkey->type != EVP_PKEY_RSA || - pkey->pkey.rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - EVP_PKEY_free(pkey); - goto err; - } + EVP_PKEY *pkey = X509_get_pubkey(ssl->session->peer); + if (pkey == NULL) { + goto err; + } - s->session->key_exchange_info = EVP_PKEY_bits(pkey); - rsa = pkey->pkey.rsa; + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); EVP_PKEY_free(pkey); + goto err; + } - pms[0] = s->client_version >> 8; - pms[1] = s->client_version & 0xff; - if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2)) { - goto err; - } - - s->session->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; - - q = p; - /* In TLS and beyond, reserve space for the length prefix. */ - if (s->version > SSL3_VERSION) { - p += 2; - n += 2; - } - if (!RSA_encrypt(rsa, &enc_pms_len, p, RSA_size(rsa), pms, pms_len, - RSA_PKCS1_PADDING)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_RSA_ENCRYPT); - goto err; - } - n += enc_pms_len; - - /* Log the premaster secret, if logging is enabled. */ - if (!ssl_ctx_log_rsa_client_key_exchange(s->ctx, p, enc_pms_len, pms, - pms_len)) { - goto err; - } - - /* Fill in the length prefix. */ - if (s->version > SSL3_VERSION) { - s2n(enc_pms_len, q); - } - } else if (alg_k & SSL_kDHE) { - DH *dh_srvr, *dh_clnt; - int dh_len; - size_t pub_len; - - if (s->s3->tmp.peer_dh_tmp == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } - dh_srvr = s->s3->tmp.peer_dh_tmp; - - /* generate a new random key */ - dh_clnt = DHparams_dup(dh_srvr); - if (dh_clnt == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); - goto err; - } - if (!DH_generate_key(dh_clnt)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); - DH_free(dh_clnt); - goto err; - } - - pms_len = DH_size(dh_clnt); - pms = OPENSSL_malloc(pms_len); - if (pms == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - DH_free(dh_clnt); - goto err; - } - - dh_len = DH_compute_key(pms, dh_srvr->pub_key, dh_clnt); - if (dh_len <= 0) { - OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); - DH_free(dh_clnt); - goto err; - } - pms_len = dh_len; - - /* send off the data */ - pub_len = BN_num_bytes(dh_clnt->pub_key); - s2n(pub_len, p); - BN_bn2bin(dh_clnt->pub_key, p); - n += 2 + pub_len; - - DH_free(dh_clnt); - } else if (alg_k & SSL_kECDHE) { - const EC_GROUP *srvr_group = NULL; - EC_KEY *tkey; - int ecdh_len; - - if (s->s3->tmp.peer_ecdh_tmp == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } - - tkey = s->s3->tmp.peer_ecdh_tmp; - - srvr_group = EC_KEY_get0_group(tkey); - srvr_ecpoint = EC_KEY_get0_public_key(tkey); - if (srvr_group == NULL || srvr_ecpoint == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } - - clnt_ecdh = EC_KEY_new(); - if (clnt_ecdh == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB); - goto err; - } - - /* Generate a new ECDH key pair */ - if (!EC_KEY_generate_key(clnt_ecdh)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); - goto err; - } - - unsigned field_size = EC_GROUP_get_degree(srvr_group); - if (field_size == 0) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); - goto err; - } + ssl->session->key_exchange_info = EVP_PKEY_bits(pkey); + EVP_PKEY_free(pkey); - pms_len = (field_size + 7) / 8; - pms = OPENSSL_malloc(pms_len); - if (pms == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } + pms[0] = ssl->client_version >> 8; + pms[1] = ssl->client_version & 0xff; + if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2)) { + goto err; + } - ecdh_len = ECDH_compute_key(pms, pms_len, srvr_ecpoint, clnt_ecdh, NULL); - if (ecdh_len <= 0) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); - goto err; - } - pms_len = ecdh_len; - - /* First check the size of encoding and allocate memory accordingly. */ - encoded_pt_len = - EC_POINT_point2oct(srvr_group, EC_KEY_get0_public_key(clnt_ecdh), - POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); - - encodedPoint = - (uint8_t *)OPENSSL_malloc(encoded_pt_len * sizeof(uint8_t)); - bn_ctx = BN_CTX_new(); - if (encodedPoint == NULL || bn_ctx == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + CBB child, *enc_pms = &cbb; + size_t enc_pms_len; + /* In TLS, there is a length prefix. */ + if (ssl->version > SSL3_VERSION) { + if (!CBB_add_u16_length_prefixed(&cbb, &child)) { goto err; } + enc_pms = &child; + } - /* Encode the public key */ - encoded_pt_len = EC_POINT_point2oct( - srvr_group, EC_KEY_get0_public_key(clnt_ecdh), - POINT_CONVERSION_UNCOMPRESSED, encodedPoint, encoded_pt_len, bn_ctx); - - *p = encoded_pt_len; /* length of encoded point */ - /* Encoded point will be copied here */ - p += 1; - n += 1; - /* copy the point */ - memcpy(p, encodedPoint, encoded_pt_len); - /* increment n to account for length field */ - n += encoded_pt_len; - - /* Free allocated memory */ - BN_CTX_free(bn_ctx); - bn_ctx = NULL; - OPENSSL_free(encodedPoint); - encodedPoint = NULL; - EC_KEY_free(clnt_ecdh); - clnt_ecdh = NULL; - EVP_PKEY_free(srvr_pub_pkey); - srvr_pub_pkey = NULL; - } else if (alg_k & SSL_kPSK) { - /* For plain PSK, other_secret is a block of 0s with the same length as - * the pre-shared key. */ - pms_len = psk_len; - pms = OPENSSL_malloc(pms_len); - if (pms == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } - memset(pms, 0, pms_len); + uint8_t *ptr; + if (!CBB_reserve(enc_pms, &ptr, RSA_size(rsa)) || + !RSA_encrypt(rsa, &enc_pms_len, ptr, RSA_size(rsa), pms, pms_len, + RSA_PKCS1_PADDING) || + /* Log the premaster secret, if logging is enabled. */ + !ssl_log_rsa_client_key_exchange(ssl, ptr, enc_pms_len, pms, pms_len) || + !CBB_did_write(enc_pms, enc_pms_len) || + !CBB_flush(&cbb)) { + goto err; + } + } else if (alg_k & (SSL_kECDHE|SSL_kDHE)) { + /* Generate a keypair and serialize the public half. ECDHE uses a u8 length + * prefix while DHE uses u16. */ + CBB child; + int child_ok; + if (alg_k & SSL_kECDHE) { + child_ok = CBB_add_u8_length_prefixed(&cbb, &child); } else { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + child_ok = CBB_add_u16_length_prefixed(&cbb, &child); + } + + if (!child_ok || + !SSL_ECDH_CTX_generate_keypair(&ssl->s3->tmp.ecdh_ctx, &child) || + !CBB_flush(&cbb)) { goto err; } - /* For a PSK cipher suite, other_secret is combined with the pre-shared - * key. */ - if (alg_a & SSL_aPSK) { - CBB cbb, child; - uint8_t *new_pms; - size_t new_pms_len; - - CBB_zero(&cbb); - if (!CBB_init(&cbb, 2 + psk_len + 2 + pms_len) || - !CBB_add_u16_length_prefixed(&cbb, &child) || - !CBB_add_bytes(&child, pms, pms_len) || - !CBB_add_u16_length_prefixed(&cbb, &child) || - !CBB_add_bytes(&child, psk, psk_len) || - !CBB_finish(&cbb, &new_pms, &new_pms_len)) { - CBB_cleanup(&cbb); - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } - OPENSSL_cleanse(pms, pms_len); - OPENSSL_free(pms); - pms = new_pms; - pms_len = new_pms_len; + /* Compute the premaster. */ + uint8_t alert; + if (!SSL_ECDH_CTX_compute_secret(&ssl->s3->tmp.ecdh_ctx, &pms, &pms_len, + &alert, ssl->s3->tmp.peer_key, + ssl->s3->tmp.peer_key_len)) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, alert); + goto err; } - /* The message must be added to the finished hash before calculating the - * master secret. */ - if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n)) { + /* The key exchange state may now be discarded. */ + SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx); + OPENSSL_free(ssl->s3->tmp.peer_key); + ssl->s3->tmp.peer_key = NULL; + } else if (alg_k & SSL_kPSK) { + /* For plain PSK, other_secret is a block of 0s with the same length as + * the pre-shared key. */ + pms_len = psk_len; + pms = OPENSSL_malloc(pms_len); + if (pms == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } - s->state = SSL3_ST_CW_KEY_EXCH_B; + memset(pms, 0, pms_len); + } else { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + goto err; + } - s->session->master_key_length = s->enc_method->generate_master_secret( - s, s->session->master_key, pms, pms_len); - if (s->session->master_key_length == 0) { + /* For a PSK cipher suite, other_secret is combined with the pre-shared + * key. */ + if (alg_a & SSL_aPSK) { + CBB pms_cbb, child; + uint8_t *new_pms; + size_t new_pms_len; + + CBB_zero(&pms_cbb); + if (!CBB_init(&pms_cbb, 2 + psk_len + 2 + pms_len) || + !CBB_add_u16_length_prefixed(&pms_cbb, &child) || + !CBB_add_bytes(&child, pms, pms_len) || + !CBB_add_u16_length_prefixed(&pms_cbb, &child) || + !CBB_add_bytes(&child, psk, psk_len) || + !CBB_finish(&pms_cbb, &new_pms, &new_pms_len)) { + CBB_cleanup(&pms_cbb); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } - s->session->extended_master_secret = s->s3->tmp.extended_master_secret; OPENSSL_cleanse(pms, pms_len); OPENSSL_free(pms); + pms = new_pms; + pms_len = new_pms_len; } + /* The message must be added to the finished hash before calculating the + * master secret. */ + size_t length; + if (!CBB_finish(&cbb, NULL, &length) || + !ssl_set_handshake_header(ssl, SSL3_MT_CLIENT_KEY_EXCHANGE, length)) { + goto err; + } + ssl->state = SSL3_ST_CW_KEY_EXCH_B; + + ssl->session->master_key_length = ssl->enc_method->generate_master_secret( + ssl, ssl->session->master_key, pms, pms_len); + if (ssl->session->master_key_length == 0) { + goto err; + } + ssl->session->extended_master_secret = ssl->s3->tmp.extended_master_secret; + OPENSSL_cleanse(pms, pms_len); + OPENSSL_free(pms); + /* SSL3_ST_CW_KEY_EXCH_B */ - return s->method->do_write(s); + return ssl_do_write(ssl); err: - BN_CTX_free(bn_ctx); - OPENSSL_free(encodedPoint); - EC_KEY_free(clnt_ecdh); - EVP_PKEY_free(srvr_pub_pkey); - if (pms) { + if (pms != NULL) { OPENSSL_cleanse(pms, pms_len); OPENSSL_free(pms); } return -1; } -int ssl3_send_cert_verify(SSL *s) { - if (s->state == SSL3_ST_CW_CERT_VRFY_A || - s->state == SSL3_ST_CW_CERT_VRFY_B) { - enum ssl_private_key_result_t sign_result; - uint8_t *p = ssl_handshake_start(s); - size_t signature_length = 0; - unsigned long n = 0; - assert(ssl_has_private_key(s)); - - if (s->state == SSL3_ST_CW_CERT_VRFY_A) { - uint8_t *buf = (uint8_t *)s->init_buf->data; - const EVP_MD *md = NULL; - uint8_t digest[EVP_MAX_MD_SIZE]; - size_t digest_length; - - /* Write out the digest type if need be. */ - if (SSL_USE_SIGALGS(s)) { - md = tls1_choose_signing_digest(s); - if (!tls12_get_sigandhash(s, p, md)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return -1; - } - p += 2; - n += 2; - } +int ssl3_send_cert_verify(SSL *ssl) { + if (ssl->state == SSL3_ST_CW_CERT_VRFY_C) { + return ssl_do_write(ssl); + } - /* Compute the digest. */ - const int pkey_type = ssl_private_key_type(s); - if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey_type)) { - return -1; - } + CBB cbb, child; + if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl), + ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl))) { + goto err; + } - /* The handshake buffer is no longer necessary. */ - ssl3_free_handshake_buffer(s); + assert(ssl_has_private_key(ssl)); - /* Sign the digest. */ - signature_length = ssl_private_key_max_signature_len(s); - if (p + 2 + signature_length > buf + SSL3_RT_MAX_PLAIN_LENGTH) { - OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); - return -1; + const size_t max_sig_len = ssl_private_key_max_signature_len(ssl); + size_t sig_len; + enum ssl_private_key_result_t sign_result; + if (ssl->state == SSL3_ST_CW_CERT_VRFY_A) { + /* Select and write out the digest type in TLS 1.2. */ + const EVP_MD *md = NULL; + if (SSL_USE_SIGALGS(ssl)) { + md = tls1_choose_signing_digest(ssl); + if (!tls12_add_sigandhash(ssl, &cbb, md)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + goto err; } + } - s->rwstate = SSL_PRIVATE_KEY_OPERATION; - sign_result = ssl_private_key_sign(s, &p[2], &signature_length, - signature_length, md, digest, - digest_length); - } else { - if (SSL_USE_SIGALGS(s)) { - /* The digest has already been selected and written. */ - p += 2; - n += 2; - } - signature_length = ssl_private_key_max_signature_len(s); - s->rwstate = SSL_PRIVATE_KEY_OPERATION; - sign_result = ssl_private_key_sign_complete(s, &p[2], &signature_length, - signature_length); + /* Compute the digest. In TLS 1.1 and below, the digest type is also + * selected here. */ + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!ssl3_cert_verify_hash(ssl, digest, &digest_len, &md, + ssl_private_key_type(ssl))) { + goto err; } - if (sign_result == ssl_private_key_retry) { - s->state = SSL3_ST_CW_CERT_VRFY_B; - return -1; + /* The handshake buffer is no longer necessary. */ + ssl3_free_handshake_buffer(ssl); + + /* Sign the digest. */ + uint8_t *ptr; + if (!CBB_add_u16_length_prefixed(&cbb, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { + goto err; } - s->rwstate = SSL_NOTHING; - if (sign_result != ssl_private_key_success) { - return -1; + sign_result = ssl_private_key_sign(ssl, ptr, &sig_len, max_sig_len, md, + digest, digest_len); + } else { + assert(ssl->state == SSL3_ST_CW_CERT_VRFY_B); + + /* Skip over the already written signature algorithm and retry the + * signature. */ + uint8_t *ptr; + if ((SSL_USE_SIGALGS(ssl) && !CBB_did_write(&cbb, 2)) || + !CBB_add_u16_length_prefixed(&cbb, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { + goto err; } + sign_result = + ssl_private_key_sign_complete(ssl, ptr, &sig_len, max_sig_len); + } - s2n(signature_length, p); - n += signature_length + 2; - if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n)) { - return -1; - } - s->state = SSL3_ST_CW_CERT_VRFY_C; + switch (sign_result) { + case ssl_private_key_success: + ssl->rwstate = SSL_NOTHING; + break; + case ssl_private_key_failure: + ssl->rwstate = SSL_NOTHING; + goto err; + case ssl_private_key_retry: + ssl->rwstate = SSL_PRIVATE_KEY_OPERATION; + ssl->state = SSL3_ST_CW_CERT_VRFY_B; + goto err; } - return ssl_do_write(s); + size_t length; + if (!CBB_did_write(&child, sig_len) || + !CBB_finish(&cbb, NULL, &length) || + !ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE_VERIFY, length)) { + goto err; + } + + ssl->state = SSL3_ST_CW_CERT_VRFY_C; + return ssl_do_write(ssl); + +err: + CBB_cleanup(&cbb); + return -1; } /* ssl3_has_client_certificate returns true if a client certificate is @@ -1998,47 +1871,47 @@ static int ssl3_has_client_certificate(SSL *ssl) { return ssl->cert && ssl->cert->x509 && ssl_has_private_key(ssl); } -int ssl3_send_client_certificate(SSL *s) { +int ssl3_send_client_certificate(SSL *ssl) { X509 *x509 = NULL; EVP_PKEY *pkey = NULL; int i; - if (s->state == SSL3_ST_CW_CERT_A) { + if (ssl->state == SSL3_ST_CW_CERT_A) { /* Let cert callback update client certificates if required */ - if (s->cert->cert_cb) { - i = s->cert->cert_cb(s, s->cert->cert_cb_arg); + if (ssl->cert->cert_cb) { + i = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); if (i < 0) { - s->rwstate = SSL_X509_LOOKUP; + ssl->rwstate = SSL_X509_LOOKUP; return -1; } if (i == 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return 0; } - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; } - if (ssl3_has_client_certificate(s)) { - s->state = SSL3_ST_CW_CERT_C; + if (ssl3_has_client_certificate(ssl)) { + ssl->state = SSL3_ST_CW_CERT_C; } else { - s->state = SSL3_ST_CW_CERT_B; + ssl->state = SSL3_ST_CW_CERT_B; } } /* We need to get a client cert */ - if (s->state == SSL3_ST_CW_CERT_B) { + if (ssl->state == SSL3_ST_CW_CERT_B) { /* If we get an error, we need to: * ssl->rwstate=SSL_X509_LOOKUP; return(-1); * We then get retried later */ - i = ssl_do_client_cert_cb(s, &x509, &pkey); + i = ssl_do_client_cert_cb(ssl, &x509, &pkey); if (i < 0) { - s->rwstate = SSL_X509_LOOKUP; + ssl->rwstate = SSL_X509_LOOKUP; return -1; } - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; if (i == 1 && pkey != NULL && x509 != NULL) { - s->state = SSL3_ST_CW_CERT_B; - if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) { + ssl->state = SSL3_ST_CW_CERT_B; + if (!SSL_use_certificate(ssl, x509) || !SSL_use_PrivateKey(ssl, pkey)) { i = 0; } } else if (i == 1) { @@ -2048,42 +1921,42 @@ int ssl3_send_client_certificate(SSL *s) { X509_free(x509); EVP_PKEY_free(pkey); - if (i && !ssl3_has_client_certificate(s)) { + if (i && !ssl3_has_client_certificate(ssl)) { i = 0; } if (i == 0) { - if (s->version == SSL3_VERSION) { - s->s3->tmp.cert_req = 0; - ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); + if (ssl->version == SSL3_VERSION) { + ssl->s3->tmp.cert_req = 0; + ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); return 1; } else { - s->s3->tmp.cert_req = 2; + ssl->s3->tmp.cert_req = 2; /* There is no client certificate, so the handshake buffer may be * released. */ - ssl3_free_handshake_buffer(s); + ssl3_free_handshake_buffer(ssl); } } /* Ok, we have a cert */ - s->state = SSL3_ST_CW_CERT_C; + ssl->state = SSL3_ST_CW_CERT_C; } - if (s->state == SSL3_ST_CW_CERT_C) { - if (s->s3->tmp.cert_req == 2) { + if (ssl->state == SSL3_ST_CW_CERT_C) { + if (ssl->s3->tmp.cert_req == 2) { /* Send an empty Certificate message. */ - uint8_t *p = ssl_handshake_start(s); + uint8_t *p = ssl_handshake_start(ssl); l2n3(0, p); - if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, 3)) { + if (!ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE, 3)) { return -1; } - } else if (!ssl3_output_cert_chain(s)) { + } else if (!ssl3_output_cert_chain(ssl)) { return -1; } - s->state = SSL3_ST_CW_CERT_D; + ssl->state = SSL3_ST_CW_CERT_D; } /* SSL3_ST_CW_CERT_D */ - return ssl_do_write(s); + return ssl_do_write(ssl); } int ssl3_send_next_proto(SSL *ssl) { @@ -2117,12 +1990,6 @@ int ssl3_send_next_proto(SSL *ssl) { return ssl_do_write(ssl); } -static int write_32_byte_big_endian(CBB *out, const BIGNUM *in) { - uint8_t *ptr; - return CBB_add_space(out, &ptr, 32) && - BN_bn2bin_padded(ptr, 32, in); -} - int ssl3_send_channel_id(SSL *ssl) { if (ssl->state == SSL3_ST_CW_CHANNEL_ID_B) { return ssl_do_write(ssl); @@ -2148,13 +2015,13 @@ int ssl3_send_channel_id(SSL *ssl) { } ssl->rwstate = SSL_NOTHING; - if (EVP_PKEY_id(ssl->tlsext_channel_id_private) != EVP_PKEY_EC) { + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->tlsext_channel_id_private); + if (ec_key == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } int ret = -1; - EC_KEY *ec_key = ssl->tlsext_channel_id_private->pkey.ec; BIGNUM *x = BN_new(); BIGNUM *y = BN_new(); ECDSA_SIG *sig = NULL; @@ -2183,10 +2050,10 @@ int ssl3_send_channel_id(SSL *ssl) { ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) || !CBB_add_u16(&cbb, TLSEXT_TYPE_channel_id) || !CBB_add_u16_length_prefixed(&cbb, &child) || - !write_32_byte_big_endian(&child, x) || - !write_32_byte_big_endian(&child, y) || - !write_32_byte_big_endian(&child, sig->r) || - !write_32_byte_big_endian(&child, sig->s) || + !BN_bn2cbb_padded(&child, 32, x) || + !BN_bn2cbb_padded(&child, 32, y) || + !BN_bn2cbb_padded(&child, 32, sig->r) || + !BN_bn2cbb_padded(&child, 32, sig->s) || !CBB_finish(&cbb, NULL, &length) || !ssl_set_handshake_header(ssl, SSL3_MT_ENCRYPTED_EXTENSIONS, length)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); @@ -2211,15 +2078,15 @@ int ssl_do_client_cert_cb(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) { return ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey); } -int ssl3_verify_server_cert(SSL *s) { - int ret = ssl_verify_cert_chain(s, s->session->cert_chain); - if (s->verify_mode != SSL_VERIFY_NONE && ret <= 0) { - int al = ssl_verify_alarm_type(s->verify_result); - ssl3_send_alert(s, SSL3_AL_FATAL, al); +int ssl3_verify_server_cert(SSL *ssl) { + int ret = ssl_verify_cert_chain(ssl, ssl->session->cert_chain); + if (ssl->verify_mode != SSL_VERIFY_NONE && ret <= 0) { + int al = ssl_verify_alarm_type(ssl->verify_result); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); } else { ret = 1; - ERR_clear_error(); /* but we keep s->verify_result */ + ERR_clear_error(); /* but we keep ssl->verify_result */ } return ret; diff --git a/src/ssl/s3_enc.c b/src/ssl/s3_enc.c index aa0d717..89d861a 100644 --- a/src/ssl/s3_enc.c +++ b/src/ssl/s3_enc.c @@ -162,10 +162,10 @@ static const uint8_t ssl3_pad_2[48] = { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, }; -static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len, +static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len, uint8_t *p); -int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, +int ssl3_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret, size_t secret_len, const char *label, size_t label_len, const uint8_t *seed1, size_t seed1_len, const uint8_t *seed2, size_t seed2_len) { @@ -228,13 +228,13 @@ int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, return 1; } -void ssl3_cleanup_key_block(SSL *s) { - if (s->s3->tmp.key_block != NULL) { - OPENSSL_cleanse(s->s3->tmp.key_block, s->s3->tmp.key_block_length); - OPENSSL_free(s->s3->tmp.key_block); - s->s3->tmp.key_block = NULL; +void ssl3_cleanup_key_block(SSL *ssl) { + if (ssl->s3->tmp.key_block != NULL) { + OPENSSL_cleanse(ssl->s3->tmp.key_block, ssl->s3->tmp.key_block_length); + OPENSSL_free(ssl->s3->tmp.key_block); + ssl->s3->tmp.key_block = NULL; } - s->s3->tmp.key_block_length = 0; + ssl->s3->tmp.key_block_length = 0; } int ssl3_init_handshake_buffer(SSL *ssl) { @@ -309,20 +309,20 @@ int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len) { return 1; } -int ssl3_cert_verify_mac(SSL *s, int md_nid, uint8_t *p) { - return ssl3_handshake_mac(s, md_nid, NULL, 0, p); +int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p) { + return ssl3_handshake_mac(ssl, md_nid, NULL, 0, p); } -int ssl3_final_finish_mac(SSL *s, const char *sender, int len, uint8_t *p) { +int ssl3_final_finish_mac(SSL *ssl, const char *sender, int len, uint8_t *p) { int ret, sha1len; - ret = ssl3_handshake_mac(s, NID_md5, sender, len, p); + ret = ssl3_handshake_mac(ssl, NID_md5, sender, len, p); if (ret == 0) { return 0; } p += ret; - sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p); + sha1len = ssl3_handshake_mac(ssl, NID_sha1, sender, len, p); if (sha1len == 0) { return 0; } @@ -331,7 +331,7 @@ int ssl3_final_finish_mac(SSL *s, const char *sender, int len, uint8_t *p) { return ret; } -static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len, +static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len, uint8_t *p) { unsigned int ret; size_t npad, n; @@ -341,9 +341,9 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len, const EVP_MD_CTX *ctx_template; if (md_nid == NID_md5) { - ctx_template = &s->s3->handshake_md5; - } else if (md_nid == EVP_MD_CTX_type(&s->s3->handshake_hash)) { - ctx_template = &s->s3->handshake_hash; + ctx_template = &ssl->s3->handshake_md5; + } else if (md_nid == EVP_MD_CTX_type(&ssl->s3->handshake_hash)) { + ctx_template = &ssl->s3->handshake_hash; } else { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_REQUIRED_DIGEST); return 0; @@ -362,7 +362,8 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len, if (sender != NULL) { EVP_DigestUpdate(&ctx, sender, len); } - EVP_DigestUpdate(&ctx, s->session->master_key, s->session->master_key_length); + EVP_DigestUpdate(&ctx, ssl->session->master_key, + ssl->session->master_key_length); EVP_DigestUpdate(&ctx, ssl3_pad_1, npad); EVP_DigestFinal_ex(&ctx, md_buf, &i); @@ -371,7 +372,8 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len, OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); return 0; } - EVP_DigestUpdate(&ctx, s->session->master_key, s->session->master_key_length); + EVP_DigestUpdate(&ctx, ssl->session->master_key, + ssl->session->master_key_length); EVP_DigestUpdate(&ctx, ssl3_pad_2, npad); EVP_DigestUpdate(&ctx, md_buf, i); EVP_DigestFinal_ex(&ctx, p, &ret); diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c index 7bf223d..64f9f8c 100644 --- a/src/ssl/s3_lib.c +++ b/src/ssl/s3_lib.c @@ -181,21 +181,23 @@ int ssl3_supports_cipher(const SSL_CIPHER *cipher) { return 1; } -int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len) { - uint8_t *p = (uint8_t *)s->init_buf->data; +int ssl3_set_handshake_header(SSL *ssl, int htype, unsigned long len) { + uint8_t *p = (uint8_t *)ssl->init_buf->data; *(p++) = htype; l2n3(len, p); - s->init_num = (int)len + SSL3_HM_HEADER_LENGTH; - s->init_off = 0; + ssl->init_num = (int)len + SSL3_HM_HEADER_LENGTH; + ssl->init_off = 0; /* Add the message to the handshake hash. */ - return ssl3_update_handshake_hash(s, (uint8_t *)s->init_buf->data, - s->init_num); + return ssl3_update_handshake_hash(ssl, (uint8_t *)ssl->init_buf->data, + ssl->init_num); } -int ssl3_handshake_write(SSL *s) { return ssl3_do_write(s, SSL3_RT_HANDSHAKE); } +int ssl3_handshake_write(SSL *ssl) { + return ssl3_do_write(ssl, SSL3_RT_HANDSHAKE); +} -int ssl3_new(SSL *s) { +int ssl3_new(SSL *ssl) { SSL3_STATE *s3; s3 = OPENSSL_malloc(sizeof *s3); @@ -207,43 +209,41 @@ int ssl3_new(SSL *s) { EVP_MD_CTX_init(&s3->handshake_hash); EVP_MD_CTX_init(&s3->handshake_md5); - s->s3 = s3; + ssl->s3 = s3; /* Set the version to the highest supported version for TLS. This controls the - * initial state of |s->enc_method| and what the API reports as the version + * initial state of |ssl->enc_method| and what the API reports as the version * prior to negotiation. * * TODO(davidben): This is fragile and confusing. */ - s->version = TLS1_2_VERSION; + ssl->version = TLS1_2_VERSION; return 1; err: return 0; } -void ssl3_free(SSL *s) { - if (s == NULL || s->s3 == NULL) { +void ssl3_free(SSL *ssl) { + if (ssl == NULL || ssl->s3 == NULL) { return; } - ssl3_cleanup_key_block(s); - ssl_read_buffer_clear(s); - ssl_write_buffer_clear(s); - DH_free(s->s3->tmp.dh); - EC_KEY_free(s->s3->tmp.ecdh); + ssl3_cleanup_key_block(ssl); + ssl_read_buffer_clear(ssl); + ssl_write_buffer_clear(ssl); + SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx); + OPENSSL_free(ssl->s3->tmp.peer_key); - sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); - OPENSSL_free(s->s3->tmp.certificate_types); - OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist); - OPENSSL_free(s->s3->tmp.peer_psk_identity_hint); - DH_free(s->s3->tmp.peer_dh_tmp); - EC_KEY_free(s->s3->tmp.peer_ecdh_tmp); - ssl3_free_handshake_buffer(s); - ssl3_free_handshake_hash(s); - OPENSSL_free(s->s3->alpn_selected); + sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free); + OPENSSL_free(ssl->s3->tmp.certificate_types); + OPENSSL_free(ssl->s3->tmp.peer_ellipticcurvelist); + OPENSSL_free(ssl->s3->tmp.peer_psk_identity_hint); + ssl3_free_handshake_buffer(ssl); + ssl3_free_handshake_hash(ssl); + OPENSSL_free(ssl->s3->alpn_selected); - OPENSSL_cleanse(s->s3, sizeof *s->s3); - OPENSSL_free(s->s3); - s->s3 = NULL; + OPENSSL_cleanse(ssl->s3, sizeof *ssl->s3); + OPENSSL_free(ssl->s3); + ssl->s3 = NULL; } int SSL_session_reused(const SSL *ssl) { @@ -299,8 +299,8 @@ int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) { OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - ctx->cert->ecdh_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); - return 1; + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); + return SSL_CTX_set1_curves(ctx, &nid, 1); } int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) { @@ -308,8 +308,8 @@ int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) { OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - ssl->cert->ecdh_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); - return 1; + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); + return SSL_set1_curves(ssl, &nid, 1); } int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx) { @@ -335,8 +335,9 @@ int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) { } int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) { - if (EVP_PKEY_id(private_key) != EVP_PKEY_EC || - EC_GROUP_get_curve_name(EC_KEY_get0_group(private_key->pkey.ec)) != + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key); + if (ec_key == NULL || + EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != NID_X9_62_prime256v1) { OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); return 0; @@ -446,30 +447,30 @@ int SSL_CTX_set_tlsext_ticket_key_cb( return 1; } -struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *s) { - if (s->cipher_list != NULL) { - return s->cipher_list; +struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *ssl) { + if (ssl->cipher_list != NULL) { + return ssl->cipher_list; } - if (s->version >= TLS1_1_VERSION && s->ctx != NULL && - s->ctx->cipher_list_tls11 != NULL) { - return s->ctx->cipher_list_tls11; + if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL && + ssl->ctx->cipher_list_tls11 != NULL) { + return ssl->ctx->cipher_list_tls11; } - if (s->version >= TLS1_VERSION && s->ctx != NULL && - s->ctx->cipher_list_tls10 != NULL) { - return s->ctx->cipher_list_tls10; + if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL && + ssl->ctx->cipher_list_tls10 != NULL) { + return ssl->ctx->cipher_list_tls10; } - if (s->ctx != NULL && s->ctx->cipher_list != NULL) { - return s->ctx->cipher_list; + if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) { + return ssl->ctx->cipher_list; } return NULL; } const SSL_CIPHER *ssl3_choose_cipher( - SSL *s, STACK_OF(SSL_CIPHER) *clnt, + SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, struct ssl_cipher_preference_list_st *server_pref) { const SSL_CIPHER *c, *ret = NULL; STACK_OF(SSL_CIPHER) *srvr = server_pref->ciphers, *prio, *allow; @@ -486,7 +487,7 @@ const SSL_CIPHER *ssl3_choose_cipher( * such value exists yet. */ int group_min = -1; - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { prio = srvr; in_group_flags = server_pref->in_group_flags; allow = clnt; @@ -496,7 +497,7 @@ const SSL_CIPHER *ssl3_choose_cipher( allow = srvr; } - ssl_get_compatible_server_ciphers(s, &mask_k, &mask_a); + ssl_get_compatible_server_ciphers(ssl, &mask_k, &mask_a); for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { c = sk_SSL_CIPHER_value(prio, i); @@ -504,7 +505,8 @@ const SSL_CIPHER *ssl3_choose_cipher( ok = 1; /* Check the TLS version. */ - if (SSL_CIPHER_get_min_version(c) > ssl3_version_from_wire(s, s->version)) { + if (SSL_CIPHER_get_min_version(c) > + ssl3_version_from_wire(ssl, ssl->version)) { ok = 0; } @@ -540,7 +542,7 @@ const SSL_CIPHER *ssl3_choose_cipher( return ret; } -int ssl3_get_req_cert_type(SSL *s, uint8_t *p) { +int ssl3_get_req_cert_type(SSL *ssl, uint8_t *p) { int ret = 0; const uint8_t *sig; size_t i, siglen; @@ -548,7 +550,7 @@ int ssl3_get_req_cert_type(SSL *s, uint8_t *p) { int have_ecdsa_sign = 0; /* get configured sigalgs */ - siglen = tls12_get_psigalgs(s, &sig); + siglen = tls12_get_psigalgs(ssl, &sig); for (i = 0; i < siglen; i += 2, sig += 2) { switch (sig[1]) { case TLSEXT_signature_rsa: @@ -567,7 +569,7 @@ int ssl3_get_req_cert_type(SSL *s, uint8_t *p) { /* ECDSA certs can be used with RSA cipher suites as well so we don't need to * check for SSL_kECDH or SSL_kECDHE. */ - if (s->version >= TLS1_VERSION && have_ecdsa_sign) { + if (ssl->version >= TLS1_VERSION && have_ecdsa_sign) { p[ret++] = TLS_CT_ECDSA_SIGN; } @@ -576,9 +578,9 @@ int ssl3_get_req_cert_type(SSL *s, uint8_t *p) { /* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and * handshake macs if required. */ -uint32_t ssl_get_algorithm_prf(SSL *s) { - uint32_t algorithm_prf = s->s3->tmp.new_cipher->algorithm_prf; - if (s->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF && +uint32_t ssl_get_algorithm_prf(SSL *ssl) { + uint32_t algorithm_prf = ssl->s3->tmp.new_cipher->algorithm_prf; + if (ssl->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF && algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT) { return SSL_HANDSHAKE_MAC_SHA256; } diff --git a/src/ssl/s3_meth.c b/src/ssl/s3_meth.c index 01c1101..b60b5f2 100644 --- a/src/ssl/s3_meth.c +++ b/src/ssl/s3_meth.c @@ -67,6 +67,7 @@ static const SSL_PROTOCOL_METHOD TLS_protocol_method = { ssl3_connect, ssl3_get_message, ssl3_read_app_data, + ssl3_read_change_cipher_spec, ssl3_read_close_notify, ssl3_write_app_data, ssl3_dispatch_alert, diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.c index 7416d0e..4c1133c 100644 --- a/src/ssl/s3_pkt.c +++ b/src/ssl/s3_pkt.c @@ -122,7 +122,7 @@ #include "internal.h" -static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned len); +static int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len); /* kMaxWarningAlerts is the number of consecutive warning alerts that will be * processed. */ @@ -158,7 +158,6 @@ again: SSL3_RECORD *rr = &ssl->s3->rrec; rr->type = type; rr->length = (uint16_t)len; - rr->off = 0; rr->data = out; return 1; @@ -189,18 +188,18 @@ int ssl3_write_app_data(SSL *ssl, const void *buf, int len) { /* Call this to write data in records of type |type|. It will return <= 0 if * not all data has been sent or non-blocking IO. */ -int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) { +int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, int len) { const uint8_t *buf = buf_; unsigned int tot, n, nw; int i; - s->rwstate = SSL_NOTHING; - assert(s->s3->wnum <= INT_MAX); - tot = s->s3->wnum; - s->s3->wnum = 0; + ssl->rwstate = SSL_NOTHING; + assert(ssl->s3->wnum <= INT_MAX); + tot = ssl->s3->wnum; + ssl->s3->wnum = 0; - if (!s->in_handshake && SSL_in_init(s) && !SSL_in_false_start(s)) { - i = s->handshake_func(s); + if (!ssl->in_handshake && SSL_in_init(ssl) && !SSL_in_false_start(ssl)) { + i = ssl->handshake_func(ssl); if (i < 0) { return i; } @@ -226,21 +225,21 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) { for (;;) { /* max contains the maximum number of bytes that we can put into a * record. */ - unsigned max = s->max_send_fragment; + unsigned max = ssl->max_send_fragment; if (n > max) { nw = max; } else { nw = n; } - i = do_ssl3_write(s, type, &buf[tot], nw); + i = do_ssl3_write(ssl, type, &buf[tot], nw); if (i <= 0) { - s->s3->wnum = tot; + ssl->s3->wnum = tot; return i; } if (i == (int)n || (type == SSL3_RT_APPLICATION_DATA && - (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { + (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { return tot + i; } @@ -249,33 +248,33 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) { } } -static int ssl3_write_pending(SSL *s, int type, const uint8_t *buf, +static int ssl3_write_pending(SSL *ssl, int type, const uint8_t *buf, unsigned int len) { - if (s->s3->wpend_tot > (int)len || - (s->s3->wpend_buf != buf && - !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) || - s->s3->wpend_type != type) { + if (ssl->s3->wpend_tot > (int)len || + (ssl->s3->wpend_buf != buf && + !(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) || + ssl->s3->wpend_type != type) { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY); return -1; } - int ret = ssl_write_buffer_flush(s); + int ret = ssl_write_buffer_flush(ssl); if (ret <= 0) { return ret; } - return s->s3->wpend_ret; + return ssl->s3->wpend_ret; } /* do_ssl3_write writes an SSL record of the given type. */ -static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned len) { +static int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len) { /* If there is still data from the previous record, flush it. */ - if (ssl_write_buffer_is_pending(s)) { - return ssl3_write_pending(s, type, buf, len); + if (ssl_write_buffer_is_pending(ssl)) { + return ssl3_write_pending(ssl, type, buf, len); } /* If we have an alert to send, lets send it */ - if (s->s3->alert_dispatch) { - int ret = s->method->ssl_dispatch_alert(s); + if (ssl->s3->alert_dispatch) { + int ret = ssl->method->ssl_dispatch_alert(ssl); if (ret <= 0) { return ret; } @@ -291,47 +290,55 @@ static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned len) { return 0; } - size_t max_out = len + ssl_max_seal_overhead(s); + size_t max_out = len + ssl_max_seal_overhead(ssl); if (max_out < len) { OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); return -1; } uint8_t *out; size_t ciphertext_len; - if (!ssl_write_buffer_init(s, &out, max_out) || - !tls_seal_record(s, out, &ciphertext_len, max_out, type, buf, len)) { + if (!ssl_write_buffer_init(ssl, &out, max_out) || + !tls_seal_record(ssl, out, &ciphertext_len, max_out, type, buf, len)) { return -1; } - ssl_write_buffer_set_len(s, ciphertext_len); + ssl_write_buffer_set_len(ssl, ciphertext_len); /* memorize arguments so that ssl3_write_pending can detect bad write retries * later */ - s->s3->wpend_tot = len; - s->s3->wpend_buf = buf; - s->s3->wpend_type = type; - s->s3->wpend_ret = len; + ssl->s3->wpend_tot = len; + ssl->s3->wpend_buf = buf; + ssl->s3->wpend_type = type; + ssl->s3->wpend_ret = len; /* we now just need to write the buffer */ - return ssl3_write_pending(s, type, buf, len); + return ssl3_write_pending(ssl, type, buf, len); } -/* ssl3_expect_change_cipher_spec informs the record layer that a - * ChangeCipherSpec record is required at this point. If a Handshake record is - * received before ChangeCipherSpec, the connection will fail. Moreover, if - * there are unprocessed handshake bytes, the handshake will also fail and the - * function returns zero. Otherwise, the function returns one. */ -int ssl3_expect_change_cipher_spec(SSL *s) { - if (s->s3->handshake_fragment_len > 0 || s->s3->tmp.reuse_message) { - OPENSSL_PUT_ERROR(SSL, SSL_R_UNPROCESSED_HANDSHAKE_DATA); - return 0; +int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) { + return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek); +} + +int ssl3_read_change_cipher_spec(SSL *ssl) { + uint8_t byte; + int ret = ssl3_read_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1 /* len */, + 0 /* no peek */); + if (ret <= 0) { + return ret; } + assert(ret == 1); - s->s3->flags |= SSL3_FLAGS_EXPECT_CCS; - return 1; -} + if (ssl->s3->rrec.length != 0 || byte != SSL3_MT_CCS) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return -1; + } -int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) { - return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek); + if (ssl->msg_callback != NULL) { + ssl->msg_callback(0, ssl->version, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1, + ssl, ssl->msg_callback_arg); + } + + return 1; } void ssl3_read_close_notify(SSL *ssl) { @@ -358,72 +365,36 @@ static int ssl3_can_renegotiate(SSL *ssl) { * 'type' is one of the following: * * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) - * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - SSL3_RT_CHANGE_CIPHER_SPEC (when ssl3_read_change_cipher_spec calls us) + * - SSL3_RT_APPLICATION_DATA (when ssl3_read_app_data calls us) * - 0 (during a shutdown, no data has to be returned) * * If we don't have stored data to work from, read a SSL/TLS record first * (possibly multiple records if we still don't have anything to return). * * This function must handle any surprises the peer may have for us, such as - * Alert records (e.g. close_notify), ChangeCipherSpec records (not really - * a surprise, but handled as if it were), or renegotiation requests. - * Also if record payloads contain fragments too small to process, we store - * them until there is enough for the respective protocol (the record protocol - * may use arbitrary fragmentation and even interleaving): - * Change cipher spec protocol - * just 1 byte needed, no need for keeping anything stored - * Alert protocol - * 2 bytes needed (AlertLevel, AlertDescription) - * Handshake protocol - * 4 bytes needed (HandshakeType, uint24 length) -- we just have - * to detect unexpected Client Hello and Hello Request messages - * here, anything else is handled by higher layers - * Application data protocol - * none of our business - */ -int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek) { + * Alert records (e.g. close_notify) or renegotiation requests. */ +int ssl3_read_bytes(SSL *ssl, int type, uint8_t *buf, int len, int peek) { int al, i, ret; unsigned int n; SSL3_RECORD *rr; void (*cb)(const SSL *ssl, int type, int value) = NULL; - if ((type && type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) || + if ((type && type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE && + type != SSL3_RT_CHANGE_CIPHER_SPEC) || (peek && type != SSL3_RT_APPLICATION_DATA)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } - if (type == SSL3_RT_HANDSHAKE && s->s3->handshake_fragment_len > 0) { - /* (partially) satisfy request from storage */ - uint8_t *src = s->s3->handshake_fragment; - uint8_t *dst = buf; - unsigned int k; - - /* peek == 0 */ - n = 0; - while (len > 0 && s->s3->handshake_fragment_len > 0) { - *dst++ = *src++; - len--; - s->s3->handshake_fragment_len--; - n++; - } - /* move any remaining fragment bytes: */ - for (k = 0; k < s->s3->handshake_fragment_len; k++) { - s->s3->handshake_fragment[k] = *src++; - } - return n; - } - - /* Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */ - /* This may require multiple iterations. False Start will cause - * |s->handshake_func| to signal success one step early, but the handshake + * |ssl->handshake_func| to signal success one step early, but the handshake * must be completely finished before other modes are accepted. * * TODO(davidben): Move this check up to a higher level. */ - while (!s->in_handshake && SSL_in_init(s)) { + while (!ssl->in_handshake && SSL_in_init(ssl)) { assert(type == SSL3_RT_APPLICATION_DATA); - i = s->handshake_func(s); + i = ssl->handshake_func(ssl); if (i < 0) { return i; } @@ -434,17 +405,17 @@ int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek) { } start: - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; - /* s->s3->rrec.type - is the type of record - * s->s3->rrec.data - data - * s->s3->rrec.off - offset into 'data' for next read - * s->s3->rrec.length - number of bytes. */ - rr = &s->s3->rrec; + /* ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data - data + * ssl->s3->rrec.off - offset into 'data' for next read + * ssl->s3->rrec.length - number of bytes. */ + rr = &ssl->s3->rrec; /* get new packet if necessary */ if (rr->length == 0) { - ret = ssl3_get_record(s); + ret = ssl3_get_record(ssl); if (ret <= 0) { return ret; } @@ -452,39 +423,21 @@ start: /* we now have a packet which can be read and processed */ - /* |change_cipher_spec is set when we receive a ChangeCipherSpec and reset by - * ssl3_get_finished. */ - if (s->s3->change_cipher_spec && rr->type != SSL3_RT_HANDSHAKE && - rr->type != SSL3_RT_ALERT) { - al = SSL_AD_UNEXPECTED_MESSAGE; - OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); - goto f_err; - } - - /* If we are expecting a ChangeCipherSpec, it is illegal to receive a - * Handshake record. */ - if (rr->type == SSL3_RT_HANDSHAKE && (s->s3->flags & SSL3_FLAGS_EXPECT_CCS)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_RECORD_BEFORE_CCS); - goto f_err; - } - /* If the other end has shut down, throw anything we read away (even in * 'peek' mode) */ - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) { rr->length = 0; - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; return 0; } if (type != 0 && type == rr->type) { - s->s3->warning_alert_count = 0; + ssl->s3->warning_alert_count = 0; - /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ - /* make sure that we are not getting application data when we are doing a - * handshake for the first time */ - if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA && - s->aead_read_ctx == NULL) { + /* Make sure that we are not getting application data when we are doing a + * handshake for the first time. */ + if (SSL_in_init(ssl) && type == SSL3_RT_APPLICATION_DATA && + ssl->aead_read_ctx == NULL) { /* TODO(davidben): Is this check redundant with the handshake_func * check? */ al = SSL_AD_UNEXPECTED_MESSAGE; @@ -507,14 +460,13 @@ start: n = (unsigned int)len; } - memcpy(buf, &(rr->data[rr->off]), n); + memcpy(buf, rr->data, n); if (!peek) { rr->length -= n; - rr->off += n; + rr->data += n; if (rr->length == 0) { - rr->off = 0; /* The record has been consumed, so we may now clear the buffer. */ - ssl_read_buffer_discard(s); + ssl_read_buffer_discard(ssl); } } @@ -523,45 +475,40 @@ start: /* Process unexpected records. */ - if (rr->type == SSL3_RT_HANDSHAKE) { + if (type == SSL3_RT_APPLICATION_DATA && rr->type == SSL3_RT_HANDSHAKE) { /* If peer renegotiations are disabled, all out-of-order handshake records * are fatal. Renegotiations as a server are never supported. */ - if (s->server || !ssl3_can_renegotiate(s)) { + if (ssl->server || !ssl3_can_renegotiate(ssl)) { al = SSL_AD_NO_RENEGOTIATION; OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); goto f_err; } - /* HelloRequests may be fragmented across multiple records. */ - const size_t size = sizeof(s->s3->handshake_fragment); - const size_t avail = size - s->s3->handshake_fragment_len; - const size_t todo = (rr->length < avail) ? rr->length : avail; - memcpy(s->s3->handshake_fragment + s->s3->handshake_fragment_len, - &rr->data[rr->off], todo); - rr->off += todo; - rr->length -= todo; - s->s3->handshake_fragment_len += todo; - if (s->s3->handshake_fragment_len < size) { - goto start; /* fragment was too small */ - } - - /* Parse out and consume a HelloRequest. */ - if (s->s3->handshake_fragment[0] != SSL3_MT_HELLO_REQUEST || - s->s3->handshake_fragment[1] != 0 || - s->s3->handshake_fragment[2] != 0 || - s->s3->handshake_fragment[3] != 0) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST); - goto f_err; + /* This must be a HelloRequest, possibly fragmented over multiple records. + * Consume data from the handshake protocol until it is complete. */ + static const uint8_t kHelloRequest[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0}; + while (ssl->s3->hello_request_len < sizeof(kHelloRequest)) { + if (rr->length == 0) { + /* Get a new record. */ + goto start; + } + if (rr->data[0] != kHelloRequest[ssl->s3->hello_request_len]) { + al = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST); + goto f_err; + } + rr->data++; + rr->length--; + ssl->s3->hello_request_len++; } - s->s3->handshake_fragment_len = 0; + ssl->s3->hello_request_len = 0; - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - s->s3->handshake_fragment, 4, s, s->msg_callback_arg); + if (ssl->msg_callback) { + ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, kHelloRequest, + sizeof(kHelloRequest), ssl, ssl->msg_callback_arg); } - if (!SSL_is_init_finished(s) || !s->s3->initial_handshake_complete) { + if (!SSL_is_init_finished(ssl) || !ssl->s3->initial_handshake_complete) { /* This cannot happen. If a handshake is in progress, |type| must be * |SSL3_RT_HANDSHAKE|. */ assert(0); @@ -569,7 +516,7 @@ start: goto err; } - if (s->renegotiate_mode == ssl_renegotiate_ignore) { + if (ssl->renegotiate_mode == ssl_renegotiate_ignore) { goto start; } @@ -577,16 +524,16 @@ start: * protocol, namely in HTTPS, just before reading the HTTP response. Require * the record-layer be idle and avoid complexities of sending a handshake * record while an application_data record is being written. */ - if (ssl_write_buffer_is_pending(s)) { + if (ssl_write_buffer_is_pending(ssl)) { al = SSL_AD_NO_RENEGOTIATION; OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); goto f_err; } /* Begin a new handshake. */ - s->s3->total_renegotiations++; - s->state = SSL_ST_CONNECT; - i = s->handshake_func(s); + ssl->s3->total_renegotiations++; + ssl->state = SSL_ST_CONNECT; + i = ssl->handshake_func(ssl); if (i < 0) { return i; } @@ -609,29 +556,30 @@ start: goto f_err; } - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_ALERT, &rr->data[rr->off], 2, s, - s->msg_callback_arg); + if (ssl->msg_callback) { + ssl->msg_callback(0, ssl->version, SSL3_RT_ALERT, rr->data, 2, ssl, + ssl->msg_callback_arg); } - const uint8_t alert_level = rr->data[rr->off++]; - const uint8_t alert_descr = rr->data[rr->off++]; + const uint8_t alert_level = rr->data[0]; + const uint8_t alert_descr = rr->data[1]; rr->length -= 2; + rr->data += 2; - if (s->info_callback != NULL) { - cb = s->info_callback; - } else if (s->ctx->info_callback != NULL) { - cb = s->ctx->info_callback; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; } if (cb != NULL) { uint16_t alert = (alert_level << 8) | alert_descr; - cb(s, SSL_CB_READ_ALERT, alert); + cb(ssl, SSL_CB_READ_ALERT, alert); } if (alert_level == SSL3_AL_WARNING) { - s->s3->warn_alert = alert_descr; + ssl->s3->warn_alert = alert_descr; if (alert_descr == SSL_AD_CLOSE_NOTIFY) { - s->shutdown |= SSL_RECEIVED_SHUTDOWN; + ssl->shutdown |= SSL_RECEIVED_SHUTDOWN; return 0; } @@ -648,8 +596,8 @@ start: goto f_err; } - s->s3->warning_alert_count++; - if (s->s3->warning_alert_count > kMaxWarningAlerts) { + ssl->s3->warning_alert_count++; + if (ssl->s3->warning_alert_count > kMaxWarningAlerts) { al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_WARNING_ALERTS); goto f_err; @@ -657,13 +605,13 @@ start: } else if (alert_level == SSL3_AL_FATAL) { char tmp[16]; - s->rwstate = SSL_NOTHING; - s->s3->fatal_alert = alert_descr; + ssl->rwstate = SSL_NOTHING; + ssl->s3->fatal_alert = alert_descr; OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr); BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr); ERR_add_error_data(2, "SSL alert number ", tmp); - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->ctx, s->session); + ssl->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(ssl->ctx, ssl->session); return 0; } else { al = SSL_AD_ILLEGAL_PARAMETER; @@ -674,97 +622,54 @@ start: goto start; } - if (s->shutdown & SSL_SENT_SHUTDOWN) { + if (ssl->shutdown & SSL_SENT_SHUTDOWN) { /* close_notify has been sent, so discard all records other than alerts. */ rr->length = 0; goto start; } - if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { - /* 'Change Cipher Spec' is just a single byte, so we know exactly what the - * record payload has to look like */ - if (rr->length != 1 || rr->off != 0 || rr->data[0] != SSL3_MT_CCS) { - al = SSL_AD_ILLEGAL_PARAMETER; - OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto f_err; - } - - /* Check we have a cipher to change to */ - if (s->s3->tmp.new_cipher == NULL) { - al = SSL_AD_UNEXPECTED_MESSAGE; - OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY); - goto f_err; - } - - if (!(s->s3->flags & SSL3_FLAGS_EXPECT_CCS)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY); - goto f_err; - } - - s->s3->flags &= ~SSL3_FLAGS_EXPECT_CCS; - - rr->length = 0; - - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, - s->msg_callback_arg); - } - - s->s3->change_cipher_spec = 1; - if (!ssl3_do_change_cipher_spec(s)) { - goto err; - } else { - goto start; - } - } - - /* We already handled these. */ - assert(rr->type != SSL3_RT_CHANGE_CIPHER_SPEC && rr->type != SSL3_RT_ALERT && - rr->type != SSL3_RT_HANDSHAKE); - al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: return -1; } -int ssl3_do_change_cipher_spec(SSL *s) { +int ssl3_do_change_cipher_spec(SSL *ssl) { int i; - if (s->state & SSL_ST_ACCEPT) { + if (ssl->state & SSL_ST_ACCEPT) { i = SSL3_CHANGE_CIPHER_SERVER_READ; } else { i = SSL3_CHANGE_CIPHER_CLIENT_READ; } - if (s->s3->tmp.key_block == NULL) { - if (s->session == NULL || s->session->master_key_length == 0) { + if (ssl->s3->tmp.key_block == NULL) { + if (ssl->session == NULL || ssl->session->master_key_length == 0) { /* might happen if dtls1_read_bytes() calls this */ OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY); return 0; } - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->enc_method->setup_key_block(s)) { + ssl->session->cipher = ssl->s3->tmp.new_cipher; + if (!ssl->enc_method->setup_key_block(ssl)) { return 0; } } - if (!s->enc_method->change_cipher_state(s, i)) { + if (!ssl->enc_method->change_cipher_state(ssl, i)) { return 0; } return 1; } -int ssl3_send_alert(SSL *s, int level, int desc) { +int ssl3_send_alert(SSL *ssl, int level, int desc) { /* Map tls/ssl alert value to correct one */ - desc = s->enc_method->alert_value(desc); - if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) { + desc = ssl->enc_method->alert_value(desc); + if (ssl->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) { /* SSL 3.0 does not have protocol_version alerts */ desc = SSL_AD_HANDSHAKE_FAILURE; } @@ -773,17 +678,17 @@ int ssl3_send_alert(SSL *s, int level, int desc) { } /* If a fatal one, remove from cache */ - if (level == 2 && s->session != NULL) { - SSL_CTX_remove_session(s->ctx, s->session); + if (level == 2 && ssl->session != NULL) { + SSL_CTX_remove_session(ssl->ctx, ssl->session); } - s->s3->alert_dispatch = 1; - s->s3->send_alert[0] = level; - s->s3->send_alert[1] = desc; - if (!ssl_write_buffer_is_pending(s)) { + ssl->s3->alert_dispatch = 1; + ssl->s3->send_alert[0] = level; + ssl->s3->send_alert[1] = desc; + if (!ssl_write_buffer_is_pending(ssl)) { /* Nothing is being written out, so the alert may be dispatched * immediately. */ - return s->method->ssl_dispatch_alert(s); + return ssl->method->ssl_dispatch_alert(ssl); } /* else data is still being written out, we will get written some time in the @@ -791,35 +696,35 @@ int ssl3_send_alert(SSL *s, int level, int desc) { return -1; } -int ssl3_dispatch_alert(SSL *s) { +int ssl3_dispatch_alert(SSL *ssl) { int i, j; void (*cb)(const SSL *ssl, int type, int value) = NULL; - s->s3->alert_dispatch = 0; - i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2); + ssl->s3->alert_dispatch = 0; + i = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2); if (i <= 0) { - s->s3->alert_dispatch = 1; + ssl->s3->alert_dispatch = 1; } else { /* Alert sent to BIO. If it is important, flush it now. If the message * does not get sent due to non-blocking IO, we will not worry too much. */ - if (s->s3->send_alert[0] == SSL3_AL_FATAL) { - BIO_flush(s->wbio); + if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { + BIO_flush(ssl->wbio); } - if (s->msg_callback) { - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s, - s->msg_callback_arg); + if (ssl->msg_callback) { + ssl->msg_callback(1, ssl->version, SSL3_RT_ALERT, ssl->s3->send_alert, 2, + ssl, ssl->msg_callback_arg); } - if (s->info_callback != NULL) { - cb = s->info_callback; - } else if (s->ctx->info_callback != NULL) { - cb = s->ctx->info_callback; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; } if (cb != NULL) { - j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; - cb(s, SSL_CB_WRITE_ALERT, j); + j = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; + cb(ssl, SSL_CB_WRITE_ALERT, j); } } diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c index 8cfa0e6..49a1a95 100644 --- a/src/ssl/s3_srvr.c +++ b/src/ssl/s3_srvr.c @@ -174,154 +174,154 @@ #include "../crypto/dh/internal.h" -int ssl3_accept(SSL *s) { +int ssl3_accept(SSL *ssl) { BUF_MEM *buf = NULL; uint32_t alg_a; void (*cb)(const SSL *ssl, int type, int value) = NULL; int ret = -1; int new_state, state, skip = 0; - assert(s->handshake_func == ssl3_accept); - assert(s->server); - assert(!SSL_IS_DTLS(s)); + assert(ssl->handshake_func == ssl3_accept); + assert(ssl->server); + assert(!SSL_IS_DTLS(ssl)); ERR_clear_error(); ERR_clear_system_error(); - if (s->info_callback != NULL) { - cb = s->info_callback; - } else if (s->ctx->info_callback != NULL) { - cb = s->ctx->info_callback; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; } - s->in_handshake++; + ssl->in_handshake++; - if (s->cert == NULL) { + if (ssl->cert == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); return -1; } for (;;) { - state = s->state; + state = ssl->state; - switch (s->state) { + switch (ssl->state) { case SSL_ST_ACCEPT: if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_START, 1); + cb(ssl, SSL_CB_HANDSHAKE_START, 1); } - if (s->init_buf == NULL) { + if (ssl->init_buf == NULL) { buf = BUF_MEM_new(); if (!buf || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { ret = -1; goto end; } - s->init_buf = buf; + ssl->init_buf = buf; buf = NULL; } - s->init_num = 0; + ssl->init_num = 0; /* Enable a write buffer. This groups handshake messages within a flight * into a single write. */ - if (!ssl_init_wbio_buffer(s, 1)) { + if (!ssl_init_wbio_buffer(ssl, 1)) { ret = -1; goto end; } - if (!ssl3_init_handshake_buffer(s)) { + if (!ssl3_init_handshake_buffer(ssl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); ret = -1; goto end; } - if (!s->s3->have_version) { - s->state = SSL3_ST_SR_INITIAL_BYTES; + if (!ssl->s3->have_version) { + ssl->state = SSL3_ST_SR_INITIAL_BYTES; } else { - s->state = SSL3_ST_SR_CLNT_HELLO_A; + ssl->state = SSL3_ST_SR_CLNT_HELLO_A; } break; case SSL3_ST_SR_INITIAL_BYTES: - ret = ssl3_get_initial_bytes(s); + ret = ssl3_get_initial_bytes(ssl); if (ret <= 0) { goto end; } - /* ssl3_get_initial_bytes sets s->state to one of + /* ssl3_get_initial_bytes sets ssl->state to one of * SSL3_ST_SR_V2_CLIENT_HELLO or SSL3_ST_SR_CLNT_HELLO_A on success. */ break; case SSL3_ST_SR_V2_CLIENT_HELLO: - ret = ssl3_get_v2_client_hello(s); + ret = ssl3_get_v2_client_hello(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SR_CLNT_HELLO_A; + ssl->state = SSL3_ST_SR_CLNT_HELLO_A; break; case SSL3_ST_SR_CLNT_HELLO_A: case SSL3_ST_SR_CLNT_HELLO_B: case SSL3_ST_SR_CLNT_HELLO_C: case SSL3_ST_SR_CLNT_HELLO_D: - s->shutdown = 0; - ret = ssl3_get_client_hello(s); + ssl->shutdown = 0; + ret = ssl3_get_client_hello(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_SRVR_HELLO_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_SRVR_HELLO_A; + ssl->init_num = 0; break; case SSL3_ST_SW_SRVR_HELLO_A: case SSL3_ST_SW_SRVR_HELLO_B: - ret = ssl3_send_server_hello(s); + ret = ssl3_send_server_hello(ssl); if (ret <= 0) { goto end; } - if (s->hit) { - if (s->tlsext_ticket_expected) { - s->state = SSL3_ST_SW_SESSION_TICKET_A; + if (ssl->hit) { + if (ssl->tlsext_ticket_expected) { + ssl->state = SSL3_ST_SW_SESSION_TICKET_A; } else { - s->state = SSL3_ST_SW_CHANGE_A; + ssl->state = SSL3_ST_SW_CHANGE_A; } } else { - s->state = SSL3_ST_SW_CERT_A; + ssl->state = SSL3_ST_SW_CERT_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: - if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { - ret = ssl3_send_server_certificate(s); + if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) { + ret = ssl3_send_server_certificate(ssl); if (ret <= 0) { goto end; } - if (s->s3->tmp.certificate_status_expected) { - s->state = SSL3_ST_SW_CERT_STATUS_A; + if (ssl->s3->tmp.certificate_status_expected) { + ssl->state = SSL3_ST_SW_CERT_STATUS_A; } else { - s->state = SSL3_ST_SW_KEY_EXCH_A; + ssl->state = SSL3_ST_SW_KEY_EXCH_A; } } else { skip = 1; - s->state = SSL3_ST_SW_KEY_EXCH_A; + ssl->state = SSL3_ST_SW_KEY_EXCH_A; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_SW_CERT_STATUS_A: case SSL3_ST_SW_CERT_STATUS_B: - ret = ssl3_send_certificate_status(s); + ret = ssl3_send_certificate_status(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_KEY_EXCH_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_KEY_EXCH_A; + ssl->init_num = 0; break; case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: case SSL3_ST_SW_KEY_EXCH_C: - alg_a = s->s3->tmp.new_cipher->algorithm_auth; + alg_a = ssl->s3->tmp.new_cipher->algorithm_auth; /* Send a ServerKeyExchange message if: * - The key exchange is ephemeral or anonymous @@ -330,9 +330,9 @@ int ssl3_accept(SSL *s) { * * TODO(davidben): This logic is currently duplicated in d1_srvr.c. Fix * this. In the meantime, keep them in sync. */ - if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher) || - ((alg_a & SSL_aPSK) && s->psk_identity_hint)) { - ret = ssl3_send_server_key_exchange(s); + if (ssl_cipher_requires_server_key_exchange(ssl->s3->tmp.new_cipher) || + ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) { + ret = ssl3_send_server_key_exchange(ssl); if (ret <= 0) { goto end; } @@ -340,33 +340,33 @@ int ssl3_accept(SSL *s) { skip = 1; } - s->state = SSL3_ST_SW_CERT_REQ_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_CERT_REQ_A; + ssl->init_num = 0; break; case SSL3_ST_SW_CERT_REQ_A: case SSL3_ST_SW_CERT_REQ_B: - if (s->s3->tmp.cert_request) { - ret = ssl3_send_certificate_request(s); + if (ssl->s3->tmp.cert_request) { + ret = ssl3_send_certificate_request(ssl); if (ret <= 0) { goto end; } } else { skip = 1; } - s->state = SSL3_ST_SW_SRVR_DONE_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_SRVR_DONE_A; + ssl->init_num = 0; break; case SSL3_ST_SW_SRVR_DONE_A: case SSL3_ST_SW_SRVR_DONE_B: - ret = ssl3_send_server_done(s); + ret = ssl3_send_server_done(ssl); if (ret <= 0) { goto end; } - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; + ssl->s3->tmp.next_state = SSL3_ST_SR_CERT_A; + ssl->state = SSL3_ST_SW_FLUSH; + ssl->init_num = 0; break; case SSL3_ST_SW_FLUSH: @@ -375,151 +375,149 @@ int ssl3_accept(SSL *s) { * in PR#1939. The proposed fix doesn't completely resolve this issue * as buggy implementations of BIO_CTRL_PENDING still exist. So instead * we just flush unconditionally. */ - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { + ssl->rwstate = SSL_WRITING; + if (BIO_flush(ssl->wbio) <= 0) { ret = -1; goto end; } - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; + ssl->state = ssl->s3->tmp.next_state; break; case SSL3_ST_SR_CERT_A: case SSL3_ST_SR_CERT_B: - if (s->s3->tmp.cert_request) { - ret = ssl3_get_client_certificate(s); + if (ssl->s3->tmp.cert_request) { + ret = ssl3_get_client_certificate(ssl); if (ret <= 0) { goto end; } } - s->init_num = 0; - s->state = SSL3_ST_SR_KEY_EXCH_A; + ssl->init_num = 0; + ssl->state = SSL3_ST_SR_KEY_EXCH_A; break; case SSL3_ST_SR_KEY_EXCH_A: case SSL3_ST_SR_KEY_EXCH_B: case SSL3_ST_SR_KEY_EXCH_C: - ret = ssl3_get_client_key_exchange(s); + ret = ssl3_get_client_key_exchange(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; + ssl->state = SSL3_ST_SR_CERT_VRFY_A; + ssl->init_num = 0; break; case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: - ret = ssl3_get_cert_verify(s); + ret = ssl3_get_cert_verify(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SR_CHANGE; - s->init_num = 0; + ssl->state = SSL3_ST_SR_CHANGE; + ssl->init_num = 0; break; - case SSL3_ST_SR_CHANGE: { - char next_proto_neg = 0; - char channel_id = 0; - next_proto_neg = s->s3->next_proto_neg_seen; - channel_id = s->s3->tlsext_channel_id_valid; + case SSL3_ST_SR_CHANGE: + ret = ssl->method->ssl_read_change_cipher_spec(ssl); + if (ret <= 0) { + goto end; + } - /* At this point, the next message must be entirely behind a - * ChangeCipherSpec. */ - if (!ssl3_expect_change_cipher_spec(s)) { + if (!ssl3_do_change_cipher_spec(ssl)) { ret = -1; goto end; } - if (next_proto_neg) { - s->state = SSL3_ST_SR_NEXT_PROTO_A; - } else if (channel_id) { - s->state = SSL3_ST_SR_CHANNEL_ID_A; + + if (ssl->s3->next_proto_neg_seen) { + ssl->state = SSL3_ST_SR_NEXT_PROTO_A; + } else if (ssl->s3->tlsext_channel_id_valid) { + ssl->state = SSL3_ST_SR_CHANNEL_ID_A; } else { - s->state = SSL3_ST_SR_FINISHED_A; + ssl->state = SSL3_ST_SR_FINISHED_A; } break; - } case SSL3_ST_SR_NEXT_PROTO_A: case SSL3_ST_SR_NEXT_PROTO_B: - ret = ssl3_get_next_proto(s); + ret = ssl3_get_next_proto(ssl); if (ret <= 0) { goto end; } - s->init_num = 0; - if (s->s3->tlsext_channel_id_valid) { - s->state = SSL3_ST_SR_CHANNEL_ID_A; + ssl->init_num = 0; + if (ssl->s3->tlsext_channel_id_valid) { + ssl->state = SSL3_ST_SR_CHANNEL_ID_A; } else { - s->state = SSL3_ST_SR_FINISHED_A; + ssl->state = SSL3_ST_SR_FINISHED_A; } break; case SSL3_ST_SR_CHANNEL_ID_A: case SSL3_ST_SR_CHANNEL_ID_B: - ret = ssl3_get_channel_id(s); + ret = ssl3_get_channel_id(ssl); if (ret <= 0) { goto end; } - s->init_num = 0; - s->state = SSL3_ST_SR_FINISHED_A; + ssl->init_num = 0; + ssl->state = SSL3_ST_SR_FINISHED_A; break; case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: - ret = - ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); + ret = ssl3_get_finished(ssl, SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); if (ret <= 0) { goto end; } - if (s->hit) { - s->state = SSL_ST_OK; - } else if (s->tlsext_ticket_expected) { - s->state = SSL3_ST_SW_SESSION_TICKET_A; + if (ssl->hit) { + ssl->state = SSL_ST_OK; + } else if (ssl->tlsext_ticket_expected) { + ssl->state = SSL3_ST_SW_SESSION_TICKET_A; } else { - s->state = SSL3_ST_SW_CHANGE_A; + ssl->state = SSL3_ST_SW_CHANGE_A; } /* If this is a full handshake with ChannelID then record the hashshake - * hashes in |s->session| in case we need them to verify a ChannelID + * hashes in |ssl->session| in case we need them to verify a ChannelID * signature on a resumption of this session in the future. */ - if (!s->hit && s->s3->tlsext_channel_id_valid) { - ret = tls1_record_handshake_hashes_for_channel_id(s); + if (!ssl->hit && ssl->s3->tlsext_channel_id_valid) { + ret = tls1_record_handshake_hashes_for_channel_id(ssl); if (ret <= 0) { goto end; } } - s->init_num = 0; + ssl->init_num = 0; break; case SSL3_ST_SW_SESSION_TICKET_A: case SSL3_ST_SW_SESSION_TICKET_B: - ret = ssl3_send_new_session_ticket(s); + ret = ssl3_send_new_session_ticket(ssl); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_CHANGE_A; + ssl->init_num = 0; break; case SSL3_ST_SW_CHANGE_A: case SSL3_ST_SW_CHANGE_B: - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->enc_method->setup_key_block(s)) { + ssl->session->cipher = ssl->s3->tmp.new_cipher; + if (!ssl->enc_method->setup_key_block(ssl)) { ret = -1; goto end; } - ret = ssl3_send_change_cipher_spec(s, SSL3_ST_SW_CHANGE_A, + ret = ssl3_send_change_cipher_spec(ssl, SSL3_ST_SW_CHANGE_A, SSL3_ST_SW_CHANGE_B); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_FINISHED_A; - s->init_num = 0; + ssl->state = SSL3_ST_SW_FINISHED_A; + ssl->init_num = 0; - if (!s->enc_method->change_cipher_state( - s, SSL3_CHANGE_CIPHER_SERVER_WRITE)) { + if (!ssl->enc_method->change_cipher_state( + ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) { ret = -1; goto end; } @@ -527,49 +525,49 @@ int ssl3_accept(SSL *s) { case SSL3_ST_SW_FINISHED_A: case SSL3_ST_SW_FINISHED_B: - ret = - ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A, SSL3_ST_SW_FINISHED_B, - s->enc_method->server_finished_label, - s->enc_method->server_finished_label_len); + ret = ssl3_send_finished(ssl, SSL3_ST_SW_FINISHED_A, + SSL3_ST_SW_FINISHED_B, + ssl->enc_method->server_finished_label, + ssl->enc_method->server_finished_label_len); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_FLUSH; - if (s->hit) { - s->s3->tmp.next_state = SSL3_ST_SR_CHANGE; + ssl->state = SSL3_ST_SW_FLUSH; + if (ssl->hit) { + ssl->s3->tmp.next_state = SSL3_ST_SR_CHANGE; } else { - s->s3->tmp.next_state = SSL_ST_OK; + ssl->s3->tmp.next_state = SSL_ST_OK; } - s->init_num = 0; + ssl->init_num = 0; break; case SSL_ST_OK: /* clean a few things up */ - ssl3_cleanup_key_block(s); + ssl3_cleanup_key_block(ssl); - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; + BUF_MEM_free(ssl->init_buf); + ssl->init_buf = NULL; /* remove buffering on output */ - ssl_free_wbio_buffer(s); + ssl_free_wbio_buffer(ssl); - s->init_num = 0; + ssl->init_num = 0; /* If we aren't retaining peer certificates then we can discard it * now. */ - if (s->ctx->retain_only_sha256_of_client_certs) { - X509_free(s->session->peer); - s->session->peer = NULL; - sk_X509_pop_free(s->session->cert_chain, X509_free); - s->session->cert_chain = NULL; + if (ssl->ctx->retain_only_sha256_of_client_certs) { + X509_free(ssl->session->peer); + ssl->session->peer = NULL; + sk_X509_pop_free(ssl->session->cert_chain, X509_free); + ssl->session->cert_chain = NULL; } - s->s3->initial_handshake_complete = 1; + ssl->s3->initial_handshake_complete = 1; - ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + ssl_update_cache(ssl, SSL_SESS_CACHE_SERVER); if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_DONE, 1); + cb(ssl, SSL_CB_HANDSHAKE_DONE, 1); } ret = 1; @@ -581,34 +579,35 @@ int ssl3_accept(SSL *s) { goto end; } - if (!s->s3->tmp.reuse_message && !skip && cb != NULL && s->state != state) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; + if (!ssl->s3->tmp.reuse_message && !skip && cb != NULL && + ssl->state != state) { + new_state = ssl->state; + ssl->state = state; + cb(ssl, SSL_CB_ACCEPT_LOOP, 1); + ssl->state = new_state; } skip = 0; } end: - s->in_handshake--; + ssl->in_handshake--; BUF_MEM_free(buf); if (cb != NULL) { - cb(s, SSL_CB_ACCEPT_EXIT, ret); + cb(ssl, SSL_CB_ACCEPT_EXIT, ret); } return ret; } -int ssl3_get_initial_bytes(SSL *s) { +int ssl3_get_initial_bytes(SSL *ssl) { /* Read the first 5 bytes, the size of the TLS record header. This is * sufficient to detect a V2ClientHello and ensures that we never read beyond * the first record. */ - int ret = ssl_read_buffer_extend_to(s, SSL3_RT_HEADER_LENGTH); + int ret = ssl_read_buffer_extend_to(ssl, SSL3_RT_HEADER_LENGTH); if (ret <= 0) { return ret; } - assert(ssl_read_buffer_len(s) == SSL3_RT_HEADER_LENGTH); - const uint8_t *p = ssl_read_buffer(s); + assert(ssl_read_buffer_len(ssl) == SSL3_RT_HEADER_LENGTH); + const uint8_t *p = ssl_read_buffer(ssl); /* Some dedicated error codes for protocol mixups should the application wish * to interpret them differently. (These do not overlap with ClientHello or @@ -629,16 +628,16 @@ int ssl3_get_initial_bytes(SSL *s) { if ((p[0] & 0x80) && p[2] == SSL2_MT_CLIENT_HELLO && p[3] >= SSL3_VERSION_MAJOR) { /* This is a V2ClientHello. */ - s->state = SSL3_ST_SR_V2_CLIENT_HELLO; + ssl->state = SSL3_ST_SR_V2_CLIENT_HELLO; return 1; } /* Fall through to the standard logic. */ - s->state = SSL3_ST_SR_CLNT_HELLO_A; + ssl->state = SSL3_ST_SR_CLNT_HELLO_A; return 1; } -int ssl3_get_v2_client_hello(SSL *s) { +int ssl3_get_v2_client_hello(SSL *ssl) { const uint8_t *p; int ret; CBS v2_client_hello, cipher_specs, session_id, challenge; @@ -649,8 +648,8 @@ int ssl3_get_v2_client_hello(SSL *s) { uint8_t random[SSL3_RANDOM_SIZE]; /* Determine the length of the V2ClientHello. */ - assert(ssl_read_buffer_len(s) >= SSL3_RT_HEADER_LENGTH); - p = ssl_read_buffer(s); + assert(ssl_read_buffer_len(ssl) >= SSL3_RT_HEADER_LENGTH); + p = ssl_read_buffer(ssl); msg_length = ((p[0] & 0x7f) << 8) | p[1]; if (msg_length > (1024 * 4)) { OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); @@ -665,22 +664,22 @@ int ssl3_get_v2_client_hello(SSL *s) { } /* Read the remainder of the V2ClientHello. */ - ret = ssl_read_buffer_extend_to(s, 2 + msg_length); + ret = ssl_read_buffer_extend_to(ssl, 2 + msg_length); if (ret <= 0) { return ret; } - assert(ssl_read_buffer_len(s) == msg_length + 2); - CBS_init(&v2_client_hello, ssl_read_buffer(s) + 2, msg_length); + assert(ssl_read_buffer_len(ssl) == msg_length + 2); + CBS_init(&v2_client_hello, ssl_read_buffer(ssl) + 2, msg_length); /* The V2ClientHello without the length is incorporated into the handshake * hash. */ - if (!ssl3_update_handshake_hash(s, CBS_data(&v2_client_hello), + if (!ssl3_update_handshake_hash(ssl, CBS_data(&v2_client_hello), CBS_len(&v2_client_hello))) { return -1; } - if (s->msg_callback) { - s->msg_callback(0, SSL2_VERSION, 0, CBS_data(&v2_client_hello), - CBS_len(&v2_client_hello), s, s->msg_callback_arg); + if (ssl->msg_callback) { + ssl->msg_callback(0, SSL2_VERSION, 0, CBS_data(&v2_client_hello), + CBS_len(&v2_client_hello), ssl, ssl->msg_callback_arg); } if (!CBS_get_u8(&v2_client_hello, &msg_type) || @@ -711,8 +710,8 @@ int ssl3_get_v2_client_hello(SSL *s) { /* Write out an equivalent SSLv3 ClientHello. */ CBB_zero(&client_hello); - if (!CBB_init_fixed(&client_hello, (uint8_t *)s->init_buf->data, - s->init_buf->max) || + if (!CBB_init_fixed(&client_hello, (uint8_t *)ssl->init_buf->data, + ssl->init_buf->max) || !CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) || !CBB_add_u24_length_prefixed(&client_hello, &hello_body) || !CBB_add_u16(&hello_body, version) || @@ -754,19 +753,19 @@ int ssl3_get_v2_client_hello(SSL *s) { } /* Mark the message for "re"-use by the version-specific method. */ - s->s3->tmp.reuse_message = 1; - s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO; + ssl->s3->tmp.reuse_message = 1; + ssl->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO; /* The handshake message header is 4 bytes. */ - s->s3->tmp.message_size = len - 4; + ssl->s3->tmp.message_size = len - 4; /* Consume and discard the V2ClientHello. */ - ssl_read_buffer_consume(s, 2 + msg_length); - ssl_read_buffer_discard(s); + ssl_read_buffer_consume(ssl, 2 + msg_length); + ssl_read_buffer_discard(ssl); return 1; } -int ssl3_get_client_hello(SSL *s) { +int ssl3_get_client_hello(SSL *ssl) { int ok, al = SSL_AD_INTERNAL_ERROR, ret = -1; long n; const SSL_CIPHER *c; @@ -781,11 +780,11 @@ int ssl3_get_client_hello(SSL *s) { * and we get SSLv3, we will respond with TLSv1, This down switching should * be handled by a different method. If we are SSLv3, we will respond with * SSLv3, even if prompted with TLSv1. */ - switch (s->state) { + switch (ssl->state) { case SSL3_ST_SR_CLNT_HELLO_A: case SSL3_ST_SR_CLNT_HELLO_B: - n = s->method->ssl_get_message( - s, SSL3_ST_SR_CLNT_HELLO_A, SSL3_ST_SR_CLNT_HELLO_B, + n = ssl->method->ssl_get_message( + ssl, SSL3_ST_SR_CLNT_HELLO_A, SSL3_ST_SR_CLNT_HELLO_B, SSL3_MT_CLIENT_HELLO, SSL3_RT_MAX_PLAIN_LENGTH, ssl_hash_message, &ok); @@ -793,18 +792,18 @@ int ssl3_get_client_hello(SSL *s) { return n; } - s->state = SSL3_ST_SR_CLNT_HELLO_C; + ssl->state = SSL3_ST_SR_CLNT_HELLO_C; /* fallthrough */ case SSL3_ST_SR_CLNT_HELLO_C: case SSL3_ST_SR_CLNT_HELLO_D: /* We have previously parsed the ClientHello message, and can't call * ssl_get_message again without hashing the message into the Finished * digest again. */ - n = s->init_num; + n = ssl->init_num; memset(&early_ctx, 0, sizeof(early_ctx)); - early_ctx.ssl = s; - early_ctx.client_hello = s->init_msg; + early_ctx.ssl = ssl; + early_ctx.client_hello = ssl->init_msg; early_ctx.client_hello_len = n; if (!ssl_early_callback_init(&early_ctx)) { al = SSL_AD_DECODE_ERROR; @@ -812,12 +811,12 @@ int ssl3_get_client_hello(SSL *s) { goto f_err; } - if (s->state == SSL3_ST_SR_CLNT_HELLO_C && - s->ctx->select_certificate_cb != NULL) { - s->state = SSL3_ST_SR_CLNT_HELLO_D; - switch (s->ctx->select_certificate_cb(&early_ctx)) { + if (ssl->state == SSL3_ST_SR_CLNT_HELLO_C && + ssl->ctx->select_certificate_cb != NULL) { + ssl->state = SSL3_ST_SR_CLNT_HELLO_D; + switch (ssl->ctx->select_certificate_cb(&early_ctx)) { case 0: - s->rwstate = SSL_CERTIFICATE_SELECTION_PENDING; + ssl->rwstate = SSL_CERTIFICATE_SELECTION_PENDING; goto err; case -1: @@ -830,7 +829,7 @@ int ssl3_get_client_hello(SSL *s) { /* fallthrough */; } } - s->state = SSL3_ST_SR_CLNT_HELLO_D; + ssl->state = SSL3_ST_SR_CLNT_HELLO_D; break; default: @@ -838,7 +837,7 @@ int ssl3_get_client_hello(SSL *s) { return -1; } - CBS_init(&client_hello, s->init_msg, n); + CBS_init(&client_hello, ssl->init_msg, n); if (!CBS_get_u16(&client_hello, &client_version) || !CBS_get_bytes(&client_hello, &client_random, SSL3_RANDOM_SIZE) || !CBS_get_u8_length_prefixed(&client_hello, &session_id) || @@ -850,12 +849,12 @@ int ssl3_get_client_hello(SSL *s) { /* use version from inside client hello, not from record header (may differ: * see RFC 2246, Appendix E, second paragraph) */ - s->client_version = client_version; + ssl->client_version = client_version; /* Load the client random. */ - memcpy(s->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE); + memcpy(ssl->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE); - if (SSL_IS_DTLS(s)) { + if (SSL_IS_DTLS(ssl)) { CBS cookie; if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) || @@ -871,40 +870,40 @@ int ssl3_get_client_hello(SSL *s) { * * TODO(davidben): Clean up the order of events around ClientHello * processing. */ - if (!s->s3->have_version) { + if (!ssl->s3->have_version) { /* Select version to use */ - uint16_t version = ssl3_get_mutual_version(s, client_version); + uint16_t version = ssl3_get_mutual_version(ssl, client_version); if (version == 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL); - s->version = s->client_version; + ssl->version = ssl->client_version; al = SSL_AD_PROTOCOL_VERSION; goto f_err; } - s->version = version; - s->enc_method = ssl3_get_enc_method(version); - assert(s->enc_method != NULL); - /* At this point, the connection's version is known and |s->version| is + ssl->version = version; + ssl->enc_method = ssl3_get_enc_method(version); + assert(ssl->enc_method != NULL); + /* At this point, the connection's version is known and |ssl->version| is * fixed. Begin enforcing the record-layer version. */ - s->s3->have_version = 1; - } else if (SSL_IS_DTLS(s) ? (s->client_version > s->version) - : (s->client_version < s->version)) { + ssl->s3->have_version = 1; + } else if (SSL_IS_DTLS(ssl) ? (ssl->client_version > ssl->version) + : (ssl->client_version < ssl->version)) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER); al = SSL_AD_PROTOCOL_VERSION; goto f_err; } - s->hit = 0; + ssl->hit = 0; int send_new_ticket = 0; - switch (ssl_get_prev_session(s, &session, &send_new_ticket, &early_ctx)) { + switch (ssl_get_prev_session(ssl, &session, &send_new_ticket, &early_ctx)) { case ssl_session_success: break; case ssl_session_error: goto err; case ssl_session_retry: - s->rwstate = SSL_PENDING_SESSION; + ssl->rwstate = SSL_PENDING_SESSION; goto err; } - s->tlsext_ticket_expected = send_new_ticket; + ssl->tlsext_ticket_expected = send_new_ticket; /* The EMS state is needed when making the resumption decision, but * extensions are not normally parsed until later. This detects the EMS @@ -913,7 +912,7 @@ int ssl3_get_client_hello(SSL *s) { const uint8_t *ems_data; size_t ems_len; int have_extended_master_secret = - s->version != SSL3_VERSION && + ssl->version != SSL3_VERSION && SSL_early_callback_ctx_extension_get(&early_ctx, TLSEXT_TYPE_extended_master_secret, &ems_data, &ems_len) && @@ -929,34 +928,35 @@ int ssl3_get_client_hello(SSL *s) { goto f_err; } - s->hit = + ssl->hit = /* Only resume if the session's version matches the negotiated version: * most clients do not accept a mismatch. */ - s->version == session->ssl_version && + ssl->version == session->ssl_version && /* If the client offers the EMS extension, but the previous session * didn't use it, then negotiate a new session. */ have_extended_master_secret == session->extended_master_secret; } - if (s->hit) { + if (ssl->hit) { /* Use the new session. */ - SSL_SESSION_free(s->session); - s->session = session; + SSL_SESSION_free(ssl->session); + ssl->session = session; session = NULL; - s->verify_result = s->session->verify_result; + ssl->verify_result = ssl->session->verify_result; } else { - if (!ssl_get_new_session(s, 1 /* server */)) { + if (!ssl_get_new_session(ssl, 1 /* server */)) { goto err; } /* Clear the session ID if we want the session to be single-use. */ - if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) { - s->session->session_id_length = 0; + if (!(ssl->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) { + ssl->session->session_id_length = 0; } } - if (s->ctx->dos_protection_cb != NULL && s->ctx->dos_protection_cb(&early_ctx) == 0) { + if (ssl->ctx->dos_protection_cb != NULL && + ssl->ctx->dos_protection_cb(&early_ctx) == 0) { /* Connection rejected for DOS reasons. */ al = SSL_AD_ACCESS_DENIED; OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); @@ -973,16 +973,16 @@ int ssl3_get_client_hello(SSL *s) { goto f_err; } - ciphers = ssl_bytes_to_cipher_list(s, &cipher_suites); + ciphers = ssl_bytes_to_cipher_list(ssl, &cipher_suites); if (ciphers == NULL) { goto err; } /* If it is a hit, check that the cipher is in the list. */ - if (s->hit) { + if (ssl->hit) { size_t j; int found_cipher = 0; - uint32_t id = s->session->cipher->id; + uint32_t id = ssl->session->cipher->id; for (j = 0; j < sk_SSL_CIPHER_num(ciphers); j++) { c = sk_SSL_CIPHER_value(ciphers, j); @@ -1010,8 +1010,8 @@ int ssl3_get_client_hello(SSL *s) { } /* TLS extensions. */ - if (s->version >= SSL3_VERSION && - !ssl_parse_clienthello_tlsext(s, &client_hello)) { + if (ssl->version >= SSL3_VERSION && + !ssl_parse_clienthello_tlsext(ssl, &client_hello)) { OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); goto err; } @@ -1024,14 +1024,14 @@ int ssl3_get_client_hello(SSL *s) { goto f_err; } - if (have_extended_master_secret != s->s3->tmp.extended_master_secret) { + if (have_extended_master_secret != ssl->s3->tmp.extended_master_secret) { al = SSL_AD_INTERNAL_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_EMS_STATE_INCONSISTENT); goto f_err; } /* Given ciphers and SSL_get_ciphers, we must pick a cipher */ - if (!s->hit) { + if (!ssl->hit) { if (ciphers == NULL) { al = SSL_AD_ILLEGAL_PARAMETER; OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_PASSED); @@ -1039,54 +1039,54 @@ int ssl3_get_client_hello(SSL *s) { } /* Let cert callback update server certificates if required */ - if (s->cert->cert_cb) { - int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); + if (ssl->cert->cert_cb) { + int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); if (rv == 0) { al = SSL_AD_INTERNAL_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); goto f_err; } if (rv < 0) { - s->rwstate = SSL_X509_LOOKUP; + ssl->rwstate = SSL_X509_LOOKUP; goto err; } - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; } - c = ssl3_choose_cipher(s, ciphers, ssl_get_cipher_preferences(s)); + c = ssl3_choose_cipher(ssl, ciphers, ssl_get_cipher_preferences(ssl)); if (c == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER); goto f_err; } - s->s3->tmp.new_cipher = c; + ssl->s3->tmp.new_cipher = c; /* Determine whether to request a client certificate. */ - s->s3->tmp.cert_request = !!(s->verify_mode & SSL_VERIFY_PEER); + ssl->s3->tmp.cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER); /* Only request a certificate if Channel ID isn't negotiated. */ - if ((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && - s->s3->tlsext_channel_id_valid) { - s->s3->tmp.cert_request = 0; + if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && + ssl->s3->tlsext_channel_id_valid) { + ssl->s3->tmp.cert_request = 0; } /* Plain PSK forbids Certificate and CertificateRequest. */ - if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) { - s->s3->tmp.cert_request = 0; + if (ssl->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) { + ssl->s3->tmp.cert_request = 0; } } else { /* Session-id reuse */ - s->s3->tmp.new_cipher = s->session->cipher; - s->s3->tmp.cert_request = 0; + ssl->s3->tmp.new_cipher = ssl->session->cipher; + ssl->s3->tmp.cert_request = 0; } /* Now that the cipher is known, initialize the handshake hash. */ - if (!ssl3_init_handshake_hash(s)) { + if (!ssl3_init_handshake_hash(ssl)) { goto f_err; } /* In TLS 1.2, client authentication requires hashing the handshake transcript * under a different hash. Otherwise, release the handshake buffer. */ - if (!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) { - ssl3_free_handshake_buffer(s); + if (!SSL_USE_SIGALGS(ssl) || !ssl->s3->tmp.cert_request) { + ssl3_free_handshake_buffer(ssl); } /* we now have the following setup; @@ -1095,17 +1095,15 @@ int ssl3_get_client_hello(SSL *s) { * ciphers - the clients prefered list of ciphers * compression - basically ignored right now * ssl version is set - sslv3 - * s->session - The ssl session has been setup. - * s->hit - session reuse flag - * s->tmp.new_cipher - the new cipher to use. */ + * ssl->session - The ssl session has been setup. + * ssl->hit - session reuse flag + * ssl->tmp.new_cipher - the new cipher to use. */ - if (ret < 0) { - ret = -ret; - } + ret = 1; if (0) { f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); } err: @@ -1191,324 +1189,203 @@ int ssl3_send_certificate_status(SSL *ssl) { return ssl_do_write(ssl); } -int ssl3_send_server_done(SSL *s) { - if (s->state == SSL3_ST_SW_SRVR_DONE_A) { - if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) { +int ssl3_send_server_done(SSL *ssl) { + if (ssl->state == SSL3_ST_SW_SRVR_DONE_A) { + if (!ssl_set_handshake_header(ssl, SSL3_MT_SERVER_DONE, 0)) { return -1; } - s->state = SSL3_ST_SW_SRVR_DONE_B; + ssl->state = SSL3_ST_SW_SRVR_DONE_B; } /* SSL3_ST_SW_SRVR_DONE_B */ - return ssl_do_write(s); + return ssl_do_write(ssl); } -int ssl3_send_server_key_exchange(SSL *s) { - DH *dh = NULL, *dhp; - EC_KEY *ecdh = NULL; - uint8_t *encodedPoint = NULL; - int encodedlen = 0; - uint16_t curve_id = 0; - BN_CTX *bn_ctx = NULL; - const char *psk_identity_hint = NULL; - size_t psk_identity_hint_len = 0; - size_t sig_len; - size_t max_sig_len; - uint8_t *p, *d; - int al, i; - uint32_t alg_k; - uint32_t alg_a; - int n; - CERT *cert; - BIGNUM *r[4]; - int nr[4]; - BUF_MEM *buf; - EVP_MD_CTX md_ctx; - - if (s->state == SSL3_ST_SW_KEY_EXCH_C) { - return ssl_do_write(s); +int ssl3_send_server_key_exchange(SSL *ssl) { + if (ssl->state == SSL3_ST_SW_KEY_EXCH_C) { + return ssl_do_write(ssl); } - if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { - if (!ssl_has_private_key(s)) { - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - max_sig_len = ssl_private_key_max_signature_len(s); - } else { - max_sig_len = 0; + CBB cbb, child; + if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl), + ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl))) { + goto err; } - EVP_MD_CTX_init(&md_ctx); - enum ssl_private_key_result_t sign_result; - if (s->state == SSL3_ST_SW_KEY_EXCH_A) { - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - cert = s->cert; + if (ssl->state == SSL3_ST_SW_KEY_EXCH_A) { + /* This is the first iteration, so write parameters. */ + uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey; + uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth; - buf = s->init_buf; - - r[0] = r[1] = r[2] = r[3] = NULL; - n = 0; + /* PSK ciphers begin with an identity hint. */ if (alg_a & SSL_aPSK) { - /* size for PSK identity hint */ - psk_identity_hint = s->psk_identity_hint; - if (psk_identity_hint) { - psk_identity_hint_len = strlen(psk_identity_hint); - } else { - psk_identity_hint_len = 0; + size_t len = + (ssl->psk_identity_hint == NULL) ? 0 : strlen(ssl->psk_identity_hint); + if (!CBB_add_u16_length_prefixed(&cbb, &child) || + !CBB_add_bytes(&child, (const uint8_t *)ssl->psk_identity_hint, + len)) { + goto err; } - n += 2 + psk_identity_hint_len; } if (alg_k & SSL_kDHE) { - dhp = cert->dh_tmp; - if (dhp == NULL && s->cert->dh_tmp_cb != NULL) { - dhp = s->cert->dh_tmp_cb(s, 0, 1024); + /* Determine the group to use. */ + DH *params = ssl->cert->dh_tmp; + if (params == NULL && ssl->cert->dh_tmp_cb != NULL) { + params = ssl->cert->dh_tmp_cb(ssl, 0, 1024); } - if (dhp == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; + if (params == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY); - goto f_err; - } - - if (s->s3->tmp.dh != NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); goto err; } - dh = DHparams_dup(dhp); + ssl->session->key_exchange_info = DH_num_bits(params); + + /* Set up DH, generate a key, and emit the public half. */ + DH *dh = DHparams_dup(params); if (dh == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); goto err; } - s->s3->tmp.dh = dh; - if (!DH_generate_key(dh)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); + SSL_ECDH_CTX_init_for_dhe(&ssl->s3->tmp.ecdh_ctx, dh); + if (!CBB_add_u16_length_prefixed(&cbb, &child) || + !BN_bn2cbb_padded(&child, BN_num_bytes(params->p), params->p) || + !CBB_add_u16_length_prefixed(&cbb, &child) || + !BN_bn2cbb_padded(&child, BN_num_bytes(params->g), params->g) || + !CBB_add_u16_length_prefixed(&cbb, &child) || + !SSL_ECDH_CTX_generate_keypair(&ssl->s3->tmp.ecdh_ctx, &child)) { goto err; } - - r[0] = dh->p; - r[1] = dh->g; - r[2] = dh->pub_key; } else if (alg_k & SSL_kECDHE) { /* Determine the curve to use. */ - int nid = NID_undef; - if (cert->ecdh_nid != NID_undef) { - nid = cert->ecdh_nid; - } else if (cert->ecdh_tmp_cb != NULL) { - /* Note: |ecdh_tmp_cb| does NOT pass ownership of the result - * to the caller. */ - EC_KEY *template = s->cert->ecdh_tmp_cb(s, 0, 1024); - if (template != NULL && EC_KEY_get0_group(template) != NULL) { - nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(template)); - } - } else { - nid = tls1_get_shared_curve(s); - } - if (nid == NID_undef) { - al = SSL_AD_HANDSHAKE_FAILURE; + uint16_t curve_id; + if (!tls1_get_shared_curve(ssl, &curve_id)) { OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_ECDH_KEY); - goto f_err; - } - - if (s->s3->tmp.ecdh != NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } - ecdh = EC_KEY_new_by_curve_name(nid); - if (ecdh == NULL) { - goto err; - } - s->s3->tmp.ecdh = ecdh; - - if (!EC_KEY_generate_key(ecdh)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); - goto err; - } - - /* We only support ephemeral ECDH keys over named (not generic) curves. */ - const EC_GROUP *group = EC_KEY_get0_group(ecdh); - if (!tls1_ec_nid2curve_id(&curve_id, EC_GROUP_get_curve_name(group))) { - OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); goto err; } - - /* Encode the public key. First check the size of encoding and allocate - * memory accordingly. */ - encodedlen = - EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), - POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); - - encodedPoint = (uint8_t *)OPENSSL_malloc(encodedlen * sizeof(uint8_t)); - bn_ctx = BN_CTX_new(); - if (encodedPoint == NULL || bn_ctx == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } - - encodedlen = EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), - POINT_CONVERSION_UNCOMPRESSED, - encodedPoint, encodedlen, bn_ctx); - - if (encodedlen == 0) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); + ssl->session->key_exchange_info = curve_id; + + /* Set up ECDH, generate a key, and emit the public half. */ + if (!SSL_ECDH_CTX_init(&ssl->s3->tmp.ecdh_ctx, curve_id) || + !CBB_add_u8(&cbb, NAMED_CURVE_TYPE) || + !CBB_add_u16(&cbb, curve_id) || + !CBB_add_u8_length_prefixed(&cbb, &child) || + !SSL_ECDH_CTX_generate_keypair(&ssl->s3->tmp.ecdh_ctx, &child)) { goto err; } - - BN_CTX_free(bn_ctx); - bn_ctx = NULL; - - /* We only support named (not generic) curves in ECDH ephemeral key - * exchanges. In this situation, we need four additional bytes to encode - * the entire ServerECDHParams structure. */ - n += 4 + encodedlen; - - /* We'll generate the serverKeyExchange message explicitly so we can set - * these to NULLs */ - r[0] = NULL; - r[1] = NULL; - r[2] = NULL; - r[3] = NULL; - } else if (!(alg_k & SSL_kPSK)) { - al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); - goto f_err; + } else { + assert(alg_k & SSL_kPSK); } - for (i = 0; i < 4 && r[i] != NULL; i++) { - nr[i] = BN_num_bytes(r[i]); - n += 2 + nr[i]; - } + /* Otherwise, restore |cbb| from the previous iteration. + * TODO(davidben): When |ssl->init_buf| is gone, come up with a simpler + * pattern. Probably keep the |CBB| around in the handshake state. */ + } else if (!CBB_did_write(&cbb, ssl->init_num - SSL_HM_HEADER_LENGTH(ssl))) { + goto err; + } - if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + max_sig_len)) { - OPENSSL_PUT_ERROR(SSL, ERR_LIB_BUF); + /* Add a signature. */ + if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) { + if (!ssl_has_private_key(ssl)) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); goto err; } - d = p = ssl_handshake_start(s); - - for (i = 0; i < 4 && r[i] != NULL; i++) { - s2n(nr[i], p); - BN_bn2bin(r[i], p); - p += nr[i]; - } - /* Note: ECDHE PSK ciphersuites use SSL_kECDHE and SSL_aPSK. When one of - * them is used, the server key exchange record needs to have both the - * psk_identity_hint and the ServerECDHParams. */ - if (alg_a & SSL_aPSK) { - /* copy PSK identity hint (if provided) */ - s2n(psk_identity_hint_len, p); - if (psk_identity_hint_len > 0) { - memcpy(p, psk_identity_hint, psk_identity_hint_len); - p += psk_identity_hint_len; + const size_t max_sig_len = ssl_private_key_max_signature_len(ssl); + size_t sig_len; + enum ssl_private_key_result_t sign_result; + if (ssl->state == SSL3_ST_SW_KEY_EXCH_A) { + /* This is the first iteration, so set up the signature. Sample the + * parameter length before adding a signature algorithm. */ + if (!CBB_flush(&cbb)) { + goto err; } - } - - if (alg_k & SSL_kECDHE) { - /* We only support named (not generic) curves. In this situation, the - * serverKeyExchange message has: - * [1 byte CurveType], [2 byte CurveName] - * [1 byte length of encoded point], followed by - * the actual encoded point itself. */ - *(p++) = NAMED_CURVE_TYPE; - *(p++) = (uint8_t)(curve_id >> 8); - *(p++) = (uint8_t)(curve_id & 0xff); - *(p++) = encodedlen; - memcpy(p, encodedPoint, encodedlen); - p += encodedlen; - OPENSSL_free(encodedPoint); - encodedPoint = NULL; - } - - if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { - /* n is the length of the params, they start at d and p points to - * the space at the end. */ - const EVP_MD *md; - uint8_t digest[EVP_MAX_MD_SIZE]; - unsigned int digest_length; - - const int pkey_type = ssl_private_key_type(s); + size_t params_len = CBB_len(&cbb); /* Determine signature algorithm. */ - if (SSL_USE_SIGALGS(s)) { - md = tls1_choose_signing_digest(s); - if (!tls12_get_sigandhash(s, p, md)) { - /* Should never happen */ - al = SSL_AD_INTERNAL_ERROR; + const EVP_MD *md; + if (SSL_USE_SIGALGS(ssl)) { + md = tls1_choose_signing_digest(ssl); + if (!tls12_add_sigandhash(ssl, &cbb, md)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto f_err; + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + goto err; } - p += 2; - } else if (pkey_type == EVP_PKEY_RSA) { + } else if (ssl_private_key_type(ssl) == EVP_PKEY_RSA) { md = EVP_md5_sha1(); } else { md = EVP_sha1(); } - if (!EVP_DigestInit_ex(&md_ctx, md, NULL) || - !EVP_DigestUpdate(&md_ctx, s->s3->client_random, SSL3_RANDOM_SIZE) || - !EVP_DigestUpdate(&md_ctx, s->s3->server_random, SSL3_RANDOM_SIZE) || - !EVP_DigestUpdate(&md_ctx, d, n) || - !EVP_DigestFinal_ex(&md_ctx, digest, &digest_length)) { - OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); + /* Compute the digest and sign it. */ + uint8_t digest[EVP_MAX_MD_SIZE]; + unsigned digest_len = 0; + EVP_MD_CTX md_ctx; + EVP_MD_CTX_init(&md_ctx); + int digest_ret = + EVP_DigestInit_ex(&md_ctx, md, NULL) && + EVP_DigestUpdate(&md_ctx, ssl->s3->client_random, SSL3_RANDOM_SIZE) && + EVP_DigestUpdate(&md_ctx, ssl->s3->server_random, SSL3_RANDOM_SIZE) && + EVP_DigestUpdate(&md_ctx, CBB_data(&cbb), params_len) && + EVP_DigestFinal_ex(&md_ctx, digest, &digest_len); + EVP_MD_CTX_cleanup(&md_ctx); + uint8_t *ptr; + if (!digest_ret || + !CBB_add_u16_length_prefixed(&cbb, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { goto err; } - - sign_result = ssl_private_key_sign(s, &p[2], &sig_len, max_sig_len, - EVP_MD_CTX_md(&md_ctx), digest, - digest_length); + sign_result = ssl_private_key_sign(ssl, ptr, &sig_len, max_sig_len, md, + digest, digest_len); } else { - /* This key exchange doesn't involve a signature. */ - sign_result = ssl_private_key_success; - sig_len = 0; + assert(ssl->state == SSL3_ST_SW_KEY_EXCH_B); + + /* Retry the signature. */ + uint8_t *ptr; + if (!CBB_add_u16_length_prefixed(&cbb, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { + goto err; + } + sign_result = + ssl_private_key_sign_complete(ssl, ptr, &sig_len, max_sig_len); } - } else { - assert(s->state == SSL3_ST_SW_KEY_EXCH_B); - /* Restore |p|. */ - p = ssl_handshake_start(s) + s->init_num - SSL_HM_HEADER_LENGTH(s); - sign_result = ssl_private_key_sign_complete(s, &p[2], &sig_len, - max_sig_len); - } - switch (sign_result) { - case ssl_private_key_success: - s->rwstate = SSL_NOTHING; - break; - case ssl_private_key_failure: - s->rwstate = SSL_NOTHING; - goto err; - case ssl_private_key_retry: - s->rwstate = SSL_PRIVATE_KEY_OPERATION; - /* Stash away |p|. */ - s->init_num = p - ssl_handshake_start(s) + SSL_HM_HEADER_LENGTH(s); - s->state = SSL3_ST_SW_KEY_EXCH_B; - goto err; + switch (sign_result) { + case ssl_private_key_success: + ssl->rwstate = SSL_NOTHING; + if (!CBB_did_write(&child, sig_len)) { + goto err; + } + break; + case ssl_private_key_failure: + ssl->rwstate = SSL_NOTHING; + goto err; + case ssl_private_key_retry: + /* Discard the unfinished signature and save the state of |cbb| for the + * next iteration. */ + CBB_discard_child(&cbb); + ssl->init_num = SSL_HM_HEADER_LENGTH(ssl) + CBB_len(&cbb); + ssl->rwstate = SSL_PRIVATE_KEY_OPERATION; + ssl->state = SSL3_ST_SW_KEY_EXCH_B; + goto err; + } } - if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { - s2n(sig_len, p); - p += sig_len; - } - if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, - p - ssl_handshake_start(s))) { + size_t length; + if (!CBB_finish(&cbb, NULL, &length) || + !ssl_set_handshake_header(ssl, SSL3_MT_SERVER_KEY_EXCHANGE, length)) { goto err; } - s->state = SSL3_ST_SW_KEY_EXCH_C; - - EVP_MD_CTX_cleanup(&md_ctx); - return ssl_do_write(s); + ssl->state = SSL3_ST_SW_KEY_EXCH_C; + return ssl_do_write(ssl); -f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); err: - OPENSSL_free(encodedPoint); - BN_CTX_free(bn_ctx); - EVP_MD_CTX_cleanup(&md_ctx); + CBB_cleanup(&cbb); return -1; } -int ssl3_send_certificate_request(SSL *s) { +int ssl3_send_certificate_request(SSL *ssl) { uint8_t *p, *d; size_t i; int j, nl, off, n; @@ -1516,21 +1393,21 @@ int ssl3_send_certificate_request(SSL *s) { X509_NAME *name; BUF_MEM *buf; - if (s->state == SSL3_ST_SW_CERT_REQ_A) { - buf = s->init_buf; + if (ssl->state == SSL3_ST_SW_CERT_REQ_A) { + buf = ssl->init_buf; - d = p = ssl_handshake_start(s); + d = p = ssl_handshake_start(ssl); /* get the list of acceptable cert types */ p++; - n = ssl3_get_req_cert_type(s, p); + n = ssl3_get_req_cert_type(ssl, p); d[0] = n; p += n; n++; - if (SSL_USE_SIGALGS(s)) { + if (SSL_USE_SIGALGS(ssl)) { const uint8_t *psigs; - nl = tls12_get_psigalgs(s, &psigs); + nl = tls12_get_psigalgs(ssl, &psigs); s2n(nl, p); memcpy(p, psigs, nl); p += nl; @@ -1541,17 +1418,17 @@ int ssl3_send_certificate_request(SSL *s) { p += 2; n += 2; - sk = SSL_get_client_CA_list(s); + sk = SSL_get_client_CA_list(ssl); nl = 0; if (sk != NULL) { for (i = 0; i < sk_X509_NAME_num(sk); i++) { name = sk_X509_NAME_value(sk, i); j = i2d_X509_NAME(name, NULL); - if (!BUF_MEM_grow_clean(buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) { + if (!BUF_MEM_grow_clean(buf, SSL_HM_HEADER_LENGTH(ssl) + n + j + 2)) { OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); goto err; } - p = ssl_handshake_start(s) + n; + p = ssl_handshake_start(ssl) + n; s2n(j, p); i2d_X509_NAME(name, &p); n += 2 + j; @@ -1560,33 +1437,23 @@ int ssl3_send_certificate_request(SSL *s) { } /* else no CA names */ - p = ssl_handshake_start(s) + off; + p = ssl_handshake_start(ssl) + off; s2n(nl, p); - if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n)) { + if (!ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE_REQUEST, n)) { goto err; } - s->state = SSL3_ST_SW_CERT_REQ_B; + ssl->state = SSL3_ST_SW_CERT_REQ_B; } /* SSL3_ST_SW_CERT_REQ_B */ - return ssl_do_write(s); + return ssl_do_write(ssl); err: return -1; } -static struct CRYPTO_STATIC_MUTEX g_d5_bug_lock = CRYPTO_STATIC_MUTEX_INIT; -static uint64_t g_d5_bug_use_count = 0; - -uint64_t OPENSSL_get_d5_bug_use_count(void) { - CRYPTO_STATIC_MUTEX_lock_read(&g_d5_bug_lock); - uint64_t ret = g_d5_bug_use_count; - CRYPTO_STATIC_MUTEX_unlock(&g_d5_bug_lock); - return ret; -} - -int ssl3_get_client_key_exchange(SSL *s) { +int ssl3_get_client_key_exchange(SSL *ssl) { int al; CBS client_key_exchange; uint32_t alg_k; @@ -1594,30 +1461,24 @@ int ssl3_get_client_key_exchange(SSL *s) { uint8_t *premaster_secret = NULL; size_t premaster_secret_len = 0; uint8_t *decrypt_buf = NULL; - BIGNUM *pub = NULL; - DH *dh_srvr; - - EC_KEY *srvr_ecdh = NULL; - EVP_PKEY *clnt_pub_pkey = NULL; - EC_POINT *clnt_ecpoint = NULL; - BN_CTX *bn_ctx = NULL; - unsigned int psk_len = 0; + + unsigned psk_len = 0; uint8_t psk[PSK_MAX_PSK_LEN]; - if (s->state == SSL3_ST_SR_KEY_EXCH_A || - s->state == SSL3_ST_SR_KEY_EXCH_B) { + if (ssl->state == SSL3_ST_SR_KEY_EXCH_A || + ssl->state == SSL3_ST_SR_KEY_EXCH_B) { int ok; - const long n = s->method->ssl_get_message( - s, SSL3_ST_SR_KEY_EXCH_A, SSL3_ST_SR_KEY_EXCH_B, + const long n = ssl->method->ssl_get_message( + ssl, SSL3_ST_SR_KEY_EXCH_A, SSL3_ST_SR_KEY_EXCH_B, SSL3_MT_CLIENT_KEY_EXCHANGE, 2048 /* ??? */, ssl_hash_message, &ok); if (!ok) { return n; } } - CBS_init(&client_key_exchange, s->init_msg, s->init_num); - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; + CBS_init(&client_key_exchange, ssl->init_msg, ssl->init_num); + alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey; + alg_a = ssl->s3->tmp.new_cipher->algorithm_auth; /* If using a PSK key exchange, prepare the pre-shared key. */ if (alg_a & SSL_aPSK) { @@ -1632,7 +1493,7 @@ int ssl3_get_client_key_exchange(SSL *s) { goto f_err; } - if (s->psk_server_callback == NULL) { + if (ssl->psk_server_callback == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB); al = SSL_AD_INTERNAL_ERROR; goto f_err; @@ -1645,15 +1506,15 @@ int ssl3_get_client_key_exchange(SSL *s) { goto f_err; } - if (!CBS_strdup(&psk_identity, &s->session->psk_identity)) { + if (!CBS_strdup(&psk_identity, &ssl->session->psk_identity)) { al = SSL_AD_INTERNAL_ERROR; OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto f_err; } /* Look up the key for the identity. */ - psk_len = - s->psk_server_callback(s, s->session->psk_identity, psk, sizeof(psk)); + psk_len = ssl->psk_server_callback(ssl, ssl->session->psk_identity, psk, + sizeof(psk)); if (psk_len > PSK_MAX_PSK_LEN) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); al = SSL_AD_INTERNAL_ERROR; @@ -1669,13 +1530,8 @@ int ssl3_get_client_key_exchange(SSL *s) { /* Depending on the key exchange method, compute |premaster_secret| and * |premaster_secret_len|. */ if (alg_k & SSL_kRSA) { - CBS encrypted_premaster_secret; - uint8_t rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; - uint8_t good; - size_t decrypt_len, premaster_index, j; - const size_t rsa_size = ssl_private_key_max_signature_len(s); - /* Allocate a buffer large enough for an RSA decryption. */ + const size_t rsa_size = ssl_private_key_max_signature_len(ssl); decrypt_buf = OPENSSL_malloc(rsa_size); if (decrypt_buf == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); @@ -1683,265 +1539,131 @@ int ssl3_get_client_key_exchange(SSL *s) { } enum ssl_private_key_result_t decrypt_result; - if (s->state == SSL3_ST_SR_KEY_EXCH_B) { - if (!ssl_has_private_key(s) || ssl_private_key_type(s) != EVP_PKEY_RSA) { + size_t decrypt_len; + if (ssl->state == SSL3_ST_SR_KEY_EXCH_B) { + if (!ssl_has_private_key(ssl) || + ssl_private_key_type(ssl) != EVP_PKEY_RSA) { al = SSL_AD_HANDSHAKE_FAILURE; OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE); goto f_err; } - /* TLS and [incidentally] DTLS{0xFEFF} */ - if (s->version > SSL3_VERSION) { - CBS copy = client_key_exchange; + CBS encrypted_premaster_secret; + if (ssl->version > SSL3_VERSION) { if (!CBS_get_u16_length_prefixed(&client_key_exchange, &encrypted_premaster_secret) || CBS_len(&client_key_exchange) != 0) { - if (!(s->options & SSL_OP_TLS_D5_BUG)) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, - SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); - goto f_err; - } else { - CRYPTO_STATIC_MUTEX_lock_write(&g_d5_bug_lock); - g_d5_bug_use_count++; - CRYPTO_STATIC_MUTEX_unlock(&g_d5_bug_lock); - - encrypted_premaster_secret = copy; - } + al = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, + SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto f_err; } } else { encrypted_premaster_secret = client_key_exchange; } - /* Reject overly short RSA keys because we want to be sure that the buffer - * size makes it safe to iterate over the entire size of a premaster - * secret (SSL_MAX_MASTER_KEY_LENGTH). The actual expected size is larger - * due to RSA padding, but the bound is sufficient to be safe. */ - if (rsa_size < SSL_MAX_MASTER_KEY_LENGTH) { - al = SSL_AD_DECRYPT_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); - goto f_err; - } - /* Decrypt with no padding. PKCS#1 padding will be removed as part of the * timing-sensitive code below. */ decrypt_result = ssl_private_key_decrypt( - s, decrypt_buf, &decrypt_len, rsa_size, + ssl, decrypt_buf, &decrypt_len, rsa_size, CBS_data(&encrypted_premaster_secret), CBS_len(&encrypted_premaster_secret)); } else { - assert(s->state == SSL3_ST_SR_KEY_EXCH_C); + assert(ssl->state == SSL3_ST_SR_KEY_EXCH_C); /* Complete async decrypt. */ decrypt_result = ssl_private_key_decrypt_complete( - s, decrypt_buf, &decrypt_len, rsa_size); + ssl, decrypt_buf, &decrypt_len, rsa_size); } switch (decrypt_result) { case ssl_private_key_success: - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; break; case ssl_private_key_failure: - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; goto err; case ssl_private_key_retry: - s->rwstate = SSL_PRIVATE_KEY_OPERATION; - s->state = SSL3_ST_SR_KEY_EXCH_C; + ssl->rwstate = SSL_PRIVATE_KEY_OPERATION; + ssl->state = SSL3_ST_SR_KEY_EXCH_C; goto err; } - if (decrypt_len != rsa_size) { - /* This should never happen, but do a check so we do not read - * uninitialized memory. */ - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } + assert(decrypt_len == rsa_size); - /* Remove the PKCS#1 padding and adjust |decrypt_len| as appropriate. - * |good| will be 0xff if the premaster is acceptable and zero otherwise. - * */ - good = - constant_time_eq_int_8(RSA_message_index_PKCS1_type_2( - decrypt_buf, decrypt_len, &premaster_index), - 1); - decrypt_len = decrypt_len - premaster_index; - - /* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH. */ - good &= constant_time_eq_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH); - - /* Copy over the unpadded premaster. Whatever the value of - * |decrypt_good_mask|, copy as if the premaster were the right length. It - * is important the memory access pattern be constant. */ - premaster_secret = - BUF_memdup(decrypt_buf + (rsa_size - SSL_MAX_MASTER_KEY_LENGTH), - SSL_MAX_MASTER_KEY_LENGTH); + /* Prepare a random premaster, to be used on invalid padding. See RFC 5246, + * section 7.4.7.1. */ + premaster_secret_len = SSL_MAX_MASTER_KEY_LENGTH; + premaster_secret = OPENSSL_malloc(premaster_secret_len); if (premaster_secret == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } - OPENSSL_free(decrypt_buf); - decrypt_buf = NULL; - - /* If the version in the decrypted pre-master secret is correct then - * version_good will be 0xff, otherwise it'll be zero. The - * Klima-Pokorny-Rosa extension of Bleichenbacher's attack - * (http://eprint.iacr.org/2003/052/) exploits the version number check as - * a "bad version oracle". Thus version checks are done in constant time - * and are treated like any other decryption error. */ - good &= constant_time_eq_8(premaster_secret[0], - (unsigned)(s->client_version >> 8)); - good &= constant_time_eq_8(premaster_secret[1], - (unsigned)(s->client_version & 0xff)); - - /* We must not leak whether a decryption failure occurs because of - * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, - * section 7.4.7.1). The code follows that advice of the TLS RFC and - * generates a random premaster secret for the case that the decrypt - * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - if (!RAND_bytes(rand_premaster_secret, sizeof(rand_premaster_secret))) { + if (!RAND_bytes(premaster_secret, premaster_secret_len)) { goto err; } - /* Now copy rand_premaster_secret over premaster_secret using - * decrypt_good_mask. */ - for (j = 0; j < sizeof(rand_premaster_secret); j++) { - premaster_secret[j] = constant_time_select_8(good, premaster_secret[j], - rand_premaster_secret[j]); - } - - premaster_secret_len = sizeof(rand_premaster_secret); - } else if (alg_k & SSL_kDHE) { - CBS dh_Yc; - int dh_len; - - if (!CBS_get_u16_length_prefixed(&client_key_exchange, &dh_Yc) || - CBS_len(&dh_Yc) == 0 || CBS_len(&client_key_exchange) != 0) { - OPENSSL_PUT_ERROR(SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); - al = SSL_R_DECODE_ERROR; - goto f_err; - } - - if (s->s3->tmp.dh == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY); + /* The smallest padded premaster is 11 bytes of overhead. Small keys are + * publicly invalid. */ + if (decrypt_len < 11 + premaster_secret_len) { + al = SSL_AD_DECRYPT_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); goto f_err; } - dh_srvr = s->s3->tmp.dh; - - pub = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL); - if (pub == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_R_BN_LIB); - goto err; - } - - /* Allocate a buffer for the premaster secret. */ - premaster_secret = OPENSSL_malloc(DH_size(dh_srvr)); - if (premaster_secret == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - BN_clear_free(pub); - goto err; - } - - dh_len = DH_compute_key(premaster_secret, pub, dh_srvr); - if (dh_len <= 0) { - OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); - BN_clear_free(pub); - goto err; - } - - DH_free(s->s3->tmp.dh); - s->s3->tmp.dh = NULL; - BN_clear_free(pub); - pub = NULL; - premaster_secret_len = dh_len; - } else if (alg_k & SSL_kECDHE) { - int ecdh_len; - const EC_KEY *tkey; - const EC_GROUP *group; - const BIGNUM *priv_key; - CBS ecdh_Yc; - - /* initialize structures for server's ECDH key pair */ - srvr_ecdh = EC_KEY_new(); - if (srvr_ecdh == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; + /* Check the padding. See RFC 3447, section 7.2.2. */ + size_t padding_len = decrypt_len - premaster_secret_len; + uint8_t good = constant_time_eq_int_8(decrypt_buf[0], 0) & + constant_time_eq_int_8(decrypt_buf[1], 2); + size_t i; + for (i = 2; i < padding_len - 1; i++) { + good &= ~constant_time_is_zero_8(decrypt_buf[i]); } + good &= constant_time_is_zero_8(decrypt_buf[padding_len - 1]); - /* Use the ephermeral values we saved when generating the ServerKeyExchange - * msg. */ - tkey = s->s3->tmp.ecdh; + /* The premaster secret must begin with |client_version|. This too must be + * checked in constant time (http://eprint.iacr.org/2003/052/). */ + good &= constant_time_eq_8(decrypt_buf[padding_len], + (unsigned)(ssl->client_version >> 8)); + good &= constant_time_eq_8(decrypt_buf[padding_len + 1], + (unsigned)(ssl->client_version & 0xff)); - group = EC_KEY_get0_group(tkey); - priv_key = EC_KEY_get0_private_key(tkey); - - if (!EC_KEY_set_group(srvr_ecdh, group) || - !EC_KEY_set_private_key(srvr_ecdh, priv_key)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB); - goto err; + /* Select, in constant time, either the decrypted premaster or the random + * premaster based on |good|. */ + for (i = 0; i < premaster_secret_len; i++) { + premaster_secret[i] = constant_time_select_8( + good, decrypt_buf[padding_len + i], premaster_secret[i]); } - /* Let's get client's public key */ - clnt_ecpoint = EC_POINT_new(group); - if (clnt_ecpoint == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; + OPENSSL_free(decrypt_buf); + decrypt_buf = NULL; + } else if (alg_k & (SSL_kECDHE|SSL_kDHE)) { + /* Parse the ClientKeyExchange. ECDHE uses a u8 length prefix while DHE uses + * u16. */ + CBS peer_key; + int peer_key_ok; + if (alg_k & SSL_kECDHE) { + peer_key_ok = CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key); + } else { + peer_key_ok = + CBS_get_u16_length_prefixed(&client_key_exchange, &peer_key); } - /* Get client's public key from encoded point in the ClientKeyExchange - * message. */ - if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ecdh_Yc) || - CBS_len(&client_key_exchange) != 0) { + if (!peer_key_ok || CBS_len(&client_key_exchange) != 0) { al = SSL_AD_DECODE_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } - bn_ctx = BN_CTX_new(); - if (bn_ctx == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EC_POINT_oct2point(group, clnt_ecpoint, CBS_data(&ecdh_Yc), - CBS_len(&ecdh_Yc), bn_ctx)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB); - goto err; - } - - /* Allocate a buffer for both the secret and the PSK. */ - unsigned field_size = EC_GROUP_get_degree(group); - if (field_size == 0) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); - goto err; - } - - ecdh_len = (field_size + 7) / 8; - premaster_secret = OPENSSL_malloc(ecdh_len); - if (premaster_secret == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Compute the shared pre-master secret */ - ecdh_len = ECDH_compute_key(premaster_secret, ecdh_len, clnt_ecpoint, - srvr_ecdh, NULL); - if (ecdh_len <= 0) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); - goto err; + /* Compute the premaster. */ + uint8_t alert; + if (!SSL_ECDH_CTX_compute_secret(&ssl->s3->tmp.ecdh_ctx, &premaster_secret, + &premaster_secret_len, &alert, + CBS_data(&peer_key), CBS_len(&peer_key))) { + al = alert; + goto f_err; } - EVP_PKEY_free(clnt_pub_pkey); - clnt_pub_pkey = NULL; - EC_POINT_free(clnt_ecpoint); - clnt_ecpoint = NULL; - EC_KEY_free(srvr_ecdh); - srvr_ecdh = NULL; - BN_CTX_free(bn_ctx); - bn_ctx = NULL; - EC_KEY_free(s->s3->tmp.ecdh); - s->s3->tmp.ecdh = NULL; - - premaster_secret_len = ecdh_len; + /* The key exchange state may now be discarded. */ + SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx); } else if (alg_k & SSL_kPSK) { /* For plain PSK, other_secret is a block of 0s with the same length as the * pre-shared key. */ @@ -1984,40 +1706,34 @@ int ssl3_get_client_key_exchange(SSL *s) { } /* Compute the master secret */ - s->session->master_key_length = s->enc_method->generate_master_secret( - s, s->session->master_key, premaster_secret, premaster_secret_len); - if (s->session->master_key_length == 0) { + ssl->session->master_key_length = ssl->enc_method->generate_master_secret( + ssl, ssl->session->master_key, premaster_secret, premaster_secret_len); + if (ssl->session->master_key_length == 0) { goto err; } - s->session->extended_master_secret = s->s3->tmp.extended_master_secret; + ssl->session->extended_master_secret = ssl->s3->tmp.extended_master_secret; OPENSSL_cleanse(premaster_secret, premaster_secret_len); OPENSSL_free(premaster_secret); return 1; f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: - if (premaster_secret) { - if (premaster_secret_len) { - OPENSSL_cleanse(premaster_secret, premaster_secret_len); - } + if (premaster_secret != NULL) { + OPENSSL_cleanse(premaster_secret, premaster_secret_len); OPENSSL_free(premaster_secret); } OPENSSL_free(decrypt_buf); - EVP_PKEY_free(clnt_pub_pkey); - EC_POINT_free(clnt_ecpoint); - EC_KEY_free(srvr_ecdh); - BN_CTX_free(bn_ctx); return -1; } -int ssl3_get_cert_verify(SSL *s) { +int ssl3_get_cert_verify(SSL *ssl) { int al, ok, ret = 0; long n; CBS certificate_verify, signature; - X509 *peer = s->session->peer; + X509 *peer = ssl->session->peer; EVP_PKEY *pkey = NULL; const EVP_MD *md = NULL; uint8_t digest[EVP_MAX_MD_SIZE]; @@ -2028,12 +1744,12 @@ int ssl3_get_cert_verify(SSL *s) { * CertificateVerify is required if and only if there's a client certificate. * */ if (peer == NULL) { - ssl3_free_handshake_buffer(s); + ssl3_free_handshake_buffer(ssl); return 1; } - n = s->method->ssl_get_message( - s, SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B, + n = ssl->method->ssl_get_message( + ssl, SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B, SSL3_MT_CERTIFICATE_VERIFY, SSL3_RT_MAX_PLAIN_LENGTH, ssl_dont_hash_message, &ok); @@ -2053,10 +1769,10 @@ int ssl3_get_cert_verify(SSL *s) { goto f_err; } - CBS_init(&certificate_verify, s->init_msg, n); + CBS_init(&certificate_verify, ssl->init_msg, n); /* Determine the digest type if needbe. */ - if (SSL_USE_SIGALGS(s)) { + if (SSL_USE_SIGALGS(ssl)) { uint8_t hash, signature_type; if (!CBS_get_u8(&certificate_verify, &hash) || !CBS_get_u8(&certificate_verify, &signature_type)) { @@ -2064,20 +1780,20 @@ int ssl3_get_cert_verify(SSL *s) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } - if (!tls12_check_peer_sigalg(s, &md, &al, hash, signature_type, pkey)) { + if (!tls12_check_peer_sigalg(ssl, &md, &al, hash, signature_type, pkey)) { goto f_err; } } /* Compute the digest. */ - if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey->type)) { + if (!ssl3_cert_verify_hash(ssl, digest, &digest_length, &md, pkey->type)) { goto err; } /* The handshake buffer is no longer necessary, and we may hash the current * message.*/ - ssl3_free_handshake_buffer(s); - if (!ssl3_hash_current_message(s)) { + ssl3_free_handshake_buffer(ssl); + if (!ssl3_hash_current_message(ssl)) { goto err; } @@ -2106,7 +1822,7 @@ int ssl3_get_cert_verify(SSL *s) { if (0) { f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); } err: @@ -2116,7 +1832,7 @@ err: return ret; } -int ssl3_get_client_certificate(SSL *s) { +int ssl3_get_client_certificate(SSL *ssl) { int i, ok, al, ret = -1; X509 *x = NULL; unsigned long n; @@ -2125,40 +1841,41 @@ int ssl3_get_client_certificate(SSL *s) { CBS certificate_msg, certificate_list; int is_first_certificate = 1; - n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, -1, - (long)s->max_cert_list, ssl_hash_message, &ok); + n = ssl->method->ssl_get_message(ssl, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, + -1, (long)ssl->max_cert_list, + ssl_hash_message, &ok); if (!ok) { return n; } - if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { - if ((s->verify_mode & SSL_VERIFY_PEER) && - (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + if (ssl->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { + if ((ssl->verify_mode & SSL_VERIFY_PEER) && + (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); al = SSL_AD_HANDSHAKE_FAILURE; goto f_err; } /* If tls asked for a client cert, the client must return a 0 list */ - if (s->version > SSL3_VERSION && s->s3->tmp.cert_request) { + if (ssl->version > SSL3_VERSION && ssl->s3->tmp.cert_request) { OPENSSL_PUT_ERROR(SSL, SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); al = SSL_AD_UNEXPECTED_MESSAGE; goto f_err; } - s->s3->tmp.reuse_message = 1; + ssl->s3->tmp.reuse_message = 1; return 1; } - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { + if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } - CBS_init(&certificate_msg, s->init_msg, n); + CBS_init(&certificate_msg, ssl->init_msg, n); sk = sk_X509_new_null(); if (sk == NULL) { @@ -2183,18 +1900,19 @@ int ssl3_get_client_certificate(SSL *s) { goto f_err; } - if (is_first_certificate && s->ctx->retain_only_sha256_of_client_certs) { + if (is_first_certificate && ssl->ctx->retain_only_sha256_of_client_certs) { /* If this is the first certificate, and we don't want to keep peer * certificates in memory, then we hash it right away. */ SHA256_Init(&sha256); SHA256_Update(&sha256, CBS_data(&certificate), CBS_len(&certificate)); - SHA256_Final(s->session->peer_sha256, &sha256); - s->session->peer_sha256_valid = 1; + SHA256_Final(ssl->session->peer_sha256, &sha256); + ssl->session->peer_sha256_valid = 1; } is_first_certificate = 0; + /* A u24 length cannot overflow a long. */ data = CBS_data(&certificate); - x = d2i_X509(NULL, &data, CBS_len(&certificate)); + x = d2i_X509(NULL, &data, (long)CBS_len(&certificate)); if (x == NULL) { al = SSL_AD_BAD_CERTIFICATE; OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); @@ -2214,35 +1932,35 @@ int ssl3_get_client_certificate(SSL *s) { if (sk_X509_num(sk) <= 0) { /* No client certificate so the handshake buffer may be discarded. */ - ssl3_free_handshake_buffer(s); + ssl3_free_handshake_buffer(ssl); /* TLS does not mind 0 certs returned */ - if (s->version == SSL3_VERSION) { + if (ssl->version == SSL3_VERSION) { al = SSL_AD_HANDSHAKE_FAILURE; OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED); goto f_err; - } else if ((s->verify_mode & SSL_VERIFY_PEER) && - (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + } else if ((ssl->verify_mode & SSL_VERIFY_PEER) && + (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { /* Fail for TLS only if we required a certificate */ OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); al = SSL_AD_HANDSHAKE_FAILURE; goto f_err; } } else { - i = ssl_verify_cert_chain(s, sk); + i = ssl_verify_cert_chain(ssl, sk); if (i <= 0) { - al = ssl_verify_alarm_type(s->verify_result); + al = ssl_verify_alarm_type(ssl->verify_result); OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); goto f_err; } } - X509_free(s->session->peer); - s->session->peer = sk_X509_shift(sk); - s->session->verify_result = s->verify_result; + X509_free(ssl->session->peer); + ssl->session->peer = sk_X509_shift(sk); + ssl->session->verify_result = ssl->verify_result; - sk_X509_pop_free(s->session->cert_chain, X509_free); - s->session->cert_chain = sk; + sk_X509_pop_free(ssl->session->cert_chain, X509_free); + ssl->session->cert_chain = sk; /* Inconsistency alert: cert_chain does *not* include the peer's own * certificate, while we do include it in s3_clnt.c */ @@ -2252,7 +1970,7 @@ int ssl3_get_client_certificate(SSL *s) { if (0) { f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); } err: @@ -2261,20 +1979,20 @@ err: return ret; } -int ssl3_send_server_certificate(SSL *s) { - if (s->state == SSL3_ST_SW_CERT_A) { - if (!ssl3_output_cert_chain(s)) { +int ssl3_send_server_certificate(SSL *ssl) { + if (ssl->state == SSL3_ST_SW_CERT_A) { + if (!ssl3_output_cert_chain(ssl)) { return 0; } - s->state = SSL3_ST_SW_CERT_B; + ssl->state = SSL3_ST_SW_CERT_B; } /* SSL3_ST_SW_CERT_B */ - return ssl_do_write(s); + return ssl_do_write(ssl); } /* send a new session ticket (not necessarily for a new session) */ -int ssl3_send_new_session_ticket(SSL *s) { +int ssl3_send_new_session_ticket(SSL *ssl) { int ret = -1; uint8_t *session = NULL; size_t session_len; @@ -2284,11 +2002,11 @@ int ssl3_send_new_session_ticket(SSL *s) { EVP_CIPHER_CTX_init(&ctx); HMAC_CTX_init(&hctx); - if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { + if (ssl->state == SSL3_ST_SW_SESSION_TICKET_A) { uint8_t *p, *macstart; int len; unsigned int hlen; - SSL_CTX *tctx = s->initial_ctx; + SSL_CTX *tctx = ssl->initial_ctx; uint8_t iv[EVP_MAX_IV_LENGTH]; uint8_t key_name[16]; /* The maximum overhead of encrypting the session is 16 (key name) + IV + @@ -2297,7 +2015,8 @@ int ssl3_send_new_session_ticket(SSL *s) { 16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE; /* Serialize the SSL_SESSION to be encoded into the ticket. */ - if (!SSL_SESSION_to_bytes_for_ticket(s->session, &session, &session_len)) { + if (!SSL_SESSION_to_bytes_for_ticket(ssl->session, &session, + &session_len)) { goto err; } @@ -2310,7 +2029,7 @@ int ssl3_send_new_session_ticket(SSL *s) { OPENSSL_free(session); session = NULL; - p = ssl_handshake_start(s); + p = ssl_handshake_start(ssl); /* Emit ticket_lifetime_hint. */ l2n(0, p); /* Emit ticket. */ @@ -2318,26 +2037,26 @@ int ssl3_send_new_session_ticket(SSL *s) { memcpy(p, kTicketPlaceholder, placeholder_len); p += placeholder_len; - len = p - ssl_handshake_start(s); - if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len)) { + len = p - ssl_handshake_start(ssl); + if (!ssl_set_handshake_header(ssl, SSL3_MT_NEWSESSION_TICKET, len)) { goto err; } - s->state = SSL3_ST_SW_SESSION_TICKET_B; - return ssl_do_write(s); + ssl->state = SSL3_ST_SW_SESSION_TICKET_B; + return ssl_do_write(ssl); } /* Grow buffer if need be: the length calculation is as follows: * handshake_header_length + 4 (ticket lifetime hint) + 2 (ticket length) + * max_ticket_overhead + * session_length */ - if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + 6 + + if (!BUF_MEM_grow(ssl->init_buf, SSL_HM_HEADER_LENGTH(ssl) + 6 + max_ticket_overhead + session_len)) { goto err; } - p = ssl_handshake_start(s); + p = ssl_handshake_start(ssl); /* Initialize HMAC and cipher contexts. If callback present it does all the * work otherwise use generated values from parent ctx. */ if (tctx->tlsext_ticket_key_cb) { - if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, &hctx, + if (tctx->tlsext_ticket_key_cb(ssl, key_name, iv, &ctx, &hctx, 1 /* encrypt */) < 0) { goto err; } @@ -2355,7 +2074,7 @@ int ssl3_send_new_session_ticket(SSL *s) { /* Ticket lifetime hint (advisory only): We leave this unspecified for * resumed session (for simplicity), and guess that tickets for new * sessions will live as long as their sessions. */ - l2n(s->hit ? 0 : s->session->timeout, p); + l2n(ssl->hit ? 0 : ssl->session->timeout, p); /* Skip ticket length for now */ p += 2; @@ -2384,18 +2103,18 @@ int ssl3_send_new_session_ticket(SSL *s) { p += hlen; /* Now write out lengths: p points to end of data written */ /* Total length */ - len = p - ssl_handshake_start(s); + len = p - ssl_handshake_start(ssl); /* Skip ticket lifetime hint */ - p = ssl_handshake_start(s) + 4; + p = ssl_handshake_start(ssl) + 4; s2n(len - 6, p); - if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len)) { + if (!ssl_set_handshake_header(ssl, SSL3_MT_NEWSESSION_TICKET, len)) { goto err; } - s->state = SSL3_ST_SW_SESSION_TICKET_B; + ssl->state = SSL3_ST_SW_SESSION_TICKET_B; } /* SSL3_ST_SW_SESSION_TICKET_B */ - ret = ssl_do_write(s); + ret = ssl_do_write(ssl); err: OPENSSL_free(session); @@ -2406,19 +2125,19 @@ err: /* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It * sets the next_proto member in s if found */ -int ssl3_get_next_proto(SSL *s) { +int ssl3_get_next_proto(SSL *ssl) { int ok; long n; CBS next_protocol, selected_protocol, padding; /* Clients cannot send a NextProtocol message if we didn't see the extension * in their ClientHello */ - if (!s->s3->next_proto_neg_seen) { + if (!ssl->s3->next_proto_neg_seen) { OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); return -1; } - n = s->method->ssl_get_message(s, SSL3_ST_SR_NEXT_PROTO_A, + n = ssl->method->ssl_get_message(ssl, SSL3_ST_SR_NEXT_PROTO_A, SSL3_ST_SR_NEXT_PROTO_B, SSL3_MT_NEXT_PROTO, 514, /* See the payload format below */ ssl_hash_message, &ok); @@ -2427,18 +2146,7 @@ int ssl3_get_next_proto(SSL *s) { return n; } - /* s->state doesn't reflect whether ChangeCipherSpec has been received in - * this handshake, but s->s3->change_cipher_spec does (will be reset by - * ssl3_get_finished). - * - * TODO(davidben): Is this check now redundant with - * SSL3_FLAGS_EXPECT_CCS? */ - if (!s->s3->change_cipher_spec) { - OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); - return -1; - } - - CBS_init(&next_protocol, s->init_msg, n); + CBS_init(&next_protocol, ssl->init_msg, n); /* The payload looks like: * uint8 proto_len; @@ -2448,8 +2156,8 @@ int ssl3_get_next_proto(SSL *s) { if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) || !CBS_get_u8_length_prefixed(&next_protocol, &padding) || CBS_len(&next_protocol) != 0 || - !CBS_stow(&selected_protocol, &s->next_proto_negotiated, - &s->next_proto_negotiated_len)) { + !CBS_stow(&selected_protocol, &ssl->next_proto_negotiated, + &ssl->next_proto_negotiated_len)) { return 0; } @@ -2457,7 +2165,7 @@ int ssl3_get_next_proto(SSL *s) { } /* ssl3_get_channel_id reads and verifies a ClientID handshake message. */ -int ssl3_get_channel_id(SSL *s) { +int ssl3_get_channel_id(SSL *ssl) { int ret = -1, ok; long n; uint8_t channel_id_hash[EVP_MAX_MD_SIZE]; @@ -2471,8 +2179,8 @@ int ssl3_get_channel_id(SSL *s) { BIGNUM x, y; CBS encrypted_extensions, extension; - n = s->method->ssl_get_message( - s, SSL3_ST_SR_CHANNEL_ID_A, SSL3_ST_SR_CHANNEL_ID_B, + n = ssl->method->ssl_get_message( + ssl, SSL3_ST_SR_CHANNEL_ID_A, SSL3_ST_SR_CHANNEL_ID_B, SSL3_MT_ENCRYPTED_EXTENSIONS, 2 + 2 + TLSEXT_CHANNEL_ID_SIZE, ssl_dont_hash_message, &ok); @@ -2482,26 +2190,16 @@ int ssl3_get_channel_id(SSL *s) { /* Before incorporating the EncryptedExtensions message to the handshake * hash, compute the hash that should have been signed. */ - if (!tls1_channel_id_hash(s, channel_id_hash, &channel_id_hash_len)) { + if (!tls1_channel_id_hash(ssl, channel_id_hash, &channel_id_hash_len)) { return -1; } assert(channel_id_hash_len == SHA256_DIGEST_LENGTH); - if (!ssl3_hash_current_message(s)) { + if (!ssl3_hash_current_message(ssl)) { return -1; } - /* s->state doesn't reflect whether ChangeCipherSpec has been received in - * this handshake, but s->s3->change_cipher_spec does (will be reset by - * ssl3_get_finished). - * - * TODO(davidben): Is this check now redundant with SSL3_FLAGS_EXPECT_CCS? */ - if (!s->s3->change_cipher_spec) { - OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS); - return -1; - } - - CBS_init(&encrypted_extensions, s->init_msg, n); + CBS_init(&encrypted_extensions, ssl->init_msg, n); /* EncryptedExtensions could include multiple extensions, but the only * extension that could be negotiated is ChannelID, so there can only be one @@ -2547,7 +2245,8 @@ int ssl3_get_channel_id(SSL *s) { } point = EC_POINT_new(p256); - if (!point || !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL)) { + if (!point || + !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL)) { goto err; } @@ -2561,11 +2260,11 @@ int ssl3_get_channel_id(SSL *s) { * were called. */ if (!ECDSA_do_verify(channel_id_hash, channel_id_hash_len, &sig, key)) { OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID); - s->s3->tlsext_channel_id_valid = 0; + ssl->s3->tlsext_channel_id_valid = 0; goto err; } - memcpy(s->s3->tlsext_channel_id, p, 64); + memcpy(ssl->s3->tlsext_channel_id, p, 64); ret = 1; err: diff --git a/src/ssl/ssl_aead_ctx.c b/src/ssl/ssl_aead_ctx.c index f9001c7..8829679 100644 --- a/src/ssl/ssl_aead_ctx.c +++ b/src/ssl/ssl_aead_ctx.c @@ -74,17 +74,20 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction, assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH); aead_ctx->variable_nonce_len = (uint8_t)EVP_AEAD_nonce_length(aead); if (mac_key_len == 0) { - /* For a real AEAD, the IV is the fixed part of the nonce. */ - if (fixed_iv_len > sizeof(aead_ctx->fixed_nonce) || - fixed_iv_len > aead_ctx->variable_nonce_len) { - SSL_AEAD_CTX_free(aead_ctx); - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return 0; - } - aead_ctx->variable_nonce_len -= fixed_iv_len; - + assert(fixed_iv_len <= sizeof(aead_ctx->fixed_nonce)); memcpy(aead_ctx->fixed_nonce, fixed_iv, fixed_iv_len); aead_ctx->fixed_nonce_len = fixed_iv_len; + + if (cipher->algorithm_enc & SSL_CHACHA20POLY1305) { + /* The fixed nonce into the actual nonce (the sequence number). */ + aead_ctx->xor_fixed_nonce = 1; + aead_ctx->variable_nonce_len = 8; + } else { + /* The fixed IV is prepended to the nonce. */ + assert(fixed_iv_len <= aead_ctx->variable_nonce_len); + aead_ctx->variable_nonce_len -= fixed_iv_len; + } + /* AES-GCM uses an explicit nonce. */ if (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) { aead_ctx->variable_nonce_included_in_record = 1; @@ -176,8 +179,17 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len, /* Assemble the nonce. */ uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; size_t nonce_len = 0; - memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len); - nonce_len += aead->fixed_nonce_len; + + /* Prepend the fixed nonce, or left-pad with zeros if XORing. */ + if (aead->xor_fixed_nonce) { + nonce_len = aead->fixed_nonce_len - aead->variable_nonce_len; + memset(nonce, 0, nonce_len); + } else { + memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len); + nonce_len += aead->fixed_nonce_len; + } + + /* Add the variable nonce. */ if (aead->variable_nonce_included_in_record) { if (in_len < aead->variable_nonce_len) { /* Publicly invalid. */ @@ -193,6 +205,15 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len, } nonce_len += aead->variable_nonce_len; + /* XOR the fixed nonce, if necessary. */ + if (aead->xor_fixed_nonce) { + assert(nonce_len == aead->fixed_nonce_len); + size_t i; + for (i = 0; i < aead->fixed_nonce_len; i++) { + nonce[i] ^= aead->fixed_nonce[i]; + } + } + return EVP_AEAD_CTX_open(&aead->ctx, out, out_len, max_out, nonce, nonce_len, in, in_len, ad, ad_len); } @@ -219,8 +240,17 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len, /* Assemble the nonce. */ uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; size_t nonce_len = 0; - memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len); - nonce_len += aead->fixed_nonce_len; + + /* Prepend the fixed nonce, or left-pad with zeros if XORing. */ + if (aead->xor_fixed_nonce) { + nonce_len = aead->fixed_nonce_len - aead->variable_nonce_len; + memset(nonce, 0, nonce_len); + } else { + memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len); + nonce_len += aead->fixed_nonce_len; + } + + /* Select the variable nonce. */ if (aead->random_variable_nonce) { assert(aead->variable_nonce_included_in_record); if (!RAND_bytes(nonce + nonce_len, aead->variable_nonce_len)) { @@ -230,13 +260,14 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len, /* When sending we use the sequence number as the variable part of the * nonce. */ assert(aead->variable_nonce_len == 8); - memcpy(nonce + nonce_len, ad, aead->variable_nonce_len); + memcpy(nonce + nonce_len, seqnum, aead->variable_nonce_len); } nonce_len += aead->variable_nonce_len; /* Emit the variable nonce if included in the record. */ size_t extra_len = 0; if (aead->variable_nonce_included_in_record) { + assert(!aead->xor_fixed_nonce); if (max_out < aead->variable_nonce_len) { OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); return 0; @@ -251,6 +282,15 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len, max_out -= aead->variable_nonce_len; } + /* XOR the fixed nonce, if necessary. */ + if (aead->xor_fixed_nonce) { + assert(nonce_len == aead->fixed_nonce_len); + size_t i; + for (i = 0; i < aead->fixed_nonce_len; i++) { + nonce[i] ^= aead->fixed_nonce[i]; + } + } + if (!EVP_AEAD_CTX_seal(&aead->ctx, out, out_len, max_out, nonce, nonce_len, in, in_len, ad, ad_len)) { return 0; diff --git a/src/ssl/ssl_asn1.c b/src/ssl/ssl_asn1.c index 0ad4a11..5ec33eb 100644 --- a/src/ssl/ssl_asn1.c +++ b/src/ssl/ssl_asn1.c @@ -492,8 +492,12 @@ static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag, } static X509 *parse_x509(CBS *cbs) { + if (CBS_len(cbs) > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return NULL; + } const uint8_t *ptr = CBS_data(cbs); - X509 *ret = d2i_X509(NULL, &ptr, CBS_len(cbs)); + X509 *ret = d2i_X509(NULL, &ptr, (long)CBS_len(cbs)); if (ret == NULL) { return NULL; } diff --git a/src/ssl/ssl_buffer.c b/src/ssl/ssl_buffer.c index f1abc53..7fd74e4 100644 --- a/src/ssl/ssl_buffer.c +++ b/src/ssl/ssl_buffer.c @@ -70,8 +70,8 @@ static void clear_buffer(SSL3_BUFFER *buf) { memset(buf, 0, sizeof(SSL3_BUFFER)); } -OPENSSL_COMPILE_ASSERT(DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH + - SSL3_RT_MAX_EXTRA <= 0xffff, +OPENSSL_COMPILE_ASSERT(DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <= + 0xffff, maximum_read_buffer_too_large); /* setup_read_buffer initializes the read buffer if not already initialized. It @@ -90,9 +90,6 @@ static int setup_read_buffer(SSL *ssl) { } else { cap += SSL3_RT_HEADER_LENGTH; } - if (ssl->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { - cap += SSL3_RT_MAX_EXTRA; - } return setup_buffer(buf, header_len, cap); } @@ -131,9 +128,6 @@ static int tls_read_buffer_extend_to(SSL *ssl, size_t len) { SSL3_BUFFER *buf = &ssl->s3->read_buffer; if (len > buf->cap) { - /* This may occur if |SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER| was toggled after - * |setup_read_buffer| was called. Stay within bounds, but do not attempt to - * recover. */ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); return -1; } diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c index 4094b27..4952cfd 100644 --- a/src/ssl/ssl_cert.c +++ b/src/ssl/ssl_cert.c @@ -166,28 +166,9 @@ CERT *ssl_cert_dup(CERT *cert) { OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); goto err; } - if (cert->dh_tmp->priv_key) { - BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); - if (!b) { - OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB); - goto err; - } - ret->dh_tmp->priv_key = b; - } - if (cert->dh_tmp->pub_key) { - BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); - if (!b) { - OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB); - goto err; - } - ret->dh_tmp->pub_key = b; - } } ret->dh_tmp_cb = cert->dh_tmp_cb; - ret->ecdh_nid = cert->ecdh_nid; - ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; - if (cert->x509 != NULL) { ret->x509 = X509_up_ref(cert->x509); } diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.c index e87835f..77fa8fa 100644 --- a/src/ssl/ssl_cipher.c +++ b/src/ssl/ssl_cipher.c @@ -155,33 +155,50 @@ /* kCiphers is an array of all supported ciphers, sorted by id. */ -const SSL_CIPHER kCiphers[] = { +static const SSL_CIPHER kCiphers[] = { /* The RSA ciphers */ /* Cipher 02 */ { - SSL3_TXT_RSA_NULL_SHA, SSL3_CK_RSA_NULL_SHA, SSL_kRSA, SSL_aRSA, - SSL_eNULL, SSL_SHA1, SSL_SSLV3, SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT, 0, 0, + SSL3_TXT_RSA_NULL_SHA, + SSL3_CK_RSA_NULL_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher 04 */ { - SSL3_TXT_RSA_RC4_128_MD5, SSL3_CK_RSA_RC4_128_MD5, SSL_kRSA, SSL_aRSA, - SSL_RC4, SSL_MD5, SSL_SSLV3, SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + SSL3_TXT_RSA_RC4_128_MD5, + SSL3_CK_RSA_RC4_128_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher 05 */ { - SSL3_TXT_RSA_RC4_128_SHA, SSL3_CK_RSA_RC4_128_SHA, SSL_kRSA, SSL_aRSA, - SSL_RC4, SSL_SHA1, SSL_SSLV3, SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + SSL3_TXT_RSA_RC4_128_SHA, + SSL3_CK_RSA_RC4_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher 0A */ { - SSL3_TXT_RSA_DES_192_CBC3_SHA, SSL3_CK_RSA_DES_192_CBC3_SHA, SSL_kRSA, - SSL_aRSA, SSL_3DES, SSL_SHA1, SSL_SSLV3, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 112, 168, + SSL3_TXT_RSA_DES_192_CBC3_SHA, + SSL3_CK_RSA_DES_192_CBC3_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, @@ -189,30 +206,46 @@ const SSL_CIPHER kCiphers[] = { /* Cipher 2F */ { - TLS1_TXT_RSA_WITH_AES_128_SHA, TLS1_CK_RSA_WITH_AES_128_SHA, SSL_kRSA, - SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + TLS1_TXT_RSA_WITH_AES_128_SHA, + TLS1_CK_RSA_WITH_AES_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher 33 */ { - TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, TLS1_CK_DHE_RSA_WITH_AES_128_SHA, - SSL_kDHE, SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, + TLS1_CK_DHE_RSA_WITH_AES_128_SHA, + SSL_kDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher 35 */ { - TLS1_TXT_RSA_WITH_AES_256_SHA, TLS1_CK_RSA_WITH_AES_256_SHA, SSL_kRSA, - SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 256, 256, + TLS1_TXT_RSA_WITH_AES_256_SHA, + TLS1_CK_RSA_WITH_AES_256_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher 39 */ { - TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, TLS1_CK_DHE_RSA_WITH_AES_256_SHA, - SSL_kDHE, SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 256, 256, + TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, + TLS1_CK_DHE_RSA_WITH_AES_256_SHA, + SSL_kDHE, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, @@ -220,55 +253,81 @@ const SSL_CIPHER kCiphers[] = { /* Cipher 3C */ { - TLS1_TXT_RSA_WITH_AES_128_SHA256, TLS1_CK_RSA_WITH_AES_128_SHA256, - SSL_kRSA, SSL_aRSA, SSL_AES128, SSL_SHA256, SSL_TLSV1_2, - SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256, 128, 128, + TLS1_TXT_RSA_WITH_AES_128_SHA256, + TLS1_CK_RSA_WITH_AES_128_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, }, /* Cipher 3D */ { - TLS1_TXT_RSA_WITH_AES_256_SHA256, TLS1_CK_RSA_WITH_AES_256_SHA256, - SSL_kRSA, SSL_aRSA, SSL_AES256, SSL_SHA256, SSL_TLSV1_2, - SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256, 256, 256, + TLS1_TXT_RSA_WITH_AES_256_SHA256, + TLS1_CK_RSA_WITH_AES_256_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, }, /* Cipher 67 */ { TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256, - TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128, - SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256, 128, 128, + TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, + SSL_kDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, }, /* Cipher 6B */ { TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256, - TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES256, - SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256, 256, 256, + TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, + SSL_kDHE, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, }, /* PSK cipher suites. */ /* Cipher 8A */ { - TLS1_TXT_PSK_WITH_RC4_128_SHA, TLS1_CK_PSK_WITH_RC4_128_SHA, SSL_kPSK, - SSL_aPSK, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + TLS1_TXT_PSK_WITH_RC4_128_SHA, + TLS1_CK_PSK_WITH_RC4_128_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_RC4, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher 8C */ { - TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, TLS1_CK_PSK_WITH_AES_128_CBC_SHA, - SSL_kPSK, SSL_aPSK, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, + TLS1_CK_PSK_WITH_AES_128_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher 8D */ { - TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, TLS1_CK_PSK_WITH_AES_256_CBC_SHA, - SSL_kPSK, SSL_aPSK, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 256, 256, + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, + TLS1_CK_PSK_WITH_AES_256_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* GCM ciphersuites from RFC5288 */ @@ -276,84 +335,111 @@ const SSL_CIPHER kCiphers[] = { /* Cipher 9C */ { TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, SSL_kRSA, SSL_aRSA, SSL_AES128GCM, - SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, + TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA256, - 128, 128, }, /* Cipher 9D */ { TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, SSL_kRSA, SSL_aRSA, SSL_AES256GCM, - SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, + TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, + SSL_kRSA, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA384, - 256, 256, }, /* Cipher 9E */ { TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128GCM, - SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, + TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, + SSL_kDHE, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA256, - 128, 128, }, /* Cipher 9F */ { TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kDHE, SSL_aRSA, SSL_AES256GCM, - SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, + TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, + SSL_kDHE, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA384, - 256, 256, }, /* Cipher C007 */ { TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_kECDHE, SSL_aECDSA, SSL_RC4, - SSL_SHA1, SSL_TLSV1, SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT, 128, - 128, + TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, + SSL_kECDHE, + SSL_aECDSA, + SSL_RC4, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher C009 */ { TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aECDSA, - SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher C00A */ { TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aECDSA, - SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 256, 256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher C011 */ { - TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, - SSL_kECDHE, SSL_aRSA, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, + TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, + SSL_kECDHE, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher C013 */ { TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES128, - SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher C014 */ { TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES256, - SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 256, 256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, @@ -362,33 +448,45 @@ const SSL_CIPHER kCiphers[] = { /* Cipher C023 */ { TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aECDSA, - SSL_AES128, SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256, 128, 128, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, }, /* Cipher C024 */ { TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aECDSA, - SSL_AES256, SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384, 256, 256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256, + SSL_SHA384, + SSL_HANDSHAKE_MAC_SHA384, }, /* Cipher C027 */ { TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256, - TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aRSA, SSL_AES128, - SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256, 128, 128, + TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, }, /* Cipher C028 */ { TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384, - TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aRSA, SSL_AES256, - SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384, 256, 256, + TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256, + SSL_SHA384, + SSL_HANDSHAKE_MAC_SHA384, }, @@ -397,37 +495,45 @@ const SSL_CIPHER kCiphers[] = { /* Cipher C02B */ { TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aECDSA, - SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128GCM, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA256, - 128, 128, }, /* Cipher C02C */ { TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aECDSA, - SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256GCM, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA384, - 256, 256, }, /* Cipher C02F */ { TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aRSA, - SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA256, - 128, 128, }, /* Cipher C030 */ { TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aRSA, - SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA384, - 256, 256, }, /* ECDHE-PSK cipher suites. */ @@ -436,37 +542,80 @@ const SSL_CIPHER kCiphers[] = { { TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA, TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA, - SSL_kECDHE, SSL_aPSK, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 128, 128, + SSL_kECDHE, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, /* Cipher C036 */ { TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA, TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA, - SSL_kECDHE, SSL_aPSK, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT, 256, 256, + SSL_kECDHE, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, }, -#if !defined(BORINGSSL_ANDROID_SYSTEM) /* ChaCha20-Poly1305 cipher suites. */ +#if !defined(BORINGSSL_ANDROID_SYSTEM) { TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD, - TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, SSL_kECDHE, SSL_aRSA, - SSL_CHACHA20POLY1305_OLD, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH, + TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, + SSL_kECDHE, + SSL_aRSA, + SSL_CHACHA20POLY1305_OLD, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA256, - 256, 256, }, { TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD, - TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, SSL_kECDHE, SSL_aECDSA, - SSL_CHACHA20POLY1305_OLD, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH, + TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, + SSL_kECDHE, + SSL_aECDSA, + SSL_CHACHA20POLY1305_OLD, + SSL_AEAD, SSL_HANDSHAKE_MAC_SHA256, - 256, 256, }, #endif + + /* Cipher CCA8 */ + { + TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + /* Cipher CCA9 */ + { + TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + /* Cipher CCAB */ + { + TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aPSK, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, }; static const size_t kCiphersLen = sizeof(kCiphers) / sizeof(kCiphers[0]); @@ -496,13 +645,15 @@ typedef struct cipher_alias_st { uint32_t algorithm_auth; uint32_t algorithm_enc; uint32_t algorithm_mac; - uint32_t algorithm_ssl; - uint32_t algo_strength; + + /* min_version, if non-zero, matches all ciphers which were added in that + * particular protocol version. */ + uint16_t min_version; } CIPHER_ALIAS; static const CIPHER_ALIAS kCipherAliases[] = { /* "ALL" doesn't include eNULL (must be specifically enabled) */ - {"ALL", ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, ~0u}, + {"ALL", ~0u, ~0u, ~SSL_eNULL, ~0u, 0}, /* The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. */ @@ -510,58 +661,59 @@ static const CIPHER_ALIAS kCipherAliases[] = { * (some of those using only a single bit here combine * multiple key exchange algs according to the RFCs, * e.g. kEDH combines DHE_DSS and DHE_RSA) */ - {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, ~0u, ~0u}, + {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, 0}, - {"kDHE", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, - {"kEDH", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, - {"DH", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, + {"kDHE", SSL_kDHE, ~0u, ~0u, ~0u, 0}, + {"kEDH", SSL_kDHE, ~0u, ~0u, ~0u, 0}, + {"DH", SSL_kDHE, ~0u, ~0u, ~0u, 0}, - {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, - {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, - {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, + {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, - {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, ~0u, ~0u}, + {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, 0}, /* server authentication aliases */ - {"aRSA", ~0u, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u}, - {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u}, - {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u}, - {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, ~0u, ~0u}, + {"aRSA", ~0u, SSL_aRSA, ~SSL_eNULL, ~0u, 0}, + {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0}, + {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0}, + {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, 0}, /* aliases combining key exchange and server authentication */ - {"DHE", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, - {"EDH", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, - {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, - {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u}, - {"RSA", SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u}, - {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, ~0u, ~0u}, + {"DHE", SSL_kDHE, ~0u, ~0u, ~0u, 0}, + {"EDH", SSL_kDHE, ~0u, ~0u, ~0u, 0}, + {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"RSA", SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, 0}, + {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, 0}, /* symmetric encryption aliases */ - {"3DES", ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u}, - {"RC4", ~0u, ~0u, SSL_RC4, ~0u, ~0u, ~0u}, - {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, ~0u, ~0u}, - {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, ~0u, ~0u}, - {"AES", ~0u, ~0u, SSL_AES, ~0u, ~0u, ~0u}, - {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, ~0u, ~0u}, - {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, ~0u, ~0u}, + {"3DES", ~0u, ~0u, SSL_3DES, ~0u, 0}, + {"RC4", ~0u, ~0u, SSL_RC4, ~0u, 0}, + {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, 0}, + {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, 0}, + {"AES", ~0u, ~0u, SSL_AES, ~0u, 0}, + {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, 0}, + {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_OLD, ~0u, + 0}, /* MAC aliases */ - {"MD5", ~0u, ~0u, ~0u, SSL_MD5, ~0u, ~0u}, - {"SHA1", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u}, - {"SHA", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u}, - {"SHA256", ~0u, ~0u, ~0u, SSL_SHA256, ~0u, ~0u}, - {"SHA384", ~0u, ~0u, ~0u, SSL_SHA384, ~0u, ~0u}, - - /* protocol version aliases */ - {"SSLv3", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_SSLV3, ~0u}, - {"TLSv1", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1, ~0u}, - {"TLSv1.2", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1_2, ~0u}, - - /* strength classes */ - {"MEDIUM", ~0u, ~0u, ~0u, ~0u, ~0u, SSL_MEDIUM}, - {"HIGH", ~0u, ~0u, ~0u, ~0u, ~0u, SSL_HIGH}, - /* FIPS 140-2 approved ciphersuite */ - {"FIPS", ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, SSL_FIPS}, + {"MD5", ~0u, ~0u, ~0u, SSL_MD5, 0}, + {"SHA1", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, 0}, + {"SHA", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, 0}, + {"SHA256", ~0u, ~0u, ~0u, SSL_SHA256, 0}, + {"SHA384", ~0u, ~0u, ~0u, SSL_SHA384, 0}, + + /* Legacy protocol minimum version aliases. "TLSv1" is intentionally the + * same as "SSLv3". */ + {"SSLv3", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL3_VERSION}, + {"TLSv1", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL3_VERSION}, + {"TLSv1.2", ~0u, ~0u, ~SSL_eNULL, ~0u, TLS1_2_VERSION}, + + /* Legacy strength classes. */ + {"MEDIUM", ~0u, ~0u, SSL_RC4, ~0u, 0}, + {"HIGH", ~0u, ~0u, ~(SSL_eNULL|SSL_RC4), ~0u, 0}, + {"FIPS", ~0u, ~0u, ~(SSL_eNULL|SSL_RC4), ~0u, 0}, }; static const size_t kCipherAliasesLen = @@ -618,6 +770,11 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, return 1; #endif + case SSL_CHACHA20POLY1305: + *out_aead = EVP_aead_chacha20_poly1305(); + *out_fixed_iv_len = 12; + return 1; + case SSL_RC4: switch (cipher->algorithm_mac) { case SSL_MD5: @@ -838,19 +995,18 @@ static void ssl_cipher_collect_ciphers(const SSL_PROTOCOL_METHOD *ssl_method, * - Otherwise, if |strength_bits| is non-negative, it selects ciphers * of that strength. * - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and - * |algo_strength|. */ + * |min_version|. */ static void ssl_cipher_apply_rule( uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth, - uint32_t alg_enc, uint32_t alg_mac, uint32_t alg_ssl, - uint32_t algo_strength, int rule, int strength_bits, int in_group, - CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { + uint32_t alg_enc, uint32_t alg_mac, uint16_t min_version, int rule, + int strength_bits, int in_group, CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { CIPHER_ORDER *head, *tail, *curr, *next, *last; const SSL_CIPHER *cp; int reverse = 0; - if (cipher_id == 0 && strength_bits == -1 && - (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0 || - alg_ssl == 0 || algo_strength == 0)) { + if (cipher_id == 0 && strength_bits == -1 && min_version == 0 && + (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0)) { /* The rule matches nothing, so bail early. */ return; } @@ -892,15 +1048,15 @@ static void ssl_cipher_apply_rule( continue; } } else if (strength_bits >= 0) { - if (strength_bits != cp->strength_bits) { + if (strength_bits != SSL_CIPHER_get_bits(cp, NULL)) { continue; } } else if (!(alg_mkey & cp->algorithm_mkey) || !(alg_auth & cp->algorithm_auth) || !(alg_enc & cp->algorithm_enc) || !(alg_mac & cp->algorithm_mac) || - !(alg_ssl & cp->algorithm_ssl) || - !(algo_strength & cp->algo_strength)) { + (min_version != 0 && + SSL_CIPHER_get_min_version(cp) != min_version)) { continue; } @@ -969,8 +1125,9 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, max_strength_bits = 0; curr = *head_p; while (curr != NULL) { - if (curr->active && curr->cipher->strength_bits > max_strength_bits) { - max_strength_bits = curr->cipher->strength_bits; + if (curr->active && + SSL_CIPHER_get_bits(curr->cipher, NULL) > max_strength_bits) { + max_strength_bits = SSL_CIPHER_get_bits(curr->cipher, NULL); } curr = curr->next; } @@ -986,7 +1143,7 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, curr = *head_p; while (curr != NULL) { if (curr->active) { - number_uses[curr->cipher->strength_bits]++; + number_uses[SSL_CIPHER_get_bits(curr->cipher, NULL)]++; } curr = curr->next; } @@ -994,8 +1151,7 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, /* Go through the list of used strength_bits values in descending order. */ for (i = max_strength_bits; i >= 0; i--) { if (number_uses[i] > 0) { - ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, head_p, - tail_p); + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, head_p, tail_p); } } @@ -1007,9 +1163,10 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method, const char *rule_str, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { - uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength; + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; + uint16_t min_version; const char *l, *buf; - int multi, rule, retval, ok, in_group = 0, has_group = 0; + int multi, skip_rule, rule, retval, ok, in_group = 0, has_group = 0; size_t j, buf_len; uint32_t cipher_id; char ch; @@ -1090,8 +1247,8 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method, alg_auth = ~0u; alg_enc = ~0u; alg_mac = ~0u; - alg_ssl = ~0u; - algo_strength = ~0u; + min_version = 0; + skip_rule = 0; for (;;) { ch = *l; @@ -1135,13 +1292,18 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method, alg_auth &= kCipherAliases[j].algorithm_auth; alg_enc &= kCipherAliases[j].algorithm_enc; alg_mac &= kCipherAliases[j].algorithm_mac; - alg_ssl &= kCipherAliases[j].algorithm_ssl; - algo_strength &= kCipherAliases[j].algo_strength; + + if (min_version != 0 && + min_version != kCipherAliases[j].min_version) { + skip_rule = 1; + } else { + min_version = kCipherAliases[j].min_version; + } break; } } if (j == kCipherAliasesLen) { - alg_mkey = alg_auth = alg_enc = alg_mac = alg_ssl = algo_strength = 0; + skip_rule = 1; } } @@ -1153,6 +1315,29 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method, multi = 1; } + /* If one of the CHACHA20_POLY1305 variants is selected, include the other + * as well. They have the same name to avoid requiring changes in + * configuration. Apply this transformation late so that the cipher name + * still behaves as an exact name and not an alias in multipart rules. + * + * This is temporary and will be removed when the pre-standard construction + * is removed. */ + if (cipher_id == TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD || + cipher_id == TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) { + cipher_id = 0; + alg_mkey = SSL_kECDHE; + alg_auth = SSL_aRSA; + alg_enc = SSL_CHACHA20POLY1305|SSL_CHACHA20POLY1305_OLD; + alg_mac = SSL_AEAD; + } else if (cipher_id == TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD || + cipher_id == TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) { + cipher_id = 0; + alg_mkey = SSL_kECDHE; + alg_auth = SSL_aECDSA; + alg_enc = SSL_CHACHA20POLY1305|SSL_CHACHA20POLY1305_OLD; + alg_mac = SSL_AEAD; + } + /* Ok, we have the rule, now apply it. */ if (rule == CIPHER_SPECIAL) { /* special command */ @@ -1172,10 +1357,9 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method, while (*l != '\0' && !ITEM_SEP(*l)) { l++; } - } else { + } else if (!skip_rule) { ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac, - alg_ssl, algo_strength, rule, -1, in_group, head_p, - tail_p); + min_version, rule, -1, in_group, head_p, tail_p); } } @@ -1221,56 +1405,61 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method, /* Everything else being equal, prefer ECDHE_ECDSA then ECDHE_RSA over other * key exchange mechanisms */ - ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u, - CIPHER_ADD, -1, 0, &head, &tail); - ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_ADD, -1, - 0, &head, &tail); - ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_DEL, -1, + ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1, 0, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0, + &head, &tail); + ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0, + &head, &tail); /* Order the bulk ciphers. First the preferred AEAD ciphers. We prefer * CHACHA20 unless there is hardware support for fast and constant-time - * AES_GCM. */ + * AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the + * old one. */ if (EVP_has_aes_hardware()) { - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, ~0u, ~0u, CIPHER_ADD, - -1, 0, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, ~0u, ~0u, CIPHER_ADD, + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, -1, 0, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, ~0u, ~0u, + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0, CIPHER_ADD, -1, 0, &head, &tail); } else { - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, ~0u, ~0u, - CIPHER_ADD, -1, 0, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, ~0u, ~0u, CIPHER_ADD, - -1, 0, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, ~0u, ~0u, CIPHER_ADD, + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, -1, 0, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0, + CIPHER_ADD, -1, 0, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0, + &head, &tail); } /* Then the legacy non-AEAD ciphers: AES_256_CBC, AES-128_CBC, RC4_128_SHA, * RC4_128_MD5, 3DES_EDE_CBC_SHA. */ - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, ~0u, ~0u, CIPHER_ADD, -1, - 0, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, ~0u, ~0u, CIPHER_ADD, -1, - 0, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, ~SSL_MD5, ~0u, ~0u, CIPHER_ADD, - -1, 0, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, SSL_MD5, ~0u, ~0u, CIPHER_ADD, -1, - 0, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u, CIPHER_ADD, -1, 0, + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, 0, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, 0, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, ~SSL_MD5, 0, CIPHER_ADD, -1, 0, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, SSL_MD5, 0, CIPHER_ADD, -1, 0, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, 0, &head, + &tail); /* Temporarily enable everything else for sorting */ - ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_ADD, -1, 0, - &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0, &head, + &tail); /* Move ciphers without forward secrecy to the end. */ - ssl_cipher_apply_rule(0, ~(SSL_kDHE | SSL_kECDHE), ~0u, ~0u, ~0u, ~0u, ~0u, + ssl_cipher_apply_rule(0, ~(SSL_kDHE | SSL_kECDHE), ~0u, ~0u, ~0u, 0, CIPHER_ORD, -1, 0, &head, &tail); /* Now disable everything (maintaining the ordering!) */ - ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_DEL, -1, 0, - &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0, &head, + &tail); /* If the rule_string begins with DEFAULT, apply the default rule before * using the (possibly available) additional rules. */ @@ -1396,8 +1585,17 @@ int SSL_CIPHER_is_AES128GCM(const SSL_CIPHER *cipher) { return (cipher->algorithm_enc & SSL_AES128GCM) != 0; } +int SSL_CIPHER_is_AES128CBC(const SSL_CIPHER *cipher) { + return (cipher->algorithm_enc & SSL_AES128) != 0; +} + +int SSL_CIPHER_is_AES256CBC(const SSL_CIPHER *cipher) { + return (cipher->algorithm_enc & SSL_AES256) != 0; +} + int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher) { - return (cipher->algorithm_enc & SSL_CHACHA20POLY1305_OLD) != 0; + return (cipher->algorithm_enc & + (SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_OLD)) != 0; } int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher) { @@ -1418,8 +1616,14 @@ int SSL_CIPHER_is_ECDSA(const SSL_CIPHER *cipher) { return (cipher->algorithm_auth & SSL_aECDSA) != 0; } +int SSL_CIPHER_is_ECDHE(const SSL_CIPHER *cipher) { + return (cipher->algorithm_mkey & SSL_kECDHE) != 0; +} + uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) { - if (cipher->algorithm_ssl & SSL_TLSV1_2) { + if (cipher->algorithm_prf != SSL_HANDSHAKE_MAC_DEFAULT) { + /* Cipher suites before TLS 1.2 use the default PRF, while all those added + * afterwards specify a particular hash. */ return TLS1_2_VERSION; } return SSL3_VERSION; @@ -1489,6 +1693,7 @@ static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) { return "AES_128_GCM"; case SSL_AES256GCM: return "AES_256_GCM"; + case SSL_CHACHA20POLY1305: case SSL_CHACHA20POLY1305_OLD: return "CHACHA20_POLY1305"; break; @@ -1554,32 +1759,57 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) { return 0; } + int alg_bits, strength_bits; + switch (cipher->algorithm_enc) { + case SSL_AES128: + case SSL_AES128GCM: + case SSL_RC4: + alg_bits = 128; + strength_bits = 128; + break; + + case SSL_AES256: + case SSL_AES256GCM: +#if !defined(BORINGSSL_ANDROID_SYSTEM) + case SSL_CHACHA20POLY1305_OLD: +#endif + case SSL_CHACHA20POLY1305: + alg_bits = 256; + strength_bits = 256; + break; + + case SSL_3DES: + alg_bits = 168; + strength_bits = 112; + break; + + case SSL_eNULL: + alg_bits = 0; + strength_bits = 0; + break; + + default: + assert(0); + alg_bits = 0; + strength_bits = 0; + } + if (out_alg_bits != NULL) { - *out_alg_bits = cipher->alg_bits; + *out_alg_bits = alg_bits; } - return cipher->strength_bits; + return strength_bits; } const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) { - const char *ver; const char *kx, *au, *enc, *mac; - uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl; - static const char *format = "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n"; + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; + static const char *format = "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n"; alg_mkey = cipher->algorithm_mkey; alg_auth = cipher->algorithm_auth; alg_enc = cipher->algorithm_enc; alg_mac = cipher->algorithm_mac; - alg_ssl = cipher->algorithm_ssl; - - if (alg_ssl & SSL_SSLV3) { - ver = "SSLv3"; - } else if (alg_ssl & SSL_TLSV1_2) { - ver = "TLSv1.2"; - } else { - ver = "unknown"; - } switch (alg_mkey) { case SSL_kRSA: @@ -1646,6 +1876,10 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, break; case SSL_CHACHA20POLY1305_OLD: + enc = "ChaCha20-Poly1305-Old"; + break; + + case SSL_CHACHA20POLY1305: enc = "ChaCha20-Poly1305"; break; @@ -1694,7 +1928,7 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, return "Buffer too small"; } - BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac); + BIO_snprintf(buf, len, format, cipher->name, kx, au, enc, mac); return buf; } diff --git a/src/ssl/ssl_ecdh.c b/src/ssl/ssl_ecdh.c new file mode 100644 index 0000000..45c5b26 --- /dev/null +++ b/src/ssl/ssl_ecdh.c @@ -0,0 +1,383 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <openssl/ssl.h> + +#include <assert.h> +#include <string.h> + +#include <openssl/bn.h> +#include <openssl/bytestring.h> +#include <openssl/curve25519.h> +#include <openssl/ec.h> +#include <openssl/err.h> +#include <openssl/mem.h> +#include <openssl/obj.h> + +#include "internal.h" + + +/* |EC_POINT| implementation. */ + +static void ssl_ec_point_cleanup(SSL_ECDH_CTX *ctx) { + BIGNUM *private_key = (BIGNUM *)ctx->data; + BN_clear_free(private_key); +} + +static int ssl_ec_point_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out) { + assert(ctx->data == NULL); + BIGNUM *private_key = BN_new(); + if (private_key == NULL) { + return 0; + } + ctx->data = private_key; + + /* Set up a shared |BN_CTX| for all operations. */ + BN_CTX *bn_ctx = BN_CTX_new(); + if (bn_ctx == NULL) { + return 0; + } + BN_CTX_start(bn_ctx); + + int ret = 0; + EC_POINT *public_key = NULL; + EC_GROUP *group = EC_GROUP_new_by_curve_name(ctx->method->nid); + if (group == NULL) { + goto err; + } + + /* Generate a private key. */ + const BIGNUM *order = EC_GROUP_get0_order(group); + do { + if (!BN_rand_range(private_key, order)) { + goto err; + } + } while (BN_is_zero(private_key)); + + /* Compute the corresponding public key. */ + public_key = EC_POINT_new(group); + if (public_key == NULL || + !EC_POINT_mul(group, public_key, private_key, NULL, NULL, bn_ctx)) { + goto err; + } + + /* Serialize the public key. */ + size_t len = EC_POINT_point2oct( + group, public_key, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx); + uint8_t *ptr; + if (len == 0 || + !CBB_add_space(out, &ptr, len) || + EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, ptr, + len, bn_ctx) != len) { + goto err; + } + + ret = 1; + +err: + EC_GROUP_free(group); + EC_POINT_free(public_key); + BN_CTX_end(bn_ctx); + BN_CTX_free(bn_ctx); + return ret; +} + +int ssl_ec_point_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret, + size_t *out_secret_len, uint8_t *out_alert, + const uint8_t *peer_key, size_t peer_key_len) { + BIGNUM *private_key = (BIGNUM *)ctx->data; + assert(private_key != NULL); + *out_alert = SSL_AD_INTERNAL_ERROR; + + /* Set up a shared |BN_CTX| for all operations. */ + BN_CTX *bn_ctx = BN_CTX_new(); + if (bn_ctx == NULL) { + return 0; + } + BN_CTX_start(bn_ctx); + + int ret = 0; + EC_GROUP *group = EC_GROUP_new_by_curve_name(ctx->method->nid); + EC_POINT *peer_point = NULL, *result = NULL; + uint8_t *secret = NULL; + if (group == NULL) { + goto err; + } + + /* Compute the x-coordinate of |peer_key| * |private_key|. */ + peer_point = EC_POINT_new(group); + result = EC_POINT_new(group); + if (peer_point == NULL || result == NULL) { + goto err; + } + BIGNUM *x = BN_CTX_get(bn_ctx); + if (x == NULL) { + goto err; + } + if (!EC_POINT_oct2point(group, peer_point, peer_key, peer_key_len, bn_ctx)) { + *out_alert = SSL_AD_DECODE_ERROR; + goto err; + } + if (!EC_POINT_mul(group, result, NULL, peer_point, private_key, bn_ctx) || + !EC_POINT_get_affine_coordinates_GFp(group, result, x, NULL, bn_ctx)) { + goto err; + } + + /* Encode the x-coordinate left-padded with zeros. */ + size_t secret_len = (EC_GROUP_get_degree(group) + 7) / 8; + secret = OPENSSL_malloc(secret_len); + if (secret == NULL || !BN_bn2bin_padded(secret, secret_len, x)) { + goto err; + } + + *out_secret = secret; + *out_secret_len = secret_len; + secret = NULL; + ret = 1; + +err: + EC_GROUP_free(group); + EC_POINT_free(peer_point); + EC_POINT_free(result); + BN_CTX_end(bn_ctx); + BN_CTX_free(bn_ctx); + OPENSSL_free(secret); + return ret; +} + + +/* X25119 implementation. */ + +static void ssl_x25519_cleanup(SSL_ECDH_CTX *ctx) { + if (ctx->data == NULL) { + return; + } + OPENSSL_cleanse(ctx->data, 32); + OPENSSL_free(ctx->data); +} + +static int ssl_x25519_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out) { + assert(ctx->data == NULL); + + ctx->data = OPENSSL_malloc(32); + if (ctx->data == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + uint8_t public_key[32]; + X25519_keypair(public_key, (uint8_t *)ctx->data); + return CBB_add_bytes(out, public_key, sizeof(public_key)); +} + +static int ssl_x25519_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret, + size_t *out_secret_len, uint8_t *out_alert, + const uint8_t *peer_key, + size_t peer_key_len) { + assert(ctx->data != NULL); + *out_alert = SSL_AD_INTERNAL_ERROR; + + uint8_t *secret = OPENSSL_malloc(32); + if (secret == NULL) { + return 0; + } + + if (peer_key_len != 32 || + !X25519(secret, (uint8_t *)ctx->data, peer_key)) { + OPENSSL_free(secret); + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + return 0; + } + + *out_secret = secret; + *out_secret_len = 32; + return 1; +} + + +/* Legacy DHE-based implementation. */ + +static void ssl_dhe_cleanup(SSL_ECDH_CTX *ctx) { + DH_free((DH *)ctx->data); +} + +static int ssl_dhe_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out) { + DH *dh = (DH *)ctx->data; + /* The group must have been initialized already, but not the key. */ + assert(dh != NULL); + assert(dh->priv_key == NULL); + + /* Due to a bug in yaSSL, the public key must be zero padded to the size of + * the prime. */ + return DH_generate_key(dh) && + BN_bn2cbb_padded(out, BN_num_bytes(dh->p), dh->pub_key); +} + +static int ssl_dhe_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret, + size_t *out_secret_len, uint8_t *out_alert, + const uint8_t *peer_key, + size_t peer_key_len) { + DH *dh = (DH *)ctx->data; + assert(dh != NULL); + assert(dh->priv_key != NULL); + *out_alert = SSL_AD_INTERNAL_ERROR; + + int secret_len = 0; + uint8_t *secret = NULL; + BIGNUM *peer_point = BN_bin2bn(peer_key, peer_key_len, NULL); + if (peer_point == NULL) { + goto err; + } + + secret = OPENSSL_malloc(DH_size(dh)); + if (secret == NULL) { + goto err; + } + secret_len = DH_compute_key(secret, peer_point, dh); + if (secret_len <= 0) { + goto err; + } + + *out_secret = secret; + *out_secret_len = (size_t)secret_len; + BN_free(peer_point); + return 1; + +err: + if (secret_len > 0) { + OPENSSL_cleanse(secret, (size_t)secret_len); + } + OPENSSL_free(secret); + BN_free(peer_point); + return 0; +} + +static const SSL_ECDH_METHOD kDHEMethod = { + NID_undef, 0, "", + ssl_dhe_cleanup, + ssl_dhe_generate_keypair, + ssl_dhe_compute_secret, +}; + + +static const SSL_ECDH_METHOD kMethods[] = { + { + NID_X9_62_prime256v1, + SSL_CURVE_SECP256R1, + "P-256", + ssl_ec_point_cleanup, + ssl_ec_point_generate_keypair, + ssl_ec_point_compute_secret, + }, + { + NID_secp384r1, + SSL_CURVE_SECP384R1, + "P-384", + ssl_ec_point_cleanup, + ssl_ec_point_generate_keypair, + ssl_ec_point_compute_secret, + }, + { + NID_secp521r1, + SSL_CURVE_SECP521R1, + "P-521", + ssl_ec_point_cleanup, + ssl_ec_point_generate_keypair, + ssl_ec_point_compute_secret, + }, + { + NID_x25519, + SSL_CURVE_ECDH_X25519, + "X25519", + ssl_x25519_cleanup, + ssl_x25519_generate_keypair, + ssl_x25519_compute_secret, + }, +}; + +static const SSL_ECDH_METHOD *method_from_curve_id(uint16_t curve_id) { + size_t i; + for (i = 0; i < sizeof(kMethods) / sizeof(kMethods[0]); i++) { + if (kMethods[i].curve_id == curve_id) { + return &kMethods[i]; + } + } + return NULL; +} + +static const SSL_ECDH_METHOD *method_from_nid(int nid) { + size_t i; + for (i = 0; i < sizeof(kMethods) / sizeof(kMethods[0]); i++) { + if (kMethods[i].nid == nid) { + return &kMethods[i]; + } + } + return NULL; +} + +const char* SSL_get_curve_name(uint16_t curve_id) { + const SSL_ECDH_METHOD *method = method_from_curve_id(curve_id); + if (method == NULL) { + return NULL; + } + return method->name; +} + +int ssl_nid_to_curve_id(uint16_t *out_curve_id, int nid) { + const SSL_ECDH_METHOD *method = method_from_nid(nid); + if (method == NULL) { + return 0; + } + *out_curve_id = method->curve_id; + return 1; +} + +int SSL_ECDH_CTX_init(SSL_ECDH_CTX *ctx, uint16_t curve_id) { + SSL_ECDH_CTX_cleanup(ctx); + + const SSL_ECDH_METHOD *method = method_from_curve_id(curve_id); + if (method == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + return 0; + } + ctx->method = method; + return 1; +} + +void SSL_ECDH_CTX_init_for_dhe(SSL_ECDH_CTX *ctx, DH *params) { + SSL_ECDH_CTX_cleanup(ctx); + + ctx->method = &kDHEMethod; + ctx->data = params; +} + +void SSL_ECDH_CTX_cleanup(SSL_ECDH_CTX *ctx) { + if (ctx->method == NULL) { + return; + } + ctx->method->cleanup(ctx); + ctx->method = NULL; + ctx->data = NULL; +} + +int SSL_ECDH_CTX_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out_public_key) { + return ctx->method->generate_keypair(ctx, out_public_key); +} + +int SSL_ECDH_CTX_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret, + size_t *out_secret_len, uint8_t *out_alert, + const uint8_t *peer_key, size_t peer_key_len) { + return ctx->method->compute_secret(ctx, out_secret, out_secret_len, out_alert, + peer_key, peer_key_len); +} diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c index c78a91a..08578a6 100644 --- a/src/ssl/ssl_lib.c +++ b/src/ssl/ssl_lib.c @@ -274,7 +274,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) { goto err; } - CRYPTO_new_ex_data(&g_ex_data_class_ssl_ctx, ret, &ret->ex_data); + CRYPTO_new_ex_data(&ret->ex_data); ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; @@ -285,10 +285,6 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) { ret->options |= SSL_OP_NO_TICKET; } - /* Default is to connect to non-RI servers. When RI is more widely deployed - * might change this. */ - ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; - /* Lock the SSL_CTX to the specified version, for compatibility with legacy * uses of SSL_METHOD. */ if (method->version != 0) { @@ -343,14 +339,11 @@ void SSL_CTX_free(SSL_CTX *ctx) { OPENSSL_free(ctx->ocsp_response); OPENSSL_free(ctx->signed_cert_timestamp_list); EVP_PKEY_free(ctx->tlsext_channel_id_private); - BIO_free(ctx->keylog_bio); OPENSSL_free(ctx); } SSL *SSL_new(SSL_CTX *ctx) { - SSL *s; - if (ctx == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX); return NULL; @@ -360,100 +353,101 @@ SSL *SSL_new(SSL_CTX *ctx) { return NULL; } - s = (SSL *)OPENSSL_malloc(sizeof(SSL)); - if (s == NULL) { + SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL)); + if (ssl == NULL) { goto err; } - memset(s, 0, sizeof(SSL)); + memset(ssl, 0, sizeof(SSL)); - s->min_version = ctx->min_version; - s->max_version = ctx->max_version; + ssl->min_version = ctx->min_version; + ssl->max_version = ctx->max_version; - s->options = ctx->options; - s->mode = ctx->mode; - s->max_cert_list = ctx->max_cert_list; + ssl->options = ctx->options; + ssl->mode = ctx->mode; + ssl->max_cert_list = ctx->max_cert_list; - s->cert = ssl_cert_dup(ctx->cert); - if (s->cert == NULL) { + ssl->cert = ssl_cert_dup(ctx->cert); + if (ssl->cert == NULL) { goto err; } - s->msg_callback = ctx->msg_callback; - s->msg_callback_arg = ctx->msg_callback_arg; - s->verify_mode = ctx->verify_mode; - s->sid_ctx_length = ctx->sid_ctx_length; - assert(s->sid_ctx_length <= sizeof s->sid_ctx); - memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx)); - s->verify_callback = ctx->default_verify_callback; + ssl->msg_callback = ctx->msg_callback; + ssl->msg_callback_arg = ctx->msg_callback_arg; + ssl->verify_mode = ctx->verify_mode; + ssl->sid_ctx_length = ctx->sid_ctx_length; + assert(ssl->sid_ctx_length <= sizeof ssl->sid_ctx); + memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx)); + ssl->verify_callback = ctx->default_verify_callback; - s->param = X509_VERIFY_PARAM_new(); - if (!s->param) { + ssl->param = X509_VERIFY_PARAM_new(); + if (!ssl->param) { goto err; } - X509_VERIFY_PARAM_inherit(s->param, ctx->param); - s->quiet_shutdown = ctx->quiet_shutdown; - s->max_send_fragment = ctx->max_send_fragment; + X509_VERIFY_PARAM_inherit(ssl->param, ctx->param); + ssl->quiet_shutdown = ctx->quiet_shutdown; + ssl->max_send_fragment = ctx->max_send_fragment; CRYPTO_refcount_inc(&ctx->references); - s->ctx = ctx; + ssl->ctx = ctx; CRYPTO_refcount_inc(&ctx->references); - s->initial_ctx = ctx; + ssl->initial_ctx = ctx; if (ctx->tlsext_ellipticcurvelist) { - s->tlsext_ellipticcurvelist = + ssl->tlsext_ellipticcurvelist = BUF_memdup(ctx->tlsext_ellipticcurvelist, ctx->tlsext_ellipticcurvelist_length * 2); - if (!s->tlsext_ellipticcurvelist) { + if (!ssl->tlsext_ellipticcurvelist) { goto err; } - s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length; + ssl->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length; } - if (s->ctx->alpn_client_proto_list) { - s->alpn_client_proto_list = BUF_memdup(s->ctx->alpn_client_proto_list, - s->ctx->alpn_client_proto_list_len); - if (s->alpn_client_proto_list == NULL) { + if (ssl->ctx->alpn_client_proto_list) { + ssl->alpn_client_proto_list = BUF_memdup( + ssl->ctx->alpn_client_proto_list, ssl->ctx->alpn_client_proto_list_len); + if (ssl->alpn_client_proto_list == NULL) { goto err; } - s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len; + ssl->alpn_client_proto_list_len = ssl->ctx->alpn_client_proto_list_len; } - s->verify_result = X509_V_OK; - s->method = ctx->method; + ssl->verify_result = X509_V_OK; + ssl->method = ctx->method; - if (!s->method->ssl_new(s)) { + if (!ssl->method->ssl_new(ssl)) { goto err; } - s->enc_method = ssl3_get_enc_method(s->version); - assert(s->enc_method != NULL); + ssl->enc_method = ssl3_get_enc_method(ssl->version); + assert(ssl->enc_method != NULL); - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; - CRYPTO_new_ex_data(&g_ex_data_class_ssl, s, &s->ex_data); + CRYPTO_new_ex_data(&ssl->ex_data); - s->psk_identity_hint = NULL; + ssl->psk_identity_hint = NULL; if (ctx->psk_identity_hint) { - s->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint); - if (s->psk_identity_hint == NULL) { + ssl->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint); + if (ssl->psk_identity_hint == NULL) { goto err; } } - s->psk_client_callback = ctx->psk_client_callback; - s->psk_server_callback = ctx->psk_server_callback; + ssl->psk_client_callback = ctx->psk_client_callback; + ssl->psk_server_callback = ctx->psk_server_callback; - s->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled; + ssl->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled; if (ctx->tlsext_channel_id_private) { - s->tlsext_channel_id_private = + ssl->tlsext_channel_id_private = EVP_PKEY_up_ref(ctx->tlsext_channel_id_private); } - s->signed_cert_timestamps_enabled = s->ctx->signed_cert_timestamps_enabled; - s->ocsp_stapling_enabled = s->ctx->ocsp_stapling_enabled; + ssl->signed_cert_timestamps_enabled = + ssl->ctx->signed_cert_timestamps_enabled; + ssl->ocsp_stapling_enabled = ssl->ctx->ocsp_stapling_enabled; - return s; + return ssl; err: - SSL_free(s); + SSL_free(ssl); OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return NULL; @@ -745,8 +739,8 @@ int SSL_get_error(const SSL *ssl, int ret_code) { /* This one doesn't make too much sense ... We never try to write to the * rbio, and an application program where rbio and wbio are separate * couldn't even know what it should wait for. However if we ever set - * s->rwstate incorrectly (so that we have SSL_want_read(s) instead of - * SSL_want_write(s)) and rbio and wbio *are* the same, this test works + * ssl->rwstate incorrectly (so that we have SSL_want_read(ssl) instead of + * SSL_want_write(ssl)) and rbio and wbio *are* the same, this test works * around that bug; so it might be safer to keep it. */ return SSL_ERROR_WANT_WRITE; } @@ -976,61 +970,6 @@ void ssl_cipher_preference_list_free( OPENSSL_free(cipher_list); } -struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup( - struct ssl_cipher_preference_list_st *cipher_list) { - struct ssl_cipher_preference_list_st *ret = NULL; - size_t n = sk_SSL_CIPHER_num(cipher_list->ciphers); - - ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st)); - if (!ret) { - goto err; - } - - ret->ciphers = NULL; - ret->in_group_flags = NULL; - ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers); - if (!ret->ciphers) { - goto err; - } - ret->in_group_flags = BUF_memdup(cipher_list->in_group_flags, n); - if (!ret->in_group_flags) { - goto err; - } - - return ret; - -err: - ssl_cipher_preference_list_free(ret); - return NULL; -} - -struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_from_ciphers( - STACK_OF(SSL_CIPHER) *ciphers) { - struct ssl_cipher_preference_list_st *ret = NULL; - size_t n = sk_SSL_CIPHER_num(ciphers); - - ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st)); - if (!ret) { - goto err; - } - ret->ciphers = NULL; - ret->in_group_flags = NULL; - ret->ciphers = sk_SSL_CIPHER_dup(ciphers); - if (!ret->ciphers) { - goto err; - } - ret->in_group_flags = OPENSSL_malloc(n); - if (!ret->in_group_flags) { - goto err; - } - memset(ret->in_group_flags, 0, n); - return ret; - -err: - ssl_cipher_preference_list_free(ret); - return NULL; -} - X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; } X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; } @@ -1169,11 +1108,11 @@ void SSL_set_verify_depth(SSL *ssl, int depth) { int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; } -int SSL_get_read_ahead(const SSL *s) { return 0; } +int SSL_get_read_ahead(const SSL *ssl) { return 0; } void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { } -void SSL_set_read_ahead(SSL *s, int yes) { } +void SSL_set_read_ahead(SSL *ssl, int yes) { } int SSL_pending(const SSL *ssl) { if (ssl->s3->rrec.type != SSL3_RT_APPLICATION_DATA) { @@ -1334,17 +1273,17 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) { /* return a STACK of the ciphers available for the SSL and in order of * algorithm id */ -STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) { - if (s == NULL) { +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *ssl) { + if (ssl == NULL) { return NULL; } - if (s->cipher_list_by_id != NULL) { - return s->cipher_list_by_id; + if (ssl->cipher_list_by_id != NULL) { + return ssl->cipher_list_by_id; } - if (s->ctx != NULL && s->ctx->cipher_list_by_id != NULL) { - return s->ctx->cipher_list_by_id; + if (ssl->ctx != NULL && ssl->ctx->cipher_list_by_id != NULL) { + return ssl->ctx->cipher_list_by_id; } return NULL; @@ -1435,13 +1374,13 @@ int SSL_set_cipher_list(SSL *ssl, const char *str) { return 1; } -STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) { +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *ssl, const CBS *cbs) { CBS cipher_suites = *cbs; const SSL_CIPHER *c; STACK_OF(SSL_CIPHER) *sk; - if (s->s3) { - s->s3->send_connection_binding = 0; + if (ssl->s3) { + ssl->s3->send_connection_binding = 0; } if (CBS_len(&cipher_suites) % 2 != 0) { @@ -1464,24 +1403,24 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) { } /* Check for SCSV. */ - if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) { + if (ssl->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) { /* SCSV is fatal if renegotiating. */ - if (s->s3->initial_handshake_complete) { + if (ssl->s3->initial_handshake_complete) { OPENSSL_PUT_ERROR(SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); goto err; } - s->s3->send_connection_binding = 1; + ssl->s3->send_connection_binding = 1; continue; } /* Check for FALLBACK_SCSV. */ - if (s->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) { - uint16_t max_version = ssl3_get_max_server_version(s); - if (SSL_IS_DTLS(s) ? (uint16_t)s->version > max_version - : (uint16_t)s->version < max_version) { + if (ssl->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) { + uint16_t max_version = ssl3_get_max_server_version(ssl); + if (SSL_IS_DTLS(ssl) ? (uint16_t)ssl->version > max_version + : (uint16_t)ssl->version < max_version) { OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK); goto err; } continue; @@ -1743,9 +1682,9 @@ void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) { ssl_cert_set_cert_cb(ssl->cert, cb, arg); } -void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k, +void ssl_get_compatible_server_ciphers(SSL *ssl, uint32_t *out_mask_k, uint32_t *out_mask_a) { - CERT *c = s->cert; + CERT *c = ssl->cert; int have_rsa_cert = 0, dh_tmp; uint32_t mask_k, mask_a; int have_ecc_cert = 0, ecdsa_ok; @@ -1753,10 +1692,10 @@ void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k, dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL); - if (s->cert->x509 != NULL && ssl_has_private_key(s)) { - if (ssl_private_key_type(s) == EVP_PKEY_RSA) { + if (ssl->cert->x509 != NULL && ssl_has_private_key(ssl)) { + if (ssl_private_key_type(ssl) == EVP_PKEY_RSA) { have_rsa_cert = 1; - } else if (ssl_private_key_type(s) == EVP_PKEY_EC) { + } else if (ssl_private_key_type(ssl) == EVP_PKEY_EC) { have_ecc_cert = 1; } } @@ -1781,7 +1720,7 @@ void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k, ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; - if (!tls1_check_ec_cert(s, x)) { + if (!tls1_check_ec_cert(ssl, x)) { ecdsa_ok = 0; } if (ecdsa_ok) { @@ -1790,13 +1729,14 @@ void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k, } /* If we are considering an ECC cipher suite that uses an ephemeral EC - * key, check it. */ - if (tls1_check_ec_tmp_key(s)) { + * key, check for a shared curve. */ + uint16_t unused; + if (tls1_get_shared_curve(ssl, &unused)) { mask_k |= SSL_kECDHE; } /* PSK requires a server callback. */ - if (s->psk_server_callback != NULL) { + if (ssl->psk_server_callback != NULL) { mask_k |= SSL_kPSK; mask_a |= SSL_aPSK; } @@ -1882,28 +1822,24 @@ const char *SSL_SESSION_get_version(const SSL_SESSION *session) { return ssl_get_version(session->ssl_version); } -const char* SSL_get_curve_name(uint16_t curve_id) { - return tls1_ec_curve_id2name(curve_id); +void ssl_clear_cipher_ctx(SSL *ssl) { + SSL_AEAD_CTX_free(ssl->aead_read_ctx); + ssl->aead_read_ctx = NULL; + SSL_AEAD_CTX_free(ssl->aead_write_ctx); + ssl->aead_write_ctx = NULL; } -void ssl_clear_cipher_ctx(SSL *s) { - SSL_AEAD_CTX_free(s->aead_read_ctx); - s->aead_read_ctx = NULL; - SSL_AEAD_CTX_free(s->aead_write_ctx); - s->aead_write_ctx = NULL; -} - -X509 *SSL_get_certificate(const SSL *s) { - if (s->cert != NULL) { - return s->cert->x509; +X509 *SSL_get_certificate(const SSL *ssl) { + if (ssl->cert != NULL) { + return ssl->cert->x509; } return NULL; } -EVP_PKEY *SSL_get_privatekey(const SSL *s) { - if (s->cert != NULL) { - return s->cert->privatekey; +EVP_PKEY *SSL_get_privatekey(const SSL *ssl) { + if (ssl->cert != NULL) { + return ssl->cert->privatekey; } return NULL; @@ -1932,23 +1868,23 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) { return ssl->aead_write_ctx->cipher; } -const COMP_METHOD *SSL_get_current_compression(SSL *s) { return NULL; } +const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; } -const COMP_METHOD *SSL_get_current_expansion(SSL *s) { return NULL; } +const COMP_METHOD *SSL_get_current_expansion(SSL *ssl) { return NULL; } -int ssl_init_wbio_buffer(SSL *s, int push) { +int ssl_init_wbio_buffer(SSL *ssl, int push) { BIO *bbio; - if (s->bbio == NULL) { + if (ssl->bbio == NULL) { bbio = BIO_new(BIO_f_buffer()); if (bbio == NULL) { return 0; } - s->bbio = bbio; + ssl->bbio = bbio; } else { - bbio = s->bbio; - if (s->bbio == s->wbio) { - s->wbio = BIO_pop(s->wbio); + bbio = ssl->bbio; + if (ssl->bbio == ssl->wbio) { + ssl->wbio = BIO_pop(ssl->wbio); } } @@ -1959,30 +1895,30 @@ int ssl_init_wbio_buffer(SSL *s, int push) { } if (push) { - if (s->wbio != bbio) { - s->wbio = BIO_push(bbio, s->wbio); + if (ssl->wbio != bbio) { + ssl->wbio = BIO_push(bbio, ssl->wbio); } } else { - if (s->wbio == bbio) { - s->wbio = BIO_pop(bbio); + if (ssl->wbio == bbio) { + ssl->wbio = BIO_pop(bbio); } } return 1; } -void ssl_free_wbio_buffer(SSL *s) { - if (s->bbio == NULL) { +void ssl_free_wbio_buffer(SSL *ssl) { + if (ssl->bbio == NULL) { return; } - if (s->bbio == s->wbio) { + if (ssl->bbio == ssl->wbio) { /* remove buffering */ - s->wbio = BIO_pop(s->wbio); + ssl->wbio = BIO_pop(ssl->wbio); } - BIO_free(s->bbio); - s->bbio = NULL; + BIO_free(ssl->bbio); + ssl->bbio = NULL; } void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) { @@ -2065,11 +2001,11 @@ void SSL_set_verify_result(SSL *ssl, long result) { long SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; } -int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int index; if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl, &index, argl, argp, - new_func, dup_func, free_func)) { + dup_func, free_func)) { return -1; } return index; @@ -2083,12 +2019,12 @@ void *SSL_get_ex_data(const SSL *ssl, int idx) { return CRYPTO_get_ex_data(&ssl->ex_data, idx); } -int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int index; if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl_ctx, &index, argl, argp, - new_func, dup_func, free_func)) { + dup_func, free_func)) { return -1; } return index; @@ -2133,18 +2069,6 @@ void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*callback)(SSL *ssl, int is_export, ssl->cert->dh_tmp_cb = callback; } -void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, - EC_KEY *(*callback)(SSL *ssl, int is_export, - int keylength)) { - ctx->cert->ecdh_tmp_cb = callback; -} - -void SSL_set_tmp_ecdh_callback(SSL *ssl, - EC_KEY *(*callback)(SSL *ssl, int is_export, - int keylength)) { - ssl->cert->ecdh_tmp_cb = callback; -} - int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) { if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); @@ -2252,9 +2176,9 @@ void SSL_set_msg_callback_arg(SSL *ssl, void *arg) { ssl->msg_callback_arg = arg; } -void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio) { - BIO_free(ctx->keylog_bio); - ctx->keylog_bio = keylog_bio; +void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, const char *line)) { + ctx->keylog_callback = cb; } static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) { @@ -2274,18 +2198,12 @@ static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) { return 1; } -int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx, - const uint8_t *encrypted_premaster, - size_t encrypted_premaster_len, - const uint8_t *premaster, - size_t premaster_len) { - BIO *bio = ctx->keylog_bio; - CBB cbb; - uint8_t *out; - size_t out_len; - int ret; - - if (bio == NULL) { +int ssl_log_rsa_client_key_exchange(const SSL *ssl, + const uint8_t *encrypted_premaster, + size_t encrypted_premaster_len, + const uint8_t *premaster, + size_t premaster_len) { + if (ssl->ctx->keylog_callback == NULL) { return 1; } @@ -2294,7 +2212,9 @@ int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx, return 0; } - CBB_zero(&cbb); + CBB cbb; + uint8_t *out; + size_t out_len; if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1) || !CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) || /* Only the first 8 bytes of the encrypted premaster secret are @@ -2302,30 +2222,21 @@ int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx, !cbb_add_hex(&cbb, encrypted_premaster, 8) || !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) || !cbb_add_hex(&cbb, premaster, premaster_len) || - !CBB_add_bytes(&cbb, (const uint8_t *)"\n", 1) || + !CBB_add_u8(&cbb, 0 /* NUL */) || !CBB_finish(&cbb, &out, &out_len)) { CBB_cleanup(&cbb); return 0; } - CRYPTO_MUTEX_lock_write(&ctx->lock); - ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio); - CRYPTO_MUTEX_unlock(&ctx->lock); - + ssl->ctx->keylog_callback(ssl, (const char *)out); OPENSSL_free(out); - return ret; + return 1; } -int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random, - size_t client_random_len, const uint8_t *master, - size_t master_len) { - BIO *bio = ctx->keylog_bio; - CBB cbb; - uint8_t *out; - size_t out_len; - int ret; - - if (bio == NULL) { +int ssl_log_master_secret(const SSL *ssl, const uint8_t *client_random, + size_t client_random_len, const uint8_t *master, + size_t master_len) { + if (ssl->ctx->keylog_callback == NULL) { return 1; } @@ -2334,24 +2245,23 @@ int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random, return 0; } - CBB_zero(&cbb); + CBB cbb; + uint8_t *out; + size_t out_len; if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1) || !CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) || !cbb_add_hex(&cbb, client_random, 32) || !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) || !cbb_add_hex(&cbb, master, master_len) || - !CBB_add_bytes(&cbb, (const uint8_t *)"\n", 1) || + !CBB_add_u8(&cbb, 0 /* NUL */) || !CBB_finish(&cbb, &out, &out_len)) { CBB_cleanup(&cbb); return 0; } - CRYPTO_MUTEX_lock_write(&ctx->lock); - ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio); - CRYPTO_MUTEX_unlock(&ctx->lock); - + ssl->ctx->keylog_callback(ssl, (const char *)out); OPENSSL_free(out); - return ret; + return 1; } int SSL_is_init_finished(const SSL *ssl) { @@ -2366,8 +2276,8 @@ int SSL_in_false_start(const SSL *ssl) { return ssl->s3->tmp.in_false_start; } -int SSL_cutthrough_complete(const SSL *s) { - return SSL_in_false_start(s); +int SSL_cutthrough_complete(const SSL *ssl) { + return SSL_in_false_start(ssl); } void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size, @@ -2377,18 +2287,16 @@ void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size, *ssl_session_size = sizeof(SSL_SESSION); } -int ssl3_can_false_start(const SSL *s) { - const SSL_CIPHER *const cipher = SSL_get_current_cipher(s); +int ssl3_can_false_start(const SSL *ssl) { + const SSL_CIPHER *const cipher = SSL_get_current_cipher(ssl); /* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */ - return !SSL_IS_DTLS(s) && - SSL_version(s) >= TLS1_2_VERSION && - (s->s3->alpn_selected || s->s3->next_proto_neg_seen) && + return !SSL_IS_DTLS(ssl) && + SSL_version(ssl) >= TLS1_2_VERSION && + (ssl->s3->alpn_selected || ssl->s3->next_proto_neg_seen) && cipher != NULL && cipher->algorithm_mkey == SSL_kECDHE && - (cipher->algorithm_enc == SSL_AES128GCM || - cipher->algorithm_enc == SSL_AES256GCM || - cipher->algorithm_enc == SSL_CHACHA20POLY1305_OLD); + cipher->algorithm_mac == SSL_AEAD; } const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) { @@ -2412,84 +2320,89 @@ const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) { } } -uint16_t ssl3_get_max_server_version(const SSL *s) { +uint16_t ssl3_get_max_server_version(const SSL *ssl) { uint16_t max_version; - if (SSL_IS_DTLS(s)) { - max_version = (s->max_version != 0) ? s->max_version : DTLS1_2_VERSION; - if (!(s->options & SSL_OP_NO_DTLSv1_2) && DTLS1_2_VERSION >= max_version) { + if (SSL_IS_DTLS(ssl)) { + max_version = (ssl->max_version != 0) ? ssl->max_version : DTLS1_2_VERSION; + if (!(ssl->options & SSL_OP_NO_DTLSv1_2) && + DTLS1_2_VERSION >= max_version) { return DTLS1_2_VERSION; } - if (!(s->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) { + if (!(ssl->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) { return DTLS1_VERSION; } return 0; } - max_version = (s->max_version != 0) ? s->max_version : TLS1_2_VERSION; - if (!(s->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) { + max_version = (ssl->max_version != 0) ? ssl->max_version : TLS1_2_VERSION; + if (!(ssl->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) { return TLS1_2_VERSION; } - if (!(s->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) { + if (!(ssl->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) { return TLS1_1_VERSION; } - if (!(s->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) { + if (!(ssl->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) { return TLS1_VERSION; } - if (!(s->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) { + if (!(ssl->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) { return SSL3_VERSION; } return 0; } -uint16_t ssl3_get_mutual_version(SSL *s, uint16_t client_version) { +uint16_t ssl3_get_mutual_version(SSL *ssl, uint16_t client_version) { uint16_t version = 0; - if (SSL_IS_DTLS(s)) { + if (SSL_IS_DTLS(ssl)) { /* Clamp client_version to max_version. */ - if (s->max_version != 0 && client_version < s->max_version) { - client_version = s->max_version; + if (ssl->max_version != 0 && client_version < ssl->max_version) { + client_version = ssl->max_version; } - if (client_version <= DTLS1_2_VERSION && !(s->options & SSL_OP_NO_DTLSv1_2)) { + if (client_version <= DTLS1_2_VERSION && + !(ssl->options & SSL_OP_NO_DTLSv1_2)) { version = DTLS1_2_VERSION; } else if (client_version <= DTLS1_VERSION && - !(s->options & SSL_OP_NO_DTLSv1)) { + !(ssl->options & SSL_OP_NO_DTLSv1)) { version = DTLS1_VERSION; } /* Check against min_version. */ - if (version != 0 && s->min_version != 0 && version > s->min_version) { + if (version != 0 && ssl->min_version != 0 && version > ssl->min_version) { return 0; } return version; } else { /* Clamp client_version to max_version. */ - if (s->max_version != 0 && client_version > s->max_version) { - client_version = s->max_version; + if (ssl->max_version != 0 && client_version > ssl->max_version) { + client_version = ssl->max_version; } - if (client_version >= TLS1_2_VERSION && !(s->options & SSL_OP_NO_TLSv1_2)) { + if (client_version >= TLS1_2_VERSION && + !(ssl->options & SSL_OP_NO_TLSv1_2)) { version = TLS1_2_VERSION; } else if (client_version >= TLS1_1_VERSION && - !(s->options & SSL_OP_NO_TLSv1_1)) { + !(ssl->options & SSL_OP_NO_TLSv1_1)) { version = TLS1_1_VERSION; - } else if (client_version >= TLS1_VERSION && !(s->options & SSL_OP_NO_TLSv1)) { + } else if (client_version >= TLS1_VERSION && + !(ssl->options & SSL_OP_NO_TLSv1)) { version = TLS1_VERSION; - } else if (client_version >= SSL3_VERSION && !(s->options & SSL_OP_NO_SSLv3)) { + } else if (client_version >= SSL3_VERSION && + !(ssl->options & SSL_OP_NO_SSLv3)) { version = SSL3_VERSION; } /* Check against min_version. */ - if (version != 0 && s->min_version != 0 && version < s->min_version) { + if (version != 0 && ssl->min_version != 0 && version < ssl->min_version) { return 0; } return version; } } -uint16_t ssl3_get_max_client_version(SSL *s) { - uint32_t options = s->options; +uint16_t ssl3_get_max_client_version(SSL *ssl) { + uint32_t options = ssl->options; uint16_t version = 0; /* OpenSSL's API for controlling versions entails blacklisting individual @@ -2505,15 +2418,15 @@ uint16_t ssl3_get_max_client_version(SSL *s) { * * By this scheme, the maximum version is the lowest version V such that V is * enabled and V+1 is disabled or unimplemented. */ - if (SSL_IS_DTLS(s)) { + if (SSL_IS_DTLS(ssl)) { if (!(options & SSL_OP_NO_DTLSv1_2)) { version = DTLS1_2_VERSION; } if (!(options & SSL_OP_NO_DTLSv1) && (options & SSL_OP_NO_DTLSv1_2)) { version = DTLS1_VERSION; } - if (s->max_version != 0 && version < s->max_version) { - version = s->max_version; + if (ssl->max_version != 0 && version < ssl->max_version) { + version = ssl->max_version; } } else { if (!(options & SSL_OP_NO_TLSv1_2)) { @@ -2528,53 +2441,53 @@ uint16_t ssl3_get_max_client_version(SSL *s) { if (!(options & SSL_OP_NO_SSLv3) && (options & SSL_OP_NO_TLSv1)) { version = SSL3_VERSION; } - if (s->max_version != 0 && version > s->max_version) { - version = s->max_version; + if (ssl->max_version != 0 && version > ssl->max_version) { + version = ssl->max_version; } } return version; } -int ssl3_is_version_enabled(SSL *s, uint16_t version) { - if (SSL_IS_DTLS(s)) { - if (s->max_version != 0 && version < s->max_version) { +int ssl3_is_version_enabled(SSL *ssl, uint16_t version) { + if (SSL_IS_DTLS(ssl)) { + if (ssl->max_version != 0 && version < ssl->max_version) { return 0; } - if (s->min_version != 0 && version > s->min_version) { + if (ssl->min_version != 0 && version > ssl->min_version) { return 0; } switch (version) { case DTLS1_VERSION: - return !(s->options & SSL_OP_NO_DTLSv1); + return !(ssl->options & SSL_OP_NO_DTLSv1); case DTLS1_2_VERSION: - return !(s->options & SSL_OP_NO_DTLSv1_2); + return !(ssl->options & SSL_OP_NO_DTLSv1_2); default: return 0; } } else { - if (s->max_version != 0 && version > s->max_version) { + if (ssl->max_version != 0 && version > ssl->max_version) { return 0; } - if (s->min_version != 0 && version < s->min_version) { + if (ssl->min_version != 0 && version < ssl->min_version) { return 0; } switch (version) { case SSL3_VERSION: - return !(s->options & SSL_OP_NO_SSLv3); + return !(ssl->options & SSL_OP_NO_SSLv3); case TLS1_VERSION: - return !(s->options & SSL_OP_NO_TLSv1); + return !(ssl->options & SSL_OP_NO_TLSv1); case TLS1_1_VERSION: - return !(s->options & SSL_OP_NO_TLSv1_1); + return !(ssl->options & SSL_OP_NO_TLSv1_1); case TLS1_2_VERSION: - return !(s->options & SSL_OP_NO_TLSv1_2); + return !(ssl->options & SSL_OP_NO_TLSv1_2); default: return 0; @@ -2582,8 +2495,8 @@ int ssl3_is_version_enabled(SSL *s, uint16_t version) { } } -uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version) { - if (!SSL_IS_DTLS(s)) { +uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version) { + if (!SSL_IS_DTLS(ssl)) { return wire_version; } diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c index 512a41f..990979b 100644 --- a/src/ssl/ssl_rsa.c +++ b/src/ssl/ssl_rsa.c @@ -56,6 +56,8 @@ #include <openssl/ssl.h> +#include <limits.h> + #include <openssl/err.h> #include <openssl/evp.h> #include <openssl/mem.h> @@ -79,18 +81,22 @@ int SSL_use_certificate(SSL *ssl, X509 *x) { return ssl_set_cert(ssl->cert, x); } -int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d, int len) { - X509 *x; - int ret; +int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } - x = d2i_X509(NULL, &d, (long)len); - if (x == NULL) { + const uint8_t *p = der; + X509 *x509 = d2i_X509(NULL, &p, (long)der_len); + if (x509 == NULL || p != der + der_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + X509_free(x509); return 0; } - ret = SSL_use_certificate(ssl, x); - X509_free(x); + int ret = SSL_use_certificate(ssl, x509); + X509_free(x509); return ret; } @@ -165,19 +171,22 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { return ret; } -int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) { - int ret; - const uint8_t *p; - EVP_PKEY *pkey; +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } - p = d; - pkey = d2i_PrivateKey(type, NULL, &p, (long)len); - if (pkey == NULL) { + const uint8_t *p = der; + EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len); + if (pkey == NULL || p != der + der_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + EVP_PKEY_free(pkey); return 0; } - ret = SSL_use_PrivateKey(ssl, pkey); + int ret = SSL_use_PrivateKey(ssl, pkey); EVP_PKEY_free(pkey); return ret; } @@ -227,18 +236,23 @@ static int ssl_set_cert(CERT *c, X509 *x) { return 1; } -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const uint8_t *d) { - X509 *x; - int ret; +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } - x = d2i_X509(NULL, &d, (long)len); - if (x == NULL) { + const uint8_t *p = der; + X509 *x509 = d2i_X509(NULL, &p, (long)der_len); + if (x509 == NULL || p != der + der_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + X509_free(x509); return 0; } - ret = SSL_CTX_use_certificate(ctx, x); - X509_free(x); + int ret = SSL_CTX_use_certificate(ctx, x509); + X509_free(x509); return ret; } @@ -287,20 +301,22 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { return ssl_set_pkey(ctx->cert, pkey); } -int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d, - long len) { - int ret; - const uint8_t *p; - EVP_PKEY *pkey; +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } - p = d; - pkey = d2i_PrivateKey(type, NULL, &p, (long)len); - if (pkey == NULL) { + const uint8_t *p = der; + EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len); + if (pkey == NULL || p != der + der_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + EVP_PKEY_free(pkey); return 0; } - ret = SSL_CTX_use_PrivateKey(ctx, pkey); + int ret = SSL_CTX_use_PrivateKey(ctx, pkey); EVP_PKEY_free(pkey); return ret; } @@ -385,20 +401,19 @@ enum ssl_private_key_result_t ssl_private_key_decrypt( in_len); } - if (ssl_private_key_type(ssl) != EVP_PKEY_RSA) { + RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey); + if (rsa == NULL) { /* Decrypt operations are only supported for RSA keys. */ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return ssl_private_key_failure; } - enum ssl_private_key_result_t ret = ssl_private_key_failure; - RSA *rsa = ssl->cert->privatekey->pkey.rsa; /* Decrypt with no padding. PKCS#1 padding will be removed as part * of the timing-sensitive code by the caller. */ - if (RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) { - ret = ssl_private_key_success; + if (!RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) { + return ssl_private_key_failure; } - return ret; + return ssl_private_key_success; } enum ssl_private_key_result_t ssl_private_key_decrypt_complete( diff --git a/src/ssl/ssl_session.c b/src/ssl/ssl_session.c index ead0b75..3d59bc3 100644 --- a/src/ssl/ssl_session.c +++ b/src/ssl/ssl_session.c @@ -172,7 +172,7 @@ SSL_SESSION *SSL_SESSION_new(void) { session->references = 1; session->timeout = SSL_DEFAULT_SESSION_TIMEOUT; session->time = (unsigned long)time(NULL); - CRYPTO_new_ex_data(&g_ex_data_class, session, &session->ex_data); + CRYPTO_new_ex_data(&session->ex_data); return session; } @@ -278,12 +278,13 @@ SSL_SESSION *SSL_get1_session(SSL *ssl) { return SSL_SESSION_up_ref(ssl->session); } -int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int index; - if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func, - dup_func, free_func)) { + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func, + free_func)) { return -1; } return index; @@ -644,10 +645,10 @@ void SSL_CTX_flush_sessions(SSL_CTX *ctx, long time) { CRYPTO_MUTEX_unlock(&ctx->lock); } -int ssl_clear_bad_session(SSL *s) { - if (s->session != NULL && !(s->shutdown & SSL_SENT_SHUTDOWN) && - !SSL_in_init(s)) { - SSL_CTX_remove_session(s->ctx, s->session); +int ssl_clear_bad_session(SSL *ssl) { + if (ssl->session != NULL && !(ssl->shutdown & SSL_SENT_SHUTDOWN) && + !SSL_in_init(ssl)) { + SSL_CTX_remove_session(ssl->ctx, ssl->session); return 1; } diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc index 0cd42a2..9558f1c 100644 --- a/src/ssl/ssl_test.cc +++ b/src/ssl/ssl_test.cc @@ -50,7 +50,9 @@ static const char kRule1[] = "ECDHE-RSA-AES128-GCM-SHA256"; static const ExpectedCipher kExpected1[] = { + { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 }, + { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, @@ -67,8 +69,10 @@ static const char kRule2[] = "+aRSA"; static const ExpectedCipher kExpected2[] = { + { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 }, { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, + { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, { 0, 0 }, @@ -83,6 +87,7 @@ static const char kRule3[] = "ECDHE-RSA-AES128-GCM-SHA256"; static const ExpectedCipher kExpected3[] = { + { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 }, { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, { 0, 0 }, @@ -119,7 +124,9 @@ static const char kRule6[] = "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4"; static const ExpectedCipher kExpected6[] = { + { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 }, + { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, @@ -133,8 +140,10 @@ static const char kRule7[] = "ECDHE-RSA-AES128-GCM-SHA256"; static const ExpectedCipher kExpected7[] = { + { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1 }, { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1 }, { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, + { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1 }, { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, { 0, 0 }, @@ -157,6 +166,7 @@ static const char kRule8[] = static const ExpectedCipher kExpected8[] = { { TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 }, + { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, { TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0 }, { TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0 }, @@ -169,13 +179,55 @@ static const ExpectedCipher kExpected8[] = { // Exact ciphers may not be used in multi-part rules; they are treated // as unknown aliases. static const char kRule9[] = + "ECDHE-ECDSA-AES128-GCM-SHA256:" + "ECDHE-RSA-AES128-GCM-SHA256:" + "!ECDHE-RSA-AES128-GCM-SHA256+RSA:" + "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256"; + +static const ExpectedCipher kExpected9[] = { + { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, + { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, + { 0, 0 }, +}; + +// SSLv3 matches everything that existed before TLS 1.2. +static const char kRule10[] = "AES128-SHA:AES128-SHA256:!SSLv3"; + +static const ExpectedCipher kExpected10[] = { + { TLS1_CK_RSA_WITH_AES_128_SHA256, 0 }, + { 0, 0 }, +}; + +// TLSv1.2 matches everything added in TLS 1.2. +static const char kRule11[] = "AES128-SHA:AES128-SHA256:!TLSv1.2"; + +static const ExpectedCipher kExpected11[] = { + { TLS1_CK_RSA_WITH_AES_128_SHA, 0 }, + { 0, 0 }, +}; + +// The two directives have no intersection. +static const char kRule12[] = "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3"; + +static const ExpectedCipher kExpected12[] = { + { TLS1_CK_RSA_WITH_AES_128_SHA, 0 }, + { TLS1_CK_RSA_WITH_AES_128_SHA256, 0 }, + { 0, 0 }, +}; + +// The shared name of the CHACHA20_POLY1305 variants behaves like a cipher name +// and not an alias. It may not be used in a multipart rule. (That the shared +// name works is covered by the standard tests.) +static const char kRule13[] = "ECDHE-ECDSA-CHACHA20-POLY1305:" "ECDHE-RSA-CHACHA20-POLY1305:" "!ECDHE-RSA-CHACHA20-POLY1305+RSA:" "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305"; -static const ExpectedCipher kExpected9[] = { +static const ExpectedCipher kExpected13[] = { + { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 }, + { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, { 0, 0 }, }; @@ -190,6 +242,10 @@ static CipherTest kCipherTests[] = { { kRule7, kExpected7 }, { kRule8, kExpected8 }, { kRule9, kExpected9 }, + { kRule10, kExpected10 }, + { kRule11, kExpected11 }, + { kRule12, kExpected12 }, + { kRule13, kExpected13 }, { NULL, NULL }, }; @@ -222,6 +278,8 @@ static const char *kMustNotIncludeNull[] = { "DEFAULT", "ALL:!eNULL", "ALL:!NULL", + "MEDIUM", + "HIGH", "FIPS", "SHA", "SHA1", @@ -521,7 +579,7 @@ static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) { } out->resize(len); - if (!EVP_DecodeBase64(bssl::vector_data(out), &len, len, (const uint8_t *)in, + if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in, strlen(in))) { fprintf(stderr, "EVP_DecodeBase64 failed\n"); return false; @@ -541,8 +599,7 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) { } // Verify the SSL_SESSION decodes. - ScopedSSL_SESSION session(SSL_SESSION_from_bytes(bssl::vector_data(&input), - input.size())); + ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size())); if (!session) { fprintf(stderr, "SSL_SESSION_from_bytes failed\n"); return false; @@ -558,7 +615,7 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) { } encoded.reset(encoded_raw); if (encoded_len != input.size() || - memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) { + memcmp(input.data(), encoded.get(), input.size()) != 0) { fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n"); hexdump(stderr, "Before: ", input.data(), input.size()); hexdump(stderr, "After: ", encoded_raw, encoded_len); @@ -566,9 +623,9 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) { } // Verify the SSL_SESSION also decodes with the legacy API. - cptr = bssl::vector_data(&input); + cptr = input.data(); session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size())); - if (!session || cptr != bssl::vector_data(&input) + input.size()) { + if (!session || cptr != input.data() + input.size()) { fprintf(stderr, "d2i_SSL_SESSION failed\n"); return false; } @@ -596,7 +653,7 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) { fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n"); return false; } - if (memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) { + if (memcmp(input.data(), encoded.get(), input.size()) != 0) { fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n"); return false; } @@ -611,8 +668,7 @@ static bool TestBadSSL_SESSIONEncoding(const char *input_b64) { } // Verify that the SSL_SESSION fails to decode. - ScopedSSL_SESSION session(SSL_SESSION_from_bytes(bssl::vector_data(&input), - input.size())); + ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size())); if (session) { fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n"); return false; @@ -668,6 +724,8 @@ static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = { { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" }, { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" }, + { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" }, // These names are non-standard: { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" }, @@ -700,8 +758,7 @@ static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) { if (!DecodeBase64(&der, kOpenSSLSession)) { return nullptr; } - ScopedSSL_SESSION session(SSL_SESSION_from_bytes(bssl::vector_data(&der), - der.size())); + ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size())); if (!session) { return nullptr; } diff --git a/src/ssl/t1_enc.c b/src/ssl/t1_enc.c index 076f8bd..0f1d683 100644 --- a/src/ssl/t1_enc.c +++ b/src/ssl/t1_enc.c @@ -159,40 +159,36 @@ static int tls1_P_hash(uint8_t *out, size_t out_len, const EVP_MD *md, const uint8_t *seed1, size_t seed1_len, const uint8_t *seed2, size_t seed2_len, const uint8_t *seed3, size_t seed3_len) { - size_t chunk; HMAC_CTX ctx, ctx_tmp, ctx_init; uint8_t A1[EVP_MAX_MD_SIZE]; unsigned A1_len; int ret = 0; - chunk = EVP_MD_size(md); + size_t chunk = EVP_MD_size(md); HMAC_CTX_init(&ctx); HMAC_CTX_init(&ctx_tmp); HMAC_CTX_init(&ctx_init); if (!HMAC_Init_ex(&ctx_init, secret, secret_len, md, NULL) || !HMAC_CTX_copy_ex(&ctx, &ctx_init) || - (seed1_len && !HMAC_Update(&ctx, seed1, seed1_len)) || - (seed2_len && !HMAC_Update(&ctx, seed2, seed2_len)) || - (seed3_len && !HMAC_Update(&ctx, seed3, seed3_len)) || + !HMAC_Update(&ctx, seed1, seed1_len) || + !HMAC_Update(&ctx, seed2, seed2_len) || + !HMAC_Update(&ctx, seed3, seed3_len) || !HMAC_Final(&ctx, A1, &A1_len)) { goto err; } for (;;) { - /* Reinit mac contexts. */ + unsigned len; + uint8_t hmac[EVP_MAX_MD_SIZE]; if (!HMAC_CTX_copy_ex(&ctx, &ctx_init) || !HMAC_Update(&ctx, A1, A1_len) || + /* Save a copy of |ctx| to compute the next A1 value below. */ (out_len > chunk && !HMAC_CTX_copy_ex(&ctx_tmp, &ctx)) || - (seed1_len && !HMAC_Update(&ctx, seed1, seed1_len)) || - (seed2_len && !HMAC_Update(&ctx, seed2, seed2_len)) || - (seed3_len && !HMAC_Update(&ctx, seed3, seed3_len))) { - goto err; - } - - unsigned len; - uint8_t hmac[EVP_MAX_MD_SIZE]; - if (!HMAC_Final(&ctx, hmac, &len)) { + !HMAC_Update(&ctx, seed1, seed1_len) || + !HMAC_Update(&ctx, seed2, seed2_len) || + !HMAC_Update(&ctx, seed3, seed3_len) || + !HMAC_Final(&ctx, hmac, &len)) { goto err; } assert(len == chunk); @@ -228,7 +224,7 @@ err: return ret; } -int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, +int tls1_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret, size_t secret_len, const char *label, size_t label_len, const uint8_t *seed1, size_t seed1_len, const uint8_t *seed2, size_t seed2_len) { @@ -239,7 +235,7 @@ int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, memset(out, 0, out_len); - uint32_t algorithm_prf = ssl_get_algorithm_prf(s); + uint32_t algorithm_prf = ssl_get_algorithm_prf(ssl); if (algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT) { /* If using the MD5/SHA1 PRF, |secret| is partitioned between SHA-1 and * MD5, MD5 first. */ @@ -264,17 +260,15 @@ int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, return 1; } -static int tls1_generate_key_block(SSL *s, uint8_t *out, size_t out_len) { - return s->enc_method->prf(s, out, out_len, s->session->master_key, - s->session->master_key_length, - TLS_MD_KEY_EXPANSION_CONST, - TLS_MD_KEY_EXPANSION_CONST_SIZE, - s->s3->server_random, SSL3_RANDOM_SIZE, - s->s3->client_random, - SSL3_RANDOM_SIZE); +static int tls1_generate_key_block(SSL *ssl, uint8_t *out, size_t out_len) { + return ssl->enc_method->prf( + ssl, out, out_len, ssl->session->master_key, + ssl->session->master_key_length, TLS_MD_KEY_EXPANSION_CONST, + TLS_MD_KEY_EXPANSION_CONST_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE, + ssl->s3->client_random, SSL3_RANDOM_SIZE); } -int tls1_change_cipher_state(SSL *s, int which) { +int tls1_change_cipher_state(SSL *ssl, int which) { /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we * need to update the read cipherspec. Otherwise we have just written one. */ const char is_read = (which & SSL3_CC_READ) != 0; @@ -286,17 +280,28 @@ int tls1_change_cipher_state(SSL *s, int which) { const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret; const uint8_t *client_write_key, *server_write_key, *key; const uint8_t *client_write_iv, *server_write_iv, *iv; - const EVP_AEAD *aead = s->s3->tmp.new_aead; + const EVP_AEAD *aead = ssl->s3->tmp.new_aead; size_t key_len, iv_len, mac_secret_len; const uint8_t *key_data; /* Reset sequence number to zero. */ - if (!SSL_IS_DTLS(s)) { - memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8); + if (is_read) { + if (SSL_IS_DTLS(ssl)) { + ssl->d1->r_epoch++; + memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap)); + } + memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence)); + } else { + if (SSL_IS_DTLS(ssl)) { + ssl->d1->w_epoch++; + memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence, + sizeof(ssl->s3->write_sequence)); + } + memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence)); } - mac_secret_len = s->s3->tmp.new_mac_secret_len; - iv_len = s->s3->tmp.new_fixed_iv_len; + mac_secret_len = ssl->s3->tmp.new_mac_secret_len; + iv_len = ssl->s3->tmp.new_fixed_iv_len; if (aead == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); @@ -315,7 +320,7 @@ int tls1_change_cipher_state(SSL *s, int which) { key_len -= mac_secret_len + iv_len; } - key_data = s->s3->tmp.key_block; + key_data = ssl->s3->tmp.key_block; client_write_mac_secret = key_data; key_data += mac_secret_len; server_write_mac_secret = key_data; @@ -339,58 +344,46 @@ int tls1_change_cipher_state(SSL *s, int which) { iv = server_write_iv; } - if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length) { + if (key_data - ssl->s3->tmp.key_block != ssl->s3->tmp.key_block_length) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } if (is_read) { - SSL_AEAD_CTX_free(s->aead_read_ctx); - s->aead_read_ctx = SSL_AEAD_CTX_new( - evp_aead_open, ssl3_version_from_wire(s, s->version), - s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv, + SSL_AEAD_CTX_free(ssl->aead_read_ctx); + ssl->aead_read_ctx = SSL_AEAD_CTX_new( + evp_aead_open, ssl3_version_from_wire(ssl, ssl->version), + ssl->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv, iv_len); - return s->aead_read_ctx != NULL; + return ssl->aead_read_ctx != NULL; } - SSL_AEAD_CTX_free(s->aead_write_ctx); - s->aead_write_ctx = SSL_AEAD_CTX_new( - evp_aead_seal, ssl3_version_from_wire(s, s->version), - s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv, + SSL_AEAD_CTX_free(ssl->aead_write_ctx); + ssl->aead_write_ctx = SSL_AEAD_CTX_new( + evp_aead_seal, ssl3_version_from_wire(ssl, ssl->version), + ssl->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv, iv_len); - if (s->aead_write_ctx == NULL) { - return 0; - } - - s->s3->need_record_splitting = 0; - if (!SSL_USE_EXPLICIT_IV(s) && - (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 && - SSL_CIPHER_is_block_cipher(s->s3->tmp.new_cipher)) { - /* Enable 1/n-1 record-splitting to randomize the IV. See - * https://www.openssl.org/~bodo/tls-cbc.txt and the BEAST attack. */ - s->s3->need_record_splitting = 1; - } - return 1; + return ssl->aead_write_ctx != NULL; } -int tls1_setup_key_block(SSL *s) { +int tls1_setup_key_block(SSL *ssl) { uint8_t *p; const EVP_AEAD *aead = NULL; int ret = 0; size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len; size_t key_block_len; - if (s->s3->tmp.key_block_length != 0) { + if (ssl->s3->tmp.key_block_length != 0) { return 1; } - if (s->session->cipher == NULL) { + if (ssl->session->cipher == NULL) { goto cipher_unavailable_err; } if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len, - s->session->cipher, - ssl3_version_from_wire(s, s->version))) { + ssl->session->cipher, + ssl3_version_from_wire(ssl, ssl->version))) { goto cipher_unavailable_err; } key_len = EVP_AEAD_key_length(aead); @@ -417,15 +410,15 @@ int tls1_setup_key_block(SSL *s) { assert(fixed_iv_len < 256); assert(variable_iv_len < 256); - s->s3->tmp.new_aead = aead; - s->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len; - s->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len; - s->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len; + ssl->s3->tmp.new_aead = aead; + ssl->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len; + ssl->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len; + ssl->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len; key_block_len = key_len + mac_secret_len + fixed_iv_len; key_block_len *= 2; - ssl3_cleanup_key_block(s); + ssl3_cleanup_key_block(ssl); p = (uint8_t *)OPENSSL_malloc(key_block_len); if (p == NULL) { @@ -433,10 +426,10 @@ int tls1_setup_key_block(SSL *s) { goto err; } - s->s3->tmp.key_block_length = key_block_len; - s->s3->tmp.key_block = p; + ssl->s3->tmp.key_block_length = key_block_len; + ssl->s3->tmp.key_block = p; - if (!tls1_generate_key_block(s, p, key_block_len)) { + if (!tls1_generate_key_block(ssl, p, key_block_len)) { goto err; } @@ -450,12 +443,12 @@ cipher_unavailable_err: return 0; } -int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) { +int tls1_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *out) { const EVP_MD_CTX *ctx_template; if (md_nid == NID_md5) { - ctx_template = &s->s3->handshake_md5; - } else if (md_nid == EVP_MD_CTX_type(&s->s3->handshake_hash)) { - ctx_template = &s->s3->handshake_hash; + ctx_template = &ssl->s3->handshake_md5; + } else if (md_nid == EVP_MD_CTX_type(&ssl->s3->handshake_hash)) { + ctx_template = &ssl->s3->handshake_hash; } else { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_REQUIRED_DIGEST); return 0; @@ -503,15 +496,15 @@ err: * written or -1 in the event of an error. This function works on a copy of the * underlying digests so can be called multiple times and prior to the final * update etc. */ -int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) { +int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len) { size_t md5_len = 0; - if (EVP_MD_CTX_md(&s->s3->handshake_md5) != NULL && - !append_digest(&s->s3->handshake_md5, out, &md5_len, out_len)) { + if (EVP_MD_CTX_md(&ssl->s3->handshake_md5) != NULL && + !append_digest(&ssl->s3->handshake_md5, out, &md5_len, out_len)) { return -1; } size_t len; - if (!append_digest(&s->s3->handshake_hash, out + md5_len, &len, + if (!append_digest(&ssl->s3->handshake_hash, out + md5_len, &len, out_len - md5_len)) { return -1; } @@ -519,24 +512,24 @@ int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) { return (int)(md5_len + len); } -int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) { +int tls1_final_finish_mac(SSL *ssl, const char *str, int slen, uint8_t *out) { uint8_t buf[2 * EVP_MAX_MD_SIZE]; int err = 0; int digests_len; /* At this point, the handshake should have released the handshake buffer on * its own. */ - assert(s->s3->handshake_buffer == NULL); + assert(ssl->s3->handshake_buffer == NULL); - digests_len = tls1_handshake_digest(s, buf, sizeof(buf)); + digests_len = tls1_handshake_digest(ssl, buf, sizeof(buf)); if (digests_len < 0) { err = 1; digests_len = 0; } - if (!s->enc_method->prf(s, out, 12, s->session->master_key, - s->session->master_key_length, str, slen, buf, - digests_len, NULL, 0)) { + if (!ssl->enc_method->prf(ssl, out, 12, ssl->session->master_key, + ssl->session->master_key_length, str, slen, buf, + digests_len, NULL, 0)) { err = 1; } @@ -547,27 +540,29 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) { } } -int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster, +int tls1_generate_master_secret(SSL *ssl, uint8_t *out, + const uint8_t *premaster, size_t premaster_len) { - if (s->s3->tmp.extended_master_secret) { + if (ssl->s3->tmp.extended_master_secret) { uint8_t digests[2 * EVP_MAX_MD_SIZE]; - int digests_len = tls1_handshake_digest(s, digests, sizeof(digests)); + int digests_len = tls1_handshake_digest(ssl, digests, sizeof(digests)); if (digests_len == -1) { return 0; } - if (!s->enc_method->prf(s, out, SSL3_MASTER_SECRET_SIZE, premaster, - premaster_len, TLS_MD_EXTENDED_MASTER_SECRET_CONST, - TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests, - digests_len, NULL, 0)) { + if (!ssl->enc_method->prf(ssl, out, SSL3_MASTER_SECRET_SIZE, premaster, + premaster_len, + TLS_MD_EXTENDED_MASTER_SECRET_CONST, + TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests, + digests_len, NULL, 0)) { return 0; } } else { - if (!s->enc_method->prf(s, out, SSL3_MASTER_SECRET_SIZE, premaster, - premaster_len, TLS_MD_MASTER_SECRET_CONST, - TLS_MD_MASTER_SECRET_CONST_SIZE, - s->s3->client_random, SSL3_RANDOM_SIZE, - s->s3->server_random, SSL3_RANDOM_SIZE)) { + if (!ssl->enc_method->prf(ssl, out, SSL3_MASTER_SECRET_SIZE, premaster, + premaster_len, TLS_MD_MASTER_SECRET_CONST, + TLS_MD_MASTER_SECRET_CONST_SIZE, + ssl->s3->client_random, SSL3_RANDOM_SIZE, + ssl->s3->server_random, SSL3_RANDOM_SIZE)) { return 0; } } @@ -575,11 +570,11 @@ int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster, return SSL3_MASTER_SECRET_SIZE; } -int tls1_export_keying_material(SSL *s, uint8_t *out, size_t out_len, +int tls1_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, const uint8_t *context, size_t context_len, int use_context) { - if (!s->s3->have_version || s->version == SSL3_VERSION) { + if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -598,17 +593,17 @@ int tls1_export_keying_material(SSL *s, uint8_t *out, size_t out_len, return 0; } - memcpy(seed, s->s3->client_random, SSL3_RANDOM_SIZE); - memcpy(seed + SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE); + memcpy(seed, ssl->s3->client_random, SSL3_RANDOM_SIZE); + memcpy(seed + SSL3_RANDOM_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE); if (use_context) { seed[2 * SSL3_RANDOM_SIZE] = (uint8_t)(context_len >> 8); seed[2 * SSL3_RANDOM_SIZE + 1] = (uint8_t)context_len; memcpy(seed + 2 * SSL3_RANDOM_SIZE + 2, context, context_len); } - int ret = s->enc_method->prf(s, out, out_len, s->session->master_key, - s->session->master_key_length, label, label_len, - seed, seed_len, NULL, 0); + int ret = ssl->enc_method->prf(ssl, out, out_len, ssl->session->master_key, + ssl->session->master_key_length, label, + label_len, seed, seed_len, NULL, 0); OPENSSL_free(seed); return ret; } diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c index 9a29028..5aea08b 100644 --- a/src/ssl/t1_lib.c +++ b/src/ssl/t1_lib.c @@ -127,8 +127,8 @@ #include "internal.h" -static int ssl_check_clienthello_tlsext(SSL *s); -static int ssl_check_serverhello_tlsext(SSL *s); +static int ssl_check_clienthello_tlsext(SSL *ssl); +static int ssl_check_serverhello_tlsext(SSL *ssl); const SSL3_ENC_METHOD TLSv1_enc_data = { tls1_prf, @@ -335,126 +335,61 @@ int SSL_early_callback_ctx_extension_get( return 0; } -struct tls_curve { - uint16_t curve_id; - int nid; - const char curve_name[8]; -}; - -/* ECC curves from RFC4492. */ -static const struct tls_curve tls_curves[] = { - {21, NID_secp224r1, "P-224"}, - {23, NID_X9_62_prime256v1, "P-256"}, - {24, NID_secp384r1, "P-384"}, - {25, NID_secp521r1, "P-521"}, -}; - static const uint16_t eccurves_default[] = { - 23, /* X9_62_prime256v1 */ - 24, /* secp384r1 */ + SSL_CURVE_SECP256R1, + SSL_CURVE_SECP384R1, #if defined(BORINGSSL_ANDROID_SYSTEM) - 25, /* secp521r1 */ + SSL_CURVE_SECP521R1, #endif }; -int tls1_ec_curve_id2nid(uint16_t curve_id) { - size_t i; - for (i = 0; i < sizeof(tls_curves) / sizeof(tls_curves[0]); i++) { - if (curve_id == tls_curves[i].curve_id) { - return tls_curves[i].nid; - } - } - return NID_undef; -} - -int tls1_ec_nid2curve_id(uint16_t *out_curve_id, int nid) { - size_t i; - for (i = 0; i < sizeof(tls_curves) / sizeof(tls_curves[0]); i++) { - if (nid == tls_curves[i].nid) { - *out_curve_id = tls_curves[i].curve_id; - return 1; - } - } - return 0; -} - -const char* tls1_ec_curve_id2name(uint16_t curve_id) { - size_t i; - for (i = 0; i < sizeof(tls_curves) / sizeof(tls_curves[0]); i++) { - if (curve_id == tls_curves[i].curve_id) { - return tls_curves[i].curve_name; - } - } - return NULL; -} - /* tls1_get_curvelist sets |*out_curve_ids| and |*out_curve_ids_len| to the * list of allowed curve IDs. If |get_peer_curves| is non-zero, return the * peer's curve list. Otherwise, return the preferred list. */ -static void tls1_get_curvelist(SSL *s, int get_peer_curves, +static void tls1_get_curvelist(SSL *ssl, int get_peer_curves, const uint16_t **out_curve_ids, size_t *out_curve_ids_len) { if (get_peer_curves) { /* Only clients send a curve list, so this function is only called * on the server. */ - assert(s->server); - *out_curve_ids = s->s3->tmp.peer_ellipticcurvelist; - *out_curve_ids_len = s->s3->tmp.peer_ellipticcurvelist_length; + assert(ssl->server); + *out_curve_ids = ssl->s3->tmp.peer_ellipticcurvelist; + *out_curve_ids_len = ssl->s3->tmp.peer_ellipticcurvelist_length; return; } - *out_curve_ids = s->tlsext_ellipticcurvelist; - *out_curve_ids_len = s->tlsext_ellipticcurvelist_length; + *out_curve_ids = ssl->tlsext_ellipticcurvelist; + *out_curve_ids_len = ssl->tlsext_ellipticcurvelist_length; if (!*out_curve_ids) { *out_curve_ids = eccurves_default; *out_curve_ids_len = sizeof(eccurves_default) / sizeof(eccurves_default[0]); } } -int tls1_check_curve(SSL *s, CBS *cbs, uint16_t *out_curve_id) { - uint8_t curve_type; - uint16_t curve_id; - const uint16_t *curves; - size_t curves_len, i; - - /* Only support named curves. */ - if (!CBS_get_u8(cbs, &curve_type) || - curve_type != NAMED_CURVE_TYPE || - !CBS_get_u16(cbs, &curve_id)) { - return 0; - } - - tls1_get_curvelist(s, 0, &curves, &curves_len); - for (i = 0; i < curves_len; i++) { - if (curve_id == curves[i]) { - *out_curve_id = curve_id; - return 1; - } - } - - return 0; -} - -int tls1_get_shared_curve(SSL *s) { +int tls1_get_shared_curve(SSL *ssl, uint16_t *out_curve_id) { const uint16_t *curves, *peer_curves, *pref, *supp; size_t curves_len, peer_curves_len, pref_len, supp_len, i, j; /* Can't do anything on client side */ - if (s->server == 0) { - return NID_undef; + if (ssl->server == 0) { + return 0; } - tls1_get_curvelist(s, 0 /* local curves */, &curves, &curves_len); - tls1_get_curvelist(s, 1 /* peer curves */, &peer_curves, &peer_curves_len); + tls1_get_curvelist(ssl, 0 /* local curves */, &curves, &curves_len); + tls1_get_curvelist(ssl, 1 /* peer curves */, &peer_curves, &peer_curves_len); if (peer_curves_len == 0) { /* Clients are not required to send a supported_curves extension. In this * case, the server is free to pick any curve it likes. See RFC 4492, - * section 4, paragraph 3. */ - return (curves_len == 0) ? NID_undef : tls1_ec_curve_id2nid(curves[0]); + * section 4, paragraph 3. + * + * However, in the interests of compatibility, we will skip ECDH if the + * client didn't send an extension because we can't be sure that they'll + * support our favoured curve. */ + return 0; } - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { pref = curves; pref_len = curves_len; supp = peer_curves; @@ -469,12 +404,13 @@ int tls1_get_shared_curve(SSL *s) { for (i = 0; i < pref_len; i++) { for (j = 0; j < supp_len; j++) { if (pref[i] == supp[j]) { - return tls1_ec_curve_id2nid(pref[i]); + *out_curve_id = pref[i]; + return 1; } } } - return NID_undef; + return 0; } int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len, @@ -488,7 +424,7 @@ int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len, } for (i = 0; i < ncurves; i++) { - if (!tls1_ec_nid2curve_id(&curve_ids[i], curves[i])) { + if (!ssl_nid_to_curve_id(&curve_ids[i], curves[i])) { OPENSSL_free(curve_ids); return 0; } @@ -521,7 +457,7 @@ static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id, /* Determine curve ID */ nid = EC_GROUP_get_curve_name(grp); - if (!tls1_ec_nid2curve_id(&id, nid)) { + if (!ssl_nid_to_curve_id(&id, nid)) { return 0; } @@ -545,19 +481,19 @@ static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id, /* tls1_check_curve_id returns one if |curve_id| is consistent with both our * and the peer's curve preferences. Note: if called as the client, only our * preferences are checked; the peer (the server) does not send preferences. */ -static int tls1_check_curve_id(SSL *s, uint16_t curve_id) { +int tls1_check_curve_id(SSL *ssl, uint16_t curve_id) { const uint16_t *curves; size_t curves_len, i, get_peer_curves; /* Check against our list, then the peer's list. */ for (get_peer_curves = 0; get_peer_curves <= 1; get_peer_curves++) { - if (get_peer_curves && !s->server) { + if (get_peer_curves && !ssl->server) { /* Servers do not present a preference list so, if we are a client, only * check our list. */ continue; } - tls1_get_curvelist(s, get_peer_curves, &curves, &curves_len); + tls1_get_curvelist(ssl, get_peer_curves, &curves, &curves_len); if (get_peer_curves && curves_len == 0) { /* Clients are not required to send a supported_curves extension. In this * case, the server is free to pick any curve it likes. See RFC 4492, @@ -578,16 +514,19 @@ static int tls1_check_curve_id(SSL *s, uint16_t curve_id) { return 1; } -int tls1_check_ec_cert(SSL *s, X509 *x) { +int tls1_check_ec_cert(SSL *ssl, X509 *x) { int ret = 0; EVP_PKEY *pkey = X509_get_pubkey(x); uint16_t curve_id; uint8_t comp_id; - if (!pkey || - pkey->type != EVP_PKEY_EC || - !tls1_curve_params_from_ec_key(&curve_id, &comp_id, pkey->pkey.ec) || - !tls1_check_curve_id(s, curve_id) || + if (!pkey) { + goto done; + } + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + if (ec_key == NULL || + !tls1_curve_params_from_ec_key(&curve_id, &comp_id, ec_key) || + !tls1_check_curve_id(ssl, curve_id) || comp_id != TLSEXT_ECPOINTFORMAT_uncompressed) { goto done; } @@ -599,25 +538,6 @@ done: return ret; } -int tls1_check_ec_tmp_key(SSL *s) { - if (s->cert->ecdh_nid != NID_undef) { - /* If the curve is preconfigured, ECDH is acceptable iff the peer supports - * the curve. */ - uint16_t curve_id; - return tls1_ec_nid2curve_id(&curve_id, s->cert->ecdh_nid) && - tls1_check_curve_id(s, curve_id); - } - - if (s->cert->ecdh_tmp_cb != NULL) { - /* Assume the callback will provide an acceptable curve. */ - return 1; - } - - /* Otherwise, the curve gets selected automatically. ECDH is acceptable iff - * there is a shared curve. */ - return tls1_get_shared_curve(s) != NID_undef; -} - /* List of supported signature algorithms and hashes. Should make this * customisable at some point, for now include everything we support. */ @@ -635,7 +555,7 @@ static const uint8_t tls12_sigalgs[] = { tlsext_sigalg(TLSEXT_hash_sha1) }; -size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs) { +size_t tls12_get_psigalgs(SSL *ssl, const uint8_t **psigs) { *psigs = tls12_sigalgs; return sizeof(tls12_sigalgs); } @@ -660,23 +580,6 @@ int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert, return 0; } - if (pkey->type == EVP_PKEY_EC) { - uint16_t curve_id; - uint8_t comp_id; - /* Check compression and curve matches extensions */ - if (!tls1_curve_params_from_ec_key(&curve_id, &comp_id, pkey->pkey.ec)) { - *out_alert = SSL_AD_INTERNAL_ERROR; - return 0; - } - - if (ssl->server && (!tls1_check_curve_id(ssl, curve_id) || - comp_id != TLSEXT_ECPOINTFORMAT_uncompressed)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); - *out_alert = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - } - /* Check signature matches a type we sent */ sent_sigslen = tls12_get_psigalgs(ssl, &sent_sigs); for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) { @@ -705,8 +608,8 @@ int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert, * supported or doesn't appear in supported signature algorithms. Unlike * ssl_cipher_get_disabled this applies to a specific session and not global * settings. */ -void ssl_set_client_disabled(SSL *s) { - CERT *c = s->cert; +void ssl_set_client_disabled(SSL *ssl) { + CERT *c = ssl->cert; const uint8_t *sigalgs; size_t i, sigalgslen; int have_rsa = 0, have_ecdsa = 0; @@ -715,7 +618,7 @@ void ssl_set_client_disabled(SSL *s) { /* Now go through all signature algorithms seeing if we support any for RSA, * DSA, ECDSA. Do this for all versions not just TLS 1.2. */ - sigalgslen = tls12_get_psigalgs(s, &sigalgs); + sigalgslen = tls12_get_psigalgs(ssl, &sigalgs); for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) { switch (sigalgs[1]) { case TLSEXT_signature_rsa: @@ -737,7 +640,7 @@ void ssl_set_client_disabled(SSL *s) { } /* with PSK there must be client callback set */ - if (!s->psk_client_callback) { + if (!ssl->psk_client_callback) { c->mask_a |= SSL_aPSK; c->mask_k |= SSL_kPSK; } @@ -798,7 +701,8 @@ static int ext_sni_add_clienthello(SSL *ssl, CBB *out) { return 1; } -static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert, CBS *contents) { +static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert, + CBS *contents) { if (contents == NULL) { return 1; } @@ -821,7 +725,8 @@ static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert, CBS *contents return 1; } -static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) { +static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert, + CBS *contents) { if (contents == NULL) { return 1; } @@ -943,23 +848,24 @@ static int ext_ri_add_clienthello(SSL *ssl, CBB *out) { static int ext_ri_parse_serverhello(SSL *ssl, uint8_t *out_alert, CBS *contents) { + /* Servers may not switch between omitting the extension and supporting it. + * See RFC 5746, sections 3.5 and 4.2. */ + if (ssl->s3->initial_handshake_complete && + (contents != NULL) != ssl->s3->send_connection_binding) { + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + return 0; + } + if (contents == NULL) { - /* No renegotiation extension received. - * - * Strictly speaking if we want to avoid an attack we should *always* see + /* Strictly speaking, if we want to avoid an attack we should *always* see * RI even on initial ServerHello because the client doesn't see any * renegotiation during an attack. However this would mean we could not * connect to any server which doesn't support RI. * - * A lack of the extension is allowed if SSL_OP_LEGACY_SERVER_CONNECT is - * defined. */ - if (ssl->options & SSL_OP_LEGACY_SERVER_CONNECT) { - return 1; - } - - *out_alert = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - return 0; + * OpenSSL has |SSL_OP_LEGACY_SERVER_CONNECT| to control this, but in + * practical terms every client sets it so it's just assumed here. */ + return 1; } const size_t expected_len = ssl->s3->previous_client_finished_len + @@ -1037,7 +943,8 @@ static int ext_ri_parse_clienthello(SSL *ssl, uint8_t *out_alert, } /* Check that the extension matches */ - if (!CBS_mem_equal(&renegotiated_connection, ssl->s3->previous_client_finished, + if (!CBS_mem_equal(&renegotiated_connection, + ssl->s3->previous_client_finished, ssl->s3->previous_client_finished_len)) { OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); *out_alert = SSL_AD_HANDSHAKE_FAILURE; @@ -1101,7 +1008,8 @@ static int ext_ems_parse_serverhello(SSL *ssl, uint8_t *out_alert, return 1; } -static int ext_ems_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) { +static int ext_ems_parse_clienthello(SSL *ssl, uint8_t *out_alert, + CBS *contents) { if (ssl->version == SSL3_VERSION || contents == NULL) { return 1; } @@ -1183,7 +1091,8 @@ static int ext_ticket_parse_serverhello(SSL *ssl, uint8_t *out_alert, return 1; } -static int ext_ticket_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) { +static int ext_ticket_parse_clienthello(SSL *ssl, uint8_t *out_alert, + CBS *contents) { /* This function isn't used because the ticket extension from the client is * handled in ssl_session.c. */ return 1; @@ -1661,7 +1570,8 @@ static int ext_alpn_add_serverhello(SSL *ssl, CBB *out) { !CBB_add_u16_length_prefixed(out, &contents) || !CBB_add_u16_length_prefixed(&contents, &proto_list) || !CBB_add_u8_length_prefixed(&proto_list, &proto) || - !CBB_add_bytes(&proto, ssl->s3->alpn_selected, ssl->s3->alpn_selected_len) || + !CBB_add_bytes(&proto, ssl->s3->alpn_selected, + ssl->s3->alpn_selected_len) || !CBB_flush(out)) { return 0; } @@ -2217,7 +2127,6 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) { return 1; } - size_t orig_len = CBB_len(out); CBB extensions; if (!CBB_add_u16_length_prefixed(out, &extensions)) { goto err; @@ -2251,7 +2160,7 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) { } if (!SSL_IS_DTLS(ssl)) { - header_len += CBB_len(&extensions) - orig_len; + header_len += 2 + CBB_len(&extensions); if (header_len > 0xff && header_len < 0x200) { /* Add padding to workaround bugs in F5 terminators. See RFC 7685. * @@ -2278,10 +2187,8 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) { } } - /* If only two bytes have been written then the extensions are actually empty - * and those two bytes are the zero length. In that case, we don't bother - * sending the extensions length. */ - if (CBB_len(&extensions) - orig_len == 2) { + /* Discard empty extensions blocks. */ + if (CBB_len(&extensions) == 0) { CBB_discard_child(out); } @@ -2293,8 +2200,6 @@ err: } int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out) { - const size_t orig_len = CBB_len(out); - CBB extensions; if (!CBB_add_u16_length_prefixed(out, &extensions)) { goto err; @@ -2318,10 +2223,8 @@ int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out) { goto err; } - /* If only two bytes have been written then the extensions are actually empty - * and those two bytes are the zero length. In that case, we don't bother - * sending the extensions length. */ - if (CBB_len(&extensions) - orig_len == 2) { + /* Discard empty extensions blocks. */ + if (CBB_len(&extensions) == 0) { CBB_discard_child(out); } @@ -2332,16 +2235,16 @@ err: return 0; } -static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) { +static int ssl_scan_clienthello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) { size_t i; for (i = 0; i < kNumExtensions; i++) { if (kExtensions[i].init != NULL) { - kExtensions[i].init(s); + kExtensions[i].init(ssl); } } - s->s3->tmp.extensions.received = 0; - s->s3->tmp.custom_extensions.received = 0; + ssl->s3->tmp.extensions.received = 0; + ssl->s3->tmp.custom_extensions.received = 0; /* The renegotiation extension must always be at index zero because the * |received| and |sent| bitsets need to be tweaked when the "extension" is * sent as an SCSV. */ @@ -2370,7 +2273,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) { /* RFC 5746 made the existence of extensions in SSL 3.0 somewhat * ambiguous. Ignore all but the renegotiation_info extension. */ - if (s->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) { + if (ssl->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) { continue; } @@ -2379,16 +2282,16 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) { tls_extension_find(&ext_index, type); if (ext == NULL) { - if (!custom_ext_parse_clienthello(s, out_alert, type, &extension)) { + if (!custom_ext_parse_clienthello(ssl, out_alert, type, &extension)) { OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); return 0; } continue; } - s->s3->tmp.extensions.received |= (1u << ext_index); + ssl->s3->tmp.extensions.received |= (1u << ext_index); uint8_t alert = SSL_AD_DECODE_ERROR; - if (!ext->parse_clienthello(s, &alert, &extension)) { + if (!ext->parse_clienthello(ssl, &alert, &extension)) { *out_alert = alert; OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); ERR_add_error_dataf("extension: %u", (unsigned)type); @@ -2398,11 +2301,11 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) { } for (i = 0; i < kNumExtensions; i++) { - if (!(s->s3->tmp.extensions.received & (1u << i))) { + if (!(ssl->s3->tmp.extensions.received & (1u << i))) { /* Extension wasn't observed so call the callback with a NULL * parameter. */ uint8_t alert = SSL_AD_DECODE_ERROR; - if (!kExtensions[i].parse_clienthello(s, &alert, NULL)) { + if (!kExtensions[i].parse_clienthello(ssl, &alert, NULL)) { OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value); *out_alert = alert; @@ -2414,14 +2317,14 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) { return 1; } -int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs) { +int ssl_parse_clienthello_tlsext(SSL *ssl, CBS *cbs) { int alert = -1; - if (ssl_scan_clienthello_tlsext(s, cbs, &alert) <= 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, alert); + if (ssl_scan_clienthello_tlsext(ssl, cbs, &alert) <= 0) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, alert); return 0; } - if (ssl_check_clienthello_tlsext(s) <= 0) { + if (ssl_check_clienthello_tlsext(ssl) <= 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT); return 0; } @@ -2431,7 +2334,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs) { OPENSSL_COMPILE_ASSERT(kNumExtensions <= sizeof(uint32_t) * 8, too_many_bits); -static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) { +static int ssl_scan_serverhello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) { uint32_t received = 0; if (CBS_len(cbs) != 0) { @@ -2460,13 +2363,13 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) { tls_extension_find(&ext_index, type); if (ext == NULL) { - if (!custom_ext_parse_serverhello(s, out_alert, type, &extension)) { + if (!custom_ext_parse_serverhello(ssl, out_alert, type, &extension)) { return 0; } continue; } - if (!(s->s3->tmp.extensions.sent & (1u << ext_index))) { + if (!(ssl->s3->tmp.extensions.sent & (1u << ext_index))) { /* If the extension was never sent then it is illegal. */ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); ERR_add_error_dataf("extension :%u", (unsigned)type); @@ -2477,7 +2380,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) { received |= (1u << ext_index); uint8_t alert = SSL_AD_DECODE_ERROR; - if (!ext->parse_serverhello(s, &alert, &extension)) { + if (!ext->parse_serverhello(ssl, &alert, &extension)) { OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); ERR_add_error_dataf("extension: %u", (unsigned)type); *out_alert = alert; @@ -2492,7 +2395,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) { /* Extension wasn't observed so call the callback with a NULL * parameter. */ uint8_t alert = SSL_AD_DECODE_ERROR; - if (!kExtensions[i].parse_serverhello(s, &alert, NULL)) { + if (!kExtensions[i].parse_serverhello(ssl, &alert, NULL)) { OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value); *out_alert = alert; @@ -2504,33 +2407,33 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) { return 1; } -static int ssl_check_clienthello_tlsext(SSL *s) { +static int ssl_check_clienthello_tlsext(SSL *ssl) { int ret = SSL_TLSEXT_ERR_NOACK; int al = SSL_AD_UNRECOGNIZED_NAME; /* The handling of the ECPointFormats extension is done elsewhere, namely in * ssl3_choose_cipher in s3_lib.c. */ - if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) { - ret = s->ctx->tlsext_servername_callback(s, &al, - s->ctx->tlsext_servername_arg); - } else if (s->initial_ctx != NULL && - s->initial_ctx->tlsext_servername_callback != 0) { - ret = s->initial_ctx->tlsext_servername_callback( - s, &al, s->initial_ctx->tlsext_servername_arg); + if (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) { + ret = ssl->ctx->tlsext_servername_callback(ssl, &al, + ssl->ctx->tlsext_servername_arg); + } else if (ssl->initial_ctx != NULL && + ssl->initial_ctx->tlsext_servername_callback != 0) { + ret = ssl->initial_ctx->tlsext_servername_callback( + ssl, &al, ssl->initial_ctx->tlsext_servername_arg); } switch (ret) { case SSL_TLSEXT_ERR_ALERT_FATAL: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); return -1; case SSL_TLSEXT_ERR_ALERT_WARNING: - ssl3_send_alert(s, SSL3_AL_WARNING, al); + ssl3_send_alert(ssl, SSL3_AL_WARNING, al); return 1; case SSL_TLSEXT_ERR_NOACK: - s->s3->tmp.should_ack_sni = 0; + ssl->s3->tmp.should_ack_sni = 0; return 1; default: @@ -2538,26 +2441,26 @@ static int ssl_check_clienthello_tlsext(SSL *s) { } } -static int ssl_check_serverhello_tlsext(SSL *s) { +static int ssl_check_serverhello_tlsext(SSL *ssl) { int ret = SSL_TLSEXT_ERR_OK; int al = SSL_AD_UNRECOGNIZED_NAME; - if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) { - ret = s->ctx->tlsext_servername_callback(s, &al, - s->ctx->tlsext_servername_arg); - } else if (s->initial_ctx != NULL && - s->initial_ctx->tlsext_servername_callback != 0) { - ret = s->initial_ctx->tlsext_servername_callback( - s, &al, s->initial_ctx->tlsext_servername_arg); + if (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) { + ret = ssl->ctx->tlsext_servername_callback(ssl, &al, + ssl->ctx->tlsext_servername_arg); + } else if (ssl->initial_ctx != NULL && + ssl->initial_ctx->tlsext_servername_callback != 0) { + ret = ssl->initial_ctx->tlsext_servername_callback( + ssl, &al, ssl->initial_ctx->tlsext_servername_arg); } switch (ret) { case SSL_TLSEXT_ERR_ALERT_FATAL: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); return -1; case SSL_TLSEXT_ERR_ALERT_WARNING: - ssl3_send_alert(s, SSL3_AL_WARNING, al); + ssl3_send_alert(ssl, SSL3_AL_WARNING, al); return 1; default: @@ -2565,14 +2468,14 @@ static int ssl_check_serverhello_tlsext(SSL *s) { } } -int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs) { +int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs) { int alert = -1; - if (ssl_scan_serverhello_tlsext(s, cbs, &alert) <= 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, alert); + if (ssl_scan_serverhello_tlsext(ssl, cbs, &alert) <= 0) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, alert); return 0; } - if (ssl_check_serverhello_tlsext(s) <= 0) { + if (ssl_check_serverhello_tlsext(ssl) <= 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_SERVERHELLO_TLSEXT); return 0; } @@ -2616,9 +2519,9 @@ int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session, const uint8_t *iv = ticket + SSL_TICKET_KEY_NAME_LEN; if (ssl_ctx->tlsext_ticket_key_cb != NULL) { - int cb_ret = ssl_ctx->tlsext_ticket_key_cb(ssl, (uint8_t*)ticket /* name */, - (uint8_t*)iv, &cipher_ctx, &hmac_ctx, - 0 /* decrypt */); + int cb_ret = ssl_ctx->tlsext_ticket_key_cb( + ssl, (uint8_t *)ticket /* name */, (uint8_t *)iv, &cipher_ctx, + &hmac_ctx, 0 /* decrypt */); if (cb_ret < 0) { ret = 0; goto done; @@ -2732,27 +2635,15 @@ int tls12_get_sigid(int pkey_type) { sizeof(tls12_sig) / sizeof(tls12_lookup)); } -int tls12_get_sigandhash(SSL *ssl, uint8_t *p, const EVP_MD *md) { - int sig_id, md_id; +int tls12_add_sigandhash(SSL *ssl, CBB *out, const EVP_MD *md) { + int md_id = tls12_find_id(EVP_MD_type(md), tls12_md, + sizeof(tls12_md) / sizeof(tls12_lookup)); + int sig_id = tls12_get_sigid(ssl_private_key_type(ssl)); - if (!md) { - return 0; - } - - md_id = tls12_find_id(EVP_MD_type(md), tls12_md, - sizeof(tls12_md) / sizeof(tls12_lookup)); - if (md_id == -1) { - return 0; - } - - sig_id = tls12_get_sigid(ssl_private_key_type(ssl)); - if (sig_id == -1) { - return 0; - } - - p[0] = (uint8_t)md_id; - p[1] = (uint8_t)sig_id; - return 1; + return md_id != -1 && + sig_id != -1 && + CBB_add_u8(out, (uint8_t)md_id) && + CBB_add_u8(out, (uint8_t)sig_id); } const EVP_MD *tls12_get_hash(uint8_t hash_alg) { @@ -2921,24 +2812,25 @@ err: } /* tls1_record_handshake_hashes_for_channel_id records the current handshake - * hashes in |s->session| so that Channel ID resumptions can sign that data. */ -int tls1_record_handshake_hashes_for_channel_id(SSL *s) { + * hashes in |ssl->session| so that Channel ID resumptions can sign that + * data. */ +int tls1_record_handshake_hashes_for_channel_id(SSL *ssl) { int digest_len; /* This function should never be called for a resumed session because the * handshake hashes that we wish to record are for the original, full * handshake. */ - if (s->hit) { + if (ssl->hit) { return -1; } digest_len = - tls1_handshake_digest(s, s->session->original_handshake_hash, - sizeof(s->session->original_handshake_hash)); + tls1_handshake_digest(ssl, ssl->session->original_handshake_hash, + sizeof(ssl->session->original_handshake_hash)); if (digest_len < 0) { return -1; } - s->session->original_handshake_hash_len = digest_len; + ssl->session->original_handshake_hash_len = digest_len; return 1; } diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc index 07ba9f5..74674a4 100644 --- a/src/ssl/test/bssl_shim.cc +++ b/src/ssl/test/bssl_shim.cc @@ -12,6 +12,10 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif + #include <openssl/base.h> #if !defined(OPENSSL_WINDOWS) @@ -20,7 +24,7 @@ #include <netinet/tcp.h> #include <signal.h> #include <sys/socket.h> -#include <sys/types.h> +#include <sys/time.h> #include <unistd.h> #else #include <io.h> @@ -32,8 +36,8 @@ #pragma comment(lib, "Ws2_32.lib") #endif +#include <inttypes.h> #include <string.h> -#include <sys/types.h> #include <openssl/bio.h> #include <openssl/buf.h> @@ -42,6 +46,7 @@ #include <openssl/crypto.h> #include <openssl/err.h> #include <openssl/hmac.h> +#include <openssl/obj.h> #include <openssl/rand.h> #include <openssl/ssl.h> @@ -120,9 +125,10 @@ static const TestConfig *GetConfigPtr(const SSL *ssl) { return (const TestConfig *)SSL_get_ex_data(ssl, g_config_index); } -static bool SetTestState(SSL *ssl, std::unique_ptr<TestState> async) { - if (SSL_set_ex_data(ssl, g_state_index, (void *)async.get()) == 1) { - async.release(); +static bool SetTestState(SSL *ssl, std::unique_ptr<TestState> state) { + // |SSL_set_ex_data| takes ownership of |state| only on success. + if (SSL_set_ex_data(ssl, g_state_index, state.get()) == 1) { + state.release(); return true; } return false; @@ -172,8 +178,8 @@ static ssl_private_key_result_t AsyncPrivateKeySign( return ssl_private_key_failure; } test_state->private_key_result.resize(len); - if (!EVP_PKEY_sign(ctx.get(), bssl::vector_data( - &test_state->private_key_result), &len, in, in_len)) { + if (!EVP_PKEY_sign(ctx.get(), test_state->private_key_result.data(), &len, in, + in_len)) { return ssl_private_key_failure; } test_state->private_key_result.resize(len); @@ -202,7 +208,7 @@ static ssl_private_key_result_t AsyncPrivateKeySignComplete( fprintf(stderr, "Output buffer too small.\n"); return ssl_private_key_failure; } - memcpy(out, bssl::vector_data(&test_state->private_key_result), + memcpy(out, test_state->private_key_result.data(), test_state->private_key_result.size()); *out_len = test_state->private_key_result.size(); @@ -221,16 +227,14 @@ static ssl_private_key_result_t AsyncPrivateKeyDecrypt( abort(); } - EVP_PKEY *pkey = test_state->private_key.get(); - if (pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) { + RSA *rsa = EVP_PKEY_get0_RSA(test_state->private_key.get()); + if (rsa == NULL) { fprintf(stderr, "AsyncPrivateKeyDecrypt called with incorrect key type.\n"); abort(); } - RSA *rsa = pkey->pkey.rsa; test_state->private_key_result.resize(RSA_size(rsa)); - if (!RSA_decrypt(rsa, out_len, - bssl::vector_data(&test_state->private_key_result), + if (!RSA_decrypt(rsa, out_len, test_state->private_key_result.data(), RSA_size(rsa), in, in_len, RSA_NO_PADDING)) { return ssl_private_key_failure; } @@ -262,7 +266,7 @@ static ssl_private_key_result_t AsyncPrivateKeyDecryptComplete( fprintf(stderr, "Output buffer too small.\n"); return ssl_private_key_failure; } - memcpy(out, bssl::vector_data(&test_state->private_key_result), + memcpy(out, test_state->private_key_result.data(), test_state->private_key_result.size()); *out_len = test_state->private_key_result.size(); @@ -728,6 +732,24 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) { } ScopedDH dh(DH_get_2048_256(NULL)); + + if (config->use_sparse_dh_prime) { + // This prime number is 2^1024 + 643 – a value just above a power of two. + // Because of its form, values modulo it are essentially certain to be one + // byte shorter. This is used to test padding of these values. + if (BN_hex2bn( + &dh->p, + "1000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000028" + "3") == 0 || + !BN_set_word(dh->g, 2)) { + return nullptr; + } + dh->priv_length = 0; + } + if (!dh || !SSL_CTX_set_tmp_dh(ssl_ctx.get(), dh.get())) { return nullptr; } @@ -1070,6 +1092,15 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) { return false; } + if (config->expect_key_exchange_info != 0) { + uint32_t info = SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl)); + if (static_cast<uint32_t>(config->expect_key_exchange_info) != info) { + fprintf(stderr, "key_exchange_info was %" PRIu32 ", wanted %" PRIu32 "\n", + info, static_cast<uint32_t>(config->expect_key_exchange_info)); + return false; + } + } + if (!config->is_server) { /* Clients should expect a peer certificate chain iff this was not a PSK * cipher suite. */ @@ -1143,15 +1174,6 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx, if (config->no_ssl3) { SSL_set_options(ssl.get(), SSL_OP_NO_SSLv3); } - if (config->tls_d5_bug) { - SSL_set_options(ssl.get(), SSL_OP_TLS_D5_BUG); - } - if (config->microsoft_big_sslv3_buffer) { - SSL_set_options(ssl.get(), SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); - } - if (config->no_legacy_server_connect) { - SSL_clear_options(ssl.get(), SSL_OP_LEGACY_SERVER_CONNECT); - } if (!config->expected_channel_id.empty()) { SSL_enable_tls_channel_id(ssl.get()); } @@ -1223,6 +1245,21 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx, if (config->disable_npn) { SSL_set_options(ssl.get(), SSL_OP_DISABLE_NPN); } + if (config->p384_only) { + int nid = NID_secp384r1; + if (!SSL_set1_curves(ssl.get(), &nid, 1)) { + return false; + } + } + if (config->enable_all_curves) { + static const int kAllCurves[] = { + NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, NID_x25519, + }; + if (!SSL_set1_curves(ssl.get(), kAllCurves, + sizeof(kAllCurves) / sizeof(kAllCurves[0]))) { + return false; + } + } int sock = Connect(config->port); if (sock == -1) { diff --git a/src/ssl/test/packeted_bio.h b/src/ssl/test/packeted_bio.h index 30697a5..75cfa13 100644 --- a/src/ssl/test/packeted_bio.h +++ b/src/ssl/test/packeted_bio.h @@ -25,7 +25,7 @@ #include <winsock2.h> #pragma warning(pop) #else -#include <sys/types.h> +#include <sys/time.h> #endif diff --git a/src/ssl/test/runner/chacha20_poly1305.go b/src/ssl/test/runner/chacha20_poly1305.go index f2a1bbf..3c6ad82 100644 --- a/src/ssl/test/runner/chacha20_poly1305.go +++ b/src/ssl/test/runner/chacha20_poly1305.go @@ -5,11 +5,11 @@ import ( "crypto/subtle" "encoding/binary" "errors" + + "./poly1305" ) -// See draft-agl-tls-chacha20poly1305-04 and -// draft-irtf-cfrg-chacha20-poly1305-10. Where the two differ, the -// draft-agl-tls-chacha20poly1305-04 variant is implemented. +// See RFC 7539. func leftRotate(a uint32, n uint) uint32 { return (a << n) | (a >> (32 - n)) @@ -62,37 +62,30 @@ func sliceForAppend(in []byte, n int) (head, tail []byte) { return } -type chaCha20Poly1305 struct { - key [32]byte -} - -func newChaCha20Poly1305(key []byte) (cipher.AEAD, error) { - if len(key) != 32 { - return nil, errors.New("bad key length") - } - aead := new(chaCha20Poly1305) - copy(aead.key[:], key) - return aead, nil -} - -func (c *chaCha20Poly1305) NonceSize() int { return 8 } -func (c *chaCha20Poly1305) Overhead() int { return 16 } - -func (c *chaCha20Poly1305) chaCha20(out, in, nonce []byte, counter uint64) { +func chaCha20(out, in, key, nonce []byte, counter uint64) { var state [16]uint32 state[0] = 0x61707865 state[1] = 0x3320646e state[2] = 0x79622d32 state[3] = 0x6b206574 for i := 0; i < 8; i++ { - state[4+i] = binary.LittleEndian.Uint32(c.key[i*4 : i*4+4]) + state[4+i] = binary.LittleEndian.Uint32(key[i*4 : i*4+4]) + } + + switch len(nonce) { + case 8: + state[14] = binary.LittleEndian.Uint32(nonce[0:4]) + state[15] = binary.LittleEndian.Uint32(nonce[4:8]) + case 12: + state[13] = binary.LittleEndian.Uint32(nonce[0:4]) + state[14] = binary.LittleEndian.Uint32(nonce[4:8]) + state[15] = binary.LittleEndian.Uint32(nonce[8:12]) + default: + panic("bad nonce length") } - state[14] = binary.LittleEndian.Uint32(nonce[0:4]) - state[15] = binary.LittleEndian.Uint32(nonce[4:8]) for i := 0; i < len(in); i += 64 { - state[12] = uint32(counter & 0xffffffff) - state[13] = uint32(counter >> 32) + state[12] = uint32(counter) var tmp [64]byte chaCha20Block(&state, tmp[:]) @@ -108,7 +101,68 @@ func (c *chaCha20Poly1305) chaCha20(out, in, nonce []byte, counter uint64) { } } +// chaCha20Poly1305 implements the AEAD from +// RFC 7539 and draft-agl-tls-chacha20poly1305-04. +type chaCha20Poly1305 struct { + key [32]byte + // oldMode, if true, indicates that the draft spec should be + // implemented rather than the final, RFC version. + oldMode bool +} + +func newChaCha20Poly1305(key []byte) (cipher.AEAD, error) { + if len(key) != 32 { + return nil, errors.New("bad key length") + } + aead := new(chaCha20Poly1305) + copy(aead.key[:], key) + return aead, nil +} + +func newChaCha20Poly1305Old(key []byte) (cipher.AEAD, error) { + if len(key) != 32 { + return nil, errors.New("bad key length") + } + aead := &chaCha20Poly1305{ + oldMode: true, + } + copy(aead.key[:], key) + return aead, nil +} + +func (c *chaCha20Poly1305) NonceSize() int { + if c.oldMode { + return 8 + } else { + return 12 + } +} + +func (c *chaCha20Poly1305) Overhead() int { return 16 } + func (c *chaCha20Poly1305) poly1305(tag *[16]byte, nonce, ciphertext, additionalData []byte) { + input := make([]byte, 0, len(additionalData)+15+len(ciphertext)+15+8+8) + input = append(input, additionalData...) + var zeros [15]byte + if pad := len(input) % 16; pad != 0 { + input = append(input, zeros[:16-pad]...) + } + input = append(input, ciphertext...) + if pad := len(input) % 16; pad != 0 { + input = append(input, zeros[:16-pad]...) + } + input, out := sliceForAppend(input, 8) + binary.LittleEndian.PutUint64(out, uint64(len(additionalData))) + input, out = sliceForAppend(input, 8) + binary.LittleEndian.PutUint64(out, uint64(len(ciphertext))) + + var poly1305Key [32]byte + chaCha20(poly1305Key[:], poly1305Key[:], c.key[:], nonce, 0) + + poly1305.Sum(tag, input, &poly1305Key) +} + +func (c *chaCha20Poly1305) poly1305Old(tag *[16]byte, nonce, ciphertext, additionalData []byte) { input := make([]byte, 0, len(additionalData)+8+len(ciphertext)+8) input = append(input, additionalData...) input, out := sliceForAppend(input, 8) @@ -118,28 +172,32 @@ func (c *chaCha20Poly1305) poly1305(tag *[16]byte, nonce, ciphertext, additional binary.LittleEndian.PutUint64(out, uint64(len(ciphertext))) var poly1305Key [32]byte - c.chaCha20(poly1305Key[:], poly1305Key[:], nonce, 0) + chaCha20(poly1305Key[:], poly1305Key[:], c.key[:], nonce, 0) - poly1305Sum(tag, input, &poly1305Key) + poly1305.Sum(tag, input, &poly1305Key) } func (c *chaCha20Poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte { - if len(nonce) != 8 { + if len(nonce) != c.NonceSize() { panic("Bad nonce length") } ret, out := sliceForAppend(dst, len(plaintext)+16) - c.chaCha20(out[:len(plaintext)], plaintext, nonce, 1) + chaCha20(out[:len(plaintext)], plaintext, c.key[:], nonce, 1) var tag [16]byte - c.poly1305(&tag, nonce, out[:len(plaintext)], additionalData) + if c.oldMode { + c.poly1305Old(&tag, nonce, out[:len(plaintext)], additionalData) + } else { + c.poly1305(&tag, nonce, out[:len(plaintext)], additionalData) + } copy(out[len(plaintext):], tag[:]) return ret } func (c *chaCha20Poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { - if len(nonce) != 8 { + if len(nonce) != c.NonceSize() { panic("Bad nonce length") } if len(ciphertext) < 16 { @@ -148,12 +206,16 @@ func (c *chaCha20Poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ( plaintextLen := len(ciphertext) - 16 var tag [16]byte - c.poly1305(&tag, nonce, ciphertext[:plaintextLen], additionalData) + if c.oldMode { + c.poly1305Old(&tag, nonce, ciphertext[:plaintextLen], additionalData) + } else { + c.poly1305(&tag, nonce, ciphertext[:plaintextLen], additionalData) + } if subtle.ConstantTimeCompare(tag[:], ciphertext[plaintextLen:]) != 1 { return nil, errors.New("chacha20: message authentication failed") } ret, out := sliceForAppend(dst, plaintextLen) - c.chaCha20(out, ciphertext[:plaintextLen], nonce, 1) + chaCha20(out, ciphertext[:plaintextLen], c.key[:], nonce, 1) return ret, nil } diff --git a/src/ssl/test/runner/chacha20_poly1305_test.go b/src/ssl/test/runner/chacha20_poly1305_test.go index be49b11..4d19b8c 100644 --- a/src/ssl/test/runner/chacha20_poly1305_test.go +++ b/src/ssl/test/runner/chacha20_poly1305_test.go @@ -6,7 +6,7 @@ import ( "testing" ) -// See draft-irtf-cfrg-chacha20-poly1305-10, section 2.1.1. +// See RFC 7539, section 2.1.1. func TestChaChaQuarterRound(t *testing.T) { state := [16]uint32{0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567} chaChaQuarterRound(&state, 0, 1, 2, 3) @@ -17,7 +17,7 @@ func TestChaChaQuarterRound(t *testing.T) { } } -// See draft-irtf-cfrg-chacha20-poly1305-10, section 2.2.1. +// See RFC 7539, section 2.2.1. func TestChaChaQuarterRoundState(t *testing.T) { state := [16]uint32{ 0x879531e0, 0xc5ecf37d, 0x516461b1, 0xc9a62f8a, @@ -40,7 +40,7 @@ func TestChaChaQuarterRoundState(t *testing.T) { } } -// See draft-irtf-cfrg-chacha20-poly1305-10, section 2.3.2. +// See RFC 7539, section 2.3.2. func TestChaCha20Block(t *testing.T) { state := [16]uint32{ 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574, @@ -66,15 +66,23 @@ func TestChaCha20Block(t *testing.T) { } } +func decodeHexOrPanic(in string) []byte { + out, err := hex.DecodeString(in) + if err != nil { + panic(err) + } + return out +} + // See draft-agl-tls-chacha20poly1305-04, section 7. -func TestChaCha20Poly1305(t *testing.T) { - key, _ := hex.DecodeString("4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007") - input, _ := hex.DecodeString("86d09974840bded2a5ca") - nonce, _ := hex.DecodeString("cd7cf67be39c794a") - ad, _ := hex.DecodeString("87e229d4500845a079c0") - output, _ := hex.DecodeString("e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6") +func TestChaCha20Poly1305Old(t *testing.T) { + key := decodeHexOrPanic("4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007") + input := decodeHexOrPanic("86d09974840bded2a5ca") + nonce := decodeHexOrPanic("cd7cf67be39c794a") + ad := decodeHexOrPanic("87e229d4500845a079c0") + output := decodeHexOrPanic("e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6") - aead, err := newChaCha20Poly1305(key) + aead, err := newChaCha20Poly1305Old(key) if err != nil { t.Fatal(err) } @@ -97,3 +105,58 @@ func TestChaCha20Poly1305(t *testing.T) { t.Errorf("Open on malformed data unexpectedly succeeded") } } + +var chaCha20Poly1305TestVectors = []struct { + key, input, nonce, ad, output string +}{ + { + // See RFC 7539, section 2.8.2. + key: "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + input: "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e", + nonce: "070000004041424344454647", + ad: "50515253c0c1c2c3c4c5c6c7", + output: "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691", + }, + { + // See RFC 7539, section A.5. + key: "1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0", + input: "496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d", + nonce: "000000000102030405060708", + ad: "f33388860000000000004e91", + output: "64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709beead9d67890cbb22392336fea1851f38", + }, +} + +// See draft-agl-tls-chacha20poly1305-04, section 7. +func TestChaCha20Poly1305(t *testing.T) { + for i, tt := range chaCha20Poly1305TestVectors { + key := decodeHexOrPanic(tt.key) + input := decodeHexOrPanic(tt.input) + nonce := decodeHexOrPanic(tt.nonce) + ad := decodeHexOrPanic(tt.ad) + output := decodeHexOrPanic(tt.output) + + aead, err := newChaCha20Poly1305(key) + if err != nil { + t.Fatal(err) + } + + out, err := aead.Open(nil, nonce, output, ad) + if err != nil { + t.Errorf("%d. Open failed: %s", i, err) + } else if !bytes.Equal(out, input) { + t.Errorf("%d. Open gave %x, wanted %x", i, out, input) + } + + out = aead.Seal(nil, nonce, input, ad) + if !bytes.Equal(out, output) { + t.Errorf("%d. Open gave %x, wanted %x", i, out, output) + } + + out[0]++ + _, err = aead.Open(nil, nonce, out, ad) + if err == nil { + t.Errorf("%d. Open on malformed data unexpectedly succeeded", i) + } + } +} diff --git a/src/ssl/test/runner/cipher_suites.go b/src/ssl/test/runner/cipher_suites.go index c406000..bfd31a5 100644 --- a/src/ssl/test/runner/cipher_suites.go +++ b/src/ssl/test/runner/cipher_suites.go @@ -86,8 +86,10 @@ type cipherSuite struct { var cipherSuites = []*cipherSuite{ // Ciphersuite order is chosen so that ECDHE comes before plain RSA // and RC4 comes before AES (because of the Lucky13 attack). - {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, - {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 0, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, + {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, + {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, + {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old}, + {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, 0, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old}, {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM}, {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, @@ -119,11 +121,12 @@ var cipherSuites = []*cipherSuite{ {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, {TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, dheRSAKA, 0, cipher3DES, macSHA1, nil}, {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil}, + {TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, + {TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil}, + {TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil}, {TLS_PSK_WITH_RC4_128_SHA, 16, 20, 0, pskKA, suiteNoDTLS | suitePSK, cipherRC4, macSHA1, nil}, {TLS_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil}, {TLS_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil}, - {TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil}, - {TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil}, {TLS_RSA_WITH_NULL_SHA, 0, 20, 0, rsaKA, suiteNoDTLS, cipherNull, macSHA1, nil}, } @@ -248,12 +251,58 @@ func aeadAESGCM(key, fixedNonce []byte) *tlsAead { return &tlsAead{&fixedNonceAEAD{nonce1, nonce2, aead}, true} } +func aeadCHACHA20POLY1305Old(key, fixedNonce []byte) *tlsAead { + aead, err := newChaCha20Poly1305Old(key) + if err != nil { + panic(err) + } + return &tlsAead{aead, false} +} + +func xorSlice(out, in []byte) { + for i := range out { + out[i] ^= in[i] + } +} + +// xorNonceAEAD wraps an AEAD and XORs a fixed portion of the nonce, left-padded +// if necessary, each call. +type xorNonceAEAD struct { + // sealNonce and openNonce are buffers where the larger nonce will be + // constructed. Since a seal and open operation may be running + // concurrently, there is a separate buffer for each. + sealNonce, openNonce []byte + aead cipher.AEAD +} + +func (x *xorNonceAEAD) NonceSize() int { return 8 } +func (x *xorNonceAEAD) Overhead() int { return x.aead.Overhead() } + +func (x *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { + xorSlice(x.sealNonce[len(x.sealNonce)-len(nonce):], nonce) + ret := x.aead.Seal(out, x.sealNonce, plaintext, additionalData) + xorSlice(x.sealNonce[len(x.sealNonce)-len(nonce):], nonce) + return ret +} + +func (x *xorNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) { + xorSlice(x.openNonce[len(x.openNonce)-len(nonce):], nonce) + ret, err := x.aead.Open(out, x.openNonce, plaintext, additionalData) + xorSlice(x.openNonce[len(x.openNonce)-len(nonce):], nonce) + return ret, err +} + func aeadCHACHA20POLY1305(key, fixedNonce []byte) *tlsAead { aead, err := newChaCha20Poly1305(key) if err != nil { panic(err) } - return &tlsAead{aead, false} + + nonce1, nonce2 := make([]byte, len(fixedNonce)), make([]byte, len(fixedNonce)) + copy(nonce1, fixedNonce) + copy(nonce2, fixedNonce) + + return &tlsAead{&xorNonceAEAD{nonce1, nonce2, aead}, false} } // ssl30MAC implements the SSLv3 MAC function, as defined in @@ -375,49 +424,52 @@ func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { // A list of the possible cipher suite ids. Taken from // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml const ( - TLS_RSA_WITH_NULL_SHA uint16 = 0x0002 - TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004 - TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 - TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a - TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016 - TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f - TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033 - TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 - TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039 - TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c - TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003d - TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067 - TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006b - TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008a - TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008c - TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008d - TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c - TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d - TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009e - TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009f - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a - TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xc024 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xc028 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 - TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xc035 - TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xc036 - renegotiationSCSV uint16 = 0x00ff - fallbackSCSV uint16 = 0x5600 + TLS_RSA_WITH_NULL_SHA uint16 = 0x0002 + TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004 + TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 + TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016 + TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f + TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033 + TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039 + TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c + TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003d + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006b + TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008a + TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008c + TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008d + TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c + TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009e + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009f + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a + TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xc024 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xc028 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xc035 + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xc036 + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8 + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9 + TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xccac + renegotiationSCSV uint16 = 0x00ff + fallbackSCSV uint16 = 0x5600 ) // Additional cipher suite IDs, not IANA-assigned. const ( - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc13 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc14 + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD uint16 = 0xcc13 + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD uint16 = 0xcc14 ) diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go index 078c227..db3c675 100644 --- a/src/ssl/test/runner/common.go +++ b/src/ssl/test/runner/common.go @@ -98,10 +98,11 @@ const ( type CurveID uint16 const ( - CurveP224 CurveID = 21 - CurveP256 CurveID = 23 - CurveP384 CurveID = 24 - CurveP521 CurveID = 25 + CurveP224 CurveID = 21 + CurveP256 CurveID = 23 + CurveP384 CurveID = 24 + CurveP521 CurveID = 25 + CurveX25519 CurveID = 29 ) // TLS Elliptic Curve Point Formats @@ -399,6 +400,17 @@ const ( NumBadValues ) +type RSABadValue int + +const ( + RSABadValueNone RSABadValue = iota + RSABadValueCorrupt + RSABadValueTooLong + RSABadValueTooShort + RSABadValueWrongVersion + NumRSABadValues +) + type ProtocolBugs struct { // InvalidSKXSignature specifies that the signature in a // ServerKeyExchange message should be invalid. @@ -509,10 +521,9 @@ type ProtocolBugs struct { // alert to be sent. SendSpuriousAlert alert - // RsaClientKeyExchangeVersion, if non-zero, causes the client to send a - // ClientKeyExchange with the specified version rather than the - // client_version when performing the RSA key exchange. - RsaClientKeyExchangeVersion uint16 + // BadRSAClientKeyExchange causes the client to send a corrupted RSA + // ClientKeyExchange which would not pass padding checks. + BadRSAClientKeyExchange RSABadValue // RenewTicketOnResume causes the server to renew the session ticket and // send a NewSessionTicket message during an abbreviated handshake. @@ -535,11 +546,6 @@ type ProtocolBugs struct { // closed the connection) before or after sending app data. AlertBeforeFalseStartTest alert - // SSL3RSAKeyExchange causes the client to always send an RSA - // ClientKeyExchange message without the two-byte length - // prefix, as if it were SSL3. - SSL3RSAKeyExchange bool - // SkipCipherVersionCheck causes the server to negotiate // TLS 1.2 ciphers in earlier versions of TLS. SkipCipherVersionCheck bool @@ -584,10 +590,18 @@ type ProtocolBugs struct { // renegotiation handshake to be incorrect. BadRenegotiationInfo bool - // NoRenegotiationInfo causes the client to behave as if it - // didn't support the renegotiation info extension. + // NoRenegotiationInfo disables renegotiation info support in all + // handshakes. NoRenegotiationInfo bool + // NoRenegotiationInfoInInitial disables renegotiation info support in + // the initial handshake. + NoRenegotiationInfoInInitial bool + + // NoRenegotiationInfoAfterInitial disables renegotiation info support + // in renegotiation handshakes. + NoRenegotiationInfoAfterInitial bool + // RequireRenegotiationInfo, if true, causes the client to return an // error if the server doesn't reply with the renegotiation extension. RequireRenegotiationInfo bool @@ -787,6 +801,19 @@ type ProtocolBugs struct { // HelloRequest handshake message to be sent before each application // data record. This only makes sense for a server. SendHelloRequestBeforeEveryAppDataRecord bool + + // RequireDHPublicValueLen causes a fatal error if the length (in + // bytes) of the server's Diffie-Hellman public value is not equal to + // this. + RequireDHPublicValueLen int + + // BadChangeCipherSpec, if not nil, is the body to be sent in + // ChangeCipherSpec records instead of {1}. + BadChangeCipherSpec []byte + + // BadHelloRequest, if not nil, is what to send instead of a + // HelloRequest. + BadHelloRequest []byte } func (c *Config) serverInit() { @@ -844,7 +871,7 @@ func (c *Config) maxVersion() uint16 { return c.MaxVersion } -var defaultCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521} +var defaultCurvePreferences = []CurveID{CurveX25519, CurveP256, CurveP384, CurveP521} func (c *Config) curvePreferences() []CurveID { if c == nil || len(c.CurvePreferences) == 0 { diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go index ab9e233..cb60a92 100644 --- a/src/ssl/test/runner/conn.go +++ b/src/ssl/test/runner/conn.go @@ -1201,8 +1201,11 @@ func (c *Conn) handleRenegotiation() error { func (c *Conn) Renegotiate() error { if !c.isClient { - helloReq := new(helloRequestMsg) - c.writeRecord(recordTypeHandshake, helloReq.marshal()) + helloReq := new(helloRequestMsg).marshal() + if c.config.Bugs.BadHelloRequest != nil { + helloReq = c.config.Bugs.BadHelloRequest + } + c.writeRecord(recordTypeHandshake, helloReq) } c.handshakeComplete = false @@ -1414,3 +1417,18 @@ func (c *Conn) ExportKeyingMaterial(length int, label, context []byte, useContex prfForVersion(c.vers, c.cipherSuite)(result, c.masterSecret[:], label, seed) return result, nil } + +// noRenegotiationInfo returns true if the renegotiation info extension +// should be supported in the current handshake. +func (c *Conn) noRenegotiationInfo() bool { + if c.config.Bugs.NoRenegotiationInfo { + return true + } + if c.cipherSuite == nil && c.config.Bugs.NoRenegotiationInfoInInitial { + return true + } + if c.cipherSuite != nil && c.config.Bugs.NoRenegotiationInfoAfterInitial { + return true + } + return false +} diff --git a/src/ssl/test/runner/curve25519/const_amd64.s b/src/ssl/test/runner/curve25519/const_amd64.s new file mode 100644 index 0000000..797f9b0 --- /dev/null +++ b/src/ssl/test/runner/curve25519/const_amd64.s @@ -0,0 +1,20 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF +GLOBL ·REDMASK51(SB), 8, $8 + +DATA ·_121666_213(SB)/8, $996687872 +GLOBL ·_121666_213(SB), 8, $8 + +DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA +GLOBL ·_2P0(SB), 8, $8 + +DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE +GLOBL ·_2P1234(SB), 8, $8 diff --git a/src/ssl/test/runner/curve25519/cswap_amd64.s b/src/ssl/test/runner/curve25519/cswap_amd64.s new file mode 100644 index 0000000..45484d1 --- /dev/null +++ b/src/ssl/test/runner/curve25519/cswap_amd64.s @@ -0,0 +1,88 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +// func cswap(inout *[5]uint64, v uint64) +TEXT ·cswap(SB),7,$0 + MOVQ inout+0(FP),DI + MOVQ v+8(FP),SI + + CMPQ SI,$1 + MOVQ 0(DI),SI + MOVQ 80(DI),DX + MOVQ 8(DI),CX + MOVQ 88(DI),R8 + MOVQ SI,R9 + CMOVQEQ DX,SI + CMOVQEQ R9,DX + MOVQ CX,R9 + CMOVQEQ R8,CX + CMOVQEQ R9,R8 + MOVQ SI,0(DI) + MOVQ DX,80(DI) + MOVQ CX,8(DI) + MOVQ R8,88(DI) + MOVQ 16(DI),SI + MOVQ 96(DI),DX + MOVQ 24(DI),CX + MOVQ 104(DI),R8 + MOVQ SI,R9 + CMOVQEQ DX,SI + CMOVQEQ R9,DX + MOVQ CX,R9 + CMOVQEQ R8,CX + CMOVQEQ R9,R8 + MOVQ SI,16(DI) + MOVQ DX,96(DI) + MOVQ CX,24(DI) + MOVQ R8,104(DI) + MOVQ 32(DI),SI + MOVQ 112(DI),DX + MOVQ 40(DI),CX + MOVQ 120(DI),R8 + MOVQ SI,R9 + CMOVQEQ DX,SI + CMOVQEQ R9,DX + MOVQ CX,R9 + CMOVQEQ R8,CX + CMOVQEQ R9,R8 + MOVQ SI,32(DI) + MOVQ DX,112(DI) + MOVQ CX,40(DI) + MOVQ R8,120(DI) + MOVQ 48(DI),SI + MOVQ 128(DI),DX + MOVQ 56(DI),CX + MOVQ 136(DI),R8 + MOVQ SI,R9 + CMOVQEQ DX,SI + CMOVQEQ R9,DX + MOVQ CX,R9 + CMOVQEQ R8,CX + CMOVQEQ R9,R8 + MOVQ SI,48(DI) + MOVQ DX,128(DI) + MOVQ CX,56(DI) + MOVQ R8,136(DI) + MOVQ 64(DI),SI + MOVQ 144(DI),DX + MOVQ 72(DI),CX + MOVQ 152(DI),R8 + MOVQ SI,R9 + CMOVQEQ DX,SI + CMOVQEQ R9,DX + MOVQ CX,R9 + CMOVQEQ R8,CX + CMOVQEQ R9,R8 + MOVQ SI,64(DI) + MOVQ DX,144(DI) + MOVQ CX,72(DI) + MOVQ R8,152(DI) + MOVQ DI,AX + MOVQ SI,DX + RET diff --git a/src/ssl/test/runner/curve25519/curve25519.go b/src/ssl/test/runner/curve25519/curve25519.go new file mode 100644 index 0000000..6918c47 --- /dev/null +++ b/src/ssl/test/runner/curve25519/curve25519.go @@ -0,0 +1,841 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// We have a implementation in amd64 assembly so this code is only run on +// non-amd64 platforms. The amd64 assembly does not support gccgo. +// +build !amd64 gccgo appengine + +package curve25519 + +// This code is a port of the public domain, "ref10" implementation of +// curve25519 from SUPERCOP 20130419 by D. J. Bernstein. + +// fieldElement represents an element of the field GF(2^255 - 19). An element +// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 +// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on +// context. +type fieldElement [10]int32 + +func feZero(fe *fieldElement) { + for i := range fe { + fe[i] = 0 + } +} + +func feOne(fe *fieldElement) { + feZero(fe) + fe[0] = 1 +} + +func feAdd(dst, a, b *fieldElement) { + for i := range dst { + dst[i] = a[i] + b[i] + } +} + +func feSub(dst, a, b *fieldElement) { + for i := range dst { + dst[i] = a[i] - b[i] + } +} + +func feCopy(dst, src *fieldElement) { + for i := range dst { + dst[i] = src[i] + } +} + +// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +func feCSwap(f, g *fieldElement, b int32) { + var x fieldElement + b = -b + for i := range x { + x[i] = b & (f[i] ^ g[i]) + } + + for i := range f { + f[i] ^= x[i] + } + for i := range g { + g[i] ^= x[i] + } +} + +// load3 reads a 24-bit, little-endian value from in. +func load3(in []byte) int64 { + var r int64 + r = int64(in[0]) + r |= int64(in[1]) << 8 + r |= int64(in[2]) << 16 + return r +} + +// load4 reads a 32-bit, little-endian value from in. +func load4(in []byte) int64 { + var r int64 + r = int64(in[0]) + r |= int64(in[1]) << 8 + r |= int64(in[2]) << 16 + r |= int64(in[3]) << 24 + return r +} + +func feFromBytes(dst *fieldElement, src *[32]byte) { + h0 := load4(src[:]) + h1 := load3(src[4:]) << 6 + h2 := load3(src[7:]) << 5 + h3 := load3(src[10:]) << 3 + h4 := load3(src[13:]) << 2 + h5 := load4(src[16:]) + h6 := load3(src[20:]) << 7 + h7 := load3(src[23:]) << 5 + h8 := load3(src[26:]) << 4 + h9 := load3(src[29:]) << 2 + + var carry [10]int64 + carry[9] = (h9 + 1<<24) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + carry[1] = (h1 + 1<<24) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[3] = (h3 + 1<<24) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[5] = (h5 + 1<<24) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + carry[7] = (h7 + 1<<24) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[0] = (h0 + 1<<25) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[2] = (h2 + 1<<25) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[4] = (h4 + 1<<25) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[6] = (h6 + 1<<25) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + carry[8] = (h8 + 1<<25) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + dst[0] = int32(h0) + dst[1] = int32(h1) + dst[2] = int32(h2) + dst[3] = int32(h3) + dst[4] = int32(h4) + dst[5] = int32(h5) + dst[6] = int32(h6) + dst[7] = int32(h7) + dst[8] = int32(h8) + dst[9] = int32(h9) +} + +// feToBytes marshals h to s. +// Preconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Write p=2^255-19; q=floor(h/p). +// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). +// +// Proof: +// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. +// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4. +// +// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). +// Then 0<y<1. +// +// Write r=h-pq. +// Have 0<=r<=p-1=2^255-20. +// Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1. +// +// Write x=r+19(2^-255)r+y. +// Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q. +// +// Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1)) +// so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q. +func feToBytes(s *[32]byte, h *fieldElement) { + var carry [10]int32 + + q := (19*h[9] + (1 << 24)) >> 25 + q = (h[0] + q) >> 26 + q = (h[1] + q) >> 25 + q = (h[2] + q) >> 26 + q = (h[3] + q) >> 25 + q = (h[4] + q) >> 26 + q = (h[5] + q) >> 25 + q = (h[6] + q) >> 26 + q = (h[7] + q) >> 25 + q = (h[8] + q) >> 26 + q = (h[9] + q) >> 25 + + // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. + h[0] += 19 * q + // Goal: Output h-2^255 q, which is between 0 and 2^255-20. + + carry[0] = h[0] >> 26 + h[1] += carry[0] + h[0] -= carry[0] << 26 + carry[1] = h[1] >> 25 + h[2] += carry[1] + h[1] -= carry[1] << 25 + carry[2] = h[2] >> 26 + h[3] += carry[2] + h[2] -= carry[2] << 26 + carry[3] = h[3] >> 25 + h[4] += carry[3] + h[3] -= carry[3] << 25 + carry[4] = h[4] >> 26 + h[5] += carry[4] + h[4] -= carry[4] << 26 + carry[5] = h[5] >> 25 + h[6] += carry[5] + h[5] -= carry[5] << 25 + carry[6] = h[6] >> 26 + h[7] += carry[6] + h[6] -= carry[6] << 26 + carry[7] = h[7] >> 25 + h[8] += carry[7] + h[7] -= carry[7] << 25 + carry[8] = h[8] >> 26 + h[9] += carry[8] + h[8] -= carry[8] << 26 + carry[9] = h[9] >> 25 + h[9] -= carry[9] << 25 + // h10 = carry9 + + // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + // Have h[0]+...+2^230 h[9] between 0 and 2^255-1; + // evidently 2^255 h10-2^255 q = 0. + // Goal: Output h[0]+...+2^230 h[9]. + + s[0] = byte(h[0] >> 0) + s[1] = byte(h[0] >> 8) + s[2] = byte(h[0] >> 16) + s[3] = byte((h[0] >> 24) | (h[1] << 2)) + s[4] = byte(h[1] >> 6) + s[5] = byte(h[1] >> 14) + s[6] = byte((h[1] >> 22) | (h[2] << 3)) + s[7] = byte(h[2] >> 5) + s[8] = byte(h[2] >> 13) + s[9] = byte((h[2] >> 21) | (h[3] << 5)) + s[10] = byte(h[3] >> 3) + s[11] = byte(h[3] >> 11) + s[12] = byte((h[3] >> 19) | (h[4] << 6)) + s[13] = byte(h[4] >> 2) + s[14] = byte(h[4] >> 10) + s[15] = byte(h[4] >> 18) + s[16] = byte(h[5] >> 0) + s[17] = byte(h[5] >> 8) + s[18] = byte(h[5] >> 16) + s[19] = byte((h[5] >> 24) | (h[6] << 1)) + s[20] = byte(h[6] >> 7) + s[21] = byte(h[6] >> 15) + s[22] = byte((h[6] >> 23) | (h[7] << 3)) + s[23] = byte(h[7] >> 5) + s[24] = byte(h[7] >> 13) + s[25] = byte((h[7] >> 21) | (h[8] << 4)) + s[26] = byte(h[8] >> 4) + s[27] = byte(h[8] >> 12) + s[28] = byte((h[8] >> 20) | (h[9] << 6)) + s[29] = byte(h[9] >> 2) + s[30] = byte(h[9] >> 10) + s[31] = byte(h[9] >> 18) +} + +// feMul calculates h = f * g +// Can overlap h with f or g. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Notes on implementation strategy: +// +// Using schoolbook multiplication. +// Karatsuba would save a little in some cost models. +// +// Most multiplications by 2 and 19 are 32-bit precomputations; +// cheaper than 64-bit postcomputations. +// +// There is one remaining multiplication by 19 in the carry chain; +// one *19 precomputation can be merged into this, +// but the resulting data flow is considerably less clean. +// +// There are 12 carries below. +// 10 of them are 2-way parallelizable and vectorizable. +// Can get away with 11 carries, but then data flow is much deeper. +// +// With tighter constraints on inputs can squeeze carries into int32. +func feMul(h, f, g *fieldElement) { + f0 := f[0] + f1 := f[1] + f2 := f[2] + f3 := f[3] + f4 := f[4] + f5 := f[5] + f6 := f[6] + f7 := f[7] + f8 := f[8] + f9 := f[9] + g0 := g[0] + g1 := g[1] + g2 := g[2] + g3 := g[3] + g4 := g[4] + g5 := g[5] + g6 := g[6] + g7 := g[7] + g8 := g[8] + g9 := g[9] + g1_19 := 19 * g1 // 1.4*2^29 + g2_19 := 19 * g2 // 1.4*2^30; still ok + g3_19 := 19 * g3 + g4_19 := 19 * g4 + g5_19 := 19 * g5 + g6_19 := 19 * g6 + g7_19 := 19 * g7 + g8_19 := 19 * g8 + g9_19 := 19 * g9 + f1_2 := 2 * f1 + f3_2 := 2 * f3 + f5_2 := 2 * f5 + f7_2 := 2 * f7 + f9_2 := 2 * f9 + f0g0 := int64(f0) * int64(g0) + f0g1 := int64(f0) * int64(g1) + f0g2 := int64(f0) * int64(g2) + f0g3 := int64(f0) * int64(g3) + f0g4 := int64(f0) * int64(g4) + f0g5 := int64(f0) * int64(g5) + f0g6 := int64(f0) * int64(g6) + f0g7 := int64(f0) * int64(g7) + f0g8 := int64(f0) * int64(g8) + f0g9 := int64(f0) * int64(g9) + f1g0 := int64(f1) * int64(g0) + f1g1_2 := int64(f1_2) * int64(g1) + f1g2 := int64(f1) * int64(g2) + f1g3_2 := int64(f1_2) * int64(g3) + f1g4 := int64(f1) * int64(g4) + f1g5_2 := int64(f1_2) * int64(g5) + f1g6 := int64(f1) * int64(g6) + f1g7_2 := int64(f1_2) * int64(g7) + f1g8 := int64(f1) * int64(g8) + f1g9_38 := int64(f1_2) * int64(g9_19) + f2g0 := int64(f2) * int64(g0) + f2g1 := int64(f2) * int64(g1) + f2g2 := int64(f2) * int64(g2) + f2g3 := int64(f2) * int64(g3) + f2g4 := int64(f2) * int64(g4) + f2g5 := int64(f2) * int64(g5) + f2g6 := int64(f2) * int64(g6) + f2g7 := int64(f2) * int64(g7) + f2g8_19 := int64(f2) * int64(g8_19) + f2g9_19 := int64(f2) * int64(g9_19) + f3g0 := int64(f3) * int64(g0) + f3g1_2 := int64(f3_2) * int64(g1) + f3g2 := int64(f3) * int64(g2) + f3g3_2 := int64(f3_2) * int64(g3) + f3g4 := int64(f3) * int64(g4) + f3g5_2 := int64(f3_2) * int64(g5) + f3g6 := int64(f3) * int64(g6) + f3g7_38 := int64(f3_2) * int64(g7_19) + f3g8_19 := int64(f3) * int64(g8_19) + f3g9_38 := int64(f3_2) * int64(g9_19) + f4g0 := int64(f4) * int64(g0) + f4g1 := int64(f4) * int64(g1) + f4g2 := int64(f4) * int64(g2) + f4g3 := int64(f4) * int64(g3) + f4g4 := int64(f4) * int64(g4) + f4g5 := int64(f4) * int64(g5) + f4g6_19 := int64(f4) * int64(g6_19) + f4g7_19 := int64(f4) * int64(g7_19) + f4g8_19 := int64(f4) * int64(g8_19) + f4g9_19 := int64(f4) * int64(g9_19) + f5g0 := int64(f5) * int64(g0) + f5g1_2 := int64(f5_2) * int64(g1) + f5g2 := int64(f5) * int64(g2) + f5g3_2 := int64(f5_2) * int64(g3) + f5g4 := int64(f5) * int64(g4) + f5g5_38 := int64(f5_2) * int64(g5_19) + f5g6_19 := int64(f5) * int64(g6_19) + f5g7_38 := int64(f5_2) * int64(g7_19) + f5g8_19 := int64(f5) * int64(g8_19) + f5g9_38 := int64(f5_2) * int64(g9_19) + f6g0 := int64(f6) * int64(g0) + f6g1 := int64(f6) * int64(g1) + f6g2 := int64(f6) * int64(g2) + f6g3 := int64(f6) * int64(g3) + f6g4_19 := int64(f6) * int64(g4_19) + f6g5_19 := int64(f6) * int64(g5_19) + f6g6_19 := int64(f6) * int64(g6_19) + f6g7_19 := int64(f6) * int64(g7_19) + f6g8_19 := int64(f6) * int64(g8_19) + f6g9_19 := int64(f6) * int64(g9_19) + f7g0 := int64(f7) * int64(g0) + f7g1_2 := int64(f7_2) * int64(g1) + f7g2 := int64(f7) * int64(g2) + f7g3_38 := int64(f7_2) * int64(g3_19) + f7g4_19 := int64(f7) * int64(g4_19) + f7g5_38 := int64(f7_2) * int64(g5_19) + f7g6_19 := int64(f7) * int64(g6_19) + f7g7_38 := int64(f7_2) * int64(g7_19) + f7g8_19 := int64(f7) * int64(g8_19) + f7g9_38 := int64(f7_2) * int64(g9_19) + f8g0 := int64(f8) * int64(g0) + f8g1 := int64(f8) * int64(g1) + f8g2_19 := int64(f8) * int64(g2_19) + f8g3_19 := int64(f8) * int64(g3_19) + f8g4_19 := int64(f8) * int64(g4_19) + f8g5_19 := int64(f8) * int64(g5_19) + f8g6_19 := int64(f8) * int64(g6_19) + f8g7_19 := int64(f8) * int64(g7_19) + f8g8_19 := int64(f8) * int64(g8_19) + f8g9_19 := int64(f8) * int64(g9_19) + f9g0 := int64(f9) * int64(g0) + f9g1_38 := int64(f9_2) * int64(g1_19) + f9g2_19 := int64(f9) * int64(g2_19) + f9g3_38 := int64(f9_2) * int64(g3_19) + f9g4_19 := int64(f9) * int64(g4_19) + f9g5_38 := int64(f9_2) * int64(g5_19) + f9g6_19 := int64(f9) * int64(g6_19) + f9g7_38 := int64(f9_2) * int64(g7_19) + f9g8_19 := int64(f9) * int64(g8_19) + f9g9_38 := int64(f9_2) * int64(g9_19) + h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38 + h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19 + h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38 + h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19 + h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38 + h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19 + h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38 + h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19 + h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38 + h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 + var carry [10]int64 + + // |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38)) + // i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8 + // |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19)) + // i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + // |h0| <= 2^25 + // |h4| <= 2^25 + // |h1| <= 1.51*2^58 + // |h5| <= 1.51*2^58 + + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + // |h1| <= 2^24; from now on fits into int32 + // |h5| <= 2^24; from now on fits into int32 + // |h2| <= 1.21*2^59 + // |h6| <= 1.21*2^59 + + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + // |h2| <= 2^25; from now on fits into int32 unchanged + // |h6| <= 2^25; from now on fits into int32 unchanged + // |h3| <= 1.51*2^58 + // |h7| <= 1.51*2^58 + + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + // |h3| <= 2^24; from now on fits into int32 unchanged + // |h7| <= 2^24; from now on fits into int32 unchanged + // |h4| <= 1.52*2^33 + // |h8| <= 1.52*2^33 + + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + // |h4| <= 2^25; from now on fits into int32 unchanged + // |h8| <= 2^25; from now on fits into int32 unchanged + // |h5| <= 1.01*2^24 + // |h9| <= 1.51*2^58 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + // |h9| <= 2^24; from now on fits into int32 unchanged + // |h0| <= 1.8*2^37 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + // |h0| <= 2^25; from now on fits into int32 unchanged + // |h1| <= 1.01*2^24 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feSquare calculates h = f*f. Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func feSquare(h, f *fieldElement) { + f0 := f[0] + f1 := f[1] + f2 := f[2] + f3 := f[3] + f4 := f[4] + f5 := f[5] + f6 := f[6] + f7 := f[7] + f8 := f[8] + f9 := f[9] + f0_2 := 2 * f0 + f1_2 := 2 * f1 + f2_2 := 2 * f2 + f3_2 := 2 * f3 + f4_2 := 2 * f4 + f5_2 := 2 * f5 + f6_2 := 2 * f6 + f7_2 := 2 * f7 + f5_38 := 38 * f5 // 1.31*2^30 + f6_19 := 19 * f6 // 1.31*2^30 + f7_38 := 38 * f7 // 1.31*2^30 + f8_19 := 19 * f8 // 1.31*2^30 + f9_38 := 38 * f9 // 1.31*2^30 + f0f0 := int64(f0) * int64(f0) + f0f1_2 := int64(f0_2) * int64(f1) + f0f2_2 := int64(f0_2) * int64(f2) + f0f3_2 := int64(f0_2) * int64(f3) + f0f4_2 := int64(f0_2) * int64(f4) + f0f5_2 := int64(f0_2) * int64(f5) + f0f6_2 := int64(f0_2) * int64(f6) + f0f7_2 := int64(f0_2) * int64(f7) + f0f8_2 := int64(f0_2) * int64(f8) + f0f9_2 := int64(f0_2) * int64(f9) + f1f1_2 := int64(f1_2) * int64(f1) + f1f2_2 := int64(f1_2) * int64(f2) + f1f3_4 := int64(f1_2) * int64(f3_2) + f1f4_2 := int64(f1_2) * int64(f4) + f1f5_4 := int64(f1_2) * int64(f5_2) + f1f6_2 := int64(f1_2) * int64(f6) + f1f7_4 := int64(f1_2) * int64(f7_2) + f1f8_2 := int64(f1_2) * int64(f8) + f1f9_76 := int64(f1_2) * int64(f9_38) + f2f2 := int64(f2) * int64(f2) + f2f3_2 := int64(f2_2) * int64(f3) + f2f4_2 := int64(f2_2) * int64(f4) + f2f5_2 := int64(f2_2) * int64(f5) + f2f6_2 := int64(f2_2) * int64(f6) + f2f7_2 := int64(f2_2) * int64(f7) + f2f8_38 := int64(f2_2) * int64(f8_19) + f2f9_38 := int64(f2) * int64(f9_38) + f3f3_2 := int64(f3_2) * int64(f3) + f3f4_2 := int64(f3_2) * int64(f4) + f3f5_4 := int64(f3_2) * int64(f5_2) + f3f6_2 := int64(f3_2) * int64(f6) + f3f7_76 := int64(f3_2) * int64(f7_38) + f3f8_38 := int64(f3_2) * int64(f8_19) + f3f9_76 := int64(f3_2) * int64(f9_38) + f4f4 := int64(f4) * int64(f4) + f4f5_2 := int64(f4_2) * int64(f5) + f4f6_38 := int64(f4_2) * int64(f6_19) + f4f7_38 := int64(f4) * int64(f7_38) + f4f8_38 := int64(f4_2) * int64(f8_19) + f4f9_38 := int64(f4) * int64(f9_38) + f5f5_38 := int64(f5) * int64(f5_38) + f5f6_38 := int64(f5_2) * int64(f6_19) + f5f7_76 := int64(f5_2) * int64(f7_38) + f5f8_38 := int64(f5_2) * int64(f8_19) + f5f9_76 := int64(f5_2) * int64(f9_38) + f6f6_19 := int64(f6) * int64(f6_19) + f6f7_38 := int64(f6) * int64(f7_38) + f6f8_38 := int64(f6_2) * int64(f8_19) + f6f9_38 := int64(f6) * int64(f9_38) + f7f7_38 := int64(f7) * int64(f7_38) + f7f8_38 := int64(f7_2) * int64(f8_19) + f7f9_76 := int64(f7_2) * int64(f9_38) + f8f8_19 := int64(f8) * int64(f8_19) + f8f9_38 := int64(f8) * int64(f9_38) + f9f9_38 := int64(f9) * int64(f9_38) + h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38 + h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38 + h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19 + h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38 + h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38 + h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38 + h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19 + h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38 + h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38 + h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2 + var carry [10]int64 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feMul121666 calculates h = f * 121666. Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func feMul121666(h, f *fieldElement) { + h0 := int64(f[0]) * 121666 + h1 := int64(f[1]) * 121666 + h2 := int64(f[2]) * 121666 + h3 := int64(f[3]) * 121666 + h4 := int64(f[4]) * 121666 + h5 := int64(f[5]) * 121666 + h6 := int64(f[6]) * 121666 + h7 := int64(f[7]) * 121666 + h8 := int64(f[8]) * 121666 + h9 := int64(f[9]) * 121666 + var carry [10]int64 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feInvert sets out = z^-1. +func feInvert(out, z *fieldElement) { + var t0, t1, t2, t3 fieldElement + var i int + + feSquare(&t0, z) + for i = 1; i < 1; i++ { + feSquare(&t0, &t0) + } + feSquare(&t1, &t0) + for i = 1; i < 2; i++ { + feSquare(&t1, &t1) + } + feMul(&t1, z, &t1) + feMul(&t0, &t0, &t1) + feSquare(&t2, &t0) + for i = 1; i < 1; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t1, &t2) + feSquare(&t2, &t1) + for i = 1; i < 5; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t2, &t1) + for i = 1; i < 10; i++ { + feSquare(&t2, &t2) + } + feMul(&t2, &t2, &t1) + feSquare(&t3, &t2) + for i = 1; i < 20; i++ { + feSquare(&t3, &t3) + } + feMul(&t2, &t3, &t2) + feSquare(&t2, &t2) + for i = 1; i < 10; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t2, &t1) + for i = 1; i < 50; i++ { + feSquare(&t2, &t2) + } + feMul(&t2, &t2, &t1) + feSquare(&t3, &t2) + for i = 1; i < 100; i++ { + feSquare(&t3, &t3) + } + feMul(&t2, &t3, &t2) + feSquare(&t2, &t2) + for i = 1; i < 50; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t1, &t1) + for i = 1; i < 5; i++ { + feSquare(&t1, &t1) + } + feMul(out, &t1, &t0) +} + +func scalarMult(out, in, base *[32]byte) { + var e [32]byte + + copy(e[:], in[:]) + e[0] &= 248 + e[31] &= 127 + e[31] |= 64 + + var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement + feFromBytes(&x1, base) + feOne(&x2) + feCopy(&x3, &x1) + feOne(&z3) + + swap := int32(0) + for pos := 254; pos >= 0; pos-- { + b := e[pos/8] >> uint(pos&7) + b &= 1 + swap ^= int32(b) + feCSwap(&x2, &x3, swap) + feCSwap(&z2, &z3, swap) + swap = int32(b) + + feSub(&tmp0, &x3, &z3) + feSub(&tmp1, &x2, &z2) + feAdd(&x2, &x2, &z2) + feAdd(&z2, &x3, &z3) + feMul(&z3, &tmp0, &x2) + feMul(&z2, &z2, &tmp1) + feSquare(&tmp0, &tmp1) + feSquare(&tmp1, &x2) + feAdd(&x3, &z3, &z2) + feSub(&z2, &z3, &z2) + feMul(&x2, &tmp1, &tmp0) + feSub(&tmp1, &tmp1, &tmp0) + feSquare(&z2, &z2) + feMul121666(&z3, &tmp1) + feSquare(&x3, &x3) + feAdd(&tmp0, &tmp0, &z3) + feMul(&z3, &x1, &z2) + feMul(&z2, &tmp1, &tmp0) + } + + feCSwap(&x2, &x3, swap) + feCSwap(&z2, &z3, swap) + + feInvert(&z2, &z2) + feMul(&x2, &x2, &z2) + feToBytes(out, &x2) +} diff --git a/src/ssl/test/runner/curve25519/curve25519_test.go b/src/ssl/test/runner/curve25519/curve25519_test.go new file mode 100644 index 0000000..14b0ee8 --- /dev/null +++ b/src/ssl/test/runner/curve25519/curve25519_test.go @@ -0,0 +1,29 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package curve25519 + +import ( + "fmt" + "testing" +) + +const expectedHex = "89161fde887b2b53de549af483940106ecc114d6982daa98256de23bdf77661a" + +func TestBaseScalarMult(t *testing.T) { + var a, b [32]byte + in := &a + out := &b + a[0] = 1 + + for i := 0; i < 200; i++ { + ScalarBaseMult(out, in) + in, out = out, in + } + + result := fmt.Sprintf("%x", in[:]) + if result != expectedHex { + t.Errorf("incorrect result: got %s, want %s", result, expectedHex) + } +} diff --git a/src/ssl/test/runner/curve25519/doc.go b/src/ssl/test/runner/curve25519/doc.go new file mode 100644 index 0000000..ebeea3c --- /dev/null +++ b/src/ssl/test/runner/curve25519/doc.go @@ -0,0 +1,23 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package curve25519 provides an implementation of scalar multiplication on +// the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html +package curve25519 // import "golang.org/x/crypto/curve25519" + +// basePoint is the x coordinate of the generator of the curve. +var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +// ScalarMult sets dst to the product in*base where dst and base are the x +// coordinates of group points and all values are in little-endian form. +func ScalarMult(dst, in, base *[32]byte) { + scalarMult(dst, in, base) +} + +// ScalarBaseMult sets dst to the product in*base where dst and base are the x +// coordinates of group points, base is the standard generator and all values +// are in little-endian form. +func ScalarBaseMult(dst, in *[32]byte) { + ScalarMult(dst, in, &basePoint) +} diff --git a/src/ssl/test/runner/curve25519/freeze_amd64.s b/src/ssl/test/runner/curve25519/freeze_amd64.s new file mode 100644 index 0000000..37599fa --- /dev/null +++ b/src/ssl/test/runner/curve25519/freeze_amd64.s @@ -0,0 +1,94 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +// func freeze(inout *[5]uint64) +TEXT ·freeze(SB),7,$96-8 + MOVQ inout+0(FP), DI + + MOVQ SP,R11 + MOVQ $31,CX + NOTQ CX + ANDQ CX,SP + ADDQ $32,SP + + MOVQ R11,0(SP) + MOVQ R12,8(SP) + MOVQ R13,16(SP) + MOVQ R14,24(SP) + MOVQ R15,32(SP) + MOVQ BX,40(SP) + MOVQ BP,48(SP) + MOVQ 0(DI),SI + MOVQ 8(DI),DX + MOVQ 16(DI),CX + MOVQ 24(DI),R8 + MOVQ 32(DI),R9 + MOVQ ·REDMASK51(SB),AX + MOVQ AX,R10 + SUBQ $18,R10 + MOVQ $3,R11 +REDUCELOOP: + MOVQ SI,R12 + SHRQ $51,R12 + ANDQ AX,SI + ADDQ R12,DX + MOVQ DX,R12 + SHRQ $51,R12 + ANDQ AX,DX + ADDQ R12,CX + MOVQ CX,R12 + SHRQ $51,R12 + ANDQ AX,CX + ADDQ R12,R8 + MOVQ R8,R12 + SHRQ $51,R12 + ANDQ AX,R8 + ADDQ R12,R9 + MOVQ R9,R12 + SHRQ $51,R12 + ANDQ AX,R9 + IMUL3Q $19,R12,R12 + ADDQ R12,SI + SUBQ $1,R11 + JA REDUCELOOP + MOVQ $1,R12 + CMPQ R10,SI + CMOVQLT R11,R12 + CMPQ AX,DX + CMOVQNE R11,R12 + CMPQ AX,CX + CMOVQNE R11,R12 + CMPQ AX,R8 + CMOVQNE R11,R12 + CMPQ AX,R9 + CMOVQNE R11,R12 + NEGQ R12 + ANDQ R12,AX + ANDQ R12,R10 + SUBQ R10,SI + SUBQ AX,DX + SUBQ AX,CX + SUBQ AX,R8 + SUBQ AX,R9 + MOVQ SI,0(DI) + MOVQ DX,8(DI) + MOVQ CX,16(DI) + MOVQ R8,24(DI) + MOVQ R9,32(DI) + MOVQ 0(SP),R11 + MOVQ 8(SP),R12 + MOVQ 16(SP),R13 + MOVQ 24(SP),R14 + MOVQ 32(SP),R15 + MOVQ 40(SP),BX + MOVQ 48(SP),BP + MOVQ R11,SP + MOVQ DI,AX + MOVQ SI,DX + RET diff --git a/src/ssl/test/runner/curve25519/ladderstep_amd64.s b/src/ssl/test/runner/curve25519/ladderstep_amd64.s new file mode 100644 index 0000000..3949f9c --- /dev/null +++ b/src/ssl/test/runner/curve25519/ladderstep_amd64.s @@ -0,0 +1,1398 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +// func ladderstep(inout *[5][5]uint64) +TEXT ·ladderstep(SB),0,$384-8 + MOVQ inout+0(FP),DI + + MOVQ SP,R11 + MOVQ $31,CX + NOTQ CX + ANDQ CX,SP + ADDQ $32,SP + + MOVQ R11,0(SP) + MOVQ R12,8(SP) + MOVQ R13,16(SP) + MOVQ R14,24(SP) + MOVQ R15,32(SP) + MOVQ BX,40(SP) + MOVQ BP,48(SP) + MOVQ 40(DI),SI + MOVQ 48(DI),DX + MOVQ 56(DI),CX + MOVQ 64(DI),R8 + MOVQ 72(DI),R9 + MOVQ SI,AX + MOVQ DX,R10 + MOVQ CX,R11 + MOVQ R8,R12 + MOVQ R9,R13 + ADDQ ·_2P0(SB),AX + ADDQ ·_2P1234(SB),R10 + ADDQ ·_2P1234(SB),R11 + ADDQ ·_2P1234(SB),R12 + ADDQ ·_2P1234(SB),R13 + ADDQ 80(DI),SI + ADDQ 88(DI),DX + ADDQ 96(DI),CX + ADDQ 104(DI),R8 + ADDQ 112(DI),R9 + SUBQ 80(DI),AX + SUBQ 88(DI),R10 + SUBQ 96(DI),R11 + SUBQ 104(DI),R12 + SUBQ 112(DI),R13 + MOVQ SI,56(SP) + MOVQ DX,64(SP) + MOVQ CX,72(SP) + MOVQ R8,80(SP) + MOVQ R9,88(SP) + MOVQ AX,96(SP) + MOVQ R10,104(SP) + MOVQ R11,112(SP) + MOVQ R12,120(SP) + MOVQ R13,128(SP) + MOVQ 96(SP),AX + MULQ 96(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 96(SP),AX + SHLQ $1,AX + MULQ 104(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 96(SP),AX + SHLQ $1,AX + MULQ 112(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 96(SP),AX + SHLQ $1,AX + MULQ 120(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 96(SP),AX + SHLQ $1,AX + MULQ 128(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 104(SP),AX + MULQ 104(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 104(SP),AX + SHLQ $1,AX + MULQ 112(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 104(SP),AX + SHLQ $1,AX + MULQ 120(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 104(SP),DX + IMUL3Q $38,DX,AX + MULQ 128(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 112(SP),AX + MULQ 112(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 112(SP),DX + IMUL3Q $38,DX,AX + MULQ 120(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 112(SP),DX + IMUL3Q $38,DX,AX + MULQ 128(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 120(SP),DX + IMUL3Q $19,DX,AX + MULQ 120(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 120(SP),DX + IMUL3Q $38,DX,AX + MULQ 128(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 128(SP),DX + IMUL3Q $19,DX,AX + MULQ 128(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ ·REDMASK51(SB),DX + SHLQ $13,CX:SI + ANDQ DX,SI + SHLQ $13,R9:R8 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R11:R10 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + ANDQ DX,SI + MOVQ CX,R8 + SHRQ $51,CX + ADDQ R10,CX + ANDQ DX,R8 + MOVQ CX,R9 + SHRQ $51,CX + ADDQ R12,CX + ANDQ DX,R9 + MOVQ CX,AX + SHRQ $51,CX + ADDQ R14,CX + ANDQ DX,AX + MOVQ CX,R10 + SHRQ $51,CX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,136(SP) + MOVQ R8,144(SP) + MOVQ R9,152(SP) + MOVQ AX,160(SP) + MOVQ R10,168(SP) + MOVQ 56(SP),AX + MULQ 56(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 56(SP),AX + SHLQ $1,AX + MULQ 64(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 56(SP),AX + SHLQ $1,AX + MULQ 72(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 56(SP),AX + SHLQ $1,AX + MULQ 80(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 56(SP),AX + SHLQ $1,AX + MULQ 88(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 64(SP),AX + MULQ 64(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 64(SP),AX + SHLQ $1,AX + MULQ 72(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 64(SP),AX + SHLQ $1,AX + MULQ 80(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 64(SP),DX + IMUL3Q $38,DX,AX + MULQ 88(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 72(SP),AX + MULQ 72(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 72(SP),DX + IMUL3Q $38,DX,AX + MULQ 80(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 72(SP),DX + IMUL3Q $38,DX,AX + MULQ 88(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 80(SP),DX + IMUL3Q $19,DX,AX + MULQ 80(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 80(SP),DX + IMUL3Q $38,DX,AX + MULQ 88(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 88(SP),DX + IMUL3Q $19,DX,AX + MULQ 88(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ ·REDMASK51(SB),DX + SHLQ $13,CX:SI + ANDQ DX,SI + SHLQ $13,R9:R8 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R11:R10 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + ANDQ DX,SI + MOVQ CX,R8 + SHRQ $51,CX + ADDQ R10,CX + ANDQ DX,R8 + MOVQ CX,R9 + SHRQ $51,CX + ADDQ R12,CX + ANDQ DX,R9 + MOVQ CX,AX + SHRQ $51,CX + ADDQ R14,CX + ANDQ DX,AX + MOVQ CX,R10 + SHRQ $51,CX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,176(SP) + MOVQ R8,184(SP) + MOVQ R9,192(SP) + MOVQ AX,200(SP) + MOVQ R10,208(SP) + MOVQ SI,SI + MOVQ R8,DX + MOVQ R9,CX + MOVQ AX,R8 + MOVQ R10,R9 + ADDQ ·_2P0(SB),SI + ADDQ ·_2P1234(SB),DX + ADDQ ·_2P1234(SB),CX + ADDQ ·_2P1234(SB),R8 + ADDQ ·_2P1234(SB),R9 + SUBQ 136(SP),SI + SUBQ 144(SP),DX + SUBQ 152(SP),CX + SUBQ 160(SP),R8 + SUBQ 168(SP),R9 + MOVQ SI,216(SP) + MOVQ DX,224(SP) + MOVQ CX,232(SP) + MOVQ R8,240(SP) + MOVQ R9,248(SP) + MOVQ 120(DI),SI + MOVQ 128(DI),DX + MOVQ 136(DI),CX + MOVQ 144(DI),R8 + MOVQ 152(DI),R9 + MOVQ SI,AX + MOVQ DX,R10 + MOVQ CX,R11 + MOVQ R8,R12 + MOVQ R9,R13 + ADDQ ·_2P0(SB),AX + ADDQ ·_2P1234(SB),R10 + ADDQ ·_2P1234(SB),R11 + ADDQ ·_2P1234(SB),R12 + ADDQ ·_2P1234(SB),R13 + ADDQ 160(DI),SI + ADDQ 168(DI),DX + ADDQ 176(DI),CX + ADDQ 184(DI),R8 + ADDQ 192(DI),R9 + SUBQ 160(DI),AX + SUBQ 168(DI),R10 + SUBQ 176(DI),R11 + SUBQ 184(DI),R12 + SUBQ 192(DI),R13 + MOVQ SI,256(SP) + MOVQ DX,264(SP) + MOVQ CX,272(SP) + MOVQ R8,280(SP) + MOVQ R9,288(SP) + MOVQ AX,296(SP) + MOVQ R10,304(SP) + MOVQ R11,312(SP) + MOVQ R12,320(SP) + MOVQ R13,328(SP) + MOVQ 280(SP),SI + IMUL3Q $19,SI,AX + MOVQ AX,336(SP) + MULQ 112(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 288(SP),DX + IMUL3Q $19,DX,AX + MOVQ AX,344(SP) + MULQ 104(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 256(SP),AX + MULQ 96(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 256(SP),AX + MULQ 104(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 256(SP),AX + MULQ 112(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 256(SP),AX + MULQ 120(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 256(SP),AX + MULQ 128(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 264(SP),AX + MULQ 96(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 264(SP),AX + MULQ 104(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 264(SP),AX + MULQ 112(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 264(SP),AX + MULQ 120(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 264(SP),DX + IMUL3Q $19,DX,AX + MULQ 128(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 272(SP),AX + MULQ 96(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 272(SP),AX + MULQ 104(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 272(SP),AX + MULQ 112(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 272(SP),DX + IMUL3Q $19,DX,AX + MULQ 120(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 272(SP),DX + IMUL3Q $19,DX,AX + MULQ 128(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 280(SP),AX + MULQ 96(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 280(SP),AX + MULQ 104(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 336(SP),AX + MULQ 120(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 336(SP),AX + MULQ 128(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 288(SP),AX + MULQ 96(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 344(SP),AX + MULQ 112(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 344(SP),AX + MULQ 120(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 344(SP),AX + MULQ 128(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ ·REDMASK51(SB),DX + SHLQ $13,CX:SI + ANDQ DX,SI + SHLQ $13,R9:R8 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R11:R10 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,96(SP) + MOVQ R8,104(SP) + MOVQ R9,112(SP) + MOVQ AX,120(SP) + MOVQ R10,128(SP) + MOVQ 320(SP),SI + IMUL3Q $19,SI,AX + MOVQ AX,256(SP) + MULQ 72(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 328(SP),DX + IMUL3Q $19,DX,AX + MOVQ AX,264(SP) + MULQ 64(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 296(SP),AX + MULQ 56(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 296(SP),AX + MULQ 64(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 296(SP),AX + MULQ 72(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 296(SP),AX + MULQ 80(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 296(SP),AX + MULQ 88(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 304(SP),AX + MULQ 56(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 304(SP),AX + MULQ 64(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 304(SP),AX + MULQ 72(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 304(SP),AX + MULQ 80(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 304(SP),DX + IMUL3Q $19,DX,AX + MULQ 88(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 312(SP),AX + MULQ 56(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 312(SP),AX + MULQ 64(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 312(SP),AX + MULQ 72(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 312(SP),DX + IMUL3Q $19,DX,AX + MULQ 80(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 312(SP),DX + IMUL3Q $19,DX,AX + MULQ 88(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 320(SP),AX + MULQ 56(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 320(SP),AX + MULQ 64(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 256(SP),AX + MULQ 80(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 256(SP),AX + MULQ 88(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 328(SP),AX + MULQ 56(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 264(SP),AX + MULQ 72(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 264(SP),AX + MULQ 80(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 264(SP),AX + MULQ 88(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ ·REDMASK51(SB),DX + SHLQ $13,CX:SI + ANDQ DX,SI + SHLQ $13,R9:R8 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R11:R10 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,DX + MOVQ R8,CX + MOVQ R9,R11 + MOVQ AX,R12 + MOVQ R10,R13 + ADDQ ·_2P0(SB),DX + ADDQ ·_2P1234(SB),CX + ADDQ ·_2P1234(SB),R11 + ADDQ ·_2P1234(SB),R12 + ADDQ ·_2P1234(SB),R13 + ADDQ 96(SP),SI + ADDQ 104(SP),R8 + ADDQ 112(SP),R9 + ADDQ 120(SP),AX + ADDQ 128(SP),R10 + SUBQ 96(SP),DX + SUBQ 104(SP),CX + SUBQ 112(SP),R11 + SUBQ 120(SP),R12 + SUBQ 128(SP),R13 + MOVQ SI,120(DI) + MOVQ R8,128(DI) + MOVQ R9,136(DI) + MOVQ AX,144(DI) + MOVQ R10,152(DI) + MOVQ DX,160(DI) + MOVQ CX,168(DI) + MOVQ R11,176(DI) + MOVQ R12,184(DI) + MOVQ R13,192(DI) + MOVQ 120(DI),AX + MULQ 120(DI) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 120(DI),AX + SHLQ $1,AX + MULQ 128(DI) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 120(DI),AX + SHLQ $1,AX + MULQ 136(DI) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 120(DI),AX + SHLQ $1,AX + MULQ 144(DI) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 120(DI),AX + SHLQ $1,AX + MULQ 152(DI) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 128(DI),AX + MULQ 128(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 128(DI),AX + SHLQ $1,AX + MULQ 136(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 128(DI),AX + SHLQ $1,AX + MULQ 144(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 128(DI),DX + IMUL3Q $38,DX,AX + MULQ 152(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 136(DI),AX + MULQ 136(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 136(DI),DX + IMUL3Q $38,DX,AX + MULQ 144(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 136(DI),DX + IMUL3Q $38,DX,AX + MULQ 152(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 144(DI),DX + IMUL3Q $19,DX,AX + MULQ 144(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 144(DI),DX + IMUL3Q $38,DX,AX + MULQ 152(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 152(DI),DX + IMUL3Q $19,DX,AX + MULQ 152(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ ·REDMASK51(SB),DX + SHLQ $13,CX:SI + ANDQ DX,SI + SHLQ $13,R9:R8 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R11:R10 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + ANDQ DX,SI + MOVQ CX,R8 + SHRQ $51,CX + ADDQ R10,CX + ANDQ DX,R8 + MOVQ CX,R9 + SHRQ $51,CX + ADDQ R12,CX + ANDQ DX,R9 + MOVQ CX,AX + SHRQ $51,CX + ADDQ R14,CX + ANDQ DX,AX + MOVQ CX,R10 + SHRQ $51,CX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,120(DI) + MOVQ R8,128(DI) + MOVQ R9,136(DI) + MOVQ AX,144(DI) + MOVQ R10,152(DI) + MOVQ 160(DI),AX + MULQ 160(DI) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 160(DI),AX + SHLQ $1,AX + MULQ 168(DI) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 160(DI),AX + SHLQ $1,AX + MULQ 176(DI) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 160(DI),AX + SHLQ $1,AX + MULQ 184(DI) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 160(DI),AX + SHLQ $1,AX + MULQ 192(DI) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 168(DI),AX + MULQ 168(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 168(DI),AX + SHLQ $1,AX + MULQ 176(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 168(DI),AX + SHLQ $1,AX + MULQ 184(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 168(DI),DX + IMUL3Q $38,DX,AX + MULQ 192(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(DI),AX + MULQ 176(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 176(DI),DX + IMUL3Q $38,DX,AX + MULQ 184(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(DI),DX + IMUL3Q $38,DX,AX + MULQ 192(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 184(DI),DX + IMUL3Q $19,DX,AX + MULQ 184(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 184(DI),DX + IMUL3Q $38,DX,AX + MULQ 192(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 192(DI),DX + IMUL3Q $19,DX,AX + MULQ 192(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ ·REDMASK51(SB),DX + SHLQ $13,CX:SI + ANDQ DX,SI + SHLQ $13,R9:R8 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R11:R10 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + ANDQ DX,SI + MOVQ CX,R8 + SHRQ $51,CX + ADDQ R10,CX + ANDQ DX,R8 + MOVQ CX,R9 + SHRQ $51,CX + ADDQ R12,CX + ANDQ DX,R9 + MOVQ CX,AX + SHRQ $51,CX + ADDQ R14,CX + ANDQ DX,AX + MOVQ CX,R10 + SHRQ $51,CX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,160(DI) + MOVQ R8,168(DI) + MOVQ R9,176(DI) + MOVQ AX,184(DI) + MOVQ R10,192(DI) + MOVQ 184(DI),SI + IMUL3Q $19,SI,AX + MOVQ AX,56(SP) + MULQ 16(DI) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 192(DI),DX + IMUL3Q $19,DX,AX + MOVQ AX,64(SP) + MULQ 8(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 160(DI),AX + MULQ 0(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 160(DI),AX + MULQ 8(DI) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 160(DI),AX + MULQ 16(DI) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 160(DI),AX + MULQ 24(DI) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 160(DI),AX + MULQ 32(DI) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 168(DI),AX + MULQ 0(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 168(DI),AX + MULQ 8(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 168(DI),AX + MULQ 16(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 168(DI),AX + MULQ 24(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 168(DI),DX + IMUL3Q $19,DX,AX + MULQ 32(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(DI),AX + MULQ 0(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 176(DI),AX + MULQ 8(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 176(DI),AX + MULQ 16(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 176(DI),DX + IMUL3Q $19,DX,AX + MULQ 24(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(DI),DX + IMUL3Q $19,DX,AX + MULQ 32(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 184(DI),AX + MULQ 0(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 184(DI),AX + MULQ 8(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 56(SP),AX + MULQ 24(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 56(SP),AX + MULQ 32(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 192(DI),AX + MULQ 0(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 64(SP),AX + MULQ 16(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 64(SP),AX + MULQ 24(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 64(SP),AX + MULQ 32(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ ·REDMASK51(SB),DX + SHLQ $13,CX:SI + ANDQ DX,SI + SHLQ $13,R9:R8 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R11:R10 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,160(DI) + MOVQ R8,168(DI) + MOVQ R9,176(DI) + MOVQ AX,184(DI) + MOVQ R10,192(DI) + MOVQ 200(SP),SI + IMUL3Q $19,SI,AX + MOVQ AX,56(SP) + MULQ 152(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 208(SP),DX + IMUL3Q $19,DX,AX + MOVQ AX,64(SP) + MULQ 144(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(SP),AX + MULQ 136(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(SP),AX + MULQ 144(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 176(SP),AX + MULQ 152(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 176(SP),AX + MULQ 160(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 176(SP),AX + MULQ 168(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 184(SP),AX + MULQ 136(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 184(SP),AX + MULQ 144(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 184(SP),AX + MULQ 152(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 184(SP),AX + MULQ 160(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 184(SP),DX + IMUL3Q $19,DX,AX + MULQ 168(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 192(SP),AX + MULQ 136(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 192(SP),AX + MULQ 144(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 192(SP),AX + MULQ 152(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 192(SP),DX + IMUL3Q $19,DX,AX + MULQ 160(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 192(SP),DX + IMUL3Q $19,DX,AX + MULQ 168(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 200(SP),AX + MULQ 136(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 200(SP),AX + MULQ 144(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 56(SP),AX + MULQ 160(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 56(SP),AX + MULQ 168(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 208(SP),AX + MULQ 136(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 64(SP),AX + MULQ 152(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 64(SP),AX + MULQ 160(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 64(SP),AX + MULQ 168(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ ·REDMASK51(SB),DX + SHLQ $13,CX:SI + ANDQ DX,SI + SHLQ $13,R9:R8 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R11:R10 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,40(DI) + MOVQ R8,48(DI) + MOVQ R9,56(DI) + MOVQ AX,64(DI) + MOVQ R10,72(DI) + MOVQ 216(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + MOVQ AX,SI + MOVQ DX,CX + MOVQ 224(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + ADDQ AX,CX + MOVQ DX,R8 + MOVQ 232(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + ADDQ AX,R8 + MOVQ DX,R9 + MOVQ 240(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + ADDQ AX,R9 + MOVQ DX,R10 + MOVQ 248(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + ADDQ AX,R10 + IMUL3Q $19,DX,DX + ADDQ DX,SI + ADDQ 136(SP),SI + ADDQ 144(SP),CX + ADDQ 152(SP),R8 + ADDQ 160(SP),R9 + ADDQ 168(SP),R10 + MOVQ SI,80(DI) + MOVQ CX,88(DI) + MOVQ R8,96(DI) + MOVQ R9,104(DI) + MOVQ R10,112(DI) + MOVQ 104(DI),SI + IMUL3Q $19,SI,AX + MOVQ AX,56(SP) + MULQ 232(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 112(DI),DX + IMUL3Q $19,DX,AX + MOVQ AX,64(SP) + MULQ 224(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 80(DI),AX + MULQ 216(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 80(DI),AX + MULQ 224(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 80(DI),AX + MULQ 232(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 80(DI),AX + MULQ 240(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 80(DI),AX + MULQ 248(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 88(DI),AX + MULQ 216(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 88(DI),AX + MULQ 224(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 88(DI),AX + MULQ 232(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 88(DI),AX + MULQ 240(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 88(DI),DX + IMUL3Q $19,DX,AX + MULQ 248(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 96(DI),AX + MULQ 216(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 96(DI),AX + MULQ 224(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 96(DI),AX + MULQ 232(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 96(DI),DX + IMUL3Q $19,DX,AX + MULQ 240(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 96(DI),DX + IMUL3Q $19,DX,AX + MULQ 248(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 104(DI),AX + MULQ 216(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 104(DI),AX + MULQ 224(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 56(SP),AX + MULQ 240(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 56(SP),AX + MULQ 248(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 112(DI),AX + MULQ 216(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 64(SP),AX + MULQ 232(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 64(SP),AX + MULQ 240(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 64(SP),AX + MULQ 248(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ ·REDMASK51(SB),DX + SHLQ $13,CX:SI + ANDQ DX,SI + SHLQ $13,R9:R8 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R11:R10 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,80(DI) + MOVQ R8,88(DI) + MOVQ R9,96(DI) + MOVQ AX,104(DI) + MOVQ R10,112(DI) + MOVQ 0(SP),R11 + MOVQ 8(SP),R12 + MOVQ 16(SP),R13 + MOVQ 24(SP),R14 + MOVQ 32(SP),R15 + MOVQ 40(SP),BX + MOVQ 48(SP),BP + MOVQ R11,SP + MOVQ DI,AX + MOVQ SI,DX + RET diff --git a/src/ssl/test/runner/curve25519/mont25519_amd64.go b/src/ssl/test/runner/curve25519/mont25519_amd64.go new file mode 100644 index 0000000..5822bd5 --- /dev/null +++ b/src/ssl/test/runner/curve25519/mont25519_amd64.go @@ -0,0 +1,240 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64,!gccgo,!appengine + +package curve25519 + +// These functions are implemented in the .s files. The names of the functions +// in the rest of the file are also taken from the SUPERCOP sources to help +// people following along. + +//go:noescape + +func cswap(inout *[5]uint64, v uint64) + +//go:noescape + +func ladderstep(inout *[5][5]uint64) + +//go:noescape + +func freeze(inout *[5]uint64) + +//go:noescape + +func mul(dest, a, b *[5]uint64) + +//go:noescape + +func square(out, in *[5]uint64) + +// mladder uses a Montgomery ladder to calculate (xr/zr) *= s. +func mladder(xr, zr *[5]uint64, s *[32]byte) { + var work [5][5]uint64 + + work[0] = *xr + setint(&work[1], 1) + setint(&work[2], 0) + work[3] = *xr + setint(&work[4], 1) + + j := uint(6) + var prevbit byte + + for i := 31; i >= 0; i-- { + for j < 8 { + bit := ((*s)[i] >> j) & 1 + swap := bit ^ prevbit + prevbit = bit + cswap(&work[1], uint64(swap)) + ladderstep(&work) + j-- + } + j = 7 + } + + *xr = work[1] + *zr = work[2] +} + +func scalarMult(out, in, base *[32]byte) { + var e [32]byte + copy(e[:], (*in)[:]) + e[0] &= 248 + e[31] &= 127 + e[31] |= 64 + + var t, z [5]uint64 + unpack(&t, base) + mladder(&t, &z, &e) + invert(&z, &z) + mul(&t, &t, &z) + pack(out, &t) +} + +func setint(r *[5]uint64, v uint64) { + r[0] = v + r[1] = 0 + r[2] = 0 + r[3] = 0 + r[4] = 0 +} + +// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian +// order. +func unpack(r *[5]uint64, x *[32]byte) { + r[0] = uint64(x[0]) | + uint64(x[1])<<8 | + uint64(x[2])<<16 | + uint64(x[3])<<24 | + uint64(x[4])<<32 | + uint64(x[5])<<40 | + uint64(x[6]&7)<<48 + + r[1] = uint64(x[6])>>3 | + uint64(x[7])<<5 | + uint64(x[8])<<13 | + uint64(x[9])<<21 | + uint64(x[10])<<29 | + uint64(x[11])<<37 | + uint64(x[12]&63)<<45 + + r[2] = uint64(x[12])>>6 | + uint64(x[13])<<2 | + uint64(x[14])<<10 | + uint64(x[15])<<18 | + uint64(x[16])<<26 | + uint64(x[17])<<34 | + uint64(x[18])<<42 | + uint64(x[19]&1)<<50 + + r[3] = uint64(x[19])>>1 | + uint64(x[20])<<7 | + uint64(x[21])<<15 | + uint64(x[22])<<23 | + uint64(x[23])<<31 | + uint64(x[24])<<39 | + uint64(x[25]&15)<<47 + + r[4] = uint64(x[25])>>4 | + uint64(x[26])<<4 | + uint64(x[27])<<12 | + uint64(x[28])<<20 | + uint64(x[29])<<28 | + uint64(x[30])<<36 | + uint64(x[31]&127)<<44 +} + +// pack sets out = x where out is the usual, little-endian form of the 5, +// 51-bit limbs in x. +func pack(out *[32]byte, x *[5]uint64) { + t := *x + freeze(&t) + + out[0] = byte(t[0]) + out[1] = byte(t[0] >> 8) + out[2] = byte(t[0] >> 16) + out[3] = byte(t[0] >> 24) + out[4] = byte(t[0] >> 32) + out[5] = byte(t[0] >> 40) + out[6] = byte(t[0] >> 48) + + out[6] ^= byte(t[1]<<3) & 0xf8 + out[7] = byte(t[1] >> 5) + out[8] = byte(t[1] >> 13) + out[9] = byte(t[1] >> 21) + out[10] = byte(t[1] >> 29) + out[11] = byte(t[1] >> 37) + out[12] = byte(t[1] >> 45) + + out[12] ^= byte(t[2]<<6) & 0xc0 + out[13] = byte(t[2] >> 2) + out[14] = byte(t[2] >> 10) + out[15] = byte(t[2] >> 18) + out[16] = byte(t[2] >> 26) + out[17] = byte(t[2] >> 34) + out[18] = byte(t[2] >> 42) + out[19] = byte(t[2] >> 50) + + out[19] ^= byte(t[3]<<1) & 0xfe + out[20] = byte(t[3] >> 7) + out[21] = byte(t[3] >> 15) + out[22] = byte(t[3] >> 23) + out[23] = byte(t[3] >> 31) + out[24] = byte(t[3] >> 39) + out[25] = byte(t[3] >> 47) + + out[25] ^= byte(t[4]<<4) & 0xf0 + out[26] = byte(t[4] >> 4) + out[27] = byte(t[4] >> 12) + out[28] = byte(t[4] >> 20) + out[29] = byte(t[4] >> 28) + out[30] = byte(t[4] >> 36) + out[31] = byte(t[4] >> 44) +} + +// invert calculates r = x^-1 mod p using Fermat's little theorem. +func invert(r *[5]uint64, x *[5]uint64) { + var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64 + + square(&z2, x) /* 2 */ + square(&t, &z2) /* 4 */ + square(&t, &t) /* 8 */ + mul(&z9, &t, x) /* 9 */ + mul(&z11, &z9, &z2) /* 11 */ + square(&t, &z11) /* 22 */ + mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */ + + square(&t, &z2_5_0) /* 2^6 - 2^1 */ + for i := 1; i < 5; i++ { /* 2^20 - 2^10 */ + square(&t, &t) + } + mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */ + + square(&t, &z2_10_0) /* 2^11 - 2^1 */ + for i := 1; i < 10; i++ { /* 2^20 - 2^10 */ + square(&t, &t) + } + mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */ + + square(&t, &z2_20_0) /* 2^21 - 2^1 */ + for i := 1; i < 20; i++ { /* 2^40 - 2^20 */ + square(&t, &t) + } + mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */ + + square(&t, &t) /* 2^41 - 2^1 */ + for i := 1; i < 10; i++ { /* 2^50 - 2^10 */ + square(&t, &t) + } + mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */ + + square(&t, &z2_50_0) /* 2^51 - 2^1 */ + for i := 1; i < 50; i++ { /* 2^100 - 2^50 */ + square(&t, &t) + } + mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */ + + square(&t, &z2_100_0) /* 2^101 - 2^1 */ + for i := 1; i < 100; i++ { /* 2^200 - 2^100 */ + square(&t, &t) + } + mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */ + + square(&t, &t) /* 2^201 - 2^1 */ + for i := 1; i < 50; i++ { /* 2^250 - 2^50 */ + square(&t, &t) + } + mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */ + + square(&t, &t) /* 2^251 - 2^1 */ + square(&t, &t) /* 2^252 - 2^2 */ + square(&t, &t) /* 2^253 - 2^3 */ + + square(&t, &t) /* 2^254 - 2^4 */ + + square(&t, &t) /* 2^255 - 2^5 */ + mul(r, &t, &z11) /* 2^255 - 21 */ +} diff --git a/src/ssl/test/runner/curve25519/mul_amd64.s b/src/ssl/test/runner/curve25519/mul_amd64.s new file mode 100644 index 0000000..e48d183 --- /dev/null +++ b/src/ssl/test/runner/curve25519/mul_amd64.s @@ -0,0 +1,191 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +// func mul(dest, a, b *[5]uint64) +TEXT ·mul(SB),0,$128-24 + MOVQ dest+0(FP), DI + MOVQ a+8(FP), SI + MOVQ b+16(FP), DX + + MOVQ SP,R11 + MOVQ $31,CX + NOTQ CX + ANDQ CX,SP + ADDQ $32,SP + + MOVQ R11,0(SP) + MOVQ R12,8(SP) + MOVQ R13,16(SP) + MOVQ R14,24(SP) + MOVQ R15,32(SP) + MOVQ BX,40(SP) + MOVQ BP,48(SP) + MOVQ DI,56(SP) + MOVQ DX,CX + MOVQ 24(SI),DX + IMUL3Q $19,DX,AX + MOVQ AX,64(SP) + MULQ 16(CX) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 32(SI),DX + IMUL3Q $19,DX,AX + MOVQ AX,72(SP) + MULQ 8(CX) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 0(SI),AX + MULQ 0(CX) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 0(SI),AX + MULQ 8(CX) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 0(SI),AX + MULQ 16(CX) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 0(SI),AX + MULQ 24(CX) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 0(SI),AX + MULQ 32(CX) + MOVQ AX,BX + MOVQ DX,BP + MOVQ 8(SI),AX + MULQ 0(CX) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 8(SI),AX + MULQ 8(CX) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 8(SI),AX + MULQ 16(CX) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 8(SI),AX + MULQ 24(CX) + ADDQ AX,BX + ADCQ DX,BP + MOVQ 8(SI),DX + IMUL3Q $19,DX,AX + MULQ 32(CX) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 16(SI),AX + MULQ 0(CX) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 16(SI),AX + MULQ 8(CX) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 16(SI),AX + MULQ 16(CX) + ADDQ AX,BX + ADCQ DX,BP + MOVQ 16(SI),DX + IMUL3Q $19,DX,AX + MULQ 24(CX) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 16(SI),DX + IMUL3Q $19,DX,AX + MULQ 32(CX) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 24(SI),AX + MULQ 0(CX) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 24(SI),AX + MULQ 8(CX) + ADDQ AX,BX + ADCQ DX,BP + MOVQ 64(SP),AX + MULQ 24(CX) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 64(SP),AX + MULQ 32(CX) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 32(SI),AX + MULQ 0(CX) + ADDQ AX,BX + ADCQ DX,BP + MOVQ 72(SP),AX + MULQ 16(CX) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 72(SP),AX + MULQ 24(CX) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 72(SP),AX + MULQ 32(CX) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ ·REDMASK51(SB),SI + SHLQ $13,R9:R8 + ANDQ SI,R8 + SHLQ $13,R11:R10 + ANDQ SI,R10 + ADDQ R9,R10 + SHLQ $13,R13:R12 + ANDQ SI,R12 + ADDQ R11,R12 + SHLQ $13,R15:R14 + ANDQ SI,R14 + ADDQ R13,R14 + SHLQ $13,BP:BX + ANDQ SI,BX + ADDQ R15,BX + IMUL3Q $19,BP,DX + ADDQ DX,R8 + MOVQ R8,DX + SHRQ $51,DX + ADDQ R10,DX + MOVQ DX,CX + SHRQ $51,DX + ANDQ SI,R8 + ADDQ R12,DX + MOVQ DX,R9 + SHRQ $51,DX + ANDQ SI,CX + ADDQ R14,DX + MOVQ DX,AX + SHRQ $51,DX + ANDQ SI,R9 + ADDQ BX,DX + MOVQ DX,R10 + SHRQ $51,DX + ANDQ SI,AX + IMUL3Q $19,DX,DX + ADDQ DX,R8 + ANDQ SI,R10 + MOVQ R8,0(DI) + MOVQ CX,8(DI) + MOVQ R9,16(DI) + MOVQ AX,24(DI) + MOVQ R10,32(DI) + MOVQ 0(SP),R11 + MOVQ 8(SP),R12 + MOVQ 16(SP),R13 + MOVQ 24(SP),R14 + MOVQ 32(SP),R15 + MOVQ 40(SP),BX + MOVQ 48(SP),BP + MOVQ R11,SP + MOVQ DI,AX + MOVQ SI,DX + RET diff --git a/src/ssl/test/runner/curve25519/square_amd64.s b/src/ssl/test/runner/curve25519/square_amd64.s new file mode 100644 index 0000000..78d1a50 --- /dev/null +++ b/src/ssl/test/runner/curve25519/square_amd64.s @@ -0,0 +1,153 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +// func square(out, in *[5]uint64) +TEXT ·square(SB),7,$96-16 + MOVQ out+0(FP), DI + MOVQ in+8(FP), SI + + MOVQ SP,R11 + MOVQ $31,CX + NOTQ CX + ANDQ CX,SP + ADDQ $32, SP + + MOVQ R11,0(SP) + MOVQ R12,8(SP) + MOVQ R13,16(SP) + MOVQ R14,24(SP) + MOVQ R15,32(SP) + MOVQ BX,40(SP) + MOVQ BP,48(SP) + MOVQ 0(SI),AX + MULQ 0(SI) + MOVQ AX,CX + MOVQ DX,R8 + MOVQ 0(SI),AX + SHLQ $1,AX + MULQ 8(SI) + MOVQ AX,R9 + MOVQ DX,R10 + MOVQ 0(SI),AX + SHLQ $1,AX + MULQ 16(SI) + MOVQ AX,R11 + MOVQ DX,R12 + MOVQ 0(SI),AX + SHLQ $1,AX + MULQ 24(SI) + MOVQ AX,R13 + MOVQ DX,R14 + MOVQ 0(SI),AX + SHLQ $1,AX + MULQ 32(SI) + MOVQ AX,R15 + MOVQ DX,BX + MOVQ 8(SI),AX + MULQ 8(SI) + ADDQ AX,R11 + ADCQ DX,R12 + MOVQ 8(SI),AX + SHLQ $1,AX + MULQ 16(SI) + ADDQ AX,R13 + ADCQ DX,R14 + MOVQ 8(SI),AX + SHLQ $1,AX + MULQ 24(SI) + ADDQ AX,R15 + ADCQ DX,BX + MOVQ 8(SI),DX + IMUL3Q $38,DX,AX + MULQ 32(SI) + ADDQ AX,CX + ADCQ DX,R8 + MOVQ 16(SI),AX + MULQ 16(SI) + ADDQ AX,R15 + ADCQ DX,BX + MOVQ 16(SI),DX + IMUL3Q $38,DX,AX + MULQ 24(SI) + ADDQ AX,CX + ADCQ DX,R8 + MOVQ 16(SI),DX + IMUL3Q $38,DX,AX + MULQ 32(SI) + ADDQ AX,R9 + ADCQ DX,R10 + MOVQ 24(SI),DX + IMUL3Q $19,DX,AX + MULQ 24(SI) + ADDQ AX,R9 + ADCQ DX,R10 + MOVQ 24(SI),DX + IMUL3Q $38,DX,AX + MULQ 32(SI) + ADDQ AX,R11 + ADCQ DX,R12 + MOVQ 32(SI),DX + IMUL3Q $19,DX,AX + MULQ 32(SI) + ADDQ AX,R13 + ADCQ DX,R14 + MOVQ ·REDMASK51(SB),SI + SHLQ $13,R8:CX + ANDQ SI,CX + SHLQ $13,R10:R9 + ANDQ SI,R9 + ADDQ R8,R9 + SHLQ $13,R12:R11 + ANDQ SI,R11 + ADDQ R10,R11 + SHLQ $13,R14:R13 + ANDQ SI,R13 + ADDQ R12,R13 + SHLQ $13,BX:R15 + ANDQ SI,R15 + ADDQ R14,R15 + IMUL3Q $19,BX,DX + ADDQ DX,CX + MOVQ CX,DX + SHRQ $51,DX + ADDQ R9,DX + ANDQ SI,CX + MOVQ DX,R8 + SHRQ $51,DX + ADDQ R11,DX + ANDQ SI,R8 + MOVQ DX,R9 + SHRQ $51,DX + ADDQ R13,DX + ANDQ SI,R9 + MOVQ DX,AX + SHRQ $51,DX + ADDQ R15,DX + ANDQ SI,AX + MOVQ DX,R10 + SHRQ $51,DX + IMUL3Q $19,DX,DX + ADDQ DX,CX + ANDQ SI,R10 + MOVQ CX,0(DI) + MOVQ R8,8(DI) + MOVQ R9,16(DI) + MOVQ AX,24(DI) + MOVQ R10,32(DI) + MOVQ 0(SP),R11 + MOVQ 8(SP),R12 + MOVQ 16(SP),R13 + MOVQ 24(SP),R14 + MOVQ 32(SP),R15 + MOVQ 40(SP),BX + MOVQ 48(SP),BP + MOVQ R11,SP + MOVQ DI,AX + MOVQ SI,DX + RET diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go index 9d8ffee..64630ba 100644 --- a/src/ssl/test/runner/handshake_client.go +++ b/src/ssl/test/runner/handshake_client.go @@ -98,7 +98,7 @@ func (c *Conn) clientHandshake() error { } } - if c.config.Bugs.NoRenegotiationInfo { + if c.noRenegotiationInfo() { hello.secureRenegotiation = nil } @@ -282,7 +282,7 @@ NextCipherSuite: return errors.New("tls: renegotiation extension missing") } - if len(c.clientVerify) > 0 && !c.config.Bugs.NoRenegotiationInfo { + if len(c.clientVerify) > 0 && !c.noRenegotiationInfo() { var expectedRenegInfo []byte expectedRenegInfo = append(expectedRenegInfo, c.clientVerify...) expectedRenegInfo = append(expectedRenegInfo, c.serverVerify...) @@ -924,7 +924,11 @@ func (hs *clientHandshakeState) sendFinished(out []byte, isResume bool) error { if !c.config.Bugs.SkipChangeCipherSpec && c.config.Bugs.EarlyChangeCipherSpec == 0 { - c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) + ccs := []byte{1} + if c.config.Bugs.BadChangeCipherSpec != nil { + ccs = c.config.Bugs.BadChangeCipherSpec + } + c.writeRecord(recordTypeChangeCipherSpec, ccs) } if c.config.Bugs.AppDataAfterChangeCipherSpec != nil { diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go index 568f836..0232772 100644 --- a/src/ssl/test/runner/handshake_server.go +++ b/src/ssl/test/runner/handshake_server.go @@ -286,7 +286,7 @@ Curves: hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation } - if c.config.Bugs.NoRenegotiationInfo { + if c.noRenegotiationInfo() { hs.hello.secureRenegotiation = nil } @@ -914,7 +914,11 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error { c.dtlsFlushHandshake() if !c.config.Bugs.SkipChangeCipherSpec { - c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) + ccs := []byte{1} + if c.config.Bugs.BadChangeCipherSpec != nil { + ccs = c.config.Bugs.BadChangeCipherSpec + } + c.writeRecord(recordTypeChangeCipherSpec, ccs) } if c.config.Bugs.AppDataAfterChangeCipherSpec != nil { diff --git a/src/ssl/test/runner/key_agreement.go b/src/ssl/test/runner/key_agreement.go index 3a9b899..4f399d9 100644 --- a/src/ssl/test/runner/key_agreement.go +++ b/src/ssl/test/runner/key_agreement.go @@ -12,11 +12,15 @@ import ( "crypto/rand" "crypto/rsa" "crypto/sha1" + "crypto/subtle" "crypto/x509" "encoding/asn1" "errors" + "fmt" "io" "math/big" + + "./curve25519" ) var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message") @@ -137,10 +141,11 @@ func (ka *rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello } func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { + bad := config.Bugs.BadRSAClientKeyExchange preMasterSecret := make([]byte, 48) vers := clientHello.vers - if config.Bugs.RsaClientKeyExchangeVersion != 0 { - vers = config.Bugs.RsaClientKeyExchangeVersion + if bad == RSABadValueWrongVersion { + vers ^= 1 } vers = versionToWire(vers, clientHello.isDTLS) preMasterSecret[0] = byte(vers >> 8) @@ -150,12 +155,25 @@ func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello return nil, nil, err } - encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret) + sentPreMasterSecret := preMasterSecret + if bad == RSABadValueTooLong { + sentPreMasterSecret = make([]byte, len(sentPreMasterSecret)+1) + copy(sentPreMasterSecret, preMasterSecret) + } else if bad == RSABadValueTooShort { + sentPreMasterSecret = sentPreMasterSecret[:len(sentPreMasterSecret)-1] + } + + encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), sentPreMasterSecret) if err != nil { return nil, nil, err } + if bad == RSABadValueCorrupt { + encrypted[len(encrypted)-1] ^= 1 + // Clear the high byte to ensure |encrypted| is still below the RSA modulus. + encrypted[0] = 0 + } ckx := new(clientKeyExchangeMsg) - if clientHello.vers != VersionSSL30 && !config.Bugs.SSL3RSAKeyExchange { + if clientHello.vers != VersionSSL30 { ckx.ciphertext = make([]byte, len(encrypted)+2) ckx.ciphertext[0] = byte(len(encrypted) >> 8) ckx.ciphertext[1] = byte(len(encrypted)) @@ -232,16 +250,90 @@ func pickTLS12HashForSignature(sigType uint8, clientList, serverList []signature return 0, errors.New("tls: client doesn't support any common hash functions") } -func curveForCurveID(id CurveID) (elliptic.Curve, bool) { +// A ecdhCurve is an instance of ECDH-style key agreement for TLS. +type ecdhCurve interface { + // generateKeypair generates a keypair using rand. It returns the + // encoded public key. + generateKeypair(rand io.Reader) (publicKey []byte, err error) + + // computeSecret performs a key exchange against peerKey and returns + // the resulting shared secret. + computeSecret(peerKey []byte) (preMasterSecret []byte, err error) +} + +// ellipticECDHCurve implements ecdhCurve with an elliptic.Curve. +type ellipticECDHCurve struct { + curve elliptic.Curve + privateKey []byte +} + +func (e *ellipticECDHCurve) generateKeypair(rand io.Reader) (publicKey []byte, err error) { + var x, y *big.Int + e.privateKey, x, y, err = elliptic.GenerateKey(e.curve, rand) + if err != nil { + return nil, err + } + return elliptic.Marshal(e.curve, x, y), nil +} + +func (e *ellipticECDHCurve) computeSecret(peerKey []byte) (preMasterSecret []byte, err error) { + x, y := elliptic.Unmarshal(e.curve, peerKey) + if x == nil { + return nil, errors.New("tls: invalid peer key") + } + x, _ = e.curve.ScalarMult(x, y, e.privateKey) + preMasterSecret = make([]byte, (e.curve.Params().BitSize+7)>>3) + xBytes := x.Bytes() + copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) + + return preMasterSecret, nil +} + +// x25519ECDHCurve implements ecdhCurve with X25519. +type x25519ECDHCurve struct { + privateKey [32]byte +} + +func (e *x25519ECDHCurve) generateKeypair(rand io.Reader) (publicKey []byte, err error) { + _, err = io.ReadFull(rand, e.privateKey[:]) + if err != nil { + return + } + var out [32]byte + curve25519.ScalarBaseMult(&out, &e.privateKey) + return out[:], nil +} + +func (e *x25519ECDHCurve) computeSecret(peerKey []byte) (preMasterSecret []byte, err error) { + if len(peerKey) != 32 { + return nil, errors.New("tls: invalid peer key") + } + var out, peerKeyCopy [32]byte + copy(peerKeyCopy[:], peerKey) + curve25519.ScalarMult(&out, &e.privateKey, &peerKeyCopy) + + // Per draft-irtf-cfrg-curves-11, reject the all-zero value in constant + // time. + var zeros [32]byte + if subtle.ConstantTimeCompare(zeros[:], out[:]) == 1 { + return nil, errors.New("tls: X25519 value with wrong order") + } + + return out[:], nil +} + +func curveForCurveID(id CurveID) (ecdhCurve, bool) { switch id { case CurveP224: - return elliptic.P224(), true + return &ellipticECDHCurve{curve: elliptic.P224()}, true case CurveP256: - return elliptic.P256(), true + return &ellipticECDHCurve{curve: elliptic.P256()}, true case CurveP384: - return elliptic.P384(), true + return &ellipticECDHCurve{curve: elliptic.P384()}, true case CurveP521: - return elliptic.P521(), true + return &ellipticECDHCurve{curve: elliptic.P521()}, true + case CurveX25519: + return &x25519ECDHCurve{}, true default: return nil, false } @@ -269,6 +361,24 @@ func (ka *nilKeyAgreementAuthentication) verifyParameters(config *Config, client return nil } +func maybeCorruptECDSAValue(n *big.Int, typeOfCorruption BadValue, limit *big.Int) *big.Int { + switch typeOfCorruption { + case BadValueNone: + return n + case BadValueNegative: + return new(big.Int).Neg(n) + case BadValueZero: + return big.NewInt(0) + case BadValueLimit: + return limit + case BadValueLarge: + bad := new(big.Int).Set(limit) + return bad.Lsh(bad, 20) + default: + panic("unknown BadValue type") + } +} + // signedKeyAgreement signs the ServerKeyExchange parameters with the // server's private key. type signedKeyAgreement struct { @@ -414,28 +524,9 @@ func (ka *signedKeyAgreement) verifyParameters(config *Config, clientHello *clie // pre-master secret is then calculated using ECDH. The signature may // either be ECDSA or RSA. type ecdheKeyAgreement struct { - auth keyAgreementAuthentication - privateKey []byte - curve elliptic.Curve - x, y *big.Int -} - -func maybeCorruptECDSAValue(n *big.Int, typeOfCorruption BadValue, limit *big.Int) *big.Int { - switch typeOfCorruption { - case BadValueNone: - return n - case BadValueNegative: - return new(big.Int).Neg(n) - case BadValueZero: - return big.NewInt(0) - case BadValueLimit: - return limit - case BadValueLarge: - bad := new(big.Int).Set(limit) - return bad.Lsh(bad, 20) - default: - panic("unknown BadValue type") - } + auth keyAgreementAuthentication + curve ecdhCurve + peerKey []byte } func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { @@ -461,24 +552,21 @@ NextCandidate: return nil, errors.New("tls: preferredCurves includes unsupported curve") } - var x, y *big.Int - var err error - ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand()) + publicKey, err := ka.curve.generateKeypair(config.rand()) if err != nil { return nil, err } - ecdhePublic := elliptic.Marshal(ka.curve, x, y) // http://tools.ietf.org/html/rfc4492#section-5.4 - serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic)) + serverECDHParams := make([]byte, 1+2+1+len(publicKey)) serverECDHParams[0] = 3 // named curve serverECDHParams[1] = byte(curveid >> 8) serverECDHParams[2] = byte(curveid) if config.Bugs.InvalidSKXCurve { serverECDHParams[2] ^= 0xff } - serverECDHParams[3] = byte(len(ecdhePublic)) - copy(serverECDHParams[4:], ecdhePublic) + serverECDHParams[3] = byte(len(publicKey)) + copy(serverECDHParams[4:], publicKey) return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams) } @@ -487,16 +575,7 @@ func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Cert if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { return nil, errClientKeyExchange } - x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:]) - if x == nil { - return nil, errClientKeyExchange - } - x, _ = ka.curve.ScalarMult(x, y, ka.privateKey) - preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3) - xBytes := x.Bytes() - copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) - - return preMasterSecret, nil + return ka.curve.computeSecret(ckx.ciphertext[1:]) } func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { @@ -517,13 +596,12 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell if publicLen+4 > len(skx.key) { return errServerKeyExchange } - ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen]) - if ka.x == nil { - return errServerKeyExchange - } + // Save the peer key for later. + ka.peerKey = skx.key[4 : 4+publicLen] + + // Check the signature. serverECDHParams := skx.key[:4+publicLen] sig := skx.key[4+publicLen:] - return ka.auth.verifyParameters(config, clientHello, serverHello, cert, serverECDHParams, sig) } @@ -531,21 +609,20 @@ func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHel if ka.curve == nil { return nil, nil, errors.New("missing ServerKeyExchange message") } - priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand()) + + publicKey, err := ka.curve.generateKeypair(config.rand()) + if err != nil { + return nil, nil, err + } + preMasterSecret, err := ka.curve.computeSecret(ka.peerKey) if err != nil { return nil, nil, err } - x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv) - preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3) - xBytes := x.Bytes() - copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) - - serialized := elliptic.Marshal(ka.curve, mx, my) ckx := new(clientKeyExchangeMsg) - ckx.ciphertext = make([]byte, 1+len(serialized)) - ckx.ciphertext[0] = byte(len(serialized)) - copy(ckx.ciphertext[1:], serialized) + ckx.ciphertext = make([]byte, 1+len(publicKey)) + ckx.ciphertext[0] = byte(len(publicKey)) + copy(ckx.ciphertext[1:], publicKey) return preMasterSecret, ckx, nil } @@ -652,6 +729,10 @@ func (ka *dheKeyAgreement) processServerKeyExchange(config *Config, clientHello return errServerKeyExchange } + if l := config.Bugs.RequireDHPublicValueLen; l != 0 && l != yLen { + return fmt.Errorf("RequireDHPublicValueLen set to %d, but server's public value was %d bytes on the wire and %d bytes if minimal", l, yLen, (ka.yTheirs.BitLen()+7)/8) + } + sig := k serverDHParams := skx.key[:len(skx.key)-len(sig)] diff --git a/src/ssl/test/runner/packet_adapter.go b/src/ssl/test/runner/packet_adapter.go index 2351eb0..a8da311 100644 --- a/src/ssl/test/runner/packet_adapter.go +++ b/src/ssl/test/runner/packet_adapter.go @@ -96,7 +96,7 @@ func (p *packetAdaptor) Write(b []byte) (int, error) { // for acknowledgement of the timeout, buffering any packets received since // then. The packets are then returned. func (p *packetAdaptor) SendReadTimeout(d time.Duration) ([][]byte, error) { - p.log("Simulating read timeout: " + d.String(), nil) + p.log("Simulating read timeout: "+d.String(), nil) payload := make([]byte, 1+8) payload[0] = opcodeTimeout diff --git a/src/ssl/test/runner/poly1305/const_amd64.s b/src/ssl/test/runner/poly1305/const_amd64.s new file mode 100644 index 0000000..8e861f3 --- /dev/null +++ b/src/ssl/test/runner/poly1305/const_amd64.s @@ -0,0 +1,45 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +DATA ·SCALE(SB)/8, $0x37F4000000000000 +GLOBL ·SCALE(SB), 8, $8 +DATA ·TWO32(SB)/8, $0x41F0000000000000 +GLOBL ·TWO32(SB), 8, $8 +DATA ·TWO64(SB)/8, $0x43F0000000000000 +GLOBL ·TWO64(SB), 8, $8 +DATA ·TWO96(SB)/8, $0x45F0000000000000 +GLOBL ·TWO96(SB), 8, $8 +DATA ·ALPHA32(SB)/8, $0x45E8000000000000 +GLOBL ·ALPHA32(SB), 8, $8 +DATA ·ALPHA64(SB)/8, $0x47E8000000000000 +GLOBL ·ALPHA64(SB), 8, $8 +DATA ·ALPHA96(SB)/8, $0x49E8000000000000 +GLOBL ·ALPHA96(SB), 8, $8 +DATA ·ALPHA130(SB)/8, $0x4C08000000000000 +GLOBL ·ALPHA130(SB), 8, $8 +DATA ·DOFFSET0(SB)/8, $0x4330000000000000 +GLOBL ·DOFFSET0(SB), 8, $8 +DATA ·DOFFSET1(SB)/8, $0x4530000000000000 +GLOBL ·DOFFSET1(SB), 8, $8 +DATA ·DOFFSET2(SB)/8, $0x4730000000000000 +GLOBL ·DOFFSET2(SB), 8, $8 +DATA ·DOFFSET3(SB)/8, $0x4930000000000000 +GLOBL ·DOFFSET3(SB), 8, $8 +DATA ·DOFFSET3MINUSTWO128(SB)/8, $0x492FFFFE00000000 +GLOBL ·DOFFSET3MINUSTWO128(SB), 8, $8 +DATA ·HOFFSET0(SB)/8, $0x43300001FFFFFFFB +GLOBL ·HOFFSET0(SB), 8, $8 +DATA ·HOFFSET1(SB)/8, $0x45300001FFFFFFFE +GLOBL ·HOFFSET1(SB), 8, $8 +DATA ·HOFFSET2(SB)/8, $0x47300001FFFFFFFE +GLOBL ·HOFFSET2(SB), 8, $8 +DATA ·HOFFSET3(SB)/8, $0x49300003FFFFFFFE +GLOBL ·HOFFSET3(SB), 8, $8 +DATA ·ROUNDING(SB)/2, $0x137f +GLOBL ·ROUNDING(SB), 8, $2 diff --git a/src/ssl/test/runner/poly1305/poly1305.go b/src/ssl/test/runner/poly1305/poly1305.go new file mode 100644 index 0000000..4a5f826 --- /dev/null +++ b/src/ssl/test/runner/poly1305/poly1305.go @@ -0,0 +1,32 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package poly1305 implements Poly1305 one-time message authentication code as specified in http://cr.yp.to/mac/poly1305-20050329.pdf. + +Poly1305 is a fast, one-time authentication function. It is infeasible for an +attacker to generate an authenticator for a message without the key. However, a +key must only be used for a single message. Authenticating two different +messages with the same key allows an attacker to forge authenticators for other +messages with the same key. + +Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was +used with a fixed key in order to generate one-time keys from an nonce. +However, in this package AES isn't used and the one-time key is specified +directly. +*/ +package poly1305 // import "golang.org/x/crypto/poly1305" + +import "crypto/subtle" + +// TagSize is the size, in bytes, of a poly1305 authenticator. +const TagSize = 16 + +// Verify returns true if mac is a valid authenticator for m with the given +// key. +func Verify(mac *[16]byte, m []byte, key *[32]byte) bool { + var tmp [16]byte + Sum(&tmp, m, key) + return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 +} diff --git a/src/ssl/test/runner/poly1305/poly1305_amd64.s b/src/ssl/test/runner/poly1305/poly1305_amd64.s new file mode 100644 index 0000000..f8d4ee9 --- /dev/null +++ b/src/ssl/test/runner/poly1305/poly1305_amd64.s @@ -0,0 +1,497 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key) +TEXT ·poly1305(SB),0,$224-32 + MOVQ out+0(FP),DI + MOVQ m+8(FP),SI + MOVQ mlen+16(FP),DX + MOVQ key+24(FP),CX + + MOVQ SP,R11 + MOVQ $31,R9 + NOTQ R9 + ANDQ R9,SP + ADDQ $32,SP + + MOVQ R11,32(SP) + MOVQ R12,40(SP) + MOVQ R13,48(SP) + MOVQ R14,56(SP) + MOVQ R15,64(SP) + MOVQ BX,72(SP) + MOVQ BP,80(SP) + FLDCW ·ROUNDING(SB) + MOVL 0(CX),R8 + MOVL 4(CX),R9 + MOVL 8(CX),AX + MOVL 12(CX),R10 + MOVQ DI,88(SP) + MOVQ CX,96(SP) + MOVL $0X43300000,108(SP) + MOVL $0X45300000,116(SP) + MOVL $0X47300000,124(SP) + MOVL $0X49300000,132(SP) + ANDL $0X0FFFFFFF,R8 + ANDL $0X0FFFFFFC,R9 + ANDL $0X0FFFFFFC,AX + ANDL $0X0FFFFFFC,R10 + MOVL R8,104(SP) + MOVL R9,112(SP) + MOVL AX,120(SP) + MOVL R10,128(SP) + FMOVD 104(SP), F0 + FSUBD ·DOFFSET0(SB), F0 + FMOVD 112(SP), F0 + FSUBD ·DOFFSET1(SB), F0 + FMOVD 120(SP), F0 + FSUBD ·DOFFSET2(SB), F0 + FMOVD 128(SP), F0 + FSUBD ·DOFFSET3(SB), F0 + FXCHD F0, F3 + FMOVDP F0, 136(SP) + FXCHD F0, F1 + FMOVD F0, 144(SP) + FMULD ·SCALE(SB), F0 + FMOVDP F0, 152(SP) + FMOVD F0, 160(SP) + FMULD ·SCALE(SB), F0 + FMOVDP F0, 168(SP) + FMOVD F0, 176(SP) + FMULD ·SCALE(SB), F0 + FMOVDP F0, 184(SP) + FLDZ + FLDZ + FLDZ + FLDZ + CMPQ DX,$16 + JB ADDATMOST15BYTES + INITIALATLEAST16BYTES: + MOVL 12(SI),DI + MOVL 8(SI),CX + MOVL 4(SI),R8 + MOVL 0(SI),R9 + MOVL DI,128(SP) + MOVL CX,120(SP) + MOVL R8,112(SP) + MOVL R9,104(SP) + ADDQ $16,SI + SUBQ $16,DX + FXCHD F0, F3 + FADDD 128(SP), F0 + FSUBD ·DOFFSET3MINUSTWO128(SB), F0 + FXCHD F0, F1 + FADDD 112(SP), F0 + FSUBD ·DOFFSET1(SB), F0 + FXCHD F0, F2 + FADDD 120(SP), F0 + FSUBD ·DOFFSET2(SB), F0 + FXCHD F0, F3 + FADDD 104(SP), F0 + FSUBD ·DOFFSET0(SB), F0 + CMPQ DX,$16 + JB MULTIPLYADDATMOST15BYTES + MULTIPLYADDATLEAST16BYTES: + MOVL 12(SI),DI + MOVL 8(SI),CX + MOVL 4(SI),R8 + MOVL 0(SI),R9 + MOVL DI,128(SP) + MOVL CX,120(SP) + MOVL R8,112(SP) + MOVL R9,104(SP) + ADDQ $16,SI + SUBQ $16,DX + FMOVD ·ALPHA130(SB), F0 + FADDD F2,F0 + FSUBD ·ALPHA130(SB), F0 + FSUBD F0,F2 + FMULD ·SCALE(SB), F0 + FMOVD ·ALPHA32(SB), F0 + FADDD F2,F0 + FSUBD ·ALPHA32(SB), F0 + FSUBD F0,F2 + FXCHD F0, F2 + FADDDP F0,F1 + FMOVD ·ALPHA64(SB), F0 + FADDD F4,F0 + FSUBD ·ALPHA64(SB), F0 + FSUBD F0,F4 + FMOVD ·ALPHA96(SB), F0 + FADDD F6,F0 + FSUBD ·ALPHA96(SB), F0 + FSUBD F0,F6 + FXCHD F0, F6 + FADDDP F0,F1 + FXCHD F0, F3 + FADDDP F0,F5 + FXCHD F0, F3 + FADDDP F0,F1 + FMOVD 176(SP), F0 + FMULD F3,F0 + FMOVD 160(SP), F0 + FMULD F4,F0 + FMOVD 144(SP), F0 + FMULD F5,F0 + FMOVD 136(SP), F0 + FMULDP F0,F6 + FMOVD 160(SP), F0 + FMULD F4,F0 + FADDDP F0,F3 + FMOVD 144(SP), F0 + FMULD F4,F0 + FADDDP F0,F2 + FMOVD 136(SP), F0 + FMULD F4,F0 + FADDDP F0,F1 + FMOVD 184(SP), F0 + FMULDP F0,F4 + FXCHD F0, F3 + FADDDP F0,F5 + FMOVD 144(SP), F0 + FMULD F4,F0 + FADDDP F0,F2 + FMOVD 136(SP), F0 + FMULD F4,F0 + FADDDP F0,F1 + FMOVD 184(SP), F0 + FMULD F4,F0 + FADDDP F0,F3 + FMOVD 168(SP), F0 + FMULDP F0,F4 + FXCHD F0, F3 + FADDDP F0,F4 + FMOVD 136(SP), F0 + FMULD F5,F0 + FADDDP F0,F1 + FXCHD F0, F3 + FMOVD 184(SP), F0 + FMULD F5,F0 + FADDDP F0,F3 + FXCHD F0, F1 + FMOVD 168(SP), F0 + FMULD F5,F0 + FADDDP F0,F1 + FMOVD 152(SP), F0 + FMULDP F0,F5 + FXCHD F0, F4 + FADDDP F0,F1 + CMPQ DX,$16 + FXCHD F0, F2 + FMOVD 128(SP), F0 + FSUBD ·DOFFSET3MINUSTWO128(SB), F0 + FADDDP F0,F1 + FXCHD F0, F1 + FMOVD 120(SP), F0 + FSUBD ·DOFFSET2(SB), F0 + FADDDP F0,F1 + FXCHD F0, F3 + FMOVD 112(SP), F0 + FSUBD ·DOFFSET1(SB), F0 + FADDDP F0,F1 + FXCHD F0, F2 + FMOVD 104(SP), F0 + FSUBD ·DOFFSET0(SB), F0 + FADDDP F0,F1 + JAE MULTIPLYADDATLEAST16BYTES + MULTIPLYADDATMOST15BYTES: + FMOVD ·ALPHA130(SB), F0 + FADDD F2,F0 + FSUBD ·ALPHA130(SB), F0 + FSUBD F0,F2 + FMULD ·SCALE(SB), F0 + FMOVD ·ALPHA32(SB), F0 + FADDD F2,F0 + FSUBD ·ALPHA32(SB), F0 + FSUBD F0,F2 + FMOVD ·ALPHA64(SB), F0 + FADDD F5,F0 + FSUBD ·ALPHA64(SB), F0 + FSUBD F0,F5 + FMOVD ·ALPHA96(SB), F0 + FADDD F7,F0 + FSUBD ·ALPHA96(SB), F0 + FSUBD F0,F7 + FXCHD F0, F7 + FADDDP F0,F1 + FXCHD F0, F5 + FADDDP F0,F1 + FXCHD F0, F3 + FADDDP F0,F5 + FADDDP F0,F1 + FMOVD 176(SP), F0 + FMULD F1,F0 + FMOVD 160(SP), F0 + FMULD F2,F0 + FMOVD 144(SP), F0 + FMULD F3,F0 + FMOVD 136(SP), F0 + FMULDP F0,F4 + FMOVD 160(SP), F0 + FMULD F5,F0 + FADDDP F0,F3 + FMOVD 144(SP), F0 + FMULD F5,F0 + FADDDP F0,F2 + FMOVD 136(SP), F0 + FMULD F5,F0 + FADDDP F0,F1 + FMOVD 184(SP), F0 + FMULDP F0,F5 + FXCHD F0, F4 + FADDDP F0,F3 + FMOVD 144(SP), F0 + FMULD F5,F0 + FADDDP F0,F2 + FMOVD 136(SP), F0 + FMULD F5,F0 + FADDDP F0,F1 + FMOVD 184(SP), F0 + FMULD F5,F0 + FADDDP F0,F4 + FMOVD 168(SP), F0 + FMULDP F0,F5 + FXCHD F0, F4 + FADDDP F0,F2 + FMOVD 136(SP), F0 + FMULD F5,F0 + FADDDP F0,F1 + FMOVD 184(SP), F0 + FMULD F5,F0 + FADDDP F0,F4 + FMOVD 168(SP), F0 + FMULD F5,F0 + FADDDP F0,F3 + FMOVD 152(SP), F0 + FMULDP F0,F5 + FXCHD F0, F4 + FADDDP F0,F1 + ADDATMOST15BYTES: + CMPQ DX,$0 + JE NOMOREBYTES + MOVL $0,0(SP) + MOVL $0, 4 (SP) + MOVL $0, 8 (SP) + MOVL $0, 12 (SP) + LEAQ 0(SP),DI + MOVQ DX,CX + REP; MOVSB + MOVB $1,0(DI) + MOVL 12 (SP),DI + MOVL 8 (SP),SI + MOVL 4 (SP),DX + MOVL 0(SP),CX + MOVL DI,128(SP) + MOVL SI,120(SP) + MOVL DX,112(SP) + MOVL CX,104(SP) + FXCHD F0, F3 + FADDD 128(SP), F0 + FSUBD ·DOFFSET3(SB), F0 + FXCHD F0, F2 + FADDD 120(SP), F0 + FSUBD ·DOFFSET2(SB), F0 + FXCHD F0, F1 + FADDD 112(SP), F0 + FSUBD ·DOFFSET1(SB), F0 + FXCHD F0, F3 + FADDD 104(SP), F0 + FSUBD ·DOFFSET0(SB), F0 + FMOVD ·ALPHA130(SB), F0 + FADDD F3,F0 + FSUBD ·ALPHA130(SB), F0 + FSUBD F0,F3 + FMULD ·SCALE(SB), F0 + FMOVD ·ALPHA32(SB), F0 + FADDD F2,F0 + FSUBD ·ALPHA32(SB), F0 + FSUBD F0,F2 + FMOVD ·ALPHA64(SB), F0 + FADDD F6,F0 + FSUBD ·ALPHA64(SB), F0 + FSUBD F0,F6 + FMOVD ·ALPHA96(SB), F0 + FADDD F5,F0 + FSUBD ·ALPHA96(SB), F0 + FSUBD F0,F5 + FXCHD F0, F4 + FADDDP F0,F3 + FXCHD F0, F6 + FADDDP F0,F1 + FXCHD F0, F3 + FADDDP F0,F5 + FXCHD F0, F3 + FADDDP F0,F1 + FMOVD 176(SP), F0 + FMULD F3,F0 + FMOVD 160(SP), F0 + FMULD F4,F0 + FMOVD 144(SP), F0 + FMULD F5,F0 + FMOVD 136(SP), F0 + FMULDP F0,F6 + FMOVD 160(SP), F0 + FMULD F5,F0 + FADDDP F0,F3 + FMOVD 144(SP), F0 + FMULD F5,F0 + FADDDP F0,F2 + FMOVD 136(SP), F0 + FMULD F5,F0 + FADDDP F0,F1 + FMOVD 184(SP), F0 + FMULDP F0,F5 + FXCHD F0, F4 + FADDDP F0,F5 + FMOVD 144(SP), F0 + FMULD F6,F0 + FADDDP F0,F2 + FMOVD 136(SP), F0 + FMULD F6,F0 + FADDDP F0,F1 + FMOVD 184(SP), F0 + FMULD F6,F0 + FADDDP F0,F4 + FMOVD 168(SP), F0 + FMULDP F0,F6 + FXCHD F0, F5 + FADDDP F0,F4 + FMOVD 136(SP), F0 + FMULD F2,F0 + FADDDP F0,F1 + FMOVD 184(SP), F0 + FMULD F2,F0 + FADDDP F0,F5 + FMOVD 168(SP), F0 + FMULD F2,F0 + FADDDP F0,F3 + FMOVD 152(SP), F0 + FMULDP F0,F2 + FXCHD F0, F1 + FADDDP F0,F3 + FXCHD F0, F3 + FXCHD F0, F2 + NOMOREBYTES: + MOVL $0,R10 + FMOVD ·ALPHA130(SB), F0 + FADDD F4,F0 + FSUBD ·ALPHA130(SB), F0 + FSUBD F0,F4 + FMULD ·SCALE(SB), F0 + FMOVD ·ALPHA32(SB), F0 + FADDD F2,F0 + FSUBD ·ALPHA32(SB), F0 + FSUBD F0,F2 + FMOVD ·ALPHA64(SB), F0 + FADDD F4,F0 + FSUBD ·ALPHA64(SB), F0 + FSUBD F0,F4 + FMOVD ·ALPHA96(SB), F0 + FADDD F6,F0 + FSUBD ·ALPHA96(SB), F0 + FXCHD F0, F6 + FSUBD F6,F0 + FXCHD F0, F4 + FADDDP F0,F3 + FXCHD F0, F4 + FADDDP F0,F1 + FXCHD F0, F2 + FADDDP F0,F3 + FXCHD F0, F4 + FADDDP F0,F3 + FXCHD F0, F3 + FADDD ·HOFFSET0(SB), F0 + FXCHD F0, F3 + FADDD ·HOFFSET1(SB), F0 + FXCHD F0, F1 + FADDD ·HOFFSET2(SB), F0 + FXCHD F0, F2 + FADDD ·HOFFSET3(SB), F0 + FXCHD F0, F3 + FMOVDP F0, 104(SP) + FMOVDP F0, 112(SP) + FMOVDP F0, 120(SP) + FMOVDP F0, 128(SP) + MOVL 108(SP),DI + ANDL $63,DI + MOVL 116(SP),SI + ANDL $63,SI + MOVL 124(SP),DX + ANDL $63,DX + MOVL 132(SP),CX + ANDL $63,CX + MOVL 112(SP),R8 + ADDL DI,R8 + MOVQ R8,112(SP) + MOVL 120(SP),DI + ADCL SI,DI + MOVQ DI,120(SP) + MOVL 128(SP),DI + ADCL DX,DI + MOVQ DI,128(SP) + MOVL R10,DI + ADCL CX,DI + MOVQ DI,136(SP) + MOVQ $5,DI + MOVL 104(SP),SI + ADDL SI,DI + MOVQ DI,104(SP) + MOVL R10,DI + MOVQ 112(SP),DX + ADCL DX,DI + MOVQ DI,112(SP) + MOVL R10,DI + MOVQ 120(SP),CX + ADCL CX,DI + MOVQ DI,120(SP) + MOVL R10,DI + MOVQ 128(SP),R8 + ADCL R8,DI + MOVQ DI,128(SP) + MOVQ $0XFFFFFFFC,DI + MOVQ 136(SP),R9 + ADCL R9,DI + SARL $16,DI + MOVQ DI,R9 + XORL $0XFFFFFFFF,R9 + ANDQ DI,SI + MOVQ 104(SP),AX + ANDQ R9,AX + ORQ AX,SI + ANDQ DI,DX + MOVQ 112(SP),AX + ANDQ R9,AX + ORQ AX,DX + ANDQ DI,CX + MOVQ 120(SP),AX + ANDQ R9,AX + ORQ AX,CX + ANDQ DI,R8 + MOVQ 128(SP),DI + ANDQ R9,DI + ORQ DI,R8 + MOVQ 88(SP),DI + MOVQ 96(SP),R9 + ADDL 16(R9),SI + ADCL 20(R9),DX + ADCL 24(R9),CX + ADCL 28(R9),R8 + MOVL SI,0(DI) + MOVL DX,4(DI) + MOVL CX,8(DI) + MOVL R8,12(DI) + MOVQ 32(SP),R11 + MOVQ 40(SP),R12 + MOVQ 48(SP),R13 + MOVQ 56(SP),R14 + MOVQ 64(SP),R15 + MOVQ 72(SP),BX + MOVQ 80(SP),BP + MOVQ R11,SP + RET diff --git a/src/ssl/test/runner/poly1305/poly1305_arm.s b/src/ssl/test/runner/poly1305/poly1305_arm.s new file mode 100644 index 0000000..c153867 --- /dev/null +++ b/src/ssl/test/runner/poly1305/poly1305_arm.s @@ -0,0 +1,379 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 5a from the public +// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305. + +// +build arm,!gccgo,!appengine + +DATA poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff +DATA poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03 +DATA poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff +DATA poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff +DATA poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff +GLOBL poly1305_init_constants_armv6<>(SB), 8, $20 + +// Warning: the linker may use R11 to synthesize certain instructions. Please +// take care and verify that no synthetic instructions use it. + +TEXT poly1305_init_ext_armv6<>(SB),4,$-4 + MOVM.DB.W [R4-R11], (R13) + MOVM.IA.W (R1), [R2-R5] + MOVW $poly1305_init_constants_armv6<>(SB), R7 + MOVW R2, R8 + MOVW R2>>26, R9 + MOVW R3>>20, g + MOVW R4>>14, R11 + MOVW R5>>8, R12 + ORR R3<<6, R9, R9 + ORR R4<<12, g, g + ORR R5<<18, R11, R11 + MOVM.IA (R7), [R2-R6] + AND R8, R2, R2 + AND R9, R3, R3 + AND g, R4, R4 + AND R11, R5, R5 + AND R12, R6, R6 + MOVM.IA.W [R2-R6], (R0) + EOR R2, R2, R2 + EOR R3, R3, R3 + EOR R4, R4, R4 + EOR R5, R5, R5 + EOR R6, R6, R6 + MOVM.IA.W [R2-R6], (R0) + MOVM.IA.W (R1), [R2-R5] + MOVM.IA [R2-R6], (R0) + MOVM.IA.W (R13), [R4-R11] + RET + +#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \ + MOVBU (offset+0)(Rsrc), Rtmp; \ + MOVBU Rtmp, (offset+0)(Rdst); \ + MOVBU (offset+1)(Rsrc), Rtmp; \ + MOVBU Rtmp, (offset+1)(Rdst); \ + MOVBU (offset+2)(Rsrc), Rtmp; \ + MOVBU Rtmp, (offset+2)(Rdst); \ + MOVBU (offset+3)(Rsrc), Rtmp; \ + MOVBU Rtmp, (offset+3)(Rdst) + +TEXT poly1305_blocks_armv6<>(SB),4,$-4 + MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13) + SUB $128, R13 + MOVW R0, 36(R13) + MOVW R1, 40(R13) + MOVW R2, 44(R13) + MOVW R1, R14 + MOVW R2, R12 + MOVW 56(R0), R8 + WORD $0xe1180008 // TST R8, R8 not working see issue 5921 + EOR R6, R6, R6 + MOVW.EQ $(1<<24), R6 + MOVW R6, 32(R13) + ADD $64, R13, g + MOVM.IA (R0), [R0-R9] + MOVM.IA [R0-R4], (g) + CMP $16, R12 + BLO poly1305_blocks_armv6_done +poly1305_blocks_armv6_mainloop: + WORD $0xe31e0003 // TST R14, #3 not working see issue 5921 + BEQ poly1305_blocks_armv6_mainloop_aligned + ADD $48, R13, g + MOVW_UNALIGNED(R14, g, R0, 0) + MOVW_UNALIGNED(R14, g, R0, 4) + MOVW_UNALIGNED(R14, g, R0, 8) + MOVW_UNALIGNED(R14, g, R0, 12) + MOVM.IA (g), [R0-R3] + ADD $16, R14 + B poly1305_blocks_armv6_mainloop_loaded +poly1305_blocks_armv6_mainloop_aligned: + MOVM.IA.W (R14), [R0-R3] +poly1305_blocks_armv6_mainloop_loaded: + MOVW R0>>26, g + MOVW R1>>20, R11 + MOVW R2>>14, R12 + MOVW R14, 40(R13) + MOVW R3>>8, R4 + ORR R1<<6, g, g + ORR R2<<12, R11, R11 + ORR R3<<18, R12, R12 + BIC $0xfc000000, R0, R0 + BIC $0xfc000000, g, g + MOVW 32(R13), R3 + BIC $0xfc000000, R11, R11 + BIC $0xfc000000, R12, R12 + ADD R0, R5, R5 + ADD g, R6, R6 + ORR R3, R4, R4 + ADD R11, R7, R7 + ADD $64, R13, R14 + ADD R12, R8, R8 + ADD R4, R9, R9 + MOVM.IA (R14), [R0-R4] + MULLU R4, R5, (R11, g) + MULLU R3, R5, (R14, R12) + MULALU R3, R6, (R11, g) + MULALU R2, R6, (R14, R12) + MULALU R2, R7, (R11, g) + MULALU R1, R7, (R14, R12) + ADD R4<<2, R4, R4 + ADD R3<<2, R3, R3 + MULALU R1, R8, (R11, g) + MULALU R0, R8, (R14, R12) + MULALU R0, R9, (R11, g) + MULALU R4, R9, (R14, R12) + MOVW g, 24(R13) + MOVW R11, 28(R13) + MOVW R12, 16(R13) + MOVW R14, 20(R13) + MULLU R2, R5, (R11, g) + MULLU R1, R5, (R14, R12) + MULALU R1, R6, (R11, g) + MULALU R0, R6, (R14, R12) + MULALU R0, R7, (R11, g) + MULALU R4, R7, (R14, R12) + ADD R2<<2, R2, R2 + ADD R1<<2, R1, R1 + MULALU R4, R8, (R11, g) + MULALU R3, R8, (R14, R12) + MULALU R3, R9, (R11, g) + MULALU R2, R9, (R14, R12) + MOVW g, 8(R13) + MOVW R11, 12(R13) + MOVW R12, 0(R13) + MOVW R14, w+4(SP) + MULLU R0, R5, (R11, g) + MULALU R4, R6, (R11, g) + MULALU R3, R7, (R11, g) + MULALU R2, R8, (R11, g) + MULALU R1, R9, (R11, g) + MOVM.IA (R13), [R0-R7] + MOVW g>>26, R12 + MOVW R4>>26, R14 + ORR R11<<6, R12, R12 + ORR R5<<6, R14, R14 + BIC $0xfc000000, g, g + BIC $0xfc000000, R4, R4 + ADD.S R12, R0, R0 + ADC $0, R1, R1 + ADD.S R14, R6, R6 + ADC $0, R7, R7 + MOVW R0>>26, R12 + MOVW R6>>26, R14 + ORR R1<<6, R12, R12 + ORR R7<<6, R14, R14 + BIC $0xfc000000, R0, R0 + BIC $0xfc000000, R6, R6 + ADD R14<<2, R14, R14 + ADD.S R12, R2, R2 + ADC $0, R3, R3 + ADD R14, g, g + MOVW R2>>26, R12 + MOVW g>>26, R14 + ORR R3<<6, R12, R12 + BIC $0xfc000000, g, R5 + BIC $0xfc000000, R2, R7 + ADD R12, R4, R4 + ADD R14, R0, R0 + MOVW R4>>26, R12 + BIC $0xfc000000, R4, R8 + ADD R12, R6, R9 + MOVW w+44(SP), R12 + MOVW w+40(SP), R14 + MOVW R0, R6 + CMP $32, R12 + SUB $16, R12, R12 + MOVW R12, 44(R13) + BHS poly1305_blocks_armv6_mainloop +poly1305_blocks_armv6_done: + MOVW 36(R13), R12 + MOVW R5, 20(R12) + MOVW R6, 24(R12) + MOVW R7, 28(R12) + MOVW R8, 32(R12) + MOVW R9, 36(R12) + ADD $128, R13, R13 + MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14] + RET + +#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \ + MOVBU.P 1(Rsrc), Rtmp; \ + MOVBU.P Rtmp, 1(Rdst); \ + MOVBU.P 1(Rsrc), Rtmp; \ + MOVBU.P Rtmp, 1(Rdst) + +#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \ + MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \ + MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) + +TEXT poly1305_finish_ext_armv6<>(SB),4,$-4 + MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13) + SUB $16, R13, R13 + MOVW R0, R5 + MOVW R1, R6 + MOVW R2, R7 + MOVW R3, R8 + AND.S R2, R2, R2 + BEQ poly1305_finish_ext_armv6_noremaining + EOR R0, R0 + MOVW R13, R9 + MOVW R0, 0(R13) + MOVW R0, 4(R13) + MOVW R0, 8(R13) + MOVW R0, 12(R13) + WORD $0xe3110003 // TST R1, #3 not working see issue 5921 + BEQ poly1305_finish_ext_armv6_aligned + WORD $0xe3120008 // TST R2, #8 not working see issue 5921 + BEQ poly1305_finish_ext_armv6_skip8 + MOVWP_UNALIGNED(R1, R9, g) + MOVWP_UNALIGNED(R1, R9, g) +poly1305_finish_ext_armv6_skip8: + WORD $0xe3120004 // TST $4, R2 not working see issue 5921 + BEQ poly1305_finish_ext_armv6_skip4 + MOVWP_UNALIGNED(R1, R9, g) +poly1305_finish_ext_armv6_skip4: + WORD $0xe3120002 // TST $2, R2 not working see issue 5921 + BEQ poly1305_finish_ext_armv6_skip2 + MOVHUP_UNALIGNED(R1, R9, g) + B poly1305_finish_ext_armv6_skip2 +poly1305_finish_ext_armv6_aligned: + WORD $0xe3120008 // TST R2, #8 not working see issue 5921 + BEQ poly1305_finish_ext_armv6_skip8_aligned + MOVM.IA.W (R1), [g-R11] + MOVM.IA.W [g-R11], (R9) +poly1305_finish_ext_armv6_skip8_aligned: + WORD $0xe3120004 // TST $4, R2 not working see issue 5921 + BEQ poly1305_finish_ext_armv6_skip4_aligned + MOVW.P 4(R1), g + MOVW.P g, 4(R9) +poly1305_finish_ext_armv6_skip4_aligned: + WORD $0xe3120002 // TST $2, R2 not working see issue 5921 + BEQ poly1305_finish_ext_armv6_skip2 + MOVHU.P 2(R1), g + MOVH.P g, 2(R9) +poly1305_finish_ext_armv6_skip2: + WORD $0xe3120001 // TST $1, R2 not working see issue 5921 + BEQ poly1305_finish_ext_armv6_skip1 + MOVBU.P 1(R1), g + MOVBU.P g, 1(R9) +poly1305_finish_ext_armv6_skip1: + MOVW $1, R11 + MOVBU R11, 0(R9) + MOVW R11, 56(R5) + MOVW R5, R0 + MOVW R13, R1 + MOVW $16, R2 + BL poly1305_blocks_armv6<>(SB) +poly1305_finish_ext_armv6_noremaining: + MOVW 20(R5), R0 + MOVW 24(R5), R1 + MOVW 28(R5), R2 + MOVW 32(R5), R3 + MOVW 36(R5), R4 + MOVW R4>>26, R12 + BIC $0xfc000000, R4, R4 + ADD R12<<2, R12, R12 + ADD R12, R0, R0 + MOVW R0>>26, R12 + BIC $0xfc000000, R0, R0 + ADD R12, R1, R1 + MOVW R1>>26, R12 + BIC $0xfc000000, R1, R1 + ADD R12, R2, R2 + MOVW R2>>26, R12 + BIC $0xfc000000, R2, R2 + ADD R12, R3, R3 + MOVW R3>>26, R12 + BIC $0xfc000000, R3, R3 + ADD R12, R4, R4 + ADD $5, R0, R6 + MOVW R6>>26, R12 + BIC $0xfc000000, R6, R6 + ADD R12, R1, R7 + MOVW R7>>26, R12 + BIC $0xfc000000, R7, R7 + ADD R12, R2, g + MOVW g>>26, R12 + BIC $0xfc000000, g, g + ADD R12, R3, R11 + MOVW $-(1<<26), R12 + ADD R11>>26, R12, R12 + BIC $0xfc000000, R11, R11 + ADD R12, R4, R14 + MOVW R14>>31, R12 + SUB $1, R12 + AND R12, R6, R6 + AND R12, R7, R7 + AND R12, g, g + AND R12, R11, R11 + AND R12, R14, R14 + MVN R12, R12 + AND R12, R0, R0 + AND R12, R1, R1 + AND R12, R2, R2 + AND R12, R3, R3 + AND R12, R4, R4 + ORR R6, R0, R0 + ORR R7, R1, R1 + ORR g, R2, R2 + ORR R11, R3, R3 + ORR R14, R4, R4 + ORR R1<<26, R0, R0 + MOVW R1>>6, R1 + ORR R2<<20, R1, R1 + MOVW R2>>12, R2 + ORR R3<<14, R2, R2 + MOVW R3>>18, R3 + ORR R4<<8, R3, R3 + MOVW 40(R5), R6 + MOVW 44(R5), R7 + MOVW 48(R5), g + MOVW 52(R5), R11 + ADD.S R6, R0, R0 + ADC.S R7, R1, R1 + ADC.S g, R2, R2 + ADC.S R11, R3, R3 + MOVM.IA [R0-R3], (R8) + MOVW R5, R12 + EOR R0, R0, R0 + EOR R1, R1, R1 + EOR R2, R2, R2 + EOR R3, R3, R3 + EOR R4, R4, R4 + EOR R5, R5, R5 + EOR R6, R6, R6 + EOR R7, R7, R7 + MOVM.IA.W [R0-R7], (R12) + MOVM.IA [R0-R7], (R12) + ADD $16, R13, R13 + MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14] + RET + +// func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]key) +TEXT ·poly1305_auth_armv6(SB),0,$280-16 + MOVW out+0(FP), R4 + MOVW m+4(FP), R5 + MOVW mlen+8(FP), R6 + MOVW key+12(FP), R7 + + MOVW R13, R8 + BIC $63, R13 + SUB $64, R13, R13 + MOVW R13, R0 + MOVW R7, R1 + BL poly1305_init_ext_armv6<>(SB) + BIC.S $15, R6, R2 + BEQ poly1305_auth_armv6_noblocks + MOVW R13, R0 + MOVW R5, R1 + ADD R2, R5, R5 + SUB R2, R6, R6 + BL poly1305_blocks_armv6<>(SB) +poly1305_auth_armv6_noblocks: + MOVW R13, R0 + MOVW R5, R1 + MOVW R6, R2 + MOVW R4, R3 + BL poly1305_finish_ext_armv6<>(SB) + MOVW R8, R13 + RET diff --git a/src/ssl/test/runner/poly1305/poly1305_test.go b/src/ssl/test/runner/poly1305/poly1305_test.go new file mode 100644 index 0000000..b3e9231 --- /dev/null +++ b/src/ssl/test/runner/poly1305/poly1305_test.go @@ -0,0 +1,86 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package poly1305 + +import ( + "bytes" + "testing" + "unsafe" +) + +var testData = []struct { + in, k, correct []byte +}{ + { + []byte("Hello world!"), + []byte("this is 32-byte key for Poly1305"), + []byte{0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2, 0xf0}, + }, + { + make([]byte, 32), + []byte("this is 32-byte key for Poly1305"), + []byte{0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03, 0x07}, + }, + { + make([]byte, 2007), + []byte("this is 32-byte key for Poly1305"), + []byte{0xda, 0x84, 0xbc, 0xab, 0x02, 0x67, 0x6c, 0x38, 0xcd, 0xb0, 0x15, 0x60, 0x42, 0x74, 0xc2, 0xaa}, + }, + { + make([]byte, 2007), + make([]byte, 32), + make([]byte, 16), + }, +} + +func testSum(t *testing.T, unaligned bool) { + var out [16]byte + var key [32]byte + + for i, v := range testData { + in := v.in + if unaligned { + in = unalignBytes(in) + } + copy(key[:], v.k) + Sum(&out, in, &key) + if !bytes.Equal(out[:], v.correct) { + t.Errorf("%d: expected %x, got %x", i, v.correct, out[:]) + } + } +} + +func TestSum(t *testing.T) { testSum(t, false) } +func TestSumUnaligned(t *testing.T) { testSum(t, true) } + +func benchmark(b *testing.B, size int, unaligned bool) { + var out [16]byte + var key [32]byte + in := make([]byte, size) + if unaligned { + in = unalignBytes(in) + } + b.SetBytes(int64(len(in))) + b.ResetTimer() + for i := 0; i < b.N; i++ { + Sum(&out, in, &key) + } +} + +func Benchmark64(b *testing.B) { benchmark(b, 64, false) } +func Benchmark1K(b *testing.B) { benchmark(b, 1024, false) } +func Benchmark64Unaligned(b *testing.B) { benchmark(b, 64, true) } +func Benchmark1KUnaligned(b *testing.B) { benchmark(b, 1024, true) } + +func unalignBytes(in []byte) []byte { + out := make([]byte, len(in)+1) + if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { + out = out[1:] + } else { + out = out[:len(in)] + } + copy(out, in) + return out +} diff --git a/src/ssl/test/runner/poly1305/sum_amd64.go b/src/ssl/test/runner/poly1305/sum_amd64.go new file mode 100644 index 0000000..6775c70 --- /dev/null +++ b/src/ssl/test/runner/poly1305/sum_amd64.go @@ -0,0 +1,24 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64,!gccgo,!appengine + +package poly1305 + +// This function is implemented in poly1305_amd64.s + +//go:noescape + +func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte) + +// Sum generates an authenticator for m using a one-time key and puts the +// 16-byte result into out. Authenticating two different messages with the same +// key allows an attacker to forge messages at will. +func Sum(out *[16]byte, m []byte, key *[32]byte) { + var mPtr *byte + if len(m) > 0 { + mPtr = &m[0] + } + poly1305(out, mPtr, uint64(len(m)), key) +} diff --git a/src/ssl/test/runner/poly1305/sum_arm.go b/src/ssl/test/runner/poly1305/sum_arm.go new file mode 100644 index 0000000..50b979c --- /dev/null +++ b/src/ssl/test/runner/poly1305/sum_arm.go @@ -0,0 +1,24 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build arm,!gccgo,!appengine + +package poly1305 + +// This function is implemented in poly1305_arm.s + +//go:noescape + +func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte) + +// Sum generates an authenticator for m using a one-time key and puts the +// 16-byte result into out. Authenticating two different messages with the same +// key allows an attacker to forge messages at will. +func Sum(out *[16]byte, m []byte, key *[32]byte) { + var mPtr *byte + if len(m) > 0 { + mPtr = &m[0] + } + poly1305_auth_armv6(out, mPtr, uint32(len(m)), key) +} diff --git a/src/ssl/test/runner/poly1305.go b/src/ssl/test/runner/poly1305/sum_ref.go index edef338..0b24fc7 100644 --- a/src/ssl/test/runner/poly1305.go +++ b/src/ssl/test/runner/poly1305/sum_ref.go @@ -2,15 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package runner +// +build !amd64,!arm gccgo appengine + +package poly1305 // Based on original, public domain implementation from NaCl by D. J. // Bernstein. -import ( - "crypto/subtle" - "math" -) +import "math" const ( alpham80 = 0.00000000558793544769287109375 @@ -32,18 +31,10 @@ const ( offset3 = 535219245894202480694386063513315216128475136.0 ) -// poly1305Verify returns true if mac is a valid authenticator for m with the -// given key. -func poly1305Verify(mac *[16]byte, m []byte, key *[32]byte) bool { - var tmp [16]byte - poly1305Sum(&tmp, m, key) - return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 -} - -// poly1305Sum generates an authenticator for m using a one-time key and puts -// the 16-byte result into out. Authenticating two different messages with the -// same key allows an attacker to forge messages at will. -func poly1305Sum(out *[16]byte, m []byte, key *[32]byte) { +// Sum generates an authenticator for m using a one-time key and puts the +// 16-byte result into out. Authenticating two different messages with the same +// key allows an attacker to forge messages at will. +func Sum(out *[16]byte, m []byte, key *[32]byte) { r := key s := key[16:] var ( diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go index 6ab71cf..45bb0b7 100644 --- a/src/ssl/test/runner/runner.go +++ b/src/ssl/test/runner/runner.go @@ -27,6 +27,7 @@ import ( var ( useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind") useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb") + useLLDB = flag.Bool("lldb", false, "If true, run BoringSSL code under lldb") flagDebug = flag.Bool("debug", false, "Hexdump the contents of the connection") mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.") mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask bssl_shim to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.") @@ -521,6 +522,14 @@ func gdbOf(path string, args ...string) *exec.Cmd { return exec.Command("xterm", xtermArgs...) } +func lldbOf(path string, args ...string) *exec.Cmd { + xtermArgs := []string{"-e", "lldb", "--"} + xtermArgs = append(xtermArgs, path) + xtermArgs = append(xtermArgs, args...) + + return exec.Command("xterm", xtermArgs...) +} + type moreMallocsError struct{} func (moreMallocsError) Error() string { @@ -637,6 +646,8 @@ func runTest(test *testCase, shimPath string, mallocNumToFail int64) error { shim = valgrindOf(false, shimPath, flags...) } else if *useGDB { shim = gdbOf(shimPath, flags...) + } else if *useLLDB { + shim = lldbOf(shimPath, flags...) } else { shim = exec.Command(shimPath, flags...) } @@ -801,6 +812,7 @@ var testCipherSuites = []struct { {"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, {"ECDHE-ECDSA-AES256-SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384}, {"ECDHE-ECDSA-CHACHA20-POLY1305", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, + {"ECDHE-ECDSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD}, {"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA}, {"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, {"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, @@ -809,11 +821,13 @@ var testCipherSuites = []struct { {"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, {"ECDHE-RSA-AES256-SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384}, {"ECDHE-RSA-CHACHA20-POLY1305", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, + {"ECDHE-RSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD}, {"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA}, {"PSK-AES128-CBC-SHA", TLS_PSK_WITH_AES_128_CBC_SHA}, {"PSK-AES256-CBC-SHA", TLS_PSK_WITH_AES_256_CBC_SHA}, {"ECDHE-PSK-AES128-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, {"ECDHE-PSK-AES256-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA}, + {"ECDHE-PSK-CHACHA20-POLY1305", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256}, {"PSK-RC4-SHA", TLS_PSK_WITH_RC4_128_SHA}, {"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5}, {"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA}, @@ -824,6 +838,12 @@ func hasComponent(suiteName, component string) bool { return strings.Contains("-"+suiteName+"-", "-"+component+"-") } +func isTLSOnly(suiteName string) bool { + // BoringSSL doesn't support ECDHE without a curves extension, and + // SSLv3 doesn't contain extensions. + return hasComponent(suiteName, "ECDHE") || isTLS12Only(suiteName) +} + func isTLS12Only(suiteName string) bool { return hasComponent(suiteName, "GCM") || hasComponent(suiteName, "SHA256") || @@ -907,18 +927,6 @@ func addBasicTests() { expectedError: ":WRONG_CURVE:", }, { - testType: serverTest, - name: "BadRSAVersion", - config: Config{ - CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, - Bugs: ProtocolBugs{ - RsaClientKeyExchangeVersion: VersionTLS11, - }, - }, - shouldFail: true, - expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", - }, - { name: "NoFallbackSCSV", config: Config{ Bugs: ProtocolBugs{ @@ -1006,7 +1014,7 @@ func addBasicTests() { }, }, shouldFail: true, - expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:", + expectedError: ":UNEXPECTED_RECORD:", }, { testType: serverTest, @@ -1017,7 +1025,7 @@ func addBasicTests() { }, }, shouldFail: true, - expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:", + expectedError: ":UNEXPECTED_RECORD:", }, { testType: serverTest, @@ -1032,7 +1040,7 @@ func addBasicTests() { "-advertise-npn", "\x03foo\x03bar\x03baz", }, shouldFail: true, - expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:", + expectedError: ":UNEXPECTED_RECORD:", }, { name: "FragmentAcrossChangeCipherSpec-Client", @@ -1042,7 +1050,7 @@ func addBasicTests() { }, }, shouldFail: true, - expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:", + expectedError: ":UNEXPECTED_RECORD:", }, { testType: serverTest, @@ -1053,7 +1061,7 @@ func addBasicTests() { }, }, shouldFail: true, - expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:", + expectedError: ":UNEXPECTED_RECORD:", }, { testType: serverTest, @@ -1068,7 +1076,7 @@ func addBasicTests() { "-advertise-npn", "\x03foo\x03bar\x03baz", }, shouldFail: true, - expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:", + expectedError: ":UNEXPECTED_RECORD:", }, { testType: serverTest, @@ -1127,7 +1135,7 @@ func addBasicTests() { }, }, shouldFail: true, - expectedError: ":CCS_RECEIVED_EARLY:", + expectedError: ":UNEXPECTED_RECORD:", }, { testType: serverTest, @@ -1138,7 +1146,7 @@ func addBasicTests() { }, }, shouldFail: true, - expectedError: ":CCS_RECEIVED_EARLY:", + expectedError: ":UNEXPECTED_RECORD:", }, { name: "SkipNewSessionTicket", @@ -1148,7 +1156,7 @@ func addBasicTests() { }, }, shouldFail: true, - expectedError: ":CCS_RECEIVED_EARLY:", + expectedError: ":UNEXPECTED_RECORD:", }, { testType: serverTest, @@ -1425,7 +1433,7 @@ func addBasicTests() { }, }, shouldFail: true, - expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:", + expectedError: ":UNEXPECTED_RECORD:", }, { name: "AppDataAfterChangeCipherSpec-Empty", @@ -1435,7 +1443,7 @@ func addBasicTests() { }, }, shouldFail: true, - expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:", + expectedError: ":UNEXPECTED_RECORD:", }, { protocol: dtls, @@ -1689,14 +1697,13 @@ func addBasicTests() { { name: "UnsupportedCurve", config: Config{ - CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, - // BoringSSL implements P-224 but doesn't enable it by - // default. - CurvePreferences: []CurveID{CurveP224}, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{CurveP256}, Bugs: ProtocolBugs{ IgnorePeerCurvePreferences: true, }, }, + flags: []string{"-p384-only"}, shouldFail: true, expectedError: ":WRONG_CURVE:", }, @@ -1812,6 +1819,8 @@ func addBasicTests() { NoSupportedCurves: true, }, }, + shouldFail: true, + expectedError: ":NO_SHARED_CIPHER:", }, { testType: serverTest, @@ -1997,6 +2006,88 @@ func addBasicTests() { resumeSession: true, expectResumeRejected: true, }, + { + name: "CheckLeafCurve", + config: Config{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + Certificates: []Certificate{getECDSACertificate()}, + }, + flags: []string{"-p384-only"}, + shouldFail: true, + expectedError: ":BAD_ECC_CERT:", + }, + { + name: "BadChangeCipherSpec-1", + config: Config{ + Bugs: ProtocolBugs{ + BadChangeCipherSpec: []byte{2}, + }, + }, + shouldFail: true, + expectedError: ":BAD_CHANGE_CIPHER_SPEC:", + }, + { + name: "BadChangeCipherSpec-2", + config: Config{ + Bugs: ProtocolBugs{ + BadChangeCipherSpec: []byte{1, 1}, + }, + }, + shouldFail: true, + expectedError: ":BAD_CHANGE_CIPHER_SPEC:", + }, + { + protocol: dtls, + name: "BadChangeCipherSpec-DTLS-1", + config: Config{ + Bugs: ProtocolBugs{ + BadChangeCipherSpec: []byte{2}, + }, + }, + shouldFail: true, + expectedError: ":BAD_CHANGE_CIPHER_SPEC:", + }, + { + protocol: dtls, + name: "BadChangeCipherSpec-DTLS-2", + config: Config{ + Bugs: ProtocolBugs{ + BadChangeCipherSpec: []byte{1, 1}, + }, + }, + shouldFail: true, + expectedError: ":BAD_CHANGE_CIPHER_SPEC:", + }, + { + name: "BadHelloRequest-1", + renegotiate: 1, + config: Config{ + Bugs: ProtocolBugs{ + BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1}, + }, + }, + flags: []string{ + "-renegotiate-freely", + "-expect-total-renegotiations", "1", + }, + shouldFail: true, + expectedError: ":BAD_HELLO_REQUEST:", + }, + { + name: "BadHelloRequest-2", + renegotiate: 1, + config: Config{ + Bugs: ProtocolBugs{ + BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0}, + }, + }, + flags: []string{ + "-renegotiate-freely", + "-expect-total-renegotiations", "1", + }, + shouldFail: true, + expectedError: ":BAD_HELLO_REQUEST:", + }, } testCases = append(testCases, basicTests...) } @@ -2035,9 +2126,16 @@ func addCipherSuiteTests() { continue } + shouldFail := isTLSOnly(suite.name) && ver.version == VersionSSL30 + + expectedError := "" + if shouldFail { + expectedError = ":NO_SHARED_CIPHER:" + } + testCases = append(testCases, testCase{ - testType: clientTest, - name: ver.name + "-" + suite.name + "-client", + testType: serverTest, + name: ver.name + "-" + suite.name + "-server", config: Config{ MinVersion: ver.version, MaxVersion: ver.version, @@ -2046,13 +2144,21 @@ func addCipherSuiteTests() { PreSharedKey: []byte(psk), PreSharedKeyIdentity: pskIdentity, }, + certFile: certFile, + keyFile: keyFile, flags: flags, resumeSession: true, + shouldFail: shouldFail, + expectedError: expectedError, }) + if shouldFail { + continue + } + testCases = append(testCases, testCase{ - testType: serverTest, - name: ver.name + "-" + suite.name + "-server", + testType: clientTest, + name: ver.name + "-" + suite.name + "-client", config: Config{ MinVersion: ver.version, MaxVersion: ver.version, @@ -2061,8 +2167,6 @@ func addCipherSuiteTests() { PreSharedKey: []byte(psk), PreSharedKeyIdentity: pskIdentity, }, - certFile: certFile, - keyFile: keyFile, flags: flags, resumeSession: true, }) @@ -2115,20 +2219,6 @@ func addCipherSuiteTests() { flags: flags, messageLen: maxPlaintext, }) - testCases = append(testCases, testCase{ - name: suite.name + "-LargeRecord-Extra", - config: Config{ - CipherSuites: []uint16{suite.id}, - Certificates: []Certificate{cert}, - PreSharedKey: []byte(psk), - PreSharedKeyIdentity: pskIdentity, - Bugs: ProtocolBugs{ - SendLargeRecords: true, - }, - }, - flags: append(flags, "-microsoft-big-sslv3-buffer"), - messageLen: maxPlaintext + 16384, - }) if isDTLSCipher(suite.name) { testCases = append(testCases, testCase{ protocol: dtls, @@ -2157,7 +2247,37 @@ func addCipherSuiteTests() { }, }, shouldFail: true, - expectedError: "BAD_DH_P_LENGTH", + expectedError: ":BAD_DH_P_LENGTH:", + }) + + testCases = append(testCases, testCase{ + name: "SillyDH", + config: Config{ + CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, + Bugs: ProtocolBugs{ + // This is a 4097-bit prime number, generated + // with: + // openssl gendh 4097 | openssl asn1parse -i + DHGroupPrime: bigFromHex("01D366FA64A47419B0CD4A45918E8D8C8430F674621956A9F52B0CA592BC104C6E38D60C58F2CA66792A2B7EBDC6F8FFE75AB7D6862C261F34E96A2AEEF53AB7C21365C2E8FB0582F71EB57B1C227C0E55AE859E9904A25EFECD7B435C4D4357BD840B03649D4A1F8037D89EA4E1967DBEEF1CC17A6111C48F12E9615FFF336D3F07064CB17C0B765A012C850B9E3AA7A6984B96D8C867DDC6D0F4AB52042572244796B7ECFF681CD3B3E2E29AAECA391A775BEE94E502FB15881B0F4AC60314EA947C0C82541C3D16FD8C0E09BB7F8F786582032859D9C13187CE6C0CB6F2D3EE6C3C9727C15F14B21D3CD2E02BDB9D119959B0E03DC9E5A91E2578762300B1517D2352FC1D0BB934A4C3E1B20CE9327DB102E89A6C64A8C3148EDFC5A94913933853442FA84451B31FD21E492F92DD5488E0D871AEBFE335A4B92431DEC69591548010E76A5B365D346786E9A2D3E589867D796AA5E25211201D757560D318A87DFB27F3E625BC373DB48BF94A63161C674C3D4265CB737418441B7650EABC209CF675A439BEB3E9D1AA1B79F67198A40CEFD1C89144F7D8BAF61D6AD36F466DA546B4174A0E0CAF5BD788C8243C7C2DDDCC3DB6FC89F12F17D19FBD9B0BC76FE92891CD6BA07BEA3B66EF12D0D85E788FD58675C1B0FBD16029DCC4D34E7A1A41471BDEDF78BF591A8B4E96D88BEC8EDC093E616292BFC096E69A916E8D624B"), + }, + }, + shouldFail: true, + expectedError: ":DH_P_TOO_LONG:", + }) + + // This test ensures that Diffie-Hellman public values are padded with + // zeros so that they're the same length as the prime. This is to avoid + // hitting a bug in yaSSL. + testCases = append(testCases, testCase{ + testType: serverTest, + name: "DHPublicValuePadded", + config: Config{ + CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, + Bugs: ProtocolBugs{ + RequireDHPublicValueLen: (1025 + 7) / 8, + }, + }, + flags: []string{"-use-sparse-dh-prime"}, }) // versionSpecificCiphersTest specifies a test for the TLS 1.0 and TLS @@ -3168,40 +3288,6 @@ func addMinimumVersionTests() { } } -func addD5BugTests() { - testCases = append(testCases, testCase{ - testType: serverTest, - name: "D5Bug-NoQuirk-Reject", - config: Config{ - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, - Bugs: ProtocolBugs{ - SSL3RSAKeyExchange: true, - }, - }, - shouldFail: true, - expectedError: ":TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG:", - }) - testCases = append(testCases, testCase{ - testType: serverTest, - name: "D5Bug-Quirk-Normal", - config: Config{ - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, - }, - flags: []string{"-tls-d5-bug"}, - }) - testCases = append(testCases, testCase{ - testType: serverTest, - name: "D5Bug-Quirk-Bug", - config: Config{ - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, - Bugs: ProtocolBugs{ - SSL3RSAKeyExchange: true, - }, - }, - flags: []string{"-tls-d5-bug"}, - }) -} - func addExtensionTests() { testCases = append(testCases, testCase{ testType: clientTest, @@ -3801,15 +3887,28 @@ func addRenegotiationTests() { expectedError: ":RENEGOTIATION_MISMATCH:", }) testCases = append(testCases, testCase{ - name: "Renegotiate-Client-NoExt", + name: "Renegotiate-Client-Downgrade", + renegotiate: 1, + config: Config{ + Bugs: ProtocolBugs{ + NoRenegotiationInfoAfterInitial: true, + }, + }, + flags: []string{"-renegotiate-freely"}, + shouldFail: true, + expectedError: ":RENEGOTIATION_MISMATCH:", + }) + testCases = append(testCases, testCase{ + name: "Renegotiate-Client-Upgrade", + renegotiate: 1, config: Config{ Bugs: ProtocolBugs{ - NoRenegotiationInfo: true, + NoRenegotiationInfoInInitial: true, }, }, + flags: []string{"-renegotiate-freely"}, shouldFail: true, - expectedError: ":UNSAFE_LEGACY_RENEGOTIATION_DISABLED:", - flags: []string{"-no-legacy-server-connect"}, + expectedError: ":RENEGOTIATION_MISMATCH:", }) testCases = append(testCases, testCase{ name: "Renegotiate-Client-NoExt-Allowed", @@ -4518,6 +4617,114 @@ func addCustomExtensionTests() { }) } +func addRSAClientKeyExchangeTests() { + for bad := RSABadValue(1); bad < NumRSABadValues; bad++ { + testCases = append(testCases, testCase{ + testType: serverTest, + name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad), + config: Config{ + // Ensure the ClientHello version and final + // version are different, to detect if the + // server uses the wrong one. + MaxVersion: VersionTLS11, + CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, + Bugs: ProtocolBugs{ + BadRSAClientKeyExchange: bad, + }, + }, + shouldFail: true, + expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", + }) + } +} + +var testCurves = []struct { + name string + id CurveID +}{ + {"P-256", CurveP256}, + {"P-384", CurveP384}, + {"P-521", CurveP521}, + {"X25519", CurveX25519}, +} + +func addCurveTests() { + for _, curve := range testCurves { + testCases = append(testCases, testCase{ + name: "CurveTest-Client-" + curve.name, + config: Config{ + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{curve.id}, + }, + flags: []string{"-enable-all-curves"}, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "CurveTest-Server-" + curve.name, + config: Config{ + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{curve.id}, + }, + flags: []string{"-enable-all-curves"}, + }) + } +} + +func addKeyExchangeInfoTests() { + testCases = append(testCases, testCase{ + name: "KeyExchangeInfo-RSA-Client", + config: Config{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + }, + // key.pem is a 1024-bit RSA key. + flags: []string{"-expect-key-exchange-info", "1024"}, + }) + // TODO(davidben): key_exchange_info doesn't work for plain RSA on the + // server. Either fix this or change the API as it's not very useful in + // this case. + + testCases = append(testCases, testCase{ + name: "KeyExchangeInfo-DHE-Client", + config: Config{ + CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, + Bugs: ProtocolBugs{ + // This is a 1234-bit prime number, generated + // with: + // openssl gendh 1234 | openssl asn1parse -i + DHGroupPrime: bigFromHex("0215C589A86BE450D1255A86D7A08877A70E124C11F0C75E476BA6A2186B1C830D4A132555973F2D5881D5F737BB800B7F417C01EC5960AEBF79478F8E0BBB6A021269BD10590C64C57F50AD8169D5488B56EE38DC5E02DA1A16ED3B5F41FEB2AD184B78A31F3A5B2BEC8441928343DA35DE3D4F89F0D4CEDE0034045084A0D1E6182E5EF7FCA325DD33CE81BE7FA87D43613E8FA7A1457099AB53"), + }, + }, + flags: []string{"-expect-key-exchange-info", "1234"}, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "KeyExchangeInfo-DHE-Server", + config: Config{ + CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, + }, + // bssl_shim as a server configures a 2048-bit DHE group. + flags: []string{"-expect-key-exchange-info", "2048"}, + }) + + testCases = append(testCases, testCase{ + name: "KeyExchangeInfo-ECDHE-Client", + config: Config{ + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{CurveX25519}, + }, + flags: []string{"-expect-key-exchange-info", "29", "-enable-all-curves"}, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "KeyExchangeInfo-ECDHE-Server", + config: Config{ + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{CurveX25519}, + }, + flags: []string{"-expect-key-exchange-info", "29", "-enable-all-curves"}, + }) +} + func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { defer wg.Done() @@ -4604,7 +4811,6 @@ func main() { addDDoSCallbackTests() addVersionNegotiationTests() addMinimumVersionTests() - addD5BugTests() addExtensionTests() addResumptionVersionTests() addExtendedMasterSecretTests() @@ -4615,6 +4821,9 @@ func main() { addExportKeyingMaterialTests() addTLSUniqueTests() addCustomExtensionTests() + addRSAClientKeyExchangeTests() + addCurveTests() + addKeyExchangeInfoTests() for _, async := range []bool{false, true} { for _, splitHandshake := range []bool{false, true} { for _, protocol := range []protocol{tls, dtls} { diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc index 50e6b23..1cf316d 100644 --- a/src/ssl/test/test_config.cc +++ b/src/ssl/test/test_config.cc @@ -61,7 +61,6 @@ const Flag<bool> kBoolFlags[] = { { "-no-tls1", &TestConfig::no_tls1 }, { "-no-ssl3", &TestConfig::no_ssl3 }, { "-shim-writes-first", &TestConfig::shim_writes_first }, - { "-tls-d5-bug", &TestConfig::tls_d5_bug }, { "-expect-session-miss", &TestConfig::expect_session_miss }, { "-expect-extended-master-secret", &TestConfig::expect_extended_master_secret }, @@ -76,7 +75,6 @@ const Flag<bool> kBoolFlags[] = { { "-fail-second-ddos-callback", &TestConfig::fail_second_ddos_callback }, { "-handshake-never-done", &TestConfig::handshake_never_done }, { "-use-export-context", &TestConfig::use_export_context }, - { "-no-legacy-server-connect", &TestConfig::no_legacy_server_connect }, { "-tls-unique", &TestConfig::tls_unique }, { "-expect-ticket-renewal", &TestConfig::expect_ticket_renewal }, { "-expect-no-session", &TestConfig::expect_no_session }, @@ -90,7 +88,6 @@ const Flag<bool> kBoolFlags[] = { { "-custom-extension-fail-add", &TestConfig::custom_extension_fail_add }, { "-check-close-notify", &TestConfig::check_close_notify }, { "-shim-shuts-down", &TestConfig::shim_shuts_down }, - { "-microsoft-big-sslv3-buffer", &TestConfig::microsoft_big_sslv3_buffer }, { "-verify-fail", &TestConfig::verify_fail }, { "-verify-peer", &TestConfig::verify_peer }, { "-expect-verify-result", &TestConfig::expect_verify_result }, @@ -98,6 +95,9 @@ const Flag<bool> kBoolFlags[] = { { "-renegotiate-freely", &TestConfig::renegotiate_freely }, { "-renegotiate-ignore", &TestConfig::renegotiate_ignore }, { "-disable-npn", &TestConfig::disable_npn }, + { "-p384-only", &TestConfig::p384_only }, + { "-enable-all-curves", &TestConfig::enable_all_curves }, + { "-use-sparse-dh-prime", &TestConfig::use_sparse_dh_prime }, }; const Flag<std::string> kStringFlags[] = { @@ -143,6 +143,8 @@ const Flag<int> kIntFlags[] = { { "-expect-total-renegotiations", &TestConfig::expect_total_renegotiations }, { "-expect-server-key-exchange-hash", &TestConfig::expect_server_key_exchange_hash }, + { "-expect-key-exchange-info", + &TestConfig::expect_key_exchange_info }, }; } // namespace diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h index 9f295ae..4e0a46a 100644 --- a/src/ssl/test/test_config.h +++ b/src/ssl/test/test_config.h @@ -45,7 +45,6 @@ struct TestConfig { std::string expected_channel_id; std::string send_channel_id; bool shim_writes_first = false; - bool tls_d5_bug = false; std::string host_name; std::string advertise_alpn; std::string expected_alpn; @@ -77,7 +76,6 @@ struct TestConfig { std::string export_label; std::string export_context; bool use_export_context = false; - bool no_legacy_server_connect = false; bool tls_unique = false; bool expect_ticket_renewal = false; bool expect_no_session = false; @@ -90,7 +88,6 @@ struct TestConfig { std::string ocsp_response; bool check_close_notify = false; bool shim_shuts_down = false; - bool microsoft_big_sslv3_buffer = false; bool verify_fail = false; bool verify_peer = false; bool expect_verify_result = false; @@ -101,6 +98,10 @@ struct TestConfig { bool renegotiate_ignore = false; bool disable_npn = false; int expect_server_key_exchange_hash = 0; + bool p384_only = false; + bool enable_all_curves = false; + bool use_sparse_dh_prime = false; + int expect_key_exchange_info = 0; }; bool ParseConfig(int argc, char **argv, TestConfig *out_config); diff --git a/src/ssl/tls_record.c b/src/ssl/tls_record.c index bdc5c01..3381eae 100644 --- a/src/ssl/tls_record.c +++ b/src/ssl/tls_record.c @@ -114,7 +114,6 @@ #include <openssl/err.h> #include "internal.h" -#include "../crypto/internal.h" /* kMaxEmptyRecords is the number of consecutive, empty records that will be @@ -123,14 +122,12 @@ * forever. */ static const uint8_t kMaxEmptyRecords = 32; -static struct CRYPTO_STATIC_MUTEX g_big_buffer_lock = CRYPTO_STATIC_MUTEX_INIT; -static uint64_t g_big_buffer_use_count = 0; - -uint64_t OPENSSL_get_big_buffer_use_count(void) { - CRYPTO_STATIC_MUTEX_lock_read(&g_big_buffer_lock); - uint64_t ret = g_big_buffer_use_count; - CRYPTO_STATIC_MUTEX_unlock(&g_big_buffer_lock); - return ret; +/* ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher + * state needs record-splitting and zero otherwise. */ +static int ssl_needs_record_splitting(const SSL *ssl) { + return !SSL_USE_EXPLICIT_IV(ssl) && ssl->aead_write_ctx != NULL && + (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 && + SSL_CIPHER_is_block_cipher(ssl->aead_write_ctx->cipher); } size_t ssl_record_prefix_len(const SSL *ssl) { @@ -150,7 +147,7 @@ size_t ssl_seal_prefix_len(const SSL *ssl) { } else { size_t ret = SSL3_RT_HEADER_LENGTH + SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx); - if (ssl->s3->need_record_splitting) { + if (ssl_needs_record_splitting(ssl)) { ret += SSL3_RT_HEADER_LENGTH; ret += ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher); } @@ -165,7 +162,7 @@ size_t ssl_max_seal_overhead(const SSL *ssl) { } else { size_t ret = SSL3_RT_HEADER_LENGTH + SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx); - if (ssl->s3->need_record_splitting) { + if (ssl_needs_record_splitting(ssl)) { ret *= 2; } return ret; @@ -198,11 +195,7 @@ enum ssl_open_record_t tls_open_record( } /* Check the ciphertext length. */ - size_t extra = 0; - if (ssl->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { - extra = SSL3_RT_MAX_EXTRA; - } - if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH + extra) { + if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) { OPENSSL_PUT_ERROR(SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); *out_alert = SSL_AD_RECORD_OVERFLOW; return ssl_open_record_error; @@ -235,20 +228,12 @@ enum ssl_open_record_t tls_open_record( } /* Check the plaintext length. */ - if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH + extra) { + if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH) { OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); *out_alert = SSL_AD_RECORD_OVERFLOW; return ssl_open_record_error; } - if (extra > 0 && - (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH || - plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH)) { - CRYPTO_STATIC_MUTEX_lock_write(&g_big_buffer_lock); - g_big_buffer_use_count++; - CRYPTO_STATIC_MUTEX_unlock(&g_big_buffer_lock); - } - /* Limit the number of consecutive empty records. */ if (plaintext_len == 0) { ssl->s3->empty_record_count++; @@ -323,8 +308,8 @@ static int do_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, uint8_t type, const uint8_t *in, size_t in_len) { size_t frag_len = 0; - if (ssl->s3->need_record_splitting && type == SSL3_RT_APPLICATION_DATA && - in_len > 1) { + if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 && + ssl_needs_record_splitting(ssl)) { /* |do_seal_record| will notice if it clobbers |in[0]|, but not if it * aliases the rest of |in|. */ if (in + 1 <= out && out < in + in_len) { diff --git a/src/tool/CMakeLists.txt b/src/tool/CMakeLists.txt index a6cc15f..f0af283 100644 --- a/src/tool/CMakeLists.txt +++ b/src/tool/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable( client.cc const.cc digest.cc + generate_ed25519.cc genrsa.cc pkcs12.cc rand.cc diff --git a/src/tool/client.cc b/src/tool/client.cc index cd8353b..dbec184 100644 --- a/src/tool/client.cc +++ b/src/tool/client.cc @@ -14,6 +14,8 @@ #include <openssl/base.h> +#include <stdio.h> + #include <openssl/err.h> #include <openssl/pem.h> #include <openssl/ssl.h> @@ -80,6 +82,10 @@ static const struct argument kArguments[] = { "A file to write the negotiated session to.", }, { + "-key", kOptionalArgument, + "Private-key file to use (default is no client certificate)", + }, + { "", kOptionalArgument, "", }, }; @@ -119,6 +125,13 @@ static int NextProtoSelectCallback(SSL* ssl, uint8_t** out, uint8_t* outlen, return SSL_TLSEXT_ERR_OK; } +static FILE *g_keylog_file = nullptr; + +static void KeyLogCallback(const SSL *ssl, const char *line) { + fprintf(g_keylog_file, "%s\n", line); + fflush(g_keylog_file); +} + bool Client(const std::vector<std::string> &args) { if (!InitSocketLibrary()) { return false; @@ -135,12 +148,12 @@ bool Client(const std::vector<std::string> &args) { const char *keylog_file = getenv("SSLKEYLOGFILE"); if (keylog_file) { - BIO *keylog_bio = BIO_new_file(keylog_file, "a"); - if (!keylog_bio) { - ERR_print_errors_cb(PrintErrorCallback, stderr); + g_keylog_file = fopen(keylog_file, "a"); + if (g_keylog_file == nullptr) { + perror("fopen"); return false; } - SSL_CTX_set_keylog_bio(ctx.get(), keylog_bio); + SSL_CTX_set_keylog_callback(ctx.get(), KeyLogCallback); } if (args_map.count("-cipher") != 0 && @@ -227,6 +240,18 @@ bool Client(const std::vector<std::string> &args) { SSL_CTX_set_mode(ctx.get(), SSL_MODE_ENABLE_FALSE_START); } + if (args_map.count("-key") != 0) { + const std::string &key = args_map["-key"]; + if (!SSL_CTX_use_PrivateKey_file(ctx.get(), key.c_str(), SSL_FILETYPE_PEM)) { + fprintf(stderr, "Failed to load private key: %s\n", key.c_str()); + return false; + } + if (!SSL_CTX_use_certificate_chain_file(ctx.get(), key.c_str())) { + fprintf(stderr, "Failed to load cert chain: %s\n", key.c_str()); + return false; + } + } + int sock = -1; if (!Connect(&sock, args_map["-connect"])) { return false; diff --git a/src/tool/generate_ed25519.cc b/src/tool/generate_ed25519.cc new file mode 100644 index 0000000..15d3692 --- /dev/null +++ b/src/tool/generate_ed25519.cc @@ -0,0 +1,67 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <openssl/curve25519.h> + +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#include "../crypto/test/scoped_types.h" +#include "internal.h" + + +static const struct argument kArguments[] = { + { + "-out-public", kRequiredArgument, "The file to write the public key to", + }, + { + "-out-private", kRequiredArgument, + "The file to write the private key to", + }, + { + "", kOptionalArgument, "", + }, +}; + +static bool WriteToFile(const std::string &path, const uint8_t *in, + size_t in_len) { + ScopedFILE file(fopen(path.c_str(), "wb")); + if (!file) { + fprintf(stderr, "Failed to open '%s': %s\n", path.c_str(), strerror(errno)); + return false; + } + if (fwrite(in, in_len, 1, file.get()) != 1) { + fprintf(stderr, "Failed to write to '%s': %s\n", path.c_str(), + strerror(errno)); + return false; + } + return true; +} + +bool GenerateEd25519Key(const std::vector<std::string> &args) { + std::map<std::string, std::string> args_map; + + if (!ParseKeyValueArguments(&args_map, args, kArguments)) { + PrintUsage(kArguments); + return false; + } + + uint8_t public_key[32], private_key[64]; + ED25519_keypair(public_key, private_key); + + return WriteToFile(args_map["-out-public"], public_key, sizeof(public_key)) && + WriteToFile(args_map["-out-private"], private_key, + sizeof(private_key)); +} diff --git a/src/tool/server.cc b/src/tool/server.cc index abc71cf..14f37a4 100644 --- a/src/tool/server.cc +++ b/src/tool/server.cc @@ -103,11 +103,11 @@ bool Server(const std::vector<std::string> &args) { if (args_map.count("-key") != 0) { key_file = args_map["-key"]; } - if (SSL_CTX_use_PrivateKey_file(ctx, key_file.c_str(), SSL_FILETYPE_PEM) <= 0) { + if (!SSL_CTX_use_PrivateKey_file(ctx, key_file.c_str(), SSL_FILETYPE_PEM)) { fprintf(stderr, "Failed to load private key: %s\n", key_file.c_str()); return false; } - if (SSL_CTX_use_certificate_chain_file(ctx, key_file.c_str()) != 1) { + if (!SSL_CTX_use_certificate_chain_file(ctx, key_file.c_str())) { fprintf(stderr, "Failed to load cert chain: %s\n", key_file.c_str()); return false; } diff --git a/src/tool/speed.cc b/src/tool/speed.cc index 39bbadb..db7c5fa 100644 --- a/src/tool/speed.cc +++ b/src/tool/speed.cc @@ -21,6 +21,7 @@ #include <string.h> #include <openssl/aead.h> +#include <openssl/curve25519.h> #include <openssl/digest.h> #include <openssl/err.h> #include <openssl/obj.h> @@ -397,6 +398,75 @@ static bool SpeedECDSA(const std::string &selected) { SpeedECDSACurve("ECDSA P-521", NID_secp521r1, selected); } +static bool Speed25519(const std::string &selected) { + if (!selected.empty() && selected.find("25519") == std::string::npos) { + return true; + } + + TimeResults results; + + uint8_t public_key[32], private_key[64]; + + if (!TimeFunction(&results, [&public_key, &private_key]() -> bool { + ED25519_keypair(public_key, private_key); + return true; + })) { + return false; + } + + results.Print("Ed25519 key generation"); + + static const uint8_t kMessage[] = {0, 1, 2, 3, 4, 5}; + uint8_t signature[64]; + + if (!TimeFunction(&results, [&private_key, &signature]() -> bool { + return ED25519_sign(signature, kMessage, sizeof(kMessage), + private_key) == 1; + })) { + return false; + } + + results.Print("Ed25519 signing"); + + if (!TimeFunction(&results, [&public_key, &signature]() -> bool { + return ED25519_verify(kMessage, sizeof(kMessage), signature, + public_key) == 1; + })) { + fprintf(stderr, "Ed25519 verify failed.\n"); + return false; + } + + results.Print("Ed25519 verify"); + + if (!TimeFunction(&results, []() -> bool { + uint8_t out[32], in[32]; + memset(in, 0, sizeof(in)); + X25519_public_from_private(out, in); + return true; + })) { + fprintf(stderr, "Curve25519 base-point multiplication failed.\n"); + return false; + } + + results.Print("Curve25519 base-point multiplication"); + + if (!TimeFunction(&results, []() -> bool { + uint8_t out[32], in1[32], in2[32]; + memset(in1, 0, sizeof(in1)); + memset(in2, 0, sizeof(in2)); + in1[0] = 1; + in2[0] = 9; + return X25519(out, in1, in2) == 1; + })) { + fprintf(stderr, "Curve25519 arbitrary point multiplication failed.\n"); + return false; + } + + results.Print("Curve25519 arbitrary point multiplication"); + + return true; +} + bool Speed(const std::vector<std::string> &args) { std::string selected; if (args.size() > 1) { @@ -458,11 +528,14 @@ bool Speed(const std::vector<std::string> &args) { if (!SpeedAEAD(EVP_aead_aes_128_gcm(), "AES-128-GCM", kTLSADLen, selected) || !SpeedAEAD(EVP_aead_aes_256_gcm(), "AES-256-GCM", kTLSADLen, selected) || - !SpeedAEAD(EVP_aead_chacha20_poly1305_rfc7539(), "ChaCha20-Poly1305", - kTLSADLen, selected) || + !SpeedAEAD(EVP_aead_chacha20_poly1305(), "ChaCha20-Poly1305", kTLSADLen, + selected) || !SpeedAEAD(EVP_aead_chacha20_poly1305_old(), "ChaCha20-Poly1305-Old", kTLSADLen, selected) || !SpeedAEAD(EVP_aead_rc4_md5_tls(), "RC4-MD5", kLegacyADLen, selected) || + !SpeedAEAD(EVP_aead_rc4_sha1_tls(), "RC4-SHA1", kLegacyADLen, selected) || + !SpeedAEAD(EVP_aead_des_ede3_cbc_sha1_tls(), "DES-EDE3-CBC-SHA1", + kLegacyADLen, selected) || !SpeedAEAD(EVP_aead_aes_128_cbc_sha1_tls(), "AES-128-CBC-SHA1", kLegacyADLen, selected) || !SpeedAEAD(EVP_aead_aes_256_cbc_sha1_tls(), "AES-256-CBC-SHA1", @@ -472,7 +545,8 @@ bool Speed(const std::vector<std::string> &args) { !SpeedHash(EVP_sha512(), "SHA-512", selected) || !SpeedRandom(selected) || !SpeedECDH(selected) || - !SpeedECDSA(selected)) { + !SpeedECDSA(selected) || + !Speed25519(selected)) { return false; } diff --git a/src/tool/tool.cc b/src/tool/tool.cc index afe6840..b825008 100644 --- a/src/tool/tool.cc +++ b/src/tool/tool.cc @@ -30,6 +30,7 @@ bool Ciphers(const std::vector<std::string> &args); bool Client(const std::vector<std::string> &args); bool DoPKCS12(const std::vector<std::string> &args); +bool GenerateEd25519Key(const std::vector<std::string> &args); bool GenerateRSAKey(const std::vector<std::string> &args); bool MD5Sum(const std::vector<std::string> &args); bool Rand(const std::vector<std::string> &args); @@ -44,13 +45,14 @@ bool Speed(const std::vector<std::string> &args); typedef bool (*tool_func_t)(const std::vector<std::string> &args); struct Tool { - char name[16]; + const char *name; tool_func_t func; }; static const Tool kTools[] = { { "ciphers", Ciphers }, { "client", Client }, + { "generate-ed25519", GenerateEd25519Key }, { "genrsa", GenerateRSAKey }, { "md5sum", MD5Sum }, { "pkcs12", DoPKCS12 }, @@ -68,19 +70,17 @@ static const Tool kTools[] = { }; static void usage(const char *name) { - printf("Usage: %s [", name); + printf("Usage: %s COMMAND\n", name); + printf("\n"); + printf("Available commands:\n"); for (size_t i = 0;; i++) { const Tool &tool = kTools[i]; if (tool.func == nullptr) { break; } - if (i > 0) { - printf("|"); - } - printf("%s", tool.name); + printf(" %s\n", tool.name); } - printf("]\n"); } tool_func_t FindTool(const std::string &name) { diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc index cfda6c3..2c15c00 100644 --- a/src/tool/transport_common.cc +++ b/src/tool/transport_common.cc @@ -172,6 +172,11 @@ void PrintConnectionInfo(const SSL *ssl) { fprintf(stderr, " Resumed session: %s\n", SSL_session_reused(ssl) ? "yes" : "no"); fprintf(stderr, " Cipher: %s\n", SSL_CIPHER_get_name(cipher)); + if (SSL_CIPHER_is_ECDHE(cipher)) { + fprintf(stderr, " ECDHE curve: %s\n", + SSL_get_curve_name( + SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl)))); + } fprintf(stderr, " Secure renegotiation: %s\n", SSL_get_secure_renegotiation_support(ssl) ? "yes" : "no"); diff --git a/src/util/all_tests.json b/src/util/all_tests.json index ba57cc7..c621799 100644 --- a/src/util/all_tests.json +++ b/src/util/all_tests.json @@ -31,6 +31,8 @@ ["crypto/cipher/cipher_test", "crypto/cipher/test/cipher_test.txt"], ["crypto/cmac/cmac_test"], ["crypto/constant_time_test"], + ["crypto/curve25519/ed25519_test", "crypto/curve25519/ed25519_tests.txt"], + ["crypto/curve25519/x25519_test"], ["crypto/dh/dh_test"], ["crypto/digest/digest_test"], ["crypto/dsa/dsa_test"], diff --git a/src/util/bot/update_clang.py b/src/util/bot/update_clang.py index 0836d11..1824393 100644 --- a/src/util/bot/update_clang.py +++ b/src/util/bot/update_clang.py @@ -20,7 +20,7 @@ import tempfile import urllib # CLANG_REVISION and CLANG_SUB_REVISION determine the build of clang -# to use. These should be synced with tools/clang/scripts/update.sh in +# to use. These should be synced with tools/clang/scripts/update.py in # Chromium. CLANG_REVISION = "233105" CLANG_SUB_REVISION = "1" diff --git a/src/util/doc.config b/src/util/doc.config index 77498ee..cbee543 100644 --- a/src/util/doc.config +++ b/src/util/doc.config @@ -24,6 +24,7 @@ "include/openssl/aes.h", "include/openssl/bn.h", "include/openssl/cmac.h", + "include/openssl/curve25519.h", "include/openssl/des.h", "include/openssl/dh.h", "include/openssl/dsa.h", diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py index 856960e..6321c5c 100644 --- a/src/util/generate_build_files.py +++ b/src/util/generate_build_files.py @@ -39,9 +39,10 @@ OS_ARCH_COMBOS = [ # perlasm system. NON_PERL_FILES = { ('linux', 'arm'): [ - 'src/crypto/poly1305/poly1305_arm_asm.S', 'src/crypto/chacha/chacha_vec_arm.S', 'src/crypto/cpu-arm-asm.S', + 'src/crypto/curve25519/asm/x25519-asm-arm.S', + 'src/crypto/poly1305/poly1305_arm_asm.S', ], } @@ -149,8 +150,8 @@ class Android(object): with open('sources.mk', 'w+') as makefile: makefile.write(self.header) - files['crypto'].extend(self.ExtraFiles()) - self.PrintVariableSection(makefile, 'crypto_sources', files['crypto']) + crypto_files = files['crypto'] + self.ExtraFiles() + self.PrintVariableSection(makefile, 'crypto_sources', crypto_files) self.PrintVariableSection(makefile, 'ssl_sources', files['ssl']) self.PrintVariableSection(makefile, 'tool_sources', files['tool']) diff --git a/win-x86/crypto/sha/sha1-586.asm b/win-x86/crypto/sha/sha1-586.asm index 43bf964..cee8c62 100644 --- a/win-x86/crypto/sha/sha1-586.asm +++ b/win-x86/crypto/sha/sha1-586.asm @@ -35,6 +35,11 @@ L$000pic_point: mov ecx,DWORD [8+esi] test eax,16777216 jz NEAR L$001x86 + and edx,268435456 + and eax,1073741824 + or eax,edx + cmp eax,1342177280 + je NEAR L$avx_shortcut jmp NEAR L$ssse3_shortcut align 16 L$001x86: @@ -2619,6 +2624,1174 @@ L$005done: pop ebx pop ebp ret +align 16 +__sha1_block_data_order_avx: + push ebp + push ebx + push esi + push edi + call L$006pic_point +L$006pic_point: + pop ebp + lea ebp,[(L$K_XX_XX-L$006pic_point)+ebp] +L$avx_shortcut: + vzeroall + vmovdqa xmm7,[ebp] + vmovdqa xmm0,[16+ebp] + vmovdqa xmm1,[32+ebp] + vmovdqa xmm2,[48+ebp] + vmovdqa xmm6,[64+ebp] + mov edi,DWORD [20+esp] + mov ebp,DWORD [24+esp] + mov edx,DWORD [28+esp] + mov esi,esp + sub esp,208 + and esp,-64 + vmovdqa [112+esp],xmm0 + vmovdqa [128+esp],xmm1 + vmovdqa [144+esp],xmm2 + shl edx,6 + vmovdqa [160+esp],xmm7 + add edx,ebp + vmovdqa [176+esp],xmm6 + add ebp,64 + mov DWORD [192+esp],edi + mov DWORD [196+esp],ebp + mov DWORD [200+esp],edx + mov DWORD [204+esp],esi + mov eax,DWORD [edi] + mov ebx,DWORD [4+edi] + mov ecx,DWORD [8+edi] + mov edx,DWORD [12+edi] + mov edi,DWORD [16+edi] + mov esi,ebx + vmovdqu xmm0,[ebp-64] + vmovdqu xmm1,[ebp-48] + vmovdqu xmm2,[ebp-32] + vmovdqu xmm3,[ebp-16] + vpshufb xmm0,xmm0,xmm6 + vpshufb xmm1,xmm1,xmm6 + vpshufb xmm2,xmm2,xmm6 + vmovdqa [96+esp],xmm7 + vpshufb xmm3,xmm3,xmm6 + vpaddd xmm4,xmm0,xmm7 + vpaddd xmm5,xmm1,xmm7 + vpaddd xmm6,xmm2,xmm7 + vmovdqa [esp],xmm4 + mov ebp,ecx + vmovdqa [16+esp],xmm5 + xor ebp,edx + vmovdqa [32+esp],xmm6 + and esi,ebp + jmp NEAR L$007loop +align 16 +L$007loop: + shrd ebx,ebx,2 + xor esi,edx + vpalignr xmm4,xmm1,xmm0,8 + mov ebp,eax + add edi,DWORD [esp] + vpaddd xmm7,xmm7,xmm3 + vmovdqa [64+esp],xmm0 + xor ebx,ecx + shld eax,eax,5 + vpsrldq xmm6,xmm3,4 + add edi,esi + and ebp,ebx + vpxor xmm4,xmm4,xmm0 + xor ebx,ecx + add edi,eax + vpxor xmm6,xmm6,xmm2 + shrd eax,eax,7 + xor ebp,ecx + vmovdqa [48+esp],xmm7 + mov esi,edi + add edx,DWORD [4+esp] + vpxor xmm4,xmm4,xmm6 + xor eax,ebx + shld edi,edi,5 + add edx,ebp + and esi,eax + vpsrld xmm6,xmm4,31 + xor eax,ebx + add edx,edi + shrd edi,edi,7 + xor esi,ebx + vpslldq xmm0,xmm4,12 + vpaddd xmm4,xmm4,xmm4 + mov ebp,edx + add ecx,DWORD [8+esp] + xor edi,eax + shld edx,edx,5 + vpsrld xmm7,xmm0,30 + vpor xmm4,xmm4,xmm6 + add ecx,esi + and ebp,edi + xor edi,eax + add ecx,edx + vpslld xmm0,xmm0,2 + shrd edx,edx,7 + xor ebp,eax + vpxor xmm4,xmm4,xmm7 + mov esi,ecx + add ebx,DWORD [12+esp] + xor edx,edi + shld ecx,ecx,5 + vpxor xmm4,xmm4,xmm0 + add ebx,ebp + and esi,edx + vmovdqa xmm0,[96+esp] + xor edx,edi + add ebx,ecx + shrd ecx,ecx,7 + xor esi,edi + vpalignr xmm5,xmm2,xmm1,8 + mov ebp,ebx + add eax,DWORD [16+esp] + vpaddd xmm0,xmm0,xmm4 + vmovdqa [80+esp],xmm1 + xor ecx,edx + shld ebx,ebx,5 + vpsrldq xmm7,xmm4,4 + add eax,esi + and ebp,ecx + vpxor xmm5,xmm5,xmm1 + xor ecx,edx + add eax,ebx + vpxor xmm7,xmm7,xmm3 + shrd ebx,ebx,7 + xor ebp,edx + vmovdqa [esp],xmm0 + mov esi,eax + add edi,DWORD [20+esp] + vpxor xmm5,xmm5,xmm7 + xor ebx,ecx + shld eax,eax,5 + add edi,ebp + and esi,ebx + vpsrld xmm7,xmm5,31 + xor ebx,ecx + add edi,eax + shrd eax,eax,7 + xor esi,ecx + vpslldq xmm1,xmm5,12 + vpaddd xmm5,xmm5,xmm5 + mov ebp,edi + add edx,DWORD [24+esp] + xor eax,ebx + shld edi,edi,5 + vpsrld xmm0,xmm1,30 + vpor xmm5,xmm5,xmm7 + add edx,esi + and ebp,eax + xor eax,ebx + add edx,edi + vpslld xmm1,xmm1,2 + shrd edi,edi,7 + xor ebp,ebx + vpxor xmm5,xmm5,xmm0 + mov esi,edx + add ecx,DWORD [28+esp] + xor edi,eax + shld edx,edx,5 + vpxor xmm5,xmm5,xmm1 + add ecx,ebp + and esi,edi + vmovdqa xmm1,[112+esp] + xor edi,eax + add ecx,edx + shrd edx,edx,7 + xor esi,eax + vpalignr xmm6,xmm3,xmm2,8 + mov ebp,ecx + add ebx,DWORD [32+esp] + vpaddd xmm1,xmm1,xmm5 + vmovdqa [96+esp],xmm2 + xor edx,edi + shld ecx,ecx,5 + vpsrldq xmm0,xmm5,4 + add ebx,esi + and ebp,edx + vpxor xmm6,xmm6,xmm2 + xor edx,edi + add ebx,ecx + vpxor xmm0,xmm0,xmm4 + shrd ecx,ecx,7 + xor ebp,edi + vmovdqa [16+esp],xmm1 + mov esi,ebx + add eax,DWORD [36+esp] + vpxor xmm6,xmm6,xmm0 + xor ecx,edx + shld ebx,ebx,5 + add eax,ebp + and esi,ecx + vpsrld xmm0,xmm6,31 + xor ecx,edx + add eax,ebx + shrd ebx,ebx,7 + xor esi,edx + vpslldq xmm2,xmm6,12 + vpaddd xmm6,xmm6,xmm6 + mov ebp,eax + add edi,DWORD [40+esp] + xor ebx,ecx + shld eax,eax,5 + vpsrld xmm1,xmm2,30 + vpor xmm6,xmm6,xmm0 + add edi,esi + and ebp,ebx + xor ebx,ecx + add edi,eax + vpslld xmm2,xmm2,2 + vmovdqa xmm0,[64+esp] + shrd eax,eax,7 + xor ebp,ecx + vpxor xmm6,xmm6,xmm1 + mov esi,edi + add edx,DWORD [44+esp] + xor eax,ebx + shld edi,edi,5 + vpxor xmm6,xmm6,xmm2 + add edx,ebp + and esi,eax + vmovdqa xmm2,[112+esp] + xor eax,ebx + add edx,edi + shrd edi,edi,7 + xor esi,ebx + vpalignr xmm7,xmm4,xmm3,8 + mov ebp,edx + add ecx,DWORD [48+esp] + vpaddd xmm2,xmm2,xmm6 + vmovdqa [64+esp],xmm3 + xor edi,eax + shld edx,edx,5 + vpsrldq xmm1,xmm6,4 + add ecx,esi + and ebp,edi + vpxor xmm7,xmm7,xmm3 + xor edi,eax + add ecx,edx + vpxor xmm1,xmm1,xmm5 + shrd edx,edx,7 + xor ebp,eax + vmovdqa [32+esp],xmm2 + mov esi,ecx + add ebx,DWORD [52+esp] + vpxor xmm7,xmm7,xmm1 + xor edx,edi + shld ecx,ecx,5 + add ebx,ebp + and esi,edx + vpsrld xmm1,xmm7,31 + xor edx,edi + add ebx,ecx + shrd ecx,ecx,7 + xor esi,edi + vpslldq xmm3,xmm7,12 + vpaddd xmm7,xmm7,xmm7 + mov ebp,ebx + add eax,DWORD [56+esp] + xor ecx,edx + shld ebx,ebx,5 + vpsrld xmm2,xmm3,30 + vpor xmm7,xmm7,xmm1 + add eax,esi + and ebp,ecx + xor ecx,edx + add eax,ebx + vpslld xmm3,xmm3,2 + vmovdqa xmm1,[80+esp] + shrd ebx,ebx,7 + xor ebp,edx + vpxor xmm7,xmm7,xmm2 + mov esi,eax + add edi,DWORD [60+esp] + xor ebx,ecx + shld eax,eax,5 + vpxor xmm7,xmm7,xmm3 + add edi,ebp + and esi,ebx + vmovdqa xmm3,[112+esp] + xor ebx,ecx + add edi,eax + vpalignr xmm2,xmm7,xmm6,8 + vpxor xmm0,xmm0,xmm4 + shrd eax,eax,7 + xor esi,ecx + mov ebp,edi + add edx,DWORD [esp] + vpxor xmm0,xmm0,xmm1 + vmovdqa [80+esp],xmm4 + xor eax,ebx + shld edi,edi,5 + vmovdqa xmm4,xmm3 + vpaddd xmm3,xmm3,xmm7 + add edx,esi + and ebp,eax + vpxor xmm0,xmm0,xmm2 + xor eax,ebx + add edx,edi + shrd edi,edi,7 + xor ebp,ebx + vpsrld xmm2,xmm0,30 + vmovdqa [48+esp],xmm3 + mov esi,edx + add ecx,DWORD [4+esp] + xor edi,eax + shld edx,edx,5 + vpslld xmm0,xmm0,2 + add ecx,ebp + and esi,edi + xor edi,eax + add ecx,edx + shrd edx,edx,7 + xor esi,eax + mov ebp,ecx + add ebx,DWORD [8+esp] + vpor xmm0,xmm0,xmm2 + xor edx,edi + shld ecx,ecx,5 + vmovdqa xmm2,[96+esp] + add ebx,esi + and ebp,edx + xor edx,edi + add ebx,ecx + add eax,DWORD [12+esp] + xor ebp,edi + mov esi,ebx + shld ebx,ebx,5 + add eax,ebp + xor esi,edx + shrd ecx,ecx,7 + add eax,ebx + vpalignr xmm3,xmm0,xmm7,8 + vpxor xmm1,xmm1,xmm5 + add edi,DWORD [16+esp] + xor esi,ecx + mov ebp,eax + shld eax,eax,5 + vpxor xmm1,xmm1,xmm2 + vmovdqa [96+esp],xmm5 + add edi,esi + xor ebp,ecx + vmovdqa xmm5,xmm4 + vpaddd xmm4,xmm4,xmm0 + shrd ebx,ebx,7 + add edi,eax + vpxor xmm1,xmm1,xmm3 + add edx,DWORD [20+esp] + xor ebp,ebx + mov esi,edi + shld edi,edi,5 + vpsrld xmm3,xmm1,30 + vmovdqa [esp],xmm4 + add edx,ebp + xor esi,ebx + shrd eax,eax,7 + add edx,edi + vpslld xmm1,xmm1,2 + add ecx,DWORD [24+esp] + xor esi,eax + mov ebp,edx + shld edx,edx,5 + add ecx,esi + xor ebp,eax + shrd edi,edi,7 + add ecx,edx + vpor xmm1,xmm1,xmm3 + add ebx,DWORD [28+esp] + xor ebp,edi + vmovdqa xmm3,[64+esp] + mov esi,ecx + shld ecx,ecx,5 + add ebx,ebp + xor esi,edi + shrd edx,edx,7 + add ebx,ecx + vpalignr xmm4,xmm1,xmm0,8 + vpxor xmm2,xmm2,xmm6 + add eax,DWORD [32+esp] + xor esi,edx + mov ebp,ebx + shld ebx,ebx,5 + vpxor xmm2,xmm2,xmm3 + vmovdqa [64+esp],xmm6 + add eax,esi + xor ebp,edx + vmovdqa xmm6,[128+esp] + vpaddd xmm5,xmm5,xmm1 + shrd ecx,ecx,7 + add eax,ebx + vpxor xmm2,xmm2,xmm4 + add edi,DWORD [36+esp] + xor ebp,ecx + mov esi,eax + shld eax,eax,5 + vpsrld xmm4,xmm2,30 + vmovdqa [16+esp],xmm5 + add edi,ebp + xor esi,ecx + shrd ebx,ebx,7 + add edi,eax + vpslld xmm2,xmm2,2 + add edx,DWORD [40+esp] + xor esi,ebx + mov ebp,edi + shld edi,edi,5 + add edx,esi + xor ebp,ebx + shrd eax,eax,7 + add edx,edi + vpor xmm2,xmm2,xmm4 + add ecx,DWORD [44+esp] + xor ebp,eax + vmovdqa xmm4,[80+esp] + mov esi,edx + shld edx,edx,5 + add ecx,ebp + xor esi,eax + shrd edi,edi,7 + add ecx,edx + vpalignr xmm5,xmm2,xmm1,8 + vpxor xmm3,xmm3,xmm7 + add ebx,DWORD [48+esp] + xor esi,edi + mov ebp,ecx + shld ecx,ecx,5 + vpxor xmm3,xmm3,xmm4 + vmovdqa [80+esp],xmm7 + add ebx,esi + xor ebp,edi + vmovdqa xmm7,xmm6 + vpaddd xmm6,xmm6,xmm2 + shrd edx,edx,7 + add ebx,ecx + vpxor xmm3,xmm3,xmm5 + add eax,DWORD [52+esp] + xor ebp,edx + mov esi,ebx + shld ebx,ebx,5 + vpsrld xmm5,xmm3,30 + vmovdqa [32+esp],xmm6 + add eax,ebp + xor esi,edx + shrd ecx,ecx,7 + add eax,ebx + vpslld xmm3,xmm3,2 + add edi,DWORD [56+esp] + xor esi,ecx + mov ebp,eax + shld eax,eax,5 + add edi,esi + xor ebp,ecx + shrd ebx,ebx,7 + add edi,eax + vpor xmm3,xmm3,xmm5 + add edx,DWORD [60+esp] + xor ebp,ebx + vmovdqa xmm5,[96+esp] + mov esi,edi + shld edi,edi,5 + add edx,ebp + xor esi,ebx + shrd eax,eax,7 + add edx,edi + vpalignr xmm6,xmm3,xmm2,8 + vpxor xmm4,xmm4,xmm0 + add ecx,DWORD [esp] + xor esi,eax + mov ebp,edx + shld edx,edx,5 + vpxor xmm4,xmm4,xmm5 + vmovdqa [96+esp],xmm0 + add ecx,esi + xor ebp,eax + vmovdqa xmm0,xmm7 + vpaddd xmm7,xmm7,xmm3 + shrd edi,edi,7 + add ecx,edx + vpxor xmm4,xmm4,xmm6 + add ebx,DWORD [4+esp] + xor ebp,edi + mov esi,ecx + shld ecx,ecx,5 + vpsrld xmm6,xmm4,30 + vmovdqa [48+esp],xmm7 + add ebx,ebp + xor esi,edi + shrd edx,edx,7 + add ebx,ecx + vpslld xmm4,xmm4,2 + add eax,DWORD [8+esp] + xor esi,edx + mov ebp,ebx + shld ebx,ebx,5 + add eax,esi + xor ebp,edx + shrd ecx,ecx,7 + add eax,ebx + vpor xmm4,xmm4,xmm6 + add edi,DWORD [12+esp] + xor ebp,ecx + vmovdqa xmm6,[64+esp] + mov esi,eax + shld eax,eax,5 + add edi,ebp + xor esi,ecx + shrd ebx,ebx,7 + add edi,eax + vpalignr xmm7,xmm4,xmm3,8 + vpxor xmm5,xmm5,xmm1 + add edx,DWORD [16+esp] + xor esi,ebx + mov ebp,edi + shld edi,edi,5 + vpxor xmm5,xmm5,xmm6 + vmovdqa [64+esp],xmm1 + add edx,esi + xor ebp,ebx + vmovdqa xmm1,xmm0 + vpaddd xmm0,xmm0,xmm4 + shrd eax,eax,7 + add edx,edi + vpxor xmm5,xmm5,xmm7 + add ecx,DWORD [20+esp] + xor ebp,eax + mov esi,edx + shld edx,edx,5 + vpsrld xmm7,xmm5,30 + vmovdqa [esp],xmm0 + add ecx,ebp + xor esi,eax + shrd edi,edi,7 + add ecx,edx + vpslld xmm5,xmm5,2 + add ebx,DWORD [24+esp] + xor esi,edi + mov ebp,ecx + shld ecx,ecx,5 + add ebx,esi + xor ebp,edi + shrd edx,edx,7 + add ebx,ecx + vpor xmm5,xmm5,xmm7 + add eax,DWORD [28+esp] + vmovdqa xmm7,[80+esp] + shrd ecx,ecx,7 + mov esi,ebx + xor ebp,edx + shld ebx,ebx,5 + add eax,ebp + xor esi,ecx + xor ecx,edx + add eax,ebx + vpalignr xmm0,xmm5,xmm4,8 + vpxor xmm6,xmm6,xmm2 + add edi,DWORD [32+esp] + and esi,ecx + xor ecx,edx + shrd ebx,ebx,7 + vpxor xmm6,xmm6,xmm7 + vmovdqa [80+esp],xmm2 + mov ebp,eax + xor esi,ecx + vmovdqa xmm2,xmm1 + vpaddd xmm1,xmm1,xmm5 + shld eax,eax,5 + add edi,esi + vpxor xmm6,xmm6,xmm0 + xor ebp,ebx + xor ebx,ecx + add edi,eax + add edx,DWORD [36+esp] + vpsrld xmm0,xmm6,30 + vmovdqa [16+esp],xmm1 + and ebp,ebx + xor ebx,ecx + shrd eax,eax,7 + mov esi,edi + vpslld xmm6,xmm6,2 + xor ebp,ebx + shld edi,edi,5 + add edx,ebp + xor esi,eax + xor eax,ebx + add edx,edi + add ecx,DWORD [40+esp] + and esi,eax + vpor xmm6,xmm6,xmm0 + xor eax,ebx + shrd edi,edi,7 + vmovdqa xmm0,[96+esp] + mov ebp,edx + xor esi,eax + shld edx,edx,5 + add ecx,esi + xor ebp,edi + xor edi,eax + add ecx,edx + add ebx,DWORD [44+esp] + and ebp,edi + xor edi,eax + shrd edx,edx,7 + mov esi,ecx + xor ebp,edi + shld ecx,ecx,5 + add ebx,ebp + xor esi,edx + xor edx,edi + add ebx,ecx + vpalignr xmm1,xmm6,xmm5,8 + vpxor xmm7,xmm7,xmm3 + add eax,DWORD [48+esp] + and esi,edx + xor edx,edi + shrd ecx,ecx,7 + vpxor xmm7,xmm7,xmm0 + vmovdqa [96+esp],xmm3 + mov ebp,ebx + xor esi,edx + vmovdqa xmm3,[144+esp] + vpaddd xmm2,xmm2,xmm6 + shld ebx,ebx,5 + add eax,esi + vpxor xmm7,xmm7,xmm1 + xor ebp,ecx + xor ecx,edx + add eax,ebx + add edi,DWORD [52+esp] + vpsrld xmm1,xmm7,30 + vmovdqa [32+esp],xmm2 + and ebp,ecx + xor ecx,edx + shrd ebx,ebx,7 + mov esi,eax + vpslld xmm7,xmm7,2 + xor ebp,ecx + shld eax,eax,5 + add edi,ebp + xor esi,ebx + xor ebx,ecx + add edi,eax + add edx,DWORD [56+esp] + and esi,ebx + vpor xmm7,xmm7,xmm1 + xor ebx,ecx + shrd eax,eax,7 + vmovdqa xmm1,[64+esp] + mov ebp,edi + xor esi,ebx + shld edi,edi,5 + add edx,esi + xor ebp,eax + xor eax,ebx + add edx,edi + add ecx,DWORD [60+esp] + and ebp,eax + xor eax,ebx + shrd edi,edi,7 + mov esi,edx + xor ebp,eax + shld edx,edx,5 + add ecx,ebp + xor esi,edi + xor edi,eax + add ecx,edx + vpalignr xmm2,xmm7,xmm6,8 + vpxor xmm0,xmm0,xmm4 + add ebx,DWORD [esp] + and esi,edi + xor edi,eax + shrd edx,edx,7 + vpxor xmm0,xmm0,xmm1 + vmovdqa [64+esp],xmm4 + mov ebp,ecx + xor esi,edi + vmovdqa xmm4,xmm3 + vpaddd xmm3,xmm3,xmm7 + shld ecx,ecx,5 + add ebx,esi + vpxor xmm0,xmm0,xmm2 + xor ebp,edx + xor edx,edi + add ebx,ecx + add eax,DWORD [4+esp] + vpsrld xmm2,xmm0,30 + vmovdqa [48+esp],xmm3 + and ebp,edx + xor edx,edi + shrd ecx,ecx,7 + mov esi,ebx + vpslld xmm0,xmm0,2 + xor ebp,edx + shld ebx,ebx,5 + add eax,ebp + xor esi,ecx + xor ecx,edx + add eax,ebx + add edi,DWORD [8+esp] + and esi,ecx + vpor xmm0,xmm0,xmm2 + xor ecx,edx + shrd ebx,ebx,7 + vmovdqa xmm2,[80+esp] + mov ebp,eax + xor esi,ecx + shld eax,eax,5 + add edi,esi + xor ebp,ebx + xor ebx,ecx + add edi,eax + add edx,DWORD [12+esp] + and ebp,ebx + xor ebx,ecx + shrd eax,eax,7 + mov esi,edi + xor ebp,ebx + shld edi,edi,5 + add edx,ebp + xor esi,eax + xor eax,ebx + add edx,edi + vpalignr xmm3,xmm0,xmm7,8 + vpxor xmm1,xmm1,xmm5 + add ecx,DWORD [16+esp] + and esi,eax + xor eax,ebx + shrd edi,edi,7 + vpxor xmm1,xmm1,xmm2 + vmovdqa [80+esp],xmm5 + mov ebp,edx + xor esi,eax + vmovdqa xmm5,xmm4 + vpaddd xmm4,xmm4,xmm0 + shld edx,edx,5 + add ecx,esi + vpxor xmm1,xmm1,xmm3 + xor ebp,edi + xor edi,eax + add ecx,edx + add ebx,DWORD [20+esp] + vpsrld xmm3,xmm1,30 + vmovdqa [esp],xmm4 + and ebp,edi + xor edi,eax + shrd edx,edx,7 + mov esi,ecx + vpslld xmm1,xmm1,2 + xor ebp,edi + shld ecx,ecx,5 + add ebx,ebp + xor esi,edx + xor edx,edi + add ebx,ecx + add eax,DWORD [24+esp] + and esi,edx + vpor xmm1,xmm1,xmm3 + xor edx,edi + shrd ecx,ecx,7 + vmovdqa xmm3,[96+esp] + mov ebp,ebx + xor esi,edx + shld ebx,ebx,5 + add eax,esi + xor ebp,ecx + xor ecx,edx + add eax,ebx + add edi,DWORD [28+esp] + and ebp,ecx + xor ecx,edx + shrd ebx,ebx,7 + mov esi,eax + xor ebp,ecx + shld eax,eax,5 + add edi,ebp + xor esi,ebx + xor ebx,ecx + add edi,eax + vpalignr xmm4,xmm1,xmm0,8 + vpxor xmm2,xmm2,xmm6 + add edx,DWORD [32+esp] + and esi,ebx + xor ebx,ecx + shrd eax,eax,7 + vpxor xmm2,xmm2,xmm3 + vmovdqa [96+esp],xmm6 + mov ebp,edi + xor esi,ebx + vmovdqa xmm6,xmm5 + vpaddd xmm5,xmm5,xmm1 + shld edi,edi,5 + add edx,esi + vpxor xmm2,xmm2,xmm4 + xor ebp,eax + xor eax,ebx + add edx,edi + add ecx,DWORD [36+esp] + vpsrld xmm4,xmm2,30 + vmovdqa [16+esp],xmm5 + and ebp,eax + xor eax,ebx + shrd edi,edi,7 + mov esi,edx + vpslld xmm2,xmm2,2 + xor ebp,eax + shld edx,edx,5 + add ecx,ebp + xor esi,edi + xor edi,eax + add ecx,edx + add ebx,DWORD [40+esp] + and esi,edi + vpor xmm2,xmm2,xmm4 + xor edi,eax + shrd edx,edx,7 + vmovdqa xmm4,[64+esp] + mov ebp,ecx + xor esi,edi + shld ecx,ecx,5 + add ebx,esi + xor ebp,edx + xor edx,edi + add ebx,ecx + add eax,DWORD [44+esp] + and ebp,edx + xor edx,edi + shrd ecx,ecx,7 + mov esi,ebx + xor ebp,edx + shld ebx,ebx,5 + add eax,ebp + xor esi,edx + add eax,ebx + vpalignr xmm5,xmm2,xmm1,8 + vpxor xmm3,xmm3,xmm7 + add edi,DWORD [48+esp] + xor esi,ecx + mov ebp,eax + shld eax,eax,5 + vpxor xmm3,xmm3,xmm4 + vmovdqa [64+esp],xmm7 + add edi,esi + xor ebp,ecx + vmovdqa xmm7,xmm6 + vpaddd xmm6,xmm6,xmm2 + shrd ebx,ebx,7 + add edi,eax + vpxor xmm3,xmm3,xmm5 + add edx,DWORD [52+esp] + xor ebp,ebx + mov esi,edi + shld edi,edi,5 + vpsrld xmm5,xmm3,30 + vmovdqa [32+esp],xmm6 + add edx,ebp + xor esi,ebx + shrd eax,eax,7 + add edx,edi + vpslld xmm3,xmm3,2 + add ecx,DWORD [56+esp] + xor esi,eax + mov ebp,edx + shld edx,edx,5 + add ecx,esi + xor ebp,eax + shrd edi,edi,7 + add ecx,edx + vpor xmm3,xmm3,xmm5 + add ebx,DWORD [60+esp] + xor ebp,edi + mov esi,ecx + shld ecx,ecx,5 + add ebx,ebp + xor esi,edi + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD [esp] + vpaddd xmm7,xmm7,xmm3 + xor esi,edx + mov ebp,ebx + shld ebx,ebx,5 + add eax,esi + vmovdqa [48+esp],xmm7 + xor ebp,edx + shrd ecx,ecx,7 + add eax,ebx + add edi,DWORD [4+esp] + xor ebp,ecx + mov esi,eax + shld eax,eax,5 + add edi,ebp + xor esi,ecx + shrd ebx,ebx,7 + add edi,eax + add edx,DWORD [8+esp] + xor esi,ebx + mov ebp,edi + shld edi,edi,5 + add edx,esi + xor ebp,ebx + shrd eax,eax,7 + add edx,edi + add ecx,DWORD [12+esp] + xor ebp,eax + mov esi,edx + shld edx,edx,5 + add ecx,ebp + xor esi,eax + shrd edi,edi,7 + add ecx,edx + mov ebp,DWORD [196+esp] + cmp ebp,DWORD [200+esp] + je NEAR L$008done + vmovdqa xmm7,[160+esp] + vmovdqa xmm6,[176+esp] + vmovdqu xmm0,[ebp] + vmovdqu xmm1,[16+ebp] + vmovdqu xmm2,[32+ebp] + vmovdqu xmm3,[48+ebp] + add ebp,64 + vpshufb xmm0,xmm0,xmm6 + mov DWORD [196+esp],ebp + vmovdqa [96+esp],xmm7 + add ebx,DWORD [16+esp] + xor esi,edi + vpshufb xmm1,xmm1,xmm6 + mov ebp,ecx + shld ecx,ecx,5 + vpaddd xmm4,xmm0,xmm7 + add ebx,esi + xor ebp,edi + shrd edx,edx,7 + add ebx,ecx + vmovdqa [esp],xmm4 + add eax,DWORD [20+esp] + xor ebp,edx + mov esi,ebx + shld ebx,ebx,5 + add eax,ebp + xor esi,edx + shrd ecx,ecx,7 + add eax,ebx + add edi,DWORD [24+esp] + xor esi,ecx + mov ebp,eax + shld eax,eax,5 + add edi,esi + xor ebp,ecx + shrd ebx,ebx,7 + add edi,eax + add edx,DWORD [28+esp] + xor ebp,ebx + mov esi,edi + shld edi,edi,5 + add edx,ebp + xor esi,ebx + shrd eax,eax,7 + add edx,edi + add ecx,DWORD [32+esp] + xor esi,eax + vpshufb xmm2,xmm2,xmm6 + mov ebp,edx + shld edx,edx,5 + vpaddd xmm5,xmm1,xmm7 + add ecx,esi + xor ebp,eax + shrd edi,edi,7 + add ecx,edx + vmovdqa [16+esp],xmm5 + add ebx,DWORD [36+esp] + xor ebp,edi + mov esi,ecx + shld ecx,ecx,5 + add ebx,ebp + xor esi,edi + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD [40+esp] + xor esi,edx + mov ebp,ebx + shld ebx,ebx,5 + add eax,esi + xor ebp,edx + shrd ecx,ecx,7 + add eax,ebx + add edi,DWORD [44+esp] + xor ebp,ecx + mov esi,eax + shld eax,eax,5 + add edi,ebp + xor esi,ecx + shrd ebx,ebx,7 + add edi,eax + add edx,DWORD [48+esp] + xor esi,ebx + vpshufb xmm3,xmm3,xmm6 + mov ebp,edi + shld edi,edi,5 + vpaddd xmm6,xmm2,xmm7 + add edx,esi + xor ebp,ebx + shrd eax,eax,7 + add edx,edi + vmovdqa [32+esp],xmm6 + add ecx,DWORD [52+esp] + xor ebp,eax + mov esi,edx + shld edx,edx,5 + add ecx,ebp + xor esi,eax + shrd edi,edi,7 + add ecx,edx + add ebx,DWORD [56+esp] + xor esi,edi + mov ebp,ecx + shld ecx,ecx,5 + add ebx,esi + xor ebp,edi + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD [60+esp] + xor ebp,edx + mov esi,ebx + shld ebx,ebx,5 + add eax,ebp + shrd ecx,ecx,7 + add eax,ebx + mov ebp,DWORD [192+esp] + add eax,DWORD [ebp] + add esi,DWORD [4+ebp] + add ecx,DWORD [8+ebp] + mov DWORD [ebp],eax + add edx,DWORD [12+ebp] + mov DWORD [4+ebp],esi + add edi,DWORD [16+ebp] + mov ebx,ecx + mov DWORD [8+ebp],ecx + xor ebx,edx + mov DWORD [12+ebp],edx + mov DWORD [16+ebp],edi + mov ebp,esi + and esi,ebx + mov ebx,ebp + jmp NEAR L$007loop +align 16 +L$008done: + add ebx,DWORD [16+esp] + xor esi,edi + mov ebp,ecx + shld ecx,ecx,5 + add ebx,esi + xor ebp,edi + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD [20+esp] + xor ebp,edx + mov esi,ebx + shld ebx,ebx,5 + add eax,ebp + xor esi,edx + shrd ecx,ecx,7 + add eax,ebx + add edi,DWORD [24+esp] + xor esi,ecx + mov ebp,eax + shld eax,eax,5 + add edi,esi + xor ebp,ecx + shrd ebx,ebx,7 + add edi,eax + add edx,DWORD [28+esp] + xor ebp,ebx + mov esi,edi + shld edi,edi,5 + add edx,ebp + xor esi,ebx + shrd eax,eax,7 + add edx,edi + add ecx,DWORD [32+esp] + xor esi,eax + mov ebp,edx + shld edx,edx,5 + add ecx,esi + xor ebp,eax + shrd edi,edi,7 + add ecx,edx + add ebx,DWORD [36+esp] + xor ebp,edi + mov esi,ecx + shld ecx,ecx,5 + add ebx,ebp + xor esi,edi + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD [40+esp] + xor esi,edx + mov ebp,ebx + shld ebx,ebx,5 + add eax,esi + xor ebp,edx + shrd ecx,ecx,7 + add eax,ebx + add edi,DWORD [44+esp] + xor ebp,ecx + mov esi,eax + shld eax,eax,5 + add edi,ebp + xor esi,ecx + shrd ebx,ebx,7 + add edi,eax + add edx,DWORD [48+esp] + xor esi,ebx + mov ebp,edi + shld edi,edi,5 + add edx,esi + xor ebp,ebx + shrd eax,eax,7 + add edx,edi + add ecx,DWORD [52+esp] + xor ebp,eax + mov esi,edx + shld edx,edx,5 + add ecx,ebp + xor esi,eax + shrd edi,edi,7 + add ecx,edx + add ebx,DWORD [56+esp] + xor esi,edi + mov ebp,ecx + shld ecx,ecx,5 + add ebx,esi + xor ebp,edi + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD [60+esp] + xor ebp,edx + mov esi,ebx + shld ebx,ebx,5 + add eax,ebp + shrd ecx,ecx,7 + add eax,ebx + vzeroall + mov ebp,DWORD [192+esp] + add eax,DWORD [ebp] + mov esp,DWORD [204+esp] + add esi,DWORD [4+ebp] + add ecx,DWORD [8+ebp] + mov DWORD [ebp],eax + add edx,DWORD [12+ebp] + mov DWORD [4+ebp],esi + add edi,DWORD [16+ebp] + mov DWORD [8+ebp],ecx + mov DWORD [12+ebp],edx + mov DWORD [16+ebp],edi + pop edi + pop esi + pop ebx + pop ebp + ret align 64 L$K_XX_XX: dd 1518500249,1518500249,1518500249,1518500249 diff --git a/win-x86/crypto/sha/sha256-586.asm b/win-x86/crypto/sha/sha256-586.asm index d03558c..3e7cfcc 100644 --- a/win-x86/crypto/sha/sha256-586.asm +++ b/win-x86/crypto/sha/sha256-586.asm @@ -52,12 +52,13 @@ L$000pic_point: or ecx,ebx and ecx,1342177280 cmp ecx,1342177280 + je NEAR L$004AVX test ebx,512 - jnz NEAR L$004SSSE3 + jnz NEAR L$005SSSE3 L$003no_xmm: sub eax,edi cmp eax,256 - jae NEAR L$005unrolled + jae NEAR L$006unrolled jmp NEAR L$002loop align 16 L$002loop: @@ -129,7 +130,7 @@ L$002loop: mov DWORD [28+esp],ecx mov DWORD [32+esp],edi align 16 -L$00600_15: +L$00700_15: mov ecx,edx mov esi,DWORD [24+esp] ror ecx,14 @@ -167,11 +168,11 @@ L$00600_15: add ebp,4 add eax,ebx cmp esi,3248222580 - jne NEAR L$00600_15 + jne NEAR L$00700_15 mov ecx,DWORD [156+esp] - jmp NEAR L$00716_63 + jmp NEAR L$00816_63 align 16 -L$00716_63: +L$00816_63: mov ebx,ecx mov esi,DWORD [104+esp] ror ecx,11 @@ -226,7 +227,7 @@ L$00716_63: add ebp,4 add eax,ebx cmp esi,3329325298 - jne NEAR L$00716_63 + jne NEAR L$00816_63 mov esi,DWORD [356+esp] mov ebx,DWORD [8+esp] mov ecx,DWORD [16+esp] @@ -270,7 +271,7 @@ db 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97 db 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 db 62,0 align 16 -L$005unrolled: +L$006unrolled: lea esp,[esp-96] mov eax,DWORD [esi] mov ebp,DWORD [4+esi] @@ -287,9 +288,9 @@ L$005unrolled: mov DWORD [20+esp],ebx mov DWORD [24+esp],ecx mov DWORD [28+esp],esi - jmp NEAR L$008grand_loop + jmp NEAR L$009grand_loop align 16 -L$008grand_loop: +L$009grand_loop: mov ebx,DWORD [edi] mov ecx,DWORD [4+edi] bswap ebx @@ -3169,7 +3170,7 @@ L$008grand_loop: mov DWORD [24+esp],ebx mov DWORD [28+esp],ecx cmp edi,DWORD [104+esp] - jb NEAR L$008grand_loop + jb NEAR L$009grand_loop mov esp,DWORD [108+esp] pop edi pop esi @@ -3177,7 +3178,7 @@ L$008grand_loop: pop ebp ret align 32 -L$004SSSE3: +L$005SSSE3: lea esp,[esp-96] mov eax,DWORD [esi] mov ebx,DWORD [4+esi] @@ -3196,9 +3197,9 @@ L$004SSSE3: mov DWORD [24+esp],ecx mov DWORD [28+esp],esi movdqa xmm7,[256+ebp] - jmp NEAR L$009grand_ssse3 + jmp NEAR L$010grand_ssse3 align 16 -L$009grand_ssse3: +L$010grand_ssse3: movdqu xmm0,[edi] movdqu xmm1,[16+edi] movdqu xmm2,[32+edi] @@ -3221,9 +3222,9 @@ db 102,15,56,0,223 paddd xmm7,xmm3 movdqa [64+esp],xmm6 movdqa [80+esp],xmm7 - jmp NEAR L$010ssse3_00_47 + jmp NEAR L$011ssse3_00_47 align 16 -L$010ssse3_00_47: +L$011ssse3_00_47: add ebp,64 mov ecx,edx movdqa xmm4,xmm1 @@ -3866,7 +3867,7 @@ db 102,15,58,15,249,4 add eax,ecx movdqa [80+esp],xmm6 cmp DWORD [64+ebp],66051 - jne NEAR L$010ssse3_00_47 + jne NEAR L$011ssse3_00_47 mov ecx,edx ror edx,14 mov esi,DWORD [20+esp] @@ -4380,12 +4381,1193 @@ db 102,15,58,15,249,4 movdqa xmm7,[64+ebp] sub ebp,192 cmp edi,DWORD [104+esp] - jb NEAR L$009grand_ssse3 + jb NEAR L$010grand_ssse3 mov esp,DWORD [108+esp] pop edi pop esi pop ebx pop ebp ret +align 32 +L$004AVX: + lea esp,[esp-96] + vzeroall + mov eax,DWORD [esi] + mov ebx,DWORD [4+esi] + mov ecx,DWORD [8+esi] + mov edi,DWORD [12+esi] + mov DWORD [4+esp],ebx + xor ebx,ecx + mov DWORD [8+esp],ecx + mov DWORD [12+esp],edi + mov edx,DWORD [16+esi] + mov edi,DWORD [20+esi] + mov ecx,DWORD [24+esi] + mov esi,DWORD [28+esi] + mov DWORD [20+esp],edi + mov edi,DWORD [100+esp] + mov DWORD [24+esp],ecx + mov DWORD [28+esp],esi + vmovdqa xmm7,[256+ebp] + jmp NEAR L$012grand_avx +align 32 +L$012grand_avx: + vmovdqu xmm0,[edi] + vmovdqu xmm1,[16+edi] + vmovdqu xmm2,[32+edi] + vmovdqu xmm3,[48+edi] + add edi,64 + vpshufb xmm0,xmm0,xmm7 + mov DWORD [100+esp],edi + vpshufb xmm1,xmm1,xmm7 + vpshufb xmm2,xmm2,xmm7 + vpaddd xmm4,xmm0,[ebp] + vpshufb xmm3,xmm3,xmm7 + vpaddd xmm5,xmm1,[16+ebp] + vpaddd xmm6,xmm2,[32+ebp] + vpaddd xmm7,xmm3,[48+ebp] + vmovdqa [32+esp],xmm4 + vmovdqa [48+esp],xmm5 + vmovdqa [64+esp],xmm6 + vmovdqa [80+esp],xmm7 + jmp NEAR L$013avx_00_47 +align 16 +L$013avx_00_47: + add ebp,64 + vpalignr xmm4,xmm1,xmm0,4 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [20+esp] + vpalignr xmm7,xmm3,xmm2,4 + xor edx,ecx + mov edi,DWORD [24+esp] + xor esi,edi + vpsrld xmm6,xmm4,7 + shrd edx,edx,5 + and esi,ecx + mov DWORD [16+esp],ecx + vpaddd xmm0,xmm0,xmm7 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrld xmm7,xmm4,3 + mov ecx,eax + add edx,edi + mov edi,DWORD [4+esp] + vpslld xmm5,xmm4,14 + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [esp],eax + vpxor xmm4,xmm7,xmm6 + xor ecx,eax + xor eax,edi + add edx,DWORD [28+esp] + vpshufd xmm7,xmm3,250 + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + vpsrld xmm6,xmm6,11 + add edx,DWORD [32+esp] + xor ebx,edi + shrd ecx,ecx,2 + vpxor xmm4,xmm4,xmm5 + add ebx,edx + add edx,DWORD [12+esp] + add ebx,ecx + vpslld xmm5,xmm5,11 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [16+esp] + vpxor xmm4,xmm4,xmm6 + xor edx,ecx + mov edi,DWORD [20+esp] + xor esi,edi + vpsrld xmm6,xmm7,10 + shrd edx,edx,5 + and esi,ecx + mov DWORD [12+esp],ecx + vpxor xmm4,xmm4,xmm5 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrlq xmm5,xmm7,17 + mov ecx,ebx + add edx,edi + mov edi,DWORD [esp] + vpaddd xmm0,xmm0,xmm4 + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [28+esp],ebx + vpxor xmm6,xmm6,xmm5 + xor ecx,ebx + xor ebx,edi + add edx,DWORD [24+esp] + vpsrlq xmm7,xmm7,19 + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + vpxor xmm6,xmm6,xmm7 + add edx,DWORD [36+esp] + xor eax,edi + shrd ecx,ecx,2 + vpshufd xmm7,xmm6,132 + add eax,edx + add edx,DWORD [8+esp] + add eax,ecx + vpsrldq xmm7,xmm7,8 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [12+esp] + vpaddd xmm0,xmm0,xmm7 + xor edx,ecx + mov edi,DWORD [16+esp] + xor esi,edi + vpshufd xmm7,xmm0,80 + shrd edx,edx,5 + and esi,ecx + mov DWORD [8+esp],ecx + vpsrld xmm6,xmm7,10 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrlq xmm5,xmm7,17 + mov ecx,eax + add edx,edi + mov edi,DWORD [28+esp] + vpxor xmm6,xmm6,xmm5 + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [24+esp],eax + vpsrlq xmm7,xmm7,19 + xor ecx,eax + xor eax,edi + add edx,DWORD [20+esp] + vpxor xmm6,xmm6,xmm7 + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + vpshufd xmm7,xmm6,232 + add edx,DWORD [40+esp] + xor ebx,edi + shrd ecx,ecx,2 + vpslldq xmm7,xmm7,8 + add ebx,edx + add edx,DWORD [4+esp] + add ebx,ecx + vpaddd xmm0,xmm0,xmm7 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [8+esp] + vpaddd xmm6,xmm0,[ebp] + xor edx,ecx + mov edi,DWORD [12+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [4+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [24+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [20+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [16+esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [44+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [esp] + add eax,ecx + vmovdqa [32+esp],xmm6 + vpalignr xmm4,xmm2,xmm1,4 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [4+esp] + vpalignr xmm7,xmm0,xmm3,4 + xor edx,ecx + mov edi,DWORD [8+esp] + xor esi,edi + vpsrld xmm6,xmm4,7 + shrd edx,edx,5 + and esi,ecx + mov DWORD [esp],ecx + vpaddd xmm1,xmm1,xmm7 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrld xmm7,xmm4,3 + mov ecx,eax + add edx,edi + mov edi,DWORD [20+esp] + vpslld xmm5,xmm4,14 + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [16+esp],eax + vpxor xmm4,xmm7,xmm6 + xor ecx,eax + xor eax,edi + add edx,DWORD [12+esp] + vpshufd xmm7,xmm0,250 + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + vpsrld xmm6,xmm6,11 + add edx,DWORD [48+esp] + xor ebx,edi + shrd ecx,ecx,2 + vpxor xmm4,xmm4,xmm5 + add ebx,edx + add edx,DWORD [28+esp] + add ebx,ecx + vpslld xmm5,xmm5,11 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [esp] + vpxor xmm4,xmm4,xmm6 + xor edx,ecx + mov edi,DWORD [4+esp] + xor esi,edi + vpsrld xmm6,xmm7,10 + shrd edx,edx,5 + and esi,ecx + mov DWORD [28+esp],ecx + vpxor xmm4,xmm4,xmm5 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrlq xmm5,xmm7,17 + mov ecx,ebx + add edx,edi + mov edi,DWORD [16+esp] + vpaddd xmm1,xmm1,xmm4 + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [12+esp],ebx + vpxor xmm6,xmm6,xmm5 + xor ecx,ebx + xor ebx,edi + add edx,DWORD [8+esp] + vpsrlq xmm7,xmm7,19 + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + vpxor xmm6,xmm6,xmm7 + add edx,DWORD [52+esp] + xor eax,edi + shrd ecx,ecx,2 + vpshufd xmm7,xmm6,132 + add eax,edx + add edx,DWORD [24+esp] + add eax,ecx + vpsrldq xmm7,xmm7,8 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [28+esp] + vpaddd xmm1,xmm1,xmm7 + xor edx,ecx + mov edi,DWORD [esp] + xor esi,edi + vpshufd xmm7,xmm1,80 + shrd edx,edx,5 + and esi,ecx + mov DWORD [24+esp],ecx + vpsrld xmm6,xmm7,10 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrlq xmm5,xmm7,17 + mov ecx,eax + add edx,edi + mov edi,DWORD [12+esp] + vpxor xmm6,xmm6,xmm5 + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [8+esp],eax + vpsrlq xmm7,xmm7,19 + xor ecx,eax + xor eax,edi + add edx,DWORD [4+esp] + vpxor xmm6,xmm6,xmm7 + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + vpshufd xmm7,xmm6,232 + add edx,DWORD [56+esp] + xor ebx,edi + shrd ecx,ecx,2 + vpslldq xmm7,xmm7,8 + add ebx,edx + add edx,DWORD [20+esp] + add ebx,ecx + vpaddd xmm1,xmm1,xmm7 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [24+esp] + vpaddd xmm6,xmm1,[16+ebp] + xor edx,ecx + mov edi,DWORD [28+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [20+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [8+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [4+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [60+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [16+esp] + add eax,ecx + vmovdqa [48+esp],xmm6 + vpalignr xmm4,xmm3,xmm2,4 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [20+esp] + vpalignr xmm7,xmm1,xmm0,4 + xor edx,ecx + mov edi,DWORD [24+esp] + xor esi,edi + vpsrld xmm6,xmm4,7 + shrd edx,edx,5 + and esi,ecx + mov DWORD [16+esp],ecx + vpaddd xmm2,xmm2,xmm7 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrld xmm7,xmm4,3 + mov ecx,eax + add edx,edi + mov edi,DWORD [4+esp] + vpslld xmm5,xmm4,14 + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [esp],eax + vpxor xmm4,xmm7,xmm6 + xor ecx,eax + xor eax,edi + add edx,DWORD [28+esp] + vpshufd xmm7,xmm1,250 + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + vpsrld xmm6,xmm6,11 + add edx,DWORD [64+esp] + xor ebx,edi + shrd ecx,ecx,2 + vpxor xmm4,xmm4,xmm5 + add ebx,edx + add edx,DWORD [12+esp] + add ebx,ecx + vpslld xmm5,xmm5,11 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [16+esp] + vpxor xmm4,xmm4,xmm6 + xor edx,ecx + mov edi,DWORD [20+esp] + xor esi,edi + vpsrld xmm6,xmm7,10 + shrd edx,edx,5 + and esi,ecx + mov DWORD [12+esp],ecx + vpxor xmm4,xmm4,xmm5 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrlq xmm5,xmm7,17 + mov ecx,ebx + add edx,edi + mov edi,DWORD [esp] + vpaddd xmm2,xmm2,xmm4 + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [28+esp],ebx + vpxor xmm6,xmm6,xmm5 + xor ecx,ebx + xor ebx,edi + add edx,DWORD [24+esp] + vpsrlq xmm7,xmm7,19 + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + vpxor xmm6,xmm6,xmm7 + add edx,DWORD [68+esp] + xor eax,edi + shrd ecx,ecx,2 + vpshufd xmm7,xmm6,132 + add eax,edx + add edx,DWORD [8+esp] + add eax,ecx + vpsrldq xmm7,xmm7,8 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [12+esp] + vpaddd xmm2,xmm2,xmm7 + xor edx,ecx + mov edi,DWORD [16+esp] + xor esi,edi + vpshufd xmm7,xmm2,80 + shrd edx,edx,5 + and esi,ecx + mov DWORD [8+esp],ecx + vpsrld xmm6,xmm7,10 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrlq xmm5,xmm7,17 + mov ecx,eax + add edx,edi + mov edi,DWORD [28+esp] + vpxor xmm6,xmm6,xmm5 + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [24+esp],eax + vpsrlq xmm7,xmm7,19 + xor ecx,eax + xor eax,edi + add edx,DWORD [20+esp] + vpxor xmm6,xmm6,xmm7 + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + vpshufd xmm7,xmm6,232 + add edx,DWORD [72+esp] + xor ebx,edi + shrd ecx,ecx,2 + vpslldq xmm7,xmm7,8 + add ebx,edx + add edx,DWORD [4+esp] + add ebx,ecx + vpaddd xmm2,xmm2,xmm7 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [8+esp] + vpaddd xmm6,xmm2,[32+ebp] + xor edx,ecx + mov edi,DWORD [12+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [4+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [24+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [20+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [16+esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [76+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [esp] + add eax,ecx + vmovdqa [64+esp],xmm6 + vpalignr xmm4,xmm0,xmm3,4 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [4+esp] + vpalignr xmm7,xmm2,xmm1,4 + xor edx,ecx + mov edi,DWORD [8+esp] + xor esi,edi + vpsrld xmm6,xmm4,7 + shrd edx,edx,5 + and esi,ecx + mov DWORD [esp],ecx + vpaddd xmm3,xmm3,xmm7 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrld xmm7,xmm4,3 + mov ecx,eax + add edx,edi + mov edi,DWORD [20+esp] + vpslld xmm5,xmm4,14 + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [16+esp],eax + vpxor xmm4,xmm7,xmm6 + xor ecx,eax + xor eax,edi + add edx,DWORD [12+esp] + vpshufd xmm7,xmm2,250 + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + vpsrld xmm6,xmm6,11 + add edx,DWORD [80+esp] + xor ebx,edi + shrd ecx,ecx,2 + vpxor xmm4,xmm4,xmm5 + add ebx,edx + add edx,DWORD [28+esp] + add ebx,ecx + vpslld xmm5,xmm5,11 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [esp] + vpxor xmm4,xmm4,xmm6 + xor edx,ecx + mov edi,DWORD [4+esp] + xor esi,edi + vpsrld xmm6,xmm7,10 + shrd edx,edx,5 + and esi,ecx + mov DWORD [28+esp],ecx + vpxor xmm4,xmm4,xmm5 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrlq xmm5,xmm7,17 + mov ecx,ebx + add edx,edi + mov edi,DWORD [16+esp] + vpaddd xmm3,xmm3,xmm4 + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [12+esp],ebx + vpxor xmm6,xmm6,xmm5 + xor ecx,ebx + xor ebx,edi + add edx,DWORD [8+esp] + vpsrlq xmm7,xmm7,19 + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + vpxor xmm6,xmm6,xmm7 + add edx,DWORD [84+esp] + xor eax,edi + shrd ecx,ecx,2 + vpshufd xmm7,xmm6,132 + add eax,edx + add edx,DWORD [24+esp] + add eax,ecx + vpsrldq xmm7,xmm7,8 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [28+esp] + vpaddd xmm3,xmm3,xmm7 + xor edx,ecx + mov edi,DWORD [esp] + xor esi,edi + vpshufd xmm7,xmm3,80 + shrd edx,edx,5 + and esi,ecx + mov DWORD [24+esp],ecx + vpsrld xmm6,xmm7,10 + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + vpsrlq xmm5,xmm7,17 + mov ecx,eax + add edx,edi + mov edi,DWORD [12+esp] + vpxor xmm6,xmm6,xmm5 + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [8+esp],eax + vpsrlq xmm7,xmm7,19 + xor ecx,eax + xor eax,edi + add edx,DWORD [4+esp] + vpxor xmm6,xmm6,xmm7 + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + vpshufd xmm7,xmm6,232 + add edx,DWORD [88+esp] + xor ebx,edi + shrd ecx,ecx,2 + vpslldq xmm7,xmm7,8 + add ebx,edx + add edx,DWORD [20+esp] + add ebx,ecx + vpaddd xmm3,xmm3,xmm7 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [24+esp] + vpaddd xmm6,xmm3,[48+ebp] + xor edx,ecx + mov edi,DWORD [28+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [20+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [8+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [4+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [92+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [16+esp] + add eax,ecx + vmovdqa [80+esp],xmm6 + cmp DWORD [64+ebp],66051 + jne NEAR L$013avx_00_47 + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [20+esp] + xor edx,ecx + mov edi,DWORD [24+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [16+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,eax + add edx,edi + mov edi,DWORD [4+esp] + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [esp],eax + xor ecx,eax + xor eax,edi + add edx,DWORD [28+esp] + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + add edx,DWORD [32+esp] + xor ebx,edi + shrd ecx,ecx,2 + add ebx,edx + add edx,DWORD [12+esp] + add ebx,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [16+esp] + xor edx,ecx + mov edi,DWORD [20+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [12+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [28+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [24+esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [36+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [8+esp] + add eax,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [12+esp] + xor edx,ecx + mov edi,DWORD [16+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [8+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,eax + add edx,edi + mov edi,DWORD [28+esp] + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [24+esp],eax + xor ecx,eax + xor eax,edi + add edx,DWORD [20+esp] + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + add edx,DWORD [40+esp] + xor ebx,edi + shrd ecx,ecx,2 + add ebx,edx + add edx,DWORD [4+esp] + add ebx,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [8+esp] + xor edx,ecx + mov edi,DWORD [12+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [4+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [24+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [20+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [16+esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [44+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [esp] + add eax,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [4+esp] + xor edx,ecx + mov edi,DWORD [8+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,eax + add edx,edi + mov edi,DWORD [20+esp] + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [16+esp],eax + xor ecx,eax + xor eax,edi + add edx,DWORD [12+esp] + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + add edx,DWORD [48+esp] + xor ebx,edi + shrd ecx,ecx,2 + add ebx,edx + add edx,DWORD [28+esp] + add ebx,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [esp] + xor edx,ecx + mov edi,DWORD [4+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [28+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [16+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [12+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [8+esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [52+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [24+esp] + add eax,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [28+esp] + xor edx,ecx + mov edi,DWORD [esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [24+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,eax + add edx,edi + mov edi,DWORD [12+esp] + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [8+esp],eax + xor ecx,eax + xor eax,edi + add edx,DWORD [4+esp] + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + add edx,DWORD [56+esp] + xor ebx,edi + shrd ecx,ecx,2 + add ebx,edx + add edx,DWORD [20+esp] + add ebx,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [24+esp] + xor edx,ecx + mov edi,DWORD [28+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [20+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [8+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [4+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [60+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [16+esp] + add eax,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [20+esp] + xor edx,ecx + mov edi,DWORD [24+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [16+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,eax + add edx,edi + mov edi,DWORD [4+esp] + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [esp],eax + xor ecx,eax + xor eax,edi + add edx,DWORD [28+esp] + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + add edx,DWORD [64+esp] + xor ebx,edi + shrd ecx,ecx,2 + add ebx,edx + add edx,DWORD [12+esp] + add ebx,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [16+esp] + xor edx,ecx + mov edi,DWORD [20+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [12+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [28+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [24+esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [68+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [8+esp] + add eax,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [12+esp] + xor edx,ecx + mov edi,DWORD [16+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [8+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,eax + add edx,edi + mov edi,DWORD [28+esp] + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [24+esp],eax + xor ecx,eax + xor eax,edi + add edx,DWORD [20+esp] + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + add edx,DWORD [72+esp] + xor ebx,edi + shrd ecx,ecx,2 + add ebx,edx + add edx,DWORD [4+esp] + add ebx,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [8+esp] + xor edx,ecx + mov edi,DWORD [12+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [4+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [24+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [20+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [16+esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [76+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [esp] + add eax,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [4+esp] + xor edx,ecx + mov edi,DWORD [8+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,eax + add edx,edi + mov edi,DWORD [20+esp] + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [16+esp],eax + xor ecx,eax + xor eax,edi + add edx,DWORD [12+esp] + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + add edx,DWORD [80+esp] + xor ebx,edi + shrd ecx,ecx,2 + add ebx,edx + add edx,DWORD [28+esp] + add ebx,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [esp] + xor edx,ecx + mov edi,DWORD [4+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [28+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [16+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [12+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [8+esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [84+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [24+esp] + add eax,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [28+esp] + xor edx,ecx + mov edi,DWORD [esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [24+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,eax + add edx,edi + mov edi,DWORD [12+esp] + mov esi,eax + shrd ecx,ecx,9 + mov DWORD [8+esp],eax + xor ecx,eax + xor eax,edi + add edx,DWORD [4+esp] + shrd ecx,ecx,11 + and ebx,eax + xor ecx,esi + add edx,DWORD [88+esp] + xor ebx,edi + shrd ecx,ecx,2 + add ebx,edx + add edx,DWORD [20+esp] + add ebx,ecx + mov ecx,edx + shrd edx,edx,14 + mov esi,DWORD [24+esp] + xor edx,ecx + mov edi,DWORD [28+esp] + xor esi,edi + shrd edx,edx,5 + and esi,ecx + mov DWORD [20+esp],ecx + xor edx,ecx + xor edi,esi + shrd edx,edx,6 + mov ecx,ebx + add edx,edi + mov edi,DWORD [8+esp] + mov esi,ebx + shrd ecx,ecx,9 + mov DWORD [4+esp],ebx + xor ecx,ebx + xor ebx,edi + add edx,DWORD [esp] + shrd ecx,ecx,11 + and eax,ebx + xor ecx,esi + add edx,DWORD [92+esp] + xor eax,edi + shrd ecx,ecx,2 + add eax,edx + add edx,DWORD [16+esp] + add eax,ecx + mov esi,DWORD [96+esp] + xor ebx,edi + mov ecx,DWORD [12+esp] + add eax,DWORD [esi] + add ebx,DWORD [4+esi] + add edi,DWORD [8+esi] + add ecx,DWORD [12+esi] + mov DWORD [esi],eax + mov DWORD [4+esi],ebx + mov DWORD [8+esi],edi + mov DWORD [12+esi],ecx + mov DWORD [4+esp],ebx + xor ebx,edi + mov DWORD [8+esp],edi + mov DWORD [12+esp],ecx + mov edi,DWORD [20+esp] + mov ecx,DWORD [24+esp] + add edx,DWORD [16+esi] + add edi,DWORD [20+esi] + add ecx,DWORD [24+esi] + mov DWORD [16+esi],edx + mov DWORD [20+esi],edi + mov DWORD [20+esp],edi + mov edi,DWORD [28+esp] + mov DWORD [24+esi],ecx + add edi,DWORD [28+esi] + mov DWORD [24+esp],ecx + mov DWORD [28+esi],edi + mov DWORD [28+esp],edi + mov edi,DWORD [100+esp] + vmovdqa xmm7,[64+ebp] + sub ebp,192 + cmp edi,DWORD [104+esp] + jb NEAR L$012grand_avx + mov esp,DWORD [108+esp] + vzeroall + pop edi + pop esi + pop ebx + pop ebp + ret segment .bss common _OPENSSL_ia32cap_P 16 diff --git a/win-x86_64/crypto/bn/x86_64-mont5.asm b/win-x86_64/crypto/bn/x86_64-mont5.asm index 284318a..560b384 100644 --- a/win-x86_64/crypto/bn/x86_64-mont5.asm +++ b/win-x86_64/crypto/bn/x86_64-mont5.asm @@ -1616,6 +1616,15 @@ $L$8x_tail: ALIGN 32 $L$8x_tail_done: add r8,QWORD[rdx] + adc r9,0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + adc r14,0 + adc r15,0 + + xor rax,rax neg rsi diff --git a/win-x86_64/crypto/ec/p256-x86_64-asm.asm b/win-x86_64/crypto/ec/p256-x86_64-asm.asm index c9789f5..45ba686 100644 --- a/win-x86_64/crypto/ec/p256-x86_64-asm.asm +++ b/win-x86_64/crypto/ec/p256-x86_64-asm.asm @@ -11,10 +11,6 @@ ALIGN 64 $L$poly: DQ 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 - -$L$RR: - DQ 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd - $L$One: DD 1,1,1,1,1,1,1,1 $L$Two: @@ -24,7 +20,6 @@ $L$Three: $L$ONE_mont: DQ 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe -global ecp_nistz256_mul_by_2 ALIGN 64 ecp_nistz256_mul_by_2: @@ -78,266 +73,6 @@ $L$SEH_end_ecp_nistz256_mul_by_2: -global ecp_nistz256_div_by_2 - -ALIGN 32 -ecp_nistz256_div_by_2: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_div_by_2: - mov rdi,rcx - mov rsi,rdx - - - push r12 - push r13 - - mov r8,QWORD[rsi] - mov r9,QWORD[8+rsi] - mov r10,QWORD[16+rsi] - mov rax,r8 - mov r11,QWORD[24+rsi] - lea rsi,[$L$poly] - - mov rdx,r9 - xor r13,r13 - add r8,QWORD[rsi] - mov rcx,r10 - adc r9,QWORD[8+rsi] - adc r10,QWORD[16+rsi] - mov r12,r11 - adc r11,QWORD[24+rsi] - adc r13,0 - xor rsi,rsi - test rax,1 - - cmovz r8,rax - cmovz r9,rdx - cmovz r10,rcx - cmovz r11,r12 - cmovz r13,rsi - - mov rax,r9 - shr r8,1 - shl rax,63 - mov rdx,r10 - shr r9,1 - or r8,rax - shl rdx,63 - mov rcx,r11 - shr r10,1 - or r9,rdx - shl rcx,63 - shr r11,1 - shl r13,63 - or r10,rcx - or r11,r13 - - mov QWORD[rdi],r8 - mov QWORD[8+rdi],r9 - mov QWORD[16+rdi],r10 - mov QWORD[24+rdi],r11 - - pop r13 - pop r12 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret -$L$SEH_end_ecp_nistz256_div_by_2: - - - -global ecp_nistz256_mul_by_3 - -ALIGN 32 -ecp_nistz256_mul_by_3: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_mul_by_3: - mov rdi,rcx - mov rsi,rdx - - - push r12 - push r13 - - mov r8,QWORD[rsi] - xor r13,r13 - mov r9,QWORD[8+rsi] - add r8,r8 - mov r10,QWORD[16+rsi] - adc r9,r9 - mov r11,QWORD[24+rsi] - mov rax,r8 - adc r10,r10 - adc r11,r11 - mov rdx,r9 - adc r13,0 - - sub r8,-1 - mov rcx,r10 - sbb r9,QWORD[(($L$poly+8))] - sbb r10,0 - mov r12,r11 - sbb r11,QWORD[(($L$poly+24))] - test r13,r13 - - cmovz r8,rax - cmovz r9,rdx - cmovz r10,rcx - cmovz r11,r12 - - xor r13,r13 - add r8,QWORD[rsi] - adc r9,QWORD[8+rsi] - mov rax,r8 - adc r10,QWORD[16+rsi] - adc r11,QWORD[24+rsi] - mov rdx,r9 - adc r13,0 - - sub r8,-1 - mov rcx,r10 - sbb r9,QWORD[(($L$poly+8))] - sbb r10,0 - mov r12,r11 - sbb r11,QWORD[(($L$poly+24))] - test r13,r13 - - cmovz r8,rax - cmovz r9,rdx - mov QWORD[rdi],r8 - cmovz r10,rcx - mov QWORD[8+rdi],r9 - cmovz r11,r12 - mov QWORD[16+rdi],r10 - mov QWORD[24+rdi],r11 - - pop r13 - pop r12 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret -$L$SEH_end_ecp_nistz256_mul_by_3: - - - -global ecp_nistz256_add - -ALIGN 32 -ecp_nistz256_add: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_add: - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - - - push r12 - push r13 - - mov r8,QWORD[rsi] - xor r13,r13 - mov r9,QWORD[8+rsi] - mov r10,QWORD[16+rsi] - mov r11,QWORD[24+rsi] - lea rsi,[$L$poly] - - add r8,QWORD[rdx] - adc r9,QWORD[8+rdx] - mov rax,r8 - adc r10,QWORD[16+rdx] - adc r11,QWORD[24+rdx] - mov rdx,r9 - adc r13,0 - - sub r8,QWORD[rsi] - mov rcx,r10 - sbb r9,QWORD[8+rsi] - sbb r10,QWORD[16+rsi] - mov r12,r11 - sbb r11,QWORD[24+rsi] - test r13,r13 - - cmovz r8,rax - cmovz r9,rdx - mov QWORD[rdi],r8 - cmovz r10,rcx - mov QWORD[8+rdi],r9 - cmovz r11,r12 - mov QWORD[16+rdi],r10 - mov QWORD[24+rdi],r11 - - pop r13 - pop r12 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret -$L$SEH_end_ecp_nistz256_add: - - - -global ecp_nistz256_sub - -ALIGN 32 -ecp_nistz256_sub: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_sub: - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - - - push r12 - push r13 - - mov r8,QWORD[rsi] - xor r13,r13 - mov r9,QWORD[8+rsi] - mov r10,QWORD[16+rsi] - mov r11,QWORD[24+rsi] - lea rsi,[$L$poly] - - sub r8,QWORD[rdx] - sbb r9,QWORD[8+rdx] - mov rax,r8 - sbb r10,QWORD[16+rdx] - sbb r11,QWORD[24+rdx] - mov rdx,r9 - sbb r13,0 - - add r8,QWORD[rsi] - mov rcx,r10 - adc r9,QWORD[8+rsi] - adc r10,QWORD[16+rsi] - mov r12,r11 - adc r11,QWORD[24+rsi] - test r13,r13 - - cmovz r8,rax - cmovz r9,rdx - mov QWORD[rdi],r8 - cmovz r10,rcx - mov QWORD[8+rdi],r9 - cmovz r11,r12 - mov QWORD[16+rdi],r10 - mov QWORD[24+rdi],r11 - - pop r13 - pop r12 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret -$L$SEH_end_ecp_nistz256_sub: - - - global ecp_nistz256_neg ALIGN 32 @@ -395,26 +130,6 @@ $L$SEH_end_ecp_nistz256_neg: -global ecp_nistz256_to_mont - -ALIGN 32 -ecp_nistz256_to_mont: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_to_mont: - mov rdi,rcx - mov rsi,rdx - - - lea rdx,[$L$RR] - jmp NEAR $L$mul_mont -$L$SEH_end_ecp_nistz256_to_mont: - - - - - global ecp_nistz256_mul_mont diff --git a/win-x86_64/crypto/rc4/rc4-md5-x86_64.asm b/win-x86_64/crypto/rc4/rc4-md5-x86_64.asm deleted file mode 100644 index f1ea965..0000000 --- a/win-x86_64/crypto/rc4/rc4-md5-x86_64.asm +++ /dev/null @@ -1,1372 +0,0 @@ -default rel -%define XMMWORD -%define YMMWORD -%define ZMMWORD -section .text code align=64 - -ALIGN 16 - -global rc4_md5_enc - -rc4_md5_enc: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_rc4_md5_enc: - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - mov rcx,r9 - mov r8,QWORD[40+rsp] - mov r9,QWORD[48+rsp] - - - cmp r9,0 - je NEAR $L$abort - push rbx - push rbp - push r12 - push r13 - push r14 - push r15 - sub rsp,40 -$L$body: - mov r11,rcx - mov r12,r9 - mov r13,rsi - mov r14,rdx - mov r15,r8 - xor rbp,rbp - xor rcx,rcx - - lea rdi,[8+rdi] - mov bpl,BYTE[((-8))+rdi] - mov cl,BYTE[((-4))+rdi] - - inc bpl - sub r14,r13 - mov eax,DWORD[rbp*4+rdi] - add cl,al - lea rsi,[rbp*4+rdi] - shl r12,6 - add r12,r15 - mov QWORD[16+rsp],r12 - - mov QWORD[24+rsp],r11 - mov r8d,DWORD[r11] - mov r9d,DWORD[4+r11] - mov r10d,DWORD[8+r11] - mov r11d,DWORD[12+r11] - jmp NEAR $L$oop - -ALIGN 16 -$L$oop: - mov DWORD[rsp],r8d - mov DWORD[4+rsp],r9d - mov DWORD[8+rsp],r10d - mov r12d,r11d - mov DWORD[12+rsp],r11d - pxor xmm0,xmm0 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],eax - and r12d,r9d - add r8d,DWORD[r15] - add al,dl - mov ebx,DWORD[4+rsi] - add r8d,3614090360 - xor r12d,r11d - movzx eax,al - mov DWORD[rsi],edx - add r8d,r12d - add cl,bl - rol r8d,7 - mov r12d,r10d - movd xmm0,DWORD[rax*4+rdi] - - add r8d,r9d - pxor xmm1,xmm1 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],ebx - and r12d,r8d - add r11d,DWORD[4+r15] - add bl,dl - mov eax,DWORD[8+rsi] - add r11d,3905402710 - xor r12d,r10d - movzx ebx,bl - mov DWORD[4+rsi],edx - add r11d,r12d - add cl,al - rol r11d,12 - mov r12d,r9d - movd xmm1,DWORD[rbx*4+rdi] - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],eax - and r12d,r11d - add r10d,DWORD[8+r15] - add al,dl - mov ebx,DWORD[12+rsi] - add r10d,606105819 - xor r12d,r9d - movzx eax,al - mov DWORD[8+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,17 - mov r12d,r8d - pinsrw xmm0,WORD[rax*4+rdi],1 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],ebx - and r12d,r10d - add r9d,DWORD[12+r15] - add bl,dl - mov eax,DWORD[16+rsi] - add r9d,3250441966 - xor r12d,r8d - movzx ebx,bl - mov DWORD[12+rsi],edx - add r9d,r12d - add cl,al - rol r9d,22 - mov r12d,r11d - pinsrw xmm1,WORD[rbx*4+rdi],1 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],eax - and r12d,r9d - add r8d,DWORD[16+r15] - add al,dl - mov ebx,DWORD[20+rsi] - add r8d,4118548399 - xor r12d,r11d - movzx eax,al - mov DWORD[16+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,7 - mov r12d,r10d - pinsrw xmm0,WORD[rax*4+rdi],2 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],ebx - and r12d,r8d - add r11d,DWORD[20+r15] - add bl,dl - mov eax,DWORD[24+rsi] - add r11d,1200080426 - xor r12d,r10d - movzx ebx,bl - mov DWORD[20+rsi],edx - add r11d,r12d - add cl,al - rol r11d,12 - mov r12d,r9d - pinsrw xmm1,WORD[rbx*4+rdi],2 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],eax - and r12d,r11d - add r10d,DWORD[24+r15] - add al,dl - mov ebx,DWORD[28+rsi] - add r10d,2821735955 - xor r12d,r9d - movzx eax,al - mov DWORD[24+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,17 - mov r12d,r8d - pinsrw xmm0,WORD[rax*4+rdi],3 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],ebx - and r12d,r10d - add r9d,DWORD[28+r15] - add bl,dl - mov eax,DWORD[32+rsi] - add r9d,4249261313 - xor r12d,r8d - movzx ebx,bl - mov DWORD[28+rsi],edx - add r9d,r12d - add cl,al - rol r9d,22 - mov r12d,r11d - pinsrw xmm1,WORD[rbx*4+rdi],3 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],eax - and r12d,r9d - add r8d,DWORD[32+r15] - add al,dl - mov ebx,DWORD[36+rsi] - add r8d,1770035416 - xor r12d,r11d - movzx eax,al - mov DWORD[32+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,7 - mov r12d,r10d - pinsrw xmm0,WORD[rax*4+rdi],4 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],ebx - and r12d,r8d - add r11d,DWORD[36+r15] - add bl,dl - mov eax,DWORD[40+rsi] - add r11d,2336552879 - xor r12d,r10d - movzx ebx,bl - mov DWORD[36+rsi],edx - add r11d,r12d - add cl,al - rol r11d,12 - mov r12d,r9d - pinsrw xmm1,WORD[rbx*4+rdi],4 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],eax - and r12d,r11d - add r10d,DWORD[40+r15] - add al,dl - mov ebx,DWORD[44+rsi] - add r10d,4294925233 - xor r12d,r9d - movzx eax,al - mov DWORD[40+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,17 - mov r12d,r8d - pinsrw xmm0,WORD[rax*4+rdi],5 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],ebx - and r12d,r10d - add r9d,DWORD[44+r15] - add bl,dl - mov eax,DWORD[48+rsi] - add r9d,2304563134 - xor r12d,r8d - movzx ebx,bl - mov DWORD[44+rsi],edx - add r9d,r12d - add cl,al - rol r9d,22 - mov r12d,r11d - pinsrw xmm1,WORD[rbx*4+rdi],5 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],eax - and r12d,r9d - add r8d,DWORD[48+r15] - add al,dl - mov ebx,DWORD[52+rsi] - add r8d,1804603682 - xor r12d,r11d - movzx eax,al - mov DWORD[48+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,7 - mov r12d,r10d - pinsrw xmm0,WORD[rax*4+rdi],6 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],ebx - and r12d,r8d - add r11d,DWORD[52+r15] - add bl,dl - mov eax,DWORD[56+rsi] - add r11d,4254626195 - xor r12d,r10d - movzx ebx,bl - mov DWORD[52+rsi],edx - add r11d,r12d - add cl,al - rol r11d,12 - mov r12d,r9d - pinsrw xmm1,WORD[rbx*4+rdi],6 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],eax - and r12d,r11d - add r10d,DWORD[56+r15] - add al,dl - mov ebx,DWORD[60+rsi] - add r10d,2792965006 - xor r12d,r9d - movzx eax,al - mov DWORD[56+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,17 - mov r12d,r8d - pinsrw xmm0,WORD[rax*4+rdi],7 - - add r10d,r11d - movdqu xmm2,XMMWORD[r13] - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],ebx - and r12d,r10d - add r9d,DWORD[60+r15] - add bl,dl - mov eax,DWORD[64+rsi] - add r9d,1236535329 - xor r12d,r8d - movzx ebx,bl - mov DWORD[60+rsi],edx - add r9d,r12d - add cl,al - rol r9d,22 - mov r12d,r10d - pinsrw xmm1,WORD[rbx*4+rdi],7 - - add r9d,r10d - psllq xmm1,8 - pxor xmm2,xmm0 - pxor xmm2,xmm1 - pxor xmm0,xmm0 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],eax - and r12d,r11d - add r8d,DWORD[4+r15] - add al,dl - mov ebx,DWORD[68+rsi] - add r8d,4129170786 - xor r12d,r10d - movzx eax,al - mov DWORD[64+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,5 - mov r12d,r9d - movd xmm0,DWORD[rax*4+rdi] - - add r8d,r9d - pxor xmm1,xmm1 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],ebx - and r12d,r10d - add r11d,DWORD[24+r15] - add bl,dl - mov eax,DWORD[72+rsi] - add r11d,3225465664 - xor r12d,r9d - movzx ebx,bl - mov DWORD[68+rsi],edx - add r11d,r12d - add cl,al - rol r11d,9 - mov r12d,r8d - movd xmm1,DWORD[rbx*4+rdi] - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],eax - and r12d,r9d - add r10d,DWORD[44+r15] - add al,dl - mov ebx,DWORD[76+rsi] - add r10d,643717713 - xor r12d,r8d - movzx eax,al - mov DWORD[72+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,14 - mov r12d,r11d - pinsrw xmm0,WORD[rax*4+rdi],1 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],ebx - and r12d,r8d - add r9d,DWORD[r15] - add bl,dl - mov eax,DWORD[80+rsi] - add r9d,3921069994 - xor r12d,r11d - movzx ebx,bl - mov DWORD[76+rsi],edx - add r9d,r12d - add cl,al - rol r9d,20 - mov r12d,r10d - pinsrw xmm1,WORD[rbx*4+rdi],1 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],eax - and r12d,r11d - add r8d,DWORD[20+r15] - add al,dl - mov ebx,DWORD[84+rsi] - add r8d,3593408605 - xor r12d,r10d - movzx eax,al - mov DWORD[80+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,5 - mov r12d,r9d - pinsrw xmm0,WORD[rax*4+rdi],2 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],ebx - and r12d,r10d - add r11d,DWORD[40+r15] - add bl,dl - mov eax,DWORD[88+rsi] - add r11d,38016083 - xor r12d,r9d - movzx ebx,bl - mov DWORD[84+rsi],edx - add r11d,r12d - add cl,al - rol r11d,9 - mov r12d,r8d - pinsrw xmm1,WORD[rbx*4+rdi],2 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],eax - and r12d,r9d - add r10d,DWORD[60+r15] - add al,dl - mov ebx,DWORD[92+rsi] - add r10d,3634488961 - xor r12d,r8d - movzx eax,al - mov DWORD[88+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,14 - mov r12d,r11d - pinsrw xmm0,WORD[rax*4+rdi],3 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],ebx - and r12d,r8d - add r9d,DWORD[16+r15] - add bl,dl - mov eax,DWORD[96+rsi] - add r9d,3889429448 - xor r12d,r11d - movzx ebx,bl - mov DWORD[92+rsi],edx - add r9d,r12d - add cl,al - rol r9d,20 - mov r12d,r10d - pinsrw xmm1,WORD[rbx*4+rdi],3 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],eax - and r12d,r11d - add r8d,DWORD[36+r15] - add al,dl - mov ebx,DWORD[100+rsi] - add r8d,568446438 - xor r12d,r10d - movzx eax,al - mov DWORD[96+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,5 - mov r12d,r9d - pinsrw xmm0,WORD[rax*4+rdi],4 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],ebx - and r12d,r10d - add r11d,DWORD[56+r15] - add bl,dl - mov eax,DWORD[104+rsi] - add r11d,3275163606 - xor r12d,r9d - movzx ebx,bl - mov DWORD[100+rsi],edx - add r11d,r12d - add cl,al - rol r11d,9 - mov r12d,r8d - pinsrw xmm1,WORD[rbx*4+rdi],4 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],eax - and r12d,r9d - add r10d,DWORD[12+r15] - add al,dl - mov ebx,DWORD[108+rsi] - add r10d,4107603335 - xor r12d,r8d - movzx eax,al - mov DWORD[104+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,14 - mov r12d,r11d - pinsrw xmm0,WORD[rax*4+rdi],5 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],ebx - and r12d,r8d - add r9d,DWORD[32+r15] - add bl,dl - mov eax,DWORD[112+rsi] - add r9d,1163531501 - xor r12d,r11d - movzx ebx,bl - mov DWORD[108+rsi],edx - add r9d,r12d - add cl,al - rol r9d,20 - mov r12d,r10d - pinsrw xmm1,WORD[rbx*4+rdi],5 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],eax - and r12d,r11d - add r8d,DWORD[52+r15] - add al,dl - mov ebx,DWORD[116+rsi] - add r8d,2850285829 - xor r12d,r10d - movzx eax,al - mov DWORD[112+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,5 - mov r12d,r9d - pinsrw xmm0,WORD[rax*4+rdi],6 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],ebx - and r12d,r10d - add r11d,DWORD[8+r15] - add bl,dl - mov eax,DWORD[120+rsi] - add r11d,4243563512 - xor r12d,r9d - movzx ebx,bl - mov DWORD[116+rsi],edx - add r11d,r12d - add cl,al - rol r11d,9 - mov r12d,r8d - pinsrw xmm1,WORD[rbx*4+rdi],6 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],eax - and r12d,r9d - add r10d,DWORD[28+r15] - add al,dl - mov ebx,DWORD[124+rsi] - add r10d,1735328473 - xor r12d,r8d - movzx eax,al - mov DWORD[120+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,14 - mov r12d,r11d - pinsrw xmm0,WORD[rax*4+rdi],7 - - add r10d,r11d - movdqu xmm3,XMMWORD[16+r13] - add bpl,32 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],ebx - and r12d,r8d - add r9d,DWORD[48+r15] - add bl,dl - mov eax,DWORD[rbp*4+rdi] - add r9d,2368359562 - xor r12d,r11d - movzx ebx,bl - mov DWORD[124+rsi],edx - add r9d,r12d - add cl,al - rol r9d,20 - mov r12d,r11d - pinsrw xmm1,WORD[rbx*4+rdi],7 - - add r9d,r10d - mov rsi,rcx - xor rcx,rcx - mov cl,sil - lea rsi,[rbp*4+rdi] - psllq xmm1,8 - pxor xmm3,xmm0 - pxor xmm3,xmm1 - pxor xmm0,xmm0 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],eax - xor r12d,r9d - add r8d,DWORD[20+r15] - add al,dl - mov ebx,DWORD[4+rsi] - add r8d,4294588738 - movzx eax,al - add r8d,r12d - mov DWORD[rsi],edx - add cl,bl - rol r8d,4 - mov r12d,r10d - movd xmm0,DWORD[rax*4+rdi] - - add r8d,r9d - pxor xmm1,xmm1 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],ebx - xor r12d,r8d - add r11d,DWORD[32+r15] - add bl,dl - mov eax,DWORD[8+rsi] - add r11d,2272392833 - movzx ebx,bl - add r11d,r12d - mov DWORD[4+rsi],edx - add cl,al - rol r11d,11 - mov r12d,r9d - movd xmm1,DWORD[rbx*4+rdi] - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],eax - xor r12d,r11d - add r10d,DWORD[44+r15] - add al,dl - mov ebx,DWORD[12+rsi] - add r10d,1839030562 - movzx eax,al - add r10d,r12d - mov DWORD[8+rsi],edx - add cl,bl - rol r10d,16 - mov r12d,r8d - pinsrw xmm0,WORD[rax*4+rdi],1 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],ebx - xor r12d,r10d - add r9d,DWORD[56+r15] - add bl,dl - mov eax,DWORD[16+rsi] - add r9d,4259657740 - movzx ebx,bl - add r9d,r12d - mov DWORD[12+rsi],edx - add cl,al - rol r9d,23 - mov r12d,r11d - pinsrw xmm1,WORD[rbx*4+rdi],1 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],eax - xor r12d,r9d - add r8d,DWORD[4+r15] - add al,dl - mov ebx,DWORD[20+rsi] - add r8d,2763975236 - movzx eax,al - add r8d,r12d - mov DWORD[16+rsi],edx - add cl,bl - rol r8d,4 - mov r12d,r10d - pinsrw xmm0,WORD[rax*4+rdi],2 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],ebx - xor r12d,r8d - add r11d,DWORD[16+r15] - add bl,dl - mov eax,DWORD[24+rsi] - add r11d,1272893353 - movzx ebx,bl - add r11d,r12d - mov DWORD[20+rsi],edx - add cl,al - rol r11d,11 - mov r12d,r9d - pinsrw xmm1,WORD[rbx*4+rdi],2 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],eax - xor r12d,r11d - add r10d,DWORD[28+r15] - add al,dl - mov ebx,DWORD[28+rsi] - add r10d,4139469664 - movzx eax,al - add r10d,r12d - mov DWORD[24+rsi],edx - add cl,bl - rol r10d,16 - mov r12d,r8d - pinsrw xmm0,WORD[rax*4+rdi],3 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],ebx - xor r12d,r10d - add r9d,DWORD[40+r15] - add bl,dl - mov eax,DWORD[32+rsi] - add r9d,3200236656 - movzx ebx,bl - add r9d,r12d - mov DWORD[28+rsi],edx - add cl,al - rol r9d,23 - mov r12d,r11d - pinsrw xmm1,WORD[rbx*4+rdi],3 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],eax - xor r12d,r9d - add r8d,DWORD[52+r15] - add al,dl - mov ebx,DWORD[36+rsi] - add r8d,681279174 - movzx eax,al - add r8d,r12d - mov DWORD[32+rsi],edx - add cl,bl - rol r8d,4 - mov r12d,r10d - pinsrw xmm0,WORD[rax*4+rdi],4 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],ebx - xor r12d,r8d - add r11d,DWORD[r15] - add bl,dl - mov eax,DWORD[40+rsi] - add r11d,3936430074 - movzx ebx,bl - add r11d,r12d - mov DWORD[36+rsi],edx - add cl,al - rol r11d,11 - mov r12d,r9d - pinsrw xmm1,WORD[rbx*4+rdi],4 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],eax - xor r12d,r11d - add r10d,DWORD[12+r15] - add al,dl - mov ebx,DWORD[44+rsi] - add r10d,3572445317 - movzx eax,al - add r10d,r12d - mov DWORD[40+rsi],edx - add cl,bl - rol r10d,16 - mov r12d,r8d - pinsrw xmm0,WORD[rax*4+rdi],5 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],ebx - xor r12d,r10d - add r9d,DWORD[24+r15] - add bl,dl - mov eax,DWORD[48+rsi] - add r9d,76029189 - movzx ebx,bl - add r9d,r12d - mov DWORD[44+rsi],edx - add cl,al - rol r9d,23 - mov r12d,r11d - pinsrw xmm1,WORD[rbx*4+rdi],5 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],eax - xor r12d,r9d - add r8d,DWORD[36+r15] - add al,dl - mov ebx,DWORD[52+rsi] - add r8d,3654602809 - movzx eax,al - add r8d,r12d - mov DWORD[48+rsi],edx - add cl,bl - rol r8d,4 - mov r12d,r10d - pinsrw xmm0,WORD[rax*4+rdi],6 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],ebx - xor r12d,r8d - add r11d,DWORD[48+r15] - add bl,dl - mov eax,DWORD[56+rsi] - add r11d,3873151461 - movzx ebx,bl - add r11d,r12d - mov DWORD[52+rsi],edx - add cl,al - rol r11d,11 - mov r12d,r9d - pinsrw xmm1,WORD[rbx*4+rdi],6 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],eax - xor r12d,r11d - add r10d,DWORD[60+r15] - add al,dl - mov ebx,DWORD[60+rsi] - add r10d,530742520 - movzx eax,al - add r10d,r12d - mov DWORD[56+rsi],edx - add cl,bl - rol r10d,16 - mov r12d,r8d - pinsrw xmm0,WORD[rax*4+rdi],7 - - add r10d,r11d - movdqu xmm4,XMMWORD[32+r13] - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],ebx - xor r12d,r10d - add r9d,DWORD[8+r15] - add bl,dl - mov eax,DWORD[64+rsi] - add r9d,3299628645 - movzx ebx,bl - add r9d,r12d - mov DWORD[60+rsi],edx - add cl,al - rol r9d,23 - mov r12d,-1 - pinsrw xmm1,WORD[rbx*4+rdi],7 - - add r9d,r10d - psllq xmm1,8 - pxor xmm4,xmm0 - pxor xmm4,xmm1 - pxor xmm0,xmm0 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],eax - or r12d,r9d - add r8d,DWORD[r15] - add al,dl - mov ebx,DWORD[68+rsi] - add r8d,4096336452 - movzx eax,al - xor r12d,r10d - mov DWORD[64+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,6 - mov r12d,-1 - movd xmm0,DWORD[rax*4+rdi] - - add r8d,r9d - pxor xmm1,xmm1 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],ebx - or r12d,r8d - add r11d,DWORD[28+r15] - add bl,dl - mov eax,DWORD[72+rsi] - add r11d,1126891415 - movzx ebx,bl - xor r12d,r9d - mov DWORD[68+rsi],edx - add r11d,r12d - add cl,al - rol r11d,10 - mov r12d,-1 - movd xmm1,DWORD[rbx*4+rdi] - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],eax - or r12d,r11d - add r10d,DWORD[56+r15] - add al,dl - mov ebx,DWORD[76+rsi] - add r10d,2878612391 - movzx eax,al - xor r12d,r8d - mov DWORD[72+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,15 - mov r12d,-1 - pinsrw xmm0,WORD[rax*4+rdi],1 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],ebx - or r12d,r10d - add r9d,DWORD[20+r15] - add bl,dl - mov eax,DWORD[80+rsi] - add r9d,4237533241 - movzx ebx,bl - xor r12d,r11d - mov DWORD[76+rsi],edx - add r9d,r12d - add cl,al - rol r9d,21 - mov r12d,-1 - pinsrw xmm1,WORD[rbx*4+rdi],1 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],eax - or r12d,r9d - add r8d,DWORD[48+r15] - add al,dl - mov ebx,DWORD[84+rsi] - add r8d,1700485571 - movzx eax,al - xor r12d,r10d - mov DWORD[80+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,6 - mov r12d,-1 - pinsrw xmm0,WORD[rax*4+rdi],2 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],ebx - or r12d,r8d - add r11d,DWORD[12+r15] - add bl,dl - mov eax,DWORD[88+rsi] - add r11d,2399980690 - movzx ebx,bl - xor r12d,r9d - mov DWORD[84+rsi],edx - add r11d,r12d - add cl,al - rol r11d,10 - mov r12d,-1 - pinsrw xmm1,WORD[rbx*4+rdi],2 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],eax - or r12d,r11d - add r10d,DWORD[40+r15] - add al,dl - mov ebx,DWORD[92+rsi] - add r10d,4293915773 - movzx eax,al - xor r12d,r8d - mov DWORD[88+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,15 - mov r12d,-1 - pinsrw xmm0,WORD[rax*4+rdi],3 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],ebx - or r12d,r10d - add r9d,DWORD[4+r15] - add bl,dl - mov eax,DWORD[96+rsi] - add r9d,2240044497 - movzx ebx,bl - xor r12d,r11d - mov DWORD[92+rsi],edx - add r9d,r12d - add cl,al - rol r9d,21 - mov r12d,-1 - pinsrw xmm1,WORD[rbx*4+rdi],3 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],eax - or r12d,r9d - add r8d,DWORD[32+r15] - add al,dl - mov ebx,DWORD[100+rsi] - add r8d,1873313359 - movzx eax,al - xor r12d,r10d - mov DWORD[96+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,6 - mov r12d,-1 - pinsrw xmm0,WORD[rax*4+rdi],4 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],ebx - or r12d,r8d - add r11d,DWORD[60+r15] - add bl,dl - mov eax,DWORD[104+rsi] - add r11d,4264355552 - movzx ebx,bl - xor r12d,r9d - mov DWORD[100+rsi],edx - add r11d,r12d - add cl,al - rol r11d,10 - mov r12d,-1 - pinsrw xmm1,WORD[rbx*4+rdi],4 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],eax - or r12d,r11d - add r10d,DWORD[24+r15] - add al,dl - mov ebx,DWORD[108+rsi] - add r10d,2734768916 - movzx eax,al - xor r12d,r8d - mov DWORD[104+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,15 - mov r12d,-1 - pinsrw xmm0,WORD[rax*4+rdi],5 - - add r10d,r11d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],ebx - or r12d,r10d - add r9d,DWORD[52+r15] - add bl,dl - mov eax,DWORD[112+rsi] - add r9d,1309151649 - movzx ebx,bl - xor r12d,r11d - mov DWORD[108+rsi],edx - add r9d,r12d - add cl,al - rol r9d,21 - mov r12d,-1 - pinsrw xmm1,WORD[rbx*4+rdi],5 - - add r9d,r10d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r11d - mov DWORD[rcx*4+rdi],eax - or r12d,r9d - add r8d,DWORD[16+r15] - add al,dl - mov ebx,DWORD[116+rsi] - add r8d,4149444226 - movzx eax,al - xor r12d,r10d - mov DWORD[112+rsi],edx - add r8d,r12d - add cl,bl - rol r8d,6 - mov r12d,-1 - pinsrw xmm0,WORD[rax*4+rdi],6 - - add r8d,r9d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r10d - mov DWORD[rcx*4+rdi],ebx - or r12d,r8d - add r11d,DWORD[44+r15] - add bl,dl - mov eax,DWORD[120+rsi] - add r11d,3174756917 - movzx ebx,bl - xor r12d,r9d - mov DWORD[116+rsi],edx - add r11d,r12d - add cl,al - rol r11d,10 - mov r12d,-1 - pinsrw xmm1,WORD[rbx*4+rdi],6 - - add r11d,r8d - mov edx,DWORD[rcx*4+rdi] - xor r12d,r9d - mov DWORD[rcx*4+rdi],eax - or r12d,r11d - add r10d,DWORD[8+r15] - add al,dl - mov ebx,DWORD[124+rsi] - add r10d,718787259 - movzx eax,al - xor r12d,r8d - mov DWORD[120+rsi],edx - add r10d,r12d - add cl,bl - rol r10d,15 - mov r12d,-1 - pinsrw xmm0,WORD[rax*4+rdi],7 - - add r10d,r11d - movdqu xmm5,XMMWORD[48+r13] - add bpl,32 - mov edx,DWORD[rcx*4+rdi] - xor r12d,r8d - mov DWORD[rcx*4+rdi],ebx - or r12d,r10d - add r9d,DWORD[36+r15] - add bl,dl - mov eax,DWORD[rbp*4+rdi] - add r9d,3951481745 - movzx ebx,bl - xor r12d,r11d - mov DWORD[124+rsi],edx - add r9d,r12d - add cl,al - rol r9d,21 - mov r12d,-1 - pinsrw xmm1,WORD[rbx*4+rdi],7 - - add r9d,r10d - mov rsi,rbp - xor rbp,rbp - mov bpl,sil - mov rsi,rcx - xor rcx,rcx - mov cl,sil - lea rsi,[rbp*4+rdi] - psllq xmm1,8 - pxor xmm5,xmm0 - pxor xmm5,xmm1 - add r8d,DWORD[rsp] - add r9d,DWORD[4+rsp] - add r10d,DWORD[8+rsp] - add r11d,DWORD[12+rsp] - - movdqu XMMWORD[r13*1+r14],xmm2 - movdqu XMMWORD[16+r13*1+r14],xmm3 - movdqu XMMWORD[32+r13*1+r14],xmm4 - movdqu XMMWORD[48+r13*1+r14],xmm5 - lea r15,[64+r15] - lea r13,[64+r13] - cmp r15,QWORD[16+rsp] - jb NEAR $L$oop - - mov r12,QWORD[24+rsp] - sub cl,al - mov DWORD[r12],r8d - mov DWORD[4+r12],r9d - mov DWORD[8+r12],r10d - mov DWORD[12+r12],r11d - sub bpl,1 - mov DWORD[((-8))+rdi],ebp - mov DWORD[((-4))+rdi],ecx - - mov r15,QWORD[40+rsp] - mov r14,QWORD[48+rsp] - mov r13,QWORD[56+rsp] - mov r12,QWORD[64+rsp] - mov rbp,QWORD[72+rsp] - mov rbx,QWORD[80+rsp] - lea rsp,[88+rsp] -$L$epilogue: -$L$abort: - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret -$L$SEH_end_rc4_md5_enc: -EXTERN __imp_RtlVirtualUnwind - -ALIGN 16 -se_handler: - push rsi - push rdi - push rbx - push rbp - push r12 - push r13 - push r14 - push r15 - pushfq - sub rsp,64 - - mov rax,QWORD[120+r8] - mov rbx,QWORD[248+r8] - - lea r10,[$L$body] - cmp rbx,r10 - jb NEAR $L$in_prologue - - mov rax,QWORD[152+r8] - - lea r10,[$L$epilogue] - cmp rbx,r10 - jae NEAR $L$in_prologue - - mov r15,QWORD[40+rax] - mov r14,QWORD[48+rax] - mov r13,QWORD[56+rax] - mov r12,QWORD[64+rax] - mov rbp,QWORD[72+rax] - mov rbx,QWORD[80+rax] - lea rax,[88+rax] - - mov QWORD[144+r8],rbx - mov QWORD[160+r8],rbp - mov QWORD[216+r8],r12 - mov QWORD[224+r8],r13 - mov QWORD[232+r8],r14 - mov QWORD[240+r8],r15 - -$L$in_prologue: - mov rdi,QWORD[8+rax] - mov rsi,QWORD[16+rax] - mov QWORD[152+r8],rax - mov QWORD[168+r8],rsi - mov QWORD[176+r8],rdi - - mov rdi,QWORD[40+r9] - mov rsi,r8 - mov ecx,154 - DD 0xa548f3fc - - mov rsi,r9 - xor rcx,rcx - mov rdx,QWORD[8+rsi] - mov r8,QWORD[rsi] - mov r9,QWORD[16+rsi] - mov r10,QWORD[40+rsi] - lea r11,[56+rsi] - lea r12,[24+rsi] - mov QWORD[32+rsp],r10 - mov QWORD[40+rsp],r11 - mov QWORD[48+rsp],r12 - mov QWORD[56+rsp],rcx - call QWORD[__imp_RtlVirtualUnwind] - - mov eax,1 - add rsp,64 - popfq - pop r15 - pop r14 - pop r13 - pop r12 - pop rbp - pop rbx - pop rdi - pop rsi - DB 0F3h,0C3h ;repret - - -section .pdata rdata align=4 -ALIGN 4 - DD $L$SEH_begin_rc4_md5_enc wrt ..imagebase - DD $L$SEH_end_rc4_md5_enc wrt ..imagebase - DD $L$SEH_info_rc4_md5_enc wrt ..imagebase - -section .xdata rdata align=8 -ALIGN 8 -$L$SEH_info_rc4_md5_enc: -DB 9,0,0,0 - DD se_handler wrt ..imagebase diff --git a/win-x86_64/crypto/sha/sha1-x86_64.asm b/win-x86_64/crypto/sha/sha1-x86_64.asm index 0f5361a..168f78d 100644 --- a/win-x86_64/crypto/sha/sha1-x86_64.asm +++ b/win-x86_64/crypto/sha/sha1-x86_64.asm @@ -24,6 +24,11 @@ $L$SEH_begin_sha1_block_data_order: mov r10d,DWORD[((OPENSSL_ia32cap_P+8))] test r8d,512 jz NEAR $L$ialu + and r8d,268435456 + and r9d,1073741824 + or r8d,r9d + cmp r8d,1342177280 + je NEAR _avx_shortcut jmp NEAR _ssse3_shortcut ALIGN 16 @@ -2445,6 +2450,1146 @@ $L$epilogue_ssse3: mov rsi,QWORD[16+rsp] DB 0F3h,0C3h ;repret $L$SEH_end_sha1_block_data_order_ssse3: + +ALIGN 16 +sha1_block_data_order_avx: + mov QWORD[8+rsp],rdi ;WIN64 prologue + mov QWORD[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_sha1_block_data_order_avx: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + +_avx_shortcut: + mov rax,rsp + push rbx + push rbp + push r12 + push r13 + push r14 + lea rsp,[((-160))+rsp] + vzeroupper + vmovaps XMMWORD[(-40-96)+rax],xmm6 + vmovaps XMMWORD[(-40-80)+rax],xmm7 + vmovaps XMMWORD[(-40-64)+rax],xmm8 + vmovaps XMMWORD[(-40-48)+rax],xmm9 + vmovaps XMMWORD[(-40-32)+rax],xmm10 + vmovaps XMMWORD[(-40-16)+rax],xmm11 +$L$prologue_avx: + mov r14,rax + and rsp,-64 + mov r8,rdi + mov r9,rsi + mov r10,rdx + + shl r10,6 + add r10,r9 + lea r11,[((K_XX_XX+64))] + + mov eax,DWORD[r8] + mov ebx,DWORD[4+r8] + mov ecx,DWORD[8+r8] + mov edx,DWORD[12+r8] + mov esi,ebx + mov ebp,DWORD[16+r8] + mov edi,ecx + xor edi,edx + and esi,edi + + vmovdqa xmm6,XMMWORD[64+r11] + vmovdqa xmm11,XMMWORD[((-64))+r11] + vmovdqu xmm0,XMMWORD[r9] + vmovdqu xmm1,XMMWORD[16+r9] + vmovdqu xmm2,XMMWORD[32+r9] + vmovdqu xmm3,XMMWORD[48+r9] + vpshufb xmm0,xmm0,xmm6 + add r9,64 + vpshufb xmm1,xmm1,xmm6 + vpshufb xmm2,xmm2,xmm6 + vpshufb xmm3,xmm3,xmm6 + vpaddd xmm4,xmm0,xmm11 + vpaddd xmm5,xmm1,xmm11 + vpaddd xmm6,xmm2,xmm11 + vmovdqa XMMWORD[rsp],xmm4 + vmovdqa XMMWORD[16+rsp],xmm5 + vmovdqa XMMWORD[32+rsp],xmm6 + jmp NEAR $L$oop_avx +ALIGN 16 +$L$oop_avx: + shrd ebx,ebx,2 + xor esi,edx + vpalignr xmm4,xmm1,xmm0,8 + mov edi,eax + add ebp,DWORD[rsp] + vpaddd xmm9,xmm11,xmm3 + xor ebx,ecx + shld eax,eax,5 + vpsrldq xmm8,xmm3,4 + add ebp,esi + and edi,ebx + vpxor xmm4,xmm4,xmm0 + xor ebx,ecx + add ebp,eax + vpxor xmm8,xmm8,xmm2 + shrd eax,eax,7 + xor edi,ecx + mov esi,ebp + add edx,DWORD[4+rsp] + vpxor xmm4,xmm4,xmm8 + xor eax,ebx + shld ebp,ebp,5 + vmovdqa XMMWORD[48+rsp],xmm9 + add edx,edi + and esi,eax + vpsrld xmm8,xmm4,31 + xor eax,ebx + add edx,ebp + shrd ebp,ebp,7 + xor esi,ebx + vpslldq xmm10,xmm4,12 + vpaddd xmm4,xmm4,xmm4 + mov edi,edx + add ecx,DWORD[8+rsp] + xor ebp,eax + shld edx,edx,5 + vpsrld xmm9,xmm10,30 + vpor xmm4,xmm4,xmm8 + add ecx,esi + and edi,ebp + xor ebp,eax + add ecx,edx + vpslld xmm10,xmm10,2 + vpxor xmm4,xmm4,xmm9 + shrd edx,edx,7 + xor edi,eax + mov esi,ecx + add ebx,DWORD[12+rsp] + vpxor xmm4,xmm4,xmm10 + xor edx,ebp + shld ecx,ecx,5 + add ebx,edi + and esi,edx + xor edx,ebp + add ebx,ecx + shrd ecx,ecx,7 + xor esi,ebp + vpalignr xmm5,xmm2,xmm1,8 + mov edi,ebx + add eax,DWORD[16+rsp] + vpaddd xmm9,xmm11,xmm4 + xor ecx,edx + shld ebx,ebx,5 + vpsrldq xmm8,xmm4,4 + add eax,esi + and edi,ecx + vpxor xmm5,xmm5,xmm1 + xor ecx,edx + add eax,ebx + vpxor xmm8,xmm8,xmm3 + shrd ebx,ebx,7 + xor edi,edx + mov esi,eax + add ebp,DWORD[20+rsp] + vpxor xmm5,xmm5,xmm8 + xor ebx,ecx + shld eax,eax,5 + vmovdqa XMMWORD[rsp],xmm9 + add ebp,edi + and esi,ebx + vpsrld xmm8,xmm5,31 + xor ebx,ecx + add ebp,eax + shrd eax,eax,7 + xor esi,ecx + vpslldq xmm10,xmm5,12 + vpaddd xmm5,xmm5,xmm5 + mov edi,ebp + add edx,DWORD[24+rsp] + xor eax,ebx + shld ebp,ebp,5 + vpsrld xmm9,xmm10,30 + vpor xmm5,xmm5,xmm8 + add edx,esi + and edi,eax + xor eax,ebx + add edx,ebp + vpslld xmm10,xmm10,2 + vpxor xmm5,xmm5,xmm9 + shrd ebp,ebp,7 + xor edi,ebx + mov esi,edx + add ecx,DWORD[28+rsp] + vpxor xmm5,xmm5,xmm10 + xor ebp,eax + shld edx,edx,5 + vmovdqa xmm11,XMMWORD[((-32))+r11] + add ecx,edi + and esi,ebp + xor ebp,eax + add ecx,edx + shrd edx,edx,7 + xor esi,eax + vpalignr xmm6,xmm3,xmm2,8 + mov edi,ecx + add ebx,DWORD[32+rsp] + vpaddd xmm9,xmm11,xmm5 + xor edx,ebp + shld ecx,ecx,5 + vpsrldq xmm8,xmm5,4 + add ebx,esi + and edi,edx + vpxor xmm6,xmm6,xmm2 + xor edx,ebp + add ebx,ecx + vpxor xmm8,xmm8,xmm4 + shrd ecx,ecx,7 + xor edi,ebp + mov esi,ebx + add eax,DWORD[36+rsp] + vpxor xmm6,xmm6,xmm8 + xor ecx,edx + shld ebx,ebx,5 + vmovdqa XMMWORD[16+rsp],xmm9 + add eax,edi + and esi,ecx + vpsrld xmm8,xmm6,31 + xor ecx,edx + add eax,ebx + shrd ebx,ebx,7 + xor esi,edx + vpslldq xmm10,xmm6,12 + vpaddd xmm6,xmm6,xmm6 + mov edi,eax + add ebp,DWORD[40+rsp] + xor ebx,ecx + shld eax,eax,5 + vpsrld xmm9,xmm10,30 + vpor xmm6,xmm6,xmm8 + add ebp,esi + and edi,ebx + xor ebx,ecx + add ebp,eax + vpslld xmm10,xmm10,2 + vpxor xmm6,xmm6,xmm9 + shrd eax,eax,7 + xor edi,ecx + mov esi,ebp + add edx,DWORD[44+rsp] + vpxor xmm6,xmm6,xmm10 + xor eax,ebx + shld ebp,ebp,5 + add edx,edi + and esi,eax + xor eax,ebx + add edx,ebp + shrd ebp,ebp,7 + xor esi,ebx + vpalignr xmm7,xmm4,xmm3,8 + mov edi,edx + add ecx,DWORD[48+rsp] + vpaddd xmm9,xmm11,xmm6 + xor ebp,eax + shld edx,edx,5 + vpsrldq xmm8,xmm6,4 + add ecx,esi + and edi,ebp + vpxor xmm7,xmm7,xmm3 + xor ebp,eax + add ecx,edx + vpxor xmm8,xmm8,xmm5 + shrd edx,edx,7 + xor edi,eax + mov esi,ecx + add ebx,DWORD[52+rsp] + vpxor xmm7,xmm7,xmm8 + xor edx,ebp + shld ecx,ecx,5 + vmovdqa XMMWORD[32+rsp],xmm9 + add ebx,edi + and esi,edx + vpsrld xmm8,xmm7,31 + xor edx,ebp + add ebx,ecx + shrd ecx,ecx,7 + xor esi,ebp + vpslldq xmm10,xmm7,12 + vpaddd xmm7,xmm7,xmm7 + mov edi,ebx + add eax,DWORD[56+rsp] + xor ecx,edx + shld ebx,ebx,5 + vpsrld xmm9,xmm10,30 + vpor xmm7,xmm7,xmm8 + add eax,esi + and edi,ecx + xor ecx,edx + add eax,ebx + vpslld xmm10,xmm10,2 + vpxor xmm7,xmm7,xmm9 + shrd ebx,ebx,7 + xor edi,edx + mov esi,eax + add ebp,DWORD[60+rsp] + vpxor xmm7,xmm7,xmm10 + xor ebx,ecx + shld eax,eax,5 + add ebp,edi + and esi,ebx + xor ebx,ecx + add ebp,eax + vpalignr xmm8,xmm7,xmm6,8 + vpxor xmm0,xmm0,xmm4 + shrd eax,eax,7 + xor esi,ecx + mov edi,ebp + add edx,DWORD[rsp] + vpxor xmm0,xmm0,xmm1 + xor eax,ebx + shld ebp,ebp,5 + vpaddd xmm9,xmm11,xmm7 + add edx,esi + and edi,eax + vpxor xmm0,xmm0,xmm8 + xor eax,ebx + add edx,ebp + shrd ebp,ebp,7 + xor edi,ebx + vpsrld xmm8,xmm0,30 + vmovdqa XMMWORD[48+rsp],xmm9 + mov esi,edx + add ecx,DWORD[4+rsp] + xor ebp,eax + shld edx,edx,5 + vpslld xmm0,xmm0,2 + add ecx,edi + and esi,ebp + xor ebp,eax + add ecx,edx + shrd edx,edx,7 + xor esi,eax + mov edi,ecx + add ebx,DWORD[8+rsp] + vpor xmm0,xmm0,xmm8 + xor edx,ebp + shld ecx,ecx,5 + add ebx,esi + and edi,edx + xor edx,ebp + add ebx,ecx + add eax,DWORD[12+rsp] + xor edi,ebp + mov esi,ebx + shld ebx,ebx,5 + add eax,edi + xor esi,edx + shrd ecx,ecx,7 + add eax,ebx + vpalignr xmm8,xmm0,xmm7,8 + vpxor xmm1,xmm1,xmm5 + add ebp,DWORD[16+rsp] + xor esi,ecx + mov edi,eax + shld eax,eax,5 + vpxor xmm1,xmm1,xmm2 + add ebp,esi + xor edi,ecx + vpaddd xmm9,xmm11,xmm0 + shrd ebx,ebx,7 + add ebp,eax + vpxor xmm1,xmm1,xmm8 + add edx,DWORD[20+rsp] + xor edi,ebx + mov esi,ebp + shld ebp,ebp,5 + vpsrld xmm8,xmm1,30 + vmovdqa XMMWORD[rsp],xmm9 + add edx,edi + xor esi,ebx + shrd eax,eax,7 + add edx,ebp + vpslld xmm1,xmm1,2 + add ecx,DWORD[24+rsp] + xor esi,eax + mov edi,edx + shld edx,edx,5 + add ecx,esi + xor edi,eax + shrd ebp,ebp,7 + add ecx,edx + vpor xmm1,xmm1,xmm8 + add ebx,DWORD[28+rsp] + xor edi,ebp + mov esi,ecx + shld ecx,ecx,5 + add ebx,edi + xor esi,ebp + shrd edx,edx,7 + add ebx,ecx + vpalignr xmm8,xmm1,xmm0,8 + vpxor xmm2,xmm2,xmm6 + add eax,DWORD[32+rsp] + xor esi,edx + mov edi,ebx + shld ebx,ebx,5 + vpxor xmm2,xmm2,xmm3 + add eax,esi + xor edi,edx + vpaddd xmm9,xmm11,xmm1 + vmovdqa xmm11,XMMWORD[r11] + shrd ecx,ecx,7 + add eax,ebx + vpxor xmm2,xmm2,xmm8 + add ebp,DWORD[36+rsp] + xor edi,ecx + mov esi,eax + shld eax,eax,5 + vpsrld xmm8,xmm2,30 + vmovdqa XMMWORD[16+rsp],xmm9 + add ebp,edi + xor esi,ecx + shrd ebx,ebx,7 + add ebp,eax + vpslld xmm2,xmm2,2 + add edx,DWORD[40+rsp] + xor esi,ebx + mov edi,ebp + shld ebp,ebp,5 + add edx,esi + xor edi,ebx + shrd eax,eax,7 + add edx,ebp + vpor xmm2,xmm2,xmm8 + add ecx,DWORD[44+rsp] + xor edi,eax + mov esi,edx + shld edx,edx,5 + add ecx,edi + xor esi,eax + shrd ebp,ebp,7 + add ecx,edx + vpalignr xmm8,xmm2,xmm1,8 + vpxor xmm3,xmm3,xmm7 + add ebx,DWORD[48+rsp] + xor esi,ebp + mov edi,ecx + shld ecx,ecx,5 + vpxor xmm3,xmm3,xmm4 + add ebx,esi + xor edi,ebp + vpaddd xmm9,xmm11,xmm2 + shrd edx,edx,7 + add ebx,ecx + vpxor xmm3,xmm3,xmm8 + add eax,DWORD[52+rsp] + xor edi,edx + mov esi,ebx + shld ebx,ebx,5 + vpsrld xmm8,xmm3,30 + vmovdqa XMMWORD[32+rsp],xmm9 + add eax,edi + xor esi,edx + shrd ecx,ecx,7 + add eax,ebx + vpslld xmm3,xmm3,2 + add ebp,DWORD[56+rsp] + xor esi,ecx + mov edi,eax + shld eax,eax,5 + add ebp,esi + xor edi,ecx + shrd ebx,ebx,7 + add ebp,eax + vpor xmm3,xmm3,xmm8 + add edx,DWORD[60+rsp] + xor edi,ebx + mov esi,ebp + shld ebp,ebp,5 + add edx,edi + xor esi,ebx + shrd eax,eax,7 + add edx,ebp + vpalignr xmm8,xmm3,xmm2,8 + vpxor xmm4,xmm4,xmm0 + add ecx,DWORD[rsp] + xor esi,eax + mov edi,edx + shld edx,edx,5 + vpxor xmm4,xmm4,xmm5 + add ecx,esi + xor edi,eax + vpaddd xmm9,xmm11,xmm3 + shrd ebp,ebp,7 + add ecx,edx + vpxor xmm4,xmm4,xmm8 + add ebx,DWORD[4+rsp] + xor edi,ebp + mov esi,ecx + shld ecx,ecx,5 + vpsrld xmm8,xmm4,30 + vmovdqa XMMWORD[48+rsp],xmm9 + add ebx,edi + xor esi,ebp + shrd edx,edx,7 + add ebx,ecx + vpslld xmm4,xmm4,2 + add eax,DWORD[8+rsp] + xor esi,edx + mov edi,ebx + shld ebx,ebx,5 + add eax,esi + xor edi,edx + shrd ecx,ecx,7 + add eax,ebx + vpor xmm4,xmm4,xmm8 + add ebp,DWORD[12+rsp] + xor edi,ecx + mov esi,eax + shld eax,eax,5 + add ebp,edi + xor esi,ecx + shrd ebx,ebx,7 + add ebp,eax + vpalignr xmm8,xmm4,xmm3,8 + vpxor xmm5,xmm5,xmm1 + add edx,DWORD[16+rsp] + xor esi,ebx + mov edi,ebp + shld ebp,ebp,5 + vpxor xmm5,xmm5,xmm6 + add edx,esi + xor edi,ebx + vpaddd xmm9,xmm11,xmm4 + shrd eax,eax,7 + add edx,ebp + vpxor xmm5,xmm5,xmm8 + add ecx,DWORD[20+rsp] + xor edi,eax + mov esi,edx + shld edx,edx,5 + vpsrld xmm8,xmm5,30 + vmovdqa XMMWORD[rsp],xmm9 + add ecx,edi + xor esi,eax + shrd ebp,ebp,7 + add ecx,edx + vpslld xmm5,xmm5,2 + add ebx,DWORD[24+rsp] + xor esi,ebp + mov edi,ecx + shld ecx,ecx,5 + add ebx,esi + xor edi,ebp + shrd edx,edx,7 + add ebx,ecx + vpor xmm5,xmm5,xmm8 + add eax,DWORD[28+rsp] + shrd ecx,ecx,7 + mov esi,ebx + xor edi,edx + shld ebx,ebx,5 + add eax,edi + xor esi,ecx + xor ecx,edx + add eax,ebx + vpalignr xmm8,xmm5,xmm4,8 + vpxor xmm6,xmm6,xmm2 + add ebp,DWORD[32+rsp] + and esi,ecx + xor ecx,edx + shrd ebx,ebx,7 + vpxor xmm6,xmm6,xmm7 + mov edi,eax + xor esi,ecx + vpaddd xmm9,xmm11,xmm5 + shld eax,eax,5 + add ebp,esi + vpxor xmm6,xmm6,xmm8 + xor edi,ebx + xor ebx,ecx + add ebp,eax + add edx,DWORD[36+rsp] + vpsrld xmm8,xmm6,30 + vmovdqa XMMWORD[16+rsp],xmm9 + and edi,ebx + xor ebx,ecx + shrd eax,eax,7 + mov esi,ebp + vpslld xmm6,xmm6,2 + xor edi,ebx + shld ebp,ebp,5 + add edx,edi + xor esi,eax + xor eax,ebx + add edx,ebp + add ecx,DWORD[40+rsp] + and esi,eax + vpor xmm6,xmm6,xmm8 + xor eax,ebx + shrd ebp,ebp,7 + mov edi,edx + xor esi,eax + shld edx,edx,5 + add ecx,esi + xor edi,ebp + xor ebp,eax + add ecx,edx + add ebx,DWORD[44+rsp] + and edi,ebp + xor ebp,eax + shrd edx,edx,7 + mov esi,ecx + xor edi,ebp + shld ecx,ecx,5 + add ebx,edi + xor esi,edx + xor edx,ebp + add ebx,ecx + vpalignr xmm8,xmm6,xmm5,8 + vpxor xmm7,xmm7,xmm3 + add eax,DWORD[48+rsp] + and esi,edx + xor edx,ebp + shrd ecx,ecx,7 + vpxor xmm7,xmm7,xmm0 + mov edi,ebx + xor esi,edx + vpaddd xmm9,xmm11,xmm6 + vmovdqa xmm11,XMMWORD[32+r11] + shld ebx,ebx,5 + add eax,esi + vpxor xmm7,xmm7,xmm8 + xor edi,ecx + xor ecx,edx + add eax,ebx + add ebp,DWORD[52+rsp] + vpsrld xmm8,xmm7,30 + vmovdqa XMMWORD[32+rsp],xmm9 + and edi,ecx + xor ecx,edx + shrd ebx,ebx,7 + mov esi,eax + vpslld xmm7,xmm7,2 + xor edi,ecx + shld eax,eax,5 + add ebp,edi + xor esi,ebx + xor ebx,ecx + add ebp,eax + add edx,DWORD[56+rsp] + and esi,ebx + vpor xmm7,xmm7,xmm8 + xor ebx,ecx + shrd eax,eax,7 + mov edi,ebp + xor esi,ebx + shld ebp,ebp,5 + add edx,esi + xor edi,eax + xor eax,ebx + add edx,ebp + add ecx,DWORD[60+rsp] + and edi,eax + xor eax,ebx + shrd ebp,ebp,7 + mov esi,edx + xor edi,eax + shld edx,edx,5 + add ecx,edi + xor esi,ebp + xor ebp,eax + add ecx,edx + vpalignr xmm8,xmm7,xmm6,8 + vpxor xmm0,xmm0,xmm4 + add ebx,DWORD[rsp] + and esi,ebp + xor ebp,eax + shrd edx,edx,7 + vpxor xmm0,xmm0,xmm1 + mov edi,ecx + xor esi,ebp + vpaddd xmm9,xmm11,xmm7 + shld ecx,ecx,5 + add ebx,esi + vpxor xmm0,xmm0,xmm8 + xor edi,edx + xor edx,ebp + add ebx,ecx + add eax,DWORD[4+rsp] + vpsrld xmm8,xmm0,30 + vmovdqa XMMWORD[48+rsp],xmm9 + and edi,edx + xor edx,ebp + shrd ecx,ecx,7 + mov esi,ebx + vpslld xmm0,xmm0,2 + xor edi,edx + shld ebx,ebx,5 + add eax,edi + xor esi,ecx + xor ecx,edx + add eax,ebx + add ebp,DWORD[8+rsp] + and esi,ecx + vpor xmm0,xmm0,xmm8 + xor ecx,edx + shrd ebx,ebx,7 + mov edi,eax + xor esi,ecx + shld eax,eax,5 + add ebp,esi + xor edi,ebx + xor ebx,ecx + add ebp,eax + add edx,DWORD[12+rsp] + and edi,ebx + xor ebx,ecx + shrd eax,eax,7 + mov esi,ebp + xor edi,ebx + shld ebp,ebp,5 + add edx,edi + xor esi,eax + xor eax,ebx + add edx,ebp + vpalignr xmm8,xmm0,xmm7,8 + vpxor xmm1,xmm1,xmm5 + add ecx,DWORD[16+rsp] + and esi,eax + xor eax,ebx + shrd ebp,ebp,7 + vpxor xmm1,xmm1,xmm2 + mov edi,edx + xor esi,eax + vpaddd xmm9,xmm11,xmm0 + shld edx,edx,5 + add ecx,esi + vpxor xmm1,xmm1,xmm8 + xor edi,ebp + xor ebp,eax + add ecx,edx + add ebx,DWORD[20+rsp] + vpsrld xmm8,xmm1,30 + vmovdqa XMMWORD[rsp],xmm9 + and edi,ebp + xor ebp,eax + shrd edx,edx,7 + mov esi,ecx + vpslld xmm1,xmm1,2 + xor edi,ebp + shld ecx,ecx,5 + add ebx,edi + xor esi,edx + xor edx,ebp + add ebx,ecx + add eax,DWORD[24+rsp] + and esi,edx + vpor xmm1,xmm1,xmm8 + xor edx,ebp + shrd ecx,ecx,7 + mov edi,ebx + xor esi,edx + shld ebx,ebx,5 + add eax,esi + xor edi,ecx + xor ecx,edx + add eax,ebx + add ebp,DWORD[28+rsp] + and edi,ecx + xor ecx,edx + shrd ebx,ebx,7 + mov esi,eax + xor edi,ecx + shld eax,eax,5 + add ebp,edi + xor esi,ebx + xor ebx,ecx + add ebp,eax + vpalignr xmm8,xmm1,xmm0,8 + vpxor xmm2,xmm2,xmm6 + add edx,DWORD[32+rsp] + and esi,ebx + xor ebx,ecx + shrd eax,eax,7 + vpxor xmm2,xmm2,xmm3 + mov edi,ebp + xor esi,ebx + vpaddd xmm9,xmm11,xmm1 + shld ebp,ebp,5 + add edx,esi + vpxor xmm2,xmm2,xmm8 + xor edi,eax + xor eax,ebx + add edx,ebp + add ecx,DWORD[36+rsp] + vpsrld xmm8,xmm2,30 + vmovdqa XMMWORD[16+rsp],xmm9 + and edi,eax + xor eax,ebx + shrd ebp,ebp,7 + mov esi,edx + vpslld xmm2,xmm2,2 + xor edi,eax + shld edx,edx,5 + add ecx,edi + xor esi,ebp + xor ebp,eax + add ecx,edx + add ebx,DWORD[40+rsp] + and esi,ebp + vpor xmm2,xmm2,xmm8 + xor ebp,eax + shrd edx,edx,7 + mov edi,ecx + xor esi,ebp + shld ecx,ecx,5 + add ebx,esi + xor edi,edx + xor edx,ebp + add ebx,ecx + add eax,DWORD[44+rsp] + and edi,edx + xor edx,ebp + shrd ecx,ecx,7 + mov esi,ebx + xor edi,edx + shld ebx,ebx,5 + add eax,edi + xor esi,edx + add eax,ebx + vpalignr xmm8,xmm2,xmm1,8 + vpxor xmm3,xmm3,xmm7 + add ebp,DWORD[48+rsp] + xor esi,ecx + mov edi,eax + shld eax,eax,5 + vpxor xmm3,xmm3,xmm4 + add ebp,esi + xor edi,ecx + vpaddd xmm9,xmm11,xmm2 + shrd ebx,ebx,7 + add ebp,eax + vpxor xmm3,xmm3,xmm8 + add edx,DWORD[52+rsp] + xor edi,ebx + mov esi,ebp + shld ebp,ebp,5 + vpsrld xmm8,xmm3,30 + vmovdqa XMMWORD[32+rsp],xmm9 + add edx,edi + xor esi,ebx + shrd eax,eax,7 + add edx,ebp + vpslld xmm3,xmm3,2 + add ecx,DWORD[56+rsp] + xor esi,eax + mov edi,edx + shld edx,edx,5 + add ecx,esi + xor edi,eax + shrd ebp,ebp,7 + add ecx,edx + vpor xmm3,xmm3,xmm8 + add ebx,DWORD[60+rsp] + xor edi,ebp + mov esi,ecx + shld ecx,ecx,5 + add ebx,edi + xor esi,ebp + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD[rsp] + vpaddd xmm9,xmm11,xmm3 + xor esi,edx + mov edi,ebx + shld ebx,ebx,5 + add eax,esi + vmovdqa XMMWORD[48+rsp],xmm9 + xor edi,edx + shrd ecx,ecx,7 + add eax,ebx + add ebp,DWORD[4+rsp] + xor edi,ecx + mov esi,eax + shld eax,eax,5 + add ebp,edi + xor esi,ecx + shrd ebx,ebx,7 + add ebp,eax + add edx,DWORD[8+rsp] + xor esi,ebx + mov edi,ebp + shld ebp,ebp,5 + add edx,esi + xor edi,ebx + shrd eax,eax,7 + add edx,ebp + add ecx,DWORD[12+rsp] + xor edi,eax + mov esi,edx + shld edx,edx,5 + add ecx,edi + xor esi,eax + shrd ebp,ebp,7 + add ecx,edx + cmp r9,r10 + je NEAR $L$done_avx + vmovdqa xmm6,XMMWORD[64+r11] + vmovdqa xmm11,XMMWORD[((-64))+r11] + vmovdqu xmm0,XMMWORD[r9] + vmovdqu xmm1,XMMWORD[16+r9] + vmovdqu xmm2,XMMWORD[32+r9] + vmovdqu xmm3,XMMWORD[48+r9] + vpshufb xmm0,xmm0,xmm6 + add r9,64 + add ebx,DWORD[16+rsp] + xor esi,ebp + vpshufb xmm1,xmm1,xmm6 + mov edi,ecx + shld ecx,ecx,5 + vpaddd xmm4,xmm0,xmm11 + add ebx,esi + xor edi,ebp + shrd edx,edx,7 + add ebx,ecx + vmovdqa XMMWORD[rsp],xmm4 + add eax,DWORD[20+rsp] + xor edi,edx + mov esi,ebx + shld ebx,ebx,5 + add eax,edi + xor esi,edx + shrd ecx,ecx,7 + add eax,ebx + add ebp,DWORD[24+rsp] + xor esi,ecx + mov edi,eax + shld eax,eax,5 + add ebp,esi + xor edi,ecx + shrd ebx,ebx,7 + add ebp,eax + add edx,DWORD[28+rsp] + xor edi,ebx + mov esi,ebp + shld ebp,ebp,5 + add edx,edi + xor esi,ebx + shrd eax,eax,7 + add edx,ebp + add ecx,DWORD[32+rsp] + xor esi,eax + vpshufb xmm2,xmm2,xmm6 + mov edi,edx + shld edx,edx,5 + vpaddd xmm5,xmm1,xmm11 + add ecx,esi + xor edi,eax + shrd ebp,ebp,7 + add ecx,edx + vmovdqa XMMWORD[16+rsp],xmm5 + add ebx,DWORD[36+rsp] + xor edi,ebp + mov esi,ecx + shld ecx,ecx,5 + add ebx,edi + xor esi,ebp + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD[40+rsp] + xor esi,edx + mov edi,ebx + shld ebx,ebx,5 + add eax,esi + xor edi,edx + shrd ecx,ecx,7 + add eax,ebx + add ebp,DWORD[44+rsp] + xor edi,ecx + mov esi,eax + shld eax,eax,5 + add ebp,edi + xor esi,ecx + shrd ebx,ebx,7 + add ebp,eax + add edx,DWORD[48+rsp] + xor esi,ebx + vpshufb xmm3,xmm3,xmm6 + mov edi,ebp + shld ebp,ebp,5 + vpaddd xmm6,xmm2,xmm11 + add edx,esi + xor edi,ebx + shrd eax,eax,7 + add edx,ebp + vmovdqa XMMWORD[32+rsp],xmm6 + add ecx,DWORD[52+rsp] + xor edi,eax + mov esi,edx + shld edx,edx,5 + add ecx,edi + xor esi,eax + shrd ebp,ebp,7 + add ecx,edx + add ebx,DWORD[56+rsp] + xor esi,ebp + mov edi,ecx + shld ecx,ecx,5 + add ebx,esi + xor edi,ebp + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD[60+rsp] + xor edi,edx + mov esi,ebx + shld ebx,ebx,5 + add eax,edi + shrd ecx,ecx,7 + add eax,ebx + add eax,DWORD[r8] + add esi,DWORD[4+r8] + add ecx,DWORD[8+r8] + add edx,DWORD[12+r8] + mov DWORD[r8],eax + add ebp,DWORD[16+r8] + mov DWORD[4+r8],esi + mov ebx,esi + mov DWORD[8+r8],ecx + mov edi,ecx + mov DWORD[12+r8],edx + xor edi,edx + mov DWORD[16+r8],ebp + and esi,edi + jmp NEAR $L$oop_avx + +ALIGN 16 +$L$done_avx: + add ebx,DWORD[16+rsp] + xor esi,ebp + mov edi,ecx + shld ecx,ecx,5 + add ebx,esi + xor edi,ebp + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD[20+rsp] + xor edi,edx + mov esi,ebx + shld ebx,ebx,5 + add eax,edi + xor esi,edx + shrd ecx,ecx,7 + add eax,ebx + add ebp,DWORD[24+rsp] + xor esi,ecx + mov edi,eax + shld eax,eax,5 + add ebp,esi + xor edi,ecx + shrd ebx,ebx,7 + add ebp,eax + add edx,DWORD[28+rsp] + xor edi,ebx + mov esi,ebp + shld ebp,ebp,5 + add edx,edi + xor esi,ebx + shrd eax,eax,7 + add edx,ebp + add ecx,DWORD[32+rsp] + xor esi,eax + mov edi,edx + shld edx,edx,5 + add ecx,esi + xor edi,eax + shrd ebp,ebp,7 + add ecx,edx + add ebx,DWORD[36+rsp] + xor edi,ebp + mov esi,ecx + shld ecx,ecx,5 + add ebx,edi + xor esi,ebp + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD[40+rsp] + xor esi,edx + mov edi,ebx + shld ebx,ebx,5 + add eax,esi + xor edi,edx + shrd ecx,ecx,7 + add eax,ebx + add ebp,DWORD[44+rsp] + xor edi,ecx + mov esi,eax + shld eax,eax,5 + add ebp,edi + xor esi,ecx + shrd ebx,ebx,7 + add ebp,eax + add edx,DWORD[48+rsp] + xor esi,ebx + mov edi,ebp + shld ebp,ebp,5 + add edx,esi + xor edi,ebx + shrd eax,eax,7 + add edx,ebp + add ecx,DWORD[52+rsp] + xor edi,eax + mov esi,edx + shld edx,edx,5 + add ecx,edi + xor esi,eax + shrd ebp,ebp,7 + add ecx,edx + add ebx,DWORD[56+rsp] + xor esi,ebp + mov edi,ecx + shld ecx,ecx,5 + add ebx,esi + xor edi,ebp + shrd edx,edx,7 + add ebx,ecx + add eax,DWORD[60+rsp] + xor edi,edx + mov esi,ebx + shld ebx,ebx,5 + add eax,edi + shrd ecx,ecx,7 + add eax,ebx + vzeroupper + + add eax,DWORD[r8] + add esi,DWORD[4+r8] + add ecx,DWORD[8+r8] + mov DWORD[r8],eax + add edx,DWORD[12+r8] + mov DWORD[4+r8],esi + add ebp,DWORD[16+r8] + mov DWORD[8+r8],ecx + mov DWORD[12+r8],edx + mov DWORD[16+r8],ebp + movaps xmm6,XMMWORD[((-40-96))+r14] + movaps xmm7,XMMWORD[((-40-80))+r14] + movaps xmm8,XMMWORD[((-40-64))+r14] + movaps xmm9,XMMWORD[((-40-48))+r14] + movaps xmm10,XMMWORD[((-40-32))+r14] + movaps xmm11,XMMWORD[((-40-16))+r14] + lea rsi,[r14] + mov r14,QWORD[((-40))+rsi] + mov r13,QWORD[((-32))+rsi] + mov r12,QWORD[((-24))+rsi] + mov rbp,QWORD[((-16))+rsi] + mov rbx,QWORD[((-8))+rsi] + lea rsp,[rsi] +$L$epilogue_avx: + mov rdi,QWORD[8+rsp] ;WIN64 epilogue + mov rsi,QWORD[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_sha1_block_data_order_avx: ALIGN 64 K_XX_XX: DD 0x5a827999,0x5a827999,0x5a827999,0x5a827999 @@ -2605,6 +3750,9 @@ ALIGN 4 DD $L$SEH_begin_sha1_block_data_order_ssse3 wrt ..imagebase DD $L$SEH_end_sha1_block_data_order_ssse3 wrt ..imagebase DD $L$SEH_info_sha1_block_data_order_ssse3 wrt ..imagebase + DD $L$SEH_begin_sha1_block_data_order_avx wrt ..imagebase + DD $L$SEH_end_sha1_block_data_order_avx wrt ..imagebase + DD $L$SEH_info_sha1_block_data_order_avx wrt ..imagebase section .xdata rdata align=8 ALIGN 8 $L$SEH_info_sha1_block_data_order: @@ -2614,3 +3762,7 @@ $L$SEH_info_sha1_block_data_order_ssse3: DB 9,0,0,0 DD ssse3_handler wrt ..imagebase DD $L$prologue_ssse3 wrt ..imagebase,$L$epilogue_ssse3 wrt ..imagebase +$L$SEH_info_sha1_block_data_order_avx: +DB 9,0,0,0 + DD ssse3_handler wrt ..imagebase + DD $L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase diff --git a/win-x86_64/crypto/sha/sha256-x86_64.asm b/win-x86_64/crypto/sha/sha256-x86_64.asm index e6193c5..efaf9b5 100644 --- a/win-x86_64/crypto/sha/sha256-x86_64.asm +++ b/win-x86_64/crypto/sha/sha256-x86_64.asm @@ -23,6 +23,11 @@ $L$SEH_begin_sha256_block_data_order: mov r9d,DWORD[r11] mov r10d,DWORD[4+r11] mov r11d,DWORD[8+r11] + and r9d,1073741824 + and r10d,268435968 + or r10d,r9d + cmp r10d,1342177792 + je NEAR $L$avx_shortcut test r10d,512 jnz NEAR $L$ssse3_shortcut push rbx @@ -2877,6 +2882,1082 @@ $L$epilogue_ssse3: mov rsi,QWORD[16+rsp] DB 0F3h,0C3h ;repret $L$SEH_end_sha256_block_data_order_ssse3: + +ALIGN 64 +sha256_block_data_order_avx: + mov QWORD[8+rsp],rdi ;WIN64 prologue + mov QWORD[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_sha256_block_data_order_avx: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + +$L$avx_shortcut: + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + mov r11,rsp + shl rdx,4 + sub rsp,160 + lea rdx,[rdx*4+rsi] + and rsp,-64 + mov QWORD[((64+0))+rsp],rdi + mov QWORD[((64+8))+rsp],rsi + mov QWORD[((64+16))+rsp],rdx + mov QWORD[((64+24))+rsp],r11 + movaps XMMWORD[(64+32)+rsp],xmm6 + movaps XMMWORD[(64+48)+rsp],xmm7 + movaps XMMWORD[(64+64)+rsp],xmm8 + movaps XMMWORD[(64+80)+rsp],xmm9 +$L$prologue_avx: + + vzeroupper + mov eax,DWORD[rdi] + mov ebx,DWORD[4+rdi] + mov ecx,DWORD[8+rdi] + mov edx,DWORD[12+rdi] + mov r8d,DWORD[16+rdi] + mov r9d,DWORD[20+rdi] + mov r10d,DWORD[24+rdi] + mov r11d,DWORD[28+rdi] + vmovdqa xmm8,XMMWORD[((K256+512+32))] + vmovdqa xmm9,XMMWORD[((K256+512+64))] + jmp NEAR $L$loop_avx +ALIGN 16 +$L$loop_avx: + vmovdqa xmm7,XMMWORD[((K256+512))] + vmovdqu xmm0,XMMWORD[rsi] + vmovdqu xmm1,XMMWORD[16+rsi] + vmovdqu xmm2,XMMWORD[32+rsi] + vmovdqu xmm3,XMMWORD[48+rsi] + vpshufb xmm0,xmm0,xmm7 + lea rbp,[K256] + vpshufb xmm1,xmm1,xmm7 + vpshufb xmm2,xmm2,xmm7 + vpaddd xmm4,xmm0,XMMWORD[rbp] + vpshufb xmm3,xmm3,xmm7 + vpaddd xmm5,xmm1,XMMWORD[32+rbp] + vpaddd xmm6,xmm2,XMMWORD[64+rbp] + vpaddd xmm7,xmm3,XMMWORD[96+rbp] + vmovdqa XMMWORD[rsp],xmm4 + mov r14d,eax + vmovdqa XMMWORD[16+rsp],xmm5 + mov edi,ebx + vmovdqa XMMWORD[32+rsp],xmm6 + xor edi,ecx + vmovdqa XMMWORD[48+rsp],xmm7 + mov r13d,r8d + jmp NEAR $L$avx_00_47 + +ALIGN 16 +$L$avx_00_47: + sub rbp,-128 + vpalignr xmm4,xmm1,xmm0,4 + shrd r13d,r13d,14 + mov eax,r14d + mov r12d,r9d + vpalignr xmm7,xmm3,xmm2,4 + shrd r14d,r14d,9 + xor r13d,r8d + xor r12d,r10d + vpsrld xmm6,xmm4,7 + shrd r13d,r13d,5 + xor r14d,eax + and r12d,r8d + vpaddd xmm0,xmm0,xmm7 + xor r13d,r8d + add r11d,DWORD[rsp] + mov r15d,eax + vpsrld xmm7,xmm4,3 + xor r12d,r10d + shrd r14d,r14d,11 + xor r15d,ebx + vpslld xmm5,xmm4,14 + add r11d,r12d + shrd r13d,r13d,6 + and edi,r15d + vpxor xmm4,xmm7,xmm6 + xor r14d,eax + add r11d,r13d + xor edi,ebx + vpshufd xmm7,xmm3,250 + shrd r14d,r14d,2 + add edx,r11d + add r11d,edi + vpsrld xmm6,xmm6,11 + mov r13d,edx + add r14d,r11d + shrd r13d,r13d,14 + vpxor xmm4,xmm4,xmm5 + mov r11d,r14d + mov r12d,r8d + shrd r14d,r14d,9 + vpslld xmm5,xmm5,11 + xor r13d,edx + xor r12d,r9d + shrd r13d,r13d,5 + vpxor xmm4,xmm4,xmm6 + xor r14d,r11d + and r12d,edx + xor r13d,edx + vpsrld xmm6,xmm7,10 + add r10d,DWORD[4+rsp] + mov edi,r11d + xor r12d,r9d + vpxor xmm4,xmm4,xmm5 + shrd r14d,r14d,11 + xor edi,eax + add r10d,r12d + vpsrlq xmm7,xmm7,17 + shrd r13d,r13d,6 + and r15d,edi + xor r14d,r11d + vpaddd xmm0,xmm0,xmm4 + add r10d,r13d + xor r15d,eax + shrd r14d,r14d,2 + vpxor xmm6,xmm6,xmm7 + add ecx,r10d + add r10d,r15d + mov r13d,ecx + vpsrlq xmm7,xmm7,2 + add r14d,r10d + shrd r13d,r13d,14 + mov r10d,r14d + vpxor xmm6,xmm6,xmm7 + mov r12d,edx + shrd r14d,r14d,9 + xor r13d,ecx + vpshufb xmm6,xmm6,xmm8 + xor r12d,r8d + shrd r13d,r13d,5 + xor r14d,r10d + vpaddd xmm0,xmm0,xmm6 + and r12d,ecx + xor r13d,ecx + add r9d,DWORD[8+rsp] + vpshufd xmm7,xmm0,80 + mov r15d,r10d + xor r12d,r8d + shrd r14d,r14d,11 + vpsrld xmm6,xmm7,10 + xor r15d,r11d + add r9d,r12d + shrd r13d,r13d,6 + vpsrlq xmm7,xmm7,17 + and edi,r15d + xor r14d,r10d + add r9d,r13d + vpxor xmm6,xmm6,xmm7 + xor edi,r11d + shrd r14d,r14d,2 + add ebx,r9d + vpsrlq xmm7,xmm7,2 + add r9d,edi + mov r13d,ebx + add r14d,r9d + vpxor xmm6,xmm6,xmm7 + shrd r13d,r13d,14 + mov r9d,r14d + mov r12d,ecx + vpshufb xmm6,xmm6,xmm9 + shrd r14d,r14d,9 + xor r13d,ebx + xor r12d,edx + vpaddd xmm0,xmm0,xmm6 + shrd r13d,r13d,5 + xor r14d,r9d + and r12d,ebx + vpaddd xmm6,xmm0,XMMWORD[rbp] + xor r13d,ebx + add r8d,DWORD[12+rsp] + mov edi,r9d + xor r12d,edx + shrd r14d,r14d,11 + xor edi,r10d + add r8d,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,r9d + add r8d,r13d + xor r15d,r10d + shrd r14d,r14d,2 + add eax,r8d + add r8d,r15d + mov r13d,eax + add r14d,r8d + vmovdqa XMMWORD[rsp],xmm6 + vpalignr xmm4,xmm2,xmm1,4 + shrd r13d,r13d,14 + mov r8d,r14d + mov r12d,ebx + vpalignr xmm7,xmm0,xmm3,4 + shrd r14d,r14d,9 + xor r13d,eax + xor r12d,ecx + vpsrld xmm6,xmm4,7 + shrd r13d,r13d,5 + xor r14d,r8d + and r12d,eax + vpaddd xmm1,xmm1,xmm7 + xor r13d,eax + add edx,DWORD[16+rsp] + mov r15d,r8d + vpsrld xmm7,xmm4,3 + xor r12d,ecx + shrd r14d,r14d,11 + xor r15d,r9d + vpslld xmm5,xmm4,14 + add edx,r12d + shrd r13d,r13d,6 + and edi,r15d + vpxor xmm4,xmm7,xmm6 + xor r14d,r8d + add edx,r13d + xor edi,r9d + vpshufd xmm7,xmm0,250 + shrd r14d,r14d,2 + add r11d,edx + add edx,edi + vpsrld xmm6,xmm6,11 + mov r13d,r11d + add r14d,edx + shrd r13d,r13d,14 + vpxor xmm4,xmm4,xmm5 + mov edx,r14d + mov r12d,eax + shrd r14d,r14d,9 + vpslld xmm5,xmm5,11 + xor r13d,r11d + xor r12d,ebx + shrd r13d,r13d,5 + vpxor xmm4,xmm4,xmm6 + xor r14d,edx + and r12d,r11d + xor r13d,r11d + vpsrld xmm6,xmm7,10 + add ecx,DWORD[20+rsp] + mov edi,edx + xor r12d,ebx + vpxor xmm4,xmm4,xmm5 + shrd r14d,r14d,11 + xor edi,r8d + add ecx,r12d + vpsrlq xmm7,xmm7,17 + shrd r13d,r13d,6 + and r15d,edi + xor r14d,edx + vpaddd xmm1,xmm1,xmm4 + add ecx,r13d + xor r15d,r8d + shrd r14d,r14d,2 + vpxor xmm6,xmm6,xmm7 + add r10d,ecx + add ecx,r15d + mov r13d,r10d + vpsrlq xmm7,xmm7,2 + add r14d,ecx + shrd r13d,r13d,14 + mov ecx,r14d + vpxor xmm6,xmm6,xmm7 + mov r12d,r11d + shrd r14d,r14d,9 + xor r13d,r10d + vpshufb xmm6,xmm6,xmm8 + xor r12d,eax + shrd r13d,r13d,5 + xor r14d,ecx + vpaddd xmm1,xmm1,xmm6 + and r12d,r10d + xor r13d,r10d + add ebx,DWORD[24+rsp] + vpshufd xmm7,xmm1,80 + mov r15d,ecx + xor r12d,eax + shrd r14d,r14d,11 + vpsrld xmm6,xmm7,10 + xor r15d,edx + add ebx,r12d + shrd r13d,r13d,6 + vpsrlq xmm7,xmm7,17 + and edi,r15d + xor r14d,ecx + add ebx,r13d + vpxor xmm6,xmm6,xmm7 + xor edi,edx + shrd r14d,r14d,2 + add r9d,ebx + vpsrlq xmm7,xmm7,2 + add ebx,edi + mov r13d,r9d + add r14d,ebx + vpxor xmm6,xmm6,xmm7 + shrd r13d,r13d,14 + mov ebx,r14d + mov r12d,r10d + vpshufb xmm6,xmm6,xmm9 + shrd r14d,r14d,9 + xor r13d,r9d + xor r12d,r11d + vpaddd xmm1,xmm1,xmm6 + shrd r13d,r13d,5 + xor r14d,ebx + and r12d,r9d + vpaddd xmm6,xmm1,XMMWORD[32+rbp] + xor r13d,r9d + add eax,DWORD[28+rsp] + mov edi,ebx + xor r12d,r11d + shrd r14d,r14d,11 + xor edi,ecx + add eax,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,ebx + add eax,r13d + xor r15d,ecx + shrd r14d,r14d,2 + add r8d,eax + add eax,r15d + mov r13d,r8d + add r14d,eax + vmovdqa XMMWORD[16+rsp],xmm6 + vpalignr xmm4,xmm3,xmm2,4 + shrd r13d,r13d,14 + mov eax,r14d + mov r12d,r9d + vpalignr xmm7,xmm1,xmm0,4 + shrd r14d,r14d,9 + xor r13d,r8d + xor r12d,r10d + vpsrld xmm6,xmm4,7 + shrd r13d,r13d,5 + xor r14d,eax + and r12d,r8d + vpaddd xmm2,xmm2,xmm7 + xor r13d,r8d + add r11d,DWORD[32+rsp] + mov r15d,eax + vpsrld xmm7,xmm4,3 + xor r12d,r10d + shrd r14d,r14d,11 + xor r15d,ebx + vpslld xmm5,xmm4,14 + add r11d,r12d + shrd r13d,r13d,6 + and edi,r15d + vpxor xmm4,xmm7,xmm6 + xor r14d,eax + add r11d,r13d + xor edi,ebx + vpshufd xmm7,xmm1,250 + shrd r14d,r14d,2 + add edx,r11d + add r11d,edi + vpsrld xmm6,xmm6,11 + mov r13d,edx + add r14d,r11d + shrd r13d,r13d,14 + vpxor xmm4,xmm4,xmm5 + mov r11d,r14d + mov r12d,r8d + shrd r14d,r14d,9 + vpslld xmm5,xmm5,11 + xor r13d,edx + xor r12d,r9d + shrd r13d,r13d,5 + vpxor xmm4,xmm4,xmm6 + xor r14d,r11d + and r12d,edx + xor r13d,edx + vpsrld xmm6,xmm7,10 + add r10d,DWORD[36+rsp] + mov edi,r11d + xor r12d,r9d + vpxor xmm4,xmm4,xmm5 + shrd r14d,r14d,11 + xor edi,eax + add r10d,r12d + vpsrlq xmm7,xmm7,17 + shrd r13d,r13d,6 + and r15d,edi + xor r14d,r11d + vpaddd xmm2,xmm2,xmm4 + add r10d,r13d + xor r15d,eax + shrd r14d,r14d,2 + vpxor xmm6,xmm6,xmm7 + add ecx,r10d + add r10d,r15d + mov r13d,ecx + vpsrlq xmm7,xmm7,2 + add r14d,r10d + shrd r13d,r13d,14 + mov r10d,r14d + vpxor xmm6,xmm6,xmm7 + mov r12d,edx + shrd r14d,r14d,9 + xor r13d,ecx + vpshufb xmm6,xmm6,xmm8 + xor r12d,r8d + shrd r13d,r13d,5 + xor r14d,r10d + vpaddd xmm2,xmm2,xmm6 + and r12d,ecx + xor r13d,ecx + add r9d,DWORD[40+rsp] + vpshufd xmm7,xmm2,80 + mov r15d,r10d + xor r12d,r8d + shrd r14d,r14d,11 + vpsrld xmm6,xmm7,10 + xor r15d,r11d + add r9d,r12d + shrd r13d,r13d,6 + vpsrlq xmm7,xmm7,17 + and edi,r15d + xor r14d,r10d + add r9d,r13d + vpxor xmm6,xmm6,xmm7 + xor edi,r11d + shrd r14d,r14d,2 + add ebx,r9d + vpsrlq xmm7,xmm7,2 + add r9d,edi + mov r13d,ebx + add r14d,r9d + vpxor xmm6,xmm6,xmm7 + shrd r13d,r13d,14 + mov r9d,r14d + mov r12d,ecx + vpshufb xmm6,xmm6,xmm9 + shrd r14d,r14d,9 + xor r13d,ebx + xor r12d,edx + vpaddd xmm2,xmm2,xmm6 + shrd r13d,r13d,5 + xor r14d,r9d + and r12d,ebx + vpaddd xmm6,xmm2,XMMWORD[64+rbp] + xor r13d,ebx + add r8d,DWORD[44+rsp] + mov edi,r9d + xor r12d,edx + shrd r14d,r14d,11 + xor edi,r10d + add r8d,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,r9d + add r8d,r13d + xor r15d,r10d + shrd r14d,r14d,2 + add eax,r8d + add r8d,r15d + mov r13d,eax + add r14d,r8d + vmovdqa XMMWORD[32+rsp],xmm6 + vpalignr xmm4,xmm0,xmm3,4 + shrd r13d,r13d,14 + mov r8d,r14d + mov r12d,ebx + vpalignr xmm7,xmm2,xmm1,4 + shrd r14d,r14d,9 + xor r13d,eax + xor r12d,ecx + vpsrld xmm6,xmm4,7 + shrd r13d,r13d,5 + xor r14d,r8d + and r12d,eax + vpaddd xmm3,xmm3,xmm7 + xor r13d,eax + add edx,DWORD[48+rsp] + mov r15d,r8d + vpsrld xmm7,xmm4,3 + xor r12d,ecx + shrd r14d,r14d,11 + xor r15d,r9d + vpslld xmm5,xmm4,14 + add edx,r12d + shrd r13d,r13d,6 + and edi,r15d + vpxor xmm4,xmm7,xmm6 + xor r14d,r8d + add edx,r13d + xor edi,r9d + vpshufd xmm7,xmm2,250 + shrd r14d,r14d,2 + add r11d,edx + add edx,edi + vpsrld xmm6,xmm6,11 + mov r13d,r11d + add r14d,edx + shrd r13d,r13d,14 + vpxor xmm4,xmm4,xmm5 + mov edx,r14d + mov r12d,eax + shrd r14d,r14d,9 + vpslld xmm5,xmm5,11 + xor r13d,r11d + xor r12d,ebx + shrd r13d,r13d,5 + vpxor xmm4,xmm4,xmm6 + xor r14d,edx + and r12d,r11d + xor r13d,r11d + vpsrld xmm6,xmm7,10 + add ecx,DWORD[52+rsp] + mov edi,edx + xor r12d,ebx + vpxor xmm4,xmm4,xmm5 + shrd r14d,r14d,11 + xor edi,r8d + add ecx,r12d + vpsrlq xmm7,xmm7,17 + shrd r13d,r13d,6 + and r15d,edi + xor r14d,edx + vpaddd xmm3,xmm3,xmm4 + add ecx,r13d + xor r15d,r8d + shrd r14d,r14d,2 + vpxor xmm6,xmm6,xmm7 + add r10d,ecx + add ecx,r15d + mov r13d,r10d + vpsrlq xmm7,xmm7,2 + add r14d,ecx + shrd r13d,r13d,14 + mov ecx,r14d + vpxor xmm6,xmm6,xmm7 + mov r12d,r11d + shrd r14d,r14d,9 + xor r13d,r10d + vpshufb xmm6,xmm6,xmm8 + xor r12d,eax + shrd r13d,r13d,5 + xor r14d,ecx + vpaddd xmm3,xmm3,xmm6 + and r12d,r10d + xor r13d,r10d + add ebx,DWORD[56+rsp] + vpshufd xmm7,xmm3,80 + mov r15d,ecx + xor r12d,eax + shrd r14d,r14d,11 + vpsrld xmm6,xmm7,10 + xor r15d,edx + add ebx,r12d + shrd r13d,r13d,6 + vpsrlq xmm7,xmm7,17 + and edi,r15d + xor r14d,ecx + add ebx,r13d + vpxor xmm6,xmm6,xmm7 + xor edi,edx + shrd r14d,r14d,2 + add r9d,ebx + vpsrlq xmm7,xmm7,2 + add ebx,edi + mov r13d,r9d + add r14d,ebx + vpxor xmm6,xmm6,xmm7 + shrd r13d,r13d,14 + mov ebx,r14d + mov r12d,r10d + vpshufb xmm6,xmm6,xmm9 + shrd r14d,r14d,9 + xor r13d,r9d + xor r12d,r11d + vpaddd xmm3,xmm3,xmm6 + shrd r13d,r13d,5 + xor r14d,ebx + and r12d,r9d + vpaddd xmm6,xmm3,XMMWORD[96+rbp] + xor r13d,r9d + add eax,DWORD[60+rsp] + mov edi,ebx + xor r12d,r11d + shrd r14d,r14d,11 + xor edi,ecx + add eax,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,ebx + add eax,r13d + xor r15d,ecx + shrd r14d,r14d,2 + add r8d,eax + add eax,r15d + mov r13d,r8d + add r14d,eax + vmovdqa XMMWORD[48+rsp],xmm6 + cmp BYTE[131+rbp],0 + jne NEAR $L$avx_00_47 + shrd r13d,r13d,14 + mov eax,r14d + mov r12d,r9d + shrd r14d,r14d,9 + xor r13d,r8d + xor r12d,r10d + shrd r13d,r13d,5 + xor r14d,eax + and r12d,r8d + xor r13d,r8d + add r11d,DWORD[rsp] + mov r15d,eax + xor r12d,r10d + shrd r14d,r14d,11 + xor r15d,ebx + add r11d,r12d + shrd r13d,r13d,6 + and edi,r15d + xor r14d,eax + add r11d,r13d + xor edi,ebx + shrd r14d,r14d,2 + add edx,r11d + add r11d,edi + mov r13d,edx + add r14d,r11d + shrd r13d,r13d,14 + mov r11d,r14d + mov r12d,r8d + shrd r14d,r14d,9 + xor r13d,edx + xor r12d,r9d + shrd r13d,r13d,5 + xor r14d,r11d + and r12d,edx + xor r13d,edx + add r10d,DWORD[4+rsp] + mov edi,r11d + xor r12d,r9d + shrd r14d,r14d,11 + xor edi,eax + add r10d,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,r11d + add r10d,r13d + xor r15d,eax + shrd r14d,r14d,2 + add ecx,r10d + add r10d,r15d + mov r13d,ecx + add r14d,r10d + shrd r13d,r13d,14 + mov r10d,r14d + mov r12d,edx + shrd r14d,r14d,9 + xor r13d,ecx + xor r12d,r8d + shrd r13d,r13d,5 + xor r14d,r10d + and r12d,ecx + xor r13d,ecx + add r9d,DWORD[8+rsp] + mov r15d,r10d + xor r12d,r8d + shrd r14d,r14d,11 + xor r15d,r11d + add r9d,r12d + shrd r13d,r13d,6 + and edi,r15d + xor r14d,r10d + add r9d,r13d + xor edi,r11d + shrd r14d,r14d,2 + add ebx,r9d + add r9d,edi + mov r13d,ebx + add r14d,r9d + shrd r13d,r13d,14 + mov r9d,r14d + mov r12d,ecx + shrd r14d,r14d,9 + xor r13d,ebx + xor r12d,edx + shrd r13d,r13d,5 + xor r14d,r9d + and r12d,ebx + xor r13d,ebx + add r8d,DWORD[12+rsp] + mov edi,r9d + xor r12d,edx + shrd r14d,r14d,11 + xor edi,r10d + add r8d,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,r9d + add r8d,r13d + xor r15d,r10d + shrd r14d,r14d,2 + add eax,r8d + add r8d,r15d + mov r13d,eax + add r14d,r8d + shrd r13d,r13d,14 + mov r8d,r14d + mov r12d,ebx + shrd r14d,r14d,9 + xor r13d,eax + xor r12d,ecx + shrd r13d,r13d,5 + xor r14d,r8d + and r12d,eax + xor r13d,eax + add edx,DWORD[16+rsp] + mov r15d,r8d + xor r12d,ecx + shrd r14d,r14d,11 + xor r15d,r9d + add edx,r12d + shrd r13d,r13d,6 + and edi,r15d + xor r14d,r8d + add edx,r13d + xor edi,r9d + shrd r14d,r14d,2 + add r11d,edx + add edx,edi + mov r13d,r11d + add r14d,edx + shrd r13d,r13d,14 + mov edx,r14d + mov r12d,eax + shrd r14d,r14d,9 + xor r13d,r11d + xor r12d,ebx + shrd r13d,r13d,5 + xor r14d,edx + and r12d,r11d + xor r13d,r11d + add ecx,DWORD[20+rsp] + mov edi,edx + xor r12d,ebx + shrd r14d,r14d,11 + xor edi,r8d + add ecx,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,edx + add ecx,r13d + xor r15d,r8d + shrd r14d,r14d,2 + add r10d,ecx + add ecx,r15d + mov r13d,r10d + add r14d,ecx + shrd r13d,r13d,14 + mov ecx,r14d + mov r12d,r11d + shrd r14d,r14d,9 + xor r13d,r10d + xor r12d,eax + shrd r13d,r13d,5 + xor r14d,ecx + and r12d,r10d + xor r13d,r10d + add ebx,DWORD[24+rsp] + mov r15d,ecx + xor r12d,eax + shrd r14d,r14d,11 + xor r15d,edx + add ebx,r12d + shrd r13d,r13d,6 + and edi,r15d + xor r14d,ecx + add ebx,r13d + xor edi,edx + shrd r14d,r14d,2 + add r9d,ebx + add ebx,edi + mov r13d,r9d + add r14d,ebx + shrd r13d,r13d,14 + mov ebx,r14d + mov r12d,r10d + shrd r14d,r14d,9 + xor r13d,r9d + xor r12d,r11d + shrd r13d,r13d,5 + xor r14d,ebx + and r12d,r9d + xor r13d,r9d + add eax,DWORD[28+rsp] + mov edi,ebx + xor r12d,r11d + shrd r14d,r14d,11 + xor edi,ecx + add eax,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,ebx + add eax,r13d + xor r15d,ecx + shrd r14d,r14d,2 + add r8d,eax + add eax,r15d + mov r13d,r8d + add r14d,eax + shrd r13d,r13d,14 + mov eax,r14d + mov r12d,r9d + shrd r14d,r14d,9 + xor r13d,r8d + xor r12d,r10d + shrd r13d,r13d,5 + xor r14d,eax + and r12d,r8d + xor r13d,r8d + add r11d,DWORD[32+rsp] + mov r15d,eax + xor r12d,r10d + shrd r14d,r14d,11 + xor r15d,ebx + add r11d,r12d + shrd r13d,r13d,6 + and edi,r15d + xor r14d,eax + add r11d,r13d + xor edi,ebx + shrd r14d,r14d,2 + add edx,r11d + add r11d,edi + mov r13d,edx + add r14d,r11d + shrd r13d,r13d,14 + mov r11d,r14d + mov r12d,r8d + shrd r14d,r14d,9 + xor r13d,edx + xor r12d,r9d + shrd r13d,r13d,5 + xor r14d,r11d + and r12d,edx + xor r13d,edx + add r10d,DWORD[36+rsp] + mov edi,r11d + xor r12d,r9d + shrd r14d,r14d,11 + xor edi,eax + add r10d,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,r11d + add r10d,r13d + xor r15d,eax + shrd r14d,r14d,2 + add ecx,r10d + add r10d,r15d + mov r13d,ecx + add r14d,r10d + shrd r13d,r13d,14 + mov r10d,r14d + mov r12d,edx + shrd r14d,r14d,9 + xor r13d,ecx + xor r12d,r8d + shrd r13d,r13d,5 + xor r14d,r10d + and r12d,ecx + xor r13d,ecx + add r9d,DWORD[40+rsp] + mov r15d,r10d + xor r12d,r8d + shrd r14d,r14d,11 + xor r15d,r11d + add r9d,r12d + shrd r13d,r13d,6 + and edi,r15d + xor r14d,r10d + add r9d,r13d + xor edi,r11d + shrd r14d,r14d,2 + add ebx,r9d + add r9d,edi + mov r13d,ebx + add r14d,r9d + shrd r13d,r13d,14 + mov r9d,r14d + mov r12d,ecx + shrd r14d,r14d,9 + xor r13d,ebx + xor r12d,edx + shrd r13d,r13d,5 + xor r14d,r9d + and r12d,ebx + xor r13d,ebx + add r8d,DWORD[44+rsp] + mov edi,r9d + xor r12d,edx + shrd r14d,r14d,11 + xor edi,r10d + add r8d,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,r9d + add r8d,r13d + xor r15d,r10d + shrd r14d,r14d,2 + add eax,r8d + add r8d,r15d + mov r13d,eax + add r14d,r8d + shrd r13d,r13d,14 + mov r8d,r14d + mov r12d,ebx + shrd r14d,r14d,9 + xor r13d,eax + xor r12d,ecx + shrd r13d,r13d,5 + xor r14d,r8d + and r12d,eax + xor r13d,eax + add edx,DWORD[48+rsp] + mov r15d,r8d + xor r12d,ecx + shrd r14d,r14d,11 + xor r15d,r9d + add edx,r12d + shrd r13d,r13d,6 + and edi,r15d + xor r14d,r8d + add edx,r13d + xor edi,r9d + shrd r14d,r14d,2 + add r11d,edx + add edx,edi + mov r13d,r11d + add r14d,edx + shrd r13d,r13d,14 + mov edx,r14d + mov r12d,eax + shrd r14d,r14d,9 + xor r13d,r11d + xor r12d,ebx + shrd r13d,r13d,5 + xor r14d,edx + and r12d,r11d + xor r13d,r11d + add ecx,DWORD[52+rsp] + mov edi,edx + xor r12d,ebx + shrd r14d,r14d,11 + xor edi,r8d + add ecx,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,edx + add ecx,r13d + xor r15d,r8d + shrd r14d,r14d,2 + add r10d,ecx + add ecx,r15d + mov r13d,r10d + add r14d,ecx + shrd r13d,r13d,14 + mov ecx,r14d + mov r12d,r11d + shrd r14d,r14d,9 + xor r13d,r10d + xor r12d,eax + shrd r13d,r13d,5 + xor r14d,ecx + and r12d,r10d + xor r13d,r10d + add ebx,DWORD[56+rsp] + mov r15d,ecx + xor r12d,eax + shrd r14d,r14d,11 + xor r15d,edx + add ebx,r12d + shrd r13d,r13d,6 + and edi,r15d + xor r14d,ecx + add ebx,r13d + xor edi,edx + shrd r14d,r14d,2 + add r9d,ebx + add ebx,edi + mov r13d,r9d + add r14d,ebx + shrd r13d,r13d,14 + mov ebx,r14d + mov r12d,r10d + shrd r14d,r14d,9 + xor r13d,r9d + xor r12d,r11d + shrd r13d,r13d,5 + xor r14d,ebx + and r12d,r9d + xor r13d,r9d + add eax,DWORD[60+rsp] + mov edi,ebx + xor r12d,r11d + shrd r14d,r14d,11 + xor edi,ecx + add eax,r12d + shrd r13d,r13d,6 + and r15d,edi + xor r14d,ebx + add eax,r13d + xor r15d,ecx + shrd r14d,r14d,2 + add r8d,eax + add eax,r15d + mov r13d,r8d + add r14d,eax + mov rdi,QWORD[((64+0))+rsp] + mov eax,r14d + + add eax,DWORD[rdi] + lea rsi,[64+rsi] + add ebx,DWORD[4+rdi] + add ecx,DWORD[8+rdi] + add edx,DWORD[12+rdi] + add r8d,DWORD[16+rdi] + add r9d,DWORD[20+rdi] + add r10d,DWORD[24+rdi] + add r11d,DWORD[28+rdi] + + cmp rsi,QWORD[((64+16))+rsp] + + mov DWORD[rdi],eax + mov DWORD[4+rdi],ebx + mov DWORD[8+rdi],ecx + mov DWORD[12+rdi],edx + mov DWORD[16+rdi],r8d + mov DWORD[20+rdi],r9d + mov DWORD[24+rdi],r10d + mov DWORD[28+rdi],r11d + jb NEAR $L$loop_avx + + mov rsi,QWORD[((64+24))+rsp] + vzeroupper + movaps xmm6,XMMWORD[((64+32))+rsp] + movaps xmm7,XMMWORD[((64+48))+rsp] + movaps xmm8,XMMWORD[((64+64))+rsp] + movaps xmm9,XMMWORD[((64+80))+rsp] + mov r15,QWORD[rsi] + mov r14,QWORD[8+rsi] + mov r13,QWORD[16+rsi] + mov r12,QWORD[24+rsi] + mov rbp,QWORD[32+rsi] + mov rbx,QWORD[40+rsi] + lea rsp,[48+rsi] +$L$epilogue_avx: + mov rdi,QWORD[8+rsp] ;WIN64 epilogue + mov rsi,QWORD[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_sha256_block_data_order_avx: EXTERN __imp_RtlVirtualUnwind ALIGN 16 @@ -2982,6 +4063,9 @@ ALIGN 4 DD $L$SEH_begin_sha256_block_data_order_ssse3 wrt ..imagebase DD $L$SEH_end_sha256_block_data_order_ssse3 wrt ..imagebase DD $L$SEH_info_sha256_block_data_order_ssse3 wrt ..imagebase + DD $L$SEH_begin_sha256_block_data_order_avx wrt ..imagebase + DD $L$SEH_end_sha256_block_data_order_avx wrt ..imagebase + DD $L$SEH_info_sha256_block_data_order_avx wrt ..imagebase section .xdata rdata align=8 ALIGN 8 $L$SEH_info_sha256_block_data_order: @@ -2992,3 +4076,7 @@ $L$SEH_info_sha256_block_data_order_ssse3: DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$prologue_ssse3 wrt ..imagebase,$L$epilogue_ssse3 wrt ..imagebase +$L$SEH_info_sha256_block_data_order_avx: +DB 9,0,0,0 + DD se_handler wrt ..imagebase + DD $L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase diff --git a/win-x86_64/crypto/sha/sha512-x86_64.asm b/win-x86_64/crypto/sha/sha512-x86_64.asm index b76cc0e..71449cd 100644 --- a/win-x86_64/crypto/sha/sha512-x86_64.asm +++ b/win-x86_64/crypto/sha/sha512-x86_64.asm @@ -19,6 +19,17 @@ $L$SEH_begin_sha512_block_data_order: mov rdx,r8 + lea r11,[OPENSSL_ia32cap_P] + mov r9d,DWORD[r11] + mov r10d,DWORD[4+r11] + mov r11d,DWORD[8+r11] + test r10d,2048 + jnz NEAR $L$xop_shortcut + and r9d,1073741824 + and r10d,268435968 + or r10d,r9d + cmp r10d,1342177792 + je NEAR $L$avx_shortcut push rbx push rbp push r12 @@ -1801,6 +1812,2282 @@ DB 110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54 DB 52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 DB 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 DB 111,114,103,62,0 + +ALIGN 64 +sha512_block_data_order_xop: + mov QWORD[8+rsp],rdi ;WIN64 prologue + mov QWORD[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_sha512_block_data_order_xop: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + +$L$xop_shortcut: + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + mov r11,rsp + shl rdx,4 + sub rsp,256 + lea rdx,[rdx*8+rsi] + and rsp,-64 + mov QWORD[((128+0))+rsp],rdi + mov QWORD[((128+8))+rsp],rsi + mov QWORD[((128+16))+rsp],rdx + mov QWORD[((128+24))+rsp],r11 + movaps XMMWORD[(128+32)+rsp],xmm6 + movaps XMMWORD[(128+48)+rsp],xmm7 + movaps XMMWORD[(128+64)+rsp],xmm8 + movaps XMMWORD[(128+80)+rsp],xmm9 + movaps XMMWORD[(128+96)+rsp],xmm10 + movaps XMMWORD[(128+112)+rsp],xmm11 +$L$prologue_xop: + + vzeroupper + mov rax,QWORD[rdi] + mov rbx,QWORD[8+rdi] + mov rcx,QWORD[16+rdi] + mov rdx,QWORD[24+rdi] + mov r8,QWORD[32+rdi] + mov r9,QWORD[40+rdi] + mov r10,QWORD[48+rdi] + mov r11,QWORD[56+rdi] + jmp NEAR $L$loop_xop +ALIGN 16 +$L$loop_xop: + vmovdqa xmm11,XMMWORD[((K512+1280))] + vmovdqu xmm0,XMMWORD[rsi] + lea rbp,[((K512+128))] + vmovdqu xmm1,XMMWORD[16+rsi] + vmovdqu xmm2,XMMWORD[32+rsi] + vpshufb xmm0,xmm0,xmm11 + vmovdqu xmm3,XMMWORD[48+rsi] + vpshufb xmm1,xmm1,xmm11 + vmovdqu xmm4,XMMWORD[64+rsi] + vpshufb xmm2,xmm2,xmm11 + vmovdqu xmm5,XMMWORD[80+rsi] + vpshufb xmm3,xmm3,xmm11 + vmovdqu xmm6,XMMWORD[96+rsi] + vpshufb xmm4,xmm4,xmm11 + vmovdqu xmm7,XMMWORD[112+rsi] + vpshufb xmm5,xmm5,xmm11 + vpaddq xmm8,xmm0,XMMWORD[((-128))+rbp] + vpshufb xmm6,xmm6,xmm11 + vpaddq xmm9,xmm1,XMMWORD[((-96))+rbp] + vpshufb xmm7,xmm7,xmm11 + vpaddq xmm10,xmm2,XMMWORD[((-64))+rbp] + vpaddq xmm11,xmm3,XMMWORD[((-32))+rbp] + vmovdqa XMMWORD[rsp],xmm8 + vpaddq xmm8,xmm4,XMMWORD[rbp] + vmovdqa XMMWORD[16+rsp],xmm9 + vpaddq xmm9,xmm5,XMMWORD[32+rbp] + vmovdqa XMMWORD[32+rsp],xmm10 + vpaddq xmm10,xmm6,XMMWORD[64+rbp] + vmovdqa XMMWORD[48+rsp],xmm11 + vpaddq xmm11,xmm7,XMMWORD[96+rbp] + vmovdqa XMMWORD[64+rsp],xmm8 + mov r14,rax + vmovdqa XMMWORD[80+rsp],xmm9 + mov rdi,rbx + vmovdqa XMMWORD[96+rsp],xmm10 + xor rdi,rcx + vmovdqa XMMWORD[112+rsp],xmm11 + mov r13,r8 + jmp NEAR $L$xop_00_47 + +ALIGN 16 +$L$xop_00_47: + add rbp,256 + vpalignr xmm8,xmm1,xmm0,8 + ror r13,23 + mov rax,r14 + vpalignr xmm11,xmm5,xmm4,8 + mov r12,r9 + ror r14,5 +DB 143,72,120,195,200,56 + xor r13,r8 + xor r12,r10 + vpsrlq xmm8,xmm8,7 + ror r13,4 + xor r14,rax + vpaddq xmm0,xmm0,xmm11 + and r12,r8 + xor r13,r8 + add r11,QWORD[rsp] + mov r15,rax +DB 143,72,120,195,209,7 + xor r12,r10 + ror r14,6 + vpxor xmm8,xmm8,xmm9 + xor r15,rbx + add r11,r12 + ror r13,14 + and rdi,r15 +DB 143,104,120,195,223,3 + xor r14,rax + add r11,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,rbx + ror r14,28 + vpsrlq xmm10,xmm7,6 + add rdx,r11 + add r11,rdi + vpaddq xmm0,xmm0,xmm8 + mov r13,rdx + add r14,r11 +DB 143,72,120,195,203,42 + ror r13,23 + mov r11,r14 + vpxor xmm11,xmm11,xmm10 + mov r12,r8 + ror r14,5 + xor r13,rdx + xor r12,r9 + vpxor xmm11,xmm11,xmm9 + ror r13,4 + xor r14,r11 + and r12,rdx + xor r13,rdx + vpaddq xmm0,xmm0,xmm11 + add r10,QWORD[8+rsp] + mov rdi,r11 + xor r12,r9 + ror r14,6 + vpaddq xmm10,xmm0,XMMWORD[((-128))+rbp] + xor rdi,rax + add r10,r12 + ror r13,14 + and r15,rdi + xor r14,r11 + add r10,r13 + xor r15,rax + ror r14,28 + add rcx,r10 + add r10,r15 + mov r13,rcx + add r14,r10 + vmovdqa XMMWORD[rsp],xmm10 + vpalignr xmm8,xmm2,xmm1,8 + ror r13,23 + mov r10,r14 + vpalignr xmm11,xmm6,xmm5,8 + mov r12,rdx + ror r14,5 +DB 143,72,120,195,200,56 + xor r13,rcx + xor r12,r8 + vpsrlq xmm8,xmm8,7 + ror r13,4 + xor r14,r10 + vpaddq xmm1,xmm1,xmm11 + and r12,rcx + xor r13,rcx + add r9,QWORD[16+rsp] + mov r15,r10 +DB 143,72,120,195,209,7 + xor r12,r8 + ror r14,6 + vpxor xmm8,xmm8,xmm9 + xor r15,r11 + add r9,r12 + ror r13,14 + and rdi,r15 +DB 143,104,120,195,216,3 + xor r14,r10 + add r9,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,r11 + ror r14,28 + vpsrlq xmm10,xmm0,6 + add rbx,r9 + add r9,rdi + vpaddq xmm1,xmm1,xmm8 + mov r13,rbx + add r14,r9 +DB 143,72,120,195,203,42 + ror r13,23 + mov r9,r14 + vpxor xmm11,xmm11,xmm10 + mov r12,rcx + ror r14,5 + xor r13,rbx + xor r12,rdx + vpxor xmm11,xmm11,xmm9 + ror r13,4 + xor r14,r9 + and r12,rbx + xor r13,rbx + vpaddq xmm1,xmm1,xmm11 + add r8,QWORD[24+rsp] + mov rdi,r9 + xor r12,rdx + ror r14,6 + vpaddq xmm10,xmm1,XMMWORD[((-96))+rbp] + xor rdi,r10 + add r8,r12 + ror r13,14 + and r15,rdi + xor r14,r9 + add r8,r13 + xor r15,r10 + ror r14,28 + add rax,r8 + add r8,r15 + mov r13,rax + add r14,r8 + vmovdqa XMMWORD[16+rsp],xmm10 + vpalignr xmm8,xmm3,xmm2,8 + ror r13,23 + mov r8,r14 + vpalignr xmm11,xmm7,xmm6,8 + mov r12,rbx + ror r14,5 +DB 143,72,120,195,200,56 + xor r13,rax + xor r12,rcx + vpsrlq xmm8,xmm8,7 + ror r13,4 + xor r14,r8 + vpaddq xmm2,xmm2,xmm11 + and r12,rax + xor r13,rax + add rdx,QWORD[32+rsp] + mov r15,r8 +DB 143,72,120,195,209,7 + xor r12,rcx + ror r14,6 + vpxor xmm8,xmm8,xmm9 + xor r15,r9 + add rdx,r12 + ror r13,14 + and rdi,r15 +DB 143,104,120,195,217,3 + xor r14,r8 + add rdx,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,r9 + ror r14,28 + vpsrlq xmm10,xmm1,6 + add r11,rdx + add rdx,rdi + vpaddq xmm2,xmm2,xmm8 + mov r13,r11 + add r14,rdx +DB 143,72,120,195,203,42 + ror r13,23 + mov rdx,r14 + vpxor xmm11,xmm11,xmm10 + mov r12,rax + ror r14,5 + xor r13,r11 + xor r12,rbx + vpxor xmm11,xmm11,xmm9 + ror r13,4 + xor r14,rdx + and r12,r11 + xor r13,r11 + vpaddq xmm2,xmm2,xmm11 + add rcx,QWORD[40+rsp] + mov rdi,rdx + xor r12,rbx + ror r14,6 + vpaddq xmm10,xmm2,XMMWORD[((-64))+rbp] + xor rdi,r8 + add rcx,r12 + ror r13,14 + and r15,rdi + xor r14,rdx + add rcx,r13 + xor r15,r8 + ror r14,28 + add r10,rcx + add rcx,r15 + mov r13,r10 + add r14,rcx + vmovdqa XMMWORD[32+rsp],xmm10 + vpalignr xmm8,xmm4,xmm3,8 + ror r13,23 + mov rcx,r14 + vpalignr xmm11,xmm0,xmm7,8 + mov r12,r11 + ror r14,5 +DB 143,72,120,195,200,56 + xor r13,r10 + xor r12,rax + vpsrlq xmm8,xmm8,7 + ror r13,4 + xor r14,rcx + vpaddq xmm3,xmm3,xmm11 + and r12,r10 + xor r13,r10 + add rbx,QWORD[48+rsp] + mov r15,rcx +DB 143,72,120,195,209,7 + xor r12,rax + ror r14,6 + vpxor xmm8,xmm8,xmm9 + xor r15,rdx + add rbx,r12 + ror r13,14 + and rdi,r15 +DB 143,104,120,195,218,3 + xor r14,rcx + add rbx,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,rdx + ror r14,28 + vpsrlq xmm10,xmm2,6 + add r9,rbx + add rbx,rdi + vpaddq xmm3,xmm3,xmm8 + mov r13,r9 + add r14,rbx +DB 143,72,120,195,203,42 + ror r13,23 + mov rbx,r14 + vpxor xmm11,xmm11,xmm10 + mov r12,r10 + ror r14,5 + xor r13,r9 + xor r12,r11 + vpxor xmm11,xmm11,xmm9 + ror r13,4 + xor r14,rbx + and r12,r9 + xor r13,r9 + vpaddq xmm3,xmm3,xmm11 + add rax,QWORD[56+rsp] + mov rdi,rbx + xor r12,r11 + ror r14,6 + vpaddq xmm10,xmm3,XMMWORD[((-32))+rbp] + xor rdi,rcx + add rax,r12 + ror r13,14 + and r15,rdi + xor r14,rbx + add rax,r13 + xor r15,rcx + ror r14,28 + add r8,rax + add rax,r15 + mov r13,r8 + add r14,rax + vmovdqa XMMWORD[48+rsp],xmm10 + vpalignr xmm8,xmm5,xmm4,8 + ror r13,23 + mov rax,r14 + vpalignr xmm11,xmm1,xmm0,8 + mov r12,r9 + ror r14,5 +DB 143,72,120,195,200,56 + xor r13,r8 + xor r12,r10 + vpsrlq xmm8,xmm8,7 + ror r13,4 + xor r14,rax + vpaddq xmm4,xmm4,xmm11 + and r12,r8 + xor r13,r8 + add r11,QWORD[64+rsp] + mov r15,rax +DB 143,72,120,195,209,7 + xor r12,r10 + ror r14,6 + vpxor xmm8,xmm8,xmm9 + xor r15,rbx + add r11,r12 + ror r13,14 + and rdi,r15 +DB 143,104,120,195,219,3 + xor r14,rax + add r11,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,rbx + ror r14,28 + vpsrlq xmm10,xmm3,6 + add rdx,r11 + add r11,rdi + vpaddq xmm4,xmm4,xmm8 + mov r13,rdx + add r14,r11 +DB 143,72,120,195,203,42 + ror r13,23 + mov r11,r14 + vpxor xmm11,xmm11,xmm10 + mov r12,r8 + ror r14,5 + xor r13,rdx + xor r12,r9 + vpxor xmm11,xmm11,xmm9 + ror r13,4 + xor r14,r11 + and r12,rdx + xor r13,rdx + vpaddq xmm4,xmm4,xmm11 + add r10,QWORD[72+rsp] + mov rdi,r11 + xor r12,r9 + ror r14,6 + vpaddq xmm10,xmm4,XMMWORD[rbp] + xor rdi,rax + add r10,r12 + ror r13,14 + and r15,rdi + xor r14,r11 + add r10,r13 + xor r15,rax + ror r14,28 + add rcx,r10 + add r10,r15 + mov r13,rcx + add r14,r10 + vmovdqa XMMWORD[64+rsp],xmm10 + vpalignr xmm8,xmm6,xmm5,8 + ror r13,23 + mov r10,r14 + vpalignr xmm11,xmm2,xmm1,8 + mov r12,rdx + ror r14,5 +DB 143,72,120,195,200,56 + xor r13,rcx + xor r12,r8 + vpsrlq xmm8,xmm8,7 + ror r13,4 + xor r14,r10 + vpaddq xmm5,xmm5,xmm11 + and r12,rcx + xor r13,rcx + add r9,QWORD[80+rsp] + mov r15,r10 +DB 143,72,120,195,209,7 + xor r12,r8 + ror r14,6 + vpxor xmm8,xmm8,xmm9 + xor r15,r11 + add r9,r12 + ror r13,14 + and rdi,r15 +DB 143,104,120,195,220,3 + xor r14,r10 + add r9,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,r11 + ror r14,28 + vpsrlq xmm10,xmm4,6 + add rbx,r9 + add r9,rdi + vpaddq xmm5,xmm5,xmm8 + mov r13,rbx + add r14,r9 +DB 143,72,120,195,203,42 + ror r13,23 + mov r9,r14 + vpxor xmm11,xmm11,xmm10 + mov r12,rcx + ror r14,5 + xor r13,rbx + xor r12,rdx + vpxor xmm11,xmm11,xmm9 + ror r13,4 + xor r14,r9 + and r12,rbx + xor r13,rbx + vpaddq xmm5,xmm5,xmm11 + add r8,QWORD[88+rsp] + mov rdi,r9 + xor r12,rdx + ror r14,6 + vpaddq xmm10,xmm5,XMMWORD[32+rbp] + xor rdi,r10 + add r8,r12 + ror r13,14 + and r15,rdi + xor r14,r9 + add r8,r13 + xor r15,r10 + ror r14,28 + add rax,r8 + add r8,r15 + mov r13,rax + add r14,r8 + vmovdqa XMMWORD[80+rsp],xmm10 + vpalignr xmm8,xmm7,xmm6,8 + ror r13,23 + mov r8,r14 + vpalignr xmm11,xmm3,xmm2,8 + mov r12,rbx + ror r14,5 +DB 143,72,120,195,200,56 + xor r13,rax + xor r12,rcx + vpsrlq xmm8,xmm8,7 + ror r13,4 + xor r14,r8 + vpaddq xmm6,xmm6,xmm11 + and r12,rax + xor r13,rax + add rdx,QWORD[96+rsp] + mov r15,r8 +DB 143,72,120,195,209,7 + xor r12,rcx + ror r14,6 + vpxor xmm8,xmm8,xmm9 + xor r15,r9 + add rdx,r12 + ror r13,14 + and rdi,r15 +DB 143,104,120,195,221,3 + xor r14,r8 + add rdx,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,r9 + ror r14,28 + vpsrlq xmm10,xmm5,6 + add r11,rdx + add rdx,rdi + vpaddq xmm6,xmm6,xmm8 + mov r13,r11 + add r14,rdx +DB 143,72,120,195,203,42 + ror r13,23 + mov rdx,r14 + vpxor xmm11,xmm11,xmm10 + mov r12,rax + ror r14,5 + xor r13,r11 + xor r12,rbx + vpxor xmm11,xmm11,xmm9 + ror r13,4 + xor r14,rdx + and r12,r11 + xor r13,r11 + vpaddq xmm6,xmm6,xmm11 + add rcx,QWORD[104+rsp] + mov rdi,rdx + xor r12,rbx + ror r14,6 + vpaddq xmm10,xmm6,XMMWORD[64+rbp] + xor rdi,r8 + add rcx,r12 + ror r13,14 + and r15,rdi + xor r14,rdx + add rcx,r13 + xor r15,r8 + ror r14,28 + add r10,rcx + add rcx,r15 + mov r13,r10 + add r14,rcx + vmovdqa XMMWORD[96+rsp],xmm10 + vpalignr xmm8,xmm0,xmm7,8 + ror r13,23 + mov rcx,r14 + vpalignr xmm11,xmm4,xmm3,8 + mov r12,r11 + ror r14,5 +DB 143,72,120,195,200,56 + xor r13,r10 + xor r12,rax + vpsrlq xmm8,xmm8,7 + ror r13,4 + xor r14,rcx + vpaddq xmm7,xmm7,xmm11 + and r12,r10 + xor r13,r10 + add rbx,QWORD[112+rsp] + mov r15,rcx +DB 143,72,120,195,209,7 + xor r12,rax + ror r14,6 + vpxor xmm8,xmm8,xmm9 + xor r15,rdx + add rbx,r12 + ror r13,14 + and rdi,r15 +DB 143,104,120,195,222,3 + xor r14,rcx + add rbx,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,rdx + ror r14,28 + vpsrlq xmm10,xmm6,6 + add r9,rbx + add rbx,rdi + vpaddq xmm7,xmm7,xmm8 + mov r13,r9 + add r14,rbx +DB 143,72,120,195,203,42 + ror r13,23 + mov rbx,r14 + vpxor xmm11,xmm11,xmm10 + mov r12,r10 + ror r14,5 + xor r13,r9 + xor r12,r11 + vpxor xmm11,xmm11,xmm9 + ror r13,4 + xor r14,rbx + and r12,r9 + xor r13,r9 + vpaddq xmm7,xmm7,xmm11 + add rax,QWORD[120+rsp] + mov rdi,rbx + xor r12,r11 + ror r14,6 + vpaddq xmm10,xmm7,XMMWORD[96+rbp] + xor rdi,rcx + add rax,r12 + ror r13,14 + and r15,rdi + xor r14,rbx + add rax,r13 + xor r15,rcx + ror r14,28 + add r8,rax + add rax,r15 + mov r13,r8 + add r14,rax + vmovdqa XMMWORD[112+rsp],xmm10 + cmp BYTE[135+rbp],0 + jne NEAR $L$xop_00_47 + ror r13,23 + mov rax,r14 + mov r12,r9 + ror r14,5 + xor r13,r8 + xor r12,r10 + ror r13,4 + xor r14,rax + and r12,r8 + xor r13,r8 + add r11,QWORD[rsp] + mov r15,rax + xor r12,r10 + ror r14,6 + xor r15,rbx + add r11,r12 + ror r13,14 + and rdi,r15 + xor r14,rax + add r11,r13 + xor rdi,rbx + ror r14,28 + add rdx,r11 + add r11,rdi + mov r13,rdx + add r14,r11 + ror r13,23 + mov r11,r14 + mov r12,r8 + ror r14,5 + xor r13,rdx + xor r12,r9 + ror r13,4 + xor r14,r11 + and r12,rdx + xor r13,rdx + add r10,QWORD[8+rsp] + mov rdi,r11 + xor r12,r9 + ror r14,6 + xor rdi,rax + add r10,r12 + ror r13,14 + and r15,rdi + xor r14,r11 + add r10,r13 + xor r15,rax + ror r14,28 + add rcx,r10 + add r10,r15 + mov r13,rcx + add r14,r10 + ror r13,23 + mov r10,r14 + mov r12,rdx + ror r14,5 + xor r13,rcx + xor r12,r8 + ror r13,4 + xor r14,r10 + and r12,rcx + xor r13,rcx + add r9,QWORD[16+rsp] + mov r15,r10 + xor r12,r8 + ror r14,6 + xor r15,r11 + add r9,r12 + ror r13,14 + and rdi,r15 + xor r14,r10 + add r9,r13 + xor rdi,r11 + ror r14,28 + add rbx,r9 + add r9,rdi + mov r13,rbx + add r14,r9 + ror r13,23 + mov r9,r14 + mov r12,rcx + ror r14,5 + xor r13,rbx + xor r12,rdx + ror r13,4 + xor r14,r9 + and r12,rbx + xor r13,rbx + add r8,QWORD[24+rsp] + mov rdi,r9 + xor r12,rdx + ror r14,6 + xor rdi,r10 + add r8,r12 + ror r13,14 + and r15,rdi + xor r14,r9 + add r8,r13 + xor r15,r10 + ror r14,28 + add rax,r8 + add r8,r15 + mov r13,rax + add r14,r8 + ror r13,23 + mov r8,r14 + mov r12,rbx + ror r14,5 + xor r13,rax + xor r12,rcx + ror r13,4 + xor r14,r8 + and r12,rax + xor r13,rax + add rdx,QWORD[32+rsp] + mov r15,r8 + xor r12,rcx + ror r14,6 + xor r15,r9 + add rdx,r12 + ror r13,14 + and rdi,r15 + xor r14,r8 + add rdx,r13 + xor rdi,r9 + ror r14,28 + add r11,rdx + add rdx,rdi + mov r13,r11 + add r14,rdx + ror r13,23 + mov rdx,r14 + mov r12,rax + ror r14,5 + xor r13,r11 + xor r12,rbx + ror r13,4 + xor r14,rdx + and r12,r11 + xor r13,r11 + add rcx,QWORD[40+rsp] + mov rdi,rdx + xor r12,rbx + ror r14,6 + xor rdi,r8 + add rcx,r12 + ror r13,14 + and r15,rdi + xor r14,rdx + add rcx,r13 + xor r15,r8 + ror r14,28 + add r10,rcx + add rcx,r15 + mov r13,r10 + add r14,rcx + ror r13,23 + mov rcx,r14 + mov r12,r11 + ror r14,5 + xor r13,r10 + xor r12,rax + ror r13,4 + xor r14,rcx + and r12,r10 + xor r13,r10 + add rbx,QWORD[48+rsp] + mov r15,rcx + xor r12,rax + ror r14,6 + xor r15,rdx + add rbx,r12 + ror r13,14 + and rdi,r15 + xor r14,rcx + add rbx,r13 + xor rdi,rdx + ror r14,28 + add r9,rbx + add rbx,rdi + mov r13,r9 + add r14,rbx + ror r13,23 + mov rbx,r14 + mov r12,r10 + ror r14,5 + xor r13,r9 + xor r12,r11 + ror r13,4 + xor r14,rbx + and r12,r9 + xor r13,r9 + add rax,QWORD[56+rsp] + mov rdi,rbx + xor r12,r11 + ror r14,6 + xor rdi,rcx + add rax,r12 + ror r13,14 + and r15,rdi + xor r14,rbx + add rax,r13 + xor r15,rcx + ror r14,28 + add r8,rax + add rax,r15 + mov r13,r8 + add r14,rax + ror r13,23 + mov rax,r14 + mov r12,r9 + ror r14,5 + xor r13,r8 + xor r12,r10 + ror r13,4 + xor r14,rax + and r12,r8 + xor r13,r8 + add r11,QWORD[64+rsp] + mov r15,rax + xor r12,r10 + ror r14,6 + xor r15,rbx + add r11,r12 + ror r13,14 + and rdi,r15 + xor r14,rax + add r11,r13 + xor rdi,rbx + ror r14,28 + add rdx,r11 + add r11,rdi + mov r13,rdx + add r14,r11 + ror r13,23 + mov r11,r14 + mov r12,r8 + ror r14,5 + xor r13,rdx + xor r12,r9 + ror r13,4 + xor r14,r11 + and r12,rdx + xor r13,rdx + add r10,QWORD[72+rsp] + mov rdi,r11 + xor r12,r9 + ror r14,6 + xor rdi,rax + add r10,r12 + ror r13,14 + and r15,rdi + xor r14,r11 + add r10,r13 + xor r15,rax + ror r14,28 + add rcx,r10 + add r10,r15 + mov r13,rcx + add r14,r10 + ror r13,23 + mov r10,r14 + mov r12,rdx + ror r14,5 + xor r13,rcx + xor r12,r8 + ror r13,4 + xor r14,r10 + and r12,rcx + xor r13,rcx + add r9,QWORD[80+rsp] + mov r15,r10 + xor r12,r8 + ror r14,6 + xor r15,r11 + add r9,r12 + ror r13,14 + and rdi,r15 + xor r14,r10 + add r9,r13 + xor rdi,r11 + ror r14,28 + add rbx,r9 + add r9,rdi + mov r13,rbx + add r14,r9 + ror r13,23 + mov r9,r14 + mov r12,rcx + ror r14,5 + xor r13,rbx + xor r12,rdx + ror r13,4 + xor r14,r9 + and r12,rbx + xor r13,rbx + add r8,QWORD[88+rsp] + mov rdi,r9 + xor r12,rdx + ror r14,6 + xor rdi,r10 + add r8,r12 + ror r13,14 + and r15,rdi + xor r14,r9 + add r8,r13 + xor r15,r10 + ror r14,28 + add rax,r8 + add r8,r15 + mov r13,rax + add r14,r8 + ror r13,23 + mov r8,r14 + mov r12,rbx + ror r14,5 + xor r13,rax + xor r12,rcx + ror r13,4 + xor r14,r8 + and r12,rax + xor r13,rax + add rdx,QWORD[96+rsp] + mov r15,r8 + xor r12,rcx + ror r14,6 + xor r15,r9 + add rdx,r12 + ror r13,14 + and rdi,r15 + xor r14,r8 + add rdx,r13 + xor rdi,r9 + ror r14,28 + add r11,rdx + add rdx,rdi + mov r13,r11 + add r14,rdx + ror r13,23 + mov rdx,r14 + mov r12,rax + ror r14,5 + xor r13,r11 + xor r12,rbx + ror r13,4 + xor r14,rdx + and r12,r11 + xor r13,r11 + add rcx,QWORD[104+rsp] + mov rdi,rdx + xor r12,rbx + ror r14,6 + xor rdi,r8 + add rcx,r12 + ror r13,14 + and r15,rdi + xor r14,rdx + add rcx,r13 + xor r15,r8 + ror r14,28 + add r10,rcx + add rcx,r15 + mov r13,r10 + add r14,rcx + ror r13,23 + mov rcx,r14 + mov r12,r11 + ror r14,5 + xor r13,r10 + xor r12,rax + ror r13,4 + xor r14,rcx + and r12,r10 + xor r13,r10 + add rbx,QWORD[112+rsp] + mov r15,rcx + xor r12,rax + ror r14,6 + xor r15,rdx + add rbx,r12 + ror r13,14 + and rdi,r15 + xor r14,rcx + add rbx,r13 + xor rdi,rdx + ror r14,28 + add r9,rbx + add rbx,rdi + mov r13,r9 + add r14,rbx + ror r13,23 + mov rbx,r14 + mov r12,r10 + ror r14,5 + xor r13,r9 + xor r12,r11 + ror r13,4 + xor r14,rbx + and r12,r9 + xor r13,r9 + add rax,QWORD[120+rsp] + mov rdi,rbx + xor r12,r11 + ror r14,6 + xor rdi,rcx + add rax,r12 + ror r13,14 + and r15,rdi + xor r14,rbx + add rax,r13 + xor r15,rcx + ror r14,28 + add r8,rax + add rax,r15 + mov r13,r8 + add r14,rax + mov rdi,QWORD[((128+0))+rsp] + mov rax,r14 + + add rax,QWORD[rdi] + lea rsi,[128+rsi] + add rbx,QWORD[8+rdi] + add rcx,QWORD[16+rdi] + add rdx,QWORD[24+rdi] + add r8,QWORD[32+rdi] + add r9,QWORD[40+rdi] + add r10,QWORD[48+rdi] + add r11,QWORD[56+rdi] + + cmp rsi,QWORD[((128+16))+rsp] + + mov QWORD[rdi],rax + mov QWORD[8+rdi],rbx + mov QWORD[16+rdi],rcx + mov QWORD[24+rdi],rdx + mov QWORD[32+rdi],r8 + mov QWORD[40+rdi],r9 + mov QWORD[48+rdi],r10 + mov QWORD[56+rdi],r11 + jb NEAR $L$loop_xop + + mov rsi,QWORD[((128+24))+rsp] + vzeroupper + movaps xmm6,XMMWORD[((128+32))+rsp] + movaps xmm7,XMMWORD[((128+48))+rsp] + movaps xmm8,XMMWORD[((128+64))+rsp] + movaps xmm9,XMMWORD[((128+80))+rsp] + movaps xmm10,XMMWORD[((128+96))+rsp] + movaps xmm11,XMMWORD[((128+112))+rsp] + mov r15,QWORD[rsi] + mov r14,QWORD[8+rsi] + mov r13,QWORD[16+rsi] + mov r12,QWORD[24+rsi] + mov rbp,QWORD[32+rsi] + mov rbx,QWORD[40+rsi] + lea rsp,[48+rsi] +$L$epilogue_xop: + mov rdi,QWORD[8+rsp] ;WIN64 epilogue + mov rsi,QWORD[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_sha512_block_data_order_xop: + +ALIGN 64 +sha512_block_data_order_avx: + mov QWORD[8+rsp],rdi ;WIN64 prologue + mov QWORD[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_sha512_block_data_order_avx: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + +$L$avx_shortcut: + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + mov r11,rsp + shl rdx,4 + sub rsp,256 + lea rdx,[rdx*8+rsi] + and rsp,-64 + mov QWORD[((128+0))+rsp],rdi + mov QWORD[((128+8))+rsp],rsi + mov QWORD[((128+16))+rsp],rdx + mov QWORD[((128+24))+rsp],r11 + movaps XMMWORD[(128+32)+rsp],xmm6 + movaps XMMWORD[(128+48)+rsp],xmm7 + movaps XMMWORD[(128+64)+rsp],xmm8 + movaps XMMWORD[(128+80)+rsp],xmm9 + movaps XMMWORD[(128+96)+rsp],xmm10 + movaps XMMWORD[(128+112)+rsp],xmm11 +$L$prologue_avx: + + vzeroupper + mov rax,QWORD[rdi] + mov rbx,QWORD[8+rdi] + mov rcx,QWORD[16+rdi] + mov rdx,QWORD[24+rdi] + mov r8,QWORD[32+rdi] + mov r9,QWORD[40+rdi] + mov r10,QWORD[48+rdi] + mov r11,QWORD[56+rdi] + jmp NEAR $L$loop_avx +ALIGN 16 +$L$loop_avx: + vmovdqa xmm11,XMMWORD[((K512+1280))] + vmovdqu xmm0,XMMWORD[rsi] + lea rbp,[((K512+128))] + vmovdqu xmm1,XMMWORD[16+rsi] + vmovdqu xmm2,XMMWORD[32+rsi] + vpshufb xmm0,xmm0,xmm11 + vmovdqu xmm3,XMMWORD[48+rsi] + vpshufb xmm1,xmm1,xmm11 + vmovdqu xmm4,XMMWORD[64+rsi] + vpshufb xmm2,xmm2,xmm11 + vmovdqu xmm5,XMMWORD[80+rsi] + vpshufb xmm3,xmm3,xmm11 + vmovdqu xmm6,XMMWORD[96+rsi] + vpshufb xmm4,xmm4,xmm11 + vmovdqu xmm7,XMMWORD[112+rsi] + vpshufb xmm5,xmm5,xmm11 + vpaddq xmm8,xmm0,XMMWORD[((-128))+rbp] + vpshufb xmm6,xmm6,xmm11 + vpaddq xmm9,xmm1,XMMWORD[((-96))+rbp] + vpshufb xmm7,xmm7,xmm11 + vpaddq xmm10,xmm2,XMMWORD[((-64))+rbp] + vpaddq xmm11,xmm3,XMMWORD[((-32))+rbp] + vmovdqa XMMWORD[rsp],xmm8 + vpaddq xmm8,xmm4,XMMWORD[rbp] + vmovdqa XMMWORD[16+rsp],xmm9 + vpaddq xmm9,xmm5,XMMWORD[32+rbp] + vmovdqa XMMWORD[32+rsp],xmm10 + vpaddq xmm10,xmm6,XMMWORD[64+rbp] + vmovdqa XMMWORD[48+rsp],xmm11 + vpaddq xmm11,xmm7,XMMWORD[96+rbp] + vmovdqa XMMWORD[64+rsp],xmm8 + mov r14,rax + vmovdqa XMMWORD[80+rsp],xmm9 + mov rdi,rbx + vmovdqa XMMWORD[96+rsp],xmm10 + xor rdi,rcx + vmovdqa XMMWORD[112+rsp],xmm11 + mov r13,r8 + jmp NEAR $L$avx_00_47 + +ALIGN 16 +$L$avx_00_47: + add rbp,256 + vpalignr xmm8,xmm1,xmm0,8 + shrd r13,r13,23 + mov rax,r14 + vpalignr xmm11,xmm5,xmm4,8 + mov r12,r9 + shrd r14,r14,5 + vpsrlq xmm10,xmm8,1 + xor r13,r8 + xor r12,r10 + vpaddq xmm0,xmm0,xmm11 + shrd r13,r13,4 + xor r14,rax + vpsrlq xmm11,xmm8,7 + and r12,r8 + xor r13,r8 + vpsllq xmm9,xmm8,56 + add r11,QWORD[rsp] + mov r15,rax + vpxor xmm8,xmm11,xmm10 + xor r12,r10 + shrd r14,r14,6 + vpsrlq xmm10,xmm10,7 + xor r15,rbx + add r11,r12 + vpxor xmm8,xmm8,xmm9 + shrd r13,r13,14 + and rdi,r15 + vpsllq xmm9,xmm9,7 + xor r14,rax + add r11,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,rbx + shrd r14,r14,28 + vpsrlq xmm11,xmm7,6 + add rdx,r11 + add r11,rdi + vpxor xmm8,xmm8,xmm9 + mov r13,rdx + add r14,r11 + vpsllq xmm10,xmm7,3 + shrd r13,r13,23 + mov r11,r14 + vpaddq xmm0,xmm0,xmm8 + mov r12,r8 + shrd r14,r14,5 + vpsrlq xmm9,xmm7,19 + xor r13,rdx + xor r12,r9 + vpxor xmm11,xmm11,xmm10 + shrd r13,r13,4 + xor r14,r11 + vpsllq xmm10,xmm10,42 + and r12,rdx + xor r13,rdx + vpxor xmm11,xmm11,xmm9 + add r10,QWORD[8+rsp] + mov rdi,r11 + vpsrlq xmm9,xmm9,42 + xor r12,r9 + shrd r14,r14,6 + vpxor xmm11,xmm11,xmm10 + xor rdi,rax + add r10,r12 + vpxor xmm11,xmm11,xmm9 + shrd r13,r13,14 + and r15,rdi + vpaddq xmm0,xmm0,xmm11 + xor r14,r11 + add r10,r13 + vpaddq xmm10,xmm0,XMMWORD[((-128))+rbp] + xor r15,rax + shrd r14,r14,28 + add rcx,r10 + add r10,r15 + mov r13,rcx + add r14,r10 + vmovdqa XMMWORD[rsp],xmm10 + vpalignr xmm8,xmm2,xmm1,8 + shrd r13,r13,23 + mov r10,r14 + vpalignr xmm11,xmm6,xmm5,8 + mov r12,rdx + shrd r14,r14,5 + vpsrlq xmm10,xmm8,1 + xor r13,rcx + xor r12,r8 + vpaddq xmm1,xmm1,xmm11 + shrd r13,r13,4 + xor r14,r10 + vpsrlq xmm11,xmm8,7 + and r12,rcx + xor r13,rcx + vpsllq xmm9,xmm8,56 + add r9,QWORD[16+rsp] + mov r15,r10 + vpxor xmm8,xmm11,xmm10 + xor r12,r8 + shrd r14,r14,6 + vpsrlq xmm10,xmm10,7 + xor r15,r11 + add r9,r12 + vpxor xmm8,xmm8,xmm9 + shrd r13,r13,14 + and rdi,r15 + vpsllq xmm9,xmm9,7 + xor r14,r10 + add r9,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,r11 + shrd r14,r14,28 + vpsrlq xmm11,xmm0,6 + add rbx,r9 + add r9,rdi + vpxor xmm8,xmm8,xmm9 + mov r13,rbx + add r14,r9 + vpsllq xmm10,xmm0,3 + shrd r13,r13,23 + mov r9,r14 + vpaddq xmm1,xmm1,xmm8 + mov r12,rcx + shrd r14,r14,5 + vpsrlq xmm9,xmm0,19 + xor r13,rbx + xor r12,rdx + vpxor xmm11,xmm11,xmm10 + shrd r13,r13,4 + xor r14,r9 + vpsllq xmm10,xmm10,42 + and r12,rbx + xor r13,rbx + vpxor xmm11,xmm11,xmm9 + add r8,QWORD[24+rsp] + mov rdi,r9 + vpsrlq xmm9,xmm9,42 + xor r12,rdx + shrd r14,r14,6 + vpxor xmm11,xmm11,xmm10 + xor rdi,r10 + add r8,r12 + vpxor xmm11,xmm11,xmm9 + shrd r13,r13,14 + and r15,rdi + vpaddq xmm1,xmm1,xmm11 + xor r14,r9 + add r8,r13 + vpaddq xmm10,xmm1,XMMWORD[((-96))+rbp] + xor r15,r10 + shrd r14,r14,28 + add rax,r8 + add r8,r15 + mov r13,rax + add r14,r8 + vmovdqa XMMWORD[16+rsp],xmm10 + vpalignr xmm8,xmm3,xmm2,8 + shrd r13,r13,23 + mov r8,r14 + vpalignr xmm11,xmm7,xmm6,8 + mov r12,rbx + shrd r14,r14,5 + vpsrlq xmm10,xmm8,1 + xor r13,rax + xor r12,rcx + vpaddq xmm2,xmm2,xmm11 + shrd r13,r13,4 + xor r14,r8 + vpsrlq xmm11,xmm8,7 + and r12,rax + xor r13,rax + vpsllq xmm9,xmm8,56 + add rdx,QWORD[32+rsp] + mov r15,r8 + vpxor xmm8,xmm11,xmm10 + xor r12,rcx + shrd r14,r14,6 + vpsrlq xmm10,xmm10,7 + xor r15,r9 + add rdx,r12 + vpxor xmm8,xmm8,xmm9 + shrd r13,r13,14 + and rdi,r15 + vpsllq xmm9,xmm9,7 + xor r14,r8 + add rdx,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,r9 + shrd r14,r14,28 + vpsrlq xmm11,xmm1,6 + add r11,rdx + add rdx,rdi + vpxor xmm8,xmm8,xmm9 + mov r13,r11 + add r14,rdx + vpsllq xmm10,xmm1,3 + shrd r13,r13,23 + mov rdx,r14 + vpaddq xmm2,xmm2,xmm8 + mov r12,rax + shrd r14,r14,5 + vpsrlq xmm9,xmm1,19 + xor r13,r11 + xor r12,rbx + vpxor xmm11,xmm11,xmm10 + shrd r13,r13,4 + xor r14,rdx + vpsllq xmm10,xmm10,42 + and r12,r11 + xor r13,r11 + vpxor xmm11,xmm11,xmm9 + add rcx,QWORD[40+rsp] + mov rdi,rdx + vpsrlq xmm9,xmm9,42 + xor r12,rbx + shrd r14,r14,6 + vpxor xmm11,xmm11,xmm10 + xor rdi,r8 + add rcx,r12 + vpxor xmm11,xmm11,xmm9 + shrd r13,r13,14 + and r15,rdi + vpaddq xmm2,xmm2,xmm11 + xor r14,rdx + add rcx,r13 + vpaddq xmm10,xmm2,XMMWORD[((-64))+rbp] + xor r15,r8 + shrd r14,r14,28 + add r10,rcx + add rcx,r15 + mov r13,r10 + add r14,rcx + vmovdqa XMMWORD[32+rsp],xmm10 + vpalignr xmm8,xmm4,xmm3,8 + shrd r13,r13,23 + mov rcx,r14 + vpalignr xmm11,xmm0,xmm7,8 + mov r12,r11 + shrd r14,r14,5 + vpsrlq xmm10,xmm8,1 + xor r13,r10 + xor r12,rax + vpaddq xmm3,xmm3,xmm11 + shrd r13,r13,4 + xor r14,rcx + vpsrlq xmm11,xmm8,7 + and r12,r10 + xor r13,r10 + vpsllq xmm9,xmm8,56 + add rbx,QWORD[48+rsp] + mov r15,rcx + vpxor xmm8,xmm11,xmm10 + xor r12,rax + shrd r14,r14,6 + vpsrlq xmm10,xmm10,7 + xor r15,rdx + add rbx,r12 + vpxor xmm8,xmm8,xmm9 + shrd r13,r13,14 + and rdi,r15 + vpsllq xmm9,xmm9,7 + xor r14,rcx + add rbx,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,rdx + shrd r14,r14,28 + vpsrlq xmm11,xmm2,6 + add r9,rbx + add rbx,rdi + vpxor xmm8,xmm8,xmm9 + mov r13,r9 + add r14,rbx + vpsllq xmm10,xmm2,3 + shrd r13,r13,23 + mov rbx,r14 + vpaddq xmm3,xmm3,xmm8 + mov r12,r10 + shrd r14,r14,5 + vpsrlq xmm9,xmm2,19 + xor r13,r9 + xor r12,r11 + vpxor xmm11,xmm11,xmm10 + shrd r13,r13,4 + xor r14,rbx + vpsllq xmm10,xmm10,42 + and r12,r9 + xor r13,r9 + vpxor xmm11,xmm11,xmm9 + add rax,QWORD[56+rsp] + mov rdi,rbx + vpsrlq xmm9,xmm9,42 + xor r12,r11 + shrd r14,r14,6 + vpxor xmm11,xmm11,xmm10 + xor rdi,rcx + add rax,r12 + vpxor xmm11,xmm11,xmm9 + shrd r13,r13,14 + and r15,rdi + vpaddq xmm3,xmm3,xmm11 + xor r14,rbx + add rax,r13 + vpaddq xmm10,xmm3,XMMWORD[((-32))+rbp] + xor r15,rcx + shrd r14,r14,28 + add r8,rax + add rax,r15 + mov r13,r8 + add r14,rax + vmovdqa XMMWORD[48+rsp],xmm10 + vpalignr xmm8,xmm5,xmm4,8 + shrd r13,r13,23 + mov rax,r14 + vpalignr xmm11,xmm1,xmm0,8 + mov r12,r9 + shrd r14,r14,5 + vpsrlq xmm10,xmm8,1 + xor r13,r8 + xor r12,r10 + vpaddq xmm4,xmm4,xmm11 + shrd r13,r13,4 + xor r14,rax + vpsrlq xmm11,xmm8,7 + and r12,r8 + xor r13,r8 + vpsllq xmm9,xmm8,56 + add r11,QWORD[64+rsp] + mov r15,rax + vpxor xmm8,xmm11,xmm10 + xor r12,r10 + shrd r14,r14,6 + vpsrlq xmm10,xmm10,7 + xor r15,rbx + add r11,r12 + vpxor xmm8,xmm8,xmm9 + shrd r13,r13,14 + and rdi,r15 + vpsllq xmm9,xmm9,7 + xor r14,rax + add r11,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,rbx + shrd r14,r14,28 + vpsrlq xmm11,xmm3,6 + add rdx,r11 + add r11,rdi + vpxor xmm8,xmm8,xmm9 + mov r13,rdx + add r14,r11 + vpsllq xmm10,xmm3,3 + shrd r13,r13,23 + mov r11,r14 + vpaddq xmm4,xmm4,xmm8 + mov r12,r8 + shrd r14,r14,5 + vpsrlq xmm9,xmm3,19 + xor r13,rdx + xor r12,r9 + vpxor xmm11,xmm11,xmm10 + shrd r13,r13,4 + xor r14,r11 + vpsllq xmm10,xmm10,42 + and r12,rdx + xor r13,rdx + vpxor xmm11,xmm11,xmm9 + add r10,QWORD[72+rsp] + mov rdi,r11 + vpsrlq xmm9,xmm9,42 + xor r12,r9 + shrd r14,r14,6 + vpxor xmm11,xmm11,xmm10 + xor rdi,rax + add r10,r12 + vpxor xmm11,xmm11,xmm9 + shrd r13,r13,14 + and r15,rdi + vpaddq xmm4,xmm4,xmm11 + xor r14,r11 + add r10,r13 + vpaddq xmm10,xmm4,XMMWORD[rbp] + xor r15,rax + shrd r14,r14,28 + add rcx,r10 + add r10,r15 + mov r13,rcx + add r14,r10 + vmovdqa XMMWORD[64+rsp],xmm10 + vpalignr xmm8,xmm6,xmm5,8 + shrd r13,r13,23 + mov r10,r14 + vpalignr xmm11,xmm2,xmm1,8 + mov r12,rdx + shrd r14,r14,5 + vpsrlq xmm10,xmm8,1 + xor r13,rcx + xor r12,r8 + vpaddq xmm5,xmm5,xmm11 + shrd r13,r13,4 + xor r14,r10 + vpsrlq xmm11,xmm8,7 + and r12,rcx + xor r13,rcx + vpsllq xmm9,xmm8,56 + add r9,QWORD[80+rsp] + mov r15,r10 + vpxor xmm8,xmm11,xmm10 + xor r12,r8 + shrd r14,r14,6 + vpsrlq xmm10,xmm10,7 + xor r15,r11 + add r9,r12 + vpxor xmm8,xmm8,xmm9 + shrd r13,r13,14 + and rdi,r15 + vpsllq xmm9,xmm9,7 + xor r14,r10 + add r9,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,r11 + shrd r14,r14,28 + vpsrlq xmm11,xmm4,6 + add rbx,r9 + add r9,rdi + vpxor xmm8,xmm8,xmm9 + mov r13,rbx + add r14,r9 + vpsllq xmm10,xmm4,3 + shrd r13,r13,23 + mov r9,r14 + vpaddq xmm5,xmm5,xmm8 + mov r12,rcx + shrd r14,r14,5 + vpsrlq xmm9,xmm4,19 + xor r13,rbx + xor r12,rdx + vpxor xmm11,xmm11,xmm10 + shrd r13,r13,4 + xor r14,r9 + vpsllq xmm10,xmm10,42 + and r12,rbx + xor r13,rbx + vpxor xmm11,xmm11,xmm9 + add r8,QWORD[88+rsp] + mov rdi,r9 + vpsrlq xmm9,xmm9,42 + xor r12,rdx + shrd r14,r14,6 + vpxor xmm11,xmm11,xmm10 + xor rdi,r10 + add r8,r12 + vpxor xmm11,xmm11,xmm9 + shrd r13,r13,14 + and r15,rdi + vpaddq xmm5,xmm5,xmm11 + xor r14,r9 + add r8,r13 + vpaddq xmm10,xmm5,XMMWORD[32+rbp] + xor r15,r10 + shrd r14,r14,28 + add rax,r8 + add r8,r15 + mov r13,rax + add r14,r8 + vmovdqa XMMWORD[80+rsp],xmm10 + vpalignr xmm8,xmm7,xmm6,8 + shrd r13,r13,23 + mov r8,r14 + vpalignr xmm11,xmm3,xmm2,8 + mov r12,rbx + shrd r14,r14,5 + vpsrlq xmm10,xmm8,1 + xor r13,rax + xor r12,rcx + vpaddq xmm6,xmm6,xmm11 + shrd r13,r13,4 + xor r14,r8 + vpsrlq xmm11,xmm8,7 + and r12,rax + xor r13,rax + vpsllq xmm9,xmm8,56 + add rdx,QWORD[96+rsp] + mov r15,r8 + vpxor xmm8,xmm11,xmm10 + xor r12,rcx + shrd r14,r14,6 + vpsrlq xmm10,xmm10,7 + xor r15,r9 + add rdx,r12 + vpxor xmm8,xmm8,xmm9 + shrd r13,r13,14 + and rdi,r15 + vpsllq xmm9,xmm9,7 + xor r14,r8 + add rdx,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,r9 + shrd r14,r14,28 + vpsrlq xmm11,xmm5,6 + add r11,rdx + add rdx,rdi + vpxor xmm8,xmm8,xmm9 + mov r13,r11 + add r14,rdx + vpsllq xmm10,xmm5,3 + shrd r13,r13,23 + mov rdx,r14 + vpaddq xmm6,xmm6,xmm8 + mov r12,rax + shrd r14,r14,5 + vpsrlq xmm9,xmm5,19 + xor r13,r11 + xor r12,rbx + vpxor xmm11,xmm11,xmm10 + shrd r13,r13,4 + xor r14,rdx + vpsllq xmm10,xmm10,42 + and r12,r11 + xor r13,r11 + vpxor xmm11,xmm11,xmm9 + add rcx,QWORD[104+rsp] + mov rdi,rdx + vpsrlq xmm9,xmm9,42 + xor r12,rbx + shrd r14,r14,6 + vpxor xmm11,xmm11,xmm10 + xor rdi,r8 + add rcx,r12 + vpxor xmm11,xmm11,xmm9 + shrd r13,r13,14 + and r15,rdi + vpaddq xmm6,xmm6,xmm11 + xor r14,rdx + add rcx,r13 + vpaddq xmm10,xmm6,XMMWORD[64+rbp] + xor r15,r8 + shrd r14,r14,28 + add r10,rcx + add rcx,r15 + mov r13,r10 + add r14,rcx + vmovdqa XMMWORD[96+rsp],xmm10 + vpalignr xmm8,xmm0,xmm7,8 + shrd r13,r13,23 + mov rcx,r14 + vpalignr xmm11,xmm4,xmm3,8 + mov r12,r11 + shrd r14,r14,5 + vpsrlq xmm10,xmm8,1 + xor r13,r10 + xor r12,rax + vpaddq xmm7,xmm7,xmm11 + shrd r13,r13,4 + xor r14,rcx + vpsrlq xmm11,xmm8,7 + and r12,r10 + xor r13,r10 + vpsllq xmm9,xmm8,56 + add rbx,QWORD[112+rsp] + mov r15,rcx + vpxor xmm8,xmm11,xmm10 + xor r12,rax + shrd r14,r14,6 + vpsrlq xmm10,xmm10,7 + xor r15,rdx + add rbx,r12 + vpxor xmm8,xmm8,xmm9 + shrd r13,r13,14 + and rdi,r15 + vpsllq xmm9,xmm9,7 + xor r14,rcx + add rbx,r13 + vpxor xmm8,xmm8,xmm10 + xor rdi,rdx + shrd r14,r14,28 + vpsrlq xmm11,xmm6,6 + add r9,rbx + add rbx,rdi + vpxor xmm8,xmm8,xmm9 + mov r13,r9 + add r14,rbx + vpsllq xmm10,xmm6,3 + shrd r13,r13,23 + mov rbx,r14 + vpaddq xmm7,xmm7,xmm8 + mov r12,r10 + shrd r14,r14,5 + vpsrlq xmm9,xmm6,19 + xor r13,r9 + xor r12,r11 + vpxor xmm11,xmm11,xmm10 + shrd r13,r13,4 + xor r14,rbx + vpsllq xmm10,xmm10,42 + and r12,r9 + xor r13,r9 + vpxor xmm11,xmm11,xmm9 + add rax,QWORD[120+rsp] + mov rdi,rbx + vpsrlq xmm9,xmm9,42 + xor r12,r11 + shrd r14,r14,6 + vpxor xmm11,xmm11,xmm10 + xor rdi,rcx + add rax,r12 + vpxor xmm11,xmm11,xmm9 + shrd r13,r13,14 + and r15,rdi + vpaddq xmm7,xmm7,xmm11 + xor r14,rbx + add rax,r13 + vpaddq xmm10,xmm7,XMMWORD[96+rbp] + xor r15,rcx + shrd r14,r14,28 + add r8,rax + add rax,r15 + mov r13,r8 + add r14,rax + vmovdqa XMMWORD[112+rsp],xmm10 + cmp BYTE[135+rbp],0 + jne NEAR $L$avx_00_47 + shrd r13,r13,23 + mov rax,r14 + mov r12,r9 + shrd r14,r14,5 + xor r13,r8 + xor r12,r10 + shrd r13,r13,4 + xor r14,rax + and r12,r8 + xor r13,r8 + add r11,QWORD[rsp] + mov r15,rax + xor r12,r10 + shrd r14,r14,6 + xor r15,rbx + add r11,r12 + shrd r13,r13,14 + and rdi,r15 + xor r14,rax + add r11,r13 + xor rdi,rbx + shrd r14,r14,28 + add rdx,r11 + add r11,rdi + mov r13,rdx + add r14,r11 + shrd r13,r13,23 + mov r11,r14 + mov r12,r8 + shrd r14,r14,5 + xor r13,rdx + xor r12,r9 + shrd r13,r13,4 + xor r14,r11 + and r12,rdx + xor r13,rdx + add r10,QWORD[8+rsp] + mov rdi,r11 + xor r12,r9 + shrd r14,r14,6 + xor rdi,rax + add r10,r12 + shrd r13,r13,14 + and r15,rdi + xor r14,r11 + add r10,r13 + xor r15,rax + shrd r14,r14,28 + add rcx,r10 + add r10,r15 + mov r13,rcx + add r14,r10 + shrd r13,r13,23 + mov r10,r14 + mov r12,rdx + shrd r14,r14,5 + xor r13,rcx + xor r12,r8 + shrd r13,r13,4 + xor r14,r10 + and r12,rcx + xor r13,rcx + add r9,QWORD[16+rsp] + mov r15,r10 + xor r12,r8 + shrd r14,r14,6 + xor r15,r11 + add r9,r12 + shrd r13,r13,14 + and rdi,r15 + xor r14,r10 + add r9,r13 + xor rdi,r11 + shrd r14,r14,28 + add rbx,r9 + add r9,rdi + mov r13,rbx + add r14,r9 + shrd r13,r13,23 + mov r9,r14 + mov r12,rcx + shrd r14,r14,5 + xor r13,rbx + xor r12,rdx + shrd r13,r13,4 + xor r14,r9 + and r12,rbx + xor r13,rbx + add r8,QWORD[24+rsp] + mov rdi,r9 + xor r12,rdx + shrd r14,r14,6 + xor rdi,r10 + add r8,r12 + shrd r13,r13,14 + and r15,rdi + xor r14,r9 + add r8,r13 + xor r15,r10 + shrd r14,r14,28 + add rax,r8 + add r8,r15 + mov r13,rax + add r14,r8 + shrd r13,r13,23 + mov r8,r14 + mov r12,rbx + shrd r14,r14,5 + xor r13,rax + xor r12,rcx + shrd r13,r13,4 + xor r14,r8 + and r12,rax + xor r13,rax + add rdx,QWORD[32+rsp] + mov r15,r8 + xor r12,rcx + shrd r14,r14,6 + xor r15,r9 + add rdx,r12 + shrd r13,r13,14 + and rdi,r15 + xor r14,r8 + add rdx,r13 + xor rdi,r9 + shrd r14,r14,28 + add r11,rdx + add rdx,rdi + mov r13,r11 + add r14,rdx + shrd r13,r13,23 + mov rdx,r14 + mov r12,rax + shrd r14,r14,5 + xor r13,r11 + xor r12,rbx + shrd r13,r13,4 + xor r14,rdx + and r12,r11 + xor r13,r11 + add rcx,QWORD[40+rsp] + mov rdi,rdx + xor r12,rbx + shrd r14,r14,6 + xor rdi,r8 + add rcx,r12 + shrd r13,r13,14 + and r15,rdi + xor r14,rdx + add rcx,r13 + xor r15,r8 + shrd r14,r14,28 + add r10,rcx + add rcx,r15 + mov r13,r10 + add r14,rcx + shrd r13,r13,23 + mov rcx,r14 + mov r12,r11 + shrd r14,r14,5 + xor r13,r10 + xor r12,rax + shrd r13,r13,4 + xor r14,rcx + and r12,r10 + xor r13,r10 + add rbx,QWORD[48+rsp] + mov r15,rcx + xor r12,rax + shrd r14,r14,6 + xor r15,rdx + add rbx,r12 + shrd r13,r13,14 + and rdi,r15 + xor r14,rcx + add rbx,r13 + xor rdi,rdx + shrd r14,r14,28 + add r9,rbx + add rbx,rdi + mov r13,r9 + add r14,rbx + shrd r13,r13,23 + mov rbx,r14 + mov r12,r10 + shrd r14,r14,5 + xor r13,r9 + xor r12,r11 + shrd r13,r13,4 + xor r14,rbx + and r12,r9 + xor r13,r9 + add rax,QWORD[56+rsp] + mov rdi,rbx + xor r12,r11 + shrd r14,r14,6 + xor rdi,rcx + add rax,r12 + shrd r13,r13,14 + and r15,rdi + xor r14,rbx + add rax,r13 + xor r15,rcx + shrd r14,r14,28 + add r8,rax + add rax,r15 + mov r13,r8 + add r14,rax + shrd r13,r13,23 + mov rax,r14 + mov r12,r9 + shrd r14,r14,5 + xor r13,r8 + xor r12,r10 + shrd r13,r13,4 + xor r14,rax + and r12,r8 + xor r13,r8 + add r11,QWORD[64+rsp] + mov r15,rax + xor r12,r10 + shrd r14,r14,6 + xor r15,rbx + add r11,r12 + shrd r13,r13,14 + and rdi,r15 + xor r14,rax + add r11,r13 + xor rdi,rbx + shrd r14,r14,28 + add rdx,r11 + add r11,rdi + mov r13,rdx + add r14,r11 + shrd r13,r13,23 + mov r11,r14 + mov r12,r8 + shrd r14,r14,5 + xor r13,rdx + xor r12,r9 + shrd r13,r13,4 + xor r14,r11 + and r12,rdx + xor r13,rdx + add r10,QWORD[72+rsp] + mov rdi,r11 + xor r12,r9 + shrd r14,r14,6 + xor rdi,rax + add r10,r12 + shrd r13,r13,14 + and r15,rdi + xor r14,r11 + add r10,r13 + xor r15,rax + shrd r14,r14,28 + add rcx,r10 + add r10,r15 + mov r13,rcx + add r14,r10 + shrd r13,r13,23 + mov r10,r14 + mov r12,rdx + shrd r14,r14,5 + xor r13,rcx + xor r12,r8 + shrd r13,r13,4 + xor r14,r10 + and r12,rcx + xor r13,rcx + add r9,QWORD[80+rsp] + mov r15,r10 + xor r12,r8 + shrd r14,r14,6 + xor r15,r11 + add r9,r12 + shrd r13,r13,14 + and rdi,r15 + xor r14,r10 + add r9,r13 + xor rdi,r11 + shrd r14,r14,28 + add rbx,r9 + add r9,rdi + mov r13,rbx + add r14,r9 + shrd r13,r13,23 + mov r9,r14 + mov r12,rcx + shrd r14,r14,5 + xor r13,rbx + xor r12,rdx + shrd r13,r13,4 + xor r14,r9 + and r12,rbx + xor r13,rbx + add r8,QWORD[88+rsp] + mov rdi,r9 + xor r12,rdx + shrd r14,r14,6 + xor rdi,r10 + add r8,r12 + shrd r13,r13,14 + and r15,rdi + xor r14,r9 + add r8,r13 + xor r15,r10 + shrd r14,r14,28 + add rax,r8 + add r8,r15 + mov r13,rax + add r14,r8 + shrd r13,r13,23 + mov r8,r14 + mov r12,rbx + shrd r14,r14,5 + xor r13,rax + xor r12,rcx + shrd r13,r13,4 + xor r14,r8 + and r12,rax + xor r13,rax + add rdx,QWORD[96+rsp] + mov r15,r8 + xor r12,rcx + shrd r14,r14,6 + xor r15,r9 + add rdx,r12 + shrd r13,r13,14 + and rdi,r15 + xor r14,r8 + add rdx,r13 + xor rdi,r9 + shrd r14,r14,28 + add r11,rdx + add rdx,rdi + mov r13,r11 + add r14,rdx + shrd r13,r13,23 + mov rdx,r14 + mov r12,rax + shrd r14,r14,5 + xor r13,r11 + xor r12,rbx + shrd r13,r13,4 + xor r14,rdx + and r12,r11 + xor r13,r11 + add rcx,QWORD[104+rsp] + mov rdi,rdx + xor r12,rbx + shrd r14,r14,6 + xor rdi,r8 + add rcx,r12 + shrd r13,r13,14 + and r15,rdi + xor r14,rdx + add rcx,r13 + xor r15,r8 + shrd r14,r14,28 + add r10,rcx + add rcx,r15 + mov r13,r10 + add r14,rcx + shrd r13,r13,23 + mov rcx,r14 + mov r12,r11 + shrd r14,r14,5 + xor r13,r10 + xor r12,rax + shrd r13,r13,4 + xor r14,rcx + and r12,r10 + xor r13,r10 + add rbx,QWORD[112+rsp] + mov r15,rcx + xor r12,rax + shrd r14,r14,6 + xor r15,rdx + add rbx,r12 + shrd r13,r13,14 + and rdi,r15 + xor r14,rcx + add rbx,r13 + xor rdi,rdx + shrd r14,r14,28 + add r9,rbx + add rbx,rdi + mov r13,r9 + add r14,rbx + shrd r13,r13,23 + mov rbx,r14 + mov r12,r10 + shrd r14,r14,5 + xor r13,r9 + xor r12,r11 + shrd r13,r13,4 + xor r14,rbx + and r12,r9 + xor r13,r9 + add rax,QWORD[120+rsp] + mov rdi,rbx + xor r12,r11 + shrd r14,r14,6 + xor rdi,rcx + add rax,r12 + shrd r13,r13,14 + and r15,rdi + xor r14,rbx + add rax,r13 + xor r15,rcx + shrd r14,r14,28 + add r8,rax + add rax,r15 + mov r13,r8 + add r14,rax + mov rdi,QWORD[((128+0))+rsp] + mov rax,r14 + + add rax,QWORD[rdi] + lea rsi,[128+rsi] + add rbx,QWORD[8+rdi] + add rcx,QWORD[16+rdi] + add rdx,QWORD[24+rdi] + add r8,QWORD[32+rdi] + add r9,QWORD[40+rdi] + add r10,QWORD[48+rdi] + add r11,QWORD[56+rdi] + + cmp rsi,QWORD[((128+16))+rsp] + + mov QWORD[rdi],rax + mov QWORD[8+rdi],rbx + mov QWORD[16+rdi],rcx + mov QWORD[24+rdi],rdx + mov QWORD[32+rdi],r8 + mov QWORD[40+rdi],r9 + mov QWORD[48+rdi],r10 + mov QWORD[56+rdi],r11 + jb NEAR $L$loop_avx + + mov rsi,QWORD[((128+24))+rsp] + vzeroupper + movaps xmm6,XMMWORD[((128+32))+rsp] + movaps xmm7,XMMWORD[((128+48))+rsp] + movaps xmm8,XMMWORD[((128+64))+rsp] + movaps xmm9,XMMWORD[((128+80))+rsp] + movaps xmm10,XMMWORD[((128+96))+rsp] + movaps xmm11,XMMWORD[((128+112))+rsp] + mov r15,QWORD[rsi] + mov r14,QWORD[8+rsi] + mov r13,QWORD[16+rsi] + mov r12,QWORD[24+rsi] + mov rbp,QWORD[32+rsi] + mov rbx,QWORD[40+rsi] + lea rsp,[48+rsi] +$L$epilogue_avx: + mov rdi,QWORD[8+rsp] ;WIN64 epilogue + mov rsi,QWORD[16+rsp] + DB 0F3h,0C3h ;repret +$L$SEH_end_sha512_block_data_order_avx: EXTERN __imp_RtlVirtualUnwind ALIGN 16 @@ -1903,9 +4190,23 @@ ALIGN 4 DD $L$SEH_begin_sha512_block_data_order wrt ..imagebase DD $L$SEH_end_sha512_block_data_order wrt ..imagebase DD $L$SEH_info_sha512_block_data_order wrt ..imagebase + DD $L$SEH_begin_sha512_block_data_order_xop wrt ..imagebase + DD $L$SEH_end_sha512_block_data_order_xop wrt ..imagebase + DD $L$SEH_info_sha512_block_data_order_xop wrt ..imagebase + DD $L$SEH_begin_sha512_block_data_order_avx wrt ..imagebase + DD $L$SEH_end_sha512_block_data_order_avx wrt ..imagebase + DD $L$SEH_info_sha512_block_data_order_avx wrt ..imagebase section .xdata rdata align=8 ALIGN 8 $L$SEH_info_sha512_block_data_order: DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$prologue wrt ..imagebase,$L$epilogue wrt ..imagebase +$L$SEH_info_sha512_block_data_order_xop: +DB 9,0,0,0 + DD se_handler wrt ..imagebase + DD $L$prologue_xop wrt ..imagebase,$L$epilogue_xop wrt ..imagebase +$L$SEH_info_sha512_block_data_order_avx: +DB 9,0,0,0 + DD se_handler wrt ..imagebase + DD $L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase |