On Tue, Dec 18, 2018 at 12:07 AM Mike Blaguszewski wrote:
>
> Some code of mine reads a NIST P256 private key from bytes and derives the
> public key from it, and this derived public key is incorrect about 0.4% of
> the time. I’ve attached a sample program that does the following.
>
> 1. Generate a key-pair of type NID_X9_62_prime256v1
> 2. Write the public and private components to memory
> 3. Read the private key back from memory, derive the public key, and write
> that back out.
> 4. Compare this “round-tripped” public key to the public key generated in
> step 2.
>
> The public key from step 2 almost always matches the public key from step 3,
> but about 0.4% of the time they will differ. (The sample program runs a loop
> to determine this.) Further experiments suggest it’s the
> private_key_from_binary() function that is the problem, where I derive the
> public key using EC_POINT_mul(). The sample program omits error checking, but
> in the production code no errors are reported.
>
> Does anyone see a flaw in my logic, especially in how I’m deriving the public
> key from the private key? Also let me know if this would be better submitted
> as a GitHub issue, or even if it needs to be handled as a paid support
> request.
The sample code just segfaults for me in the first iteration, before
really generating a key, so it's hard to test:
Program received signal SIGSEGV, Segmentation fault.
0x77a7e3e0 in pkey_set_type (pkey=0x380, type=408, str=0x0,
len=-1) at crypto/evp/p_lib.c:181
(gdb) bt
#0 0x77a7e3e0 in pkey_set_type (pkey=0x380, type=408,
str=0x0, len=-1) at crypto/evp/p_lib.c:181
#1 0x77a7e546 in EVP_PKEY_set_type (pkey=0x380, type=408) at
crypto/evp/p_lib.c:221
#2 0x77a7e663 in EVP_PKEY_assign (pkey=0x380, type=408,
key=0x557587c0) at crypto/evp/p_lib.c:249
#3 0x77a248fb in pkey_ec_keygen (ctx=0x55758760,
pkey=0x380) at crypto/ec/ec_pmeth.c:416
#4 0x77a80912 in EVP_PKEY_keygen (ctx=0x55758760,
ppkey=0x7fffdd18) at crypto/evp/pmeth_gn.c:107
#5 0x5046 in generate_ec_key () at foo.c:18
#6 0x5256 in main () at foo.c:73
But 0.4% is suspiciously close to 1/256, so I'm willing to bet your
problem surrounds your size assumptions in various functions. Check
the manpage of e.g. EC_POINT_point2oct and grep for usage in the
library, but the idea is to pass NULL first, then malloc, then pass
that pointer. BN_bn2bin is different. Probably the size won't be fixed
(e.g., there is a 1/256 chance you'll have one byte less, i.e. leading
zero).
So all the static 32 and 33 byte assumptions aren't holding.
Also BN_bn2bin and EC_KEY_oct2priv are not inverses of each other
IIRC. (The former is raw bytes, latter ASN1 encoding.)
BBB
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users