I've got a project ( https://github.com/zackw/moeller-ref ) which does a bunch of elliptic curve operations against custom curves, using the OpenSSL and/or Crypto++ low-level APIs (two parallel implementations of the same asymmetric cryptosystem). One function in each implementation performs decryption and therefore needs to run in constant time to prevent timing attacks. But nearly all the functions in <openssl/ec.h> and <openssl/bn.h> can fail, which means there are a good *nine* early exits from the decryption routine, all of them potentially data-dependent.
I'm appending the problematic routine. Does anyone know how to revise it so that even under failure conditions it always takes the same amount of time? You can see the whole file at https://github.com/zackw/moeller-ref/blob/master/mref-o.c . (The Crypto++ implementation probably has the same problem, but it's so slow that I do not imagine its being used for reals, and in any case, the immediate use I have for this code is in an application based on OpenSSL.) Thanks, zw int MKEM_decode_message(const MKEM *kp, uint8_t *secret, const uint8_t *message) { int use_curve0 = !(message[0] & kp->params->curve_bit); const EC_GROUP *ca = use_curve0 ? kp->params->c0 : kp->params->c1; const BIGNUM *sa = use_curve0 ? kp->s0 : kp->s1; EC_POINT *q = 0, *r = 0; uint8_t *unpadded = 0; BIGNUM x, y; size_t mlen = kp->params->msgsize; int rv; if (!kp->s0 || !kp->s1) /* secret key not available */ return -1; BN_init(&x); BN_init(&y); FAILZ(q = EC_POINT_new(ca)); FAILZ(r = EC_POINT_new(ca)); FAILZ(unpadded = malloc(mlen + 1)); /* Copy the message, erase the padding bits, and put an 0x02 byte on the front so we can use EC_POINT_oct2point to recover the y-coordinate. */ unpadded[0] = 0x02; unpadded[1] = (message[0] & ~(kp->params->pad_mask|kp->params->curve_bit)); memcpy(&unpadded[2], &message[1], mlen - 1); FAILZ(EC_POINT_oct2point(ca, q, unpadded, mlen + 1, kp->params->ctx)); FAILZ(EC_POINT_mul(ca, r, 0, q, sa, kp->params->ctx)); FAILZ(EC_POINT_get_affine_coordinates_GF2m(ca, q, &x, &y, kp->params->ctx)); if (bn2bin_padhi(&x, secret, mlen) != mlen) goto fail; FAILZ(EC_POINT_get_affine_coordinates_GF2m(ca, r, &x, &y, kp->params->ctx)); if (bn2bin_padhi(&x, secret + mlen, mlen) != mlen) goto fail; rv = 0; done: if (unpadded) { memset(unpadded, 0, mlen + 1); free(unpadded); } if (q) EC_POINT_clear_free(q); if (r) EC_POINT_clear_free(r); BN_clear(&x); BN_clear(&y); return rv; fail: rv = -1; memset(secret, 0, mlen * 2); goto done; } ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org