external/boringssl: Sync to 0e9138d2.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/aa24851515d6280aa1d6a8b1548fe74691df3136..0e9138d295cd556e830dc8b3be735e808680f4bd
This requires some build tweaks:
- trusty's rules.mk builds with BORINGSSL_NO_CXX to suppress the new C++
scopers since they build their version of keymaster without the STL.
- BORINGSSL_ENABLE_RC4_TLS to temporarily keep RC4 in the TLS stack.
Change-Id: Ic688ec5779f649a4912b00fb2b55cba64fb07449
diff --git a/Android.bp b/Android.bp
index 98b2eee..f922302 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13,6 +13,8 @@
"-fvisibility=hidden",
"-DBORINGSSL_SHARED_LIBRARY",
"-DBORINGSSL_IMPLEMENTATION",
+ // TODO(davidben): Remove this once RC4 is no longer needed in Android.
+ "-DBORINGSSL_ENABLE_RC4_TLS",
"-DOPENSSL_SMALL",
"-D_XOPEN_SOURCE=700",
"-Wno-unused-parameter",
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index 9ae6769..0d5873b 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-aa24851515d6280aa1d6a8b1548fe74691df3136
+0e9138d295cd556e830dc8b3be735e808680f4bd
diff --git a/err_data.c b/err_data.c
index c9c56c1..1818f8d 100644
--- a/err_data.c
+++ b/err_data.c
@@ -178,42 +178,42 @@
0x28340c19,
0x283480ac,
0x283500ea,
- 0x2c322843,
- 0x2c32a851,
- 0x2c332863,
- 0x2c33a875,
- 0x2c342889,
- 0x2c34a89b,
- 0x2c3528b6,
- 0x2c35a8c8,
- 0x2c3628db,
+ 0x2c3228a2,
+ 0x2c32a8b0,
+ 0x2c3328c2,
+ 0x2c33a8d4,
+ 0x2c3428e8,
+ 0x2c34a8fa,
+ 0x2c352915,
+ 0x2c35a927,
+ 0x2c36293a,
0x2c36832d,
- 0x2c3728e8,
- 0x2c37a8fa,
- 0x2c38290d,
- 0x2c38a924,
- 0x2c392932,
- 0x2c39a942,
- 0x2c3a2954,
- 0x2c3aa968,
- 0x2c3b2979,
- 0x2c3ba998,
- 0x2c3c29ac,
- 0x2c3ca9c2,
- 0x2c3d29db,
- 0x2c3da9f8,
- 0x2c3e2a09,
- 0x2c3eaa17,
- 0x2c3f2a2f,
- 0x2c3faa47,
- 0x2c402a54,
+ 0x2c372947,
+ 0x2c37a959,
+ 0x2c38296c,
+ 0x2c38a983,
+ 0x2c392991,
+ 0x2c39a9a1,
+ 0x2c3a29b3,
+ 0x2c3aa9c7,
+ 0x2c3b29d8,
+ 0x2c3ba9f7,
+ 0x2c3c2a0b,
+ 0x2c3caa21,
+ 0x2c3d2a3a,
+ 0x2c3daa57,
+ 0x2c3e2a68,
+ 0x2c3eaa76,
+ 0x2c3f2a8e,
+ 0x2c3faaa6,
+ 0x2c402ab3,
0x2c4090e7,
- 0x2c412a65,
- 0x2c41aa78,
+ 0x2c412ac4,
+ 0x2c41aad7,
0x2c4210c0,
- 0x2c42aa89,
+ 0x2c42aae8,
0x2c430720,
- 0x2c43a98a,
+ 0x2c43a9e9,
0x30320000,
0x30328015,
0x3033001f,
@@ -366,174 +366,178 @@
0x403b9861,
0x403c0064,
0x403c8083,
- 0x403d1890,
- 0x403d98a6,
- 0x403e18b5,
- 0x403e98c8,
- 0x403f18e2,
- 0x403f98f0,
- 0x40401905,
- 0x40409919,
- 0x40411936,
- 0x40419951,
- 0x4042196a,
- 0x4042997d,
- 0x40431991,
- 0x404399a9,
- 0x404419c0,
+ 0x403d18aa,
+ 0x403d98c0,
+ 0x403e18cf,
+ 0x403e98e2,
+ 0x403f18fc,
+ 0x403f990a,
+ 0x4040191f,
+ 0x40409933,
+ 0x40411950,
+ 0x4041996b,
+ 0x40421984,
+ 0x40429997,
+ 0x404319ab,
+ 0x404399c3,
+ 0x404419da,
0x404480ac,
- 0x404519d5,
- 0x404599e7,
- 0x40461a0b,
- 0x40469a2b,
- 0x40471a39,
- 0x40479a60,
- 0x40481a89,
- 0x40489aa2,
- 0x40491ab9,
- 0x40499ad3,
- 0x404a1aea,
- 0x404a9b08,
- 0x404b1b20,
- 0x404b9b37,
- 0x404c1b4d,
- 0x404c9b5f,
- 0x404d1b80,
- 0x404d9ba2,
- 0x404e1bb6,
- 0x404e9bc3,
- 0x404f1bf0,
- 0x404f9c19,
- 0x40501c43,
- 0x40509c57,
- 0x40511c72,
- 0x40519c82,
- 0x40521c99,
- 0x40529cbd,
- 0x40531cd5,
- 0x40539ce8,
- 0x40541cfd,
- 0x40549d20,
- 0x40551d2e,
- 0x40559d4b,
- 0x40561d58,
- 0x40569d71,
- 0x40571d89,
- 0x40579d9c,
- 0x40581db1,
- 0x40589dc3,
- 0x40591df2,
- 0x40599e0b,
- 0x405a1e1f,
- 0x405a9e2f,
- 0x405b1e47,
- 0x405b9e58,
- 0x405c1e6b,
- 0x405c9e7c,
- 0x405d1e89,
- 0x405d9ea0,
- 0x405e1ec0,
+ 0x404519ef,
+ 0x40459a01,
+ 0x40461a25,
+ 0x40469a45,
+ 0x40471a53,
+ 0x40479a7a,
+ 0x40481aa3,
+ 0x40489abc,
+ 0x40491ad3,
+ 0x40499aed,
+ 0x404a1b04,
+ 0x404a9b22,
+ 0x404b1b3a,
+ 0x404b9b51,
+ 0x404c1b67,
+ 0x404c9b79,
+ 0x404d1b9a,
+ 0x404d9bbc,
+ 0x404e1bd0,
+ 0x404e9bdd,
+ 0x404f1c0a,
+ 0x404f9c33,
+ 0x40501c5d,
+ 0x40509c71,
+ 0x40511c8c,
+ 0x40519c9c,
+ 0x40521cb3,
+ 0x40529cd7,
+ 0x40531cef,
+ 0x40539d02,
+ 0x40541d17,
+ 0x40549d3a,
+ 0x40551d48,
+ 0x40559d65,
+ 0x40561d72,
+ 0x40569d8b,
+ 0x40571da3,
+ 0x40579db6,
+ 0x40581dcb,
+ 0x40589df2,
+ 0x40591e21,
+ 0x40599e3a,
+ 0x405a1e4e,
+ 0x405a9e5e,
+ 0x405b1e76,
+ 0x405b9e87,
+ 0x405c1e9a,
+ 0x405c9eab,
+ 0x405d1eb8,
+ 0x405d9ecf,
+ 0x405e1eef,
0x405e8a95,
- 0x405f1ee1,
- 0x405f9eee,
- 0x40601efc,
- 0x40609f1e,
- 0x40611f46,
- 0x40619f5b,
- 0x40621f72,
- 0x40629f83,
- 0x40631f94,
- 0x40639fa9,
- 0x40641fc0,
- 0x40649fd1,
- 0x40651fec,
- 0x4065a003,
- 0x4066201b,
- 0x4066a045,
- 0x40672070,
- 0x4067a091,
- 0x406820a4,
- 0x4068a0c5,
- 0x406920f7,
- 0x4069a125,
- 0x406a2146,
- 0x406aa166,
- 0x406b22ee,
- 0x406ba311,
- 0x406c2327,
- 0x406ca553,
- 0x406d2582,
- 0x406da5aa,
- 0x406e25c3,
- 0x406ea5db,
- 0x406f25fa,
- 0x406fa60f,
- 0x40702622,
- 0x4070a63f,
+ 0x405f1f10,
+ 0x405f9f1d,
+ 0x40601f2b,
+ 0x40609f4d,
+ 0x40611f75,
+ 0x40619f8a,
+ 0x40621fa1,
+ 0x40629fb2,
+ 0x40631fc3,
+ 0x40639fd8,
+ 0x40641fef,
+ 0x4064a01b,
+ 0x40652036,
+ 0x4065a04d,
+ 0x40662065,
+ 0x4066a08f,
+ 0x406720ba,
+ 0x4067a0db,
+ 0x406820ee,
+ 0x4068a10f,
+ 0x40692141,
+ 0x4069a16f,
+ 0x406a2190,
+ 0x406aa1b0,
+ 0x406b2338,
+ 0x406ba35b,
+ 0x406c2371,
+ 0x406ca59d,
+ 0x406d25cc,
+ 0x406da5f4,
+ 0x406e2622,
+ 0x406ea63a,
+ 0x406f2659,
+ 0x406fa66e,
+ 0x40702681,
+ 0x4070a69e,
0x40710800,
- 0x4071a651,
- 0x40722664,
- 0x4072a67d,
- 0x40732695,
+ 0x4071a6b0,
+ 0x407226c3,
+ 0x4072a6dc,
+ 0x407326f4,
0x4073936d,
- 0x407426a9,
- 0x4074a6c3,
- 0x407526d4,
- 0x4075a6e8,
- 0x407626f6,
+ 0x40742708,
+ 0x4074a722,
+ 0x40752733,
+ 0x4075a747,
+ 0x40762755,
0x407691aa,
- 0x4077271b,
- 0x4077a73d,
- 0x40782758,
- 0x4078a791,
- 0x407927a8,
- 0x4079a7be,
- 0x407a27ca,
- 0x407aa7dd,
- 0x407b27f2,
- 0x407ba804,
- 0x407c2819,
- 0x407ca822,
- 0x407d20e0,
- 0x407d9c29,
- 0x407e276d,
- 0x407e9dd3,
- 0x407f1a4d,
- 0x407f986d,
- 0x40801c00,
- 0x40809a75,
- 0x40811cab,
- 0x40819bda,
- 0x41f42219,
- 0x41f922ab,
- 0x41fe219e,
- 0x41fea37a,
- 0x41ff246b,
- 0x42032232,
- 0x42082254,
- 0x4208a290,
- 0x42092182,
- 0x4209a2ca,
- 0x420a21d9,
- 0x420aa1b9,
- 0x420b21f9,
- 0x420ba272,
- 0x420c2487,
- 0x420ca347,
- 0x420d2361,
- 0x420da398,
- 0x421223b2,
- 0x4217244e,
- 0x4217a3f4,
- 0x421c2416,
- 0x421f23d1,
- 0x4221249e,
- 0x42262431,
- 0x422b2537,
- 0x422ba500,
- 0x422c251f,
- 0x422ca4da,
- 0x422d24b9,
+ 0x4077277a,
+ 0x4077a79c,
+ 0x407827b7,
+ 0x4078a7f0,
+ 0x40792807,
+ 0x4079a81d,
+ 0x407a2829,
+ 0x407aa83c,
+ 0x407b2851,
+ 0x407ba863,
+ 0x407c2878,
+ 0x407ca881,
+ 0x407d212a,
+ 0x407d9c43,
+ 0x407e27cc,
+ 0x407e9e02,
+ 0x407f1a67,
+ 0x407f9887,
+ 0x40801c1a,
+ 0x40809a8f,
+ 0x40811cc5,
+ 0x40819bf4,
+ 0x4082260d,
+ 0x4082986d,
+ 0x40831ddd,
+ 0x4083a000,
+ 0x41f42263,
+ 0x41f922f5,
+ 0x41fe21e8,
+ 0x41fea3c4,
+ 0x41ff24b5,
+ 0x4203227c,
+ 0x4208229e,
+ 0x4208a2da,
+ 0x420921cc,
+ 0x4209a314,
+ 0x420a2223,
+ 0x420aa203,
+ 0x420b2243,
+ 0x420ba2bc,
+ 0x420c24d1,
+ 0x420ca391,
+ 0x420d23ab,
+ 0x420da3e2,
+ 0x421223fc,
+ 0x42172498,
+ 0x4217a43e,
+ 0x421c2460,
+ 0x421f241b,
+ 0x422124e8,
+ 0x4226247b,
+ 0x422b2581,
+ 0x422ba54a,
+ 0x422c2569,
+ 0x422ca524,
+ 0x422d2503,
0x4432072b,
0x4432873a,
0x44330746,
@@ -576,69 +580,69 @@
0x4c3d136d,
0x4c3d937c,
0x4c3e1389,
- 0x50322a9b,
- 0x5032aaaa,
- 0x50332ab5,
- 0x5033aac5,
- 0x50342ade,
- 0x5034aaf8,
- 0x50352b06,
- 0x5035ab1c,
- 0x50362b2e,
- 0x5036ab44,
- 0x50372b5d,
- 0x5037ab70,
- 0x50382b88,
- 0x5038ab99,
- 0x50392bae,
- 0x5039abc2,
- 0x503a2be2,
- 0x503aabf8,
- 0x503b2c10,
- 0x503bac22,
- 0x503c2c3e,
- 0x503cac55,
- 0x503d2c6e,
- 0x503dac84,
- 0x503e2c91,
- 0x503eaca7,
- 0x503f2cb9,
+ 0x50322afa,
+ 0x5032ab09,
+ 0x50332b14,
+ 0x5033ab24,
+ 0x50342b3d,
+ 0x5034ab57,
+ 0x50352b65,
+ 0x5035ab7b,
+ 0x50362b8d,
+ 0x5036aba3,
+ 0x50372bbc,
+ 0x5037abcf,
+ 0x50382be7,
+ 0x5038abf8,
+ 0x50392c0d,
+ 0x5039ac21,
+ 0x503a2c41,
+ 0x503aac57,
+ 0x503b2c6f,
+ 0x503bac81,
+ 0x503c2c9d,
+ 0x503cacb4,
+ 0x503d2ccd,
+ 0x503dace3,
+ 0x503e2cf0,
+ 0x503ead06,
+ 0x503f2d18,
0x503f8382,
- 0x50402ccc,
- 0x5040acdc,
- 0x50412cf6,
- 0x5041ad05,
- 0x50422d1f,
- 0x5042ad3c,
- 0x50432d4c,
- 0x5043ad5c,
- 0x50442d6b,
+ 0x50402d2b,
+ 0x5040ad3b,
+ 0x50412d55,
+ 0x5041ad64,
+ 0x50422d7e,
+ 0x5042ad9b,
+ 0x50432dab,
+ 0x5043adbb,
+ 0x50442dca,
0x5044843f,
- 0x50452d7f,
- 0x5045ad9d,
- 0x50462db0,
- 0x5046adc6,
- 0x50472dd8,
- 0x5047aded,
- 0x50482e13,
- 0x5048ae21,
- 0x50492e34,
- 0x5049ae49,
- 0x504a2e5f,
- 0x504aae6f,
- 0x504b2e8f,
- 0x504baea2,
- 0x504c2ec5,
- 0x504caef3,
- 0x504d2f05,
- 0x504daf22,
- 0x504e2f3d,
- 0x504eaf59,
- 0x504f2f6b,
- 0x504faf82,
- 0x50502f91,
+ 0x50452dde,
+ 0x5045adfc,
+ 0x50462e0f,
+ 0x5046ae25,
+ 0x50472e37,
+ 0x5047ae4c,
+ 0x50482e72,
+ 0x5048ae80,
+ 0x50492e93,
+ 0x5049aea8,
+ 0x504a2ebe,
+ 0x504aaece,
+ 0x504b2eee,
+ 0x504baf01,
+ 0x504c2f24,
+ 0x504caf52,
+ 0x504d2f64,
+ 0x504daf81,
+ 0x504e2f9c,
+ 0x504eafb8,
+ 0x504f2fca,
+ 0x504fafe1,
+ 0x50502ff0,
0x505086ef,
- 0x50512fa4,
+ 0x50513003,
0x58320ec9,
0x68320e8b,
0x68328c25,
@@ -999,6 +1003,7 @@
"BAD_SSL_FILETYPE\0"
"BAD_WRITE_RETRY\0"
"BIO_NOT_SET\0"
+ "BLOCK_CIPHER_PAD_IS_WRONG\0"
"BUFFERED_MESSAGES_ON_CIPHER_CHANGE\0"
"CA_DN_LENGTH_MISMATCH\0"
"CA_DN_TOO_LONG\0"
@@ -1060,6 +1065,7 @@
"NO_CERTIFICATE_SET\0"
"NO_CIPHERS_AVAILABLE\0"
"NO_CIPHERS_PASSED\0"
+ "NO_CIPHERS_SPECIFIED\0"
"NO_CIPHER_MATCH\0"
"NO_COMMON_SIGNATURE_ALGORITHMS\0"
"NO_COMPRESSION_SPECIFIED\0"
@@ -1084,6 +1090,7 @@
"READ_TIMEOUT_EXPIRED\0"
"RECORD_LENGTH_MISMATCH\0"
"RECORD_TOO_LARGE\0"
+ "RENEGOTIATION_EMS_MISMATCH\0"
"RENEGOTIATION_ENCODING_ERR\0"
"RENEGOTIATION_MISMATCH\0"
"REQUIRED_CIPHER_MISSING\0"
@@ -1134,6 +1141,7 @@
"TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0"
"TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\0"
"TOO_MANY_EMPTY_FRAGMENTS\0"
+ "TOO_MANY_KEY_UPDATES\0"
"TOO_MANY_WARNING_ALERTS\0"
"UNABLE_TO_FIND_ECDH_PARAMETERS\0"
"UNEXPECTED_EXTENSION\0"
diff --git a/linux-aarch64/crypto/aes/aesv8-armx64.S b/linux-aarch64/crypto/aes/aesv8-armx64.S
index 3e8cb16..5da12e4 100644
--- a/linux-aarch64/crypto/aes/aesv8-armx64.S
+++ b/linux-aarch64/crypto/aes/aesv8-armx64.S
@@ -3,7 +3,7 @@
#if __ARM_MAX_ARCH__>=7
.text
-#if !defined(__clang__)
+#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
.arch armv8-a+crypto
#endif
.align 5
diff --git a/linux-aarch64/crypto/modes/ghashv8-armx64.S b/linux-aarch64/crypto/modes/ghashv8-armx64.S
index f39f3ba..89d780f 100644
--- a/linux-aarch64/crypto/modes/ghashv8-armx64.S
+++ b/linux-aarch64/crypto/modes/ghashv8-armx64.S
@@ -2,7 +2,7 @@
#include <openssl/arm_arch.h>
.text
-#if !defined(__clang__)
+#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
.arch armv8-a+crypto
#endif
.globl gcm_init_v8
diff --git a/linux-x86/crypto/rc4/rc4-586.S b/linux-x86/crypto/rc4/rc4-586.S
deleted file mode 100644
index d245589..0000000
--- a/linux-x86/crypto/rc4/rc4-586.S
+++ /dev/null
@@ -1,350 +0,0 @@
-#if defined(__i386__)
-.file "rc4-586.S"
-.text
-.globl asm_RC4
-.hidden asm_RC4
-.type asm_RC4,@function
-.align 16
-asm_RC4:
-.L_asm_RC4_begin:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- movl 20(%esp),%edi
- movl 24(%esp),%edx
- movl 28(%esp),%esi
- movl 32(%esp),%ebp
- xorl %eax,%eax
- xorl %ebx,%ebx
- cmpl $0,%edx
- je .L000abort
- movb (%edi),%al
- movb 4(%edi),%bl
- addl $8,%edi
- leal (%esi,%edx,1),%ecx
- subl %esi,%ebp
- movl %ecx,24(%esp)
- incb %al
- cmpl $-1,256(%edi)
- je .L001RC4_CHAR
- movl (%edi,%eax,4),%ecx
- andl $-4,%edx
- jz .L002loop1
- movl %ebp,32(%esp)
- testl $-8,%edx
- jz .L003go4loop4
- call .L004PIC_me_up
-.L004PIC_me_up:
- popl %ebp
- leal OPENSSL_ia32cap_P-.L004PIC_me_up(%ebp),%ebp
- btl $26,(%ebp)
- jnc .L003go4loop4
- movl 32(%esp),%ebp
- andl $-8,%edx
- leal -8(%esi,%edx,1),%edx
- movl %edx,-4(%edi)
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- movq (%esi),%mm0
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm2
- jmp .L005loop_mmx_enter
-.align 16
-.L006loop_mmx:
- addb %cl,%bl
- psllq $56,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movq (%esi),%mm0
- movq %mm2,-8(%ebp,%esi,1)
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm2
-.L005loop_mmx_enter:
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm0,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $8,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $16,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $24,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $32,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $40,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $48,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- movl %ebx,%edx
- xorl %ebx,%ebx
- movb %dl,%bl
- cmpl -4(%edi),%esi
- leal 8(%esi),%esi
- jb .L006loop_mmx
- psllq $56,%mm1
- pxor %mm1,%mm2
- movq %mm2,-8(%ebp,%esi,1)
- emms
- cmpl 24(%esp),%esi
- je .L007done
- jmp .L002loop1
-.align 16
-.L003go4loop4:
- leal -4(%esi,%edx,1),%edx
- movl %edx,28(%esp)
-.L008loop4:
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- movl (%edi,%eax,4),%ecx
- movl (%edi,%edx,4),%ebp
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- rorl $8,%ebp
- movl (%edi,%eax,4),%ecx
- orl (%edi,%edx,4),%ebp
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- rorl $8,%ebp
- movl (%edi,%eax,4),%ecx
- orl (%edi,%edx,4),%ebp
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- rorl $8,%ebp
- movl 32(%esp),%ecx
- orl (%edi,%edx,4),%ebp
- rorl $8,%ebp
- xorl (%esi),%ebp
- cmpl 28(%esp),%esi
- movl %ebp,(%ecx,%esi,1)
- leal 4(%esi),%esi
- movl (%edi,%eax,4),%ecx
- jb .L008loop4
- cmpl 24(%esp),%esi
- je .L007done
- movl 32(%esp),%ebp
-.align 16
-.L002loop1:
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- movl (%edi,%edx,4),%edx
- xorb (%esi),%dl
- leal 1(%esi),%esi
- movl (%edi,%eax,4),%ecx
- cmpl 24(%esp),%esi
- movb %dl,-1(%ebp,%esi,1)
- jb .L002loop1
- jmp .L007done
-.align 16
-.L001RC4_CHAR:
- movzbl (%edi,%eax,1),%ecx
-.L009cloop1:
- addb %cl,%bl
- movzbl (%edi,%ebx,1),%edx
- movb %cl,(%edi,%ebx,1)
- movb %dl,(%edi,%eax,1)
- addb %cl,%dl
- movzbl (%edi,%edx,1),%edx
- addb $1,%al
- xorb (%esi),%dl
- leal 1(%esi),%esi
- movzbl (%edi,%eax,1),%ecx
- cmpl 24(%esp),%esi
- movb %dl,-1(%ebp,%esi,1)
- jb .L009cloop1
-.L007done:
- decb %al
- movl %ebx,-4(%edi)
- movb %al,-8(%edi)
-.L000abort:
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.size asm_RC4,.-.L_asm_RC4_begin
-.globl asm_RC4_set_key
-.hidden asm_RC4_set_key
-.type asm_RC4_set_key,@function
-.align 16
-asm_RC4_set_key:
-.L_asm_RC4_set_key_begin:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- movl 20(%esp),%edi
- movl 24(%esp),%ebp
- movl 28(%esp),%esi
- call .L010PIC_me_up
-.L010PIC_me_up:
- popl %edx
- leal OPENSSL_ia32cap_P-.L010PIC_me_up(%edx),%edx
- leal 8(%edi),%edi
- leal (%esi,%ebp,1),%esi
- negl %ebp
- xorl %eax,%eax
- movl %ebp,-4(%edi)
- btl $20,(%edx)
- jc .L011c1stloop
-.align 16
-.L012w1stloop:
- movl %eax,(%edi,%eax,4)
- addb $1,%al
- jnc .L012w1stloop
- xorl %ecx,%ecx
- xorl %edx,%edx
-.align 16
-.L013w2ndloop:
- movl (%edi,%ecx,4),%eax
- addb (%esi,%ebp,1),%dl
- addb %al,%dl
- addl $1,%ebp
- movl (%edi,%edx,4),%ebx
- jnz .L014wnowrap
- movl -4(%edi),%ebp
-.L014wnowrap:
- movl %eax,(%edi,%edx,4)
- movl %ebx,(%edi,%ecx,4)
- addb $1,%cl
- jnc .L013w2ndloop
- jmp .L015exit
-.align 16
-.L011c1stloop:
- movb %al,(%edi,%eax,1)
- addb $1,%al
- jnc .L011c1stloop
- xorl %ecx,%ecx
- xorl %edx,%edx
- xorl %ebx,%ebx
-.align 16
-.L016c2ndloop:
- movb (%edi,%ecx,1),%al
- addb (%esi,%ebp,1),%dl
- addb %al,%dl
- addl $1,%ebp
- movb (%edi,%edx,1),%bl
- jnz .L017cnowrap
- movl -4(%edi),%ebp
-.L017cnowrap:
- movb %al,(%edi,%edx,1)
- movb %bl,(%edi,%ecx,1)
- addb $1,%cl
- jnc .L016c2ndloop
- movl $-1,256(%edi)
-.L015exit:
- xorl %eax,%eax
- movl %eax,-8(%edi)
- movl %eax,-4(%edi)
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.size asm_RC4_set_key,.-.L_asm_RC4_set_key_begin
-#endif
diff --git a/linux-x86_64/crypto/rc4/rc4-x86_64.S b/linux-x86_64/crypto/rc4/rc4-x86_64.S
deleted file mode 100644
index c4d1002..0000000
--- a/linux-x86_64/crypto/rc4/rc4-x86_64.S
+++ /dev/null
@@ -1,596 +0,0 @@
-#if defined(__x86_64__)
-.text
-.extern OPENSSL_ia32cap_P
-.hidden OPENSSL_ia32cap_P
-
-.globl asm_RC4
-.hidden asm_RC4
-.type asm_RC4,@function
-.align 16
-asm_RC4:
- orq %rsi,%rsi
- jne .Lentry
- .byte 0xf3,0xc3
-.Lentry:
- pushq %rbx
- pushq %r12
- pushq %r13
-.Lprologue:
- movq %rsi,%r11
- movq %rdx,%r12
- movq %rcx,%r13
- xorq %r10,%r10
- xorq %rcx,%rcx
-
- leaq 8(%rdi),%rdi
- movb -8(%rdi),%r10b
- movb -4(%rdi),%cl
- cmpl $-1,256(%rdi)
- je .LRC4_CHAR
- movl OPENSSL_ia32cap_P(%rip),%r8d
- xorq %rbx,%rbx
- incb %r10b
- subq %r10,%rbx
- subq %r12,%r13
- movl (%rdi,%r10,4),%eax
- testq $-16,%r11
- jz .Lloop1
- btl $30,%r8d
- jc .Lintel
- andq $7,%rbx
- leaq 1(%r10),%rsi
- jz .Loop8
- subq %rbx,%r11
-.Loop8_warmup:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl %edx,(%rdi,%r10,4)
- addb %dl,%al
- incb %r10b
- movl (%rdi,%rax,4),%edx
- movl (%rdi,%r10,4),%eax
- xorb (%r12),%dl
- movb %dl,(%r12,%r13,1)
- leaq 1(%r12),%r12
- decq %rbx
- jnz .Loop8_warmup
-
- leaq 1(%r10),%rsi
- jmp .Loop8
-.align 16
-.Loop8:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl 0(%rdi,%rsi,4),%ebx
- rorq $8,%r8
- movl %edx,0(%rdi,%r10,4)
- addb %al,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %bl,%cl
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- movl 4(%rdi,%rsi,4),%eax
- rorq $8,%r8
- movl %edx,4(%rdi,%r10,4)
- addb %bl,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl 8(%rdi,%rsi,4),%ebx
- rorq $8,%r8
- movl %edx,8(%rdi,%r10,4)
- addb %al,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %bl,%cl
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- movl 12(%rdi,%rsi,4),%eax
- rorq $8,%r8
- movl %edx,12(%rdi,%r10,4)
- addb %bl,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl 16(%rdi,%rsi,4),%ebx
- rorq $8,%r8
- movl %edx,16(%rdi,%r10,4)
- addb %al,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %bl,%cl
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- movl 20(%rdi,%rsi,4),%eax
- rorq $8,%r8
- movl %edx,20(%rdi,%r10,4)
- addb %bl,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl 24(%rdi,%rsi,4),%ebx
- rorq $8,%r8
- movl %edx,24(%rdi,%r10,4)
- addb %al,%dl
- movb (%rdi,%rdx,4),%r8b
- addb $8,%sil
- addb %bl,%cl
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- movl -4(%rdi,%rsi,4),%eax
- rorq $8,%r8
- movl %edx,28(%rdi,%r10,4)
- addb %bl,%dl
- movb (%rdi,%rdx,4),%r8b
- addb $8,%r10b
- rorq $8,%r8
- subq $8,%r11
-
- xorq (%r12),%r8
- movq %r8,(%r12,%r13,1)
- leaq 8(%r12),%r12
-
- testq $-8,%r11
- jnz .Loop8
- cmpq $0,%r11
- jne .Lloop1
- jmp .Lexit
-
-.align 16
-.Lintel:
- testq $-32,%r11
- jz .Lloop1
- andq $15,%rbx
- jz .Loop16_is_hot
- subq %rbx,%r11
-.Loop16_warmup:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl %edx,(%rdi,%r10,4)
- addb %dl,%al
- incb %r10b
- movl (%rdi,%rax,4),%edx
- movl (%rdi,%r10,4),%eax
- xorb (%r12),%dl
- movb %dl,(%r12,%r13,1)
- leaq 1(%r12),%r12
- decq %rbx
- jnz .Loop16_warmup
-
- movq %rcx,%rbx
- xorq %rcx,%rcx
- movb %bl,%cl
-
-.Loop16_is_hot:
- leaq (%rdi,%r10,4),%rsi
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- pxor %xmm0,%xmm0
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 4(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,0(%rsi)
- addb %bl,%cl
- pinsrw $0,(%rdi,%rax,4),%xmm0
- jmp .Loop16_enter
-.align 16
-.Loop16:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- pxor %xmm0,%xmm2
- psllq $8,%xmm1
- pxor %xmm0,%xmm0
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 4(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,0(%rsi)
- pxor %xmm1,%xmm2
- addb %bl,%cl
- pinsrw $0,(%rdi,%rax,4),%xmm0
- movdqu %xmm2,(%r12,%r13,1)
- leaq 16(%r12),%r12
-.Loop16_enter:
- movl (%rdi,%rcx,4),%edx
- pxor %xmm1,%xmm1
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 8(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,4(%rsi)
- addb %al,%cl
- pinsrw $0,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 12(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,8(%rsi)
- addb %bl,%cl
- pinsrw $1,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 16(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,12(%rsi)
- addb %al,%cl
- pinsrw $1,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 20(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,16(%rsi)
- addb %bl,%cl
- pinsrw $2,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 24(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,20(%rsi)
- addb %al,%cl
- pinsrw $2,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 28(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,24(%rsi)
- addb %bl,%cl
- pinsrw $3,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 32(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,28(%rsi)
- addb %al,%cl
- pinsrw $3,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 36(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,32(%rsi)
- addb %bl,%cl
- pinsrw $4,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 40(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,36(%rsi)
- addb %al,%cl
- pinsrw $4,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 44(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,40(%rsi)
- addb %bl,%cl
- pinsrw $5,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 48(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,44(%rsi)
- addb %al,%cl
- pinsrw $5,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 52(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,48(%rsi)
- addb %bl,%cl
- pinsrw $6,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 56(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,52(%rsi)
- addb %al,%cl
- pinsrw $6,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 60(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,56(%rsi)
- addb %bl,%cl
- pinsrw $7,(%rdi,%rax,4),%xmm0
- addb $16,%r10b
- movdqu (%r12),%xmm2
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movzbl %bl,%ebx
- movl %edx,60(%rsi)
- leaq (%rdi,%r10,4),%rsi
- pinsrw $7,(%rdi,%rbx,4),%xmm1
- movl (%rsi),%eax
- movq %rcx,%rbx
- xorq %rcx,%rcx
- subq $16,%r11
- movb %bl,%cl
- testq $-16,%r11
- jnz .Loop16
-
- psllq $8,%xmm1
- pxor %xmm0,%xmm2
- pxor %xmm1,%xmm2
- movdqu %xmm2,(%r12,%r13,1)
- leaq 16(%r12),%r12
-
- cmpq $0,%r11
- jne .Lloop1
- jmp .Lexit
-
-.align 16
-.Lloop1:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl %edx,(%rdi,%r10,4)
- addb %dl,%al
- incb %r10b
- movl (%rdi,%rax,4),%edx
- movl (%rdi,%r10,4),%eax
- xorb (%r12),%dl
- movb %dl,(%r12,%r13,1)
- leaq 1(%r12),%r12
- decq %r11
- jnz .Lloop1
- jmp .Lexit
-
-.align 16
-.LRC4_CHAR:
- addb $1,%r10b
- movzbl (%rdi,%r10,1),%eax
- testq $-8,%r11
- jz .Lcloop1
- jmp .Lcloop8
-.align 16
-.Lcloop8:
- movl (%r12),%r8d
- movl 4(%r12),%r9d
- addb %al,%cl
- leaq 1(%r10),%rsi
- movzbl (%rdi,%rcx,1),%edx
- movzbl %sil,%esi
- movzbl (%rdi,%rsi,1),%ebx
- movb %al,(%rdi,%rcx,1)
- cmpq %rsi,%rcx
- movb %dl,(%rdi,%r10,1)
- jne .Lcmov0
- movq %rax,%rbx
-.Lcmov0:
- addb %al,%dl
- xorb (%rdi,%rdx,1),%r8b
- rorl $8,%r8d
- addb %bl,%cl
- leaq 1(%rsi),%r10
- movzbl (%rdi,%rcx,1),%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%eax
- movb %bl,(%rdi,%rcx,1)
- cmpq %r10,%rcx
- movb %dl,(%rdi,%rsi,1)
- jne .Lcmov1
- movq %rbx,%rax
-.Lcmov1:
- addb %bl,%dl
- xorb (%rdi,%rdx,1),%r8b
- rorl $8,%r8d
- addb %al,%cl
- leaq 1(%r10),%rsi
- movzbl (%rdi,%rcx,1),%edx
- movzbl %sil,%esi
- movzbl (%rdi,%rsi,1),%ebx
- movb %al,(%rdi,%rcx,1)
- cmpq %rsi,%rcx
- movb %dl,(%rdi,%r10,1)
- jne .Lcmov2
- movq %rax,%rbx
-.Lcmov2:
- addb %al,%dl
- xorb (%rdi,%rdx,1),%r8b
- rorl $8,%r8d
- addb %bl,%cl
- leaq 1(%rsi),%r10
- movzbl (%rdi,%rcx,1),%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%eax
- movb %bl,(%rdi,%rcx,1)
- cmpq %r10,%rcx
- movb %dl,(%rdi,%rsi,1)
- jne .Lcmov3
- movq %rbx,%rax
-.Lcmov3:
- addb %bl,%dl
- xorb (%rdi,%rdx,1),%r8b
- rorl $8,%r8d
- addb %al,%cl
- leaq 1(%r10),%rsi
- movzbl (%rdi,%rcx,1),%edx
- movzbl %sil,%esi
- movzbl (%rdi,%rsi,1),%ebx
- movb %al,(%rdi,%rcx,1)
- cmpq %rsi,%rcx
- movb %dl,(%rdi,%r10,1)
- jne .Lcmov4
- movq %rax,%rbx
-.Lcmov4:
- addb %al,%dl
- xorb (%rdi,%rdx,1),%r9b
- rorl $8,%r9d
- addb %bl,%cl
- leaq 1(%rsi),%r10
- movzbl (%rdi,%rcx,1),%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%eax
- movb %bl,(%rdi,%rcx,1)
- cmpq %r10,%rcx
- movb %dl,(%rdi,%rsi,1)
- jne .Lcmov5
- movq %rbx,%rax
-.Lcmov5:
- addb %bl,%dl
- xorb (%rdi,%rdx,1),%r9b
- rorl $8,%r9d
- addb %al,%cl
- leaq 1(%r10),%rsi
- movzbl (%rdi,%rcx,1),%edx
- movzbl %sil,%esi
- movzbl (%rdi,%rsi,1),%ebx
- movb %al,(%rdi,%rcx,1)
- cmpq %rsi,%rcx
- movb %dl,(%rdi,%r10,1)
- jne .Lcmov6
- movq %rax,%rbx
-.Lcmov6:
- addb %al,%dl
- xorb (%rdi,%rdx,1),%r9b
- rorl $8,%r9d
- addb %bl,%cl
- leaq 1(%rsi),%r10
- movzbl (%rdi,%rcx,1),%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%eax
- movb %bl,(%rdi,%rcx,1)
- cmpq %r10,%rcx
- movb %dl,(%rdi,%rsi,1)
- jne .Lcmov7
- movq %rbx,%rax
-.Lcmov7:
- addb %bl,%dl
- xorb (%rdi,%rdx,1),%r9b
- rorl $8,%r9d
- leaq -8(%r11),%r11
- movl %r8d,(%r13)
- leaq 8(%r12),%r12
- movl %r9d,4(%r13)
- leaq 8(%r13),%r13
-
- testq $-8,%r11
- jnz .Lcloop8
- cmpq $0,%r11
- jne .Lcloop1
- jmp .Lexit
-.align 16
-.Lcloop1:
- addb %al,%cl
- movzbl %cl,%ecx
- movzbl (%rdi,%rcx,1),%edx
- movb %al,(%rdi,%rcx,1)
- movb %dl,(%rdi,%r10,1)
- addb %al,%dl
- addb $1,%r10b
- movzbl %dl,%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%rdx,1),%edx
- movzbl (%rdi,%r10,1),%eax
- xorb (%r12),%dl
- leaq 1(%r12),%r12
- movb %dl,(%r13)
- leaq 1(%r13),%r13
- subq $1,%r11
- jnz .Lcloop1
- jmp .Lexit
-
-.align 16
-.Lexit:
- subb $1,%r10b
- movl %r10d,-8(%rdi)
- movl %ecx,-4(%rdi)
-
- movq (%rsp),%r13
- movq 8(%rsp),%r12
- movq 16(%rsp),%rbx
- addq $24,%rsp
-.Lepilogue:
- .byte 0xf3,0xc3
-.size asm_RC4,.-asm_RC4
-.globl asm_RC4_set_key
-.hidden asm_RC4_set_key
-.type asm_RC4_set_key,@function
-.align 16
-asm_RC4_set_key:
- leaq 8(%rdi),%rdi
- leaq (%rdx,%rsi,1),%rdx
- negq %rsi
- movq %rsi,%rcx
- xorl %eax,%eax
- xorq %r9,%r9
- xorq %r10,%r10
- xorq %r11,%r11
-
- movl OPENSSL_ia32cap_P(%rip),%r8d
- btl $20,%r8d
- jc .Lc1stloop
- jmp .Lw1stloop
-
-.align 16
-.Lw1stloop:
- movl %eax,(%rdi,%rax,4)
- addb $1,%al
- jnc .Lw1stloop
-
- xorq %r9,%r9
- xorq %r8,%r8
-.align 16
-.Lw2ndloop:
- movl (%rdi,%r9,4),%r10d
- addb (%rdx,%rsi,1),%r8b
- addb %r10b,%r8b
- addq $1,%rsi
- movl (%rdi,%r8,4),%r11d
- cmovzq %rcx,%rsi
- movl %r10d,(%rdi,%r8,4)
- movl %r11d,(%rdi,%r9,4)
- addb $1,%r9b
- jnc .Lw2ndloop
- jmp .Lexit_key
-
-.align 16
-.Lc1stloop:
- movb %al,(%rdi,%rax,1)
- addb $1,%al
- jnc .Lc1stloop
-
- xorq %r9,%r9
- xorq %r8,%r8
-.align 16
-.Lc2ndloop:
- movb (%rdi,%r9,1),%r10b
- addb (%rdx,%rsi,1),%r8b
- addb %r10b,%r8b
- addq $1,%rsi
- movb (%rdi,%r8,1),%r11b
- jnz .Lcnowrap
- movq %rcx,%rsi
-.Lcnowrap:
- movb %r10b,(%rdi,%r8,1)
- movb %r11b,(%rdi,%r9,1)
- addb $1,%r9b
- jnc .Lc2ndloop
- movl $-1,256(%rdi)
-
-.align 16
-.Lexit_key:
- xorl %eax,%eax
- movl %eax,-8(%rdi)
- movl %eax,-4(%rdi)
- .byte 0xf3,0xc3
-.size asm_RC4_set_key,.-asm_RC4_set_key
-#endif
diff --git a/mac-x86/crypto/rc4/rc4-586.S b/mac-x86/crypto/rc4/rc4-586.S
deleted file mode 100644
index dcddc58..0000000
--- a/mac-x86/crypto/rc4/rc4-586.S
+++ /dev/null
@@ -1,350 +0,0 @@
-#if defined(__i386__)
-.file "rc4-586.S"
-.text
-.globl _asm_RC4
-.private_extern _asm_RC4
-.align 4
-_asm_RC4:
-L_asm_RC4_begin:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- movl 20(%esp),%edi
- movl 24(%esp),%edx
- movl 28(%esp),%esi
- movl 32(%esp),%ebp
- xorl %eax,%eax
- xorl %ebx,%ebx
- cmpl $0,%edx
- je L000abort
- movb (%edi),%al
- movb 4(%edi),%bl
- addl $8,%edi
- leal (%esi,%edx,1),%ecx
- subl %esi,%ebp
- movl %ecx,24(%esp)
- incb %al
- cmpl $-1,256(%edi)
- je L001RC4_CHAR
- movl (%edi,%eax,4),%ecx
- andl $-4,%edx
- jz L002loop1
- movl %ebp,32(%esp)
- testl $-8,%edx
- jz L003go4loop4
- call L004PIC_me_up
-L004PIC_me_up:
- popl %ebp
- movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L004PIC_me_up(%ebp),%ebp
- btl $26,(%ebp)
- jnc L003go4loop4
- movl 32(%esp),%ebp
- andl $-8,%edx
- leal -8(%esi,%edx,1),%edx
- movl %edx,-4(%edi)
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- movq (%esi),%mm0
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm2
- jmp L005loop_mmx_enter
-.align 4,0x90
-L006loop_mmx:
- addb %cl,%bl
- psllq $56,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movq (%esi),%mm0
- movq %mm2,-8(%ebp,%esi,1)
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm2
-L005loop_mmx_enter:
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm0,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $8,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $16,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $24,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $32,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $40,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- addb %cl,%bl
- psllq $48,%mm1
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- incl %eax
- addl %ecx,%edx
- movzbl %al,%eax
- movzbl %dl,%edx
- pxor %mm1,%mm2
- movl (%edi,%eax,4),%ecx
- movd (%edi,%edx,4),%mm1
- movl %ebx,%edx
- xorl %ebx,%ebx
- movb %dl,%bl
- cmpl -4(%edi),%esi
- leal 8(%esi),%esi
- jb L006loop_mmx
- psllq $56,%mm1
- pxor %mm1,%mm2
- movq %mm2,-8(%ebp,%esi,1)
- emms
- cmpl 24(%esp),%esi
- je L007done
- jmp L002loop1
-.align 4,0x90
-L003go4loop4:
- leal -4(%esi,%edx,1),%edx
- movl %edx,28(%esp)
-L008loop4:
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- movl (%edi,%eax,4),%ecx
- movl (%edi,%edx,4),%ebp
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- rorl $8,%ebp
- movl (%edi,%eax,4),%ecx
- orl (%edi,%edx,4),%ebp
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- rorl $8,%ebp
- movl (%edi,%eax,4),%ecx
- orl (%edi,%edx,4),%ebp
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- rorl $8,%ebp
- movl 32(%esp),%ecx
- orl (%edi,%edx,4),%ebp
- rorl $8,%ebp
- xorl (%esi),%ebp
- cmpl 28(%esp),%esi
- movl %ebp,(%ecx,%esi,1)
- leal 4(%esi),%esi
- movl (%edi,%eax,4),%ecx
- jb L008loop4
- cmpl 24(%esp),%esi
- je L007done
- movl 32(%esp),%ebp
-.align 4,0x90
-L002loop1:
- addb %cl,%bl
- movl (%edi,%ebx,4),%edx
- movl %ecx,(%edi,%ebx,4)
- movl %edx,(%edi,%eax,4)
- addl %ecx,%edx
- incb %al
- andl $255,%edx
- movl (%edi,%edx,4),%edx
- xorb (%esi),%dl
- leal 1(%esi),%esi
- movl (%edi,%eax,4),%ecx
- cmpl 24(%esp),%esi
- movb %dl,-1(%ebp,%esi,1)
- jb L002loop1
- jmp L007done
-.align 4,0x90
-L001RC4_CHAR:
- movzbl (%edi,%eax,1),%ecx
-L009cloop1:
- addb %cl,%bl
- movzbl (%edi,%ebx,1),%edx
- movb %cl,(%edi,%ebx,1)
- movb %dl,(%edi,%eax,1)
- addb %cl,%dl
- movzbl (%edi,%edx,1),%edx
- addb $1,%al
- xorb (%esi),%dl
- leal 1(%esi),%esi
- movzbl (%edi,%eax,1),%ecx
- cmpl 24(%esp),%esi
- movb %dl,-1(%ebp,%esi,1)
- jb L009cloop1
-L007done:
- decb %al
- movl %ebx,-4(%edi)
- movb %al,-8(%edi)
-L000abort:
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.globl _asm_RC4_set_key
-.private_extern _asm_RC4_set_key
-.align 4
-_asm_RC4_set_key:
-L_asm_RC4_set_key_begin:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- movl 20(%esp),%edi
- movl 24(%esp),%ebp
- movl 28(%esp),%esi
- call L010PIC_me_up
-L010PIC_me_up:
- popl %edx
- movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L010PIC_me_up(%edx),%edx
- leal 8(%edi),%edi
- leal (%esi,%ebp,1),%esi
- negl %ebp
- xorl %eax,%eax
- movl %ebp,-4(%edi)
- btl $20,(%edx)
- jc L011c1stloop
-.align 4,0x90
-L012w1stloop:
- movl %eax,(%edi,%eax,4)
- addb $1,%al
- jnc L012w1stloop
- xorl %ecx,%ecx
- xorl %edx,%edx
-.align 4,0x90
-L013w2ndloop:
- movl (%edi,%ecx,4),%eax
- addb (%esi,%ebp,1),%dl
- addb %al,%dl
- addl $1,%ebp
- movl (%edi,%edx,4),%ebx
- jnz L014wnowrap
- movl -4(%edi),%ebp
-L014wnowrap:
- movl %eax,(%edi,%edx,4)
- movl %ebx,(%edi,%ecx,4)
- addb $1,%cl
- jnc L013w2ndloop
- jmp L015exit
-.align 4,0x90
-L011c1stloop:
- movb %al,(%edi,%eax,1)
- addb $1,%al
- jnc L011c1stloop
- xorl %ecx,%ecx
- xorl %edx,%edx
- xorl %ebx,%ebx
-.align 4,0x90
-L016c2ndloop:
- movb (%edi,%ecx,1),%al
- addb (%esi,%ebp,1),%dl
- addb %al,%dl
- addl $1,%ebp
- movb (%edi,%edx,1),%bl
- jnz L017cnowrap
- movl -4(%edi),%ebp
-L017cnowrap:
- movb %al,(%edi,%edx,1)
- movb %bl,(%edi,%ecx,1)
- addb $1,%cl
- jnc L016c2ndloop
- movl $-1,256(%edi)
-L015exit:
- xorl %eax,%eax
- movl %eax,-8(%edi)
- movl %eax,-4(%edi)
- 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
-.long 0
-#endif
diff --git a/mac-x86_64/crypto/rc4/rc4-x86_64.S b/mac-x86_64/crypto/rc4/rc4-x86_64.S
deleted file mode 100644
index 7808184..0000000
--- a/mac-x86_64/crypto/rc4/rc4-x86_64.S
+++ /dev/null
@@ -1,595 +0,0 @@
-#if defined(__x86_64__)
-.text
-
-
-.globl _asm_RC4
-.private_extern _asm_RC4
-
-.p2align 4
-_asm_RC4:
- orq %rsi,%rsi
- jne L$entry
- .byte 0xf3,0xc3
-L$entry:
- pushq %rbx
- pushq %r12
- pushq %r13
-L$prologue:
- movq %rsi,%r11
- movq %rdx,%r12
- movq %rcx,%r13
- xorq %r10,%r10
- xorq %rcx,%rcx
-
- leaq 8(%rdi),%rdi
- movb -8(%rdi),%r10b
- movb -4(%rdi),%cl
- cmpl $-1,256(%rdi)
- je L$RC4_CHAR
- movl _OPENSSL_ia32cap_P(%rip),%r8d
- xorq %rbx,%rbx
- incb %r10b
- subq %r10,%rbx
- subq %r12,%r13
- movl (%rdi,%r10,4),%eax
- testq $-16,%r11
- jz L$loop1
- btl $30,%r8d
- jc L$intel
- andq $7,%rbx
- leaq 1(%r10),%rsi
- jz L$oop8
- subq %rbx,%r11
-L$oop8_warmup:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl %edx,(%rdi,%r10,4)
- addb %dl,%al
- incb %r10b
- movl (%rdi,%rax,4),%edx
- movl (%rdi,%r10,4),%eax
- xorb (%r12),%dl
- movb %dl,(%r12,%r13,1)
- leaq 1(%r12),%r12
- decq %rbx
- jnz L$oop8_warmup
-
- leaq 1(%r10),%rsi
- jmp L$oop8
-.p2align 4
-L$oop8:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl 0(%rdi,%rsi,4),%ebx
- rorq $8,%r8
- movl %edx,0(%rdi,%r10,4)
- addb %al,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %bl,%cl
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- movl 4(%rdi,%rsi,4),%eax
- rorq $8,%r8
- movl %edx,4(%rdi,%r10,4)
- addb %bl,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl 8(%rdi,%rsi,4),%ebx
- rorq $8,%r8
- movl %edx,8(%rdi,%r10,4)
- addb %al,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %bl,%cl
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- movl 12(%rdi,%rsi,4),%eax
- rorq $8,%r8
- movl %edx,12(%rdi,%r10,4)
- addb %bl,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl 16(%rdi,%rsi,4),%ebx
- rorq $8,%r8
- movl %edx,16(%rdi,%r10,4)
- addb %al,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %bl,%cl
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- movl 20(%rdi,%rsi,4),%eax
- rorq $8,%r8
- movl %edx,20(%rdi,%r10,4)
- addb %bl,%dl
- movb (%rdi,%rdx,4),%r8b
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl 24(%rdi,%rsi,4),%ebx
- rorq $8,%r8
- movl %edx,24(%rdi,%r10,4)
- addb %al,%dl
- movb (%rdi,%rdx,4),%r8b
- addb $8,%sil
- addb %bl,%cl
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- movl -4(%rdi,%rsi,4),%eax
- rorq $8,%r8
- movl %edx,28(%rdi,%r10,4)
- addb %bl,%dl
- movb (%rdi,%rdx,4),%r8b
- addb $8,%r10b
- rorq $8,%r8
- subq $8,%r11
-
- xorq (%r12),%r8
- movq %r8,(%r12,%r13,1)
- leaq 8(%r12),%r12
-
- testq $-8,%r11
- jnz L$oop8
- cmpq $0,%r11
- jne L$loop1
- jmp L$exit
-
-.p2align 4
-L$intel:
- testq $-32,%r11
- jz L$loop1
- andq $15,%rbx
- jz L$oop16_is_hot
- subq %rbx,%r11
-L$oop16_warmup:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl %edx,(%rdi,%r10,4)
- addb %dl,%al
- incb %r10b
- movl (%rdi,%rax,4),%edx
- movl (%rdi,%r10,4),%eax
- xorb (%r12),%dl
- movb %dl,(%r12,%r13,1)
- leaq 1(%r12),%r12
- decq %rbx
- jnz L$oop16_warmup
-
- movq %rcx,%rbx
- xorq %rcx,%rcx
- movb %bl,%cl
-
-L$oop16_is_hot:
- leaq (%rdi,%r10,4),%rsi
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- pxor %xmm0,%xmm0
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 4(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,0(%rsi)
- addb %bl,%cl
- pinsrw $0,(%rdi,%rax,4),%xmm0
- jmp L$oop16_enter
-.p2align 4
-L$oop16:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- pxor %xmm0,%xmm2
- psllq $8,%xmm1
- pxor %xmm0,%xmm0
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 4(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,0(%rsi)
- pxor %xmm1,%xmm2
- addb %bl,%cl
- pinsrw $0,(%rdi,%rax,4),%xmm0
- movdqu %xmm2,(%r12,%r13,1)
- leaq 16(%r12),%r12
-L$oop16_enter:
- movl (%rdi,%rcx,4),%edx
- pxor %xmm1,%xmm1
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 8(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,4(%rsi)
- addb %al,%cl
- pinsrw $0,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 12(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,8(%rsi)
- addb %bl,%cl
- pinsrw $1,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 16(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,12(%rsi)
- addb %al,%cl
- pinsrw $1,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 20(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,16(%rsi)
- addb %bl,%cl
- pinsrw $2,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 24(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,20(%rsi)
- addb %al,%cl
- pinsrw $2,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 28(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,24(%rsi)
- addb %bl,%cl
- pinsrw $3,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 32(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,28(%rsi)
- addb %al,%cl
- pinsrw $3,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 36(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,32(%rsi)
- addb %bl,%cl
- pinsrw $4,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 40(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,36(%rsi)
- addb %al,%cl
- pinsrw $4,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 44(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,40(%rsi)
- addb %bl,%cl
- pinsrw $5,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 48(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,44(%rsi)
- addb %al,%cl
- pinsrw $5,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 52(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,48(%rsi)
- addb %bl,%cl
- pinsrw $6,(%rdi,%rax,4),%xmm0
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movl 56(%rsi),%eax
- movzbl %bl,%ebx
- movl %edx,52(%rsi)
- addb %al,%cl
- pinsrw $6,(%rdi,%rbx,4),%xmm1
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- addb %dl,%al
- movl 60(%rsi),%ebx
- movzbl %al,%eax
- movl %edx,56(%rsi)
- addb %bl,%cl
- pinsrw $7,(%rdi,%rax,4),%xmm0
- addb $16,%r10b
- movdqu (%r12),%xmm2
- movl (%rdi,%rcx,4),%edx
- movl %ebx,(%rdi,%rcx,4)
- addb %dl,%bl
- movzbl %bl,%ebx
- movl %edx,60(%rsi)
- leaq (%rdi,%r10,4),%rsi
- pinsrw $7,(%rdi,%rbx,4),%xmm1
- movl (%rsi),%eax
- movq %rcx,%rbx
- xorq %rcx,%rcx
- subq $16,%r11
- movb %bl,%cl
- testq $-16,%r11
- jnz L$oop16
-
- psllq $8,%xmm1
- pxor %xmm0,%xmm2
- pxor %xmm1,%xmm2
- movdqu %xmm2,(%r12,%r13,1)
- leaq 16(%r12),%r12
-
- cmpq $0,%r11
- jne L$loop1
- jmp L$exit
-
-.p2align 4
-L$loop1:
- addb %al,%cl
- movl (%rdi,%rcx,4),%edx
- movl %eax,(%rdi,%rcx,4)
- movl %edx,(%rdi,%r10,4)
- addb %dl,%al
- incb %r10b
- movl (%rdi,%rax,4),%edx
- movl (%rdi,%r10,4),%eax
- xorb (%r12),%dl
- movb %dl,(%r12,%r13,1)
- leaq 1(%r12),%r12
- decq %r11
- jnz L$loop1
- jmp L$exit
-
-.p2align 4
-L$RC4_CHAR:
- addb $1,%r10b
- movzbl (%rdi,%r10,1),%eax
- testq $-8,%r11
- jz L$cloop1
- jmp L$cloop8
-.p2align 4
-L$cloop8:
- movl (%r12),%r8d
- movl 4(%r12),%r9d
- addb %al,%cl
- leaq 1(%r10),%rsi
- movzbl (%rdi,%rcx,1),%edx
- movzbl %sil,%esi
- movzbl (%rdi,%rsi,1),%ebx
- movb %al,(%rdi,%rcx,1)
- cmpq %rsi,%rcx
- movb %dl,(%rdi,%r10,1)
- jne L$cmov0
- movq %rax,%rbx
-L$cmov0:
- addb %al,%dl
- xorb (%rdi,%rdx,1),%r8b
- rorl $8,%r8d
- addb %bl,%cl
- leaq 1(%rsi),%r10
- movzbl (%rdi,%rcx,1),%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%eax
- movb %bl,(%rdi,%rcx,1)
- cmpq %r10,%rcx
- movb %dl,(%rdi,%rsi,1)
- jne L$cmov1
- movq %rbx,%rax
-L$cmov1:
- addb %bl,%dl
- xorb (%rdi,%rdx,1),%r8b
- rorl $8,%r8d
- addb %al,%cl
- leaq 1(%r10),%rsi
- movzbl (%rdi,%rcx,1),%edx
- movzbl %sil,%esi
- movzbl (%rdi,%rsi,1),%ebx
- movb %al,(%rdi,%rcx,1)
- cmpq %rsi,%rcx
- movb %dl,(%rdi,%r10,1)
- jne L$cmov2
- movq %rax,%rbx
-L$cmov2:
- addb %al,%dl
- xorb (%rdi,%rdx,1),%r8b
- rorl $8,%r8d
- addb %bl,%cl
- leaq 1(%rsi),%r10
- movzbl (%rdi,%rcx,1),%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%eax
- movb %bl,(%rdi,%rcx,1)
- cmpq %r10,%rcx
- movb %dl,(%rdi,%rsi,1)
- jne L$cmov3
- movq %rbx,%rax
-L$cmov3:
- addb %bl,%dl
- xorb (%rdi,%rdx,1),%r8b
- rorl $8,%r8d
- addb %al,%cl
- leaq 1(%r10),%rsi
- movzbl (%rdi,%rcx,1),%edx
- movzbl %sil,%esi
- movzbl (%rdi,%rsi,1),%ebx
- movb %al,(%rdi,%rcx,1)
- cmpq %rsi,%rcx
- movb %dl,(%rdi,%r10,1)
- jne L$cmov4
- movq %rax,%rbx
-L$cmov4:
- addb %al,%dl
- xorb (%rdi,%rdx,1),%r9b
- rorl $8,%r9d
- addb %bl,%cl
- leaq 1(%rsi),%r10
- movzbl (%rdi,%rcx,1),%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%eax
- movb %bl,(%rdi,%rcx,1)
- cmpq %r10,%rcx
- movb %dl,(%rdi,%rsi,1)
- jne L$cmov5
- movq %rbx,%rax
-L$cmov5:
- addb %bl,%dl
- xorb (%rdi,%rdx,1),%r9b
- rorl $8,%r9d
- addb %al,%cl
- leaq 1(%r10),%rsi
- movzbl (%rdi,%rcx,1),%edx
- movzbl %sil,%esi
- movzbl (%rdi,%rsi,1),%ebx
- movb %al,(%rdi,%rcx,1)
- cmpq %rsi,%rcx
- movb %dl,(%rdi,%r10,1)
- jne L$cmov6
- movq %rax,%rbx
-L$cmov6:
- addb %al,%dl
- xorb (%rdi,%rdx,1),%r9b
- rorl $8,%r9d
- addb %bl,%cl
- leaq 1(%rsi),%r10
- movzbl (%rdi,%rcx,1),%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%r10,1),%eax
- movb %bl,(%rdi,%rcx,1)
- cmpq %r10,%rcx
- movb %dl,(%rdi,%rsi,1)
- jne L$cmov7
- movq %rbx,%rax
-L$cmov7:
- addb %bl,%dl
- xorb (%rdi,%rdx,1),%r9b
- rorl $8,%r9d
- leaq -8(%r11),%r11
- movl %r8d,(%r13)
- leaq 8(%r12),%r12
- movl %r9d,4(%r13)
- leaq 8(%r13),%r13
-
- testq $-8,%r11
- jnz L$cloop8
- cmpq $0,%r11
- jne L$cloop1
- jmp L$exit
-.p2align 4
-L$cloop1:
- addb %al,%cl
- movzbl %cl,%ecx
- movzbl (%rdi,%rcx,1),%edx
- movb %al,(%rdi,%rcx,1)
- movb %dl,(%rdi,%r10,1)
- addb %al,%dl
- addb $1,%r10b
- movzbl %dl,%edx
- movzbl %r10b,%r10d
- movzbl (%rdi,%rdx,1),%edx
- movzbl (%rdi,%r10,1),%eax
- xorb (%r12),%dl
- leaq 1(%r12),%r12
- movb %dl,(%r13)
- leaq 1(%r13),%r13
- subq $1,%r11
- jnz L$cloop1
- jmp L$exit
-
-.p2align 4
-L$exit:
- subb $1,%r10b
- movl %r10d,-8(%rdi)
- movl %ecx,-4(%rdi)
-
- movq (%rsp),%r13
- movq 8(%rsp),%r12
- movq 16(%rsp),%rbx
- addq $24,%rsp
-L$epilogue:
- .byte 0xf3,0xc3
-
-.globl _asm_RC4_set_key
-.private_extern _asm_RC4_set_key
-
-.p2align 4
-_asm_RC4_set_key:
- leaq 8(%rdi),%rdi
- leaq (%rdx,%rsi,1),%rdx
- negq %rsi
- movq %rsi,%rcx
- xorl %eax,%eax
- xorq %r9,%r9
- xorq %r10,%r10
- xorq %r11,%r11
-
- movl _OPENSSL_ia32cap_P(%rip),%r8d
- btl $20,%r8d
- jc L$c1stloop
- jmp L$w1stloop
-
-.p2align 4
-L$w1stloop:
- movl %eax,(%rdi,%rax,4)
- addb $1,%al
- jnc L$w1stloop
-
- xorq %r9,%r9
- xorq %r8,%r8
-.p2align 4
-L$w2ndloop:
- movl (%rdi,%r9,4),%r10d
- addb (%rdx,%rsi,1),%r8b
- addb %r10b,%r8b
- addq $1,%rsi
- movl (%rdi,%r8,4),%r11d
- cmovzq %rcx,%rsi
- movl %r10d,(%rdi,%r8,4)
- movl %r11d,(%rdi,%r9,4)
- addb $1,%r9b
- jnc L$w2ndloop
- jmp L$exit_key
-
-.p2align 4
-L$c1stloop:
- movb %al,(%rdi,%rax,1)
- addb $1,%al
- jnc L$c1stloop
-
- xorq %r9,%r9
- xorq %r8,%r8
-.p2align 4
-L$c2ndloop:
- movb (%rdi,%r9,1),%r10b
- addb (%rdx,%rsi,1),%r8b
- addb %r10b,%r8b
- addq $1,%rsi
- movb (%rdi,%r8,1),%r11b
- jnz L$cnowrap
- movq %rcx,%rsi
-L$cnowrap:
- movb %r10b,(%rdi,%r8,1)
- movb %r11b,(%rdi,%r9,1)
- addb $1,%r9b
- jnc L$c2ndloop
- movl $-1,256(%rdi)
-
-.p2align 4
-L$exit_key:
- xorl %eax,%eax
- movl %eax,-8(%rdi)
- movl %eax,-4(%rdi)
- .byte 0xf3,0xc3
-
-#endif
diff --git a/rules.mk b/rules.mk
index e2d5ae3..76910f3 100644
--- a/rules.mk
+++ b/rules.mk
@@ -77,6 +77,10 @@
GLOBAL_INCLUDES += $(addprefix $(LOCAL_DIR)/,$(LOCAL_C_INCLUDES))
+# BoringSSL expects an STL to be available when building for C++11 to provide
+# scopers. Suppress those APIs.
+GLOBAL_CPPFLAGS += -DBORINGSSL_NO_CXX
+
MODULE_DEPS := \
lib/openssl-stubs \
diff --git a/sources.bp b/sources.bp
index aa0c3fb..49333bb 100644
--- a/sources.bp
+++ b/sources.bp
@@ -24,7 +24,6 @@
"src/crypto/aes/mode_wrappers.c",
"src/crypto/asn1/a_bitstr.c",
"src/crypto/asn1/a_bool.c",
- "src/crypto/asn1/a_bytes.c",
"src/crypto/asn1/a_d2i_fp.c",
"src/crypto/asn1/a_dup.c",
"src/crypto/asn1/a_enum.c",
@@ -331,7 +330,6 @@
"linux-x86/crypto/chacha/chacha-x86.S",
"linux-x86/crypto/md5/md5-586.S",
"linux-x86/crypto/modes/ghash-x86.S",
- "linux-x86/crypto/rc4/rc4-586.S",
"linux-x86/crypto/sha/sha1-586.S",
"linux-x86/crypto/sha/sha256-586.S",
"linux-x86/crypto/sha/sha512-586.S",
@@ -348,7 +346,6 @@
"linux-x86/crypto/chacha/chacha-x86.S",
"linux-x86/crypto/md5/md5-586.S",
"linux-x86/crypto/modes/ghash-x86.S",
- "linux-x86/crypto/rc4/rc4-586.S",
"linux-x86/crypto/sha/sha1-586.S",
"linux-x86/crypto/sha/sha256-586.S",
"linux-x86/crypto/sha/sha512-586.S",
@@ -370,7 +367,6 @@
"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-x86_64.S",
"linux-x86_64/crypto/sha/sha1-x86_64.S",
"linux-x86_64/crypto/sha/sha256-x86_64.S",
"linux-x86_64/crypto/sha/sha512-x86_64.S",
@@ -393,7 +389,6 @@
"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-x86_64.S",
"linux-x86_64/crypto/sha/sha1-x86_64.S",
"linux-x86_64/crypto/sha/sha256-x86_64.S",
"linux-x86_64/crypto/sha/sha512-x86_64.S",
@@ -491,7 +486,10 @@
"src/crypto/dsa/dsa_test.c",
"src/crypto/ec/ec_test.cc",
"src/crypto/ec/example_mul.c",
+ "src/crypto/ecdh/ecdh_test.cc",
+ "src/crypto/ecdsa/ecdsa_sign_test.cc",
"src/crypto/ecdsa/ecdsa_test.cc",
+ "src/crypto/ecdsa/ecdsa_verify_test.cc",
"src/crypto/err/err_test.cc",
"src/crypto/evp/evp_extra_test.cc",
"src/crypto/evp/evp_test.cc",
diff --git a/sources.mk b/sources.mk
index ec24114..ba585e1 100644
--- a/sources.mk
+++ b/sources.mk
@@ -22,7 +22,6 @@
src/crypto/aes/mode_wrappers.c\
src/crypto/asn1/a_bitstr.c\
src/crypto/asn1/a_bool.c\
- src/crypto/asn1/a_bytes.c\
src/crypto/asn1/a_d2i_fp.c\
src/crypto/asn1/a_dup.c\
src/crypto/asn1/a_enum.c\
@@ -323,7 +322,6 @@
linux-x86/crypto/chacha/chacha-x86.S\
linux-x86/crypto/md5/md5-586.S\
linux-x86/crypto/modes/ghash-x86.S\
- linux-x86/crypto/rc4/rc4-586.S\
linux-x86/crypto/sha/sha1-586.S\
linux-x86/crypto/sha/sha256-586.S\
linux-x86/crypto/sha/sha512-586.S\
@@ -343,7 +341,6 @@
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-x86_64.S\
linux-x86_64/crypto/sha/sha1-x86_64.S\
linux-x86_64/crypto/sha/sha256-x86_64.S\
linux-x86_64/crypto/sha/sha512-x86_64.S\
diff --git a/src/API-CONVENTIONS.md b/src/API-CONVENTIONS.md
index 1129600..6ede00d 100644
--- a/src/API-CONVENTIONS.md
+++ b/src/API-CONVENTIONS.md
@@ -85,8 +85,8 @@
compatibility, these functions return `int`, but callers may assume they always
successfully return one because reference counts use saturating arithmetic.
-C++ consumers are recommended to use `std:unique_ptr` with a custom deallocator
-to manage heap-allocated objects.
+C++ consumers are recommended to use `bssl::UniquePtr` to manage heap-allocated
+objects.
### Stack-allocated types
diff --git a/src/BUILDING.md b/src/BUILDING.md
index 5631ded..522bee1 100644
--- a/src/BUILDING.md
+++ b/src/BUILDING.md
@@ -134,6 +134,18 @@
Note that if a feature is enabled in this way, but not actually supported at
run-time, BoringSSL will likely crash.
+## Assembling ARMv8 with Clang
+
+In order to support the ARMv8 crypto instructions, Clang requires that the
+architecture be `armv8-a+crypto`. However, setting that as a general build flag
+would allow the compiler to assume that crypto instructions are *always*
+supported, even without testing for them.
+
+It's possible to set the architecture in an assembly file using the `.arch`
+directive, but only very recent versions of Clang support this. If
+`BORINGSSL_CLANG_SUPPORTS_DOT_ARCH` is defined then `.arch` directives will be
+used with Clang, otherwise you may need to craft acceptable assembler flags.
+
# Running tests
There are two sets of tests: the C/C++ tests and the blackbox tests. For former
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 050ba97..a8befab 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -32,6 +32,9 @@
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(C_CXX_FLAGS "-Wall -Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings -ggdb -fvisibility=hidden -fno-common")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wnewline-eof")
+ endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes -Wold-style-definition -Wstrict-prototypes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${C_CXX_FLAGS} -Wmissing-declarations")
elseif(MSVC)
diff --git a/src/STYLE.md b/src/STYLE.md
index a6aa359..4c88945 100644
--- a/src/STYLE.md
+++ b/src/STYLE.md
@@ -159,7 +159,7 @@
/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
* ASN.1 object can be written. The |tag| argument will be used as the tag for
* the object. It returns one on success or zero on error. */
- OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
+ OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag);
## Documentation
diff --git a/src/crypto/aes/asm/aesv8-armx.pl b/src/crypto/aes/asm/aesv8-armx.pl
index 121154a..a180426 100644
--- a/src/crypto/aes/asm/aesv8-armx.pl
+++ b/src/crypto/aes/asm/aesv8-armx.pl
@@ -51,7 +51,7 @@
.text
___
$code.=<<___ if ($flavour =~ /64/);
-#if !defined(__clang__)
+#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
.arch armv8-a+crypto
#endif
___
diff --git a/src/crypto/asn1/CMakeLists.txt b/src/crypto/asn1/CMakeLists.txt
index bee5518..25d8ba2 100644
--- a/src/crypto/asn1/CMakeLists.txt
+++ b/src/crypto/asn1/CMakeLists.txt
@@ -7,7 +7,6 @@
a_bitstr.c
a_bool.c
- a_bytes.c
a_d2i_fp.c
a_dup.c
a_enum.c
diff --git a/src/crypto/asn1/a_bytes.c b/src/crypto/asn1/a_bytes.c
deleted file mode 100644
index e6b2f2e..0000000
--- a/src/crypto/asn1/a_bytes.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/* 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.] */
-
-#include <openssl/asn1.h>
-
-#include <string.h>
-
-#include <openssl/buf.h>
-#include <openssl/err.h>
-#include <openssl/mem.h>
-
-static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
-/*
- * type is a 'bitmap' of acceptable string types.
- */
-ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
- long length, int type)
-{
- ASN1_STRING *ret = NULL;
- const unsigned char *p;
- unsigned char *s;
- long len;
- int inf, tag, xclass;
- int i = 0;
-
- p = *pp;
- inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
- if (inf & 0x80)
- goto err;
-
- if (tag >= 32) {
- i = ASN1_R_TAG_VALUE_TOO_HIGH;
- goto err;
- }
- if (!(ASN1_tag2bit(tag) & type)) {
- i = ASN1_R_WRONG_TYPE;
- goto err;
- }
-
- /* If a bit-string, exit early */
- if (tag == V_ASN1_BIT_STRING)
- return (d2i_ASN1_BIT_STRING(a, pp, length));
-
- if ((a == NULL) || ((*a) == NULL)) {
- if ((ret = ASN1_STRING_new()) == NULL)
- return (NULL);
- } else
- ret = (*a);
-
- if (len != 0) {
- s = (unsigned char *)OPENSSL_malloc((int)len + 1);
- if (s == NULL) {
- i = ERR_R_MALLOC_FAILURE;
- goto err;
- }
- memcpy(s, p, (int)len);
- s[len] = '\0';
- p += len;
- } else
- s = NULL;
-
- if (ret->data != NULL)
- OPENSSL_free(ret->data);
- ret->length = (int)len;
- ret->data = s;
- ret->type = tag;
- if (a != NULL)
- (*a) = ret;
- *pp = p;
- return (ret);
- err:
- OPENSSL_PUT_ERROR(ASN1, i);
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- ASN1_STRING_free(ret);
- return (NULL);
-}
-
-int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
-{
- int ret, r, constructed;
- unsigned char *p;
-
- if (a == NULL)
- return (0);
-
- if (tag == V_ASN1_BIT_STRING)
- return (i2d_ASN1_BIT_STRING(a, pp));
-
- ret = a->length;
- r = ASN1_object_size(0, ret, tag);
- if (pp == NULL)
- return (r);
- p = *pp;
-
- if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
- constructed = 1;
- else
- constructed = 0;
- ASN1_put_object(&p, constructed, ret, tag, xclass);
- memcpy(p, a->data, a->length);
- p += a->length;
- *pp = p;
- return (r);
-}
-
-ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
- long length, int Ptag, int Pclass)
-{
- ASN1_STRING *ret = NULL;
- const unsigned char *p;
- unsigned char *s;
- long len;
- int inf, tag, xclass;
- int i = 0;
-
- if ((a == NULL) || ((*a) == NULL)) {
- if ((ret = ASN1_STRING_new()) == NULL)
- return (NULL);
- } else
- ret = (*a);
-
- p = *pp;
- inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
- if (inf & 0x80) {
- i = ASN1_R_BAD_OBJECT_HEADER;
- goto err;
- }
-
- if (tag != Ptag) {
- i = ASN1_R_WRONG_TAG;
- goto err;
- }
-
- if (inf & V_ASN1_CONSTRUCTED) {
- ASN1_const_CTX c;
-
- c.pp = pp;
- c.p = p;
- c.inf = inf;
- c.slen = len;
- c.tag = Ptag;
- c.xclass = Pclass;
- c.max = (length == 0) ? 0 : (p + length);
- if (!asn1_collate_primitive(ret, &c))
- goto err;
- else {
- p = c.p;
- }
- } else {
- if (len != 0) {
- if ((ret->length < len) || (ret->data == NULL)) {
- s = (unsigned char *)OPENSSL_malloc((int)len + 1);
- if (s == NULL) {
- i = ERR_R_MALLOC_FAILURE;
- goto err;
- }
- if (ret->data != NULL)
- OPENSSL_free(ret->data);
- } else
- s = ret->data;
- memcpy(s, p, (int)len);
- s[len] = '\0';
- p += len;
- } else {
- s = NULL;
- if (ret->data != NULL)
- OPENSSL_free(ret->data);
- }
-
- ret->length = (int)len;
- ret->data = s;
- ret->type = Ptag;
- }
-
- if (a != NULL)
- (*a) = ret;
- *pp = p;
- return (ret);
- err:
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- ASN1_STRING_free(ret);
- OPENSSL_PUT_ERROR(ASN1, i);
- return (NULL);
-}
-
-/*
- * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them
- * into the one structure that is then returned
- */
-/*
- * There have been a few bug fixes for this function from Paul Keogh
- * <paul.keogh@sse.ie>, many thanks to him
- */
-static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
-{
- ASN1_STRING *os = NULL;
- BUF_MEM b;
- int num;
-
- b.length = 0;
- b.max = 0;
- b.data = NULL;
-
- if (a == NULL) {
- c->error = ERR_R_PASSED_NULL_PARAMETER;
- goto err;
- }
-
- num = 0;
- for (;;) {
- if (c->inf & 1) {
- c->eos = ASN1_const_check_infinite_end(&c->p,
- (long)(c->max - c->p));
- if (c->eos)
- break;
- } else {
- if (c->slen <= 0)
- break;
- }
-
- c->q = c->p;
- if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass)
- == NULL) {
- c->error = ERR_R_ASN1_LIB;
- goto err;
- }
-
- if (!BUF_MEM_grow_clean(&b, num + os->length)) {
- c->error = ERR_R_BUF_LIB;
- goto err;
- }
- memcpy(&(b.data[num]), os->data, os->length);
- if (!(c->inf & 1))
- c->slen -= (c->p - c->q);
- num += os->length;
- }
-
- if (!asn1_const_Finish(c))
- goto err;
-
- a->length = num;
- if (a->data != NULL)
- OPENSSL_free(a->data);
- a->data = (unsigned char *)b.data;
- if (os != NULL)
- ASN1_STRING_free(os);
- return (1);
- err:
- OPENSSL_PUT_ERROR(ASN1, c->error);
- if (os != NULL)
- ASN1_STRING_free(os);
- if (b.data != NULL)
- OPENSSL_free(b.data);
- return (0);
-}
diff --git a/src/crypto/asn1/a_object.c b/src/crypto/asn1/a_object.c
index 10f3839..fef9b79 100644
--- a/src/crypto/asn1/a_object.c
+++ b/src/crypto/asn1/a_object.c
@@ -72,7 +72,7 @@
return (0);
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
- if (pp == NULL)
+ if (pp == NULL || objsize == -1)
return objsize;
p = *pp;
@@ -172,8 +172,12 @@
if (!tmp)
goto err;
}
- while (blsize--)
- tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
+ while (blsize--) {
+ BN_ULONG t = BN_div_word(bl, 0x80L);
+ if (t == (BN_ULONG)-1)
+ goto err;
+ tmp[i++] = (unsigned char)t;
+ }
} else {
for (;;) {
diff --git a/src/crypto/asn1/a_time.c b/src/crypto/asn1/a_time.c
index 4391092..a12b38f 100644
--- a/src/crypto/asn1/a_time.c
+++ b/src/crypto/asn1/a_time.c
@@ -77,17 +77,6 @@
IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
-#if 0
-int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
-{
- if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
- return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
- a->type, V_ASN1_UNIVERSAL));
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_TIME);
- return -1;
-}
-#endif
-
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
{
return ASN1_TIME_adj(s, t, 0, 0);
diff --git a/src/crypto/asn1/a_utctm.c b/src/crypto/asn1/a_utctm.c
index 5a55bd2..db5cd29 100644
--- a/src/crypto/asn1/a_utctm.c
+++ b/src/crypto/asn1/a_utctm.c
@@ -65,37 +65,6 @@
#include "asn1_locl.h"
-#if 0
-int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
-{
- return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
- V_ASN1_UTCTIME, V_ASN1_UNIVERSAL));
-}
-
-ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
- long length)
-{
- ASN1_UTCTIME *ret = NULL;
-
- ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
- V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
- return (NULL);
- }
- if (!ASN1_UTCTIME_check(ret)) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
- goto err;
- }
-
- return (ret);
- err:
- if ((ret != NULL) && ((a == NULL) || (*a != ret)))
- M_ASN1_UTCTIME_free(ret);
- return (NULL);
-}
-
-#endif
int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
{
diff --git a/src/crypto/asn1/asn1_lib.c b/src/crypto/asn1/asn1_lib.c
index 38d5a03..9b4e166 100644
--- a/src/crypto/asn1/asn1_lib.c
+++ b/src/crypto/asn1/asn1_lib.c
@@ -298,26 +298,30 @@
int ASN1_object_size(int constructed, int length, int tag)
{
- int ret;
-
- ret = length;
- ret++;
+ int ret = 1;
+ if (length < 0)
+ return -1;
if (tag >= 31) {
while (tag > 0) {
tag >>= 7;
ret++;
}
}
- if (constructed == 2)
- return ret + 3;
- ret++;
- if (length > 127) {
- while (length > 0) {
- length >>= 8;
- ret++;
+ if (constructed == 2) {
+ ret += 3;
+ } else {
+ ret++;
+ if (length > 127) {
+ int tmplen = length;
+ while (tmplen > 0) {
+ tmplen >>= 8;
+ ret++;
+ }
}
}
- return (ret);
+ if (ret >= INT_MAX - length)
+ return -1;
+ return ret + length;
}
static int _asn1_Finish(ASN1_const_CTX *c)
@@ -382,7 +386,7 @@
else
len = strlen(data);
}
- if ((str->length < len) || (str->data == NULL)) {
+ if ((str->length <= len) || (str->data == NULL)) {
c = str->data;
if (c == NULL)
str->data = OPENSSL_malloc(len + 1);
diff --git a/src/crypto/asn1/asn1_test.cc b/src/crypto/asn1/asn1_test.cc
index 8b02442..77a1ee0 100644
--- a/src/crypto/asn1/asn1_test.cc
+++ b/src/crypto/asn1/asn1_test.cc
@@ -18,8 +18,6 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
-#include "../test/scoped_types.h"
-
// kTag128 is an ASN.1 structure with a universal tag with number 128.
static const uint8_t kTag128[] = {
@@ -42,7 +40,7 @@
static bool TestLargeTags() {
const uint8_t *p = kTag258;
- ScopedASN1_TYPE obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
+ bssl::UniquePtr<ASN1_TYPE> obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
if (obj) {
fprintf(stderr, "Parsed value with illegal tag (type = %d).\n", obj->type);
return false;
diff --git a/src/crypto/asn1/f_enum.c b/src/crypto/asn1/f_enum.c
index 3af16f8..7ce479d 100644
--- a/src/crypto/asn1/f_enum.c
+++ b/src/crypto/asn1/f_enum.c
@@ -56,8 +56,7 @@
#include <openssl/asn1.h>
-#include <openssl/err.h>
-#include <openssl/mem.h>
+#include <openssl/bio.h>
/* Based on a_int.c: equivalent ENUMERATED functions */
@@ -92,109 +91,3 @@
err:
return (-1);
}
-
-int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
-{
- int ret = 0;
- int i, j, k, m, n, again, bufsize;
- unsigned char *s = NULL, *sp;
- unsigned char *bufp;
- int num = 0, slen = 0, first = 1;
-
- bs->type = V_ASN1_ENUMERATED;
-
- bufsize = BIO_gets(bp, buf, size);
- for (;;) {
- if (bufsize < 1)
- goto err_sl;
- i = bufsize;
- if (buf[i - 1] == '\n')
- buf[--i] = '\0';
- if (i == 0)
- goto err_sl;
- if (buf[i - 1] == '\r')
- buf[--i] = '\0';
- if (i == 0)
- goto err_sl;
- again = (buf[i - 1] == '\\');
-
- for (j = 0; j < i; j++) {
- if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
- ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
- ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
- i = j;
- break;
- }
- }
- buf[i] = '\0';
- /*
- * We have now cleared all the crap off the end of the line
- */
- if (i < 2)
- goto err_sl;
-
- bufp = (unsigned char *)buf;
- if (first) {
- first = 0;
- if ((bufp[0] == '0') && (buf[1] == '0')) {
- bufp += 2;
- i -= 2;
- }
- }
- k = 0;
- i -= again;
- if (i % 2 != 0) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
- goto err;
- }
- i /= 2;
- if (num + i > slen) {
- if (s == NULL)
- sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
- i * 2);
- else
- sp = (unsigned char *)OPENSSL_realloc(s,
- (unsigned int)num +
- i * 2);
- if (sp == NULL) {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s = sp;
- slen = num + i * 2;
- }
- for (j = 0; j < i; j++, k += 2) {
- for (n = 0; n < 2; n++) {
- m = bufp[k + n];
- if ((m >= '0') && (m <= '9'))
- m -= '0';
- else if ((m >= 'a') && (m <= 'f'))
- m = m - 'a' + 10;
- else if ((m >= 'A') && (m <= 'F'))
- m = m - 'A' + 10;
- else {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
- goto err;
- }
- s[num + j] <<= 4;
- s[num + j] |= m;
- }
- }
- num += i;
- if (again)
- bufsize = BIO_gets(bp, buf, size);
- else
- break;
- }
- bs->length = num;
- bs->data = s;
- ret = 1;
- err:
- if (0) {
- err_sl:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
- }
- if (s != NULL)
- OPENSSL_free(s);
- return (ret);
-}
diff --git a/src/crypto/asn1/f_int.c b/src/crypto/asn1/f_int.c
index 60c0f2f..79ea152 100644
--- a/src/crypto/asn1/f_int.c
+++ b/src/crypto/asn1/f_int.c
@@ -56,8 +56,7 @@
#include <openssl/asn1.h>
-#include <openssl/err.h>
-#include <openssl/mem.h>
+#include <openssl/bio.h>
int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
{
@@ -96,107 +95,3 @@
err:
return (-1);
}
-
-int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
-{
- int ret = 0;
- int i, j, k, m, n, again, bufsize;
- unsigned char *s = NULL, *sp;
- unsigned char *bufp;
- int num = 0, slen = 0, first = 1;
-
- bs->type = V_ASN1_INTEGER;
-
- bufsize = BIO_gets(bp, buf, size);
- for (;;) {
- if (bufsize < 1)
- goto err_sl;
- i = bufsize;
- if (buf[i - 1] == '\n')
- buf[--i] = '\0';
- if (i == 0)
- goto err_sl;
- if (buf[i - 1] == '\r')
- buf[--i] = '\0';
- if (i == 0)
- goto err_sl;
- again = (buf[i - 1] == '\\');
-
- for (j = 0; j < i; j++) {
- if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
- ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
- ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
- i = j;
- break;
- }
- }
- buf[i] = '\0';
- /*
- * We have now cleared all the crap off the end of the line
- */
- if (i < 2)
- goto err_sl;
-
- bufp = (unsigned char *)buf;
- if (first) {
- first = 0;
- if ((bufp[0] == '0') && (buf[1] == '0')) {
- bufp += 2;
- i -= 2;
- }
- }
- k = 0;
- i -= again;
- if (i % 2 != 0) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
- goto err;
- }
- i /= 2;
- if (num + i > slen) {
- if (s == NULL)
- sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
- i * 2);
- else
- sp = OPENSSL_realloc_clean(s, slen, num + i * 2);
- if (sp == NULL) {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s = sp;
- slen = num + i * 2;
- }
- for (j = 0; j < i; j++, k += 2) {
- for (n = 0; n < 2; n++) {
- m = bufp[k + n];
- if ((m >= '0') && (m <= '9'))
- m -= '0';
- else if ((m >= 'a') && (m <= 'f'))
- m = m - 'a' + 10;
- else if ((m >= 'A') && (m <= 'F'))
- m = m - 'A' + 10;
- else {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
- goto err;
- }
- s[num + j] <<= 4;
- s[num + j] |= m;
- }
- }
- num += i;
- if (again)
- bufsize = BIO_gets(bp, buf, size);
- else
- break;
- }
- bs->length = num;
- bs->data = s;
- ret = 1;
- err:
- if (0) {
- err_sl:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
- }
- if (s != NULL)
- OPENSSL_free(s);
- return (ret);
-}
diff --git a/src/crypto/asn1/f_string.c b/src/crypto/asn1/f_string.c
index ec9cb83..97c6ae7 100644
--- a/src/crypto/asn1/f_string.c
+++ b/src/crypto/asn1/f_string.c
@@ -56,8 +56,7 @@
#include <openssl/asn1.h>
-#include <openssl/err.h>
-#include <openssl/mem.h>
+#include <openssl/bio.h>
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
{
@@ -90,107 +89,3 @@
err:
return (-1);
}
-
-int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
-{
- int ret = 0;
- int i, j, k, m, n, again, bufsize;
- unsigned char *s = NULL, *sp;
- unsigned char *bufp;
- int num = 0, slen = 0, first = 1;
-
- bufsize = BIO_gets(bp, buf, size);
- for (;;) {
- if (bufsize < 1) {
- if (first)
- break;
- else
- goto err_sl;
- }
- first = 0;
-
- i = bufsize;
- if (buf[i - 1] == '\n')
- buf[--i] = '\0';
- if (i == 0)
- goto err_sl;
- if (buf[i - 1] == '\r')
- buf[--i] = '\0';
- if (i == 0)
- goto err_sl;
- again = (buf[i - 1] == '\\');
-
- for (j = i - 1; j > 0; j--) {
- if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
- ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
- ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
- i = j;
- break;
- }
- }
- buf[i] = '\0';
- /*
- * We have now cleared all the crap off the end of the line
- */
- if (i < 2)
- goto err_sl;
-
- bufp = (unsigned char *)buf;
-
- k = 0;
- i -= again;
- if (i % 2 != 0) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
- goto err;
- }
- i /= 2;
- if (num + i > slen) {
- if (s == NULL)
- sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
- i * 2);
- else
- sp = (unsigned char *)OPENSSL_realloc(s,
- (unsigned int)num +
- i * 2);
- if (sp == NULL) {
- OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s = sp;
- slen = num + i * 2;
- }
- for (j = 0; j < i; j++, k += 2) {
- for (n = 0; n < 2; n++) {
- m = bufp[k + n];
- if ((m >= '0') && (m <= '9'))
- m -= '0';
- else if ((m >= 'a') && (m <= 'f'))
- m = m - 'a' + 10;
- else if ((m >= 'A') && (m <= 'F'))
- m = m - 'A' + 10;
- else {
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
- goto err;
- }
- s[num + j] <<= 4;
- s[num + j] |= m;
- }
- }
- num += i;
- if (again)
- bufsize = BIO_gets(bp, buf, size);
- else
- break;
- }
- bs->length = num;
- bs->data = s;
- ret = 1;
- err:
- if (0) {
- err_sl:
- OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
- }
- if (s != NULL)
- OPENSSL_free(s);
- return (ret);
-}
diff --git a/src/crypto/asn1/tasn_enc.c b/src/crypto/asn1/tasn_enc.c
index 409d138..7c2b365 100644
--- a/src/crypto/asn1/tasn_enc.c
+++ b/src/crypto/asn1/tasn_enc.c
@@ -56,6 +56,7 @@
#include <openssl/asn1.h>
+#include <limits.h>
#include <string.h>
#include <openssl/asn1t.h>
@@ -213,17 +214,19 @@
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
+ int tmplen;
seqtt = asn1_do_adb(pval, tt, 1);
if (!seqtt)
return 0;
pseqval = asn1_get_field_ptr(pval, seqtt);
- /* FIXME: check for errors in enhanced version */
- seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
- -1, aclass);
+ tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass);
+ if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen))
+ return -1;
+ seqcontlen += tmplen;
}
seqlen = ASN1_object_size(ndef, seqcontlen, tag);
- if (!out)
+ if (!out || seqlen == -1)
return seqlen;
/* Output SEQUENCE header */
ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
@@ -337,19 +340,24 @@
/* Determine total length of items */
skcontlen = 0;
for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) {
+ int tmplen;
skitem = sk_ASN1_VALUE_value(sk, j);
- skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
- ASN1_ITEM_ptr(tt->item),
- -1, iclass);
+ tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
+ -1, iclass);
+ if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
+ return -1;
+ skcontlen += tmplen;
}
sklen = ASN1_object_size(ndef, skcontlen, sktag);
+ if (sklen == -1)
+ return -1;
/* If EXPLICIT need length of surrounding tag */
if (flags & ASN1_TFLG_EXPTAG)
ret = ASN1_object_size(ndef, sklen, ttag);
else
ret = sklen;
- if (!out)
+ if (!out || ret == -1)
return ret;
/* Now encode this lot... */
@@ -378,7 +386,7 @@
return 0;
/* Find length of EXPLICIT tag */
ret = ASN1_object_size(ndef, i, ttag);
- if (out) {
+ if (out && ret != -1) {
/* Output tag and item */
ASN1_put_object(out, ndef, i, ttag, tclass);
ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
diff --git a/src/crypto/base64/base64_test.cc b/src/crypto/base64/base64_test.cc
index a608773..32b44f6 100644
--- a/src/crypto/base64/base64_test.cc
+++ b/src/crypto/base64/base64_test.cc
@@ -22,6 +22,8 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
+#include "../internal.h"
+
enum encoding_relation {
// canonical indicates that the encoding is the expected encoding of the
@@ -98,7 +100,7 @@
"=======\n"},
};
-static const size_t kNumTests = sizeof(kTestVectors) / sizeof(kTestVectors[0]);
+static const size_t kNumTests = OPENSSL_ARRAY_SIZE(kTestVectors);
// RemoveNewlines returns a copy of |in| with all '\n' characters removed.
static std::string RemoveNewlines(const char *in) {
diff --git a/src/crypto/bio/bio_test.cc b/src/crypto/bio/bio_test.cc
index f2eb20b..cbc4fde 100644
--- a/src/crypto/bio/bio_test.cc
+++ b/src/crypto/bio/bio_test.cc
@@ -40,7 +40,7 @@
#include <algorithm>
-#include "../test/scoped_types.h"
+#include "../internal.h"
#if !defined(OPENSSL_WINDOWS)
@@ -103,7 +103,7 @@
char hostname[80];
BIO_snprintf(hostname, sizeof(hostname), "%s:%d", "127.0.0.1",
ntohs(sin.sin_port));
- ScopedBIO bio(BIO_new_connect(hostname));
+ bssl::UniquePtr<BIO> bio(BIO_new_connect(hostname));
if (!bio) {
fprintf(stderr, "BIO_new_connect failed.\n");
return false;
@@ -206,9 +206,8 @@
// Transfer bytes from bio1_application_send_buffer to
// bio2_application_recv_buffer in various ways.
- for (size_t i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
- for (size_t j = 0; j < sizeof(kPartialLengths) / sizeof(kPartialLengths[0]);
- j++) {
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kLengths); i++) {
+ for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(kPartialLengths); j++) {
size_t total_write = 0;
size_t total_read = 0;
@@ -216,8 +215,8 @@
if (!BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize)) {
return false;
}
- ScopedBIO bio1_scoper(bio1);
- ScopedBIO bio2_scoper(bio2);
+ bssl::UniquePtr<BIO> bio1_scoper(bio1);
+ bssl::UniquePtr<BIO> bio2_scoper(bio2);
total_write += BioWriteZeroCopyWrapper(
bio1, bio1_application_send_buffer, kLengths[i]);
@@ -287,13 +286,13 @@
// 256 (the size of the buffer) to ensure edge cases are correct.
static const size_t kLengths[] = { 5, 250, 251, 252, 253, 254, 1023 };
- ScopedBIO bio(BIO_new(BIO_s_mem()));
+ bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
if (!bio) {
fprintf(stderr, "BIO_new failed\n");
return false;
}
- for (size_t i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kLengths); i++) {
char string[1024];
if (kLengths[i] >= sizeof(string)) {
fprintf(stderr, "Bad test string length\n");
@@ -331,7 +330,7 @@
static bool ReadASN1(bool should_succeed, const uint8_t *data, size_t data_len,
size_t expected_len, size_t max_len) {
- ScopedBIO bio(BIO_new_mem_buf(data, data_len));
+ bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(data, data_len));
uint8_t *out;
size_t out_len;
@@ -339,7 +338,7 @@
if (!ok) {
out = nullptr;
}
- ScopedOpenSSLBytes out_storage(out);
+ bssl::UniquePtr<uint8_t> out_storage(out);
if (should_succeed != (ok == 1)) {
return false;
@@ -369,7 +368,7 @@
static const size_t kLargePayloadLen = 8000;
static const uint8_t kLargePrefix[] = {0x30, 0x82, kLargePayloadLen >> 8,
kLargePayloadLen & 0xff};
- ScopedOpenSSLBytes large(reinterpret_cast<uint8_t *>(
+ bssl::UniquePtr<uint8_t> large(reinterpret_cast<uint8_t *>(
OPENSSL_malloc(sizeof(kLargePrefix) + kLargePayloadLen)));
if (!large) {
return false;
diff --git a/src/crypto/bn/bn_test.cc b/src/crypto/bn/bn_test.cc
index b35e59b..0867dec 100644
--- a/src/crypto/bn/bn_test.cc
+++ b/src/crypto/bn/bn_test.cc
@@ -81,29 +81,30 @@
#include <utility>
#include <openssl/bn.h>
+#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include "../crypto/test/file_test.h"
-#include "../crypto/test/scoped_types.h"
-#include "../crypto/test/test_util.h"
+#include "../internal.h"
+#include "../test/file_test.h"
+#include "../test/test_util.h"
-static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
+static int HexToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
BIGNUM *raw = NULL;
int ret = BN_hex2bn(&raw, in);
out->reset(raw);
return ret;
}
-static ScopedBIGNUM GetBIGNUM(FileTest *t, const char *attribute) {
+static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *attribute) {
std::string hex;
if (!t->GetAttribute(&hex, attribute)) {
return nullptr;
}
- ScopedBIGNUM ret;
+ bssl::UniquePtr<BIGNUM> ret;
if (HexToBIGNUM(&ret, hex.c_str()) != static_cast<int>(hex.size())) {
t->PrintLine("Could not decode '%s'.", hex.c_str());
return nullptr;
@@ -112,7 +113,7 @@
}
static bool GetInt(FileTest *t, int *out, const char *attribute) {
- ScopedBIGNUM ret = GetBIGNUM(t, attribute);
+ bssl::UniquePtr<BIGNUM> ret = GetBIGNUM(t, attribute);
if (!ret) {
return false;
}
@@ -132,8 +133,8 @@
return true;
}
- ScopedOpenSSLString expected_str(BN_bn2hex(expected));
- ScopedOpenSSLString actual_str(BN_bn2hex(actual));
+ bssl::UniquePtr<char> expected_str(BN_bn2hex(expected));
+ bssl::UniquePtr<char> actual_str(BN_bn2hex(actual));
if (!expected_str || !actual_str) {
return false;
}
@@ -146,14 +147,14 @@
}
static bool TestSum(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM b = GetBIGNUM(t, "B");
- ScopedBIGNUM sum = GetBIGNUM(t, "Sum");
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
+ bssl::UniquePtr<BIGNUM> sum = GetBIGNUM(t, "Sum");
if (!a || !b || !sum) {
return false;
}
- ScopedBIGNUM ret(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new());
if (!ret ||
!BN_add(ret.get(), a.get(), b.get()) ||
!ExpectBIGNUMsEqual(t, "A + B", sum.get(), ret.get()) ||
@@ -245,16 +246,16 @@
}
static bool TestLShift1(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM lshift1 = GetBIGNUM(t, "LShift1");
- ScopedBIGNUM zero(BN_new());
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> lshift1 = GetBIGNUM(t, "LShift1");
+ bssl::UniquePtr<BIGNUM> zero(BN_new());
if (!a || !lshift1 || !zero) {
return false;
}
BN_zero(zero.get());
- ScopedBIGNUM ret(BN_new()), two(BN_new()), remainder(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new()), two(BN_new()), remainder(BN_new());
if (!ret || !two || !remainder ||
!BN_set_word(two.get(), 2) ||
!BN_add(ret.get(), a.get(), a.get()) ||
@@ -286,14 +287,14 @@
}
static bool TestLShift(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM lshift = GetBIGNUM(t, "LShift");
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> lshift = GetBIGNUM(t, "LShift");
int n = 0;
if (!a || !lshift || !GetInt(t, &n, "N")) {
return false;
}
- ScopedBIGNUM ret(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new());
if (!ret ||
!BN_lshift(ret.get(), a.get(), n) ||
!ExpectBIGNUMsEqual(t, "A << N", lshift.get(), ret.get()) ||
@@ -306,14 +307,14 @@
}
static bool TestRShift(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM rshift = GetBIGNUM(t, "RShift");
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> rshift = GetBIGNUM(t, "RShift");
int n = 0;
if (!a || !rshift || !GetInt(t, &n, "N")) {
return false;
}
- ScopedBIGNUM ret(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new());
if (!ret ||
!BN_rshift(ret.get(), a.get(), n) ||
!ExpectBIGNUMsEqual(t, "A >> N", rshift.get(), ret.get())) {
@@ -324,16 +325,16 @@
}
static bool TestSquare(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM square = GetBIGNUM(t, "Square");
- ScopedBIGNUM zero(BN_new());
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> square = GetBIGNUM(t, "Square");
+ bssl::UniquePtr<BIGNUM> zero(BN_new());
if (!a || !square || !zero) {
return false;
}
BN_zero(zero.get());
- ScopedBIGNUM ret(BN_new()), remainder(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
if (!ret ||
!BN_sqr(ret.get(), a.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A^2", square.get(), ret.get()) ||
@@ -353,7 +354,7 @@
// BN_sqrt should fail on non-squares and negative numbers.
if (!BN_is_zero(square.get())) {
- ScopedBIGNUM tmp(BN_new());
+ bssl::UniquePtr<BIGNUM> tmp(BN_new());
if (!tmp || !BN_copy(tmp.get(), square.get())) {
return false;
}
@@ -380,17 +381,17 @@
}
static bool TestProduct(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM b = GetBIGNUM(t, "B");
- ScopedBIGNUM product = GetBIGNUM(t, "Product");
- ScopedBIGNUM zero(BN_new());
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
+ bssl::UniquePtr<BIGNUM> product = GetBIGNUM(t, "Product");
+ bssl::UniquePtr<BIGNUM> zero(BN_new());
if (!a || !b || !product || !zero) {
return false;
}
BN_zero(zero.get());
- ScopedBIGNUM ret(BN_new()), remainder(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
if (!ret || !remainder ||
!BN_mul(ret.get(), a.get(), b.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A * B", product.get(), ret.get()) ||
@@ -407,15 +408,15 @@
}
static bool TestQuotient(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM b = GetBIGNUM(t, "B");
- ScopedBIGNUM quotient = GetBIGNUM(t, "Quotient");
- ScopedBIGNUM remainder = GetBIGNUM(t, "Remainder");
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
+ bssl::UniquePtr<BIGNUM> quotient = GetBIGNUM(t, "Quotient");
+ bssl::UniquePtr<BIGNUM> remainder = GetBIGNUM(t, "Remainder");
if (!a || !b || !quotient || !remainder) {
return false;
}
- ScopedBIGNUM ret(BN_new()), ret2(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new()), ret2(BN_new());
if (!ret || !ret2 ||
!BN_div(ret.get(), ret2.get(), a.get(), b.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A / B", quotient.get(), ret.get()) ||
@@ -456,7 +457,7 @@
// Test BN_nnmod.
if (!BN_is_negative(b.get())) {
- ScopedBIGNUM nnmod(BN_new());
+ bssl::UniquePtr<BIGNUM> nnmod(BN_new());
if (!nnmod ||
!BN_copy(nnmod.get(), remainder.get()) ||
(BN_is_negative(nnmod.get()) &&
@@ -472,15 +473,15 @@
}
static bool TestModMul(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM b = GetBIGNUM(t, "B");
- ScopedBIGNUM m = GetBIGNUM(t, "M");
- ScopedBIGNUM mod_mul = GetBIGNUM(t, "ModMul");
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> b = GetBIGNUM(t, "B");
+ bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
+ bssl::UniquePtr<BIGNUM> mod_mul = GetBIGNUM(t, "ModMul");
if (!a || !b || !m || !mod_mul) {
return false;
}
- ScopedBIGNUM ret(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new());
if (!ret ||
!BN_mod_mul(ret.get(), a.get(), b.get(), m.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A * B (mod M)", mod_mul.get(), ret.get())) {
@@ -489,8 +490,8 @@
if (BN_is_odd(m.get())) {
// Reduce |a| and |b| and test the Montgomery version.
- ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
- ScopedBIGNUM a_tmp(BN_new()), b_tmp(BN_new());
+ bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
+ bssl::UniquePtr<BIGNUM> a_tmp(BN_new()), b_tmp(BN_new());
if (!mont || !a_tmp || !b_tmp ||
!BN_MONT_CTX_set(mont.get(), m.get(), ctx) ||
!BN_nnmod(a_tmp.get(), a.get(), m.get(), ctx) ||
@@ -510,15 +511,15 @@
}
static bool TestModExp(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM e = GetBIGNUM(t, "E");
- ScopedBIGNUM m = GetBIGNUM(t, "M");
- ScopedBIGNUM mod_exp = GetBIGNUM(t, "ModExp");
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
+ bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
+ bssl::UniquePtr<BIGNUM> mod_exp = GetBIGNUM(t, "ModExp");
if (!a || !e || !m || !mod_exp) {
return false;
}
- ScopedBIGNUM ret(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new());
if (!ret ||
!BN_mod_exp(ret.get(), a.get(), e.get(), m.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A ^ E (mod M)", mod_exp.get(), ret.get())) {
@@ -541,14 +542,14 @@
}
static bool TestExp(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM e = GetBIGNUM(t, "E");
- ScopedBIGNUM exp = GetBIGNUM(t, "Exp");
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
+ bssl::UniquePtr<BIGNUM> exp = GetBIGNUM(t, "Exp");
if (!a || !e || !exp) {
return false;
}
- ScopedBIGNUM ret(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new());
if (!ret ||
!BN_exp(ret.get(), a.get(), e.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A ^ E", exp.get(), ret.get())) {
@@ -559,15 +560,15 @@
}
static bool TestModSqrt(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM p = GetBIGNUM(t, "P");
- ScopedBIGNUM mod_sqrt = GetBIGNUM(t, "ModSqrt");
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
+ bssl::UniquePtr<BIGNUM> mod_sqrt = GetBIGNUM(t, "ModSqrt");
if (!a || !p || !mod_sqrt) {
return false;
}
- ScopedBIGNUM ret(BN_new());
- ScopedBIGNUM ret2(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new());
+ bssl::UniquePtr<BIGNUM> ret2(BN_new());
if (!ret ||
!ret2 ||
!BN_mod_sqrt(ret.get(), a.get(), p.get(), ctx) ||
@@ -585,14 +586,14 @@
}
static bool TestModInv(FileTest *t, BN_CTX *ctx) {
- ScopedBIGNUM a = GetBIGNUM(t, "A");
- ScopedBIGNUM m = GetBIGNUM(t, "M");
- ScopedBIGNUM mod_inv = GetBIGNUM(t, "ModInv");
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
+ bssl::UniquePtr<BIGNUM> mod_inv = GetBIGNUM(t, "ModInv");
if (!a || !m || !mod_inv) {
return false;
}
- ScopedBIGNUM ret(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new());
if (!ret ||
!BN_mod_inverse(ret.get(), a.get(), m.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "inv(A) (mod M)", mod_inv.get(), ret.get())) {
@@ -649,7 +650,7 @@
memset(zeros, 0, sizeof(zeros));
// Test edge case at 0.
- ScopedBIGNUM n(BN_new());
+ bssl::UniquePtr<BIGNUM> n(BN_new());
if (!n || !BN_bn2bin_padded(NULL, 0, n.get())) {
fprintf(stderr,
"BN_bn2bin_padded failed to encode 0 in an empty buffer.\n");
@@ -668,8 +669,7 @@
// Test a random numbers at various byte lengths.
for (size_t bytes = 128 - 7; bytes <= 128; bytes++) {
- if (!BN_rand(n.get(), bytes * 8, 0 /* make sure top bit is 1 */,
- 0 /* don't modify bottom bit */)) {
+ if (!BN_rand(n.get(), bytes * 8, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
ERR_print_errors_fp(stderr);
return false;
}
@@ -713,7 +713,7 @@
return true;
}
-static int DecimalToBIGNUM(ScopedBIGNUM *out, const char *in) {
+static int DecimalToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
BIGNUM *raw = NULL;
int ret = BN_dec2bn(&raw, in);
out->reset(raw);
@@ -721,7 +721,7 @@
}
static bool TestDec2BN(BN_CTX *ctx) {
- ScopedBIGNUM bn;
+ bssl::UniquePtr<BIGNUM> bn;
int ret = DecimalToBIGNUM(&bn, "0");
if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
fprintf(stderr, "BN_dec2bn gave a bad result.\n");
@@ -756,7 +756,7 @@
}
static bool TestHex2BN(BN_CTX *ctx) {
- ScopedBIGNUM bn;
+ bssl::UniquePtr<BIGNUM> bn;
int ret = HexToBIGNUM(&bn, "0");
if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
fprintf(stderr, "BN_hex2bn gave a bad result.\n");
@@ -790,16 +790,16 @@
return true;
}
-static ScopedBIGNUM ASCIIToBIGNUM(const char *in) {
+static bssl::UniquePtr<BIGNUM> ASCIIToBIGNUM(const char *in) {
BIGNUM *raw = NULL;
if (!BN_asc2bn(&raw, in)) {
return nullptr;
}
- return ScopedBIGNUM(raw);
+ return bssl::UniquePtr<BIGNUM>(raw);
}
static bool TestASC2BN(BN_CTX *ctx) {
- ScopedBIGNUM bn = ASCIIToBIGNUM("0");
+ bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("0");
if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
fprintf(stderr, "BN_asc2bn gave a bad result.\n");
return false;
@@ -868,9 +868,9 @@
static bool TestMPI() {
uint8_t scratch[8];
- for (size_t i = 0; i < sizeof(kMPITests) / sizeof(kMPITests[0]); i++) {
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMPITests); i++) {
const MPITest &test = kMPITests[i];
- ScopedBIGNUM bn(ASCIIToBIGNUM(test.base10));
+ bssl::UniquePtr<BIGNUM> bn(ASCIIToBIGNUM(test.base10));
const size_t mpi_len = BN_bn2mpi(bn.get(), NULL);
if (mpi_len > sizeof(scratch)) {
fprintf(stderr, "MPI test #%u: MPI size is too large to test.\n",
@@ -892,7 +892,7 @@
return false;
}
- ScopedBIGNUM bn2(BN_mpi2bn(scratch, mpi_len, NULL));
+ bssl::UniquePtr<BIGNUM> bn2(BN_mpi2bn(scratch, mpi_len, NULL));
if (bn2.get() == nullptr) {
fprintf(stderr, "MPI test #%u: failed to parse\n", (unsigned)i);
return false;
@@ -908,41 +908,41 @@
}
static bool TestRand() {
- ScopedBIGNUM bn(BN_new());
+ bssl::UniquePtr<BIGNUM> bn(BN_new());
if (!bn) {
return false;
}
// Test BN_rand accounts for degenerate cases with |top| and |bottom|
// parameters.
- if (!BN_rand(bn.get(), 0, 0 /* top */, 0 /* bottom */) ||
+ if (!BN_rand(bn.get(), 0, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY) ||
!BN_is_zero(bn.get())) {
fprintf(stderr, "BN_rand gave a bad result.\n");
return false;
}
- if (!BN_rand(bn.get(), 0, 1 /* top */, 1 /* bottom */) ||
+ if (!BN_rand(bn.get(), 0, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD) ||
!BN_is_zero(bn.get())) {
fprintf(stderr, "BN_rand gave a bad result.\n");
return false;
}
- if (!BN_rand(bn.get(), 1, 0 /* top */, 0 /* bottom */) ||
+ if (!BN_rand(bn.get(), 1, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY) ||
!BN_is_word(bn.get(), 1)) {
fprintf(stderr, "BN_rand gave a bad result.\n");
return false;
}
- if (!BN_rand(bn.get(), 1, 1 /* top */, 0 /* bottom */) ||
+ if (!BN_rand(bn.get(), 1, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY) ||
!BN_is_word(bn.get(), 1)) {
fprintf(stderr, "BN_rand gave a bad result.\n");
return false;
}
- if (!BN_rand(bn.get(), 1, -1 /* top */, 1 /* bottom */) ||
+ if (!BN_rand(bn.get(), 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ODD) ||
!BN_is_word(bn.get(), 1)) {
fprintf(stderr, "BN_rand gave a bad result.\n");
return false;
}
- if (!BN_rand(bn.get(), 2, 1 /* top */, 0 /* bottom */) ||
+ if (!BN_rand(bn.get(), 2, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY) ||
!BN_is_word(bn.get(), 3)) {
fprintf(stderr, "BN_rand gave a bad result.\n");
return false;
@@ -993,13 +993,13 @@
static bool TestASN1() {
for (const ASN1Test &test : kASN1Tests) {
- ScopedBIGNUM bn = ASCIIToBIGNUM(test.value_ascii);
+ bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM(test.value_ascii);
if (!bn) {
return false;
}
// Test that the input is correctly parsed.
- ScopedBIGNUM bn2(BN_new());
+ bssl::UniquePtr<BIGNUM> bn2(BN_new());
if (!bn2) {
return false;
}
@@ -1025,7 +1025,7 @@
CBB_cleanup(&cbb);
return false;
}
- ScopedOpenSSLBytes delete_der(der);
+ bssl::UniquePtr<uint8_t> delete_der(der);
if (der_len != test.der_len ||
memcmp(der, reinterpret_cast<const uint8_t*>(test.der), der_len) != 0) {
fprintf(stderr, "Bad serialization.\n");
@@ -1045,7 +1045,7 @@
}
for (const ASN1InvalidTest &test : kASN1InvalidTests) {
- ScopedBIGNUM bn(BN_new());
+ bssl::UniquePtr<BIGNUM> bn(BN_new());
if (!bn) {
return false;
}
@@ -1069,7 +1069,7 @@
for (const ASN1Test &test : kASN1BuggyTests) {
// These broken encodings are rejected by |BN_parse_asn1_unsigned|.
- ScopedBIGNUM bn(BN_new());
+ bssl::UniquePtr<BIGNUM> bn(BN_new());
if (!bn) {
return false;
}
@@ -1083,7 +1083,7 @@
ERR_clear_error();
// However |BN_parse_asn1_unsigned_buggy| accepts them.
- ScopedBIGNUM bn2 = ASCIIToBIGNUM(test.value_ascii);
+ bssl::UniquePtr<BIGNUM> bn2 = ASCIIToBIGNUM(test.value_ascii);
if (!bn2) {
return false;
}
@@ -1101,7 +1101,7 @@
}
// Serializing negative numbers is not supported.
- ScopedBIGNUM bn = ASCIIToBIGNUM("-1");
+ bssl::UniquePtr<BIGNUM> bn = ASCIIToBIGNUM("-1");
if (!bn) {
return false;
}
@@ -1120,9 +1120,9 @@
}
static bool TestNegativeZero(BN_CTX *ctx) {
- ScopedBIGNUM a(BN_new());
- ScopedBIGNUM b(BN_new());
- ScopedBIGNUM c(BN_new());
+ bssl::UniquePtr<BIGNUM> a(BN_new());
+ bssl::UniquePtr<BIGNUM> b(BN_new());
+ bssl::UniquePtr<BIGNUM> c(BN_new());
if (!a || !b || !c) {
return false;
}
@@ -1142,7 +1142,7 @@
}
for (int consttime = 0; consttime < 2; consttime++) {
- ScopedBIGNUM numerator(BN_new()), denominator(BN_new());
+ bssl::UniquePtr<BIGNUM> numerator(BN_new()), denominator(BN_new());
if (!numerator || !denominator) {
return false;
}
@@ -1190,8 +1190,8 @@
// Test that forcibly creating a negative zero does not break |BN_bn2hex| or
// |BN_bn2dec|.
a->neg = 1;
- ScopedOpenSSLString dec(BN_bn2dec(a.get()));
- ScopedOpenSSLString hex(BN_bn2hex(a.get()));
+ bssl::UniquePtr<char> dec(BN_bn2dec(a.get()));
+ bssl::UniquePtr<char> hex(BN_bn2hex(a.get()));
if (!dec || !hex ||
strcmp(dec.get(), "-0") != 0 ||
strcmp(hex.get(), "-0") != 0) {
@@ -1203,10 +1203,10 @@
}
static bool TestBadModulus(BN_CTX *ctx) {
- ScopedBIGNUM a(BN_new());
- ScopedBIGNUM b(BN_new());
- ScopedBIGNUM zero(BN_new());
- ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
+ bssl::UniquePtr<BIGNUM> a(BN_new());
+ bssl::UniquePtr<BIGNUM> b(BN_new());
+ bssl::UniquePtr<BIGNUM> zero(BN_new());
+ bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
if (!a || !b || !zero || !mont) {
return false;
}
@@ -1290,8 +1290,9 @@
// TestExpModZero tests that 1**0 mod 1 == 0.
static bool TestExpModZero() {
- ScopedBIGNUM zero(BN_new()), a(BN_new()), r(BN_new());
- if (!zero || !a || !r || !BN_rand(a.get(), 1024, 0, 0)) {
+ bssl::UniquePtr<BIGNUM> zero(BN_new()), a(BN_new()), r(BN_new());
+ if (!zero || !a || !r ||
+ !BN_rand(a.get(), 1024, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
return false;
}
BN_zero(zero.get());
@@ -1316,7 +1317,7 @@
static bool TestSmallPrime(BN_CTX *ctx) {
static const unsigned kBits = 10;
- ScopedBIGNUM r(BN_new());
+ bssl::UniquePtr<BIGNUM> r(BN_new());
if (!r || !BN_generate_prime_ex(r.get(), static_cast<int>(kBits), 0, NULL,
NULL, NULL)) {
return false;
@@ -1333,7 +1334,7 @@
static bool TestCmpWord() {
static const BN_ULONG kMaxWord = (BN_ULONG)-1;
- ScopedBIGNUM r(BN_new());
+ bssl::UniquePtr<BIGNUM> r(BN_new());
if (!r ||
!BN_set_word(r.get(), 0)) {
return false;
@@ -1401,6 +1402,41 @@
return true;
}
+static bool TestBN2Dec() {
+ static const char *kBN2DecTests[] = {
+ "0",
+ "1",
+ "-1",
+ "100",
+ "-100",
+ "123456789012345678901234567890",
+ "-123456789012345678901234567890",
+ "123456789012345678901234567890123456789012345678901234567890",
+ "-123456789012345678901234567890123456789012345678901234567890",
+ };
+
+ for (const char *test : kBN2DecTests) {
+ bssl::UniquePtr<BIGNUM> bn;
+ int ret = DecimalToBIGNUM(&bn, test);
+ if (ret == 0) {
+ return false;
+ }
+
+ bssl::UniquePtr<char> dec(BN_bn2dec(bn.get()));
+ if (!dec) {
+ fprintf(stderr, "BN_bn2dec failed on %s.\n", test);
+ return false;
+ }
+
+ if (strcmp(dec.get(), test) != 0) {
+ fprintf(stderr, "BN_bn2dec gave %s, wanted %s.\n", dec.get(), test);
+ return false;
+ }
+ }
+
+ return true;
+}
+
int main(int argc, char *argv[]) {
CRYPTO_library_init();
@@ -1409,7 +1445,7 @@
return 1;
}
- ScopedBN_CTX ctx(BN_CTX_new());
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
if (!ctx) {
return 1;
}
@@ -1425,7 +1461,8 @@
!TestBadModulus(ctx.get()) ||
!TestExpModZero() ||
!TestSmallPrime(ctx.get()) ||
- !TestCmpWord()) {
+ !TestCmpWord() ||
+ !TestBN2Dec()) {
return 1;
}
diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c
index 1392a70..05e27bf 100644
--- a/src/crypto/bn/convert.c
+++ b/src/crypto/bn/convert.c
@@ -370,73 +370,69 @@
}
char *BN_bn2dec(const BIGNUM *a) {
- int i = 0, num, ok = 0;
- char *buf = NULL;
- char *p;
- BIGNUM *t = NULL;
- BN_ULONG *bn_data = NULL, *lp;
-
- /* get an upper bound for the length of the decimal integer
- * num <= (BN_num_bits(a) + 1) * log(2)
- * <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1 (rounding error)
- * <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1
- */
- i = BN_num_bits(a) * 3;
- num = i / 10 + i / 1000 + 1 + 1;
- bn_data = OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
- buf = OPENSSL_malloc(num + 3);
- if ((buf == NULL) || (bn_data == NULL)) {
- OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- t = BN_dup(a);
- if (t == NULL) {
- goto err;
+ /* It is easier to print strings little-endian, so we assemble it in reverse
+ * and fix at the end. */
+ BIGNUM *copy = NULL;
+ CBB cbb;
+ if (!CBB_init(&cbb, 16) ||
+ !CBB_add_u8(&cbb, 0 /* trailing NUL */)) {
+ goto cbb_err;
}
-#define BUF_REMAIN (num + 3 - (size_t)(p - buf))
- p = buf;
- lp = bn_data;
-
- if (BN_is_negative(t)) {
- *p++ = '-';
- }
-
- if (BN_is_zero(t)) {
- *(p++) = '0';
- *(p++) = '\0';
+ if (BN_is_zero(a)) {
+ if (!CBB_add_u8(&cbb, '0')) {
+ goto cbb_err;
+ }
} else {
- while (!BN_is_zero(t)) {
- *lp = BN_div_word(t, BN_DEC_CONV);
- lp++;
+ copy = BN_dup(a);
+ if (copy == NULL) {
+ goto err;
}
- lp--;
- /* We now have a series of blocks, BN_DEC_NUM chars
- * in length, where the last one needs truncation.
- * The blocks need to be reversed in order. */
- BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp);
- while (*p) {
- p++;
- }
- while (lp != bn_data) {
- lp--;
- BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp);
- while (*p) {
- p++;
+
+ while (!BN_is_zero(copy)) {
+ BN_ULONG word = BN_div_word(copy, BN_DEC_CONV);
+ if (word == (BN_ULONG)-1) {
+ goto err;
}
+
+ const int add_leading_zeros = !BN_is_zero(copy);
+ for (int i = 0; i < BN_DEC_NUM && (add_leading_zeros || word != 0); i++) {
+ if (!CBB_add_u8(&cbb, '0' + word % 10)) {
+ goto cbb_err;
+ }
+ word /= 10;
+ }
+ assert(word == 0);
}
}
- ok = 1;
-err:
- OPENSSL_free(bn_data);
- BN_free(t);
- if (!ok) {
- OPENSSL_free(buf);
- buf = NULL;
+ if (BN_is_negative(a) &&
+ !CBB_add_u8(&cbb, '-')) {
+ goto cbb_err;
}
- return buf;
+ uint8_t *data;
+ size_t len;
+ if (!CBB_finish(&cbb, &data, &len)) {
+ goto cbb_err;
+ }
+
+ /* Reverse the buffer. */
+ for (size_t i = 0; i < len/2; i++) {
+ uint8_t tmp = data[i];
+ data[i] = data[len - 1 - i];
+ data[len - 1 - i] = tmp;
+ }
+
+ BN_free(copy);
+ return (char *)data;
+
+cbb_err:
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
+err:
+ BN_free(copy);
+ CBB_cleanup(&cbb);
+ return NULL;
}
int BN_dec2bn(BIGNUM **outp, const char *in) {
diff --git a/src/crypto/bn/div.c b/src/crypto/bn/div.c
index e824458..03577f2 100644
--- a/src/crypto/bn/div.c
+++ b/src/crypto/bn/div.c
@@ -158,13 +158,13 @@
__asm__ volatile (
"divl %4"
: "=a"(*quotient_out), "=d"(*rem_out)
- : "a"(n1), "d"(n0), "g"(d0)
+ : "a"(n1), "d"(n0), "rm"(d0)
: "cc" );
#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
__asm__ volatile (
"divq %4"
: "=a"(*quotient_out), "=d"(*rem_out)
- : "a"(n1), "d"(n0), "g"(d0)
+ : "a"(n1), "d"(n0), "rm"(d0)
: "cc" );
#else
#if defined(BN_ULLONG)
diff --git a/src/crypto/bn/gcd.c b/src/crypto/bn/gcd.c
index a27bde3..a1ed5d9 100644
--- a/src/crypto/bn/gcd.c
+++ b/src/crypto/bn/gcd.c
@@ -434,11 +434,9 @@
if (no_branch || !BN_is_odd(n)) {
if (!bn_mod_inverse_general(out, &no_inverse, a, n, ctx)) {
- OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR);
goto err;
}
} else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) {
- OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR);
goto err;
}
diff --git a/src/crypto/bn/montgomery_inv.c b/src/crypto/bn/montgomery_inv.c
index ba085ab..28db62b 100644
--- a/src/crypto/bn/montgomery_inv.c
+++ b/src/crypto/bn/montgomery_inv.c
@@ -83,9 +83,11 @@
* such that u*r - v*n == 1. |r| is the constant defined in |bn_mont_n0|. |n|
* must be odd.
*
- * This is derived from |xbinGCD| in the "Montgomery Multiplication" chapter of
- * "Hacker's Delight" by Henry S. Warren, Jr.:
- * http://www.hackersdelight.org/MontgomeryMultiplication.pdf.
+ * This is derived from |xbinGCD| in Henry S. Warren, Jr.'s "Montgomery
+ * Multiplication" (http://www.hackersdelight.org/MontgomeryMultiplication.pdf).
+ * It is very similar to the MODULAR-INVERSE function in Stephen R. Dussé's and
+ * Burton S. Kaliski Jr.'s "A Cryptographic Library for the Motorola DSP56000"
+ * (http://link.springer.com/chapter/10.1007%2F3-540-46877-3_21).
*
* This is inspired by Joppe W. Bos's "Constant Time Modular Inversion"
* (http://www.joppebos.com/files/CTInversion.pdf) so that the inversion is
diff --git a/src/crypto/bn/prime.c b/src/crypto/bn/prime.c
index 98a46a9..0f668d7 100644
--- a/src/crypto/bn/prime.c
+++ b/src/crypto/bn/prime.c
@@ -651,7 +651,7 @@
char is_single_word = bits <= BN_BITS2;
again:
- if (!BN_rand(rnd, bits, 1, 1)) {
+ if (!BN_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD)) {
return 0;
}
@@ -735,7 +735,7 @@
goto err;
}
- if (!BN_rand(rnd, bits, 0, 1)) {
+ if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) {
goto err;
}
@@ -798,7 +798,7 @@
goto err;
}
- if (!BN_rand(q, bits, 0, 1)) {
+ if (!BN_rand(q, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) {
goto err;
}
diff --git a/src/crypto/bn/random.c b/src/crypto/bn/random.c
index fb76f1d..ecf43c1 100644
--- a/src/crypto/bn/random.c
+++ b/src/crypto/bn/random.c
@@ -123,6 +123,17 @@
return 0;
}
+ if (top != BN_RAND_TOP_ANY && top != BN_RAND_TOP_ONE &&
+ top != BN_RAND_TOP_TWO) {
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ if (bottom != BN_RAND_BOTTOM_ANY && bottom != BN_RAND_BOTTOM_ODD) {
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
if (bits == 0) {
BN_zero(rnd);
return 1;
@@ -143,8 +154,8 @@
goto err;
}
- if (top != -1) {
- if (top && bits > 1) {
+ if (top != BN_RAND_TOP_ANY) {
+ if (top == BN_RAND_TOP_TWO && bits > 1) {
if (bit == 0) {
buf[0] = 1;
buf[1] |= 0x80;
@@ -158,8 +169,8 @@
buf[0] &= ~mask;
- /* set bottom bit if requested */
- if (bottom) {
+ /* Set the bottom bit if requested, */
+ if (bottom == BN_RAND_BOTTOM_ODD) {
buf[bytes - 1] |= 1;
}
@@ -210,8 +221,7 @@
/* range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer
* than range. This is a common scenario when generating a random value
* modulo an RSA public modulus, e.g. for RSA base blinding. */
- if (!BN_rand(r, n + 1, -1 /* don't set most significant bits */,
- 0 /* don't set least significant bits */)) {
+ if (!BN_rand(r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) {
return 0;
}
@@ -230,7 +240,7 @@
}
} else {
/* range = 11..._2 or range = 101..._2 */
- if (!BN_rand(r, n, -1, 0)) {
+ if (!BN_rand(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) {
return 0;
}
}
diff --git a/src/crypto/bytestring/bytestring_test.cc b/src/crypto/bytestring/bytestring_test.cc
index 0ec7d54..251aa37 100644
--- a/src/crypto/bytestring/bytestring_test.cc
+++ b/src/crypto/bytestring/bytestring_test.cc
@@ -22,11 +22,11 @@
#include <vector>
-#include <openssl/c++/bytestring.h>
+#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include "internal.h"
-#include "../test/scoped_types.h"
+#include "../internal.h"
namespace bssl {
@@ -293,7 +293,7 @@
return false;
}
- ScopedOpenSSLBytes scoper(buf);
+ bssl::UniquePtr<uint8_t> scoper(buf);
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
}
@@ -344,7 +344,7 @@
CBB_cleanup(&cbb);
return false;
}
- ScopedOpenSSLBytes scoper(out_buf);
+ bssl::UniquePtr<uint8_t> scoper(out_buf);
return out_size == 1 && out_buf[0] == 0;
}
@@ -377,7 +377,7 @@
return false;
}
- ScopedOpenSSLBytes scoper(buf);
+ bssl::UniquePtr<uint8_t> scoper(buf);
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
}
@@ -417,7 +417,7 @@
if (!CBB_finish(cbb.get(), &buf, &buf_len)) {
return false;
}
- ScopedOpenSSLBytes scoper(buf);
+ bssl::UniquePtr<uint8_t> scoper(buf);
static const uint8_t kExpected[] = {
0xaa,
@@ -463,7 +463,7 @@
CBB_cleanup(&cbb);
return false;
}
- ScopedOpenSSLBytes scoper(buf);
+ bssl::UniquePtr<uint8_t> scoper(buf);
if (buf_len != 3 ||
memcmp(buf, "\x01\x01\x02", 3) != 0) {
@@ -487,7 +487,7 @@
CBB_cleanup(&cbb);
return false;
}
- ScopedOpenSSLBytes scoper(buf);
+ bssl::UniquePtr<uint8_t> scoper(buf);
if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) {
return false;
@@ -562,7 +562,7 @@
fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name);
return false;
}
- ScopedOpenSSLBytes scoper(out);
+ bssl::UniquePtr<uint8_t> scoper(out);
if (out == NULL) {
if (ber_len != der_len ||
@@ -675,7 +675,7 @@
int ok = CBS_get_asn1_implicit_string(&in, &out, &storage,
CBS_ASN1_CONTEXT_SPECIFIC | 0,
CBS_ASN1_OCTETSTRING);
- ScopedOpenSSLBytes scoper(storage);
+ bssl::UniquePtr<uint8_t> scoper(storage);
if (static_cast<bool>(ok) != test.ok) {
fprintf(stderr, "CBS_get_asn1_implicit_string unexpectedly %s\n",
@@ -730,8 +730,7 @@
};
static bool TestASN1Uint64() {
- for (size_t i = 0; i < sizeof(kASN1Uint64Tests) / sizeof(kASN1Uint64Tests[0]);
- i++) {
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Uint64Tests); i++) {
const ASN1Uint64Test *test = &kASN1Uint64Tests[i];
CBS cbs;
uint64_t value;
@@ -754,15 +753,13 @@
CBB_cleanup(&cbb);
return false;
}
- ScopedOpenSSLBytes scoper(out);
+ bssl::UniquePtr<uint8_t> scoper(out);
if (len != test->encoding_len || memcmp(out, test->encoding, len) != 0) {
return false;
}
}
- for (size_t i = 0;
- i < sizeof(kASN1InvalidUint64Tests) / sizeof(kASN1InvalidUint64Tests[0]);
- i++) {
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kASN1InvalidUint64Tests); i++) {
const ASN1InvalidUint64Test *test = &kASN1InvalidUint64Tests[i];
CBS cbs;
uint64_t value;
diff --git a/src/crypto/bytestring/cbb.c b/src/crypto/bytestring/cbb.c
index 0672904..0d97c8a 100644
--- a/src/crypto/bytestring/cbb.c
+++ b/src/crypto/bytestring/cbb.c
@@ -327,15 +327,18 @@
return cbb_add_length_prefixed(cbb, out_contents, 3);
}
-int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
- if ((tag & 0x1f) == 0x1f) {
- /* Long form identifier octets are not supported. */
+int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) {
+ if (tag > 0xff ||
+ (tag & 0x1f) == 0x1f) {
+ /* Long form identifier octets are not supported. Further, all current valid
+ * tag serializations are 8 bits. */
cbb->base->error = 1;
return 0;
}
if (!CBB_flush(cbb) ||
- !CBB_add_u8(cbb, tag)) {
+ /* |tag|'s representation matches the DER encoding. */
+ !CBB_add_u8(cbb, (uint8_t)tag)) {
return 0;
}
diff --git a/src/crypto/cipher/aead_test.cc b/src/crypto/cipher/aead_test.cc
index b75737f..38a07d3 100644
--- a/src/crypto/cipher/aead_test.cc
+++ b/src/crypto/cipher/aead_test.cc
@@ -17,7 +17,7 @@
#include <vector>
-#include <openssl/c++/aead.h>
+#include <openssl/aead.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
diff --git a/src/crypto/cipher/cipher_test.cc b/src/crypto/cipher/cipher_test.cc
index 08c8bd5..cb42fc5 100644
--- a/src/crypto/cipher/cipher_test.cc
+++ b/src/crypto/cipher/cipher_test.cc
@@ -57,7 +57,7 @@
#include <string>
#include <vector>
-#include <openssl/c++/cipher.h>
+#include <openssl/cipher.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
diff --git a/src/crypto/cipher/e_tls.c b/src/crypto/cipher/e_tls.c
index b562a53..d44234d 100644
--- a/src/crypto/cipher/e_tls.c
+++ b/src/crypto/cipher/e_tls.c
@@ -25,7 +25,7 @@
#include <openssl/sha.h>
#include <openssl/type_check.h>
-#include "../crypto/internal.h"
+#include "../internal.h"
#include "internal.h"
diff --git a/src/crypto/cmac/cmac_test.cc b/src/crypto/cmac/cmac_test.cc
index 2496f2a..7cb1df5 100644
--- a/src/crypto/cmac/cmac_test.cc
+++ b/src/crypto/cmac/cmac_test.cc
@@ -16,9 +16,10 @@
#include <algorithm>
+#include <openssl/cipher.h>
#include <openssl/cmac.h>
+#include <openssl/mem.h>
-#include "../test/scoped_types.h"
#include "../test/test_util.h"
@@ -43,7 +44,7 @@
return 0;
}
- ScopedCMAC_CTX ctx(CMAC_CTX_new());
+ bssl::UniquePtr<CMAC_CTX> ctx(CMAC_CTX_new());
if (!ctx || !CMAC_Init(ctx.get(), key, key_len, EVP_aes_128_cbc(), NULL)) {
fprintf(stderr, "%s: CMAC_Init failed.\n", name);
return 0;
diff --git a/src/crypto/curve25519/spake25519_test.cc b/src/crypto/curve25519/spake25519_test.cc
index d97a860..363b60c 100644
--- a/src/crypto/curve25519/spake25519_test.cc
+++ b/src/crypto/curve25519/spake25519_test.cc
@@ -19,18 +19,17 @@
#include <string.h>
#include <openssl/curve25519.h>
-#include "../test/scoped_types.h"
struct SPAKE2Run {
bool Run() {
- ScopedSPAKE2_CTX alice(SPAKE2_CTX_new(
+ bssl::UniquePtr<SPAKE2_CTX> alice(SPAKE2_CTX_new(
spake2_role_alice,
reinterpret_cast<const uint8_t *>(alice_names.first.data()),
alice_names.first.size(),
reinterpret_cast<const uint8_t *>(alice_names.second.data()),
alice_names.second.size()));
- ScopedSPAKE2_CTX bob(SPAKE2_CTX_new(
+ bssl::UniquePtr<SPAKE2_CTX> bob(SPAKE2_CTX_new(
spake2_role_bob,
reinterpret_cast<const uint8_t *>(bob_names.first.data()),
bob_names.first.size(),
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index ec297c4..7545071 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -311,7 +311,7 @@
priv_bits = p_bits - 1;
}
- if (!BN_rand(priv_key, priv_bits, 0, 0)) {
+ if (!BN_rand(priv_key, priv_bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
goto err;
}
}
diff --git a/src/crypto/dh/dh_test.cc b/src/crypto/dh/dh_test.cc
index b8bfe46..9a3d780 100644
--- a/src/crypto/dh/dh_test.cc
+++ b/src/crypto/dh/dh_test.cc
@@ -62,13 +62,12 @@
#include <vector>
#include <openssl/bn.h>
-#include <openssl/c++/bytestring.h>
+#include <openssl/bytestring.h>
#include <openssl/crypto.h>
+#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include "../test/scoped_types.h"
-
namespace bssl {
static bool RunBasicTests();
@@ -115,7 +114,7 @@
static bool RunBasicTests() {
BN_GENCB cb;
BN_GENCB_set(&cb, &GenerateCallback, stdout);
- ScopedDH a(DH_new());
+ bssl::UniquePtr<DH> a(DH_new());
if (!a || !DH_generate_parameters_ex(a.get(), 64, DH_GENERATOR_5, &cb)) {
return false;
}
@@ -143,7 +142,7 @@
BN_print_fp(stdout, a->g);
printf("\n");
- ScopedDH b(DH_new());
+ bssl::UniquePtr<DH> b(DH_new());
if (!b) {
return false;
}
@@ -437,8 +436,8 @@
for (unsigned i = 0; i < sizeof(kRFCTestData) / sizeof(RFC5114TestData); i++) {
const RFC5114TestData *td = kRFCTestData + i;
/* Set up DH structures setting key components */
- ScopedDH dhA(td->get_param(nullptr));
- ScopedDH dhB(td->get_param(nullptr));
+ bssl::UniquePtr<DH> dhA(td->get_param(nullptr));
+ bssl::UniquePtr<DH> dhB(td->get_param(nullptr));
if (!dhA || !dhB) {
fprintf(stderr, "Initialisation error RFC5114 set %u\n", i + 1);
return false;
@@ -513,8 +512,8 @@
};
static bool TestBadY() {
- ScopedDH dh(DH_get_2048_224(nullptr));
- ScopedBIGNUM pub_key(
+ bssl::UniquePtr<DH> dh(DH_get_2048_224(nullptr));
+ bssl::UniquePtr<BIGNUM> pub_key(
BN_bin2bn(kRFC5114_2048_224BadY, sizeof(kRFC5114_2048_224BadY), nullptr));
if (!dh || !pub_key || !DH_generate_key(dh.get())) {
return false;
@@ -544,7 +543,7 @@
if (!BN_hex2bn(&hex_bn, hex)) {
return false;
}
- ScopedBIGNUM free_hex_bn(hex_bn);
+ bssl::UniquePtr<BIGNUM> free_hex_bn(hex_bn);
return BN_cmp(bn, hex_bn) == 0;
}
@@ -560,7 +559,7 @@
CBS cbs;
CBS_init(&cbs, kParams, sizeof(kParams));
- ScopedDH dh(DH_parse_parameters(&cbs));
+ bssl::UniquePtr<DH> dh(DH_parse_parameters(&cbs));
if (!dh || CBS_len(&cbs) != 0 ||
!BIGNUMEqualsHex(
dh->p,
@@ -577,7 +576,7 @@
!CBB_finish(cbb.get(), &der, &der_len)) {
return false;
}
- ScopedOpenSSLBytes free_der(der);
+ bssl::UniquePtr<uint8_t> free_der(der);
if (der_len != sizeof(kParams) || memcmp(der, kParams, der_len) != 0) {
return false;
}
@@ -619,7 +618,7 @@
!CBB_finish(cbb.get(), &der, &der_len)) {
return false;
}
- ScopedOpenSSLBytes free_der2(der);
+ bssl::UniquePtr<uint8_t> free_der2(der);
if (der_len != sizeof(kParamsDSA) || memcmp(der, kParamsDSA, der_len) != 0) {
return false;
}
@@ -628,7 +627,7 @@
}
static bool TestRFC3526() {
- ScopedBIGNUM bn(BN_get_rfc3526_prime_1536(nullptr));
+ bssl::UniquePtr<BIGNUM> bn(BN_get_rfc3526_prime_1536(nullptr));
if (!bn) {
return false;
}
diff --git a/src/crypto/digest/digest_test.cc b/src/crypto/digest/digest_test.cc
index c94096b..70fa483 100644
--- a/src/crypto/digest/digest_test.cc
+++ b/src/crypto/digest/digest_test.cc
@@ -18,13 +18,16 @@
#include <memory>
-#include <openssl/c++/digest.h>
#include <openssl/crypto.h>
+#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/md4.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
+#include "../internal.h"
+
+
namespace bssl {
struct MD {
@@ -247,7 +250,7 @@
static int Main() {
CRYPTO_library_init();
- for (size_t i = 0; i < sizeof(kTestVectors) / sizeof(kTestVectors[0]); i++) {
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTestVectors); i++) {
if (!TestDigest(&kTestVectors[i])) {
fprintf(stderr, "Test %d failed\n", (int)i);
return 1;
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c
index 75e906b..271fb50 100644
--- a/src/crypto/ec/ec.c
+++ b/src/crypto/ec/ec.c
@@ -229,14 +229,14 @@
/* 1.3.132.0.35 */
{0x2b, 0x81, 0x04, 0x00, 0x23}, 5,
&P521,
- NULL,
+ &EC_GFp_mont_method,
},
{
NID_secp384r1,
/* 1.3.132.0.34 */
{0x2b, 0x81, 0x04, 0x00, 0x22}, 5,
&P384,
- NULL,
+ &EC_GFp_mont_method,
},
{
NID_X9_62_prime256v1,
@@ -246,12 +246,12 @@
#if defined(BORINGSSL_USE_INT128_CODE)
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
!defined(OPENSSL_SMALL)
- EC_GFp_nistz256_method,
+ &EC_GFp_nistz256_method,
#else
- EC_GFp_nistp256_method,
+ &EC_GFp_nistp256_method,
#endif
#else
- NULL,
+ &EC_GFp_mont_method,
#endif
},
{
@@ -260,9 +260,9 @@
{0x2b, 0x81, 0x04, 0x00, 0x21}, 5,
&P224,
#if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
- EC_GFp_nistp224_method,
+ &EC_GFp_nistp224_method,
#else
- NULL,
+ &EC_GFp_mont_method,
#endif
},
{NID_undef, {0}, 0, NULL, NULL},
@@ -365,10 +365,7 @@
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx) {
- const EC_METHOD *meth = EC_GFp_mont_method();
- EC_GROUP *ret;
-
- ret = ec_group_new(meth);
+ EC_GROUP *ret = ec_group_new(&EC_GFp_mont_method);
if (ret == NULL) {
return NULL;
}
@@ -409,7 +406,6 @@
EC_GROUP *group = NULL;
EC_POINT *P = NULL;
BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
- const EC_METHOD *meth;
int ok = 0;
BN_CTX *ctx = BN_CTX_new();
@@ -429,18 +425,11 @@
goto err;
}
- if (curve->method != 0) {
- meth = curve->method();
- if (((group = ec_group_new(meth)) == NULL) ||
- (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- goto err;
- }
- } else {
- if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- goto err;
- }
+ group = ec_group_new(curve->method);
+ if (group == NULL ||
+ !group->meth->group_set_curve(group, p, a, b, ctx)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
+ goto err;
}
if ((P = EC_POINT_new(group)) == NULL) {
@@ -525,74 +514,45 @@
OPENSSL_free(group);
}
-int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
- if (dest->meth->group_copy == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- if (dest->meth != src->meth) {
- OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
- return 0;
- }
- if (dest == src) {
- return 1;
- }
-
- dest->mont_data = src->mont_data;
-
- if (src->generator != NULL) {
- if (dest->generator == NULL) {
- dest->generator = EC_POINT_new(dest);
- if (dest->generator == NULL) {
- return 0;
- }
- }
- if (!EC_POINT_copy(dest->generator, src->generator)) {
- return 0;
- }
- } else {
- EC_POINT_clear_free(dest->generator);
- dest->generator = NULL;
- }
-
- if (!BN_copy(&dest->order, &src->order)) {
- return 0;
- }
-
- dest->curve_name = src->curve_name;
-
- return dest->meth->group_copy(dest, src);
-}
-
const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group) {
return group->mont_data;
}
EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
- EC_GROUP *t = NULL;
- int ok = 0;
-
if (a == NULL) {
return NULL;
}
- t = ec_group_new(a->meth);
- if (t == NULL) {
+ if (a->meth->group_copy == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return NULL;
}
- if (!ec_group_copy(t, a)) {
+
+ EC_GROUP *ret = ec_group_new(a->meth);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ ret->mont_data = a->mont_data;
+ ret->curve_name = a->curve_name;
+
+ if (a->generator != NULL) {
+ ret->generator = EC_POINT_dup(a->generator, ret);
+ if (ret->generator == NULL) {
+ goto err;
+ }
+ }
+
+ if (!BN_copy(&ret->order, &a->order) ||
+ !ret->meth->group_copy(ret, a)) {
goto err;
}
- ok = 1;
+ return ret;
err:
- if (!ok) {
- EC_GROUP_free(t);
- return NULL;
- } else {
- return t;
- }
+ EC_GROUP_free(ret);
+ return NULL;
}
int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
@@ -691,25 +651,18 @@
}
EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
- EC_POINT *t;
- int r;
-
if (a == NULL) {
return NULL;
}
- t = EC_POINT_new(group);
- if (t == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
+ EC_POINT *ret = EC_POINT_new(group);
+ if (ret == NULL ||
+ !EC_POINT_copy(ret, a)) {
+ EC_POINT_free(ret);
return NULL;
}
- r = EC_POINT_copy(t, a);
- if (!r) {
- EC_POINT_free(t);
- return NULL;
- } else {
- return t;
- }
+
+ return ret;
}
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
diff --git a/src/crypto/ec/ec_montgomery.c b/src/crypto/ec/ec_montgomery.c
index 4c1e3b4..1253a73 100644
--- a/src/crypto/ec/ec_montgomery.c
+++ b/src/crypto/ec/ec_montgomery.c
@@ -294,8 +294,7 @@
return ret;
}
-const EC_METHOD *EC_GFp_mont_method(void) {
- static const EC_METHOD ret = {
+const EC_METHOD EC_GFp_mont_method = {
ec_GFp_mont_group_init,
ec_GFp_mont_group_finish,
ec_GFp_mont_group_copy,
@@ -306,7 +305,4 @@
ec_GFp_mont_field_sqr,
ec_GFp_mont_field_encode,
ec_GFp_mont_field_decode,
- };
-
- return &ret;
-}
+};
diff --git a/src/crypto/ec/ec_test.cc b/src/crypto/ec/ec_test.cc
index ca0e140..839acfe 100644
--- a/src/crypto/ec/ec_test.cc
+++ b/src/crypto/ec/ec_test.cc
@@ -17,13 +17,14 @@
#include <vector>
-#include <openssl/c++/bytestring.h>
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/ec_key.h>
#include <openssl/err.h>
#include <openssl/mem.h>
+#include <openssl/nid.h>
-#include "../test/scoped_types.h"
namespace bssl {
@@ -97,10 +98,11 @@
// DecodeECPrivateKey decodes |in| as an ECPrivateKey structure and returns the
// result or nullptr on error.
-static ScopedEC_KEY DecodeECPrivateKey(const uint8_t *in, size_t in_len) {
+static bssl::UniquePtr<EC_KEY> DecodeECPrivateKey(const uint8_t *in,
+ size_t in_len) {
CBS cbs;
CBS_init(&cbs, in, in_len);
- ScopedEC_KEY ret(EC_KEY_parse_private_key(&cbs, NULL));
+ bssl::UniquePtr<EC_KEY> ret(EC_KEY_parse_private_key(&cbs, NULL));
if (!ret || CBS_len(&cbs) != 0) {
return nullptr;
}
@@ -124,7 +126,7 @@
}
static bool Testd2i_ECPrivateKey() {
- ScopedEC_KEY key = DecodeECPrivateKey(kECKeyWithoutPublic,
+ bssl::UniquePtr<EC_KEY> key = DecodeECPrivateKey(kECKeyWithoutPublic,
sizeof(kECKeyWithoutPublic));
if (!key) {
fprintf(stderr, "Failed to parse private key.\n");
@@ -152,8 +154,8 @@
return false;
}
- ScopedBIGNUM x(BN_new());
- ScopedBIGNUM y(BN_new());
+ bssl::UniquePtr<BIGNUM> x(BN_new());
+ bssl::UniquePtr<BIGNUM> y(BN_new());
if (!x || !y) {
return false;
}
@@ -162,8 +164,8 @@
fprintf(stderr, "Failed to get public key in affine coordinates.\n");
return false;
}
- ScopedOpenSSLString x_hex(BN_bn2hex(x.get()));
- ScopedOpenSSLString y_hex(BN_bn2hex(y.get()));
+ bssl::UniquePtr<char> x_hex(BN_bn2hex(x.get()));
+ bssl::UniquePtr<char> y_hex(BN_bn2hex(y.get()));
if (!x_hex || !y_hex) {
return false;
}
@@ -182,7 +184,7 @@
static bool TestZeroPadding() {
// Check that the correct encoding round-trips.
- ScopedEC_KEY key = DecodeECPrivateKey(kECKeyWithZeros,
+ bssl::UniquePtr<EC_KEY> key = DecodeECPrivateKey(kECKeyWithZeros,
sizeof(kECKeyWithZeros));
std::vector<uint8_t> out;
if (!key || !EncodeECPrivateKey(&out, key.get())) {
@@ -214,7 +216,7 @@
static bool TestSpecifiedCurve() {
// Test keys with specified curves may be decoded.
- ScopedEC_KEY key =
+ bssl::UniquePtr<EC_KEY> key =
DecodeECPrivateKey(kECKeySpecifiedCurve, sizeof(kECKeySpecifiedCurve));
if (!key) {
ERR_print_errors_fp(stderr);
@@ -245,7 +247,7 @@
}
static bool TestSetAffine(const int nid) {
- ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
if (!key) {
return false;
}
@@ -265,8 +267,8 @@
return false;
}
- ScopedBIGNUM x(BN_new());
- ScopedBIGNUM y(BN_new());
+ bssl::UniquePtr<BIGNUM> x(BN_new());
+ bssl::UniquePtr<BIGNUM> y(BN_new());
if (!EC_POINT_get_affine_coordinates_GFp(group,
EC_KEY_get0_public_key(key.get()),
x.get(), y.get(), nullptr)) {
@@ -276,7 +278,7 @@
return false;
}
- ScopedEC_POINT point(EC_POINT_new(group));
+ auto point = bssl::UniquePtr<EC_POINT>(EC_POINT_new(group));
if (!point) {
return false;
}
@@ -294,7 +296,7 @@
return false;
}
- ScopedEC_POINT invalid_point(EC_POINT_new(group));
+ bssl::UniquePtr<EC_POINT> invalid_point(EC_POINT_new(group));
if (!invalid_point) {
return false;
}
@@ -314,7 +316,7 @@
static bool TestArbitraryCurve() {
// Make a P-256 key and extract the affine coordinates.
- ScopedEC_KEY key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
if (!key || !EC_KEY_generate_key(key.get())) {
return false;
}
@@ -350,25 +352,25 @@
0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
};
- ScopedBN_CTX ctx(BN_CTX_new());
- ScopedBIGNUM p(BN_bin2bn(kP, sizeof(kP), nullptr));
- ScopedBIGNUM a(BN_bin2bn(kA, sizeof(kA), nullptr));
- ScopedBIGNUM b(BN_bin2bn(kB, sizeof(kB), nullptr));
- ScopedBIGNUM gx(BN_bin2bn(kX, sizeof(kX), nullptr));
- ScopedBIGNUM gy(BN_bin2bn(kY, sizeof(kY), nullptr));
- ScopedBIGNUM order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
- ScopedBIGNUM cofactor(BN_new());
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+ bssl::UniquePtr<BIGNUM> p(BN_bin2bn(kP, sizeof(kP), nullptr));
+ bssl::UniquePtr<BIGNUM> a(BN_bin2bn(kA, sizeof(kA), nullptr));
+ bssl::UniquePtr<BIGNUM> b(BN_bin2bn(kB, sizeof(kB), nullptr));
+ bssl::UniquePtr<BIGNUM> gx(BN_bin2bn(kX, sizeof(kX), nullptr));
+ bssl::UniquePtr<BIGNUM> gy(BN_bin2bn(kY, sizeof(kY), nullptr));
+ bssl::UniquePtr<BIGNUM> order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
+ bssl::UniquePtr<BIGNUM> cofactor(BN_new());
if (!ctx || !p || !a || !b || !gx || !gy || !order || !cofactor ||
!BN_set_word(cofactor.get(), 1)) {
return false;
}
- ScopedEC_GROUP group(
+ bssl::UniquePtr<EC_GROUP> group(
EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
if (!group) {
return false;
}
- ScopedEC_POINT generator(EC_POINT_new(group.get()));
+ bssl::UniquePtr<EC_POINT> generator(EC_POINT_new(group.get()));
if (!generator ||
!EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(),
gx.get(), gy.get(), ctx.get()) ||
@@ -383,9 +385,9 @@
}
// Copy |key| to |key2| using |group|.
- ScopedEC_KEY key2(EC_KEY_new());
- ScopedEC_POINT point(EC_POINT_new(group.get()));
- ScopedBIGNUM x(BN_new()), y(BN_new());
+ bssl::UniquePtr<EC_KEY> key2(EC_KEY_new());
+ bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group.get()));
+ bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
if (!key2 || !point || !x || !y ||
!EC_KEY_set_group(key2.get(), group.get()) ||
!EC_KEY_set_private_key(key2.get(), EC_KEY_get0_private_key(key.get())) ||
@@ -409,7 +411,7 @@
}
static bool TestAddingEqualPoints(int nid) {
- ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
if (!key) {
return false;
}
@@ -422,10 +424,10 @@
return false;
}
- ScopedEC_POINT p1(EC_POINT_new(group));
- ScopedEC_POINT p2(EC_POINT_new(group));
- ScopedEC_POINT double_p1(EC_POINT_new(group));
- ScopedEC_POINT p1_plus_p2(EC_POINT_new(group));
+ bssl::UniquePtr<EC_POINT> p1(EC_POINT_new(group));
+ bssl::UniquePtr<EC_POINT> p2(EC_POINT_new(group));
+ bssl::UniquePtr<EC_POINT> double_p1(EC_POINT_new(group));
+ bssl::UniquePtr<EC_POINT> p1_plus_p2(EC_POINT_new(group));
if (!p1 || !p2 || !double_p1 || !p1_plus_p2) {
return false;
}
@@ -437,7 +439,7 @@
return false;
}
- ScopedBN_CTX ctx(BN_CTX_new());
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
if (!ctx) {
return false;
}
diff --git a/src/crypto/ec/internal.h b/src/crypto/ec/internal.h
index 10770d9..b3c2a71 100644
--- a/src/crypto/ec/internal.h
+++ b/src/crypto/ec/internal.h
@@ -109,7 +109,7 @@
BN_CTX *); /* e.g. from Montgomery */
} /* EC_METHOD */;
-const EC_METHOD* EC_GFp_mont_method(void);
+extern const EC_METHOD EC_GFp_mont_method;
struct ec_group_st {
const EC_METHOD *meth;
@@ -222,12 +222,12 @@
void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit, uint8_t in);
-const EC_METHOD *EC_GFp_nistp224_method(void);
-const EC_METHOD *EC_GFp_nistp256_method(void);
+extern const EC_METHOD EC_GFp_nistp224_method;
+extern const EC_METHOD EC_GFp_nistp256_method;
-/* Returns GFp methods using montgomery multiplication, with x86-64
- * optimized P256. See http://eprint.iacr.org/2013/816. */
-const EC_METHOD *EC_GFp_nistz256_method(void);
+/* EC_GFp_nistz256_method is a GFp method using montgomery multiplication, with
+ * x86-64 optimized P256. See http://eprint.iacr.org/2013/816. */
+extern const EC_METHOD EC_GFp_nistz256_method;
struct ec_key_st {
EC_GROUP *group;
@@ -262,7 +262,7 @@
uint8_t oid[8];
uint8_t oid_len;
const struct curve_data *data;
- const EC_METHOD *(*method)(void);
+ const EC_METHOD *method;
};
/* OPENSSL_built_in_curves is terminated with an entry where |nid| is
diff --git a/src/crypto/ec/p224-64.c b/src/crypto/ec/p224-64.c
index 1b09cb9..be85ad6 100644
--- a/src/crypto/ec/p224-64.c
+++ b/src/crypto/ec/p224-64.c
@@ -1179,19 +1179,17 @@
return ret;
}
-const EC_METHOD *EC_GFp_nistp224_method(void) {
- static const EC_METHOD ret = {ec_GFp_simple_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_copy,
- ec_GFp_simple_group_set_curve,
- ec_GFp_nistp224_point_get_affine_coordinates,
- ec_GFp_nistp224_points_mul,
- ec_GFp_simple_field_mul,
- ec_GFp_simple_field_sqr,
- 0 /* field_encode */,
- 0 /* field_decode */};
-
- return &ret;
-}
+const EC_METHOD EC_GFp_nistp224_method = {
+ ec_GFp_simple_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_copy,
+ ec_GFp_simple_group_set_curve,
+ ec_GFp_nistp224_point_get_affine_coordinates,
+ ec_GFp_nistp224_points_mul,
+ ec_GFp_simple_field_mul,
+ ec_GFp_simple_field_sqr,
+ NULL /* field_encode */,
+ NULL /* field_decode */,
+};
#endif /* 64_BIT && !WINDOWS && !SMALL */
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index 31bf0ad..6a57a73 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -1734,19 +1734,17 @@
return ret;
}
-const EC_METHOD *EC_GFp_nistp256_method(void) {
- static const EC_METHOD ret = {
- ec_GFp_simple_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_copy,
- ec_GFp_simple_group_set_curve,
- ec_GFp_nistp256_point_get_affine_coordinates,
- ec_GFp_nistp256_points_mul,
- ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr,
- 0 /* field_encode */, 0 /* field_decode */,
- };
-
- return &ret;
-}
+const EC_METHOD EC_GFp_nistp256_method = {
+ ec_GFp_simple_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_copy,
+ ec_GFp_simple_group_set_curve,
+ ec_GFp_nistp256_point_get_affine_coordinates,
+ ec_GFp_nistp256_points_mul,
+ ec_GFp_simple_field_mul,
+ ec_GFp_simple_field_sqr,
+ NULL /* field_encode */,
+ NULL /* field_decode */,
+};
#endif /* 64_BIT && !WINDOWS */
diff --git a/src/crypto/ec/p256-x86_64.c b/src/crypto/ec/p256-x86_64.c
index 3f509db..a5906e4 100644
--- a/src/crypto/ec/p256-x86_64.c
+++ b/src/crypto/ec/p256-x86_64.c
@@ -556,22 +556,19 @@
return 1;
}
-const EC_METHOD *EC_GFp_nistz256_method(void) {
- static const EC_METHOD ret = {
- ec_GFp_mont_group_init,
- ec_GFp_mont_group_finish,
- ec_GFp_mont_group_copy,
- ec_GFp_mont_group_set_curve,
- ecp_nistz256_get_affine,
- ecp_nistz256_points_mul,
- ec_GFp_mont_field_mul,
- ec_GFp_mont_field_sqr,
- ec_GFp_mont_field_encode,
- ec_GFp_mont_field_decode,
- };
- return &ret;
-}
+const EC_METHOD EC_GFp_nistz256_method = {
+ ec_GFp_mont_group_init,
+ ec_GFp_mont_group_finish,
+ ec_GFp_mont_group_copy,
+ ec_GFp_mont_group_set_curve,
+ ecp_nistz256_get_affine,
+ ecp_nistz256_points_mul,
+ ec_GFp_mont_field_mul,
+ ec_GFp_mont_field_sqr,
+ ec_GFp_mont_field_encode,
+ ec_GFp_mont_field_decode,
+};
#endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
!defined(OPENSSL_SMALL) */
diff --git a/src/crypto/ecdh/CMakeLists.txt b/src/crypto/ecdh/CMakeLists.txt
index 8eaeae5..3d95180 100644
--- a/src/crypto/ecdh/CMakeLists.txt
+++ b/src/crypto/ecdh/CMakeLists.txt
@@ -7,3 +7,14 @@
ecdh.c
)
+
+add_executable(
+ ecdh_test
+
+ ecdh_test.cc
+
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(ecdh_test crypto)
+add_dependencies(all_tests ecdh_test)
diff --git a/src/crypto/ecdh/ecdh_test.cc b/src/crypto/ecdh/ecdh_test.cc
new file mode 100644
index 0000000..a02fd22
--- /dev/null
+++ b/src/crypto/ecdh/ecdh_test.cc
@@ -0,0 +1,125 @@
+/* Copyright (c) 2016, 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 <stdio.h>
+
+#include <vector>
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdh.h>
+#include <openssl/nid.h>
+
+#include "../test/file_test.h"
+
+
+static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
+ std::string curve_name;
+ if (!t->GetAttribute(&curve_name, key)) {
+ return nullptr;
+ }
+
+ if (curve_name == "P-224") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
+ }
+ if (curve_name == "P-256") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(
+ NID_X9_62_prime256v1));
+ }
+ if (curve_name == "P-384") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
+ }
+ if (curve_name == "P-521") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
+ }
+
+ t->PrintLine("Unknown curve '%s'", curve_name.c_str());
+ return nullptr;
+}
+
+static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *key) {
+ std::vector<uint8_t> bytes;
+ if (!t->GetBytes(&bytes, key)) {
+ return nullptr;
+ }
+
+ return bssl::UniquePtr<BIGNUM>(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
+}
+
+static bool TestECDH(FileTest *t, void *arg) {
+ bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
+ bssl::UniquePtr<BIGNUM> priv_key = GetBIGNUM(t, "Private");
+ bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
+ bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
+ bssl::UniquePtr<BIGNUM> peer_x = GetBIGNUM(t, "PeerX");
+ bssl::UniquePtr<BIGNUM> peer_y = GetBIGNUM(t, "PeerY");
+ std::vector<uint8_t> z;
+ if (!group || !priv_key || !x || !y || !peer_x || !peer_y ||
+ !t->GetBytes(&z, "Z")) {
+ return false;
+ }
+
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+ bssl::UniquePtr<EC_POINT> pub_key(EC_POINT_new(group.get()));
+ bssl::UniquePtr<EC_POINT> peer_pub_key(EC_POINT_new(group.get()));
+ if (!key || !pub_key || !peer_pub_key ||
+ !EC_KEY_set_group(key.get(), group.get()) ||
+ !EC_KEY_set_private_key(key.get(), priv_key.get()) ||
+ !EC_POINT_set_affine_coordinates_GFp(group.get(), pub_key.get(), x.get(),
+ y.get(), nullptr) ||
+ !EC_POINT_set_affine_coordinates_GFp(group.get(), peer_pub_key.get(),
+ peer_x.get(), peer_y.get(),
+ nullptr) ||
+ !EC_KEY_set_public_key(key.get(), pub_key.get()) ||
+ !EC_KEY_check_key(key.get())) {
+ return false;
+ }
+
+ std::vector<uint8_t> actual_z;
+ // Make |actual_z| larger than expected to ensure |ECDH_compute_key| returns
+ // the right amount of data.
+ actual_z.resize(z.size() + 1);
+ int ret = ECDH_compute_key(actual_z.data(), actual_z.size(),
+ peer_pub_key.get(), key.get(), nullptr);
+ if (ret < 0 ||
+ !t->ExpectBytesEqual(z.data(), z.size(), actual_z.data(),
+ static_cast<size_t>(ret))) {
+ return false;
+ }
+
+ // Test |ECDH_compute_key| truncates.
+ actual_z.resize(z.size() - 1);
+ ret = ECDH_compute_key(actual_z.data(), actual_z.size(), peer_pub_key.get(),
+ key.get(), nullptr);
+ if (ret < 0 ||
+ !t->ExpectBytesEqual(z.data(), z.size() - 1, actual_z.data(),
+ static_cast<size_t>(ret))) {
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char *argv[]) {
+ CRYPTO_library_init();
+
+ if (argc != 2) {
+ fprintf(stderr, "%s <test file.txt>\n", argv[0]);
+ return 1;
+ }
+
+ return FileTestMain(TestECDH, nullptr, argv[1]);
+}
diff --git a/src/crypto/ecdh/ecdh_tests.txt b/src/crypto/ecdh/ecdh_tests.txt
new file mode 100644
index 0000000..58dc3d9
--- /dev/null
+++ b/src/crypto/ecdh/ecdh_tests.txt
@@ -0,0 +1,804 @@
+# Tests from NIST CAVP SP 800-56A ECCCDH Primitive Test Vectors.
+# http://csrc.nist.gov/groups/STM/cavp/documents/components/ecccdhtestvectors.zip
+#
+# P-521 test vectors were fixed to have the right length.
+
+Curve = P-224
+Private = 8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd
+X = 8de2e26adf72c582d6568ef638c4fd59b18da171bdf501f1d929e048
+Y = 4a68a1c2b0fb22930d120555c1ece50ea98dea8407f71be36efac0de
+PeerX = af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280
+PeerY = 882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7
+Z = 7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8
+
+Curve = P-224
+Private = 043cb216f4b72cdf7629d63720a54aee0c99eb32d74477dac0c2f73d
+X = 2f90f5c8eac9c7decdbb97b6c2f715ab725e4fe40fe6d746efbf4e1b
+Y = 66897351454f927a309b269c5a6d31338be4c19a5acfc32cf656f45c
+PeerX = 13bfcd4f8e9442393cab8fb46b9f0566c226b22b37076976f0617a46
+PeerY = eeb2427529b288c63c2f8963c1e473df2fca6caa90d52e2f8db56dd4
+Z = ee93ce06b89ff72009e858c68eb708e7bc79ee0300f73bed69bbca09
+
+Curve = P-224
+Private = 5ad0dd6dbabb4f3c2ea5fe32e561b2ca55081486df2c7c15c9622b08
+X = 005bca45d793e7fe99a843704ed838315ab14a5f6277507e9bc37531
+Y = 43e9d421e1486ae5893bfd23c210e5c140d7c6b1ada59d842c9a98de
+PeerX = 756dd806b9d9c34d899691ecb45b771af468ec004486a0fdd283411e
+PeerY = 4d02c2ca617bb2c5d9613f25dd72413d229fd2901513aa29504eeefb
+Z = 3fcc01e34d4449da2a974b23fc36f9566754259d39149790cfa1ebd3
+
+Curve = P-224
+Private = 0aa6ff55a5d820efcb4e7d10b845ea3c9f9bc5dff86106db85318e22
+X = 2f96754131e0968198aa78fbe8c201dc5f3581c792de487340d32448
+Y = 61e8a5cd79615203b6d89e9496f9e236fe3b6be8731e743d615519c6
+PeerX = 0f537bf1c1122c55656d25e8aa8417e0b44b1526ae0523144f9921c4
+PeerY = f79b26d30e491a773696cc2c79b4f0596bc5b9eebaf394d162fb8684
+Z = 49129628b23afcef48139a3f6f59ff5e9811aa746aa4ff33c24bb940
+
+Curve = P-224
+Private = efe6e6e25affaf54c98d002abbc6328da159405a1b752e32dc23950a
+X = 355e962920bde043695f6bffb4b355c63da6f5de665ed46f2ec817e2
+Y = 748e095368f62e1d364edd461719793b404adbdaacbcadd88922ff37
+PeerX = 2b3631d2b06179b3174a100f7f57131eeea8947be0786c3dc64b2239
+PeerY = 83de29ae3dad31adc0236c6de7f14561ca2ea083c5270c78a2e6cbc0
+Z = fcdc69a40501d308a6839653a8f04309ec00233949522902ffa5eac6
+
+Curve = P-224
+Private = 61cb2932524001e5e9eeed6df7d9c8935ee3322029edd7aa8acbfd51
+X = d50e4adabfd989d7dbc7cf4052546cc7c447a97630436997ad4b9536
+Y = 5bea503473c5eaef9552d42c40b1f2f7ca292733b255b9bbe1b12337
+PeerX = 4511403de29059f69a475c5a6a5f6cabed5d9f014436a8cb70a02338
+PeerY = 7d2d1b62aa046df9340f9c37a087a06b32cf7f08a223f992812a828b
+Z = 827e9025cb62e0e837c596063f3b9b5a0f7afd8d8783200086d61ec1
+
+Curve = P-224
+Private = 8c7ace347171f92def98d845475fc82e1d1496da81ee58f505b985fa
+X = b1a8dcac89aca2799320b451df1c7ff4d97567abb68141c0d95fc2aa
+Y = 3524950902b1510bdc987d860afc27ad871ceaea66935abd3c0a99a8
+PeerX = 314a0b26dd31c248845d7cc17b61cad4608259bed85a58d1f1ffd378
+PeerY = 66e4b350352e119eecada382907f3619fd748ea73ae4899dfd496302
+Z = 335ba51228d94acbed851ca7821c801d5cb1c7975d7aa90a7159f8fa
+
+Curve = P-224
+Private = 382feb9b9ba10f189d99e71a89cdfe44cb554cec13a212840977fb68
+X = abb6f1e3773ff8fc73aea2a0b107809ce70adcefed6e41fc5cb43045
+Y = a963897ae906c10a055eeadb97ffdd6f748d3e5621e5fff304e48ba7
+PeerX = abe6843beec2fd9e5fb64730d0be4d165438ce922ed75dd80b4603e5
+PeerY = 6afe8673a96c4ba9900ad85995e631e436c6cc88a2c2b47b7c4886b8
+Z = 8c2e627594206b34f7356d3426eb3d79f518ef843fbe94014cceace3
+
+Curve = P-224
+Private = e0d62035101ef487c485c60fb4500eebe6a32ec64dbe97dbe0232c46
+X = 88537735e9b23e3e0e076f135a82d33f9bffb465f3abce8322a62a62
+Y = b4c8c123673197875c0bd14ed097606d330fba2b9200ef65a44764d3
+PeerX = 13cf9d6d2c9aae8274c27d446afd0c888ffdd52ae299a35984d4f527
+PeerY = dcbee75b515751f8ee2ae355e8afd5de21c62a939a6507b538cbc4af
+Z = 632abb662728dbc994508873d5c527ca5ef923c0d31fa6c47ef4c825
+
+Curve = P-224
+Private = b96ade5b73ba72aa8b6e4d74d7bf9c58e962ff78eb542287c7b44ba2
+X = 37682926a54f70a4c1748f54d50d5b00138a055f924f2c65e5b0bbe4
+Y = 596afefcdd640d29635015b89bdddd1f8c2723686d332e7a06ca8799
+PeerX = 965b637c0dfbc0cf954035686d70f7ec30929e664e521dbaa2280659
+PeerY = 82a58ff61bc90019bbcbb5875d3863db0bc2a1fa34b0ad4de1a83f99
+Z = 34641141aab05ef58bd376d609345901fb8f63477c6be9097f037f1f
+
+Curve = P-224
+Private = a40d7e12049c71e6522c7ff2384224061c3a457058b310557655b854
+X = 399801243bfe0c2da9b0a53c8ca57f2eee87aaa94a8e4d5e029f42ca
+Y = aa49e6d4b47cee7a5c4ab71d5a67da84e0b9b425ce3e70da68c889e7
+PeerX = 73cc645372ca2e71637cda943d8148f3382ab6dd0f2e1a49da94e134
+PeerY = df5c355c23e6e232ebc3bee2ab1873ee0d83e3382f8e6fe613f6343c
+Z = 4f74ac8507501a32bfc5a78d8271c200e835966e187e8d00011a8c75
+
+Curve = P-224
+Private = ad2519bc724d484e02a69f05149bb047714bf0f5986fac2e222cd946
+X = df9c1e0ef15e53b9f626e2be1cbe893639c06f3e0439ee95d7d4b1e3
+Y = 7a52a7386adda243efdf8941085c84e31239cab92b8017336748965e
+PeerX = 546578216250354e449e21546dd11cd1c5174236739acad9ce0f4512
+PeerY = d2a22fcd66d1abedc767668327c5cb9c599043276239cf3c8516af24
+Z = ad09c9ae4d2324ea81bb555b200d3c003e22a6870ee03b52df49e4de
+
+Curve = P-224
+Private = 3d312a9b9d8ed09140900bbac1e095527ebc9e3c6493bcf3666e3a29
+X = b4a0198dc8810e884425b750928b0c960c31f7a99663400b01a179df
+Y = 812b601bfc0738242c6f86f830f27acd632ca618a0b5280c9d5769f7
+PeerX = 1d46b1dc3a28123cb51346e67baec56404868678faf7d0e8b2afa22a
+PeerY = 0ec9e65ec97e218373e7fc115c2274d5b829a60d93f71e01d58136c3
+Z = ef029c28c68064b8abd2965a38c404fb5e944ace57e8638daba9d3cd
+
+Curve = P-224
+Private = 8ce0822dc24c153995755ac350737ef506641c7d752b4f9300c612ed
+X = 00dfc7ec137690cd6d12fdb2fd0b8c5314582108769c2b722ffb3958
+Y = 5eef3da4ba458127346bb64023868bddb7558a2ecfc813645f4ce9fe
+PeerX = 266d038cc7a4fe21f6c976318e827b82bb5b8f7443a55298136506e0
+PeerY = df123d98a7a20bbdf3943df2e3563422f8c0cf74d53aaabdd7c973ba
+Z = f83c16661dfcbad021cc3b5a5af51d9a18db4653866b3ff90787ce3e
+
+Curve = P-224
+Private = 0ff9b485325ab77f29e7bc379fed74bfac859482da0dee7528c19db2
+X = 7e603e6976db83c36011508fa695d1b515249e2e54b48fcbcfb90247
+Y = 0179a600ce86adfca9b1b931fa5173d618da09e841803d19b0264286
+PeerX = eb0a09f7a1c236a61f595809ec5670efd92e4598d5e613e092cdfdca
+PeerY = 50787ae2f2f15b88bc10f7b5f0aee1418373f16153aebd1fba54288d
+Z = f51258c63f232e55a66aa25ebd597b2018d1052c02eeb63866758005
+
+Curve = P-224
+Private = 19cf5ff6306467f28b9fe0675a43c0582552c8c12e59ce7c38f292b1
+X = fc20e906e609c112cfc2e0fea6303882c5db94e87e022373ab2c082a
+Y = aecdf1daa71782bc5a26bbbd8d7e8a76490e26abc17dffc774bd7341
+PeerX = 6b2f6b18a587f562ffc61bd9b0047322286986a78f1fd139b84f7c24
+PeerY = 7096908e4615266be59a53cd655515056ff92370a6271a5d3823d704
+Z = 7fdc969a186ff18429f2a276dac43beea21182d82ce2e5a0876552b1
+
+Curve = P-224
+Private = 90a15368e3532c0b1e51e55d139447c2c89bc160719d697291ea7c14
+X = c6837d506e976da7db3ad1267c359dff2ea6fb0b7f7f8e77024c59e9
+Y = 67eb491d2fc8a530c46525d2a8b2d7c1df5fba1ae740a4649c683ee6
+PeerX = 328101ba826acd75ff9f34d5574ce0dbc92f709bad8d7a33c47940c1
+PeerY = df39f1ea88488c55d5538160878b9ced18a887ea261dd712d14024ff
+Z = 3d60ab6db2b3ffe2d29ccff46d056e54230cf34982e241556ed2920c
+
+Curve = P-224
+Private = 8e0838e05e1721491067e1cabc2e8051b290e2616eec427b7121897d
+X = e9150f770075626019e18f95473b71e6828041791d3f08d3faeeaa2b
+Y = 475f70735eaae52308a3b763dc88efe18ab590ebafa035f6e08b001c
+PeerX = 0081e34270871e2ebbd94183f617b4ae15f0416dd634fe6e934cf3c0
+PeerY = 3a1e9f38a7b90b7317d26b9f6311063ab58b268cf489b2e50386d5d6
+Z = 9116d72786f4db5df7a8b43078c6ab9160d423513d35ea5e2559306d
+
+Curve = P-224
+Private = 38106e93f16a381adb1d72cee3da66ae462ad4bbfea9ecdf35d0814e
+X = 7be6c4c917829ab657dd79e8637d7aefd2f81f0de7654d957e97658d
+Y = 430d22d9e8438310f61e0d43f25fa3e34585f432baad27db3021bf0d
+PeerX = 2623632fdf0bd856805a69aa186d4133ef5904e1f655a972d66cce07
+PeerY = 2cef9728dd06fb8b50150f529b695076d4507983912585c89bd0682e
+Z = 207c53dcefac789aaa0276d9200b3a940ce5f2296f4cb2e81a185d3d
+
+Curve = P-224
+Private = e5d1718431cf50f6cbd1bc8019fa16762dfa12c989e5999977fb4ea2
+X = 2ea4966e7f92ed7f5cc61fde792045f63b731d6e7d0de2577f2d8ece
+Y = 1c4a7b1ede6f839162292df424be78e8176fb6f942a3c02391700f31
+PeerX = 8ee4d1dcc31dee4bf6fe21ca8a587721d910acfb122c16c2a77a8152
+PeerY = 4ebf323fff04eb477069a0ac68b345f6b1ae134efc31940e513cb99f
+Z = 10e467da34f48ad7072005bccd6da1b2ba3f71eafa1c393842f91d74
+
+Curve = P-224
+Private = 3d635691b62a9a927c633951c9369c8862bd2119d30970c2644727d6
+X = 438bbb980517afb20be1d674e3ac2b31cef07a9b23fb8f6e38e0d6c0
+Y = 0be5f1c47d58d21b6ed28423b32f5a94750da47edcef33ea79942afd
+PeerX = 97dcbe6d28335882a6d193cc54a1063dd0775dc328565300bb99e691
+PeerY = dad11dd5ece8cfd9f97c9a526e4a1506e6355969ee87826fc38bcd24
+Z = 82fd2f9c60c4f999ac00bbe64bfc11da8ff8cda2e499fced65230bb1
+
+Curve = P-224
+Private = acf3c85bbdc379f02f5ea36e7f0f53095a9e7046a28685a8659bf798
+X = ff7511215c71d796bd646e8474be4416b91684ce0d269ef6f422013b
+Y = b7bf5e79b5a9393bb9ea42c0bdb2d3c2dc806e1a7306aa58e4fdbea5
+PeerX = ce9126dd53972dea1de1d11efef900de34b661859c4648c5c0e534f7
+PeerY = e113b6f2c1659d07f2716e64a83c18bbce344dd2121fe85168eae085
+Z = 530f7e7fc932613b29c981f261cb036cba3f1df3864e0e1cba2685a2
+
+Curve = P-224
+Private = cffd62cb00a0e3163fbf2c397fadc9618210f86b4f54a675287305f0
+X = 04bf4d948f4430d18b4ed6c96dbaf981fa11a403ed16887f06754981
+Y = 7c1326a9cef51f79d4e78303d6064b459f612584ac2fdf593d7d5d84
+PeerX = 84419967d6cfad41e75a02b6da605a97949a183a97c306c4b46e66a5
+PeerY = 5cc9b259718b1bc8b144fde633a894616ffd59a3a6d5d8e942c7cbb7
+Z = 49f6fd0139248ef4df2db05d1319bd5b1489e249827a45a8a5f12427
+
+Curve = P-224
+Private = 85f903e43943d13c68932e710e80de52cbc0b8f1a1418ea4da079299
+X = 970a4a7e01d4188497ceb46955eb1b842d9085819a9b925c84529d3d
+Y = dfa2526480f833ea0edbd204e4e365fef3472888fe7d9691c3ebc09f
+PeerX = 7c9cac35768063c2827f60a7f51388f2a8f4b7f8cd736bd6bc337477
+PeerY = 29ee6b849c6025d577dbcc55fbd17018f4edbc2ef105b004d6257bcd
+Z = 8f7e34e597ae8093b98270a74a8dfcdbed457f42f43df487c5487161
+
+Curve = P-224
+Private = cce64891a3d0129fee0d4a96cfbe7ac470b85e967529057cfa31a1d9
+X = a6b29632db94da2125dc1cf80e03702687b2acc1122022fa2174765a
+Y = 61723edd73e10daed73775278f1958ba56f1fc9d085ebc2b64c84fe5
+PeerX = 085a7642ad8e59b1a3e8726a7547afbecffdac1dab7e57230c6a9df4
+PeerY = f91c36d881fe9b8047a3530713554a1af4c25c5a8e654dcdcf689f2e
+Z = 71954e2261e8510be1a060733671d2e9d0a2d012eb4e09556d697d2a
+
+Curve = P-256
+Private = 7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534
+X = ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230
+Y = 28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141
+PeerX = 700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287
+PeerY = db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac
+Z = 46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b
+
+Curve = P-256
+Private = 38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5
+X = 119f2f047902782ab0c9e27a54aff5eb9b964829ca99c06b02ddba95b0a3f6d0
+Y = 8f52b726664cac366fc98ac7a012b2682cbd962e5acb544671d41b9445704d1d
+PeerX = 809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae
+PeerY = b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3
+Z = 057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67
+
+Curve = P-256
+Private = 1accfaf1b97712b85a6f54b148985a1bdc4c9bec0bd258cad4b3d603f49f32c8
+X = d9f2b79c172845bfdb560bbb01447ca5ecc0470a09513b6126902c6b4f8d1051
+Y = f815ef5ec32128d3487834764678702e64e164ff7315185e23aff5facd96d7bc
+PeerX = a2339c12d4a03c33546de533268b4ad667debf458b464d77443636440ee7fec3
+PeerY = ef48a3ab26e20220bcda2c1851076839dae88eae962869a497bf73cb66faf536
+Z = 2d457b78b4614132477618a5b077965ec90730a8c81a1c75d6d4ec68005d67ec
+
+Curve = P-256
+Private = 207c43a79bfee03db6f4b944f53d2fb76cc49ef1c9c4d34d51b6c65c4db6932d
+X = 24277c33f450462dcb3d4801d57b9ced05188f16c28eda873258048cd1607e0d
+Y = c4789753e2b1f63b32ff014ec42cd6a69fac81dfe6d0d6fd4af372ae27c46f88
+PeerX = df3989b9fa55495719b3cf46dccd28b5153f7808191dd518eff0c3cff2b705ed
+PeerY = 422294ff46003429d739a33206c8752552c8ba54a270defc06e221e0feaf6ac4
+Z = 96441259534b80f6aee3d287a6bb17b5094dd4277d9e294f8fe73e48bf2a0024
+
+Curve = P-256
+Private = 59137e38152350b195c9718d39673d519838055ad908dd4757152fd8255c09bf
+X = a8c5fdce8b62c5ada598f141adb3b26cf254c280b2857a63d2ad783a73115f6b
+Y = 806e1aafec4af80a0d786b3de45375b517a7e5b51ffb2c356537c9e6ef227d4a
+PeerX = 41192d2813e79561e6a1d6f53c8bc1a433a199c835e141b05a74a97b0faeb922
+PeerY = 1af98cc45e98a7e041b01cf35f462b7562281351c8ebf3ffa02e33a0722a1328
+Z = 19d44c8d63e8e8dd12c22a87b8cd4ece27acdde04dbf47f7f27537a6999a8e62
+
+Curve = P-256
+Private = f5f8e0174610a661277979b58ce5c90fee6c9b3bb346a90a7196255e40b132ef
+X = 7b861dcd2844a5a8363f6b8ef8d493640f55879217189d80326aad9480dfc149
+Y = c4675b45eeb306405f6c33c38bc69eb2bdec9b75ad5af4706aab84543b9cc63a
+PeerX = 33e82092a0f1fb38f5649d5867fba28b503172b7035574bf8e5b7100a3052792
+PeerY = f2cf6b601e0a05945e335550bf648d782f46186c772c0f20d3cd0d6b8ca14b2f
+Z = 664e45d5bba4ac931cd65d52017e4be9b19a515f669bea4703542a2c525cd3d3
+
+Curve = P-256
+Private = 3b589af7db03459c23068b64f63f28d3c3c6bc25b5bf76ac05f35482888b5190
+X = 9fb38e2d58ea1baf7622e96720101cae3cde4ba6c1e9fa26d9b1de0899102863
+Y = d5561b900406edf50802dd7d73e89395f8aed72fba0e1d1b61fe1d22302260f0
+PeerX = 6a9e0c3f916e4e315c91147be571686d90464e8bf981d34a90b6353bca6eeba7
+PeerY = 40f9bead39c2f2bcc2602f75b8a73ec7bdffcbcead159d0174c6c4d3c5357f05
+Z = ca342daa50dc09d61be7c196c85e60a80c5cb04931746820be548cdde055679d
+
+Curve = P-256
+Private = d8bf929a20ea7436b2461b541a11c80e61d826c0a4c9d322b31dd54e7f58b9c8
+X = 20f07631e4a6512a89ad487c4e9d63039e579cb0d7a556cb9e661cd59c1e7fa4
+Y = 6de91846b3eee8a5ec09c2ab1f41e21bd83620ccdd1bdce3ab7ea6e02dd274f5
+PeerX = a9c0acade55c2a73ead1a86fb0a9713223c82475791cd0e210b046412ce224bb
+PeerY = f6de0afa20e93e078467c053d241903edad734c6b403ba758c2b5ff04c9d4229
+Z = 35aa9b52536a461bfde4e85fc756be928c7de97923f0416c7a3ac8f88b3d4489
+
+Curve = P-256
+Private = 0f9883ba0ef32ee75ded0d8bda39a5146a29f1f2507b3bd458dbea0b2bb05b4d
+X = abb61b423be5d6c26e21c605832c9142dc1dfe5a5fff28726737936e6fbf516d
+Y = 733d2513ef58beab202090586fac91bf0fee31e80ab33473ab23a2d89e58fad6
+PeerX = 94e94f16a98255fff2b9ac0c9598aac35487b3232d3231bd93b7db7df36f9eb9
+PeerY = d8049a43579cfa90b8093a94416cbefbf93386f15b3f6e190b6e3455fedfe69a
+Z = 605c16178a9bc875dcbff54d63fe00df699c03e8a888e9e94dfbab90b25f39b4
+
+Curve = P-256
+Private = 2beedb04b05c6988f6a67500bb813faf2cae0d580c9253b6339e4a3337bb6c08
+X = 3d63e429cb5fa895a9247129bf4e48e89f35d7b11de8158efeb3e106a2a87395
+Y = 0cae9e477ef41e7c8c1064379bb7b554ddcbcae79f9814281f1e50f0403c61f3
+PeerX = e099bf2a4d557460b5544430bbf6da11004d127cb5d67f64ab07c94fcdf5274f
+PeerY = d9c50dbe70d714edb5e221f4e020610eeb6270517e688ca64fb0e98c7ef8c1c5
+Z = f96e40a1b72840854bb62bc13c40cc2795e373d4e715980b261476835a092e0b
+
+Curve = P-256
+Private = 77c15dcf44610e41696bab758943eff1409333e4d5a11bbe72c8f6c395e9f848
+X = ad5d13c3db508ddcd38457e5991434a251bed49cf5ddcb59cdee73865f138c9f
+Y = 62cec1e70588aa4fdfc7b9a09daa678081c04e1208b9d662b8a2214bf8e81a21
+PeerX = f75a5fe56bda34f3c1396296626ef012dc07e4825838778a645c8248cff01658
+PeerY = 33bbdf1b1772d8059df568b061f3f1122f28a8d819167c97be448e3dc3fb0c3c
+Z = 8388fa79c4babdca02a8e8a34f9e43554976e420a4ad273c81b26e4228e9d3a3
+
+Curve = P-256
+Private = 42a83b985011d12303db1a800f2610f74aa71cdf19c67d54ce6c9ed951e9093e
+X = ab48caa61ea35f13f8ed07ffa6a13e8db224dfecfae1a7df8b1bb6ebaf0cb97d
+Y = 1274530ca2c385a3218bddfbcbf0b4024c9badd5243bff834ebff24a8618dccb
+PeerX = 2db4540d50230756158abf61d9835712b6486c74312183ccefcaef2797b7674d
+PeerY = 62f57f314e3f3495dc4e099012f5e0ba71770f9660a1eada54104cdfde77243e
+Z = 72877cea33ccc4715038d4bcbdfe0e43f42a9e2c0c3b017fc2370f4b9acbda4a
+
+Curve = P-256
+Private = ceed35507b5c93ead5989119b9ba342cfe38e6e638ba6eea343a55475de2800b
+X = 9a8cd9bd72e71752df91440f77c547509a84df98114e7de4f26cdb39234a625d
+Y = d07cfc84c8e144fab2839f5189bb1d7c88631d579bbc58012ed9a2327da52f62
+PeerX = cd94fc9497e8990750309e9a8534fd114b0a6e54da89c4796101897041d14ecb
+PeerY = c3def4b5fe04faee0a11932229fff563637bfdee0e79c6deeaf449f85401c5c4
+Z = e4e7408d85ff0e0e9c838003f28cdbd5247cdce31f32f62494b70e5f1bc36307
+
+Curve = P-256
+Private = 43e0e9d95af4dc36483cdd1968d2b7eeb8611fcce77f3a4e7d059ae43e509604
+X = f989cf8ee956a82e7ebd9881cdbfb2fd946189b08db53559bc8cfdd48071eb14
+Y = 5eff28f1a18a616b04b7d337868679f6dd84f9a7b3d7b6f8af276c19611a541d
+PeerX = 15b9e467af4d290c417402e040426fe4cf236bae72baa392ed89780dfccdb471
+PeerY = cdf4e9170fb904302b8fd93a820ba8cc7ed4efd3a6f2d6b05b80b2ff2aee4e77
+Z = ed56bcf695b734142c24ecb1fc1bb64d08f175eb243a31f37b3d9bb4407f3b96
+
+Curve = P-256
+Private = b2f3600df3368ef8a0bb85ab22f41fc0e5f4fdd54be8167a5c3cd4b08db04903
+X = 69c627625b36a429c398b45c38677cb35d8beb1cf78a571e40e99fe4eac1cd4e
+Y = 81690112b0a88f20f7136b28d7d47e5fbc2ada3c8edd87589bc19ec9590637bd
+PeerX = 49c503ba6c4fa605182e186b5e81113f075bc11dcfd51c932fb21e951eee2fa1
+PeerY = 8af706ff0922d87b3f0c5e4e31d8b259aeb260a9269643ed520a13bb25da5924
+Z = bc5c7055089fc9d6c89f83c1ea1ada879d9934b2ea28fcf4e4a7e984b28ad2cf
+
+Curve = P-256
+Private = 4002534307f8b62a9bf67ff641ddc60fef593b17c3341239e95bdb3e579bfdc8
+X = 5fe964671315a18aa68a2a6e3dd1fde7e23b8ce7181471cfac43c99e1ae80262
+Y = d5827be282e62c84de531b963884ba832db5d6b2c3a256f0e604fe7e6b8a7f72
+PeerX = 19b38de39fdd2f70f7091631a4f75d1993740ba9429162c2a45312401636b29c
+PeerY = 09aed7232b28e060941741b6828bcdfa2bc49cc844f3773611504f82a390a5ae
+Z = 9a4e8e657f6b0e097f47954a63c75d74fcba71a30d83651e3e5a91aa7ccd8343
+
+Curve = P-256
+Private = 4dfa12defc60319021b681b3ff84a10a511958c850939ed45635934ba4979147
+X = c9b2b8496f1440bd4a2d1e52752fd372835b364885e154a7dac49295f281ec7c
+Y = fbe6b926a8a4de26ccc83b802b1212400754be25d9f3eeaf008b09870ae76321
+PeerX = 2c91c61f33adfe9311c942fdbff6ba47020feff416b7bb63cec13faf9b099954
+PeerY = 6cab31b06419e5221fca014fb84ec870622a1b12bab5ae43682aa7ea73ea08d0
+Z = 3ca1fc7ad858fb1a6aba232542f3e2a749ffc7203a2374a3f3d3267f1fc97b78
+
+Curve = P-256
+Private = 1331f6d874a4ed3bc4a2c6e9c74331d3039796314beee3b7152fcdba5556304e
+X = 59e1e101521046ad9cf1d082e9d2ec7dd22530cce064991f1e55c5bcf5fcb591
+Y = 482f4f673176c8fdaa0bb6e59b15a3e47454e3a04297d3863c9338d98add1f37
+PeerX = a28a2edf58025668f724aaf83a50956b7ac1cfbbff79b08c3bf87dfd2828d767
+PeerY = dfa7bfffd4c766b86abeaf5c99b6e50cb9ccc9d9d00b7ffc7804b0491b67bc03
+Z = 1aaabe7ee6e4a6fa732291202433a237df1b49bc53866bfbe00db96a0f58224f
+
+Curve = P-256
+Private = dd5e9f70ae740073ca0204df60763fb6036c45709bf4a7bb4e671412fad65da3
+X = 30b9db2e2e977bcdc98cb87dd736cbd8e78552121925cf16e1933657c2fb2314
+Y = 6a45028800b81291bce5c2e1fed7ded650620ebbe6050c6f3a7f0dfb4673ab5c
+PeerX = a2ef857a081f9d6eb206a81c4cf78a802bdf598ae380c8886ecd85fdc1ed7644
+PeerY = 563c4c20419f07bc17d0539fade1855e34839515b892c0f5d26561f97fa04d1a
+Z = 430e6a4fba4449d700d2733e557f66a3bf3d50517c1271b1ddae1161b7ac798c
+
+Curve = P-256
+Private = 5ae026cfc060d55600717e55b8a12e116d1d0df34af831979057607c2d9c2f76
+X = 46c9ebd1a4a3c8c0b6d572b5dcfba12467603208a9cb5d2acfbb733c40cf6391
+Y = 46c913a27d044185d38b467ace011e04d4d9bbbb8cb9ae25fa92aaf15a595e86
+PeerX = ccd8a2d86bc92f2e01bce4d6922cf7fe1626aed044685e95e2eebd464505f01f
+PeerY = e9ddd583a9635a667777d5b8a8f31b0f79eba12c75023410b54b8567dddc0f38
+Z = 1ce9e6740529499f98d1f1d71329147a33df1d05e4765b539b11cf615d6974d3
+
+Curve = P-256
+Private = b601ac425d5dbf9e1735c5e2d5bdb79ca98b3d5be4a2cfd6f2273f150e064d9d
+X = 7c9e950841d26c8dde8994398b8f5d475a022bc63de7773fcf8d552e01f1ba0a
+Y = cc42b9885c9b3bee0f8d8c57d3a8f6355016c019c4062fa22cff2f209b5cc2e1
+PeerX = c188ffc8947f7301fb7b53e36746097c2134bf9cc981ba74b4e9c4361f595e4e
+PeerY = bf7d2f2056e72421ef393f0c0f2b0e00130e3cac4abbcc00286168e85ec55051
+Z = 4690e3743c07d643f1bc183636ab2a9cb936a60a802113c49bb1b3f2d0661660
+
+Curve = P-256
+Private = fefb1dda1845312b5fce6b81b2be205af2f3a274f5a212f66c0d9fc33d7ae535
+X = 38b54db85500cb20c61056edd3d88b6a9dc26780a047f213a6e1b900f76596eb
+Y = 6387e4e5781571e4eb8ae62991a33b5dc33301c5bc7e125d53794a39160d8fd0
+PeerX = 317e1020ff53fccef18bf47bb7f2dd7707fb7b7a7578e04f35b3beed222a0eb6
+PeerY = 09420ce5a19d77c6fe1ee587e6a49fbaf8f280e8df033d75403302e5a27db2ae
+Z = 30c2261bd0004e61feda2c16aa5e21ffa8d7e7f7dbf6ec379a43b48e4b36aeb0
+
+Curve = P-256
+Private = 334ae0c4693d23935a7e8e043ebbde21e168a7cba3fa507c9be41d7681e049ce
+X = 3f2bf1589abf3047bf3e54ac9a95379bff95f8f55405f64eca36a7eebe8ffca7
+Y = 5212a94e66c5ae9a8991872f66a72723d80ec5b2e925745c456f5371943b3a06
+PeerX = 45fb02b2ceb9d7c79d9c2fa93e9c7967c2fa4df5789f9640b24264b1e524fcb1
+PeerY = 5c6e8ecf1f7d3023893b7b1ca1e4d178972ee2a230757ddc564ffe37f5c5a321
+Z = 2adae4a138a239dcd93c243a3803c3e4cf96e37fe14e6a9b717be9599959b11c
+
+Curve = P-256
+Private = 2c4bde40214fcc3bfc47d4cf434b629acbe9157f8fd0282540331de7942cf09d
+X = 29c0807f10cbc42fb45c9989da50681eead716daa7b9e91fd32e062f5eb92ca0
+Y = ff1d6d1955d7376b2da24fe1163a271659136341bc2eb1195fc706dc62e7f34d
+PeerX = a19ef7bff98ada781842fbfc51a47aff39b5935a1c7d9625c8d323d511c92de6
+PeerY = e9c184df75c955e02e02e400ffe45f78f339e1afe6d056fb3245f4700ce606ef
+Z = 2e277ec30f5ea07d6ce513149b9479b96e07f4b6913b1b5c11305c1444a1bc0b
+
+Curve = P-256
+Private = 85a268f9d7772f990c36b42b0a331adc92b5941de0b862d5d89a347cbf8faab0
+X = 9cf4b98581ca1779453cc816ff28b4100af56cf1bf2e5bc312d83b6b1b21d333
+Y = 7a5504fcac5231a0d12d658218284868229c844a04a3450d6c7381abe080bf3b
+PeerX = 356c5a444c049a52fee0adeb7e5d82ae5aa83030bfff31bbf8ce2096cf161c4b
+PeerY = 57d128de8b2a57a094d1a001e572173f96e8866ae352bf29cddaf92fc85b2f92
+Z = 1e51373bd2c6044c129c436e742a55be2a668a85ae08441b6756445df5493857
+
+Curve = P-384
+Private = 3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1
+X = 9803807f2f6d2fd966cdd0290bd410c0190352fbec7ff6247de1302df86f25d34fe4a97bef60cff548355c015dbb3e5f
+Y = ba26ca69ec2f5b5d9dad20cc9da711383a9dbe34ea3fa5a2af75b46502629ad54dd8b7d73a8abb06a3a3be47d650cc99
+PeerX = a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066
+PeerY = ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a
+Z = 5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1
+
+Curve = P-384
+Private = 92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783
+X = ea4018f5a307c379180bf6a62fd2ceceebeeb7d4df063a66fb838aa35243419791f7e2c9d4803c9319aa0eb03c416b66
+Y = 68835a91484f05ef028284df6436fb88ffebabcdd69ab0133e6735a1bcfb37203d10d340a8328a7b68770ca75878a1a6
+PeerX = 30f43fcf2b6b00de53f624f1543090681839717d53c7c955d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0
+PeerY = 25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c860857a68153ab62e525ec0530d81b5aa15897981e858757
+Z = a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd501a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff
+
+Curve = P-384
+Private = 12cf6a223a72352543830f3f18530d5cb37f26880a0b294482c8a8ef8afad09aa78b7dc2f2789a78c66af5d1cc553853
+X = fcfcea085e8cf74d0dced1620ba8423694f903a219bbf901b0b59d6ac81baad316a242ba32bde85cb248119b852fab66
+Y = 972e3c68c7ab402c5836f2a16ed451a33120a7750a6039f3ff15388ee622b7065f7122bf6d51aefbc29b37b03404581b
+PeerX = 1aefbfa2c6c8c855a1a216774550b79a24cda37607bb1f7cc906650ee4b3816d68f6a9c75da6e4242cebfb6652f65180
+PeerY = 419d28b723ebadb7658fcebb9ad9b7adea674f1da3dc6b6397b55da0f61a3eddacb4acdb14441cb214b04a0844c02fa3
+Z = 3d2e640f350805eed1ff43b40a72b2abed0a518bcebe8f2d15b111b6773223da3c3489121db173d414b5bd5ad7153435
+
+Curve = P-384
+Private = 8dd48063a3a058c334b5cc7a4ce07d02e5ee6d8f1f3c51a1600962cbab462690ae3cd974fb39e40b0e843daa0fd32de1
+X = e38c9846248123c3421861ea4d32669a7b5c3c08376ad28104399494c84ff5efa3894adb2c6cbe8c3c913ef2eec5bd3c
+Y = 9fa84024a1028796df84021f7b6c9d02f0f4bd1a612a03cbf75a0beea43fef8ae84b48c60172aadf09c1ad016d0bf3ce
+PeerX = 8bc089326ec55b9cf59b34f0eb754d93596ca290fcb3444c83d4de3a5607037ec397683f8cef07eab2fe357eae36c449
+PeerY = d9d16ce8ac85b3f1e94568521aae534e67139e310ec72693526aa2e927b5b322c95a1a033c229cb6770c957cd3148dd7
+Z = 6a42cfc392aba0bfd3d17b7ccf062b91fc09bbf3417612d02a90bdde62ae40c54bb2e56e167d6b70db670097eb8db854
+
+Curve = P-384
+Private = 84ece6cc3429309bd5b23e959793ed2b111ec5cb43b6c18085fcaea9efa0685d98a6262ee0d330ee250bc8a67d0e733f
+X = 3222063a2997b302ee60ee1961108ff4c7acf1c0ef1d5fb0d164b84bce71c431705cb9aea9a45f5d73806655a058bee3
+Y = e61fa9e7fbe7cd43abf99596a3d3a039e99fa9dc93b0bdd9cad81966d17eeaf557068afa7c78466bb5b22032d1100fa6
+PeerX = eb952e2d9ac0c20c6cc48fb225c2ad154f53c8750b003fd3b4ed8ed1dc0defac61bcdde02a2bcfee7067d75d342ed2b0
+PeerY = f1828205baece82d1b267d0d7ff2f9c9e15b69a72df47058a97f3891005d1fb38858f5603de840e591dfa4f6e7d489e1
+Z = ce7ba454d4412729a32bb833a2d1fd2ae612d4667c3a900e069214818613447df8c611de66da200db7c375cf913e4405
+
+Curve = P-384
+Private = 68fce2121dc3a1e37b10f1dde309f9e2e18fac47cd1770951451c3484cdb77cb136d00e731260597cc2859601c01a25b
+X = 868be0e694841830e424d913d8e7d86b84ee1021d82b0ecf523f09fe89a76c0c95c49f2dfbcf829c1e39709d55efbb3b
+Y = 9195eb183675b40fd92f51f37713317e4a9b4f715c8ab22e0773b1bc71d3a219f05b8116074658ee86b52e36f3897116
+PeerX = 441d029e244eb7168d647d4df50db5f4e4974ab3fdaf022aff058b3695d0b8c814cc88da6285dc6df1ac55c553885003
+PeerY = e8025ac23a41d4b1ea2aa46c50c6e479946b59b6d76497cd9249977e0bfe4a6262622f13d42a3c43d66bdbb30403c345
+Z = ba69f0acdf3e1ca95caaac4ecaf475bbe51b54777efce01ca381f45370e486fe87f9f419b150c61e329a286d1aa265ec
+
+Curve = P-384
+Private = b1764c54897e7aae6de9e7751f2f37de849291f88f0f91093155b858d1cc32a3a87980f706b86cc83f927bdfdbeae0bd
+X = c371222feaa6770c6f3ea3e0dac9740def4fcf821378b7f91ff937c21e0470f70f3a31d5c6b2912195f10926942b48ae
+Y = 047d6b4d765123563f81116bc665b7b8cc6207830d805fd84da7cb805a65baa7c12fd592d1b5b5e3e65d9672a9ef7662
+PeerX = 3d4e6bf08a73404accc1629873468e4269e82d90d832e58ad72142639b5a056ad8d35c66c60e8149fac0c797bceb7c2f
+PeerY = 9b0308dc7f0e6d29f8c277acbc65a21e5adb83d11e6873bc0a07fda0997f482504602f59e10bc5cb476b83d0a4f75e71
+Z = 1a6688ee1d6e59865d8e3ada37781d36bb0c2717eef92e61964d3927cb765c2965ea80f7f63e58c322ba0397faeaf62b
+
+Curve = P-384
+Private = f0f7a96e70d98fd5a30ad6406cf56eb5b72a510e9f192f50e1f84524dbf3d2439f7287bb36f5aa912a79deaab4adea82
+X = 99c8c41cb1ab5e0854a346e4b08a537c1706a61553387c8d94943ab15196d40dbaa55b8210a77a5d00915f2c4ea69eab
+Y = 5531065bdcf17bfb3cb55a02e41a57c7f694c383ad289f900fbd656c2233a93c92e933e7a26f54cbb56f0ad875c51bb0
+PeerX = f5f6bef1d110da03be0017eac760cc34b24d092f736f237bc7054b3865312a813bcb62d297fb10a4f7abf54708fe2d3d
+PeerY = 06fdf8d7dc032f4e10010bf19cbf6159321252ff415fb91920d438f24e67e60c2eb0463204679fa356af44cea9c9ebf5
+Z = d06a568bf2336b90cbac325161be7695eacb2295f599500d787f072612aca313ee5d874f807ddef6c1f023fe2b6e7cd0
+
+Curve = P-384
+Private = 9efb87ddc61d43c482ba66e1b143aef678fbd0d1bebc2000941fabe677fe5b706bf78fce36d100b17cc787ead74bbca2
+X = 4c34efee8f0c95565d2065d1bbac2a2dd25ae964320eb6bccedc5f3a9b42a881a1afca1bb6b880584fa27b01c193cd92
+Y = d8fb01dbf7cd0a3868c26b951f393c3c56c2858cee901f7793ff5d271925d13a41f8e52409f4eba1990f33acb0bac669
+PeerX = 7cdec77e0737ea37c67b89b7137fe38818010f4464438ee4d1d35a0c488cad3fde2f37d00885d36d3b795b9f93d23a67
+PeerY = 28c42ee8d6027c56cf979ba4c229fdb01d234944f8ac433650112c3cf0f02844e888a3569dfef7828a8a884589aa055e
+Z = bb3b1eda9c6560d82ff5bee403339f1e80342338a991344853b56b24f109a4d94b92f654f0425edd4c205903d7586104
+
+Curve = P-384
+Private = d787a57fde22ec656a0a525cf3c738b30d73af61e743ea90893ecb2d7b622add2f94ee25c2171467afb093f3f84d0018
+X = 171546923b87b2cbbad664f01ce932bf09d6a6118168678446bfa9f0938608cb4667a98f4ec8ac1462285c2508f74862
+Y = fa41cb4db68ae71f1f8a3e8939dc52c2dec61a83c983beb2a02baf29ec49278088882ed0cf56c74b5c173b552ccf63cf
+PeerX = 8eeea3a319c8df99fbc29cb55f243a720d95509515ee5cc587a5c5ae22fbbd009e626db3e911def0b99a4f7ae304b1ba
+PeerY = 73877dc94db9adddc0d9a4b24e8976c22d73c844370e1ee857f8d1b129a3bd5f63f40caf3bd0533e38a5f5777074ff9e
+Z = 1e97b60add7cb35c7403dd884c0a75795b7683fff8b49f9d8672a8206bfdcf0a106b8768f983258c74167422e44e4d14
+
+Curve = P-384
+Private = 83d70f7b164d9f4c227c767046b20eb34dfc778f5387e32e834b1e6daec20edb8ca5bb4192093f543b68e6aeb7ce788b
+X = 57cd770f3bbcbe0c78c770eab0b169bc45e139f86378ffae1c2b16966727c2f2eb724572b8f3eb228d130db4ff862c63
+Y = 7ec5c8813b685558d83e924f14bc719f6eb7ae0cbb2c474227c5bda88637a4f26c64817929af999592da6f787490332f
+PeerX = a721f6a2d4527411834b13d4d3a33c29beb83ab7682465c6cbaf6624aca6ea58c30eb0f29dd842886695400d7254f20f
+PeerY = 14ba6e26355109ad35129366d5e3a640ae798505a7fa55a96a36b5dad33de00474f6670f522214dd7952140ab0a7eb68
+Z = 1023478840e54775bfc69293a3cf97f5bc914726455c66538eb5623e218feef7df4befa23e09d77145ad577db32b41f9
+
+Curve = P-384
+Private = 8f558e05818b88ed383d5fca962e53413db1a0e4637eda194f761944cbea114ab9d5da175a7d57882550b0e432f395a9
+X = 9a2f57f4867ce753d72b0d95195df6f96c1fae934f602efd7b6a54582f556cfa539d89005ca2edac08ad9b72dd1f60ba
+Y = d9b94ee82da9cc601f346044998ba387aee56404dc6ecc8ab2b590443319d0b2b6176f9d0eac2d44678ed561607d09a9
+PeerX = d882a8505c2d5cb9b8851fc676677bb0087681ad53faceba1738286b45827561e7da37b880276c656cfc38b32ade847e
+PeerY = 34b314bdc134575654573cffaf40445da2e6aaf987f7e913cd4c3091523058984a25d8f21da8326192456c6a0fa5f60c
+Z = 6ad6b9dc8a6cf0d3691c501cbb967867f6e4bbb764b60dbff8fcff3ed42dbba39d63cf325b4b4078858495ddee75f954
+
+Curve = P-384
+Private = 0f5dee0affa7bbf239d5dff32987ebb7cf84fcceed643e1d3c62d0b3352aec23b6e5ac7fa4105c8cb26126ad2d1892cb
+X = 23346bdfbc9d7c7c736e02bdf607671ff6082fdd27334a8bc75f3b23681ebe614d0597dd614fae58677c835a9f0b273b
+Y = 82ba36290d2f94db41479eb45ab4eaf67928a2315138d59eecc9b5285dfddd6714f77557216ea44cc6fc119d8243efaf
+PeerX = 815c9d773dbf5fb6a1b86799966247f4006a23c92e68c55e9eaa998b17d8832dd4d84d927d831d4f68dac67c6488219f
+PeerY = e79269948b2611484560fd490feec887cb55ef99a4b524880fa7499d6a07283aae2afa33feab97deca40bc606c4d8764
+Z = cc9e063566d46b357b3fcae21827377331e5e290a36e60cd7c39102b828ae0b918dc5a02216b07fe6f1958d834e42437
+
+Curve = P-384
+Private = 037b633b5b8ba857c0fc85656868232e2febf59578718391b81da8541a00bfe53c30ae04151847f27499f8d7abad8cf4
+X = 8878ac8a947f7d5cb2b47aad24fbb8210d86126585399a2871f84aa9c5fde3074ae540c6bf82275ca822d0feb862bc74
+Y = 632f5cd2f900c2711c32f8930728eb647d31edd8d650f9654e7d33e5ed1b475489d08daa30d8cbcba6bfc3b60d9b5a37
+PeerX = 1c0eeda7a2be000c5bdcda0478aed4db733d2a9e341224379123ad847030f29e3b168fa18e89a3c0fba2a6ce1c28fc3b
+PeerY = ec8c1c83c118c4dbea94271869f2d868eb65e8b44e21e6f14b0f4d9b38c068daefa27114255b9a41d084cc4a1ad85456
+Z = deff7f03bd09865baf945e73edff6d5122c03fb561db87dec8662e09bed4340b28a9efe118337bb7d3d4f7f568635ff9
+
+Curve = P-384
+Private = e3d07106bedcc096e7d91630ffd3094df2c7859db8d7edbb2e37b4ac47f429a637d06a67d2fba33838764ef203464991
+X = e74a1a2b85f1cbf8dbbdf050cf1aff8acb02fda2fb6591f9d3cfe4e79d0ae938a9c1483e7b75f8db24505d65065cdb18
+Y = 1773ee591822f7abaa856a1a60bc0a5203548dbd1cb5025466eff8481bd07614eaa04a16c3db76905913e972a5b6b59d
+PeerX = c95c185e256bf997f30b311548ae7f768a38dee43eeeef43083f3077be70e2bf39ac1d4daf360c514c8c6be623443d1a
+PeerY = 3e63a663eaf75d8a765ab2b9a35513d7933fa5e26420a5244550ec6c3b6f033b96db2aca3d6ac6aab052ce929595aea5
+Z = c8b1038f735ad3bb3e4637c3e47eab487637911a6b7950a4e461948329d3923b969e5db663675623611a457fcda35a71
+
+Curve = P-384
+Private = f3f9b0c65a49a506632c8a45b10f66b5316f9eeb06fae218f2da62333f99905117b141c760e8974efc4af10570635791
+X = a4ad77aa7d86e5361118a6b921710c820721210712f4c347985fdee58aa4effa1e28be80a17b120b139f96300f89b49b
+Y = 1ddf22e07e03f1560d8f45a480094560dba9fae7f9531130c1b57ebb95982496524f31d3797793396fa823f22bdb4328
+PeerX = 3497238a7e6ad166df2dac039aa4dac8d17aa925e7c7631eb3b56e3aaa1c545fcd54d2e5985807910fb202b1fc191d2a
+PeerY = a49e5c487dcc7aa40a8f234c979446040d9174e3ad357d404d7765183195aed3f913641b90c81a306ebf0d8913861316
+Z = d337eaa32b9f716b8747b005b97a553c59dab0c51df41a2d49039cdae705aa75c7b9e7bc0b6a0e8c578c902bc4fff23e
+
+Curve = P-384
+Private = 59fce7fad7de28bac0230690c95710c720e528f9a4e54d3a6a8cd5fc5c5f21637031ce1c5b4e3d39647d8dcb9b794664
+X = 9c43bf971edf09402876ee742095381f78b1bd3aa39b5132af75dbfe7e98bd78bde10fe2e903c2b6379e1deee175a1b0
+Y = a6c58ecea5a477bb01bd543b339f1cc49f1371a2cda4d46eb4e53e250597942351a99665a122ffea9bde0636c375daf2
+PeerX = 90a34737d45b1aa65f74e0bd0659bc118f8e4b774b761944ffa6573c6df4f41dec0d11b697abd934d390871d4b453240
+PeerY = 9b590719bb3307c149a7817be355d684893a307764b512eeffe07cb699edb5a6ffbf8d6032e6c79d5e93e94212c2aa4e
+Z = 32d292b695a4488e42a7b7922e1ae537d76a3d21a0b2e36875f60e9f6d3e8779c2afb3a413b9dd79ae18e70b47d337c1
+
+Curve = P-384
+Private = 3e49fbf950a424c5d80228dc4bc35e9f6c6c0c1d04440998da0a609a877575dbe437d6a5cedaa2ddd2a1a17fd112aded
+X = 5a949594228b1a3d6f599eb3db0d06070fbc551c657b58234ba164ce3fe415fa5f3eb823c08dc29b8c341219c77b6b3d
+Y = 2baad447c8c290cfed25edd9031c41d0b76921457327f42db31122b81f337bbf0b1039ec830ce9061a3761953c75e4a8
+PeerX = dda546acfc8f903d11e2e3920669636d44b2068aeb66ff07aa266f0030e1535b0ed0203cb8a460ac990f1394faf22f1d
+PeerY = 15bbb2597913035faadf413476f4c70f7279769a40c986f470c427b4ee4962abdf8173bbad81874772925fd32f0b159f
+Z = 1220e7e6cad7b25df98e5bbdcc6c0b65ca6c2a50c5ff6c41dca71e475646fd489615979ca92fb4389aeadefde79a24f1
+
+Curve = P-384
+Private = 50ccc1f7076e92f4638e85f2db98e0b483e6e2204c92bdd440a6deea04e37a07c6e72791c190ad4e4e86e01efba84269
+X = 756c07df0ce32c839dac9fb4733c9c28b70113a676a7057c38d223f22a3a9095a8d564653af528e04c7e1824be4a6512
+Y = 17c2ce6962cbd2a2e066297b39d57dd9bb4680f0191d390f70b4e461419b2972ce68ad46127fdda6c39195774ea86df3
+PeerX = 788be2336c52f4454d63ee944b1e49bfb619a08371048e6da92e584eae70bde1f171c4df378bd1f3c0ab03048a237802
+PeerY = 4673ebd8db604eaf41711748bab2968a23ca4476ce144e728247f08af752929157b5830f1e26067466bdfa8b65145a33
+Z = 793bb9cd22a93cf468faf804a38d12b78cb12189ec679ddd2e9aa21fa9a5a0b049ab16a23574fe04c1c3c02343b91beb
+
+Curve = P-384
+Private = 06f132b71f74d87bf99857e1e4350a594e5fe35533b888552ceccbc0d8923c902e36141d7691e28631b8bc9bafe5e064
+X = 2a3cc6b8ff5cde926e7e3a189a1bd029c9b586351af8838f4f201cb8f4b70ef3b0da06d352c80fc26baf8f42b784459e
+Y = bf9985960176da6d23c7452a2954ffcbbcb24249b43019a2a023e0b3dabd461f19ad3e775c364f3f11ad49f3099400d3
+PeerX = d09bb822eb99e38060954747c82bb3278cf96bbf36fece3400f4c873838a40c135eb3babb9293bd1001bf3ecdee7bf26
+PeerY = d416db6e1b87bbb7427788a3b6c7a7ab2c165b1e366f9608df512037584f213a648d47f16ac326e19aae972f63fd76c9
+Z = 012d191cf7404a523678c6fc075de8285b243720a903047708bb33e501e0dbee5bcc40d7c3ef6c6da39ea24d830da1e8
+
+Curve = P-384
+Private = 12048ebb4331ec19a1e23f1a2c773b664ccfe90a28bfb846fc12f81dff44b7443c77647164bf1e9e67fd2c07a6766241
+X = bc18836bc7a9fdf54b5352f37d7528ab8fa8ec544a8c6180511cbfdd49cce377c39e34c031b5240dc9980503ed2f262c
+Y = 8086cbe338191080f0b7a16c7afc4c7b0326f9ac66f58552ef4bb9d24de3429ed5d3277ed58fcf48f2b5f61326bec6c6
+PeerX = 13741262ede5861dad71063dfd204b91ea1d3b7c631df68eb949969527d79a1dc59295ef7d2bca6743e8cd77b04d1b58
+PeerY = 0baaeadc7e19d74a8a04451a135f1be1b02fe299f9dc00bfdf201e83d995c6950bcc1cb89d6f7b30bf54656b9a4da586
+Z = ad0fd3ddffe8884b9263f3c15fe1f07f2a5a22ffdc7e967085eea45f0cd959f20f18f522763e28bcc925e496a52dda98
+
+Curve = P-384
+Private = 34d61a699ca576169fcdc0cc7e44e4e1221db0fe63d16850c8104029f7d48449714b9884328cae189978754ab460b486
+X = 867f81104ccd6b163a7902b670ef406042cb0cce7dcdc63d1dfc91b2c40e3cdf7595834bf9eceb79849f1636fc8462fc
+Y = 9d4bde8e875ec49697d258d1d59465f8431c6f5531e1c59e9f9ebe3cf164a8d9ce10a12f1979283a959bad244dd83863
+PeerX = 9e22cbc18657f516a864b37b783348b66f1aa9626cd631f4fa1bd32ad88cf11db52057c660860d39d11fbf024fabd444
+PeerY = 6b0d53c79681c28116df71e9cee74fd56c8b7f04b39f1198cc72284e98be9562e35926fb4f48a9fbecafe729309e8b6f
+Z = dc4ca392dc15e20185f2c6a8ea5ec31dfc96f56153a47394b3072b13d0015f5d4ae13beb3bed54d65848f9b8383e6c95
+
+Curve = P-384
+Private = dc60fa8736d702135ff16aab992bb88eac397f5972456c72ec447374d0d8ce61153831bfc86ad5a6eb5b60bfb96a862c
+X = b69beede85d0f829fec1b893ccb9c3e052ff692e13b974537bc5b0f9feaf7b22e84f03231629b24866bdb4b8cf908914
+Y = 66f85e2bfcaba2843285b0e14ebc07ef7dafff8b424416fee647b59897b619f20eed95a632e6a4206bf7da429c04c560
+PeerX = 2db5da5f940eaa884f4db5ec2139b0469f38e4e6fbbcc52df15c0f7cf7fcb1808c749764b6be85d2fdc5b16f58ad5dc0
+PeerY = 22e8b02dcf33e1b5a083849545f84ad5e43f77cb71546dbbac0d11bdb2ee202e9d3872e8d028c08990746c5e1dde9989
+Z = d765b208112d2b9ed5ad10c4046e2e3b0dbf57c469329519e239ac28b25c7d852bf757d5de0ee271cadd021d86cfd347
+
+Curve = P-384
+Private = 6fa6a1c704730987aa634b0516a826aba8c6d6411d3a4c89772d7a62610256a2e2f289f5c3440b0ec1e70fa339e251ce
+X = 53de1fc1328e8de14aecab29ad8a40d6b13768f86f7d298433d20fec791f86f8bc73f358098b256a298bb488de257bf4
+Y = ac28944fd27f17b82946c04c66c41f0053d3692f275da55cd8739a95bd8cd3af2f96e4de959ea8344d8945375905858b
+PeerX = 329647baa354224eb4414829c5368c82d7893b39804e08cbb2180f459befc4b347a389a70c91a23bd9d30c83be5295d3
+PeerY = cc8f61923fad2aa8e505d6cfa126b9fabd5af9dce290b75660ef06d1caa73681d06089c33bc4246b3aa30dbcd2435b12
+Z = d3778850aeb58804fbe9dfe6f38b9fa8e20c2ca4e0dec335aafceca0333e3f2490b53c0c1a14a831ba37c4b9d74be0f2
+
+Curve = P-384
+Private = 74ad8386c1cb2ca0fcdeb31e0869bb3f48c036afe2ef110ca302bc8b910f621c9fcc54cec32bb89ec7caa84c7b8e54a8
+X = 27a3e83cfb9d5122e73129d801615857da7cc089cccc9c54ab3032a19e0a0a9f677346e37f08a0b3ed8da6e5dd691063
+Y = 8d60e44aa5e0fd30c918456796af37f0e41957901645e5c596c6d989f5859b03a0bd7d1f4e77936fff3c74d204e5388e
+PeerX = 29d8a36d22200a75b7aea1bb47cdfcb1b7fd66de967041434728ab5d533a060df732130600fe6f75852a871fb2938e39
+PeerY = e19b53db528395de897a45108967715eb8cb55c3fcbf23379372c0873a058d57544b102ecce722b2ccabb1a603774fd5
+Z = 81e1e71575bb4505498de097350186430a6242fa6c57b85a5f984a23371123d2d1424eefbf804258392bc723e4ef1e35
+
+Curve = P-521
+Private = 017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47
+X = 00602f9d0cf9e526b29e22381c203c48a886c2b0673033366314f1ffbcba240ba42f4ef38a76174635f91e6b4ed34275eb01c8467d05ca80315bf1a7bbd945f550a5
+Y = 01b7c85f26f5d4b2d7355cf6b02117659943762b6d1db5ab4f1dbc44ce7b2946eb6c7de342962893fd387d1b73d7a8672d1f236961170b7eb3579953ee5cdc88cd2d
+PeerX = 00685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d
+PeerY = 01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676
+Z = 005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831
+
+Curve = P-521
+Private = 00816f19c1fb10ef94d4a1d81c156ec3d1de08b66761f03f06ee4bb9dcebbbfe1eaa1ed49a6a990838d8ed318c14d74cc872f95d05d07ad50f621ceb620cd905cfb8
+X = 00d45615ed5d37fde699610a62cd43ba76bedd8f85ed31005fe00d6450fbbd101291abd96d4945a8b57bc73b3fe9f4671105309ec9b6879d0551d930dac8ba45d255
+Y = 01425332844e592b440c0027972ad1526431c06732df19cd46a242172d4dd67c2c8c99dfc22e49949a56cf90c6473635ce82f25b33682fb19bc33bd910ed8ce3a7fa
+PeerX = 01df277c152108349bc34d539ee0cf06b24f5d3500677b4445453ccc21409453aafb8a72a0be9ebe54d12270aa51b3ab7f316aa5e74a951c5e53f74cd95fc29aee7a
+PeerY = 013d52f33a9f3c14384d1587fa8abe7aed74bc33749ad9c570b471776422c7d4505d9b0a96b3bfac041e4c6a6990ae7f700e5b4a6640229112deafa0cd8bb0d089b0
+Z = 000b3920ac830ade812c8f96805da2236e002acbbf13596a9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032c26d42189273ca4efa4c3db6bd12a6853759
+
+Curve = P-521
+Private = 012f2e0c6d9e9d117ceb9723bced02eb3d4eebf5feeaf8ee0113ccd8057b13ddd416e0b74280c2d0ba8ed291c443bc1b141caf8afb3a71f97f57c225c03e1e4d42b0
+X = 00717fcb3d4a40d103871ede044dc803db508aaa4ae74b70b9fb8d8dfd84bfecfad17871879698c292d2fd5e17b4f9343636c531a4fac68a35a93665546b9a878679
+Y = 00f3d96a8637036993ab5d244500fff9d2772112826f6436603d3eb234a44d5c4e5c577234679c4f9df725ee5b9118f23d8a58d0cc01096daf70e8dfec0128bdc2e8
+PeerX = 0092db3142564d27a5f0006f819908fba1b85038a5bc2509906a497daac67fd7aee0fc2daba4e4334eeaef0e0019204b471cd88024f82115d8149cc0cf4f7ce1a4d5
+PeerY = 016bad0623f517b158d9881841d2571efbad63f85cbe2e581960c5d670601a6760272675a548996217e4ab2b8ebce31d71fca63fcc3c08e91c1d8edd91cf6fe845f8
+Z = 006b380a6e95679277cfee4e8353bf96ef2a1ebdd060749f2f046fe571053740bbcc9a0b55790bc9ab56c3208aa05ddf746a10a3ad694daae00d980d944aabc6a08f
+
+Curve = P-521
+Private = 00e548a79d8b05f923b9825d11b656f222e8cb98b0f89de1d317184dc5a698f7c71161ee7dc11cd31f4f4f8ae3a981e1a3e78bdebb97d7c204b9261b4ef92e0918e0
+X = 000ce800217ed243dd10a79ad73df578aa8a3f9194af528cd1094bbfee27a3b5481ad5862c8876c0c3f91294c0ab3aa806d9020cbaa2ed72b7fecdc5a09a6dad6f32
+Y = 01543c9ab45b12469232918e21d5a351f9a4b9cbf9efb2afcc402fa9b31650bec2d641a05c440d35331c0893d11fb13151335988b303341301a73dc5f61d574e67d9
+PeerX = 00fdd40d9e9d974027cb3bae682162eac1328ad61bc4353c45bf5afe76bf607d2894c8cce23695d920f2464fda4773d4693be4b3773584691bdb0329b7f4c86cc299
+PeerY = 0034ceac6a3fef1c3e1c494bfe8d872b183832219a7e14da414d4e3474573671ec19b033be831b915435905925b44947c592959945b4eb7c951c3b9c8cf52530ba23
+Z = 00fbbcd0b8d05331fef6086f22a6cce4d35724ab7a2f49dd8458d0bfd57a0b8b70f246c17c4468c076874b0dff7a0336823b19e98bf1cec05e4beffb0591f97713c6
+
+Curve = P-521
+Private = 01c8aae94bb10b8ca4f7be577b4fb32bb2381032c4942c24fc2d753e7cc5e47b483389d9f3b956d20ee9001b1eef9f23545f72c5602140046839e963313c3decc864
+X = 0106a14e2ee8ff970aa8ab0c79b97a33bba2958e070b75b94736b77bbe3f777324fa52872771aa88a63a9e8490c3378df4dc760cd14d62be700779dd1a4377943656
+Y = 002366ce3941e0b284b1aa81215d0d3b9778fce23c8cd1e4ed6fa0abf62156c91d4b3eb55999c3471bed275e9e60e5aa9d690d310bfb15c9c5bbd6f5e9eb39682b74
+PeerX = 0098d99dee0816550e84dbfced7e88137fddcf581a725a455021115fe49f8dc3cf233cd9ea0e6f039dc7919da973cdceaca205da39e0bd98c8062536c47f258f44b5
+PeerY = 00cd225c8797371be0c4297d2b457740100c774141d8f214c23b61aa2b6cd4806b9b70722aa4965fb622f42b7391e27e5ec21c5679c5b06b59127372997d421adc1e
+Z = 0145cfa38f25943516c96a5fd4bfebb2f645d10520117aa51971eff442808a23b4e23c187e639ff928c3725fbd1c0c2ad0d4aeb207bc1a6fb6cb6d467888dc044b3c
+
+Curve = P-521
+Private = 009b0af137c9696c75b7e6df7b73156bb2d45f482e5a4217324f478b10ceb76af09724cf86afa316e7f89918d31d54824a5c33107a483c15c15b96edc661340b1c0e
+X = 00748cdbb875d35f4bccb62abe20e82d32e4c14dc2feb5b87da2d0ccb11c9b6d4b7737b6c46f0dfb4d896e2db92fcf53cdbbae2a404c0babd564ad7adeac6273efa3
+Y = 01984acab8d8f173323de0bb60274b228871609373bb22a17287e9dec7495873abc09a8915b54c8455c8e02f654f602e23a2bbd7a9ebb74f3009bd65ecc650814cc0
+PeerX = 007ae115adaaf041691ab6b7fb8c921f99d8ed32d283d67084e80b9ad9c40c56cd98389fb0a849d9ecf7268c297b6f93406119f40e32b5773ed25a28a9a85c4a7588
+PeerY = 01a28e004e37eeaefe1f4dbb71f1878696141af3a10a9691c4ed93487214643b761fa4b0fbeeb247cf6d3fba7a60697536ad03f49b80a9d1cb079673654977c5fa94
+Z = 005c5721e96c273319fd60ecc46b5962f698e974b429f28fe6962f4ac656be2eb8674c4aafc037eab48ece612953b1e8d861016b6ad0c79805784c67f73ada96f351
+
+Curve = P-521
+Private = 01e48faacee6dec83ffcde944cf6bdf4ce4bae72747888ebafee455b1e91584971efb49127976a52f4142952f7c207ec0265f2b718cf3ead96ea4f62c752e4f7acd3
+X = 010eb1b4d9172bcc23f4f20cc9560fc54928c3f34ea61c00391dc766c76ed9fa608449377d1e4fadd1236025417330b4b91086704ace3e4e6484c606e2a943478c86
+Y = 0149413864069825ee1d0828da9f4a97713005e9bd1adbc3b38c5b946900721a960fe96ad2c1b3a44fe3de9156136d44cb17cbc2415729bb782e16bfe2deb3069e43
+PeerX = 012588115e6f7f7bdcfdf57f03b169b479758baafdaf569d04135987b2ce6164c02a57685eb5276b5dae6295d3fe90620f38b5535c6d2260c173e61eb888ca920203
+PeerY = 01542c169cf97c2596fe2ddd848a222e367c5f7e6267ebc1bcd9ab5dcf49158f1a48e4af29a897b7e6a82091c2db874d8e7abf0f58064691344154f396dbaed188b6
+Z = 01736d9717429b4f412e903febe2f9e0fffd81355d6ce2c06ff3f66a3be15ceec6e65e308347593f00d7f33591da4043c30763d72749f72cdceebe825e4b34ecd570
+
+Curve = P-521
+Private = 00c29aa223ea8d64b4a1eda27f39d3bc98ea0148dd98c1cbe595f8fd2bfbde119c9e017a50f5d1fc121c08c1cef31b758859556eb3e0e042d8dd6aaac57a05ca61e3
+X = 001511c848ef60d5419a98d10204db0fe58224124370061bcfa4e9249d50618c56bf3722471b259f38263bb7b280d23caf2a1ee8737f9371cdb2732cdc958369930c
+Y = 01d461681ae6d8c49b4c5f4d6016143fb1bd7491573e3ed0e6c48b82e821644f87f82f0e5f08fd16f1f98fa17586200ab02ed8c627b35c3f27617ec5fd92f456203f
+PeerX = 0169491d55bd09049fdf4c2a53a660480fee4c03a0538675d1cd09b5bba78dac48543ef118a1173b3fbf8b20e39ce0e6b890a163c50f9645b3d21d1cbb3b60a6fff4
+PeerY = 0083494b2eba76910fed33c761804515011fab50e3b377abd8a8a045d886d2238d2c268ac1b6ec88bd71b7ba78e2c33c152e4bf7da5d565e4acbecf5e92c7ad662bb
+Z = 018f2ae9476c771726a77780208dedfefa205488996b18fecc50bfd4c132753f5766b2cd744afa9918606de2e016effc63622e9029e76dc6e3f0c69f7aeced565c2c
+
+Curve = P-521
+Private = 0028692be2bf5c4b48939846fb3d5bce74654bb2646e15f8389e23708a1afadf561511ea0d9957d0b53453819d60fba8f65a18f7b29df021b1bb01cd163293acc3cc
+X = 01cfdc10c799f5c79cb6930a65fba351748e07567993e5e410ef4cacc4cd8a25784991eb4674e41050f930c7190ac812b9245f48a7973b658daf408822fe5b85f668
+Y = 0180d9ddfc9af77b9c4a6f02a834db15e535e0b3845b2cce30388301b51cecbe3276307ef439b5c9e6a72dc2d94d879bc395052dbb4a5787d06efb280210fb8be037
+PeerX = 008415f5bbd0eee387d6c09d0ef8acaf29c66db45d6ba101860ae45d3c60e1e0e3f7247a4626a60fdd404965c3566c79f6449e856ce0bf94619f97da8da24bd2cfb6
+PeerY = 00fdd7c59c58c361bc50a7a5d0d36f723b17c4f2ad2b03c24d42dc50f74a8c465a0afc4683f10fab84652dfe9e928c2626b5456453e1573ff60be1507467d431fbb2
+Z = 0105a346988b92ed8c7a25ce4d79d21bc86cfcc7f99c6cd19dbb4a39f48ab943b79e4f0647348da0b80bd864b85c6b8d92536d6aa544dc7537a00c858f8b66319e25
+
+Curve = P-521
+Private = 01194d1ee613f5366cbc44b504d21a0cf6715e209cd358f2dd5f3e71cc0d67d0e964168c42a084ebda746f9863a86bacffc819f1edf1b8c727ccfb3047240a57c435
+X = 016bd15c8a58d366f7f2b2f298cc87b7485e9ee70d11d12448b8377c0a82c7626f67aff7f97be7a3546bf417eeeddf75a93c130191c84108042ea2fca17fd3f80d14
+Y = 01560502d04b74fce1743aab477a9d1eac93e5226981fdb97a7478ce4ce566ff7243931284fad850b0c2bcae0ddd2d97790160c1a2e77c3ed6c95ecc44b89e2637fc
+PeerX = 01c721eea805a5cba29f34ba5758775be0cf6160e6c08723f5ab17bf96a1ff2bd9427961a4f34b07fc0b14ca4b2bf6845debd5a869f124ebfa7aa72fe565050b7f18
+PeerY = 00b6e89eb0e1dcf181236f7c548fd1a8c16b258b52c1a9bfd3fe8f22841b26763265f074c4ccf2d634ae97b701956f67a11006c52d97197d92f585f5748bc2672eeb
+Z = 004531b3d2c6cd12f21604c8610e6723dbf4daf80b5a459d6ba5814397d1c1f7a21d7c114be964e27376aaebe3a7bc3d6af7a7f8c7befb611afe487ff032921f750f
+
+Curve = P-521
+Private = 01fd90e3e416e98aa3f2b6afa7f3bf368e451ad9ca5bd54b5b14aee2ed6723dde5181f5085b68169b09fbec721372ccf6b284713f9a6356b8d560a8ff78ca3737c88
+X = 01ebea1b10d3e3b971b7efb69fc878de11c7f472e4e4d384c31b8d6288d8071517acade9b39796c7af5163bcf71aeda777533f382c6cf0a4d9bbb938c85f44b78037
+Y = 016b0e3e19c2996b2cbd1ff64730e7ca90edca1984f9b2951333535e5748baa34a99f61ff4d5f812079e0f01e87789f34efdad8098015ee74a4f846dd190d16dc6e1
+PeerX = 01c35823e440a9363ab98d9fc7a7bc0c0532dc7977a79165599bf1a9cc64c00fb387b42cca365286e8430360bfad3643bc31354eda50dc936c329ecdb60905c40fcb
+PeerY = 00d9e7f433531e44df4f6d514201cbaabb06badd6783e01111726d815531d233c5cdb722893ffbb2027259d594de77438809738120c6f783934f926c3fb69b40c409
+Z = 0100c8935969077bae0ba89ef0df8161d975ec5870ac811ae7e65ca5394efba4f0633d41bf79ea5e5b9496bbd7aae000b0594baa82ef8f244e6984ae87ae1ed124b7
+
+Curve = P-521
+Private = 009012ecfdadc85ced630afea534cdc8e9d1ab8be5f3753dcf5f2b09b40eda66fc6858549bc36e6f8df55998cfa9a0703aecf6c42799c245011064f530c09db98369
+X = 00234e32be0a907131d2d128a6477e0caceb86f02479745e0fe245cb332de631c078871160482eeef584e274df7fa412cea3e1e91f71ecba8781d9205d48386341ad
+Y = 01cf86455b09b1c005cffba8d76289a3759628c874beea462f51f30bd581e3803134307dedbb771b3334ee15be2e242cd79c3407d2f58935456c6941dd9b6d155a46
+PeerX = 00093057fb862f2ad2e82e581baeb3324e7b32946f2ba845a9beeed87d6995f54918ec6619b9931955d5a89d4d74adf1046bb362192f2ef6bd3e3d2d04dd1f87054a
+PeerY = 00aa3fb2448335f694e3cda4ae0cc71b1b2f2a206fa802d7262f19983c44674fe15327acaac1fa40424c395a6556cb8167312527fae5865ecffc14bbdc17da78cdcf
+Z = 017f36af19303841d13a389d95ec0b801c7f9a679a823146c75c17bc44256e9ad422a4f8b31f14647b2c7d317b933f7c2946c4b8abd1d56d620fab1b5ff1a3adc71f
+
+Curve = P-521
+Private = 01b5ff847f8eff20b88cfad42c06e58c3742f2f8f1fdfd64b539ba48c25926926bd5e332b45649c0b184f77255e9d58fe8afa1a6d968e2cb1d4637777120c765c128
+X = 01de3dc9263bc8c4969dc684be0eec54befd9a9f3dba194d8658a789341bf0d78d84da6735227cafaf09351951691197573c8c360a11e5285712b8bbdf5ac91b977c
+Y = 00812de58cd095ec2e5a9b247eb3ed41d8bef6aeace194a7a05b65aa5d289fbc9b1770ec84bb6be0c2c64cc37c1d54a7f5d71377a9adbe20f26f6f2b544a821ea831
+PeerX = 0083192ed0b1cb31f75817794937f66ad91cf74552cd510cedb9fd641310422af5d09f221cad249ee814d16dd7ac84ded9eacdc28340fcfc9c0c06abe30a2fc28cd8
+PeerY = 002212ed868c9ba0fb2c91e2c39ba93996a3e4ebf45f2852d0928c48930e875cc7b428d0e7f3f4d503e5d60c68cb49b13c2480cd486bed9200caddaddfe4ff8e3562
+Z = 00062f9fc29ae1a68b2ee0dcf956cbd38c88ae5f645eaa546b00ebe87a7260bf724be20d34b9d02076655c933d056b21e304c24ddb1dedf1dd76de611fc4a2340336
+
+Curve = P-521
+Private = 011a6347d4e801c91923488354cc533e7e35fddf81ff0fb7f56bb0726e0c29ee5dcdc5f394ba54cf57269048aab6e055895c8da24b8b0639a742314390cc04190ed6
+X = 00fe30267f33ba5cdefc25cbb3c9320dad9ccb1d7d376644620ca4fadee5626a3cede25ad254624def727a7048f7145f76162aa98042f9b123b2076f8e8cf59b3fdf
+Y = 001145dc6631953b6e2945e94301d6cbb098fe4b04f7ee9b09411df104dc82d7d79ec46a01ed0f2d3e7db6eb680694bdeb107c1078aec6cabd9ebee3d342fe7e54df
+PeerX = 01a89b636a93e5d2ba6c2292bf23033a84f06a3ac1220ea71e806afbe097a804cc67e9baa514cfb6c12c9194be30212bf7aae7fdf6d376c212f0554e656463ffab7e
+PeerY = 0182efcaf70fc412d336602e014da47256a0b606f2addcce8053bf817ac8656bb4e42f14c8cbf2a68f488ab35dcdf64056271dee1f606a440ba4bd4e5a11b8b8e54f
+Z = 0128ab09bfec5406799e610f772ba17e892249fa8e0e7b18a04b9197034b250b48294f1867fb9641518f92766066a07a8b917b0e76879e1011e51ccbd9f540c54d4f
+
+Curve = P-521
+Private = 0022b6d2a22d71dfaa811d2d9f9f31fbed27f2e1f3d239538ddf3e4cc8c39a330266db25b7bc0a9704f17bde7f3592bf5f1f2d4b56013aacc3d8d1bc02f00d3146cc
+X = 00ba38cfbf9fd2518a3f61d43549e7a6a6d28b2be57ffd3e0faceb636b34ed17e044a9f249dae8fc132e937e2d9349cd2ed77bb1049ceb692a2ec5b17ad61502a64c
+Y = 001ec91d3058573fa6c0564a02a1a010160c313bc7c73510dc983e5461682b5be00dbce7e2c682ad73f29ca822cdc111f68fabe33a7b384a648342c3cdb9f050bcdb
+PeerX = 017200b3f16a68cbaed2bf78ba8cddfb6cffac262bba00fbc25f9dc72a07ce59372904899f364c44cb264c097b647d4412bee3e519892d534d9129f8a28f7500fee7
+PeerY = 00baba8d672a4f4a3b63de48b96f56e18df5d68f7d70d5109833f43770d6732e06b39ad60d93e5b43db8789f1ec0aba47286a39ea584235acea757dbf13d53b58364
+Z = 0101e462e9d9159968f6440e956f11dcf2227ae4aea81667122b6af9239a291eb5d6cf5a4087f358525fcacfa46bb2db01a75af1ba519b2d31da33eda87a9d565748
+
+Curve = P-521
+Private = 005bacfff268acf6553c3c583b464ea36a1d35e2b257a5d49eb3419d5a095087c2fb4d15cf5bf5af816d0f3ff7586490ccd3ddc1a98b39ce63749c6288ce0dbdac7d
+X = 0036e488da7581472a9d8e628c58d6ad727311b7e6a3f6ae33a8544f34b09280249020be7196916fafd90e2ec54b66b5468d2361b99b56fa00d7ac37abb8c6f16653
+Y = 011edb9fb8adb6a43f4f5f5fdc1421c9fe04fc8ba46c9b66334e3af927c8befb4307104f299acec4e30f812d9345c9720d19869dbfffd4ca3e7d2713eb5fc3f42615
+PeerX = 004efd5dbd2f979e3831ce98f82355d6ca14a5757842875882990ab85ab9b7352dd6b9b2f4ea9a1e95c3880d65d1f3602f9ca653dc346fac858658d75626f4d4fb08
+PeerY = 0061cf15dbdaa7f31589c98400373da284506d70c89f074ed262a9e28140796b7236c2eef99016085e71552ff488c72b7339fefb7915c38459cb20ab85aec4e45052
+Z = 0141d6a4b719ab67eaf04a92c0a41e2dda78f4354fb90bdc35202cc7699b9b04d49616f82255debf7bbec045ae58f982a66905fcfae69d689785e38c868eb4a27e7b
+
+Curve = P-521
+Private = 008e2c93c5423876223a637cad367c8589da69a2d0fc68612f31923ae50219df2452e7cc92615b67f17b57ffd2f52b19154bb40d7715336420fde2e89fee244f59dc
+X = 00fa3b35118d6c422570f724a26f90b2833b19239174cea081c53133f64db60d6940ea1261299c04c1f4587cdb0c4c39616479c1bb0c146799a118032dcf98f899c0
+Y = 0069f040229006151fa32b51f679c8816f7c17506b403809dc77cd58a2aec430d94d13b6c916de99f355aa45fcfbc6853d686c71be496a067d24bfaea4818fc51f75
+PeerX = 0129891de0cf3cf82e8c2cf1bf90bb296fe00ab08ca45bb7892e0e227a504fdd05d2381a4448b68adff9c4153c87eacb78330d8bd52515f9f9a0b58e85f446bb4e10
+PeerY = 009edd679696d3d1d0ef327f200383253f6413683d9e4fcc87bb35f112c2f110098d15e5701d7ceee416291ff5fed85e687f727388b9afe26a4f6feed560b218e6bb
+Z = 00345e26e0abb1aac12b75f3a9cf41efe1c336396dffa4a067a4c2cfeb878c68b2b045faa4e5b4e6fa4678f5b603c351903b14bf9a6a70c439257199a640890b61d1
+
+Curve = P-521
+Private = 0004d49d39d40d8111bf16d28c5936554326b197353eebbcf47545393bc8d3aaf98f14f5be7074bfb38e6cc97b989754074daddb3045f4e4ce745669fdb3ec0d5fa8
+X = 012ec226d050ce07c79b3df4d0f0891f9f7adf462e8c98dbc1a2a14f5e53a3f5ad894433587cc429a8be9ea1d84fa33b1803690dae04da7218d30026157fc995cf52
+Y = 004837dfbf3426f57b5c793269130abb9a38f618532211931154db4eeb9aede88e57290f842ea0f2ea9a5f74c6203a3920fe4e305f6118f676b154e1d75b9cb5eb88
+PeerX = 01a3c20240e59f5b7a3e17c275d2314ba1741210ad58b71036f8c83cc1f6b0f409dfdd9113e94b67ec39c3291426c23ffcc447054670d2908ff8fe67dc2306034c5c
+PeerY = 01d2825bfd3af8b1e13205780c137fe938f84fde40188e61ea02cead81badfdb425c29f7d7fb0324debadc10bbb93de68f62c35069268283f5265865db57a79f7bf7
+Z = 006fe9de6fb8e672e7fd150fdc5e617fabb0d43906354ccfd224757c7276f7a1010091b17ed072074f8d10a5ec971eb35a5cb7076603b7bc38d432cbc059f80f9488
+
+Curve = P-521
+Private = 011a5d1cc79cd2bf73ea106f0e60a5ace220813b53e27b739864334a07c03367efda7a4619fa6eef3a9746492283b3c445610a023a9cc49bf4591140384fca5c8bb5
+X = 00eb07c7332eedb7d3036059d35f7d2288d4377d5f42337ad3964079fb120ccd4c8bd384b585621055217023acd9a94fcb3b965bfb394675e788ade41a1de73e620c
+Y = 00491a835de2e6e7deb7e090f4a11f2c460c0b1f3d5e94ee8d751014dc720784fd3b54500c86ebaef18429f09e8e876d5d1538968a030d7715dde99f0d8f06e29d59
+PeerX = 007e2d138f2832e345ae8ff65957e40e5ec7163f016bdf6d24a2243daa631d878a4a16783990c722382130f9e51f0c1bd6ff5ac96780e48b68f5dec95f42e6144bb5
+PeerY = 00b0de5c896791f52886b0f09913e26e78dd0b69798fc4df6d95e3ca708ecbcbcce1c1895f5561bbabaae372e9e67e6e1a3be60e19b470cdf673ec1fc393d3426e20
+Z = 01e4e759ecedce1013baf73e6fcc0b92451d03bdd50489b78871c333114990c9ba6a9b2fc7b1a2d9a1794c1b60d9279af6f146f0bbfb0683140403bfa4ccdb524a29
+
+Curve = P-521
+Private = 010c908caf1be74c616b625fc8c1f514446a6aec83b5937141d6afbb0a8c7666a7746fa1f7a6664a2123e8cdf6cd8bf836c56d3c0ebdcc980e43a186f938f3a78ae7
+X = 0031890f4c7abec3f723362285d77d2636f876817db3bbc88b01e773597b969ff6f013ea470c854ab4a7739004eb8cbea69b82ddf36acadd406871798ecb2ac3aa7f
+Y = 00d8b429ae3250266b9643c0c765a60dc10155bc2531cf8627296f4978b6640a9e600e19d0037d58503fa80799546a814d7478a550aa90e5ebeb052527faaeae5d08
+PeerX = 00118c36022209b1af8ebad1a12b566fc48744576e1199fe80de1cdf851cdf03e5b9091a8f7e079e83b7f827259b691d0c22ee29d6bdf73ec7bbfd746f2cd97a357d
+PeerY = 00da5ff4904548a342e2e7ba6a1f4ee5f840411a96cf63e6fe622f22c13e614e0a847c11a1ab3f1d12cc850c32e095614ca8f7e2721477b486e9ff40372977c3f65c
+Z = 0163c9191d651039a5fe985a0eea1eba018a40ab1937fcd2b61220820ee8f2302e9799f6edfc3f5174f369d672d377ea8954a8d0c8b851e81a56fda95212a6578f0e
+
+Curve = P-521
+Private = 01b37d6b7288de671360425d3e5ac1ccb21815079d8d73431e9b74a6f0e7ae004a357575b11ad66642ce8b775593eba9d98bf25c75ef0b4d3a2098bbc641f59a2b77
+X = 00189a5ee34de7e35aefeaeef9220c18071b4c29a4c3bd9d954458bd3e82a7a34da34cff5579b8101c065b1f2f527cf4581501e28ef5671873e65267733d003520af
+Y = 01eb4bc50a7b4d4599d7e3fa773ddb9eb252c9b3422872e544bdf75c7bf60f5166ddc11eb08fa7c30822dabaee373ab468eb2d922e484e2a527fff2ebb804b7d9a37
+PeerX = 01780edff1ca1c03cfbe593edc6c049bcb2860294a92c355489d9afb2e702075ade1c953895a456230a0cde905de4a3f38573dbfcccd67ad6e7e93f0b5581e926a5d
+PeerY = 00a5481962c9162962e7f0ebdec936935d0eaa813e8226d40d7f6119bfd940602380c86721e61db1830f51e139f210000bcec0d8edd39e54d73a9a129f95cd5fa979
+Z = 015d613e267a36342e0d125cdad643d80d97ed0600afb9e6b9545c9e64a98cc6da7c5aaa3a8da0bdd9dd3b97e9788218a80abafc106ef065c8f1c4e1119ef58d298b
+
+Curve = P-521
+Private = 00f2661ac762f60c5fff23be5d969ccd4ec6f98e4e72618d12bdcdb9b4102162333788c0bae59f91cdfc172c7a1681ee44d96ab2135a6e5f3415ebbcd55165b1afb0
+X = 00a8e25a6902d687b4787cdc94c364ac7cecc5c495483ed363dc0aa95ee2bd739c4c4d46b17006c728b076350d7d7e54c6822f52f47162a25109aaaba690cab696ec
+Y = 0168d2f08fe19e4dc9ee7a195b03c9f7fe6676f9f520b6270557504e72ca4394a2c6918625e15ac0c51b8f95cd560123653fb8e8ee6db961e2c4c62cc54e92e2a2a9
+PeerX = 016dacffa183e5303083a334f765de724ec5ec9402026d4797884a9828a0d321a8cfac74ab737fe20a7d6befcfc73b6a35c1c7b01d373e31abc192d48a4241a35803
+PeerY = 011e5327cac22d305e7156e559176e19bee7e4f2f59e86f1a9d0b6603b6a7df1069bde6387feb71587b8ffce5b266e1bae86de29378a34e5c74b6724c4d40a719923
+Z = 014d6082a3b5ced1ab8ca265a8106f302146c4acb8c30bb14a4c991e3c82a9731288bdb91e0e85bda313912d06384fc44f2153fb13506fa9cf43c9aab5750988c943
+
+Curve = P-521
+Private = 00f430ca1261f09681a9282e9e970a9234227b1d5e58d558c3cc6eff44d1bdf53de16ad5ee2b18b92d62fc79586116b0efc15f79340fb7eaf5ce6c44341dcf8dde27
+X = 006c1d9b5eca87de1fb871a0a32f807c725adccde9b3967453a71347d608f0c030cd09e338cdecbf4a02015bc8a6e8d3e2595fe773ffc2fc4e4a55d0b1a2cc00323b
+Y = 01141b2109e7f4981c952aa818a2b9f6f5c41feccdb7a7a45b9b4b672937771b008cae5f934dfe3fed10d383ab1f38769c92ce88d9be5414817ecb073a31ab368ccb
+PeerX = 00a091421d3703e3b341e9f1e7d58f8cf7bdbd1798d001967b801d1cec27e605c580b2387c1cb464f55ce7ac80334102ab03cfb86d88af76c9f4129c01bedd3bbfc4
+PeerY = 008c9c577a8e6fc446815e9d40baa66025f15dae285f19eb668ee60ae9c98e7ecdbf2b2a68e22928059f67db188007161d3ecf397e0883f0c4eb7eaf7827a62205cc
+Z = 0020c00747cb8d492fd497e0fec54644bf027d418ab686381f109712a99cabe328b9743d2225836f9ad66e5d7fed1de247e0da92f60d5b31f9e47672e57f710598f4
+
+Curve = P-521
+Private = 005dc33aeda03c2eb233014ee468dff753b72f73b00991043ea353828ae69d4cd0fadeda7bb278b535d7c57406ff2e6e473a5a4ff98e90f90d6dadd25100e8d85666
+X = 00c825ba307373cec8dd2498eef82e21fd9862168dbfeb83593980ca9f82875333899fe94f137daf1c4189eb502937c3a367ea7951ed8b0f3377fcdf2922021d46a5
+Y = 016b8a2540d5e65493888bc337249e67c0a68774f3e8d81e3b4574a0125165f0bd58b8af9de74b35832539f95c3cd9f1b759408560aa6851ae3ac7555347b0d3b13b
+PeerX = 004f38816681771289ce0cb83a5e29a1ab06fc91f786994b23708ff08a08a0f675b809ae99e9f9967eb1a49f196057d69e50d6dedb4dd2d9a81c02bdcc8f7f518460
+PeerY = 009efb244c8b91087de1eed766500f0e81530752d469256ef79f6b965d8a2232a0c2dbc4e8e1d09214bab38485be6e357c4200d073b52f04e4a16fc6f5247187aecb
+Z = 00c2bfafcd7fbd3e2fd1c750fdea61e70bd4787a7e68468c574ee99ebc47eedef064e8944a73bcb7913dbab5d93dca660d216c553622362794f7a2acc71022bdb16f
+
+Curve = P-521
+Private = 00df14b1f1432a7b0fb053965fd8643afee26b2451ecb6a8a53a655d5fbe16e4c64ce8647225eb11e7fdcb23627471dffc5c2523bd2ae89957cba3a57a23933e5a78
+X = 004e8583bbbb2ecd93f0714c332dff5ab3bc6396e62f3c560229664329baa5138c3bb1c36428abd4e23d17fcb7a2cfcc224b2e734c8941f6f121722d7b6b94154576
+Y = 01cf0874f204b0363f020864672fadbf87c8811eb147758b254b74b14fae742159f0f671a018212bbf25b8519e126d4cad778cfff50d288fd39ceb0cac635b175ec0
+PeerX = 01a32099b02c0bd85371f60b0dd20890e6c7af048c8179890fda308b359dbbc2b7a832bb8c6526c4af99a7ea3f0b3cb96ae1eb7684132795c478ad6f962e4a6f446d
+PeerY = 017627357b39e9d7632a1370b3e93c1afb5c851b910eb4ead0c9d387df67cde85003e0e427552f1cd09059aad0262e235cce5fba8cedc4fdc1463da76dcd4b6d1a46
+Z = 01aaf24e5d47e4080c18c55ea35581cd8da30f1a079565045d2008d51b12d0abb4411cda7a0785b15d149ed301a3697062f42da237aa7f07e0af3fd00eb1800d9c41
diff --git a/src/crypto/ecdsa/CMakeLists.txt b/src/crypto/ecdsa/CMakeLists.txt
index 0cc672e..c0ab6d6 100644
--- a/src/crypto/ecdsa/CMakeLists.txt
+++ b/src/crypto/ecdsa/CMakeLists.txt
@@ -18,5 +18,23 @@
$<TARGET_OBJECTS:test_support>
)
+add_executable(
+ ecdsa_sign_test
+
+ ecdsa_sign_test.cc
+
+ $<TARGET_OBJECTS:test_support>
+)
+
+add_executable(
+ ecdsa_verify_test
+
+ ecdsa_verify_test.cc
+
+ $<TARGET_OBJECTS:test_support>
+)
+
target_link_libraries(ecdsa_test crypto)
-add_dependencies(all_tests ecdsa_test)
+target_link_libraries(ecdsa_sign_test crypto)
+target_link_libraries(ecdsa_verify_test crypto)
+add_dependencies(all_tests ecdsa_test ecdsa_sign_test ecdsa_verify_test)
diff --git a/src/crypto/ecdsa/ecdsa_sign_test.cc b/src/crypto/ecdsa/ecdsa_sign_test.cc
new file mode 100644
index 0000000..ee95773
--- /dev/null
+++ b/src/crypto/ecdsa/ecdsa_sign_test.cc
@@ -0,0 +1,120 @@
+/* Copyright (c) 2016, 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 <stdio.h>
+
+#include <vector>
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
+#include <openssl/nid.h>
+
+#include "../test/file_test.h"
+
+
+static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
+ std::string curve_name;
+ if (!t->GetAttribute(&curve_name, key)) {
+ return nullptr;
+ }
+
+ if (curve_name == "P-224") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
+ }
+ if (curve_name == "P-256") {
+ return bssl::UniquePtr<EC_GROUP>(
+ EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ }
+ if (curve_name == "P-384") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
+ }
+ if (curve_name == "P-521") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
+ }
+
+ t->PrintLine("Unknown curve '%s'", curve_name.c_str());
+ return nullptr;
+}
+
+static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *key) {
+ std::vector<uint8_t> bytes;
+ if (!t->GetBytes(&bytes, key)) {
+ return nullptr;
+ }
+
+ return bssl::UniquePtr<BIGNUM>(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
+}
+
+static bool TestECDSASign(FileTest *t, void *arg) {
+ bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
+ bssl::UniquePtr<BIGNUM> priv_key = GetBIGNUM(t, "Private");
+ bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
+ bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
+ bssl::UniquePtr<BIGNUM> k = GetBIGNUM(t, "K");
+ bssl::UniquePtr<BIGNUM> r = GetBIGNUM(t, "R");
+ bssl::UniquePtr<BIGNUM> s = GetBIGNUM(t, "S");
+ std::vector<uint8_t> digest;
+ if (!group || !priv_key || !x || !y || !k || !r || !s ||
+ !t->GetBytes(&digest, "Digest")) {
+ return false;
+ }
+
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+ bssl::UniquePtr<EC_POINT> pub_key(EC_POINT_new(group.get()));
+ if (!key || !pub_key ||
+ !EC_KEY_set_group(key.get(), group.get()) ||
+ !EC_KEY_set_private_key(key.get(), priv_key.get()) ||
+ !EC_POINT_set_affine_coordinates_GFp(group.get(), pub_key.get(), x.get(),
+ y.get(), nullptr) ||
+ !EC_KEY_set_public_key(key.get(), pub_key.get()) ||
+ !EC_KEY_check_key(key.get())) {
+ return false;
+ }
+
+ // |ECDSA_do_sign_ex| expects |k| to already be inverted.
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+ if (!ctx ||
+ !BN_mod_inverse(k.get(), k.get(), EC_GROUP_get0_order(group.get()),
+ ctx.get())) {
+ return false;
+ }
+
+ bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_do_sign_ex(digest.data(), digest.size(), k.get(),
+ r.get(), key.get()));
+ if (!sig) {
+ return false;
+ }
+
+ if (BN_cmp(r.get(), sig->r) != 0 ||
+ BN_cmp(s.get(), sig->s) != 0) {
+ t->PrintLine("Signature mismatch.");
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char *argv[]) {
+ CRYPTO_library_init();
+
+ if (argc != 2) {
+ fprintf(stderr, "%s <test file.txt>\n", argv[0]);
+ return 1;
+ }
+
+ return FileTestMain(TestECDSASign, nullptr, argv[1]);
+}
diff --git a/src/crypto/ecdsa/ecdsa_sign_tests.txt b/src/crypto/ecdsa/ecdsa_sign_tests.txt
new file mode 100644
index 0000000..513c582
--- /dev/null
+++ b/src/crypto/ecdsa/ecdsa_sign_tests.txt
@@ -0,0 +1,2166 @@
+# Tests from NIST CAVP 186-4 ECDSA2VS Test Vectors, Signature Generation Test
+# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
+#
+# NIST's files provide message and digest pairs. Since this is a low-level test,
+# the digests have been extracted. P-521 test vectors were fixed to have the
+# right number of leading zeros.
+
+Curve = P-224
+Private = 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615
+X = 605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab
+Y = f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669
+Digest = 07eb2a50bf70eee87467600614a490e7600437d077ec651a27e65e67
+K = d9a5a7328117f48b4b8dd8c17dae722e756b3ff64bd29a527137eec0
+R = 2fc2cff8cdd4866b1d74e45b07d333af46b7af0888049d0fdbc7b0d6
+S = 8d9cc4c8ea93e0fd9d6431b9a1fd99b88f281793396321b11dac41eb
+
+Curve = P-224
+Private = cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5
+X = fa21f85b99d3dc18c6d53351fbcb1e2d029c00fa7d1663a3dd94695e
+Y = e9e79578f8988b168edff1a8b34a5ed9598cc20acd1f0aed36715d88
+Digest = bde0fbb390fb05d0b75df5bd0d0a4ea29516125f19830e3b0c93b641
+K = c780d047454824af98677cf310117e5f9e99627d02414f136aed8e83
+R = 45145f06b566ec9fd0fee1b6c6551a4535c7a3bbfc0fede45f4f5038
+S = 7302dff12545b069cf27df49b26e4781270585463656f2834917c3ca
+
+Curve = P-224
+Private = dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73
+X = fc21a99b060afb0d9dbf3250ea3c4da10be94ce627a65874d8e4a630
+Y = e8373ab7190890326aac4aacca3eba89e15d1086a05434dd033fd3f3
+Digest = c2c03fe07e10538f6a38d5831b5dda9ce7478b3ed31323d60617dc95
+K = 6629366a156840477df4875cfba4f8faa809e394893e1f5525326d07
+R = 41f8e2b1ae5add7c24da8725a067585a3ad6d5a9ed9580beb226f23a
+S = a5d71bff02dce997305dd337128046f36714398f4ef6647599712fae
+
+Curve = P-224
+Private = aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e
+X = fad0a34991bbf89982ad9cf89337b4bd2565f84d5bdd004289fc1cc3
+Y = 5d8b6764f28c8163a12855a5c266efeb9388df4994b85a8b4f1bd3bc
+Digest = 5d52747226f37a5afcd94d1b95867c0111bcb34402dad12bee76c1b7
+K = 1d35d027cd5a569e25c5768c48ed0c2b127c0f99cb4e52ea094fe689
+R = 2258184ef9f0fa698735379972ce9adf034af76017668bfcdab978de
+S = 866fb8e505dea6c909c2c9143ec869d1bac2282cf12366130ff2146c
+
+Curve = P-224
+Private = 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4
+X = 0e0fc15e775a75d45f872e5021b554cc0579da19125e1a49299c7630
+Y = cb64fe462d025ae2a1394746bdbf8251f7ca5a1d6bb13e0edf6b7b09
+Digest = a1ab56bd011b7e6c7e066f25333d08cf81ac0d9c1abfa09f004ab52f
+K = 39547c10bb947d69f6c3af701f2528e011a1e80a6d04cc5a37466c02
+R = 86622c376d326cdf679bcabf8eb034bf49f0c188f3fc3afd0006325d
+S = 26613d3b33c70e635d7a998f254a5b15d2a3642bf321e8cff08f1e84
+
+Curve = P-224
+Private = 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131
+X = 2c070e68e8478341938f3d5026a1fe01e778cdffbebbdd7a4cd29209
+Y = cde21c9c7c6590ba300715a7adac278385a5175b6b4ea749c4b6a681
+Digest = 8ef4d8a368fad480bac518d625e97206adcafa87c52aef3d179cbfa9
+K = 509712f9c0f3370f6a09154159975945f0107dd1cee7327c68eaa90b
+R = 57afda5139b180de96373c3d649700682e37efd56ae182335f081013
+S = eb6cd58650cfb26dfdf21de32fa17464a6efc46830eedc16977342e6
+
+Curve = P-224
+Private = d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974
+X = 3a0d4b8e5fad1ea1abb8d3fb742cd45cd0b76d136e5bbb33206ad120
+Y = c90ac83276b2fa3757b0f226cd7360a313bc96fd8329c76a7306cc7d
+Digest = 28fabbac167f3d6a20c2f5a4bcee527c96be04bdd2c596f09d8fbab7
+K = 1f1739af68a3cee7c5f09e9e09d6485d9cd64cc4085bc2bc89795aaf
+R = 09bbdd003532d025d7c3204c00747cd52ecdfbc7ce3dde8ffbea23e1
+S = 1e745e80948779a5cc8dc5cb193beebb550ec9c2647f4948bf58ba7d
+
+Curve = P-224
+Private = 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8
+X = 4772c27cca3348b1801ae87b01cb564c8cf9b81c23cc74468a907927
+Y = de9d253935b09617a1655c42d385bf48504e06fa386f5fa533a21dcb
+Digest = 50dd74b5af40978e809cee3eb41195402ebb5056e4437f753f9a9d0d
+K = 14dbdffa326ba2f3d64f79ff966d9ee6c1aba0d51e9a8e59f5686dc1
+R = ff6d52a09ca4c3b82da0440864d6717e1be0b50b6dcf5e1d74c0ff56
+S = 09490be77bc834c1efaa23410dcbf800e6fae40d62a737214c5a4418
+
+Curve = P-224
+Private = 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2
+X = 1f249911b125348e6e0a473479105cc4b8cfb4fa32d897810fc69ffe
+Y = a17db03b9877d1b6328329061ea67aec5a38a884362e9e5b7d7642dc
+Digest = 9fee01807ab6c43a794abf6dcd6118915252ca7d3a31a1ff96b88a8d
+K = ab3a41fedc77d1f96f3103cc7dce215bf45054a755cf101735fef503
+R = 70ccc0824542e296d17a79320d422f1edcf9253840dafe4427033f40
+S = e3823699c355b61ab1894be3371765fae2b720405a7ce5e790ca8c00
+
+Curve = P-224
+Private = 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7
+X = 7df67b960ee7a2cb62b22932457360ab1e046c1ec84b91ae65642003
+Y = c764ca9fc1b0cc2233fa57bdcfedaab0131fb7b5f557d6ca57f4afe0
+Digest = c349032f84384b913bd5d19b9211ddce221d66a45e8a051878254117
+K = 9ef6ebd178a76402968bc8ec8b257174a04fb5e2d65c1ab34ab039b9
+R = eef9e8428105704133e0f19636c89e570485e577786df2b09f99602a
+S = 8c01f0162891e4b9536243cb86a6e5c177323cca09777366caf2693c
+
+Curve = P-224
+Private = 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b
+X = b10150fd797eb870d377f1dbfa197f7d0f0ad29965af573ec13cc42a
+Y = 17b63ccefbe27fb2a1139e5757b1082aeaa564f478c23a8f631eed5c
+Digest = 63fe0d82cf5edf972e97316666a0914432e420f80b4f78ceb92afd1d
+K = 385803b262ee2ee875838b3a645a745d2e199ae112ef73a25d68d15f
+R = 1d293b697f297af77872582eb7f543dc250ec79ad453300d264a3b70
+S = 517a91b89c4859fcc10834242e710c5f0fed90ac938aa5ccdb7c66de
+
+Curve = P-224
+Private = c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6
+X = 3c9b4ef1748a1925578658d3af51995b989ad760790157b25fe09826
+Y = 55648f4ff4edfb899e9a13bd8d20f5c24b35dc6a6a4e42ed5983b4a0
+Digest = 9b44ee16e576c50c0b6b37ac1437bf8f013a745615012451e54a12f2
+K = b04d78d8ac40fefadb99f389a06d93f6b5b72198c1be02dbff6195f0
+R = 4bdd3c84647bad93dcaffd1b54eb87fc61a5704b19d7e6d756d11ad0
+S = fdd81e5dca54158514f44ba2330271eff4c618330328451e2d93b9fb
+
+Curve = P-224
+Private = 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc
+X = f0acdfbc75a748a4a0ac55281754b5c4a364b7d61c5390b334daae10
+Y = 86587a6768f235bf523fbfc6e062c7401ac2b0242cfe4e5fb34f4057
+Digest = 3c89c15dee194b3223e7b53a8a5845d4873a12a2f1581d5413359828
+K = 854b20c61bcdf7a89959dbf0985880bb14b628f01c65ef4f6446f1c1
+R = a2601fbb9fe89f39814735febb349143baa934170ffb91c6448a7823
+S = bf90f9305616020a0e34ef30803fc15fa97dffc0948452bbf6cb5f66
+
+Curve = P-224
+Private = 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3
+X = 5fad3c047074b5de1960247d0cc216b4e3fb7f3b9cd960575c8479fc
+Y = e4fc9c7f05ff0b040eb171fdd2a1dfe2572c564c2003a08c3179a422
+Digest = 2b7faf36fdf0e393ddeb9fc875dd99f670e3d538fd0462395ea06c8f
+K = 9267763383f8db55eed5b1ca8f4937dc2e0ca6175066dc3d4a4586af
+R = 422e2e9fe535eb62f11f5f8ce87cf2e9ec65e61c06737cf6a0019ae6
+S = 116cfcf0965b7bc63aecade71d189d7e98a0434b124f2afbe3ccf0a9
+
+Curve = P-224
+Private = 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912
+X = 6dd84f4d66f362844e41a7913c40b4aad5fa9ba56bb44c2d2ed9efac
+Y = 15f65ebcdf2fd9f8035385a330bdabec0f1cd9cc7bc31d2fadbe7cda
+Digest = 5b24b6157c0d1edf3a40c22a0745d23bdb59379e5e5e776ed040288d
+K = 7bb48839d7717bab1fdde89bf4f7b4509d1c2c12510925e13655dead
+R = 127051d85326049115f307af2bc426f6c2d08f4774a0b496fb6982b1
+S = 6857e84418c1d1179333b4e5307e92abade0b74f7521ad78044bf597
+
+Curve = P-224
+Private = 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa
+X = 4c741e4d20103670b7161ae72271082155838418084335338ac38fa4
+Y = db7919151ac28587b72bad7ab180ec8e95ab9e2c8d81d9b9d7e2e383
+Digest = 00c6fc53c1986d19a8a8b580ee553dc1240745d760647d1c0adf442c133c7f56
+K = 06f7a56007825433c4c61153df1a135eee2f38ec687b492ed40d9c90
+R = 0909c9b9cae8d2790e29db6afdb45c04f5b072c4c20410c7dc9b6772
+S = 298f4fcae1fe271da1e0345d11d07a1fca43f58af4c113b909eedea0
+
+Curve = P-224
+Private = 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972
+X = 897089f4ef05b943eeac06589f0e09ccc571a6add3eb1610a2fc830f
+Y = 62ba3f6b3e6f0f062058b93e6f25b6041246c5be13584a41cae7e244
+Digest = fb5dd3b8d280fe7c4838f01b2a5c28493ed3084f46b40642600ba39e43fbff7b
+K = 5b6f7eca2bcc5899fce41b8169d48cd57cf0c4a1b66a30a150072676
+R = f12c9985d454ffbc899ebbbb6cf43e3debcac7f19029f8f2f35cce31
+S = 12fcb848adbd8b1b4c72b2b54a04d936e4a5f480ae2a3ea2e3c1baae
+
+Curve = P-224
+Private = f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170
+X = 40a4ab1e6a9f84b4dedb81795e6a7124d1cfdfd7ec64c5d4b9e32666
+Y = 83aa32a3c2fc068e62626f2dafce5d7f050e826e5c145cd2d13d1b27
+Digest = f4083aebe08c9bdb8c08ff844ffc207f80fa4406fb73bdbc1c6020f71281bdae
+K = c31150420dfb38ba8347e29add189ec3e38c14b0c541497fb90bf395
+R = bf6c6daa89b21211ea2c9f45192d91603378d46b1a5057962dafaf12
+S = cb6b237950e0f0369323055cd1f643528c7a64616f75b11c4ddd63c7
+
+Curve = P-224
+Private = c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85
+X = 66f49457ed15f67ed4042195856f052fe774077f61cebcb9efddc365
+Y = 3a6e3f3423eec7308a69eb1b0416d67cc3b84d24f251d7cbdb45c079
+Digest = cb017b280093879c4b114b52ea670f14e97b661074abccc8539a23280fe136b4
+K = 5e5405ae9ab6164bb476c1bb021ec78480e0488736e4f8222920fbd9
+R = 7b7beaf9f696ca1a8051527478c4c075ab45aa4768937886dbf38618
+S = 93d4cf110a37c5a6f15c4e6024822118539e860dee2f60b8c3f462f6
+
+Curve = P-224
+Private = 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6
+X = 8d642868e4d0f55ee62a2052e6b806b566d2ac79dbde7939fe725773
+Y = 79505a57cd56904d2523b3e1281e9021167657d38aeb7d42fc8ec849
+Digest = 5f1d77f456d7ed30acad33795b50733d54226e57df4281a43d3821d0762f12fe
+K = ec60ea6f3d6b74d102e5574182566b7e79a69699a307fee70a2d0d22
+R = 2fd7fcbb7832c97ce325301dd338b279a9e28b8933284d49c6eabcf6
+S = 550b2f1efc312805a6ed8f252e692d8ee19eaa5bcd5d0cda63a1a3f0
+
+Curve = P-224
+Private = 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39
+X = 7924b1d7f5920cce98e25094e40f2eb3eb80d70b17e14b3d36c3671c
+Y = 26c5af35f71e61858582b7cc2b41790597c53ee514ffdf7a289d108c
+Digest = cce0671ca07521fdaa81eced1dc37282bd9a6dbbaeb8cd00d13d4cf75cef044c
+K = 751869c1d0e79eb30aae8fbfb6d97bfa332123fd6b6c72c9cd3c1796
+R = 26bb1b92b0f01e94eba5fa429271371db527ce857abba13bd1103f64
+S = 836aba9c63e1252c2b2d72a21e6a41b82241ebe32647e7f814652bcb
+
+Curve = P-224
+Private = 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6
+X = 18cb5826ad60e6696bf07655032a3749f6577ca36da3ccd6e66a137c
+Y = 194e14820fe02d784fd1363ff7a30399518309765bd3f4412d646da2
+Digest = 4ee903b828f54f35adab0bfec06eb064abde530d8ed0384730aa23e8e9664801
+K = e2a860416229dfd3f5a5cc92344ca015093a543943a0d8f73bf2b2fd
+R = 00e300c1ef4a8c4ca5da6413856f8981db49de29bdf03f32ffc3ceab
+S = f250f18a51ba5f63e1584097841099fa6ae4e98ee458c061d1d5aed7
+
+Curve = P-224
+Private = 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b
+X = 076518e393940d42dfd09819409d66966d8c9189c83d554a9cc8a082
+Y = 44d0ceaf4c0f50e46bea4a52e30423ce3ada19edd363ac5694c65cb8
+Digest = 215e9817eccaa125e0c053fed373f4605de292d27a692bd4f744e63215fd8705
+K = 6be6dd9f6a083915ccba54626caf12d246d3aece0a7eda7d8d85599c
+R = ff1460946e06fb6f5d35e8d2625ca70ffb9b45308e3fabf6ad8351b1
+S = 6029aa3990918e8cb8a388d53b0772e5cdfff49c3405fe0d3a95933a
+
+Curve = P-224
+Private = 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b
+X = 279649e2a2918e683520cde3fc98b0ae58a7100e8de35e7c9cc797b6
+Y = aa4de6be34be61f02880139787b9038f4554a8ef1c994b887c2974b5
+Digest = 6571a344765c0512d3911a7724509b649a6ce4106823be76726f117f109ec0fa
+K = 8e984864f86f7a2a73f3edda17dbccd13fac8fa4b872814abf223b1b
+R = 3b18736fa11d04e27e2614cda03a63ec11a180f357b0b3192920d09c
+S = 2f0f3dbd570727b14fbb29155538e62c930dd51c4035275c1365dc60
+
+Curve = P-224
+Private = 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8
+X = 3fa617c50b177da1a2bdb98b780ad21ad1195c4bd24465f6187de3c9
+Y = e3fd8d8876dfd03a4a4e31a1acad3a08d983826d286c250c4e5620c1
+Digest = 95914b17ff0362e12305d71657bbc9d919ae4aa746bf4ebe95b2d2fe7ca3f022
+K = 0128b8e3f50731eb5fcc223517fc0cf6b96cd1d2807eb4524bc46f77
+R = 3a6b633f96f3d0b6d54f7fb29ac33709e4f0dd8fa0e51606ed9765ca
+S = 63e8c119dfa51784decd864f6911f2210a80f8f02d472d88df10d119
+
+Curve = P-224
+Private = e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784
+X = b7ae1e992b1c7fde1141f40bd913358538ca0f07f62b729f13cea327
+Y = 811252d12120e04805fc171a439d382c43b68a21e1a0bdf5e4ec1da4
+Digest = 2dd97b10b2ac90709062989f57873e30696bf8376957e68f7de95aa333a67685
+K = 7abedab1d36f4f0959a03d968b27dd5708223b66e0fc48594d827361
+R = d35047d74e1e7305bb8c1a94e8ae47cb1591c3437a3e185e00afe710
+S = d9c425c9d5feb776ac8952e6c4eee0ecd68aef2f0e7bff2e49c9185e
+
+Curve = P-224
+Private = 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c
+X = cd95cf8fb1cd21690f40d647f2353672a1076cc6c46bddaad2d0fc56
+Y = 934262f74d9ee0f8a2754f64cb7415923d64bf00c94a39b52803f577
+Digest = 7c74a2e71f7bb3101787517394a67d03f977c95519526b47854e417b95bf8d1b
+K = 557d0e3995dc6377b3911546dd7aeaeec62a6d8f2af6a274382fc37f
+R = 56df0ea6afdcc232ceb41729eec00cf906b69b6e28423a36d3c92cc5
+S = f4f70fd948c9a147f55317fdea7b8a84c33e721014552d5800d63edc
+
+Curve = P-224
+Private = 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583
+X = b88652020e083ccc1c43dc83d1881884dd4c7e3b4e3460b344b1ea64
+Y = 22b69b517f86d7c26dc37c0f8feb4bb07fe876149fbcc3334fd2805b
+Digest = ccc04666744685c57d2256f21cee0f53857a0528a96d59bb13cdeb92fd786d4f
+K = e4f4a3280574c704c2fde47ca81ec883d27f2c5a961a294db7cda9d2
+R = b30b8a0079d9a134b5e1618c2ac63e3fbe0e95866b9dbc5f423f2707
+S = 3dc36746610271ef66e0aa52cc2ccadc5c9b08dc769e4dc4f6538c11
+
+Curve = P-224
+Private = 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2
+X = ce1a06f82df874dded37cca03b56c0648e4e8917ecd40ee73ee61588
+Y = ceb6177b8f1ac7c5c6e6e1f7737cc3026952ee392badd2cd7af32f9d
+Digest = 9e7d5f30677692b669e21cf5461fa7f2e887dfcbbeb2db88d666bd591a944e00
+K = e401fa80f96480d437ed4f61a783888062ec33d530b188fd48016a6d
+R = 28674f447c4742e4087bbccfb522fbad4e18b56031d2ce8f532b078a
+S = a5a7a13d15b423dd17771f73cea98d89dbffa846cc209b45c0e29b76
+
+Curve = P-224
+Private = f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc
+X = 0dc2cdddb990341adb1de73f02d87fc3822485a659a15145f4251d5f
+Y = cf78b2a83c7352eda1af2c74e1804ea04b35f76c04e89d90281dc2bb
+Digest = d8978f697bef71b062d4b3211e8ab5b993c09920af803614dbb9437f6e261b70
+K = 5d1476c682a64162fd2fdc82696fc8cab1469a86f707ea2757416e40
+R = 82982b38ed465138df4018d7cfb835edcb591cb57446ca49d163782b
+S = 8ef1d7b326cabee7f7ab95b7b98d3c27a069c0fd95a1599c0ccb422b
+
+Curve = P-224
+Private = 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd
+X = bd6ba605639b98fa8113a16a3bb004ddfaec901c98a931206165f4a5
+Y = a3190b10ef39e88abd60b2293b4707512b45c6c5ed5794cc11454427
+Digest = 1a9fc0195bf0f53cebba8aa7ccc8567c680d75187392d6d8201854ec4a6e6abd349037d831809e9f3add2fc09d27e4a4
+K = 0f0bb1e428bcdebf4dc62a5278068efc0f8ce75f89e89b3630f102b2
+R = aac0ea27e129f544abcc77f110e70bbdd5aa3e425dc39d5e8887025d
+S = 10e5dd06aee6b8419a04aa33d9d5678b0039c3acc3c4b61fe106bfdc
+
+Curve = P-224
+Private = e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3
+X = f5d5346f17898ea6bbdfff19c216a8757a5dc37b95315f5481628381
+Y = ae61fd172ac8b7a4f13870a932dece465834cbd4f50bbcfb802c824e
+Digest = 0f236d9a43edd55dacf5ff9f93ee805395e130ca2c8ad2eaea0fdd68e2ee2fadae9f41aa46f881485db208bd9cdc463b
+K = 35724ac043e3b44b73b5a7919cf675190306d26aa67c27c28c873534
+R = 535147c265af138eec50c7fb570bcc8d2e6f675597b0fcc034e536bc
+S = 743812c188a1dddf9fb34b90738f8b2e58760d6cd20ccceb1bb9c516
+
+Curve = P-224
+Private = b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17
+X = dc5d217862a1e5b00c95affa9d8b925a72b9beaeb7a86dc397e788d8
+Y = 5f05f8e976ae1eb1036eca6d683a82850795bf9127dee5f8b2859445
+Digest = 525b6241eb2a6dd00b55b172708aafd0775e959b7c601903f44ffcfc17ee979f34f204680f8a71044a6d7e3679a50576
+K = 408e9c8b1f33136d6ddb93ff3a498bc09d4eee99bf69cdd5af0aa5a2
+R = 1b5a964c8b1fc634c6e2b82322499df1d7f0c12a4d2a77723c816ab8
+S = cf54599a36ca064fae0aa936de5266f87704409d22a15d28c01b7f2a
+
+Curve = P-224
+Private = efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085
+X = 61521a0cfb72be77ba33cb3b8e022743cd9130ff49e97093b71aa178
+Y = ce0819aedaf6fce639d0e593f8ab0147eeb6058f5f2b448231584ea9
+Digest = 88c4b7ca396f17e82c92596c301e41d7f01810bfeb33173cc0d1fedf3fd5ace6892ba9a788de13417f0ef00ff87344fb
+K = d1eea821f286eae6ebc1f61b08f9ad4323a3787e94af4c32cd31351b
+R = b37caaa71103752ac559f9eb4943324409ebfa8b585f684dcaa5c411
+S = 7c28e7619e2944ab4b7be022878c8052ebdf2cae5dff4f976c49686a
+
+Curve = P-224
+Private = 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd
+X = a7e975c0a8f87c683bb8e31bc160843a7b69c945f4850bd60e1c08c0
+Y = 8930a454dcc2aa13bed7ea89368b2c9d689d816b2acf4e52585ee9c4
+Digest = 3babfaba30f3300171e6adcf4f62a12287031ac40078c96b2c2c063849e9a42ef3be953dc11fb319c18bf22fe511bf37
+K = 44b1fdec2629f9075f89c134ac28ff19bfddaa9db02a5d7f853582b4
+R = b0f5635d8bc9c53a1d54a3ec63de59ed66e6b2358d4ab79755414326
+S = 67c68fe265c7e5aba4232deeafb88545a2aa266fb9f2c2bb3f3ae8d2
+
+Curve = P-224
+Private = 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d
+X = 3191f0237102dac159032ab2dde53cf56c9ec827b5caddfe9e83c02a
+Y = b496b1bdcca4434ac0d0d91ea38ff3bc33f9f54095bfe17796d5a9e2
+Digest = 9f36da1a5653469a52f85e7e3b2a21ac3497cc00ff37e03235bbdf951695f182312ad5c8fb8a5fbd0295dc8c5acda068
+K = da529c52f5cc1f435d873109cd991d6cd7e1631d9ff1dd9521dd5db6
+R = 8e0ac63903f4921755430572c3f08bc272790639bdf1009fe2a9a714
+S = 6278c841a2d0a270791fe54b36c49d426d67907aa4e4f59c8638ad97
+
+Curve = P-224
+Private = 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0
+X = 9fdd99906ab77fd29e9021bde947d05a7a9eb153612269bfb0899bc9
+Y = 681b65b9ac8e4c2899bb622dafb253b7bf5a6e38e5f6595f997c291a
+Digest = 12532cbcfd4e80373bc235ac0bfa2a70b1044786d29f9384d555030f5df3cb5ab9f973df638b6835cb756792d1fe1a4e
+K = 66ed8d8934633f4125f593cf1b1d3745c4db1f15dde60cf46ca1c7f2
+R = 80199485a3a96447b39f7679cd47412a78675ba17dcbd10465dc5b48
+S = a251fd9f136a3cb0dd0bc80659ae032e4a761ba7045da0034553fb8c
+
+Curve = P-224
+Private = e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d
+X = 46c9ed837232c47022df2f1a1578fbe65ac9f2e81c98a74cc22ea31a
+Y = 6fc5e9568ae62b31412a0b0b367242e9fd7e518c83aa06a069e1d90d
+Digest = 89030408e06cc06d3dbfb51f6725c710a2bc9db9e07ff1ec8a32a827d93d2dc951834cdb01a7afa1fe4cf4e9186ee424
+K = a4c1eb402a2fb3af26e0e14a3d2fc8ed3bc1a8b2475270356a79fdd3
+R = d478b68733d8ad44be46766e7b66af782fbdc7ff7ed0b191176da98a
+S = 5eae9160ccf71fd1d359d89cecce72ef8afaeee2365f6ba828aa450a
+
+Curve = P-224
+Private = f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7
+X = 9ca2c6ea87ac8dd3a23a5b4010841a7c8af309038882ae44634bcf55
+Y = b0a347dbd5ded3b8702ac5a457e8b32bd4de06fd315095fa1b7d5fe1
+Digest = eda24262a9e64be110a6c96763e8a4b5edb38af2a084695e294593583b462c56b0db50bc014eb19278e3f3d675eb5f22
+K = e3cc786c1288ea567836c51d6d69dd0cab5c015987d936ccc3a4beb3
+R = f1234da71761b7a0f49e661a419d2a739bdc4544bf87690e3d2f96db
+S = 096d16bf8020c3d3c233894ad8eb81206010e62c6e692a215e088fd4
+
+Curve = P-224
+Private = 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c
+X = 101271a9addd4bd1f19d00bf116c8524f52cefd598e85dc381597acb
+Y = 2f17d14f4d8ccb28b216553718152ba7c104646d8eca986dd9ddea39
+Digest = 983a5d16b009cc65bdf3c3badc2f21280e04f44244b70a583c2e9732534497373f51b226c3ab7bd69c6940e46bc41fa1
+K = d169f04f05b60c625cda864d187938863964dab7bb3b9dfc04b05519
+R = e4a51be686a764b709da23ab48b1985e153c6ee238d945e743907afc
+S = 118a8f1ffe3cd556ce6345bd1a398dd9cc3729b7fd6d8af9bfd82f40
+
+Curve = P-224
+Private = 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18
+X = 9edd544107977134bf6360d43ccabb3c94d627c03963c0a04b439627
+Y = ece4c61d319a0e41f3de7863e7c355bac94395aaa74cdb5f74a87a5b
+Digest = ae7b5fde427af9c450368b11f66f49bf8c3b6e1f5abed6bb25683001924dfb005738637e1c1b7855566330d202ecc763
+K = 36f7c0f76808b826a0a974a1fd6e155e00a73f1d34674a8f88be405a
+R = 3e319444438bc2cc92f323ea842cb402b3c3c2448c89869ef7998edb
+S = 3420cc38f058f41c31e71f4b1ad488f801111c73541de69fcee60695
+
+Curve = P-224
+Private = bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a
+X = 8848f964c847fe9dddc774618d4588c9cd56bbe588d7b1fb369c8bfa
+Y = ebbb699fbd0dc08859fe9132285fe20dff3b9d561c0640b6e0717607
+Digest = 63ef787f467ff0cd6e5012b09414c00ef56dba959c4b62bf7e76a4205078d436c45591752c8d55abe728a2d28b5b0643
+K = 59f1450d857b40e5552a4b8cd4ab0df2f01716635d172c1106840f21
+R = a206d8398a16a991bc217f77f23c6f648384f254f255a8a876404444
+S = eb1169cb5b1423dc0bfaffe565ae57f986e00de06405e3e7b605862e
+
+Curve = P-224
+Private = dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738
+X = 063a5d632f4144376e14cfb03ad8ccf1489b613acd184d20dff66545
+Y = e77727f057b043d8a0f7458196b72e92d11f85b0891c6aaa9d915f58
+Digest = 11f0d587e82e7490af4737c272877d9d37c1e7ae7f2fd3b00d8fa0d4f2bcb3a41d5185e65604b8c411a407eb6c558954
+K = ff0e5cae2671db7a1b90e22c63e7570bdd27352d45bac31e338debe0
+R = 5bc0b4998481ecbd3b6609184a84ca41d69b08c37138097f559259f8
+S = 0df8828eb1ca85e46405b94e1a2972c34c5e620a54e2f640f04aecc5
+
+Curve = P-224
+Private = 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01
+X = de616848d8044a44789ef1ba3a6dd66fe9257ddc57f7534e59a701be
+Y = 26cbf74a6d25e5b34b96d30f327abd574cff7f7dbe6686573a7d6c5c
+Digest = 537d6d3d4be3e3beaf31014dae59ca7186c1c1a32c88068ff343180a138ceb6d7c38e0ae1e9b51003b71c1a2f3a3741b
+K = 3b18ca6ec8e8e255ac88f64302745ca0b73ff94b2b2d48be95b4aaee
+R = fa94fd8b827c06115c1eefd50afc02ce5926ee0e789667783c01c34b
+S = edf766a66973cfc33e4159966c07321a7f6549c3c60e8586ef41402b
+
+Curve = P-224
+Private = 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28
+X = 3858a576eef2ce24d01766997fb81b3f3f78b6104cd188610be221d7
+Y = 95ffc677ac7bfe3e0bb4cffb17355a964c8356a807151b3cba5d1f4e
+Digest = 7e16034a71ebf52a7a6cd00fe469c6edc121b2882462176298c9443aca2a0ad6ebe2eb9e145097409873170f40d503dd
+K = c1a2ec1ef16cfd5107c892790daefbed061be78bd8576696b60f64d5
+R = 18c908541843fcdac99b9ff6bb397f3f8094d16b42670216e4eaa2d7
+S = c107a8a508ff57c5d4f78f86cc37e129c864d1c44ed5e73909613b74
+
+Curve = P-224
+Private = ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6
+X = ac635fe00e8b7a3c8ef5655bdfb7f83e8532e59c0cc0b6534d810ffa
+Y = 1d067aebeba66e79b28ecfe59ac6fdf5e1970dc3a84499c9d90cd8e2
+Digest = 3edbb59a32b2464291d0a96023a798c1fc6cb5ff4fcecfadcfac2be00c26fa27181aef76c96d8269aeaf2275eeacbb777abbd9571de9279edc5695a3345cad9b
+K = 187ed1f45c466cbafcd4b9577fb222408c011225dcccfd20f08b8d89
+R = f83d54945997584c923c09662c34cf9ad1e987da8bfd9be600e7a098
+S = 4ff2dba9dba992c98a095b1144a539310e1a570e20c88b7d0aa1955c
+
+Curve = P-224
+Private = 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc
+X = ecaea8ceea55c3bd418fd34a4ff2499e25e66a104eed846bc00c31d2
+Y = 3933a356ab1f2dabc303ff0a5d076131e77032e6f502336883bf78a7
+Digest = 825ab979af5c263d9f074a2d771d1d1cdfa435e7938245a3c9ee30cb77ee8c1475051d2f09d7d11d920a6c754bfd253903131c491994679cafdb8cfbf32b763d
+K = 34cb597deae9a3b1cada937abcd247161b19b2b336b20e2e42ae01f1
+R = 58177ba46fb291490b39368774accf72736412c1fb5ee0f27b9b1e02
+S = 58337d78b95a080bfcabb5809bee012501b4da84b8ef310a4628f11c
+
+Curve = P-224
+Private = 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b
+X = d656b73b131aa4c6336a57849ce0d3682b6ab2113d013711e8c29762
+Y = 6328335ffc2029afbfe2a15cc5636978778c3f9dab84840b05f2e705
+Digest = d0db7c20c201cd8c63ca777293543750d7f6a9e375b056e74cfe9fb2c95b2cc9807d8a9607a5b0fad6eeda86e4f73ace139e77a5356181b8cbef3f88173253b6
+K = dc82840d147f893497a82f023d7d2cbf0a3a5b2ac6cc1b9b23e504be
+R = 583af080e0ec7c1ba5a491a84889b7b7b11ccfe18927c7c219b11757
+S = b23700035349df25d839f0973bef78a7515287de6c83707907074fa6
+
+Curve = P-224
+Private = afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc
+X = fe83e59fc8ea8b939355d3258fe53a64d45f63031a0716b7cc416173
+Y = f151d23060f1c856eb7f1f58be72a7228c3af89e43b56e9695b558c7
+Digest = 37d9091eddc6fc34b45cf97140e956a42ab659f6bd442e81b57c4ecfbdab45f7380a7efdbac5400ceb1bf683194232cd086c1b4e09fc9313f1bc38af731f1a98
+K = 0fbbe7b40136c81a8fb894498d5502157a1cf5a89d0643de92cd38f6
+R = 24f3f457c7b72b7e759d5a8afbf330e31c5d8d2e36f92c0e79c5d87d
+S = 36fd1193def34f12a960740fd79fb38bf2b480726ccad540eb42cdf8
+
+Curve = P-224
+Private = 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c
+X = f43d13bbfcee3b724063b3910fea49fd591b81e86fdb813b1a492d0c
+Y = 6b4c8d6fa5dc661889e3cf5ec64997a78222837885f85d2fe9b684fb
+Digest = 8ddf64c9c67289a76c2f5b44a30b8365f4adf487b4edadada5749cad9e5765c57a348a750817a53e5c2ff551e003747ca1e3438b2aa1952c6876fda8fd8f4de2
+K = 83e110d0d1e700d2f36543028737d2a2f1474aa3b4b28998a39e4793
+R = 2685265bc878e85d10ab13293dec190881a57c4a467f8fc2170432ea
+S = 80a347bb49036522369339bd6485a967cdda818915d8eb947302fcf9
+
+Curve = P-224
+Private = 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc
+X = e868690641e2cda13b289a6c5d2fb175940396044d9cf27b4f2240af
+Y = 4c78c9abdf2b7fc67ed4497001d7bcf1daca1739dc14a661f91d7c40
+Digest = 7c22f34d5897ccdf7d807f68a7f16e3093a4413625e7853401a4e0384d26893f1997c84557515f2ea66afe7629f62415e6b98e18e97dcb4fb2dec97cf2dd68d9
+K = e2374350f47c08f3c1359d4edf87e61d1ba4e7dd1540d8d9062efa79
+R = e12dc088d2bc032bb214c77d0e0fb749fc8e61ebe1ed72996f1084b6
+S = 0ab58aa31e0bba5fbc76855e6549f1036fba0a589aeab978ab01b8fb
+
+Curve = P-224
+Private = 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4
+X = e67f4385a9da54253cc371ee9bc6739ae6385a4b87669c7baf0c460d
+Y = 2bb00b6ddd7b67d9ac5653ec04ca8529fbf16f815c04da3c2e58e82d
+Digest = 016d26cbcf55236c053ece58651183e4c81edd8f07749a5ba28d8d22a5d6a9c6b33810c9618bd9cf472006cfeb62842927d3fb677d82e09bb5134e470d481812
+K = 8bf5859665b6a23e6b05a311580f60187ba1c4ae89e44877fb48af66
+R = 653675fb993c3fa9e57b32e33029ec230b966e8077c72c1ec90ddefc
+S = 792723bf87e315147cd4303de7f1dfe95cd7658ebb95c38c1a196140
+
+Curve = P-224
+Private = a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916
+X = 400e5cd4b315ceb309545cd3277acb70bdae2073fda6ad896ea14b27
+Y = fbe1d2466cd2e116f38248bd5cabaa6cbe6c4a2694d998abd7b0c991
+Digest = 47e43ab8ebe14f0394c46b55856104211b12d8f2b075f6efa1510fed823dc121cfd9198e060839ebbdf2eb994194875c342be861bf0975665aae881f28cefbc0
+K = 82f55a25d3ed6e47c22a6eed0fa52ed0818b87d6ea7950281dfefc09
+R = 16305a46a3f6f9e216ef8f6a6f5f0760d064a885657c864e1c1ea035
+S = 58fd97050bfbca6f87e64e1458c4ad80bae26e280356da344ad3b25d
+
+Curve = P-224
+Private = fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b
+X = e8dccd706c31f895f2f261ab979cbab51b8ae28196bcc12a42046380
+Y = ec246be8e71ea3859cb717a59990fe22e4b76858ff49becd70739a01
+Digest = d86bfb4fc2ae431617d8800e44b37a5b549775c78e90eaec58b42aebafed731b3123a82fab13254783e24c28db715c53f6538a2961cc888638eab768ee6b66c0
+K = a37d665fe4314aa4cd03eb8e6a1f366b43e11fdb419c96b48f787b62
+R = 05e4909bcc172ab4140be291aad4660e375032bce2d762b6269ba764
+S = e347a1c9d3670690e1d8d1d4cd9579848f442199c10526488da5cebf
+
+Curve = P-224
+Private = a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea
+X = e22e0dc4ecd96eb0071b72ba4b4988bf784f3fe73cb81bfb93d9ac4f
+Y = b3e213e518bee1367a4fb3703b9008bac9d95a1fc4aa61225fff9f3c
+Digest = e537383a08a421bf1f29e07554387bd32d685c2a5830b157df1e83c0f3c78cd11e5a5cc62830a45d7eb71920a2d13ca9cc1eec020c9db49a07d1c91433b31e2c
+K = 42c5b6f87d3bb1ed74f5ee8398d8f8c61e9e50ffa7a1da12d39893f9
+R = 5c0e5c6f057de1e99ef5d237a60d7a07fa9a42b120a82f573d9fb7b2
+S = 2fffc0bf550bd2f650fed085a84501cacfa6a1bb984df1f9237eaa59
+
+Curve = P-224
+Private = 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0
+X = 92521fa25c2e034d127e0921efdb167f0b2ff8b20504487ed87fa264
+Y = e72c770e37375ad7dc2c4e63e5701826f6606f6ffb9461ee61b4e872
+Digest = e7a2242c4409f1eefabffc48014a00424ae3b38c39651227d033b464c2ed4a365841499048b8e491506657e40548a104b4d9d08dc86b6d6dd43af27730788639
+K = eaf76ee4d7e00d13d8a6d03dffd07ad9a8bb6dc8176c9f93059b1b7f
+R = cf5058e2a6cf5e61a138b013eb292f38a1b9f07239ae5941dbce8919
+S = d14198621650d985d270bc997da6e78588fd0ef843b874c66a3de3c3
+
+Curve = P-224
+Private = 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294
+X = e7611e013e7b43ff5b8b57ad83333bffcc9e469ad23070b5791dc594
+Y = 7784da0a11dbe16208c6e0b6d5029e71fbec4dffc9fa046d3eeb71c9
+Digest = 8b751b00d1bb15cc16f6ea2e67b3235c9a50e8cb602eb20dd846c92375ef8446bf1ff1c77fdbc93cfb7d4e845774a27983aaf3fad289ba8495183d03e8b3bbe0
+K = 94db7ef9a232593091eb9a74f289529c7e0d7fef21f80b3c8556b75e
+R = a971f45bab10b1d16d7234ca8e4ec987da20d9e867f28aa063296e23
+S = e38c538d65a7e1a28fd3ec53f015a7e5beb60e9d309f1e3ba4b2c3d2
+
+Curve = P-224
+Private = b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a
+X = 242f34959516a4706172f7dede23110efa314bff22eb320ab88feeff
+Y = 45e3227710900a8acfc9bcce728119d042f64ca40876c2b380ee46e0
+Digest = 89670327dfc4c3a20cd71c6943d3404c34c4b2267b892ae69dee792107ea19e90cc792c3ab886e6c1247e37c3eae8d81cff87b24e06f476e32dae64303349a23
+K = ae61523866a8f43e6cdd42ba27a34ed06527e8a5842901a64c393f76
+R = c2732a4e0815f9f785500e80147e9486994446beccf8a6a352b97585
+S = 6ecaece6487d7920e398f7f951ab7c7aba5832dabf03704106ad1244
+
+Curve = P-224
+Private = 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4
+X = c32988171caab178bf50dc7310bc7f604df5a9d19a8e602519c72d8a
+Y = f8985d112ad9de05969e5364d943c1cc5cd198359f4c62b19da0e117
+Digest = e94800f0b0272d7e59c7e2614318df5652261e89c47fbd0c01b016e569825a4a1b0631e0749dca72b47a4edaac6e6463c7b1c8c3038b20d06d160fc0e1c217e3
+K = 827d4999da81fa920c8492ccc1e2d5cdafed9754cf7382a859952071
+R = 89c61da7422ccd676baec07e2185c12e947a2374eede87847304be6c
+S = 2685379624717ea28422e8d001c090405a130b4ef9f1ac726c3ca502
+
+Curve = P-224
+Private = 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04
+X = 6773a0436a9c42635730413b19aa4166f08c69c0e5002953da42253b
+Y = 555138290b093bf2fe79acda9131d920cd1e7ac43fb8775776cd713c
+Digest = 0bc258cd68474b7df93d2b3209048f571fb0fad76e4c1a5d6e0fc83c2aaff5e50fc978c36a47fb2c0163ad47333b78ed08e07fc21ba2230356a54885a8df2fe5
+K = 557cb45fd3a30b3bdbf08c56eabbd4478736024aaa52bf8448096453
+R = 8e92cf7a674aa5f7542dd95c695589a05747431692edd04804299b8f
+S = af4908b41f8180b71a6ff10fd51f3d143147af6ddddf7534d3284ed9
+
+Curve = P-256
+Private = 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590
+X = 29578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab
+Y = 08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800
+Digest = 5e53611194b517b0ef4f704684850dfa387f99997d586d43c9e41530
+K = 58f741771620bdc428e91a32d86d230873e9140336fcfb1e122892ee1d501bdc
+R = 4a19274429e40522234b8785dc25fc524f179dcc95ff09b3c9770fc71f54ca0d
+S = 58982b79a65b7320f5b92d13bdaecdd1259e760f0f718ba933fd098f6f75d4b7
+
+Curve = P-256
+Private = 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98
+X = 4a92396ff7930b1da9a873a479a28a9896af6cc3d39345b949b726dc3cd978b5
+Y = 475abb18eaed948879b9c1453e3ef2755dd90f77519ec7b6a30297aad08e4931
+Digest = 50be7b4f0e1fa36f06eb430ad4afe8f0cea2b97e060230f91ed1922b
+K = 36f853b5c54b1ec61588c9c6137eb56e7a708f09c57513093e4ecf6d739900e5
+R = 38b29558511061cfabdc8e5bb65ac2976d1aa2ba9a5deab8074097b2172bb9ad
+S = 0de2cde610502b6e03c0b23602eafbcd3faf886c81d111d156b7aa550f5bcd51
+
+Curve = P-256
+Private = a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870
+X = 5775174deb0248112e069cb86f1546ac7a78bc2127d0cb953bad46384dd6be5b
+Y = a27020952971cc0b0c3abd06e9ca3e141a4943f560564eba31e5288928bc7ce7
+Digest = f51177ab6c34bf80ea72d687a670e4102987d1378bd9a4d973af4dad
+K = a0d9a7a245bd9b9aa86cecb89341c9de2e4f9b5d095a8150826c7ba7fb3e7df7
+R = b02a440add66a9ff9c3c0e9acf1be678f6bd48a10cbdec2ad6d186ffe05f3f2a
+S = a98bea42aec56a1fcecec00a1cc69b01fcbcf5de7ac1b2f2dcc09b6db064f92b
+
+Curve = P-256
+Private = 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f
+X = f888e913ec6f3cd8b31eb89e4f8aaa8887d30ae5348ed7118696949d5b8cc7c1
+Y = 08895d09620500d244e5035e262dea3f2867cd8967b226324d5c05220d8b410c
+Digest = 03bf686dab49196f887f3a8083f1a39e26085127a9d9e6a78f22f652
+K = 21c942f3b487accbf7fadc1c4b7a6c7567ce876c195022459fa1ebf6d04ffbaa
+R = 2e6cc883b8acc904ee9691ef4a9f1f5a9e5fbfde847cda3be833f949fb9c7182
+S = 2ac48f7a930912131a8b4e3ab495307817c465d638c2a9ea5ae9e2808806e20a
+
+Curve = P-256
+Private = daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d
+X = 137c465085c1b1b8cccbe9fccbe9d0295a331aaf332f3ed2e285d16e574b943b
+Y = d3e8d5a24cd218c19760b0e85b35a8569945aa857cbf0fd6a3ce127581b217b6
+Digest = 40a7ece19f7f6a6473b209a7ac9441d59b00fc94ae0ded3423427c12
+K = 343251dffa56e6a612fec7b078f9c3819eab402a72686b894a47a08fd97e6c23
+R = 775e25a296bd259510ae9375f548997bec8a744900022945281dc8c4d94f2b5b
+S = d87592ceab773ae103daebbb56a04144aaccb1e14efc1024dc36c0e382df1f70
+
+Curve = P-256
+Private = 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5
+X = 82b1f1a7af9b48ca8452613d7032beb0e4f28fe710306aeccc959e4d03662a35
+Y = 5e39f33574097b8d32b471a591972496f5d44db344c037d13f06fafc75f016fd
+Digest = f6c083325d6316e337c102b16bb96faa478a43b2dc0d56d51a4affed
+K = 6de9e21f0b2cacc1762b3558fd44d3cf156b85dbef430dd28d59713bfb9cfa0b
+R = a754b42720e71925d51fcef76151405a3696cc8f9fc9ca7b46d0b16edd7fb699
+S = 603924780439cc16ac4cf97c2c3065bc95353aa9179d0ab5f0322ca82f851cf2
+
+Curve = P-256
+Private = f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96
+X = e0bbfe4016eea93e6f509518cbffc25d492de6ebbf80465a461caa5bdc018159
+Y = 3231ee7a119d84fa56e3034d50fea85929aec2eb437abc7646821e1bf805fb50
+Digest = 6890736262386d60424be27b3f95996ab696e1ddffdc4a03c256a7c0
+K = 7a33eeb9f469afd55de2fb786847a1d3e7797929305c0f90d953b6f143bb8fc6
+R = 96d1c9399948254ea381631fc0f43ea808110506db8aacf081df5535ac5eb8ad
+S = 73bf3691260dddd9997c97313f2a70783eacf8d15bdfb34bb13025cdfae72f70
+
+Curve = P-256
+Private = 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d
+X = e3c58c1c254d11c7e781ad133e4c36dd1b5de362120d336a58e7b68813f3fbee
+Y = 59760db66120afe0d962c81a8e5586588fd19de2f40556371611c73af22c8a68
+Digest = e8ed2e73fe9e3c6bb087c5179bb357be4cd147bc66e70dc1fecc10fd
+K = c0d37142dc8b0d614fad20c4d35af6eb819e259e513ddeac1e1c273e7e1dc1bb
+R = 25dd8e4086c62a40d2a310e2f90f6af5cb7e677b4dfdb4dc4e99e23ea2f0e6dc
+S = 90ad62c179b0c9d61f521dde1cd762bfd224b5525c39c3706f2549313ddb4f39
+
+Curve = P-256
+Private = 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9
+X = cb3634ec4f0cbb99986be788f889e586026d5a851e80d15382f1bdb1bda2bc75
+Y = 51e4e43bc16fb114896b18198a1aebe6054ba20ed0c0317c1b8776158c0e6bfb
+Digest = ca7e8c8c873346c85db9ac648509c8ccc9ab5651d91e35a248b951fb
+K = 98edd59fafbcaee5f64e84eb5ed59fff45d14aabada47cee2fa674377173627a
+R = 261a1cdb0fd93c0fb06ea6068b6b03c330a12f621a7eba76682a1d152c0e8d08
+S = 7ca049bad54feee101d6db807635ffb8bdb05a38e445c8c3d65d60df143514c5
+
+Curve = P-256
+Private = 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634
+X = 7cca1334bfc2a78728c50b370399be3f9690d445aa03c701da643eeb0b0f7fa8
+Y = 3f7522238668e615405e49b2f63faee58286000a30cdb4b564ac0df99bc8950f
+Digest = 3367c395a9ad7b8214c48658f2a4b377b6b0288ba272a4fbfeaa48df
+K = 8650c30712fc253610884fbba4a332a4574d4b7822f7776cab1df8f5fa05442a
+R = a18194c7ac5829afc408d78dde19542837e7be82706c3941b2d9c5e036bb51e0
+S = 188ead1cdf7c1d21114ff56d0421ffd501ab978ef58337462c0fa736d86299af
+
+Curve = P-256
+Private = 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27
+X = 0aaeed6dd1ae020d6eefc98ec4241ac93cbd3c8afed05bb28007e7da5727571b
+Y = 2dda1d5b7872eb94dfffb456115037ff8d3e72f8ebdd8fcfc42391f96809be69
+Digest = a36a7d6424763633320ca799667f1b79955f079fb1b6dc264058af41
+K = 738e050aeefe54ecba5be5f93a97bbcb7557d701f9da2d7e88483454b97b55a8
+R = 8cb9f41dfdcb9604e0725ac9b78fc0db916dc071186ee982f6dba3da36f02efa
+S = 5c87fe868fd4282fb114f5d70e9590a10a5d35cedf3ff6402ba5c4344738a32e
+
+Curve = P-256
+Private = cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d
+X = c227a2af15dfa8734e11c0c50f77e24e77ed58dd8cccf1b0e9fa06bee1c64766
+Y = b686592ce3745eb300d2704083db55e1fa8274e4cb7e256889ccc0bb34a60570
+Digest = 864f18aa83fd3af6cdf6ac7f8526062d0c48a8d3c341cc23d53be864
+K = 2d6b449bb38b543d6b6d34ff8cb053f5e5b337f949b069b21f421995ebb28823
+R = 5e89d3c9b103c2fa3cb8cebeec23640acda0257d63ffbe2d509bfc49fab1dca6
+S = d70c5b1eeb29e016af9925798d24e166c23d58fedd2f1a3bbdb1ef78cdbfb63a
+
+Curve = P-256
+Private = b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c
+X = 722e0abad4504b7832a148746153777694714eca220eced2b2156ca64cfed3dd
+Y = f0351b357b3081e859c46cad5328c5afa10546e92bc6c3fd541796ac30397a75
+Digest = 916924fcced069bf6956eeb4e8f09dc9bf928e8a690111b699e39eab
+K = b15bbce4b382145de7ecd670d947e77555ef7cd1693bd53c694e2b52b04d10e1
+R = 9d086dcd22da165a43091991bede9c1c14515e656633cb759ec2c17f51c35253
+S = 23595ad1cb714559faaecaf946beb9a71e584616030ceaed8a8470f4bf62768f
+
+Curve = P-256
+Private = 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48
+X = 4814d454495df7103e2da383aba55f7842fd84f1750ee5801ad32c10d0be6c7d
+Y = a0bd039d5097c8f0770477f6b18d247876e88e528bf0453eab515ffab8a9eda3
+Digest = ec2fb907b92865e501ce97f703cf6214a6de2303df472ba58145af16
+K = d414f1525cdcc41eba1652de017c034ebcc7946cb2efe4713d09f67c85b83153
+R = 84db02c678f9a21208cec8564d145a35ba8c6f26b4eb7e19522e439720dae44c
+S = 537c564da0d2dc5ac4376c5f0ca3b628d01d48df47a83d842c927e4d6db1e16d
+
+Curve = P-256
+Private = 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f
+X = f04e9f2831d9697ae146c7d4552e5f91085cc46778400b75b76f00205252941d
+Y = bd267148174cd0c2b019cd0a5256e2f3f889d1e597160372b5a1339c8d787f10
+Digest = b047a2a715335a1cc255beb983355e7d1363c610bf56df45d4503e69
+K = 7707db348ee6f60365b43a2a994e9b40ed56fe03c2c31c7e781bc4ffadcba760
+R = 5d95c385eeba0f15db0b80ae151912409128c9c80e554246067b8f6a36d85ea5
+S = db5d8a1e345f883e4fcb3871276f170b783c1a1e9da6b6615913368a8526f1c3
+
+Curve = P-256
+Private = 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464
+X = 1ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83
+Y = ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9
+Digest = 44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56
+K = 94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de
+R = f3ac8061b514795b8843e3d6629527ed2afd6b1f6a555a7acabb5e6f79c8c2ac
+S = 8bf77819ca05a6b2786c76262bf7371cef97b218e96f175a3ccdda2acc058903
+
+Curve = P-256
+Private = 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813
+X = e266ddfdc12668db30d4ca3e8f7749432c416044f2d2b8c10bf3d4012aeffa8a
+Y = bfa86404a2e9ffe67d47c587ef7a97a7f456b863b4d02cfc6928973ab5b1cb39
+Digest = 9b2db89cb0e8fa3cc7608b4d6cc1dec0114e0b9ff4080bea12b134f489ab2bbc
+K = 6d3e71882c3b83b156bb14e0ab184aa9fb728068d3ae9fac421187ae0b2f34c6
+R = 976d3a4e9d23326dc0baa9fa560b7c4e53f42864f508483a6473b6a11079b2db
+S = 1b766e9ceb71ba6c01dcd46e0af462cd4cfa652ae5017d4555b8eeefe36e1932
+
+Curve = P-256
+Private = e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef
+X = 74ccd8a62fba0e667c50929a53f78c21b8ff0c3c737b0b40b1750b2302b0bde8
+Y = 29074e21f3a0ef88b9efdf10d06aa4c295cc1671f758ca0e4cd108803d0f2614
+Digest = b804cf88af0c2eff8bbbfb3660ebb3294138e9d3ebd458884e19818061dacff0
+K = ad5e887eb2b380b8d8280ad6e5ff8a60f4d26243e0124c2f31a297b5d0835de2
+R = 35fb60f5ca0f3ca08542fb3cc641c8263a2cab7a90ee6a5e1583fac2bb6f6bd1
+S = ee59d81bc9db1055cc0ed97b159d8784af04e98511d0a9a407b99bb292572e96
+
+Curve = P-256
+Private = a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07
+X = 322f80371bf6e044bc49391d97c1714ab87f990b949bc178cb7c43b7c22d89e1
+Y = 3c15d54a5cc6b9f09de8457e873eb3deb1fceb54b0b295da6050294fae7fd999
+Digest = 85b957d92766235e7c880ac5447cfbe97f3cb499f486d1e43bcb5c2ff9608a1a
+K = 24fc90e1da13f17ef9fe84cc96b9471ed1aaac17e3a4bae33a115df4e5834f18
+R = d7c562370af617b581c84a2468cc8bd50bb1cbf322de41b7887ce07c0e5884ca
+S = b46d9f2d8c4bf83546ff178f1d78937c008d64e8ecc5cbb825cb21d94d670d89
+
+Curve = P-256
+Private = 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d
+X = 1bcec4570e1ec2436596b8ded58f60c3b1ebc6a403bc5543040ba82963057244
+Y = 8af62a4c683f096b28558320737bf83b9959a46ad2521004ef74cf85e67494e1
+Digest = 3360d699222f21840827cf698d7cb635bee57dc80cd7733b682d41b55b666e22
+K = 5d833e8d24cc7a402d7ee7ec852a3587cddeb48358cea71b0bedb8fabe84e0c4
+R = 18caaf7b663507a8bcd992b836dec9dc5703c080af5e51dfa3a9a7c387182604
+S = 77c68928ac3b88d985fb43fb615fb7ff45c18ba5c81af796c613dfa98352d29c
+
+Curve = P-256
+Private = 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d
+X = a32e50be3dae2c8ba3f5e4bdae14cf7645420d425ead94036c22dd6c4fc59e00
+Y = d623bf641160c289d6742c6257ae6ba574446dd1d0e74db3aaa80900b78d4ae9
+Digest = c413c4908cd0bc6d8e32001aa103043b2cf5be7fcbd61a5cec9488c3a577ca57
+K = e18f96f84dfa2fd3cdfaec9159d4c338cd54ad314134f0b31e20591fc238d0ab
+R = 8524c5024e2d9a73bde8c72d9129f57873bbad0ed05215a372a84fdbc78f2e68
+S = d18c2caf3b1072f87064ec5e8953f51301cada03469c640244760328eb5a05cb
+
+Curve = P-256
+Private = 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab
+X = 8bcfe2a721ca6d753968f564ec4315be4857e28bef1908f61a366b1f03c97479
+Y = 0f67576a30b8e20d4232d8530b52fb4c89cbc589ede291e499ddd15fe870ab96
+Digest = 88fc1e7d849794fc51b135fa135deec0db02b86c3cd8cebdaa79e8689e5b2898
+K = 295544dbb2da3da170741c9b2c6551d40af7ed4e891445f11a02b66a5c258a77
+R = c5a186d72df452015480f7f338970bfe825087f05c0088d95305f87aacc9b254
+S = 84a58f9e9d9e735344b316b1aa1ab5185665b85147dc82d92e969d7bee31ca30
+
+Curve = P-256
+Private = 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a
+X = a88bc8430279c8c0400a77d751f26c0abc93e5de4ad9a4166357952fe041e767
+Y = 2d365a1eef25ead579cc9a069b6abc1b16b81c35f18785ce26a10ba6d1381185
+Digest = 41fa8d8b4cd0a5fdf021f4e4829d6d1e996bab6b4a19dcb85585fe76c582d2bc
+K = 7c80fd66d62cc076cef2d030c17c0a69c99611549cb32c4ff662475adbe84b22
+R = 9d0c6afb6df3bced455b459cc21387e14929392664bb8741a3693a1795ca6902
+S = d7f9ddd191f1f412869429209ee3814c75c72fa46a9cccf804a2f5cc0b7e739f
+
+Curve = P-256
+Private = 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881
+X = 1bc487570f040dc94196c9befe8ab2b6de77208b1f38bdaae28f9645c4d2bc3a
+Y = ec81602abd8345e71867c8210313737865b8aa186851e1b48eaca140320f5d8f
+Digest = 2d72947c1731543b3d62490866a893952736757746d9bae13e719079299ae192
+K = 2e7625a48874d86c9e467f890aaa7cd6ebdf71c0102bfdcfa24565d6af3fdce9
+R = 2f9e2b4e9f747c657f705bffd124ee178bbc5391c86d056717b140c153570fd9
+S = f5413bfd85949da8d83de83ab0d19b2986613e224d1901d76919de23ccd03199
+
+Curve = P-256
+Private = f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308
+X = b8188bd68701fc396dab53125d4d28ea33a91daf6d21485f4770f6ea8c565dde
+Y = 423f058810f277f8fe076f6db56e9285a1bf2c2a1dae145095edd9c04970bc4a
+Digest = e138bd577c3729d0e24a98a82478bcc7482499c4cdf734a874f7208ddbc3c116
+K = 62f8665fd6e26b3fa069e85281777a9b1f0dfd2c0b9f54a086d0c109ff9fd615
+R = 1cc628533d0004b2b20e7f4baad0b8bb5e0673db159bbccf92491aef61fc9620
+S = 880e0bbf82a8cf818ed46ba03cf0fc6c898e36fca36cc7fdb1d2db7503634430
+
+Curve = P-256
+Private = b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906
+X = 51f99d2d52d4a6e734484a018b7ca2f895c2929b6754a3a03224d07ae61166ce
+Y = 4737da963c6ef7247fb88d19f9b0c667cac7fe12837fdab88c66f10d3c14cad1
+Digest = 17b03f9f00f6692ccdde485fc63c4530751ef35da6f71336610944b0894fcfb8
+K = 72b656f6b35b9ccbc712c9f1f3b1a14cbbebaec41c4bca8da18f492a062d6f6f
+R = 9886ae46c1415c3bc959e82b760ad760aab66885a84e620aa339fdf102465c42
+S = 2bf3a80bc04faa35ebecc0f4864ac02d349f6f126e0f988501b8d3075409a26c
+
+Curve = P-256
+Private = d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7
+X = 8fb287f0202ad57ae841aea35f29b2e1d53e196d0ddd9aec24813d64c0922fb7
+Y = 1f6daff1aa2dd2d6d3741623eecb5e7b612997a1039aab2e5cf2de969cfea573
+Digest = c25beae638ff8dcd370e03a6f89c594c55bed1277ee14d83bbb0ef783a0517c7
+K = d926fe10f1bfd9855610f4f5a3d666b1a149344057e35537373372ead8b1a778
+R = 490efd106be11fc365c7467eb89b8d39e15d65175356775deab211163c2504cb
+S = 644300fc0da4d40fb8c6ead510d14f0bd4e1321a469e9c0a581464c7186b7aa7
+
+Curve = P-256
+Private = b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c
+X = 68229b48c2fe19d3db034e4c15077eb7471a66031f28a980821873915298ba76
+Y = 303e8ee3742a893f78b810991da697083dd8f11128c47651c27a56740a80c24c
+Digest = 5eb28029ebf3c7025ff2fc2f6de6f62aecf6a72139e1cba5f20d11bbef036a7f
+K = e158bf4a2d19a99149d9cdb879294ccb7aaeae03d75ddd616ef8ae51a6dc1071
+R = e67a9717ccf96841489d6541f4f6adb12d17b59a6bef847b6183b8fcf16a32eb
+S = 9ae6ba6d637706849a6a9fc388cf0232d85c26ea0d1fe7437adb48de58364333
+
+Curve = P-256
+Private = 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1
+X = 0a7dbb8bf50cb605eb2268b081f26d6b08e012f952c4b70a5a1e6e7d46af98bb
+Y = f26dd7d799930062480849962ccf5004edcfd307c044f4e8f667c9baa834eeae
+Digest = 12135386c09e0bf6fd5c454a95bcfe9b3edb25c71e455c73a212405694b29002
+K = 646fe933e96c3b8f9f507498e907fdd201f08478d0202c752a7c2cfebf4d061a
+R = b53ce4da1aa7c0dc77a1896ab716b921499aed78df725b1504aba1597ba0c64b
+S = d7c246dc7ad0e67700c373edcfdd1c0a0495fc954549ad579df6ed1438840851
+
+Curve = P-256
+Private = 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1
+X = 105d22d9c626520faca13e7ced382dcbe93498315f00cc0ac39c4821d0d73737
+Y = 6c47f3cbbfa97dfcebe16270b8c7d5d3a5900b888c42520d751e8faf3b401ef4
+Digest = aea3e069e03c0ff4d6b3fa2235e0053bbedc4c7e40efbc686d4dfb5efba4cfed
+K = a6f463ee72c9492bc792fe98163112837aebd07bab7a84aaed05be64db3086f4
+R = 542c40a18140a6266d6f0286e24e9a7bad7650e72ef0e2131e629c076d962663
+S = 4f7f65305e24a6bbb5cff714ba8f5a2cee5bdc89ba8d75dcbf21966ce38eb66f
+
+Curve = P-256
+Private = b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced
+X = e0e7b99bc62d8dd67883e39ed9fa0657789c5ff556cc1fd8dd1e2a55e9e3f243
+Y = 63fbfd0232b95578075c903a4dbf85ad58f8350516e1ec89b0ee1f5e1362da69
+Digest = d9c83b92fa0979f4a5ddbd8dd22ab9377801c3c31bf50f932ace0d2146e2574da0d5552dbed4b18836280e9f94558ea6
+K = 9980b9cdfcef3ab8e219b9827ed6afdd4dbf20bd927e9cd01f15762703487007
+R = f5087878e212b703578f5c66f434883f3ef414dc23e2e8d8ab6a8d159ed5ad83
+S = 306b4c6c20213707982dffbb30fba99b96e792163dd59dbe606e734328dd7c8a
+
+Curve = P-256
+Private = 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181
+X = afda82260c9f42122a3f11c6058839488f6d7977f6f2a263c67d06e27ea2c355
+Y = 0ae2bbdd2207c590332c5bfeb4c8b5b16622134bd4dc55382ae806435468058b
+Digest = 76c8df4563375d34656f2d1dd3445c9d9f0c8da59dc015fa6122237e1a02039998c16b3935e281160923c6e21115d0a9
+K = 23129a99eeda3d99a44a5778a46e8e7568b91c31fb7a8628c5d9820d4bed4a6b
+R = e446600cab1286ebc3bb332012a2f5cc33b0a5ef7291d5a62a84de5969d77946
+S = cf89b12793ee1792eb26283b48fa0bdcb45ae6f6ad4b02564bf786bb97057d5a
+
+Curve = P-256
+Private = 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431
+X = 702b2c94d039e590dd5c8f9736e753cf5824aacf33ee3de74fe1f5f7c858d5ed
+Y = 0c28894e907af99fb0d18c9e98f19ac80dd77abfa4bebe45055c0857b82a0f4d
+Digest = bad1b2c4c35c54eede5d9dee6f6821bb0254395ae6a689ae7289790448ff787ea4e495ea418c0759c51144a74eba3ac9
+K = 9beab7722f0bcb468e5f234e074170a60225255de494108459abdf603c6e8b35
+R = c4021fb7185a07096547af1fb06932e37cf8bd90cf593dea48d48614fa237e5e
+S = 7fb45d09e2172bec8d3e330aa06c43fbb5f625525485234e7714b7f6e92ba8f1
+
+Curve = P-256
+Private = 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd
+X = d12512e934c367e4c4384dbd010e93416840288a0ba00b299b4e7c0d91578b57
+Y = ebf8835661d9b578f18d14ae4acf9c357c0dc8b7112fc32824a685ed72754e23
+Digest = c248cc5eb23ed0f6f03de308fffed1e5fdd918aef379946d7b66b8924dc38306feb28e85cc5ab5d7a3a0e55087ddecde
+K = 77cffa6f9a73904306f9fcd3f6bbb37f52d71e39931bb4aec28f9b076e436ccf
+R = 4d5a9d95b0f09ce8704b0f457b39059ee606092310df65d3f8ae7a2a424cf232
+S = 7d3c014ca470a73cef1d1da86f2a541148ad542fbccaf9149d1b0b030441a7eb
+
+Curve = P-256
+Private = 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de
+X = b4238b029fc0b7d9a5286d8c29b6f3d5a569e9108d44d889cd795c4a385905be
+Y = 8cb3fff8f6cca7187c6a9ad0a2b1d9f40ae01b32a7e8f8c4ca75d71a1fffb309
+Digest = b05d944f6752bfe003526499bb4d8721c0d25a7901999f67519b17665e907cd148b2ff1b451248d292866bcc81b506d9
+K = d02617f26ede3584f0afcfc89554cdfb2ae188c192092fdde3436335fafe43f1
+R = 26fd9147d0c86440689ff2d75569795650140506970791c90ace0924b44f1586
+S = 00a34b00c20a8099df4b0a757cbef8fea1cb3ea7ced5fbf7e987f70b25ee6d4f
+
+Curve = P-256
+Private = ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566
+X = c3bdc7c795ec94620a2cfff614c13a3390a5e86c892e53a24d3ed22228bc85bf
+Y = 70480fc5cf4aacd73e24618b61b5c56c1ced8c4f1b869580ea538e68c7a61ca3
+Digest = 847325a13b72de5a15cd899ced0920b8543ab26f9d3877fde99c5018efc78ddf14c00f88b06af7971181923aa46624d4
+K = 53291d51f68d9a12d1dcdc58892b2f786cc15f631f16997d2a49bace513557d4
+R = a860c8b286edf973ce4ce4cf6e70dc9bbf3818c36c023a845677a9963705df8b
+S = 5630f986b1c45e36e127dd7932221c4272a8cc6e255e89f0f0ca4ec3a9f76494
+
+Curve = P-256
+Private = 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee
+X = 8d40bf2299e05d758d421972e81cfb0cce68b949240dc30f315836acc70bef03
+Y = 5674e6f77f8b46f46cca937d83b128dffbe9bd7e0d3d08aa2cbbfdfb16f72c9a
+Digest = fd30608cf408dac5886ca156bdce7f75067e18172af79ca84f8d60d011b8a6b5ea33a92554d1ea34b105d5bd09062d47
+K = 373a825b5a74b7b9e02f8d4d876b577b4c3984168d704ba9f95b19c05ed590af
+R = ef6fb386ad044b63feb7445fa16b10319018e9cea9ef42bca83bdad01992234a
+S = ac1f42f652eb1786e57be01d847c81f7efa072ba566d4583af4f1551a3f76c65
+
+Curve = P-256
+Private = 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd
+X = 660da45c413cc9c9526202c16b402af602d30daaa7c342f1e722f15199407f31
+Y = e6f8cbb06913cc718f2d69ba2fb3137f04a41c27c676d1a80fbf30ea3ca46439
+Digest = 9d21e70e88c43cbab056c5fdeb63baa2660ebc44e0d1ef781f8f6bf58b28e3a2c9d5db051c8da3ba34796d8bcc7ba5cb
+K = 6b8eb7c0d8af9456b95dd70561a0e902863e6dfa1c28d0fd4a0509f1c2a647b2
+R = 08fabf9b57de81875bfa7a4118e3e44cfb38ec6a9b2014940207ba3b1c583038
+S = a58d199b1deba7350616230d867b2747a3459421811c291836abee715b8f67b4
+
+Curve = P-256
+Private = 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666
+X = b4909a5bdf25f7659f4ef35e4b811429fb2c59126e3dad09100b46aea6ebe7a6
+Y = 760ae015fa6af5c9749c4030fdb5de6e58c6b5b1944829105cf7edf7d3a22cfb
+Digest = 0bc6a254fa0016a5aa608309f9a97cf0c879370bae0b7b460da17c2694e8414db39ec8b5f943167372610fc146dd8b28
+K = 88794923d8943b5dbcc7a7a76503880ff7da632b0883aaa60a9fcc71bf880fd6
+R = 6ec9a340b77fae3c7827fa96d997e92722ff2a928217b6dd3c628f3d49ae4ce6
+S = 637b54bbcfb7e7d8a41ea317fcfca8ad74eb3bb6b778bc7ef9dec009281976f7
+
+Curve = P-256
+Private = bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67
+X = c786d9421d67b72b922cf3def2a25eeb5e73f34543eb50b152e738a98afb0ca5
+Y = 6796271e79e2496f9e74b126b1123a3d067de56b5605d6f51c8f6e1d5bb93aba
+Digest = 12520a7ef4f05f91b9f9a0fba73eddc813413c4d4764dc1c4b773c4afd5cd77b0e7f09d56e5931aec2958407c02774c0
+K = 89e690d78a5e0d2b8ce9f7fcbf34e2605fd9584760fa7729043397612dd21f94
+R = 07e5054c384839584624e8d730454dc27e673c4a90cbf129d88b91250341854d
+S = f7e665b88614d0c5cbb3007cafe713763d81831525971f1747d92e4d1ca263a7
+
+Curve = P-256
+Private = 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9
+X = 86662c014ab666ee770723be8da38c5cd299efc6480fc6f8c3603438fa8397b9
+Y = f26b3307a650c3863faaa5f642f3ba1384c3d3a02edd3d48c657c269609cc3fc
+Digest = 4b3a6ea660aac1e87dae5a252ab5588b5292d713f8c146f1a92d7b72f64bc91663c46e2beb33832e92ec0dccdf033f87
+K = ec90584ab3b383b590626f36ed4f5110e49888aec7ae7a9c5ea62dd2dc378666
+R = 13e9ad59112fde3af4163eb5c2400b5e9a602576d5869ac1c569075f08c90ff6
+S = 708ac65ff2b0baaccc6dd954e2a93df46016bd04457636de06798fcc17f02be5
+
+Curve = P-256
+Private = f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce
+X = 74a4620c578601475fc169a9b84be613b4a16cb6acab8fd98848a6ec9fbd133d
+Y = 42b9e35d347c107e63bd55f525f915bcf1e3d2b81d002d3c39acf10fc30645a1
+Digest = a357e9fa283e8699373cb7c027e4c86084259f08662fd0fc064e7b2f6a33562fb2a9e938962eda99f43e5e2b012822b8
+K = 4d578f5099636234d9c1d566f1215d5d887ae5d47022be17dbf32a11a03f053b
+R = 113a933ebc4d94ce1cef781e4829df0c493b0685d39fb2048ce01b21c398dbba
+S = 3005bd4ec63dbd04ce9ff0c6246ad65d27fcf62edb2b7e461589f9f0e7446ffd
+
+Curve = P-256
+Private = 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f
+X = 7e4078a1d50c669fb2996dd9bacb0c3ac7ede4f58fa0fa1222e78dbf5d1f4186
+Y = 0014e46e90cc171fbb83ea34c6b78202ea8137a7d926f0169147ed5ae3d6596f
+Digest = 347d91b8295d9321c84ce2a5e1c5257c4ffaf0006d884ff7337d386c63f532db444a873b8047ba373bb3538b5664ab31
+K = be522b0940b9a40d84bf790fe6abdc252877e671f2efa63a33a65a512fc2aa5c
+R = a26b9ad775ac37ff4c7f042cdc4872c5e4e5e800485f488ddfaaed379f468090
+S = f88eae2019bebbba62b453b8ee3472ca5c67c267964cffe0cf2d2933c1723dff
+
+Curve = P-256
+Private = 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b
+X = a62032dfdb87e25ed0c70cad20d927c7effeb2638e6c88ddd670f74df16090e5
+Y = 44c5ee2cf740ded468f5d2efe13daa7c5234645a37c073af35330d03a4fed976
+Digest = 46252c7ed042d8b1f691a46b4f6ca5395106871bd413e277a3812beb1757d9fb056a9805aa31376fd60e0ac567265cdd
+K = 06c1e692b045f425a21347ecf72833d0242906c7c1094f805566cdcb1256e394
+R = eb173b51fb0aec318950d097e7fda5c34e529519631c3e2c9b4550b903da417d
+S = ca2c13574bf1b7d56e9dc18315036a31b8bceddf3e2c2902dcb40f0cc9e31b45
+
+Curve = P-256
+Private = 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388
+X = 760b5624bd64d19c866e54ccd74ad7f98851afdbc3ddeae3ec2c52a135be9cfa
+Y = feca15ce9350877102eee0f5af18b2fed89dc86b7df0bf7bc2963c1638e36fe8
+Digest = 1ec1470e867e27ab4800998382f623e27fc2a897a497e6a9cb7c3584b42080c65dbe1270dc479a454566653abd402f02
+K = e4f77c6442eca239b01b0254e11a4182782d96f48ab521cc3d1d68df12b5a41a
+R = bdff14e4600309c2c77f79a25963a955b5b500a7b2d34cb172cd6acd52905c7b
+S = b0479cdb3df79923ec36a104a129534c5d59f622be7d613aa04530ad2507d3a2
+
+Curve = P-256
+Private = 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499
+X = 6b738de3398b6ac57b9591f9d7985dd4f32137ad3460dcf8970c1390cb9eaf8d
+Y = 83bc61e26d2bbbd3cf2d2ab445a2bc4ab5dde41f4a13078fd1d3cc36ab596d57
+Digest = a59ca4dd2b0347f4f2702a8962878a206775fd91047040be60463119f02aa829b7360b940b2785395406c280375c5d90ee655e51d4120df256b9a6287161c7fc
+K = 9106192170ccb3c64684d48287bb81bbed51b40d503462c900e5c7aae43e380a
+R = 275fa760878b4dc05e9d157fedfd8e9b1c9c861222a712748cb4b7754c043fb1
+S = 699d906bb8435a05345af3b37e3b357786939e94caae257852f0503adb1e0f7e
+
+Curve = P-256
+Private = f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6
+X = f2a6674d4e86152a527199bed293fa63acde1b4d8a92b62e552210ba45c38792
+Y = c72565c24f0eee6a094af341ddd8579747b865f91c8ed5b44cda8a19cc93776f
+Digest = 9e359350e87e7573ad9894cd4aad6c6202a58e9938d098dbf65650fc6f04fce3664b9adb234bfa0821788223a306daaa3e62bd46b19d7eb7a725bc5bce8998f3
+K = e547791f7185850f03d0c58419648f65b9d29cdc22ed1de2a64280220cfcafba
+R = 4782903d2aaf8b190dab5cae2223388d2d8bd845b3875d37485c54e1ded1d3d8
+S = dfb40e406bfa074f0bf832771b2b9f186e2211f0bca279644a0ca8559acf39da
+
+Curve = P-256
+Private = 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead
+X = 70b877b5e365fcf08140b1eca119baba662879f38e059d074a2cb60b03ea5d39
+Y = 5f56f94d591df40b9f3b8763ac4b3dbe622c956d5bd0c55658b6f46fa3deb201
+Digest = ff5e80ccbb51b75742a1f0e632b4c6cd119692f2aca337378f7eb2f3b17fc3d912828b7e1655d2263d8757715eea31493aa89dfe1db143a8fa13f89a00379938
+K = 79d6c967ed23c763ece9ca4b026218004c84dc2d4ccc86cf05c5d0f791f6279b
+R = 2ba2ea2d316f8937f184ad3028e364574d20a202e4e7513d7af57ac2456804d1
+S = 64fe94968d18c5967c799e0349041b9e40e6c6c92ebb475e80dd82f51cf07320
+
+Curve = P-256
+Private = 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd
+X = 3088d4f45d274cc5f418c8ecc4cbcf96be87491f420250f8cbc01cdf2503ec47
+Y = 634db48198129237ed068c88ff5809f6211921a6258f548f4b64dd125921b78b
+Digest = e9518ad1c62d686b9df1f5ae1f6797d8c5944a65fcf2244b763f47b9bc5db8ec360cbd17180e6d24678bc36a1535276733bab7817610399ef6257ca43361dfa0
+K = 0508ad7774908b5705895fda5c3b7a3032bf85dab7232bf981177019f3d76460
+R = acd9f3b63626c5f32103e90e1dd1695907b1904aa9b14f2132caef331321971b
+S = 15c04a8bd6c13ed5e9961814b2f406f064670153e4d5465dcef63c1d9dd52a87
+
+Curve = P-256
+Private = 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117
+X = 75a45758ced45ecf55f755cb56ca2601d794ebeaeb2e6107fe2fc443f580e23c
+Y = 5303d47d5a75ec821d51a2ee7548448208c699eca0cd89810ffc1aa4faf81ead
+Digest = 9fd9a5f9b73f6d01894ceaf8a1e0327a0cac0dbc30153201bcccf09b6756e2f89198781e80a7ff5119cc2bb4402c731379f5ab5eda9264e3fe88b4b528e16598
+K = 5165c54def4026ab648f7768c4f1488bcb183f6db7ffe02c7022a529a116482a
+R = ebc85fc4176b446b3384ccc62fc2526b45665561a0e7e9404ac376c90e450b59
+S = 8b2c09428e62c5109d17ed0cf8f9fd7c370d018a2a73f701effc9b17d04852c6
+
+Curve = P-256
+Private = 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61
+X = 2177e20a2092a46667debdcc21e7e45d6da72f124adecbc5ada6a7bcc7b401d5
+Y = 550e468f2626070a080afeeb98edd75a721eb773c8e62149f3e903cf9c4d7b61
+Digest = bfc07b9a8a8941b99ac47d607356e5b68d7534fb3faccfbe97751397af359d31fe239179a1d856ffac49a9738e888f599123ee96ae202fb93b897e26bc83202e
+K = 0464fe9674b01ff5bd8be21af3399fad66f90ad30f4e8ee6e2eb9bcccfd5185c
+R = f8250f073f34034c1cde58f69a85e2f5a030703ebdd4dbfb98d3b3690db7d114
+S = a9e83e05f1d6e0fef782f186bedf43684c825ac480174d48b0e4d31505e27498
+
+Curve = P-256
+Private = 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2
+X = 7b9c592f61aae0555855d0b9ebb6fd00fb6746e8842e2523565c858630b9ba00
+Y = d35b2e168b1875bbc563bea5e8d63c4e38957c774a65e762959a349eaf263ba0
+Digest = a051dcee66f456d9786785444cee2a3a342a8e27a5ebdf0e91553a0d257eea11af3a7df7e9310b46d95021a1880cd3f064c73447d92a31bacdb889f1e1390f49
+K = ef9df291ea27a4b45708f7608723c27d7d56b7df0599a54bc2c2fabbff373b40
+R = 66d057fd39958b0e4932bacd70a1769bbadcb62e4470937b45497a3d4500fabb
+S = 6c853b889e18b5a49ee54b54dd1aaedfdd642e30eba171c5cab677f0df9e7318
+
+Curve = P-256
+Private = 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7
+X = 82a1a96f4648393c5e42633ecdeb1d8245c78c5ea236b5bab460dedcc8924bc0
+Y = e8cbf03c34b5154f876de19f3bb6fd43cd2eabf6e7c95467bcfa8c8fc42d76fd
+Digest = e1a00e6e38599d7eba1f1a8a6c7337e4dcbdd4f436f47c57d17ef85829f7e266b6bff67a001598db6b9ac032ad160d6f928f8724d2f10928cf953bc76c3fd2fb
+K = efed736e627899fea944007eea39a4a63c0c2e26491cd12adb546be3e5c68f7d
+R = cf7fc24bdaa09ac0cca8497e13298b961380668613c7493954048c06385a7044
+S = f38b1c8306cf82ab76ee3a772b14416b49993fe11f986e9b0f0593c52ec91525
+
+Curve = P-256
+Private = 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870
+X = 42c292b0fbcc9f457ae361d940a9d45ad9427431a105a6e5cd90a345fe3507f7
+Y = 313b08fd2fa351908b3178051ee782cc62b9954ad95d4119aa564900f8ade70c
+Digest = bdcf1926e90c980373954c67d3c3c06ccb1a5076957673f12ddf23fa0cce7b3dc3ec2aec143a1ba58094e3da45e2b160092e1d943cf8f22fad35f8348575a0cf
+K = 4c08dd0f8b72ae9c674e1e448d4e2afe3a1ee69927fa23bbff3716f0b99553b7
+R = f2bc35eb1b8488b9e8d4a1dbb200e1abcb855458e1557dc1bf988278a174eb3b
+S = ed9a2ec043a1d578e8eba6f57217976310e8674385ad2da08d6146c629de1cd9
+
+Curve = P-256
+Private = e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf
+X = 89dd22052ec3ab4840206a62f2270c21e7836d1a9109a3407dd0974c7802b9ae
+Y = e91609ba35c7008b080c77a9068d97a14ca77b97299e74945217672b2fd5faf0
+Digest = da606bb1d0d25dd18a9c29096042e65e6b73086b30509962ea1aa75f25b74653c03a66620cba446f442765f28d7c55a5ff4f9693a6c7ce18e1196c25c12da48d
+K = c9f621441c235fc47ec34eef4c08625df1ec74918e1f86075b753f2589f4c60b
+R = a70d1a2d555d599bfb8c9b1f0d43725341151d17a8d0845fa56f3563703528a7
+S = 4e05c45adf41783e394a5312f86e66871c4be4896948c85966879d5c66d54b37
+
+Curve = P-256
+Private = 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c
+X = b0c0ad5e1f6001d8e9018ec611b2e3b91923e69fa6c98690ab644d650f640c42
+Y = 610539c0b9ed21ac0a2f27527c1a61d9b47cbf033187b1a6ada006eb5b2662ed
+Digest = efdb1d2143ecf0447a68e8156a7443897a56b31b4c0cfe499511a4a3ff6f32ba25515b3a20296a10d23378a24fb7de8c2ce606a7d93a9bd72aef3a34d1ff6401
+K = 1f6d4a905c761a53d54c362976717d0d7fc94d222bb5489e4830080a1a67535d
+R = 83404dcf8320baf206381800071e6a75160342d19743b4f176960d669dd03d07
+S = 3f75dcf102008b2989f81683ae45e9f1d4b67a6ef6fd5c8af44828af80e1cfb5
+
+Curve = P-256
+Private = f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9
+X = 250f7112d381c1751860045d9bcaf20dbeb25a001431f96ac6f19109362ffebb
+Y = 49fba9efe73546135a5a31ab3753e247034741ce839d3d94bd73936c4a17e4aa
+Digest = eeb09b1f4a74744909774bfe707977e5234db27026873fc7b5496e37d363ff82d5a1dd6fa6c97717aa0828a6f6325a2b7970e5d836ddfb63bf47b09f136eb9da
+K = 68c299be2c0c6d52d208d5d1a9e0ffa2af19b4833271404e5876e0aa93987866
+R = 7b195e92d2ba95911cda7570607e112d02a1c847ddaa33924734b51f5d81adab
+S = 10d9f206755cef70ab5143ac43f3f8d38aea2644f31d52eaf3b472ee816e11e5
+
+Curve = P-256
+Private = f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5
+X = 4ca87c5845fb04c2f76ae3273073b0523e356a445e4e95737260eba9e2d021db
+Y = 0f86475d07f82655320fdf2cd8db23b21905b1b1f2f9c48e2df87e24119c4880
+Digest = 8cd8e7876555a7393128336880c8002136e1008814a691528111220fd14158b7ff822226c67390739db56b368cf69cecc4cc147220be3d3ce587c8ad75b0f55a
+K = 91bd7d97f7ed3253cedefc144771bb8acbbda6eb24f9d752bbe1dd018e1384c7
+R = 008c1755d3df81e64e25270dbaa9396641556df7ffc7ac9add6739c382705397
+S = 77df443c729b039aded5b516b1077fecdd9986402d2c4b01734ba91e055e87fc
+
+Curve = P-256
+Private = 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628
+X = 28afa3b0f81a0e95ad302f487a9b679fcdef8d3f40236ec4d4dbf4bb0cbba8b2
+Y = bb4ac1be8405cbae8a553fbc28e29e2e689fabe7def26d653a1dafc023f3cecf
+Digest = 7a951d7de2e3552d16912a1d4381f047577f9fd7a8f55dc8ebfb5eac9c859ab8771e222bf56d3330201b82751d0aa5b6c21f42ada05db9955d46f62d530723e1
+K = f98e1933c7fad4acbe94d95c1b013e1d6931fa8f67e6dbb677b564ef7c3e56ce
+R = 15a9a5412d6a03edd71b84c121ce9a94cdd166e40da9ce4d79f1afff6a395a53
+S = 86bbc2b6c63bad706ec0b093578e3f064736ec69c0dba59b9e3e7f73762a4dc3
+
+Curve = P-256
+Private = 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49
+X = c62cc4a39ace01006ad48cf49a3e71466955bbeeca5d318d672695df926b3aa4
+Y = c85ccf517bf2ebd9ad6a9e99254def0d74d1d2fd611e328b4a3988d4f045fe6f
+Digest = 4cb0debbdb572d89e2e46dcc6c2c63ef032792683032ce965b3e7fa79e3282039a705acbcc7bd07057a88b1e65852707934f10a67710ebefaa865201dfa6d4ff
+K = dac00c462bc85bf39c31b5e01df33e2ec1569e6efcb334bf18f0951992ac6160
+R = 6e7ff8ec7a5c48e0877224a9fa8481283de45fcbee23b4c252b0c622442c26ad
+S = 3dfac320b9c873318117da6bd856000a392b815659e5aa2a6a1852ccb2501df3
+
+Curve = P-384
+Private = 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727
+X = 00ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d
+Y = 0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3e
+Digest = 5e3b235f5a8037f7556331ed6e9b503fd9f4d6e7d5851d8716780e00
+K = e2f0ce83c5bbef3a6eccd1744f893bb52952475d2531a2854a88ff0aa9b12c65961e2e517fb334ef40e0c0d7a31ed5f5
+R = c36e5f0d3de71411e6e519f63e0f56cff432330a04fefef2993fdb56343e49f2f7db5fcab7728acc1e33d4692553c02e
+S = 0d4064399d58cd771ab9420d438757f5936c3808e97081e457bc862a0c905295dca60ee94f4537591c6c7d217453909b
+
+Curve = P-384
+Private = 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246
+X = de92ff09af2950854a70f2178d2ed50cc7042a7188301a1ea81d9629ad3c29795cb7f0d56630a401e4d6e5bed0068d1e
+Y = 6135adbd8624130735e64e65ecbd43770dcc12b28e737b5ed033666f34c918eb5589508e4a13b9243374a118a628dd0b
+Digest = 871afe65a30654d09a9bd33767cb4c581a8c5a534c9cdc5801821e89
+K = f3922351d14f1e5af84faab12fe57ded30f185afe5547aeb3061104740ecc42a8df0c27f3877b4d855642b78938c4e05
+R = 38e181870cb797c1f4e6598cfd032add1cb60447d33473038d06df73919f844eddd16f40f911075f8a4bacc0d924e684
+S = a58dd1ca18aa31277de66c30c3bb7a14b53705ce6c547ed2cb0e336f63c42809422efffcc722d1155f2254330a02b278
+
+Curve = P-384
+Private = 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83
+X = 3db95ded500b2506b627270bac75688dd7d44f47029adeff99397ab4b6329a38dbb278a0fc58fe4914e6ae31721a6875
+Y = 049288341553a9ac3dc2d9e18e7a92c43dd3c25ca866f0cb4c68127bef6b0e4ba85713d27d45c7d0dc57e5782a6bf733
+Digest = 31113fbe2375b059be766f538b09bf18ca8ec6c38442847e809fe25a
+K = 04324bd078807f6b18507a93ee60da02031717217ee5ce569750737be912be72da087ac00f50e13fdf7249a6ae33f73e
+R = b2752aa7abc1e5a29421c9c76620bcc3049ecc97e6bc39fcca126f505a9a1bfae3bde89fb751a1aa7b66fa8db3891ef0
+S = f1c69e6d818ca7ae3a477049b46420cebd910c0a9a477fd1a67a38d628d6edaac123aebfca67c53a5c80fe454dba7a9d
+
+Curve = P-384
+Private = dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659
+X = c2aa0a695125279705917e02a4f258cade4c3ff9140a071414babf87764f426f7f36ffda9d5f3394375d24864235476f
+Y = 8f9808da0ce0227cf453f9e456f557db9752e23b45cce4baad5fee3844ddd7e1112bcec01ea9d67c7a76f3535bd0cb58
+Digest = 279d65e738a347fd9aa6890e497077ad9e90043868bdcb5ab09e90cd
+K = 65a0305854033cbc6fe3ca139c40ca354d45801ecb59f4a923c251dc6b25d12d452d99b5d6711fdb5efac812aa464cc4
+R = c7fc32997d17ac79baf5789e4503f5f1a8863872bc350a91f12dd3ef8cf78c254e829217809e8e00b6b8d4d85be3f1fd
+S = 1422e1838a22496df93486bce1142961dbd8478ae844b8dda54e210afdae0d9e930d587c91bb600b0bde7237186d94e6
+
+Curve = P-384
+Private = df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718
+X = 76bd4be5d520471162cb5c36f80038301b325f845d9642204a84d78b3e721098932827bf872bde0a9f86383953667d29
+Y = 415116b8b878f896a5aa4dbbdc21076f27135d8bbcaaca02489ef639d742bd63f377da0c8e8ab36ff19b4a7cc5d4ceb4
+Digest = 21cd3764d8b28d8c70eea318bba06a8cc2b359e59a0782d7f1c659a2
+K = 798abad5a30d1805794540057388ee05e2422901c6335f985b9d4447b3ef75524751abfeab6409ad6bf77d4ae3014558
+R = 98744e5c6742fa5118a74a70db4957647a3cc12add4e876b45974a6a8707809f871daadbfc0b865e01624f706b65f10c
+S = 9e256e8da8eff5a0c83baaa1ef4f7be798eba9543bf97adb0fff8719f5406ea1207a0cf703d99aa8f02169724b492273
+
+Curve = P-384
+Private = ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f
+X = cf4717c5f5de668b785f06bdc9845df5a09e4edd83f4669756407cbb60807305c632bc49f818f4a84b194369aa07736f
+Y = 7391e4982af8a2218f704f627d01f0508bfc8304992a2d598a420bf2eb519f33bd7caf79380793733b3dba0cc5e2b9d8
+Digest = dae4b61e1cbc5c2846b3b698656ca1acbd262a0fbe492f810fac6b39
+K = 7b9606b3df7b2a340dbc68d9754de0734e1faeb5a0135578a97628d948702235c60b20c8002c8fcf906783e1b389e754
+R = 0d680010bed373287f9767955b5d2850e150b6713b49e453eb280148e45230c853d99ea2d2f8fcbd3ddcba19aeec0af1
+S = 64329763a930ab5452afdb0557fef16ff71810d6343dfc9c6ae18905c3d274db6554cdc69d6078a1ca03284474a94f30
+
+Curve = P-384
+Private = 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829
+X = 40e1fe21df34bb85a642a0abe819ebd128f7e39b84d8dcc4a9a599b372fb9588da1484600ec28b1297bb685f9ae77831
+Y = f3aa69ada57879fdcbe8df19cefabc308add7d03b17b1fac2f7783fece6a8dfe20bc36f518692677d96e3f730a67a671
+Digest = 1e7ca1523ce2b48143a9665843b602d617441d1b43142631de2088cf
+K = 8eda401d98f5688c34d8dbebcd3991c87c0442b0379154eaa2e5287dabe9a9e34cfc1305d11ff68781df25d5611b331d
+R = ff2d772786e159448bba26afd8c3281941a4cb0c56fec6f5cccb4c292c4ee0f7af9bd39bbe2d88148732585e104fdb30
+S = 07a1d890770daa949a17797dca7af3e8163da981ec330c03d63d1a8312c152be6a718163205ffa08da7dcc163ba261f4
+
+Curve = P-384
+Private = 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1
+X = a143f277ab36a10b645ff6c58241ea67ffdc8acf12d60973068390f06b4d8f4d773b10c1ebf6889b1cfa73ebb90f6ca1
+Y = 7a17cad29bb507b309021f6f92cb5c10ba535f4a3e317fcc68cfd02d3ccd269f465169c73d30ff308f5350d881b08aec
+Digest = 505dff744fd26f08990ef6c68e80b5c1f1bfb328203a8a6efd444e02
+K = dbe545f920bc3d704c43d834bab21e40df12ec9e16a619a3e6b3f08760c26aae6e4fd91fad00f745194794b74bb1baee
+R = cdc39b12bba30da66fe9554713c05880ddc27afa4d2d151440f124c351fb9496dc95046516b0921083347d64369846ac
+S = 797d0344e49f9ba87a187c50f664e5015d449e346b1a7bd9427c5be559fc58173651880d5aadf053f81899d3368d6181
+
+Curve = P-384
+Private = e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d
+X = ce9a2185a68d6094aa5849a6efe78b349946f7380f0c79aa9664246cfcc71a879e90ad78a0474f58644c6a208168150e
+Y = 8354fa47673cb3e07d446521345706c5515584b2602f921c3b9c44dded9e2c3f90ce47adb36d7e5f9f95a8c5ad8af397
+Digest = b972526301f2c5d689205193c9fc73fb0cddc24ed6ff32e7b5fd6f6e
+K = 1e77367ac4e10924854d135ad2f2507f39e2bafdbce33ff256bcbe9a7329b8d27185218bcc3550aafbe3390e84c77292
+R = df3182d49ad70959fb0c95bc7312750ce70fc87f1a328d39d9b29ac05d31305ce7209d6c24d13225d9567b489f7a187b
+S = d812b05abab0e96de13291e1f0da6479444ed5cd9d959b76f6cb43d394769035364f7c831a104dc7b5bd9b4a8e64df64
+
+Curve = P-384
+Private = 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead
+X = f692578c6f77531210aef55c9e004ce3b66cf268c6900dde31a8bbb76e7562e3fb76242de34ca330d2501030aa119466
+Y = 40965833b28de926c46de060aa25beaeda98f8415a6b1e3564aa77870cf4c89bd4fde92c8f5d9bf0eb41721586859d8e
+Digest = 0659e2e64a794837b070ce3a664836d0157880e496f1e9b8c51fc7e0
+K = 11b9b36720abcac084efdb44c9f5b7d039e3250cb1e9c47850189ba3cfc1489d858b2a44df357772b61d919c7e729c0f
+R = 02b252c99820cf50e6ce060ab55bd4f682276e29b4ae4197417432e6a7bfb8cf0bac89dfe105456af805d822cee77696
+S = 8e248bbf7d7028d63177e565c9d1666ee5be4d1ffbfffc9c7814b0cd38f74b98f3f2cd59be42b9f132bfe5ee789cd96c
+
+Curve = P-384
+Private = 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0
+X = 0edcde3533ea019e18f1a3cd97b7962e8823dda36c389f8f9287549f796d11376392b8a01c7a80f127a8f75795e04f54
+Y = 63d7c458dccfc02f5148d755d59f9bbc8e3c3ea34908777928440747795955741296abcdd5386676419ed8049fedb489
+Digest = 6a29c05caf892d0b0d339eea5c58ec54f59a66da25051bfc01fef680
+K = 3ad308faf04c42ee5ac69d36bc0aa9a96aacf55ea0f27dac4f52e088f023d206340a6324874ffad169ff80624de24c96
+R = 209b72f9aae72c4339813573c3a8408a9e0be641ca863d81d9d14c48d0bf4cd44a1a7985cff07b5d68f3f9478475645b
+S = f6292e599b22a76eda95393cf59f4745fa6c472effd1f781879ad9a4437a98080b0b07dadad0c249631c682d2836a977
+
+Curve = P-384
+Private = f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1
+X = a40c64f595491ce15790a5a87fbe64c1800247b42acd08fe5257700719f46afc8acce0e4ede0517a312092d5e3d089cd
+Y = d565df9dc2f381cc0c5d84f382a43a98018524c0b4708a44b3e2817f9719f29fbf9c15803591ed9b4790c5adaba9f433
+Digest = 3978516bf80bf5bcd4acd93497d3f56d699f089207b1715b9733421b
+K = 812dcaa6d4f9a43ccc553288065d13761581485aa903a500a690ccafbd330ba4818c977b98c4bb57f8a182a1afacfae9
+R = d000f18d3e4c162ff0d16f662e6703e7a6f5bff7a333ed266fa4f44c752415946c34945c342c20f739677186b1d80ab3
+S = ae7f1271c89e0aaa238710d039ea73a69110cc28fcf426f2fe6754b63a59e417fa84f903cf7dccb5468b43ff083bbfd5
+
+Curve = P-384
+Private = 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb
+X = 13ddec844731b7e30c467451df08ca11d6c581cb64abd8a257671cffd26f5ccad4df7b9ee8924047a88a5d2d7567609c
+Y = d74ca94f590fd1d13e190cc1e03c3da6c3faab15c7dda034af3deefee8aeec3628fa8b1978c54cfcd071baa319a46ec0
+Digest = 6833365d547d47628755680dbe3a946feca5bb0a07929d88ca894923
+K = 2a9dd520207c40a379cd4036adef9ee60fa8bc8c0d39b3ad91850ac93fd543f218b1688581f23481a090b0e4c73792ac
+R = 94e08cca20fe3866f643f53ec65faf3f2b4d80cd9bcc8ff8f88bb28da9eada324fc2d048908dd3d08a9e0ebb547731bc
+S = 8e6f82c4d3069b14f4c844b4ca133a9503493265c9f77a7d4775eda67de76798a23dd7ea48e0ac3c337dd62bf058319d
+
+Curve = P-384
+Private = 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6
+X = 8d2721370df8f097d5a69396249a315f6037dc7045b3da11eacae6d43036f779d5de7053d101768b42cc2b1283a3aaea
+Y = a046039ae662141f9954d278183eaa2e03917fe58583e32d344074d59d60caa5b0949c53066525d5cca923e2f201502e
+Digest = b3b149ce5ceb3df24bcc080484fea7170b5a91e3c36dfb86a5ccb6f8
+K = d1b25ad25581cad17e96f1d302251681fee5b2efbb71c3c15ff035b2145d015d18e0e52dc3187ab5a560277b3a3929b0
+R = d836f52b14c7391744868daa2d5cf27eb9380b9b6176195573d5b04842e9f2fc3794d6cf877feafee63d11b05f6a6bee
+S = 8b89042fef2c04d4bd6c9d66a06a010514321d623a5f8d57ba5ac3686872eaabca9e0ba2d058ae7028e870acf03ca32d
+
+Curve = P-384
+Private = cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd
+X = 3a65b26c08102b44838f8c2327ea080daf1e4fc45bb279ce03af13a2f9575f0fff9e2e4423a58594ce95d1e710b590ce
+Y = fe9dcbcb2ec6e8bd8ed3af3ff0aa619e900cc8bab3f50f6e5f79fac09164fb6a2077cc4f1fed3e9ec6899e91db329bf3
+Digest = 0baa03848341fbe4df9caa8b4d52a47a174cf485659ea7044b9265f3
+K = df31908c9289d1fe25e055df199591b23e266433ab8657cc82cb3bca96b88720e229f8dfd42d8b78af7db69342430bca
+R = 6770eea9369d6718e60dd0b91aee845ff7ed7e0fcc91675f56d32e5227fd3a4612bbcb1556fe94a989b9e3bcc25bb20e
+S = c43072f706c98126d06a82b04251e3ecb0ba66c4bb6cd7c025919b9cc6019cdc635256d2a7fa017b806b1e88649d2c0d
+
+Curve = P-384
+Private = c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b
+X = 0400193b21f07cd059826e9453d3e96dd145041c97d49ff6b7047f86bb0b0439e909274cb9c282bfab88674c0765bc75
+Y = f70d89c52acbc70468d2c5ae75c76d7f69b76af62dcf95e99eba5dd11adf8f42ec9a425b0c5ec98e2f234a926b82a147
+Digest = bbbd0a5f645d3fda10e288d172b299455f9dff00e0fbc2833e18cd017d7f3ed1
+K = c10b5c25c4683d0b7827d0d88697cdc0932496b5299b798c0dd1e7af6cc757ccb30fcd3d36ead4a804877e24f3a32443
+R = b11db00cdaf53286d4483f38cd02785948477ed7ebc2ad609054551da0ab0359978c61851788aa2ec3267946d440e878
+S = 16007873c5b0604ce68112a8fee973e8e2b6e3319c683a762ff5065a076512d7c98b27e74b7887671048ac027df8cbf2
+
+Curve = P-384
+Private = 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9
+X = b36418a3014074ec9bbcc6a4b2367a4fb464cca7ec0a324cb68670d5c5e03e7a7eb07da117c5ea50b665ab62bd02a491
+Y = 4ea299c30e7d76e2c5905babada2d3bb4ee5eb35a5a23605cdb0d5133471a53eb9e6758e49105a4eaf29d2267ba84ef2
+Digest = e4cb4f2f94793f4a471a1e1de49b2c6ceb5825c5d02c69a7fe122eebda7b28b9
+K = 935eeab3edeb281fbd4eead0d9c0babd4b10ff18a31663ee9de3bfa9ae8f9d266441158ea31c889ded9b3c592da77fd7
+R = 738f9cb28f3b991335ef17b62559255faf75cad370a222464a492e27bb173c7f16b22100ada6b695875c7e4b1a28f158
+S = bc998c30e1491cd5d60dc7d1c38333165efe036b2a78db9b8f0e85ee68619cfba654e11ae5ca5ee5a87099c27cf22442
+
+Curve = P-384
+Private = d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f
+X = c703835d723c85c643260379d8445b0c816fe9534351921e14a8e147fe140ec7b0c4d704f8dc66a232b2333b28f03dee
+Y = c5d0bb054053fd86c26f147c4966757aa04b00513a02d427b8d06c16055c607955efdc518d338abfe7927c195dc28588
+Digest = a22a3d3da784a68d37ae5aaca8ef28dc1ceefc8e530431e455dd2bb2ed969684
+K = c80f63e080650c8a21e4f63a62ec909adfb7d877f365d11ee1cb260baf112eb4730c161c1d99dba98fc0d5bbd00dc97d
+R = 81de2810cde421997013513951a3d537c51a013110d6dbb29251410bcb5ba001a9686b8490f1e581e282fd2ed0974b22
+S = 9cab0bbaffe91c7677ec3dd1f17060211a3cc0be574cbca064aa8c4b66ba6e64f3d80e83da895042ca32d311c388d950
+
+Curve = P-384
+Private = d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3
+X = 135a6542612f1468d8a4d01ff1914e532b1dd64d3627db9d403dc325651d3f82b0f6f0fd1dbdeca2be967c4fb3793b5f
+Y = cbbd40f6d3a38d0dfb64582ff4789d7b268241bc0c36de2884bccfaeeff3b7b2b46a30bb35719804e0d11124b4e7f480
+Digest = 1241e0219c19b1fe70919f4f5738edf7cdf4bd51905273b030c2f522abf11823
+K = 9da6de7c87c101b68db64fea40d97f8ad974ceb88224c6796c690cbf61b8bd8eede8470b3caf6e6106b66cf3f0eebd55
+R = 17840911ecdf6ae0428b2634f442163c2c11b8dbf0cc7a5596fbe4d33e3e52f9d99e99ad169867b1f39e89c9180cedc2
+S = dd7ed67e480866d0474379ea4afff72870746f4feef2153be42f13bf472b1613d7faa5c0abb7f7464070f94d7cf3f234
+
+Curve = P-384
+Private = 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93
+X = 01989ff07a7a452d8084937448be946bfedac4049cea34b3db6f7c91d07d69e926cce0af3d6e88855a28120cf3dba8df
+Y = eb064e029d7539d4b301aabafe8de8870162deffe6383bc63cc005add6ee1d5ced4a5761219c60cd58ad5b2a7c74aaa9
+Digest = e2e52fe49dd358e95fdaf1fc6f7f4bdc638ee8f65a410890eb290342ca53f6de
+K = c5d39b436d851d94691f5f4aa9ef447f7989d984f279ae8b091aef5449ac062bcc0567740f914624ad5b99fc32f9af0b
+R = 07d5b1b12877e8cb5e0aa5e71eeeb17bf0aa203064c7e98b3a1798a74dc9717252dc47c7f06aaf1d5fe15b868323bbb9
+S = 69428cf101a7af5d08161a9fd7af212e02e33b6062aebdce4c96bf3a0684b5394cb902ca7c2dec6e2f01f40c4576009d
+
+Curve = P-384
+Private = e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1
+X = 38bc42b8c9d8866d09b214398d584b1b24a488dfacc3420d1e9506aa825b19fdf1ba74e7b8f547f47b571467fe8c4d1f
+Y = 5179d62668d3f6a7ab5c8e3761a685e12008fb87d0529a97645f65cfb5364376c1b6682e0ffcddd0bcd995c41d013ad3
+Digest = 57f030024cde572f1e3368cf23aaa686e59d645455ef5f01e3b9c14067dd0eb3
+K = 05e9718aea9669c9e434f73866da5f252dec6d24c47a1c4ee3233450b6ec626de9746ebe095b285558dfc89fc1b622fe
+R = df9bab9dd1f22ec6f27116f38831cb2089aa78aa8c073024a0faddd9a48e810a5e8e2cadd80fbf8dbd6088c71fe30b5b
+S = 1e0e8718567d12d18558c57f9e87a755c309e4ffb497335a3adfc8d7475ce8fd882d5dc33a8f5a16274b7ad74bb7862a
+
+Curve = P-384
+Private = 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960
+X = 29909d143cf7ee9c74b11d52f1a8f3ebd4a720c135612ca5618d3f432f03a95602ee75a2057e1d7aab51d0648ac0b334
+Y = 404b6c5adffbadfa1b0380ae89fed96ec1ca16cc28661e623d0f1c8b130fbaa96dd7257eae2bf03c2d3dcbc3dbc82c58
+Digest = b3533ac348a241e255a62e7bc787a44394fd80328621f62f39df170298cc6a1b
+K = 7f623c103eaa9099a0462e55f80519c565adaeffcb57a29993f3a8a92e63a560be8f0fb9d23dc80bff1064bb41abad79
+R = 932ab291950c16b2b19a8036cd2e905714c6229cb190a73b3ea49c48dd8e76063a453c7c3267a57597d2973678216296
+S = d17d4c5ddbb9c27beebf526f113b416c8abfad53d11c4224813c7f351ba41a77dd4e77d6e4a65bef2c9f62cc37a469a5
+
+Curve = P-384
+Private = 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57
+X = 37dac42ef04663238443ef33e8addee2e78c40d50a1751913a7f5c37d1f23a26c7f86e16055c788b8ca9554f06b2f2ef
+Y = bbed1549652904e3d00c39b01cc0460dbaf3185e6190c2705677a9701de1fe56dff4f4d8418ee15059ff8fc36800982d
+Digest = 8f8009afc17d98d009d1bc84afb81d07e128c941e3312cf807223fc4f33ebb53
+K = b788ca82811b0d4e4841765c71eafaa1e575378beedcd3860d8b92db3d070ac5aef7c425067860fbee6c50cf0c642bbb
+R = 7292b3851870daeb2555a8a2fb198ead78739fcfb75327e5c32a82c6b77d58983e5ad548ccb75dcf9411039c9576d9b9
+S = a378c61802d9f1dd062b6e18f16416a954018f77df4df95ad1b983570377d5cfce4cc7861759e802c52f81abc4f49aac
+
+Curve = P-384
+Private = a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1
+X = ec8ae1fb9bb88589d27d6f27d790392853396f37bc0c381631d85800fc668eea0886bf1c6cff801147df19778d5b1604
+Y = 1e1a8336c1e2506f8ee388b55cc648ae73b9295ea78467979d2affb364536fad28120f51ec62a67cbb6ce7784780389f
+Digest = 9611180f5a8b0d8320759910bf653e92accbf1f968d40dec5d8e0350a989b09b
+K = 755d025509b73cf1ea8817beb772ad150b4c17a52378be187daffe3db0158921e5e552d1ca3c85df28519939f3cb794d
+R = 23ff2ffa62bbd427d49995d9c9950116e0d5a06ef076a4553448bc109e6482c5e87d4c833bc88de0bc722bc98cae2e61
+S = 9aea13d487c3ea6917e16374caafcf0321c12a80d28902dd8cd81909bb04b8c439e2491e504756742d0d0bfb15a9c34c
+
+Curve = P-384
+Private = 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3
+X = 13e9e2c8bbcfe26e8f5f43c86268c5980ee693236a6b8777f3a7323718baa21005b482d08aafc6fa6e3667d91353544c
+Y = 9ba181b3ee505be030f87ecd249b00670a791489b42af04976013483ff95b630c91c01e95757e906129f2f9b4ce719a8
+Digest = 45607fd85aa1a246e8910dd3164b7c62c23ae515a3b464128a69c78f172138cc
+K = 08aec9a9e58bdc028805eb5dc86073d05fff1f5fb3fd17f510fc08f9272d84ba7aa66b6f77d84fe6360bd538192bf01a
+R = 2b4337c3dfbc886ffad7858ae2480cb62227e12205a70361c42f1a5ca9e658ee30fc3cf4030d85bd065edad83b99821f
+S = 2550cef8574bf17fb3d6b0c9d04ab266962bac3621bac233ff2e4989712d2a4a07171c0aebd3040cd6a32c3bd3efb8b5
+
+Curve = P-384
+Private = 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907
+X = 6e14c17bb831b0112d7f3543c5fd17c78379a516c9e0539b03b8b4bfdead2820343fc84b0382807573ded6c4d97b7003
+Y = 7f60021d2de77546db666721c9aec84c3e2ba8de0ba77443600dc77e6839bbf9316271adb22d4cb47d08f745ecb1dafd
+Digest = 5a3b963da0a115759db0cee686ee34441e35ca3a3d5dd8ccb9d85b1f001ae63f
+K = 7ad6f4ffd2b429ba10c6f112f800cacf1ad508cf8eba880893bb9659c1ddaaec57dcdc093a114500460d457bdde324f2
+R = faea950ca513806bc59028c638d6302ffc86978c3ff1f06db015dd7c4777050186cb8dd871f5e926e1416539c1939c2f
+S = 2c592240eabb8a1f9878e1b5c9d5d3ced7b3a7ae571f5a86494ed2ca567a36eb72e7bea8934bded29594bccf67ca84bd
+
+Curve = P-384
+Private = 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245
+X = 92c9e32b20cbe6d4ed0727c6c942cf804a72031d6dfd69078b5e78ebce2d192268f1f5e2abce5aaf1f8d6a35f136837f
+Y = d5167905fa7689e03b9fb1487c566f62b36f2bc1c4a2bfb6a836113b5c8d46f7c1ca51b628b14397fbc06ec9a07f4849
+Digest = 3863fc5414aef6de36c69b2a38307f9b429fefb2fb029d7dbf80483950316a8d
+K = 258dd05919735cd48627c9fe9fac5c252604aa7c2ae0460d7c1149cd96b7bd2ba195ad393bf392a2499f06aead5ba050
+R = 413793bcce52eda0f5b675a8d687cce86d5c9e1659b38a89e96246b5e05f8b0934d17dbba3b2ea44c838aa5fd87125d1
+S = ce7309fc2d6e3438818a1a29a997410b025b0403de20795b97c86c46034a6b02afeed279aeb06522d4de941bfdf50469
+
+Curve = P-384
+Private = 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7
+X = e4216e1a20af8e8e3e74653ac016545001066e53e64af679ad1c85841bb475aed3e00ead052ae9955f48d675ff4ace56
+Y = 8804c17641be21d4c6386902c9c5c888af25d97ca383703ea4a85cf93bbab360c0bbd2993374da499a303778650270b9
+Digest = 9ef131664cee116ba88d3c362e694c2a56772c19f4356d9e576c96285bc52275
+K = 6b9507fd2844df0949f8b67b6fde986e50173713ac03df2edf65cb339859321cd3a2b9aab8356f95dec62460ab19c822
+R = 018891f6381ed358b422f79a299cf0789cee783ba388af4d82cbbe17f3709751b7fd9400e9702820c28b9afc62fdf489
+S = aef73bd590802b2fd2a65c4f7fec89f9b24ecc199a69254785925f334cd1977c5e1f858bd9830d7d7d243ea707b1af0b
+
+Curve = P-384
+Private = d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5
+X = 5f94223918f2ec9f0a08342cb99e724881c92453957c59672860f69daac01b660331a0f5845e50f1f27766b219c89e7e
+Y = d76d83396130d10d1168d76c7fc83742ffffbe66d9f4da4ca3f95f5ad6dac8cc7bb65d16d317d37aa99fdbf30ec7439c
+Digest = 2d0f59dc1c0698c75de8744e75c8bca110f125fc67bd75833c2b5aaf9d99da26
+K = 4ad5a92b5b8e170b71c8a7ed419dc624c7680004562b8d16a37b6e639f581ce81d5f0d98cce44d54c4e7136229148340
+R = f7baa6a5488ab462ea59aa31a36402b15880c68110b6069f51ede0c3b52a7b1e5bf926fdbe95768931b7d5f87058835c
+S = 28b1c4ef448a432f7c91b98b0c6471691e888211b6af907369a8930859b8cdb2e94f466a44f4e52f46df9b0d65e35de6
+
+Curve = P-384
+Private = b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224
+X = 166e6d96cb60d916fd19888a2dd945a3306ff0d7b0a5e30729f47d3dac3de2be3fd5cd7437e9a80d6c48cf960d2d36f8
+Y = e6b2b70f131092ae210f29cc6bad701318bddb31bddf921695855c6208941100d0cee5d10799f8b835afe3ea510e8229
+Digest = c92cd2d52c9bfbd5c1bc55c6894cbaeae5aef12bd76a4d39d63e526aaf25760f
+K = da706ab5f61531f2378b3c0a2b342108cd119eadaa88b859df64923bccfb0ec2393fd312826f65c15a6587d1d460015b
+R = d9124c42858080c62400e4d4d8136304e03d910cbe9b9b3487f4d27c7e0540a314d34bef8c850045c8746ca631c11c42
+S = bbf6424a3b70166fa799f49e918439d515327039258ef9bd88435a59c9c19659f8ec3c8660720b0c08354ff60e0f5a76
+
+Curve = P-384
+Private = 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97
+X = c2b47944fb5de342d03285880177ca5f7d0f2fcad7678cce4229d6e1932fcac11bfc3c3e97d942a3c56bf34123013dbf
+Y = 37257906a8223866eda0743c519616a76a758ae58aee81c5fd35fbf3a855b7754a36d4a0672df95d6c44a81cf7620c2d
+Digest = 31a452d6164d904bb5724c878280231eae705c29ce9d4bc7d58e020e1085f17eebcc1a38f0ed0bf2b344d81fbd896825
+K = dcedabf85978e090f733c6e16646fa34df9ded6e5ce28c6676a00f58a25283db8885e16ce5bf97f917c81e1f25c9c771
+R = 50835a9251bad008106177ef004b091a1e4235cd0da84fff54542b0ed755c1d6f251609d14ecf18f9e1ddfe69b946e32
+S = 0475f3d30c6463b646e8d3bf2455830314611cbde404be518b14464fdb195fdcc92eb222e61f426a4a592c00a6a89721
+
+Curve = P-384
+Private = 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528
+X = 5d42d6301c54a438f65970bae2a098cbc567e98840006e356221966c86d82e8eca515bca850eaa3cd41f175f03a0cbfd
+Y = 4aef5a0ceece95d382bd70ab5ce1cb77408bae42b51a08816d5e5e1d3da8c18fcc95564a752730b0aabea983ccea4e2e
+Digest = a92784916a40feaebfeab16ea28c0c65e45c5e81eb634052944865708072e20110bd669a9838d7e722e94ac75245cdd3
+K = 67ba379366049008593eac124f59ab017358892ee0c063d38f3758bb849fd25d867c3561563cac1532a323b228dc0890
+R = fb318f4cb1276282bb43f733a7fb7c567ce94f4d02924fc758635ab2d1107108bf159b85db080cdc3b30fbb5400016f3
+S = 588e3d7af5da03eae255ecb1813100d95edc243476b724b22db8e85377660d7645ddc1c2c2ee4eaea8b683dbe22f86ca
+
+Curve = P-384
+Private = b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6
+X = 44ffb2a3a95e12d87c72b5ea0a8a7cb89f56b3bd46342b2303608d7216301c21b5d2921d80b6628dc512ccb84e2fc278
+Y = e4c1002f1828abaec768cadcb7cf42fbf93b1709ccae6df5b134c41fae2b9a188bfbe1eccff0bd348517d7227f2071a6
+Digest = b2acf6b4ae1ba9985c1e657313d59157939c21868302f6f5c5dbf037867035ae7c2009bad9fce472579923f7b4b87795
+K = 229e67638f712f57bea4c2b02279d5ccad1e7c9e201c77f6f01aeb81ea90e62b44b2d2107fd66d35e56608fff65e28e4
+R = b11db592e4ebc75b6472b879b1d8ce57452c615aef20f67a280f8bca9b11a30ad4ac9d69541258c7dd5d0b4ab8dd7d49
+S = 4eb51db8004e46d438359abf060a9444616cb46b4f99c9a05b53ba6df02e914c9c0b6cc3a9791d804d2e4c0984dab1cc
+
+Curve = P-384
+Private = de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976
+X = f1fabafc01fec7e96d982528d9ef3a2a18b7fe8ae0fa0673977341c7ae4ae8d8d3d67420343d013a984f5f61da29ae38
+Y = 1a31cf902c46343d01b2ebb614bc789c313b5f91f9302ad9418e9c797563e2fa3d44500f47b4e26ad8fdec1a816d1dcf
+Digest = ec21c9d03a7270ea9ce7e9ff83211bac2fb104d078217c370248a3aba81f6c586852f19ced56dc71f83f5251d7381c8a
+K = fc5940e661542436f9265c34bce407eff6364bd471aa79b90c906d923e15c9ed96eea4e86f3238ea86161d13b7d9359d
+R = c2fbdd6a56789024082173725d797ef9fd6accb6ae664b7260f9e83cb8ab2490428c8b9c52e153612295432fec4d59cd
+S = 8056c5bb57f41f73082888b234fcda320a33250b5da012ba1fdb4924355ae679012d81d2c08fc0f8634c708a4833232f
+
+Curve = P-384
+Private = 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc
+X = 1950166989164cbfd97968c7e8adb6fbca1873ebef811ea259eb48b7d584627f0e6d6c64defe23cbc95236505a252aa1
+Y = 41ef424b5cb076d4e32accd9250ea75fcf4ffd81814040c050d58c0a29b06be11edf67c911b403e418b7277417e52906
+Digest = f0272d0a51ee61f86d0875ca7800e12744ef6ffbac72bdda7c54ba24e5a5a6bd69ebe6f429cc20ac12b926d392efc4ce
+K = e56904028226eb04f8d071e3f9cefec91075a81ca0fa87b44cae148fe1ce9827b5d1910db2336d0eb9813ddba3e4d7b5
+R = c38ef30f55624e8935680c29f8c24824877cf48ffc0ef015e62de1068893353030d1193bf9d34237d7ce6ba92c98b0fe
+S = 651b8c3d5c9d5b936d300802a06d82ad54f7b1ba4327b2f031c0c5b0cb215ad4354edc7f932d934e877dfa1cf51b13fe
+
+Curve = P-384
+Private = 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2
+X = 2e01c5b59e619e00b79060a1e8ef695472e23bf9a511fc3d5ed77a334a242557098e40972713732c5291c97adf9cf2cf
+Y = 563e3fe4ad807e803b9e961b08da4dde4cea8925649da0d93221ce4cdceabc6a1db7612180a8c6bef3579c65539b97e9
+Digest = e114c6204bee5bf0bbdf9ffc139bb99f09e7ea2186da3ee1e011dd059185d57c4953a130d34ff0df3fc6782dda199ee8
+K = 03d23f1277b949cb6380211ad9d338e6f76c3eedac95989b91d0243cfb734a54b19bca45a5d13d6a4b9f815d919eea77
+R = abab65308f0b79c4f3a9ff28dd490acb0c320434094cef93e75adfe17e5820dc1f77544cfaaacdc8cf9ac8b38e174bef
+S = 11b783d879a6de054b316af7d56e526c3dce96c85289122e3ad927cfa77bfc50b4a96c97f85b1b8221be2df083ff58fb
+
+Curve = P-384
+Private = ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1
+X = 51c78c979452edd53b563f63eb3e854a5b23e87f1b2103942b65f77d024471f75c8ce1cc0dfef83292b368112aa5126e
+Y = 313e6aaf09caa3ba30f13072b2134878f14a4a01ee86326cccbff3d079b4df097dc57985e8c8c834a10cb9d766169366
+Digest = f11e38f4037ae3ffd0fde97c08e2e5acbc26e3ac5828a86c182232be90ef6fc0f5d21a9b1a7b93472d78c103b4136019
+K = c3de91dbe4f777698773da70dd610ef1a7efe4dc00d734399c7dd100728006a502822a5a7ff9129ffd8adf6c1fc1211a
+R = f4f477855819ad8b1763f53691b76afbc4a31a638b1e08c293f9bcd55decf797f9913ca128d4b45b2e2ea3e82c6cf565
+S = 7c26be29569ef95480a6d0c1af49dc10a51a0a8931345e48c0c39498bfb94d62962980b56143a7b41a2fddc8794c1b7f
+
+Curve = P-384
+Private = adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6
+X = ef948daae68242330a7358ef73f23b56c07e37126266db3fa6eea233a04a9b3e4915233dd6754427cd4b71b75854077d
+Y = 009453ef1828eaff9e17c856d4fc1895ab60051312c3e1db1e3766566438b2990cbf9945c2545619e3e0145bc6a79004
+Digest = f8d0170479b2d1a8f50c80556e67ff345592c8b7dcda4e4f6099f993c1a71bff6d3b60190715ae1215a8a759a8eb13df
+K = a2da3fae2e6da3cf11b49861afb34fba357fea89f54b35ce5ed7434ae09103fe53e2be75b93fc579fedf919f6d5e407e
+R = dda994b9c428b57e9f8bbaebba0d682e3aac6ed828e3a1e99a7fc4c804bff8df151137f539c7389d80e23d9f3ee497bf
+S = a0d6b10ceffd0e1b29cf784476f9173ba6ecd2cfc7929725f2d6e24e0db5a4721683640eaa2bbe151fb57560f9ce594b
+
+Curve = P-384
+Private = 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d
+X = 5709ec4305a9c3271c304face6c148142490b827a73a4c17affcfd01fffd7eaa65d2fdedfa2419fc64ed910823513faf
+Y = b083cda1cf3be6371b6c06e729ea6299213428db57119347247ec1fcd44204386cc0bca3f452d9d864b39efbfc89d6b2
+Digest = 86bc7536faf2de20028159ce93e293d0a7f5721fb6680b5b070c3f70aba845de2eaed9245144babc38c49cce59f3eac7
+K = 3c90cc7b6984056f570542a51cbe497ce4c11aeae8fc35e8fd6a0d9adeb650e8644f9d1d5e4341b5adc81e27f284c08f
+R = d13646895afb1bfd1953551bb922809c95ad65d6abe94eb3719c899aa1f6dba6b01222c7f283900fe98628b7597b6ea6
+S = 4a9a38afda04c0a6b0058943b679bd02205b14d0f3d49b8f31aac289129780cdb1c555def8c3f9106b478729e0c7efaa
+
+Curve = P-384
+Private = e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7
+X = 06c037a0cbf43fdf335dff33de06d34348405353f9fdf2ce1361efba30fb204aea9dbd2e30da0a10fd2d876188371be6
+Y = 360d38f3940e34679204b98fbf70b8a4d97f25443e46d0807ab634ed5891ad864dd7703557aa933cd380e26eea662a43
+Digest = 1128c8b09573a993adaa0a68f3ca965db30870db46de70d29e3b9a7d110ba0cd57633f1713173c62331b36fb925fa874
+K = 32386b2593c85e877b70e5e5495936f65dc49553caef1aa6cc14d9cd370c442a0ccfab4c0da9ec311b67913b1b575a9d
+R = 5886078d3495767e330c7507b7ca0fa07a50e59912a416d89f0ab1aa4e88153d6eaf00882d1b4aa64153153352d853b5
+S = 2cc10023bf1bf8ccfd14b06b82cc2114449a352389c8ff9f6f78cdc4e32bde69f3869da0e17f691b329682ae7a36e1aa
+
+Curve = P-384
+Private = d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca
+X = 49a1c631f31cf5c45b2676b1f130cbf9be683d0a50dffae0d147c1e9913ab1090c6529a84f47ddc7cf025921b771355a
+Y = 1e207eece62f2bcc6bdabc1113158145170be97469a2904eaaa93aad85b86a19719207f3e423051f5b9cbbe2754eefcb
+Digest = ab9a6d22c8d7675bc8e99e3cafed8318f33051ba5398ce0e9d8e8d3d537a6a908d4c2ace3e6d8204d0236d863eee3c28
+K = 78613c570c8d33b7dd1bd1561d87e36282e8cf4843e7c344a2b2bb6a0da94756d670eeaffe434f7ae7c780f7cf05ca08
+R = 66f92b39aa3f4aeb9e2dc03ac3855406fa3ebbab0a6c88a78d7a03482f0c9868d7b78bc081ede0947c7f37bf193074ba
+S = e5c64ed98d7f3701193f25dd237d59c91c0da6e26215e0889d82e6d3e416693f8d58843cf30ab10ab8d0edd9170b53ad
+
+Curve = P-384
+Private = 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d
+X = 70a0f16b6c61172659b027ed19b18fd8f57bd28dc0501f207bd6b0bb065b5671cf3dd1ed13d388dcf6ccc766597aa604
+Y = 4f845bf01c3c3f6126a7368c3454f51425801ee0b72e63fb6799b4420bfdebe3e37c7246db627cc82c09654979c700bb
+Digest = 68f858243fe465eb91dc2481333cbb1958883ef25099d45cf02721d17d2846d2cec4689884ae7c0412332e035a1fa3fc
+K = 28096ababe29a075fbdf894709a20d0fdedb01ed3eeacb642a33a0da6aed726e13caf6cf206792ec359f0c9f9b567552
+R = ee2923f9b9999ea05b5e57f505bed5c6ba0420def42c6fa90eef7a6ef770786525546de27cdeb2f8586f8f29fb4ee67c
+S = 50ef923fb217c4cf65a48b94412fda430fac685f0da7bd574557c6c50f5b22e0c8354d99f2c2f2c2691f252f93c7d84a
+
+Curve = P-384
+Private = 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368
+X = cadbacef4406099316db2ce3206adc636c2bb0a835847ed7941efb02862472f3150338f13f4860d47f39b7e098f0a390
+Y = 752ad0f22c9c264336cde11bbc95d1816ed4d1b1500db6b8dce259a42832e613c31178c2c7995206a62e201ba108f570
+Digest = dca5ebfebeac1696eff4a89162469c6937b80f8f8cf17299856de2e13d8f8a199bff3085cee59366886164bcc03f7e90
+K = 7b69c5d5b4d05c9950dc94c27d58403b4c52c004b80a80418ad3a89aabc5d34f21926729e76afd280cc8ee88c9805a2a
+R = db054addb6161ee49c6ce2e4d646d7670754747b6737ca8516e9d1e87859937c3ef9b1d2663e10d7e4bd00ec85b7a97a
+S = fcc504e0f00ef29587e4bc22faada4db30e2cb1ac552680a65785ae87beb666c792513f2be7a3180fc544296841a0e27
+
+Curve = P-384
+Private = ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283
+X = 33093a0568757e8b58df5b72ea5fe5bf26e6f7aeb541b4c6a8c189c93721749bcaceccf2982a2f0702586a9f812fc66f
+Y = ebe320d09e1f0662189d50b85a20403b821ac0d000afdbf66a0a33f304726c69e354d81c50b94ba3a5250efc31319cd1
+Digest = f9b152150f7dc99d5262c9da04dde148009730fb2af9ac753b9c64488d27c817f68c17ae1ff61e50ebb6749230c59a71
+K = d9b4cd1bdfa83e608289634dbfcee643f07315baf743fc91922880b55a2feda3b38ddf6040d3ba10985cd1285fc690d5
+R = 009c74063e206a4259b53decff5445683a03f44fa67252b76bd3581081c714f882f882df915e97dbeab061fa8b3cc4e7
+S = d40e09d3468b46699948007e8f59845766dbf694b9c62066890dd055c0cb9a0caf0aa611fb9f466ad0bbb00dbe29d7eb
+
+Curve = P-384
+Private = e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb
+X = a39ac353ca787982c577aff1e8601ce192aa90fd0de4c0ed627f66a8b6f02ae51315543f72ffc1c48a7269b25e7c289a
+Y = 9064a507b66b340b6e0e0d5ffaa67dd20e6dafc0ea6a6faee1635177af256f9108a22e9edf736ab4ae8e96dc207b1fa9
+Digest = 14f785ebb5a3b1bdff516a6b580e245b3c81aff37e1035e354b084a6691e973e0de30bb2a0490fca2d757f8191d7560a
+K = b094cb3a5c1440cfab9dc56d0ec2eff00f2110dea203654c70757254aa5912a7e73972e607459b1f4861e0b08a5cc763
+R = ee82c0f90501136eb0dc0e459ad17bf3be1b1c8b8d05c60068a9306a346326ff7344776a95f1f7e2e2cf9477130e735c
+S = af10b90f203af23b7500e070536e64629ba19245d6ef39aab57fcdb1b73c4c6bf7070c6263544633d3d358c12a178138
+
+Curve = P-384
+Private = 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c
+X = fb937e4a303617b71b6c1a25f2ac786087328a3e26bdef55e52d46ab5e69e5411bf9fc55f5df9994d2bf82e8f39a153e
+Y = a97d9075e92fa5bfe67e6ec18e21cc4d11fde59a68aef72c0e46a28f31a9d60385f41f39da468f4e6c3d3fbac9046765
+Digest = f863cf3749ae5256da0ceb2e6d391fcce939b1490b024527687b1a2908da35c48b44255d82956c76d70672c41c6456d78c57342e932490083f73016b560a0245
+K = 90338a7f6ffce541366ca2987c3b3ca527992d1efcf1dd2723fbd241a24cff19990f2af5fd6419ed2104b4a59b5ae631
+R = c269d9c4619aafdf5f4b3100211dddb14693abe25551e04f9499c91152a296d7449c08b36f87d1e16e8e15fee4a7f5c8
+S = 77ffed5c61665152d52161dc13ac3fbae5786928a3d736f42d34a9e4d6d4a70a02d5af90fa37a23a318902ae2656c071
+
+Curve = P-384
+Private = 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f
+X = 832cbb7061a719a316e73dbad348fa67cd17c33f40b9000a3d3b691a2a2cd821052566717c3ead01089b56086af1366f
+Y = 1e15a048d1dce642d9ebcbfac7f92b1bcee90fd0240cc79abd29e32e0e655c4ee1fd34fb88178bba92aca100e7794ed0
+Digest = 68944ca920620e1d42184d264c4ffe295882f00079f9daaaa0efc305fe10cc7bbc667985c148eacb51ee1c05a6d8a861e98371a045e11e18e200ad52d5b4cb13
+K = 2a78e651623ba604c42cf094fc7d046629306f508853427ba091448800d1092c041bb2323035fc9d19a8d44950f7dcc3
+R = 0db0cc9a2bda8dd7e565ad36f91b1c5756d78164dc8a72a5bee4b6bc45ea38c7a16b01d05b1893d4e06b62db24c30385
+S = abd383edaeda7d0b8de1b54fcd3c28874fed62ab266f1f84c8ba796a7b54e5e0695fdb43ce7fe90ed00fa468d87bca64
+
+Curve = P-384
+Private = 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7
+X = a2b24a5ad4a2e91f12199ed7699e3f297e27bf8b8ea8fbe7ed28366f3544cd8e680c238450f8a6422b40829d6647b25c
+Y = 2732be0075536e6519f6a099b975a40f8e0de337fa4d48bd0762b43f41cab8deafdef9cfbb9973e457801e3bf9c93304
+Digest = 8876ecd423fd0e903364fac777897b80b31c03f0f1ef1678372a6cb240ab701e49b51b798fd8e588ab39db7d3c77879901916babdd0ef0632cc16d5ccb9d1535
+K = b10b6258afdde81f9c971cc1526d942e20cafac02f59fee10f98e99b8674636bff1d84a6eaa49c0de8d8cfdc90d8ce84
+R = be428a8de89a364a134719141ee8d776a3a8338f1132b07e01b28573d8eaf3b9008b63304c48821e53638b6141f9660b
+S = 866181dbef5c147d391bed6adcee408c339982c307adc718c2b9ab9e5642d8dedc36dd6402559a3ab614c99c1e56b529
+
+Curve = P-384
+Private = 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf
+X = 11acb1b5cc59a4f1df1913a8d6e91cbdafb8206dc44aff7d9da45906b664fc33194d9935a82aa4d62f39618897c86025
+Y = 832ed0b9575fff52a3603bfe89f312751b4c396da98324117a61b3f525d27b2266f6cfb22be07e50b6874435e380ed62
+Digest = 2a1a866fe1596c484c38ef78bdda2e9783dd9f8df86e93e56f86cfb467e9f457d27e02d36e0c23d63401d82765e5e1a8065ad8f3a67bb0db356a6a1c5a63df27
+K = 2513075e02cc7fb3cff7b7adde46da31c5493749b5cf02758bd5b098a838bfd4d5e4c7fb8268bdc37e219c30efebe878
+R = b3d638b3be45f14f170da5bdc22d2114deac93ab340a25b3af2b5c18584bb9147e00dc6c67a2274f79aa4838793eb63f
+S = 876112bdca2c725eb2f6dbd76d07710a31f0c16d38430cb0817f320a25a9ecfec8a66137d0304612ae29a6a484fd3319
+
+Curve = P-384
+Private = 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b
+X = 722d0ea6891d509b18b85ca56f74deb5c3030d2a30433824123d430d03c99279572c3b28ecf01e747b9db8acc55d0ba3
+Y = 7e2605ea7092214f366f3639037bffd89fe103c646e990839d3a1ced8d78edb5b9bc60d834fd8e2a3c17e920bdae023a
+Digest = 96768f5d5edae35aaabf1e32158525b0cfb28a74059a48e053208e4a655f51a8fabb63e3a7e7c70be9945b1954f9bc48247d9f19c98328b8d65030d37a71b84b
+K = c8c18e53a9aa5915288c33132bd09323638f7995cd89162073984ed84e72e07a37e18c4c023933eace92c35d10e6b1b6
+R = 6512a8a2be731e301dcf4803764297862bbfa0ac8daed64d8e98b34618ecb20520fc5d3cf890b7783edf86e7ea407541
+S = 4ff10301f7b4168fae066361376007c1d7aa89a75c87719d0b54711ffef5ef3726f3eef84f7ebc025c110bde511b17f6
+
+Curve = P-384
+Private = 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69
+X = b4f100558043858efa728082d9b99ad5192b59b0947434f5ba7ff2514508a6d71ba54e7221c31cb0712103272b3f6fa4
+Y = 34f6df4eeb2da11498044635067c2715ed15ae251c78ffb9030d87909ea8539b66394e93109ca54c0406cf99960c3e93
+Digest = c2a0f9cd8fe7d7a951f19d373ad97dc7f95219cd2b8498552a3352f1a4b0e4ee25c7a7a51b1e47b66640c320e503a53dc76af6c08141c8936ec8cbdc038cb7a8
+K = 84a87137edb6894f96c5a8e94a3765162034feb84dfea94e1c71411170c285a80321ec7999e25861844143209804882c
+R = 4dc9d1b949b36e3c3847ac1c7ed114e1bc9cbe76119cf6fcd3f1b69ee6ee54e3255f1bb288fe2f8bd6d4049a21793c27
+S = 56a561d647b62ccae1e6df818b1a6fbde66c82ef0ff69ee415f183e7daf76be22630c7e02cd3fd729dfa490f26824584
+
+Curve = P-384
+Private = 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db
+X = 3c7682de540ab231daf21bf9fc80bda6abf7e17dcc79d476c7b7c3bd4d42d386877fd8ba495c1b0333e04fb5fd2a1505
+Y = 0a1582e4f4d72abea9d3476aff8369c41261f0c5dddf2ca82e10f7a163f73df09473d9e5e2552187104e4cc7c6d83611
+Digest = cc04e32af9b8c178039eb9b1cece8bd89079ea400e35bb912e5efec06eeb02f9a12905383acbb5551b949f225998169818e3e9e6bd2cb0c08e10895f022f3be8
+K = 2fa266f5cce190eb77614933ca6a55121ad8bae168ff7a9043d96d13b5ca2fe70101ff9fe1e2b2cd7413e6aa8f49abde
+R = e7ecda9da0c52d0474a9f70094dc8f061d7d6a22210d3b69a7be8f389aa666f256322099b87d16ad35357ea856574dba
+S = ba348eb40a2830ec5a1130264ac0a8675420b1ae243e808a778135809ece21f42c0c881166321102b4f02df4c5c7ed9d
+
+Curve = P-384
+Private = 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d
+X = ca43a306479bf8fb537d4b9ff9d635bbb2a0d60d9e854d5b7e269d09d91f78c6b90b616e4c931629453645a2bb371e14
+Y = 356c4d7f10e690614eaf7f82ba0f9dc1aad98130c0ad9fe353deec565cc04bef789a0a4242322e0058b46cd02f2de77d
+Digest = cf638b5ae7d04e6edc97be83aa2598afce555f9f85893208b7a5192ea84b08cbd10b54d0f5ee6e11e86a31252d766dfd927f724f276a52eb43c98fc16c4f7333
+K = 6ec81fb74f8725ba225f317264460ee300cfd2f02092000989acbdad4799cf55c244a65c557113328fe20282e6badb55
+R = cd7a4309bcebc25a8e10899fe2eda5f8b2dbcf329cd2f3d65befd67393e83fba2f8a67a15c01a6ac8314f9f5e87a9dca
+S = 6dcfc0426bc148e67e91d4784e3d7e9bc3b7ce3676be62daa7f3f55dfdff6d9dc735b5e3e0bbd0785db1f76f7ac065f3
+
+Curve = P-384
+Private = 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476
+X = e5a0463163964d984f5bad0072d45bc2059939e60a826ccca36c151460ae360f5d6679f60fe43e999b6da5841c96e48a
+Y = 30f2dd425a3fa2c95d34124217250b39e3b4a14f3e6e415ae8e5b0409eb72f43f78b64d0ce6f2d49980d6f04cd1391db
+Digest = 4f381df1ba39833f9f10e4b88314290ed04b56a8cdc4eab26d7b8b2bb03b5add622d8323b9fce5c794027b91578fdbd17208cb238cb1c8bfab7485c81bf45a90
+K = 1a2d224db4bb9c241ca5cab18920fad615fa25c1db0de0f024cb3ace0d11ef72b056885446659f67650fdff692517b1c
+R = 87b4de0fb21df38dfc9a4b1e350da67547e307f55b5b9dd6615e408afe7c3553a6e02722847367439e636074faa2182b
+S = 375d965753b9ed6c6c08576726f8308c2f8dbd2737824464e71265d47907e26f615bbeb8203ec617520d4ecd1851dc44
+
+Curve = P-384
+Private = ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa
+X = bc6b1a718284803553c173089c397870aaaecca579bb8e81a8cfa12473cd2057567fa8726a19ed427cc035baeec2c551
+Y = 14f82997d1129b669f0015350e47ad561b1b13441af4fb44656f15ed0c5706984d66655accc52f2e943eef39cb1cdc21
+Digest = d1a787cdf3c1c6c807731083e28a75a1df39f43d19a16ff121ca10b33111b5c71c561542cb61c2cca85a1632ab5535596c659d8b257df95be175843d246e6232
+K = 8053a46e875f446056b06d4318fa3e8977622de7207cbf0996bf35b0e9b19aaa507f642bcf0be9f048f1af09806f6946
+R = a994eb15b64114ce8a9342d18b5edda96a6d76314a5ac03da723699177d352a4a9f3b7121b11a91e43a6af4025da51d6
+S = 8183ae33a888e99aa76882da0a6705ad102f2bbd9572fad0d2e4d6d70151970469e00c5220e59c14724d771c1384b302
+
+Curve = P-384
+Private = 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f
+X = c9f1f63a18c761b077a1ec35fbb2de635db9b8592c36194a01769b57728c7755d4c79b3d5b97a1a4631e30c86d03f13c
+Y = f8c4a38770054d5cc9bb9182e6d4638242c4fd16e869ac22e44c4b9402d594e0c6f5df6a9a7de32a4893d9f6588f1950
+Digest = f1c6287f6a2164c20b246bcc8500b03a7cee404caa6b571ed32ee7cff17eb1979d07e8ef1c2856ca83d987bf8301d7f3a8384c22f209c831f8b12f2b11cd8154
+K = ecd395c5d8b7d6e6b2b19644e0d2e6086c912c6a0f5b8ed4b94b7290b65852c9741ce8eeb08d8751ead8a183e17d76c6
+R = e81331d78b438b0b8d98c1be03385ba5d614af182f1677f259126cc3de7eaac6c19b02be955d936b6bf9c27c6796e6f0
+S = 17c2b7a8e0fc93909762aa9f86f9561e759ecb88f02337b2018363be6095d9e4324a6d3296046686624b5efad6b52878
+
+Curve = P-384
+Private = e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1
+X = 0f753171922b5334f3dd2778a64ce2da8295121939beae71ad85e5344e893be0fd03cf14e1f031adec098e0c4409449c
+Y = 45c10a0ffc0eb2f1cec5c89b698061108313ee7d449ad580efad344f0e7cf35be8a18fca620f112e57bdc746abdace55
+Digest = 44d0ad691730209dbfde2083c68111a0f59af96d8de255875b55654055c5b6f7a48537d461ebea4df1709e196fc5d9fab1466a53f24a63c749fde05f62daf7b8
+K = d06bea06b25e6c30e866b1eb0657b45673e37b709013fb28fd7373afc8277cbc861354f821d0bd1927e52ec083a0f41f
+R = e8d4a31dd0e7d2522be62a32608e744c3775ceb606dc897899f0c73f1a40ce9a8be854cd506e65cd81fd7fa2c616cb7b
+S = 8151b681b6b6046d3c36f332d06d9ba7751e740631cdb759f88c50a25a8e950d5023df8a15c77243743733c4feaf21d5
+
+Curve = P-384
+Private = 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c
+X = a52c25f2af70e5bc6a992ecef4ea54e831ed5b9453747d28aec5cffb2fcfee05be80c5cbab21606b5507aa23878adee1
+Y = 2cf2a9afeff83f3041dc8a05f016ccae58aa1a0e0dc6be9d928e97f2598c9ba5e9718d5eb74c9cfb516fd8c09f55f5b9
+Digest = 61c5ed5d5e7d742dce869379a4322dd5b3d773c0c07575d69fca1e9fe2e7a90ea013094dd474ef1e682f30ca0fca50d8835e84f1e5e62b8a3f6140fbe5c75a44
+K = 13d047708ae5228d6e3bbada0e385afdb3b735b31123454fdf40afe3c36efed563fd2cce84dcc45c553b0993d9ca9ec3
+R = a0203f6f2c456baac03538ed506a182e57a25151802cf4b2557613b2fb615ebd4c50ddc505f87c048a45bad3b2fc371c
+S = 0eab56457c4080400fa3af124761d5a01fef35f9649edba8b97d22116386f3b8b363e97ef3f82616d5d825df1cf865ef
+
+Curve = P-384
+Private = e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c
+X = a1ffb4b790d1593e907369b69de10b93cddbb02c6131f787422364d9d692768ef8097970306cce16c97f2b10c538efa7
+Y = d0692028601ea794d2563ffe9facc7273938fab47dd00b8960be15549a9c2b3f8552583eb4c6cd212fe486c159c79153
+Digest = 5e7b908015b39fe97a2e84d30cae3c3b309103ff446e3ea2b2eafb8c004ceee6589d31a83c9904f4f4caec4cc0cec7641f62dd228a40a7696bd2b4583a016ace
+K = 2226f7329378cecd697f36ae151546643d67760856854661e31d424fae662da910e2157da9bb6dfbe3622296e0b5710c
+R = 20dcc25b67dd997621f437f65d78347fb57f8295b1b14453b1128203cda892bcfe726a2f107d30975d63172e56f11d76
+S = 51cff592cbef75ef8321c8fa1e4229c4298b8180e427bee4e91d1e24fc28a729cf296beb728960d2a58cf26773d8e2e2
+
+Curve = P-384
+Private = 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855
+X = 54c79da7f8faeeee6f3a1fdc664e405d5c0fb3b904715f3a9d89d6fda7eabe6cee86ef82c19fca0d1a29e09c1acfcf18
+Y = 926c17d68778eb066c2078cdb688b17399e54bde5a79ef1852352a58967dff02c17a792d39f95c76d146fdc086fe26b0
+Digest = 6f39c6187b6dbdfb17c7267aba7804f6087742d56647e74692afc69e1430bed1535cd71c7cef015f9647e2ade3e19f4f9574807a4c5fc5b2b219d1b6fe803bb0
+K = 1b686b45a31b31f6de9ed5362e18a3f8c8feded3d3b251b134835843b7ae8ede57c61dc61a30993123ac7699de4b6eac
+R = 9dbfa147375767dde81b014f1e3bf579c44dd22486998a9b6f9e0920e53faa11eed29a4e2356e393afd1f5c1b060a958
+S = e4d318391f7cbfe70da78908d42db85225c85f4f2ff413ecad50aad5833abe91bdd5f6d64b0cd281398eab19452087dd
+
+Curve = P-521
+Private = 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46
+X = 01a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e7
+Y = 0184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027b
+Digest = 84358f87f45970a080efcb8b1d9284c8e61e06edbf5209b1a9db9cbc
+K = 0141f679033b27ec29219afd8aa123d5e535c227badbe2c86ff6eafa5116e9778000f538579a80ca4739b1675b8ff8b6245347852aa524fe9aad781f9b672e0bb3ff
+R = 006b973a638bde22d8c1c0d804d94e40538526093705f92c0c4dac2c72e7db013a9c89ffc5b12a396886305ddf0cbaa7f10cdd4cd8866334c8abfc800e5cca365391
+S = 00b0a01eca07a3964dd27d9ba6f3750615ea36434979dc73e153cd8ed1dbcde2885ead5757ebcabba117a64fcff9b5085d848f107f0c9ecc83dfa2fa09ada3503028
+
+Curve = P-521
+Private = 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73
+X = 00156cd2c485012ea5d5aadad724fb87558637de37b34485c4cf7c8cbc3e4f106cb1efd3e64f0adf99ddb51e3ac991bdd90785172386cdaf2c582cc46d6c99b0fed1
+Y = 01edeeda717554252b9f1e13553d4af028ec9e158dbe12332684fc1676dc731f39138a5d301376505a9ab04d562cc1659b0be9cb2b5e03bad8b412f2699c245b0ba2
+Digest = 962bade1e8227c9f2a069177fb89dab45c4f7e8e2f81fdd206b0b99e
+K = 01dc3e60a788caa5f62cb079f332d7e5c918974643dca3ab3566a599642cd84964fbef43ce94290041fe3d2c8c26104d9c73a57a7d4724613242531083b49e255f33
+R = 012592c0be6cce18efb2b972cd193d036dcb850f2390fa8b9b86b2f876548bc424fb3bc13c1e5c415fa09d0ecfcae5bf76fb23e8322d7eecb264a2ae6d20ef50d405
+S = 011bc9713be88e3b9912a3e5f5d7b56f20573e979b1a75d04ce339f724bddffa4665d25995fe24d32507d8a07c5e10169f5338ef2827737f7b0291752b21237217e3
+
+Curve = P-521
+Private = 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace
+X = 018d40cc4573892b3e467d314c39c95615ee0510e3e4dbc9fa28f6cd1f73e7acde15ad7c8c5339df9a7774f8155130e7d1f8de9139ddd6dfe1841c1e64c38ea98243
+Y = 017021782d33dc513716c83afe7ba5e7abef9cb25b31f483661115b8d6b5ae469aaf6f3d54baa3b658a9af9b6249fd4d5ea7a07cb8b600f1df72b81dac614cfc384a
+Digest = 3ab194db447f5dc738e1452bf7958b346c071b84d6ca2edd9ea3b870
+K = 00c24acc1edb3777212e5b0bac744eadf4eda11fa150753b355bf96b189e6f57fc02284bb22d8b3cd8bba7a09aae9f4ea955b382063425a6f8da2f99b9647b147172
+R = 0183da7b8a9f9d5f08903359c1a2435b085fcf26a2ed09ab71357bb7634054acc569535e6fe81d28233e4703005fc4bf83ce794d9463d575795aa0f03398e854cefd
+S = 00b3621145b9866ab7809139795cc30cd0404127a7f0fafa793660491009f6c53724fdb0b1ffbf0fd51c131180b8a957fe66e76d2970247c024261c768dee9abbfb9
+
+Curve = P-521
+Private = 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc
+X = 01e855c935139c8092092cfa733db1292530506eeb2bbb1687f9602c36d97a6714e998892d5d3b842d1896a6ece9d549e9792881a256256137b3dff180c96cc5d07b
+Y = 018d83b6e93cd287311f7bf7c1d7f9eeabcf0b69c12f2d8f40e333e81e956d968532a37a4c04d761874df293b484cd7053b03fdbc2fdcd3b4c412d6f272fb7c93fe6
+Digest = 7c72d5606cbc1610e101aa50d4793f96339eab9eba88342e87ff2642
+K = 01d98619bdc04735d30c222fc67da82c069aea5f449af5e8c4db10c1786c0cb9e6f2cc0bb66fa6be18c485570d648dafcd0a973c43d5c94e9a9dacbd3170e53fa2a0
+R = 00bf47fabe107ce0ec03e2ad60a79b058e1bebb18568b6a8cdbe86032e71aa30c15766105b2ea952cfa79bcab046df601159f96e179bbcf252dc68ac73d31481fdae
+S = 01f918fec69cd07d90f9d892b7117e7519c3224947f4262f1fd97077dd5386a6c78aeddff3ee97e59ea353f06029f1336f0d6ef5c0f4b17ca59343a55319b7bfc3db
+
+Curve = P-521
+Private = 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549
+X = 01857cc7bbed20e87b3fd9a104956aa20c6502192910e0e7598410526ebfe1c99397b85189612a60c51fb8f4dd5cb08a8cd2e702563062dcb043410715c5323a0046
+Y = 01fce8d135284310d2f38c216030634b32cd223222f0d9d8d2b7c55477c4b8b74fc6c96a6092f34b05ca44d3633a5037c2166c479a032bb4f949f89fc1ba5236d07d
+Digest = b2d36a3bfc82c960eb05f4993b9bd596a25920145d4267f74481a070
+K = 016d9704c0cee791f2938bb2a8a595752a3635c2f557efeecefd719414b5f2aaf846080f582c76eae7a8fddf81859b49d0131c212524d55defa67dca1a9a28ca400f
+R = 01c9a4e51774384e8362876a87c572e6463a54413c7c6252c552ebb182f83e45ace436ade4ca373d8a7216e83efb62c8b41c4d5132a0afa65078f16d189baca39187
+S = 01e92a7dd5fea29a666398e1df5775cbb5664fe6943fe4c1d2bba516b7543c84df584458e53919c4ffab579a26fb3c892a5d1a77b0a07428c89350f8b559e627b014
+
+Curve = P-521
+Private = 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4
+X = 00bc2aebf40cd435bc37d73c09d05f2fd71321111a767c2b0d446f90dd4a186839c694ceb734e027e7ee948f0f63e4d3f1656d3d543df23c342a599306909b347109
+Y = 01f4c98ac03f0718e58d5d1762c920445b11dbdd60ec7f60095809204e14965a4ecb0be6fea06adbac8ba431d6f144c75c199225df2a619a34be99897125b3a10af8
+Digest = 06d4fd20efb2a725626550c8097bd7b38dcadf64ee36350ce8e47a24
+K = 00401187c8b89945a1e48cda9ee52167789f4121e67482a7ac797899f5d3d2e623aed31e4adae08a8d43e69028fa074d2650317cbc765f6ed191cf0317b4bae57881
+R = 01e572afed754016fba43fc33e352932c4db65efcb84e2bd159b40fc5925893b161effc40240be28d8c07154d2615f605c6f0451b976522d95afd37f46602df7a12a
+S = 0030370c1c5352c2b663ac1858b42f69545b2f58ed5b2c007f303726977d3c756b5d644ec6788f94c886f78269aa190a3d8d1ae10e4fd24d937c4556fb9e1953fd6d
+
+Curve = P-521
+Private = 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16
+X = 0057ce3777af7032f1f82308682e71fe09f88bf29dacd5018a725e1caa4b1e2bfdd894fe618f9266f31ba089856dc9c1b70e4a2faa08b4b744d1aafcd5ae99e2c736
+Y = 0199bcfef2021bc5890d7d39ec5dc0c26956801e84cae742cf6c50386eb289b6e97754dd25a94abf81f1cb1b36935b5eb29f4b32a6516d2ff6a7d23064a0daec94b3
+Digest = 8c7db2e1a2ba5f8bd0a4f7e7f67a20918a87bc6c6462c326406e6c4e
+K = 019d2d74ad8ee2d85048f386998a71899ef6c960b4ab324e5fd1c0a076c5a632fd0009500076522e052c5c9806eef7056da48df6b16eb71cdf0f1838b0e21715fce0
+R = 018ecacbcffd5414bbb96728e5f2d4c90178e27733d13617e134ec788022db124374bbaa11e2c77fe3f38d1af6e998e1b0266b77380984c423e80ffa6ff2bcafd57a
+S = 01c727f34b6a378f3087721a54e9796499b597ecf6666b8f18312d67e1190a8a66e878efc2367b551267494e0245979ef4deed6d2cbf2c3711af6d82ccfeb101a377
+
+Curve = P-521
+Private = 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37
+X = 0164ac88ed9afe137f648dd89cdd9956682830cac5f7c1a06d19a1b19f82bb1d22dfeefea30d35c11202fed93fd5ce64835d27c6564d6e181287fa04a2d20994986b
+Y = 005cb83669265f5380ccefe6b4f85fdf0049e6703f6f378a0b2e52ed0fbbcf300afebb722f4ed48e3819cb976c1d60e2ba05646b478f6dfecfbae730e9644c297f00
+Digest = 4ff99d232c8fef39fecfe8af79d274e03beb4502fb833d8af4181d7b
+K = 0189801432cba9bf8c0763d43b6ec3b8636e62324587a4e27905b09a58e4aa66d07d096dbce87824e837be1c243dd741f983c535a5dd2f077aac8beee9918258d3cb
+R = 00917723f7241e8dc7cd746b699ab621d068dd3a90e906aaf0a4862744b96fd4e5ccdb9c7796c27f7196e693d06ec209464c3ea60ad6313e9b77cceaa14767e6651c
+S = 00957b0ecdc3668f6efa5d0957615bcfffd6419c5e57579b74f960f65ae3fb9e8284322ff710b066f7e0959ac926d3cf9a594bdb70bbec756c96910b26a2486dee9e
+
+Curve = P-521
+Private = 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256
+X = 01dc8b71d55700573a26af6698b92b66180cf43e153edadb720780321dbb4e71d28e0a488e4201d207fc4848fe9dd10dcabec44492656a3ff7a665fe932445c82d0b
+Y = 01920b16331b7abeb3db883a31288ef66f80b7728b008b3cc33e03a68f68d9e653a86e3177bbc00014fa5ea4c1608c0d455c2e2ac7bd8ab8519ebf19955edf1baf8d
+Digest = c1120fe21c2c40b47a97c9815c619a223c2f11fb2ebb5e87cb175280
+K = 0160d04420e0d31b0df476f83393b1f9aff68389cc3299e42ef348d97646f7531a722b66ddfb9501bbb5c4a41d84c78be7233b11489bceb817d23060e6017433fab8
+R = 008077aabd0a342f03f912007c586cfedfc63f93d1118f720d5b62b3ce141a60f86f111dfd8fc2e31a6778981f1a5e28f29a7369bd7897bb41240c8d3a9c170e0ee0
+S = 000abc75fc154b93840579457820957e89d1260fee0a4b9bb1946f61ca1e71afd76bb5e1077b3e38ceb39d1fac5ef8b217c4110617b3ad118e02b3fcc2a39ef38613
+
+Curve = P-521
+Private = 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7
+X = 01912d33b01d51e2f777bdbd1ada23f2b1a9faf2be2f2a3b152547db9b149b697dd71824ca96547462e347bc4ef9530e7466318c25338c7e04323b1ba5fd25ea7162
+Y = 00bbe9b1e3a84accd69b76b253f556c63e3f374e3de0d1f5e3600fc19215533b2e40d6b32c3af33314d223ea2366a51d1a337af858f69326389276f91be5c466e649
+Digest = 08a10ee8d56db0cbc4bd68611f39f23d2ef379fe730eae170d84b388
+K = 014fafd60cb026f50c23481867772411bb426ec6b97054e025b35db74fe8ea8f74faa2d36e7d40b4652d1f61794878510b49b7b4fe4349afccd24fc45fec2fd9e9e7
+R = 018b1df1b6d7030a23a154cacce4a2e3761cc6251ff8bf6c9f6c89d0a15123baef9b338ada59728349ce685c03109fcde512ed01a40afd2ca34e1bc02ecf2871d45c
+S = 00a399f9b9e21aeddf450429fec2dc5749e4a4c7e4f94cee736004dcc089c47635da22845992cd076a4f0a01d2cc1b0af6e17b81a802361699b862157ad6cad8bd1d
+
+Curve = P-521
+Private = 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73
+X = 0110c6177ceb44b0aec814063f297c0c890671220413dbd900e4f037a67d87583eaf4b6a9a1d2092472c17641362313c6a96f19829bb982e76e3a993932b848c7a97
+Y = 00f6e566c4e49b2ee70a900dc53295640f3a4a66732df80b29f497f4ae2fa61d0949f7f4b12556967bb92201a4f5d1384d741120c95b617b99c47a61e11c93a482d6
+Digest = bdcae2456898841b7d4dfe7309457bbcd51de792ef4942d5ea419926
+K = 01a88667b9bdfe72fb87a6999a59b8b139e18ef9273261549bc394d884db5aa64a0bc7c7d38a8ef17333478d2119d826e2540560d65f52b9a6dc91be1340cfd8f8f8
+R = 0015f73def52ea47ddb03e0a5d154999642202e06e6734ac930c1dc84756c67bbb1cca9f21f92d61bfdb2052c5dd2833349610f68139393d77250a7662ef7bd17cbe
+S = 0155c744a729f83b27d1f325a91e63a0d564fe96ff91eaa1bad3bff17d2abffa065d14a1d20a04dd993f6ed3260b60bcc6401e31f6bc75aaafe03e8c1a9cd14d2708
+
+Curve = P-521
+Private = 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c
+X = 01a6effc96a7f23a44bf9988f64e5cfafdae23fa14e4bee530af35d7a4ddf6b80dcd0d937be9dd2db3adcda2f5216fecbce867ee67e7e3773082f255156e31358c2f
+Y = 01e7760190dfbe07ec2df87067597087de262c1e0a12355456faba91b2e7277050d73b924e14c0e93b8457a8b3e1f4207ce6e754274f88ad75c000d1b2977edc9c1a
+Digest = c7d69612a965f318f419e9e1c6fdbcce011e42bbbffc2ed4b3458036
+K = 018afea9a6a408db1e7a7bb1437a3d276f231eacfc57678bfa229d78681cbe4e800e6065332a3128db65d3aa446bb35b517dca26b02e106e1311881a95b0302d15e8
+R = 001c49b3c1d21f1678bdbe1ac12167e95e06617190bdee1a729c1c649210da19e2e210f6689e1310513bfe2ac6c0f4ee5f324f344b31b18df341eaadb826d07adc9b
+S = 0129d4931ba457443012f6ffecd002f2abc3a4b65a58fee8457917ebcf24b29a1d3055b7fc62939a74ebb0c3582172ee7c3c75e0b2fa2367c6e04df63a7a91d593ad
+
+Curve = P-521
+Private = 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace
+X = 00a79529d23a832412825c3c2ad5f121c436af0f29990347ecfa586ce2e57fd3c7e0624d8db1f099c53473dbc2578f85416ad2ac958a162051014fb96bf07f9e1d17
+Y = 017c0750f26df0c621d2d243c6c99f195f0086947b1bf0f43731555f5d677e2d4a082fb5fe8da87e1592a5fa31777da3299cede5a6f756edf81c85b77853388bb3ab
+Digest = 7131ff8c846ed0de577806cc5e57f3bc896865a1994a17101fc1d254
+K = 0042d7c36fec0415bc875deb0fab0c64548554062e618aee3aa6670ffd68ab579fe620d3a9316357267fd3111c0ed567dca663acd94b646d2ba0771953cd9690ef42
+R = 00d01dfbef126febbdfa03ef43603fd73bc7d2296dce052216e965fed7bb8cbbc24142bfcddb60c2e0bef185833a225daa0c91a2d9665176d4ad9986da785f4bfcf0
+S = 016627e2614dbcd371693c10bbf579c90c31a46c8d88adf59912c0c529047b053a7c7715142f64dcf5945dbc69ff5b706c4b0f5448d04dd1f0b5a4c3765148bf253d
+
+Curve = P-521
+Private = 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8
+X = 012d7f260e570cf548743d0557077139d65245c7b854ca58c85920ac2b290f2abfeccd3bb4217ee4a29b92513ddce3b5cbf7488fb65180bb74aeb7575f8682337ef5
+Y = 017560186230c7e8bff0bffce1272afcd37534f317b453b40716436a44e4731a3ec90a8f17c53357bc54e6ff22fc5b4ca892321aa7891252d140ece88e25258b63d5
+Digest = 3bd7a8f543e3bc2a56be31f437e5917cf18abc84da11bded6c352921
+K = 014b8a30f988cefdc0edec59537264edb0b697d8c4f9e8507cf72bc01c761304bd2019da1d67e577b84c1c43dd034b7569f16635a771542b0399737025b8d817e1c3
+R = 00fc50939ebca4f4daa83e7eaf6907cb08f330c01d6ea497b86becda43dfcad47cb5c48f5eb2cc924228628070bcd144088c449a7873242ba86badf796097dbecd6d
+S = 00ccb6463c4301ba5c043e47ed508d57dd908fd0d533af89fd3b11e76343a1cf2954ce90b0eb18cbc36acd6d76b3906612d8a0feec6ebed13d88650ed9c708b28a11
+
+Curve = P-521
+Private = 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad
+X = 000188366b9419a900ab0ed9633426d51e25e8dc03f4f0e7549904243981ec469c8d6d938f6714ee620e63bb0ec536376a73d24d40e58ad9eb44d1e6063f2eb4c51d
+Y = 009889b9203d52b9243fd515294a674afd6b81df4637ffdddc43a7414741eda78d8aa862c9cbbb618acec55bb9a29aac59616fc804a52a97a9fc4d03254f4469effe
+Digest = 83fd2803e0faa52a4bc5ff9549ed9f68531da5acf81a5bb6e23016a4
+K = 01211c8824dcbfa0e1e15a04779c9068aed2431daeac298260795e6a80401f11f6d52d36bcee3cfa36627989c49d11475163aa201d2cd4c5394144a6bb500bbaf02b
+R = 01d59401b8ac438855d545a699991142685077a409de2418c7ccfe01a4771b3870e76287a9654c209b58a12b0f51e8dc568e33140a6b630324f7ef17caa64bf4c139
+S = 0143af360b7971095b3b50679a13cd49217189eaee4713f4201720175216573c68f7ac6f688bfe6eb940a2d971809bf36c0a77decc553b025ed41935a3898685183b
+
+Curve = P-521
+Private = 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a
+X = 007d042ca19408524e68b981f1419351e3b84736c77fe58fee7d11317df2e850d960c7dd10d10ba714c8a609d163502b79d682e8bbecd4f52591d2748533e45a867a
+Y = 0197ac6416111ccf987d290459ebc8ad9ec56e49059c992155539a36a626631f4a2d89164b985154f2dddc0281ee5b5178271f3a76a0914c3fcd1f97be8e8376efb3
+Digest = 53e6537cb6ea68ae47a81611c22756d770d7a37e336c3af0b0814b04fa39434b
+K = 00dc8daaacddb8fd2ff5c34a5ce183a42261ad3c64dbfc095e58924364dc47ea1c05e2599aae917c2c95f47d6bb37da008af9f55730ddbe4d8ded24f9e8daa46db6a
+R = 009dd1f2a716843eedec7a6645ac834d4336e7b18e35701f06cae9d6b290d41491424735f3b57e829ad5de055eaeef1778f051c1ee152bf2131a081e53df2a567a8a
+S = 002148e8428d70a72bc9fa986c38c2c97deda0420f222f9dc99d32c0acba699dc7ba0a2b79ce5999ff61bd0b233c744a893bc105bca5c235423e531612da65d72e62
+
+Curve = P-521
+Private = 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c
+X = 010038bb9a7aea626de68c14c64243150e72c69e2f8a1ab922bfbdaa6f33d24fb4542c0324357b0dd640bbcd07632ecd253f64ca2bfbfbf3de9b24fffd0568ab82da
+Y = 00faf867d95308cc36d6f46844a0f535dc70f9768eed011a2464d2f308fa1d8e72c3616aec7e70516908183ffce7fdd36984a15f73efaa3858c2edf16a784d40e6c2
+Digest = 40aef13bb7192a564d72ba58f7efad15635248eca49619b4182bf6f979842d6f
+K = 014aeb96c57d99677a1f5e4588064215e7e9af4027bfb8f31ff6126dbf341b8e6f719465e4273e91ba32670feca802549808322b7ee108bb20653cf20f93284d365f
+R = 0075ead62edf7d86c5d1bc2443d1aeb5dc034fd999e6ea012cef7499d9d050cd97d262095884e9fc89a42e15bd3dee80fe3c1ba10f4caabc4aabb86347023028b663
+S = 0129a992a6ff66d41948d11fa680f732b1a74315b804c982805190ed9d2fae223f2b149980b9241998cdea0c5672595a8a49d5186a0ef7a46c0a376f925bdda81726
+
+Curve = P-521
+Private = 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d
+X = 00fb3868238ca840dbb36ecc6cf04f5f773ea0ab8e8b0fdcf779dc4039a8d7146a417504e953c0cb5e7f4e599cc2c168deda8b7f16084b5582f89f2ece4cae5167f7
+Y = 01f90b5c15eeda48e747cf3ee8183166a49dbfac6161cbd09d29d40a6854f4c495e88a435892a920cdaad20d41985890b648badd4f0a858ffcbd9afdfc23134ede18
+Digest = 6fd829bd5fc68d7a36436284c1282e3fae76ba44c5babcee423142c1cf2b52c4
+K = 01f875bbf882cd6dd034a87916c7b3ba54b41b2ea2ce84ebaf4e393fcf7291fee09dec2b5bb8b6490997c9e62f077c34f0947fe14cec99b906dd6bf0b5d301e75ca1
+R = 007aa70425697736b298233249f5d0cf25c99e640c9ff88035ef1804820e1bfe7d043755f02d7a079494f7fa6dc26740c4e6b7b430c63f29c67bbd3a5c88d2f0e8d1
+S = 00e0d42e4ff11cf5be37a9fda348514d5097a662f214687cbfb28ff42d635b13029871ca4f464bb1fbce02d5da4d5fb61b2a071844259fc863d136197bec3a61e7c7
+
+Curve = P-521
+Private = 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c
+X = 013a4bea0eed80c66ea973a9d3d4a90b6abbb5dee57d8affaf93390a8783a20982eba644d2e2809f66530adeeee7f9a1da7515447e9ba118999f76f170c375f621f7
+Y = 012f9dfaee40a75d8442b39b37a5c19ea124b464236e9b9a31bae6780cfd50f7ea4a700154b5ea0feeb64e9b35a1b0e33e46900cca1f34d13bb17e5017769841af27
+Digest = 902b55b79c29c0de27386e4fadb3469fc124f1225ad0fac06bd4a3a1e351c09e
+K = 018388a49caeda35859ef02702c1fd45ff26991998bd9d5e189c12c36cdae3f642ddd4a79561bd1d3e1cd9359de8f5c9e1604a312d207a27b08a6033f2741794ced5
+R = 015c6264795837dfea19f91876455f564f073c5c84a3c9d76e67872ae0447ba0d4850d8721302b25bec7ebfedd2721de140b2f3dead547042b24b0876117e7093cc1
+S = 0060eb74236c189a28ed20bd0822eb22d75f7d97c9043a3c8e3f6d4c90bc8ca02ac4d37c1171c799a1c7dfd2fcbf83406b5e48c051e0fbf0fd937bfe6c3db4e18154
+
+Curve = P-521
+Private = 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25
+X = 0014858a3b9bd426b678fdcf93fc53d17e7a9e8fe022442aaaba65399d12fd3a6a381958fb0f07ac6088f4e490506ec0f1ab4d0dbd461126f7eb46ff69cfa8bd88af
+Y = 018c18ce29ecc6d79d26a2de0cd31c4b32e84b5e90f6ba748f86c5afbd89618aceb9079460cbd1a8261ed5476973e61bf1d17ea78b022387443800c9247d21dde550
+Digest = 99a83d5d6471963d9e18b105e51662dce360f34f23b8d64be47d50e9f8afa4d9
+K = 005577108f4187a173e5c29e927a8fc8f5ffd37e184254a6e381ff1018955aec91a35f30085e8cee6a7555c10f9efdce26d62f2b4b52dfdbaeafc3a30983e2d50d5b
+R = 00344375ae7c804cbe32ced7a20976efae5d9c19eb88b6e24514d1d0cfb728b0f4601098b18b2e98f42b5222dd5237d4d87767007bf5acb185c5526d72047e2cb1a1
+S = 002de4cfa908c73c1102d6fb7062baf54a056a9517701e036c9c51e09899d60051612d59348945f845dffebec5aa395b2fac7229929033615788777306ccad96d0a3
+
+Curve = P-521
+Private = 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf
+X = 010fe5986b65f6e65d13c88c4d2aed781a91026904f82129d46779bdadaf6b733c845a934e941ab4a285efdea9c96ecc9dc784d87e4d937b42c337b3a9cb111a9600
+Y = 0077853768a2a4d6f596f57414e57ec60b76d3cd5ece8351cd1f335ebcb8801a3d91fb82c65caaeb5c31eea9918367bb5906863ff3ccaf7a6cee415e0d75c15ac2e0
+Digest = 2c92465f323f6355ff408e42196e2de9a47807877ec02c9a7686917d3aa166a4
+K = 01fbb4de337b09e935a6dc6215ffcfcb85d236cc490585e73251a8b8bac37cfa36c5d1df5f4536d33659be1e7a442529a783452f7efda74a4f661b6a127f9248aaf7
+R = 009d8f10eeff6178594c89d6e8184f9502117384813243ddf9ccf3c8eac5dc6502c472dfc1487a5caffc569f7dedd14a8ebcb310e9bacdb79fb6655aba026cdf87f2
+S = 00f74236c7915d638708d17c9f10e39dda358faf9bbb821d8dcda0d151aac143bfb165ad0a23a65cd3de532e32cad928728f5ae1c16f58fc16577f3ca8e36f9e708b
+
+Curve = P-521
+Private = 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570
+X = 00fdf6aed933dba73913142ef8bdcd4b760db8500831cd11d7707ab852a6372c05d112a1e7fbc7b514c42142c7370d9f4129493cd75cc6f2daf83747078f15229db6
+Y = 00ef91dffb3c43080a59534b95ca585ee87f6145f6a0199b2b82c89f456d8bd8e6ac71c78039c08177184484eb2ebd372f189db3a58fab961a75a18afec1ee32764a
+Digest = 17baaa5a7f97f2d17545c4baa468f36ef22b1945ea889b63b027806f5b1b7f90
+K = 013aa7b0471317a2a139c2f90df1c40d75e5a8a830fbaf87030fffdb2ef6f2c93d1310c9ed7fe9d7bcd4fe46537ff2495bc9c4f0aaff11461f5e4bebbfbce9a8740a
+R = 01c7a21800962c91d4651553633b18612d931bb88bff8b743ed595b4e869437e50f8e84fbf334c99061db123a1c40b73b07e203790561a37df65a660355ba2017d78
+S = 01301e1782559a38f1ca0eebe9bed0f5c7c33103d506a24f8a688f500ee1fe37f97b6685319279e82e6fe43cfd823ccbc123309974cffa76c4f8d41ec02a3cbc45f1
+
+Curve = P-521
+Private = 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6
+X = 000b8c7c0186a77dc6e9addd2018188a6a40c3e2ba396f30bbd9293dba2841d57d60866b37f587432719b544d8bf7eb06d90a8c0dc9c93b0c53d53b2f667077228ca
+Y = 01dd2e5c73ab908ae34f701689f1cd3cf5186d3a2bc941e208bf3ef970e5e429ee9b154d73286b2e5da423e75b7c7b78c7bdf915da92279db43265a0cdefca51f86a
+Digest = b8f56952078ffcf04cd9815c6b06b63812eee9d682495d7172fd3677abe1c2db
+K = 00d03506999f5cc9ec3304072984a20a9c64a22ad9b418495ca904f4bbddc96e76d34672cb52763339d3f3bc5b1701c00a675b972797e3a086314da1a8d338436566
+R = 0085406c0ff5ec91f598bb579ad8714ad718c3e133d5dcc2e67c5d2339c146b69919cac07f3bc2bda218f4c7c8be04855e2ca6fff7fbdc4fc0fda87c8c3081cad4f5
+S = 01b45f2066e583636215ae135afc202b8bf3f301eccff2e1c0198b9aeddf695fa8179488e7b622fc307f601e2f6551815117cc836bb09ef888f8e64a45d9c84ad30c
+
+Curve = P-521
+Private = 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7
+X = 01b4b8947192a7c0166c0e0b2791e217370836283e805f3ee11cfb78445aba3c5bc39fe594e01916617ad59e7c8e740d8f2d07d88905d3f33bd5e51aafd4943c5dc6
+Y = 01175d117232836c28e717ce2a55e59f4ec550effde30d18e3d99e42c6aa2283c7b3e7f2f6ff1fca605dde78c3a5bffa689347b4c93f51ba59a1787bb7d5e43861dc
+Digest = 9477d884384f80b528aa4c3408b7f7d0dc59bd3f678466b122d48a42c01fc3bd
+K = 0023645023d6bdf20652cdce1185c4ef225c66d54f18632d99ccf743bf554d04c214c88ce52a4f71ec75c899ad1b3c07c34112ca20b55c217ff1d72c9528e2774ce8
+R = 01e933f68ce0f8403cb16822b8e0564b1d39a35f27b53e4ae0bcdff3e051759464afbc34998ba7c8a7ee34ef6c1aaa722cffe48356fd0b738058358d4c768b3186c1
+S = 00a67368a305508ce6d25d29c84f552a4a513998990fef4936244f891a2909c30d5fdc9e8a267ecbf3c597138f4a08f7e92bee57d5420eadd700fee864bf78b2614b
+
+Curve = P-521
+Private = 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e
+X = 00ba3dc98326a15999351a2ec6c59e221d7d9e7ee7152a6f71686c9797f3f330d3150123620d547813ba9d7cc6c6d35cc9a087d07dff780e4821e74ad05f3762efd6
+Y = 018b051af9824b5f614d23ecadd591e38edbfe910ad6cbebc3e8a6bec11ea90691c17deb3bc5f34a4a3acd90b7b10f521f6ee7b3cfbfdc03b72d5a8783a4a77c3e4c
+Digest = e995003b47e16fcdc7487e2fe3b715b707e5c8d1246de04172a3002b140dddac
+K = 006099d2667f06c58798757632d07d8b3efbe9c1323efb0c244be6b12b3b163ba1b7cf5246c98dcc0771665a66696d687af5f28ed664fd87d5093df6427523d4db84
+R = 010dc80ea853064a2ba5a781f108aca3785c5ec0aa45aa05ba31d4de671170797589e863d54a3a986aadf6f670277f50355713dfb27d4ec7e348f787910b3cd668cd
+S = 0018572bfad4f62e3694d1f2e6ffd432faed2e2b9d7e3611a07138212f1e79e6c394839f7cfae96bc368422630016fb9346681eadc5f9699e7331c3b5fde6d65e4c6
+
+Curve = P-521
+Private = 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938
+X = 01b8c7a169d5455f16bfe5df1ba5d6ec9c76e4bad9968d4f5f96be5878a7b6f71d74bfac0076dd278bc4630629f3294646f17d6b6c712b0087e2c4d576039cfdc8b9
+Y = 018faffd5422dfd1b61432fa77b9a288b2b7d546656c0dcca3032179e6f45ee3cf61d6a447fc51731cb54457343a41569fcf78cef42895f4da5efcb14ea1fc065f8d
+Digest = ce977a38b4c4db0c74fb5d0bfda5818719fb4bec00412f235c48c99995510c55
+K = 00ac89e813f94042292aa1e77c73773c85cf881a9343b3f50711f13fa17b50f4e5cb04ac5f6fc3106a6ef4c9732016c4e08e301eefac19199459129a41a7589e0628
+R = 005bc7a253a028ee8b7253979b8d689d41d8df6fae7736341f22e28b6faf0cbbdebbd2ef4d73e56d2021af2c646dc15539a7c1e1c4dc9c7674808bd7968d8a66f947
+S = 00fd71575837a43a4cf1c47d0485cfd503c2cf36ebcea0fdef946ad29acb7fb2e7c6daf6b4eb741eb211081aed6207d02569f1518988f275ad94c7fd4735cb18a92e
+
+Curve = P-521
+Private = 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662
+X = 0172fb25a3e22c2a88975d7a814f3e02d5bb74cfb0aaa082c5af580019b429fddd8c7f9e09b6938f62e8c31019b25571aaceef3c0d479079db9a9b533ee8e1670abd
+Y = 00ff5516223b6cc7c711705f15b91db559014e96d3839249c5c849f2aced228a8998177a1e91177abbb24b57a8ea84d944e0c95da860ae0925f1b40c0e1b7c9e0a46
+Digest = 35156a6da83777e4bb100c48cd11dafc0e2e0bbe5c985faa57a6da61fcf31236
+K = 00383eda042e06c0297fbd279a2ad40559c5c12ad458f73458eebcc92b308d3c4fcec20a5b59f698e16fa6ea02dba8661b6955f67c052f67b0a56460869f24cfdf7d
+R = 01b9c35356b9d068f33aa22a61370dae44a6cb030497a34fb52af23c6b684677370268f06bb4433be6795a71de570088aec17ce0c9933d2f76c7edce7f406f62fedd
+S = 006f07ea453cfa20ad604ba855332f62834657b0b795684d50c1562a675456e37f4dae45f0df47d8e27e47bc9ce9c9cbba1554c5b94b0b17401b73c8d0c0902c6cc4
+
+Curve = P-521
+Private = 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721
+X = 0193301fc0791996ca29e2350723bd9aa0991ddbb4a78348ee72bdcd9ed63ce110ba3496f2ce0331b5c00d4d674c1b70114e17ce44a73c3e16bab14ed1ee924202e4
+Y = 00aea9b288cfb2933ec0a40efa8e2108774e09b3863b3193d0dac6cc16ccaa5bd5f9ce133aec5cd3b62cbaeec04703e4b61b19572705db38cfaa1907c3d7c785b0cd
+Digest = afe33dce77cc747ec0a7f4835740be3bbe3faa1c3b02b10afdfc40a28dae61aa
+K = 00d0e90d5ee7b5036655ad5c8f6a112c4b21c9449ca91c5c78421e364a2160bbac4428303657bc11ea69f59fb0fe85a41b8f155a362343094456fd2a39f2a79e4804
+R = 01a8c23a2965d365a4c2ffd0802ae8b3a69c6b84a1ba77fd8a5f2f61e8ec3a1dcb336f136e2a997252eaa94caf9b5ad6c9ecff5bf33abf547ca84985bb89908a11d7
+S = 01cc42a2dd97aa42b9df5ea430e0d4cb13106dd6da6e8c9315c96ed7b052db365bbde6960c9a965954a4398c18ea7db9593bbfc3c3b6b3466ff806fccac3de6424ab
+
+Curve = P-521
+Private = 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e
+X = 00fc7ae62b05ed6c34077cbcbb869629528a1656e2e6d403884e79a21f5f612e91fc83c3a8ac1478d58852f0e8ba120d5855983afd1a719949afa8a21aec407516c3
+Y = 00aa705da6459a90eaa2c057f2e6614fb72fc730d6fdebe70e968c93dbc9858534768ea2666553cd01db132331441823950a17e8d2345a3cab039c22b21bfe7bd3b9
+Digest = ff76d5393d73d021b9dce99b394b6a6b4d9c34ff74d68a2406319c48bbe6743d
+K = 019029260f88e19360b70c11107a92f06faa64524cfbd9f70fecf02bd5a94f390582a7f4c92c5313bb91dc881596768d86f75a0d6f452094adbe11d6643d1a0b2135
+R = 007f2158e9b9fa995199608263969498923cf918fdc736427c72ce27ce4a3540dce2e8e5e63a8fc7ba46f7fa42480efbf79c6ed39521f6e6ec056079e453e80a89d9
+S = 008e349eed6f1e28b0dbf0a8aeb1d67e59a95b54a699f083db885f50d702f3c6a4069591afaa5b80b3c75efb1674ebd32c7ead0040d115945f9a52ee3a51806cad45
+
+Curve = P-521
+Private = 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418
+X = 0167d8b8308259c730931db828a5f69697ec0773a79bdedbaaf15114a4937011c5ae36ab0503957373fee6b1c4650f91a3b0c92c2d604a3559dd2e856a9a84f551d9
+Y = 019d2c1346aadaa3090b5981f5353243300a4ff0ab961c4ee530f4133fe85e6aab5bad42e747eee0298c2b8051c8be7049109ad3e1b572dda1cac4a03010f99f206e
+Digest = e40ae6e430f07950c186100e20048cc62bf56be6a818ad660785bdaf3bcc0c25
+K = 01a363a344996aac9a3ac040066a65856edfb36f10bb687d4821a2e0299b329c6b60e3547dde03bdbd1afa98b0b75d79cf5aac0ef7a3116266cadf3dfbd46f8a4bfc
+R = 01ff097485faf32ce9e0c557ee064587c12c4834e7f0988cf181d07ba9ee15ae85a8208b61850080fc4bbedbd82536181d43973459f0d696ac5e6b8f2330b179d180
+S = 00306dc3c382af13c99d44db7a84ed813c8719c6ed3bbe751ead0d487b5a4aa018129862b7d282cce0bc2059a56d7722f4b226f9deb85da12d5b40648bf6ec568128
+
+Curve = P-521
+Private = 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950
+X = 013b4ab7bc1ddf7fd74ca6f75ac560c94169f435361e74eba1f8e759ac70ab3af138d8807aca3d8e73b5c2eb787f6dcca2718122bd94f08943a686b115d869d3f406
+Y = 00f293c1d627b44e7954d0546270665888144a94d437679d074787959d0d944d8223b9d4b5d068b4fbbd1176a004b476810475cd2a200b83eccd226d08b444a71e71
+Digest = 9832832c49754bdeba2d3799cbf6437af28ad9f942d3f313abd320fad0897be6b446aa24f1b23a86ea54aef12b1f5c0b
+K = 00a8d90686bd1104627836afe698effe22c51aa3b651737a940f2b0f9cd72c594575e550adb142e467a3f631f4429514df8296d8f5144df86faa9e3a8f13939ad5b3
+R = 002128f77df66d16a604ffcd1a515e039d49bf6b91a215b814b2a1c88d32039521fbd142f717817b838450229025670d99c1fd5ab18bd965f093cae7accff0675aae
+S = 0008dc65a243700a84619dce14e44ea8557e36631db1a55de15865497dbfd66e76a7471f78e510c04e613ced332aa563432a1017da8b81c146059ccc7930153103a6
+
+Curve = P-521
+Private = 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b
+X = 00e7a3d30d5bd443549d50e9b297aaa87bc80b5c9e94169602d9d43d6d0c490c0bed8cc2170288b106bdbf4c9f1ce53fd699af0b4c64b494b08520e57dc01ab9a8b0
+Y = 01d81056d37aec8a75d588f6d05977416e6f24ad0117a7f4450036d695612e7bc2771caed80e580314eebc88c8fc51c453f066e752481f212b57165d67f8a44f375a
+Digest = cca0c216abf3baaff0b0d8597bcfc7183835b4e3d025749a741a0e75d00845a341fe094214b1c39e13e8932a062c1ecf
+K = 0046639c5a3ec15afae5e4a7a418ac760846512d880c359bc2c751b199ce43b10887e861b14127809754dbea47f6cc0140d2817e3f5b9a80ce01abd81f81b748433a
+R = 00f913de91e19bd8f943d542ae357bacc942a0967abc9be6c06239a379db8cc733fa50013e0b0f088bce9d630262feaa33b30d84f91bcf5ce9976e4e740fcb112f84
+S = 008a73a5c9c24235e0d9cecaac653f68ce5a6fb186ce67fa058d6ddbbd4d0a8c4d194e571148e8ad6c8882b4e33d2f60fb23dd7d07a1ae60864e8277918f592b3dc6
+
+Curve = P-521
+Private = 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f
+X = 004f5b790cbe2984b71d41af5efed6c6893d15e13f31816d55a9c2926a104eee66f1ada83115d1388551218773b8b9d1138e3e3f027bb4392c90c14fd232580b4a11
+Y = 00660eb160e9bfc8c5619e70e948e238c6fd37739bc1bb657b8e8436e63628f91992be7e63d9a7359623a1340642777b22026feb51116a6c50c54c3589b9bd39b6cb
+Digest = 0af6f685cb6c1219cb1627dd2b9099b70b1622d32b2342cbef6c0b9604d3f22360d595198af65579062dddccb66a56ce
+K = 01e7b5e53571a24bd102dd7ad44a4b8d8a4e60e5957bc3c4e5d3c73109f55233f072e572c7892f425ba5e64d3cb7966096bb34a47e26cd5b3e3b44108b310d9f681b
+R = 01a88bcd7e2bdff6e497d943dde432fb3f855a7177c466319cb53b701230c299db030276269685857d1e3f28110e690f2f529c8d18115eb381f313bc891d92ad278e
+S = 0146f1984ea879274dfd5e86ad92e564a4de081523ddbb1c397b8f9595911ef2e6501bc081584d5340f7aa47e1af036234ac6f27a5ac31f78dd3b0ff1a62693c630d
+
+Curve = P-521
+Private = 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66
+X = 005055b9ad726ba8a48219b0ecbfffb89f8428de895b231f676705b7de9f2022d9ff4e0114ebb52dea342f9bf76b2fb060c020e29d92074ebb1fbfe5290a58c8bc10
+Y = 00415af7f20a6e945315adbf757316bb486c80780a0a3a15b4b9609f126d7341053a2b726ab63cb46feee527b0bf532b32b477e5671aea23d9b3c3e604b9029954b5
+Digest = b5008011397235faff9eda7ac9838dd1199eb52b2921d28407e5c356dcca7611184d29d268c16bfb489481a294bd7a43
+K = 005a2e92717bb4dab3ee76724d4d9c2d58a32b873e491e36127985f0c9960c610962ca1c4510dba75c98d83beebdc58b1d8678e054640951d11db1bd2d8a4ab8476b
+R = 0104a78ce94f878822daaf00ee527fbdbf6cceb3cbb23a2caa485e4109466de8910252f92379ab292cac8d1eda164f880c0067696e733fc8588a27703a3e1f5b8f1f
+S = 01ffe23e8ab5a31668a81161a234ea14879771fe9866f8872eb6edb672e0fe91d2bb75c9767a2dfbac7c15c802211236b22ea41ecd055a0b8b311ffc4255f86d5c67
+
+Curve = P-521
+Private = 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c
+X = 01f15c6b1df156fdd8381cd7446e039435e445f8f36f0247475058da0e371bf72753f6e39f98066bc79370b038c39687ba18e16cb118fe6538b7568c5403c251f6b7
+Y = 012d2b4f46b854eeae75f1c63f55b76bf0c604d47f870c28a50ecdeb52bba1dd9a0ff12e680804ff864111207652da7dd10b49edf66bb86be00bc06672de91982457
+Digest = 64c05e43191b0313abd6514eb5a44dbf25befb232b8e928f92801f75a968d9a96801facc86b2174e0a5f247d9b5e7587
+K = 0165faf3727e42fd61345cfa7b93e55fb4bf583b24bdc14ce635b6c99dbd788012f14da9a210b677c44acdd851e672f1a48188d6b8946c0efeebfe8a597ba0090a2c
+R = 01ad9463d2759abd568626548578deefdcd8b2d050ce6d9c7ed05feca20167484b86e89bdcc936fd647e0f8aedd7b6add2b8cf13ff6ff013c2b5540c6c56fda97a0c
+S = 01645a7d0e11015256cfb034adca198695eea6aedd44d9fbf496850ccfed950f43fffd8dbf41e113f2d3837d8a5dd62b2ed580112ff05800b1f73196e5576810e15b
+
+Curve = P-521
+Private = 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0
+X = 0128a4da5fc995678e457ceb3929adee93c280f851abe900fa21f4f809dafad4e33b381e0cd49ce8dd50e2e281cea162bfd60a1d6a1c0ee2228e6a011e171b559ab8
+Y = 006eb0917cd72256992c49ea527f6bb0315f13d8047794a0f1da1e93737703b1c2a74a00441ef3b47b6a2ff789c49ae32d91cabe7b29247aeec44f6c40a76597a2ca
+Digest = 9e4bf8293245611cb31caf0b0125117a4ef286ca3730f1519f3c95e65a5db326ead01b08e6b219281a26f2a41bda1e98
+K = 003269983a5c2bcc98e9476f5abf82424566b1f08b17204d29e310ece88f99eb677a537f86fe2529e409cfef2c12929644100099e0de2f27c0f0ac11105a4dca935b
+R = 01a5257ae1e8187ba954f535b86ff9b8d6a181a3b95c250d090cb4e9c3bfbd03aa64696a76c569728ef67780d6338d70ce46da40b87a3e49bfe154b93930890dfa93
+S = 005b6ccdfd5c63c7db76d3a0478064a2a376e0e050cb093be795a72a549247c2e4adba9183145c63d46479dbbdcf09986a6f64c09c7e16abc4853f6376c9558b014a
+
+Curve = P-521
+Private = 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9
+X = 00d33c151d202a5d4d831348e940b027ee32e4b0b9b48d823a05c67ff3bdaee0189fc6680565f352c062e99968afc643208b4f9c7af185b861658a88c4ad0fcc8ba2
+Y = 00e4441ddb546468ad8ffa6074f137edfbb81e82e0e7d8f05c4c54598aa996a9cde54cb371f642bfdd4ae7eca5b769696030027129a4183da93567ad142a2dff5183
+Digest = 417e8611fe90382b134add3b3df5a963d95c4de28a5a5b215b7f96731db9350d4646c1efe7455d48a1a2de6b4fcbd9c3
+K = 0046e619b83aac868b26d0b3cbfab55e630e0b55c461985b5d00f94ff3a5ce90ff412cebf46bbd84550d2031d573ca27d924624428360708c8d8491c29eb01d30f2e
+R = 008427c0f0ac0263472cd423c0fb554bf3c851b9c775c566ab0f6878717bd57665830767b05b7789c5c0b078195bd943dc737325552d32877ecb04a7c41bd07cd80c
+S = 010bb6652d6a624c40a7dd06828f15774130d02369ceb1a7d03b553e16e17b7fa5b5401f15885d5e4fc2e55c0c7a1b97871ab02f76386b93a16aa6e7eb65debac6dd
+
+Curve = P-521
+Private = 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d
+X = 01dbc2cf19627bdccf02432b1761f296275230c150cdde823ce3141ec315d7d05e16b2c29e2a67491078d5316883e933d85b4b10d4f64c477d3c4e0442dc928983a2
+Y = 007562e720807dd118d3d8b265b3abc61a71fce43e3dce0e7b5ae18b7a4cb01ecc00d39c1f22e150a9a8728997e502144f5b3f6fa9b4cb8a4136212b082ca394e3f6
+Digest = 297eed020ddcd03aeeafc77469caa105469205595ef22f64860126135e2596ae99ccaeb679d073cd9364b1e4ee2c4b60
+K = 00fbccd8d7804bdd1d1d721b5ec74d4ba37603bc306f9fce2ec241853d8e07334e6b4b12c4ecca0c54bd71193dd7146507933a20737c5f3e15085830fab9b30ca57b
+R = 0181915a3998d8fa214f9715f4ca928d09c36de168dc15c6970a8a062b5cea2dc969b2437ca17b684f78a1fd583aad8e6c762c8f4ab0c91b86a497145e3ca440d307
+S = 015a6c18c5c77f5470b27d061eafdc26b78561941a3b2ab0f5c81d40899fc053c3d9ed12d7d61e298abbae470009c7b2157731c58d7b16a66fa5abaf5e8a1b8ed394
+
+Curve = P-521
+Private = 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490
+X = 00c80fc4cecae5d53348524ddba6a160b735c75b22fdb39af17e2a613d09246e3bb0fd3f2978577f6db5d2118e05c7898024808f8eb8e021d7969cdcf7fc981200bb
+Y = 01a880c93943fd446d4b3923b574d2221c1bb7b645fb5534dda60e827b497666ff586b77921f7e7f605147947194cffd2fef0678880b89cc0bc7fb74fa96d4b112d7
+Digest = 39884fd5e7c8b6cb67836e257957cc11f6bd342f540bde745e0e4e55d3ead2ea080d8b2b2e96664056c50de0d7822f25
+K = 001a05238d595ded5c61d3bf6fde257dbf13095af8a5cb3a2e579e8e4c550fe31d12b71cc2dbcb295e6c4fd0fb8c22d1b741c097cc59d826ced1a8771f09983143c4
+R = 0132762bc81e9922a8d642e3a9d0218affa21fa2331cfcb9e452545c5981c64a8f7e4cc8e68056023b2aa78bead59061d19c7f646c931163a91e544b106b3be8de9e
+S = 00c3a1b0b000c3169984132add51d611e2cb7069a262a6983d2ae72b459c36e6469509bdb0f473600b8686700b08910779dee9ba83f82e755d4a4ef5f124eb09397f
+
+Curve = P-521
+Private = 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1
+X = 00c0bd76b0027b85bdd879052220da1494d503f6a4bb972105a48ae98e7dda8c2d9fd9336f5646385b961ef68e8464e3a95b00f96614b1a408ceaa2c87b077b6a8fb
+Y = 017eb7eb5c78db7819af92e8537d110d9f05a5e24f954f4dde21c224d4040f059ec99e051702f390413d2708d18f84d82998c61847475250fb844b20082cbe651a6b
+Digest = ac6b375afaad4c5c1b8e8aa5ac94e2aa1553e8f8603d16a86d573d53a4e6c5731f6d6c18ac732cfd3ae8aed75046c1f1
+K = 014e66853e0f7cd3300ebcae06048532e19cbb95bee140edc1c867ce7310637651445b6dfeb1d99d2e32f2ffb787ebe3fe35032277f185d3dad84f95806924550abe
+R = 00c5b3a57161098e2e8e16e0a5ae8ecf4a14df14927eea18ed4925d11dc429dda145159323ba970174b194b9b4608a8fa2373b7a825c5e8bd80574e49698285c2c82
+S = 01a0c038a51796158b42eb5b0dac37aff9ab93b903a47e06ebbdd15946e4bcc9a3b3875b18cf6294c33fc6c3693cef04ed1a43d08951e664c760e2cf3fb4e47490d2
+
+Curve = P-521
+Private = 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745
+X = 005c0ea363a3a12633ea39d564587ebdd3a22a175ef32b9ebfc7311304b19cb3a62b5adc36f6afb6a6f7fabbf810ee89fdb72854fefd613e7798e9b9ff5938ea54c6
+Y = 00bd06a85e47b885c08124b55a3fcc07ca61647cda6efbfdbd21b24d1ea7a4c7300d46cd798e76063aa979adef6f0698b15e5b7ae8a2ab39ab4f50b2d20614db6317
+Digest = d59d1ff62ae0c4e41b3b8bfcb14f8d40b1774be1d9c6b44a60cb546a21e9f2ae5f4427d45f7fdd67e238ead3afa59c8d
+K = 019cadb8c7eb10565aa4567e0709873918720f0e4b42b4817afb0b0547c70cd1100229deae97a276b9c98ea58b01d4839fee86336d749d123b03e8b1a31166acc110
+R = 00667448a8bbef1c810d40646977dc22f3dfb52a4d80928ded5e976e199cbed02fbd5a08546756ece14548d721a6eb380d0e1a71ad0660dbcac6163c776eedd3e249
+S = 00ae7f0a238daaddb7fb4a1707fe5132daf653f8e19f732347134c96f1dd798f867c479a4a4609a568a15b61afed70790adbde13ac5f68c468d0230852c1a2c22581
+
+Curve = P-521
+Private = 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f
+X = 018b872690c37995be324ddb5c2bd5462841bb062f8e63da248a853de79c3d6bb9a2eb1e6933afda0998ca43491cc807b08ace2d5336a43d0ab50563a2d3d98755f0
+Y = 0002ff31221aa32aa6546f35e8fe5b9361f938362a5e89e77ae130ba8bce3729e912dfac35a2fd21efe84b45b8be2a340850e4b574e1885b35c2afbe196b57c6cf4c
+Digest = 6985cfbbd8dbf28558ee181006d07193feb1225ac9dd46e5da122759daa9ced6fafdb95cc407c217d9f163d7c04aaa8d
+K = 0098faeb73054639cb2e4442cd68e7b3a13f4b3f397a7b26f303afa40789f8ddd3d918f1ce4f0be53c8cb69c380744e2297d7fc01e2b3daef4ce64dd3a2644234753
+R = 009c0e7649f814f70a8416cb78bc4601472a363fe97f5c587305778169677860dd97f87b5ab07c3a953bc4615fc34634509d6a25621bdded33ed42446d059509c190
+S = 0120b90e1cfb8a1b5e530df7b17d1128bc051ca4f1a65dd9c9d9d3c59d2f00c7c1e994c52b8671d40294b4d574d2c04475d5bebeacd3a0d3870a54dc7a4805614f40
+
+Curve = P-521
+Private = 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e
+X = 0127279c88719dc614db387f102e55104ea1c704ac7f57f3bca936f728439b76556730dd7cde2ac1ad0a4c2c2f036ab6f00cf34cb87ea36113571f300713044106d2
+Y = 0134a0786c31f5f2291b83c50fb579ae4c620b95e5a8bdc0c7e1ee6b996c89d764f1b20403e7faa203f397425ada297045dd8ba0e4b155d4900da249e934faab7991
+Digest = 67d285cfc8eaaedab30be810129fcf06da8b091fa7f4bc49752fd707fbf2a9cf8bc5c187db6f6191b838873fb55c9784
+K = 008bffb0778cbb06466cecc114b9e89ca243a2b2b5e2597db920bc73a8bbcbe3f57144ad33409ef7faaab430e13f4c42d304d11347360c84972ca20b1539cce3a288
+R = 01f8f504e64a502e51e7c129517931c3b71f0d8a63b19cfe01ff7c951c6525249608b3ef5d00061d77eb6b3d69581adeaa3732c773bbb9b919c3e7c71fdc09f44d06
+S = 0058044fc64b340604ffd02a5b2918d76fd6fb59ea895feab7aa218e6f1e8c8f226eb9ee345ef8140183a69272582005077b008006aab11597e808d7ff1e8382c924
+
+Curve = P-521
+Private = 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89
+X = 01811c8884486aaa083ddee1c51cb6e861cb830bd5eaa929f72efadbbd1286566ae7e7ba7fde7e02529900d35ee64591652d28798bfc1bed0d192602a9cf5a7d22e3
+Y = 006d7fc9dd494816cfd29613d4689af67f7d0a2e6fbad5d4d6e0130189172a1ab601c5ca71deaa8bfcb5a190d49da191672ff6fc048e146cb902acec5eae6d87e60a
+Digest = 10bb638f2f48a8696dca63275a35428adfd6ae154923c8a33f06d23e4fe4c42edff1f382ef09fc3970611d0806abd630
+K = 01fdc4f108070af3c66c9ba7b6c1f2603a19ceb4760399df81228cfc7eafde1082b5a0716a3ff82fbe84726f14dd0db3376ca184a78c3c60679bab6cd45f77f9b9ce
+R = 01ec310339ff056faeb341c4499c43782078b04be1725ae9a6cdcb6011c46d1a4eb3d75c358225e4ec142fd1cd344186f5eb597f7ba559ddfa954824365d5b6edaec
+S = 0005b679a33fdb7e04834f071cd0ac514c04add9f2614ab9bbd9b407b1420fed3f3e02a108e7e279899e43dcf64ae4083c289a87cd7d2103bdc036a95d36800ac7c6
+
+Curve = P-521
+Private = 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a
+X = 00cfa5a8a3f15eb8c419095673f1d0bd63b396ff9813c18dfe5aa31f40b50b82481f9ed2edd47ae5ea6a48ea01f7e0ad0000edf7b66f8909ee94f141d5a07efe315c
+Y = 018af728f7318b96d57f19c1104415c8d5989565465e429bc30cf65ced12a1c5856ac86fca02388bc151cf89959a4f048597a9e728f3034aa39259b59870946187bf
+Digest = a02db3dbf881cbe8a90a27e6513d67bbf7b33a9d3d2a422ba1f4c42b7e21e0885dd86cb9a920f7c3571e8fbcd047ba23
+K = 009078beaba465ba7a8b3624e644ac1e97c654533a58ac755e90bd606e2214f11a48cb51f9007865a0f569d967ea0370801421846a89f3d09eb0a481289270919f14
+R = 019cf91a38cc20b9269e7467857b1fc7eabb8cea915a3135f727d471e5bfcfb66d321fabe283a2cf38d4c5a6ecb6e8cbee1030474373bb87fcdfcc95cf857a8d25d0
+S = 01cf9acd9449c57589c950f287842f9e2487c5610955b2b5035f6aacfd2402f511998a1a942b39c307fc2bcab2c8d0dae94b5547ddccfb1012ca985b3edf42bbba8b
+
+Curve = P-521
+Private = 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926
+X = 0061387fd6b95914e885f912edfbb5fb274655027f216c4091ca83e19336740fd81aedfe047f51b42bdf68161121013e0d55b117a14e4303f926c8debb77a7fdaad1
+Y = 00e7d0c75c38626e895ca21526b9f9fdf84dcecb93f2b233390550d2b1463b7ee3f58df7346435ff0434199583c97c665a97f12f706f2357da4b40288def888e59e6
+Digest = 65f83408092261bda599389df03382c5be01a81fe00a36f3f4bb6541263f801627c440e50809712b0cace7c217e6e5051af81de9bfec3204dcd63c4f9a741047
+K = 003af5ab6caa29a6de86a5bab9aa83c3b16a17ffcd52b5c60c769be3053cdddeac60812d12fecf46cfe1f3db9ac9dcf881fcec3f0aa733d4ecbb83c7593e864c6df1
+R = 004de826ea704ad10bc0f7538af8a3843f284f55c8b946af9235af5af74f2b76e099e4bc72fd79d28a380f8d4b4c919ac290d248c37983ba05aea42e2dd79fdd33e8
+S = 0087488c859a96fea266ea13bf6d114c429b163be97a57559086edb64aed4a18594b46fb9efc7fd25d8b2de8f09ca0587f54bd287299f47b2ff124aac566e8ee3b43
+
+Curve = P-521
+Private = 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6
+X = 004d5c8afee038984d2ea96681ec0dccb6b52dfa4ee2e2a77a23c8cf43ef19905a34d6f5d8c5cf0981ed804d89d175b17d1a63522ceb1e785c0f5a1d2f3d15e51352
+Y = 0014368b8e746807b2b68f3615cd78d761a464ddd7918fc8df51d225962fdf1e3dc243e265100ff0ec133359e332e44dd49afd8e5f38fe86133573432d33c02fa0a3
+Digest = a6200971c6a289e2fcb80f78ec08a5079ea2675efd68bcab479552aa5bcb8edf3c993c79d7cebcc23c20e5af41723052b871134cc71d5c57206182a7068cc39b
+K = 00bc2c0f37155859303de6fa539a39714e195c37c6ea826e224c8218584ae09cd0d1cc14d94d93f2d83c96e4ef68517fdb3f383da5404e5a426bfc5d424e253c181b
+R = 01a3c4a6386c4fb614fba2cb9e74201e1aaa0001aa931a2a939c92e04b8344535a20f53c6e3c69c75c2e5d2fe3549ed27e6713cb0f4a9a94f6189eb33bff7d453fce
+S = 016a997f81aa0bea2e1469c8c1dab7df02a8b2086ba482c43af04f2174831f2b1761658795adfbdd44190a9b06fe10e578987369f3a2eced147cff89d8c2818f7471
+
+Curve = P-521
+Private = 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f
+X = 00c2d540a7557f4530de35bbd94da8a6defbff783f54a65292f8f76341c996cea38795805a1b97174a9147a8644282e0d7040a6f83423ef2a0453248156393a1782e
+Y = 0119f746c5df8cec24e4849ac1870d0d8594c799d2ceb6c3bdf891dfbd2242e7ea24d6aec3166214734acc4cbf4da8f71e2429c5c187b2b3a048527c861f58a9b97f
+Digest = 46ff533622cc90321a3aeb077ec4db4fbf372c7a9db48b59de7c5d59e6314110676ba5491bd20d0f02774eef96fc2e88ca99857d21ef255184c93fb1ff4f01d3
+K = 0186cd803e6e0c9925022e41cb68671adba3ead5548c2b1cd09348ab19612b7af3820fd14da5fe1d7b550ed1a3c8d2f30592cd7745a3c09ee7b5dcfa9ed31bdd0f1f
+R = 010ed3ab6d07a15dc3376494501c27ce5f78c8a2b30cc809d3f9c3bf1aef437e590ef66abae4e49065ead1af5f752ec145acfa98329f17bca9991a199579c41f9229
+S = 008c3457fe1f93d635bb52df9218bf3b49a7a345b8a8a988ac0a254340546752cddf02e6ce47eee58ea398fdc9130e55a4c09f5ae548c715f5bcd539f07a34034d78
+
+Curve = P-521
+Private = 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742
+X = 0160d7ea2e128ab3fabd1a3ad5455cb45e2f977c2354a1345d4ae0c7ce4e492fb9ff958eddc2aa61735e5c1971fa6c99beda0f424a20c3ce969380aaa52ef5f5daa8
+Y = 014e4c83f90d196945fb4fe1e41913488aa53e24c1d2142d35a1eed69fed784c0ef44d71bc21afe0a0065b3b87069217a5abab4355cf8f4ceae5657cd4b9c8008f1f
+Digest = 6b514f8d85145e30ced23b4b22c85d79ed2bfcfed5b6b2b03f7c730f1981d46d4dadd6699c28627d41c8684bac305b59eb1d9c966de184ae3d7470a801c99fd4
+K = 0096731f8c52e72ffcc095dd2ee4eec3da13c628f570dba169b4a7460ab471149abdede0b63e4f96faf57eab809c7d2f203fd5ab406c7bd79869b7fae9c62f97c794
+R = 01e2bf98d1186d7bd3509f517c220de51c9200981e9b344b9fb0d36f34d969026c80311e7e73bb13789a99e0d59e82ebe0e9595d9747204c5f5550c30d934aa30c05
+S = 012fed45cc874dc3ed3a11dd70f7d5c61451fbea497dd63e226e10364e0718d3722c27c7b4e5027051d54b8f2a57fc58bc070a55b1a5877b0f388d768837ef2e9cec
+
+Curve = P-521
+Private = 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697
+X = 01ceee0be3293d8c0fc3e38a78df55e85e6b4bbce0b9995251f0ac55234140f82ae0a434b2bb41dc0aa5ecf950d4628f82c7f4f67651b804d55d844a02c1da6606f7
+Y = 01f775eb6b3c5e43fc754052d1f7fc5b99137afc15d231a0199a702fc065c917e628a54e038cbfebe05c90988b65183b368a2061e5b5c1b025bbf2b748fae00ba297
+Digest = 53c86e0b08b28e22131324f6bfad52984879ab09363d6b6c051aac78bf3568be3faeade6a2dda57dece4527abaa148326d3adbd2d725374bdac9ccb8ac39e51e
+K = 0161cf5d37953e09e12dc0091dc35d5fb3754c5c874e474d2b4a4f1a90b870dff6d99fb156498516e25b9a6a0763170702bb8507fdba4a6131c7258f6ffc3add81fd
+R = 014dfa43046302b81fd9a34a454dea25ccb594ace8df4f9d98556ca5076bcd44b2a9775dfaca50282b2c8988868e5a31d9eb08e794016996942088d43ad3379eb9a1
+S = 0120be63bd97691f6258b5e78817f2dd6bf5a7bf79d01b8b1c3382860c4b00f89894c72f93a69f3119cb74c90b03e9ede27bd298b357b9616a7282d176f3899aaa24
+
+Curve = P-521
+Private = 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04
+X = 014cab9759d4487987b8a00afd16d7199585b730fb0bfe63796272dde9135e7cb9e27cec51207c876d9214214b8c76f82e7363f5086902a577e1c50b4fbf35ce9966
+Y = 01a83f0caa01ca2166e1206292342f47f358009e8b891d3cb817aec290e0cf2f47e7fc637e39dca03949391839684f76b94d34e5abc7bb750cb44486cce525eb0093
+Digest = a9e9a9cb1febc380a22c03bacd18f8c46761180badd2e58b94703bd82d5987c52baec418388bc3f1e6831a130c400b3c865c51b73514f5b0a9026d9e8da2e342
+K = 001e51fd877dbbcd2ab138fd215d508879298d10c7fcbdcc918802407088eb6ca0f18976a13f2c0a57867b0298512fc85515b209c4435e9ef30ab01ba649838bc7a0
+R = 011a1323f6132d85482d9b0f73be838d8f9e78647934f2570fededca7c234cc46aa1b97da5ac1b27b714f7a171dc4209cbb0d90e4f793c4c192dc039c31310d6d99b
+S = 00386a5a0fc55d36ca7231a9537fee6b9e51c2255363d9c9e7cb7185669b302660e23133eb21eb56d305d36e69a79f5b6fa25b46ec61b7f699e1e9e927fb0bceca06
+
+Curve = P-521
+Private = 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6
+X = 009da1536154b46e3169265ccba2b4da9b4b06a7462a067c6909f6c0dd8e19a7bc2ac1a47763ec4be06c1bec57d28c55ee936cb19588cc1398fe4ea3bd07e6676b7f
+Y = 014150cdf25da0925926422e1fd4dcfcffb05bdf8682c54d67a9bd438d21de5af43a15d979b320a847683b6d12ac1383a7183095e9da491c3b4a7c28874625e70f87
+Digest = 7e324819033de8f2bffded5472853c3e68f4872ed25db79636249aecc24242cc3ca229ce7bd6d74eac8ba32f779e7002095f5d452d0bf24b30e1ce2eb56bb413
+K = 01c1308f31716d85294b3b5f1dc87d616093b7654907f55289499b419f38ceeb906d2c9fe4cc3d80c5a38c53f9739311b0b198111fede72ebde3b0d2bc4c2ef090d2
+R = 000dbf787ce07c453c6c6a67b0bf6850c8d6ca693a3e9818d7453487844c9048a7a2e48ff982b64eb9712461b26b5127c4dc57f9a6ad1e15d8cd56d4fd6da7186429
+S = 00c6f1c7774caf198fc189beb7e21ca92ceccc3f9875f0e2d07dc1d15bcc8f210b6dd376bf65bb6a454bf563d7f563c1041d62d6078828a57538b25ba54723170665
+
+Curve = P-521
+Private = 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e
+X = 000bbd4e8a016b0c254e754f68f0f4ed081320d529ecdc7899cfb5a67dd04bc85b3aa6891a3ed2c9861ae76c3847d81780c23ad84153ea2042d7fd5d517a26ff3ce4
+Y = 00645953afc3c1b3b74fdf503e7d3f982d7ee17611d60f8eb42a4bddbec2b67db1f09b54440c30b44e8071d404658285cb571462001218fc8c5e5b98b9fae28272e6
+Digest = 4541f9a04b289cd3b13d31d2f513d9243b7e8c3a0cbd3e0c790892235a4d4569ef8aef62444ecc64608509e6ad082bf7cd060d172550faa158b2fd396aa1e37b
+K = 000eb2bd8bb56b9d2e97c51247baf734cc655c39e0bfda35375f0ac2fe82fad699bf1989577e24afb33c3868f91111e24fefe7dec802f3323ac013bec6c048fe5568
+R = 014bf63bdbc014aa352544bd1e83ede484807ed760619fa6bc38c4f8640840195e1f2f149b29903ca4b6934404fb1f7de5e39b1ea04dba42819c75dbef6a93ebe269
+S = 005d1bcf2295240ce4415042306abd494b4bda7cf36f2ee2931518d2454faa01c606be120b057062f2f3a174cb09c14f57ab6ef41cb3802140da22074d0e46f908d4
+
+Curve = P-521
+Private = 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5
+X = 00157d80bd426f6c3cee903c24b73faa02e758607c3e102d6e643b7269c299684fdaba1acddb83ee686a60acca53cddb2fe976149205c8b8ab6ad1458bc00993cc43
+Y = 016e33cbed05721b284dacc8c8fbe2d118c347fc2e2670e691d5d53daf6ef2dfec464a5fbf46f8efce81ac226915e11d43c11c8229fca2327815e1f8da5fe95021fc
+Digest = 7ec0906f9fbe0e001460852c0b6111b1cd01c9306c0c57a5e746d43f48f50ebb111551d04a90255b22690d79ea60e58bed88220d485daaf9b6431740bb499e39
+K = 00a73477264a9cc69d359464abb1ac098a18c0fb3ea35e4f2e6e1b060dab05bef1255d9f9c9b9fbb89712e5afe13745ae6fd5917a9aedb0f2860d03a0d8f113ea10c
+R = 007e315d8d958b8ce27eaf4f3782294341d2a46fb1457a60eb9fe93a9ae86f3764716c4f5f124bd6b114781ed59c3f24e18aa35c903211b2f2039d85862932987d68
+S = 01bcc1d211ebc120a97d465b603a1bb1e470109e0a55d2f1b5c597803931bd6d7718f010d7d289b31533e9fcef3d141974e5955bc7f0ee342b9cad05e29a3dded30e
+
+Curve = P-521
+Private = 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a
+X = 007002872c200e16d57e8e53f7bce6e9a7832c387f6f9c29c6b75526262c57bc2b56d63e9558c5761c1d62708357f586d3aab41c6a7ca3bf6c32d9c3ca40f9a2796a
+Y = 01fe3e52472ef224fb38d5a0a14875b52c2f50b82b99eea98d826c77e6a9ccf798de5ffa92a0d65965f740c702a3027be66b9c844f1b2e96c134eb3fdf3edddcf11c
+Digest = 7230642b79eed2fd50f19f79f943d67d6ef609ec06c9adbb4b0a62126926080ecd474922d1af6c01f4c354affde016b284b13dbb3122555dea2a2e6ca2a357dc
+K = 01a277cf0414c6adb621d1cc0311ec908401ce040c6687ed45a0cdf2910c42c9f1954a4572d8e659733d5e26cbd35e3260be40017b2f5d38ec42315f5c0b056c596d
+R = 00d732ba8b3e9c9e0a495249e152e5bee69d94e9ff012d001b140d4b5d082aa9df77e10b65f115a594a50114722db42fa5fbe457c5bd05e7ac7ee510aa68fe7b1e7f
+S = 0134ac5e1ee339727df80c35ff5b2891596dd14d6cfd137bafd50ab98e2c1ab4008a0bd03552618d217912a9ec502a902f2353e757c3b5776309f7f2cfebf913e9cd
+
+Curve = P-521
+Private = 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb
+X = 00c97a4ebcbbe701c9f7be127e87079edf479b76d3c14bfbee693e1638e5bff8d4705ac0c14597529dbe13356ca85eb03a418edfe144ce6cbf3533016d4efc29dbd4
+Y = 011c75b7a8894ef64109ac2dea972e7fd5f79b75dab1bf9441a5b8b86f1dc1324426fa6cf4e7b973b44e3d0576c52e5c9edf8ce2fc18cb3c28742d44419f044667f8
+Digest = d209f43006e29ada2b9fe840afdf5fe6b0abeeef5662acf3fbca7e6d1bf4538f7e860332ef6122020e70104b541c30c3c0581e2b1daa0d767271769d0f073133
+K = 01e25b86db041f21c2503d547e2b1b655f0b99d5b6c0e1cf2bdbd8a8c6a053f5d79d78c55b4ef75bff764a74edc920b35536e3c470b6f6b8fd53898f3bbc467539ef
+R = 01dce45ea592b34d016497882c48dc0c7afb1c8e0f81a051800d7ab8da9d237efd892207bc9401f1d30650f66af8d5349fc5b19727756270722d5a8adb0a49b72d0a
+S = 00b79ffcdc33e028b1ab894cb751ec792a69e3011b201a76f3b878655bc31efd1c0bf3b98aea2b14f262c19d142e008b98e890ebbf464d3b025764dd2f73c4251b1a
+
+Curve = P-521
+Private = 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77
+X = 01f269692c47a55242bb08731ff920f4915bfcecf4d4431a8b487c90d08565272c52ca90c47397f7604bc643982e34d05178e979c2cff7ea1b9eaec18d69ca7382de
+Y = 00750bdd866fba3e92c29599c002ac6f9e2bf39af8521b7b133f70510e9918a94d3c279edec97ab75ecda95e3dd7861af84c543371c055dc74eeeff7061726818327
+Digest = c992314e8d282d10554b2e6e8769e8b10f85686cccafb30e7db62beaad080e0da6b5cf7cd1fc5614df56705fb1a841987cb950101e2f66d55f3a285fc75829ff
+K = 01b7519becd00d750459d63a72f13318b6ac61b8c8e7077cf9415c9b4b924f35514c9c28a0fae43d06e31c670a873716156aa7bc744577d62476e038b116576a9e53
+R = 0183bddb46c249e868ef231a1ebd85d0773bf8105a092ab7d884d677a1e9b7d6014d6358c09538a99d9dca8f36f163ac1827df420c3f9360cc66900a9737a7f756f3
+S = 00d05ee3e64bac4e56d9d8bd511c8a43941e953cba4e5d83c0553acb87091ff54f3aad4d69d9f15e520a2551cc14f2c86bb45513fef0295e381a7635486bd3917b50
+
+Curve = P-521
+Private = 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c
+X = 012857c2244fa04db3b73db4847927db63cce2fa6cb22724466d3e20bc950a9250a15eafd99f236a801e5271e8f90d9e8a97f37c12f7da65bce8a2c93bcd25526205
+Y = 00f394e37c17d5b8e35b488fa05a607dbc74264965043a1fb60e92edc212296ae72d7d6fe2e3457e67be853664e1da64f57e44bd259076b3bb2b06a2c604fea1be9d
+Digest = 6e14c91db5309a075fe69f6fe8ecd663a5ba7fab14770f96b05c22e1f631cde9e086c44335a25f63d5a43ddf57da899fcedbc4a3a4350ad2edd6f70c01bb051e
+K = 00e790238796fee7b5885dc0784c7041a4cc7ca4ba757d9f7906ad1fcbab5667e3734bc2309a48047442535ff89144b518f730ff55c0c67eeb4c880c2dfd2fb60d69
+R = 01d7ce382295a2a109064ea03f0ad8761dd60eefb9c207a20e3c5551e82ac6d2ee5922b3e9655a65ba6c359dcbf8fa843fbe87239a5c3e3eaecec0407d2fcdb687c2
+S = 0161963a6237b8955a8a756d8df5dbd303140bb90143b1da5f07b32f9cb64733dc6316080924733f1e2c81ade9d0be71b5b95b55666026a035a93ab3004d0bc0b19f
+
+Curve = P-521
+Private = 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63
+X = 01d7f1e9e610619daa9d2efa563610a371677fe8b58048fdc55a98a49970f6afa6649c516f9c72085ca3722aa595f45f2803402b01c832d28aac63d9941f1a25dfea
+Y = 01571facce3fcfe733a8eef4e8305dfe99103a370f82b3f8d75085414f2592ad44969a2ef8196c8b9809f0eca2f7ddc71c47879e3f37a40b9fecf97992b97af29721
+Digest = 26b4f562053f7aed8b7268e95eff336ac80a448fae52329d2771b138c9c7f70de936ef54158446afa72b0a27c2a73ca45dfa38a2ba2bf323d31aba499651128f
+K = 00517f6e4002479dc89e8cbb55b7c426d128776ca82cf81be8c1da9557178783f40e3d047db7e77867f1af030a51de470ee3128c22e9c2d642d71e4904ab5a76edfa
+R = 01c3262a3a3fb74fa5124b71a6c7f7b7e6d56738eabaf7666b372b299b0c99ee8a16be3df88dd955de093fc8c049f76ee83a4138cee41e5fe94755d27a52ee44032f
+S = 0072fd88bb1684c4ca9531748dfce4c161037fcd6ae5c2803b7117fb60d3db5df7df380591aaf3073a3031306b76f062dcc547ded23f6690293c34a710e7e9a226c3
+
+Curve = P-521
+Private = 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da
+X = 009ec1a3761fe3958073b9647f34202c5e8ca2428d056facc4f3fedc7077fa87f1d1eb30cc74f6e3ff3d3f82df2641cea1eb3ff1529e8a3866ae2055aacec0bf68c4
+Y = 00bed0261b91f664c3ff53e337d8321cb988c3edc03b46754680097e5a8585245d80d0b7045c75a9c5be7f599d3b5eea08d828acb6294ae515a3df57a37f903ef62e
+Digest = ea13b25b80ec89ffa649a00ce85a494892f9fb7389df56eed084d670efb020c05508ac3f04872843c92a67ee5ea02e0445dad8495cd823ca16f5510d5863002b
+K = 00ac3b6d61ebda99e23301fa198d686a13c0832af594b289c9a55669ce6d62011384769013748b68465527a597ed6858a06a99d50493562b3a7dbcee975ad34657d8
+R = 00cef3f4babe6f9875e5db28c27d6a197d607c3641a90f10c2cc2cb302ba658aa151dc76c507488b99f4b3c8bb404fb5c852f959273f412cbdd5e713c5e3f0e67f94
+S = 00097ed9e005416fc944e26bcc3661a09b35c128fcccdc2742739c8a301a338dd77d9d13571612a3b9524a6164b09fe73643bbc31447ee31ef44a490843e4e7db23f
diff --git a/src/crypto/ecdsa/ecdsa_test.cc b/src/crypto/ecdsa/ecdsa_test.cc
index 8d7827d..7c68de4 100644
--- a/src/crypto/ecdsa/ecdsa_test.cc
+++ b/src/crypto/ecdsa/ecdsa_test.cc
@@ -62,8 +62,6 @@
#include <openssl/nid.h>
#include <openssl/rand.h>
-#include "../test/scoped_types.h"
-
enum Api {
kEncodedApi,
kRawApi,
@@ -82,7 +80,7 @@
if (!ECDSA_SIG_to_bytes(&der, &der_len, ecdsa_sig)) {
return false;
}
- ScopedOpenSSLBytes delete_der(der);
+ bssl::UniquePtr<uint8_t> delete_der(der);
actual_result = ECDSA_verify(0, digest, digest_len, der, der_len, eckey);
break;
}
@@ -171,7 +169,7 @@
fprintf(out, "%s: ", kCurves[n].name);
int nid = kCurves[n].nid;
- ScopedEC_GROUP group(EC_GROUP_new_by_curve_name(nid));
+ bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(nid));
if (!group) {
fprintf(out, " failed\n");
return false;
@@ -184,14 +182,14 @@
}
// Create a new ECDSA key.
- ScopedEC_KEY eckey(EC_KEY_new());
+ bssl::UniquePtr<EC_KEY> eckey(EC_KEY_new());
if (!eckey || !EC_KEY_set_group(eckey.get(), group.get()) ||
!EC_KEY_generate_key(eckey.get())) {
fprintf(out, " failed\n");
return false;
}
// Create a second key.
- ScopedEC_KEY wrong_eckey(EC_KEY_new());
+ bssl::UniquePtr<EC_KEY> wrong_eckey(EC_KEY_new());
if (!wrong_eckey || !EC_KEY_set_group(wrong_eckey.get(), group.get()) ||
!EC_KEY_generate_key(wrong_eckey.get())) {
fprintf(out, " failed\n");
@@ -253,7 +251,7 @@
fprintf(out, ".");
fflush(out);
// Verify a tampered signature.
- ScopedECDSA_SIG ecdsa_sig(ECDSA_SIG_from_bytes(
+ bssl::UniquePtr<ECDSA_SIG> ecdsa_sig(ECDSA_SIG_from_bytes(
signature.data(), signature.size()));
if (!ecdsa_sig ||
!TestTamperedSig(out, kEncodedApi, digest, 20, ecdsa_sig.get(),
@@ -313,7 +311,7 @@
static bool TestECDSA_SIG_max_len(size_t order_len) {
/* Create the largest possible |ECDSA_SIG| of the given constraints. */
- ScopedECDSA_SIG sig(ECDSA_SIG_new());
+ bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
if (!sig) {
return false;
}
@@ -328,7 +326,7 @@
if (!ECDSA_SIG_to_bytes(&der, &der_len, sig.get())) {
return false;
}
- ScopedOpenSSLBytes delete_der(der);
+ bssl::UniquePtr<uint8_t> delete_der(der);
size_t max_len = ECDSA_SIG_max_len(order_len);
if (max_len != der_len) {
diff --git a/src/crypto/ecdsa/ecdsa_verify_test.cc b/src/crypto/ecdsa/ecdsa_verify_test.cc
new file mode 100644
index 0000000..18340e2
--- /dev/null
+++ b/src/crypto/ecdsa/ecdsa_verify_test.cc
@@ -0,0 +1,110 @@
+/* Copyright (c) 2016, 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 <stdio.h>
+
+#include <vector>
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
+#include <openssl/nid.h>
+
+#include "../test/file_test.h"
+
+
+static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
+ std::string curve_name;
+ if (!t->GetAttribute(&curve_name, key)) {
+ return nullptr;
+ }
+
+ if (curve_name == "P-224") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
+ }
+ if (curve_name == "P-256") {
+ return bssl::UniquePtr<EC_GROUP>(
+ EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ }
+ if (curve_name == "P-384") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
+ }
+ if (curve_name == "P-521") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
+ }
+
+ t->PrintLine("Unknown curve '%s'", curve_name.c_str());
+ return nullptr;
+}
+
+static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *key) {
+ std::vector<uint8_t> bytes;
+ if (!t->GetBytes(&bytes, key)) {
+ return nullptr;
+ }
+
+ return bssl::UniquePtr<BIGNUM>(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
+}
+
+static bool TestECDSASign(FileTest *t, void *arg) {
+ bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
+ bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
+ bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
+ bssl::UniquePtr<BIGNUM> r = GetBIGNUM(t, "R");
+ bssl::UniquePtr<BIGNUM> s = GetBIGNUM(t, "S");
+ std::vector<uint8_t> digest;
+ if (!group || !x || !y || !r || !s ||
+ !t->GetBytes(&digest, "Digest")) {
+ return false;
+ }
+
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+ bssl::UniquePtr<EC_POINT> pub_key(EC_POINT_new(group.get()));
+ bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
+ if (!key || !pub_key || !sig ||
+ !EC_KEY_set_group(key.get(), group.get()) ||
+ !EC_POINT_set_affine_coordinates_GFp(group.get(), pub_key.get(), x.get(),
+ y.get(), nullptr) ||
+ !EC_KEY_set_public_key(key.get(), pub_key.get()) ||
+ !BN_copy(sig->r, r.get()) ||
+ !BN_copy(sig->s, s.get())) {
+ return false;
+ }
+
+ int ok = ECDSA_do_verify(digest.data(), digest.size(), sig.get(), key.get());
+ if (t->HasAttribute("Invalid")) {
+ if (ok) {
+ t->PrintLine("Signature was incorrectly accepted.");
+ return false;
+ }
+ } else if (!ok) {
+ t->PrintLine("Signature was incorrectly rejected.");
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char *argv[]) {
+ CRYPTO_library_init();
+
+ if (argc != 2) {
+ fprintf(stderr, "%s <test file.txt>\n", argv[0]);
+ return 1;
+ }
+
+ return FileTestMain(TestECDSASign, nullptr, argv[1]);
+}
diff --git a/src/crypto/ecdsa/ecdsa_verify_tests.txt b/src/crypto/ecdsa/ecdsa_verify_tests.txt
new file mode 100644
index 0000000..a1b4cb2
--- /dev/null
+++ b/src/crypto/ecdsa/ecdsa_verify_tests.txt
@@ -0,0 +1,2346 @@
+# Tests from NIST CAVP 186-4 ECDSA2VS Test Vectors, Signature Verification Test
+# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
+#
+# NIST's files provide message and digest pairs. Since this is a low-level test,
+# the digests have been extracted. P-521 test vectors were fixed to have the
+# right number of leading zeros.
+
+Curve = P-224
+X = a100d410ce497e991070285c439cd361a1a9c6c973fd6f5e1ba9ec66
+Y = 0a8c3a2f909f212c84441b8c0030529cbd731304d86f771d89d7cc29
+Digest = 6a02c84186eb132d8e91ab6fea2e066f6f8de1a5
+R = 1bfcaab01e47addd4733369320364ad208169ffb15e6aac33c2d7c06
+S = 07fb33465e7b7b373feda2ea35ab7cc9477156a1335ecad942f99627
+
+Curve = P-224
+X = a6cd3d14cd5eb188a9f59d9c32e93d890558de382f6fba5ff5c6e395
+Y = 7a76734a0afead9e5e4aba65f1ae353d6445b1689b5ea402de5f9af9
+Digest = ab1205b7f9f591a013c70cb645435b38689644c1
+R = f0f670963c3d2a3281d639f850f3781c6402d99a1bf07cd9f35b2975
+S = 758e84920c1b744502cd787cdd64ec58364ccc6917258a2580097492
+Invalid =
+
+Curve = P-224
+X = f5fe7875a517207f1336ec2bb4fe5cc7eb80ee2b0f8ebeff4c56e620
+Y = 0b7ac24ea9092d03b28904d89714b517be023235abc9cffa297cf4ad
+Digest = d62c7a42fcf3738276a6e0d27160328e9f27e5aa
+R = 88617e694e361d2cfef6b0658d444607fba030ad31fe8dead14db22e
+S = 5b0bf37c4a583dd75d99aec20943ea02617cecdbcd295d35ed01cc32
+Invalid =
+
+Curve = P-224
+X = 8a6a77179ffc0ff5d412cf859cc82aa19cd18e5224ab997e9c2e46b0
+Y = 3d67c177ca7cc12c7b05a3bf55fb78549ef5400a566efe8ae3580c9f
+Digest = 0b5a025a4038b6f9f995001c0b8d7a660e6766c2
+R = 107b7442e6569ddde54b5da55a9dac9bd348079358047a19a3de0b91
+S = 92359be39353cb263946294fb728eecf1880f50a43637f391d3e7824
+
+Curve = P-224
+X = f9f23388d573562f29e7e7c9a98f27e7a1ff02d2d66e177c6506466f
+Y = 4545937caf1878fbacc34ca38a0e5e1f6ad2b25ddd796d06c8d12351
+Digest = cf670c7589b91dac6a131fe2e863e86ee790ca75
+R = bc1db32e437c67439c27db1dc607e3c505210c984bf707a8e87abb70
+S = b760f4943a2397311e54e888a1ad379ad9c45d1fd09b5389ce1a00ee
+Invalid =
+
+Curve = P-224
+X = 8781e5a98950092570d685964e9ed27760fb7dcff8d3b6f3c8f77151
+Y = 9207cef64b7c2ed181c57337001f45f1e800e0d1bc8adac296e454b5
+Digest = e5e5e8c8b3f7146c72ef86ca1b75f422181b5729
+R = 79826ae5b0297b9404829df0f02bbb7b8acb35459e13a4045c40f242
+S = 2a629dab19c9e5cd0a551a43851fe6d8409469f86cbcf6204b41e5b5
+Invalid =
+
+Curve = P-224
+X = 03c78c532b8767784fd45e75027abce3371181f8f54914811588cbb2
+Y = 166c7b70e98fa11ac361d827557676ec07e553370a462b4fe502dedb
+Digest = 270606c9c9b136ffada9588f15f9786455369422
+R = ff18b493b166d832c9c25ee491525e4c188ff2b804e38b5964941c48
+S = bbf4291db484b4e4143c01a284c03543bbdaa2db1f1c571f1e5a5e2e
+Invalid =
+
+Curve = P-224
+X = 99fab11464484cee96d72dfcf0327d671787a2f6ee32f9b184c48fec
+Y = fe8ec3d660cfa3f3e09e5cfc2c3298d4de2f464416deb5b4a27ac062
+Digest = 9c77c796ba619aedef68b2d30b4ba00c4972488b
+R = 714c48c143cb259408c04f77a38d6484e788cb268fc9789d5e871491
+S = 542793d5dbcabcebc83a809cca02b8e95189c93fa4e330d66d5a62ef
+Invalid =
+
+Curve = P-224
+X = 014e8e57388eba32ebdce80df60c481e5c7758374f90a92e0a82f1b9
+Y = d1aa8418f992283c5b6bb0461f05dc9103050dc55e0265e1c99b935d
+Digest = 82b45d1fb3bb502c7c20ee1e2d63f2aaa9f492ab
+R = a159b83e80e656f54f614e8437821bd87f6f13264ac8eca1b3ddde29
+S = b77b7bc8cf374f012ee15f9f9224a46a560a5b689cfc92ca4fa03459
+Invalid =
+
+Curve = P-224
+X = e0b9e3cadca81311923d6d6adcfc326b62fac9c4b8d61c5f960c88fa
+Y = be505338108f8d3f0ee80aefa304d51dd4a4035477934a98a6111403
+Digest = f4da99fee346e572906e6dc8083a3d0c2e09b773
+R = 8dba585dc3312056a7be61161c7af8ba8b538f0c125c80cf9af2682e
+S = 1b5b1adac4d66c7045f3f79c3aa154a0274c4a994ac7a093e2482eeb
+Invalid =
+
+Curve = P-224
+X = 29197e94a3617e62d9999c859640871a4537a073ca4f12a4c324dcad
+Y = fe198969ac7cbe49df2c61c4cc6fa502c2207a7da10acdccec7b1cad
+Digest = 58fab970cb7c1f0dac21b7c7fd67d0ad169688a1
+R = 261670b09afaeee71c590c5658e3f57d859b18a887f70fdeb90e57ea
+S = d1d12c11cf7f4a9dd015ead4bd245793cb37ffee1f4cf109b7b68394
+Invalid =
+
+Curve = P-224
+X = 0fac352c1c444435e6aeb1d60f28ac773b0170ae902afb0944ef0a12
+Y = ac3ca693a7c5347a074808b43edea94059e2b1d0571d935fde3f5841
+Digest = 4b69dbfac12f1b974566d8170d1672d0f5fc0506
+R = c33c7a4de313ff856d2f51cd9e3d173bd10668c296f0e6b208c036ef
+S = e562d30822b5cc69713a57ce8c70f83827add85a06c88109505ebf7a
+Invalid =
+
+Curve = P-224
+X = b0d4298e998b7d9d4509322a1ac974c6180956533debafd3d9e7f2fc
+Y = 185a64ca840d4b6a2800e72433f26dd523f97daadc18d6d01533f0ad
+Digest = b84805c37e76e530729ddcb59a68ad69d40c82f9
+R = a5155ce53050cbfe84b67d62ce118c6004564087f2fe1cdf44e9c945
+S = b6894b050d77a3ff4d191ddc0c9fc7009a7472e31739949193d7cceb
+Invalid =
+
+Curve = P-224
+X = 59996a4a06658e553fc2993f0f55e3fc8ca2cb52d30f882a37729be4
+Y = a5f68f26ea6608fd1f350d8da7c187c7e70f23363177a5aa41508fce
+Digest = ef0a69578d8a1dc930803a7ad2a92c3c19ab6513
+R = 704ef49e0a43c61ef5b325899acb9d12287883a849976c8b9c950634
+S = 73da6e3a26d5c512405fc09fcfdf650dd8da748e6c3dfc05032d7a9f
+
+Curve = P-224
+X = a0cfdfc5a096b0b23ba6748ebaad17e60228b204aebdc01057a7154b
+Y = 9f6bd5369d21d88d7b5c3ce221af530fb9a8fb91e751cdb855ff32a6
+Digest = b05f0232e6d44151e249e7b75c7c9ab05c14d44b
+R = d68aa9048e84b8653b8ff3ab31bc73884c6ac7df1fd1bd3c38c16b0d
+S = 38ce58afe5fbc6af892e06a4ddd978c745d5ec700cab825c11dd8fd1
+Invalid =
+
+Curve = P-224
+X = f1eb36b3e1c96a18d87878d5fa8b79d77afce9d2ce40d26199f33482
+Y = ae819af474f3efbd62401a407036505c5a2d60449274593865de3374
+Digest = 1dd27c95dd6fb3f080afebdf5a1ad906502e12ab8f64e5f38f67c386
+R = 003122e976bac378c06ec95fd73290b067e7ff022d23493c40663ec9
+S = b99eb4220146a282c7a34f98a9a4fa38ed3f48ca2c7983cde2d3235f
+
+Curve = P-224
+X = 3bdcc7c6112cde3c0522f1a4863f1d7b6727c5bff67598ba2f1bafc1
+Y = 47acb6b254e0e8747e0039de471d0dda443cb09a592c678717d83200
+Digest = 19b39292f4e862ed3ee90c35e709587231191632dc8b35611dd24abe
+R = a5aab7768f549f8fe3c7e650154c865b71ea5089bd6303bfdfd19316
+S = ee4989c4b96bcc802464fe44b2adeb1b3506755a3f4fb3f9252bf21b
+Invalid =
+
+Curve = P-224
+X = 6d5bacf458cee3ded627d0ff14fd2aeb54fe1455d6daaf7bb43faeea
+Y = caecc8d3967ca1c8889607e9ed975b8a335a17c0acbcfbfed721ee1c
+Digest = 328ab7d2a7c56d09cb72cedaacc23a6da46d5cf984dfdfd16af60964
+R = 80e7024bf30ecddf7a658785ae51cd6e5a23963c89ee96a82346d889
+S = 561252dc8d9280fc54da0046da494fa5e4b7aed213923e8b894a1ae3
+Invalid =
+
+Curve = P-224
+X = 7f9789c729355516588a5c75cb2cbcf85a14c35e14a5d03b4ef920d7
+Y = 49e95c49e62dd20f02ed16594f35ebf3415ed50e6efdc0c548101a9d
+Digest = c5bb2d7ca9b37af1f4bb572ae6b6e69e8fcab9ac1cc5a6e1b6d1f8de
+R = 3c7b664413c2a0e4682a9d1c88243a96196fbd03f72cb873b9bee8b9
+S = 8f7f81ee9d3a2660ab1d666bac6cc434143ca9b04ff638ca7b4aa1ea
+
+Curve = P-224
+X = fd3efc7108edbe155adcd8686d8605e811fa79756c7e2dc8c1c04212
+Y = 59edea73a4e5f91541fb4cabce539afffa85b6b0113289f049ce60a0
+Digest = 562d1a8fa642dd8bbb4f4801f2d9fc8cf3452be916c0ecd6c8ddc4fc
+R = 4907884b8b7d0eb9a7b24420f69c58e3a17314e101da0280c0ceb130
+S = f7629bed92e5c40f35d7731912fb45a3cee06eab3d409a62997f2282
+Invalid =
+
+Curve = P-224
+X = 8b3f3e31d9c8408a39997455ffe0240fe128a5f1be9b3a33a97b0910
+Y = d74ac6ad8de2407887c335bd66f684454dee175a2af713bb334cb3fe
+Digest = b57ffce01c72221c6714e4a38c76746c45a8cc685f37c55a69f6773f
+R = d28ae763c22f50ae9ee9fbe5bab682fd8d820b99ab70677cc46624f7
+S = d9fa54d0300a6ac74936e7a47fbacadcbb4b25ae3a5b550aaf53991f
+Invalid =
+
+Curve = P-224
+X = f4fd02f3d224727e156a2cd7543483f3e35eb65219e32c7923f93ecf
+Y = e7aa734828ef326259f98e0e8c3f30b62bd3295c6d1af2c429a087f6
+Digest = 8e70efc206d69d1bd1dce263a29a56030ad5602046bc61848899474d
+R = 9f57e28f69d2ebd96f6d98903156a4e795730e09fb67963771b0a851
+S = 8cfe716488479e04500c8eccdc86fdd54ff00258639f7177169e2030
+Invalid =
+
+Curve = P-224
+X = 0fdb8faf52d8f46229cca1e0f22e869a91bd56eb6dccc547151f9c68
+Y = 96c8d1946528bdd2c14c3a0a9c17a088d3f0599752d095ba9de9ffa6
+Digest = db452771046d4b64ba673771b49df905881df9c4b6a1292a11f87515
+R = c53c0ce7d408278552a5fe5854c05641cbe93b1dc18eff1c68af53c1
+S = be7453a12693ce7812fe58746323882bc14eff972480b49431cb10b3
+Invalid =
+
+Curve = P-224
+X = 240431da69703b32ba2ae501d2458b355b66170725806b45996db195
+Y = 13beb5198ee00abdcfb2cc5454416d4f7c795e97a14bd93cec3f0a56
+Digest = 3598d7d7b2cd9e482fd3bbebb9ae4549a4b452c81b89f3da6f6f2e85
+R = ad03bdf64e3450407a2a977e1985853d6ea41568c3a394d696de6739
+S = 7b55db9abf2045e2dc7ccfa2e8fb501883c494662d400590c74d100f
+Invalid =
+
+Curve = P-224
+X = 8c80c86f91b1e330f86f5177fdba839e625a27e8531f232efb10a484
+Y = a24deab8978dfe7398f7a1da0633ff7cf5aa7b7365ce2d840ce81c80
+Digest = 44603667b2251cf051cd67b927714d67a25295679d884c4b79099a80
+R = 0c422b292308f31af78b1261d12765cced1cf96a83a6bc3bd90330fc
+S = db34f4462d0bb1927cc99273dc92d3fe654c85a3b53c6d74ed900621
+Invalid =
+
+Curve = P-224
+X = 3a5d1b7ee6749630c9619789b256f6bad5bc4b09950cd53b78d5ef30
+Y = e85c7ee707df680eeb5fd78451f7302ae653f96721443826096f62a3
+Digest = 2ed9e7077df2ca2f8a96dfea2127b1b34147fcf963f9d73e8aff9df6
+R = 671ad280609364b0e26c92b13891f677db7c83499d0a3d7b6d80affa
+S = 7c4b9c5a3937d540ed8bd59e340c13f02313445e06b2bf7525f5726a
+Invalid =
+
+Curve = P-224
+X = 350f59509abc9f7f9b35a8b80065258727a8ffc27e6dac635ed68900
+Y = 634fceae493b200cc7680297fd940dd86a5111da14bed68c797ef254
+Digest = 012a6edb0064f2b734b0297ab924efcb0e653be9e6ae97c371d59680
+R = 13a302b200555a0e80584e6ede32c0f9c5a199125b219c3e8d0fbf96
+S = 13f1d7b0c87acea6290cd9d36f1820f546f83dd8d7d9abe9da5812a9
+Invalid =
+
+Curve = P-224
+X = 1fdb820003a2fe61deef2b68b92ac711abc76200c534ec3abc99a187
+Y = 32f87d0554b6b5e389311fd3c86825fcd42654a0b6f5d4d5ba73031b
+Digest = 2afe40d5042eb4020b14053e9ead6774d566e0b536912b7de4450090
+R = c03e551abcb12eadbc291b2d5fdd53bf725b785933e0766969f0355e
+S = 94826a8753cb949e0199be3220b4f90318f1c835cdd67efc50df7fbd
+
+Curve = P-224
+X = 208dcc6c87e7c38bd914bc9b350602ff62ac62fa4fd633c1af5b8cd7
+Y = 0263587c7692c8be1f78de88ed6dc99ce1198ecc53a77ae6cf98a323
+Digest = 3f95e73294defecfc125a2dbbf322d31f323c030adf244c07a7c8746
+R = c12d3b396e1a894dfe4a28971ce4983547596879956504e1a3aed75c
+S = 067b729ca23be6cd520fbe9b972b9bb3d00c9ee96832a5c35e20e0e0
+Invalid =
+
+Curve = P-224
+X = a66a652fa36413dccd72c83febedda051182dc5758a1466366197f5f
+Y = dc813a79e0fc647d8892dcf4f2132c90914a520cbbad65f458ee0fae
+Digest = 8a8942761ccd4ac7c88c4afcb6bc69d431cc3d10e6ad7a2b8610892f
+R = 809d1b4557eaf36b6eab3449dad56e61d572bd8b63d51b63af1b0bc6
+S = 8bf88226a463606ab57c27ed78f1b71ccd61732fa58b62ee845fd3dd
+Invalid =
+
+Curve = P-224
+X = 8856fb8b81a4eacd971a954560018f33cbb71cc1fc243d03f63cabcb
+Y = 28afa26baf31b4d89de1dadd2289006f836f23a11383817ec7e4e799
+Digest = d8454640ad1f4632cc667823418ae56c62028825d727adfc84afdb0842b0c9a4
+R = efccef331805e71bbf876cbbc2342a6bc4508aea7c691029c8396aef
+S = bed544d09e28dbf01a30b2cfb61b98ad6201a9818f22b4f543f3e7f5
+Invalid =
+
+Curve = P-224
+X = 34c5ff3de565b85bfdd9f0a8b3fb0d46f924c57b276bcc830a1ed580
+Y = 609d22200ef38b410da77f7a8ff2f58448188042978fd9ae1b2b4477
+Digest = 831979405db4eb9dadf01249fa15f68d4846e0ece70a320d3022f75f3dc281cc
+R = f0138024fe0516738f3bd0e0fec10defaca8c3b89c161a77489cf2b7
+S = 4ae0934266d9e3d64c2a12f546b132ba0f33ef50abc90e7ef5974805
+
+Curve = P-224
+X = 465afb14f4bf85022ac1f635f46c0b2f6548bace9352d32f74eab012
+Y = 036371a3246dbf1069d2d268ca431553d1f2bf0181225145881b7be0
+Digest = 489cd3c10d94f7f284bc4ea472634a5d7f0d280d5abbf139c110ef80c8bf463f
+R = 9bcd57a2fec2518903e4b13dc0a7b84bafed5c4908546e94ffae87ed
+S = a337e06582f6b3973df38b93a0fb2a63f7774b62db50dba557e5cfcc
+Invalid =
+
+Curve = P-224
+X = b8b7f923c05ec95ebd484db7c58d219cfd26ee6b66149631f25ffe4c
+Y = 6bda5f4f988784555a80b5494eca51ad2c7f88ce94d2090ee0c76fba
+Digest = b100feed0121d9d0471e5bd94a659510c2f84e313f476431deac17ca6d87bd79
+R = ce4d86bf5a7543d1cba8e4470a297e9a48d0096d7788c6284b1c0af3
+S = 229eb0636ee62508ce3719396d7577ed892cec70a66857fdee0d1fa0
+Invalid =
+
+Curve = P-224
+X = 13e84ec2eb993818d7d78330855ee2fbe8ddb548a5e4198e2087b3b2
+Y = c95dff249e10c506fb547a92ade53c61ddbb667c760e4127a1a7f806
+Digest = 21a9f65d4cdcc287e0bf330e4f76f1168d16d0cea796dd6c0e13cd2837decaf1
+R = ed26f00ed696e114305c546ed04db5fc35efa43059c0d8bbcd418d0c
+S = 6e16efbe9501e3055d74966a49232cd76b5d1241468788b4cc7378b4
+Invalid =
+
+Curve = P-224
+X = 16c23c93699cf665a5da8b2d4baa72c36158d3433b1b945e47204b0d
+Y = 12023703e1b59ec9054ff22d15567b9f74058b47cc13f2ca08ab77c1
+Digest = d62496d0ee0453e7f13f8d9c57adcd33442a5365f626381ed665f95f528aa198
+R = ada849b673a1bd2949a8b4d8fdfc239ec53524a356d37da3c9d17ae2
+S = 698de3a3d8697c2e8e5b2c85fceb8796750c5b44154f01ce86d99e24
+Invalid =
+
+Curve = P-224
+X = a580f9a0cd15abff8e1e712f16b0fd4142d0d773af3c657abc06c2a6
+Y = 22c6286340dc072e64274209eda60503047700571caee64b4a2306c2
+Digest = 25ef291dd6a2047ea193f8aedd3f4692f2c135cb519922a17cba3e969423b030
+R = c6fae06274dc052e482102520b49d4ccc4cb7eb8a3ea41bd3680ddad
+S = 50d66b75a2bbd0468be1f9e61bfda85b6329505b0134d60846cbe4b7
+
+Curve = P-224
+X = 0b4fb6fe5f6cf6adc7d28683628d4b9c569d21d2397533f5bd121a23
+Y = b44d60a3414b9b7b6e4ad735ce2f9cb05593b0874ada5e65acdead4c
+Digest = 7d53ebba0424c4b6731806407f97af4af863a5a87c759626830c9e8753ca50fe
+R = ab5ac2039b49690c6436793decb1a6a58ac34833a8091005312a93a7
+S = 98fe955cd836501cef78c7a05fa27edf2fb3afea80990028ff64e984
+Invalid =
+
+Curve = P-224
+X = bae2b3634c7854c932551ece8dced2139a51705059503881a9239c78
+Y = 094d5e455bc9296202618d7022512b0f9ce53d796c7294e6eb076a29
+Digest = bb5c0917ec5376b2c685f3a530a9f8ef1ef1c1b398ab66f479d936cd662efc1b
+R = 2fbdc7e9e98aed5dbbcc5b034e17a95209e2fe1b01515426b8b372c3
+S = f2b19226528f10be6ef0d27ec3703db690261206b7e42f93a691192e
+Invalid =
+
+Curve = P-224
+X = 49d9ff4f4bbd4320b6806a7fbaaedd962283c766a6c130e4b62139dc
+Y = 06dbe8e7fb8fccf9758101ae46939c6fd4d3afc526ba6c8156c6b013
+Digest = 9a113d3d73543e17faba847981e0b7fbc5647e547bfc989921ddc987133692d1
+R = 2d83aa59bcfc8a0237884826e08dbd78a56733598e379f2a9d51e9e2
+S = 485036c74618d0e665775fbe2d614a313c550f9826b955d3e5636fd1
+Invalid =
+
+Curve = P-224
+X = 78451cca49655978b65d8ddd45ff367c47f321f5d55ddac7969ab82b
+Y = 25b77f820aa9ec93ec89d7fc84285f3f3deed496e0cd3fb9ee4a5c99
+Digest = 352afd36279bee1ef5727c55c7428bb79db949a9f1953eb98cfd38c4a4a458af
+R = 998789490e008ed11febdfe2981a55c733eb9739d7f37fd5c2a7ec96
+S = c3ec8afade81860ff23cc1e7d759d32d9a5775886ef17bfb719df4aa
+Invalid =
+
+Curve = P-224
+X = 18ced60b7fd9ebf76c3aa5976dcbdef40bd3e36033c013553043dd84
+Y = 30398582dbd2004064f8055e7fe0fe8df11b2c9d9e2931ad12d09628
+Digest = a1e3668af6307f6a2b7414079e73308ee0836b588b92a48bd5baa9a62f45b0f8
+R = f880143960e812464810c175001b5d39592fe63aab544deb9ca301a0
+S = 1e0657df071a25dd791264b411c8964688f4fe17ce024e659836ebe1
+Invalid =
+
+Curve = P-224
+X = 5d67c1fca848ba7f3d9de5b1894d3993ac4ebe68cdb0b49553b3b0e9
+Y = 07c219a8323273c81f5694306d0dd1d133a49efce5003bc90f05578f
+Digest = e8f714f901cd2390c66f9fa9cb81ecc5f17a82bd934cf19c5ce2bcbd3a985de9
+R = 767cb6b2efa7a40739830659b0cc24fe3de771d00104b3dcc0f640bc
+S = f2e7268bc011d79d33f3551d2edd3c95f324955479b8e29e8aba629b
+
+Curve = P-224
+X = eac72b399cb791b3ed25cb0a49eb157e69603197e0327eac5448680d
+Y = bdab3a2270066e74e8210eed7b5d43fba1e26845b6c037a8a7e2a13b
+Digest = 74aa7c8f25644514582fa904cea1ea88a0b262ffca43cdf6536ad97d8550616e
+R = 55485947e9e3c194a29c8ecaddb18eefd16fb6919aeb0bbbd8c12369
+S = 6309a2cc7fdd9eccb32b86d5577aa54ada79899a9645f2e299630d31
+Invalid =
+
+Curve = P-224
+X = 17f741267bf3e8143046707d41eafc9555953fe5f57d6c035452b232
+Y = c667554d9a55fc8ab1062203dcbcd2bf9769c696a295350cb28aa01a
+Digest = 3b997a1c220593cab4301e07886db745436911b8abfd9d1b03cc12e1c7fa4510
+R = 57408bfcc68e60ad000eddbfe6eccbe5f87b98c95de0e0a2e065da92
+S = 51249bddc149f0942be001b2f3d6f6d17a0cc36fefce147058944667
+Invalid =
+
+Curve = P-224
+X = 3297edac34cb802df263f8d366f62a8b746c316adfb1c84a1c79c58c
+Y = 79fe82e87ef5879c12eda6adda198a662fd77afa6a1fb5696cb7da9d
+Digest = e71dc3ab7ce73995d053bc6361bbb3f20e39ec2f295d97fa2bd229ed31a56dde6bf2c9cf6b0a9cc7e65962c57f3662a3
+R = 9993defdcf83965723c03e04ce6c33b3972cef3c449cdf1bc69990db
+S = 553b22a4164549f16aa1a928eee74548fc141fd3c16f213318965974
+
+Curve = P-224
+X = 2bc010527ea7427cedd213aeccf0c62dc513785888c6373740139d8b
+Y = 2e9eb7ddf027ff7678ca880511be147098b34d8e77acb4389fbc6e50
+Digest = 781195b6396344146fe8b73a2526b4b1c981d26b9adcce0123176be1239f798c847495fd714661d1ba8e41f2ccfd052b
+R = 70a7cb04295a53b4a3a695ccb5d87856fe9152fce11987d4c43207bd
+S = 49f4094368f2de9327ca2913ef940e17c5801e8f589413838831083f
+Invalid =
+
+Curve = P-224
+X = 55c6217adbefff6e21bfb5d1b75213ce7b20c900d514ee094f27ad0d
+Y = a68ae9f86eb9c10de3e7d9b03868518f33f571f85c3529d2902575d3
+Digest = a318b24bbb5ba46e6656f8ad68201c024e7b3b3849d6a70f3abce8c20f5b98ae43a326f5f48994045f0ff27098837b5b
+R = c073fba87267b45853e693910c1de791908ca7a25c1716ec2d3cec71
+S = 6138c86daf1021ae4af0faaf0abd5958f93944d5b0d82c40214bacca
+Invalid =
+
+Curve = P-224
+X = 4d0cab0dae88fa0cf53a2a6562934e0cf0271cc7fe54a30109a232be
+Y = 70835833cf9e1f989a18d419e7bee9eb5cef1fd145cf62c4411c372c
+Digest = 6abbf2557f2e9b4e020126f4a87fb0262a1ec59bd3b569581048c5692f8a1cd381ee9c3cf195fa1a362a87ab604d79b3
+R = 3b8548eab4dc123e236133d826f2badbde96f92249f456e33ccc9739
+S = c82b2e41b9e2b21594cc03b1c0de216f183403c6025e18bb29bff421
+
+Curve = P-224
+X = f55a53b818b3ec4b4402a2c63429c1d78f2cd0d8d202e33812878a03
+Y = 5a2b1a00615c56b4313828bd70526b12f402df1d40fa4900c994af8b
+Digest = da8d2571bea9840494a41f03c6c357410de030a7b5c023a0487020bb5b7c45fb6c5ed0e3dc66e4c0ab8460d9bda68c94
+R = fa934f9fdb765fabb5693ccb1de4177f172a8de108805a48f4bb989c
+S = 12994f2a26252742667044a01b509b0f315e8141629f760267b850e1
+Invalid =
+
+Curve = P-224
+X = 40a5c52dda7de858a2c17d12856c552ab820023336b9b4fc196bcd67
+Y = 301e5368f59c00f15e6f3a91510444fb75a4ead8efb0778b4419e7db
+Digest = 0f88ea2d9dd40c19cd31c7a7cff71379431c9dc0a3092041a5fcbd2c20a05a8cb6e5a8aa143f1dfa169d2eaf87d01e26
+R = 0fd8773fac425a2761b954c946020615336d3e350ae40743641917fe
+S = d59f2b806ccecc444f9387f511c7f9926fe7f045c0ea633a51b7db47
+Invalid =
+
+Curve = P-224
+X = 372a134eec0dae3322de8836b89dde11a69e0379a60b10343abd478c
+Y = 65921970ca8cf5a75f044db0e29802afe1726d18b3e07b61c768c242
+Digest = 1547d49d33566f8c05f68b9a980e113f919bbdef8d6d53046456a2c2ebe27ad86eaa52d05677fadd5ccc3e84b04c0f94
+R = be6474845a42fd4e85b91238f1e3ba11cc88e216d295c1b07d855987
+S = 2724242ffb5775f614ee06eaa4c985358f64869ce4ae4bfb16b5271d
+Invalid =
+
+Curve = P-224
+X = 9ad2cee0d92b00b11157a18fcd752f43e772ede7a46475a50e7ad8d2
+Y = a6edfae6c5589dc0db6353b8655fe3b0f7dab2aa8400cbbd72d1a572
+Digest = 60942be3ff8d2370481b04fa07743482e08a61d3724010d7edd49bcf12e1463ae059696c825ac0505f079625b95310a1
+R = c31a40b6c245572457a19efac0da0db22b2a0818de716b6fdc5bdb32
+S = ed8204de94f1d92ae3fa6e10c727eea38d0e12b58133fda1a15559bb
+Invalid =
+
+Curve = P-224
+X = ed071a20d76f81c776875f8d3307841d33b70523ea40abd691d55d21
+Y = 34ca47d8ba0a984d0d728c4d8c6b9aacdded03c6070616680aac162c
+Digest = e0776a80c616b8e596bacb0391a19956b2f0e2c566c50dd2ba99f9e59ff3dfa6197622c2a64cb4d02780a39c68d249e0
+R = c7a5dce4733a81bd738e0a6e0667dc1fade86db119e7f3cde57d6dc6
+S = dfb7f43343941cce331be27047b131617910f68393630fa53d137df4
+Invalid =
+
+Curve = P-224
+X = f51097e1e4b4f3b32e92fded0b4c8b7240a62731292e615a4cae0dcf
+Y = 0549003f18e67076bc68110a75252072fc29b6d4a336d152dac2c3d1
+Digest = 48803bce00fe101650dcc83b290c49a524b21422f1f6a3aaa6e2f201863ffc355346d167dcb0ac552007a46cf8d6e4ad
+R = 6875a118dbf586a51af2212d5f32908c9f31110e9e9a7e4cdf7494c5
+S = 1542ab4260459e82070bbad405193a1894ce717af158daf1d096bc01
+Invalid =
+
+Curve = P-224
+X = 5255e4fdc816044389e9c6f5e09b85aedbe1c85b1cf9b7190ef7c2cc
+Y = 683c8cb6f31e4cc1e2a5361eb47e305d5d8bfeaf94e261a341aedde6
+Digest = 995229c018cd0ea061672c46ec30c99693fff1cad491b13b4093df0154872adf946644dee6192657b436931c30b7af9d
+R = f1b0f8a3fbf7d4de19cc1d3b4c525c31bd97c2e2a94eb8a27c7c197d
+S = 936d3f49a9aa58935cfe227b22db83314ffadcc4751c8e26853d8cd0
+Invalid =
+
+Curve = P-224
+X = 7cdaf519f6b1254cb8da4668a2dd2015857ceec17f838c15d7d34b27
+Y = e29f80fa4f830af7737126d4454b6498905e2c633fa61ad6acb30823
+Digest = c7d8d1f060287ec402092be54ca6e06895e91f9d0c29010124c0d9bd54007d8039b7328ec7b3a29e1d5d4d8fb78807e4
+R = e640f3e676a11007e73efd00b23087adefc9b9407ae8b79b47c397f3
+S = 66b7860a0ca35c2f1c65d50f99def9f2bfc0a6cad2008dcc38d6b3d7
+Invalid =
+
+Curve = P-224
+X = ca1a04f08708ae714b7dfb3db509970d30b7e01be7fd6181613894a7
+Y = 1d90a2fcda7dd6ce8b207eef48340e58cd439a3ce17658f6f82be778
+Digest = 1f710f925826bc33c0da91798cb7d7d0700883da685a1fb9503179f0a06b589bf92eb4b67496faf21cd74c8e3d560d77
+R = 9e810ec2a0bc205df6a75bd6410e0c8ea1c738e71af060e2eb271aa6
+S = 9d05eeb46258c468b0398cb6e421149bbea5ed936be3fde3380111cb
+Invalid =
+
+Curve = P-224
+X = 558c323d8259e055a025fbbe6ba8b525b02f32caddfd31e5b08219d4
+Y = e1d6398b1c47132632cd3f3fae14fc3ee3092faa619074fd951a5870
+Digest = 4b662138833a976051b20ddfb02e67339715b77046bedeb1e30b9dccbcd84204e76da722bb3bd020fbbe33a182792e0f
+R = 05d8b0bcedf287a4740bfc548570b1c1fff71058e0a9d88476bbb6a1
+S = 769321d50e34939e622a727855501e25a7ad44ec979985e7389aa3f9
+Invalid =
+
+Curve = P-224
+X = 9237e61ad9ffafc61cc1c72b6d2f96d69b588c8feee4074359f694f7
+Y = db25a18f1eee72734c640313f5c6c0441358611406cc62619113b4ba
+Digest = 4e7bbf78843a767536977b240e9d1516c73c0fa19bc91448280fd85361b06fdd11ee413f956ca4ea3d67c0e325a1d53a
+R = a58225b10080dab26644f10d8a817ffc4ed4535011729491b6ad5d00
+S = ddbc010e295882e0731ff240f15ed82fa3e81b7552c690cc5b40be03
+
+Curve = P-224
+X = ea7efb9a7e7bf693dc0249504ead70dd422ec86806cd649ed57a7ffe
+Y = 33dfb17b1cb244279990019286ab477a2aff2b55c08959deed0b1a28
+Digest = 330f78db9f217f95d99cbcb5414a32523025b85c87ed5aaa3a5e6b006c53cecbbd446166bb9b98e944626332c3266e82356e72110bdbf7df2431b8e7faf59e45
+R = deab574de1f971419b7ba9e169866c3a6233fc627c13dc6a8cb88bdc
+S = 8d4c542bb0046da1b3912652a2c84542668cd89920808785d04e4352
+Invalid =
+
+Curve = P-224
+X = 6fce4d789b1240f2ab1c23051aa03e219da99943a18864e7876d4d11
+Y = 3e84a6bddea4a28cf8151ae73aa7b1964c37e654241353a9fa723f67
+Digest = 0088e4cbf3eddb6eaf108fd3937c439684ff8fe5595f2032948423a2a15811b34b0def245bed3b4b4ca90d3f497f3aaa2577a7154d22d7254dfc4755eb9b7b17
+R = 2d1b4f1ccaebc0a929598b650ee364abfd6091a542ba426886d75f38
+S = 44f3d7afe84ae33ab5f9426dfc85248ebc7e0df434d35980ddec75e0
+Invalid =
+
+Curve = P-224
+X = 72013dd6f5b1eb709b3b7da234987f9a36c6f0b095620b8c31f02381
+Y = 319d54c719b59d91900b3c20d963ddf1a10d80d6601ac155094b075a
+Digest = 3cba2980faf5579c7ddbeb31c3318a162a882129a1efe1fc9acc3219a617c460701f22fd7a5c46b017bd9ec9c40587127319ea14b148d2be4df9875d5bef6e4e
+R = eb38db9b757b3cf04020f09188c789bf0258cd0467cf7d67368e8703
+S = 7664e85f01e67881712b24083f89e838c8b818de4d665494e7016833
+Invalid =
+
+Curve = P-224
+X = c6a65011926eb64e02bf472d5ba37841d49cfb7f17a20fb9f59355de
+Y = 386ccb33d944fd7be6b8531863d2b6200cd602d300d7e7681537e53f
+Digest = eaa81b1236121db12f2036611eb6d3e5386f5733125fb26844cb4188109aae402525fc63bcd73494c36c170d1934b108739d79b0c4f184bd85ffce93b1beecde
+R = 9e7c637a699dd52512faea847079f0ad41b20cd7a5461c36d01e857e
+S = dec6e9ef361de3f6ec7d87de3129eaac5fd0b43b5f7f58ce46c29173
+
+Curve = P-224
+X = 5bcdbaeb2f6c57e8a9dffe94804e74daaf9db8452d13c6a8bc2a4966
+Y = a564072356c5d86200e979291a19d5e73d8bcb701cf84d9012824bf6
+Digest = 4a5de84f304f0c83365ae4213fee71c0944d8580f9d8e7455fc961e9f98bf3d51b7fc20aa44e36c0bdaa09e365767742e9bd8bc868d5c6cd8e1cd2ce2968e3dc
+R = c58436fb77aaa4468dee284e1220141ce9ff4426f75daadf5a898a6f
+S = 87aeee1229a50921d8e77e7e3478061f5c051097defb104a0455ed81
+Invalid =
+
+Curve = P-224
+X = 6c6a7deef8b3dee2eaa98d8ec877dddb460365968e63ffe5c249a421
+Y = 1ad1715797b5e47c4be24d7ecb8141f1772344a2f643cc66fbcf3f9d
+Digest = f59946dd73887a1fb945ae3e5b44b574512e36dd7d35925b0bdc3a3f69a88e50dc6ebaaac86092679961a99d7ba5724363c5886e7c2cd566433c5a9d59e2515d
+R = f778faa2dc2cee7de2af0bbc4339239dc240907e59ac034464ce986b
+S = 2ac929588a8dc8785808c9d4366bd7b1a81e0fc5be0c63e62344c251
+Invalid =
+
+Curve = P-224
+X = 0ee33a134feae6ee1488bf10edf7cf7c318a2d709080a24818619b91
+Y = d7d39536e42652baf55159847f475ded075385a3c1af5c3dcb17ee6a
+Digest = 00fc4992514c1053eee7facc5199161a2b0f69dad2770326371ba42c2c12ffdb4ff6bd86fc440dc8dc1354dad42ff0c2a055b61137532a62521b0f3508ebe611
+R = 34bd0407f80cb6fc759036e6d4522eb6da94874c92ce0f02d8f5f2ad
+S = 3a2dd970050ff990162e5702b06905d03e3c7bb2771050de6d84eece
+Invalid =
+
+Curve = P-224
+X = 31d3c62a4305c37a15e9102072e287a8e0ac027f9189cb9d87ecbea2
+Y = 26449ca391af6a2a9f8daaa036f2c9044b336773ee48bcbd9cad59f0
+Digest = dfafbf96b70ead7e91dbf48b8efd062bf2bc0aac6d3e90a7fdf61aac13a74b304bcd0d0c23c88df269d45bdd31d50f0fccfc0324698af4dbcffef04ca05a119e
+R = dc33e8f7b52f584aa3f091aba10c2a9a23be6835e1551092652e1bbc
+S = ae84a6d19f6bad3f9886930c0a1406016fae813673db1516b31b638c
+Invalid =
+
+Curve = P-224
+X = a6e4470712df583d0c795237ff46c9df5718ba2aa24139a2d99721b4
+Y = 9edb403a8c10807e8736af665dbcf6052bd4b43bcdc8b9eb8d4394fd
+Digest = 36cd6716cbb8b7f96df4617143be7b74f42bc94e468e79e6658d00b092e24d6de82f207693427fb439dd13bcf49665cac343ea35a79b5963cb21273094ce28fd
+R = 4e9ba5bc4f4fc4e507c1e5cbd0d688da4237385b16ff06601436d8ab
+S = 4e0450a57d802d0ea7b0fb57eb162267195bc4248a831a0ee8b0380d
+Invalid =
+
+Curve = P-224
+X = 350fa782e1cf7254b18cde30683e54edf2c1b4782525fd081bed5920
+Y = a77de5b4139ff63e108b6fbd3a7e6c09c3d2ea8720860a7db1c1b5c8
+Digest = 0589be3481da7becf046cc9fd84e9a68db8086c730374e8ee8542de45e1e17dbacba6ecbaa99886f4daaaf32be01bae96b1e2a04cd76f699a1a74a3d97b73019
+R = fb7073865646bd92f882f8224503ac1f340cb7a5d6319102c31fb544
+S = aed3ca77d23c78ec76f748e84483c536d447b0f8e186dbd0774b1214
+Invalid =
+
+Curve = P-224
+X = f10652c3c2c30a765564f5e393c6c202d436c81fc7d71b88857bd458
+Y = 42979ba5e6c8cd044e262c73e6aa918d8c3e0e08e4bf98ec2d5c6f57
+Digest = 680aaa97b939a5031737a40b9e34e5fb8047b8a6e495c7c90653458072cb423fb098e6ecef15c9d62d4443337f61cde237c66c1683753e65f8bced5298375bf5
+R = 072e0b130267d8e124dda2d0604f4c575ef4007628fa61f66bcd8f07
+S = 6276475fccda3bee2af7816c7b3ec222e408cec36d0409e672af23b5
+
+Curve = P-224
+X = 89cef29515f1d30fdd283625eb59e682023bdf2eb0497288ff700b27
+Y = ca0a3f7ee4853ae8454fff6e926c7a85dc7852fb4d01cc3de861c53d
+Digest = bb7394f9b30617419daa71573f5ed9d72732930b6d24141ea2bfb6bcdd67f4fd7a7e6caed8fcac76f50bad0616c291ff875d866b4085f2a0201289a0895a319a
+R = 0ff5dba589454d0ee5bb391a4dc8446b1ffd1cf8d66c9fc0f05a8a89
+S = 987c32258cd12b6b9cdcc5915eea5eb79a30ead442179a126b97fa9e
+Invalid =
+
+Curve = P-224
+X = 086d892340057368ca47a3762735519a4316f005ed8a18a9edce3b4c
+Y = e15f4c9a0d240fb94e05192ce4296c532b549af577c26de861dd3452
+Digest = dd84be132129accb134697c8b86a47bc3479eb3db37f128965c5638e210b416580ad52d8f63033b032f1897dbc4732fdddd8202479ee6b32fa12b1ee529242bc
+R = 8d1e13fdf36eeea06a837cb22d17601081df6ed2815ea9da79894a75
+S = c19713a132a562bf2abf8c2d8cae95ef3272824db63edb0776ffc1ce
+Invalid =
+
+Curve = P-224
+X = 6c8aea044d4f0b9699eaf398dbb030db4d6c68e0786068fbc2094974
+Y = 426e743008febd8597594e7247ed1cbd40561bbabe1031963591ec6b
+Digest = c5e3ff45af230a7a97d1ab13f95641d1a47953d43be0427c1f30de1b7a431d22972fcdbe748911e05aa0c8047f9211af2234ddad4c30f34abee15d421c9333d6
+R = 3041c36b8456d65f4564597c65aa880fa8bc455f2c35de0fa2298cc1
+S = b87a516d1e2dcd862c6e5fcfc363e9f36bb06ff2c0333e95221e7f36
+Invalid =
+
+Curve = P-224
+X = dc85f6701bc95a60ea52f1c476dcb211e5e3eeba5b35dc3a3786113f
+Y = a52b364fb7c4b4c9155e4ee2d8841386b8a96cbeed1e5c9957214a50
+Digest = d4e0bcf58e2083383ef94b28cfb2710a4e898b2c2a0cf30bebb99c3f2dc93403dd165e1a0c3773ed05adedf967fc92f0a158e5086965a29dab3a4aaa5e9f9911
+R = bdc7b4d3266e54a19f030f3055f83460ccf30fe8f5368be013076081
+S = 82a0e3a21a8d5e9cfcc5a673385cc2d4159498b6c1ef5791b2b02f9f
+
+Curve = P-256
+X = 1198b3c409a8b47edb1347e0982d533cb1813e5cb2a92c824b2881b3cd2f3f4a
+Y = 0bdbac5fa02e41e775f8d602446d58ecb2209b5a3d79ae69eef399016e992e87
+Digest = 01ed0c41d650479c47057f61433d7e8b24492649
+R = 9206d435f148f88c15b2effbf3c506e41b2c620102022b801e371d0767b54bea
+S = cbc4e1674ae1af69873946ccf6275946e59e0107278749b2d0010795833d80fa
+Invalid =
+
+Curve = P-256
+X = f7c6280aecd6b936513b0ca84e63346333dc41437a15442e605d46bba93ae101
+Y = 3c834cecc16167b07866a9478f9f2d882de7ef937da447cd837e60cb5ed65d81
+Digest = f91b4dfddd5eb33a875d2e50d1e949211ac819da
+R = f615af212ab030c4bbf9362d9815a1462312df4beb4358a7ce80d820355420bf
+S = d12ed715ef65cfe6fe6bf348364088a0e7f70927bbafe4c12fc4cb65c0cc51bc
+Invalid =
+
+Curve = P-256
+X = 0e7632dbc4db879e10d1d80f2789d9fa414c1fe77a6c1e56d6667af43e36e610
+Y = 6f0dd2a5840e5a6f6ff7e23f656f5c945b7a493fbb0cfd5b9b531bf04435b1ef
+Digest = 3905696f8bad8205fa1445df0e91ade3dbc413e6
+R = 2b0b9ab4a575732a168f28494b66a855fc1a757fb1177864bf3e4f0a000c4a86
+S = 54901ce2f92f55ac112afa0f8b62bc00b44c8c10fe0c863675bfd305d6dc0cd8
+Invalid =
+
+Curve = P-256
+X = 1613f12bae8e98d09b4bba53f5229596a0d417d2c625f41bb15f923b3c1e4b57
+Y = 411319fa85227997a4cf3b1756161485124d2cedc38c9c30d82f42dc2647d545
+Digest = 580d31ce22700a20c2db81bcdac37330b491c86f
+R = ed058d476a77be99c1b0fc8502abe545541b4c0ff3eed3f558133ae2f02042b0
+S = c571b4895712a4f64f7220b0694cab767379b09f1824fe7874acd127deb2371e
+Invalid =
+
+Curve = P-256
+X = 88bb041dcb1733a676a7f4ae8d3e407d72d5396547f07db77078485c1d5db077
+Y = 72cf2b55e596cd140c58228f1b0a19c34fca26ffac043528a417c5abb6fca9c9
+Digest = 7900a02f768b0718a13525c33adace583de15c50
+R = 87208734deb125dca68f0d33f9d369cf1b79cf5a021391b9c6c1727d2efe663a
+S = b984f722de18f1ce407104342948f03f2b55413a096c4b5fca1e032a2c814a4a
+Invalid =
+
+Curve = P-256
+X = 811eb5180def7fb60d632f8cb2cba831b88cee778aa2a82ec3a5fc3d80ff7fb6
+Y = db88d65b0fc35d9ba1f1ced0400434979ae895d371d1441d7c7a441a9fb1709b
+Digest = 17b7451ea903125ccb293ffaa9d1a4ca1141a2c5
+R = c329fa28dac0018276c5af0cd770e60be50bc14e2562d5556991971edc7d4916
+S = 2d111d13837a02fa279fe835a7dc59a521864d92b26649ca4e24b36ae93878e8
+Invalid =
+
+Curve = P-256
+X = 4a6f1e7f7268174d23993b8b58aa60c2a87b18de79b36a750ec86dd6f9e12227
+Y = 572df22bd6487a863a51ca544b8c5de2b47f801372a881cb996a97d9a98aa825
+Digest = 54e9a048559f370425e9c8e54a460ec91bcc930a
+R = 4a800e24de65e5c57d4cab4dd1ef7b6c38a2f0aa5cfd3a571a4b552fb1993e69
+S = d9c89fb983640a7e65edf632cacd1de0823b7efbc798fc1f7bbfacdda7398955
+Invalid =
+
+Curve = P-256
+X = f3033d1e548d245b5e45ff1147db8cd44db8a1f2823c3c164125be88f9a982c2
+Y = 3c078f6cee2f50e95e8916aa9c4e93de3fdf9b045abac6f707cfcb22d065638e
+Digest = e8d38e4c6a905a814b04c2841d898ed6da023c34
+R = d4255db86a416a5a688de4e238071ef16e5f2a20e31b9490c03dee9ae6164c34
+S = 4e0ac1e1a6725bf7c6bd207439b2d370c5f2dea1ff4decf1650ab84c7769efc0
+
+Curve = P-256
+X = 0ea0a6bb6c70966fad1a2307479c12de2322795bdecb70e4b286bd6200ba9c1a
+Y = c40eda3947021348db691ac4086fb6c06b587ce37c155bb0a7d912b93226de81
+Digest = 3b08bf1b67abc03c1cd69b0e24743b5c2d49e506
+R = f5509deff7bfda3f3759800fa4033af6a84466b114ecb48eac37eff48d2ae1b3
+S = 8c4b62dce2082f80caf220cdbb1d02567bbdfab40564b90ef31d86e3e10ce80a
+Invalid =
+
+Curve = P-256
+X = e7a57e0f6ec0fa9c7c34978034cf82f039f8fd62804070ad943573fc8efa5775
+Y = 87b2cc85dfff2dae5620fbe3e6256bd728de28fc9dc1b5eb6b5d7bd5d29186ad
+Digest = a8c5dc0344b1442dfdb5f8836251893d6c4ecbe9
+R = 97642038932fdddbe2021ec1af53ae6b9af00ef9c8b9f26aea582892e80e6285
+S = 9cb14918359338041cf795cf6781e4905837fa5ce3b3e50ffafb5f13c73b5bc8
+Invalid =
+
+Curve = P-256
+X = be7a651be0c87278569987cf62d7fa1dd1b3d6e1b868d8f4dfb56135a9960eec
+Y = b7a62c588a987760b915edbd7f95506870c60f042471de1d8b2d4cd9d6563391
+Digest = 2f93ee45db133a14c26d418c2ffd3470ae63bf50
+R = aa889fb608b6939f6eeacf2f64c3b2e3a6061f2834058c7e724321720b737a63
+S = 6cd6d0ef2b93a760daa914e11b9b414bd4d72457405f00a62ab63f36d76efb73
+Invalid =
+
+Curve = P-256
+X = 76ddc46d8db8d7ce2ce837f60cdabcee92b7c7817ee41c8f066f1ae65f85c318
+Y = bea47191f1c584c87250370ce337a1de1583bcfc20ccc23b7a82e83f19adaa88
+Digest = 2136a5470ff9d45214a0b2c300042efea8ff7266
+R = 84a42efbf7ec04166ad144d19cd98c120aa2e79d483b5eea6fbdfa7f1222e07b
+S = e41531205e691e65668f69f518abc7b60f32c373434872a043b7358462babf83
+Invalid =
+
+Curve = P-256
+X = 2f71b932f770ba9daf7c1dd47444ab6cb8881f71a1c597e719845b15cb84ca35
+Y = ab928625b40ec0738d0fc8dbc4df4a1f65d20bc0447b69cfa13bb20b95bb41d4
+Digest = ae6093bb37c1264ca3ead439e4f678721912c8c4
+R = 63fca172bbca6197cd2802a9cb61d74c2b47cf35f6d35203e67ffbaa838be775
+S = e70ec283cd212df6ba3723e26b697501f112d7cf64e4f45185dae76055e09f1e
+
+Curve = P-256
+X = ce775648b928db82ac5edb3b009d32959a73b86c45e96d4b8d5b6e640b7c2790
+Y = 52455caf08ee94d86f0984e9ec9268d74823f2102dd97fced59638055f6af18e
+Digest = 60054807acb29e3091a023c42b9885c4945249e1
+R = 2a64b29146588f3153fee1029a0131ac0a8a25ba2ecc494f697c166c7c91fc08
+S = 7b429bc12a72ca3d76c119eea9f4098633cc31c87831e54d5d93afd6e8d20f4f
+Invalid =
+
+Curve = P-256
+X = cd2f29a53f0ce57e0e4a542c3256e65ebbdc30415f4de771d5d706d3aeacc852
+Y = dbbf2c129f30d11fe77d7816a24187764eae3fb2ff70c1ec745e876e26f5232f
+Digest = 5f50e35b134942295c16d003742fd6bce5bdab45
+R = 2454c5ee84e4f77b554acd368dd412389db8c78429590a092f24db2da43cb761
+S = 63e870ce2fa4085d4ff1e360f7a5c101a1f8b288abe71cca56887e613ad034b7
+
+Curve = P-256
+X = 843f6d83d777aac75b758d58c670f417c8deea8d339a440bb626114318c34f29
+Y = 83e0c70008521c8509044b724420463e3478e3c91874d424be44413d1ce555f3
+Digest = cda2c7ad9abb2a858c4981550f78974c69e41cc31fa33509e3e83dc2
+R = d08e9a5db411019d826b20ac889227ed245503a6d839494db1e8d7995a6b245b
+S = 8d46a204054125d0dc776ab1055302ec4eb0f20b90bca6d205f21d3cefd29097
+
+Curve = P-256
+X = f08b56f73f7a0e098444f6f0a02ad81ce0b914a11cafa15893d1c84704e1c564
+Y = bbee9aeb91cdc2d1d1437b4168df73acfd64e8b02962b14c85e67187e1ef80a4
+Digest = 5453c2656550e9b3dc6c40a3f1362a73522396bc35d383dd6451128f
+R = 71b3ec982725a007ac18a5cf60587e1fd1beb57685a1f9df3cddd9df25dcbc18
+S = 407e41217325f92f8a031cfcc4eb64c1a4b17b0a7459c254af754a7ea9eac997
+Invalid =
+
+Curve = P-256
+X = 0b688e761e1ddda2305e002809da65bf5916dfe1356a5b99b61f5576a9b90efa
+Y = 90ec958e2e3a676e7bbf8e9394f72742875836125a317b0ae38374953f746a91
+Digest = 7289573d6bb7486e428e086bec9da9d7ff3c5f8bd0db2ec209fed6ae
+R = ef89df3bbf079fb250f7e882c4f85c0023fc3804e862d9ef4d9530a15f1013f0
+S = 4ba985e900e6737b8e07eac638f7b38277ead4faee6d2076a2eee90fd2a6bf0f
+Invalid =
+
+Curve = P-256
+X = 0b64480783e260e1e9caef37b4cc9c650d2d57e2c594b1106314843d8d7ab74e
+Y = 29d373d8522deffe40055aef539f53f38937eb799b44f05a8d8c0b381f12907f
+Digest = 497656e780360ec3b4bd1be97570615e4a32467982cd9330bc6aa224
+R = c5c26b0b21eef0f7a0f1cff38d0079d890376759369b01d8d8e959c1c785e203
+S = fecc400bf0deab99d87da168b9d0dd31d2dfa3435b0fe9d38b5fb8efd45195a4
+Invalid =
+
+Curve = P-256
+X = 7f78a8fd880c509940e2b83de67c9ab553ab91489bae75cdc1d5b523b06ab7f5
+Y = 7786aee7032c373cdfad7d9ddb6fa09a026f6da30fd477ab014d30a289d542a1
+Digest = 6d88da9e83ae9457e233d7977172c062dfbdd17d365694515251e031
+R = c93ada69db326f76b1362d610cb8bcc6e7ef1dc03d3d11367e153c0e39d5dc86
+S = d0c02c71b14ef7a4af4e23bd207ce98449f5d6e7e5b3ec8cbbca9549e97d379d
+
+Curve = P-256
+X = e58cdc207c56f62e0bb7c0b55b7f7236a6b308f8fc4de3e61cdb3bf20ad2f62c
+Y = 6056c0ee827e85ba284838954d0c6cc096df03b4611b1e0f7f9002bac86856d4
+Digest = 3f9a97b8ea807edc88788df8956c296b1daaed8dd12d50c712344091
+R = 2df3906527ad322000285bccdd11dd09130d633cf43534f5802604639eb847e0
+S = adaaad19b7c66836ef0f4afeff8ac5e898cd2523246a74a1a291a3a1ff583322
+
+Curve = P-256
+X = 70b4bba10b7bbc6d4175ada8d485f3685b13916d0c992301f47e45b629c63d0e
+Y = 257a93be31b09ff4cd22e3375e30b5a79f3bf3c74c80dde93e5d65e88c07c1c4
+Digest = cc3a0d3a5d4f28dc9144a3cdb276eb92265f1157a8d8192cf628673c
+R = 6e714a737b07a4784d26bde0399d8eee81998a13363785e2e4fb527e6a5c9e4e
+S = 94c0220f0f3fa66ff24f96717f464b66ae3a7b0f228ab6a0b5775038da13768a
+Invalid =
+
+Curve = P-256
+X = 8b11b48d2397355000a5289d816b9892ae64dffc842abec02a2fb2db2bb34310
+Y = fc1a42528a0473cfc2c2e184b8bc5055096350fe1549d24b526d6536681026e8
+Digest = f340e491fa935be8945b8caa485d0699c66331e0e17c7407da1b018e
+R = 61a91dd1c80049e70dc4aea84bda0efc6ec9c7b9dd16ecbccf687244c51184ce
+S = e381e7b32bab49578c7e7ce7784ce19263e4a7dab4b614df411d20eaebfc391c
+Invalid =
+
+Curve = P-256
+X = 7bad1b3d8bad4355a44511d2eb50daeae793af99418ada118327359936aa0e1d
+Y = e7eff40334b7a5455f6b0d0ecdcdc513702857bb5bbb73c910c86746092bcd7d
+Digest = 9cf84546c046b370c372c167ebba39af6aadd60463626453787bb058
+R = fd961b60b21be32b47abafa77e22197dc99af6825dcca46e0e3b1991a90aa202
+S = a0477f97b94a1c26a3b2d186791d7fc9dfa8130bbae79c28fa11ec93a3aeac0b
+Invalid =
+
+Curve = P-256
+X = 407d92c9b28723602bf09f20f0de002afdf90e22cb709a8d38e3c51e82cba96c
+Y = 4530659432e1dd74237768133e1f9808e62d0fbe5d1d979d1571baf645dcb84c
+Digest = 0cf5cd48c93f45472d254196bebea4bddb272a2adff23bab8c3adf99
+R = a7dc65293ee3deb0008ae3e2d7ef9e9a4ebb8bf7b10d165f80ab8bed58d6fdef
+S = 3e8300a3ee603a8d8234fe265c628e705015bf1903eb74c943323050626f701f
+Invalid =
+
+Curve = P-256
+X = 26aea3dd5c53f984dbdaf415c7f26e1e73048658a548eb3b59dd5f721899919a
+Y = dff15f57bd9b08644d49cbb214403647195725cd4d4511bc8a48b0770466ae9f
+Digest = 75d6b6b575d0a2c89528b83c94ef864c825b66253ab662b36bb0e716
+R = 726af92afe53e8125b0b9f3659745be401a37ae658b7b1aa88c3cb97e9de22c3
+S = 794484c5837a419efe11a4e4293341a6fa36d21230925a0e5e135887302acca9
+Invalid =
+
+Curve = P-256
+X = e73418677ce044b331a6d60773cbae199221699d31e1bec4b68b9bc0b87e4cd0
+Y = 37215db4e3d9161f3351b385a61ddb2fcf1cec469d1659e7574610ed27fe879f
+Digest = dcbb92e3be3951d37e37852d508f78da29c8183c5dbe59d6549f78ed
+R = ac469290a8f61a2a8c6adc7533dd5cfe804e2e7bf101cc74e5f624f301bccd23
+S = 4c328c3bc259316641fff44753743afebe89b8627f904df7245e42adcff2dc76
+Invalid =
+
+Curve = P-256
+X = b0892b19c508b3543a5ae864ba9194084c8f7ae544760759550cc160972e87ff
+Y = 9208e9b0c86ad6bc833e53026f233db9a42298cdb35d906326008377520b7d98
+Digest = 90333facb4f5068c1d05d1a478fb46d02f367e271a000474c06a5fec
+R = a62dd0d1518c6b9c60de766b952312a8d8c6eaa36a68196d2a30a46fb17dc067
+S = b9ded660e978129277f74c1d436003d1e6d556dc8eed9d505bbaf4c67cb13d21
+Invalid =
+
+Curve = P-256
+X = 8c5c41cb07d828a6a86be4533aef791d3a70a95cb285aa2956b21feeac2f8c49
+Y = 84101581cad7a48b7d0596df7ffed47085d22e8a4af685cddbeeb32ea69ae190
+Digest = 8bb52bd045c985167f673c07b613a3402f435a54c122877bc0c5fe34
+R = 9812449df0a51f7a2a8f78aa9a589ca9644dce285f1e69658daaea759fa5bd7e
+S = beb4c27c748a7944e37afe861576f76b5a749a8ccbbd7dec00838ba250ddfe1a
+Invalid =
+
+Curve = P-256
+X = 788d7e54ab03020e4954f41259052ee5af68361492b180da31fbbe68d868aa95
+Y = 982a3ababa6d351649e56da3faeb7160b9de74e22fe93a06ead1bd9a8dffdf7e
+Digest = 9870ae25b0f0403eff1079b94669cf95fb250fb098eeb885ff08f117
+R = 3ddea06bf8aa4a1b0c68674a2c4796def0bfb52236f4efb3332204a41fd8ea89
+S = 871237039431a41aeefcdd08f67848b2b09067e3a1344c8ed9b372d1b1c754a6
+Invalid =
+
+Curve = P-256
+X = 87f8f2b218f49845f6f10eec3877136269f5c1a54736dbdf69f89940cad41555
+Y = e15f369036f49842fac7a86c8a2b0557609776814448b8f5e84aa9f4395205e9
+Digest = a82c31412f537135d1c418bd7136fb5fde9426e70c70e7c2fb11f02f30fdeae2
+R = d19ff48b324915576416097d2544f7cbdf8768b1454ad20e0baac50e211f23b0
+S = a3e81e59311cdfff2d4784949f7a2cb50ba6c3a91fa54710568e61aca3e847c6
+Invalid =
+
+Curve = P-256
+X = 5cf02a00d205bdfee2016f7421807fc38ae69e6b7ccd064ee689fc1a94a9f7d2
+Y = ec530ce3cc5c9d1af463f264d685afe2b4db4b5828d7e61b748930f3ce622a85
+Digest = 5984eab8854d0a9aa5f0c70f96deeb510e5f9ff8c51befcdc3c41bac53577f22
+R = dc23d130c6117fb5751201455e99f36f59aba1a6a21cf2d0e7481a97451d6693
+S = d6ce7708c18dbf35d4f8aa7240922dc6823f2e7058cbc1484fcad1599db5018c
+Invalid =
+
+Curve = P-256
+X = 2ddfd145767883ffbb0ac003ab4a44346d08fa2570b3120dcce94562422244cb
+Y = 5f70c7d11ac2b7a435ccfbbae02c3df1ea6b532cc0e9db74f93fffca7c6f9a64
+Digest = 44b02ad3088076f997220a68ff0b27a58ecfa528b604427097cce5ca956274c5
+R = 9913111cff6f20c5bf453a99cd2c2019a4e749a49724a08774d14e4c113edda8
+S = 9467cd4cd21ecb56b0cab0a9a453b43386845459127a952421f5c6382866c5cc
+Invalid =
+
+Curve = P-256
+X = e424dc61d4bb3cb7ef4344a7f8957a0c5134e16f7a67c074f82e6e12f49abf3c
+Y = 970eed7aa2bc48651545949de1dddaf0127e5965ac85d1243d6f60e7dfaee927
+Digest = d1b8ef21eb4182ee270638061063a3f3c16c114e33937f69fb232cc833965a94
+R = bf96b99aa49c705c910be33142017c642ff540c76349b9dab72f981fd9347f4f
+S = 17c55095819089c2e03b9cd415abdf12444e323075d98f31920b9e0f57ec871c
+
+Curve = P-256
+X = e0fc6a6f50e1c57475673ee54e3a57f9a49f3328e743bf52f335e3eeaa3d2864
+Y = 7f59d689c91e463607d9194d99faf316e25432870816dde63f5d4b373f12f22a
+Digest = b9336a8d1f3e8ede001d19f41320bc7672d772a3d2cb0e435fff3c27d6804a2c
+R = 1d75830cd36f4c9aa181b2c4221e87f176b7f05b7c87824e82e396c88315c407
+S = cb2acb01dac96efc53a32d4a0d85d0c2e48955214783ecf50a4f0414a319c05a
+
+Curve = P-256
+X = a849bef575cac3c6920fbce675c3b787136209f855de19ffe2e8d29b31a5ad86
+Y = bf5fe4f7858f9b805bd8dcc05ad5e7fb889de2f822f3d8b41694e6c55c16b471
+Digest = 640c13e290147a48c83e0ea75a0f92723cda125ee21a747e34c8d1b36f16cf2d
+R = 25acc3aa9d9e84c7abf08f73fa4195acc506491d6fc37cb9074528a7db87b9d6
+S = 9b21d5b5259ed3f2ef07dfec6cc90d3a37855d1ce122a85ba6a333f307d31537
+Invalid =
+
+Curve = P-256
+X = 3dfb6f40f2471b29b77fdccba72d37c21bba019efa40c1c8f91ec405d7dcc5df
+Y = f22f953f1e395a52ead7f3ae3fc47451b438117b1e04d613bc8555b7d6e6d1bb
+Digest = 8a3e7ad7b9b1b0cdc48e58d1e651fe6d710fef1420addeb61582bdd982d2b44c
+R = 548886278e5ec26bed811dbb72db1e154b6f17be70deb1b210107decb1ec2a5a
+S = e93bfebd2f14f3d827ca32b464be6e69187f5edbd52def4f96599c37d58eee75
+Invalid =
+
+Curve = P-256
+X = 69b7667056e1e11d6caf6e45643f8b21e7a4bebda463c7fdbc13bc98efbd0214
+Y = d3f9b12eb46c7c6fda0da3fc85bc1fd831557f9abc902a3be3cb3e8be7d1aa2f
+Digest = d80e9933e86769731ec16ff31e6821531bcf07fcbad9e2ac16ec9e6cb343a870
+R = 288f7a1cd391842cce21f00e6f15471c04dc182fe4b14d92dc18910879799790
+S = 247b3c4e89a3bcadfea73c7bfd361def43715fa382b8c3edf4ae15d6e55e9979
+Invalid =
+
+Curve = P-256
+X = bf02cbcf6d8cc26e91766d8af0b164fc5968535e84c158eb3bc4e2d79c3cc682
+Y = 069ba6cb06b49d60812066afa16ecf7b51352f2c03bd93ec220822b1f3dfba03
+Digest = 7c1048884558961c7e178b3a9b22583fca0d17f355a9887e2f96d363d2a776a3
+R = f5acb06c59c2b4927fb852faa07faf4b1852bbb5d06840935e849c4d293d1bad
+S = 049dab79c89cc02f1484c437f523e080a75f134917fda752f2d5ca397addfe5d
+Invalid =
+
+Curve = P-256
+X = 224a4d65b958f6d6afb2904863efd2a734b31798884801fcab5a590f4d6da9de
+Y = 178d51fddada62806f097aa615d33b8f2404e6b1479f5fd4859d595734d6d2b9
+Digest = 4c8d1afb724ad0c2ec458d866ac1dbb4497e273bbf05f88153102987e376fa75
+R = 87b93ee2fecfda54deb8dff8e426f3c72c8864991f8ec2b3205bb3b416de93d2
+S = 4044a24df85be0cc76f21a4430b75b8e77b932a87f51e4eccbc45c263ebf8f66
+Invalid =
+
+Curve = P-256
+X = 43691c7795a57ead8c5c68536fe934538d46f12889680a9cb6d055a066228369
+Y = f8790110b3c3b281aa1eae037d4f1234aff587d903d93ba3af225c27ddc9ccac
+Digest = 8581034ec7d7a6b163d71820923f616b362748f2846042c9896d8e4bf7577960
+R = 8acd62e8c262fa50dd9840480969f4ef70f218ebf8ef9584f199031132c6b1ce
+S = cfca7ed3d4347fb2a29e526b43c348ae1ce6c60d44f3191b6d8ea3a2d9c92154
+Invalid =
+
+Curve = P-256
+X = 9157dbfcf8cf385f5bb1568ad5c6e2a8652ba6dfc63bc1753edf5268cb7eb596
+Y = 972570f4313d47fc96f7c02d5594d77d46f91e949808825b3d31f029e8296405
+Digest = e5b30e0041a33281210644938d9aaa15ef2c1247b4178f7ca1ee935ce23daabc
+R = dfaea6f297fa320b707866125c2a7d5d515b51a503bee817de9faa343cc48eeb
+S = 8f780ad713f9c3e5a4f7fa4c519833dfefc6a7432389b1e4af463961f09764f2
+Invalid =
+
+Curve = P-256
+X = 072b10c081a4c1713a294f248aef850e297991aca47fa96a7470abe3b8acfdda
+Y = 9581145cca04a0fb94cedce752c8f0370861916d2a94e7c647c5373ce6a4c8f5
+Digest = edd72dc0aa91649e09e2489c37ec27efab3b61953762c6b4532a9b1cd08a500d
+R = 09f5483eccec80f9d104815a1be9cc1a8e5b12b6eb482a65c6907b7480cf4f19
+S = a4f90e560c5e4eb8696cb276e5165b6a9d486345dedfb094a76e8442d026378d
+Invalid =
+
+Curve = P-256
+X = 09308ea5bfad6e5adf408634b3d5ce9240d35442f7fe116452aaec0d25be8c24
+Y = f40c93e023ef494b1c3079b2d10ef67f3170740495ce2cc57f8ee4b0618b8ee5
+Digest = 0d06ba42d256062e16b319a0f3099109518a765f26bac3b9f56930d965617726
+R = 5cc8aa7c35743ec0c23dde88dabd5e4fcd0192d2116f6926fef788cddb754e73
+S = 9c9c045ebaa1b828c32f82ace0d18daebf5e156eb7cbfdc1eff4399a8a900ae7
+Invalid =
+
+Curve = P-256
+X = 2d98ea01f754d34bbc3003df5050200abf445ec728556d7ed7d5c54c55552b6d
+Y = 9b52672742d637a32add056dfd6d8792f2a33c2e69dafabea09b960bc61e230a
+Digest = 41007876926a20f821d72d9c6f2c9dae6c03954123ea6e6939d7e6e669438891
+R = 06108e525f845d0155bf60193222b3219c98e3d49424c2fb2a0987f825c17959
+S = 62b5cdd591e5b507e560167ba8f6f7cda74673eb315680cb89ccbc4eec477dce
+
+Curve = P-256
+X = 40ded13dbbe72c629c38f07f7f95cf75a50e2a524897604c84fafde5e4cafb9f
+Y = a17202e92d7d6a37c438779349fd79567d75a40ef22b7d09ca21ccf4aec9a66c
+Digest = 5aa8e8a6f0622b841416e1a70d79a54641d2c699a075b6960fe5dcf96301da8ca6f15b0948d4ededac30a42e00d3b310
+R = be34730c31730b4e412e6c52c23edbd36583ace2102b39afa11d24b6848cb77f
+S = 03655202d5fd8c9e3ae971b6f080640c406112fd95e7015874e9b6ee77752b10
+Invalid =
+
+Curve = P-256
+X = 1f80e19ffeb51dd74f1c397ac3dfd3415ab16ebd0847ed119e6c3b15a1a884b8
+Y = 9b395787371dbfb55d1347d7bed1c261d2908121fb78de1d1bf2d00666a62aed
+Digest = 244656186c11c2e67be88099d55e60f4b68e61fba0b214aac3399dc559cfccc02f9884e85623426dbdc3243f2b5374f7
+R = 249ca2c3eb6e04ac57334c2f75dc5e658bbb485bf187100774f5099dd13ef707
+S = 97363a05202b602d13166346694e38135bbce025be94950e9233f4c8013bf5bf
+Invalid =
+
+Curve = P-256
+X = ce4dcfa7384c83443ace0fb82c4ac1adfa100a9b2c7bf09f093f8b6d084e50c2
+Y = d98ae7b91abee648d0bfde192703741ac21daad7262af418b50e406d825eb0d6
+Digest = adaeadda3f0e941fba1d3e206a84e6d7530d800e0f215b3ddd82022f27c5be44fed27bc73084c6f7ca55555532be2e3b
+R = 597e1e04d93a6b444ccc447a48651f17657ff43fb65fe94461d2bf816b01af40
+S = 359fe3817963548e676d6da34c2d0866aa42499237b682002889eaf8893814d2
+
+Curve = P-256
+X = 1b677f535ac69d1acd4592c0d12fac13c9131e5a6f8ab4f9d0afdcb3a3f327e0
+Y = 5dca2c73ec89e58ef8267cba2bb5eb0f551f412f9dc087c1a6944f0ce475277a
+Digest = e34a541f87ff0eaa0c640f555caec6bf11a1320c74c47a8ff172c4e2ec902e48d499732b12a86189e750bbf4c0424c72
+R = df0b0cd76d2555d4c38b3d70bfdf964884d0beeb9f74385f0893e87d20c9642d
+S = 128299aabf1f5496112be1fe04365f5f8215b08a040abdfeca4626f4d15c005b
+Invalid =
+
+Curve = P-256
+X = 7ffc2853f3e17887dda13b0eb43f183ce50a5ac0f8bba75fb1921172484f9b94
+Y = 4cc523d14192f80bd5b27d30b3b41e064da87bfbae15572dd382b9a176c123a2
+Digest = 0689927a38486cccf28fe9454e08e0d74843424b89be4cdee8e48f39a69addec730184da72f914cea67231c765ee2574
+R = 3156176d52eb26f9391229de4251993a41b8172f78970bb70e32a245be4bb653
+S = 62827a29e12d2f29b00fb2d02dd5f2d5412e17a4455f4431a5c996881fdfc0ee
+Invalid =
+
+Curve = P-256
+X = 5569f76dc94243cde819fb6fc85144ec67e2b5d49539f62e24d406d1b68f0058
+Y = 1208c38dbe25870deab53c486f793a1e250c9d1b8e7c147ea68b71196c440730
+Digest = 97f8f8cea435282ac746730ac744bf97d85d4e249c0b1d9c7b83c7e59aed172ffc3724d7e6fab7d6ab55ffb3a39c0775
+R = 706f2ba4025e7c06b66d6369a3f93b2fec46c51eceff42a158f7431919506cfb
+S = b4e75ac34a96393237fc4337789e37168d79382705b248051c9c72bcbac5f516
+Invalid =
+
+Curve = P-256
+X = e4b470c65b2c04db060d7105ec6911589863d3c7f7ce48726ba3f369ea3467e8
+Y = 44c38d3ae098de05f5915a5868c17fee296a6e150beb1f000df5f3bec8fc4532
+Digest = 5b937a2af46dbf18b4a6fb042ea353a6878e0d4beac016002b3d91a42bcba52856c07a3f35c08dfecb4f03e1c0b9948e
+R = c9c347ee5717e4c759ddaf09e86f4e1db2c8658593177cfda4e6514b5e3ecb87
+S = baae01e9e44a7b04d69c8eaaed77c9e3a36ce8962f95cc50a0db146b4e49eb40
+Invalid =
+
+Curve = P-256
+X = 96050c5fa2ddd1b2e5451d89ee74a0b7b54347364ddc0231715a6ef1146fe8dc
+Y = e0888a9e78aeea87f6e1e9002b2651169f36c4ee53013cfc8c9912b7fd504858
+Digest = b123e07744f05ad523790ea5bfa3f848869a3bfdbf936a496c8606b577ed8427eb7ee888e0fe18d4e3cfac73baad883f
+R = 2353d6cd3c21b8ea7dbc1cd940519812dbe365a3b15cd6aebba9d11cf269867a
+S = 85f560273cd9e82e6801e4cb1c8cd29cdac34a020da211d77453756b604b8fa7
+
+Curve = P-256
+X = 0c07bb79f44012299fbfd5a0f31397aaf7d757f8a38437407c1b09271c6551a0
+Y = 84fe7846d5d403dc92c0091fbd39f3c5cbca3f94c10b5cae44e2e96562131b13
+Digest = fb8d12652de59e63ef5297641dfbce084808de146720e9069c2ef814bcd80b6187f7422a6cd9c706f8d64ccf80e8bc54
+R = 49e9425f82d0a8c503009cead24e12adc9d48a08594094ca4f6d13ad1e3c571d
+S = 1f1b70aaa30a8ff639aa0935944e9b88326a213ab8fce5194c1a9dec070eb433
+Invalid =
+
+Curve = P-256
+X = 71db1de1a1f38f356c91feaff5cfe395d1a5b9d23cf6aa19f38ae0bcc90a486d
+Y = ecdd6ffb174a50f1cc792985c2f9608c399c98b8a64a69d2b5b7cdd9241f67e2
+Digest = 2d8c6585a3b6319a556e27b53d434f455f73e771c8fc6a115f5c92a8e9a81ce2b4336a5c3edf98910689d11f4c93632a
+R = b0443b33a6f249470d2f943675009d21b9ccbead1525ae57815df86bb20470bf
+S = 316dbee27d998e09128539c269e297ac8f34b9ef8249a0619168c3495c5c1198
+Invalid =
+
+Curve = P-256
+X = 8219b225aa15472262c648cac8de9aad4173d17a231ba24352a5a1c4eea70fad
+Y = 0fee2b08ad39fbf0db0016ef2896ca99adc07efc8c415f640f3720498be26037
+Digest = a4cc3b23f54d9d48ba6b0ad3da3b2e3a0806f41348bd7844e9c9b8648753bdeef8a039e1fa4f5172c89148d65b14056f
+R = 134fb689101aaad3954de2819d9fbd12072fe2bc36f496bbf0d13fa72114ab96
+S = e65c232bd915b59e087e7fd5ec90bf636cfa80526345c79a0adfd75003045d6f
+Invalid =
+
+Curve = P-256
+X = c934195de33b60cf00461fc3c45dad068e9f5f7af5c7fa78591e95aeb04e2617
+Y = b588dd5f9965fdaa523b475c2812c251bc6973e2df21d9beaace976abf5728cb
+Digest = b962b63a7743ad77f9072f2f08d277f6dda8cc3420ddd37d873746008895902bcce218fbfed1a8cb28406978dd8e5134
+R = 71f302440eb4ed2a939b69e33e905e6fdc545c743458d38f7e1a1d456e35f389
+S = 54eaa0eb9cd7503b19a9658f0a04955d9f0ab20ebc8a0877e33c89ee88ad068f
+Invalid =
+
+Curve = P-256
+X = 9e1adcd48e2e3f0e4c213501808228e587c40558f52bb54ddbb6102d4048ea92
+Y = 34eff98704790938e7e0bdf87ae39807a6b77dfdc9ecdfe6dd0f241abae1aeb2
+Digest = 21b883fae159867731b123a2606e9b3320fb53a00e4a5dfe3bc3429dd53b8068197be3c7288c1e0bf28a4fc7b13bd70f
+R = ce4f0d7480522c8dd1b02dd0eb382f22406642f038c1ede9411883d72b3e7ed0
+S = 8546e1ee3b77f9927cdaccbc2f1cf19d6b5576b0f738bb1b86a0c66b39ca56fb
+Invalid =
+
+Curve = P-256
+X = 93edbecb0b019c2cc03060f54cb4904b920fdb34eb83badd752be9443036ae13
+Y = b494e9295e080a9080fe7e73249b3a5904aa84e1c028121eecd3e2cf1a55f598
+Digest = fcc17b88077570c053650e1de42ae6bb1522900b38996decc87704aab6a87ab01d52f83f6442875f378a262c22d23ab2
+R = eec2986d47b71995892b0915d3d5becc4dcb2ab55206d772e0189541b2184ddf
+S = 8a6c1edeb6452627ad27c8319599c54ac44cdd831ea66f13f49d90affe6ad45b
+
+Curve = P-256
+X = 3205bae876f9bd50b0713959e72457165e826cbbe3895d67320909daa48b0ebc
+Y = d1592562273e5e0f57bbfb92cedd9af7f133255684ee050af9b6f02019bbcafa
+Digest = 299a6070d32a5557010753d7559dbd8d2bde8a8feae5417616ceb5b167997fd2fac0c2bd44264106d3a9720d5e805a04
+R = 0124f3f1c61ec458561a4eaa6c155bd29e59703d14556324924683db3a4cf43b
+S = 688a5c5fc0c7ba92210c50cce5b512a468a880e05acc21ca56571d89f45f603a
+Invalid =
+
+Curve = P-256
+X = 484e31e69ef70bb8527853c22c6b6b4cd2a51311dde66c7b63f097dbb6ab27bf
+Y = e1ff8177f4061d4fbbacbbc70519f0fc8c8b6053d72af0fe4f048d615004f74e
+Digest = f1e9cda2e096ece9a1fc57e55eeeb56b1c635380c0f9a1800a4a1a5f105d1fc0c60e776234daaa8a6f7c0f5286bb420b3f607e7cc0a7d840ad5dcbab26c797b0
+R = 91a303d8fe3ab4176070f6406267f6b79bfe5eb5f62ae6aeb374d90667858518
+S = e152119cefa26826ea07ec40a428869132d70812c5578c5a260e48d6800e046a
+Invalid =
+
+Curve = P-256
+X = 8b75fc0129c9a78f8395c63ae9694b05cd6950665cf5da7d66118de451422624
+Y = b394171981d4896d6e1b4ef2336d9befe7d27e1eb87f1c14b8ddda622af379dc
+Digest = 0527199fadea30f9e5e66166a3ebcdf6aedf906984535f48165e591eff36f1c0de6b0fa69aefb6399e8a213cc2ce53268fbe18c3471b7708bc27c426aaa769a4
+R = 17e298e67ad2af76f6892fdcead00a88256573868f79dc74431b55103058f0b0
+S = 881328cd91e43d30133f6e471e0b9b04353b17893fb7614fd7333d812a3df6b4
+Invalid =
+
+Curve = P-256
+X = 76e51086e078b2b116fd1e9c6fa3d53f675ae40252fb9f0cc62817bd9ce8831d
+Y = ca7e609a0b1d14b7c9249b53da0b2050450e2a25cb6c8f81c5311974a7efb576
+Digest = c926a5026d8f83ffa2092caf863f2d8a886af391462969b13a11d3c6c5fa66bb4281bc6e60a1e99a2e1ae95d689a66282096a0f27aacc048f32d39297649a014
+R = 23b653faaa7d4552388771931803ce939dd5ee62d3fa72b019be1b2272c85592
+S = a03c6f5c54a10861d6b8922821708e9306fd6d5d10d566845a106539cbf4fadd
+Invalid =
+
+Curve = P-256
+X = bc7c8e09bd093468f706740a4130c544374fdc924a535ef02e9d3be6c6d3bbfa
+Y = af3f813ae6646f5b6dbfb0f261fd42537705c800bb1647386343428a9f2e10fc
+Digest = 4d74631eb67fd1a6fa93ecb6e6112b6699e78c1d4c24ae81d0d5842efe5d93c2fd7a7863f8d45d1b2fafecbe41b7dc19c4b2bc208e014ffdc216e7eda0392a70
+R = 6bd7ce95af25abfbf14aef4b17392f1da877ab562eca38d785fe39682e9c9324
+S = 6688bea20c87bab34d420642da9bdd4c69456bdec50835887367bb4fb7cd8650
+Invalid =
+
+Curve = P-256
+X = 9cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f7
+Y = 2d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78
+Digest = 0250f93e6932887df519921f9a8dcff110be0768dc351ef73a940a579fae2d20061759e892e289c3e4ba5f7fe17d6ebb15c5931d48db55ebc81549f6637292fe
+R = 4b9f91e4285287261a1d1c923cf619cd52c175cfe7f1be60a5258c610348ba3d
+S = 28c45f901d71c41b298638ec0d6a85d7fcb0c33bbfec5a9c810846b639289a84
+
+Curve = P-256
+X = e31096c2d512fbf84f81e9bdb16f33121702897605b43a3db546f8fb695b5f6f
+Y = 6fbec6a04a8c59d61c900a851d8bf8522187d3ec2637b10fa8f377689e086bba
+Digest = f91b09107d10904d3968ec29f85e456ac4e828f32e8da3db6a13f5566bfa625e2ad03f8dad5425a073c0d61d25de63dcafa9f4fcd206f29e9cb6b0fecd74aa57
+R = 1b244c21c08c0c0a10477fb7a21382d405b95c755088292859ca0e71bab68361
+S = 852f4cbfd346e90f404e1dd5c4b2c1debca3ea1abefe8400685d703aea6c5c7f
+Invalid =
+
+Curve = P-256
+X = 633c2ee5630b62c9ce839efd4d485a6d35e8b9430d264ffe501d28dbace79123
+Y = 4b668a1a6d1a25b089f75c2bd8d8c6a9a14fe7b729f45a82565da2e866e2c490
+Digest = 575c64df58c8dc517ce65b388fa3ed69470163afecbabc3fa94b497ff7f3fe36ff12fabe2b84cebbf667744195091e4e2335a71d36414e0af0d0260fc8e8ea44
+R = bf2111c93ec055a7eda90c106fce494fd866045634fd2aa28d6e018f9106994e
+S = 86b0341208a0aa55edecfd272f49cb34408ce54b7febc1d0a1c2ce77ab6988f8
+Invalid =
+
+Curve = P-256
+X = f78dce40d1cb8c4af2749bf22c6f8a9a470b1e41112796215dd017e57df1b38a
+Y = 61b29b0bc03dff7fa00613b4de1e2317cfbf2badd50dee3376c032a887c5b865
+Digest = 4c097f2f5b2489c94258b34d529675bb5d77d4be083b51b01188dd42b4b5473982728763ee6fbad479375c5eacb5edaaec0b6583a10b19aad81ec88dde2d0e7f
+R = 4a96169a5dea36a2594011537ee0dc19e8f9f74e82c07434079447155a830152
+S = a204eaa4e97d7553a1521d9f6baadc0b6d6183ba0f385d8593d6ca83607c4d82
+Invalid =
+
+Curve = P-256
+X = 3fcc3b3e1b103fe435ac214c756bdaad309389e1c803e6d84bbbc27039fcf900
+Y = 7f09edd1ec87a6d36dc81c1528d52a62776e666c274415a9f441d6a8df6b9237
+Digest = 1a3dd21cb6ac1fa7fc196319cf534b7608afb93805420fcb5250dff453564a5b22e22971a3ce6dd222405fea018cd0508d86c561eca15e1ac7d79c14e916b86a
+R = 1cac13f277354456ae67ab09b09e07eb1af2a2bf45108da70f5c8c6a4cbcd538
+S = 5d83752e540525602ba7e6fee4d4263f3eda59e67df20aac79ca67e8899fed0d
+Invalid =
+
+Curve = P-256
+X = 5ec702d43a67ada86efbfc136cf16d96078906954a3f1f9e440674cd907e4676
+Y = 05a62044fed8470dd4fca38d89d583ce36d50d28b66ab0b51922b21da92c56d9
+Digest = c5c016f6c9b525987dd835131def77cc72d8360d364eeccdd7af8b95712b6cd487c0b846201f3b64466fd140833514ae8d765da395fbd9d3c03ca410effa9a69
+R = 75f3037298f1457dba55743999976a1c2636b2b8ab2ed3df4736a6d2934acc83
+S = 19d43ad168dda1bb8ac423f8f08876515234b3d841e57faef1b5ab27359b27ef
+Invalid =
+
+Curve = P-256
+X = f63afe99e1b5fc652782f86b59926af22e6072be93390fe41f541204f9c935d1
+Y = f6e19ce5935e336183c21becf66596b8f559d2d02ee282aa87a7d6f936f7260c
+Digest = 9eb2f9fa96a1f3ffcef9600522730e86d26d328ec0c1bf2fbfe55a38754610341fda1b894fdcf10c9bc4f48819010fdcf0d24f27ff539e40c6855cafbd306386
+R = cef4831e4515c77ca062282614b54a11b7dc4057e6997685c2fbfa95b392bf72
+S = f20dc01bf38e1344ba675a22239d9893b3a3e33d9a403329a3d21650e9125b75
+
+Curve = P-256
+X = 6d11b09d2767cf8d275faee746c203486259f66dd2bfa3a65c39371a66b23385
+Y = 4eb05c73e05261e979182833f20311e5366f72f4b949665ff294f959375534c6
+Digest = 0e71b28b0a1eac7aa881c09daec616c93d9a9286b5f5fdf2642d211021b125fa884b2595b73c7c3e649e61cd7157ef6660076a3b87ddf830db46533f3aa30afa
+R = 15a697cdb614e11c0810e1e764cd501fcabc70874c957587bc4883d9438e177f
+S = 7bf6244f92bc768063cecb5336c8eaacd23db930b28703560f241c7d93950dfd
+Invalid =
+
+Curve = P-256
+X = f3899caba038efb534c4cea0bd276814ffd80194473c903b81af11c8c05cb6e6
+Y = 6ea6b17402fcf2e8e737d11ffc7c2ed3b2d0bc3b8f271a381f4294cff62682c3
+Digest = 104ace16689d785df09a81c5cf47a496db30fbd696aa4df080219487575a23641436e70329dd1c13290582c0d03aae200e51189d43666c86f38a5203c16cd7e4
+R = 57b99380452e1d37b133c49b9ba493dee8630940477ca3351a43d90b99871e6a
+S = df599c3a37105af3ecc159b3b685ccb3e151b7d5cf2d97147974ae71f466b615
+Invalid =
+
+Curve = P-256
+X = 1fd6f4b98d0755291e7a230e9f81ecf909e6350aadb08e42a3262ff19200fbd2
+Y = 5578fef79bc477acfb8ed0dc10c4f5809c14dc5492405b3792a7940650b305d7
+Digest = 761a54f3718985b6d7bcfdd57d6c4823f854831bd29305fcb07e34e3f825d451fca28a62ce9582e3957d89ea7c1bc1afe3aa58fd2fa18566974600fc394cf2a8
+R = 97a99e96e407b3ada2c2dcf9ceeeb984d9a4d0aa66ddf0a74ca23cabfb1566cc
+S = 0ecac315dc199cfea3c15348c130924a1f787019fe4cd3ae47ca8b111268754a
+Invalid =
+
+Curve = P-256
+X = 2dcbd8790cee552e9f18f2b3149a2252dcd58b99ca7dc9680b92c8c43aa33874
+Y = 5dbc8bb8813c8e019d80e19acdb0792f537980fecde93db621aaf1f6d0e6ee34
+Digest = 45b082e804443b53a82229cdf13e4c5f8f31fe93170cc8a23f63eef506cb7748388e1a971a2f81e3daa324cf2bb69118f7418f40df66a24f50c34a55e1416c3a
+R = 2bdbd8b0d759595662cc10b10236136ef6ce429641f68cf6480f472fcc77bc9f
+S = 7e7df0c8b86f7db06caf1610166f7b9c4c75447f991d5aaf4dea720c25985c8c
+
+Curve = P-384
+X = 6881154cfe3f09affbee04cd387b27b7854326faf8906c4b9c9e6ac2c632e0d59717b3f33f6d747d7b7cbb4e4dc01fb8
+Y = ba295ae0966f06ad9d84b3bb4da7f99b56044c99f88d71082cfea6964ea3c63bb79806a6a41fcc314b55b3f64f82b68a
+Digest = 8a6429d55885146f7aab582a1aa9360fa9591b0a
+R = 2112385a75d4edda89ae2bc3c74524dc792544a3a52fdb588da3f0feaee6a11623db275e2ab8abdd998cc42a29c60856
+S = 8d308a3987b81c595f8cec19898b1a42da8eda97496af280033b0f915283f171fed7e2a221fa9c78927962189333f437
+Invalid =
+
+Curve = P-384
+X = 2f2f43f244ae027c3d2ec5c900393f80a8ad0e9b9a12a047195d29a39f2b7026b071688dd9a6764379d02a5ed8035ec1
+Y = e43d45851bc76c37d34dbed996a65ffcfbbaf0e2cbfbc9f62d2116bdf3b330bbef5acdbcd0aa6d949f771daa17cda1e3
+Digest = 5f41322db1a276042ae807f0f0d6f1e04cb5cd26
+R = c011c52e9cb02048957a233704ff9a2c1d4c56e08ebb083aa8ba351f041a23a7d0da19088ac6c60ea2ca117531c7cf35
+S = a66ca9bf06c35d129a8253a0f793acf681e482d9994868b275a230b215286e03a66a0de77c7a53174375137fd4688556
+Invalid =
+
+Curve = P-384
+X = 9a5e1932d318bfa7986f0dac4489c6f55775427bb60fb24bac7646b9994bbc3a9b5cd15e818cc4e832afc1c3fca9abae
+Y = 64c89e7c3399c136b2718ab675944207157f0bf23d9e2a807ae7ac3bef81da7ec3c56c2d2c08afc53301af2a3cc71861
+Digest = d36ef9ee70a3b61ba31cdfcd0cac6e49331a407f
+R = 4cf6c63fea6c80efc105cd99afe2b53da05ae16566ddb20b9d40a076575ffac419b6807fa336fc6e7c7416c59775ef09
+S = aec2d96054b4b23c49faaf9903ccf63bc96281fb7c1b9d14daa54bba51bb2b2f4d3a901f3b0b9cb2b62976459219350c
+Invalid =
+
+Curve = P-384
+X = b3aeff27b65540c6da10a88008404b1d49239c87fbf47932518fb87a9bb132403d1f310f531d086340bb4a68c3e64b9b
+Y = 567e75f442fcd81017b8adc4cce634f5ffa3cd497d38221d34dc1f43aef99133131ff1b197f7b9f37beecae5c438849a
+Digest = dd0f9c326fb50593fd0a0df31abeeb00a22eb956
+R = 3b94a2514eb915b71e18c867ad7f508a35375c5bcd4b797b86054798569870b2477e2ac14406628017d829400efc63b2
+S = 179a10441a0beea3b375248e697e0d19e24bb68184c373fe4302839b97dd7353a5a25929c2733796b0c0d8211bd67c51
+Invalid =
+
+Curve = P-384
+X = 0874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d9
+Y = 1f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267
+Digest = a871caf9fff9856031a79a55b96753c1a34ccb73
+R = 8d9d3e3d0b2b2871ea2f03f27ba8699f214be8d875c0d770b0fff1c4ce341f0c834ac11f9ec12bfdb8320b1724c8c220
+S = 62150dfba8e65c0c7be7ef81c87241d2c37a83c27eb31ccc2b3c3957670a744c81be6d741340b5189cc0c547df81b0d2
+
+Curve = P-384
+X = b4b92211edbd41c5468d2ba70810bc37b5e7c954c7bd0db80c4fa89ccba10bf07cdab953828a068bc0104d28e4040c14
+Y = 93ed318efce3dff98fc782b788d78658ea5ecde4f716e2d5d0ec2d87a2e761daa1f1658cfb857762caa567baaccf9924
+Digest = 765343d50541bc2c0e20193648048016a95e7588
+R = aa3978eabd196ddf9cab2815cc9cbab0b61cd639deaf70e093a10a58ddf9f410ee1ab965ff8fbb98efbe812421a613d3
+S = 02761a2947e1855806b8a25b9ebb0762be9f5517461a371e5783f34b184f32c4ea684b362119b1a2d8a3ff439f10291f
+
+Curve = P-384
+X = 63b4cc14f9efd3b8f29e65806591d1e9c54f34a3f5231339bcdbfa4109c42d946a59cdd7bbd2591fd1b2383a0819772f
+Y = 55ab3d208109da6ef039c23cddd52a5af619266d8fe066dcabb1af885ad5501401a78c44ed3b5fff2892fdcb2a3ac8b2
+Digest = 4535ef8d7396b4f2af65660ebbb56f356cacefd9
+R = a3f9b840fd7201356f35b5dde39027410aad26ac61919c14fe7b0535bb74e7218cb3312bfa60aac63f14166f32ceff26
+S = 1b1bcbcb0237fad4e406c8d4e3e39b55642d8535afa9ccbc9c601cb4e01891df79f1bc792687cb3a5ee7703565c4a13b
+Invalid =
+
+Curve = P-384
+X = f82f82f8f7454ce7a94a040ec0bbb52d49e3b9f8ddd095704973c760ee6067a5c28369656f22d70d8bb1cd70ef9bfea0
+Y = 0e36e256d02870ee5646a17aac4b280c9d1d2e1d4803eb3cb32e7f754cc889522120efd7c4d8a82e509a4d8f266d3ce4
+Digest = 26302c41e6da59e2df2e26c12382738880be94cc
+R = 27a2332f3c59464f5dfe7bb1201a3936248d375bde603724c048eb8f7c0c2be3ed4b56c14b51d7d68bd2554526b36d9e
+S = e1f90367b0cc530c545f95163d9ffb1208c943685d5ae221052b83ee40953397be581e5979c9855b20246e9d26d57acc
+Invalid =
+
+Curve = P-384
+X = 7d40b51127cb1642dd8538d4124138a2f49c41b4d12f702c1b0cec8deba50c3712e01c2e1e693e00438af0e86025da33
+Y = e734b5939b673c45dd32baf20d234f01b7124b391d14beea231e9c604e813fc83b3a77b0cb1f2ce4873a69b0165e369d
+Digest = 0b30b209147432207a72177997d28d6f1d03330f
+R = abf16821b6657e0005071f78c679cbbb130bee6e7ca63526eef0f747fb721feefe6258dae1aa02064a700e963bd9dedf
+S = 3f7e61c34a30cc5ff7a8be375fcc9c38a76dbc0c30a4356843421ca37a7bcf24edcd41d8235903bb522fb6e5a8033885
+Invalid =
+
+Curve = P-384
+X = a5b59d59599c105e39f61354da99c7c9135c749cf996cc2252eb83b008299cdafbcb44227d2d2c4a5ffa44823922893b
+Y = 0399fb0edcbfd0b76b524f22b7b87ddbb4fa02f510661615312a4492eb3f2001e0fc0e479f77c33a88f9a7e20757373c
+Digest = 44aa3083d111bbce7feb412af74a782cd320becd
+R = a4c9cac2409a9bfea1ebe28fec4e19545f08cd18fdd31048f52a3f2d32b2ed859dcae4dc12fb2fecabe542c4f03191ba
+S = b4d83f927ad1980d96cbb0ccc36aa640f786293b8b19e4dd97a797d192b420f630a5e42ac42d8736e7d42008f445dbc1
+Invalid =
+
+Curve = P-384
+X = 29178ce9127e1048ea70c7d435439e9ff9915387e51b7e5ca10bfdafe53565978eb3784d9a4226f443d4834f4d451685
+Y = 5cc2970589a453488649711bdf3cdac9a200519aae65b1c6bd54fed0d965755b36b74d978d674275bd71a03e8f054b0e
+Digest = c679b4a0e61406c4869d721192bd314d77e1cb39
+R = 5d6f5e9a94d9c92a0890c558bc0408b3405cd04e33f663df16701e80520e4394f1c54d3c8225d36f4753a799aaf6ff90
+S = d895b1cc522ceec6a7867867b8f603245c6e4d48945dfc43af721ebae4683d40a3c21b905ca3bd4b974d36806825b2cd
+Invalid =
+
+Curve = P-384
+X = 9f03569f8c6ca2c16d707f0ca36a8a8cf214a9d5c14034829d709e283cd675eb4e3090c6b973429efdf476c0782e0a7c
+Y = e1b842536731e91596782787d57af17db85dc92fd2fb95ac65339174aee66775ce0a4721d1faeb29da968ea5eb705e59
+Digest = ae1a63f88a59c7da5d9f512d11bbd5d75dd1f583
+R = 31ccbe22a360b1786dac89394c6ef4ed6604943e50837395f96052821f6182914840096e90f2ad650917bd91d7bd4cfd
+S = d97199a6b952dcaefb1defe23def92bf2ee236ad18046a2ccf8924d42ee10a62e70ffe7f3c909b11112278f160d98b7a
+
+Curve = P-384
+X = b85e78a935d169dd5ba8f558f964b21c07804464816f9231233184675f557463a8b00470ac0ca8278cd008f4642e7962
+Y = 8edf7be8584c5f207939d479e65173e2e69673090a8538fa93efb4432127895d92b4e4cf13b7632a830e9a33b37f75e1
+Digest = 811685f7ff2701e692f6830a33d8712d0432cd5a
+R = fd2876b250a94ced71734aa7a0d32423b2c6f039c926c557e748f38e23bbdb46e17d1204832c6f76c3ea854e1da23979
+S = 76409e381799502c81194ba87540aec0b89fc4680dd683780d49f82a46a7191b40f5f06ccb02e45e704c31fcd59382b9
+Invalid =
+
+Curve = P-384
+X = 0c74aaa0527524cb6171ab741896b405a6ac4615e474cdc09c9457b18bed33c6383e1b92f2fa1306e8e5dcd1667e45fe
+Y = 7b00d934dfd876f6e07dc0582b20ed650be104fa603a5a1255c62b6059d2685aa9773f1ba31254d213c815d0efc8ed93
+Digest = 328029316d73d1b8d2b8927d12332036e5671384
+R = 832c62b0f34986eda9d1ace5068a0c5318051b0d0166d3dacf137ac072cc359f109ad6e17059e700bb1958bcf4101246
+S = 6bb56f4eb550688ea66e5dd09aebe7e0b39e2716b4697ebb68f113e080f0ff26fd0fc947a34f3c5a8a2f10e07dc1405e
+Invalid =
+
+Curve = P-384
+X = 4104de08b4108ee26ee239e0a5d340c1b1aa48b1b3b40717debd6ed3ff0d777923c106f857a3830ce7f3d08d0d6d7908
+Y = 00498c38393e6393edcf254804558f86e461df1f5a6557bc5144f8d2f3806413d372b6ce417d531c08a52d1e38e8b949
+Digest = a13ebaf4431c43b684d1e18e610a75fd7527200e
+R = 9924a3273248db20db007309560a0e616572ac799d773529a5215786cf4a6e03cc73bea81d4810c1eee4b5e975652eee
+S = 6cc8ea4c4c56da87c25946a198e86917227bcb90da7be1dcde7b6547bc45a98e8175dd54af15bb6ef955b4cb48b7bb0a
+Invalid =
+
+Curve = P-384
+X = b6bc9418f3da0cce38a65f1b52bb3a9d22a0368e02f5f12fa1f1303ac67df1cffa55d049a782bf5bddb5e841b125aed6
+Y = 3b578a0560280a2958a14286e10faa7f5dec77fd8d90123aff5780efa8a636cee833fc9f10d7a164f1254a483b613746
+Digest = 7b44de2e448107197558cb071bb5bec9a5849467827d29b2c6625708
+R = 6602090aec001c16e5f6e7e3e488bed5d1702d36b258b6a8a2d8392a5ff30a6af12fbf4308d67eed6aaa8b7be8b831c5
+S = 65d0c3bb1910ba0b7cc108ae1ccaae63405ff01a8df91021e17cd46aa6f8ca8f4eaeac6d6fc26fc816a3ea537fd9576b
+Invalid =
+
+Curve = P-384
+X = b4ab83a4ded7d76aa15eaecb1bafe59427d3cfc38564af9123cb707da2405184acd40a6c093ba29e321ba0f67c1e0c6a
+Y = 26e2902499495f8550e798617a44ac9990c4c1cc3527dc0dd003a15aee3cbd3955151f7863de1692a94aafd3730e7665
+Digest = 8f902a34f36d7cd36748d5ddcc8fba6040be223a462842d506f185d1
+R = 61e48d5a100049578e820768ea57f30f27ffd1a1f839fabc55e8f4816c9b95d042619cd3bcc7180fd99834e344f53e7f
+S = 977b81d43216f31d8bedc3ffe873047817de3441df8b80a321aa0a80931f25a15c6628f43cf8e48d5c6aeca7626b0a18
+
+Curve = P-384
+X = f886f36fcf34e8df2a7e09220051b9981a3a6f693ec5999f28864e012c13896d633c9564f0118a95631cea8355b25b20
+Y = 746f9a77835325f18338dee5dc88a9b086b858ce15b4e4462a98844bb01811195f4fae0bee8f457c32823e142210dbb8
+Digest = 6a80377d3c7f0e6a50f6dc1656cef5a0d33cf7934441244f69f0062a
+R = 665390653ed280b8f6bd3718d8423f26cb38d2d7faa10fc0f094295677d9dafad45fc64cfc22ded56afdd86a77cf3c33
+S = 864f0eb3a8d93c388d987cfcb60bba76098039d46bf4ff4be083961f70a29e724c25cf56685802b7b5be048107ad52e3
+Invalid =
+
+Curve = P-384
+X = 5fc835a2f5429adb719ed22f11dfcb02731da6759a8ea75c21d1af9631187626c31e191f4dcdc183df01c48e13dbbce6
+Y = 9ed2d03df1cbeaefd4478b8106e90f92e0b6e958145cb81b9648aef0b96b71d1d55918564694b1987d68cc8e7cbd7dd1
+Digest = 807f609592e2ededa12792a7006a6db641904e86a1df3cec477dfd3c
+R = 94d9dedd27f2d014ba84ea58d2e88d68f3e86ba88b93750e50255211effe88b0a0e2f62017f22965726cdc77c55bca4f
+S = 14814bd09d9b7ba81b2485777cc588b5c0a4064df95c63f18a8bfd57494cd0f40c5bda9dc6c01ea72540f57a354360ef
+Invalid =
+
+Curve = P-384
+X = 0b86851d7c19f0f04a16e5e2903a36d09bf1863e152d87936fb2d74cf916bcf6dedf3c066d242f7dd327df0fcb42270a
+Y = b0c93480740bb635e6c25fb61630fdfcc462a1418366a51b1265656f721e18ba89ebf754c7dfdad865a252c884a6c4fc
+Digest = c34e896a31fc4de7596679e12bb2416a51e58e8942eabd5cb01f0737
+R = 33fa5fe3e495076e90f4b62753d3cdc7603aa7f5b407dbf89a854b9521d15e6c381d3cf28f103035dc4291ae318c5f82
+S = 30919a2a3fae71e1afe8378aedcaa08fadfab6c6bf954031452d4fe514969ede2acf0347a2f1e81abf1bfb9d8bd55a36
+Invalid =
+
+Curve = P-384
+X = 6f8f2fc40d1db28309c8850bf94d77c01c5449b4fc556e6bf50e5ee805209c4489d8ff9bd781699eb0e42f6a962d56fe
+Y = a4c7c77271dbbe7e00d1c6e4287dddc5463c6803a577a18f89a5eea01c6addc12404353abbc128cb9cf2496732312d65
+Digest = c19cabc6141b2adf67fe4bd0a3fead50473dea8cb0276de1fdc467c5
+R = 327c4642019a635d80dab82f7dc22e3102a3c1ba684c2b6de67d3d3009a17d39ae3d58ca2caec9f6f03f5ba3b406178c
+S = 6b1af807cc7265cc6d3049959cd7779ae0de819036647f9510b0e9f7e4c0e3fece5fc3741b68881145a2c944dc5c54d1
+
+Curve = P-384
+X = e98ba8016a976dcc3c50127d2af792969835b1096b1644b37c004d1786f4fb1026233f33ad56cd9444ba0a332c92efb8
+Y = 54bbcb78ffa3c855dd24bf182376ff5d28dd7b7551e4b05a19549c9f59c83dcc12a43092d63c5967fc0256612475b7d4
+Digest = d8d9319d3f705d03dfc992e8e7596586200fb1574f2a918350deb268
+R = 3b76a0c0ece2348085f3554fc92b9e5b0fe84801ab2adf1d239d7c81c9697b62285e8e5667774559d1bbc6e86f2ade64
+S = 91d929e42f8223ccc74d4cb09ee7eb619d3a348886c21091ec55d36164ad3cc04e1da6edd88ad89710a908ca4bc00333
+Invalid =
+
+Curve = P-384
+X = b8d7a836715635a8b095d3712817aa9e6ffdd98d24be2db751bb0c1fad42b082542500ea255cde17525ec159afca7002
+Y = 1a526c876d4771157b4f66e3056485c95066d4bd1e73e991ce6d5d3642807efe80015c52ef3cf8c86e57ab9a510ec86a
+Digest = fe23e8ab9dc934144247930a48babb0d8ba57703c2bef60e0e9a1e2b
+R = 9e36f47ec1b7ffdc6e3472f3cbec913494c0bbaa0c073f597e01845b5a3107c0e23a4575de4f2b582e1c2fe3067ec048
+S = b013cf51008a89b379a2a6b519b8d229ff0374401eae21a8da350fe35756b94168e7fafbd81f0f681f21c056941a82eb
+Invalid =
+
+Curve = P-384
+X = 4ffdecf5d5f7c1164297a93742c8a685bb425b97fdfe85f630dab2064ab29e52a0df34629c2531048c288216723fc9bf
+Y = 84fcff3e7e478a6932ace6f6b0ab70e61d8a5137b76886c59e721d938e0e252e2f7e57c2ab7dab90493446ad85c3fe4c
+Digest = 28d44c363bfb2e36bc59bb68c56e8b5d2587f149839fd3b8c05d9eb3
+R = 7d909d9aacf064c32d070c3149ace8b8f5d83b2006e8460b84c4bce664fc20e91c61ac8b415965b6155eddbe9238fe3d
+S = 19d909e358e71985179dab9113941ecad21e4f3608cb3a32dd065868af1657df8e06aa86855ac7ad757a7f8fb568a953
+Invalid =
+
+Curve = P-384
+X = e805e0733fc156bd582faaf794e58d4630ce73fc383cdc964dd337728f774e4989a697d79665a3282ee6e0ee343d6c7b
+Y = 43821b7b9a6ce1ddf0c59ada552668a0cfc85a87a610b5c36b7a691947116b49a4099340306e53494fc6b496cb8d12b0
+Digest = fd1bb27d666e3d40f5bd19d8c026a3614404b9edc11e582eb80b044c
+R = 3d4fa4ec95b55feac607fddc618d6f4eed71da65dc49d732e64460e5c80c57dc4421c64bacf3ef1e22995fd19c2a3cf5
+S = b11898ba475f2b28402d038afc15f171b99aab93437b35a2f8a3b89f42fdb7f93a0469d9da7652882000dd5bb1e8b9a8
+Invalid =
+
+Curve = P-384
+X = e15c7ef9791b9392c3e97389f2597ee161545c267e584b94262870ef25fda348f72349f396c27ac884fa8d776387fdd8
+Y = 107b4a7da8be564a14f9c45e4df5cc9b62f0671b3f2c0573c33fa37f985fefd1ae3ff2640947ebb12dffda72757db6af
+Digest = 3d9611421379fc93226fff23f5fe472a33f6bdc759d5705f7e9a2be3
+R = 9d715fd1a3668283fa83c407242e8d2a4f3fa1bf41919ca4101114bd0e0ac1b16c4379edb11de5210eee8618d42e9ed1
+S = 2dc37f453c8cfe01ea80c56d1865daf0f28847b12970132a1853c3ed80da6693e0da47a2476207947f29da34d68d604a
+Invalid =
+
+Curve = P-384
+X = efcb97dd73106b0a2be4f665c496352f6938da9d0fa97690dc0e8d018b06dce2ba8d19b93ddfe889d549a33e64497c31
+Y = 66a0cb7e64f40470b6d09b9e12f217b59e9e6615af52fbdc4ddcb379e77809361eca2093a3e24c7103e971567018400f
+Digest = 5598b06acf834ffbb2e50784fe2bc493fa51967f7ffadf1ece63f9b2
+R = 4ea5d4faf8ee52540db2f4c6283cea5302a3540a56e14c8a7533441c248465be99e10f23bba85be9634efaba7a8b172e
+S = 4c98a2142ecaba7db44c78658efffc1175f810a147306ba2e6498553526adb1507d7a99a372e0f84c8dbd160ef7fd5bf
+
+Curve = P-384
+X = 4e916a3cf2561580b49ecc52321db7103292fd2fcce8dd4d6f86be6035808e0df51c3c4ac1894f0b08ef6ebf953e0d18
+Y = 4e6f28895d024b4c71220b27052ddd4bf6115a260825acade48c043b3e06d2b6b8e4ebdf465980f3b013cb575d475bbb
+Digest = 1668ee6ae19c2d6f23b9184b6895ede8f55549b23095d53ef89487f6
+R = efce00544ebe0d98ba6015c07e3e9d09af808d49a0820c22ef572a3ef9c8a684b377bef1f8b3bbddb734b9b0bd0b1cd4
+S = e80d0e183b3f00098308e20e5b4ae393a07f1d1a8defda9a9d10f19b3e5236e42f593b1dc57f6718dd8d4583f0175ff7
+Invalid =
+
+Curve = P-384
+X = 3c6528c82d9d5e8dddf41a211c70f78604d81f49853bdc746270f1340a2a645dca3bc7844c3680268fa5973cd1758313
+Y = 4b9e697f1caf83d3224486bb0a8cd6a7c56e47c91043d8cba3aba51b6e504441d37abcc9b7b2d49b9126463703e514a0
+Digest = 1b39217bcc5dc841b32ddf00245623c581f19cac8a4ecd03eb2c07f0
+R = 848814c01c3d18534f39bcd53a8736db16f0f77a015a0e578cbb2f831739723e83b29cb6d4eee7822c76ff056d0f467d
+S = 05beb19f766bd1d4ec5e65786042258298a2dc617e3f13d8e2f0f4b50d934565f3162c737fa791a81897397f29305943
+Invalid =
+
+Curve = P-384
+X = 80c3f6488dcd76f33cdb75e30f8452ab9a3bd6110f14e25179b0aefe4c19c60a07b4af10844b130b0b75a7024e341298
+Y = 6c85a17ad4bbefb33910250e05ac02a17c892c3380712d06dd070843dff0d040e219dae78679b774cd5eff0adb67189a
+Digest = 23cd0066d1d88702c5d4461deff89aa5662b517806a04c4da30e0d82
+R = bc444deb0c7dd9f96f20a7ffd3ddb35a1189316655531860c39b5f87f09992106985e5562e083ee9f538c8e2d5363c52
+S = 91adde5d47eae80a98661f4347fd6e4778478c3d4aff3cff8aa92e2345a8e03cd4ab64adfd38e461bb98b496516439e7
+Invalid =
+
+Curve = P-384
+X = 97c3f446803a61a7014f61cb7f8b3f36486c7ea96d90ee1767f5c7e1d896dd5114255abb36c74be218c1f0a4e7ebba3d
+Y = 553ed1fed72c62851e042f0171454f120029adba4ee26855ab881d9470355f1947aa1d2e806a7ff2583660fedbd037a0
+Digest = 647eb206a8477440b4bd048d00f37dca8635b15c2a8e79e2a9d74fb9a5553211
+R = 7b06d6c2b63f1cc3bfdaa897d07dc15a83bdf35d979f70c34578332b3f4920422bb24867c51bde10831324df424e04ec
+S = 4bef715161f400dc98d4b63bd13ff4ad4a6c981ead44bfc662fe9bca4b56cd790698e4deddf9a4bd69327f26bfe801e6
+Invalid =
+
+Curve = P-384
+X = 08bd5c6cdc1f8c611df96485090e20e9188df6abb766bff3c1ba341ed209ad5dfd78b628ec60998ddfdd0dd029352fbd
+Y = d9831d75dec760e9f405d1aa5e23aac506dc019fb64d44bd57f6c570d017e6609f8fdbb2dc7b28ca9e00e37cd32a3b73
+Digest = 9a4985f744dd6f2774cb6f20ad6b6969e212abf4ac035b72ad3f8b1955ae1862
+R = 8b372c86ed1eec2163d6f7152e53696b4a10958948d863eb622873b471702ac5b2e75ff852149a499e61510905f98e4c
+S = b2ed728e8b30787a28f2a6d3740872e47348686c7cb426411379411310241d25f08a026b853789b1157f1fc1a7f6ff49
+Invalid =
+
+Curve = P-384
+X = 10a784abb3c549444a62c28df1c926b8aabb20c8d9aa4b1f7ca830258857cbe9718dbc9845fa9cbb78587a373baee80d
+Y = a1ad0c10b5ab6780cad49c8cd3eebd27de8f1b382ddd7a604458cef8e76ca632a7e44e1c63141a742426cec598029e2e
+Digest = f5b47101b4ff9baf64aca830b6afbc4f9620035d88a1d84a12cefa6f7f99faf2
+R = d9e52be2a3f7f566899cf6daaa38116d092473066f3a1bf91f3df44d81bca1deb438d9d25ce1632599c1d3576a30f128
+S = 0cad30bce4b3d7f40b3eef762a21bb1a3bad77439838b13024b7b2c70316875a99e80723a74a9e7a404715ca06a5d673
+Invalid =
+
+Curve = P-384
+X = 8760182393132d69011edfa127e36f92eeac8272641c27f52f3337ef8af7451e6d14f4e4590c7eb9fafb76e8c92865cf
+Y = ebc2b123ed871ca570ead40ae8f6f32335393c569b21b38f626d09c064a3c8668e9fb10a4667e0f0c68bf25ca98fd6dc
+Digest = 979131ca1d07e0b4ac6f27b20a978e0a230159eec4906db5dbd22b10ec71af87
+R = 1db957e5c2d294035d7f476a0cbc28a4aac2614d8212de5017076cd836bf04ffe237dce8fec91f2fb5ef82449ff1c65d
+S = 3e3b9058d0a9c5b417f9c6f86557b9d50e7a902694a7012a1be6bb70708497e4d39fc1f6d6bc60dfa52d23cab173385f
+Invalid =
+
+Curve = P-384
+X = 2b1f98d2acdda8347b9a68c75174408eae7de3d6b9c08c26e73ce9ed2ac147b8d90cd82e30ab43909d63f6b457de2071
+Y = 33f5e6f5f5793201991e014cce0045d04adc352298e32f45f4e374450111c8456b5c2efaec43d157949b5c191b2bc934
+Digest = a1daaf888d93a2a7e52bcd2a66cca3ff2e02916616d1919adefdd7257490e5b8
+R = 23d046402cbce807d232bcf0dc96d53c72992e0ba1ffce0d79050c0f4c5ad9bfbbdc1c96c730d67ff3aa3edaa3845da9
+S = 2cd46a4fe5d120b3af3a6d9ea63cc78f4079e8b5520a8fa96828334a4f182ff4d5e3d79470019e4eb8afc4f598b6becb
+Invalid =
+
+Curve = P-384
+X = 86ac12dd0a7fe5b81fdae86b12435d316ef9392a3f50b307ab65d9c6079dd0d2d819dc09e22861459c2ed99fbab66fae
+Y = ac8444077aaed6d6ccacbe67a4caacee0b5a094a3575ca12ea4b4774c030fe1c870c9249023f5dc4d9ad6e333668cc38
+Digest = e3bcded61cbb0bf6ec20d59f91e8e73e532f15b082b89c984c1b51fb0d1db8a9
+R = 798065f1d1cbd3a1897794f4a025ed47565df773843f4fa74c85fe4d30e3a394783ec5723b530fc5f57906f946ce15e8
+S = b57166044c57c7d9582066805b5885abc06e0bfc02433850c2b74973205ca357a2da94a65172086f5a1580baa697400b
+
+Curve = P-384
+X = 9e7553eab8cc7e2e7396128f42ab260c6dbb5457cbff2070ea7c0db21def1537939e3f02699e5dd460eca3798d08bd6d
+Y = 892c0c8e47dddf858e89099a8fc1026e8b8333532b22f561f7647f63f9c79dbf5e8dd18fbfe6ff34902233119c5d5aa3
+Digest = 0f2a9b447ea5cfcfb9e67d661d7f0752befd3b4e3454fe40b9ae1eca47806025
+R = 2452da6a48c3749b66e576e0f1f768d51728be17aea149164c4e1654c5ce27f625a4610c4a2eeddb3a0626d3abc6c37c
+S = 499504fb58c9db24a7ff5f7921e1312f8aa583c08a308e080f5ef1acf5cdae7927c4101573db069ab0b6de7f4f1cab38
+Invalid =
+
+Curve = P-384
+X = 0cf4dc51e71185a29c0c6fa3c075d9da5bd7ede085053344dce5dbbe8329e8ac9045f7246c9d0efed393b8e113c71429
+Y = fdb7917b73974b355cf9f3bef6a0a460c2d39fdf1fe32a7744be0a54ddd1cfa8d03914cff4b5ca536b40707ff2629aa4
+Digest = 331aefe2369b9c5ee6dd9f850259b3b8512f5934434e61573f97fe2c1cd2b147
+R = 3812c2dc2881d7ef7f621993b161672329b261ff100bbd19fb5826c9face09aec2017b6843d69336b813b673c5402527
+S = 5dc102fab9d6325131c556ec00309c2959d1031a63fbc1e2d5d04996d3234ed33875c0ab98e5878e9bc72742519ed398
+Invalid =
+
+Curve = P-384
+X = 6c590434988155236b43147389c6dbfdd27dcd3387e9b4c2587ece670753a542a13a736579887791cf53d31e5ce99994
+Y = 35a20194ff3f1b55f7ffb2758ddd4b98dd0d9e0cc213e10ed25e8e0430fe861066c1d4423c67f0c93f7ebd87fd3c561e
+Digest = 153475076a003545d3ca3d4a772866f12cc85f6e69f8c486a91a80fd709206b1
+R = 89ff866889245e797926509e563b1746920b78c9370a6cdae52663730d131e558e327d1f5fef8faf9e6c802fa29504ed
+S = 8dd68e2de2f788e598b3e5a60c18d81849a0cc14b3b0e3c931910639f3125e5d6045f00330b1fa989252a80f95419b04
+Invalid =
+
+Curve = P-384
+X = 499cbdf18ec4e69b88051543c7da80845fa2de8be2b9d9045fee7f104a8b5b7d04e69142de9955c5ab18c5a34ebff075
+Y = a29cb8d28836b201a389922b6f8f93870f09c80a00242d00d32656a43ac1440fc55bcb123551a73290f603c3469be9ed
+Digest = 5f00b3b48c1ee8287abe6f3fbc3438b91f4268f318ae2aa1e7810369d6716020
+R = 25d4d243da6fd9b439a9242c3656fade7acb7a306e8cf23ea89e3ff4f9330be19c61aaa42d7b426d12c8e0f96b80dae5
+S = e7a99cf4b269bb4a6210d185e9654602523b5cfa1cddc94b1db92018aa557ecb6adda44c816975f5ec1756b6df3c44fd
+Invalid =
+
+Curve = P-384
+X = 9a74ea00203c571bd91ae873ce0ed517f8f0a929c1854d68abd3b83a5051c0b686bb37d12958a54940cfa2de23902da7
+Y = 6f20ccf8fa360a9ec03d7bb79ff17ad885f714757ef62995f824908561dc0c3dffc49d873627936a2fff018b82879ced
+Digest = 45c3a1b29a18780234f12f5e4b64e7af9de2acf0029ce55b706cc79a7e4df994
+R = acc1fcac98c593fb0a0765fce35a601c2e9570d63ea1e612fff8bc99ac2d4d877750bb44cfb1014e52e00b9235e350af
+S = 7f53de3afa4146b1447e829ebac8f5645e948cc99e871c07280cc631613cfdaf52ccaeccbe93588a3fd12170a7ec79fa
+
+Curve = P-384
+X = e22f221809fb7a054ac799a70b3d24744eb7c5096c8671770399527c88ccf9ddaea0257a0ae9430d927ff5d9f109c533
+Y = af4101d60df9b306ae92da7592f4faf3df422a3e33f1c2ed2973b2b900eefc346b4cf024de650abf537cecd12ac77618
+Digest = ef1057d83a6e6481be7caf2c12c15f085ff971f02f0db8544352558e2b9fd61c
+R = c39a8e79f0560b9f26504469a470c7b2230c0d25de07c206e87dfbde9aff0a5d85322f56dfb50d4c1fc67c67d615dad7
+S = 2ad94dd13a39cf4f4cb24c2c81d4c1181652363addd856dc9ba7455458e40ed047cd113129bc87f43949d5a98a0d5205
+Invalid =
+
+Curve = P-384
+X = fa8ebc3682d90ac7356f0b75b9e3376e76518676e0bedd176cfa7fa57fea4b3a399dbb2bf735ec90b9c1705cf9fa6f57
+Y = 18c3fbca0150ec10696b3851f31fb3ba62c0b6be509d249e0d4b374c7a08e49338e0922e2a8a9319999e6569ab8d292e
+Digest = 0c7152ec620fe9b783625196b41192dd5d49df184ad26965c970ac5e28bb1c4b
+R = fb58ab09b8a7ef7a6ec05b854eae11af9b713f7c7540e25115f609846e636ad4f88dcf4dd61e311273df23ccda474f03
+S = 485be4c21b7c3a9c6b39ffc9f0c39f4050f76d2a6b3fae203d016318c541c1b4ad6cfc0d0950636ff6883895dd49e4e9
+
+Curve = P-384
+X = e5f331536a2940cd67234bedf813c12e15aefa9a1a68429f8754bf2769a47c9c2efb5c42135e7b01a110d7302e097eac
+Y = 63b2398612c863febd482184e834d3acb51408c49aacbbd35d8719746f37cb13e013c9505ce034cd815aacd10d2f7a0d
+Digest = d925955406f6b6dd4df05270a2539a5924830dfbcbf6a5a34f21354db246244b
+R = 96c35f22d036785a392dc6abf9b3cfb0ad37b5c59caefcc0b5212e94e86739a2674020ff79258094d90d7d59f09d47a1
+S = 373cbc865384734c56952f7a35a1fdecd88e8b343ee3aa073d30f5f25b73506f1e5f5857f668b0080dec6edeb5e1be96
+Invalid =
+
+Curve = P-384
+X = c53ad865beb1e2b92764065f1a6bb465ee94aacabe43426a93c277d02e00fe36be1c859ba08a031fc518a0d007668979
+Y = 6728d42bae9bc097151748ffa0982964bdd16076fa0e7cc15837c1f773b08d02c3dbc57339091ccc34105b84781150b4
+Digest = 6d5fa5b492406a1e93df6bb6364d7b17a24ef43807a1159acc77486dd7b49b60
+R = d4f0dd94fc3b657dbd234767949207624082ff946de9ce0aeb0d9993b8c7d7935760e1bf9d8b233bc7d6cd34928f5218
+S = 0941df05062aa8849610f4b37d184db77ed1bc19ad2bb42f9a12c123017592bf4086bf424b3caad9a404b260a0f69efb
+Invalid =
+
+Curve = P-384
+X = 1f94eb6f439a3806f8054dd79124847d138d14d4f52bac93b042f2ee3cdb7dc9e09925c2a5fee70d4ce08c61e3b19160
+Y = 1c4fd111f6e33303069421deb31e873126be35eeb436fe2034856a3ed1e897f26c846ee3233cd16240989a7990c19d8c
+Digest = 8cf5e81c6858b8395421d8c913f1ac887e282b5818eab525fb79feb9bc64bca7eb98f94b9e48b705e6c28311bb0ca672
+R = 3c15c3cedf2a6fbff2f906e661f5932f2542f0ce68e2a8182e5ed3858f33bd3c5666f17ac39e52cb004b80a0d4ba73cd
+S = 9de879083cbb0a97973c94f1963d84f581e4c6541b7d000f9850deb25154b23a37dd72267bdd72665cc7027f88164fab
+Invalid =
+
+Curve = P-384
+X = cb908b1fd516a57b8ee1e14383579b33cb154fece20c5035e2b3765195d1951d75bd78fb23e00fef37d7d064fd9af144
+Y = cd99c46b5857401ddcff2cf7cf822121faf1cbad9a011bed8c551f6f59b2c360f79bfbe32adbcaa09583bdfdf7c374bb
+Digest = 965b83f5d34f7443eb88e78fcc23479156c9cb0080dd68334dac0ad33ba8c774100e440063db28b40b51ac37705d4d70
+R = 33f64fb65cd6a8918523f23aea0bbcf56bba1daca7aff817c8791dc92428d605ac629de2e847d43cee55ba9e4a0e83ba
+S = 4428bb478a43ac73ecd6de51ddf7c28ff3c2441625a081714337dd44fea8011bae71959a10947b6ea33f77e128d3c6ae
+
+Curve = P-384
+X = 9b3c48d924194146eca4172b6d7d618423682686f43e1dbc54ed909053d075ca53b68ae12f0f16a1633d5d9cb17011ec
+Y = 695039f837b68e59330ee95d11d5315a8fb5602a7b60c15142dbba6e93b5e4aba8ae4469eac39fa6436323eccc60dcb6
+Digest = c68382d0641ffad850c41365a8ec68e3d55acba376d1bb941e7dcdf7b71f37b8288b023b942373a40be1dfaaf4aea633
+R = 202da4e4e9632bcb6bf0f6dafb7e348528d0b469d77e46b9f939e2fa946a608dd1f166bcbcde96cfad551701da69f6c2
+S = db595b49983882c48df8a396884cd98893a469c4d590e56c6a59b6150d9a0acdf142cf92151052644702ed857a5b7981
+Invalid =
+
+Curve = P-384
+X = 5140108b93b52d9ad572d6129ed6564766f8df3755e49fa53eba41a5a0d6c1d24a483c90070583a66e3cfa52b6fb1f31
+Y = ff52498446a40c61e60c97554256472625633eda0c1a8b4061481fecfbe9c4503e99dfc69e86c9e85c8cc53dca6b8dc4
+Digest = 4b945020c329a61221060e924ec682eceb842c09537fe26265ad084753b89f7650cee4e8df30b38126984d80fd25d246
+R = b2726b2ba9da02de35e9953fc283d1e78700860d4c33dce8db04dd41499d904866c1b8debb377f6c0dfcb0704252174f
+S = 0775b027068d7ad55121a278a819f52099ace750d5e996eaec9dee7be72758736cf769650148fbd5c411beb9b88f979e
+Invalid =
+
+Curve = P-384
+X = 31f4fc2fac3a163a5796f5e414af6f8107ab5e4a98c755d81efa9d5a83c10128c16c863190112fc29d3d5f3057a2edf1
+Y = fe208743f3e96c3a34b5fff78c9716c074a1ce3dc01c3f0e471ddfae91cd88e7dda38dd0e5e1f91b00b8539da3cc10bc
+Digest = 2d6affdf541609f649dbe9fd5829059bf42021fcfefee42d8c9cd5c127015c06b4c3c13ef56d08767788955887752e44
+R = 706911812ec9e7370234efd57b2855975eab81e9c2fe783aa8e442dc6e7d681dab2dc0dfc6765f87ab67001108e3facf
+S = 42c89efa22d853d32f619c9fe13e9852889ac98a9fed5d4fa47fed238e1cbe70d7970af9f7bdf84e51176af4885f2490
+Invalid =
+
+Curve = P-384
+X = 1f7911dcfe63a6f270cf75b8584d9b1b4a00afc1fa43543c945945b8a821ebeb37fbc705a000f9cc7c35f7d27027b7bb
+Y = f11835ec80c4ac06d99247e73bf72522109ac255e6109262de4dfbf9619244f74fb6c9ee57694537d7e79c248db34dc4
+Digest = f4b0a912331e7fc59a7071e5f47c9dafa6dc09b32c5c3d05301b3833bbe0b9168e2b63f12248849572a322b2f5423b8d
+R = 3587c9c6885adf3be1086825f9a41ccd2edfa0bd95e7fc4dba5a9710f41d539132de7772f14c18e318f8992b66d2a86c
+S = 73a844d729599d4e3e3c1b63e9c4bf5a73d1f69e0160857fe63a56c381c051f5c37ea6b4cc4caacb6ff26ef9699efe30
+Invalid =
+
+Curve = P-384
+X = 2039661db813d494a9ecb2c4e0cdd7b54068aae8a5d0597009f67f4f36f32c8ee939abe03716e94970bba69f595fead6
+Y = e2d5236e7e357744514e66a3fb111073336de929598eb79fb4368c5bf80814e7584a3b94118faac9321df37452a846fc
+Digest = cae50a424395e38bde9ba31fa5ea0c107ccceaff06663719162aac2c3e15f2b2cfd376f90d371326e1d29e0392a756ee
+R = 164b8ac2b34c4c499b9d6727e130b5ef37c296bd22c306d1396c6aa54ca661f729aa6353b55d7cf1793b80b5a485115f
+S = 4e7187f8f735b7272f2c0985315b5602bb9b1a09f32233aa10570c82d1ccedef6e725800336511e47f88ddbbbdc08f54
+Invalid =
+
+Curve = P-384
+X = 46dcf8ee848c6459fa66d1cae91ccd471401a5782cb2d3b9b9264189f0e9ddf7197b05c694931bde3306240cf9d24b7e
+Y = 79d9508f82c5ead05c3f9392f3b1458f6d6c02f44420b9021d656e59402e2645bf3ba1a6b244ddb12edbb69516d5873b
+Digest = 039fe89dfc54e7f2162545af700a8c49a1216b08854643656b07d74e7032516fd0c9368c5e5ce54655e4d08baa29b6f0
+R = 5ffba3b5bd7c3a89ec40b47884b0b3464e8abb78608c6d61e1e62c2ca98d44fcdf61825d69dffee8408d0849d0623bac
+S = 0d2597b5fc3842ffce1957172253a8c9c0e4dbe770ce54f70f139e0545dc34ec639d609e14175bdb2b812ccfda00c9d4
+Invalid =
+
+Curve = P-384
+X = 097cea75f685cf4d54324ad2124ce3f77b1e490bbaa1ffacde40dd988f7591e1c5d158e6f232500d958762831914af7f
+Y = 716d8bc056daf69ca2edd21b89a6ae9923cfcae87bfda5f9a6e514dd4b9d28d164fcc613ca2afb9660adfece59f09b66
+Digest = 02afb35f1df33b3d83df3391ca4184121ca52f520dd12ffc891aee77eab6503f232a5b1231bd997239751f46c4133edb
+R = 1c5d4561d2a3af8835839b543098c101c715c545eb7d00300c5cb05bb08dac29e732ffdc31c50915e691999ad505104c
+S = c3442f2fb1498fd47c2f959edff37a19783e3ccee80dc6955ca64db087fd188e67358e7b9223535bbb858d21ba6a978c
+Invalid =
+
+Curve = P-384
+X = d2e2b3d262bb1105d914c32c007ea23d15a98197f0ed90b46a17f3d403e406a76c8f752be1a8cd01a94fd45157f6511a
+Y = e585fba180017b9983b4c853ad3a5dd52e079c5f0ef792d1a0213b6085e390b073de1a4b01749ceab27806e5604980fe
+Digest = e66b11b84f87c38526438e5e3c5b4521248c358eaab80e40526906a05fb29d14d4e5686681f03bc3f0025d45dfb83b5f
+R = 49c001c47bbcee10c81c0cdfdb84c86e5b388510801e9c9dc7f81bf667e43f74b6a6769c4ac0a38863dc4f21c558f286
+S = 1fb4ff67340cc44f212404ba60f39a2cb8dcd3f354c81b7219289d32e849d4915e9d2f91969ba71e3dd4414f1e8f18f7
+Invalid =
+
+Curve = P-384
+X = cd887c65c01a1f0880bf58611bf360a8435573bc6704bfb249f1192793f6d3283637cd50f3911e5134b0d6130a1db60e
+Y = f2b3cbf4fe475fd15a7897561e5c898f10caa6d9d73fef10d4345917b527ce30caeaef138e21ac6d0a49ef2fef14bee6
+Digest = f6325d6bcaaaf1aba1197a290b33974f2fe8af200d5d726e78705904e9894ec31988e35dc76b9976834b7cd1c4c67146
+R = addfa475b998f391144156c418561d323bdfd0c4f416a2f71a946712c349bb79ba1334c3de5b86c2567b8657fe4ca1f1
+S = 1c314b1339f73545ff457323470695e0474c4b6860b35d703784fbf66e9c665de6ca3acb60283df61413e0740906f19e
+Invalid =
+
+Curve = P-384
+X = a370cdbef95d1df5bf68ec487122514a107db87df3f8852068fd4694abcadb9b14302c72491a76a64442fc07bd99f02c
+Y = d397c25dc1a5781573d039f2520cf329bf65120fdbe964b6b80101160e533d5570e62125b9f3276c49244b8d0f3e44ec
+Digest = 709d1bf45b5817f5a67b859651eb47133ebed2622fda09ab66d3467b5e95da50ecc2c74d8f4d289feebec29729a4bfa3
+R = c6c7bb516cc3f37a304328d136b2f44bb89d3dac78f1f5bcd36b412a8b4d879f6cdb75175292c696b58bfa9c91fe6391
+S = 6b711425e1b14f7224cd4b96717a84d65a60ec9951a30152ea1dd3b6ea66a0088d1fd3e9a1ef069804b7d969148c37a0
+
+Curve = P-384
+X = d1cf635ca04f09b58879d29012f2025479a002bda590020e6a238bccc764478131cac7e6980c67027d92ece947fea5a6
+Y = 21f7675c2be60c0a5b7d6df2bcc89b56212a2849ec0210c59316200c59864fd86b9a19e1641d206fd8b29af7768b61d3
+Digest = 5d54d236db6ab4691b3d50dc81471c5d388e5735ebdd435e9742a5a8a0ad0e841bab57326c8535a680ada57d2b3a70fa
+R = 6101d26e76690634b7294b6b162dcc1a5e6233813ba09edf8567fb57a8f707e024abe0eb3ce948675cd518bb3bfd4383
+S = 4e2a30f71c8f18b74184837f981a90485cd5943c7a184aba9ac787d179f170114a96ddbb8720860a213cc289ae340f1f
+Invalid =
+
+Curve = P-384
+X = d15ca4b2d944d5539658a19be8ef85874f0c363b870f1cd1f2dc9cb68b2a43a10d37064697c84543e60982ab62bb32c8
+Y = 062fb7dfc379fc6465302ac5d8d11d3b957b594c9ef445cfe856765dd59e6f10f11809e115ac64969baa23543f2e5661
+Digest = 67cf9e6f9e9558a379ef7361771323a4f3925f2c7a5d94d9156bf2d9d45f9f8fc4d47322da622fbce92fc764a2ccc327
+R = e2cf123ce15ca4edad5f087778d483d9536e4a37d2d55599541c06f878e60354aa31df250b2fc4ed252b80219552c958
+S = 696707a7e3f9a4b918e7c994e7332103d8e816bbe6d0d1cf72877318e087ed0e230b0d1269902f369acb432b9e97a389
+
+Curve = P-384
+X = c83d30de9c4e18167cb41c990781b34b9fceb52793b4627e696796c5803515dbc4d142977d914bc04c153261cc5b537f
+Y = 42318e5c15d65c3f545189781619267d899250d80acc611fe7ed0943a0f5bfc9d4328ff7ccf675ae0aac069ccb4b4d6e
+Digest = e8d6b550271b486e79f6975cff753d49519ed9393b207af7039b4c070cbc2fe7d49dd1bb87f7021e442fadd80ce8a5b0
+R = b567c37f7c84107ef72639e52065486c2e5bf4125b861d37ea3b44fc0b75bcd96dcea3e4dbb9e8f4f45923240b2b9e44
+S = d06266e0f27cfe4be1c6210734a8fa689a6cd1d63240cb19127961365e35890a5f1b464dcb4305f3e8295c6f842ef344
+Invalid =
+
+Curve = P-384
+X = d4e93c4bafb54c06814011309e9f3d8e68b76a5452e364ef05ccc3b44b271e576c9028106b1584f09271c886d467f41d
+Y = db730ccfdeb6644362f4fb510d5254bfe6f23e891e936132f90f1913e93baa8b1f8c0613a0f0c61a760ce659f22babc6
+Digest = d5c82ff11f555ce21c3f20a9ecfa6047cb6895e32fa0fb379f49085a59f61b7c8fa05058ef144cf47db5738fa40f4890cb59695998a2358162bbbf6d7f53517b
+R = 8d0fd14a59c24b0c2a34b438e162f1f536fe09a698cacfe0760d026d1593265d02f2668d2a5e49ac0b21e93807aa9c18
+S = 3162ffd2adc9dd5ec1bb1d97d2b0c27b8ae234235ffb374878d0b76382002ea505e885c178d56a2d7809bd1d83117ef1
+Invalid =
+
+Curve = P-384
+X = c665feccf51e6bca31593087df60f65b9fe14a12022814615deb892eedb99d86069a82aa91319310b66588185282dad6
+Y = 1e6e25bb8ae7714415b94f89def0f75dcb81d4af6b78d61f277b74b990c11aff51bd12fc88d691c99f2afde7fbd13e51
+Digest = ea056beb112fa9aad69c8dfe51ea947b772bf1c11287edcede43a98089d21492ed581edcb6d1823e2873aabba213b84291db3bffa6eac3ae43a92fc2da276a24
+R = 0e18c4063137468fe864fdc405ad4e120176eb91b4538b28ce43a22ae1a310cc22a2f7a2b3a0f3d15e0f82038b4a4301
+S = 5a1620e42041ce4357daf824befbb2ed65596bcd8214e88726149b26b1f416b9472a8877413f1c3705fc2edf4731943b
+
+Curve = P-384
+X = a6bbf85e8068151482ce855ccf0ed22988fcf4b162c4b811cb7243b849299e3390a083147fbd68683203ba33588b13ae
+Y = 5c837ec9f2eda225c83ab2d5f10b1aa5bfb56387deebf27ecda779f6254a17968260247c75dd813ea0e1926887d46f86
+Digest = 81b1303e10f25d37877b09f9d82dbd894e40264992d86cc74656ebeef505b46fdf9dec312a7f0a26e3f56a7195d5b01d198c378fff9d049e00cbad9586da20c9
+R = 9c11879e59659848274fc1ef5a6a181af813d23708b09a24dc06c089b93b918828dd938a75a34d5a681b0af362dc19a0
+S = 9c362231962ba7579c4a874e87bdc60dc15cb2e0677149c8ea31162963e05a6614616f67a5269616071cf095be7ff44b
+Invalid =
+
+Curve = P-384
+X = 9c1eb5cdb1a873e4c275b7ded8712b9058ee0d9ded06c96a2a8d7c652b82e894e2f918dd8e18138e5c34821744b97952
+Y = dd474c93619f02b5d4fe30ea7805c1a13fb80008a81bb5f3eeb95cd11f38841b8e34d64f2c6cc2d6cc2587365eed6b6e
+Digest = c0f9ae90fe8aaf54962e7d47a832e4ca6e60355e4066cd2b08bff78650d4e4a5d1eb1de296f9f0ef92887e09f82e0db4411aa9c3c6b109159bd39feed40419a3
+R = f17b2f2fa3b5c8e9c62a633e5d417139ddf3dafba75b464fa156c99b3948a0aca532c7fd3e14a266eb17e7fa80881da2
+S = 01c246866983fa74d6dff38b1ea091f8afd218b5a42467761b147c19a3bb20cd24be8ed1f95f1e61863a709d2d0148e2
+Invalid =
+
+Curve = P-384
+X = 20622a293edc96d83fee77cf1ee8077c61d6f8ed0073d53cfb5ee9c68e764c553fa4fc35fe42dade3a7307179d6fc9c2
+Y = 710fa24383f78cc4568fe0f4ecbbe6b11f0dce5434f4483712a6d2befae975a2efb554907aa46356f29bf7c6c2707c65
+Digest = 5cb8ed471a4001e280a0927faf25183c857b9b2de21c8566e8a1bf04ee085c36db7fab9d8f627898b3bb23c10225305938b56a732659f2cab3fa857d80dfde19
+R = 45a6cf5cef06256139caa709292d1e0f963d176add188572e9c7be29af21a95853a98e23aef0a0850e58d44d60b6d780
+S = df8d71cd5ab22fc718070078103483e5258734872ab935435f21ea199018e49a69c064a63801beb0759fde6e2c4a85b8
+Invalid =
+
+Curve = P-384
+X = 83a4fecc0bf0a353b0acf6f54094b822f2b12564e172b296f3461cafa7315d7d31d0089b1b4c18ad3c86bd18f539774a
+Y = e4fd57c5b2937e6fba1e7d72fc3f02352bd79c13611931935f4dfd073b9379f862f2277585137e996e212b5b6533dcba
+Digest = cd7c623c3c3b52f46be0ebb2b353ff97db3cd7dfc1a059a57668fc50101aeeb37b8aee9ddda8ab611546999a120cc9acb0e2c3df48dee66d5c31a46a7be94bc7
+R = fb02804010a570d702ebfbcf3d6cc9d55ddac2bd4b4de56d325e9790571b1737f91d3fa1d4caeec6eea806195aed3187
+S = 1fd20fe383e907e77639c05594642798619b2742090919bedeefb672c5700881baf0df19b9529d64bc7bb02683226103
+
+Curve = P-384
+X = 208a8c5a6b59458160c5b680116c8b23799c54a7ee8954a4869425a717739facfe4fe24540505cdc133fde8c74bfca78
+Y = 22aa7aba797bde1e8389c3c3f8d8d9aa2a914f4d2d7aaf7187ebed9b2761975718ef97660ba0b8a71dee17f2b982e2cf
+Digest = 007b907b90fa60835d45d2f0201a4486d9782fea4f0a235d97d4968336c5369c6c2e82bded56288a10fd6741f4c15d1633bc92e0196308d9f0490fc2077d3b6c
+R = 0b4e835ed83151d2bde96e201c54544ba5f301aca853957d3c538c9858fcce796b60fc50f5600a48dcdf13e5bc029827
+S = 0270adf02d31d5428d523e13d7d315c1929a1d89bbd0f61eec0b1186abe1c307cbba6b1067a68bc3947e6196d49719a0
+Invalid =
+
+Curve = P-384
+X = 80ae47e99107d6148b1088c6694df5c1273ff336b66e45b68a7c65fed735129dadcaf2b900e9f8ec50eff70a5ba89ea3
+Y = 47450efb5669bfacd7cbff1f801aafa0812ff88a6ae7b5a1f85e88e19129ed995f509fbf8dec15ce42bbbbd33814c09e
+Digest = 1cacc8f609080e7b8339529f944850a700977ef9107f40956fb35645e15fdd54ef01755f07a2582d0bf2ca0cb84ee8ab154fe0914dfc9ad7ad5fe54b857d0f4e
+R = bae6fba7b1485ecdca48219ead3c39295fa9c196b1f0941445b1ac768e33962f68d37f1f1749eaad7200064aa202fb41
+S = b411a38d02deb42d1015a7837b033c89d2f37d92c70fa8bb1f592223f7750520b950f30277abfb4155a3ab194b3beca0
+Invalid =
+
+Curve = P-384
+X = 45cb6dcca8d2e80ac04536a22f9d68ea2313245550108ddcd32799d154c0a55492e49463e826275bd9bf0d5e380205c1
+Y = 6fd124f5a6c745751ccfb3ba4dd9144ea8fd41a4d9a4b34820434da66aa7385e73ffe71e6c11ed1beb6c7af22ce00edf
+Digest = dd7947a5b9a1c988dd7dff537e15335aacafd3e602adc8373765013f338334dd58aed4fb7144de0007c3410d79f5e78bcd4cf0dd63cc33ed3dd564882e299c7b
+R = 2c782c4263eeee63657fbf20fa287a1a81fcd14b1d3bae333928ba4fc31abb20edebc130714380608e38ea74309eca9d
+S = 716113d95bc9dba532bfb470112b0d43d9cd6560ad15e0de2e514994801ff339bcf19ad4ee2b8af573f57c038fbd70f0
+
+Curve = P-384
+X = 36c1459d9e9f7b6c1598778c784cbf94661a2b11370c02ee092f6ea0ca20acf81f1ed5048a28a1466a91689df26bc291
+Y = d1367418c7b216bd32c6dafc8b2be99d02cab68df990758b2ddd543b7eb6ff6e285b649ffe588b1811b549cfb5f0289b
+Digest = 242ff2713c03e3d5277652f8e7fb1e5a1f0422b6652e1bdd696e46c03cdd3aaac329b1d88e7aa345ff7224ce6dc6df05c7e9d7dc2665282c817d15a15b8288fd
+R = 40c338adeb504193444bdb95336177362031aaadc5b7e151e42030df9dd8687f3cb8fe2292fd4f9206989c089d966dae
+S = be4b2ba251094c24de006c89af2b5c77e6937f36d7bb703b4f8edcfe65d45f4b2fd2486222163ae0ed9e215c0a96f488
+Invalid =
+
+Curve = P-384
+X = b5eb6670bb0b0d3aef10e533d3660756b7372a2a081d9d920130034f48202cd43b9e2d1e5893d0cfb322db65ab839716
+Y = e28444770396041b489b302786a57fca9a98f19685cb4b455d219151e64645ad30dd3149ec96f3bc90879834b65e58aa
+Digest = 8d2e653807e87962883956ee3705b2167c50370c3af12eb8f6c26f0f15ede56dddc7d0c9642a1c1c2444b06571fa1a4d47e7884acc7ea3884daaa50940f782e2
+R = 0887a13df940907864b425ec0d8f91ac719abcc62b276fa08c5122b38831c8930abd3c8454e98182bb588fc72843717a
+S = a380284eacaa36a34e35f04fbf6e28ffb59176f41ea52d9c9bc1362eccd8e0d699c2e08111d93e9dc2785637b1f4f09e
+Invalid =
+
+Curve = P-384
+X = 700e8f65e052e918a63a96fa57f4eda849f9f9faca3302d6ead66ebf85838f8145a6d6718a681b7bef73170d7254958f
+Y = 9e9e10357658913007803859165926cd1e5e92c3a644d834098cb1cbfab466349bf4238a5154cf50ed77c77a78263e81
+Digest = cf885fa7a96db595f825a0ccc56b70b60e0e1c30d0a15af636d1f4957328aecb7eeb734d5874bd72ddaf15c357ca36bd42abf387f7b771ea6160e2e23a08652e
+R = 59be870e0fd684b000cce95c616d9f34674354e9d20db15d204b8a6285ff55258e4eeb49da1573ef1030cd6b2626dcfb
+S = c0bbbf71d87479d82575458be9f4d686921db7ea458d620271f51ec3f4d1afe3bf25ef9c0c400eb7b92cd7058fb17346
+Invalid =
+
+Curve = P-384
+X = a9de6f029445fffcf16349b44095cc83b11e3d0d9f08654b158014803b1cc31b8dfe00b1a8167c6f704d69cdd62c6512
+Y = 27336a503a669ba1d1f3619f51dc8aa2a44b2075c682a36f071be486e7dafba9adfac2ce74be0442b7251e99304ffc05
+Digest = b7e73f38767f253790e7fff019b4e0e61562aeb97b2b749afec2a61c87ab0e15916d4286c0a13989912f6bafdf3efc6f64ddc3b944f9041266e5abd4480c1606
+R = f93a4d2eb94d087f28572847e0099ae2ee944efacdad392ec268c9c1e632e6ccd670c36584e58aba52a4c2b07127d55a
+S = 941ee89cea6e7ed20213a95482fae134707ddf4d292ab1952ed5464f1f1138669dedbfc9998b696eaf469be5fb240c80
+Invalid =
+
+Curve = P-384
+X = e63500d6d13069c01fafc4518f1d429661c5bb6ad1ff0383037ca6a469a5c20c453dce03bf6e4164f7e26f849016b3d0
+Y = 83b7b731c2531c3ac61b194cf3db6dc02ccdfa16d9eb49f97bc4ec3fe6c8bd865ea27f1538531ad07dc44fc5107af8e6
+Digest = afc0ed355377d0ab0c4f79d420dcf67ad4920c013d5c8afde2287525da4596672927540418a61568b21ae7799d7659f16b85f611bd6e8d2066a55903da0c48b9
+R = eb78733e73fd64a6a1f23eba5311af23d26816fb8847671e01fdbd8dc7d5fce1a0823b080ee99e8d75edb3f100e16077
+S = bcaedfe599f98b51542c0f94ae1010611c6767ac3abb2bd887399d62fd0f1b3a0e97deb24c95a76de44521bf24c8645e
+Invalid =
+
+Curve = P-384
+X = 3ebd869be687f82d844416e6816d698d82e1e22a1f451d50b6c146134deb07f05204c0b04e7dc07ebdcfd916531dc7c3
+Y = 6e4d7bde063edb7254a82b9d9249d2a2b9ad8988c37a84ac9f7c09daed42b1fd28f7cca1ea8b4f91a66e878224800bdc
+Digest = 56a61339a35750e95770f28846930e3f594e8d759e07423718734a82b2a80430b0fb3378e40bdcf5c12be135be9a9bec32916b4988a763091a6da7b44631414e
+R = 575f87a8a7980555a198cfdec279cbb2f89551b5271d242397c29f6bc4bf413dc30312a7e626ef7fc77a9124a79bf9be
+S = f0b7d759246ad36ba8240c537b1eeb5d148c38d324f48028c598eaef6e49d79ff3f6cfe3a32fbbf6f3ed3aaaec31d572
+Invalid =
+
+Curve = P-521
+X = 01939b25d13ee8e04203643ba3709526a92912b0e98f06962fb217ed18d1ba52bff192640f980d3f7f92c116b5d94dfd48c25a26b72acb9425e316b3d2ac130a6943
+Y = 0122d0809c5de123c6e5373c1680a4d566c565408b6750d942c024d56c0d6761807adf9dab454b84254671dc68f6917f09a442643e6db1bb35e6796816dd3e5c6a7a
+Digest = 6f89ccb8daf6d4ee583b04786812da9e2960a6e5
+R = 0144c1a1e075aced5e10f50ab7ab0f795bac07439c953ca0c749dc12d50a7e4dce21850dac1fd773e46576335a555f20d266842a8bb47fb464fe3fe297e9ee356e48
+S = 0125f3b6f1cf7eb704bd37391a43034df9260c4d5fdccd583bf65dd5ab4b007c8f837a31a0b7c5a0be3743a187b2569841fc4c69f816c8234d8ae845b92fb9263242
+Invalid =
+
+Curve = P-521
+X = 00882e2cfed1286668e62699ab20c6c40068b460917b306e51ce7f72a4d760e19b3f6cb5897de599cfd84ae70c26d1a39144772b90f8ba1ec2d0f09395265f0308cf
+Y = 0020b80b99778dcdd3dc47da42b279cc289eaae369b9e2c4b0322d2eee9b1a76eed6b5b70d03d83f1db81a67ad6bea98ce71b120e9f83f0178cd6fa3f109a87b1fa9
+Digest = 838b0206f0df827b5aa38abedc972a8ed59611fa
+R = 013ec7124331d896832b77440854c043cb605ae9cc7d20cb358513a5bab26371903c6abc6e4860a0b4940bc5429755341a10251195e5f8af42494c002340ccc57bc9
+S = 01460bda2fd76ef05dcbe1cd17b9c5663b03551cce586c56e103179069fbef6ecae47f6555db755860f0b06eb1bf247312ae0f9d64c5cf13fbc42b923d6bee151b5f
+Invalid =
+
+Curve = P-521
+X = 011a5a6f7166fe435c5cc4238daf92a2d1af483543b7f505785ec4e2d93b2ca1d1eed3bccc31761aa60f7dadc97629475d2712998c2eccb82a78d6da7b0524662e9f
+Y = 00c66d54768f5daf947cd414a1296a54c90e2b65a14cb94aecf0ba51c280676c160c39539955f2a8194357a983a1311845f8cac51cdca1e209bbac32cc809f0e4e10
+Digest = b14bfba79b3a36303dd4c5c7e6bb6981cf37bcc8
+R = 010f45ccf0b4de7d2af890d65395c715043dc5ca1489c79b820347d51848f599ebd4aa558c62ce8769c5d5a294679f9aa74414ca6a1b82f183f23558b0a8dc6cce68
+S = 01adaf876dc35310ac592d1e3ba89f148c3b76417799f43aa1b24c1d2e3f544c018f066ed7baef480f7488820593bcbb25ce08183fc14c6c12fce0c118743f04e281
+Invalid =
+
+Curve = P-521
+X = 00f3bd2590cbf620991d990b84efee86073f6c789deb07b89a1f278e6cc9ea573d8586ac395958ce4e1b09bda73af1b1e6f2a8c09ecc697c021974c024564ed87165
+Y = 00514871935c187e57d1aac376aeb018acf57c4d005d85cc939a6c83256f38b2c9ecb1a0ec8d132e0f5169843faca4ae664459124bf5f30309fa86f87a2604058150
+Digest = d9cba47d31015f5fe70b1bf0c2a7ce40676bd1e8
+R = 0083e6155dd97bf9ba7c60dbcdcba7824b125a73df1433fcb46f57c51f63ae161ce67393d327d174aec7f0b552decb8131a192ae940deb84acc3b45be61917fc580c
+S = 001fbfe61d75dc3fd814eeabdececf361a0a066b8c06c40f0e057faf8e4e7b206dfbbd3a99ef55df67234a29fb1a618620d2e27636d35bb98eb7535d1749c4b7e7d2
+Invalid =
+
+Curve = P-521
+X = 013136c4e5dee983f761955bce7c196a000cb26863a1dea762884bb041e45363a1ab1665c0ca69d1167e555bd63bceba08f6ee14571acd06eea3e1e5d9c11a036984
+Y = 011c830e1fd29ee4e10d7c6db7e90d6c1319c9858f87a944542c28679d83680747eaf71a29362ea2c22a89d78e2ce020dfbba74448d2f46b3f84b99f22604075b22e
+Digest = eb4d89e3ce396c525fdbb67e4620ca99d9585d31
+R = 0124b3bcdae17413de84721e6ebe64409d80ac07a3b6c9a603ef19c5162566076108d30ec79426d24c72ac12af6fa1caa4830d55b4e6fcee900b0e4b20cdae0eaf70
+S = 003e0724d156c3fe5cb799a17972fbb891f0e11cfb650a1c524f6f2aab134c70fb114084a7821e0e12054fe071c516cbfb393fe9d98c840e1cc9e8475d3add81e0c7
+Invalid =
+
+Curve = P-521
+X = 019eb73393f070160d871cc396cd8d6973d828d6f3c17bcec7168843f0342c1b54f3c02a1b11348da1035833df6fa469d75692ecaa2feddce9210a813bdb0e1f9936
+Y = 00e030c5a11e2317ba10a20ec373cf69c96660b434445235efff0a9d23904c5d3ef49efdf0897222e51624f047b567ed61814f3f9e8c62f16ac27160897d5a09f476
+Digest = 43a5c6621edef91f6938507b2dc2092c6b17fc9e
+R = 00ca41bcf9e80780687ba70d7f5ffec7da25542dc22144d9f6843889e941cad2fd8d8771755f38c0ef77909416371726b066464d1d41f888efa39456dee859f0ce98
+S = 01770961a369ca70f9d73b61aec34662735cf228299a7c668aa24afbc9d7f621cb3acff79cee19d107361614c1e71ff1f32ae4f02b7bf94486f0fcd61b6f76f304e4
+Invalid =
+
+Curve = P-521
+X = 000c12d47011ed272aaabcb0fb6c12d8627f33bda02b2b3c3ec7b5ed60eaa577add4205d222b8ba0485b1d98ade9df18ee1e1ad9e0a9e78242322201e3c664bf8c9f
+Y = 00d1b86d4a1171bc80822e0e1094a96bdf7e031201ec212ab7d0e7b55394cad8335050701327a0a1a17181b586b89ff24a658e4b0ee16b8418dfcac122f2457f67b1
+Digest = 35802e4fd349e7cdff4b85c76a417977c3e40b65
+R = 00e4678311d0c068eab2118fc0a59014ec32c89cfd1e0273b966634b87783011b58a99204d266014d0236bd6f276f49c693a4d62b0601c307c936252cf718e239dfc
+S = 0149f5cc02a6aaa126a99a59b83ae34f405f8076b597540625fa76e27dd29a85b6a4b0fc3e73a245a91d64a8f2b13ac345553b7a40835af76a9528cb48ac8d0be364
+Invalid =
+
+Curve = P-521
+X = 00f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab4
+Y = 00f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee
+Digest = ca6b94a2773e9b7392b2a6b2863efb113fea8bba
+R = 001e7cbb20c9a66abf149c79d11859051d35cfddd04f420dd23bd3206c82b29e782453cabfefe792e4e3e68c9bf6bf50d5a00ba5dd73b41378fb46e91ca797dbb250
+S = 00f1e9252573c003cb77f22c8c6d56f2149f7e8d88d699983da9250c8edfd4b9f864a46c48819524651886e3fd56492f4b6c75fb50a1d59e8bfc25f9fd42dc4e1d37
+
+Curve = P-521
+X = 00fc6486a5cc9a366b2c25d57f3f1caadf93659223c7eb38c310916cd44bc49d3ecf1cfbd429b57e329e1eab5f552abaf828ad9cfbc2f7534dc8c87f54d252e7b69b
+Y = 01c0010af6c5cdfe26b068990cf44b1bcf324d0940bce1e953f7366c757aadaf25ff7dee4947879f305d3deb1e9a849db3cffb83bc1c7e5e82777be140931d58d177
+Digest = adb7456d405053624755076f2654f24f2bb521d6
+R = 00a58843085162864b2246c619d6cd38626657eb8f13ed5921b73071b6bddd56640ec9a55e7f2190481ef5e356425749e626a4b988b811cc12dd21c61cea89640095
+S = 019fbd1f9b108aad0208d1a27735ead4685f04d01882ed18c217d8e0e0fc71d8a98d3c45c471327e4dfa631cf4b826ead3bd5fd4bc0426fcc95b58bd354d012cfcd2
+Invalid =
+
+Curve = P-521
+X = 000933ee70d1470acaea66626394023020ed521d5b9a52e068b827d23af283bdbbbf3999b0c2ced0abf607b467fa86ef89bee3852d4e993df3c2c73a49488740cabf
+Y = 010231bba67cba896274e7af7f9c65403e48c56356fba772120aa8781611239d0f50b8958ec8709a301078379b59123b47c5edb87bc2327cf607f876154904b93e92
+Digest = 40d6902c8bdedd45f6f6789f8657e8716c66d6d3
+R = 016f79df89a498ac65bb39d62e1ce82e5578eaf778084ec5926a638d50ee5943c87955c8255340a90f800fd43d4dca125b68dfe957d148533126d5761d711412bcb9
+S = 0175198228ce2eb0222d64eeaa403c0571989046e638419ef96612a90094a26fb819ff1addd823f8912e07ff32ac72790c38c601505b45dbb9cafd1b46f352aaea0e
+Invalid =
+
+Curve = P-521
+X = 0007a5694d537eea406d753532b307c5b86e8823d31e81f6e7371e6def61f31c8f706c1b89f8655e54f68e6821096e6b96a7c3752e47d8d3ef5da135f881927ed92a
+Y = 005810620b7d83d3e7e48f7338b18e03c2e97dde5dacdd5d54e4c7e75d736f159dc45431d5d3c07153a334fa60567307271bfb85cb0fcae142cbd7baaddcbdfdc018
+Digest = 6067b9f7fd22c43c4a91550c461201318220cd1d
+R = 002cba23e78a1f9c6c18bd26321cec0c26db4f1100b986d37a0f24fc42c75ce4731a2876e8865ae21700289734ad5bae3611418ea37a13fae67db2d1a58a86f85422
+S = 00c438e76249b5016e0b83ddef5447420fd13aee6f099a0b9ffafcba4e7227f70cc5dd5abba03532ebc50424fefdd4f6d258ffe044573aa51b8a5d1d5c6e5dbf318a
+
+Curve = P-521
+X = 00a00f34f4572450d93607d3ffb1fffe7c86334426ad60fda27aa647e67c34b2cb1f0a12f4707336f1f708b3ba1f3cdd599ae92a2be92f9ae5526eba9d4adc052fa4
+Y = 0166808273466ec1ef2865e92b263b897131c5ea97fce1adb1ef88c8ac2e63eab97567d82db9c0825510812db1b2e4cba705ba64d33ffdce676b7f3aa2e343f7834e
+Digest = 3d0012d4148fc6bf2e703ddfec9293c27a9fc4fd
+R = 018ada7d95f4d05350ae95494b7c81e233168ec88c5ebffa2d2a3ac74cf90b6d9f80407276f92bd9b3ca949e5d5cd51166e29678aae58a284b9e6ceda3a550b08c15
+S = 01ff12f5e9b12efd941e8a445ac036d735e7bf64237972002568e8eeb0dbb887709b53cfa67186f4df215e2a9f7b9feb045270c72196e19335a9c554a19cee0a8397
+Invalid =
+
+Curve = P-521
+X = 0013a5c825a9ffe6179cd106b4a2343fd3318d83cf3be58d971704d0328486738f7536041cc69e6f9548851cf591ba080c4a1c4b4f5d95d216138d72bc56eb63779d
+Y = 00e79075f5acb9f52b67f8411f310c02aac5a98dcce0275438e59f8a2a3754ebe57815247a00d3506fd342d3d43607ba67d4cb608da3a9296d57619223c02e0c4f8e
+Digest = 4ee72ed3337db64795f3b859021c9b6b405bfaef
+R = 01ad988418099c6483e6a8d62fc16a9fe571ad35c8cf111c3f35e680541a2f5ed96896715efa4943f8b46d20a0abb228852bdd5cfce1787c150d01231abc065718e3
+S = 0095c1e7dcd09375d1760700c5351ab23618b1fdf1b2b02e918c0ec341e5156300b602f7960e0eee2c027aa0076b194080e63155dc56a81699e8aea36ddfe703b94f
+Invalid =
+
+Curve = P-521
+X = 0092bf4245f0ece3a8c3a723de152c6413526c333a64f4f2455e7b45396c1614c473460246f49c65e957dcf779af0b675eaf5ed7800539d3619a6fb131f1bc610968
+Y = 0047689692e52baa835ee9c49793bca7b01ed3bc4d4c396a54eaefe0520840a31fa3c35cc0d2317ce367881a15a3c06e7c26b192e90fe16c10e84c92233910d7df7d
+Digest = 8f0ab491cf25b8526f8da76e329bf886a84c279a
+R = 0141f936c6a5ca580e5a18caeb85fc13e9ff57d50d89b8447c8645ff66202e71eff4303d57c28ee6b68915de6767a124f3652c22940656f4227d61ff30b17c2b9aeb
+S = 01c7bb4c22e68920bc6b9df0626b09ac79e5b76ba29d0b632c0b892c8661087461c4131771a2b3a9834ea4b3d3bddac9910331774643ae22b613bd0b2464a12cfabb
+Invalid =
+
+Curve = P-521
+X = 0194cc7f51d9caff692137190541f5aea160977bedb0d3b67c3deed6669bff160696a96550934b3dba4129e204f068901c84c821523bec91ec40336dce0d2673e794
+Y = 00709279f85ef54164fd7347afcdbfe42d8d14e6808002b3e0b59bcbed80ce0c16e2db1b320c1d98ccdd75efc50fcd6ce91df6baaa99ecbee6df41da9c142a74386c
+Digest = 4eab87203ae54fe6b3c0913cb865266d7be8bda4
+R = 00d2542223b0a5322249e8f1af6d559a87c39aa5c3c7e595b07fb7be4d3bd0184a419651f96811f3e8c9c578a4be68188a8a3a1ff0ccba4af5429ef95c64f34d645b
+S = 01ee3123fd300cceabe2ad99bd1975c4594005ac9ec31d44ee4b9fe325d39049a5a83b4ac2a7f0b603c82dd88d136507bca2d383c7e8375c36eda82a169b3e4b4034
+
+Curve = P-521
+X = 0145896c96ede10f5b049edc0475870c0c6a09ab9cc47667146deca1729d98c124bbe009e5e161b88c7ff61e79d6f85b9c4673c0664e039dab852e8f99fb0ae70a64
+Y = 005afb810a0a9c7f008850e8ecc67d907a74ff9e58f6d60ed14b3ed31e4751077a60de444a43d4d9a9b944905b79ff0c0ab431b21e0fb160cce8f08784677fb58bbf
+Digest = 7cbce9271d00009eab429db9025bb4edc9ff7151ec964873f74a5277
+R = 012f63284068bb815ba935833f382ee2a8a5f64e2dbc9869be281ec7d3a28e2d7d2a84e214d79598213f82217d95ba9868da4dc3a3ec7fcfd7c8c457a053e8b0ce5e
+S = 012b62183c893455324b94b7cea2fa2e1c912362f99e5159e229ce67a80f45c7c0d27340e57b4a8f40b80a4d572345df083061d311b578a73c8faaba4e6a194b4726
+Invalid =
+
+Curve = P-521
+X = 0113a72cee148a7428065d8f8e89dce2dc7e1bffad46a130af8f6fc8d0fabf26ad76bb64ee078ee66fbf0212987e363e176f0106369eb1e43297851ff409e935e216
+Y = 01a723ee3f44aa68e1b43185a50bfca99f349ad47d848dba8f9dfbd773f9f53bc0298bf43130e19ccb8021be39ed70c7b1f7295cfd034e713878f47d7508059a4f81
+Digest = 0068909a03ecb0947b2d585eea1f5496a6b3e50861089cdeb75b516f
+R = 0010b883cb3b76612b6cd8f9288459d373d58c2e0366f300623ff6b28224036ad1df47d1d9df8037a18e774e0bcb42910e96dc7d7fee0b53686d5d3af13485453c66
+S = 00a29c87d9be8e91da4333089043693425892f50333c7f93ab27dabfa5cf89697f366573621a86d523e850caf31a4c26051e76b91ad3e20a391ba724d4e58641cc00
+Invalid =
+
+Curve = P-521
+X = 005766da7e6d9ebbe7cbb5b9bcdd657edf36fc4a7d4a173b99bd1caa804e35e937289e05cec2cedf86f0f7a8de42958e6052500c8a63b496ebea88252cf1b44ee5da
+Y = 00ad35038ce07b53148cd7d0b4ee8c8ad6d89a2c68c0458d0d694036120893ba24a52792e0c8097f86591dce015151659908829f323a5dfaecfc51470779f8e5a5fb
+Digest = f743f4bafec75012878f74c39b30bcdfe1a0d0e4da1ba84ba8320796
+R = 011c5357042c1d98133e76f0a696e27a22738c78ff17c903d8a5190b3c5fb186374fce58fe47d9933c2b361cb20546d730bb5602fab6c8d14e0114a64f9d2b1d892c
+S = 0115ece7d8ab1b578b0e870faa8139d009f6cc3cdacf3172c047bffc1a31e2c66b198ac1ab8c90e826af291de58990e32b18e71b26fe01b6bcbaf86db6b1a726f51b
+Invalid =
+
+Curve = P-521
+X = 00ea4254c3111118d3d859c704474251fa951b0cfbfd2f249bd32f70cecd80526e8fb72c1258c994d8067539e478890d5637ad925ef43e2caf297fd1eb49d9acac77
+Y = 01ed78a277869d8bf7f2d5eb9c2753aedd89197fbfcaf36a633a4f3b2bdb5e706983641156f0aa6e13d38e907546a2603bb1cec785bc334fb03033600a77fed391f2
+Digest = e2a441ca0e946139960943cb42fd6a1d6b6d6fbfb9739d8fba72ead7
+R = 0127570a0c0141bb4c2ababef5fa879e55c1637407686b49535fd17b3b911452650e302e9186d539782cde4d48ee43c258572ec299ee63d961def2333a4f1f8d2af9
+S = 012ed61b0b4c889bb36ff9ba648318a2b11604be6fcff858adbba8e59fa49fa30e2e20df5f2d26a8b9e6d989ab4e50586732adfdd4ca49ddee11cd889f0176a59ca9
+
+Curve = P-521
+X = 00549a23bf1b24fba2e921c5c2ba78809d6b0623fb1b92a506690b668c946daa393ec42ddb113f10a34f1b11475ac1250f119e83149d5211791dbf6cfe4f591b6f44
+Y = 01ecdd45de1ee27f6abc1270fe11f770d4e26d5dd12d0a7baae6f3fc9c7f074541bb05ff0137c3923e1f858d643ec63f7c50f776f45009f2998a0b4f37c192210ce3
+Digest = c063ab8a65966f0b7d6c4127d45ad56f57e5922f5bb0537f71ec51d3
+R = 012bf2daa304f162454686f98330f526a21d066b430969547ccb0ace347cadb4af7bf62b473e33aa1f62b5959b7c431451913d5b1ad297b4c1f6bc5f3afc9e052794
+S = 008c7c58e4703f46fe0885f353f97bfefbecf5f10b95a02d4ac7764a0a713919004a153ff443ce417d24db60d325357408b59dbe7ad043e7fc7c1c23cda14a867d83
+Invalid =
+
+Curve = P-521
+X = 0087784b171cb62451eec46449a2a1ab769225288a092d833aeb823c99de8542ebef8c290f96636a45e2a9cab678a2c55e10283ceea6780c8d61d341952643903f51
+Y = 014a9315a888dc2f774633ed1c5ba95e09b6898764dc5a9d568d727b56fb50d3b288eb77c9db3b1cd31aa204ebf0f2402fa513b782527ce5c5652a97df6bb05e35c8
+Digest = 4a06dfd0dc3fe089a1081066ae40a7297c9bf929dca9a6b6f2a41a49
+R = 0137a47e2f3e1c2916a4a590adea04e93b4d18f2d548a3cf832401bcc42b1b35ad820e88a7efbc15d1462f518342cf81d41a40abd68651bef73816f58d1ace55e338
+S = 0101e3233d8da91e092a6ed4db279c594494f73bd8d6d7bf5f6a8437146a29b1ba78fe3694502ca987cf108af9f461b6341735b8c2a21653d1b52010bf2ee02e02b6
+Invalid =
+
+Curve = P-521
+X = 00b97948459489a548f94459fdbcff544e87f5b93c3ffd8baaa997f616eba75187f7a8fb13d848ddf427aaefc3cd001553c213bd1b1c5d892847eaff2d2663d90637
+Y = 000eb07b08b69af1f15260ab6a8eb84f9337d9d3f99148e61f5ee06c5a031f1eb467e897b65c0d14773018929d9da129d3cd66b8f9c11ddede32bf9f339e3de57b13
+Digest = ab236a98d4f9487b888cfd01d52f7d3746ffc189207b6eb31d4eac5e
+R = 01a31ea52171394839ce630bb1c2912b42b045c5143c3bb1c04a5b97a738887f8367c9607971b00964d5d9fc5d921877cd6b099a84e19024cd77249d263e729e7f7e
+S = 007600944031efbf27face352b6267349f3cb72eca5679d74d4a0d47fa6e84b391f4743cf2f4704afcbb9dcf7b522d812d268a1ff393d0ff1b44b11b6d75fb84d750
+Invalid =
+
+Curve = P-521
+X = 00edc8ee8d40918ab15122d92522bd862e9d46bbb6550ef22a52de0e4fbb6e4a4635be48406bf54bfb24dc385f506086c0a6e1297cea60ec847007e798a632867cab
+Y = 003e92534bf025440635fcd4d40e4b97c5396f33eb16fb1e3390830f24737b6b1645262b0336fe74284afdb99ed6b8551f82a449d80911b0c0f02592c7d210958b94
+Digest = d8704904fd8939d7a1017495a039883a8b07f371eba096b2a54d3057
+R = 00a1f835da9b892687201294cf15769d7390e62e46efe1f61ce7ddc80fc47dc83c86db35a5096cee41289d66d7803f7e8e11fb9c9ca867123027af343fddf2b1b89d
+S = 000b5b9653b2533da8e52292f37b86aaef201743c6d12352470656ca165092d74a8f97ab1772299c62b93d61ec097c957ae231d3c80ef1b9dad1f40b06e0c92ece2d
+Invalid =
+
+Curve = P-521
+X = 01f1464035dcc9c6dbc5e32c318b6b3e9def33cd2feb02b7d4b7249155078915034ef823a4d55fcefecfe6a10603891a4a9c3e6ccc1a05809bc510032d5fd30030e5
+Y = 00ec160b9da57cd8e55630ab9524301ae7f0f53be5d55f7e7b99270272f6e6a33d6fa5fba73195d242e7ababa5cb69f6bfe9165ae3fcc1645df5ca4b6254460029b7
+Digest = a824681278f1dcdd937c6d7d97e5c028106277a07c3926150c7bfd39
+R = 013489e2917236dce23e929f8c1ed0057b0d70c68762073c7b1787bd3cbdd084174f24aef0af10d09c77530c3f76099ce53b63598c0d8f8ce53df83a9af11b7e173d
+S = 0111e1868e71f5e83eb5e38f97fbc466a9e729e19165169ad81cfd214a1ad1e56fa47bc97ef47a93511397c849e9da3f7cee68bccfca4c5c60762d99b8c41393b879
+Invalid =
+
+Curve = P-521
+X = 001248e0953894616aa4b5573644bf4c0b1f45a5c0a47a193c3ebd2215b29dcd387d76ac98183894bed359f06c6de7bb94e975c3e6f9c1be3fbe3b763e2501b524cb
+Y = 01971e69438e24b67baa6203ac5904159763202c16d6afa91298fb43eafc867bead0e61be1601a3fd70219af962f7140cd0a29cc26ebf765c22b895ad0f91aca7500
+Digest = 4d9ded4947fe2a964a6d54f6262292162a14b054b5d8606342d32523
+R = 00215d8b547b0fcb9d18eeb5acf277f90d97ab6371aaa6e8a3c1dfe66d2c6ba5fef45260028d25cf600bb24560e599238b285a823a0dec5e014db4cddfb89ce64aaa
+S = 00bc5c4dba8bea55b73866c0b4bf739c764ba67121b9b1fb261b282fc1882f22eeaecb5c89edbedf90318ae8537554dd8604930bb893d21ba36ea445d0cfeaa28664
+
+Curve = P-521
+X = 00bb34185d844a096f7f673f86b317c27e84fbd6938c1e22e4afb1120489c38508dc643a92ecc963b694dd6f2c7d0958966d49b20883daad4b00a8d0107f2b8ea2ed
+Y = 01e5d3adceda7ed7c7177040b1845fa8064e187a16b9336294c1402ea2eb89e6c14bdd392bbdd2ab516aa7ff3987bc44f6dda8109452db403b39cba9536a39f1ddeb
+Digest = 2f2a916d2c907ab764986fb1ee972907379a8b66a281ff6996e1d158
+R = 00d1f2dd7534f9f093a281fb538660324fef9cec2dbabd3527b1482f980dc08cc84de25f83b062ee5cfe1d3372555b7bcf618c71fc464caeef5a8bb141f39531f15c
+S = 01a1be81c9379abd578ae9663cad8fdc892ff46144f77da469b832fec4e5eee8a6465be3f211f26e3b72de5a9e45aafa064e24d501fc1963733388af20c7b9c9959f
+Invalid =
+
+Curve = P-521
+X = 012918b48baedcb53edc782cef70d772232d1d9e1f5e995f70c76b510f3effcd5c239625e3ec5e37d202b37e4e6047a28d70b489b44bf5bfc2b2cf03c8abaabcc4fa
+Y = 015ada9031e346257778a7b6a7d8285b9d66cbb27b1686ce3de3490c08a3d0a64495906f0ed6e1e4b7edf1ff657091f97bcc383e16f2ddb3c723c53d559fa0c5ffac
+Digest = b1e5176dee3fe3678e36e8471f4e5769b366271eaee73858e53d22fc
+R = 0074cc58e3fdbee1b3b09fd82621bd593118fd4fb372adfedf8895f1775add9bb38fceefb42298c16cacff33af75e38443388b448ae251ff8c049a09fc7af3cf6ad6
+S = 00c51622876dadca150cb6be19dd5de70446cffd2bcaacfb8dfae4e1c7d58c41defa4589668b45958cb5f164bec71353ee57817e0a882c8643fa7bc6339dd88480ac
+Invalid =
+
+Curve = P-521
+X = 015f8a3371c14a76d932a83f242c56097843ca370385db632fd91e05939ce0f87a94028f9f197c435e89525da4624db332ab1b36a1a59cca8c1ebba281ef5ea48bd0
+Y = 01bdd578714cab38b3d07f28f286a55659cb4de6bdbf13ffc149f0cdf71be6be2d11ef800614a1ab97731886179f50360bb98a8c74ec5a222dbc9b6762a4f56734e7
+Digest = 3f9668946bb66d9f63774aa4bd7f15c9dc94da241867b13570e7e4aa
+R = 00c15e0d1c06abac899b90c86ba6e37c8b8cc982780262e303c94a0c9a1ac52554423257dfaedb70760e6ecd66f9b74913a283a2e44d05dc8eb85e5aaee5a4323015
+S = 0014783e744895c7b6084d536a58e9d05a1a53a4ab96321d09cc4c89a908f75f01515c45df3c471ea02cca0bf9f07d1873bb3404d3ba5b51dcccf30e9a5ea0bb151f
+Invalid =
+
+Curve = P-521
+X = 00af896543430ecf3b22534a1a3c1c84fa0ae28f1cc659432417426fcfa814faef9397801f16da3bd610206c2ad62f775ca01ebaf380fe64e928cfcb48213a268cdd
+Y = 01bf669b84b415f99e8e997b4e67d0b9f359823e0df92688c760ca99c08350f0375b301c404eee80d86af5de31e95d64ca95d9494e2d8622edda97282732e7e2757d
+Digest = 5d90c46baf8cfe5541ab3ee8f3aa02e881db1d12692dc16b0d013420
+R = 0191e914f1520532b8b3ccc536b103e4eaf2aceda838117b7090de8b3c2ea03fbfc1f54d15d6fe8e6d2cbb794d0206ae3387e808661518bf5c6dd608b5a40756e24b
+S = 0152e95ec2ba49b5e4d65a3f50a29d140b144f10d2eeba729e439f34ecd7b97dbe672dcc25647446a49e43f5710280d79fe01c0a7b7956fd80bf35cb6d7e560cc983
+Invalid =
+
+Curve = P-521
+X = 01ccee36646013645ac83b532106a9d78828cb387819bdec3f7d982ad2744292281a00d59cd4c1290365d5b821cfeccdbaa8ebd5f10aa1b4b1342bbca27e7619023e
+Y = 0171cfb6c2a95aae42458b6bb582d8efbeaf7219594dca5904b2b3c22a203eac193068e603acf1afd10125306595d0056e2bdee05aeef2d4b774498619cd5f1a3664
+Digest = e201f8ff4c18ef73b7ee6ea2ab3cc482e785bc77b71badf828d9ef29
+R = 004347e5389a6b4a3de2e543d7474c28e5fa284f5268e474f8998395a7dd154fd0c09253b8160f9bae840189161bc3c85db268d500d6aa82a3c383aa025553fc25c9
+S = 010623dda9d2c39d5e6d463d96dc1ae91f0c3f34df698dec0de2e1840467aa54a5bdbe7815426b175f6c19d1a5f09cec6f5270658a80ccbfcf58a30e10cb342e9e01
+
+Curve = P-521
+X = 015bd9bf7a35cc60147b32b64e0e4e54bf9ac2173cc6784b3d4ebd076aa5d45c1e3d0846b20b61d6342341a8801a2f63028c991831318245c2fe31f8acde6bf2003e
+Y = 01afb67c9c700ed332b47a2d148e6ddd3571e138f02a81c3cfe6d4dee0f512d92e76574fe5797c5566c05b3239fabb212c735615e719e718fb40fa6783c964357f72
+Digest = 3dfb0c771418d4f1ffd092de8aae7a563af2c9e559ad0b53a5b61090ea77eacd
+R = 01a341d0e8906239faace79554b90d1445bd28f703d7c7cc8eb163337ad3d4bfb3725cb06e618991491534d399866df5c5bdef897c889947b21148d89c657e64124d
+S = 005c5b728837d44b7b6935efb2b721b4f45c1675d803d87f70158e451434176d9682034c9b356b5f9181e07599bdcb55e5bc808fdd36fef9c19ddb6342c975262024
+Invalid =
+
+Curve = P-521
+X = 009f21a6e7295b183656709089b3c647140c81f71b0b3812e6de22c52245335599ade6a3116cb70277dc2485f91c7b1f46d62afb60fc17a110358c9a02e02e010960
+Y = 01e914284cea47dd6836e7ce899d0c9a88d67fc9d039ffa9fa5bee58d247e0d0dc9251be8b82afd3add327f98c5570bdcd8ad8827820032774d19db09232aeba190a
+Digest = 6b7b1a121d5e8f4d3d0294abbb62ae16561f37b6fbdd6d519209c6663669323b
+R = 00ce4b2ac68afd071531027b90d4b92d9b0e1044b824ccebb2c9ab241d5b909ead1ffa2dc3d330f57187efbea7374bc77c4f7ce7ee689aa5a1e27aa78abc3cc1e751
+S = 00aa85d84f9c7fecd25064dbae69c16d6fcff38040027bf476c7f913746272b5d4b9bd34d2482e27730522df724895b99253aed86011139928fa9a272892f8c99d8f
+Invalid =
+
+Curve = P-521
+X = 01098be00de7b2ee7390f26eff82ba5b6de8f04d7f11909193923866d2feefad9b01c5d78b699ce0a6900dc2a3073a03505ae946aa6f384ab0573ec9d17fa775dacd
+Y = 0106e122e7148b547a0314da646b6f834e66c2ff7f64f39da9dc7983e80e84063e23c8ce12994e8495b7786c2b3180d7f22bd2d2becf1e1ba2029cbbe8d4801b65b1
+Digest = a1aa4766ee9db4cb7bcc31a333214b096fa608623acf5a246ba0de66067d61de
+R = 01092e5ccfc4f966c3281a3924cd527606ce8e64cfd78f57373cfd702f528368beb71eb1a2cd64005bb172cb35b4ea61af88cb06bc8f1a38e2d75b235d23947dc209
+S = 01aff29a28d935d0e10bf8015f38ec128e0ec047f04020d1474366807b140e4d4a6d069aefc8dce723fcb4fc803df30b3880cc6d0dfc75c291d848d89e06ab7e24d1
+Invalid =
+
+Curve = P-521
+X = 001ec67de63455605b31a460d4faa664697cc505885577c0844472842dee78fa6d522e4b942d3c7e2de684e6399f6a44a328ccaab5e678cd99d49f015e35a934cdd9
+Y = 019b41da41e7506cbcb7c31d39751669cda166fd045c86e1fac68d39d2ebb0f1ed50b8a923511e1306952888e068092b19130181c2de5f25c5e1fc4fd9ea202258d6
+Digest = f00b9327fbfba5a3fdd7bd9331582822b7bf8bd8f2fc97f0af5ba207fcc92b71
+R = 01e1882a3d98c236189a35ffddc9fecdb7cb5fc5e3d0784eabb69d9c37862dbb38eed6c5567a0abc4f74099329681b9a0921515f1df83ba8948b51d3871866a8f7ce
+S = 0025ff707889678f7cd05665c941a2bbe13622a1e75ab986cc86778658c62e527f55804ab27d0643f6bb8adaab0614eac47f33f0e1fba109c63b28fa6732a5afbe49
+Invalid =
+
+Curve = P-521
+X = 00defff5ef7cc5de0e1ac32261e7a74e8c434c0b51f76df7566b612cc5b8201e7b38c51aa6118b6307f436394bf452a72224c977e37e410eae9525df2ee00a8123bf
+Y = 00263b7db73558ddc783824f0b19776802aaf5e46ccb1b1d1dda07d2d6c5843f5036ae8d381b235ccd2ed04eb90c5d51e32cbd7acdc7031cae63c06797556fb66fe3
+Digest = 63c7b65f78581fc15992ac54b1221f16545a6e50a0c740e3f3a1685f09f358a8
+R = 0089bd129a537840a52ef434d5a8ba4add952f72f22a84ac4523ea0bc02cbfa8b681ab0ed3fa2bca24ae575f23fce7efbb9bfd28e465174158a5ad2b08fd9e0b7132
+S = 0004ed533337791e05f8d097eabdf4be96b3fcc9f876d47fb8c5c7a05cbddba398cded2edf5ec9b7dbb4e32c1374b46953d66a193c211ef12de4b9d73adc369d5e95
+Invalid =
+
+Curve = P-521
+X = 0180f1e933054473e81ac82aa458094b7cb95d4b8d399600420cfb082e37980414909a133d5e42ebb7d2defddb34a9fb51fe4ab72e88526fc28608e152aaaba3ee5b
+Y = 01c5cee9fd322d1c3af1726366e8a1e3f22099d9246d4bb02708eed89ecef1fc73926dc97a5c263afa235edb39a9e63d9690608846abc482397a2d8673c5d472c970
+Digest = 1f2f2957156270593c0998ba0d12c6d2adfe8728ccacf3332f9e6c936c33c805
+R = 017f1fd4df519ef432f68b5f426ff23a8f36b5729fdf7c8363d73f4e707d9800c7b50174fc3d66d89813a5265f8734602e5c998c2d7b51bdef6e90ee5a527e1357e0
+S = 010560ed68f152d649493c02c1e32bf4138aacb5f2d7f449e7685336edde24e5ce1cfaa2c54530f1419593614971896f1a877dda7bc5d56ccdbab18e770647287979
+Invalid =
+
+Curve = P-521
+X = 006d8c16536b17cab6ff41f5df4038fe416c05ccb601710909708dc561b02ceed9cf020441d9daa075e8fd604531ff58084035b1c19a498b82582f5b20f9cedf61f9
+Y = 00e89d71c66e55c4f5bf245413388bfe9de83944b11d1abdb4692db7da8a086442965ee512f7089f89464dda5d7786e52cc26a8a30bc8824cc56a289fefcd42bdfd2
+Digest = 2e139493b5db177dd536c562e0c90445b59a686eeb27e0a7b7cd93d72fa4ab7d
+R = 0087f86cf4bd36e8253097ac1bc8500dedafdbccbe5767ec25e53c73c4f053f3b37acd1d5ea4c16e4058919b61d2a67393220ffefe07535d53923ace6815463c4c31
+S = 01def2582fd0df89fa28c9ce882f5c3846135f51bdf7f4b2497b190136ef04618eaa22a8c5a117b0adfc6425eac3111b6558df145a8b14ad39524b98659e01d51c21
+Invalid =
+
+Curve = P-521
+X = 01c7fb4747a409a3723177c38c9943b81b2d0aee867b8f424e227f3a664f1877c560d37953e7cc09390e05599292bde1ea345073ec365834d99ac59332f6e5bd29d7
+Y = 01b7485b454d5ed5d581c7897a7e68f425d8c23cd89b934747d90765a5fda1cfc3d997af61728f328cc8bdfca8a3ae1b3b90be13cf164c343d199b8e16b0400f3e33
+Digest = 8ba31656449e19607c84d9a8d689193f30a6111aa87b8f978b9cff5abac9f827
+R = 01552ac2dfbe67c6abad8d3325713c1e28537eae620d805a73dbaa4e5e04acff6ae0498346d6e41df1cbdb20b70d8e548564da8fa239fe6c6f28b6c2a6ef57973097
+S = 00cc9e60b694d792f36cbe9adff8dc79f0f75b3ec11ff2d54419227c7566e0bd441655eb30b558c78a55ac613c1bf3c3058ea7a4bb70adbf5b49fcae15e54defd6db
+Invalid =
+
+Curve = P-521
+X = 016c0e1d1fc81e5069e9c02794fdfe1f5a8ac5008305d9ac2234eb0117e565203acc6777c570f41661c5db1adb26097d7f5f2a1762c4f8039f1b68caad75915baab8
+Y = 000b3690995d6d881dc1564f792ab174cdc1a0fc6f12d69a21088d5e82de4a7d56947a2dad0ce64d9ad0675e72b6da755e3ef82c9cc6d532378c23112210236889d6
+Digest = 4d3c537785e9dc1d434091ddd3be8a48b86a02df7e6ffa269642d44cf8f32c25
+R = 01316e9a934cad1aa0f7dbade1c9ad942d61bbe1bf41b7b95e3b25b761b9899f6125790369277aa09fa57340a2b8c3c609a08ae7be5a3c09dd4d081e6cb54d9f3061
+S = 00d6b285f91c3c8d6192af624336caf793ad5300d96262f5e25228dfb60896c4e28e61be22e92ca7d6e11a02f36655441032bf291f895aaa117f6bfdfb422286f255
+Invalid =
+
+Curve = P-521
+X = 006194b1780a2416dde8c9402e3ddbf310c51ed87fc40530ad5c97931b99336c00098337fcca7b01c634e56a7874309177364e6d4c24c2ab33d6a1a09a84689ad0b5
+Y = 00c5bfcdf640c0a7573ecf4a9dc1aa75db298ddf1a679609e0669182a594b9b9a8186ee961b902d84fe998e3b380c304a0be98974514966965bfef9971f05a57c162
+Digest = 23e932281d4fb08520bb7c563808e6b9ff43e83fc59977df1ff2c00ab5a0f7b5
+R = 018051118c2d8b841c6d78e2e5068c7305039cbae1f8b5a479b9bba559ebc45d8c8ac18d1f6033713871e656fa4eba9c1c0892e7263bb22c46ec3c72aae92afe2c79
+S = 00de0db6a6ba5e6a953a126be3b87d6c895f4bc2db27be223109dc67cf115bbc8c566e1c9a1bdf1a87e632f8a0e4b31331a086caeb60793e87f03b404140aba206ae
+Invalid =
+
+Curve = P-521
+X = 00397714abcc503eaa0c18abd1fd26586d28ec1b1035d37ac710f2823911ec9afa429b41ea89cec13d5bcae9d6d7147794407e409f3b267cf4dd27e8c77e7ccf4d36
+Y = 00a3a4b749d19b84708e42b59e9faa5a99ac0f0a01121655fab87785fca38c8cd4277c8c2c9a0024ff608c3cce954596315dfe0e3b133aeab08bb5389eb2a4f1fb42
+Digest = 61bcad3941eeb4005c391745635dbca42b451c3222b6123af2cd1279f89f3b2d
+R = 019da96a866db12948e0aec7231f797061f345739d439bdaaba63e4d03e0bb52c3fea2fb593347d983f24a3afa6a77f476e6bb49a5de843b4c4755cddce97b8b909e
+S = 001bb442f428b2ca445a75ad88ed49d965d6659d748d02cebf78faa1ecc187b606f284d11d47791d585dc371c2d91848a55ca7b092f06d561efcf64e0de0814e1db4
+
+Curve = P-521
+X = 01af06b10d357fc3c807854b4be235f81d5036da4df1af6a054a03ff800c1aa2d59c2ad5c0e25ed25c002057cae4b4adb92b95c36cf422a46c8833fd8968e0f32441
+Y = 018432172be0e535a3f3a5f6d6927dfbf6a00051cc1983ba25410ee3598a60dd1f7c38526de7ee23f8e9ee973ffddff49eb3edb28adc7d094cd95b63d52ba45ecb58
+Digest = 006e84c19a348fd59fd011cfc5c189d0bbb68bdd2ad30448e13ce2e01f2cdde0
+R = 01396b4f044919d0ba5ad43004cd37b8bb0626ea5549d57c532339358ee1794988a7c9eab91a9340dc2aa0f18e89b236a6c20d03a6e98f35c011430fc4213cd65dbd
+S = 0101e5a788a867d9b5a4444554c9651173f9f8e15c0f39f9adb66c18ef8075243f23b95d5229ccf5f56b87f5c50920b01b22ab7476ecf4c865a3d6d8f2242d422d8d
+Invalid =
+
+Curve = P-521
+X = 0176f1276918fed24a098d6d03077f3c33ae543316df1b6b06ce877e74b69b2cd4131fdf797e77e5f6391b0b32411120d03c0c59ba1721a7187d18708121d6f3a86f
+Y = 010f9d38b30a2da1a745840de7c9994578e32bb10f9334b46f533b6eab550aa55048e4ac601889564ac8314e01b61613fc7b8e2bd3f1a188c5c5e869af16a8d61d9b
+Digest = c11b8b03fcd4f2ae25f60af2ec2ccc9afcbf760f61782fad21a02d69b1024cdb
+R = 019cb5639a321e95214c90a612d29c9ffd5ae5aaa2a814ee2d66ac1ce1d2ab3229009129ec9d472061444cbfbf50c7e4cba09aab65299a42740bce7af3fddf2a1f46
+S = 00082ce6bf1d809d3bb4f9f09a95590bb64b0c41bcee5fcdd332947a9b59618da5da897fff44968d92635e7833dec1e91d8d99bd8b527609393b446c83d109a32243
+
+Curve = P-521
+X = 0089565cf5838658fd36b70cf5246cbe999a394562c46e9d8057928e0aa9e04ade6002cfb83f315e06790e58ea833b3bd64fba8e93c5fdba8319c5d38be7cf25a21a
+Y = 008faeff531e683d28d817045a03b2dd22e50e6168f1e5fda5b5abc71859effc5e5c45b88705b62ca090e3362a8313dc472ec2ed970bbb5029200318e7582643d613
+Digest = ae3204e3df3b8aa0265cfeec6b0facd4b3025af6af26fab931ee5f2188fb4864
+R = 006b5237ad17da6037aef116532b3aaa70172d0ca0eebdc478c35e6f8bd0f9a6472d052c5a18a23dcced7be6e5e7b6d0bcb5b3cea707000e7d114b6f41084d6f5620
+S = 005e2556425b35e6495b137f7dab522c7e7b812004c87a002f6ce4f4b6cc5f967b8f5b7d3786a17d5f717d3ac467b73e176e90cdd8c5151a6e62fc4604cbeab7e717
+Invalid =
+
+Curve = P-521
+X = 00aa42473f80d9d81f6d41ed05c8ba35c005f90e2690f71dfdb12555b7590c7a8e95b618368c39f4e84d6cba25f522c9bdd256c60d3f8c8425ad313701225a9cc9c4
+Y = 01992b7966b925f42c91f810eb05d602b804301849ea278466a68e5b616e3a0bce110fc9250db14f9c8f5929347e1bb8727bcf8072c6aebc26958954fe96df04e139
+Digest = b7e0d79517efe3d961ca5bbdc0916bab7a32743f5150d53cd60300b3edceff49
+R = 00cbb35513420f206bd26b568712503b66e159a54e154c8d4e9c661aa954e0bf425871275fff5e8f368c8ccc77ffe6adf84ba88a84483d8ba5cc862bd408f6a192c1
+S = 002ffb4e461e3161c801ad217a0483045181013deed29eec29cca94776139ddf5fe9d7771e5ac7b637a4bf7e5276940489bd8ae36f41ef6be93cff4b96bd0e1f3e59
+
+Curve = P-521
+X = 00984cf3de2bbaf1b37ad4e9121a1294a0128d8a031ddfac7a8c5d7c9db83699de26c50012d42223d902cbd4be7e6fb611f4502ce8444d43d3eb0685aee07349d0c5
+Y = 017165e8feaada26cc599ee394dfb5de7e2201004f755ebecb92ffda0a24be55aba88ab9b3c7a575884ffa7b78b631806f54e01ef875c5819fd2d52dd6369d649615
+Digest = a0f94fba76704fb2749e4cd454312e47f7606ece0b2013748096de2ff30626c3c7c7aaa855f33908ed60fc8943101625
+R = 0036c8554602661d9d8f4bfecbb099f01e9e314136e50c6d026de2297bbaf66213ea72fce13b73bb07e6e333523f19d3910983ea5842a1b634b3e3ec8157d270b496
+S = 0129b439d3ba2d66c89c34be2a674013128dccfcef33f5d3844c4465381453c361ce80e1b52b6a611749bc70933655caa56da2c5dd6b04defcd8baeb2d9be06f3caf
+Invalid =
+
+Curve = P-521
+X = 00f976d58a015d3015a14997fa3f59ca8d762a6541861be923d6110c9e742a0a2a77d59a6a9335c67f13a626d9545b27c072349c3d20b80c35b0a9490f3e6c5c1b3c
+Y = 00425c22ac0755c58fe3497c1f1a9f537d5e26127d9b031359c2378fd4b13f83691a854444eac3fa346bb5a63bb9567c122945ce99d2aeb0bb1b956ad348f7c9c461
+Digest = dd84b1706091da5e5e27099894e439027b9f45c56e0f31ea0cc528dd587f13a45b9dc87aeb90bb2003e16f56c60b8ad8
+R = 01ca7346a2efe39e03e627ee9480a9b7c925a6677dc80932ffd67ca52b7e46acd2063402545d678d218ac579a64cf1fa4eff4f32f92d3fa4510eea22472dbd3daa72
+S = 00893d86a6502d5973f6c766413e7c7ecbc4583577c58672ef36a76c83755a0ab65af0e0af0ad0f3e6cb8f9ef67669132ce7e996d6122cbbe1dec710a7ba9c9d1ff9
+Invalid =
+
+Curve = P-521
+X = 0066ad5c073425bbbe3a1d97ce6e1a9f2c298392c5afb95c60eee1393f7cd5c9a12c283258b1a53f2ed4abd13ba1287f3a1b051a09cb0f337cb6cf616dffd16aacc2
+Y = 009d2b2afc181bd82043b13b8222cd206b9264d73b229c71d9abcf74a478a7f7088bc8c7bb1e54882fee693340a3cf1aa56ccc2fb81d2675b19bba754dae0c2f00c3
+Digest = 89990b6ae2d21961eba4f7c9efd2e910ecf1c7809e1171d219236f2a8a38bceaefb553bbef7083114af5ea891fe44e89
+R = 004e6f08380c43f225169acb0e9f3ff61cdd2e9b713d149f63b5b6a4510d381409648fc1d442fa1bbbce2a8fe1ff7d1de0597f72d7681c79d3a876db6d3ef89ed192
+S = 011745ab4dec3542cbf37d10090d6038bd1ef9cce8216a4069b21e4a08075e7e8502ec97b99d3b18fd314d6ab6826bbbfaa2343ada1abc7c3b551c0b854dc45ffa75
+Invalid =
+
+Curve = P-521
+X = 0068801cdbb1e07f4b72218c52aa24bda872f1b2ab4e0c13b686cb8b10096ff88018e82196769359227192752a1c4c884f08cfa7f947ac428651f528bd41d1034073
+Y = 01aeb335cb89ecae3cbc05681e2170870dcf40d486db4011c4d7bd84c58c6b3204161d9ca3516760b0c42466605077c96c0540939c635bf5d7d11e1407b6da30c094
+Digest = ad6637c97ce73a8476c08eab09a8e98f42ae6253517f9abed3b3527942075dac7132122d96978a68324ca4dc11193d47
+R = 01ce67a3509d59f8a0f171b86559f1d84589ff2693ff7d3ad3ae64b0e5af85db2fd99bfd7eda6e8f984a87f16767231cbd9026bed0a9a49d74ea5047201227c98f41
+S = 0032b0e4c043df8e81ff22c9bead36f704c992ec160d6be7764640200e1307002421b5d73154eccde012b463aeefd11138c5b9b705623c2c849736da23c122df06f9
+
+Curve = P-521
+X = 001dd34056fd2ff3009bca2d0bbfa70ea0fb678597d41dc545358263ce2cef9a2efc016622c12099c2a50257609d6a14f3c5ffac8a52661e4a34689a3aebdbe86163
+Y = 017926740659acf72f7c7a147a3a320d501efadef8519bb289ebc33e348d6b9efd65fa516048101678548898619d311b8ef2a0d4a6f59f86810e9e6534176a24faf9
+Digest = 1cd3273e0dd337d53131614aaab0b6ffaba8d4c17863a1ddf1e7cf4965bc548628e7230f7331e1ae72b1ed9d1d2f8ae8
+R = 019043db42f44b957784a0e1f09d2e0a0dd548b865947f93b516f249ef1757402544ce5dc402cf8c1f180e9a3be01657258a1dfc14b25ef564805651763d6f609d43
+S = 01e0b45e00bde9c4e8dfe094f9bcd7af5a19b631db850a69bf0b6291fd3df6e26f4c712e3b5d4b7b8572f637874057d5652fa2bcd1977065a695d26a80669a23f0e9
+Invalid =
+
+Curve = P-521
+X = 016e5b4f4ff81c1b1e7956103c5cde951c56b37259fb8bf735b386e4d8b3d44063ef062d6e179f618a506ec8ad9773cfe99044748e2c8ae229a51bca6262aaefe2f5
+Y = 000069bfdb9123885d8ce4ce67c63311055aa9a1a5150197717a853d0549bd17d2683e427fc90a0b78af5dc96465ea3f2862cf98e8f3ee2a07089e8837aa8d09d97f
+Digest = 9949e2a22eee8ae6aa35dae08f3c81a11e0e2c546ccc11428133c65c43d36686c40b17bfb6ecdb47f3279c01defec943
+R = 011550cb365daec01901b5a5cabe7930c10d79128c5e510d58b7593c88647eee811e6fa736b26351558cbe7f17d7c882bfd1ffa72ca3bf4bc1cf1c05f31f5e8bc057
+S = 00d6fc97ad14639a5157c92b39cfd1315d7e940a454f1289c8e95c8cbbce8731ad37180554e7a91565d86cffb3f5caf4ef883184d717e03eb776af714a32234e3f5f
+Invalid =
+
+Curve = P-521
+X = 00202896ccf6710cf780bef8908a2783b3c8d5b8356f1546a1b6b909b0d65ffd7999a16112d8d68c837597656e520a56c2f6578e322df6dd794d2c08bc5d8f9f4c37
+Y = 00576152d30218c941e83080a502cdfbf9de7ca2c394969e779b76c359ffcb84902ff89e37125dea7dcdea0ba928ce2305c619b1906955e6be5ce40d087c5245eb45
+Digest = 90de70a32a54280bcf6acec4f4d2ff996855de0a224f538e2002106c06b695c8d9d143cfe0c90a1679a2fca7a15bf3ed
+R = 00bc6a7f5d77cb6ebb36a261e80d739f42b67ddc7a6496acc0ba7804d14b4850cf3fe4d8b56cdd8c019ef9f0d33aa26746018fbb4c69f4587b6da1adcf2feee2b438
+S = 00f09c6a94a8550a2781e70b4542096407fc07617f537cd27f1a1ddd15c599d5a9e3fa41da57094456277b44b89d40b26f2cc054fbe657788fa9d71659008d0d698c
+
+Curve = P-521
+X = 006ee95783b768c895e2af569bb84b0b1b00c8b72eec022df255892527987ffecdd81bd8afe267408a8912cce80982bad79c30610571a37d2a0e027e73ad23923b8d
+Y = 01ca3f60a37b18bd8b08529da1e39f93d518ae3feead5d00e07150d80d641b20e887c62e8e910ca1c2f64cdcfa678c89b2e3012e3d9b96088ae31dd660dfe6369cb6
+Digest = 8a27d78796a750bf11f75bbed9fa9807633adb4d907125004f69d29b881ec79d14feac2f0e0ed5f113932563eb38c63f
+R = 006823e8f6514e42e79d50a112f0f320ecd53963729038ef0d66d5fb59e1c664fda493027678a02b139fcf290657fffd7a529f4f38ac73542f316e1b0b25b3b88cfd
+S = 01b3bf9e54b0f48bfcc7289d187e831d94d165949db3c660cb63106be1b933e10614e3673bb8078bd8b80ba052c63d566899e618ea31e2a37e0c9c10da111ad11560
+Invalid =
+
+Curve = P-521
+X = 01ba73e2af308df78d4f2a9e552c3b9fd35d35bf20126fdf751d8ad9917cc58d734fb9de27553cd07c02eabc077f16ad4532871a8aeb59bbec82e46ef1581e4abac0
+Y = 00cf888c75582fb50bd0de724a9f4834ea127a1eea437b9a05935d1ec06815bace3464c230314b7f796423ba9fa983b2e6d1eb0260a32cf2f163a5ff46a9623ff149
+Digest = c9a34291213a5edc7474aee794f9de901be35159890bb660f9596efaf8ae7b02118457dfc3d8d2649cfd0bf5c7eea0eb
+R = 01df7e724658f1666aee8d5d75609e3f5215228ac32b978ea53434b7d154dd4edf661c688083d0937e43836c3611526c75f6f26b08f7844a95113ea4a6f1ab824a0b
+S = 019d40a7e03bd69ca568f70a066a4a57c0e6ab82dc8c2c8aa52b00c3ee4c327a87eeb7d837b0c4de68e25f7ac7cf6c0d8bbe0393b98dd61ac4961c7f8c70b40082e0
+Invalid =
+
+Curve = P-521
+X = 01419bc65174998ac21026f81e6807d8b42f0477396e7ff8a330e17c1d84bdc9b39b2a310767b46c41711f3f2fe503504350c86bf3d2b39473b64822ee32dec526e4
+Y = 0184c968f6ad79bf0da00520e5339751cd9c50e41e7cd21ef37756bd0e36e23a8071e5f0240988b73acb3bb2b6002002e09bc7ef70ffcfc7cf42d6b7c65110f54ae0
+Digest = c1c0b91842d461d466e94b411c673069d3737c898435972eda2f6ba1118ce9db013d57d3970b137071446a1fa2477930
+R = 00d785b38c5283466f796988242aba08398ed2493aaabf959ed0e8b7b915cbb711d7694f94206db74641a518642d43c843ea7f43b8354a956a3695764021cc5d2774
+S = 012c20c6ab988ae911c7cdea0549de2e40e3e68c47cfe58fb777ebc204641bbb44f2c8b6a0196d330ea2ffa1d8cdc1dd9be353f1c657e43f7fe3c094898a569c45b6
+Invalid =
+
+Curve = P-521
+X = 010f3bb1c96a753d278ddf6435e7a79a53bc2855d26d9f8d5c1337b0fd7d70bccf204377a02a1cbe95cb63e21a9e8a3ce8ee7c8d4ade16ff4083dcacbc6c4b2a350e
+Y = 01f98a0273c48fa78a91c0f8c1a43f59c7bccb74780fa38b08989d334f2ba0353a3619e6d4a1072e4e052720ed10e4f2c07e12d0c81a062fe912708dc51d4cdba97c
+Digest = 38688d539ee5c3792c29a505d8f8c01ad86efeb2fa3292e49cb921a76eca20dc536ae3feddf2e473dbe798926eb73fa9
+R = 014c4b9e23f51df21b4e02ed7611a8530466d1ed799b50b34b5fcac3bd1d63fa345925122414119cca76d22c167c18ad0fa8e1b47b53ab0f201bd4ca7ea25e011965
+S = 00ce91a050938119f80b5f584a9d9515c998212f6e122780f1607cebdb9b538dceb2d4039ab5e1b13736f4166e73d86c720516f20ad8f24e4b9fadd459c2988534ed
+Invalid =
+
+Curve = P-521
+X = 00819178ace7bf1e6e942fd6ed69193386f6c90cf65b42e9204d34ec96a0ce8fb92552ca57a7ba658422dc8b53bee150170362e6e74bdda24fb458271602aaa9b832
+Y = 014af772624921f61b3d1275591ec2d68702fbf348382e9e552a9b6c110eebf6e93f20c8bff287d504fa08ae3628e611fc1262736916fa9edd87db1c78ed2426cab2
+Digest = dda4a591219b9762f682a9c9a626f172b9cb78ce191cf8acacf137ebbd3e28857e768a9e4f2407c990b192f07c5cf5ed
+R = 012c45d6ac0b5dbd9647211f770c3cca4411666aa39b6988a968bab345129237597b6c9b3bd788c5f9f39a38463a8afb159ad72f19e7e33e7f9ce8d67d611c3d9b46
+S = 01684000b3d7381aded85b18576832c4a89b4faeea0515454677e29e3f072097e786fef11f72f229b63defa1c2fd3c07090b34f9147647035854cf2950c12a8b16d8
+Invalid =
+
+Curve = P-521
+X = 011f8e50ed6905b029ce4b16c8acb8ed9136b1c5adf6f11bfb5f3dd8bb1e208ca8329a0aff9bf286e3be90e4d61d5147bcaf2293f934862cca6aead51d6e0a083093
+Y = 01963e84a2f06a9cb273a424ee5fa1ae5900fef348371cc91c99323f58bbcd8742a4495a4f7ef52677501a4d5d663658c1f6c8f6edef8b7880e6894ff9e52bb617da
+Digest = c55e6d3091b6eb8f48794749ae0c7e9394ca3cb7b083ad65177f8f8db938a76ed6d3c1286a3d51b333c74d1c0f8032b7
+R = 012fc3e0c18c4edbcda4f82b5136c893a6307c3f60affa15d0d99fc0e4a3576b7daefa363b3a362014d14f631c35619f6861bdff9a7b503825bf9f027fcb9a31fd8a
+S = 01a138d6b02fd2a7ba45f7f952b2f329ba6a8e25697379330dddd91d1d6e865d3df1541bc4717d3e09b10a57cf38dcef587ac31b4a8abedef43e4f6cdf6ec3f49eea
+Invalid =
+
+Curve = P-521
+X = 01efc81c1efc7a9bc36ed49a5ef6fa1ba641360fa5c0f96cc1e4a3f4d973c95e86935d979fc2101370777637ab210a56fc4173a50a758725d60e9f925f2066d2bc00
+Y = 0108225fc94ab33c74aff785dcc68c45cfc3cbbdfa3481fd2a3f97308be671fb32fc8d268c129d97f140210def188dceecc9d712ac397793dbc39c5cac332671ec54
+Digest = 5fe56235e4684bd7419e321db508565d30cd351086ef67d943aa5b932f93efdce875be295920ce5210b7d3f092f401e6
+R = 00480c48a24e7a7ef832547d107769254fcdb4e7982d0e6abd16822837fd4f3b66d81e1d4a018606881abebd220ed8ca865d7e00499ac9651a98c65502baebf34a98
+S = 00ccd22d1b44a1701c99f662535aea9abff7e27f73628101f42708737db8b07effdc2b0b05d4ef233c5910b6261ae9d9c540115f27d2af766c0494c33d31bd56b3db
+Invalid =
+
+Curve = P-521
+X = 00a15c8040f94235b8b444f7a74ca293ed1b718449911eefbdb74332687850a644395394c690aa98e8064f6eca600fc3f659208c0f8a21a1e7113bed0c6e00e3176e
+Y = 004bebea7037b731d175043dec3630b2ee85c680a81256921a89407c14507c10ac043deb5d474602211ad58cb569a8b805686bdac3ef7ff62a4d25b27200706b603d
+Digest = d27a626bc9154bfc85b03724329b8a06454d5dc005997bd565f64a80134c865e73a2e123d2b433927efcbdfa3eafa827
+R = 00c1a70919025aceb29dbabdfc2a43715192cc60fc3d1ceababb40f91e3110b2cdd8f6e9c1bafe7415a26fa4179f8fc261b143ddb094fe61117afb13adae9db8943d
+S = 00197d7f87aea8d6ccd2178614b147b290ec780c8075f8439137803c0e9a589e415d84fa23f5f31d61c1674f87142d4ba4f8473fc92d7715c281dcf3f1ee5c2f1390
+
+Curve = P-521
+X = 012a593f568ca2571e543e00066ecd3a3272a57e1c94fe311e5df96afc1b792e5862720fc730e62052bbf3e118d3a078f0144fc00c9d8baaaa8298ff63981d09d911
+Y = 017cea5ae75a74100ee03cdf2468393eef55ddabfe8fd5718e88903eb9fd241e8cbf9c68ae16f4a1db26c6352afcb1894a9812da6d32cb862021c86cd8aa483afc26
+Digest = 7679eaaf0495725fa99c51a2dd0c35c8882b840e1c2340ba793013b1e2567471cba35c0dd6247cc2c2ca14f6556912a5687023fb2f0ee02114393bed4c598742
+R = 01aac7692baf3aa94a97907307010895efc1337cdd686f9ef2fd8404796a74701e55b03ceef41f3e6f50a0eeea11869c4789a3e8ab5b77324961d081e1a3377ccc91
+S = 0009c1e7d93d056b5a97759458d58c49134a45071854b8a6b8272f9fe7e78e1f3d8097e8a6e731f7ab4851eb26d5aa4fdadba6296dc7af835fe3d1b6dba4b031d5f3
+Invalid =
+
+Curve = P-521
+X = 01d6aef44370325a8a5882f4667c21172cdc8fa41d712562883ececff53883ac8ee276124e825088c79d6c9d96323cb7b8c0b7ea44d3f0026e2538f4b62d785bb1af
+Y = 0027203959a6e944b91fe6306debe74dc5dde9831fd0ec27e8be2d0b56807d63151b15f6495b8632e919e1e6b015f5ae5f2b6fb8cf75b5f848f00cf4ee457cebed3a
+Digest = b99c410653ce928e365d3613331b5df067020e92f634696279d5cee80f1f4a82f7d976a059e318b36eb25314b56f8765a81070d0944f4c86e8407d9c3e2aa7da
+R = 004417ff74889dde6bb1820b5d13da5c81dcf9b0723ee89bb1ff0d3faa90d497685709f315b2cbe55481dee43ebb6d25b1501ae69494dd69e7bffb72f987d1573b93
+S = 00fd7aa027c665458c7ac11d54d4f32cb4a1e727b499ce27b08d3d647c636cc3222a4f0a6057732249ddc22574d7cb80c3769c3ea9de3d33db3edd8ea90cb3f8dc8a
+Invalid =
+
+Curve = P-521
+X = 0153eb2be05438e5c1effb41b413efc2843b927cbf19f0bc9cc14b693eee26394a0d8880dc946a06656bcd09871544a5f15c7a1fa68e00cdc728c7cfb9c448034867
+Y = 0143ae8eecbce8fcf6b16e6159b2970a9ceb32c17c1d878c09317311b7519ed5ece3374e7929f338ddd0ec0522d81f2fa4fa47033ef0c0872dc049bb89233eef9bc1
+Digest = 97ff5a81fc88f7ddd3bc58154ffd2695912fe50ce7c63b62bd798fb673c6aa49f54bc7301fb7bddc6edc51b7e0d0b4dec9f80851fff02a33671ad9a406bbabe5
+R = 00dd633947446d0d51a96a0173c01125858abb2bece670af922a92dedcec067136c1fa92e5fa73d7116ac9c1a42b9cb642e4ac19310b049e48c53011ffc6e7461c36
+S = 00efbdc6a414bb8d663bb5cdb7c586bccfe7589049076f98cee82cdb5d203fddb2e0ffb77954959dfa5ed0de850e42a86f5a63c5a6592e9b9b8bd1b40557b9cd0cc0
+
+Curve = P-521
+X = 01184b27a48e223891cbd1f4a0255747d078f82768157e5adcc8e78355a2ff17d8363dfa39bcdb48e2fae759ea3bd6a8909ce1b2e7c20653915b7cd7b94d8f110349
+Y = 003bd6e273ee4278743f1bb71ff7aefe1f2c52954d674c96f268f3985e69727f22adbe31e0dbe01da91e3e6d19baf8efa4dcb4d1cacd06a8efe1b617bd681839e6b9
+Digest = ee21776d7174103b7fb65f03fd5d78744d2706c6726ece81e3943cf90f60fad6d8978af6cae9bc059aee2412ef86d0600694447a10b9d21079b9ca77500634a9
+R = 004c1d88d03878f967133eb56714945d3c89c3200fad08bd2d3b930190246bf8d43e453643c94fdab9c646c5a11271c800d5df25c11927c000263e785251d62acd59
+S = 012e31766af5c605a1a67834702052e7e56bbd9e2381163a9bf16b579912a98bebabb70587da58bec621c1e779a8a21c193dda0785018fd58034f9a6ac3e297e3790
+Invalid =
+
+Curve = P-521
+X = 01d9020b8e6717254eebe619d46dd5a9dda7ba5491a7d1b6820fba888e236fafd71179200437f4d61284fb5a3dfbada66bac3e6909ccbeee03c2b93a8bebe41a73f4
+Y = 0048a5f09174fda12704acdd8ed560695dec42864b6300a030768a0be7f09d25f82d7b126125e41417a145641937807ed8d1af7a53f5bc3fc3c57427d755dcce3e25
+Digest = cc4e8efb1e9061500bd2dcc5233c2bfa3d3bd89067c26cfee4fff4a5a7c9c9b15151aec1fa91e78b67cfe3efd966ce65681dd3daf36b887d844033a473be592d
+R = 0092df2dcb457fc7578eaacc98ffd73ade07d764e9553506f3dc958cdb3f65d37665528cb2f5f8bded0db0a57e6fa73bfad1aaf94718379d1655db4f32d4c505a785
+S = 010e0c31479c2b29dc2726fe9f75b397d9e37a17619e96bc631c62e9ece71f05b199804cc803940d43ddee41171dd7787668c7db05049dd5b63e4f63562aa700ca81
+Invalid =
+
+Curve = P-521
+X = 0007067d2cf7b7619b9fcff2c898246ae0950439b8bab92d809624970eda18456cb99953ce1ae45ee5d36ef02fcd5caa4d951de8581f0c21e572caad56d6dce60da3
+Y = 01913c59007a309005f226b6a30122828d60b4d0390359e1977f88b5347dacf2056dd362648e8b1d6fc038a3bd3fde6f1140c740efa9075ab8b4a64b334c5cd43f09
+Digest = 996010910456dee59309f1631f30e3dbf7ac2da7d5d7f69223c8a18f491cb18f7e11d0ca09352b715354a071e6d392a8c1dc0751569bdfcf36c158c8b07a5ba6
+R = 012aa4a532c108aa3cfb1753f95ca626bb72bd96a423d727656d4ebdc3f406d6cc6c44d3718f9abae8a0b46be9b57f8fd3a540326b63d0d4a8a93165715920437787
+S = 001badaf38e16efd75915f4806f054d40abd2d11e402039bd48c832f66cbfd145e4dac93357d476b7e608d7b75a017374ae76eee86c505f2cc16eaa19075827ccd60
+Invalid =
+
+Curve = P-521
+X = 00365388d9589c18ae608124b4cf746ff488183a912e07d26b6e867c5defb552a5a0df5a16b6342014dd1b0b6760072bcd60045d6a9a514fc74d16047c2e8765636d
+Y = 01a5319b26fd555f2a12e557418f6aa65a3461aeaea5c0c6d8698ceaa5495eed7a7d2fed0b76e77b5be11834f36e413d5288e47231c0eb0e9007d4b042bb7a1b6014
+Digest = f8e150be2f657c8266fadc9bdb04648fc5a51f3c3f7521022aaf58d24165f8af4ad66319d8aa2dab48fe8a2f773c8d0e6c8c4f732e0fdfbae4b91918530c1f91
+R = 01d9ef377063a592cf81e27815a2c20789ff9b60f7f125e618b52d90b35abdd41cd7f437cfad337953ab0314fe8e79a2f2d27fa08597d4b28313358f714a737321fb
+S = 00f01d4f150e0a174674a6a61a58a4ba781406024f6dd1b5252e04807b8a807a4ff8d52883eaa258286e506ef4b04ca890e6f81a79ed9a0cd5ed585094fea0bc5c43
+
+Curve = P-521
+X = 00fd0cac24aeb75ca50c50a72340256b43649050e0fa155f72342877bf49c3d57ac2b51b828385ee6aea94bae38587e63390f5ef4ac5540a9e6fc6f1c1e79b524693
+Y = 0107b227bdd307efd7a8d4034f733d150c41601215e76eea2bac62ad2427dff52f75f46da3d5fe31bfaedf071d2a8bb5e3c82bf6c84ecdf89ca233c92d599d376309
+Digest = d0d8c24bc5b6f34bf35b08f25dc2d6ebcd36b565f96bee9c1b47030428f10c3ad2904de19247b29650690c08517404e8ca55f366ab176e5089a4c9c661f90eb2
+R = 01c00196aa5dcbc4c4404fa76504a5eacbc96aa66c3ba531a3a679f3fb675ce58f863e08b0d2bdeae74d96ad93a39a78ed4bb3749e26567d0ca5c48a71079925b617
+S = 00f1188eba4f0943f4003ddad6a54606c13af26014db2eb8e60534fad3dae8f07c021cea0990987f1e02dce03fe53360472c3dee3c305bb3ef4b0b53ea6625bf152a
+Invalid =
+
+Curve = P-521
+X = 0104a96beea09d88ea6789a9925880c8a9ece8d764be931675640c1bf847ac8e7a8b14f408ba6722c2bf6295db9132d6ad2fe287fa6e6855f7c58ed238148a896944
+Y = 01b5e8e643fae552261427ea7d521f380adf605579462315c75e9203203ebdc9ee33dd7ba885b6cccccbd2327462988223c4b31485311c935a341ee87ba1ee820ce0
+Digest = e9ea3c8aeae3133be537da09b98c096b9a9eb287a02b3542efd30f0026ea9cb3f242b842b2cedbf02e70b44ff8a0b1bcf6f31956eaf6c0dd9a023bea36440068
+R = 00ba2c57827baae684d2c637590275c782a6db263a5358c8e1a08b5460ca3cf0f5ff8d4119a6b0d55fc68a75c793098e0a5622a0b4e2fcb0f17943440138d751797b
+S = 01594beb73b2ebb7c573ff07b5c43e722dc05979df0eef53587e9fe06a920f61d2efcc7671e6cb875df4e4d92cd4d37cc3eadcb9b6aee8f2097790ce24d6dcda8706
+Invalid =
+
+Curve = P-521
+X = 010d587aa82a4d8e690672c00e3fd71826d892862d14dc4fbad4935aaab86924dc7ee6f7fd3e2bbe86a8652589448494dab83d363d1d623cbae59f6c2670706a0576
+Y = 01a9734c99b6ff21267050738937c30971d0f6fe07e29794748a5017ea1036c975c9a52e6d3739ca0e8d70e784529cc1a7437aac5d75c69121b69020a95356137f1d
+Digest = 8814a9dbef9e6d9b8322bdf8d471b207388bb7bf831d9fba8ad29da52d528d5d5108c01e4459f5ca13e26bf5da3c848195558828d7a00f53abb9fce47ef35091
+R = 0188dcb840dfc573a97117009226d58dbb930ba8ec848931786abc770611f3519c8ba73cceb5b489170805bcf04974672fe66c908ba379aca99fa67fec81a994c2d1
+S = 000b1a185512dc6a65e454ea2bdb8049ef8f012a53ae87b759fb5d9edba51ea32e254e80545a99eb4b7c58af96b7c433535fa3f009cc644b1c97666d88355af9fc19
+
+Curve = P-521
+X = 0182c957a62e2e27aa28acee2e2f7b1ed6aef81c68001d2648da47d2b621e8b8bd18d991cd1e3fb9afb84f639fbed1050584428cd2a1d50f877532ffdefdd4e6f7ba
+Y = 005fadeef58cc0d79362b599e94636f9c70e3e5580c085b7ea52a5fd24fe4a892120b8f28ba53ec249c42d6d3b36268b8ca8464e54b72d37327d7504d9b7ce534d95
+Digest = e1838cf6ab5daf5ed28dc1b3365eb03466e01cc30f6fec9756c966cc7b89ef5ddb32754302a33b5aa309c871f98de082a21cf734ba8a368794d89b0cde1cfcf7
+R = 01e3a78e973fef6b6de8a0356401e89f435ae5f49c0173f073c4dbb9c91463e420f5265eade8305f11d30fa8d97e5b4c5ab33975f73385aea81fbdde2f7ddf7fdf16
+S = 00efeca10b5362e05a8f2e3df6661d0d536b32ca1e0a62515df2d94eb314aadb5eb40468483e24b16efe85c503d6c231ef860aabe674b72ed1ddd93853338e5e4e50
+Invalid =
+
+Curve = P-521
+X = 009911b41f9af525c874e05bfdf050331bf830296911bcb18eec16275027d63fa106c8989b07921c7e58b02711b5b5880cc4e6d9174e0d31060548cf643bf7ed4f0c
+Y = 0184fc0fac3c2c80c69c1c0293f4e5e22fa08c267b1f36ac5ad6dfdf4da1754f7942f48cb56f56cba05e22b91508fe4db3703066e8f697aca56f974f3fe530c9640c
+Digest = 365868aac67d82cc0510bcfb012f9035f99b5841329344f1b45f0489463cfe22c2f3641f7d6c59a3703aa2804323db8fec4fb3804f521149e5f7d38c9e1e94f2
+R = 017b8a22fd8f73112310867909f234fad6aa82999c28ea5a2e74b4b4bc79b2f89008b4d361ef7e797c7656f7d9317eff3e5a4982799b8cc0db82618bd2aa3959f617
+S = 01edacc6d1c0004b2090d2025d615de1fd53a96e826a3930c7cafaf3c87f34b2583997534cfa127485600a7ae04e6af4a2e98c77fd04507195e520e80014aa982a3c
+Invalid =
+
+Curve = P-521
+X = 006da3b694e3123ef96b3fd2ab964f85a36110590720dc1724a5d50d3050498957211c6a1535032cf1f31240bfab967cc0cf3b442c35a1bfa3e72470df1863d2593a
+Y = 017d0a5dc460c85d0365c7bdc2e9300e276b8aa97368af9972744f4422442afc601ecfe7903a33b0354c901c7b61f29d2d3c5610192cd188291c5651754b385b87a8
+Digest = 4e992e9e5403eb9822958f2737b70fa8096474a845a0f37244af744a6009e3b6e6e008faa7192fc01755bb785e03e4e3d2caef03eeadfe32a7fbc7e3bda49f5e
+R = 01f9cb1f4e2e65282a929acd8b685ab34da176f5c73bcb374fd1b09bc995385ce3902d6c5496b02916fd5a28f6f8bb662828a76aa0ad14b01bc24a63b328c7bb949b
+S = 001d6b3a2f34e3b7bf63d06b11ace172ca61ac5a911a4b408d766eb586c9ab820d42f555e546d892643e12a6752465427c213e3839e4f8cb3a7e4fd83642843e8544
+Invalid =
+
+Curve = P-521
+X = 00b7e03f0d623a0998add5360dfb0bfe836fcb0a46b0d6f697ba6b3766bd8698ac8c7af62f50511c6aa5e613f4a99fa28f70b220ba1cddb22482be74c969953ae6e5
+Y = 00d4ee40ee4441dc85356760f87ba32e2e7c269a2e53a2e8425d5ff02f5e4fe8d65cefe20e162c3915d2eb9ad1354bd28595a86dbdc94a5d40c5b44b1e3aa3965455
+Digest = 8ebb37c7b60ba4622070391864a70b5e797dc2464151304b1d9614b77f0bcb92fce230f42cf98f9b2612f481c21f70564f5cbfc4e81e48e08ae27b466f717e02
+R = 01fcba4781de6506f7c3f26521f0e036b5225f651e69e115d6784b2176a666edf69d759627468400a73a136f599fb8db4643fcc16bdeeef6384a1875e1c81c36b962
+S = 00a21cfaa7e1ee0eff7efc3d7e936378500283b00687363070974483ad474c58c6b55b77f678d78e7cb44d9745f79394659bdd26b72663608384b5ae9cac1c888d13
+Invalid =
+
+Curve = P-521
+X = 001bb7c623fde41beec7ddfb96f65848c2f52b50b39576bf06de6ccf157b8ec49889528728480928236300447da7171f58c8f0e0ba8fd3e2cf378b88619aa6c1e0bc
+Y = 01f8b20a1a7df319bf78c2cee03581a1ffe8ca5107fbfd40760fbd5ef5247e2df1092d5caf504a9ee653ded2995f0cdd841d6af29c9f720770056ebbc128705f68e6
+Digest = c18be2e3f935561d1ad1cacf6ae06e733a463c7e5063cbb0cfaf162a579522786755dff879d2bb0b63d4eea9120a2ed648d601a5cb2dee936dbada679bcc134b
+R = 0000db4c31f316912295c5b9506aabc24b0b2dc2b2358e6b023148889d9200bcf44762e88575e359b4868b2d93ba7bdb24800b09fc22eade0744b9832b71ee784e9c
+S = 018c84437fac7cd82099a2a4230084ac27ec7ea9c92e1c9d9a71290df9b37dc881f9ba59ed331c22dca4b2cbb837cd916e0a78398d2b7aaf8e88f113a942beac48c0
+Invalid =
diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata
index 7753f17..bca4931 100644
--- a/src/crypto/err/ssl.errordata
+++ b/src/crypto/err/ssl.errordata
@@ -18,6 +18,7 @@
SSL,117,BAD_SSL_FILETYPE
SSL,118,BAD_WRITE_RETRY
SSL,119,BIO_NOT_SET
+SSL,261,BLOCK_CIPHER_PAD_IS_WRONG
SSL,120,BN_LIB
SSL,255,BUFFERED_MESSAGES_ON_CIPHER_CHANGE
SSL,121,BUFFER_TOO_SMALL
@@ -82,6 +83,7 @@
SSL,174,NO_CERTIFICATE_SET
SSL,175,NO_CIPHERS_AVAILABLE
SSL,176,NO_CIPHERS_PASSED
+SSL,262,NO_CIPHERS_SPECIFIED
SSL,177,NO_CIPHER_MATCH
SSL,253,NO_COMMON_SIGNATURE_ALGORITHMS
SSL,178,NO_COMPRESSION_SPECIFIED
@@ -107,6 +109,7 @@
SSL,198,READ_TIMEOUT_EXPIRED
SSL,199,RECORD_LENGTH_MISMATCH
SSL,200,RECORD_TOO_LARGE
+SSL,263,RENEGOTIATION_EMS_MISMATCH
SSL,201,RENEGOTIATION_ENCODING_ERR
SSL,202,RENEGOTIATION_MISMATCH
SSL,203,REQUIRED_CIPHER_MISSING
@@ -157,6 +160,7 @@
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,260,TOO_MANY_KEY_UPDATES
SSL,220,TOO_MANY_WARNING_ALERTS
SSL,221,UNABLE_TO_FIND_ECDH_PARAMETERS
SSL,222,UNEXPECTED_EXTENSION
diff --git a/src/crypto/evp/evp_asn1.c b/src/crypto/evp/evp_asn1.c
index 3681d4f..2b24858 100644
--- a/src/crypto/evp/evp_asn1.c
+++ b/src/crypto/evp/evp_asn1.c
@@ -65,6 +65,7 @@
#include <openssl/rsa.h>
#include "internal.h"
+#include "../internal.h"
static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = {
@@ -80,7 +81,7 @@
}
unsigned i;
- for (i = 0; i < sizeof(kASN1Methods)/sizeof(kASN1Methods[0]); i++) {
+ for (i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) {
const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i];
if (CBS_len(&oid) == method->oid_len &&
memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) {
diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc
index b2c519e..755fa83 100644
--- a/src/crypto/evp/evp_extra_test.cc
+++ b/src/crypto/evp/evp_extra_test.cc
@@ -20,14 +20,13 @@
#include <utility>
#include <vector>
-#include <openssl/c++/bytestring.h>
-#include <openssl/c++/digest.h>
+#include <openssl/bytestring.h>
#include <openssl/crypto.h>
+#include <openssl/digest.h>
#include <openssl/err.h>
+#include <openssl/pkcs8.h>
#include <openssl/rsa.h>
-#include "../test/scoped_types.h"
-
namespace bssl {
// kExampleRSAKeyDER is an RSA private key in ASN.1, DER format. Of course, you
@@ -357,13 +356,13 @@
0x48, 0x30, 0x01, 0xaa, 0x02, 0x86, 0xc0, 0x30, 0xdf, 0xe9, 0x80,
};
-static ScopedEVP_PKEY LoadExampleRSAKey() {
- ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
+static bssl::UniquePtr<EVP_PKEY> LoadExampleRSAKey() {
+ bssl::UniquePtr<RSA> rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
sizeof(kExampleRSAKeyDER)));
if (!rsa) {
return nullptr;
}
- ScopedEVP_PKEY pkey(EVP_PKEY_new());
+ bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) {
return nullptr;
}
@@ -371,7 +370,7 @@
}
static bool TestEVP_DigestSignInit(void) {
- ScopedEVP_PKEY pkey = LoadExampleRSAKey();
+ bssl::UniquePtr<EVP_PKEY> pkey = LoadExampleRSAKey();
ScopedEVP_MD_CTX md_ctx;
if (!pkey ||
!EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
@@ -409,7 +408,7 @@
}
static bool TestEVP_DigestVerifyInit(void) {
- ScopedEVP_PKEY pkey = LoadExampleRSAKey();
+ bssl::UniquePtr<EVP_PKEY> pkey = LoadExampleRSAKey();
ScopedEVP_MD_CTX md_ctx;
if (!pkey ||
!EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL,
@@ -422,12 +421,12 @@
}
static bool TestVerifyRecover() {
- ScopedEVP_PKEY pkey = LoadExampleRSAKey();
+ bssl::UniquePtr<EVP_PKEY> pkey = LoadExampleRSAKey();
if (!pkey) {
return false;
}
- ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
+ bssl::UniquePtr<RSA> rsa(EVP_PKEY_get1_RSA(pkey.get()));
if (!rsa) {
return false;
}
@@ -444,7 +443,7 @@
}
size_t out_len;
- ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
+ bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
if (!EVP_PKEY_verify_recover_init(ctx.get()) ||
!EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) ||
!EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_sha256()) ||
@@ -502,7 +501,7 @@
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));
+ bssl::UniquePtr<EVP_PKEY> pkey(d2i_AutoPrivateKey(NULL, &p, input_len));
if (!pkey || p != input + input_len) {
fprintf(stderr, "d2i_AutoPrivateKey failed\n");
return false;
@@ -556,7 +555,7 @@
}
const uint8_t *p = kInvalidPrivateKey;
- ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey)));
+ bssl::UniquePtr<EVP_PKEY> pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey)));
if (pkey) {
fprintf(stderr, "Parsed invalid private key\n");
return false;
@@ -569,14 +568,14 @@
// TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format.
static bool TestEVP_PKCS82PKEY(void) {
const uint8_t *derp = kExampleBadECKeyDER;
- ScopedPKCS8_PRIV_KEY_INFO p8inf(
+ bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> p8inf(
d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER)));
if (!p8inf || derp != kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)) {
fprintf(stderr, "Failed to parse key\n");
return false;
}
- ScopedEVP_PKEY pkey(EVP_PKCS82PKEY(p8inf.get()));
+ bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKCS82PKEY(p8inf.get()));
if (pkey) {
fprintf(stderr, "Imported invalid EC key\n");
return false;
@@ -588,7 +587,7 @@
// TestEVPMarshalEmptyPublicKey tests |EVP_marshal_public_key| on an empty key.
static bool TestEVPMarshalEmptyPublicKey(void) {
- ScopedEVP_PKEY empty(EVP_PKEY_new());
+ bssl::UniquePtr<EVP_PKEY> empty(EVP_PKEY_new());
if (!empty) {
return false;
}
@@ -608,7 +607,7 @@
// Testd2i_PrivateKey tests |d2i_PrivateKey|.
static bool Testd2i_PrivateKey(void) {
const uint8_t *derp = kExampleRSAKeyDER;
- ScopedEVP_PKEY pkey(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &derp,
+ bssl::UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &derp,
sizeof(kExampleRSAKeyDER)));
if (!pkey || derp != kExampleRSAKeyDER + sizeof(kExampleRSAKeyDER)) {
fprintf(stderr, "Failed to import raw RSA key.\n");
diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc
index 9c8735b..68b869a 100644
--- a/src/crypto/evp/evp_test.cc
+++ b/src/crypto/evp/evp_test.cc
@@ -68,13 +68,12 @@
OPENSSL_MSVC_PRAGMA(warning(pop))
-#include <openssl/c++/bytestring.h>
+#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include "../test/file_test.h"
-#include "../test/scoped_types.h"
namespace bssl {
@@ -115,7 +114,7 @@
return EVP_PKEY_NONE;
}
-using KeyMap = std::map<std::string, ScopedEVP_PKEY>;
+using KeyMap = std::map<std::string, bssl::UniquePtr<EVP_PKEY>>;
static bool ImportKey(FileTest *t, KeyMap *key_map,
EVP_PKEY *(*parse_func)(CBS *cbs),
@@ -127,7 +126,7 @@
CBS cbs;
CBS_init(&cbs, input.data(), input.size());
- ScopedEVP_PKEY pkey(parse_func(&cbs));
+ bssl::UniquePtr<EVP_PKEY> pkey(parse_func(&cbs));
if (!pkey) {
return false;
}
@@ -150,7 +149,7 @@
!CBB_finish(cbb.get(), &der, &der_len)) {
return false;
}
- ScopedOpenSSLBytes free_der(der);
+ bssl::UniquePtr<uint8_t> free_der(der);
std::vector<uint8_t> output = input;
if (t->HasAttribute("Output") &&
@@ -215,7 +214,7 @@
}
// Set up the EVP_PKEY_CTX.
- ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(key, nullptr));
+ bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
if (!ctx || !key_op_init(ctx.get())) {
return false;
}
diff --git a/src/crypto/evp/print.c b/src/crypto/evp/print.c
index 56521ec..53527b4 100644
--- a/src/crypto/evp/print.c
+++ b/src/crypto/evp/print.c
@@ -60,6 +60,7 @@
#include <openssl/mem.h>
#include <openssl/rsa.h>
+#include "../internal.h"
#include "../rsa/internal.h"
@@ -479,8 +480,7 @@
},
};
-static size_t kPrintMethodsLen =
- sizeof(kPrintMethods) / sizeof(kPrintMethods[0]);
+static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods);
static EVP_PKEY_PRINT_METHOD *find_method(int type) {
size_t i;
diff --git a/src/crypto/hkdf/hkdf_test.c b/src/crypto/hkdf/hkdf_test.c
index a0f75a9..4499cc0 100644
--- a/src/crypto/hkdf/hkdf_test.c
+++ b/src/crypto/hkdf/hkdf_test.c
@@ -20,6 +20,7 @@
#include <openssl/err.h>
#include <openssl/hkdf.h>
+#include "../internal.h"
#include "../test/test_util.h"
@@ -252,7 +253,7 @@
CRYPTO_library_init();
- for (i = 0; i < sizeof(kTests) / sizeof(kTests[0]); i++) {
+ for (i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) {
const hkdf_test_vector_t *test = &kTests[i];
if (!HKDF_extract(prk, &prk_len, test->md_func(), test->ikm, test->ikm_len,
test->salt, test->salt_len)) {
diff --git a/src/crypto/hmac/hmac_test.cc b/src/crypto/hmac/hmac_test.cc
index 3d49d9e..60a9581 100644
--- a/src/crypto/hmac/hmac_test.cc
+++ b/src/crypto/hmac/hmac_test.cc
@@ -61,9 +61,9 @@
#include <string>
#include <vector>
-#include <openssl/c++/hmac.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
+#include <openssl/hmac.h>
#include "../test/file_test.h"
diff --git a/src/crypto/internal.h b/src/crypto/internal.h
index 05fa569..d6e341a 100644
--- a/src/crypto/internal.h
+++ b/src/crypto/internal.h
@@ -147,6 +147,7 @@
typedef __uint128_t uint128_t;
#endif
+#define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
/* buffers_alias returns one if |a| and |b| alias and zero otherwise. */
static inline int buffers_alias(const uint8_t *a, size_t a_len,
diff --git a/src/crypto/modes/asm/ghashv8-armx.pl b/src/crypto/modes/asm/ghashv8-armx.pl
index 3a7b8d8..15fc478 100644
--- a/src/crypto/modes/asm/ghashv8-armx.pl
+++ b/src/crypto/modes/asm/ghashv8-armx.pl
@@ -59,7 +59,7 @@
.text
___
$code.=<<___ if ($flavour =~ /64/);
-#if !defined(__clang__)
+#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
.arch armv8-a+crypto
#endif
___
diff --git a/src/crypto/modes/ofb.c b/src/crypto/modes/ofb.c
index 2c5bdc9..0ee95ca 100644
--- a/src/crypto/modes/ofb.c
+++ b/src/crypto/modes/ofb.c
@@ -49,6 +49,7 @@
#include <openssl/type_check.h>
#include <assert.h>
+#include <string.h>
#include "internal.h"
@@ -68,27 +69,15 @@
n = (n + 1) % 16;
}
-#if STRICT_ALIGNMENT
- if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
- size_t l = 0;
- while (l < len) {
- if (n == 0) {
- (*block)(ivec, ivec, key);
- }
- out[l] = in[l] ^ ivec[n];
- ++l;
- n = (n + 1) % 16;
- }
-
- *num = n;
- return;
- }
-#endif
-
while (len >= 16) {
(*block)(ivec, ivec, key);
for (; n < 16; n += sizeof(size_t)) {
- *(size_t *)(out + n) = *(size_t *)(in + n) ^ *(size_t *)(ivec + n);
+ size_t a, b;
+ memcpy(&a, in + n, sizeof(size_t));
+ memcpy(&b, ivec + n, sizeof(size_t));
+
+ const size_t c = a ^ b;
+ memcpy(out + n, &c, sizeof(size_t));
}
len -= 16;
out += 16;
diff --git a/src/crypto/newhope/newhope_statistical_test.cc b/src/crypto/newhope/newhope_statistical_test.cc
index 44fac48..3ca6d78 100644
--- a/src/crypto/newhope/newhope_statistical_test.cc
+++ b/src/crypto/newhope/newhope_statistical_test.cc
@@ -19,9 +19,9 @@
#include <string.h>
#include <openssl/crypto.h>
+#include <openssl/newhope.h>
#include <openssl/rand.h>
-#include "../test/scoped_types.h"
#include "internal.h"
@@ -108,7 +108,7 @@
uint8_t key[NEWHOPE_KEY_LENGTH];
uint8_t offermsg[NEWHOPE_OFFERMSG_LENGTH];
- ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new()), pk(NEWHOPE_POLY_new()),
+ bssl::UniquePtr<NEWHOPE_POLY> sk(NEWHOPE_POLY_new()), pk(NEWHOPE_POLY_new()),
sp(NEWHOPE_POLY_new()), ep(NEWHOPE_POLY_new()), epp(NEWHOPE_POLY_new()),
a(NEWHOPE_POLY_new()), bp(NEWHOPE_POLY_new()), rec(NEWHOPE_POLY_new());
diff --git a/src/crypto/newhope/newhope_test.cc b/src/crypto/newhope/newhope_test.cc
index 6637393..a590721 100644
--- a/src/crypto/newhope/newhope_test.cc
+++ b/src/crypto/newhope/newhope_test.cc
@@ -19,7 +19,6 @@
#include <openssl/crypto.h>
#include <openssl/rand.h>
-#include "../test/scoped_types.h"
#include "internal.h"
@@ -28,7 +27,7 @@
static bool TestKeys(void) {
// Alice generates a public key.
- ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new());
+ bssl::UniquePtr<NEWHOPE_POLY> sk(NEWHOPE_POLY_new());
uint8_t offer_msg[NEWHOPE_OFFERMSG_LENGTH];
NEWHOPE_offer(offer_msg, sk.get());
@@ -58,7 +57,7 @@
static bool TestInvalidSK(void) {
// Alice generates a public key.
uint8_t offer_msg[NEWHOPE_OFFERMSG_LENGTH];
- ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new());
+ bssl::UniquePtr<NEWHOPE_POLY> sk(NEWHOPE_POLY_new());
NEWHOPE_offer(offer_msg, sk.get());
// Bob derives a secret key and creates a response.
@@ -93,7 +92,7 @@
static bool TestInvalidAcceptMsg(void) {
// Alice generates a public key.
- ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new());
+ bssl::UniquePtr<NEWHOPE_POLY> sk(NEWHOPE_POLY_new());
uint8_t offer_msg[NEWHOPE_OFFERMSG_LENGTH];
NEWHOPE_offer(offer_msg, sk.get());
diff --git a/src/crypto/newhope/newhope_vectors_test.cc b/src/crypto/newhope/newhope_vectors_test.cc
index fe84cd4..64aa0bb 100644
--- a/src/crypto/newhope/newhope_vectors_test.cc
+++ b/src/crypto/newhope/newhope_vectors_test.cc
@@ -20,17 +20,16 @@
#include <openssl/rand.h>
#include "../test/file_test.h"
-#include "../test/scoped_types.h"
#include "internal.h"
static bool TestNewhope(FileTest *t, void *arg) {
- ScopedNEWHOPE_POLY a(NEWHOPE_POLY_new());
- ScopedNEWHOPE_POLY s(NEWHOPE_POLY_new()), sp(NEWHOPE_POLY_new());
- ScopedNEWHOPE_POLY e(NEWHOPE_POLY_new()), ep(NEWHOPE_POLY_new()),
+ bssl::UniquePtr<NEWHOPE_POLY> a(NEWHOPE_POLY_new());
+ bssl::UniquePtr<NEWHOPE_POLY> s(NEWHOPE_POLY_new()), sp(NEWHOPE_POLY_new());
+ bssl::UniquePtr<NEWHOPE_POLY> e(NEWHOPE_POLY_new()), ep(NEWHOPE_POLY_new()),
epp(NEWHOPE_POLY_new());
- ScopedNEWHOPE_POLY in_pk(NEWHOPE_POLY_new());
- ScopedNEWHOPE_POLY in_rec(NEWHOPE_POLY_new());
+ bssl::UniquePtr<NEWHOPE_POLY> in_pk(NEWHOPE_POLY_new());
+ bssl::UniquePtr<NEWHOPE_POLY> in_rec(NEWHOPE_POLY_new());
if (t->GetType() == "InRandA") {
std::vector<uint8_t> a_bytes, s_bytes, e_bytes, expected_pk;
diff --git a/src/crypto/pkcs8/pkcs12_test.cc b/src/crypto/pkcs8/pkcs12_test.cc
index 17bcd27..5c1a1b4 100644
--- a/src/crypto/pkcs8/pkcs12_test.cc
+++ b/src/crypto/pkcs8/pkcs12_test.cc
@@ -23,8 +23,6 @@
#include <openssl/stack.h>
#include <openssl/x509.h>
-#include "../test/scoped_types.h"
-
/* kPKCS12DER contains sample PKCS#12 data generated by OpenSSL with:
* openssl pkcs12 -export -inkey key.pem -in cacert.pem */
@@ -684,7 +682,7 @@
static const char kPassword[] = "foo";
static bool Test(const char *name, const uint8_t *der, size_t der_len) {
- ScopedX509Stack certs(sk_X509_new_null());
+ bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
if (!certs) {
return false;
}
@@ -697,7 +695,7 @@
ERR_print_errors_fp(stderr);
return false;
}
- ScopedEVP_PKEY delete_key(key);
+ bssl::UniquePtr<EVP_PKEY> delete_key(key);
if (sk_X509_num(certs.get()) != 1 || key == nullptr) {
fprintf(stderr, "Bad result from %s data.\n", name);
@@ -708,12 +706,12 @@
}
static bool TestCompat(const uint8_t *der, size_t der_len) {
- ScopedBIO bio(BIO_new_mem_buf(der, der_len));
+ bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(der, der_len));
if (!bio) {
return false;
}
- ScopedPKCS12 p12(d2i_PKCS12_bio(bio.get(), nullptr));
+ bssl::UniquePtr<PKCS12> p12(d2i_PKCS12_bio(bio.get(), nullptr));
if (!p12) {
fprintf(stderr, "PKCS12_parse failed.\n");
ERR_print_errors_fp(stderr);
@@ -738,9 +736,9 @@
ERR_print_errors_fp(stderr);
return false;
}
- ScopedEVP_PKEY delete_key(key);
- ScopedX509 delete_cert(cert);
- ScopedX509Stack delete_ca_certs(ca_certs);
+ bssl::UniquePtr<EVP_PKEY> delete_key(key);
+ bssl::UniquePtr<X509> delete_cert(cert);
+ bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);
if (key == nullptr || cert == nullptr) {
fprintf(stderr, "Bad result from PKCS12_parse.\n");
diff --git a/src/crypto/pkcs8/pkcs8.c b/src/crypto/pkcs8/pkcs8.c
index 4ecf17f..2363aa8 100644
--- a/src/crypto/pkcs8/pkcs8.c
+++ b/src/crypto/pkcs8/pkcs8.c
@@ -71,6 +71,7 @@
#include <openssl/x509.h>
#include "internal.h"
+#include "../internal.h"
#include "../bytestring/internal.h"
@@ -310,7 +311,7 @@
static const struct pbe_suite *get_pbe_suite(int pbe_nid) {
unsigned i;
- for (i = 0; i < sizeof(kBuiltinPBE) / sizeof(kBuiltinPBE[0]); i++) {
+ for (i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) {
if (kBuiltinPBE[i].pbe_nid == pbe_nid) {
return &kBuiltinPBE[i];
}
diff --git a/src/crypto/pkcs8/pkcs8_test.cc b/src/crypto/pkcs8/pkcs8_test.cc
index 7a88ddf..cbb2043 100644
--- a/src/crypto/pkcs8/pkcs8_test.cc
+++ b/src/crypto/pkcs8/pkcs8_test.cc
@@ -21,8 +21,6 @@
#include <openssl/pkcs8.h>
#include <openssl/x509.h>
-#include "../test/scoped_types.h"
-
/* kDER is a PKCS#8 encrypted private key. It was generated with:
*
@@ -64,14 +62,14 @@
static bool test(const uint8_t *der, size_t der_len) {
const uint8_t *data = der;
- ScopedX509_SIG sig(d2i_X509_SIG(NULL, &data, der_len));
+ bssl::UniquePtr<X509_SIG> sig(d2i_X509_SIG(NULL, &data, der_len));
if (sig.get() == NULL || data != der + der_len) {
fprintf(stderr, "d2i_X509_SIG failed or did not consume all bytes.\n");
return false;
}
static const char kPassword[] = "testing";
- ScopedPKCS8_PRIV_KEY_INFO keypair(PKCS8_decrypt(sig.get(), kPassword, -1));
+ bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> keypair(PKCS8_decrypt(sig.get(), kPassword, -1));
if (!keypair) {
fprintf(stderr, "PKCS8_decrypt failed.\n");
ERR_print_errors_fp(stderr);
diff --git a/src/crypto/rc4/CMakeLists.txt b/src/crypto/rc4/CMakeLists.txt
index 151773a..a008fe5 100644
--- a/src/crypto/rc4/CMakeLists.txt
+++ b/src/crypto/rc4/CMakeLists.txt
@@ -1,29 +1,9 @@
include_directories(../../include)
-if (${ARCH} STREQUAL "x86_64")
- set(
- RC4_ARCH_SOURCES
-
- rc4-x86_64.${ASM_EXT}
- )
-endif()
-
-if (${ARCH} STREQUAL "x86")
- set(
- RC4_ARCH_SOURCES
-
- rc4-586.${ASM_EXT}
- )
-endif()
-
add_library(
rc4
OBJECT
rc4.c
- ${RC4_ARCH_SOURCES}
)
-
-perlasm(rc4-x86_64.${ASM_EXT} asm/rc4-x86_64.pl)
-perlasm(rc4-586.${ASM_EXT} asm/rc4-586.pl)
diff --git a/src/crypto/rc4/asm/rc4-586.pl b/src/crypto/rc4/asm/rc4-586.pl
deleted file mode 100644
index 78f48cc..0000000
--- a/src/crypto/rc4/asm/rc4-586.pl
+++ /dev/null
@@ -1,392 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# [Re]written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# At some point it became apparent that the original SSLeay RC4
-# assembler implementation performs suboptimally on latest IA-32
-# microarchitectures. After re-tuning performance has changed as
-# following:
-#
-# Pentium -10%
-# Pentium III +12%
-# AMD +50%(*)
-# P4 +250%(**)
-#
-# (*) This number is actually a trade-off:-) It's possible to
-# achieve +72%, but at the cost of -48% off PIII performance.
-# In other words code performing further 13% faster on AMD
-# would perform almost 2 times slower on Intel PIII...
-# For reference! This code delivers ~80% of rc4-amd64.pl
-# performance on the same Opteron machine.
-# (**) This number requires compressed key schedule set up by
-# RC4_set_key [see commentary below for further details].
-#
-# <appro@fy.chalmers.se>
-
-# May 2011
-#
-# Optimize for Core2 and Westmere [and incidentally Opteron]. Current
-# performance in cycles per processed byte (less is better) and
-# improvement relative to previous version of this module is:
-#
-# Pentium 10.2 # original numbers
-# Pentium III 7.8(*)
-# Intel P4 7.5
-#
-# Opteron 6.1/+20% # new MMX numbers
-# Core2 5.3/+67%(**)
-# Westmere 5.1/+94%(**)
-# Sandy Bridge 5.0/+8%
-# Atom 12.6/+6%
-#
-# (*) PIII can actually deliver 6.6 cycles per byte with MMX code,
-# but this specific code performs poorly on Core2. And vice
-# versa, below MMX/SSE code delivering 5.8/7.1 on Core2 performs
-# poorly on PIII, at 8.0/14.5:-( As PIII is not a "hot" CPU
-# [anymore], I chose to discard PIII-specific code path and opt
-# for original IALU-only code, which is why MMX/SSE code path
-# is guarded by SSE2 bit (see below), not MMX/SSE.
-# (**) Performance vs. block size on Core2 and Westmere had a maximum
-# at ... 64 bytes block size. And it was quite a maximum, 40-60%
-# in comparison to largest 8KB block size. Above improvement
-# coefficients are for the largest block size.
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC,"${dir}","${dir}../../perlasm");
-require "x86asm.pl";
-
-$output=pop;
-open STDOUT,">$output";
-
-&asm_init($ARGV[0],"rc4-586.pl",$x86only = $ARGV[$#ARGV] eq "386");
-
-$xx="eax";
-$yy="ebx";
-$tx="ecx";
-$ty="edx";
-$inp="esi";
-$out="ebp";
-$dat="edi";
-
-sub RC4_loop {
- my $i=shift;
- my $func = ($i==0)?*mov:*or;
-
- &add (&LB($yy),&LB($tx));
- &mov ($ty,&DWP(0,$dat,$yy,4));
- &mov (&DWP(0,$dat,$yy,4),$tx);
- &mov (&DWP(0,$dat,$xx,4),$ty);
- &add ($ty,$tx);
- &inc (&LB($xx));
- &and ($ty,0xff);
- &ror ($out,8) if ($i!=0);
- if ($i<3) {
- &mov ($tx,&DWP(0,$dat,$xx,4));
- } else {
- &mov ($tx,&wparam(3)); # reload [re-biased] out
- }
- &$func ($out,&DWP(0,$dat,$ty,4));
-}
-
-if ($alt=0) {
- # >20% faster on Atom and Sandy Bridge[!], 8% faster on Opteron,
- # but ~40% slower on Core2 and Westmere... Attempt to add movz
- # brings down Opteron by 25%, Atom and Sandy Bridge by 15%, yet
- # on Core2 with movz it's almost 20% slower than below alternative
- # code... Yes, it's a total mess...
- my @XX=($xx,$out);
- $RC4_loop_mmx = sub { # SSE actually...
- my $i=shift;
- my $j=$i<=0?0:$i>>1;
- my $mm=$i<=0?"mm0":"mm".($i&1);
-
- &add (&LB($yy),&LB($tx));
- &lea (@XX[1],&DWP(1,@XX[0]));
- &pxor ("mm2","mm0") if ($i==0);
- &psllq ("mm1",8) if ($i==0);
- &and (@XX[1],0xff);
- &pxor ("mm0","mm0") if ($i<=0);
- &mov ($ty,&DWP(0,$dat,$yy,4));
- &mov (&DWP(0,$dat,$yy,4),$tx);
- &pxor ("mm1","mm2") if ($i==0);
- &mov (&DWP(0,$dat,$XX[0],4),$ty);
- &add (&LB($ty),&LB($tx));
- &movd (@XX[0],"mm7") if ($i==0);
- &mov ($tx,&DWP(0,$dat,@XX[1],4));
- &pxor ("mm1","mm1") if ($i==1);
- &movq ("mm2",&QWP(0,$inp)) if ($i==1);
- &movq (&QWP(-8,(@XX[0],$inp)),"mm1") if ($i==0);
- &pinsrw ($mm,&DWP(0,$dat,$ty,4),$j);
-
- push (@XX,shift(@XX)) if ($i>=0);
- }
-} else {
- # Using pinsrw here improves performane on Intel CPUs by 2-3%, but
- # brings down AMD by 7%...
- $RC4_loop_mmx = sub {
- my $i=shift;
-
- &add (&LB($yy),&LB($tx));
- &psllq ("mm1",8*(($i-1)&7)) if (abs($i)!=1);
- &mov ($ty,&DWP(0,$dat,$yy,4));
- &mov (&DWP(0,$dat,$yy,4),$tx);
- &mov (&DWP(0,$dat,$xx,4),$ty);
- &inc ($xx);
- &add ($ty,$tx);
- &movz ($xx,&LB($xx)); # (*)
- &movz ($ty,&LB($ty)); # (*)
- &pxor ("mm2",$i==1?"mm0":"mm1") if ($i>=0);
- &movq ("mm0",&QWP(0,$inp)) if ($i<=0);
- &movq (&QWP(-8,($out,$inp)),"mm2") if ($i==0);
- &mov ($tx,&DWP(0,$dat,$xx,4));
- &movd ($i>0?"mm1":"mm2",&DWP(0,$dat,$ty,4));
-
- # (*) This is the key to Core2 and Westmere performance.
- # Whithout movz out-of-order execution logic confuses
- # itself and fails to reorder loads and stores. Problem
- # appears to be fixed in Sandy Bridge...
- }
-}
-
-&external_label("OPENSSL_ia32cap_P");
-
-# void asm_RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out);
-&function_begin("asm_RC4");
- &mov ($dat,&wparam(0)); # load key schedule pointer
- &mov ($ty, &wparam(1)); # load len
- &mov ($inp,&wparam(2)); # load inp
- &mov ($out,&wparam(3)); # load out
-
- &xor ($xx,$xx); # avoid partial register stalls
- &xor ($yy,$yy);
-
- &cmp ($ty,0); # safety net
- &je (&label("abort"));
-
- &mov (&LB($xx),&BP(0,$dat)); # load key->x
- &mov (&LB($yy),&BP(4,$dat)); # load key->y
- &add ($dat,8);
-
- &lea ($tx,&DWP(0,$inp,$ty));
- &sub ($out,$inp); # re-bias out
- &mov (&wparam(1),$tx); # save input+len
-
- &inc (&LB($xx));
-
- # detect compressed key schedule...
- &cmp (&DWP(256,$dat),-1);
- &je (&label("RC4_CHAR"));
-
- &mov ($tx,&DWP(0,$dat,$xx,4));
-
- &and ($ty,-4); # how many 4-byte chunks?
- &jz (&label("loop1"));
-
- &mov (&wparam(3),$out); # $out as accumulator in these loops
- if ($x86only) {
- &jmp (&label("go4loop4"));
- } else {
- &test ($ty,-8);
- &jz (&label("go4loop4"));
-
- &picmeup($out,"OPENSSL_ia32cap_P");
- &bt (&DWP(0,$out),26); # check SSE2 bit [could have been MMX]
- &jnc (&label("go4loop4"));
-
- &mov ($out,&wparam(3)) if (!$alt);
- &movd ("mm7",&wparam(3)) if ($alt);
- &and ($ty,-8);
- &lea ($ty,&DWP(-8,$inp,$ty));
- &mov (&DWP(-4,$dat),$ty); # save input+(len/8)*8-8
-
- &$RC4_loop_mmx(-1);
- &jmp(&label("loop_mmx_enter"));
-
- &set_label("loop_mmx",16);
- &$RC4_loop_mmx(0);
- &set_label("loop_mmx_enter");
- for ($i=1;$i<8;$i++) { &$RC4_loop_mmx($i); }
- &mov ($ty,$yy);
- &xor ($yy,$yy); # this is second key to Core2
- &mov (&LB($yy),&LB($ty)); # and Westmere performance...
- &cmp ($inp,&DWP(-4,$dat));
- &lea ($inp,&DWP(8,$inp));
- &jb (&label("loop_mmx"));
-
- if ($alt) {
- &movd ($out,"mm7");
- &pxor ("mm2","mm0");
- &psllq ("mm1",8);
- &pxor ("mm1","mm2");
- &movq (&QWP(-8,$out,$inp),"mm1");
- } else {
- &psllq ("mm1",56);
- &pxor ("mm2","mm1");
- &movq (&QWP(-8,$out,$inp),"mm2");
- }
- &emms ();
-
- &cmp ($inp,&wparam(1)); # compare to input+len
- &je (&label("done"));
- &jmp (&label("loop1"));
- }
-
-&set_label("go4loop4",16);
- &lea ($ty,&DWP(-4,$inp,$ty));
- &mov (&wparam(2),$ty); # save input+(len/4)*4-4
-
- &set_label("loop4");
- for ($i=0;$i<4;$i++) { RC4_loop($i); }
- &ror ($out,8);
- &xor ($out,&DWP(0,$inp));
- &cmp ($inp,&wparam(2)); # compare to input+(len/4)*4-4
- &mov (&DWP(0,$tx,$inp),$out);# $tx holds re-biased out here
- &lea ($inp,&DWP(4,$inp));
- &mov ($tx,&DWP(0,$dat,$xx,4));
- &jb (&label("loop4"));
-
- &cmp ($inp,&wparam(1)); # compare to input+len
- &je (&label("done"));
- &mov ($out,&wparam(3)); # restore $out
-
- &set_label("loop1",16);
- &add (&LB($yy),&LB($tx));
- &mov ($ty,&DWP(0,$dat,$yy,4));
- &mov (&DWP(0,$dat,$yy,4),$tx);
- &mov (&DWP(0,$dat,$xx,4),$ty);
- &add ($ty,$tx);
- &inc (&LB($xx));
- &and ($ty,0xff);
- &mov ($ty,&DWP(0,$dat,$ty,4));
- &xor (&LB($ty),&BP(0,$inp));
- &lea ($inp,&DWP(1,$inp));
- &mov ($tx,&DWP(0,$dat,$xx,4));
- &cmp ($inp,&wparam(1)); # compare to input+len
- &mov (&BP(-1,$out,$inp),&LB($ty));
- &jb (&label("loop1"));
-
- &jmp (&label("done"));
-
-# this is essentially Intel P4 specific codepath...
-&set_label("RC4_CHAR",16);
- &movz ($tx,&BP(0,$dat,$xx));
- # strangely enough unrolled loop performs over 20% slower...
- &set_label("cloop1");
- &add (&LB($yy),&LB($tx));
- &movz ($ty,&BP(0,$dat,$yy));
- &mov (&BP(0,$dat,$yy),&LB($tx));
- &mov (&BP(0,$dat,$xx),&LB($ty));
- &add (&LB($ty),&LB($tx));
- &movz ($ty,&BP(0,$dat,$ty));
- &add (&LB($xx),1);
- &xor (&LB($ty),&BP(0,$inp));
- &lea ($inp,&DWP(1,$inp));
- &movz ($tx,&BP(0,$dat,$xx));
- &cmp ($inp,&wparam(1));
- &mov (&BP(-1,$out,$inp),&LB($ty));
- &jb (&label("cloop1"));
-
-&set_label("done");
- &dec (&LB($xx));
- &mov (&DWP(-4,$dat),$yy); # save key->y
- &mov (&BP(-8,$dat),&LB($xx)); # save key->x
-&set_label("abort");
-&function_end("asm_RC4");
-
-########################################################################
-
-$inp="esi";
-$out="edi";
-$idi="ebp";
-$ido="ecx";
-$idx="edx";
-
-# void asm_RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
-&function_begin("asm_RC4_set_key");
- &mov ($out,&wparam(0)); # load key
- &mov ($idi,&wparam(1)); # load len
- &mov ($inp,&wparam(2)); # load data
- &picmeup($idx,"OPENSSL_ia32cap_P");
-
- &lea ($out,&DWP(2*4,$out)); # &key->data
- &lea ($inp,&DWP(0,$inp,$idi)); # $inp to point at the end
- &neg ($idi);
- &xor ("eax","eax");
- &mov (&DWP(-4,$out),$idi); # borrow key->y
-
- &bt (&DWP(0,$idx),20); # check for bit#20
- &jc (&label("c1stloop"));
-
-&set_label("w1stloop",16);
- &mov (&DWP(0,$out,"eax",4),"eax"); # key->data[i]=i;
- &add (&LB("eax"),1); # i++;
- &jnc (&label("w1stloop"));
-
- &xor ($ido,$ido);
- &xor ($idx,$idx);
-
-&set_label("w2ndloop",16);
- &mov ("eax",&DWP(0,$out,$ido,4));
- &add (&LB($idx),&BP(0,$inp,$idi));
- &add (&LB($idx),&LB("eax"));
- &add ($idi,1);
- &mov ("ebx",&DWP(0,$out,$idx,4));
- &jnz (&label("wnowrap"));
- &mov ($idi,&DWP(-4,$out));
- &set_label("wnowrap");
- &mov (&DWP(0,$out,$idx,4),"eax");
- &mov (&DWP(0,$out,$ido,4),"ebx");
- &add (&LB($ido),1);
- &jnc (&label("w2ndloop"));
-&jmp (&label("exit"));
-
-# Unlike all other x86 [and x86_64] implementations, Intel P4 core
-# [including EM64T] was found to perform poorly with above "32-bit" key
-# schedule, a.k.a. RC4_INT. Performance improvement for IA-32 hand-coded
-# assembler turned out to be 3.5x if re-coded for compressed 8-bit one,
-# a.k.a. RC4_CHAR! It's however inappropriate to just switch to 8-bit
-# schedule for x86[_64], because non-P4 implementations suffer from
-# significant performance losses then, e.g. PIII exhibits >2x
-# deterioration, and so does Opteron. In order to assure optimal
-# all-round performance, we detect P4 at run-time and set up compressed
-# key schedule, which is recognized by RC4 procedure.
-
-&set_label("c1stloop",16);
- &mov (&BP(0,$out,"eax"),&LB("eax")); # key->data[i]=i;
- &add (&LB("eax"),1); # i++;
- &jnc (&label("c1stloop"));
-
- &xor ($ido,$ido);
- &xor ($idx,$idx);
- &xor ("ebx","ebx");
-
-&set_label("c2ndloop",16);
- &mov (&LB("eax"),&BP(0,$out,$ido));
- &add (&LB($idx),&BP(0,$inp,$idi));
- &add (&LB($idx),&LB("eax"));
- &add ($idi,1);
- &mov (&LB("ebx"),&BP(0,$out,$idx));
- &jnz (&label("cnowrap"));
- &mov ($idi,&DWP(-4,$out));
- &set_label("cnowrap");
- &mov (&BP(0,$out,$idx),&LB("eax"));
- &mov (&BP(0,$out,$ido),&LB("ebx"));
- &add (&LB($ido),1);
- &jnc (&label("c2ndloop"));
-
- &mov (&DWP(256,$out),-1); # mark schedule as compressed
-
-&set_label("exit");
- &xor ("eax","eax");
- &mov (&DWP(-8,$out),"eax"); # key->x=0;
- &mov (&DWP(-4,$out),"eax"); # key->y=0;
-&function_end("asm_RC4_set_key");
-
-&asm_finish();
-
-close STDOUT;
diff --git a/src/crypto/rc4/asm/rc4-x86_64.pl b/src/crypto/rc4/asm/rc4-x86_64.pl
deleted file mode 100644
index fd52fbb..0000000
--- a/src/crypto/rc4/asm/rc4-x86_64.pl
+++ /dev/null
@@ -1,653 +0,0 @@
-#!/usr/bin/env perl
-#
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-#
-# July 2004
-#
-# 2.22x RC4 tune-up:-) It should be noted though that my hand [as in
-# "hand-coded assembler"] doesn't stand for the whole improvement
-# coefficient. It turned out that eliminating RC4_CHAR from config
-# line results in ~40% improvement (yes, even for C implementation).
-# Presumably it has everything to do with AMD cache architecture and
-# RAW or whatever penalties. Once again! The module *requires* config
-# line *without* RC4_CHAR! As for coding "secret," I bet on partial
-# register arithmetics. For example instead of 'inc %r8; and $255,%r8'
-# I simply 'inc %r8b'. Even though optimization manual discourages
-# to operate on partial registers, it turned out to be the best bet.
-# At least for AMD... How IA32E would perform remains to be seen...
-
-# November 2004
-#
-# As was shown by Marc Bevand reordering of couple of load operations
-# results in even higher performance gain of 3.3x:-) At least on
-# Opteron... For reference, 1x in this case is RC4_CHAR C-code
-# compiled with gcc 3.3.2, which performs at ~54MBps per 1GHz clock.
-# Latter means that if you want to *estimate* what to expect from
-# *your* Opteron, then multiply 54 by 3.3 and clock frequency in GHz.
-
-# November 2004
-#
-# Intel P4 EM64T core was found to run the AMD64 code really slow...
-# The only way to achieve comparable performance on P4 was to keep
-# RC4_CHAR. Kind of ironic, huh? As it's apparently impossible to
-# compose blended code, which would perform even within 30% marginal
-# on either AMD and Intel platforms, I implement both cases. See
-# rc4_skey.c for further details...
-
-# April 2005
-#
-# P4 EM64T core appears to be "allergic" to 64-bit inc/dec. Replacing
-# those with add/sub results in 50% performance improvement of folded
-# loop...
-
-# May 2005
-#
-# As was shown by Zou Nanhai loop unrolling can improve Intel EM64T
-# performance by >30% [unlike P4 32-bit case that is]. But this is
-# provided that loads are reordered even more aggressively! Both code
-# pathes, AMD64 and EM64T, reorder loads in essentially same manner
-# as my IA-64 implementation. On Opteron this resulted in modest 5%
-# improvement [I had to test it], while final Intel P4 performance
-# achieves respectful 432MBps on 2.8GHz processor now. For reference.
-# If executed on Xeon, current RC4_CHAR code-path is 2.7x faster than
-# RC4_INT code-path. While if executed on Opteron, it's only 25%
-# slower than the RC4_INT one [meaning that if CPU µ-arch detection
-# is not implemented, then this final RC4_CHAR code-path should be
-# preferred, as it provides better *all-round* performance].
-
-# March 2007
-#
-# Intel Core2 was observed to perform poorly on both code paths:-( It
-# apparently suffers from some kind of partial register stall, which
-# occurs in 64-bit mode only [as virtually identical 32-bit loop was
-# observed to outperform 64-bit one by almost 50%]. Adding two movzb to
-# cloop1 boosts its performance by 80%! This loop appears to be optimal
-# fit for Core2 and therefore the code was modified to skip cloop8 on
-# this CPU.
-
-# May 2010
-#
-# Intel Westmere was observed to perform suboptimally. Adding yet
-# another movzb to cloop1 improved performance by almost 50%! Core2
-# performance is improved too, but nominally...
-
-# May 2011
-#
-# The only code path that was not modified is P4-specific one. Non-P4
-# Intel code path optimization is heavily based on submission by Maxim
-# Perminov, Maxim Locktyukhin and Jim Guilford of Intel. I've used
-# some of the ideas even in attempt to optmize the original RC4_INT
-# code path... Current performance in cycles per processed byte (less
-# is better) and improvement coefficients relative to previous
-# version of this module are:
-#
-# Opteron 5.3/+0%(*)
-# P4 6.5
-# Core2 6.2/+15%(**)
-# Westmere 4.2/+60%
-# Sandy Bridge 4.2/+120%
-# Atom 9.3/+80%
-#
-# (*) But corresponding loop has less instructions, which should have
-# positive effect on upcoming Bulldozer, which has one less ALU.
-# For reference, Intel code runs at 6.8 cpb rate on Opteron.
-# (**) Note that Core2 result is ~15% lower than corresponding result
-# for 32-bit code, meaning that it's possible to improve it,
-# but more than likely at the cost of the others (see rc4-586.pl
-# to get the idea)...
-
-$flavour = shift;
-$output = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-
-$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $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;
-
-$dat="%rdi"; # arg1
-$len="%rsi"; # arg2
-$inp="%rdx"; # arg3
-$out="%rcx"; # arg4
-
-{
-$code=<<___;
-.text
-.extern OPENSSL_ia32cap_P
-
-.globl asm_RC4
-.type asm_RC4,\@function,4
-.align 16
-asm_RC4:
- or $len,$len
- jne .Lentry
- ret
-.Lentry:
- push %rbx
- push %r12
- push %r13
-.Lprologue:
- mov $len,%r11
- mov $inp,%r12
- mov $out,%r13
-___
-my $len="%r11"; # reassign input arguments
-my $inp="%r12";
-my $out="%r13";
-
-my @XX=("%r10","%rsi");
-my @TX=("%rax","%rbx");
-my $YY="%rcx";
-my $TY="%rdx";
-
-$code.=<<___;
- xor $XX[0],$XX[0]
- xor $YY,$YY
-
- lea 8($dat),$dat
- mov -8($dat),$XX[0]#b
- mov -4($dat),$YY#b
- cmpl \$-1,256($dat)
- je .LRC4_CHAR
- mov OPENSSL_ia32cap_P(%rip),%r8d
- xor $TX[1],$TX[1]
- inc $XX[0]#b
- sub $XX[0],$TX[1]
- sub $inp,$out
- movl ($dat,$XX[0],4),$TX[0]#d
- test \$-16,$len
- jz .Lloop1
- bt \$30,%r8d # Intel CPU?
- jc .Lintel
- and \$7,$TX[1]
- lea 1($XX[0]),$XX[1]
- jz .Loop8
- sub $TX[1],$len
-.Loop8_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 ($inp),$TY#b
- movb $TY#b,($out,$inp)
- lea 1($inp),$inp
- dec $TX[1]
- jnz .Loop8_warmup
-
- lea 1($XX[0]),$XX[1]
- jmp .Loop8
-.align 16
-.Loop8:
-___
-for ($i=0;$i<8;$i++) {
-$code.=<<___ if ($i==7);
- add \$8,$XX[1]#b
-___
-$code.=<<___;
- add $TX[0]#b,$YY#b
- movl ($dat,$YY,4),$TY#d
- movl $TX[0]#d,($dat,$YY,4)
- movl `4*($i==7?-1:$i)`($dat,$XX[1],4),$TX[1]#d
- ror \$8,%r8 # ror is redundant when $i=0
- movl $TY#d,4*$i($dat,$XX[0],4)
- add $TX[0]#b,$TY#b
- movb ($dat,$TY,4),%r8b
-___
-push(@TX,shift(@TX)); #push(@XX,shift(@XX)); # "rotate" registers
-}
-$code.=<<___;
- add \$8,$XX[0]#b
- ror \$8,%r8
- sub \$8,$len
-
- xor ($inp),%r8
- mov %r8,($out,$inp)
- lea 8($inp),$inp
-
- test \$-8,$len
- jnz .Loop8
- cmp \$0,$len
- jne .Lloop1
- jmp .Lexit
-
-.align 16
-.Lintel:
- test \$-32,$len
- jz .Lloop1
- and \$15,$TX[1]
- jz .Loop16_is_hot
- sub $TX[1],$len
-.Loop16_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 ($inp),$TY#b
- movb $TY#b,($out,$inp)
- lea 1($inp),$inp
- dec $TX[1]
- jnz .Loop16_warmup
-
- mov $YY,$TX[1]
- xor $YY,$YY
- mov $TX[1]#b,$YY#b
-
-.Loop16_is_hot:
- lea ($dat,$XX[0],4),$XX[1]
-___
-sub RC4_loop {
- my $i=shift;
- my $j=$i<0?0:$i;
- my $xmm="%xmm".($j&1);
-
- $code.=" add \$16,$XX[0]#b\n" if ($i==15);
- $code.=" movdqu ($inp),%xmm2\n" if ($i==15);
- $code.=" add $TX[0]#b,$YY#b\n" if ($i<=0);
- $code.=" movl ($dat,$YY,4),$TY#d\n";
- $code.=" pxor %xmm0,%xmm2\n" if ($i==0);
- $code.=" psllq \$8,%xmm1\n" if ($i==0);
- $code.=" pxor $xmm,$xmm\n" if ($i<=1);
- $code.=" movl $TX[0]#d,($dat,$YY,4)\n";
- $code.=" add $TY#b,$TX[0]#b\n";
- $code.=" movl `4*($j+1)`($XX[1]),$TX[1]#d\n" if ($i<15);
- $code.=" movz $TX[0]#b,$TX[0]#d\n";
- $code.=" movl $TY#d,4*$j($XX[1])\n";
- $code.=" pxor %xmm1,%xmm2\n" if ($i==0);
- $code.=" lea ($dat,$XX[0],4),$XX[1]\n" if ($i==15);
- $code.=" add $TX[1]#b,$YY#b\n" if ($i<15);
- $code.=" pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n";
- $code.=" movdqu %xmm2,($out,$inp)\n" if ($i==0);
- $code.=" lea 16($inp),$inp\n" if ($i==0);
- $code.=" movl ($XX[1]),$TX[1]#d\n" if ($i==15);
-}
- RC4_loop(-1);
-$code.=<<___;
- jmp .Loop16_enter
-.align 16
-.Loop16:
-___
-
-for ($i=0;$i<16;$i++) {
- $code.=".Loop16_enter:\n" if ($i==1);
- RC4_loop($i);
- push(@TX,shift(@TX)); # "rotate" registers
-}
-$code.=<<___;
- mov $YY,$TX[1]
- xor $YY,$YY # keyword to partial register
- sub \$16,$len
- mov $TX[1]#b,$YY#b
- test \$-16,$len
- jnz .Loop16
-
- psllq \$8,%xmm1
- pxor %xmm0,%xmm2
- pxor %xmm1,%xmm2
- movdqu %xmm2,($out,$inp)
- lea 16($inp),$inp
-
- cmp \$0,$len
- jne .Lloop1
- jmp .Lexit
-
-.align 16
-.Lloop1:
- 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 ($inp),$TY#b
- movb $TY#b,($out,$inp)
- lea 1($inp),$inp
- dec $len
- jnz .Lloop1
- jmp .Lexit
-
-.align 16
-.LRC4_CHAR:
- add \$1,$XX[0]#b
- movzb ($dat,$XX[0]),$TX[0]#d
- test \$-8,$len
- jz .Lcloop1
- jmp .Lcloop8
-.align 16
-.Lcloop8:
- mov ($inp),%r8d
- mov 4($inp),%r9d
-___
-# unroll 2x4-wise, because 64-bit rotates kill Intel P4...
-for ($i=0;$i<4;$i++) {
-$code.=<<___;
- add $TX[0]#b,$YY#b
- lea 1($XX[0]),$XX[1]
- movzb ($dat,$YY),$TY#d
- movzb $XX[1]#b,$XX[1]#d
- movzb ($dat,$XX[1]),$TX[1]#d
- movb $TX[0]#b,($dat,$YY)
- cmp $XX[1],$YY
- movb $TY#b,($dat,$XX[0])
- jne .Lcmov$i # Intel cmov is sloooow...
- mov $TX[0],$TX[1]
-.Lcmov$i:
- add $TX[0]#b,$TY#b
- xor ($dat,$TY),%r8b
- ror \$8,%r8d
-___
-push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers
-}
-for ($i=4;$i<8;$i++) {
-$code.=<<___;
- add $TX[0]#b,$YY#b
- lea 1($XX[0]),$XX[1]
- movzb ($dat,$YY),$TY#d
- movzb $XX[1]#b,$XX[1]#d
- movzb ($dat,$XX[1]),$TX[1]#d
- movb $TX[0]#b,($dat,$YY)
- cmp $XX[1],$YY
- movb $TY#b,($dat,$XX[0])
- jne .Lcmov$i # Intel cmov is sloooow...
- mov $TX[0],$TX[1]
-.Lcmov$i:
- add $TX[0]#b,$TY#b
- xor ($dat,$TY),%r9b
- ror \$8,%r9d
-___
-push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers
-}
-$code.=<<___;
- lea -8($len),$len
- mov %r8d,($out)
- lea 8($inp),$inp
- mov %r9d,4($out)
- lea 8($out),$out
-
- test \$-8,$len
- jnz .Lcloop8
- cmp \$0,$len
- jne .Lcloop1
- jmp .Lexit
-___
-$code.=<<___;
-.align 16
-.Lcloop1:
- add $TX[0]#b,$YY#b
- movzb $YY#b,$YY#d
- movzb ($dat,$YY),$TY#d
- movb $TX[0]#b,($dat,$YY)
- movb $TY#b,($dat,$XX[0])
- add $TX[0]#b,$TY#b
- add \$1,$XX[0]#b
- movzb $TY#b,$TY#d
- movzb $XX[0]#b,$XX[0]#d
- movzb ($dat,$TY),$TY#d
- movzb ($dat,$XX[0]),$TX[0]#d
- xorb ($inp),$TY#b
- lea 1($inp),$inp
- movb $TY#b,($out)
- lea 1($out),$out
- sub \$1,$len
- jnz .Lcloop1
- jmp .Lexit
-
-.align 16
-.Lexit:
- sub \$1,$XX[0]#b
- movl $XX[0]#d,-8($dat)
- movl $YY#d,-4($dat)
-
- mov (%rsp),%r13
- mov 8(%rsp),%r12
- mov 16(%rsp),%rbx
- add \$24,%rsp
-.Lepilogue:
- ret
-.size asm_RC4,.-asm_RC4
-___
-}
-
-$idx="%r8";
-$ido="%r9";
-
-$code.=<<___;
-.globl asm_RC4_set_key
-.type asm_RC4_set_key,\@function,3
-.align 16
-asm_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
-
- mov OPENSSL_ia32cap_P(%rip),$idx#d
- bt \$20,$idx#d # RC4_CHAR?
- jc .Lc1stloop
- 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
- jmp .Lexit_key
-
-.align 16
-.Lc1stloop:
- mov %al,($dat,%rax)
- add \$1,%al
- jnc .Lc1stloop
-
- xor $ido,$ido
- xor $idx,$idx
-.align 16
-.Lc2ndloop:
- mov ($dat,$ido),%r10b
- add ($inp,$len),$idx#b
- add %r10b,$idx#b
- add \$1,$len
- mov ($dat,$idx),%r11b
- jnz .Lcnowrap
- mov %rcx,$len
-.Lcnowrap:
- mov %r10b,($dat,$idx)
- mov %r11b,($dat,$ido)
- add \$1,$ido#b
- jnc .Lc2ndloop
- movl \$-1,256($dat)
-
-.align 16
-.Lexit_key:
- xor %eax,%eax
- mov %eax,-8($dat)
- mov %eax,-4($dat)
- ret
-.size asm_RC4_set_key,.-asm_RC4_set_key
-___
-
-# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-# CONTEXT *context,DISPATCHER_CONTEXT *disp)
-if ($win64) {
-$rec="%rcx";
-$frame="%rdx";
-$context="%r8";
-$disp="%r9";
-
-$code.=<<___;
-.extern __imp_RtlVirtualUnwind
-.type stream_se_handler,\@abi-omnipotent
-.align 16
-stream_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 .Lprologue(%rip),%r10
- cmp %r10,%rbx # context->Rip<prologue label
- jb .Lin_prologue
-
- mov 152($context),%rax # pull context->Rsp
-
- lea .Lepilogue(%rip),%r10
- cmp %r10,%rbx # context->Rip>=epilogue label
- jae .Lin_prologue
-
- lea 24(%rax),%rax
-
- mov -8(%rax),%rbx
- mov -16(%rax),%r12
- mov -24(%rax),%r13
- mov %rbx,144($context) # restore context->Rbx
- mov %r12,216($context) # restore context->R12
- mov %r13,224($context) # restore context->R13
-
-.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
-
- jmp .Lcommon_seh_exit
-.size stream_se_handler,.-stream_se_handler
-
-.type key_se_handler,\@abi-omnipotent
-.align 16
-key_se_handler:
- push %rsi
- push %rdi
- push %rbx
- push %rbp
- push %r12
- push %r13
- push %r14
- push %r15
- pushfq
- sub \$64,%rsp
-
- mov 152($context),%rax # pull context->Rsp
- mov 8(%rax),%rdi
- mov 16(%rax),%rsi
- mov %rsi,168($context) # restore context->Rsi
- mov %rdi,176($context) # restore context->Rdi
-
-.Lcommon_seh_exit:
-
- 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 key_se_handler,.-key_se_handler
-
-.section .pdata
-.align 4
- .rva .LSEH_begin_asm_RC4
- .rva .LSEH_end_asm_RC4
- .rva .LSEH_info_asm_RC4
-
- .rva .LSEH_begin_asm_RC4_set_key
- .rva .LSEH_end_asm_RC4_set_key
- .rva .LSEH_info_asm_RC4_set_key
-
-.section .xdata
-.align 8
-.LSEH_info_asm_RC4:
- .byte 9,0,0,0
- .rva stream_se_handler
-.LSEH_info_asm_RC4_set_key:
- .byte 9,0,0,0
- .rva key_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;
-
-print $code;
-
-close STDOUT;
diff --git a/src/crypto/rc4/rc4.c b/src/crypto/rc4/rc4.c
index b8e1d9f..a27a657 100644
--- a/src/crypto/rc4/rc4.c
+++ b/src/crypto/rc4/rc4.c
@@ -56,228 +56,43 @@
#include <openssl/rc4.h>
-#if defined(OPENSSL_NO_ASM) || \
- (!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86))
-
-#if defined(OPENSSL_64_BIT)
-#define RC4_CHUNK uint64_t
-#elif defined(OPENSSL_32_BIT)
-#define RC4_CHUNK uint32_t
-#else
-#error "Unknown word size"
-#endif
-
-
-/* RC4 as implemented from a posting from
- * Newsgroups: sci.crypt
- * From: sterndark@netcom.com (David Sterndark)
- * Subject: RC4 Algorithm revealed.
- * Message-ID: <sternCvKL4B.Hyy@netcom.com>
- * Date: Wed, 14 Sep 1994 06:35:31 GMT */
void RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out) {
- uint32_t *d;
- uint32_t x, y, tx, ty;
- size_t i;
+ uint32_t x = key->x;
+ uint32_t y = key->y;
+ uint32_t *d = key->data;
- x = key->x;
- y = key->y;
- d = key->data;
-
-#define RC4_STEP \
- (x = (x + 1) & 0xff, tx = d[x], y = (tx + y) & 0xff, ty = d[y], d[y] = tx, \
- d[x] = ty, (RC4_CHUNK)d[(tx + ty) & 0xff])
-
- if ((((size_t)in & (sizeof(RC4_CHUNK) - 1)) |
- ((size_t)out & (sizeof(RC4_CHUNK) - 1))) == 0) {
- RC4_CHUNK ichunk, otp;
- const union {
- long one;
- char little;
- } is_endian = {1};
-
- /* I reckon we can afford to implement both endian
- * cases and to decide which way to take at run-time
- * because the machine code appears to be very compact
- * and redundant 1-2KB is perfectly tolerable (i.e.
- * in case the compiler fails to eliminate it:-). By
- * suggestion from Terrel Larson <terr@terralogic.net>
- * who also stands for the is_endian union:-)
- *
- * Special notes.
- *
- * - is_endian is declared automatic as doing otherwise
- * (declaring static) prevents gcc from eliminating
- * the redundant code;
- * - compilers (those I've tried) don't seem to have
- * problems eliminating either the operators guarded
- * by "if (sizeof(RC4_CHUNK)==8)" or the condition
- * expressions themselves so I've got 'em to replace
- * corresponding #ifdefs from the previous version;
- * - I chose to let the redundant switch cases when
- * sizeof(RC4_CHUNK)!=8 be (were also #ifdefed
- * before);
- * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in
- * [LB]ESHFT guards against "shift is out of range"
- * warnings when sizeof(RC4_CHUNK)!=8
- *
- * <appro@fy.chalmers.se> */
- if (!is_endian.little) { /* BIG-ENDIAN CASE */
-#define BESHFT(c) \
- (((sizeof(RC4_CHUNK) - (c) - 1) * 8) & (sizeof(RC4_CHUNK) * 8 - 1))
- for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) {
- ichunk = *(RC4_CHUNK *)in;
- otp = RC4_STEP << BESHFT(0);
- otp |= RC4_STEP << BESHFT(1);
- otp |= RC4_STEP << BESHFT(2);
- otp |= RC4_STEP << BESHFT(3);
-#if defined(OPENSSL_64_BIT)
- otp |= RC4_STEP << BESHFT(4);
- otp |= RC4_STEP << BESHFT(5);
- otp |= RC4_STEP << BESHFT(6);
- otp |= RC4_STEP << BESHFT(7);
-#endif
- *(RC4_CHUNK *)out = otp ^ ichunk;
- in += sizeof(RC4_CHUNK);
- out += sizeof(RC4_CHUNK);
- }
- } else { /* LITTLE-ENDIAN CASE */
-#define LESHFT(c) (((c) * 8) & (sizeof(RC4_CHUNK) * 8 - 1))
- for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) {
- ichunk = *(RC4_CHUNK *)in;
- otp = RC4_STEP;
- otp |= RC4_STEP << 8;
- otp |= RC4_STEP << 16;
- otp |= RC4_STEP << 24;
-#if defined(OPENSSL_64_BIT)
- otp |= RC4_STEP << LESHFT(4);
- otp |= RC4_STEP << LESHFT(5);
- otp |= RC4_STEP << LESHFT(6);
- otp |= RC4_STEP << LESHFT(7);
-#endif
- *(RC4_CHUNK *)out = otp ^ ichunk;
- in += sizeof(RC4_CHUNK);
- out += sizeof(RC4_CHUNK);
- }
- }
+ for (size_t i = 0; i < len; i++) {
+ x = (x + 1) & 0xff;
+ uint32_t tx = d[x];
+ y = (tx + y) & 0xff;
+ uint32_t ty = d[y];
+ d[x] = ty;
+ d[y] = tx;
+ out[i] = d[(tx + ty) & 0xff] ^ in[i];
}
-#define LOOP(in, out) \
- x = ((x + 1) & 0xff); \
- tx = d[x]; \
- y = (tx + y) & 0xff; \
- d[x] = ty = d[y]; \
- d[y] = tx; \
- (out) = d[(tx + ty) & 0xff] ^ (in);
-#ifndef RC4_INDEX
-#define RC4_LOOP(a, b, i) LOOP(*((a)++), *((b)++))
-#else
-#define RC4_LOOP(a, b, i) LOOP(a[i], b[i])
-#endif
-
- i = len >> 3;
- if (i) {
- for (;;) {
- RC4_LOOP(in, out, 0);
- RC4_LOOP(in, out, 1);
- RC4_LOOP(in, out, 2);
- RC4_LOOP(in, out, 3);
- RC4_LOOP(in, out, 4);
- RC4_LOOP(in, out, 5);
- RC4_LOOP(in, out, 6);
- RC4_LOOP(in, out, 7);
-#ifdef RC4_INDEX
- in += 8;
- out += 8;
-#endif
- if (--i == 0) {
- break;
- }
- }
- }
- i = len & 0x07;
- if (i) {
- for (;;) {
- RC4_LOOP(in, out, 0);
- if (--i == 0) {
- break;
- }
- RC4_LOOP(in, out, 1);
- if (--i == 0) {
- break;
- }
- RC4_LOOP(in, out, 2);
- if (--i == 0) {
- break;
- }
- RC4_LOOP(in, out, 3);
- if (--i == 0) {
- break;
- }
- RC4_LOOP(in, out, 4);
- if (--i == 0) {
- break;
- }
- RC4_LOOP(in, out, 5);
- if (--i == 0) {
- break;
- }
- RC4_LOOP(in, out, 6);
- if (--i == 0) {
- break;
- }
- }
- }
key->x = x;
key->y = y;
}
void RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key) {
- uint32_t tmp;
- unsigned i, id1, id2;
- uint32_t *d;
-
- d = &rc4key->data[0];
+ uint32_t *d = &rc4key->data[0];
rc4key->x = 0;
rc4key->y = 0;
- id1 = id2 = 0;
-#define SK_LOOP(d, n) \
- { \
- tmp = d[(n)]; \
- id2 = (key[id1] + tmp + id2) & 0xff; \
- if (++id1 == len) \
- id1 = 0; \
- d[(n)] = d[id2]; \
- d[id2] = tmp; \
- }
-
- for (i = 0; i < 256; i++) {
+ for (unsigned i = 0; i < 256; i++) {
d[i] = i;
}
- for (i = 0; i < 256; i += 4) {
- SK_LOOP(d, i + 0);
- SK_LOOP(d, i + 1);
- SK_LOOP(d, i + 2);
- SK_LOOP(d, i + 3);
+
+ unsigned id1 = 0, id2 = 0;
+ for (unsigned i = 0; i < 256; i++) {
+ uint32_t tmp = d[i];
+ id2 = (key[id1] + tmp + id2) & 0xff;
+ if (++id1 == len) {
+ id1 = 0;
+ }
+ d[i] = d[id2];
+ d[id2] = tmp;
}
}
-
-#else
-
-/* In this case several functions are provided by asm code. However, one cannot
- * control asm symbol visibility with command line flags and such so they are
- * always hidden and wrapped by these C functions, which can be so
- * controlled. */
-
-void asm_RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out);
-void RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out) {
- asm_RC4(key, len, in, out);
-}
-
-void asm_RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key);
-void RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key) {
- asm_RC4_set_key(rc4key, len, key);
-}
-
-#endif /* OPENSSL_NO_ASM || (!OPENSSL_X86_64 && !OPENSSL_X86) */
diff --git a/src/crypto/rsa/rsa_test.cc b/src/crypto/rsa/rsa_test.cc
index 62177a4..8c4a787 100644
--- a/src/crypto/rsa/rsa_test.cc
+++ b/src/crypto/rsa/rsa_test.cc
@@ -65,8 +65,6 @@
#include <openssl/err.h>
#include <openssl/nid.h>
-#include "../test/scoped_types.h"
-
// kPlaintext is a sample plaintext.
static const uint8_t kPlaintext[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
@@ -526,7 +524,7 @@
static bool TestRSA(const uint8_t *der, size_t der_len,
const uint8_t *oaep_ciphertext,
size_t oaep_ciphertext_len) {
- ScopedRSA key(RSA_private_key_from_bytes(der, der_len));
+ bssl::UniquePtr<RSA> key(RSA_private_key_from_bytes(der, der_len));
if (!key) {
return false;
}
@@ -612,7 +610,7 @@
static bool TestMultiPrimeKey(int nprimes, const uint8_t *der, size_t der_size,
const uint8_t *enc, size_t enc_size) {
- ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &der, der_size));
+ bssl::UniquePtr<RSA> rsa(d2i_RSAPrivateKey(nullptr, &der, der_size));
if (!rsa) {
fprintf(stderr, "%d-prime key failed to parse.\n", nprimes);
ERR_print_errors_fp(stderr);
@@ -645,8 +643,8 @@
uint8_t encrypted[kBits / 8], decrypted[kBits / 8];
size_t encrypted_len, decrypted_len;
- ScopedRSA rsa(RSA_new());
- ScopedBIGNUM e(BN_new());
+ bssl::UniquePtr<RSA> rsa(RSA_new());
+ bssl::UniquePtr<BIGNUM> e(BN_new());
if (!rsa || !e ||
!BN_set_word(e.get(), RSA_F4) ||
!RSA_generate_multi_prime_key(rsa.get(), kBits, 3, e.get(), nullptr) ||
@@ -666,8 +664,8 @@
}
static bool TestBadKey() {
- ScopedRSA key(RSA_new());
- ScopedBIGNUM e(BN_new());
+ bssl::UniquePtr<RSA> key(RSA_new());
+ bssl::UniquePtr<BIGNUM> e(BN_new());
if (!key || !e || !BN_set_word(e.get(), RSA_F4)) {
return false;
@@ -705,7 +703,7 @@
uint8_t buf[64];
unsigned buf_len = sizeof(buf);
- ScopedRSA key(RSA_new());
+ bssl::UniquePtr<RSA> key(RSA_new());
if (!key ||
!BN_hex2bn(&key->n, kN) ||
!BN_hex2bn(&key->e, kE) ||
@@ -739,7 +737,7 @@
// Keys without the public exponent must continue to work when blinding is
// disabled to support Java's RSAPrivateKeySpec API. See
// https://bugs.chromium.org/p/boringssl/issues/detail?id=12.
- ScopedRSA key2(RSA_new());
+ bssl::UniquePtr<RSA> key2(RSA_new());
if (!key2 ||
!BN_hex2bn(&key2->n, kN) ||
!BN_hex2bn(&key2->d, kD)) {
@@ -772,7 +770,7 @@
}
static bool TestRecoverCRTParams() {
- ScopedBIGNUM e(BN_new());
+ bssl::UniquePtr<BIGNUM> e(BN_new());
if (!e || !BN_set_word(e.get(), RSA_F4)) {
return false;
}
@@ -780,7 +778,7 @@
ERR_clear_error();
for (unsigned i = 0; i < 1; i++) {
- ScopedRSA key1(RSA_new());
+ bssl::UniquePtr<RSA> key1(RSA_new());
if (!key1 ||
!RSA_generate_key_ex(key1.get(), 512, e.get(), nullptr)) {
fprintf(stderr, "RSA_generate_key_ex failed.\n");
@@ -794,7 +792,7 @@
return false;
}
- ScopedRSA key2(RSA_new());
+ bssl::UniquePtr<RSA> key2(RSA_new());
if (!key2) {
return false;
}
@@ -844,7 +842,7 @@
static bool TestASN1() {
// Test that private keys may be decoded.
- ScopedRSA rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1));
+ bssl::UniquePtr<RSA> rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1));
if (!rsa) {
return false;
}
@@ -855,7 +853,7 @@
if (!RSA_private_key_to_bytes(&der, &der_len, rsa.get())) {
return false;
}
- ScopedOpenSSLBytes delete_der(der);
+ bssl::UniquePtr<uint8_t> delete_der(der);
if (der_len != sizeof(kKey1) - 1 || memcmp(der, kKey1, der_len) != 0) {
return false;
}
@@ -878,7 +876,7 @@
if (!RSA_public_key_to_bytes(&der2, &der2_len, rsa.get())) {
return false;
}
- ScopedOpenSSLBytes delete_der2(der2);
+ bssl::UniquePtr<uint8_t> delete_der2(der2);
if (der_len != der2_len || memcmp(der, der2, der_len) != 0) {
return false;
}
@@ -910,7 +908,7 @@
}
static bool TestBadExponent() {
- ScopedRSA rsa(RSA_public_key_from_bytes(kExponent1RSAKey,
+ bssl::UniquePtr<RSA> rsa(RSA_public_key_from_bytes(kExponent1RSAKey,
sizeof(kExponent1RSAKey)));
if (rsa) {
diff --git a/src/crypto/sha/asm/sha1-x86_64.pl b/src/crypto/sha/asm/sha1-x86_64.pl
index cdc7285..ff960bb 100644
--- a/src/crypto/sha/asm/sha1-x86_64.pl
+++ b/src/crypto/sha/asm/sha1-x86_64.pl
@@ -364,9 +364,9 @@
.align 16
.Loop_shaext:
dec $num
- lea 0x40($inp),%rax # next input block
+ lea 0x40($inp),%r8 # next input block
paddd @MSG[0],$E
- cmovne %rax,$inp
+ cmovne %r8,$inp
movdqa $ABCD,$ABCD_SAVE # offload $ABCD
___
for($i=0;$i<20-4;$i+=2) {
diff --git a/src/crypto/test/scoped_types.h b/src/crypto/test/scoped_types.h
deleted file mode 100644
index c124235..0000000
--- a/src/crypto/test/scoped_types.h
+++ /dev/null
@@ -1,133 +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_SCOPED_TYPES_H
-#define OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
-
-#include <stdint.h>
-#include <stdio.h>
-
-#include <memory>
-
-#include <openssl/aead.h>
-#include <openssl/asn1.h>
-#include <openssl/bio.h>
-#include <openssl/bn.h>
-#include <openssl/bytestring.h>
-#include <openssl/cmac.h>
-#include <openssl/curve25519.h>
-#include <openssl/dh.h>
-#include <openssl/ecdsa.h>
-#include <openssl/ec.h>
-#include <openssl/ec_key.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/mem.h>
-#include <openssl/newhope.h>
-#include <openssl/pkcs8.h>
-#include <openssl/rsa.h>
-#include <openssl/stack.h>
-#include <openssl/x509.h>
-
-
-template<typename T, void (*func)(T*)>
-struct OpenSSLDeleter {
- void operator()(T *obj) {
- func(obj);
- }
-};
-
-template<typename StackType, typename T, void (*func)(T*)>
-struct OpenSSLStackDeleter {
- void operator()(StackType *obj) {
- sk_pop_free(reinterpret_cast<_STACK*>(obj),
- reinterpret_cast<void (*)(void *)>(func));
- }
-};
-
-template<typename T>
-struct OpenSSLFree {
- void operator()(T *buf) {
- OPENSSL_free(buf);
- }
-};
-
-struct FileCloser {
- void operator()(FILE *file) {
- fclose(file);
- }
-};
-
-template<typename T, void (*func)(T*)>
-using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>;
-
-template<typename StackType, typename T, void (*func)(T*)>
-using ScopedOpenSSLStack =
- std::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>;
-
-template<typename T, typename CleanupRet, void (*init_func)(T*),
- CleanupRet (*cleanup_func)(T*)>
-class ScopedOpenSSLContext {
- public:
- ScopedOpenSSLContext() {
- init_func(&ctx_);
- }
- ~ScopedOpenSSLContext() {
- cleanup_func(&ctx_);
- }
-
- T *get() { return &ctx_; }
- const T *get() const { return &ctx_; }
-
- void Reset() {
- cleanup_func(&ctx_);
- init_func(&ctx_);
- }
-
- private:
- T ctx_;
-};
-
-using ScopedASN1_TYPE = ScopedOpenSSLType<ASN1_TYPE, ASN1_TYPE_free>;
-using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>;
-using ScopedBIGNUM = ScopedOpenSSLType<BIGNUM, BN_free>;
-using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>;
-using ScopedBN_MONT_CTX = ScopedOpenSSLType<BN_MONT_CTX, BN_MONT_CTX_free>;
-using ScopedCMAC_CTX = ScopedOpenSSLType<CMAC_CTX, CMAC_CTX_free>;
-using ScopedDH = ScopedOpenSSLType<DH, DH_free>;
-using ScopedECDSA_SIG = ScopedOpenSSLType<ECDSA_SIG, ECDSA_SIG_free>;
-using ScopedEC_GROUP = ScopedOpenSSLType<EC_GROUP, EC_GROUP_free>;
-using ScopedEC_KEY = ScopedOpenSSLType<EC_KEY, EC_KEY_free>;
-using ScopedEC_POINT = ScopedOpenSSLType<EC_POINT, EC_POINT_free>;
-using ScopedEVP_PKEY = ScopedOpenSSLType<EVP_PKEY, EVP_PKEY_free>;
-using ScopedEVP_PKEY_CTX = ScopedOpenSSLType<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
-using ScopedNEWHOPE_POLY = ScopedOpenSSLType<NEWHOPE_POLY, NEWHOPE_POLY_free>;
-using ScopedPKCS8_PRIV_KEY_INFO = ScopedOpenSSLType<PKCS8_PRIV_KEY_INFO,
- PKCS8_PRIV_KEY_INFO_free>;
-using ScopedPKCS12 = ScopedOpenSSLType<PKCS12, PKCS12_free>;
-using ScopedSPAKE2_CTX = ScopedOpenSSLType<SPAKE2_CTX, SPAKE2_CTX_free>;
-using ScopedRSA = ScopedOpenSSLType<RSA, RSA_free>;
-using ScopedX509 = ScopedOpenSSLType<X509, X509_free>;
-using ScopedX509_ALGOR = ScopedOpenSSLType<X509_ALGOR, X509_ALGOR_free>;
-using ScopedX509_SIG = ScopedOpenSSLType<X509_SIG, X509_SIG_free>;
-using ScopedX509_STORE_CTX = ScopedOpenSSLType<X509_STORE_CTX, X509_STORE_CTX_free>;
-
-using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
-
-using ScopedOpenSSLBytes = std::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>;
-using ScopedOpenSSLString = std::unique_ptr<char, OpenSSLFree<char>>;
-
-using ScopedFILE = std::unique_ptr<FILE, FileCloser>;
-
-#endif // OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
diff --git a/src/crypto/x509/x509_r2x.c b/src/crypto/x509/x509_r2x.c
index 83951a2..9bdf441 100644
--- a/src/crypto/x509/x509_r2x.c
+++ b/src/crypto/x509/x509_r2x.c
@@ -68,10 +68,12 @@
X509 *ret = NULL;
X509_CINF *xi = NULL;
X509_NAME *xn;
+ EVP_PKEY *pubkey = NULL;
+ int res;
if ((ret = X509_new()) == NULL) {
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto err;
+ return NULL;
}
/* duplicate the request */
@@ -89,9 +91,9 @@
}
xn = X509_REQ_get_subject_name(r);
- if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0)
+ if (X509_set_subject_name(ret, xn) == 0)
goto err;
- if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0)
+ if (X509_set_issuer_name(ret, xn) == 0)
goto err;
if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
@@ -100,9 +102,11 @@
NULL)
goto err;
- X509_set_pubkey(ret, X509_REQ_get_pubkey(r));
+ pubkey = X509_REQ_get_pubkey(r);
+ res = X509_set_pubkey(ret, pubkey);
+ EVP_PKEY_free(pubkey);
- if (!X509_sign(ret, pkey, EVP_md5()))
+ if (!res || !X509_sign(ret, pkey, EVP_md5()))
goto err;
if (0) {
err:
diff --git a/src/crypto/x509/x509_test.cc b/src/crypto/x509/x509_test.cc
index d1eed2a..a62088d 100644
--- a/src/crypto/x509/x509_test.cc
+++ b/src/crypto/x509/x509_test.cc
@@ -17,14 +17,12 @@
#include <assert.h>
#include <string.h>
-#include <openssl/c++/digest.h>
#include <openssl/crypto.h>
+#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
-#include "../test/scoped_types.h"
-
namespace bssl {
static const char kCrossSigningRootPEM[] =
@@ -226,23 +224,25 @@
// CertFromPEM parses the given, NUL-terminated pem block and returns an
// |X509*|.
-static ScopedX509 CertFromPEM(const char *pem) {
- ScopedBIO bio(BIO_new_mem_buf(pem, strlen(pem)));
- return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {
+ bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
+ return bssl::UniquePtr<X509>(
+ PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
}
// PrivateKeyFromPEM parses the given, NUL-terminated pem block and returns an
// |EVP_PKEY*|.
-static ScopedEVP_PKEY PrivateKeyFromPEM(const char *pem) {
- ScopedBIO bio(BIO_new_mem_buf(const_cast<char *>(pem), strlen(pem)));
- return ScopedEVP_PKEY(
+static bssl::UniquePtr<EVP_PKEY> PrivateKeyFromPEM(const char *pem) {
+ bssl::UniquePtr<BIO> bio(
+ BIO_new_mem_buf(const_cast<char *>(pem), strlen(pem)));
+ return bssl::UniquePtr<EVP_PKEY>(
PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
}
// CertsToStack converts a vector of |X509*| to an OpenSSL STACK_OF(X509*),
// bumping the reference counts for each certificate in question.
static STACK_OF(X509)* CertsToStack(const std::vector<X509*> &certs) {
- ScopedX509Stack stack(sk_X509_new_null());
+ bssl::UniquePtr<STACK_OF(X509)> stack(sk_X509_new_null());
if (!stack) {
return nullptr;
}
@@ -259,14 +259,16 @@
static bool Verify(X509 *leaf, const std::vector<X509 *> &roots,
const std::vector<X509 *> &intermediates,
unsigned long flags = 0) {
- ScopedX509Stack roots_stack(CertsToStack(roots));
- ScopedX509Stack intermediates_stack(CertsToStack(intermediates));
+ bssl::UniquePtr<STACK_OF(X509)> roots_stack(CertsToStack(roots));
+ bssl::UniquePtr<STACK_OF(X509)> intermediates_stack(
+ CertsToStack(intermediates));
+
if (!roots_stack ||
!intermediates_stack) {
return false;
}
- ScopedX509_STORE_CTX ctx(X509_STORE_CTX_new());
+ bssl::UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
if (!ctx) {
return false;
}
@@ -293,14 +295,15 @@
}
static bool TestVerify() {
- ScopedX509 cross_signing_root(CertFromPEM(kCrossSigningRootPEM));
- ScopedX509 root(CertFromPEM(kRootCAPEM));
- ScopedX509 root_cross_signed(CertFromPEM(kRootCrossSignedPEM));
- ScopedX509 intermediate(CertFromPEM(kIntermediatePEM));
- ScopedX509 intermediate_self_signed(CertFromPEM(kIntermediateSelfSignedPEM));
- ScopedX509 leaf(CertFromPEM(kLeafPEM));
- ScopedX509 leaf_no_key_usage(CertFromPEM(kLeafNoKeyUsagePEM));
- ScopedX509 forgery(CertFromPEM(kForgeryPEM));
+ bssl::UniquePtr<X509> cross_signing_root(CertFromPEM(kCrossSigningRootPEM));
+ bssl::UniquePtr<X509> root(CertFromPEM(kRootCAPEM));
+ bssl::UniquePtr<X509> root_cross_signed(CertFromPEM(kRootCrossSignedPEM));
+ bssl::UniquePtr<X509> intermediate(CertFromPEM(kIntermediatePEM));
+ bssl::UniquePtr<X509> intermediate_self_signed(
+ CertFromPEM(kIntermediateSelfSignedPEM));
+ bssl::UniquePtr<X509> leaf(CertFromPEM(kLeafPEM));
+ bssl::UniquePtr<X509> leaf_no_key_usage(CertFromPEM(kLeafNoKeyUsagePEM));
+ bssl::UniquePtr<X509> forgery(CertFromPEM(kForgeryPEM));
if (!cross_signing_root ||
!root ||
@@ -380,12 +383,12 @@
}
static bool TestPSS() {
- ScopedX509 cert(CertFromPEM(kExamplePSSCert));
+ bssl::UniquePtr<X509> cert(CertFromPEM(kExamplePSSCert));
if (!cert) {
return false;
}
- ScopedEVP_PKEY pkey(X509_get_pubkey(cert.get()));
+ bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert.get()));
if (!pkey) {
return false;
}
@@ -398,12 +401,12 @@
}
static bool TestBadPSSParameters() {
- ScopedX509 cert(CertFromPEM(kBadPSSCertPEM));
+ bssl::UniquePtr<X509> cert(CertFromPEM(kBadPSSCertPEM));
if (!cert) {
return false;
}
- ScopedEVP_PKEY pkey(X509_get_pubkey(cert.get()));
+ bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert.get()));
if (!pkey) {
return false;
}
@@ -418,7 +421,7 @@
static bool SignatureRoundTrips(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
// Make a certificate like signed with |md_ctx|'s settings.'
- ScopedX509 cert(CertFromPEM(kLeafPEM));
+ bssl::UniquePtr<X509> cert(CertFromPEM(kLeafPEM));
if (!cert || !X509_sign_ctx(cert.get(), md_ctx)) {
return false;
}
@@ -429,7 +432,7 @@
}
static bool TestSignCtx() {
- ScopedEVP_PKEY pkey(PrivateKeyFromPEM(kRSAKey));
+ bssl::UniquePtr<EVP_PKEY> pkey(PrivateKeyFromPEM(kRSAKey));
if (!pkey) {
return false;
}
diff --git a/src/include/openssl/aead.h b/src/include/openssl/aead.h
index 7895825..0cad405 100644
--- a/src/include/openssl/aead.h
+++ b/src/include/openssl/aead.h
@@ -82,10 +82,8 @@
* permits implicit context to be authenticated but may be empty if not needed.
*
* The "seal" and "open" operations may work in-place if the |out| and |in|
- * arguments are equal. They may also be used to shift the data left inside the
- * same buffer if |out| is less than |in|. However, |out| may not point inside
- * the input data otherwise the input may be overwritten before it has been
- * read. This situation will cause an error.
+ * arguments are equal. Otherwise, if |out| and |in| alias, input data may be
+ * overwritten before it is read. This situation will cause an error.
*
* The "seal" and "open" operations return one on success and zero on error. */
@@ -333,6 +331,21 @@
#if defined(__cplusplus)
} /* extern C */
+
+#if !defined(BORINGSSL_NO_CXX)
+extern "C++" {
+
+namespace bssl {
+
+using ScopedEVP_AEAD_CTX =
+ internal::StackAllocated<EVP_AEAD_CTX, void, EVP_AEAD_CTX_zero,
+ EVP_AEAD_CTX_cleanup>;
+
+} // namespace bssl
+
+} // extern C++
+#endif
+
#endif
#endif /* OPENSSL_HEADER_AEAD_H */
diff --git a/src/include/openssl/asn1.h b/src/include/openssl/asn1.h
index 42c9535..391be81 100644
--- a/src/include/openssl/asn1.h
+++ b/src/include/openssl/asn1.h
@@ -475,7 +475,7 @@
DECLARE_ASN1_SET_OF(ASN1_INTEGER)
-typedef struct asn1_type_st
+struct asn1_type_st
{
int type;
union {
@@ -503,7 +503,7 @@
ASN1_STRING * sequence;
ASN1_VALUE * asn1_value;
} value;
- } ASN1_TYPE;
+ };
DECLARE_ASN1_SET_OF(ASN1_TYPE)
@@ -574,9 +574,6 @@
(const ASN1_STRING *)a,(const ASN1_STRING *)b)
#define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
#define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b)
-#define M_i2d_ASN1_OCTET_STRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
- V_ASN1_UNIVERSAL)
#define B_ASN1_TIME \
B_ASN1_UTCTIME | \
@@ -609,59 +606,26 @@
#define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING)
#define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
- pp,a->type,V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_PRINTABLE(a,pp,l) \
- d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
- B_ASN1_PRINTABLE)
#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
#define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
- pp,a->type,V_ASN1_UNIVERSAL)
-#define M_d2i_DIRECTORYSTRING(a,pp,l) \
- d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
- B_ASN1_DIRECTORYSTRING)
#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
- pp,a->type,V_ASN1_UNIVERSAL)
-#define M_d2i_DISPLAYTEXT(a,pp,l) \
- d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
- B_ASN1_DISPLAYTEXT)
#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
#define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
- (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
#define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\
ASN1_STRING_type_new(V_ASN1_T61STRING)
#define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_T61STRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_T61STRING(a,pp,l) \
- (ASN1_T61STRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
#define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\
ASN1_STRING_type_new(V_ASN1_IA5STRING)
#define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
#define M_ASN1_IA5STRING_dup(a) \
(ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
-#define M_i2d_ASN1_IA5STRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_IA5STRING(a,pp,l) \
- (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
- B_ASN1_IA5STRING)
#define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\
ASN1_STRING_type_new(V_ASN1_UTCTIME)
@@ -684,56 +648,22 @@
#define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\
ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
#define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_GENERALSTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
- (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
#define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\
ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
#define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
- (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
#define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\
ASN1_STRING_type_new(V_ASN1_BMPSTRING)
#define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_BMPSTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_BMPSTRING(a,pp,l) \
- (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
#define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\
ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
#define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_VISIBLESTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
- (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
#define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\
ASN1_STRING_type_new(V_ASN1_UTF8STRING)
#define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_UTF8STRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_UTF8STRING(a,pp,l) \
- (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
-
- /* for the is_set parameter to i2d_ASN1_SET */
-#define IS_SEQUENCE 0
-#define IS_SET 1
DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
@@ -842,19 +772,9 @@
OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
-OPENSSL_EXPORT int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, int ex_class, int is_set);
-OPENSSL_EXPORT STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
- const unsigned char **pp,
- long length, d2i_of_void *d2i,
- void (*free_func)(OPENSSL_BLOCK), int ex_tag,
- int ex_class);
-
OPENSSL_EXPORT int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
-OPENSSL_EXPORT int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
OPENSSL_EXPORT int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
-OPENSSL_EXPORT int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
OPENSSL_EXPORT int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
-OPENSSL_EXPORT int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
OPENSSL_EXPORT int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
OPENSSL_EXPORT int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
@@ -875,11 +795,7 @@
/* given a string, return the correct type, max is the maximum length */
OPENSSL_EXPORT int ASN1_PRINTABLE_type(const unsigned char *s, int max);
-OPENSSL_EXPORT int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
-OPENSSL_EXPORT ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, long length, int Ptag, int Pclass);
OPENSSL_EXPORT unsigned long ASN1_tag2bit(int tag);
-/* type is one or more of the B_ASN1_ values. */
-OPENSSL_EXPORT ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp, long length,int type);
/* PARSING */
OPENSSL_EXPORT int asn1_Finish(ASN1_CTX *c);
@@ -977,16 +893,7 @@
int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
-OPENSSL_EXPORT STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
-OPENSSL_EXPORT unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, unsigned char **buf, int *len );
-OPENSSL_EXPORT void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
OPENSSL_EXPORT void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
-OPENSSL_EXPORT ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_OCTET_STRING **oct);
-
-#define ASN1_pack_string_of(type,obj,i2d,oct) \
- (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
- CHECKED_I2D_OF(type, i2d), \
- oct))
OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
@@ -1016,6 +923,19 @@
#ifdef __cplusplus
}
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(ASN1_OBJECT, ASN1_OBJECT_free)
+BORINGSSL_MAKE_DELETER(ASN1_STRING, ASN1_STRING_free)
+BORINGSSL_MAKE_DELETER(ASN1_TYPE, ASN1_TYPE_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define ASN1_R_ASN1_LENGTH_MISMATCH 100
diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h
index 441aa29..fab293e 100644
--- a/src/include/openssl/base.h
+++ b/src/include/openssl/base.h
@@ -195,6 +195,7 @@
typedef struct asn1_string_st ASN1_UTCTIME;
typedef struct asn1_string_st ASN1_UTF8STRING;
typedef struct asn1_string_st ASN1_VISIBLESTRING;
+typedef struct asn1_type_st ASN1_TYPE;
typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
typedef struct BASIC_CONSTRAINTS_st BASIC_CONSTRAINTS;
@@ -286,6 +287,7 @@
typedef struct x509_cert_pair_st X509_CERT_PAIR;
typedef struct x509_cinf_st X509_CINF;
typedef struct x509_crl_method_st X509_CRL_METHOD;
+typedef struct x509_lookup_st X509_LOOKUP;
typedef struct x509_revoked_st X509_REVOKED;
typedef struct x509_st X509;
typedef struct x509_store_ctx_st X509_STORE_CTX;
@@ -297,6 +299,113 @@
#if defined(__cplusplus)
} /* extern C */
+
+// MSVC doesn't set __cplusplus to 201103 to indicate C++11 support (see
+// https://connect.microsoft.com/VisualStudio/feedback/details/763051/a-value-of-predefined-macro-cplusplus-is-still-199711l)
+// so MSVC is just assumed to support C++11.
+#if !defined(BORINGSSL_NO_CXX) && __cplusplus < 201103L && !defined(_MSC_VER)
+#define BORINGSSL_NO_CXX
+#endif
+
+#if !defined(BORINGSSL_NO_CXX)
+extern "C++" {
+
+#include <memory>
+
+// STLPort, used by some Android consumers, not have std::unique_ptr.
+#if defined(_STLPORT_VERSION)
+#define BORINGSSL_NO_CXX
+#endif
+
+} // extern C++
+#endif // !BORINGSSL_NO_CXX
+
+#if defined(BORINGSSL_NO_CXX)
+
+#define BORINGSSL_MAKE_DELETER(type, deleter)
+#define BORINGSSL_MAKE_STACK_DELETER(type, deleter)
+
+#else
+
+extern "C++" {
+
+#include <memory>
+
+namespace bssl {
+
+namespace internal {
+
+template <typename T>
+struct DeleterImpl {};
+
+template <typename T>
+struct Deleter {
+ void operator()(T *ptr) {
+ // Rather than specialize Deleter for each type, we specialize
+ // DeleterImpl. This allows bssl::UniquePtr<T> to be used while only
+ // including base.h as long as the destructor is not emitted. This matches
+ // std::unique_ptr's behavior on forward-declared types.
+ //
+ // DeleterImpl itself is specialized in the corresponding module's header
+ // and must be included to release an object. If not included, the compiler
+ // will error that DeleterImpl<T> does not have a method Free.
+ DeleterImpl<T>::Free(ptr);
+ }
+};
+
+template <typename T, typename CleanupRet, void (*init)(T *),
+ CleanupRet (*cleanup)(T *)>
+class StackAllocated {
+ public:
+ StackAllocated() { init(&ctx_); }
+ ~StackAllocated() { cleanup(&ctx_); }
+
+ T *get() { return &ctx_; }
+ const T *get() const { return &ctx_; }
+
+ void Reset() {
+ cleanup(&ctx_);
+ init(&ctx_);
+ }
+
+ private:
+ T ctx_;
+};
+
+} // namespace internal
+
+#define BORINGSSL_MAKE_DELETER(type, deleter) \
+ namespace internal { \
+ template <> \
+ struct DeleterImpl<type> { \
+ static void Free(type *ptr) { deleter(ptr); } \
+ }; \
+ }
+
+// This makes a unique_ptr to STACK_OF(type) that owns all elements on the
+// stack, i.e. it uses sk_pop_free() to clean up.
+#define BORINGSSL_MAKE_STACK_DELETER(type, deleter) \
+ namespace internal { \
+ template <> \
+ struct DeleterImpl<STACK_OF(type)> { \
+ static void Free(STACK_OF(type) *ptr) { \
+ sk_##type##_pop_free(ptr, deleter); \
+ } \
+ }; \
+ }
+
+// Holds ownership of heap-allocated BoringSSL structures. Sample usage:
+// bssl::UniquePtr<BIO> rsa(RSA_new());
+// bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
+template <typename T>
+using UniquePtr = std::unique_ptr<T, internal::Deleter<T>>;
+
+} // namespace bssl
+
+} /* extern C++ */
+
+#endif // !BORINGSSL_NO_CXX
+
#endif
#endif /* OPENSSL_HEADER_BASE_H */
diff --git a/src/include/openssl/bio.h b/src/include/openssl/bio.h
index 9622f96..41c30ca 100644
--- a/src/include/openssl/bio.h
+++ b/src/include/openssl/bio.h
@@ -895,6 +895,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(BIO, BIO_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define BIO_R_BAD_FOPEN_MODE 100
diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h
index ff9d680..554a81b 100644
--- a/src/include/openssl/bn.h
+++ b/src/include/openssl/bn.h
@@ -327,7 +327,7 @@
OPENSSL_EXPORT void bn_correct_top(BIGNUM *bn);
/* bn_wexpand ensures that |bn| has at least |words| works of space without
- * altering its value. It returns one on success or zero on allocation
+ * altering its value. It returns |bn| on success or NULL on allocation
* failure. */
OPENSSL_EXPORT BIGNUM *bn_wexpand(BIGNUM *bn, size_t words);
@@ -577,15 +577,27 @@
/* Random and prime number generation. */
-/* BN_rand sets |rnd| to a random number of length |bits|. If |top| is zero, the
- * most-significant bit, if any, will be set. If |top| is one, the two most
- * significant bits, if any, will be set.
+/* The following are values for the |top| parameter of |BN_rand|. */
+#define BN_RAND_TOP_ANY -1
+#define BN_RAND_TOP_ONE 0
+#define BN_RAND_TOP_TWO 1
+
+/* The following are values for the |bottom| parameter of |BN_rand|. */
+#define BN_RAND_BOTTOM_ANY 0
+#define BN_RAND_BOTTOM_ODD 1
+
+/* BN_rand sets |rnd| to a random number of length |bits|. It returns one on
+ * success and zero otherwise.
*
- * If |top| is -1 then no extra action will be taken and |BN_num_bits(rnd)| may
- * not equal |bits| if the most significant bits randomly ended up as zeros.
+ * |top| must be one of the |BN_RAND_TOP_*| values. If |BN_RAND_TOP_ONE|, the
+ * most-significant bit, if any, will be set. If |BN_RAND_TOP_TWO|, the two
+ * most significant bits, if any, will be set. If |BN_RAND_TOP_ANY|, no extra
+ * action will be taken and |BN_num_bits(rnd)| may not equal |bits| if the most
+ * significant bits randomly ended up as zeros.
*
- * If |bottom| is non-zero, the least-significant bit, if any, will be set. The
- * function returns one on success or zero otherwise. */
+ * |bottom| must be one of the |BN_RAND_BOTTOM_*| values. If
+ * |BN_RAND_BOTTOM_ODD|, the least-significant bit, if any, will be set. If
+ * |BN_RAND_BOTTOM_ANY|, no extra action will be taken. */
OPENSSL_EXPORT int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
/* BN_pseudo_rand is an alias for |BN_rand|. */
@@ -901,6 +913,19 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(BIGNUM, BN_free)
+BORINGSSL_MAKE_DELETER(BN_CTX, BN_CTX_free)
+BORINGSSL_MAKE_DELETER(BN_MONT_CTX, BN_MONT_CTX_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define BN_R_ARG2_LT_ARG3 100
diff --git a/src/include/openssl/buf.h b/src/include/openssl/buf.h
index 8ae856b..30f3af7 100644
--- a/src/include/openssl/buf.h
+++ b/src/include/openssl/buf.h
@@ -117,6 +117,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(BUF_MEM, BUF_MEM_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#endif /* OPENSSL_HEADER_BUFFER_H */
diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h
index 68138bc..2985268 100644
--- a/src/include/openssl/bytestring.h
+++ b/src/include/openssl/bytestring.h
@@ -125,6 +125,7 @@
/* Parsing ASN.1 */
+/* The following values are tag numbers for UNIVERSAL elements. */
#define CBS_ASN1_BOOLEAN 0x1
#define CBS_ASN1_INTEGER 0x2
#define CBS_ASN1_BITSTRING 0x3
@@ -148,8 +149,27 @@
#define CBS_ASN1_UNIVERSALSTRING 0x1c
#define CBS_ASN1_BMPSTRING 0x1e
+/* CBS_ASN1_CONSTRUCTED may be ORed into a tag to toggle the constructed
+ * bit. |CBS| and |CBB| APIs consider the constructed bit to be part of the
+ * tag. */
#define CBS_ASN1_CONSTRUCTED 0x20
+
+/* The following values specify the constructed bit or tag class and may be ORed
+ * into a tag number to produce the final tag. If none is used, the tag will be
+ * UNIVERSAL.
+ *
+ * Note that although they currently match the DER serialization, consumers must
+ * use these bits rather than make assumptions about the representation. This is
+ * to allow for tag numbers beyond 31 in the future. */
+#define CBS_ASN1_APPLICATION 0x40
#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
+#define CBS_ASN1_PRIVATE 0xc0
+
+/* CBS_ASN1_CLASS_MASK may be ANDed with a tag to query its class. */
+#define CBS_ASN1_CLASS_MASK 0xc0
+
+/* CBS_ASN1_TAG_NUMBER_MASK may be ANDed with a tag to query its number. */
+#define CBS_ASN1_TAG_NUMBER_MASK 0x1f
/* CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not
* including tag and length bytes) and advances |cbs| over it. The ASN.1
@@ -345,7 +365,7 @@
* the object. Passing in |tag| number 31 will return in an error since only
* single octet identifiers are supported. It returns one on success or zero
* on error. */
-OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
+OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag);
/* CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on
* success and zero otherwise. */
@@ -396,6 +416,20 @@
#if defined(__cplusplus)
} /* extern C */
+
+
+#if !defined(BORINGSSL_NO_CXX)
+extern "C++" {
+
+namespace bssl {
+
+using ScopedCBB = internal::StackAllocated<CBB, void, CBB_zero, CBB_cleanup>;
+
+} // namespace bssl
+
+} // extern C++
+#endif
+
#endif
#endif /* OPENSSL_HEADER_BYTESTRING_H */
diff --git a/src/include/openssl/c++/aead.h b/src/include/openssl/c++/aead.h
deleted file mode 100644
index 1530923..0000000
--- a/src/include/openssl/c++/aead.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2016, 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_CXX_AEAD_H
-#define OPENSSL_HEADER_CXX_AEAD_H
-
-#include <openssl/aead.h>
-#include <openssl/c++/scoped_helpers.h>
-
-namespace bssl {
-
-using ScopedEVP_AEAD_CTX =
- ScopedContext<EVP_AEAD_CTX, void, EVP_AEAD_CTX_zero, EVP_AEAD_CTX_cleanup>;
-
-} // namespace bssl
-
-#endif /* OPENSSL_HEADER_CXX_AEAD_H */
diff --git a/src/include/openssl/c++/bytestring.h b/src/include/openssl/c++/bytestring.h
deleted file mode 100644
index 87325a9..0000000
--- a/src/include/openssl/c++/bytestring.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (c) 2016, 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_CXX_BYTESTRING_H
-#define OPENSSL_HEADER_CXX_BYTESTRING_H
-
-#include <openssl/bytestring.h>
-#include <openssl/c++/scoped_helpers.h>
-
-namespace bssl {
-
-using ScopedCBB = ScopedContext<CBB, void, CBB_zero, CBB_cleanup>;
-
-} // namespace bssl
-
-#endif /* OPENSSL_HEADER_CXX_BYTESTRING_H */
diff --git a/src/include/openssl/c++/cipher.h b/src/include/openssl/c++/cipher.h
deleted file mode 100644
index 997a606..0000000
--- a/src/include/openssl/c++/cipher.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2016, 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_CXX_CIPHER_H
-#define OPENSSL_HEADER_CXX_CIPHER_H
-
-#include <openssl/cipher.h>
-#include <openssl/c++/scoped_helpers.h>
-
-namespace bssl {
-
-using ScopedEVP_CIPHER_CTX =
- ScopedContext<EVP_CIPHER_CTX, int, EVP_CIPHER_CTX_init,
- EVP_CIPHER_CTX_cleanup>;
-
-} // namespace bssl
-
-#endif /* OPENSSL_HEADER_CXX_CIPHER_H */
diff --git a/src/include/openssl/c++/digest.h b/src/include/openssl/c++/digest.h
deleted file mode 100644
index f557921..0000000
--- a/src/include/openssl/c++/digest.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2016, 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_CXX_DIGEST_H
-#define OPENSSL_HEADER_CXX_DIGEST_H
-
-#include <openssl/c++/scoped_helpers.h>
-#include <openssl/evp.h>
-
-namespace bssl {
-
-using ScopedEVP_MD_CTX =
- ScopedContext<EVP_MD_CTX, int, EVP_MD_CTX_init, EVP_MD_CTX_cleanup>;
-
-} // namespace bssl
-
-#endif /* OPENSSL_HEADER_CXX_DIGEST_H */
diff --git a/src/include/openssl/c++/hmac.h b/src/include/openssl/c++/hmac.h
deleted file mode 100644
index 0e8d2e1..0000000
--- a/src/include/openssl/c++/hmac.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2016, 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_CXX_HMAC_H
-#define OPENSSL_HEADER_CXX_HMAC_H
-
-#include <openssl/c++/scoped_helpers.h>
-#include <openssl/hmac.h>
-
-namespace bssl {
-
-using ScopedHMAC_CTX =
- ScopedContext<HMAC_CTX, void, HMAC_CTX_init, HMAC_CTX_cleanup>;
-
-} // namespace bssl
-
-#endif /* OPENSSL_HEADER_CXX_HMAC_H */
diff --git a/src/include/openssl/c++/scoped_helpers.h b/src/include/openssl/c++/scoped_helpers.h
deleted file mode 100644
index daaf50e..0000000
--- a/src/include/openssl/c++/scoped_helpers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) 2016, 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_CXX_SCOPED_HELPERS_H
-#define OPENSSL_HEADER_CXX_SCOPED_HELPERS_H
-
-namespace bssl {
-
-template<typename T, typename CleanupRet, void (*init_func)(T*),
- CleanupRet (*cleanup_func)(T*)>
-class ScopedContext {
- public:
- ScopedContext() {
- init_func(&ctx_);
- }
- ~ScopedContext() {
- cleanup_func(&ctx_);
- }
-
- T *get() { return &ctx_; }
- const T *get() const { return &ctx_; }
-
- void Reset() {
- cleanup_func(&ctx_);
- init_func(&ctx_);
- }
-
- private:
- T ctx_;
-};
-
-} // namespace bssl
-
-#endif /* OPENSSL_HEADER_CXX_SCOPED_HELPERS_H */
diff --git a/src/include/openssl/cipher.h b/src/include/openssl/cipher.h
index 5312308..a8585d7 100644
--- a/src/include/openssl/cipher.h
+++ b/src/include/openssl/cipher.h
@@ -540,6 +540,23 @@
#if defined(__cplusplus)
} /* extern C */
+
+#if !defined(BORINGSSL_NO_CXX)
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free)
+
+using ScopedEVP_CIPHER_CTX =
+ internal::StackAllocated<EVP_CIPHER_CTX, int, EVP_CIPHER_CTX_init,
+ EVP_CIPHER_CTX_cleanup>;
+
+} // namespace bssl
+
+} // extern C++
+#endif
+
#endif
#define CIPHER_R_AES_KEY_SETUP_FAILED 100
diff --git a/src/include/openssl/cmac.h b/src/include/openssl/cmac.h
index 0bb44b9..0f05bc9 100644
--- a/src/include/openssl/cmac.h
+++ b/src/include/openssl/cmac.h
@@ -71,6 +71,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(CMAC_CTX, CMAC_CTX_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#endif /* OPENSSL_HEADER_CMAC_H */
diff --git a/src/include/openssl/conf.h b/src/include/openssl/conf.h
index 2aa3b79..6e6364f 100644
--- a/src/include/openssl/conf.h
+++ b/src/include/openssl/conf.h
@@ -158,6 +158,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(CONF, NCONF_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define CONF_R_LIST_CANNOT_BE_NULL 100
diff --git a/src/include/openssl/curve25519.h b/src/include/openssl/curve25519.h
index a9441cd..e9ba04d 100644
--- a/src/include/openssl/curve25519.h
+++ b/src/include/openssl/curve25519.h
@@ -167,6 +167,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(SPAKE2_CTX, SPAKE2_CTX_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#endif /* OPENSSL_HEADER_CURVE25519_H */
diff --git a/src/include/openssl/dh.h b/src/include/openssl/dh.h
index 4025656..ed2396d 100644
--- a/src/include/openssl/dh.h
+++ b/src/include/openssl/dh.h
@@ -274,6 +274,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(DH, DH_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define DH_R_BAD_GENERATOR 100
diff --git a/src/include/openssl/digest.h b/src/include/openssl/digest.h
index 6c5d6cf..ec62993 100644
--- a/src/include/openssl/digest.h
+++ b/src/include/openssl/digest.h
@@ -261,6 +261,23 @@
#if defined(__cplusplus)
} /* extern C */
+
+#if !defined(BORINGSSL_NO_CXX)
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(EVP_MD_CTX, EVP_MD_CTX_destroy)
+
+using ScopedEVP_MD_CTX =
+ internal::StackAllocated<EVP_MD_CTX, int, EVP_MD_CTX_init,
+ EVP_MD_CTX_cleanup>;
+
+} // namespace bssl
+
+} // extern C++
+#endif
+
#endif
#define DIGEST_R_INPUT_NOT_INITIALIZED 100
diff --git a/src/include/openssl/dsa.h b/src/include/openssl/dsa.h
index 1e1ff65..d6c3204 100644
--- a/src/include/openssl/dsa.h
+++ b/src/include/openssl/dsa.h
@@ -411,6 +411,18 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(DSA, DSA_free)
+BORINGSSL_MAKE_DELETER(DSA_SIG, DSA_SIG_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define DSA_R_BAD_Q_VALUE 100
diff --git a/src/include/openssl/ec.h b/src/include/openssl/ec.h
index 71c59d1..c2ef066 100644
--- a/src/include/openssl/ec.h
+++ b/src/include/openssl/ec.h
@@ -356,6 +356,18 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(EC_POINT, EC_POINT_free)
+BORINGSSL_MAKE_DELETER(EC_GROUP, EC_GROUP_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define EC_R_BUFFER_TOO_SMALL 100
diff --git a/src/include/openssl/ec_key.h b/src/include/openssl/ec_key.h
index 0658deb..1dbae62 100644
--- a/src/include/openssl/ec_key.h
+++ b/src/include/openssl/ec_key.h
@@ -321,6 +321,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(EC_KEY, EC_KEY_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#endif /* OPENSSL_HEADER_EC_KEY_H */
diff --git a/src/include/openssl/ecdsa.h b/src/include/openssl/ecdsa.h
index a060eab..f6e9982 100644
--- a/src/include/openssl/ecdsa.h
+++ b/src/include/openssl/ecdsa.h
@@ -194,6 +194,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(ECDSA_SIG, ECDSA_SIG_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define ECDSA_R_BAD_SIGNATURE 100
diff --git a/src/include/openssl/engine.h b/src/include/openssl/engine.h
index 128a2ae..b029ef9 100644
--- a/src/include/openssl/engine.h
+++ b/src/include/openssl/engine.h
@@ -91,6 +91,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(ENGINE, ENGINE_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define ENGINE_R_OPERATION_NOT_SUPPORTED 100
diff --git a/src/include/openssl/evp.h b/src/include/openssl/evp.h
index d5d528e..58b388a 100644
--- a/src/include/openssl/evp.h
+++ b/src/include/openssl/evp.h
@@ -750,6 +750,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(EVP_PKEY, EVP_PKEY_free)
+BORINGSSL_MAKE_DELETER(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define EVP_R_BUFFER_TOO_SMALL 100
diff --git a/src/include/openssl/hmac.h b/src/include/openssl/hmac.h
index 35c7f58..e4cc04e 100644
--- a/src/include/openssl/hmac.h
+++ b/src/include/openssl/hmac.h
@@ -155,6 +155,20 @@
#if defined(__cplusplus)
} /* extern C */
+
+#if !defined(BORINGSSL_NO_CXX)
+extern "C++" {
+
+namespace bssl {
+
+using ScopedHMAC_CTX =
+ internal::StackAllocated<HMAC_CTX, void, HMAC_CTX_init, HMAC_CTX_cleanup>;
+
+} // namespace bssl
+
+} // extern C++
+#endif
+
#endif
#endif /* OPENSSL_HEADER_HMAC_H */
diff --git a/src/include/openssl/mem.h b/src/include/openssl/mem.h
index 31756f0..5d96a2d 100644
--- a/src/include/openssl/mem.h
+++ b/src/include/openssl/mem.h
@@ -133,6 +133,18 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(char, OPENSSL_free)
+BORINGSSL_MAKE_DELETER(uint8_t, OPENSSL_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#endif /* OPENSSL_HEADER_MEM_H */
diff --git a/src/include/openssl/newhope.h b/src/include/openssl/newhope.h
index 487e03f..47b9913 100644
--- a/src/include/openssl/newhope.h
+++ b/src/include/openssl/newhope.h
@@ -142,6 +142,17 @@
#if defined(__cplusplus)
} /* extern "C" */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(NEWHOPE_POLY, NEWHOPE_POLY_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#endif /* OPENSSL_HEADER_NEWHOPE_H */
diff --git a/src/include/openssl/pkcs8.h b/src/include/openssl/pkcs8.h
index 28cf6ac..e04a4f3 100644
--- a/src/include/openssl/pkcs8.h
+++ b/src/include/openssl/pkcs8.h
@@ -187,6 +187,18 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(PKCS12, PKCS12_free)
+BORINGSSL_MAKE_DELETER(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define PKCS8_R_BAD_PKCS12_DATA 100
diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h
index b4c7653..78d5b32 100644
--- a/src/include/openssl/rsa.h
+++ b/src/include/openssl/rsa.h
@@ -636,6 +636,17 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(RSA, RSA_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define RSA_R_BAD_ENCODING 100
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index fe6bac2..ce2ba41 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -921,13 +921,21 @@
* before TLS 1.2. */
#define SSL_SIGN_RSA_PKCS1_MD5_SHA1 0xff01
+/* SSL_CTX_set_signing_algorithm_prefs configures |ctx| to use |prefs| as the
+ * preference list when signing with |ctx|'s private key. It returns one on
+ * success and zero on error. |prefs| should not include the internal-only value
+ * |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. */
+OPENSSL_EXPORT int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx,
+ const uint16_t *prefs,
+ size_t num_prefs);
+
/* SSL_set_signing_algorithm_prefs configures |ssl| to use |prefs| as the
* preference list when signing with |ssl|'s private key. It returns one on
* success and zero on error. |prefs| should not include the internal-only value
* |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. */
OPENSSL_EXPORT int SSL_set_signing_algorithm_prefs(SSL *ssl,
const uint16_t *prefs,
- size_t prefs_len);
+ size_t num_prefs);
/* Certificate and private key convenience functions. */
@@ -1645,7 +1653,7 @@
/* SSL_SESS_CACHE_SERVER enables session caching for a server. */
#define SSL_SESS_CACHE_SERVER 0x0002
-/* SSL_SESS_CACHE_SERVER enables session caching for both client and server. */
+/* SSL_SESS_CACHE_BOTH enables session caching for both client and server. */
#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER)
/* SSL_SESS_CACHE_NO_AUTO_CLEAR disables automatically calling
@@ -2163,9 +2171,6 @@
* either |X509_V_OK| or a |X509_V_ERR_*| value. */
OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl);
-/* SSL_set_verify_result overrides the result of certificate verification. */
-OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long result);
-
/* SSL_get_ex_data_X509_STORE_CTX_idx returns the ex_data index used to look up
* the |SSL| associated with an |X509_STORE_CTX| in the verify callback. */
OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void);
@@ -3569,18 +3574,6 @@
OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
const char *dir);
-/* SSL_SESSION_get_key_exchange_info returns a value that describes the
- * strength of the asymmetric operation that provides confidentiality to
- * |session|. Its interpretation depends on the operation used. See the
- * documentation for this value in the |SSL_SESSION| structure.
- *
- * Use |SSL_get_curve_id| or |SSL_get_dhe_group_size| instead.
- *
- * TODO(davidben): Remove this API once Chromium has switched to the new
- * APIs. */
-OPENSSL_EXPORT uint32_t SSL_SESSION_get_key_exchange_info(
- const SSL_SESSION *session);
-
/* SSL_set_private_key_digest_prefs copies |num_digests| NIDs from |digest_nids|
* into |ssl|. These digests will be used, in decreasing order of preference,
* when signing with |ssl|'s private key. It returns one on success and zero on
@@ -3593,6 +3586,12 @@
const int *digest_nids,
size_t num_digests);
+/* SSL_set_verify_result calls |abort| unless |result| is |X509_V_OK|.
+ *
+ * TODO(davidben): Remove this function once it has been removed from
+ * netty-tcnative. */
+OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long result);
+
/* Private structures.
*
@@ -3666,9 +3665,9 @@
* |peer|, but when a server it does not. */
STACK_OF(X509) *cert_chain;
- /* when app_verify_callback accepts a session where the peer's certificate is
- * not ok, we must remember the error for session reuse: */
- long verify_result; /* only for servers */
+ /* verify_result is the result of certificate verification in the case of
+ * non-fatal certificate errors. */
+ long verify_result;
long timeout;
long time;
@@ -4128,7 +4127,6 @@
SSL_CTX *ctx;
/* extra application data */
- long verify_result;
CRYPTO_EX_DATA ex_data;
/* for server side, keep the list of CA_dn we can use */
@@ -4290,6 +4288,9 @@
* received. */
uint8_t warning_alert_count;
+ /* key_update_count is the number of consecutive KeyUpdates received. */
+ uint8_t key_update_count;
+
/* aead_read_ctx is the current read cipher state. */
SSL_AEAD_CTX *aead_read_ctx;
@@ -4440,6 +4441,9 @@
* immutable. */
SSL_SESSION *established_session;
+ /* session_reused indicates whether a session was resumed. */
+ unsigned session_reused:1;
+
/* Connection binding to prevent renegotiation attacks */
uint8_t previous_client_finished[EVP_MAX_MD_SIZE];
uint8_t previous_client_finished_len;
@@ -4642,6 +4646,19 @@
#if defined(__cplusplus)
} /* extern C */
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(SSL, SSL_free)
+BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free)
+BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
@@ -4804,6 +4821,10 @@
#define SSL_R_DUPLICATE_EXTENSION 257
#define SSL_R_MISSING_KEY_SHARE 258
#define SSL_R_INVALID_ALPN_PROTOCOL 259
+#define SSL_R_TOO_MANY_KEY_UPDATES 260
+#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 261
+#define SSL_R_NO_CIPHERS_SPECIFIED 262
+#define SSL_R_RENEGOTIATION_EMS_MISMATCH 263
#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/stack.h b/src/include/openssl/stack.h
index 6f53b0a..c6e0de3 100644
--- a/src/include/openssl/stack.h
+++ b/src/include/openssl/stack.h
@@ -180,14 +180,12 @@
typedef char *OPENSSL_STRING;
DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
-DEFINE_SPECIAL_STACK_OF(OPENSSL_BLOCK, uint8_t)
/* The make_macros.sh script in this directory parses the following lines and
* generates the stack_macros.h file that contains macros for the following
* types of stacks:
*
- * SPECIAL_STACK_OF:OPENSSL_STRING
- * SPECIAL_STACK_OF:OPENSSL_BLOCK */
+ * SPECIAL_STACK_OF:OPENSSL_STRING */
#define IN_STACK_H
#include <openssl/stack_macros.h>
diff --git a/src/include/openssl/stack_macros.h b/src/include/openssl/stack_macros.h
index 2a60b8f..d5f47f7 100644
--- a/src/include/openssl/stack_macros.h
+++ b/src/include/openssl/stack_macros.h
@@ -3900,87 +3900,3 @@
CHECKED_CAST(void *(*)(void *), OPENSSL_STRING (*)(OPENSSL_STRING), \
copy_func), \
CHECKED_CAST(void (*)(void *), void (*)(OPENSSL_STRING), free_func)))
-
-/* OPENSSL_BLOCK */
-#define sk_OPENSSL_BLOCK_new(comp) \
- ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_CAST( \
- stack_cmp_func, int (*)(const OPENSSL_BLOCK *a, const OPENSSL_BLOCK *b), \
- comp)))
-
-#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
-
-#define sk_OPENSSL_BLOCK_num(sk) \
- sk_num(CHECKED_CAST(const _STACK *, const STACK_OF(OPENSSL_BLOCK) *, sk))
-
-#define sk_OPENSSL_BLOCK_zero(sk) \
- sk_zero(CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk));
-
-#define sk_OPENSSL_BLOCK_value(sk, i) \
- ((OPENSSL_BLOCK)sk_value( \
- CHECKED_CAST(const _STACK *, const STACK_OF(OPENSSL_BLOCK) *, sk), (i)))
-
-#define sk_OPENSSL_BLOCK_set(sk, i, p) \
- ((OPENSSL_BLOCK)sk_set( \
- CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk), (i), \
- CHECKED_CAST(void *, OPENSSL_BLOCK, p)))
-
-#define sk_OPENSSL_BLOCK_free(sk) \
- sk_free(CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk))
-
-#define sk_OPENSSL_BLOCK_pop_free(sk, free_func) \
- sk_pop_free( \
- CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk), \
- CHECKED_CAST(void (*)(void *), void (*)(OPENSSL_BLOCK), free_func))
-
-#define sk_OPENSSL_BLOCK_insert(sk, p, where) \
- sk_insert(CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk), \
- CHECKED_CAST(void *, OPENSSL_BLOCK, p), (where))
-
-#define sk_OPENSSL_BLOCK_delete(sk, where) \
- ((OPENSSL_BLOCK)sk_delete( \
- CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk), (where)))
-
-#define sk_OPENSSL_BLOCK_delete_ptr(sk, p) \
- ((OPENSSL_BLOCK)sk_delete_ptr( \
- CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk), \
- CHECKED_CAST(void *, OPENSSL_BLOCK, p)))
-
-#define sk_OPENSSL_BLOCK_find(sk, out_index, p) \
- sk_find(CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk), (out_index), \
- CHECKED_CAST(void *, OPENSSL_BLOCK, p))
-
-#define sk_OPENSSL_BLOCK_shift(sk) \
- ((OPENSSL_BLOCK)sk_shift( \
- CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk)))
-
-#define sk_OPENSSL_BLOCK_push(sk, p) \
- sk_push(CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk), \
- CHECKED_CAST(void *, OPENSSL_BLOCK, p))
-
-#define sk_OPENSSL_BLOCK_pop(sk) \
- ((OPENSSL_BLOCK)sk_pop(CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk)))
-
-#define sk_OPENSSL_BLOCK_dup(sk) \
- ((STACK_OF(OPENSSL_BLOCK) *)sk_dup( \
- CHECKED_CAST(const _STACK *, const STACK_OF(OPENSSL_BLOCK) *, sk)))
-
-#define sk_OPENSSL_BLOCK_sort(sk) \
- sk_sort(CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk))
-
-#define sk_OPENSSL_BLOCK_is_sorted(sk) \
- sk_is_sorted( \
- CHECKED_CAST(const _STACK *, const STACK_OF(OPENSSL_BLOCK) *, sk))
-
-#define sk_OPENSSL_BLOCK_set_cmp_func(sk, comp) \
- ((int (*)(const OPENSSL_BLOCK **a, const OPENSSL_BLOCK **b))sk_set_cmp_func( \
- CHECKED_CAST(_STACK *, STACK_OF(OPENSSL_BLOCK) *, sk), \
- CHECKED_CAST(stack_cmp_func, \
- int (*)(const OPENSSL_BLOCK **a, const OPENSSL_BLOCK **b), \
- comp)))
-
-#define sk_OPENSSL_BLOCK_deep_copy(sk, copy_func, free_func) \
- ((STACK_OF(OPENSSL_BLOCK) *)sk_deep_copy( \
- CHECKED_CAST(const _STACK *, const STACK_OF(OPENSSL_BLOCK) *, sk), \
- CHECKED_CAST(void *(*)(void *), OPENSSL_BLOCK (*)(OPENSSL_BLOCK), \
- copy_func), \
- CHECKED_CAST(void (*)(void *), void (*)(OPENSSL_BLOCK), free_func)))
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index 5bbf651..b45dd3b 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -1224,6 +1224,34 @@
#ifdef __cplusplus
}
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_STACK_DELETER(X509, X509_free)
+BORINGSSL_MAKE_DELETER(X509, X509_free)
+BORINGSSL_MAKE_DELETER(X509_ALGOR, X509_ALGOR_free)
+BORINGSSL_MAKE_DELETER(X509_CRL, X509_CRL_free)
+BORINGSSL_MAKE_DELETER(X509_CRL_METHOD, X509_CRL_METHOD_free)
+BORINGSSL_MAKE_DELETER(X509_EXTENSION, X509_EXTENSION_free)
+BORINGSSL_MAKE_DELETER(X509_INFO, X509_INFO_free)
+BORINGSSL_MAKE_DELETER(X509_LOOKUP, X509_LOOKUP_free)
+BORINGSSL_MAKE_DELETER(X509_NAME, X509_NAME_free)
+BORINGSSL_MAKE_DELETER(X509_NAME_ENTRY, X509_NAME_ENTRY_free)
+BORINGSSL_MAKE_DELETER(X509_PKEY, X509_PKEY_free)
+BORINGSSL_MAKE_DELETER(X509_POLICY_TREE, X509_policy_tree_free)
+BORINGSSL_MAKE_DELETER(X509_REQ, X509_REQ_free)
+BORINGSSL_MAKE_DELETER(X509_REVOKED, X509_REVOKED_free)
+BORINGSSL_MAKE_DELETER(X509_SIG, X509_SIG_free)
+BORINGSSL_MAKE_DELETER(X509_STORE, X509_STORE_free)
+BORINGSSL_MAKE_DELETER(X509_STORE_CTX, X509_STORE_CTX_free)
+BORINGSSL_MAKE_DELETER(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free)
+
+} // namespace bssl
+
+} /* extern C++ */
+
#endif
#define X509_R_AKID_MISMATCH 100
diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h
index 50ded0d..0a45aad 100644
--- a/src/include/openssl/x509_vfy.h
+++ b/src/include/openssl/x509_vfy.h
@@ -129,8 +129,6 @@
} data;
} X509_OBJECT;
-typedef struct x509_lookup_st X509_LOOKUP;
-
DECLARE_STACK_OF(X509_LOOKUP)
DECLARE_STACK_OF(X509_OBJECT)
diff --git a/src/ssl/handshake_client.c b/src/ssl/handshake_client.c
index 34c1adc..237f452 100644
--- a/src/ssl/handshake_client.c
+++ b/src/ssl/handshake_client.c
@@ -514,7 +514,7 @@
* of the new established_session due to False Start. The caller may
* have taken a reference to the temporary session. */
ssl->s3->established_session =
- SSL_SESSION_dup(ssl->s3->new_session, 1 /* include ticket */);
+ SSL_SESSION_dup(ssl->s3->new_session, SSL_SESSION_DUP_ALL);
if (ssl->s3->established_session == NULL) {
/* Do not stay in SSL_ST_OK, to avoid confusing |SSL_in_init|
* callers. */
@@ -605,6 +605,16 @@
if (!CBB_add_u16(&child, ssl_cipher_get_value(cipher))) {
return 0;
}
+ /* Add PSK ciphers for TLS 1.3 resumption. */
+ if (ssl->session != NULL &&
+ ssl->method->version_from_wire(ssl->session->ssl_version) >=
+ TLS1_3_VERSION) {
+ uint16_t resumption_cipher;
+ if (ssl_cipher_get_ecdhe_psk_cipher(cipher, &resumption_cipher) &&
+ !CBB_add_u16(&child, resumption_cipher)) {
+ return 0;
+ }
+ }
}
/* If all ciphers were disabled, return the error to the caller. */
@@ -708,10 +718,10 @@
if (ssl->session != NULL) {
uint16_t session_version =
ssl->method->version_from_wire(ssl->session->ssl_version);
- struct timeval now;
- ssl_get_current_time(ssl, &now);
- if (ssl->session->session_id_length == 0 || ssl->session->not_resumable ||
- ssl->session->timeout < (long)now.tv_sec - ssl->session->time ||
+ if ((session_version < TLS1_3_VERSION &&
+ ssl->session->session_id_length == 0) ||
+ ssl->session->not_resumable ||
+ !ssl_session_is_time_valid(ssl, ssl->session) ||
session_version < min_version || session_version > max_version) {
SSL_set_session(ssl, NULL);
}
@@ -885,18 +895,11 @@
goto f_err;
}
- assert(ssl->session == NULL || ssl->session->session_id_length > 0);
if (!ssl->s3->initial_handshake_complete && ssl->session != NULL &&
+ ssl->session->session_id_length != 0 &&
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;
- }
+ ssl->s3->session_reused = 1;
} else {
/* The session wasn't resumed. Create a fresh SSL_SESSION to
* fill out. */
@@ -946,6 +949,13 @@
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
goto f_err;
}
+ if (!ssl_session_is_context_valid(ssl, ssl->session)) {
+ /* This is 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;
+ }
} else {
ssl->s3->new_session->cipher = c;
}
@@ -1091,11 +1101,11 @@
}
static int ssl3_verify_server_cert(SSL *ssl) {
- if (!ssl_verify_cert_chain(ssl, ssl->s3->new_session->cert_chain)) {
+ if (!ssl_verify_cert_chain(ssl, &ssl->s3->new_session->verify_result,
+ ssl->s3->new_session->cert_chain)) {
return -1;
}
- ssl->s3->new_session->verify_result = ssl->verify_result;
return 1;
}
@@ -1935,8 +1945,7 @@
/* 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. */
- session = SSL_SESSION_dup(ssl->session,
- 0 /* Don't duplicate session ticket */);
+ session = SSL_SESSION_dup(ssl->session, SSL_SESSION_INCLUDE_NONAUTH);
if (session == NULL) {
/* This should never happen. */
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
diff --git a/src/ssl/handshake_server.c b/src/ssl/handshake_server.c
index 4e7aae2..f041129 100644
--- a/src/ssl/handshake_server.c
+++ b/src/ssl/handshake_server.c
@@ -712,7 +712,7 @@
/* Use the old session. */
ssl->session = session;
session = NULL;
- ssl->verify_result = ssl->session->verify_result;
+ ssl->s3->session_reused = 1;
} else {
SSL_set_session(ssl, NULL);
if (!ssl_get_new_session(ssl, 1 /* server */)) {
@@ -808,6 +808,12 @@
if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
ssl->s3->tmp.cert_request = 0;
}
+
+ if (!ssl->s3->tmp.cert_request) {
+ /* OpenSSL returns X509_V_OK when no certificates are requested. This is
+ * classed by them as a bug, but it's assumed by at least NGINX. */
+ ssl->s3->new_session->verify_result = X509_V_OK;
+ }
}
/* Now that the cipher is known, initialize the handshake hash. */
@@ -1188,13 +1194,12 @@
if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
const uint16_t *sigalgs;
- size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs);
+ size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
goto err;
}
- size_t i;
- for (i = 0; i < sigalgs_len; i++) {
+ for (size_t i = 0; i < num_sigalgs; i++) {
if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
goto err;
}
@@ -1243,13 +1248,17 @@
if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
if (ssl->version == SSL3_VERSION &&
ssl->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
- /* In SSL 3.0, the Certificate message is omitted to signal no certificate. */
+ /* In SSL 3.0, the Certificate message is omitted to signal no
+ * certificate. */
if (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return -1;
}
+ /* OpenSSL returns X509_V_OK when no certificates are received. This is
+ * classed by them as a bug, but it's assumed by at least NGINX. */
+ ssl->s3->new_session->verify_result = X509_V_OK;
ssl->s3->tmp.reuse_message = 1;
return 1;
}
@@ -1296,20 +1305,24 @@
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
goto err;
}
+
+ /* OpenSSL returns X509_V_OK when no certificates are received. This is
+ * classed by them as a bug, but it's assumed by at least NGINX. */
+ ssl->s3->new_session->verify_result = X509_V_OK;
} else {
/* The hash would have been filled in. */
if (ssl->ctx->retain_only_sha256_of_client_certs) {
ssl->s3->new_session->peer_sha256_valid = 1;
}
- if (!ssl_verify_cert_chain(ssl, chain)) {
+ if (!ssl_verify_cert_chain(ssl, &ssl->s3->new_session->verify_result,
+ chain)) {
goto err;
}
}
X509_free(ssl->s3->new_session->peer);
ssl->s3->new_session->peer = sk_X509_shift(chain);
- ssl->s3->new_session->verify_result = ssl->verify_result;
sk_X509_pop_free(ssl->s3->new_session->cert_chain, X509_free);
ssl->s3->new_session->cert_chain = chain;
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 4fcf4b9..660ba79 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -148,6 +148,7 @@
#include <openssl/ssl.h>
#include <openssl/stack.h>
+
#if defined(OPENSSL_WINDOWS)
/* Windows defines struct timeval in winsock2.h. */
OPENSSL_MSVC_PRAGMA(warning(push, 3))
@@ -241,6 +242,11 @@
/* ssl_cipher_get_value returns the cipher suite id of |cipher|. */
uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher);
+/* ssl_cipher_get_resumption_cipher returns the cipher suite id of the cipher
+ * matching |cipher| with PSK enabled. */
+int ssl_cipher_get_ecdhe_psk_cipher(const SSL_CIPHER *cipher,
+ uint16_t *out_cipher);
+
/* ssl_cipher_get_key_type returns the |EVP_PKEY_*| value corresponding to the
* server key used in |cipher| or |EVP_PKEY_NONE| if there is none. */
int ssl_cipher_get_key_type(const SSL_CIPHER *cipher);
@@ -848,6 +854,18 @@
* 0 for the Client Finished. */
int tls13_finished_mac(SSL *ssl, uint8_t *out, size_t *out_len, int is_server);
+/* tls13_resumption_psk calculates the PSK to use for the resumption of
+ * |session| and stores the result in |out|. It returns one on success, and
+ * zero on failure. */
+int tls13_resumption_psk(SSL *ssl, uint8_t *out, size_t out_len,
+ const SSL_SESSION *session);
+
+/* tls13_resumption_context derives the context to be used for the handshake
+ * transcript on the resumption of |session|. It returns one on success, and
+ * zero on failure. */
+int tls13_resumption_context(SSL *ssl, uint8_t *out, size_t out_len,
+ const SSL_SESSION *session);
+
/* Handshake functions. */
@@ -889,8 +907,12 @@
uint8_t *public_key;
size_t public_key_len;
- uint8_t *cert_context;
- size_t cert_context_len;
+ /* peer_sigalgs are the signature algorithms that the peer supports. These are
+ * taken from the contents of the signature algorithms extension for a server
+ * or from the CertificateRequest for a client. */
+ uint16_t *peer_sigalgs;
+ /* num_peer_sigalgs is the number of entries in |peer_sigalgs|. */
+ size_t num_peer_sigalgs;
uint8_t session_tickets_sent;
} /* SSL_HANDSHAKE */;
@@ -938,6 +960,13 @@
uint8_t *out_alert, CBS *contents);
int ssl_ext_key_share_add_serverhello(SSL *ssl, CBB *out);
+int ssl_ext_pre_shared_key_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents);
+int ssl_ext_pre_shared_key_parse_clienthello(SSL *ssl,
+ SSL_SESSION **out_session,
+ uint8_t *out_alert, CBS *contents);
+int ssl_ext_pre_shared_key_add_serverhello(SSL *ssl, CBB *out);
+
int ssl_add_client_hello_body(SSL *ssl, CBB *body);
@@ -1008,17 +1037,10 @@
DH *dh_tmp;
DH *(*dh_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. */
- uint16_t *peer_sigalgs;
- /* peer_sigalgslen is the number of entries in |peer_sigalgs|. */
- size_t peer_sigalgslen;
-
- /* sigalgs, if non-NULL, is the set of digests supported by |privatekey| in
- * decreasing order of preference. */
+ /* sigalgs, if non-NULL, is the set of signature algorithms supported by
+ * |privatekey| in decreasing order of preference. */
uint16_t *sigalgs;
- size_t sigalgs_len;
+ size_t num_sigalgs;
/* Certificate setup callback: if set is called whenever a
* certificate may be required (client or server). the callback
@@ -1232,6 +1254,14 @@
int ssl_get_new_session(SSL *ssl, int is_server);
int ssl_encrypt_ticket(SSL *ssl, CBB *out, const SSL_SESSION *session);
+/* ssl_session_is_context_valid returns one if |session|'s session ID context
+ * matches the one set on |ssl| and zero otherwise. */
+int ssl_session_is_context_valid(const SSL *ssl, const SSL_SESSION *session);
+
+/* ssl_session_is_time_valid returns one if |session| is still valid and zero if
+ * it has expired. */
+int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session);
+
enum ssl_session_result_t {
ssl_session_success,
ssl_session_error,
@@ -1248,11 +1278,18 @@
SSL *ssl, SSL_SESSION **out_session, int *out_send_ticket,
const struct ssl_early_callback_ctx *ctx);
+/* The following flags determine which parts of the session are duplicated. */
+#define SSL_SESSION_DUP_AUTH_ONLY 0x0
+#define SSL_SESSION_INCLUDE_TICKET 0x1
+#define SSL_SESSION_INCLUDE_NONAUTH 0x2
+#define SSL_SESSION_DUP_ALL \
+ (SSL_SESSION_INCLUDE_TICKET | SSL_SESSION_INCLUDE_NONAUTH)
+
/* SSL_SESSION_dup returns a newly-allocated |SSL_SESSION| with a copy of the
* fields in |session| or NULL on error. The new session is non-resumable and
* must be explicitly marked resumable once it has been filled in. */
OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session,
- int include_ticket);
+ int dup_flags);
void ssl_cipher_preference_list_free(
struct ssl_cipher_preference_list_st *cipher_list);
@@ -1265,7 +1302,8 @@
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_verify_cert_chain(SSL *ssl, long *out_verify_result,
+ STACK_OF(X509) * cert_chain);
void ssl_update_cache(SSL *ssl, int mode);
/* ssl_get_compatible_server_ciphers determines the key exchange and
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index cb5d0da..aa8dea6 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -130,6 +130,45 @@
#include "internal.h"
+SSL_HANDSHAKE *ssl_handshake_new(enum ssl_hs_wait_t (*do_handshake)(SSL *ssl)) {
+ SSL_HANDSHAKE *hs = OPENSSL_malloc(sizeof(SSL_HANDSHAKE));
+ if (hs == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ memset(hs, 0, sizeof(SSL_HANDSHAKE));
+ hs->do_handshake = do_handshake;
+ hs->wait = ssl_hs_ok;
+ return hs;
+}
+
+void ssl_handshake_clear_groups(SSL_HANDSHAKE *hs) {
+ if (hs->groups == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < hs->groups_len; i++) {
+ SSL_ECDH_CTX_cleanup(&hs->groups[i]);
+ }
+ OPENSSL_free(hs->groups);
+ hs->groups = NULL;
+ hs->groups_len = 0;
+}
+
+void ssl_handshake_free(SSL_HANDSHAKE *hs) {
+ if (hs == NULL) {
+ return;
+ }
+
+ OPENSSL_cleanse(hs->secret, sizeof(hs->secret));
+ OPENSSL_cleanse(hs->traffic_secret_0, sizeof(hs->traffic_secret_0));
+ ssl_handshake_clear_groups(hs);
+ OPENSSL_free(hs->key_share_bytes);
+ OPENSSL_free(hs->public_key);
+ OPENSSL_free(hs->peer_sigalgs);
+ OPENSSL_free(hs);
+}
+
/* 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 success
* and <= 0 on error. */
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index c35834e..e770279 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -158,18 +158,6 @@
}
memset(ret, 0, sizeof(CERT));
- ret->mask_k = cert->mask_k;
- ret->mask_a = cert->mask_a;
-
- if (cert->dh_tmp != NULL) {
- ret->dh_tmp = DHparams_dup(cert->dh_tmp);
- if (ret->dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
- goto err;
- }
- }
- ret->dh_tmp_cb = cert->dh_tmp_cb;
-
if (cert->x509 != NULL) {
X509_up_ref(cert->x509);
ret->x509 = cert->x509;
@@ -190,6 +178,27 @@
ret->key_method = cert->key_method;
+ ret->mask_k = cert->mask_k;
+ ret->mask_a = cert->mask_a;
+
+ if (cert->dh_tmp != NULL) {
+ ret->dh_tmp = DHparams_dup(cert->dh_tmp);
+ if (ret->dh_tmp == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
+ goto err;
+ }
+ }
+ ret->dh_tmp_cb = cert->dh_tmp_cb;
+
+ if (cert->sigalgs != NULL) {
+ ret->sigalgs =
+ BUF_memdup(cert->sigalgs, cert->num_sigalgs * sizeof(cert->sigalgs[0]));
+ if (ret->sigalgs == NULL) {
+ goto err;
+ }
+ }
+ ret->num_sigalgs = cert->num_sigalgs;
+
ret->cert_cb = cert->cert_cb;
ret->cert_cb_arg = cert->cert_cb_arg;
@@ -228,7 +237,6 @@
DH_free(c->dh_tmp);
ssl_cert_clear_certs(c);
- OPENSSL_free(c->peer_sigalgs);
OPENSSL_free(c->sigalgs);
X509_STORE_free(c->verify_store);
@@ -285,7 +293,8 @@
c->cert_cb_arg = arg;
}
-int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain) {
+int ssl_verify_cert_chain(SSL *ssl, long *out_verify_result,
+ STACK_OF(X509) *cert_chain) {
if (cert_chain == NULL || sk_X509_num(cert_chain) == 0) {
return 0;
}
@@ -326,12 +335,11 @@
verify_ret = X509_verify_cert(&ctx);
}
- ssl->verify_result = ctx.error;
+ *out_verify_result = ctx.error;
/* If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result. */
if (verify_ret <= 0 && ssl->verify_mode != SSL_VERIFY_NONE) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL,
- ssl_verify_alarm_type(ssl->verify_result));
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, ssl_verify_alarm_type(ctx.error));
OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
goto err;
}
diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.c
index 3810667..e58d889 100644
--- a/src/ssl/ssl_cipher.c
+++ b/src/ssl/ssl_cipher.c
@@ -151,6 +151,7 @@
#include <openssl/stack.h>
#include "internal.h"
+#include "../crypto/internal.h"
/* kCiphers is an array of all supported ciphers, sorted by id. */
@@ -167,6 +168,7 @@
SSL_HANDSHAKE_MAC_DEFAULT,
},
+#ifdef BORINGSSL_ENABLE_RC4_TLS
/* Cipher 04 */
{
SSL3_TXT_RSA_RC4_128_MD5,
@@ -188,6 +190,7 @@
SSL_SHA1,
SSL_HANDSHAKE_MAC_DEFAULT,
},
+#endif
/* Cipher 0A */
{
@@ -296,6 +299,7 @@
/* PSK cipher suites. */
+#ifdef BORINGSSL_ENABLE_RC4_TLS
/* Cipher 8A */
{
TLS1_TXT_PSK_WITH_RC4_128_SHA,
@@ -306,6 +310,7 @@
SSL_SHA1,
SSL_HANDSHAKE_MAC_DEFAULT,
},
+#endif
/* Cipher 8C */
{
@@ -421,6 +426,7 @@
SSL_HANDSHAKE_MAC_SHA384,
},
+#ifdef BORINGSSL_ENABLE_RC4_TLS
/* Cipher C007 */
{
TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
@@ -431,6 +437,7 @@
SSL_SHA1,
SSL_HANDSHAKE_MAC_DEFAULT,
},
+#endif
/* Cipher C009 */
{
@@ -454,6 +461,7 @@
SSL_HANDSHAKE_MAC_DEFAULT,
},
+#ifdef BORINGSSL_ENABLE_RC4_TLS
/* Cipher C011 */
{
TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA,
@@ -464,6 +472,7 @@
SSL_SHA1,
SSL_HANDSHAKE_MAC_DEFAULT,
},
+#endif
/* Cipher C013 */
{
@@ -686,7 +695,7 @@
};
-static const size_t kCiphersLen = sizeof(kCiphers) / sizeof(kCiphers[0]);
+static const size_t kCiphersLen = OPENSSL_ARRAY_SIZE(kCiphers);
#define CIPHER_ADD 1
#define CIPHER_KILL 2
@@ -786,8 +795,7 @@
{"FIPS", ~SSL_kCECPQ1, ~0u, ~(SSL_eNULL|SSL_RC4), ~0u, 0},
};
-static const size_t kCipherAliasesLen =
- sizeof(kCipherAliases) / sizeof(kCipherAliases[0]);
+static const size_t kCipherAliasesLen = OPENSSL_ARRAY_SIZE(kCipherAliases);
static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
const SSL_CIPHER *a = in_a;
@@ -845,6 +853,7 @@
*out_fixed_iv_len = 12;
break;
+#ifdef BORINGSSL_ENABLE_RC4_TLS
case SSL_RC4:
switch (cipher->algorithm_mac) {
case SSL_MD5:
@@ -867,6 +876,7 @@
return 0;
}
break;
+#endif
case SSL_AES128:
switch (cipher->algorithm_mac) {
@@ -1660,6 +1670,30 @@
return id & 0xffff;
}
+int ssl_cipher_get_ecdhe_psk_cipher(const SSL_CIPHER *cipher,
+ uint16_t *out_cipher) {
+ switch (cipher->id) {
+ case TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ case TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+ case TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
+ *out_cipher = TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 & 0xffff;
+ return 1;
+
+ case TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ case TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ case TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256:
+ *out_cipher = TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256 & 0xffff;
+ return 1;
+
+ case TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ case TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ case TLS1_CK_ECDHE_PSK_WITH_AES_256_GCM_SHA384:
+ *out_cipher = TLS1_CK_ECDHE_PSK_WITH_AES_256_GCM_SHA384 & 0xffff;
+ return 1;
+ }
+ return 0;
+}
+
int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher) {
return (cipher->algorithm_enc & SSL_AES) != 0;
}
diff --git a/src/ssl/ssl_ecdh.c b/src/ssl/ssl_ecdh.c
index 47b6eab..079ddb5 100644
--- a/src/ssl/ssl_ecdh.c
+++ b/src/ssl/ssl_ecdh.c
@@ -27,6 +27,7 @@
#include <openssl/nid.h>
#include "internal.h"
+#include "../crypto/internal.h"
/* |EC_POINT| implementation. */
@@ -504,7 +505,7 @@
static const SSL_ECDH_METHOD *method_from_group_id(uint16_t group_id) {
size_t i;
- for (i = 0; i < sizeof(kMethods) / sizeof(kMethods[0]); i++) {
+ for (i = 0; i < OPENSSL_ARRAY_SIZE(kMethods); i++) {
if (kMethods[i].group_id == group_id) {
return &kMethods[i];
}
@@ -514,7 +515,7 @@
static const SSL_ECDH_METHOD *method_from_nid(int nid) {
size_t i;
- for (i = 0; i < sizeof(kMethods) / sizeof(kMethods[0]); i++) {
+ for (i = 0; i < OPENSSL_ARRAY_SIZE(kMethods); i++) {
if (kMethods[i].nid == nid) {
return &kMethods[i];
}
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index 1a950ad..4c3b40e 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -141,6 +141,7 @@
#include <openssl/ssl.h>
#include <assert.h>
+#include <stdlib.h>
#include <string.h>
#include <openssl/bytestring.h>
@@ -167,6 +168,11 @@
* to avoid downstream churn. */
OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL)
+/* The following errors are no longer emitted, but are used in nginx without
+ * #ifdefs. */
+OPENSSL_DECLARE_ERROR_REASON(SSL, BLOCK_CIPHER_PAD_IS_WRONG)
+OPENSSL_DECLARE_ERROR_REASON(SSL, NO_CIPHERS_SPECIFIED)
+
/* Some error codes are special. Ensure the make_errors.go script never
* regresses this. */
OPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
@@ -440,7 +446,6 @@
ssl->alpn_client_proto_list_len = ssl->ctx->alpn_client_proto_list_len;
}
- ssl->verify_result = X509_V_ERR_INVALID_CALL;
ssl->method = ctx->method;
if (!ssl->method->ssl_new(ssl)) {
@@ -722,6 +727,7 @@
int got_handshake;
int ret = ssl->method->read_app_data(ssl, &got_handshake, buf, num, peek);
if (ret > 0 || !got_handshake) {
+ ssl->s3->key_update_count = 0;
return ret;
}
@@ -2162,7 +2168,7 @@
}
int SSL_session_reused(const SSL *ssl) {
- return ssl->session != NULL;
+ return ssl->s3->session_reused;
}
const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; }
@@ -2309,10 +2315,18 @@
}
void SSL_set_verify_result(SSL *ssl, long result) {
- ssl->verify_result = result;
+ if (result != X509_V_OK) {
+ abort();
+ }
}
-long SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; }
+long SSL_get_verify_result(const SSL *ssl) {
+ SSL_SESSION *session = SSL_get_session(ssl);
+ if (session == NULL) {
+ return X509_V_ERR_INVALID_CALL;
+ }
+ return session->verify_result;
+}
int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
@@ -2658,7 +2672,7 @@
{TLS1_3_VERSION, SSL_OP_NO_TLSv1_3},
};
-static const size_t kVersionsLen = sizeof(kVersions) / sizeof(kVersions[0]);
+static const size_t kVersionsLen = OPENSSL_ARRAY_SIZE(kVersions);
int ssl_get_full_version_range(const SSL *ssl, uint16_t *out_min_version,
uint16_t *out_fallback_version,
diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c
index c06207f..a5f15f4 100644
--- a/src/ssl/ssl_rsa.c
+++ b/src/ssl/ssl_rsa.c
@@ -336,19 +336,30 @@
ctx->cert->key_method = key_method;
}
-int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
- size_t prefs_len) {
- ssl->cert->sigalgs_len = 0;
- ssl->cert->sigalgs = BUF_memdup(prefs, prefs_len * sizeof(prefs[0]));
- if (ssl->cert->sigalgs == NULL) {
+static int set_signing_algorithm_prefs(CERT *cert, const uint16_t *prefs,
+ size_t num_prefs) {
+ cert->num_sigalgs = 0;
+ cert->sigalgs = BUF_memdup(prefs, num_prefs * sizeof(prefs[0]));
+ if (cert->sigalgs == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
- ssl->cert->sigalgs_len = prefs_len;
+ cert->num_sigalgs = num_prefs;
return 1;
}
+int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
+ size_t num_prefs) {
+ return set_signing_algorithm_prefs(ctx->cert, prefs, num_prefs);
+}
+
+
+int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
+ size_t num_prefs) {
+ return set_signing_algorithm_prefs(ssl->cert, prefs, num_prefs);
+}
+
OPENSSL_COMPILE_ASSERT(sizeof(int) >= 2 * sizeof(uint16_t),
digest_list_conversion_cannot_overflow);
@@ -356,7 +367,7 @@
size_t num_digests) {
OPENSSL_free(ssl->cert->sigalgs);
- ssl->cert->sigalgs_len = 0;
+ ssl->cert->num_sigalgs = 0;
ssl->cert->sigalgs = OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests);
if (ssl->cert->sigalgs == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
@@ -369,27 +380,27 @@
for (size_t i = 0; i < num_digests; i++) {
switch (digest_nids[i]) {
case NID_sha1:
- ssl->cert->sigalgs[ssl->cert->sigalgs_len] = SSL_SIGN_RSA_PKCS1_SHA1;
- ssl->cert->sigalgs[ssl->cert->sigalgs_len + 1] = SSL_SIGN_ECDSA_SHA1;
- ssl->cert->sigalgs_len += 2;
+ ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA1;
+ ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = SSL_SIGN_ECDSA_SHA1;
+ ssl->cert->num_sigalgs += 2;
break;
case NID_sha256:
- ssl->cert->sigalgs[ssl->cert->sigalgs_len] = SSL_SIGN_RSA_PKCS1_SHA256;
- ssl->cert->sigalgs[ssl->cert->sigalgs_len + 1] =
+ ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA256;
+ ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
SSL_SIGN_ECDSA_SECP256R1_SHA256;
- ssl->cert->sigalgs_len += 2;
+ ssl->cert->num_sigalgs += 2;
break;
case NID_sha384:
- ssl->cert->sigalgs[ssl->cert->sigalgs_len] = SSL_SIGN_RSA_PKCS1_SHA384;
- ssl->cert->sigalgs[ssl->cert->sigalgs_len + 1] =
+ ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA384;
+ ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
SSL_SIGN_ECDSA_SECP384R1_SHA384;
- ssl->cert->sigalgs_len += 2;
+ ssl->cert->num_sigalgs += 2;
break;
case NID_sha512:
- ssl->cert->sigalgs[ssl->cert->sigalgs_len] = SSL_SIGN_RSA_PKCS1_SHA512;
- ssl->cert->sigalgs[ssl->cert->sigalgs_len + 1] =
+ ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA512;
+ ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
SSL_SIGN_ECDSA_SECP521R1_SHA512;
- ssl->cert->sigalgs_len += 2;
+ ssl->cert->num_sigalgs += 2;
break;
}
}
@@ -653,7 +664,8 @@
}
const EVP_MD *md;
- if (is_rsa_pkcs1(&md, signature_algorithm)) {
+ if (is_rsa_pkcs1(&md, signature_algorithm) &&
+ ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
return ssl_sign_rsa_pkcs1(ssl, out, out_len, max_out, md, in, in_len)
? ssl_private_key_success
: ssl_private_key_failure;
@@ -666,8 +678,7 @@
: ssl_private_key_failure;
}
- if (is_rsa_pss(&md, signature_algorithm) &&
- ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (is_rsa_pss(&md, signature_algorithm)) {
return ssl_sign_rsa_pss(ssl, out, out_len, max_out, md, in, in_len)
? ssl_private_key_success
: ssl_private_key_failure;
@@ -681,7 +692,8 @@
size_t signature_len, uint16_t signature_algorithm,
EVP_PKEY *pkey, const uint8_t *in, size_t in_len) {
const EVP_MD *md;
- if (is_rsa_pkcs1(&md, signature_algorithm)) {
+ if (is_rsa_pkcs1(&md, signature_algorithm) &&
+ ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
return ssl_verify_rsa_pkcs1(ssl, signature, signature_len, md, pkey, in,
in_len);
}
@@ -692,8 +704,7 @@
in_len);
}
- if (is_rsa_pss(&md, signature_algorithm) &&
- ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (is_rsa_pss(&md, signature_algorithm)) {
return ssl_verify_rsa_pss(ssl, signature, signature_len, md, pkey, in,
in_len);
}
@@ -735,7 +746,8 @@
int ssl_private_key_supports_signature_algorithm(SSL *ssl,
uint16_t signature_algorithm) {
const EVP_MD *md;
- if (is_rsa_pkcs1(&md, signature_algorithm)) {
+ if (is_rsa_pkcs1(&md, signature_algorithm) &&
+ ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
return ssl_private_key_type(ssl) == NID_rsaEncryption;
}
@@ -756,8 +768,7 @@
}
if (is_rsa_pss(&md, signature_algorithm)) {
- if (ssl3_protocol_version(ssl) < TLS1_3_VERSION ||
- ssl_private_key_type(ssl) != NID_rsaEncryption) {
+ if (ssl_private_key_type(ssl) != NID_rsaEncryption) {
return 0;
}
diff --git a/src/ssl/ssl_session.c b/src/ssl/ssl_session.c
index 1d634d8..3a56dcd 100644
--- a/src/ssl/ssl_session.c
+++ b/src/ssl/ssl_session.c
@@ -175,22 +175,23 @@
return session;
}
-SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session, int include_ticket) {
+SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) {
SSL_SESSION *new_session = SSL_SESSION_new();
if (new_session == NULL) {
goto err;
}
new_session->ssl_version = session->ssl_version;
- new_session->key_exchange_info = session->key_exchange_info;
+ new_session->sid_ctx_length = session->sid_ctx_length;
+ memcpy(new_session->sid_ctx, session->sid_ctx, session->sid_ctx_length);
+
+ /* Copy the key material. */
new_session->master_key_length = session->master_key_length;
memcpy(new_session->master_key, session->master_key,
session->master_key_length);
- new_session->session_id_length = session->session_id_length;
- memcpy(new_session->session_id, session->session_id,
- session->session_id_length);
- new_session->sid_ctx_length = session->sid_ctx_length;
- memcpy(new_session->sid_ctx, session->sid_ctx, session->sid_ctx_length);
+ new_session->cipher = session->cipher;
+
+ /* Copy authentication state. */
if (session->psk_identity != NULL) {
new_session->psk_identity = BUF_strdup(session->psk_identity);
if (new_session->psk_identity == NULL) {
@@ -208,26 +209,15 @@
}
}
new_session->verify_result = session->verify_result;
- new_session->timeout = session->timeout;
- new_session->time = session->time;
- new_session->cipher = session->cipher;
- /* The new_session does not get a copy of the ex_data. */
- if (session->tlsext_hostname != NULL) {
- new_session->tlsext_hostname = BUF_strdup(session->tlsext_hostname);
- if (new_session->tlsext_hostname == NULL) {
+
+ new_session->ocsp_response_length = session->ocsp_response_length;
+ if (session->ocsp_response != NULL) {
+ new_session->ocsp_response = BUF_memdup(session->ocsp_response,
+ session->ocsp_response_length);
+ if (new_session->ocsp_response == NULL) {
goto err;
}
}
- if (include_ticket) {
- if (session->tlsext_tick != NULL) {
- new_session->tlsext_tick =
- BUF_memdup(session->tlsext_tick, session->tlsext_ticklen);
- if (new_session->tlsext_tick == NULL) {
- goto err;
- }
- }
- new_session->tlsext_ticklen = session->tlsext_ticklen;
- }
new_session->tlsext_signed_cert_timestamp_list_length =
session->tlsext_signed_cert_timestamp_list_length;
@@ -239,25 +229,52 @@
goto err;
}
}
- new_session->ocsp_response_length = session->ocsp_response_length;
- if (session->ocsp_response != NULL) {
- new_session->ocsp_response = BUF_memdup(session->ocsp_response,
- session->ocsp_response_length);
- if (new_session->ocsp_response == NULL) {
- goto err;
- }
- }
+
memcpy(new_session->peer_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH);
- memcpy(new_session->original_handshake_hash,
- session->original_handshake_hash,
- session->original_handshake_hash_len);
- new_session->original_handshake_hash_len =
- session->original_handshake_hash_len;
- new_session->tlsext_tick_lifetime_hint = session->tlsext_tick_lifetime_hint;
- new_session->ticket_flags = session->ticket_flags;
- new_session->ticket_age_add = session->ticket_age_add;
- new_session->extended_master_secret = session->extended_master_secret;
new_session->peer_sha256_valid = session->peer_sha256_valid;
+
+ /* Copy non-authentication connection properties. */
+ if (dup_flags & SSL_SESSION_INCLUDE_NONAUTH) {
+ new_session->session_id_length = session->session_id_length;
+ memcpy(new_session->session_id, session->session_id,
+ session->session_id_length);
+
+ new_session->key_exchange_info = session->key_exchange_info;
+ new_session->timeout = session->timeout;
+ new_session->time = session->time;
+
+ if (session->tlsext_hostname != NULL) {
+ new_session->tlsext_hostname = BUF_strdup(session->tlsext_hostname);
+ if (new_session->tlsext_hostname == NULL) {
+ goto err;
+ }
+ }
+
+ memcpy(new_session->original_handshake_hash,
+ session->original_handshake_hash,
+ session->original_handshake_hash_len);
+ new_session->original_handshake_hash_len =
+ session->original_handshake_hash_len;
+ new_session->tlsext_tick_lifetime_hint = session->tlsext_tick_lifetime_hint;
+ new_session->ticket_flags = session->ticket_flags;
+ new_session->ticket_age_add = session->ticket_age_add;
+ new_session->extended_master_secret = session->extended_master_secret;
+ }
+
+ /* Copy the ticket. */
+ if (dup_flags & SSL_SESSION_INCLUDE_TICKET) {
+ if (session->tlsext_tick != NULL) {
+ new_session->tlsext_tick =
+ BUF_memdup(session->tlsext_tick, session->tlsext_ticklen);
+ if (new_session->tlsext_tick == NULL) {
+ goto err;
+ }
+ }
+ new_session->tlsext_ticklen = session->tlsext_ticklen;
+ }
+
+ /* The new_session does not get a copy of the ex_data. */
+
new_session->not_resumable = 1;
return new_session;
@@ -313,10 +330,6 @@
return session->time;
}
-uint32_t SSL_SESSION_get_key_exchange_info(const SSL_SESSION *session) {
- return session->key_exchange_info;
-}
-
X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) {
return session->peer;
}
@@ -564,6 +577,25 @@
return ret;
}
+int ssl_session_is_context_valid(const SSL *ssl, const SSL_SESSION *session) {
+ if (session == NULL) {
+ return 0;
+ }
+
+ return session->sid_ctx_length == ssl->sid_ctx_length &&
+ memcmp(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length) == 0;
+}
+
+int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) {
+ if (session == NULL) {
+ return 0;
+ }
+
+ struct timeval now;
+ ssl_get_current_time(ssl, &now);
+ return session->timeout >= (long)now.tv_sec - session->time;
+}
+
/* ssl_lookup_session looks up |session_id| in the session cache and sets
* |*out_session| to an |SSL_SESSION| object if found. The caller takes
* ownership of the result. */
@@ -576,7 +608,7 @@
return ssl_session_success;
}
- SSL_SESSION *session;
+ SSL_SESSION *session = NULL;
/* Try the internal cache, if it exists. */
if (!(ssl->initial_ctx->session_cache_mode &
SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
@@ -592,39 +624,51 @@
}
/* TODO(davidben): This should probably move it to the front of the list. */
CRYPTO_MUTEX_unlock_read(&ssl->initial_ctx->lock);
-
- if (session != NULL) {
- *out_session = session;
- return ssl_session_success;
- }
}
/* Fall back to the external cache, if it exists. */
- if (ssl->initial_ctx->get_session_cb == NULL) {
- return ssl_session_success;
+ if (session == NULL &&
+ ssl->initial_ctx->get_session_cb != NULL) {
+ int copy = 1;
+ session = ssl->initial_ctx->get_session_cb(ssl, (uint8_t *)session_id,
+ session_id_len, ©);
+
+ if (session == NULL) {
+ return ssl_session_success;
+ }
+
+ if (session == SSL_magic_pending_session_ptr()) {
+ return ssl_session_retry;
+ }
+
+ /* Increment reference count now if the session callback asks us to do so
+ * (note that if the session structures returned by the callback are shared
+ * between threads, it must handle the reference count itself [i.e. copy ==
+ * 0], or things won't be thread-safe). */
+ if (copy) {
+ SSL_SESSION_up_ref(session);
+ }
+
+ /* Add the externally cached session to the internal cache if necessary. */
+ if (!(ssl->initial_ctx->session_cache_mode &
+ SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
+ SSL_CTX_add_session(ssl->initial_ctx, session);
+ }
}
- int copy = 1;
- session = ssl->initial_ctx->get_session_cb(ssl, (uint8_t *)session_id,
- session_id_len, ©);
+
if (session == NULL) {
return ssl_session_success;
}
- if (session == SSL_magic_pending_session_ptr()) {
- return ssl_session_retry;
- }
- /* Increment reference count now if the session callback asks us to do so
- * (note that if the session structures returned by the callback are shared
- * between threads, it must handle the reference count itself [i.e. copy ==
- * 0], or things won't be thread-safe). */
- if (copy) {
- SSL_SESSION_up_ref(session);
- }
-
- /* Add the externally cached session to the internal cache if necessary. */
- if (!(ssl->initial_ctx->session_cache_mode &
- SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
- SSL_CTX_add_session(ssl->initial_ctx, session);
+ if (!ssl_session_is_context_valid(ssl, session)) {
+ /* The client did not offer a suitable ticket or session ID. */
+ SSL_SESSION_free(session);
+ session = NULL;
+ } else if (!ssl_session_is_time_valid(ssl, session)) {
+ /* The session was from the cache, so remove it. */
+ SSL_CTX_remove_session(ssl->initial_ctx, session);
+ SSL_SESSION_free(session);
+ session = NULL;
}
*out_session = session;
@@ -647,7 +691,6 @@
ssl->version > SSL3_VERSION &&
SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_session_ticket,
&ticket, &ticket_len);
- int from_cache = 0;
if (tickets_supported && ticket_len > 0) {
if (!tls_process_ticket(ssl, &session, &renew_ticket, ticket, ticket_len,
ctx->session_id, ctx->session_id_len)) {
@@ -660,35 +703,14 @@
if (lookup_ret != ssl_session_success) {
return lookup_ret;
}
- from_cache = 1;
- }
-
- if (session == NULL ||
- session->sid_ctx_length != ssl->sid_ctx_length ||
- memcmp(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length) != 0) {
- /* The client did not offer a suitable ticket or session ID. If supported,
- * the new session should use a ticket. */
- goto no_session;
- }
-
- struct timeval now;
- ssl_get_current_time(ssl, &now);
- if (session->timeout < (long)now.tv_sec - session->time) {
- if (from_cache) {
- /* The session was from the cache, so remove it. */
- SSL_CTX_remove_session(ssl->initial_ctx, session);
- }
- goto no_session;
}
*out_session = session;
- *out_send_ticket = renew_ticket;
- return ssl_session_success;
-
-no_session:
- *out_session = NULL;
- *out_send_ticket = tickets_supported;
- SSL_SESSION_free(session);
+ if (session != NULL) {
+ *out_send_ticket = renew_ticket;
+ } else {
+ *out_send_ticket = tickets_supported;
+ }
return ssl_session_success;
}
@@ -778,7 +800,6 @@
ssl->session = session;
if (session != NULL) {
SSL_SESSION_up_ref(session);
- ssl->verify_result = session->verify_result;
}
return 1;
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 4c4f6d9..78900e9 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -31,7 +31,7 @@
#include <openssl/x509.h>
#include "internal.h"
-#include "test/scoped_types.h"
+#include "../crypto/internal.h"
#include "../crypto/test/test_util.h"
#if defined(OPENSSL_WINDOWS)
@@ -168,9 +168,13 @@
{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},
+#ifdef BORINGSSL_ENABLE_RC4_TLS
{TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0},
+#endif
{TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
+#ifdef BORINGSSL_ENABLE_RC4_TLS
{SSL3_CK_RSA_RC4_128_SHA, 0},
+#endif
{TLS1_CK_RSA_WITH_AES_128_SHA, 0},
{TLS1_CK_RSA_WITH_AES_256_SHA, 0},
},
@@ -254,7 +258,9 @@
"DEFAULT",
"ALL:!eNULL",
"ALL:!NULL",
+#ifdef BORINGSSL_ENABLE_RC4_TLS
"MEDIUM",
+#endif
"HIGH",
"FIPS",
"SHA",
@@ -268,7 +274,9 @@
static const char *kMustNotIncludeCECPQ1[] = {
"ALL",
"DEFAULT",
+#ifdef BORINGSSL_ENABLE_RC4_TLS
"MEDIUM",
+#endif
"HIGH",
"FIPS",
"SHA",
@@ -311,7 +319,7 @@
}
static bool TestCipherRule(const CipherTest &t) {
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
if (!ctx) {
return false;
}
@@ -343,7 +351,7 @@
}
static bool TestRuleDoesNotIncludeNull(const char *rule) {
- ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
if (!ctx) {
return false;
}
@@ -361,7 +369,7 @@
}
static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
if (!ctx) {
return false;
}
@@ -386,7 +394,7 @@
}
for (const char *rule : kBadRules) {
- ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
if (!ctx) {
return false;
}
@@ -622,7 +630,7 @@
}
// Verify the SSL_SESSION decodes.
- ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
+ bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
if (!session) {
fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
return false;
@@ -630,7 +638,7 @@
// Verify the SSL_SESSION encoding round-trips.
size_t encoded_len;
- ScopedOpenSSLBytes encoded;
+ bssl::UniquePtr<uint8_t> encoded;
uint8_t *encoded_raw;
if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
@@ -691,7 +699,7 @@
}
// Verify that the SSL_SESSION fails to decode.
- ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
+ bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
if (session) {
fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
return false;
@@ -702,7 +710,7 @@
static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
const SSL_METHOD *(*method)(void)) {
- ScopedSSL_CTX ctx(SSL_CTX_new(method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
if (!ctx) {
return false;
}
@@ -719,7 +727,7 @@
if (cipher == NULL) {
return false;
}
- ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
+ bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
if (!rfc_name) {
return false;
}
@@ -734,7 +742,9 @@
static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
{ SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
+#ifdef BORINGSSL_ENABLE_RC4_TLS
{ SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
+#endif
{ TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
{ TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
{ TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
@@ -749,7 +759,9 @@
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
+#ifdef BORINGSSL_ENABLE_RC4_TLS
{ TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
+#endif
{ 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,
@@ -763,7 +775,7 @@
static bool TestCipherGetRFCName(void) {
for (size_t i = 0;
- i < sizeof(kCipherRFCNameTests) / sizeof(kCipherRFCNameTests[0]); i++) {
+ i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
std::string rfc_name;
if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
@@ -781,12 +793,12 @@
// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
// replaced for one of length |ticket_len| or nullptr on failure.
-static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
+static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
std::vector<uint8_t> der;
if (!DecodeBase64(&der, kOpenSSLSession)) {
return nullptr;
}
- ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
+ bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
if (!session) {
return nullptr;
}
@@ -806,7 +818,7 @@
}
static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
- ScopedBIO bio(BIO_new(BIO_s_mem()));
+ bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
if (!bio) {
return false;
}
@@ -833,12 +845,12 @@
// |ticket_len| and records the ClientHello. It returns the length of the
// ClientHello, not including the record header, on success and zero on error.
static size_t GetClientHelloLen(size_t ticket_len) {
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
- ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
if (!ctx || !session) {
return 0;
}
- ScopedSSL ssl(SSL_new(ctx.get()));
+ bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
return 0;
}
@@ -903,11 +915,11 @@
// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
// before configuring as a server.
static bool TestClientCAList() {
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
if (!ctx) {
return false;
}
- ScopedSSL ssl(SSL_new(ctx.get()));
+ bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
if (!ssl) {
return false;
}
@@ -961,8 +973,8 @@
return actual == expected_copy;
}
-static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
- ScopedSSL_SESSION ret(SSL_SESSION_new());
+static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
+ bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
if (!ret) {
return nullptr;
}
@@ -975,15 +987,15 @@
// Test that the internal session cache behaves as expected.
static bool TestInternalSessionCache() {
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
if (!ctx) {
return false;
}
// Prepare 10 test sessions.
- std::vector<ScopedSSL_SESSION> sessions;
+ std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
for (int i = 0; i < 10; i++) {
- ScopedSSL_SESSION session = CreateTestSession(i);
+ bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
if (!session) {
return false;
}
@@ -1019,7 +1031,7 @@
// Although collisions should be impossible (256-bit session IDs), the cache
// must handle them gracefully.
- ScopedSSL_SESSION collision(CreateTestSession(7));
+ bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
return false;
}
@@ -1062,7 +1074,7 @@
return static_cast<uint16_t>(seq >> 48);
}
-static ScopedX509 GetTestCertificate() {
+static bssl::UniquePtr<X509> GetTestCertificate() {
static const char kCertPEM[] =
"-----BEGIN CERTIFICATE-----\n"
"MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
@@ -1079,11 +1091,11 @@
"T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
"j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
"-----END CERTIFICATE-----\n";
- ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
- return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+ bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
+ return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
}
-static ScopedEVP_PKEY GetTestKey() {
+static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
static const char kKeyPEM[] =
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
@@ -1100,15 +1112,45 @@
"tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
"moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
"-----END RSA PRIVATE KEY-----\n";
- ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
- return ScopedEVP_PKEY(
+ bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
+ return bssl::UniquePtr<EVP_PKEY>(
PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
}
-static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
+static bssl::UniquePtr<X509> GetECDSATestCertificate() {
+ static const char kCertPEM[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
+ "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
+ "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
+ "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
+ "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
+ "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
+ "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
+ "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
+ "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
+ "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
+ "-----END CERTIFICATE-----\n";
+ bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
+ return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+}
+
+static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
+ static const char kKeyPEM[] =
+ "-----BEGIN PRIVATE KEY-----\n"
+ "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
+ "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
+ "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
+ "-----END PRIVATE KEY-----\n";
+ bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
+ return bssl::UniquePtr<EVP_PKEY>(
+ PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
+}
+
+static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
SSL_CTX *client_ctx, SSL_CTX *server_ctx,
SSL_SESSION *session) {
- ScopedSSL client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
+ bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
if (!client || !server) {
return false;
}
@@ -1156,21 +1198,21 @@
}
static bool TestSequenceNumber(bool dtls) {
- ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
- ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+ bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+ bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
if (!client_ctx || !server_ctx) {
return false;
}
- ScopedX509 cert = GetTestCertificate();
- ScopedEVP_PKEY key = GetTestKey();
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
if (!cert || !key ||
!SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
!SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
return false;
}
- ScopedSSL client, server;
+ bssl::UniquePtr<SSL> client, server;
if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
server_ctx.get(), nullptr /* no session */)) {
return false;
@@ -1225,21 +1267,21 @@
}
static bool TestOneSidedShutdown() {
- ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
- ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
if (!client_ctx || !server_ctx) {
return false;
}
- ScopedX509 cert = GetTestCertificate();
- ScopedEVP_PKEY key = GetTestKey();
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
if (!cert || !key ||
!SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
!SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
return false;
}
- ScopedSSL client, server;
+ bssl::UniquePtr<SSL> client, server;
if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
server_ctx.get(), nullptr /* no session */)) {
return false;
@@ -1280,28 +1322,28 @@
return true;
}
static bool TestSessionDuplication() {
- ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
- ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
if (!client_ctx || !server_ctx) {
return false;
}
- ScopedX509 cert = GetTestCertificate();
- ScopedEVP_PKEY key = GetTestKey();
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
if (!cert || !key ||
!SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
!SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
return false;
}
- ScopedSSL client, server;
+ bssl::UniquePtr<SSL> client, server;
if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
server_ctx.get(), nullptr /* no session */)) {
return false;
}
SSL_SESSION *session0 = SSL_get_session(client.get());
- ScopedSSL_SESSION session1(SSL_SESSION_dup(session0, 1));
+ bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
if (!session1) {
return false;
}
@@ -1312,12 +1354,12 @@
if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
return false;
}
- ScopedOpenSSLBytes free_s0(s0_bytes);
+ bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
return false;
}
- ScopedOpenSSLBytes free_s1(s1_bytes);
+ bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
}
@@ -1340,13 +1382,13 @@
}
static bool TestSetFD() {
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
if (!ctx) {
return false;
}
// Test setting different read and write FDs.
- ScopedSSL ssl(SSL_new(ctx.get()));
+ bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
if (!ssl ||
!SSL_set_rfd(ssl.get(), 1) ||
!SSL_set_wfd(ssl.get(), 2) ||
@@ -1423,13 +1465,13 @@
}
static bool TestSetBIO() {
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
if (!ctx) {
return false;
}
- ScopedSSL ssl(SSL_new(ctx.get()));
- ScopedBIO bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
+ bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
+ bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
bio3(BIO_new(BIO_s_mem()));
if (!ssl || !bio1 || !bio2 || !bio3) {
return false;
@@ -1486,15 +1528,15 @@
static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
static bool TestGetPeerCertificate() {
- ScopedX509 cert = GetTestCertificate();
- ScopedEVP_PKEY key = GetTestKey();
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
if (!cert || !key) {
return false;
}
for (uint16_t version : kVersions) {
// Configure both client and server to accept any certificate.
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
if (!ctx ||
!SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
!SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
@@ -1506,14 +1548,14 @@
ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
- ScopedSSL client, server;
+ bssl::UniquePtr<SSL> client, server;
if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
nullptr /* no session */)) {
return false;
}
// Client and server should both see the leaf certificate.
- ScopedX509 peer(SSL_get_peer_certificate(server.get()));
+ bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
return false;
@@ -1542,8 +1584,8 @@
}
static bool TestRetainOnlySHA256OfCerts() {
- ScopedX509 cert = GetTestCertificate();
- ScopedEVP_PKEY key = GetTestKey();
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
if (!cert || !key) {
return false;
}
@@ -1553,7 +1595,7 @@
if (cert_der_len < 0) {
return false;
}
- ScopedOpenSSLBytes free_cert_der(cert_der);
+ bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
SHA256(cert_der, cert_der_len, cert_sha256);
@@ -1561,7 +1603,7 @@
for (uint16_t version : kVersions) {
// Configure both client and server to accept any certificate, but the
// server must retain only the SHA-256 of the peer.
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
if (!ctx ||
!SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
!SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
@@ -1574,14 +1616,14 @@
SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
- ScopedSSL client, server;
+ bssl::UniquePtr<SSL> client, server;
if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
nullptr /* no session */)) {
return false;
}
// The peer certificate has been dropped.
- ScopedX509 peer(SSL_get_peer_certificate(server.get()));
+ bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
if (peer) {
fprintf(stderr, "%x: Peer certificate was retained.\n", version);
return false;
@@ -1604,17 +1646,17 @@
static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
size_t expected_len) {
- ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
if (!ctx) {
return false;
}
SSL_CTX_set_max_version(ctx.get(), version);
// Our default cipher list varies by CPU capabilities, so manually place the
// ChaCha20 ciphers in front.
- if (!SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
+ if (!SSL_CTX_set_cipher_list(ctx.get(), "!RC4:CHACHA20:ALL")) {
return false;
}
- ScopedSSL ssl(SSL_new(ctx.get()));
+ bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
if (!ssl) {
return false;
}
@@ -1654,13 +1696,28 @@
// Tests that our ClientHellos do not change unexpectedly.
static bool TestClientHello() {
static const uint8_t kSSL3ClientHello[] = {
- 0x16, 0x03, 0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x43, 0x03, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1c, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x33, 0xc0, 0x0a, 0xc0,
- 0x14, 0x00, 0x39, 0xc0, 0x07, 0xc0, 0x11, 0x00, 0x2f, 0x00, 0x35,
- 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04, 0x00, 0xff, 0x01, 0x00,
+ 0x16,
+ 0x03, 0x00,
+ 0x00, 0x3f,
+ 0x01,
+ 0x00, 0x00, 0x3b,
+ 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x00, 0x14,
+ 0xc0, 0x09,
+ 0xc0, 0x13,
+ 0x00, 0x33,
+ 0xc0, 0x0a,
+ 0xc0, 0x14,
+ 0x00, 0x39,
+ 0x00, 0x2f,
+ 0x00, 0x35,
+ 0x00, 0x0a,
+ 0x00, 0xff, 0x01, 0x00,
};
if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
sizeof(kSSL3ClientHello))) {
@@ -1668,12 +1725,27 @@
}
static const uint8_t kTLS1ClientHello[] = {
- 0x16, 0x03, 0x01, 0x00, 0x66, 0x01, 0x00, 0x00, 0x62, 0x03, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xc0, 0x09,
- 0xc0, 0x13, 0x00, 0x33, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x39, 0xc0, 0x07,
- 0xc0, 0x11, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04,
+ 0x16,
+ 0x03, 0x01,
+ 0x00, 0x5e,
+ 0x01,
+ 0x00, 0x00, 0x5a,
+ 0x03, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x00, 0x12,
+ 0xc0, 0x09,
+ 0xc0, 0x13,
+ 0x00, 0x33,
+ 0xc0, 0x0a,
+ 0xc0, 0x14,
+ 0x00, 0x39,
+ 0x00, 0x2f,
+ 0x00, 0x35,
+ 0x00, 0x0a,
0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
@@ -1684,12 +1756,27 @@
}
static const uint8_t kTLS11ClientHello[] = {
- 0x16, 0x03, 0x01, 0x00, 0x66, 0x01, 0x00, 0x00, 0x62, 0x03, 0x02, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xc0, 0x09,
- 0xc0, 0x13, 0x00, 0x33, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x39, 0xc0, 0x07,
- 0xc0, 0x11, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04,
+ 0x16,
+ 0x03, 0x01,
+ 0x00, 0x5e,
+ 0x01,
+ 0x00, 0x00, 0x5a,
+ 0x03, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x00, 0x12,
+ 0xc0, 0x09,
+ 0xc0, 0x13,
+ 0x00, 0x33,
+ 0xc0, 0x0a,
+ 0xc0, 0x14,
+ 0x00, 0x39,
+ 0x00, 0x2f,
+ 0x00, 0x35,
+ 0x00, 0x0a,
0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
@@ -1700,21 +1787,20 @@
}
static const uint8_t kTLS12ClientHello[] = {
- 0x16, 0x03, 0x01, 0x00, 0xa4, 0x01, 0x00, 0x00, 0xa0, 0x03, 0x03, 0x00,
+ 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcc, 0xa9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
- 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0xc0, 0x07, 0xc0, 0x11, 0x00, 0x9c,
- 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a,
- 0x00, 0x05, 0x00, 0x04, 0x01, 0x00, 0x00, 0x35, 0xff, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
- 0x12, 0x00, 0x10, 0x06, 0x01, 0x06, 0x03, 0x05, 0x01, 0x05, 0x03, 0x04,
- 0x01, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01,
- 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
- 0x18,
+ 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
+ 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
+ 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
+ 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x07, 0x02, 0x06, 0x01, 0x06,
+ 0x03, 0x07, 0x01, 0x05, 0x01, 0x05, 0x03, 0x07, 0x00, 0x04, 0x01, 0x04,
+ 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
};
if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
sizeof(kTLS12ClientHello))) {
@@ -1727,7 +1813,7 @@
return true;
}
-static ScopedSSL_SESSION g_last_session;
+static bssl::UniquePtr<SSL_SESSION> g_last_session;
static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
// Save the most recent session.
@@ -1735,13 +1821,13 @@
return 1;
}
-static ScopedSSL_SESSION CreateClientSession(SSL_CTX *client_ctx,
+static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
SSL_CTX *server_ctx) {
g_last_session = nullptr;
SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
// Connect client and server to get a session.
- ScopedSSL client, server;
+ bssl::UniquePtr<SSL> client, server;
if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
nullptr /* no session */)) {
fprintf(stderr, "Failed to connect client and server.\n");
@@ -1763,7 +1849,7 @@
static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
SSL_SESSION *session,
bool reused) {
- ScopedSSL client, server;
+ bssl::UniquePtr<SSL> client, server;
if (!ConnectClientAndServer(&client, &server, client_ctx,
server_ctx, session)) {
fprintf(stderr, "Failed to connect client and server.\n");
@@ -1786,8 +1872,8 @@
}
static bool TestSessionIDContext() {
- ScopedX509 cert = GetTestCertificate();
- ScopedEVP_PKEY key = GetTestKey();
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
if (!cert || !key) {
return false;
}
@@ -1796,13 +1882,8 @@
static const uint8_t kContext2[] = {2};
for (uint16_t version : kVersions) {
- // TODO(davidben): Enable this when TLS 1.3 resumption is implemented.
- if (version == TLS1_3_VERSION) {
- continue;
- }
-
- ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
- ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
if (!server_ctx || !client_ctx ||
!SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
!SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
@@ -1819,7 +1900,7 @@
SSL_CTX_set_max_version(server_ctx.get(), version);
SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
- ScopedSSL_SESSION session =
+ bssl::UniquePtr<SSL_SESSION> session =
CreateClientSession(client_ctx.get(), server_ctx.get());
if (!session) {
fprintf(stderr, "Error getting session (version = %04x).\n", version);
@@ -1857,20 +1938,15 @@
}
static bool TestSessionTimeout() {
- ScopedX509 cert = GetTestCertificate();
- ScopedEVP_PKEY key = GetTestKey();
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
if (!cert || !key) {
return false;
}
for (uint16_t version : kVersions) {
- // TODO(davidben): Enable this when TLS 1.3 resumption is implemented.
- if (version == TLS1_3_VERSION) {
- continue;
- }
-
- ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
- ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
if (!server_ctx || !client_ctx ||
!SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
!SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
@@ -1886,7 +1962,7 @@
SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
- ScopedSSL_SESSION session =
+ bssl::UniquePtr<SSL_SESSION> session =
CreateClientSession(client_ctx.get(), server_ctx.get());
if (!session) {
fprintf(stderr, "Error getting session (version = %04x).\n", version);
@@ -1915,6 +1991,114 @@
return true;
}
+static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
+ SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
+ SSL_set_SSL_CTX(ssl, ctx);
+ return SSL_TLSEXT_ERR_OK;
+}
+
+static bool TestSNICallback() {
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
+ bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
+ if (!cert || !key || !cert2 || !key2) {
+ return false;
+ }
+
+ // At each version, test that switching the |SSL_CTX| at the SNI callback
+ // behaves correctly.
+ for (uint16_t version : kVersions) {
+ if (version == SSL3_VERSION) {
+ continue;
+ }
+
+ static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
+
+ bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
+ if (!server_ctx || !server_ctx2 || !client_ctx ||
+ !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
+ !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
+ !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
+ !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
+ // Historically signing preferences would be lost in some cases with the
+ // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
+ // this doesn't happen when |version| is TLS 1.2, configure the private
+ // key to only sign SHA-256.
+ !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
+ &kECDSAWithSHA256, 1)) {
+ return false;
+ }
+
+ SSL_CTX_set_min_version(client_ctx.get(), version);
+ SSL_CTX_set_max_version(client_ctx.get(), version);
+ SSL_CTX_set_min_version(server_ctx.get(), version);
+ SSL_CTX_set_max_version(server_ctx.get(), version);
+ SSL_CTX_set_min_version(server_ctx2.get(), version);
+ SSL_CTX_set_max_version(server_ctx2.get(), version);
+
+ SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
+ SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
+
+ bssl::UniquePtr<SSL> client, server;
+ if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
+ server_ctx.get(), nullptr)) {
+ fprintf(stderr, "Handshake failed at version %04x.\n", version);
+ return false;
+ }
+
+ // The client should have received |cert2|.
+ bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
+ if (!peer ||
+ X509_cmp(peer.get(), cert2.get()) != 0) {
+ fprintf(stderr, "Incorrect certificate received at version %04x.\n",
+ version);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
+ SSL_set_max_version(ctx->ssl, TLS1_2_VERSION);
+ return 1;
+}
+
+// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
+// maximum version.
+static bool TestEarlyCallbackVersionSwitch() {
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
+ bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
+ bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
+ if (!cert || !key || !server_ctx || !client_ctx ||
+ !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
+ !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
+ return false;
+ }
+
+ SSL_CTX_set_max_version(client_ctx.get(), TLS1_3_VERSION);
+ SSL_CTX_set_max_version(server_ctx.get(), TLS1_3_VERSION);
+
+ SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
+
+ bssl::UniquePtr<SSL> client, server;
+ if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
+ server_ctx.get(), nullptr)) {
+ return false;
+ }
+
+ if (SSL_version(client.get()) != TLS1_2_VERSION) {
+ fprintf(stderr, "Early callback failed to switch the maximum version.\n");
+ return false;
+ }
+
+ return true;
+}
+
int main() {
CRYPTO_library_init();
@@ -1948,7 +2132,9 @@
!TestRetainOnlySHA256OfCerts() ||
!TestClientHello() ||
!TestSessionIDContext() ||
- !TestSessionTimeout()) {
+ !TestSessionTimeout() ||
+ !TestSNICallback() ||
+ !TestEarlyCallbackVersionSwitch()) {
ERR_print_errors_fp(stderr);
return 1;
}
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c
index 5e790a4..0cdcb39 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -124,6 +124,7 @@
#include <openssl/type_check.h>
#include "internal.h"
+#include "../crypto/internal.h"
static int ssl_check_clienthello_tlsext(SSL *ssl);
@@ -327,7 +328,7 @@
*out_group_ids_len = ssl->supported_group_list_len;
if (!*out_group_ids) {
*out_group_ids = kDefaultGroups;
- *out_group_ids_len = sizeof(kDefaultGroups) / sizeof(kDefaultGroups[0]);
+ *out_group_ids_len = OPENSSL_ARRAY_SIZE(kDefaultGroups);
}
}
@@ -512,29 +513,24 @@
* customisable at some point, for now include everything we support. */
static const uint16_t kDefaultSignatureAlgorithms[] = {
- SSL_SIGN_RSA_PKCS1_SHA512,
- SSL_SIGN_ECDSA_SECP521R1_SHA512,
-
- SSL_SIGN_RSA_PKCS1_SHA384,
- SSL_SIGN_ECDSA_SECP384R1_SHA384,
-
- SSL_SIGN_RSA_PKCS1_SHA256,
- SSL_SIGN_ECDSA_SECP256R1_SHA256,
-
- SSL_SIGN_RSA_PKCS1_SHA1,
- SSL_SIGN_ECDSA_SHA1,
-};
-
-static const uint16_t kDefaultTLS13SignatureAlgorithms[] = {
+ /* For now, do not ship RSA-PSS signature algorithms on Android's system
+ * BoringSSL. Once TLS 1.3 is finalized and the change in Chrome has stuck,
+ * restore them. */
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
SSL_SIGN_RSA_PSS_SHA512,
+#endif
SSL_SIGN_RSA_PKCS1_SHA512,
SSL_SIGN_ECDSA_SECP521R1_SHA512,
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
SSL_SIGN_RSA_PSS_SHA384,
+#endif
SSL_SIGN_RSA_PKCS1_SHA384,
SSL_SIGN_ECDSA_SECP384R1_SHA384,
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
SSL_SIGN_RSA_PSS_SHA256,
+#endif
SSL_SIGN_RSA_PKCS1_SHA256,
SSL_SIGN_ECDSA_SECP256R1_SHA256,
@@ -543,22 +539,8 @@
};
size_t tls12_get_psigalgs(SSL *ssl, const uint16_t **psigs) {
- uint16_t version;
- if (ssl->s3->have_version) {
- version = ssl3_protocol_version(ssl);
- } else {
- version = ssl->method->version_from_wire(ssl->client_version);
- }
-
- if (version >= TLS1_3_VERSION) {
- *psigs = kDefaultTLS13SignatureAlgorithms;
- return sizeof(kDefaultTLS13SignatureAlgorithms) /
- sizeof(kDefaultTLS13SignatureAlgorithms[0]);
- }
-
*psigs = kDefaultSignatureAlgorithms;
- return sizeof(kDefaultSignatureAlgorithms) /
- sizeof(kDefaultSignatureAlgorithms[0]);
+ return OPENSSL_ARRAY_SIZE(kDefaultSignatureAlgorithms);
}
int tls12_check_peer_sigalg(SSL *ssl, int *out_alert, uint16_t sigalg) {
@@ -588,16 +570,15 @@
* settings. */
void ssl_set_client_disabled(SSL *ssl) {
CERT *c = ssl->cert;
- const uint16_t *sigalgs;
- size_t i, sigalgslen;
int have_rsa = 0, have_ecdsa = 0;
c->mask_a = 0;
c->mask_k = 0;
/* 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(ssl, &sigalgs);
- for (i = 0; i < sigalgslen; i++) {
+ const uint16_t *sigalgs;
+ size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
+ for (size_t i = 0; i < num_sigalgs; i++) {
switch (sigalgs[i]) {
case SSL_SIGN_RSA_PSS_SHA512:
case SSL_SIGN_RSA_PSS_SHA384:
@@ -801,6 +782,16 @@
* https://tools.ietf.org/html/rfc5746 */
static int ext_ri_add_clienthello(SSL *ssl, CBB *out) {
+ uint16_t min_version, max_version;
+ if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
+ return 0;
+ }
+
+ /* Renegotiation indication is not necessary in TLS 1.3. */
+ if (min_version >= TLS1_3_VERSION) {
+ return 1;
+ }
+
CBB contents, prev_finished;
if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
@@ -943,12 +934,14 @@
*
* https://tools.ietf.org/html/rfc7627 */
-static void ext_ems_init(SSL *ssl) {
- ssl->s3->tmp.extended_master_secret = 0;
-}
-
static int ext_ems_add_clienthello(SSL *ssl, CBB *out) {
- if (ssl->version == SSL3_VERSION) {
+ uint16_t min_version, max_version;
+ if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
+ return 0;
+ }
+
+ /* Extended master secret is not necessary in TLS 1.3. */
+ if (min_version >= TLS1_3_VERSION || max_version <= SSL3_VERSION) {
return 1;
}
@@ -962,6 +955,17 @@
static int ext_ems_parse_serverhello(SSL *ssl, uint8_t *out_alert,
CBS *contents) {
+ /* Whether EMS is negotiated may not change on renegotation. */
+ if (ssl->s3->initial_handshake_complete) {
+ if ((contents != NULL) != ssl->s3->tmp.extended_master_secret) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_EMS_MISMATCH);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+
+ return 1;
+ }
+
if (contents == NULL) {
return 1;
}
@@ -1017,7 +1021,14 @@
* https://tools.ietf.org/html/rfc5077 */
static int ext_ticket_add_clienthello(SSL *ssl, CBB *out) {
- if (SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
+ uint16_t min_version, max_version;
+ if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
+ return 0;
+ }
+
+ /* TLS 1.3 uses a different ticket extension. */
+ if (min_version >= TLS1_3_VERSION ||
+ SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
return 1;
}
@@ -1030,7 +1041,10 @@
* without upstream's 3c3f0259238594d77264a78944d409f2127642c4. */
if (!ssl->s3->initial_handshake_complete &&
ssl->session != NULL &&
- ssl->session->tlsext_tick != NULL) {
+ ssl->session->tlsext_tick != NULL &&
+ /* Don't send TLS 1.3 session tickets in the ticket extension. */
+ ssl->method->version_from_wire(ssl->session->ssl_version) <
+ TLS1_3_VERSION) {
ticket_data = ssl->session->tlsext_tick;
ticket_len = ssl->session->tlsext_ticklen;
}
@@ -1098,19 +1112,18 @@
return 1;
}
- const uint16_t *sigalgs_data;
- const size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs_data);
+ const uint16_t *sigalgs;
+ const size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
- CBB contents, sigalgs;
+ CBB contents, sigalgs_cbb;
if (!CBB_add_u16(out, TLSEXT_TYPE_signature_algorithms) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
- !CBB_add_u16_length_prefixed(&contents, &sigalgs)) {
+ !CBB_add_u16_length_prefixed(&contents, &sigalgs_cbb)) {
return 0;
}
- size_t i;
- for (i = 0; i < sigalgs_len; i++) {
- if (!CBB_add_u16(&sigalgs, sigalgs_data[i])) {
+ for (size_t i = 0; i < num_sigalgs; i++) {
+ if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
return 0;
}
}
@@ -1124,9 +1137,9 @@
static int ext_sigalgs_parse_clienthello(SSL *ssl, uint8_t *out_alert,
CBS *contents) {
- OPENSSL_free(ssl->cert->peer_sigalgs);
- ssl->cert->peer_sigalgs = NULL;
- ssl->cert->peer_sigalgslen = 0;
+ OPENSSL_free(ssl->s3->hs->peer_sigalgs);
+ ssl->s3->hs->peer_sigalgs = NULL;
+ ssl->s3->hs->num_peer_sigalgs = 0;
if (contents == NULL) {
return 1;
@@ -1428,7 +1441,7 @@
}
/* Session resumption uses the original session information. */
- if (ssl->session == NULL &&
+ if (!ssl->s3->session_reused &&
!CBS_stow(
contents,
&ssl->s3->new_session->tlsext_signed_cert_timestamp_list,
@@ -1447,7 +1460,7 @@
static int ext_sct_add_serverhello(SSL *ssl, CBB *out) {
/* The extension shouldn't be sent when resuming sessions. */
- if (ssl->session != NULL ||
+ if (ssl->s3->session_reused ||
ssl->ctx->signed_cert_timestamp_list_length == 0) {
return 1;
}
@@ -1972,6 +1985,89 @@
}
+/* Pre Shared Key
+ *
+ * https://tools.ietf.org/html/draft-ietf-tls-tls13-14 */
+
+static int ext_pre_shared_key_add_clienthello(SSL *ssl, CBB *out) {
+ uint16_t min_version, max_version;
+ if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
+ return 0;
+ }
+
+ if (max_version < TLS1_3_VERSION || ssl->session == NULL ||
+ ssl->method->version_from_wire(ssl->session->ssl_version) <
+ TLS1_3_VERSION) {
+ return 1;
+ }
+
+ CBB contents, identities, identity;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &identities) ||
+ !CBB_add_u16_length_prefixed(&identities, &identity) ||
+ !CBB_add_bytes(&identity, ssl->session->tlsext_tick,
+ ssl->session->tlsext_ticklen)) {
+ return 0;
+ }
+
+ return CBB_flush(out);
+}
+
+int ssl_ext_pre_shared_key_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ uint16_t psk_id;
+ if (!CBS_get_u16(contents, &psk_id) ||
+ CBS_len(contents) != 0) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ if (psk_id != 0) {
+ *out_alert = SSL_AD_UNKNOWN_PSK_IDENTITY;
+ return 0;
+ }
+
+ return 1;
+}
+
+int ssl_ext_pre_shared_key_parse_clienthello(SSL *ssl,
+ SSL_SESSION **out_session,
+ uint8_t *out_alert,
+ CBS *contents) {
+ CBS identities, identity;
+ if (!CBS_get_u16_length_prefixed(contents, &identities) ||
+ !CBS_get_u16_length_prefixed(&identities, &identity) ||
+ CBS_len(contents) != 0) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ /* TLS 1.3 session tickets are renewed separately as part of the
+ * NewSessionTicket. */
+ int renew;
+ return tls_process_ticket(ssl, out_session, &renew, CBS_data(&identity),
+ CBS_len(&identity), NULL, 0);
+}
+
+int ssl_ext_pre_shared_key_add_serverhello(SSL *ssl, CBB *out) {
+ if (!ssl->s3->session_reused) {
+ return 1;
+ }
+
+ CBB contents;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ /* We only consider the first identity for resumption */
+ !CBB_add_u16(&contents, 0) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
/* Key Share
*
* https://tools.ietf.org/html/draft-ietf-tls-tls13-12 */
@@ -2053,8 +2149,8 @@
size_t *out_secret_len,
uint8_t *out_alert, CBS *contents) {
CBS peer_key;
- uint16_t group;
- if (!CBS_get_u16(contents, &group) ||
+ uint16_t group_id;
+ if (!CBS_get_u16(contents, &group_id) ||
!CBS_get_u16_length_prefixed(contents, &peer_key) ||
CBS_len(contents) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
@@ -2063,7 +2159,7 @@
SSL_ECDH_CTX *group_ctx = NULL;
for (size_t i = 0; i < ssl->s3->hs->groups_len; i++) {
- if (SSL_ECDH_CTX_get_id(&ssl->s3->hs->groups[i]) == group) {
+ if (SSL_ECDH_CTX_get_id(&ssl->s3->hs->groups[i]) == group_id) {
group_ctx = &ssl->s3->hs->groups[i];
break;
}
@@ -2081,6 +2177,7 @@
return 0;
}
+ ssl->s3->new_session->key_exchange_info = group_id;
ssl_handshake_clear_groups(ssl->s3->hs);
return 1;
}
@@ -2150,6 +2247,7 @@
return 0;
}
+ ssl->s3->new_session->key_exchange_info = group_id;
return 1;
}
@@ -2193,7 +2291,8 @@
static int ext_supported_groups_parse_serverhello(SSL *ssl, uint8_t *out_alert,
CBS *contents) {
- /* This extension is not expected to be echoed by servers and is ignored. */
+ /* This extension is not expected to be echoed by servers in TLS 1.2, but some
+ * BigIP servers send it nonetheless, so do not enforce this. */
return 1;
}
@@ -2265,7 +2364,7 @@
},
{
TLSEXT_TYPE_extended_master_secret,
- ext_ems_init,
+ NULL,
ext_ems_add_clienthello,
ext_ems_parse_serverhello,
ext_ems_parse_clienthello,
@@ -2360,6 +2459,14 @@
ignore_parse_clienthello,
dont_add_serverhello,
},
+ {
+ TLSEXT_TYPE_pre_shared_key,
+ NULL,
+ ext_pre_shared_key_add_clienthello,
+ forbid_parse_serverhello,
+ ignore_parse_clienthello,
+ dont_add_serverhello,
+ },
/* The final extension must be non-empty. WebSphere Application Server 7.0 is
* intolerant to the last extension being zero-length. See
* https://crbug.com/363583. */
@@ -2785,6 +2892,10 @@
*out_renew_ticket = 0;
*out_session = NULL;
+ if (SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
+ goto done;
+ }
+
if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
goto done;
}
@@ -2874,6 +2985,12 @@
memcpy(session->session_id, session_id, session_id_len);
session->session_id_length = session_id_len;
+ if (!ssl_session_is_context_valid(ssl, session) ||
+ !ssl_session_is_time_valid(ssl, session)) {
+ SSL_SESSION_free(session);
+ session = NULL;
+ }
+
*out_session = session;
done:
@@ -2889,13 +3006,12 @@
return 1;
}
- CERT *const cert = ssl->cert;
- OPENSSL_free(cert->peer_sigalgs);
- cert->peer_sigalgs = NULL;
- cert->peer_sigalgslen = 0;
+ SSL_HANDSHAKE *hs = ssl->s3->hs;
+ OPENSSL_free(hs->peer_sigalgs);
+ hs->peer_sigalgs = NULL;
+ hs->num_peer_sigalgs = 0;
size_t num_sigalgs = CBS_len(in_sigalgs);
-
if (num_sigalgs % 2 != 0) {
return 0;
}
@@ -2909,18 +3025,16 @@
/* This multiplication doesn't overflow because sizeof(uint16_t) is two
* and we just divided |num_sigalgs| by two. */
- cert->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
- if (cert->peer_sigalgs == NULL) {
+ hs->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
+ if (hs->peer_sigalgs == NULL) {
return 0;
}
- cert->peer_sigalgslen = num_sigalgs;
+ hs->num_peer_sigalgs = num_sigalgs;
CBS sigalgs;
CBS_init(&sigalgs, CBS_data(in_sigalgs), CBS_len(in_sigalgs));
-
- size_t i;
- for (i = 0; i < num_sigalgs; i++) {
- if (!CBS_get_u16(&sigalgs, &cert->peer_sigalgs[i])) {
+ for (size_t i = 0; i < num_sigalgs; i++) {
+ if (!CBS_get_u16(&sigalgs, &hs->peer_sigalgs[i])) {
return 0;
}
}
@@ -2930,7 +3044,7 @@
int tls1_choose_signature_algorithm(SSL *ssl, uint16_t *out) {
CERT *cert = ssl->cert;
- size_t i, j;
+ SSL_HANDSHAKE *hs = ssl->s3->hs;
/* Before TLS 1.2, the signature algorithm isn't negotiated as part of the
* handshake. It is fixed at MD5-SHA1 for RSA and SHA1 for ECDSA. */
@@ -2949,26 +3063,25 @@
}
const uint16_t *sigalgs;
- size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs);
+ size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
if (cert->sigalgs != NULL) {
sigalgs = cert->sigalgs;
- sigalgs_len = cert->sigalgs_len;
+ num_sigalgs = cert->num_sigalgs;
}
- const uint16_t *peer_sigalgs = cert->peer_sigalgs;
- size_t peer_sigalgs_len = cert->peer_sigalgslen;
- if (peer_sigalgs_len == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
+ const uint16_t *peer_sigalgs = hs->peer_sigalgs;
+ size_t num_peer_sigalgs = hs->num_peer_sigalgs;
+ if (num_peer_sigalgs == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
/* If the client didn't specify any signature_algorithms extension then
* we can assume that it supports SHA1. See
* http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
static const uint16_t kDefaultPeerAlgorithms[] = {SSL_SIGN_RSA_PKCS1_SHA1,
SSL_SIGN_ECDSA_SHA1};
peer_sigalgs = kDefaultPeerAlgorithms;
- peer_sigalgs_len =
- sizeof(kDefaultPeerAlgorithms) / sizeof(kDefaultPeerAlgorithms);
+ num_peer_sigalgs = OPENSSL_ARRAY_SIZE(kDefaultPeerAlgorithms);
}
- for (i = 0; i < sigalgs_len; i++) {
+ for (size_t i = 0; i < num_sigalgs; i++) {
uint16_t sigalg = sigalgs[i];
/* SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal value and should never be
* negotiated. */
@@ -2977,7 +3090,7 @@
continue;
}
- for (j = 0; j < peer_sigalgs_len; j++) {
+ for (size_t j = 0; j < num_peer_sigalgs; j++) {
if (sigalg == peer_sigalgs[j]) {
*out = sigalg;
return 1;
diff --git a/src/ssl/test/PORTING.md b/src/ssl/test/PORTING.md
new file mode 100644
index 0000000..1d5ac57
--- /dev/null
+++ b/src/ssl/test/PORTING.md
@@ -0,0 +1,106 @@
+# Porting to Other Implementations
+
+## Introduction
+
+This document provides an overview of the test runner and how to
+integrate it with other stacks. So far we have it working with
+BoringSSL and some incomplete integrations with NSS and OpenSSL.
+
+Note that supporting non-BoringSSL implementations is a work in
+progress and interfaces may change in the future. Consumers should pin
+to a particular revision rather than using BoringSSL’s master branch
+directly. As we gain experience with other implementations, we hope to
+make further improvements to portability, so please contact
+davidben@google.com and ekr@rtfm.com if implementing a new shim.
+
+
+## Integration Architecture
+
+The test runner integrates with the TLS stack under test through a
+“shim”: a command line program which encapsulates the stack. By
+default, the shim points to the BoringSSL shim in the same source
+tree, but any program can be supplied via the `-shim-path` flag. The
+runner opens up a server socket and provides the shim with a `-port`
+argument that points to that socket. The shim always connects to the
+runner as a TCP client even when acting as a TLS server. For DTLS,
+there is a small framing layer that gives packet boundaries over
+TCP. The shim can also pass a variety of command line arguments which
+are used to configure the stack under test. These can be found at
+`test_config.cc`.
+
+
+The shim reports success by exiting with a `0` error code and failure by
+reporting a non-zero error code and generally sending a textual error
+value to stderr. Many of the tests expect specific error string (such
+as `NO_SHARED_CIPHER`) that indicates what went wrong.
+
+
+## Compatibility Issues
+
+There are a number of situations in which the runner might succeed
+with some tests and not others:
+
+* Defects in the stack under test
+* Features which haven’t yet been implemented
+* Failure to implement one or more of the command line flags the runner uses with the shim
+* Disagreement about the right behavior/interpretation of the spec
+
+
+We have implemented several features which allow implementations to ease these compatibility issues.
+
+### Configuration File
+
+The runner can be supplied with a JSON configuration file which is
+intended to allow for a per-stack mapping. This file currently takes
+two directives:
+
+
+* `DisabledTests`: A JSON map consisting of the pattern matching the
+ tests to be disabled as the key and some sort of reason why it was
+ disabled as the value. The key is used as a match against the test
+ name. The value is ignored and is just used for documentation
+ purposes so you can remember why you disabled a
+ test. `-include-disabled` overrides this filter.
+
+* `ErrorMap`: A JSON map from the internal errors the runner expects to
+ the error strings that your implementation spits out. Generally
+ you’ll need to map every error, but if you also provide the
+ ` -loose-errors` flag, then every un-mapped error just gets mapped to
+ the empty string and treated as if it matched every error the runner
+ expects.
+
+
+The `-shim-config` flag is used to provide the config file.
+
+
+### Unimplemented Features
+If the shim encounters some request from the runner that it knows it
+can’t fulfill (e.g., a command line flag that it doesn’t recognize),
+then it can exit with the special code `89`. Shims are recommended to
+use this exit code on unknown command-line arguments.
+
+The test runner interprets this as “unimplemented” and skips the
+test. If run normally, this will cause the test runner to report that
+the entire test suite failed. The `-allow-unimplemented` flag suppresses
+this behavior and causes the test runner to ignore these tests for the
+purpose of evaluating the success or failure of the test suite.
+
+
+### Malloc Tests
+
+The test runner can also be used to stress malloc failure
+codepaths. If passed `-malloc-test=0`, the runner will run each test
+repeatedly with an incrementing `MALLOC_NUMBER_TO_FAIL` environment
+variable. The shim should then replace the malloc implementation with
+one which fails at the specified number of calls. If there are not
+enough calls to reach the number, the shim should fail with exit code
+`88`. This signals to the runner that the test has completed.
+
+See `crypto/test/malloc.cc` for an example malloc implementation.
+
+
+## Example: Running Against NSS
+
+```
+DYLD_LIBRARY_PATH=~/dev/nss-dev/nss-sandbox/dist/Darwin15.6.0_64_DBG.OBJ/lib go test -shim-path ~/dev/nss-dev/nss-sandbox/dist/Darwin15.6.0_64_DBG.OBJ/bin/nss_bogo_shim -loose-errors -allow-unimplemented -shim-config ~/dev/nss-dev/nss-sandbox/nss/external_tests/nss_bogo_shim/config.json
+```
diff --git a/src/ssl/test/README.md b/src/ssl/test/README.md
index 7a46c32..7da29eb 100644
--- a/src/ssl/test/README.md
+++ b/src/ssl/test/README.md
@@ -33,3 +33,6 @@
* `test_config.h`, `test_config.cc`: the command-line flags which control the
shim's behavior.
* `bssl_shim.cc`: the shim binary itself.
+
+For porting the test suite to a different implementation see
+[PORTING.md](./PORTING.md).
diff --git a/src/ssl/test/async_bio.cc b/src/ssl/test/async_bio.cc
index 7a5737b..605b33a 100644
--- a/src/ssl/test/async_bio.cc
+++ b/src/ssl/test/async_bio.cc
@@ -17,6 +17,7 @@
#include <errno.h>
#include <string.h>
+#include <openssl/bio.h>
#include <openssl/mem.h>
@@ -150,12 +151,12 @@
} // namespace
-ScopedBIO AsyncBioCreate() {
- return ScopedBIO(BIO_new(&g_async_bio_method));
+bssl::UniquePtr<BIO> AsyncBioCreate() {
+ return bssl::UniquePtr<BIO>(BIO_new(&g_async_bio_method));
}
-ScopedBIO AsyncBioCreateDatagram() {
- ScopedBIO ret(BIO_new(&g_async_bio_method));
+bssl::UniquePtr<BIO> AsyncBioCreateDatagram() {
+ bssl::UniquePtr<BIO> ret(BIO_new(&g_async_bio_method));
if (!ret) {
return nullptr;
}
diff --git a/src/ssl/test/async_bio.h b/src/ssl/test/async_bio.h
index fbc4016..9974139 100644
--- a/src/ssl/test/async_bio.h
+++ b/src/ssl/test/async_bio.h
@@ -17,20 +17,18 @@
#include <openssl/bio.h>
-#include "../../crypto/test/scoped_types.h"
-
// AsyncBioCreate creates a filter BIO for testing asynchronous state
// machines which consume a stream socket. Reads and writes will fail
// and return EAGAIN unless explicitly allowed. Each async BIO has a
// read quota and a write quota. Initially both are zero. As each is
// incremented, bytes are allowed to flow through the BIO.
-ScopedBIO AsyncBioCreate();
+bssl::UniquePtr<BIO> AsyncBioCreate();
// AsyncBioCreateDatagram creates a filter BIO for testing for
// asynchronous state machines which consume datagram sockets. The read
// and write quota count in packets rather than bytes.
-ScopedBIO AsyncBioCreateDatagram();
+bssl::UniquePtr<BIO> AsyncBioCreateDatagram();
// AsyncBioAllowRead increments |bio|'s read quota by |count|.
void AsyncBioAllowRead(BIO *bio, size_t count);
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 2a4db6b..a5bea16 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -43,23 +43,25 @@
#include <openssl/bio.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
-#include <openssl/c++/digest.h>
#include <openssl/cipher.h>
#include <openssl/crypto.h>
+#include <openssl/dh.h>
+#include <openssl/digest.h>
#include <openssl/err.h>
+#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
+#include <openssl/x509.h>
#include <memory>
#include <string>
#include <vector>
-#include "../../crypto/test/scoped_types.h"
+#include "../../crypto/internal.h"
#include "async_bio.h"
#include "packeted_bio.h"
-#include "scoped_types.h"
#include "test_config.h"
namespace bssl {
@@ -88,19 +90,20 @@
BIO *async_bio = nullptr;
// packeted_bio is the packeted BIO which simulates read timeouts.
BIO *packeted_bio = nullptr;
- ScopedEVP_PKEY channel_id;
+ bssl::UniquePtr<EVP_PKEY> channel_id;
bool cert_ready = false;
- ScopedSSL_SESSION session;
- ScopedSSL_SESSION pending_session;
+ bssl::UniquePtr<SSL_SESSION> session;
+ bssl::UniquePtr<SSL_SESSION> pending_session;
bool early_callback_called = false;
bool handshake_done = false;
// private_key is the underlying private key used when testing custom keys.
- ScopedEVP_PKEY private_key;
+ bssl::UniquePtr<EVP_PKEY> private_key;
std::vector<uint8_t> private_key_result;
// private_key_retries is the number of times an asynchronous private key
// operation has been retried.
unsigned private_key_retries = 0;
bool got_new_session = false;
+ bssl::UniquePtr<SSL_SESSION> new_session;
bool ticket_decrypt_done = false;
bool alpn_select_done = false;
};
@@ -134,20 +137,21 @@
return (TestState *)SSL_get_ex_data(ssl, g_state_index);
}
-static ScopedX509 LoadCertificate(const std::string &file) {
- ScopedBIO bio(BIO_new(BIO_s_file()));
+static bssl::UniquePtr<X509> LoadCertificate(const std::string &file) {
+ bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
return nullptr;
}
- return ScopedX509(PEM_read_bio_X509(bio.get(), NULL, NULL, NULL));
+ return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), NULL, NULL, NULL));
}
-static ScopedEVP_PKEY LoadPrivateKey(const std::string &file) {
- ScopedBIO bio(BIO_new(BIO_s_file()));
+static bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(const std::string &file) {
+ bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
return nullptr;
}
- return ScopedEVP_PKEY(PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
+ return bssl::UniquePtr<EVP_PKEY>(
+ PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
}
static int AsyncPrivateKeyType(SSL *ssl) {
@@ -315,8 +319,8 @@
}
};
-static bool GetCertificate(SSL *ssl, ScopedX509 *out_x509,
- ScopedEVP_PKEY *out_pkey) {
+static bool GetCertificate(SSL *ssl, bssl::UniquePtr<X509> *out_x509,
+ bssl::UniquePtr<EVP_PKEY> *out_pkey) {
const TestConfig *config = GetTestConfig(ssl);
if (!config->digest_prefs.empty()) {
@@ -370,8 +374,8 @@
}
static bool InstallCertificate(SSL *ssl) {
- ScopedX509 x509;
- ScopedEVP_PKEY pkey;
+ bssl::UniquePtr<X509> x509;
+ bssl::UniquePtr<EVP_PKEY> pkey;
if (!GetCertificate(ssl, &x509, &pkey)) {
return false;
}
@@ -451,8 +455,8 @@
return -1;
}
- ScopedX509 x509;
- ScopedEVP_PKEY pkey;
+ bssl::UniquePtr<X509> x509;
+ bssl::UniquePtr<EVP_PKEY> pkey;
if (!GetCertificate(ssl, &x509, &pkey)) {
return -1;
}
@@ -645,8 +649,7 @@
static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
GetTestState(ssl)->got_new_session = true;
- // BoringSSL passes a reference to |session|.
- SSL_SESSION_free(session);
+ GetTestState(ssl)->new_session.reset(session);
return 1;
}
@@ -798,8 +801,8 @@
const int sock_;
};
-static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
- ScopedSSL_CTX ssl_ctx(SSL_CTX_new(
+static bssl::UniquePtr<SSL_CTX> SetupCtx(const TestConfig *config) {
+ bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(
config->is_dtls ? DTLS_method() : TLS_method()));
if (!ssl_ctx) {
return nullptr;
@@ -830,7 +833,7 @@
return nullptr;
}
- ScopedDH dh(DH_get_2048_256(NULL));
+ bssl::UniquePtr<DH> dh(DH_get_2048_256(NULL));
if (!dh) {
return nullptr;
}
@@ -972,7 +975,8 @@
AsyncBioAllowWrite(test_state->async_bio, 1);
return true;
case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP: {
- ScopedEVP_PKEY pkey = LoadPrivateKey(GetTestConfig(ssl)->send_channel_id);
+ bssl::UniquePtr<EVP_PKEY> pkey =
+ LoadPrivateKey(GetTestConfig(ssl)->send_channel_id);
if (!pkey) {
return false;
}
@@ -1255,10 +1259,10 @@
// true and sets |*out_session| to the negotiated SSL session. If the test is a
// resumption attempt, |is_resume| is true and |session| is the session from the
// previous exchange.
-static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
- const TestConfig *config, bool is_resume,
- SSL_SESSION *session) {
- ScopedSSL ssl(SSL_new(ssl_ctx));
+static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session,
+ SSL_CTX *ssl_ctx, const TestConfig *config,
+ bool is_resume, SSL_SESSION *session) {
+ bssl::UniquePtr<SSL> ssl(SSL_new(ssl_ctx));
if (!ssl) {
return false;
}
@@ -1318,7 +1322,7 @@
SSL_enable_tls_channel_id(ssl.get());
if (!config->async) {
// The async case will be supplied by |ChannelIdCallback|.
- ScopedEVP_PKEY pkey = LoadPrivateKey(config->send_channel_id);
+ bssl::UniquePtr<EVP_PKEY> pkey = LoadPrivateKey(config->send_channel_id);
if (!pkey || !SSL_set1_tls_channel_id(ssl.get(), pkey.get())) {
return false;
}
@@ -1396,7 +1400,7 @@
NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, NID_X25519,
};
if (!SSL_set1_curves(ssl.get(), kAllCurves,
- sizeof(kAllCurves) / sizeof(kAllCurves[0]))) {
+ OPENSSL_ARRAY_SIZE(kAllCurves))) {
return false;
}
}
@@ -1411,12 +1415,12 @@
}
SocketCloser closer(sock);
- ScopedBIO bio(BIO_new_socket(sock, BIO_NOCLOSE));
+ bssl::UniquePtr<BIO> bio(BIO_new_socket(sock, BIO_NOCLOSE));
if (!bio) {
return false;
}
if (config->is_dtls) {
- ScopedBIO packeted = PacketedBioCreate(!config->async);
+ bssl::UniquePtr<BIO> packeted = PacketedBioCreate(!config->async);
if (!packeted) {
return false;
}
@@ -1425,7 +1429,7 @@
bio = std::move(packeted);
}
if (config->async) {
- ScopedBIO async_scoped =
+ bssl::UniquePtr<BIO> async_scoped =
config->is_dtls ? AsyncBioCreateDatagram() : AsyncBioCreate();
if (!async_scoped) {
return false;
@@ -1535,8 +1539,7 @@
memset(buf.get(), 0x42, kBufLen);
static const size_t kRecordSizes[] = {
0, 1, 255, 256, 257, 16383, 16384, 16385, 32767, 32768, 32769};
- for (size_t i = 0; i < sizeof(kRecordSizes) / sizeof(kRecordSizes[0]);
- i++) {
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kRecordSizes); i++) {
const size_t len = kRecordSizes[i];
if (len > kBufLen) {
fprintf(stderr, "Bad kRecordSizes value.\n");
@@ -1621,7 +1624,7 @@
}
if (out_session) {
- out_session->reset(SSL_get1_session(ssl.get()));
+ *out_session = std::move(GetTestState(ssl.get())->new_session);
}
ret = DoShutdown(ssl.get());
@@ -1692,24 +1695,27 @@
return Usage(argv[0]);
}
- ScopedSSL_CTX ssl_ctx = SetupCtx(&config);
+ bssl::UniquePtr<SSL_CTX> ssl_ctx = SetupCtx(&config);
if (!ssl_ctx) {
ERR_print_errors_fp(stderr);
return 1;
}
- ScopedSSL_SESSION session;
- if (!DoExchange(&session, ssl_ctx.get(), &config, false /* is_resume */,
- NULL /* session */)) {
- ERR_print_errors_fp(stderr);
- return 1;
- }
+ bssl::UniquePtr<SSL_SESSION> session;
+ for (int i = 0; i < config.resume_count + 1; i++) {
+ bool is_resume = i > 0;
+ if (is_resume && !config.is_server && !session) {
+ fprintf(stderr, "No session to offer.\n");
+ return 1;
+ }
- if (config.resume &&
- !DoExchange(NULL, ssl_ctx.get(), &config, true /* is_resume */,
- session.get())) {
- ERR_print_errors_fp(stderr);
- return 1;
+ bssl::UniquePtr<SSL_SESSION> offer_session = std::move(session);
+ if (!DoExchange(&session, ssl_ctx.get(), &config, is_resume,
+ offer_session.get())) {
+ fprintf(stderr, "Connection %d failed.\n", i + 1);
+ ERR_print_errors_fp(stderr);
+ return 1;
+ }
}
return 0;
diff --git a/src/ssl/test/packeted_bio.cc b/src/ssl/test/packeted_bio.cc
index b0982b0..f7267fc 100644
--- a/src/ssl/test/packeted_bio.cc
+++ b/src/ssl/test/packeted_bio.cc
@@ -272,8 +272,8 @@
} // namespace
-ScopedBIO PacketedBioCreate(bool advance_clock) {
- ScopedBIO bio(BIO_new(&g_packeted_bio_method));
+bssl::UniquePtr<BIO> PacketedBioCreate(bool advance_clock) {
+ bssl::UniquePtr<BIO> bio(BIO_new(&g_packeted_bio_method));
if (!bio) {
return nullptr;
}
diff --git a/src/ssl/test/packeted_bio.h b/src/ssl/test/packeted_bio.h
index 9bab635..07930d4 100644
--- a/src/ssl/test/packeted_bio.h
+++ b/src/ssl/test/packeted_bio.h
@@ -18,8 +18,6 @@
#include <openssl/base.h>
#include <openssl/bio.h>
-#include "../../crypto/test/scoped_types.h"
-
#if defined(OPENSSL_WINDOWS)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
@@ -38,7 +36,7 @@
// continues reading, subject to the read deadline. Otherwise, it fails
// immediately. The caller must then call |PacketedBioAdvanceClock| before
// retrying |BIO_read|.
-ScopedBIO PacketedBioCreate(bool advance_clock);
+bssl::UniquePtr<BIO> PacketedBioCreate(bool advance_clock);
// PacketedBioGetClock returns the current time for |bio|.
timeval PacketedBioGetClock(const BIO *bio);
diff --git a/src/ssl/test/runner/alert.go b/src/ssl/test/runner/alert.go
index 363a770..b690c6f 100644
--- a/src/ssl/test/runner/alert.go
+++ b/src/ssl/test/runner/alert.go
@@ -41,6 +41,7 @@
alertNoRenegotiation alert = 100
alertMissingExtension alert = 109
alertUnsupportedExtension alert = 110
+ alertUnrecognizedName alert = 112
alertUnknownPSKIdentity alert = 115
)
@@ -70,6 +71,7 @@
alertNoRenegotiation: "no renegotiation",
alertMissingExtension: "missing extension",
alertUnsupportedExtension: "unsupported extension",
+ alertUnrecognizedName: "unrecognized name",
alertUnknownPSKIdentity: "unknown PSK identity",
}
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index f3d57c7..c73d74c 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -635,9 +635,15 @@
// return.
ALPNProtocol *string
- // AllowSessionVersionMismatch causes the server to resume sessions
- // regardless of the version associated with the session.
- AllowSessionVersionMismatch bool
+ // AcceptAnySession causes the server to resume sessions regardless of
+ // the version associated with the session or cipher suite. It also
+ // causes the server to look in both TLS 1.2 and 1.3 extensions to
+ // process a ticket.
+ AcceptAnySession bool
+
+ // SendBothTickets, if true, causes the client to send tickets in both
+ // TLS 1.2 and 1.3 extensions.
+ SendBothTickets bool
// CorruptTicket causes a client to corrupt a session ticket before
// sending it in a resume handshake.
@@ -647,14 +653,28 @@
// resumption attempt to be too large (33 bytes).
OversizedSessionId bool
+ // ExpectNoTLS12Session, if true, causes the server to fail the
+ // connection if either a session ID or TLS 1.2 ticket is offered.
+ ExpectNoTLS12Session bool
+
+ // ExpectNoTLS13PSK, if true, causes the server to fail the connection
+ // if a TLS 1.3 PSK is offered.
+ ExpectNoTLS13PSK bool
+
// RequireExtendedMasterSecret, if true, requires that the peer support
// the extended master secret option.
RequireExtendedMasterSecret bool
// NoExtendedMasterSecret causes the client and server to behave as if
- // they didn't support an extended master secret.
+ // they didn't support an extended master secret in the initial
+ // handshake.
NoExtendedMasterSecret bool
+ // NoExtendedMasterSecretOnRenegotiation causes the client and server to
+ // behave as if they didn't support an extended master secret in
+ // renegotiation handshakes.
+ NoExtendedMasterSecretOnRenegotiation bool
+
// EmptyRenegotiationInfo causes the renegotiation extension to be
// empty in a renegotiation handshake.
EmptyRenegotiationInfo bool
@@ -1027,9 +1047,26 @@
// HelloRequest in the same record as Finished.
PackHelloRequestWithFinished bool
+ // ExpectMissingKeyShare, if true, causes the TLS server to fail the
+ // connection if the selected curve appears in the client's initial
+ // ClientHello. That is, it requires that a HelloRetryRequest be sent.
+ ExpectMissingKeyShare bool
+
// SendExtraFinished, if true, causes an extra Finished message to be
// sent.
SendExtraFinished bool
+
+ // SendRequestContext, if not empty, is the request context to send in
+ // a TLS 1.3 CertificateRequest.
+ SendRequestContext []byte
+
+ // SendSNIWarningAlert, if true, causes the server to send an
+ // unrecognized_name alert before the ServerHello.
+ SendSNIWarningAlert bool
+
+ // SendCompressionMethods, if not nil, is the compression method list to
+ // send in the ClientHello.
+ SendCompressionMethods []byte
}
func (c *Config) serverInit() {
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index 46b4732..d9d4451 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -79,11 +79,12 @@
customExtension: c.config.Bugs.CustomExtension,
}
- if c.config.Bugs.SendClientVersion != 0 {
- hello.vers = c.config.Bugs.SendClientVersion
+ disableEMS := c.config.Bugs.NoExtendedMasterSecret
+ if c.cipherSuite != nil {
+ disableEMS = c.config.Bugs.NoExtendedMasterSecretOnRenegotiation
}
- if c.config.Bugs.NoExtendedMasterSecret {
+ if disableEMS {
hello.extendedMasterSecret = false
}
@@ -91,6 +92,10 @@
hello.supportedCurves = nil
}
+ if c.config.Bugs.SendCompressionMethods != nil {
+ hello.compressionMethods = c.config.Bugs.SendCompressionMethods
+ }
+
if len(c.clientVerify) > 0 && !c.config.Bugs.EmptyRenegotiationInfo {
if c.config.Bugs.BadRenegotiationInfo {
hello.secureRenegotiation = append(hello.secureRenegotiation, c.clientVerify...)
@@ -207,10 +212,24 @@
// Check that the ciphersuite/version used for the
// previous session are still valid.
cipherSuiteOk := false
- for _, id := range hello.cipherSuites {
- if id == candidateSession.cipherSuite {
- cipherSuiteOk = true
- break
+ if candidateSession.vers >= VersionTLS13 {
+ // Account for ciphers changing on resumption.
+ //
+ // TODO(davidben): This will be gone with the
+ // new cipher negotiation scheme.
+ resumeCipher := ecdhePSKSuite(candidateSession.cipherSuite)
+ for _, id := range hello.cipherSuites {
+ if ecdhePSKSuite(id) == resumeCipher {
+ cipherSuiteOk = true
+ break
+ }
+ }
+ } else {
+ for _, id := range hello.cipherSuites {
+ if id == candidateSession.cipherSuite {
+ cipherSuiteOk = true
+ break
+ }
}
}
@@ -234,39 +253,38 @@
ticket[offset] ^= 0x40
}
- if session.vers >= VersionTLS13 {
+ if session.vers >= VersionTLS13 || c.config.Bugs.SendBothTickets {
// TODO(nharper): Support sending more
// than one PSK identity.
- if session.ticketFlags&ticketAllowDHEResumption != 0 {
- var found bool
- for _, id := range hello.cipherSuites {
- if id == session.cipherSuite {
- found = true
- break
- }
- }
- if found {
- hello.pskIdentities = [][]uint8{ticket}
- hello.cipherSuites = append(hello.cipherSuites, ecdhePSKSuite(session.cipherSuite))
- }
+ if session.ticketFlags&ticketAllowDHEResumption != 0 || c.config.Bugs.SendBothTickets {
+ hello.pskIdentities = [][]uint8{ticket}
+ hello.cipherSuites = append(hello.cipherSuites, ecdhePSKSuite(session.cipherSuite))
}
- } else if ticket != nil {
- hello.sessionTicket = ticket
- // A random session ID is used to detect when the
- // server accepted the ticket and is resuming a session
- // (see RFC 5077).
- sessionIdLen := 16
- if c.config.Bugs.OversizedSessionId {
- sessionIdLen = 33
- }
- hello.sessionId = make([]byte, sessionIdLen)
- if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
- c.sendAlert(alertInternalError)
- return errors.New("tls: short read from Rand: " + err.Error())
- }
- } else {
- hello.sessionId = session.sessionId
}
+
+ if session.vers < VersionTLS13 || c.config.Bugs.SendBothTickets {
+ if ticket != nil {
+ hello.sessionTicket = ticket
+ // A random session ID is used to detect when the
+ // server accepted the ticket and is resuming a session
+ // (see RFC 5077).
+ sessionIdLen := 16
+ if c.config.Bugs.OversizedSessionId {
+ sessionIdLen = 33
+ }
+ hello.sessionId = make([]byte, sessionIdLen)
+ if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: short read from Rand: " + err.Error())
+ }
+ } else {
+ hello.sessionId = session.sessionId
+ }
+ }
+ }
+
+ if c.config.Bugs.SendClientVersion != 0 {
+ hello.vers = c.config.Bugs.SendClientVersion
}
var helloBytes []byte
@@ -669,6 +687,10 @@
var ok bool
certReq, ok = msg.(*certificateRequestMsg)
if ok {
+ if len(certReq.requestContext) != 0 {
+ return errors.New("tls: non-empty certificate request context sent in handshake")
+ }
+
if c.config.Bugs.IgnorePeerSignatureAlgorithmPreferences {
certReq.signatureAlgorithms = c.config.signSignatureAlgorithms()
}
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index fe860f8..e04075c 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -220,6 +220,19 @@
}
}
+ if config.Bugs.ExpectNoTLS12Session {
+ if len(hs.clientHello.sessionId) > 0 {
+ return fmt.Errorf("tls: client offered an unexpected session ID")
+ }
+ if len(hs.clientHello.sessionTicket) > 0 {
+ return fmt.Errorf("tls: client offered an unexpected session ticket")
+ }
+ }
+
+ if config.Bugs.ExpectNoTLS13PSK && len(hs.clientHello.pskIdentities) > 0 {
+ return fmt.Errorf("tls: client offered unexpected PSK identities")
+ }
+
if config.Bugs.NegotiateVersion != 0 {
c.vers = config.Bugs.NegotiateVersion
} else if c.haveVers && config.Bugs.NegotiateVersionOnRenego != 0 {
@@ -307,29 +320,50 @@
_, ecdsaOk := hs.cert.PrivateKey.(*ecdsa.PrivateKey)
- for i, pskIdentity := range hs.clientHello.pskIdentities {
+ pskIdentities := hs.clientHello.pskIdentities
+ if len(pskIdentities) == 0 && len(hs.clientHello.sessionTicket) > 0 && c.config.Bugs.AcceptAnySession {
+ pskIdentities = [][]uint8{hs.clientHello.sessionTicket}
+ }
+ for i, pskIdentity := range pskIdentities {
sessionState, ok := c.decryptTicket(pskIdentity)
if !ok {
continue
}
- if sessionState.vers != c.vers {
- continue
+ if !config.Bugs.AcceptAnySession {
+ if sessionState.vers != c.vers && c.config.Bugs.AcceptAnySession {
+ continue
+ }
+ if sessionState.ticketFlags&ticketAllowDHEResumption == 0 {
+ continue
+ }
+ if sessionState.ticketExpiration.Before(c.config.time()) {
+ continue
+ }
}
- if sessionState.ticketFlags&ticketAllowDHEResumption == 0 {
- continue
- }
- if sessionState.ticketExpiration.Before(c.config.time()) {
- continue
- }
+
suiteId := ecdhePSKSuite(sessionState.cipherSuite)
- suite := mutualCipherSuite(hs.clientHello.cipherSuites, suiteId)
+
+ // Check the client offered the cipher.
+ clientCipherSuites := hs.clientHello.cipherSuites
+ if config.Bugs.AcceptAnySession {
+ clientCipherSuites = []uint16{suiteId}
+ }
+ suite := mutualCipherSuite(clientCipherSuites, suiteId)
+
+ // Check the cipher is enabled by the server or is a resumption
+ // suite of one enabled by the server. Account for the cipher
+ // change on resume.
+ //
+ // TODO(davidben): The ecdhePSKSuite mess will be gone with the
+ // new cipher negotiation scheme.
var found bool
for _, id := range config.cipherSuites() {
- if id == sessionState.cipherSuite {
+ if ecdhePSKSuite(id) == suiteId {
found = true
break
}
}
+
if suite != nil && found {
hs.sessionState = sessionState
hs.suite = suite
@@ -401,6 +435,10 @@
}
}
+ if config.Bugs.ExpectMissingKeyShare && selectedKeyShare != nil {
+ return errors.New("tls: expected missing key share")
+ }
+
sendHelloRetryRequest := selectedKeyShare == nil
if config.Bugs.UnnecessaryHelloRetryRequest {
sendHelloRetryRequest = true
@@ -422,6 +460,7 @@
}
hs.writeServerHash(helloRetryRequestMsg.marshal())
c.writeRecord(recordTypeHandshake, helloRetryRequestMsg.marshal())
+ c.flushHandshake()
// Read new ClientHello.
newMsg, err := c.readHandshake()
@@ -562,6 +601,7 @@
certReq := &certificateRequestMsg{
hasSignatureAlgorithm: true,
hasRequestContext: true,
+ requestContext: config.Bugs.SendRequestContext,
}
if !config.Bugs.NoSignatureAlgorithms {
certReq.signatureAlgorithms = config.verifySignatureAlgorithms()
@@ -921,7 +961,11 @@
}
if c.vers < VersionTLS13 || config.Bugs.NegotiateEMSAtAllVersions {
- serverExtensions.extendedMasterSecret = c.vers >= VersionTLS10 && hs.clientHello.extendedMasterSecret && !c.config.Bugs.NoExtendedMasterSecret
+ disableEMS := config.Bugs.NoExtendedMasterSecret
+ if c.cipherSuite != nil {
+ disableEMS = config.Bugs.NoExtendedMasterSecretOnRenegotiation
+ }
+ serverExtensions.extendedMasterSecret = c.vers >= VersionTLS10 && hs.clientHello.extendedMasterSecret && !disableEMS
}
if c.vers < VersionTLS13 || config.Bugs.NegotiateChannelIDAtAllVersions {
@@ -965,13 +1009,17 @@
func (hs *serverHandshakeState) checkForResumption() bool {
c := hs.c
- if len(hs.clientHello.sessionTicket) > 0 {
+ ticket := hs.clientHello.sessionTicket
+ if len(ticket) == 0 && len(hs.clientHello.pskIdentities) > 0 && c.config.Bugs.AcceptAnySession {
+ ticket = hs.clientHello.pskIdentities[0]
+ }
+ if len(ticket) > 0 {
if c.config.SessionTicketsDisabled {
return false
}
var ok bool
- if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); !ok {
+ if hs.sessionState, ok = c.decryptTicket(ticket); !ok {
return false
}
} else {
@@ -986,21 +1034,23 @@
}
}
- // Never resume a session for a different SSL version.
- if !c.config.Bugs.AllowSessionVersionMismatch && c.vers != hs.sessionState.vers {
- return false
- }
-
- cipherSuiteOk := false
- // Check that the client is still offering the ciphersuite in the session.
- for _, id := range hs.clientHello.cipherSuites {
- if id == hs.sessionState.cipherSuite {
- cipherSuiteOk = true
- break
+ if !c.config.Bugs.AcceptAnySession {
+ // Never resume a session for a different SSL version.
+ if c.vers != hs.sessionState.vers {
+ return false
}
- }
- if !cipherSuiteOk {
- return false
+
+ cipherSuiteOk := false
+ // Check that the client is still offering the ciphersuite in the session.
+ for _, id := range hs.clientHello.cipherSuites {
+ if id == hs.sessionState.cipherSuite {
+ cipherSuiteOk = true
+ break
+ }
+ }
+ if !cipherSuiteOk {
+ return false
+ }
}
// Check that we also support the ciphersuite from the session.
@@ -1089,6 +1139,10 @@
hs.writeClientHash(hs.clientHello.marshal())
hs.writeServerHash(hs.hello.marshal())
+ if config.Bugs.SendSNIWarningAlert {
+ c.SendAlert(alertLevelWarning, alertUnrecognizedName)
+ }
+
c.writeRecord(recordTypeHandshake, hs.hello.marshal())
if !isPSK {
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 45d3e13..7d2a6bf 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -62,6 +62,7 @@
looseErrors = flag.Bool("loose-errors", false, "If true, allow shims to report an untranslated error code.")
shimConfigFile = flag.String("shim-config", "", "A config file to use to configure the tests for this shim.")
includeDisabled = flag.Bool("include-disabled", false, "If true, also runs disabled tests.")
+ includeRC4 = flag.Bool("include-rc4", false, "If true, test RC4 ciphersuites.")
)
// ShimConfigurations is used with the “json” package and represents a shim
@@ -294,6 +295,9 @@
// resumeSession controls whether a second connection should be tested
// which attempts to resume the first session.
resumeSession bool
+ // resumeRenewedSession controls whether a third connection should be
+ // tested which attempts to resume the second connection's session.
+ resumeRenewedSession bool
// expectResumeRejected, if true, specifies that the attempted
// resumption must be rejected by the client. This is only valid for a
// serverTest.
@@ -353,6 +357,9 @@
// sendWarningAlerts is the number of consecutive warning alerts to send
// before and after the test message.
sendWarningAlerts int
+ // sendKeyUpdates is the number of consecutive key updates to send
+ // before and after the test message.
+ sendKeyUpdates int
// expectMessageDropped, if true, means the test message is expected to
// be dropped by the client rather than echoed back.
expectMessageDropped bool
@@ -414,6 +421,32 @@
}
func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
+ if !test.noSessionCache {
+ if config.ClientSessionCache == nil {
+ config.ClientSessionCache = NewLRUClientSessionCache(1)
+ }
+ if config.ServerSessionCache == nil {
+ config.ServerSessionCache = NewLRUServerSessionCache(1)
+ }
+ }
+ if test.testType == clientTest {
+ if len(config.Certificates) == 0 {
+ config.Certificates = []Certificate{rsaCertificate}
+ }
+ } else {
+ // Supply a ServerName to ensure a constant session cache key,
+ // rather than falling back to net.Conn.RemoteAddr.
+ if len(config.ServerName) == 0 {
+ config.ServerName = "test"
+ }
+ }
+ if *fuzzer {
+ config.Bugs.NullAllCiphers = true
+ }
+ if *deterministic {
+ config.Rand = &deterministicRand{}
+ }
+
conn = &timeoutConn{conn, *idleTimeout}
if test.protocol == dtls {
@@ -589,6 +622,10 @@
}
}
+ for i := 0; i < test.sendKeyUpdates; i++ {
+ tlsConn.SendKeyUpdate()
+ }
+
for i := 0; i < test.sendEmptyRecords; i++ {
tlsConn.Write(nil)
}
@@ -645,6 +682,10 @@
}
tlsConn.Write(testMessage)
+ for i := 0; i < test.sendKeyUpdates; i++ {
+ tlsConn.SendKeyUpdate()
+ }
+
for i := 0; i < test.sendEmptyRecords; i++ {
tlsConn.Write(nil)
}
@@ -794,8 +835,16 @@
flags = append(flags, "-dtls")
}
+ var resumeCount int
if test.resumeSession {
- flags = append(flags, "-resume")
+ resumeCount++
+ if test.resumeRenewedSession {
+ resumeCount++
+ }
+ }
+
+ if resumeCount > 0 {
+ flags = append(flags, "-resume-count", strconv.Itoa(resumeCount))
}
if test.shimWritesFirst {
@@ -854,27 +903,6 @@
go func() { waitChan <- shim.Wait() }()
config := test.config
- if !test.noSessionCache {
- config.ClientSessionCache = NewLRUClientSessionCache(1)
- config.ServerSessionCache = NewLRUServerSessionCache(1)
- }
- if test.testType == clientTest {
- if len(config.Certificates) == 0 {
- config.Certificates = []Certificate{rsaCertificate}
- }
- } else {
- // Supply a ServerName to ensure a constant session cache key,
- // rather than falling back to net.Conn.RemoteAddr.
- if len(config.ServerName) == 0 {
- config.ServerName = "test"
- }
- }
- if *fuzzer {
- config.Bugs.NullAllCiphers = true
- }
- if *deterministic {
- config.Rand = &deterministicRand{}
- }
conn, err := acceptOrWait(listener, waitChan)
if err == nil {
@@ -882,29 +910,15 @@
conn.Close()
}
- if err == nil && test.resumeSession {
+ for i := 0; err == nil && i < resumeCount; i++ {
var resumeConfig Config
if test.resumeConfig != nil {
resumeConfig = *test.resumeConfig
- if len(resumeConfig.ServerName) == 0 {
- resumeConfig.ServerName = config.ServerName
- }
- if len(resumeConfig.Certificates) == 0 {
- resumeConfig.Certificates = []Certificate{rsaCertificate}
- }
- if test.newSessionsOnResume {
- if !test.noSessionCache {
- resumeConfig.ClientSessionCache = NewLRUClientSessionCache(1)
- resumeConfig.ServerSessionCache = NewLRUServerSessionCache(1)
- }
- } else {
+ if !test.newSessionsOnResume {
resumeConfig.SessionTicketKey = config.SessionTicketKey
resumeConfig.ClientSessionCache = config.ClientSessionCache
resumeConfig.ServerSessionCache = config.ServerSessionCache
}
- if *fuzzer {
- resumeConfig.Bugs.NullAllCiphers = true
- }
resumeConfig.Rand = config.Rand
} else {
resumeConfig = config
@@ -1022,7 +1036,6 @@
{"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},
{"ECDHE-RSA-AES128-SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
@@ -1031,7 +1044,6 @@
{"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},
{"CECPQ1-RSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256},
{"CECPQ1-ECDSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
{"CECPQ1-RSA-AES256-GCM-SHA384", TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
@@ -1043,9 +1055,6 @@
{"ECDHE-PSK-CHACHA20-POLY1305", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256},
{"ECDHE-PSK-AES128-GCM-SHA256", TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256},
{"ECDHE-PSK-AES256-GCM-SHA384", TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384},
- {"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},
{"NULL-SHA", TLS_RSA_WITH_NULL_SHA},
}
@@ -2002,6 +2011,15 @@
expectedError: ":TOO_MANY_WARNING_ALERTS:",
},
{
+ name: "SendKeyUpdates",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ },
+ sendKeyUpdates: 33,
+ shouldFail: true,
+ expectedError: ":TOO_MANY_KEY_UPDATES:",
+ },
+ {
name: "EmptySessionID",
config: Config{
MaxVersion: VersionTLS12,
@@ -2104,9 +2122,7 @@
FailIfSessionOffered: true,
},
},
- flags: []string{"-expect-no-session"},
- resumeSession: true,
- expectResumeRejected: true,
+ flags: []string{"-expect-no-session"},
},
{
name: "BadHelloRequest-1",
@@ -2184,7 +2200,7 @@
// elliptic curves, so no extensions are
// involved.
MaxVersion: VersionTLS12,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
Bugs: ProtocolBugs{
SendV2ClientHello: true,
},
@@ -2206,7 +2222,7 @@
// elliptic curves, so no extensions are
// involved.
MaxVersion: VersionTLS12,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
Bugs: ProtocolBugs{
SendV2ClientHello: true,
},
@@ -2231,6 +2247,64 @@
},
},
},
+ {
+ name: "SendSNIWarningAlert",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ Bugs: ProtocolBugs{
+ SendSNIWarningAlert: true,
+ },
+ },
+ },
+ {
+ testType: serverTest,
+ name: "ExtraCompressionMethods-TLS12",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ Bugs: ProtocolBugs{
+ SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6},
+ },
+ },
+ },
+ {
+ testType: serverTest,
+ name: "ExtraCompressionMethods-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":INVALID_COMPRESSION_LIST:",
+ expectedLocalError: "remote error: illegal parameter",
+ },
+ {
+ testType: serverTest,
+ name: "NoNullCompression-TLS12",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ Bugs: ProtocolBugs{
+ SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":NO_COMPRESSION_SPECIFIED:",
+ expectedLocalError: "remote error: illegal parameter",
+ },
+ {
+ testType: serverTest,
+ name: "NoNullCompression-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":INVALID_COMPRESSION_LIST:",
+ expectedLocalError: "remote error: illegal parameter",
+ },
}
testCases = append(testCases, basicTests...)
}
@@ -2238,6 +2312,19 @@
func addCipherSuiteTests() {
const bogusCipher = 0xfe00
+ if *includeRC4 {
+ testCipherSuites = append(testCipherSuites, []struct {
+ name string
+ id uint16
+ }{
+ {"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
+ {"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+ {"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},
+ }...)
+ }
+
for _, suite := range testCipherSuites {
const psk = "12345"
const pskIdentity = "luggage combo"
@@ -2313,9 +2400,6 @@
expectedClientError = ":WRONG_CIPHER_RETURNED:"
}
- // TODO(davidben,svaldez): Implement resumption for TLS 1.3.
- resumeSession := ver.version < VersionTLS13
-
testCases = append(testCases, testCase{
testType: serverTest,
protocol: protocol,
@@ -2336,7 +2420,7 @@
certFile: certFile,
keyFile: keyFile,
flags: flags,
- resumeSession: resumeSession,
+ resumeSession: true,
shouldFail: shouldServerFail,
expectedError: expectedServerError,
})
@@ -2358,7 +2442,7 @@
},
},
flags: flags,
- resumeSession: resumeSession,
+ resumeSession: true,
shouldFail: shouldClientFail,
expectedError: expectedClientError,
})
@@ -2407,12 +2491,12 @@
name: "UnsupportedCipherSuite",
config: Config{
MaxVersion: VersionTLS12,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
Bugs: ProtocolBugs{
IgnorePeerCipherPreferences: true,
},
},
- flags: []string{"-cipher", "DEFAULT:!RC4"},
+ flags: []string{"-cipher", "DEFAULT:!AES"},
shouldFail: true,
expectedError: ":WRONG_CIPHER_RETURNED:",
})
@@ -2510,24 +2594,24 @@
{
// Test that the null case (where no version-specific ciphers are set)
// works as expected.
- "RC4-SHA:AES128-SHA", // default ciphers
- "", // no ciphers specifically for TLS ≥ 1.0
- "", // no ciphers specifically for TLS ≥ 1.1
+ "DES-CBC3-SHA:AES128-SHA", // default ciphers
+ "", // no ciphers specifically for TLS ≥ 1.0
+ "", // no ciphers specifically for TLS ≥ 1.1
map[uint16]uint16{
- VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
- VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
- VersionTLS11: TLS_RSA_WITH_RC4_128_SHA,
- VersionTLS12: TLS_RSA_WITH_RC4_128_SHA,
+ VersionSSL30: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ VersionTLS10: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ VersionTLS11: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ VersionTLS12: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
},
},
{
// With ciphers_tls10 set, TLS 1.0, 1.1 and 1.2 should get a different
// cipher.
- "RC4-SHA:AES128-SHA", // default
- "AES128-SHA", // these ciphers for TLS ≥ 1.0
- "", // no ciphers specifically for TLS ≥ 1.1
+ "DES-CBC3-SHA:AES128-SHA", // default
+ "AES128-SHA", // these ciphers for TLS ≥ 1.0
+ "", // no ciphers specifically for TLS ≥ 1.1
map[uint16]uint16{
- VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionSSL30: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
@@ -2536,12 +2620,12 @@
{
// With ciphers_tls11 set, TLS 1.1 and 1.2 should get a different
// cipher.
- "RC4-SHA:AES128-SHA", // default
- "", // no ciphers specifically for TLS ≥ 1.0
- "AES128-SHA", // these ciphers for TLS ≥ 1.1
+ "DES-CBC3-SHA:AES128-SHA", // default
+ "", // no ciphers specifically for TLS ≥ 1.0
+ "AES128-SHA", // these ciphers for TLS ≥ 1.1
map[uint16]uint16{
- VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
- VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
+ VersionSSL30: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ VersionTLS10: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
},
@@ -2549,11 +2633,11 @@
{
// With both ciphers_tls10 and ciphers_tls11 set, ciphers_tls11 should
// mask ciphers_tls10 for TLS 1.1 and 1.2.
- "RC4-SHA:AES128-SHA", // default
- "AES128-SHA", // these ciphers for TLS ≥ 1.0
- "AES256-SHA", // these ciphers for TLS ≥ 1.1
+ "DES-CBC3-SHA:AES128-SHA", // default
+ "AES128-SHA", // these ciphers for TLS ≥ 1.0
+ "AES256-SHA", // these ciphers for TLS ≥ 1.1
map[uint16]uint16{
- VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionSSL30: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
VersionTLS11: TLS_RSA_WITH_AES_256_CBC_SHA,
VersionTLS12: TLS_RSA_WITH_AES_256_CBC_SHA,
@@ -2577,7 +2661,7 @@
config: Config{
MaxVersion: version,
MinVersion: version,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA},
+ CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA},
},
flags: flags,
expectedCipher: expectedCipherSuite,
@@ -2742,91 +2826,84 @@
},
})
}
+
+ testCases = append(testCases, testCase{
+ name: "NoClientCertificate-" + ver.name,
+ config: Config{
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ ClientAuth: RequireAnyClientCert,
+ },
+ shouldFail: true,
+ expectedLocalError: "client didn't provide a certificate",
+ })
+
+ testCases = append(testCases, testCase{
+ // Even if not configured to expect a certificate, OpenSSL will
+ // return X509_V_OK as the verify_result.
+ testType: serverTest,
+ name: "NoClientCertificateRequested-Server-" + ver.name,
+ config: Config{
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ },
+ flags: []string{
+ "-expect-verify-result",
+ },
+ // TODO(davidben): Switch this to true when TLS 1.3
+ // supports session resumption.
+ resumeSession: ver.version < VersionTLS13,
+ })
+
+ testCases = append(testCases, testCase{
+ // If a client certificate is not provided, OpenSSL will still
+ // return X509_V_OK as the verify_result.
+ testType: serverTest,
+ name: "NoClientCertificate-Server-" + ver.name,
+ config: Config{
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ },
+ flags: []string{
+ "-expect-verify-result",
+ "-verify-peer",
+ },
+ // TODO(davidben): Switch this to true when TLS 1.3
+ // supports session resumption.
+ resumeSession: ver.version < VersionTLS13,
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "RequireAnyClientCertificate-" + ver.name,
+ config: Config{
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ },
+ flags: []string{"-require-any-client-certificate"},
+ shouldFail: true,
+ expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
+ })
+
+ if ver.version != VersionSSL30 {
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SkipClientCertificate-" + ver.name,
+ config: Config{
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ Bugs: ProtocolBugs{
+ SkipClientCertificate: true,
+ },
+ },
+ // Setting SSL_VERIFY_PEER allows anonymous clients.
+ flags: []string{"-verify-peer"},
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ })
+ }
}
- testCases = append(testCases, testCase{
- name: "NoClientCertificate",
- config: Config{
- MaxVersion: VersionTLS12,
- ClientAuth: RequireAnyClientCert,
- },
- shouldFail: true,
- expectedLocalError: "client didn't provide a certificate",
- })
-
- testCases = append(testCases, testCase{
- name: "NoClientCertificate-TLS13",
- config: Config{
- MaxVersion: VersionTLS13,
- ClientAuth: RequireAnyClientCert,
- },
- shouldFail: true,
- expectedLocalError: "client didn't provide a certificate",
- })
-
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "RequireAnyClientCertificate",
- config: Config{
- MaxVersion: VersionTLS12,
- },
- flags: []string{"-require-any-client-certificate"},
- shouldFail: true,
- expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
- })
-
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "RequireAnyClientCertificate-TLS13",
- config: Config{
- MaxVersion: VersionTLS13,
- },
- flags: []string{"-require-any-client-certificate"},
- shouldFail: true,
- expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
- })
-
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "RequireAnyClientCertificate-SSL3",
- config: Config{
- MaxVersion: VersionSSL30,
- },
- flags: []string{"-require-any-client-certificate"},
- shouldFail: true,
- expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
- })
-
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "SkipClientCertificate",
- config: Config{
- MaxVersion: VersionTLS12,
- Bugs: ProtocolBugs{
- SkipClientCertificate: true,
- },
- },
- // Setting SSL_VERIFY_PEER allows anonymous clients.
- flags: []string{"-verify-peer"},
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- })
-
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "SkipClientCertificate-TLS13",
- config: Config{
- MaxVersion: VersionTLS13,
- Bugs: ProtocolBugs{
- SkipClientCertificate: true,
- },
- },
- // Setting SSL_VERIFY_PEER allows anonymous clients.
- flags: []string{"-verify-peer"},
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- })
-
// Client auth is only legal in certificate-based ciphers.
testCases = append(testCases, testCase{
testType: clientTest,
@@ -3015,6 +3092,57 @@
}
}
}
+
+ // Switching EMS on renegotiation is forbidden.
+ testCases = append(testCases, testCase{
+ name: "ExtendedMasterSecret-Renego-NoEMS",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ Bugs: ProtocolBugs{
+ NoExtendedMasterSecret: true,
+ NoExtendedMasterSecretOnRenegotiation: true,
+ },
+ },
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ name: "ExtendedMasterSecret-Renego-Upgrade",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ Bugs: ProtocolBugs{
+ NoExtendedMasterSecret: true,
+ },
+ },
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ shouldFail: true,
+ expectedError: ":RENEGOTIATION_EMS_MISMATCH:",
+ })
+
+ testCases = append(testCases, testCase{
+ name: "ExtendedMasterSecret-Renego-Downgrade",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ Bugs: ProtocolBugs{
+ NoExtendedMasterSecretOnRenegotiation: true,
+ },
+ },
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ shouldFail: true,
+ expectedError: ":RENEGOTIATION_EMS_MISMATCH:",
+ })
}
type stateMachineTestConfig struct {
@@ -3071,8 +3199,9 @@
RenewTicketOnResume: true,
},
},
- flags: []string{"-expect-ticket-renewal"},
- resumeSession: true,
+ flags: []string{"-expect-ticket-renewal"},
+ resumeSession: true,
+ resumeRenewedSession: true,
})
tests = append(tests, testCase{
name: "Basic-Client-NoTicket",
@@ -3130,19 +3259,59 @@
})
// TLS 1.3 basic handshake shapes.
- tests = append(tests, testCase{
- name: "TLS13-1RTT-Client",
- config: Config{
- MaxVersion: VersionTLS13,
- },
- })
- tests = append(tests, testCase{
- testType: serverTest,
- name: "TLS13-1RTT-Server",
- config: Config{
- MaxVersion: VersionTLS13,
- },
- })
+ if config.protocol == tls {
+ tests = append(tests, testCase{
+ name: "TLS13-1RTT-Client",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ },
+ resumeSession: true,
+ resumeRenewedSession: true,
+ })
+
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "TLS13-1RTT-Server",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ },
+ resumeSession: true,
+ resumeRenewedSession: true,
+ })
+
+ tests = append(tests, testCase{
+ name: "TLS13-HelloRetryRequest-Client",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ // P-384 requires a HelloRetryRequest against
+ // BoringSSL's default configuration. Assert
+ // that we do indeed test this with
+ // ExpectMissingKeyShare.
+ CurvePreferences: []CurveID{CurveP384},
+ Bugs: ProtocolBugs{
+ ExpectMissingKeyShare: true,
+ },
+ },
+ // Cover HelloRetryRequest during an ECDHE-PSK resumption.
+ resumeSession: true,
+ })
+
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "TLS13-HelloRetryRequest-Server",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ // Require a HelloRetryRequest for every curve.
+ DefaultCurves: []CurveID{},
+ },
+ // Cover HelloRetryRequest during an ECDHE-PSK resumption.
+ resumeSession: true,
+ })
+ }
// TLS client auth.
tests = append(tests, testCase{
@@ -3426,9 +3595,7 @@
base64.StdEncoding.EncodeToString(testOCSPResponse),
"-verify-peer",
},
- // TODO(davidben): Enable this when resumption is implemented
- // in TLS 1.3.
- resumeSession: false,
+ resumeSession: true,
})
tests = append(tests, testCase{
testType: serverTest,
@@ -3441,9 +3608,7 @@
"-ocsp-response",
base64.StdEncoding.EncodeToString(testOCSPResponse),
},
- // TODO(davidben): Enable this when resumption is implemented
- // in TLS 1.3.
- resumeSession: false,
+ resumeSession: true,
})
// Certificate verification tests.
@@ -3474,9 +3639,7 @@
flag,
"-expect-verify-result",
},
- // TODO(davidben): Enable this when resumption is
- // implemented in TLS 1.3.
- resumeSession: vers.version != VersionTLS13,
+ resumeSession: true,
})
tests = append(tests, testCase{
testType: testType,
@@ -3507,9 +3670,7 @@
"-verify-fail",
"-expect-verify-result",
},
- // TODO(davidben): Enable this when resumption is
- // implemented in TLS 1.3.
- resumeSession: vers.version != VersionTLS13,
+ resumeSession: true,
})
}
@@ -3679,7 +3840,7 @@
// elliptic curves, so no extensions are
// involved.
MaxVersion: VersionTLS12,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
Bugs: ProtocolBugs{
SendV2ClientHello: true,
},
@@ -3822,7 +3983,6 @@
func addDDoSCallbackTests() {
// DDoS callback.
- // TODO(davidben): Implement DDoS resumption tests for TLS 1.3.
for _, resume := range []bool{false, true} {
suffix := "Resume"
if resume {
@@ -3838,17 +3998,15 @@
flags: []string{"-install-ddos-callback"},
resumeSession: resume,
})
- if !resume {
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "Server-DDoS-OK-" + suffix + "-TLS13",
- config: Config{
- MaxVersion: VersionTLS13,
- },
- flags: []string{"-install-ddos-callback"},
- resumeSession: resume,
- })
- }
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "Server-DDoS-OK-" + suffix + "-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ },
+ flags: []string{"-install-ddos-callback"},
+ resumeSession: resume,
+ })
failFlag := "-fail-ddos-callback"
if resume {
@@ -3865,19 +4023,17 @@
shouldFail: true,
expectedError: ":CONNECTION_REJECTED:",
})
- if !resume {
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "Server-DDoS-Reject-" + suffix + "-TLS13",
- config: Config{
- MaxVersion: VersionTLS13,
- },
- flags: []string{"-install-ddos-callback", failFlag},
- resumeSession: resume,
- shouldFail: true,
- expectedError: ":CONNECTION_REJECTED:",
- })
- }
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "Server-DDoS-Reject-" + suffix + "-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ },
+ flags: []string{"-install-ddos-callback", failFlag},
+ resumeSession: resume,
+ shouldFail: true,
+ expectedError: ":CONNECTION_REJECTED:",
+ })
}
}
@@ -4223,9 +4379,6 @@
continue
}
- // TODO(davidben): Implement resumption in TLS 1.3.
- resumeSession := ver.version < VersionTLS13
-
// Test that duplicate extensions are rejected.
testCases = append(testCases, testCase{
testType: clientTest,
@@ -4297,7 +4450,7 @@
ServerName: "example.com",
},
flags: []string{"-expect-server-name", "example.com"},
- resumeSession: resumeSession,
+ resumeSession: true,
})
// Test ALPN.
@@ -4314,7 +4467,7 @@
},
expectedNextProto: "foo",
expectedNextProtoType: alpn,
- resumeSession: resumeSession,
+ resumeSession: true,
})
testCases = append(testCases, testCase{
testType: clientTest,
@@ -4345,7 +4498,7 @@
},
expectedNextProto: "foo",
expectedNextProtoType: alpn,
- resumeSession: resumeSession,
+ resumeSession: true,
})
testCases = append(testCases, testCase{
testType: serverTest,
@@ -4356,7 +4509,7 @@
},
flags: []string{"-decline-alpn"},
expectNoNextProto: true,
- resumeSession: resumeSession,
+ resumeSession: true,
})
// Test ALPN in async mode as well to ensure that extensions callbacks are only
@@ -4375,7 +4528,7 @@
},
expectedNextProto: "foo",
expectedNextProtoType: alpn,
- resumeSession: resumeSession,
+ resumeSession: true,
})
var emptyString string
@@ -4430,7 +4583,7 @@
},
expectedNextProto: "foo",
expectedNextProtoType: alpn,
- resumeSession: resumeSession,
+ resumeSession: true,
})
testCases = append(testCases, testCase{
testType: serverTest,
@@ -4449,7 +4602,7 @@
},
expectedNextProto: "foo",
expectedNextProtoType: alpn,
- resumeSession: resumeSession,
+ resumeSession: true,
})
// Test that negotiating both NPN and ALPN is forbidden.
@@ -4503,66 +4656,65 @@
}
// Test ticket behavior.
- //
- // TODO(davidben): Add TLS 1.3 versions of these.
+
+ // Resume with a corrupt ticket.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "CorruptTicket-" + ver.name,
+ config: Config{
+ MaxVersion: ver.version,
+ Bugs: ProtocolBugs{
+ CorruptTicket: true,
+ },
+ },
+ resumeSession: true,
+ expectResumeRejected: true,
+ })
+ // Test the ticket callback, with and without renewal.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TicketCallback-" + ver.name,
+ config: Config{
+ MaxVersion: ver.version,
+ },
+ resumeSession: true,
+ flags: []string{"-use-ticket-callback"},
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TicketCallback-Renew-" + ver.name,
+ config: Config{
+ MaxVersion: ver.version,
+ Bugs: ProtocolBugs{
+ ExpectNewTicket: true,
+ },
+ },
+ flags: []string{"-use-ticket-callback", "-renew-ticket"},
+ resumeSession: true,
+ })
+
+ // Test that the ticket callback is only called once when everything before
+ // it in the ClientHello is asynchronous. This corrupts the ticket so
+ // certificate selection callbacks run.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TicketCallback-SingleCall-" + ver.name,
+ config: Config{
+ MaxVersion: ver.version,
+ Bugs: ProtocolBugs{
+ CorruptTicket: true,
+ },
+ },
+ resumeSession: true,
+ expectResumeRejected: true,
+ flags: []string{
+ "-use-ticket-callback",
+ "-async",
+ },
+ })
+
+ // Resume with an oversized session id.
if ver.version < VersionTLS13 {
- // Resume with a corrupt ticket.
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "CorruptTicket-" + ver.name,
- config: Config{
- MaxVersion: ver.version,
- Bugs: ProtocolBugs{
- CorruptTicket: true,
- },
- },
- resumeSession: true,
- expectResumeRejected: true,
- })
- // Test the ticket callback, with and without renewal.
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "TicketCallback-" + ver.name,
- config: Config{
- MaxVersion: ver.version,
- },
- resumeSession: true,
- flags: []string{"-use-ticket-callback"},
- })
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "TicketCallback-Renew-" + ver.name,
- config: Config{
- MaxVersion: ver.version,
- Bugs: ProtocolBugs{
- ExpectNewTicket: true,
- },
- },
- flags: []string{"-use-ticket-callback", "-renew-ticket"},
- resumeSession: true,
- })
-
- // Test that the ticket callback is only called once when everything before
- // it in the ClientHello is asynchronous. This corrupts the ticket so
- // certificate selection callbacks run.
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "TicketCallback-SingleCall-" + ver.name,
- config: Config{
- MaxVersion: ver.version,
- Bugs: ProtocolBugs{
- CorruptTicket: true,
- },
- },
- resumeSession: true,
- expectResumeRejected: true,
- flags: []string{
- "-use-ticket-callback",
- "-async",
- },
- })
-
- // Resume with an oversized session id.
testCases = append(testCases, testCase{
testType: serverTest,
name: "OversizedSessionId-" + ver.name,
@@ -4674,7 +4826,7 @@
"-expect-signed-cert-timestamps",
base64.StdEncoding.EncodeToString(testSCTList),
},
- resumeSession: resumeSession,
+ resumeSession: true,
})
testCases = append(testCases, testCase{
name: "SendSCTListOnResume-" + ver.name,
@@ -4689,7 +4841,7 @@
"-expect-signed-cert-timestamps",
base64.StdEncoding.EncodeToString(testSCTList),
},
- resumeSession: resumeSession,
+ resumeSession: true,
})
testCases = append(testCases, testCase{
name: "SignedCertificateTimestampList-Server-" + ver.name,
@@ -4702,7 +4854,7 @@
base64.StdEncoding.EncodeToString(testSCTList),
},
expectedSCTList: testSCTList,
- resumeSession: resumeSession,
+ resumeSession: true,
})
}
@@ -4874,14 +5026,7 @@
func addResumptionVersionTests() {
for _, sessionVers := range tlsVersions {
- // TODO(davidben,svaldez): Implement resumption in TLS 1.3.
- if sessionVers.version >= VersionTLS13 {
- continue
- }
for _, resumeVers := range tlsVersions {
- if resumeVers.version >= VersionTLS13 {
- continue
- }
cipher := TLS_RSA_WITH_AES_128_CBC_SHA
if sessionVers.version >= VersionTLS13 || resumeVers.version >= VersionTLS13 {
// TLS 1.3 only shares ciphers with TLS 1.2, so
@@ -4911,11 +5056,25 @@
config: Config{
MaxVersion: sessionVers.version,
CipherSuites: []uint16{cipher},
+ Bugs: ProtocolBugs{
+ ExpectNoTLS12Session: sessionVers.version >= VersionTLS13,
+ ExpectNoTLS13PSK: sessionVers.version < VersionTLS13,
+ },
},
expectedVersion: sessionVers.version,
expectedResumeVersion: resumeVers.version,
})
} else {
+ error := ":OLD_SESSION_VERSION_NOT_RETURNED:"
+
+ // Offering a TLS 1.3 session sends an empty session ID, so
+ // there is no way to convince a non-lookahead client the
+ // session was resumed. It will appear to the client that a
+ // stray ChangeCipherSpec was sent.
+ if resumeVers.version < VersionTLS13 && sessionVers.version >= VersionTLS13 {
+ error = ":UNEXPECTED_RECORD:"
+ }
+
testCases = append(testCases, testCase{
protocol: protocol,
name: "Resume-Client-Mismatch" + suffix,
@@ -4929,12 +5088,12 @@
MaxVersion: resumeVers.version,
CipherSuites: []uint16{cipher},
Bugs: ProtocolBugs{
- AllowSessionVersionMismatch: true,
+ AcceptAnySession: true,
},
},
expectedResumeVersion: resumeVers.version,
shouldFail: true,
- expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:",
+ expectedError: error,
})
}
@@ -4970,6 +5129,9 @@
resumeConfig: &Config{
MaxVersion: resumeVers.version,
CipherSuites: []uint16{cipher},
+ Bugs: ProtocolBugs{
+ SendBothTickets: true,
+ },
},
expectedResumeVersion: resumeVers.version,
})
@@ -4977,7 +5139,6 @@
}
}
- // TODO(davidben): This test should have a TLS 1.3 variant later.
testCases = append(testCases, testCase{
name: "Resume-Client-CipherMismatch",
resumeSession: true,
@@ -4995,6 +5156,24 @@
shouldFail: true,
expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
})
+
+ testCases = append(testCases, testCase{
+ name: "Resume-Client-CipherMismatch-TLS13",
+ resumeSession: true,
+ config: Config{
+ MaxVersion: VersionTLS13,
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ },
+ resumeConfig: &Config{
+ MaxVersion: VersionTLS13,
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ SendCipherSuite: TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
+ })
}
func addRenegotiationTests() {
@@ -5127,7 +5306,7 @@
renegotiate: 1,
config: Config{
MaxVersion: VersionTLS12,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
},
renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
flags: []string{
@@ -5142,7 +5321,7 @@
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
},
- renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ renegotiateCiphers: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
flags: []string{
"-renegotiate-freely",
"-expect-total-renegotiations", "1",
@@ -5451,8 +5630,8 @@
if ver.version >= VersionTLS13 && alg.id == signatureECDSAWithSHA1 {
shouldFail = true
}
- // RSA-PSS does not exist in TLS 1.2.
- if ver.version == VersionTLS12 && hasComponent(alg.name, "PSS") {
+ // RSA-PKCS1 does not exist in TLS 1.3.
+ if ver.version == VersionTLS13 && hasComponent(alg.name, "PKCS1") {
shouldFail = true
}
@@ -5778,7 +5957,7 @@
// Test that, if the list is missing, the peer falls back to SHA-1 in
// TLS 1.2, but not TLS 1.3.
testCases = append(testCases, testCase{
- name: "ClientAuth-SHA1-Fallback",
+ name: "ClientAuth-SHA1-Fallback-RSA",
config: Config{
MaxVersion: VersionTLS12,
ClientAuth: RequireAnyClientCert,
@@ -5797,10 +5976,9 @@
testCases = append(testCases, testCase{
testType: serverTest,
- name: "ServerAuth-SHA1-Fallback",
+ name: "ServerAuth-SHA1-Fallback-RSA",
config: Config{
- MaxVersion: VersionTLS12,
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ MaxVersion: VersionTLS12,
VerifySignatureAlgorithms: []signatureAlgorithm{
signatureRSAPKCS1WithSHA1,
},
@@ -5808,6 +5986,46 @@
NoSignatureAlgorithms: true,
},
},
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ name: "ClientAuth-SHA1-Fallback-ECDSA",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ ClientAuth: RequireAnyClientCert,
+ VerifySignatureAlgorithms: []signatureAlgorithm{
+ signatureECDSAWithSHA1,
+ },
+ Bugs: ProtocolBugs{
+ NoSignatureAlgorithms: true,
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
+ "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "ServerAuth-SHA1-Fallback-ECDSA",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ VerifySignatureAlgorithms: []signatureAlgorithm{
+ signatureECDSAWithSHA1,
+ },
+ Bugs: ProtocolBugs{
+ NoSignatureAlgorithms: true,
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
+ "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
+ },
})
testCases = append(testCases, testCase{
@@ -6145,6 +6363,31 @@
shouldFail: true,
expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
})
+
+ // Test that RSA-PSS is enabled by default for TLS 1.2.
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "RSA-PSS-Default-Verify",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ SignSignatureAlgorithms: []signatureAlgorithm{
+ signatureRSAPSSWithSHA256,
+ },
+ },
+ flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "RSA-PSS-Default-Sign",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ VerifySignatureAlgorithms: []signatureAlgorithm{
+ signatureRSAPSSWithSHA256,
+ },
+ },
+ flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
+ })
}
// timeouts is the retransmit schedule for BoringSSL. It doubles and
@@ -6664,7 +6907,7 @@
// version are different, to detect if the
// server uses the wrong one.
MaxVersion: VersionTLS11,
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
Bugs: ProtocolBugs{
BadRSAClientKeyExchange: bad,
},
@@ -6696,7 +6939,10 @@
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
CurvePreferences: []CurveID{curve.id},
},
- flags: []string{"-enable-all-curves"},
+ flags: []string{
+ "-enable-all-curves",
+ "-expect-curve-id", strconv.Itoa(int(curve.id)),
+ },
expectedCurveID: curve.id,
})
testCases = append(testCases, testCase{
@@ -6706,7 +6952,10 @@
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
CurvePreferences: []CurveID{curve.id},
},
- flags: []string{"-enable-all-curves"},
+ flags: []string{
+ "-enable-all-curves",
+ "-expect-curve-id", strconv.Itoa(int(curve.id)),
+ },
expectedCurveID: curve.id,
})
testCases = append(testCases, testCase{
@@ -6717,7 +6966,10 @@
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
CurvePreferences: []CurveID{curve.id},
},
- flags: []string{"-enable-all-curves"},
+ flags: []string{
+ "-enable-all-curves",
+ "-expect-curve-id", strconv.Itoa(int(curve.id)),
+ },
expectedCurveID: curve.id,
})
testCases = append(testCases, testCase{
@@ -6728,7 +6980,10 @@
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
CurvePreferences: []CurveID{curve.id},
},
- flags: []string{"-enable-all-curves"},
+ flags: []string{
+ "-enable-all-curves",
+ "-expect-curve-id", strconv.Itoa(int(curve.id)),
+ },
expectedCurveID: curve.id,
})
}
@@ -6966,9 +7221,9 @@
})
}
-func addKeyExchangeInfoTests() {
+func addDHEGroupSizeTests() {
testCases = append(testCases, testCase{
- name: "KeyExchangeInfo-DHE-Client",
+ name: "DHEGroupSize-Client",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
@@ -6983,7 +7238,7 @@
})
testCases = append(testCases, testCase{
testType: serverTest,
- name: "KeyExchangeInfo-DHE-Server",
+ name: "DHEGroupSize-Server",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
@@ -6991,26 +7246,6 @@
// bssl_shim as a server configures a 2048-bit DHE group.
flags: []string{"-expect-dhe-group-size", "2048"},
})
-
- testCases = append(testCases, testCase{
- name: "KeyExchangeInfo-ECDHE-Client",
- config: Config{
- MaxVersion: VersionTLS12,
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- CurvePreferences: []CurveID{CurveX25519},
- },
- flags: []string{"-expect-curve-id", "29", "-enable-all-curves"},
- })
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "KeyExchangeInfo-ECDHE-Server",
- config: Config{
- MaxVersion: VersionTLS12,
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- CurvePreferences: []CurveID{CurveX25519},
- },
- flags: []string{"-expect-curve-id", "29", "-enable-all-curves"},
- })
}
func addTLS13RecordTests() {
@@ -7971,6 +8206,24 @@
shouldFail: true,
expectedError: ":WRONG_CURVE:",
})
+
+ testCases = append(testCases, testCase{
+ name: "TLS13-RequestContextInHandshake",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ ClientAuth: RequireAnyClientCert,
+ Bugs: ProtocolBugs{
+ SendRequestContext: []byte("request context"),
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ shouldFail: true,
+ expectedError: ":DECODE_ERROR:",
+ })
}
func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
@@ -8082,7 +8335,7 @@
addRSAClientKeyExchangeTests()
addCurveTests()
addCECPQ1Tests()
- addKeyExchangeInfoTests()
+ addDHEGroupSizeTests()
addTLS13RecordTests()
addAllStateMachineCoverageTests()
addChangeCipherSpecTests()
diff --git a/src/ssl/test/runner/sign.go b/src/ssl/test/runner/sign.go
index 1674c4a..5f56ff9 100644
--- a/src/ssl/test/runner/sign.go
+++ b/src/ssl/test/runner/sign.go
@@ -258,15 +258,25 @@
// TODO(davidben): Forbid RSASSA-PKCS1-v1_5 in TLS 1.3.
switch sigAlg {
case signatureRSAPKCS1WithMD5:
- return &rsaPKCS1Signer{crypto.MD5}, nil
+ if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
+ return &rsaPKCS1Signer{crypto.MD5}, nil
+ }
case signatureRSAPKCS1WithSHA1:
- return &rsaPKCS1Signer{crypto.SHA1}, nil
+ if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
+ return &rsaPKCS1Signer{crypto.SHA1}, nil
+ }
case signatureRSAPKCS1WithSHA256:
- return &rsaPKCS1Signer{crypto.SHA256}, nil
+ if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
+ return &rsaPKCS1Signer{crypto.SHA256}, nil
+ }
case signatureRSAPKCS1WithSHA384:
- return &rsaPKCS1Signer{crypto.SHA384}, nil
+ if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
+ return &rsaPKCS1Signer{crypto.SHA384}, nil
+ }
case signatureRSAPKCS1WithSHA512:
- return &rsaPKCS1Signer{crypto.SHA512}, nil
+ if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
+ return &rsaPKCS1Signer{crypto.SHA512}, nil
+ }
case signatureECDSAWithSHA1:
return &ecdsaSigner{version, config, nil, crypto.SHA1}, nil
case signatureECDSAWithP256AndSHA256:
@@ -276,17 +286,11 @@
case signatureECDSAWithP521AndSHA512:
return &ecdsaSigner{version, config, elliptic.P521(), crypto.SHA512}, nil
case signatureRSAPSSWithSHA256:
- if version >= VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
- return &rsaPSSSigner{crypto.SHA256}, nil
- }
+ return &rsaPSSSigner{crypto.SHA256}, nil
case signatureRSAPSSWithSHA384:
- if version >= VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
- return &rsaPSSSigner{crypto.SHA384}, nil
- }
+ return &rsaPSSSigner{crypto.SHA384}, nil
case signatureRSAPSSWithSHA512:
- if version >= VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
- return &rsaPSSSigner{crypto.SHA512}, nil
- }
+ return &rsaPSSSigner{crypto.SHA512}, nil
}
return nil, fmt.Errorf("unsupported signature algorithm %04x", sigAlg)
diff --git a/src/ssl/test/scoped_types.h b/src/ssl/test/scoped_types.h
deleted file mode 100644
index 7e92cee..0000000
--- a/src/ssl/test/scoped_types.h
+++ /dev/null
@@ -1,28 +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_SSL_TEST_SCOPED_TYPES_H
-#define OPENSSL_HEADER_SSL_TEST_SCOPED_TYPES_H
-
-#include <openssl/ssl.h>
-
-#include "../../crypto/test/scoped_types.h"
-
-
-using ScopedSSL = ScopedOpenSSLType<SSL, SSL_free>;
-using ScopedSSL_CTX = ScopedOpenSSLType<SSL_CTX, SSL_CTX_free>;
-using ScopedSSL_SESSION = ScopedOpenSSLType<SSL_SESSION, SSL_SESSION_free>;
-
-
-#endif // OPENSSL_HEADER_SSL_TEST_SCOPED_TYPES_H
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 2fa1f17..677aa54 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -46,7 +46,6 @@
const Flag<bool> kBoolFlags[] = {
{ "-server", &TestConfig::is_server },
{ "-dtls", &TestConfig::is_dtls },
- { "-resume", &TestConfig::resume },
{ "-fallback-scsv", &TestConfig::fallback_scsv },
{ "-require-any-client-certificate",
&TestConfig::require_any_client_certificate },
@@ -143,6 +142,7 @@
const Flag<int> kIntFlags[] = {
{ "-port", &TestConfig::port },
+ { "-resume-count", &TestConfig::resume_count },
{ "-min-version", &TestConfig::min_version },
{ "-max-version", &TestConfig::max_version },
{ "-fallback-version", &TestConfig::fallback_version },
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index f6a1f12..8ed74ac 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -23,7 +23,7 @@
int port = 0;
bool is_server = false;
bool is_dtls = false;
- bool resume = false;
+ int resume_count = 0;
bool fallback_scsv = false;
std::string digest_prefs;
std::vector<int> signing_prefs;
diff --git a/src/ssl/tls13_both.c b/src/ssl/tls13_both.c
index 2527896..e634790 100644
--- a/src/ssl/tls13_both.c
+++ b/src/ssl/tls13_both.c
@@ -28,44 +28,10 @@
#include "internal.h"
-SSL_HANDSHAKE *ssl_handshake_new(enum ssl_hs_wait_t (*do_handshake)(SSL *ssl)) {
- SSL_HANDSHAKE *hs = OPENSSL_malloc(sizeof(SSL_HANDSHAKE));
- if (hs == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- memset(hs, 0, sizeof(SSL_HANDSHAKE));
- hs->do_handshake = do_handshake;
- hs->wait = ssl_hs_ok;
- return hs;
-}
-
-void ssl_handshake_clear_groups(SSL_HANDSHAKE *hs) {
- if (hs->groups == NULL) {
- return;
- }
-
- for (size_t i = 0; i < hs->groups_len; i++) {
- SSL_ECDH_CTX_cleanup(&hs->groups[i]);
- }
- OPENSSL_free(hs->groups);
- hs->groups = NULL;
- hs->groups_len = 0;
-}
-
-void ssl_handshake_free(SSL_HANDSHAKE *hs) {
- if (hs == NULL) {
- return;
- }
-
- OPENSSL_cleanse(hs->secret, sizeof(hs->secret));
- OPENSSL_cleanse(hs->traffic_secret_0, sizeof(hs->traffic_secret_0));
- ssl_handshake_clear_groups(hs);
- OPENSSL_free(hs->key_share_bytes);
- OPENSSL_free(hs->public_key);
- OPENSSL_free(hs->cert_context);
- OPENSSL_free(hs);
-}
+/* kMaxKeyUpdates is the number of consecutive KeyUpdates that will be
+ * processed. Without this limit an attacker could force unbounded processing
+ * without being able to return application data. */
+static const uint8_t kMaxKeyUpdates = 32;
int tls13_handshake(SSL *ssl) {
SSL_HANDSHAKE *hs = ssl->s3->hs;
@@ -216,6 +182,10 @@
goto err;
}
+ /* OpenSSL returns X509_V_OK when no certificates are requested. This is
+ * classed by them as a bug, but it's assumed by at least NGINX. */
+ ssl->s3->new_session->verify_result = X509_V_OK;
+
/* No certificate, so nothing more to do. */
ret = 1;
goto err;
@@ -223,12 +193,11 @@
ssl->s3->new_session->peer_sha256_valid = retain_sha256;
- if (!ssl_verify_cert_chain(ssl, chain)) {
+ if (!ssl_verify_cert_chain(ssl, &ssl->s3->new_session->verify_result,
+ chain)) {
goto err;
}
- ssl->s3->new_session->verify_result = ssl->verify_result;
-
X509_free(ssl->s3->new_session->peer);
X509 *leaf = sk_X509_value(chain, 0);
X509_up_ref(leaf);
@@ -285,6 +254,10 @@
int sig_ok =
ssl_public_key_verify(ssl, CBS_data(&signature), CBS_len(&signature),
signature_algorithm, pkey, msg, msg_len);
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ sig_ok = 1;
+ ERR_clear_error();
+#endif
if (!sig_ok) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
@@ -318,8 +291,13 @@
return 0;
}
- if (ssl->init_num != verify_data_len ||
- CRYPTO_memcmp(verify_data, ssl->init_msg, verify_data_len) != 0) {
+ int finished_ok =
+ ssl->init_num == verify_data_len &&
+ CRYPTO_memcmp(verify_data, ssl->init_msg, verify_data_len) == 0;
+#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
+ finished_ok = 1;
+#endif
+ if (!finished_ok) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
return 0;
@@ -329,11 +307,10 @@
}
int tls13_prepare_certificate(SSL *ssl) {
- CBB cbb, body, context;
+ CBB cbb, body;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CERTIFICATE) ||
- !CBB_add_u8_length_prefixed(&body, &context) ||
- !CBB_add_bytes(&context, ssl->s3->hs->cert_context,
- ssl->s3->hs->cert_context_len) ||
+ /* The request context is always empty in the handshake. */
+ !CBB_add_u8(&body, 0) ||
!ssl_add_cert_chain(ssl, &body) ||
!ssl->method->finish_message(ssl, &cbb)) {
CBB_cleanup(&cbb);
@@ -438,9 +415,18 @@
int tls13_post_handshake(SSL *ssl) {
if (ssl->s3->tmp.message_type == SSL3_MT_KEY_UPDATE) {
+ ssl->s3->key_update_count++;
+ if (ssl->s3->key_update_count > kMaxKeyUpdates) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_KEY_UPDATES);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ return 0;
+ }
+
return tls13_receive_key_update(ssl);
}
+ ssl->s3->key_update_count = 0;
+
if (ssl->s3->tmp.message_type == SSL3_MT_NEW_SESSION_TICKET &&
!ssl->server) {
return tls13_process_new_session_ticket(ssl);
diff --git a/src/ssl/tls13_client.c b/src/ssl/tls13_client.c
index 61e1414..d2d99a7 100644
--- a/src/ssl/tls13_client.c
+++ b/src/ssl/tls13_client.c
@@ -151,8 +151,8 @@
}
/* Parse out the extensions. */
- int have_key_share = 0;
- CBS key_share;
+ int have_key_share = 0, have_pre_shared_key = 0;
+ CBS key_share, pre_shared_key;
while (CBS_len(&extensions) != 0) {
uint16_t type;
CBS extension;
@@ -173,6 +173,15 @@
key_share = extension;
have_key_share = 1;
break;
+ case TLSEXT_TYPE_pre_shared_key:
+ if (have_pre_shared_key) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
+ pre_shared_key = extension;
+ have_pre_shared_key = 1;
+ break;
default:
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
@@ -183,10 +192,48 @@
assert(ssl->s3->have_version);
memcpy(ssl->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
- SSL_set_session(ssl, NULL);
- if (!ssl_get_new_session(ssl, 0)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return ssl_hs_error;
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (have_pre_shared_key) {
+ if (ssl->session == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+ return ssl_hs_error;
+ }
+
+ if (!ssl_ext_pre_shared_key_parse_serverhello(ssl, &alert,
+ &pre_shared_key)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return ssl_hs_error;
+ }
+
+ if (ssl->session->ssl_version != ssl->version) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
+
+ if (!ssl_session_is_context_valid(ssl, ssl->session)) {
+ /* This is actually a client application bug. */
+ OPENSSL_PUT_ERROR(SSL,
+ SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
+
+ ssl->s3->session_reused = 1;
+ /* Only authentication information carries over in TLS 1.3. */
+ ssl->s3->new_session =
+ SSL_SESSION_dup(ssl->session, SSL_SESSION_DUP_AUTH_ONLY);
+ if (ssl->s3->new_session == NULL) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
+ SSL_set_session(ssl, NULL);
+ } else {
+ if (!ssl_get_new_session(ssl, 0)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
}
const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite);
@@ -196,15 +243,26 @@
return ssl_hs_error;
}
- /* Check if the cipher is disabled. */
- if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
- (cipher->algorithm_auth & ssl->cert->mask_a) ||
- SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) ||
- SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl) ||
- !sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(ssl), NULL, cipher)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
- return ssl_hs_error;
+ if (!ssl->s3->session_reused) {
+ /* Check if the cipher is disabled. */
+ if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
+ (cipher->algorithm_auth & ssl->cert->mask_a) ||
+ SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) ||
+ SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl) ||
+ !sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(ssl), NULL, cipher)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
+ } else {
+ uint16_t resumption_cipher;
+ if (!ssl_cipher_get_ecdhe_psk_cipher(ssl->s3->new_session->cipher,
+ &resumption_cipher) ||
+ resumption_cipher != ssl_cipher_get_value(cipher)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
}
ssl->s3->new_session->cipher = cipher;
@@ -212,18 +270,35 @@
/* The PRF hash is now known. Set up the key schedule. */
static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
- size_t hash_len =
+ size_t resumption_ctx_len =
EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
- if (!tls13_init_key_schedule(ssl, kZeroes, hash_len)) {
+ if (ssl->s3->session_reused) {
+ uint8_t resumption_ctx[EVP_MAX_MD_SIZE];
+ if (!tls13_resumption_context(ssl, resumption_ctx, resumption_ctx_len,
+ ssl->s3->new_session) ||
+ !tls13_init_key_schedule(ssl, resumption_ctx, resumption_ctx_len)) {
+ return ssl_hs_error;
+ }
+ } else if (!tls13_init_key_schedule(ssl, kZeroes, resumption_ctx_len)) {
return ssl_hs_error;
}
/* Resolve PSK and incorporate it into the secret. */
if (cipher->algorithm_auth == SSL_aPSK) {
- /* TODO(davidben): Support PSK. */
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return ssl_hs_error;
- } else if (!tls13_advance_key_schedule(ssl, kZeroes, hash_len)) {
+ if (!ssl->s3->session_reused) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
+
+ uint8_t resumption_psk[EVP_MAX_MD_SIZE];
+ if (!tls13_resumption_psk(ssl, resumption_psk, hs->hash_len,
+ ssl->s3->new_session) ||
+ !tls13_advance_key_schedule(ssl, resumption_psk, hs->hash_len)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
+ } else if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len)) {
return ssl_hs_error;
}
@@ -237,7 +312,6 @@
uint8_t *dhe_secret;
size_t dhe_secret_len;
- uint8_t alert = SSL_AD_DECODE_ERROR;
if (!ssl_ext_key_share_parse_serverhello(ssl, &dhe_secret, &dhe_secret_len,
&alert, &key_share)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
@@ -255,7 +329,7 @@
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
return ssl_hs_error;
}
- if (!tls13_advance_key_schedule(ssl, kZeroes, hash_len)) {
+ if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len)) {
return ssl_hs_error;
}
}
@@ -320,8 +394,8 @@
CBS cbs, context, supported_signature_algorithms;
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
if (!CBS_get_u8_length_prefixed(&cbs, &context) ||
- !CBS_stow(&context, &ssl->s3->hs->cert_context,
- &ssl->s3->hs->cert_context_len) ||
+ /* The request context is always empty during the handshake. */
+ CBS_len(&context) != 0 ||
!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms) ||
CBS_len(&supported_signature_algorithms) == 0 ||
!tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) {
@@ -568,8 +642,9 @@
}
int tls13_process_new_session_ticket(SSL *ssl) {
- SSL_SESSION *session = SSL_SESSION_dup(ssl->s3->established_session,
- 0 /* don't include ticket */);
+ SSL_SESSION *session =
+ SSL_SESSION_dup(ssl->s3->established_session,
+ SSL_SESSION_INCLUDE_NONAUTH);
if (session == NULL) {
return 0;
}
diff --git a/src/ssl/tls13_enc.c b/src/ssl/tls13_enc.c
index 70b041a..88fe8f0 100644
--- a/src/ssl/tls13_enc.c
+++ b/src/ssl/tls13_enc.c
@@ -318,7 +318,7 @@
uint8_t key[EVP_MAX_MD_SIZE];
size_t key_len = EVP_MD_size(digest);
- uint8_t *traffic_secret;
+ const uint8_t *traffic_secret;
const char *label;
if (is_server) {
label = "server finished";
@@ -351,6 +351,28 @@
return 1;
}
+static const char kTLS13LabelResumptionPSK[] = "resumption psk";
+static const char kTLS13LabelResumptionContext[] = "resumption context";
+
+int tls13_resumption_psk(SSL *ssl, uint8_t *out, size_t out_len,
+ const SSL_SESSION *session) {
+ const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl));
+ return hkdf_expand_label(out, digest, session->master_key,
+ session->master_key_length,
+ (const uint8_t *)kTLS13LabelResumptionPSK,
+ strlen(kTLS13LabelResumptionPSK), NULL, 0, out_len);
+}
+
+int tls13_resumption_context(SSL *ssl, uint8_t *out, size_t out_len,
+ const SSL_SESSION *session) {
+ const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl));
+ return hkdf_expand_label(out, digest, session->master_key,
+ session->master_key_length,
+ (const uint8_t *)kTLS13LabelResumptionContext,
+ strlen(kTLS13LabelResumptionContext), NULL, 0,
+ out_len);
+}
+
int tls13_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,
diff --git a/src/ssl/tls13_server.c b/src/ssl/tls13_server.c
index a1aeeea..48279a7 100644
--- a/src/ssl/tls13_server.c
+++ b/src/ssl/tls13_server.c
@@ -58,9 +58,14 @@
return tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len);
}
- /* TODO(davidben): Support PSK. */
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
+ uint8_t resumption_psk[EVP_MAX_MD_SIZE];
+ if (!tls13_resumption_psk(ssl, resumption_psk, hs->hash_len,
+ ssl->s3->new_session) ||
+ !tls13_advance_key_schedule(ssl, resumption_psk, hs->hash_len)) {
+ return 0;
+ }
+
+ return 1;
}
static int resolve_ecdhe_secret(SSL *ssl, int *out_need_retry,
@@ -123,10 +128,44 @@
}
memcpy(ssl->s3->client_random, client_hello.random, client_hello.random_len);
- SSL_set_session(ssl, NULL);
- if (!ssl_get_new_session(ssl, 1 /* server */)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return ssl_hs_error;
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ SSL_SESSION *session = NULL;
+ CBS pre_shared_key;
+ if (ssl_early_callback_get_extension(&client_hello, &pre_shared_key,
+ TLSEXT_TYPE_pre_shared_key) &&
+ !ssl_ext_pre_shared_key_parse_clienthello(ssl, &session, &alert,
+ &pre_shared_key)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return 0;
+ }
+
+ uint16_t resumption_cipher;
+ if (session != NULL &&
+ /* We currently only support ECDHE-PSK resumption. */
+ ((session->ticket_flags & SSL_TICKET_ALLOW_DHE_RESUMPTION) == 0 ||
+ /* Only resume if the session's version matches. */
+ session->ssl_version != ssl->version ||
+ !ssl_cipher_get_ecdhe_psk_cipher(session->cipher, &resumption_cipher) ||
+ !ssl_client_cipher_list_contains_cipher(&client_hello,
+ resumption_cipher))) {
+ SSL_SESSION_free(session);
+ session = NULL;
+ }
+
+ if (session == NULL) {
+ if (!ssl_get_new_session(ssl, 1 /* server */)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
+ } else {
+ /* Only authentication information carries over in TLS 1.3. */
+ ssl->s3->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
+ if (ssl->s3->new_session == NULL) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
+ ssl->s3->session_reused = 1;
+ SSL_SESSION_free(session);
}
if (ssl->ctx->dos_protection_cb != NULL &&
@@ -156,17 +195,19 @@
}
static enum ssl_hs_wait_t do_select_parameters(SSL *ssl, SSL_HANDSHAKE *hs) {
- /* Call |cert_cb| to update server certificates if required. */
- if (ssl->cert->cert_cb != NULL) {
- int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
- if (rv == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return ssl_hs_error;
- }
- if (rv < 0) {
- hs->state = state_select_parameters;
- return ssl_hs_x509_lookup;
+ if (!ssl->s3->session_reused) {
+ /* Call |cert_cb| to update server certificates if required. */
+ if (ssl->cert->cert_cb != NULL) {
+ int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
+ if (rv == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
+ if (rv < 0) {
+ hs->state = state_select_parameters;
+ return ssl_hs_x509_lookup;
+ }
}
}
@@ -178,25 +219,45 @@
return ssl_hs_error;
}
- const SSL_CIPHER *cipher =
- ssl3_choose_cipher(ssl, &client_hello, ssl_get_cipher_preferences(ssl));
- if (cipher == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- return ssl_hs_error;
- }
+ if (!ssl->s3->session_reused) {
+ const SSL_CIPHER *cipher =
+ ssl3_choose_cipher(ssl, &client_hello, ssl_get_cipher_preferences(ssl));
+ if (cipher == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ return ssl_hs_error;
+ }
- ssl->s3->new_session->cipher = cipher;
- ssl->s3->tmp.new_cipher = cipher;
+ ssl->s3->new_session->cipher = cipher;
+ ssl->s3->tmp.new_cipher = cipher;
+ } else {
+ uint16_t resumption_cipher;
+ if (!ssl_cipher_get_ecdhe_psk_cipher(ssl->s3->new_session->cipher,
+ &resumption_cipher)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ return ssl_hs_error;
+ }
+ ssl->s3->tmp.new_cipher = SSL_get_cipher_by_value(resumption_cipher);
+ }
ssl->method->received_flight(ssl);
/* The PRF hash is now known. Set up the key schedule and hash the
* ClientHello. */
- size_t hash_len =
+ size_t resumption_ctx_len =
EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
- if (!tls13_init_key_schedule(ssl, kZeroes, hash_len)) {
- return ssl_hs_error;
+ if (ssl->s3->session_reused) {
+ uint8_t resumption_ctx[EVP_MAX_MD_SIZE];
+ if (!tls13_resumption_context(ssl, resumption_ctx, resumption_ctx_len,
+ ssl->s3->new_session) ||
+ !tls13_init_key_schedule(ssl, resumption_ctx, resumption_ctx_len)) {
+ return ssl_hs_error;
+ }
+ } else {
+ if (!tls13_init_key_schedule(ssl, kZeroes, resumption_ctx_len)) {
+ return ssl_hs_error;
+ }
}
/* Resolve PSK and incorporate it into the secret. */
@@ -285,6 +346,7 @@
!CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
!CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
!CBB_add_u16_length_prefixed(&body, &extensions) ||
+ !ssl_ext_pre_shared_key_add_serverhello(ssl, &extensions) ||
!ssl_ext_key_share_add_serverhello(ssl, &extensions) ||
!ssl->method->finish_message(ssl, &cbb)) {
CBB_cleanup(&cbb);
@@ -337,12 +399,12 @@
}
const uint16_t *sigalgs;
- size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs);
+ size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
goto err;
}
- for (size_t i = 0; i < sigalgs_len; i++) {
+ for (size_t i = 0; i < num_sigalgs; i++) {
if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
goto err;
}
@@ -427,8 +489,12 @@
static enum ssl_hs_wait_t do_process_client_certificate(SSL *ssl,
SSL_HANDSHAKE *hs) {
if (!ssl->s3->tmp.cert_request) {
+ /* OpenSSL returns X509_V_OK when no certificates are requested. This is
+ * classed by them as a bug, but it's assumed by at least NGINX. */
+ ssl->s3->new_session->verify_result = X509_V_OK;
+
/* Skip this state. */
- hs->state = state_process_client_certificate_verify;
+ hs->state = state_process_client_finished;
return ssl_hs_ok;
}
diff --git a/src/tool/ciphers.cc b/src/tool/ciphers.cc
index d7cc36b..f52527b 100644
--- a/src/tool/ciphers.cc
+++ b/src/tool/ciphers.cc
@@ -20,8 +20,6 @@
#include <openssl/ssl.h>
-#include "../crypto/test/scoped_types.h"
-#include "../ssl/test/scoped_types.h"
#include "internal.h"
@@ -33,7 +31,7 @@
const std::string &ciphers_string = args.back();
- ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_client_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_client_method()));
if (!SSL_CTX_set_cipher_list(ctx.get(), ciphers_string.c_str())) {
fprintf(stderr, "Failed to parse cipher suite config.\n");
ERR_print_errors_fp(stderr);
diff --git a/src/tool/client.cc b/src/tool/client.cc
index 9d662d7..27084fc 100644
--- a/src/tool/client.cc
+++ b/src/tool/client.cc
@@ -20,8 +20,6 @@
#include <openssl/pem.h>
#include <openssl/ssl.h>
-#include "../crypto/test/scoped_types.h"
-#include "../ssl/test/scoped_types.h"
#include "internal.h"
#include "transport_common.h"
@@ -95,13 +93,13 @@
},
};
-static ScopedEVP_PKEY LoadPrivateKey(const std::string &file) {
- ScopedBIO bio(BIO_new(BIO_s_file()));
+static bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(const std::string &file) {
+ bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
return nullptr;
}
- ScopedEVP_PKEY pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr,
- nullptr));
+ bssl::UniquePtr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr,
+ nullptr, nullptr));
return pkey;
}
@@ -119,7 +117,7 @@
fflush(g_keylog_file);
}
-static ScopedBIO session_out;
+static bssl::UniquePtr<BIO> session_out;
static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
if (session_out) {
@@ -146,7 +144,7 @@
return false;
}
- ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_client_method()));
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_client_method()));
const char *keylog_file = getenv("SSLKEYLOGFILE");
if (keylog_file) {
@@ -232,7 +230,8 @@
}
if (args_map.count("-channel-id-key") != 0) {
- ScopedEVP_PKEY pkey = LoadPrivateKey(args_map["-channel-id-key"]);
+ bssl::UniquePtr<EVP_PKEY> pkey =
+ LoadPrivateKey(args_map["-channel-id-key"]);
if (!pkey || !SSL_CTX_set1_tls_channel_id(ctx.get(), pkey.get())) {
return false;
}
@@ -257,10 +256,12 @@
if (args_map.count("-session-out") != 0) {
session_out.reset(BIO_new_file(args_map["-session-out"].c_str(), "wb"));
if (!session_out) {
- fprintf(stderr, "Error while saving session:\n");
+ fprintf(stderr, "Error while opening %s:\n",
+ args_map["-session-out"].c_str());
ERR_print_errors_cb(PrintErrorCallback, stderr);
return false;
}
+ SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_CLIENT);
SSL_CTX_sess_set_new_cb(ctx.get(), NewSessionCallback);
}
@@ -281,22 +282,23 @@
}
}
- ScopedBIO bio(BIO_new_socket(sock, BIO_CLOSE));
- ScopedSSL ssl(SSL_new(ctx.get()));
+ bssl::UniquePtr<BIO> bio(BIO_new_socket(sock, BIO_CLOSE));
+ bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
if (args_map.count("-server-name") != 0) {
SSL_set_tlsext_host_name(ssl.get(), args_map["-server-name"].c_str());
}
if (args_map.count("-session-in") != 0) {
- ScopedBIO in(BIO_new_file(args_map["-session-in"].c_str(), "rb"));
+ bssl::UniquePtr<BIO> in(BIO_new_file(args_map["-session-in"].c_str(),
+ "rb"));
if (!in) {
fprintf(stderr, "Error reading session\n");
ERR_print_errors_cb(PrintErrorCallback, stderr);
return false;
}
- ScopedSSL_SESSION session(PEM_read_bio_SSL_SESSION(in.get(), nullptr,
- nullptr, nullptr));
+ bssl::UniquePtr<SSL_SESSION> session(PEM_read_bio_SSL_SESSION(in.get(),
+ nullptr, nullptr, nullptr));
if (!session) {
fprintf(stderr, "Error reading session\n");
ERR_print_errors_cb(PrintErrorCallback, stderr);
diff --git a/src/tool/generate_ed25519.cc b/src/tool/generate_ed25519.cc
index 15d3692..35b57b9 100644
--- a/src/tool/generate_ed25519.cc
+++ b/src/tool/generate_ed25519.cc
@@ -18,10 +18,17 @@
#include <stdio.h>
#include <string.h>
-#include "../crypto/test/scoped_types.h"
#include "internal.h"
+struct FileCloser {
+ void operator()(FILE *file) {
+ fclose(file);
+ }
+};
+
+using ScopedFILE = std::unique_ptr<FILE, FileCloser>;
+
static const struct argument kArguments[] = {
{
"-out-public", kRequiredArgument, "The file to write the public key to",
diff --git a/src/tool/genrsa.cc b/src/tool/genrsa.cc
index 4b39401..b49ebbc 100644
--- a/src/tool/genrsa.cc
+++ b/src/tool/genrsa.cc
@@ -18,7 +18,6 @@
#include <openssl/pem.h>
#include <openssl/rsa.h>
-#include "../crypto/test/scoped_types.h"
#include "internal.h"
@@ -51,9 +50,9 @@
return false;
}
- ScopedRSA rsa(RSA_new());
- ScopedBIGNUM e(BN_new());
- ScopedBIO bio(BIO_new_fp(stdout, BIO_NOCLOSE));
+ bssl::UniquePtr<RSA> rsa(RSA_new());
+ bssl::UniquePtr<BIGNUM> e(BN_new());
+ bssl::UniquePtr<BIO> bio(BIO_new_fp(stdout, BIO_NOCLOSE));
if (!BN_set_word(e.get(), RSA_F4) ||
!RSA_generate_multi_prime_key(rsa.get(), bits, nprimes, e.get(), NULL) ||
diff --git a/src/tool/speed.cc b/src/tool/speed.cc
index a8eb8bf..d5cdb45 100644
--- a/src/tool/speed.cc
+++ b/src/tool/speed.cc
@@ -18,12 +18,17 @@
#include <vector>
#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
#include <openssl/aead.h>
+#include <openssl/bn.h>
#include <openssl/curve25519.h>
#include <openssl/digest.h>
#include <openssl/err.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/ec_key.h>
#include <openssl/newhope.h>
#include <openssl/nid.h>
#include <openssl/rand.h>
@@ -35,9 +40,10 @@
OPENSSL_MSVC_PRAGMA(warning(pop))
#elif defined(OPENSSL_APPLE)
#include <sys/time.h>
+#else
+#include <time.h>
#endif
-#include "../crypto/test/scoped_types.h"
#include "internal.h"
@@ -87,10 +93,12 @@
}
#endif
+static uint64_t g_timeout_seconds = 1;
+
static bool TimeFunction(TimeResults *results, std::function<bool()> func) {
- // kTotalMS is the total amount of time that we'll aim to measure a function
+ // total_us is the total amount of time that we'll aim to measure a function
// for.
- static const uint64_t kTotalUS = 1000000;
+ const uint64_t total_us = g_timeout_seconds * 1000000;
uint64_t start = time_now(), now, delta;
unsigned done = 0, iterations_between_time_checks;
@@ -121,7 +129,7 @@
}
now = time_now();
- if (now - start > kTotalUS) {
+ if (now - start > total_us) {
break;
}
}
@@ -144,6 +152,9 @@
TimeResults results;
if (!TimeFunction(&results,
[key, &sig, &fake_sha256_hash, &sig_len]() -> bool {
+ /* Usually during RSA signing we're using a long-lived |RSA| that has
+ * already had all of its |BN_MONT_CTX|s constructed, so it makes
+ * sense to use |key| directly here. */
return RSA_sign(NID_sha256, fake_sha256_hash, sizeof(fake_sha256_hash),
sig.get(), &sig_len, key);
})) {
@@ -155,6 +166,21 @@
if (!TimeFunction(&results,
[key, &fake_sha256_hash, &sig, sig_len]() -> bool {
+ /* Usually during RSA verification we have to parse an RSA key from a
+ * certificate or similar, in which case we'd need to construct a new
+ * RSA key, with a new |BN_MONT_CTX| for the public modulus. If we were
+ * to use |key| directly instead, then these costs wouldn't be
+ * accounted for. */
+ bssl::UniquePtr<RSA> verify_key(RSA_new());
+ if (!verify_key) {
+ return false;
+ }
+ verify_key->n = BN_dup(key->n);
+ verify_key->e = BN_dup(key->e);
+ if (!verify_key->n ||
+ !verify_key->e) {
+ return false;
+ }
return RSA_verify(NID_sha256, fake_sha256_hash,
sizeof(fake_sha256_hash), sig.get(), sig_len, key);
})) {
@@ -313,17 +339,17 @@
TimeResults results;
if (!TimeFunction(&results, [nid]() -> bool {
- ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
if (!key ||
!EC_KEY_generate_key(key.get())) {
return false;
}
const EC_GROUP *const group = EC_KEY_get0_group(key.get());
- ScopedEC_POINT point(EC_POINT_new(group));
- ScopedBN_CTX ctx(BN_CTX_new());
+ bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group));
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
- ScopedBIGNUM x(BN_new());
- ScopedBIGNUM y(BN_new());
+ bssl::UniquePtr<BIGNUM> x(BN_new());
+ bssl::UniquePtr<BIGNUM> y(BN_new());
if (!point || !ctx || !x || !y ||
!EC_POINT_mul(group, point.get(), NULL,
@@ -349,7 +375,7 @@
return true;
}
- ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
if (!key ||
!EC_KEY_generate_key(key.get())) {
return false;
@@ -478,9 +504,9 @@
static const uint8_t kAliceName[] = {'A'};
static const uint8_t kBobName[] = {'B'};
static const uint8_t kPassword[] = "password";
- ScopedSPAKE2_CTX alice(SPAKE2_CTX_new(spake2_role_alice, kAliceName,
- sizeof(kAliceName), kBobName,
- sizeof(kBobName)));
+ bssl::UniquePtr<SPAKE2_CTX> alice(SPAKE2_CTX_new(spake2_role_alice,
+ kAliceName, sizeof(kAliceName), kBobName,
+ sizeof(kBobName)));
uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE];
size_t alice_msg_len;
@@ -492,9 +518,9 @@
}
if (!TimeFunction(&results, [&alice_msg, alice_msg_len]() -> bool {
- ScopedSPAKE2_CTX bob(SPAKE2_CTX_new(spake2_role_bob, kBobName,
- sizeof(kBobName), kAliceName,
- sizeof(kAliceName)));
+ bssl::UniquePtr<SPAKE2_CTX> bob(SPAKE2_CTX_new(spake2_role_bob,
+ kBobName, sizeof(kBobName), kAliceName,
+ sizeof(kAliceName)));
uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE], bob_key[64];
size_t bob_msg_len, bob_key_len;
if (!SPAKE2_generate_msg(bob.get(), bob_msg, &bob_msg_len,
@@ -543,14 +569,34 @@
return true;
}
+static const struct argument kArguments[] = {
+ {
+ "-filter", kOptionalArgument,
+ "A filter on the speed tests to run",
+ },
+ {
+ "-timeout", kOptionalArgument,
+ "The number of seconds to run each test for (default is 1)",
+ },
+ {
+ "", kOptionalArgument, "",
+ },
+};
+
bool Speed(const std::vector<std::string> &args) {
- std::string selected;
- if (args.size() > 1) {
- fprintf(stderr, "Usage: bssl speed [speed test selector, i.e. 'RNG']\n");
+ std::map<std::string, std::string> args_map;
+ if (!ParseKeyValueArguments(&args_map, args, kArguments)) {
+ PrintUsage(kArguments);
return false;
}
- if (args.size() > 0) {
- selected = args[0];
+
+ std::string selected;
+ if (args_map.count("-filter") != 0) {
+ selected = args_map["-filter"];
+ }
+
+ if (args_map.count("-timeout") != 0) {
+ g_timeout_seconds = atoi(args_map["-timeout"].c_str());
}
RSA *key = RSA_private_key_from_bytes(kDERRSAPrivate2048,
diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc
index 23fa3bb..9a3612c 100644
--- a/src/tool/transport_common.cc
+++ b/src/tool/transport_common.cc
@@ -201,6 +201,36 @@
return false;
}
+static const char *SignatureAlgorithmToString(uint16_t version, uint16_t sigalg) {
+ const bool is_tls12 = version == TLS1_2_VERSION || version == DTLS1_2_VERSION;
+ switch (sigalg) {
+ case SSL_SIGN_RSA_PKCS1_SHA1:
+ return "rsa_pkcs1_sha1";
+ case SSL_SIGN_RSA_PKCS1_SHA256:
+ return "rsa_pkcs1_sha256";
+ case SSL_SIGN_RSA_PKCS1_SHA384:
+ return "rsa_pkcs1_sha384";
+ case SSL_SIGN_RSA_PKCS1_SHA512:
+ return "rsa_pkcs1_sha512";
+ case SSL_SIGN_ECDSA_SHA1:
+ return "ecdsa_sha1";
+ case SSL_SIGN_ECDSA_SECP256R1_SHA256:
+ return is_tls12 ? "ecdsa_sha256" : "ecdsa_secp256r1_sha256";
+ case SSL_SIGN_ECDSA_SECP384R1_SHA384:
+ return is_tls12 ? "ecdsa_sha384" : "ecdsa_secp384r1_sha384";
+ case SSL_SIGN_ECDSA_SECP521R1_SHA512:
+ return is_tls12 ? "ecdsa_sha512" : "ecdsa_secp521r1_sha512";
+ case SSL_SIGN_RSA_PSS_SHA256:
+ return "rsa_pss_sha256";
+ case SSL_SIGN_RSA_PSS_SHA384:
+ return "rsa_pss_sha384";
+ case SSL_SIGN_RSA_PSS_SHA512:
+ return "rsa_pss_sha512";
+ default:
+ return "(unknown)";
+ }
+}
+
void PrintConnectionInfo(const SSL *ssl) {
const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
@@ -216,6 +246,11 @@
if (dhe_bits != 0) {
fprintf(stderr, " DHE group size: %u bits\n", dhe_bits);
}
+ uint16_t sigalg = SSL_get_peer_signature_algorithm(ssl);
+ if (sigalg != 0) {
+ fprintf(stderr, " Signature algorithm: %s\n",
+ SignatureAlgorithmToString(SSL_version(ssl), sigalg));
+ }
fprintf(stderr, " Secure renegotiation: %s\n",
SSL_get_secure_renegotiation_support(ssl) ? "yes" : "no");
fprintf(stderr, " Extended master secret: %s\n",
diff --git a/src/util/BUILD.toplevel b/src/util/BUILD.toplevel
index 51e95b1..6b645e6 100644
--- a/src/util/BUILD.toplevel
+++ b/src/util/BUILD.toplevel
@@ -113,10 +113,7 @@
cc_binary(
name = "bssl",
- srcs = tool_sources + tool_headers + [
- "src/crypto/test/scoped_types.h",
- "src/ssl/test/scoped_types.h",
- ],
+ srcs = tool_sources + tool_headers,
copts = boringssl_copts_cxx,
visibility = ["//visibility:public"],
deps = [":ssl"],
diff --git a/src/util/all_tests.json b/src/util/all_tests.json
index b2e8139..1ba529b 100644
--- a/src/util/all_tests.json
+++ b/src/util/all_tests.json
@@ -41,7 +41,10 @@
["crypto/dsa/dsa_test"],
["crypto/ec/ec_test"],
["crypto/ec/example_mul"],
+ ["crypto/ecdh/ecdh_test", "crypto/ecdh/ecdh_tests.txt"],
+ ["crypto/ecdsa/ecdsa_sign_test", "crypto/ecdsa/ecdsa_sign_tests.txt"],
["crypto/ecdsa/ecdsa_test"],
+ ["crypto/ecdsa/ecdsa_verify_test", "crypto/ecdsa/ecdsa_verify_tests.txt"],
["crypto/err/err_test"],
["crypto/evp/evp_extra_test"],
["crypto/evp/evp_test", "crypto/evp/evp_tests.txt"],
diff --git a/src/util/bot/DEPS b/src/util/bot/DEPS
index 2a1e01a..c57864c 100644
--- a/src/util/bot/DEPS
+++ b/src/util/bot/DEPS
@@ -18,13 +18,13 @@
deps = {
'boringssl/util/bot/gyp':
- Var('chromium_git') + '/external/gyp.git' + '@' + '4cf07e8d616739f6484e46c9359b2a35196b2585',
+ Var('chromium_git') + '/external/gyp.git' + '@' + 'e7079f0e0e14108ab0dba58728ff219637458563',
}
deps_os = {
'android': {
'boringssl/util/bot/android_tools':
- Var('chromium_git') + '/android_tools.git' + '@' + '5b5f2f60b78198eaef25d442ac60f823142a8a6e',
+ Var('chromium_git') + '/android_tools.git' + '@' + 'af1c5a4cd6329ccdcf8c2bc93d9eea02f9d74869',
},
}
diff --git a/src/util/bot/go/bootstrap.py b/src/util/bot/go/bootstrap.py
index 8d08cc3..058cc6c 100755
--- a/src/util/bot/go/bootstrap.py
+++ b/src/util/bot/go/bootstrap.py
@@ -45,7 +45,7 @@
EXE_SFX = '.exe' if sys.platform == 'win32' else ''
# Pinned version of Go toolset to download.
-TOOLSET_VERSION = 'go1.6.2'
+TOOLSET_VERSION = 'go1.7'
# Platform dependent portion of a download URL. See http://golang.org/dl/.
TOOLSET_VARIANTS = {
diff --git a/src/util/bot/update_clang.py b/src/util/bot/update_clang.py
index e48a287..cd446e8 100644
--- a/src/util/bot/update_clang.py
+++ b/src/util/bot/update_clang.py
@@ -22,7 +22,7 @@
# CLANG_REVISION and CLANG_SUB_REVISION determine the build of clang
# to use. These should be synced with tools/clang/scripts/update.py in
# Chromium.
-CLANG_REVISION = "267383"
+CLANG_REVISION = "280106"
CLANG_SUB_REVISION = "1"
PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)
diff --git a/win-x86/crypto/rc4/rc4-586.asm b/win-x86/crypto/rc4/rc4-586.asm
deleted file mode 100644
index 0bab2be..0000000
--- a/win-x86/crypto/rc4/rc4-586.asm
+++ /dev/null
@@ -1,353 +0,0 @@
-%ifidn __OUTPUT_FORMAT__,obj
-section code use32 class=code align=64
-%elifidn __OUTPUT_FORMAT__,win32
-%ifdef __YASM_VERSION_ID__
-%if __YASM_VERSION_ID__ < 01010000h
-%error yasm version 1.1.0 or later needed.
-%endif
-; Yasm automatically includes .00 and complains about redefining it.
-; https://www.tortall.net/projects/yasm/manual/html/objfmt-win32-safeseh.html
-%else
-$@feat.00 equ 1
-%endif
-section .text code align=64
-%else
-section .text code
-%endif
-;extern _OPENSSL_ia32cap_P
-global _asm_RC4
-align 16
-_asm_RC4:
-L$_asm_RC4_begin:
- push ebp
- push ebx
- push esi
- push edi
- mov edi,DWORD [20+esp]
- mov edx,DWORD [24+esp]
- mov esi,DWORD [28+esp]
- mov ebp,DWORD [32+esp]
- xor eax,eax
- xor ebx,ebx
- cmp edx,0
- je NEAR L$000abort
- mov al,BYTE [edi]
- mov bl,BYTE [4+edi]
- add edi,8
- lea ecx,[edx*1+esi]
- sub ebp,esi
- mov DWORD [24+esp],ecx
- inc al
- cmp DWORD [256+edi],-1
- je NEAR L$001RC4_CHAR
- mov ecx,DWORD [eax*4+edi]
- and edx,-4
- jz NEAR L$002loop1
- mov DWORD [32+esp],ebp
- test edx,-8
- jz NEAR L$003go4loop4
- lea ebp,[_OPENSSL_ia32cap_P]
- bt DWORD [ebp],26
- jnc NEAR L$003go4loop4
- mov ebp,DWORD [32+esp]
- and edx,-8
- lea edx,[edx*1+esi-8]
- mov DWORD [edi-4],edx
- add bl,cl
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- inc eax
- add edx,ecx
- movzx eax,al
- movzx edx,dl
- movq mm0,[esi]
- mov ecx,DWORD [eax*4+edi]
- movd mm2,DWORD [edx*4+edi]
- jmp NEAR L$004loop_mmx_enter
-align 16
-L$005loop_mmx:
- add bl,cl
- psllq mm1,56
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- inc eax
- add edx,ecx
- movzx eax,al
- movzx edx,dl
- pxor mm2,mm1
- movq mm0,[esi]
- movq [esi*1+ebp-8],mm2
- mov ecx,DWORD [eax*4+edi]
- movd mm2,DWORD [edx*4+edi]
-L$004loop_mmx_enter:
- add bl,cl
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- inc eax
- add edx,ecx
- movzx eax,al
- movzx edx,dl
- pxor mm2,mm0
- mov ecx,DWORD [eax*4+edi]
- movd mm1,DWORD [edx*4+edi]
- add bl,cl
- psllq mm1,8
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- inc eax
- add edx,ecx
- movzx eax,al
- movzx edx,dl
- pxor mm2,mm1
- mov ecx,DWORD [eax*4+edi]
- movd mm1,DWORD [edx*4+edi]
- add bl,cl
- psllq mm1,16
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- inc eax
- add edx,ecx
- movzx eax,al
- movzx edx,dl
- pxor mm2,mm1
- mov ecx,DWORD [eax*4+edi]
- movd mm1,DWORD [edx*4+edi]
- add bl,cl
- psllq mm1,24
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- inc eax
- add edx,ecx
- movzx eax,al
- movzx edx,dl
- pxor mm2,mm1
- mov ecx,DWORD [eax*4+edi]
- movd mm1,DWORD [edx*4+edi]
- add bl,cl
- psllq mm1,32
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- inc eax
- add edx,ecx
- movzx eax,al
- movzx edx,dl
- pxor mm2,mm1
- mov ecx,DWORD [eax*4+edi]
- movd mm1,DWORD [edx*4+edi]
- add bl,cl
- psllq mm1,40
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- inc eax
- add edx,ecx
- movzx eax,al
- movzx edx,dl
- pxor mm2,mm1
- mov ecx,DWORD [eax*4+edi]
- movd mm1,DWORD [edx*4+edi]
- add bl,cl
- psllq mm1,48
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- inc eax
- add edx,ecx
- movzx eax,al
- movzx edx,dl
- pxor mm2,mm1
- mov ecx,DWORD [eax*4+edi]
- movd mm1,DWORD [edx*4+edi]
- mov edx,ebx
- xor ebx,ebx
- mov bl,dl
- cmp esi,DWORD [edi-4]
- lea esi,[8+esi]
- jb NEAR L$005loop_mmx
- psllq mm1,56
- pxor mm2,mm1
- movq [esi*1+ebp-8],mm2
- emms
- cmp esi,DWORD [24+esp]
- je NEAR L$006done
- jmp NEAR L$002loop1
-align 16
-L$003go4loop4:
- lea edx,[edx*1+esi-4]
- mov DWORD [28+esp],edx
-L$007loop4:
- add bl,cl
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- add edx,ecx
- inc al
- and edx,255
- mov ecx,DWORD [eax*4+edi]
- mov ebp,DWORD [edx*4+edi]
- add bl,cl
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- add edx,ecx
- inc al
- and edx,255
- ror ebp,8
- mov ecx,DWORD [eax*4+edi]
- or ebp,DWORD [edx*4+edi]
- add bl,cl
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- add edx,ecx
- inc al
- and edx,255
- ror ebp,8
- mov ecx,DWORD [eax*4+edi]
- or ebp,DWORD [edx*4+edi]
- add bl,cl
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- add edx,ecx
- inc al
- and edx,255
- ror ebp,8
- mov ecx,DWORD [32+esp]
- or ebp,DWORD [edx*4+edi]
- ror ebp,8
- xor ebp,DWORD [esi]
- cmp esi,DWORD [28+esp]
- mov DWORD [esi*1+ecx],ebp
- lea esi,[4+esi]
- mov ecx,DWORD [eax*4+edi]
- jb NEAR L$007loop4
- cmp esi,DWORD [24+esp]
- je NEAR L$006done
- mov ebp,DWORD [32+esp]
-align 16
-L$002loop1:
- add bl,cl
- mov edx,DWORD [ebx*4+edi]
- mov DWORD [ebx*4+edi],ecx
- mov DWORD [eax*4+edi],edx
- add edx,ecx
- inc al
- and edx,255
- mov edx,DWORD [edx*4+edi]
- xor dl,BYTE [esi]
- lea esi,[1+esi]
- mov ecx,DWORD [eax*4+edi]
- cmp esi,DWORD [24+esp]
- mov BYTE [esi*1+ebp-1],dl
- jb NEAR L$002loop1
- jmp NEAR L$006done
-align 16
-L$001RC4_CHAR:
- movzx ecx,BYTE [eax*1+edi]
-L$008cloop1:
- add bl,cl
- movzx edx,BYTE [ebx*1+edi]
- mov BYTE [ebx*1+edi],cl
- mov BYTE [eax*1+edi],dl
- add dl,cl
- movzx edx,BYTE [edx*1+edi]
- add al,1
- xor dl,BYTE [esi]
- lea esi,[1+esi]
- movzx ecx,BYTE [eax*1+edi]
- cmp esi,DWORD [24+esp]
- mov BYTE [esi*1+ebp-1],dl
- jb NEAR L$008cloop1
-L$006done:
- dec al
- mov DWORD [edi-4],ebx
- mov BYTE [edi-8],al
-L$000abort:
- pop edi
- pop esi
- pop ebx
- pop ebp
- ret
-global _asm_RC4_set_key
-align 16
-_asm_RC4_set_key:
-L$_asm_RC4_set_key_begin:
- push ebp
- push ebx
- push esi
- push edi
- mov edi,DWORD [20+esp]
- mov ebp,DWORD [24+esp]
- mov esi,DWORD [28+esp]
- lea edx,[_OPENSSL_ia32cap_P]
- lea edi,[8+edi]
- lea esi,[ebp*1+esi]
- neg ebp
- xor eax,eax
- mov DWORD [edi-4],ebp
- bt DWORD [edx],20
- jc NEAR L$009c1stloop
-align 16
-L$010w1stloop:
- mov DWORD [eax*4+edi],eax
- add al,1
- jnc NEAR L$010w1stloop
- xor ecx,ecx
- xor edx,edx
-align 16
-L$011w2ndloop:
- mov eax,DWORD [ecx*4+edi]
- add dl,BYTE [ebp*1+esi]
- add dl,al
- add ebp,1
- mov ebx,DWORD [edx*4+edi]
- jnz NEAR L$012wnowrap
- mov ebp,DWORD [edi-4]
-L$012wnowrap:
- mov DWORD [edx*4+edi],eax
- mov DWORD [ecx*4+edi],ebx
- add cl,1
- jnc NEAR L$011w2ndloop
- jmp NEAR L$013exit
-align 16
-L$009c1stloop:
- mov BYTE [eax*1+edi],al
- add al,1
- jnc NEAR L$009c1stloop
- xor ecx,ecx
- xor edx,edx
- xor ebx,ebx
-align 16
-L$014c2ndloop:
- mov al,BYTE [ecx*1+edi]
- add dl,BYTE [ebp*1+esi]
- add dl,al
- add ebp,1
- mov bl,BYTE [edx*1+edi]
- jnz NEAR L$015cnowrap
- mov ebp,DWORD [edi-4]
-L$015cnowrap:
- mov BYTE [edx*1+edi],al
- mov BYTE [ecx*1+edi],bl
- add cl,1
- jnc NEAR L$014c2ndloop
- mov DWORD [256+edi],-1
-L$013exit:
- xor eax,eax
- mov DWORD [edi-8],eax
- mov DWORD [edi-4],eax
- pop edi
- pop esi
- pop ebx
- pop ebp
- ret
-segment .bss
-common _OPENSSL_ia32cap_P 16
diff --git a/win-x86_64/crypto/rc4/rc4-x86_64.asm b/win-x86_64/crypto/rc4/rc4-x86_64.asm
deleted file mode 100644
index c7c3b7b..0000000
--- a/win-x86_64/crypto/rc4/rc4-x86_64.asm
+++ /dev/null
@@ -1,741 +0,0 @@
-default rel
-%define XMMWORD
-%define YMMWORD
-%define ZMMWORD
-section .text code align=64
-
-EXTERN OPENSSL_ia32cap_P
-
-global asm_RC4
-
-ALIGN 16
-asm_RC4:
- mov QWORD[8+rsp],rdi ;WIN64 prologue
- mov QWORD[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_asm_RC4:
- mov rdi,rcx
- mov rsi,rdx
- mov rdx,r8
- mov rcx,r9
-
-
- or rsi,rsi
- jne NEAR $L$entry
- mov rdi,QWORD[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$entry:
- push rbx
- push r12
- push r13
-$L$prologue:
- mov r11,rsi
- mov r12,rdx
- mov r13,rcx
- xor r10,r10
- xor rcx,rcx
-
- lea rdi,[8+rdi]
- mov r10b,BYTE[((-8))+rdi]
- mov cl,BYTE[((-4))+rdi]
- cmp DWORD[256+rdi],-1
- je NEAR $L$RC4_CHAR
- mov r8d,DWORD[OPENSSL_ia32cap_P]
- xor rbx,rbx
- inc r10b
- sub rbx,r10
- sub r13,r12
- mov eax,DWORD[r10*4+rdi]
- test r11,-16
- jz NEAR $L$loop1
- bt r8d,30
- jc NEAR $L$intel
- and rbx,7
- lea rsi,[1+r10]
- jz NEAR $L$oop8
- sub r11,rbx
-$L$oop8_warmup:
- add cl,al
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- mov DWORD[r10*4+rdi],edx
- add al,dl
- inc r10b
- mov edx,DWORD[rax*4+rdi]
- mov eax,DWORD[r10*4+rdi]
- xor dl,BYTE[r12]
- mov BYTE[r13*1+r12],dl
- lea r12,[1+r12]
- dec rbx
- jnz NEAR $L$oop8_warmup
-
- lea rsi,[1+r10]
- jmp NEAR $L$oop8
-ALIGN 16
-$L$oop8:
- add cl,al
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- mov ebx,DWORD[rsi*4+rdi]
- ror r8,8
- mov DWORD[r10*4+rdi],edx
- add dl,al
- mov r8b,BYTE[rdx*4+rdi]
- add cl,bl
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- mov eax,DWORD[4+rsi*4+rdi]
- ror r8,8
- mov DWORD[4+r10*4+rdi],edx
- add dl,bl
- mov r8b,BYTE[rdx*4+rdi]
- add cl,al
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- mov ebx,DWORD[8+rsi*4+rdi]
- ror r8,8
- mov DWORD[8+r10*4+rdi],edx
- add dl,al
- mov r8b,BYTE[rdx*4+rdi]
- add cl,bl
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- mov eax,DWORD[12+rsi*4+rdi]
- ror r8,8
- mov DWORD[12+r10*4+rdi],edx
- add dl,bl
- mov r8b,BYTE[rdx*4+rdi]
- add cl,al
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- mov ebx,DWORD[16+rsi*4+rdi]
- ror r8,8
- mov DWORD[16+r10*4+rdi],edx
- add dl,al
- mov r8b,BYTE[rdx*4+rdi]
- add cl,bl
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- mov eax,DWORD[20+rsi*4+rdi]
- ror r8,8
- mov DWORD[20+r10*4+rdi],edx
- add dl,bl
- mov r8b,BYTE[rdx*4+rdi]
- add cl,al
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- mov ebx,DWORD[24+rsi*4+rdi]
- ror r8,8
- mov DWORD[24+r10*4+rdi],edx
- add dl,al
- mov r8b,BYTE[rdx*4+rdi]
- add sil,8
- add cl,bl
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- mov eax,DWORD[((-4))+rsi*4+rdi]
- ror r8,8
- mov DWORD[28+r10*4+rdi],edx
- add dl,bl
- mov r8b,BYTE[rdx*4+rdi]
- add r10b,8
- ror r8,8
- sub r11,8
-
- xor r8,QWORD[r12]
- mov QWORD[r13*1+r12],r8
- lea r12,[8+r12]
-
- test r11,-8
- jnz NEAR $L$oop8
- cmp r11,0
- jne NEAR $L$loop1
- jmp NEAR $L$exit
-
-ALIGN 16
-$L$intel:
- test r11,-32
- jz NEAR $L$loop1
- and rbx,15
- jz NEAR $L$oop16_is_hot
- sub r11,rbx
-$L$oop16_warmup:
- add cl,al
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- mov DWORD[r10*4+rdi],edx
- add al,dl
- inc r10b
- mov edx,DWORD[rax*4+rdi]
- mov eax,DWORD[r10*4+rdi]
- xor dl,BYTE[r12]
- mov BYTE[r13*1+r12],dl
- lea r12,[1+r12]
- dec rbx
- jnz NEAR $L$oop16_warmup
-
- mov rbx,rcx
- xor rcx,rcx
- mov cl,bl
-
-$L$oop16_is_hot:
- lea rsi,[r10*4+rdi]
- add cl,al
- mov edx,DWORD[rcx*4+rdi]
- pxor xmm0,xmm0
- mov DWORD[rcx*4+rdi],eax
- add al,dl
- mov ebx,DWORD[4+rsi]
- movzx eax,al
- mov DWORD[rsi],edx
- add cl,bl
- pinsrw xmm0,WORD[rax*4+rdi],0
- jmp NEAR $L$oop16_enter
-ALIGN 16
-$L$oop16:
- add cl,al
- mov edx,DWORD[rcx*4+rdi]
- pxor xmm2,xmm0
- psllq xmm1,8
- pxor xmm0,xmm0
- mov DWORD[rcx*4+rdi],eax
- add al,dl
- mov ebx,DWORD[4+rsi]
- movzx eax,al
- mov DWORD[rsi],edx
- pxor xmm2,xmm1
- add cl,bl
- pinsrw xmm0,WORD[rax*4+rdi],0
- movdqu XMMWORD[r13*1+r12],xmm2
- lea r12,[16+r12]
-$L$oop16_enter:
- mov edx,DWORD[rcx*4+rdi]
- pxor xmm1,xmm1
- mov DWORD[rcx*4+rdi],ebx
- add bl,dl
- mov eax,DWORD[8+rsi]
- movzx ebx,bl
- mov DWORD[4+rsi],edx
- add cl,al
- pinsrw xmm1,WORD[rbx*4+rdi],0
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- add al,dl
- mov ebx,DWORD[12+rsi]
- movzx eax,al
- mov DWORD[8+rsi],edx
- add cl,bl
- pinsrw xmm0,WORD[rax*4+rdi],1
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- add bl,dl
- mov eax,DWORD[16+rsi]
- movzx ebx,bl
- mov DWORD[12+rsi],edx
- add cl,al
- pinsrw xmm1,WORD[rbx*4+rdi],1
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- add al,dl
- mov ebx,DWORD[20+rsi]
- movzx eax,al
- mov DWORD[16+rsi],edx
- add cl,bl
- pinsrw xmm0,WORD[rax*4+rdi],2
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- add bl,dl
- mov eax,DWORD[24+rsi]
- movzx ebx,bl
- mov DWORD[20+rsi],edx
- add cl,al
- pinsrw xmm1,WORD[rbx*4+rdi],2
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- add al,dl
- mov ebx,DWORD[28+rsi]
- movzx eax,al
- mov DWORD[24+rsi],edx
- add cl,bl
- pinsrw xmm0,WORD[rax*4+rdi],3
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- add bl,dl
- mov eax,DWORD[32+rsi]
- movzx ebx,bl
- mov DWORD[28+rsi],edx
- add cl,al
- pinsrw xmm1,WORD[rbx*4+rdi],3
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- add al,dl
- mov ebx,DWORD[36+rsi]
- movzx eax,al
- mov DWORD[32+rsi],edx
- add cl,bl
- pinsrw xmm0,WORD[rax*4+rdi],4
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- add bl,dl
- mov eax,DWORD[40+rsi]
- movzx ebx,bl
- mov DWORD[36+rsi],edx
- add cl,al
- pinsrw xmm1,WORD[rbx*4+rdi],4
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- add al,dl
- mov ebx,DWORD[44+rsi]
- movzx eax,al
- mov DWORD[40+rsi],edx
- add cl,bl
- pinsrw xmm0,WORD[rax*4+rdi],5
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- add bl,dl
- mov eax,DWORD[48+rsi]
- movzx ebx,bl
- mov DWORD[44+rsi],edx
- add cl,al
- pinsrw xmm1,WORD[rbx*4+rdi],5
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- add al,dl
- mov ebx,DWORD[52+rsi]
- movzx eax,al
- mov DWORD[48+rsi],edx
- add cl,bl
- pinsrw xmm0,WORD[rax*4+rdi],6
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- add bl,dl
- mov eax,DWORD[56+rsi]
- movzx ebx,bl
- mov DWORD[52+rsi],edx
- add cl,al
- pinsrw xmm1,WORD[rbx*4+rdi],6
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- add al,dl
- mov ebx,DWORD[60+rsi]
- movzx eax,al
- mov DWORD[56+rsi],edx
- add cl,bl
- pinsrw xmm0,WORD[rax*4+rdi],7
- add r10b,16
- movdqu xmm2,XMMWORD[r12]
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],ebx
- add bl,dl
- movzx ebx,bl
- mov DWORD[60+rsi],edx
- lea rsi,[r10*4+rdi]
- pinsrw xmm1,WORD[rbx*4+rdi],7
- mov eax,DWORD[rsi]
- mov rbx,rcx
- xor rcx,rcx
- sub r11,16
- mov cl,bl
- test r11,-16
- jnz NEAR $L$oop16
-
- psllq xmm1,8
- pxor xmm2,xmm0
- pxor xmm2,xmm1
- movdqu XMMWORD[r13*1+r12],xmm2
- lea r12,[16+r12]
-
- cmp r11,0
- jne NEAR $L$loop1
- jmp NEAR $L$exit
-
-ALIGN 16
-$L$loop1:
- add cl,al
- mov edx,DWORD[rcx*4+rdi]
- mov DWORD[rcx*4+rdi],eax
- mov DWORD[r10*4+rdi],edx
- add al,dl
- inc r10b
- mov edx,DWORD[rax*4+rdi]
- mov eax,DWORD[r10*4+rdi]
- xor dl,BYTE[r12]
- mov BYTE[r13*1+r12],dl
- lea r12,[1+r12]
- dec r11
- jnz NEAR $L$loop1
- jmp NEAR $L$exit
-
-ALIGN 16
-$L$RC4_CHAR:
- add r10b,1
- movzx eax,BYTE[r10*1+rdi]
- test r11,-8
- jz NEAR $L$cloop1
- jmp NEAR $L$cloop8
-ALIGN 16
-$L$cloop8:
- mov r8d,DWORD[r12]
- mov r9d,DWORD[4+r12]
- add cl,al
- lea rsi,[1+r10]
- movzx edx,BYTE[rcx*1+rdi]
- movzx esi,sil
- movzx ebx,BYTE[rsi*1+rdi]
- mov BYTE[rcx*1+rdi],al
- cmp rcx,rsi
- mov BYTE[r10*1+rdi],dl
- jne NEAR $L$cmov0
- mov rbx,rax
-$L$cmov0:
- add dl,al
- xor r8b,BYTE[rdx*1+rdi]
- ror r8d,8
- add cl,bl
- lea r10,[1+rsi]
- movzx edx,BYTE[rcx*1+rdi]
- movzx r10d,r10b
- movzx eax,BYTE[r10*1+rdi]
- mov BYTE[rcx*1+rdi],bl
- cmp rcx,r10
- mov BYTE[rsi*1+rdi],dl
- jne NEAR $L$cmov1
- mov rax,rbx
-$L$cmov1:
- add dl,bl
- xor r8b,BYTE[rdx*1+rdi]
- ror r8d,8
- add cl,al
- lea rsi,[1+r10]
- movzx edx,BYTE[rcx*1+rdi]
- movzx esi,sil
- movzx ebx,BYTE[rsi*1+rdi]
- mov BYTE[rcx*1+rdi],al
- cmp rcx,rsi
- mov BYTE[r10*1+rdi],dl
- jne NEAR $L$cmov2
- mov rbx,rax
-$L$cmov2:
- add dl,al
- xor r8b,BYTE[rdx*1+rdi]
- ror r8d,8
- add cl,bl
- lea r10,[1+rsi]
- movzx edx,BYTE[rcx*1+rdi]
- movzx r10d,r10b
- movzx eax,BYTE[r10*1+rdi]
- mov BYTE[rcx*1+rdi],bl
- cmp rcx,r10
- mov BYTE[rsi*1+rdi],dl
- jne NEAR $L$cmov3
- mov rax,rbx
-$L$cmov3:
- add dl,bl
- xor r8b,BYTE[rdx*1+rdi]
- ror r8d,8
- add cl,al
- lea rsi,[1+r10]
- movzx edx,BYTE[rcx*1+rdi]
- movzx esi,sil
- movzx ebx,BYTE[rsi*1+rdi]
- mov BYTE[rcx*1+rdi],al
- cmp rcx,rsi
- mov BYTE[r10*1+rdi],dl
- jne NEAR $L$cmov4
- mov rbx,rax
-$L$cmov4:
- add dl,al
- xor r9b,BYTE[rdx*1+rdi]
- ror r9d,8
- add cl,bl
- lea r10,[1+rsi]
- movzx edx,BYTE[rcx*1+rdi]
- movzx r10d,r10b
- movzx eax,BYTE[r10*1+rdi]
- mov BYTE[rcx*1+rdi],bl
- cmp rcx,r10
- mov BYTE[rsi*1+rdi],dl
- jne NEAR $L$cmov5
- mov rax,rbx
-$L$cmov5:
- add dl,bl
- xor r9b,BYTE[rdx*1+rdi]
- ror r9d,8
- add cl,al
- lea rsi,[1+r10]
- movzx edx,BYTE[rcx*1+rdi]
- movzx esi,sil
- movzx ebx,BYTE[rsi*1+rdi]
- mov BYTE[rcx*1+rdi],al
- cmp rcx,rsi
- mov BYTE[r10*1+rdi],dl
- jne NEAR $L$cmov6
- mov rbx,rax
-$L$cmov6:
- add dl,al
- xor r9b,BYTE[rdx*1+rdi]
- ror r9d,8
- add cl,bl
- lea r10,[1+rsi]
- movzx edx,BYTE[rcx*1+rdi]
- movzx r10d,r10b
- movzx eax,BYTE[r10*1+rdi]
- mov BYTE[rcx*1+rdi],bl
- cmp rcx,r10
- mov BYTE[rsi*1+rdi],dl
- jne NEAR $L$cmov7
- mov rax,rbx
-$L$cmov7:
- add dl,bl
- xor r9b,BYTE[rdx*1+rdi]
- ror r9d,8
- lea r11,[((-8))+r11]
- mov DWORD[r13],r8d
- lea r12,[8+r12]
- mov DWORD[4+r13],r9d
- lea r13,[8+r13]
-
- test r11,-8
- jnz NEAR $L$cloop8
- cmp r11,0
- jne NEAR $L$cloop1
- jmp NEAR $L$exit
-ALIGN 16
-$L$cloop1:
- add cl,al
- movzx ecx,cl
- movzx edx,BYTE[rcx*1+rdi]
- mov BYTE[rcx*1+rdi],al
- mov BYTE[r10*1+rdi],dl
- add dl,al
- add r10b,1
- movzx edx,dl
- movzx r10d,r10b
- movzx edx,BYTE[rdx*1+rdi]
- movzx eax,BYTE[r10*1+rdi]
- xor dl,BYTE[r12]
- lea r12,[1+r12]
- mov BYTE[r13],dl
- lea r13,[1+r13]
- sub r11,1
- jnz NEAR $L$cloop1
- jmp NEAR $L$exit
-
-ALIGN 16
-$L$exit:
- sub r10b,1
- mov DWORD[((-8))+rdi],r10d
- mov DWORD[((-4))+rdi],ecx
-
- mov r13,QWORD[rsp]
- mov r12,QWORD[8+rsp]
- mov rbx,QWORD[16+rsp]
- add rsp,24
-$L$epilogue:
- mov rdi,QWORD[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$SEH_end_asm_RC4:
-global asm_RC4_set_key
-
-ALIGN 16
-asm_RC4_set_key:
- mov QWORD[8+rsp],rdi ;WIN64 prologue
- mov QWORD[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_asm_RC4_set_key:
- mov rdi,rcx
- mov rsi,rdx
- mov rdx,r8
-
-
- lea rdi,[8+rdi]
- lea rdx,[rsi*1+rdx]
- neg rsi
- mov rcx,rsi
- xor eax,eax
- xor r9,r9
- xor r10,r10
- xor r11,r11
-
- mov r8d,DWORD[OPENSSL_ia32cap_P]
- bt r8d,20
- jc NEAR $L$c1stloop
- jmp NEAR $L$w1stloop
-
-ALIGN 16
-$L$w1stloop:
- mov DWORD[rax*4+rdi],eax
- add al,1
- jnc NEAR $L$w1stloop
-
- xor r9,r9
- xor r8,r8
-ALIGN 16
-$L$w2ndloop:
- mov r10d,DWORD[r9*4+rdi]
- add r8b,BYTE[rsi*1+rdx]
- add r8b,r10b
- add rsi,1
- mov r11d,DWORD[r8*4+rdi]
- cmovz rsi,rcx
- mov DWORD[r8*4+rdi],r10d
- mov DWORD[r9*4+rdi],r11d
- add r9b,1
- jnc NEAR $L$w2ndloop
- jmp NEAR $L$exit_key
-
-ALIGN 16
-$L$c1stloop:
- mov BYTE[rax*1+rdi],al
- add al,1
- jnc NEAR $L$c1stloop
-
- xor r9,r9
- xor r8,r8
-ALIGN 16
-$L$c2ndloop:
- mov r10b,BYTE[r9*1+rdi]
- add r8b,BYTE[rsi*1+rdx]
- add r8b,r10b
- add rsi,1
- mov r11b,BYTE[r8*1+rdi]
- jnz NEAR $L$cnowrap
- mov rsi,rcx
-$L$cnowrap:
- mov BYTE[r8*1+rdi],r10b
- mov BYTE[r9*1+rdi],r11b
- add r9b,1
- jnc NEAR $L$c2ndloop
- mov DWORD[256+rdi],-1
-
-ALIGN 16
-$L$exit_key:
- xor eax,eax
- mov DWORD[((-8))+rdi],eax
- mov DWORD[((-4))+rdi],eax
- mov rdi,QWORD[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$SEH_end_asm_RC4_set_key:
-EXTERN __imp_RtlVirtualUnwind
-
-ALIGN 16
-stream_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$prologue]
- 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
-
- lea rax,[24+rax]
-
- mov rbx,QWORD[((-8))+rax]
- mov r12,QWORD[((-16))+rax]
- mov r13,QWORD[((-24))+rax]
- mov QWORD[144+r8],rbx
- mov QWORD[216+r8],r12
- mov QWORD[224+r8],r13
-
-$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
-
- jmp NEAR $L$common_seh_exit
-
-
-
-ALIGN 16
-key_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[152+r8]
- mov rdi,QWORD[8+rax]
- mov rsi,QWORD[16+rax]
- mov QWORD[168+r8],rsi
- mov QWORD[176+r8],rdi
-
-$L$common_seh_exit:
-
- 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_asm_RC4 wrt ..imagebase
- DD $L$SEH_end_asm_RC4 wrt ..imagebase
- DD $L$SEH_info_asm_RC4 wrt ..imagebase
-
- DD $L$SEH_begin_asm_RC4_set_key wrt ..imagebase
- DD $L$SEH_end_asm_RC4_set_key wrt ..imagebase
- DD $L$SEH_info_asm_RC4_set_key wrt ..imagebase
-
-section .xdata rdata align=8
-ALIGN 8
-$L$SEH_info_asm_RC4:
-DB 9,0,0,0
- DD stream_se_handler wrt ..imagebase
-$L$SEH_info_asm_RC4_set_key:
-DB 9,0,0,0
- DD key_se_handler wrt ..imagebase