From aeb088ac096ac7ca672a1066fba291935dfa4782 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Fri, 20 Jun 2014 12:00:00 -0700 Subject: [PATCH] EC infinity fix. Fix handling of points at infinity in ec_GFp_simple_points_make_affine. When inverting an array of Z coordinates, the algorithm is supposed to treat any 0 essentially like a 1 to remain in the multiplicative group; however, for one of the cases, we incorrectly multiplied by 0 and thus ended up with garbage. --- crypto/ec/simple.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/crypto/ec/simple.c b/crypto/ec/simple.c index 144d056a..c62deb0d 100644 --- a/crypto/ec/simple.c +++ b/crypto/ec/simple.c @@ -1232,6 +1232,11 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, if (heap == NULL) goto err; + /* TODO(bmoeller): There is no reason to use this tree structure. + * We should instead proceed sequentially, exactly as in + * ec_GFp_nistp_points_make_affine_internal, which makes everything + * much simpler. */ + /* The array is used as a binary tree, exactly as in heapsort: * * heap[1] @@ -1300,14 +1305,19 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, for (i = 2; i < pow2 / 2 + num; i += 2) { /* i is even */ if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1])) { - if (!group->meth->field_mul(group, tmp0, heap[i / 2], heap[i + 1], ctx)) - goto err; - if (!group->meth->field_mul(group, tmp1, heap[i / 2], heap[i], ctx)) - goto err; - if (!BN_copy(heap[i], tmp0)) - goto err; - if (!BN_copy(heap[i + 1], tmp1)) - goto err; + if (!BN_is_zero(heap[i])) { + if (!group->meth->field_mul(group, tmp0, heap[i / 2], heap[i + 1], ctx)) + goto err; + if (!group->meth->field_mul(group, tmp1, heap[i / 2], heap[i], ctx)) + goto err; + if (!BN_copy(heap[i], tmp0)) + goto err; + if (!BN_copy(heap[i + 1], tmp1)) + goto err; + } else { + if (!BN_copy(heap[i + 1], heap[i / 2])) + goto err; + } } else { if (!BN_copy(heap[i], heap[i / 2])) goto err;