Subversion Repositories

?revision_form?Rev ?revision_input??revision_submit??revision_endform?

Rev 154 | Blame | Compare with Previous | Last modification | View Log | RSS feed

Origin: upstream, https://git.lysator.liu.se/nettle/nettle/commit/fa269b6ad06dd13c901dbd84a12e52b918a09cd7
From: Niels Möller <nisse@lysator.liu.se>
Subject: CVE-2015-8804: Carry folding bug in x86_64 ecc_384_modp.
Bug: https://bugs.debian.org/813679

--- a/x86_64/ecc-384-modp.asm
+++ b/x86_64/ecc-384-modp.asm
@@ -20,7 +20,7 @@ C MA 02111-1301, USA.
        .file "ecc-384-modp.asm"
 
 define(<RP>, <%rsi>)
-define(<D4>, <%rax>)
+define(<D5>, <%rax>)
 define(<T0>, <%rbx>)
 define(<T1>, <%rcx>)
 define(<T2>, <%rdx>)
@@ -35,8 +35,8 @@ define(<H4>, <%r13>)
 define(<H5>, <%r14>)
 define(<C2>, <%r15>)
 define(<C0>, H5)       C Overlap
-define(<D0>, RP)       C Overlap
-define(<TMP>, H4)      C Overlap
+define(<TMP>, RP)      C Overlap
+
 
 PROLOGUE(nettle_ecc_384_modp)
        W64_ENTRY(2, 0)
@@ -48,34 +48,38 @@ PROLOGUE(nettle_ecc_384_modp)
        push    %r14
        push    %r15
 
-       C First get top 2 limbs, which need folding twice
+       C First get top 2 limbs, which need folding twice.
+       C B^10 = B^6 + B^4 + 2^32 (B-1)B^4.
+       C We handle the terms as follow:
        C
-       C   H5 H4
-       C     -H5
-       C  ------
-       C   H0 D4
+       C B^6: Folded immediatly.
        C
-       C Then shift right, (H1,H0,D4)  <--  (H0,D4) << 32
-       C and add
+       C B^4: Delayed, added in in the next folding.
        C
-       C     H5 H4
-       C     H1 H0
-       C ----------
-       C  C2 H1 H0
-
-       mov     80(RP), D4
-       mov     88(RP), H0
-       mov     D4, H4
-       mov     H0, H5
-       sub     H0, D4
-       sbb     $0, H0
-
-       mov     D4, T2
-       mov     H0, H1
-       shl     $32, H0
-       shr     $32, T2
+       C 2^32(B-1) B^4: Low half limb delayed until the next
+       C folding. Top 1.5 limbs subtracted and shifter now, resulting
+       C in 2.5 limbs. The low limb saved in D5, high 1.5 limbs added
+       C in.
+
+       mov     80(RP), H4
+       mov     88(RP), H5
+       C Shift right 32 bits, into H1, H0
+       mov     H4, H0
+       mov     H5, H1
+       mov     H5, D5
        shr     $32, H1
-       or      T2, H0
+       shl     $32, D5
+       shr     $32, H0
+       or      D5, H0
+
+       C       H1 H0
+       C       -  H1 H0
+       C       --------
+       C       H1 H0 D5
+       mov     H0, D5
+       neg     D5
+       sbb     H1, H0
+       sbb     $0, H1
 
        xor     C2, C2
        add     H4, H0
@@ -114,118 +118,95 @@ PROLOGUE(nettle_ecc_384_modp)
        adc     H3, T5
        adc     $0, C0
 
-       C   H3 H2 H1 H0  0
-       C - H4 H3 H2 H1 H0
-       C  ---------------
-       C   H3 H2 H1 H0 D0
-
-       mov     XREG(D4), XREG(D4)
-       mov     H0, D0
-       neg     D0
-       sbb     H1, H0
-       sbb     H2, H1
-       sbb     H3, H2
-       sbb     H4, H3
-       sbb     $0, D4
-
-       C Shift right. High bits are sign, to be added to C0.
-       mov     D4, TMP
-       sar     $32, TMP
-       shl     $32, D4
-       add     TMP, C0
-
+       C Shift left, including low half of H4
        mov     H3, TMP
+       shl     $32, H4
        shr     $32, TMP
-       shl     $32, H3
-       or      TMP, D4
+       or      TMP, H4
 
        mov     H2, TMP
+       shl     $32, H3
        shr     $32, TMP
-       shl     $32, H2
        or      TMP, H3
 
        mov     H1, TMP
+       shl     $32, H2
        shr     $32, TMP
-       shl     $32, H1
        or      TMP, H2
 
        mov     H0, TMP
+       shl     $32, H1
        shr     $32, TMP
-       shl     $32, H0
        or      TMP, H1
 
-       mov     D0, TMP
-       shr     $32, TMP
-       shl     $32, D0
-       or      TMP, H0
+       shl     $32, H0
+
+       C   H4 H3 H2 H1 H0  0
+       C  -   H4 H3 H2 H1 H0
+       C  ---------------
+       C   H4 H3 H2 H1 H0 TMP
 
-       add     D0, T0
+       mov     H0, TMP
+       neg     TMP
+       sbb     H1, H0
+       sbb     H2, H1
+       sbb     H3, H2
+       sbb     H4, H3
+       sbb     $0, H4
+
+       add     TMP, T0
        adc     H0, T1
        adc     H1, T2
        adc     H2, T3
        adc     H3, T4
-       adc     D4, T5
+       adc     H4, T5
        adc     $0, C0
 
        C Remains to add in C2 and C0
-       C                         C0  C0<<32  (-2^32+1)C0
-       C    C2  C2<<32  (-2^32+1)C2
-       C where C2 is always positive, while C0 may be -1.
+       C Set H1, H0 = (2^96 - 2^32 + 1) C0
        mov     C0, H0
        mov     C0, H1
-       mov     C0, H2
-       sar     $63, C0         C Get sign
        shl     $32, H1
-       sub     H1, H0          C Gives borrow iff C0 > 0
+       sub     H1, H0
        sbb     $0, H1
-       add     C0, H2
 
+       C Set H3, H2 = (2^96 - 2^32 + 1) C2
+       mov     C2, H2
+       mov     C2, H3
+       shl     $32, H3
+       sub     H3, H2
+       sbb     $0, H3
+       add     C0, H2          C No carry. Could use lea trick
+
+       xor     C0, C0
        add     H0, T0
        adc     H1, T1
-       adc     $0, H2
-       adc     $0, C0
-
-       C Set (H1 H0)  <-- C2 << 96 - C2 << 32 + 1
-       mov     C2, H0
-       mov     C2, H1
-       shl     $32, H1
-       sub     H1, H0
-       sbb     $0, H1
-
-       add     H2, H0
-       adc     C0, H1
-       adc     C2, C0
-       mov     C0, H2
-       sar     $63, C0
-       add     H0, T2
-       adc     H1, T3
-       adc     H2, T4
-       adc     C0, T5
-       sbb     C0, C0
+       adc     H2, T2
+       adc     H3, T3
+       adc     C2, T4
+       adc     D5, T5          C Value delayed from initial folding
+       adc     $0, C0          C Use sbb and switch sign?
 
        C Final unlikely carry
        mov     C0, H0
        mov     C0, H1
-       mov     C0, H2
-       sar     $63, C0
        shl     $32, H1
        sub     H1, H0
        sbb     $0, H1
-       add     C0, H2
 
        pop     RP
 
-       sub     H0, T0
+       add     H0, T0
        mov     T0, (RP)
-       sbb     H1, T1
+       adc     H1, T1
        mov     T1, 8(RP)
-       sbb     H2, T2
+       adc     C0, T2
        mov     T2, 16(RP)
-       sbb     C0, T3
+       adc     $0, T3
        mov     T3, 24(RP)
-       sbb     C0, T4
+       adc     $0, T4
        mov     T4, 32(RP)
-       sbb     C0, T5
+       adc     $0, T5
        mov     T5, 40(RP)
 
        pop     %r15