I have tryed to sign sha256 digest using ECDSA_OpenSSL() method and
secp160r1 domain parameters. Unfortunately during this operation
apears an error which sugests that I am trying to sign too long
digest. But in such standards as IEEE 1363-2000 and SEC-1 (I do not
know what is in ANSI X9.62-2005) there is possibility to sign
arbitrary long digest with any domain parameters.

In SEC-1 we have following steps to convert arbitrary long hash to
integer 'e' (this integer is called 'm' in OpenSSL implementation).
This procedure is both in sign and verification primitive.

# Number 'n' denotes order of EC generator.

4. Use the hash function selected during the setup procedure
to compute the hash value:
H = Hash(M)
of length hashlen octets as specified in Section 3.5. If the
hash function outputs 'invalid', output 'invalid' and stop.

5. Derive an integer e from H as follows:
5.1. Convert the octet string H to a bit string H
using the conversion routine OS2BS.
5.2. Set E = H if ceil(log_2(n)) >= 8*hashlen, and
set E equal to the leftmost ceil(log_2(n)) bits of
H if ceil(log_2(n)) < 8*hashlen.
5.3. Convert the bit string E to an octet string
EOS using the conversion routine BS2OS.
5.4. Convert the octet string EOS to an integer e
using the conversion routine OS2Int.


In function ecdsa_do_sign in crypto/ecdsa/ecs_ossl.c we have

>
> if (dgst_len > BN_num_bytes(order))
> {
> ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
> ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
> goto err;
> }
>
> if (!BN_bin2bn(dgst, dgst_len, m))
> {
> ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
> goto err;
> }
>


I sugest to change this implementation as follows

>
> /* digest -> m (as stated in SEC-1 4.1.3 signing operation) */
> if (!BN_bin2bn(dgst, dgst_len, m))
> {
> ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
> goto err;
> }
>
> if ( (BN_num_bits(order) < 8*dgst_len)
> && !BN_rshift(m, m, 8*dgst_len - BN_num_bits(order)) )
> {
> ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
> goto err;
> }
>


The same situation is in ecdsa_do_verify function in crypto/ecdsa/ecs_ossl.c

>
> /* digest -> m */
> if (!BN_bin2bn(dgst, dgst_len, m))
> {
> ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
> goto err;
> }
> /* u1 = m * tmp mod order */
> if (!BN_mod_mul(u1, m, u2, order, ctx))
> {
> ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
> goto err;
> }
>


I sugest to change this implementation as follows

>
> /* digest -> m (as stated in SEC-1 4.1.3 verifying operation) */
> if (!BN_bin2bn(dgst, dgst_len, m))
> {
> ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
> goto err;
> }
>
> if ( (BN_num_bits(order) < 8*dgst_len)
> && !BN_rshift(m, m, 8*dgst_len - BN_num_bits(order)) )
> {
> ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
> goto err;
> }
>
> /* u1 = m * tmp mod order */
> if (!BN_mod_mul(u1, m, u2, order, ctx))
> {
> ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
> goto err;
> }
>

__________________________________________________ ____________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-dev@openssl.org
Automated List Manager majordomo@openssl.org