Use bn_rshift_words for the ECDSA bit-shift.

May as well use it. Also avoid an overflow with digest_len if someone
asks to sign a truly enormous digest.

Change-Id: Ia0a53007a496f9c7cadd44b1020ec2774b310936
Reviewed-on: https://boringssl-review.googlesource.com/26966
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/fipsmodule/bn/internal.h b/crypto/fipsmodule/bn/internal.h
index 7d96151..8c121a0 100644
--- a/crypto/fipsmodule/bn/internal.h
+++ b/crypto/fipsmodule/bn/internal.h
@@ -370,6 +370,11 @@
 // bn_rshift1_words sets |r| to |a| >> 1, where both arrays are |num| bits wide.
 void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num);
 
+// bn_rshift_words sets |r| to |a| >> |shift|, where both arrays are |num| bits
+// wide.
+void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift,
+                     size_t num);
+
 // bn_rshift_secret_shift behaves like |BN_rshift| but runs in time independent
 // of both |a| and |n|.
 OPENSSL_EXPORT int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a,
diff --git a/crypto/fipsmodule/bn/shift.c b/crypto/fipsmodule/bn/shift.c
index 3e71739..ccf7141 100644
--- a/crypto/fipsmodule/bn/shift.c
+++ b/crypto/fipsmodule/bn/shift.c
@@ -133,8 +133,8 @@
   return 1;
 }
 
-static void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift,
-                            size_t num) {
+void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift,
+                     size_t num) {
   unsigned shift_bits = shift % BN_BITS2;
   size_t shift_words = shift / BN_BITS2;
   if (shift_words >= num) {
diff --git a/crypto/fipsmodule/ecdsa/ecdsa.c b/crypto/fipsmodule/ecdsa/ecdsa.c
index 1d08123..2f73718 100644
--- a/crypto/fipsmodule/ecdsa/ecdsa.c
+++ b/crypto/fipsmodule/ecdsa/ecdsa.c
@@ -116,22 +116,18 @@
   const BIGNUM *order = &group->order;
   size_t num_bits = BN_num_bits(order);
   // Need to truncate digest if it is too long: first truncate whole bytes.
-  if (8 * digest_len > num_bits) {
-    digest_len = (num_bits + 7) / 8;
+  size_t num_bytes = (num_bits + 7) / 8;
+  if (digest_len > num_bytes) {
+    digest_len = num_bytes;
   }
   OPENSSL_memset(out, 0, sizeof(EC_SCALAR));
   for (size_t i = 0; i < digest_len; i++) {
     out->bytes[i] = digest[digest_len - 1 - i];
   }
 
-  // If still too long truncate remaining bits with a shift
+  // If it is still too long, truncate remaining bits with a shift.
   if (8 * digest_len > num_bits) {
-    size_t shift = 8 - (num_bits & 0x7);
-    for (int i = 0; i < order->width - 1; i++) {
-      out->words[i] =
-          (out->words[i] >> shift) | (out->words[i + 1] << (BN_BITS2 - shift));
-    }
-    out->words[order->width - 1] >>= shift;
+    bn_rshift_words(out->words, out->words, 8 - (num_bits & 0x7), order->width);
   }
 }