/* Provenance: openssl/openssl bn_sub_words (fixed). * repo: openssl/openssl * commit: a00d757d9ca212994625d1a02c81cc5edd27e13b * parent: 908eaceb62624f5b5c505b286d904bd3a4e8a64a * commit_url: https://github.com/openssl/openssl/commit/a00d757d9ca212994625d1a02c81cc5edd27e13b * cve: CVE-2022-4304 * license: Apache-2.0 * function: bn_sub_words * relpath: crypto/bn/bn_asm.c */ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) { BN_ULONG t1, t2; int c = 0; assert(n >= 0); if (n <= 0) return (BN_ULONG)0; #ifndef OPENSSL_SMALL_FOOTPRINT while (n & ~3) { t1 = a[0]; t2 = (t1 - c) & BN_MASK2; c = (t2 > t1); t1 = b[0]; t1 = (t2 - t1) & BN_MASK2; r[0] = t1; c += (t1 > t2); t1 = a[1]; t2 = (t1 - c) & BN_MASK2; c = (t2 > t1); t1 = b[1]; t1 = (t2 - t1) & BN_MASK2; r[1] = t1; c += (t1 > t2); t1 = a[2]; t2 = (t1 - c) & BN_MASK2; c = (t2 > t1); t1 = b[2]; t1 = (t2 - t1) & BN_MASK2; r[2] = t1; c += (t1 > t2); t1 = a[3]; t2 = (t1 - c) & BN_MASK2; c = (t2 > t1); t1 = b[3]; t1 = (t2 - t1) & BN_MASK2; r[3] = t1; c += (t1 > t2); a += 4; b += 4; r += 4; n -= 4; } #endif while (n) { t1 = a[0]; t2 = (t1 - c) & BN_MASK2; c = (t2 > t1); t1 = b[0]; t1 = (t2 - t1) & BN_MASK2; r[0] = t1; c += (t1 > t2); a++; b++; r++; n--; } return c; }