~ubuntu-branches/ubuntu/precise/openssl/precise-updates

« back to all changes in this revision

Viewing changes to .pc/CVE-2014-3570.patch/crypto/bn/asm/x86_64-gcc.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-01-09 10:24:21 UTC
  • Revision ID: package-import@ubuntu.com-20150109102421-dj8j4nriyzn00vor
Tags: 1.0.1-4ubuntu5.21
* SECURITY UPDATE: denial of service via unexpected handshake when
  no-ssl3 build option is used (not the default)
  - debian/patches/CVE-2014-3569.patch: keep the old method for now in
    ssl/s23_srvr.c.
  - CVE-2014-3569
* SECURITY UPDATE: bignum squaring may produce incorrect results
  - debian/patches/CVE-2014-3570.patch: fix bignum logic in
    crypto/bn/asm/mips.pl, crypto/bn/asm/x86_64-gcc.c,
    crypto/bn/bn_asm.c, removed crypto/bn/asm/mips3.s, added test to
    crypto/bn/bntest.c.
  - CVE-2014-3570
* SECURITY UPDATE: DTLS segmentation fault in dtls1_get_record
  - debian/patches/CVE-2014-3571-1.patch: fix crash in ssl/d1_pkt.c,
    ssl/s3_pkt.c.
  - debian/patches/CVE-2014-3571-2.patch: make code more obvious in
    ssl/d1_pkt.c.
  - CVE-2014-3571
* SECURITY UPDATE: ECDHE silently downgrades to ECDH [Client]
  - debian/patches/CVE-2014-3572.patch: don't skip server key exchange in
    ssl/s3_clnt.c.
  - CVE-2014-3572
* SECURITY UPDATE: certificate fingerprints can be modified
  - debian/patches/CVE-2014-8275.patch: fix various fingerprint issues in
    crypto/asn1/a_bitstr.c, crypto/asn1/a_type.c, crypto/asn1/a_verify.c,
    crypto/asn1/asn1.h, crypto/asn1/asn1_err.c, crypto/asn1/x_algor.c,
    crypto/dsa/dsa_asn1.c, crypto/ecdsa/ecs_vrf.c, crypto/x509/x509.h,
    crypto/x509/x_all.c.
  - CVE-2014-8275
* SECURITY UPDATE: RSA silently downgrades to EXPORT_RSA [Client]
  - debian/patches/CVE-2015-0204.patch: only allow ephemeral RSA keys in
    export ciphersuites in ssl/d1_srvr.c, ssl/s3_clnt.c, ssl/s3_srvr.c,
    ssl/ssl.h, adjust documentation in doc/ssl/SSL_CTX_set_options.pod,
    doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod.
  - CVE-2015-0204
* SECURITY UPDATE: DTLS memory leak in dtls1_buffer_record
  - debian/patches/CVE-2015-0206.patch: properly handle failures in
    ssl/d1_pkt.c.
  - CVE-2015-0206
* debian/patches/CVE-2015-0205.patch: fix code to prevent confusion in
    ssl/s3_srvr.c.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "../bn_lcl.h"
 
2
#if !(defined(__GNUC__) && __GNUC__>=2)
 
3
# include "../bn_asm.c" /* kind of dirty hack for Sun Studio */
 
4
#else
 
5
/*
 
6
 * x86_64 BIGNUM accelerator version 0.1, December 2002.
 
7
 *
 
8
 * Implemented by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
 
9
 * project.
 
10
 *
 
11
 * Rights for redistribution and usage in source and binary forms are
 
12
 * granted according to the OpenSSL license. Warranty of any kind is
 
13
 * disclaimed.
 
14
 *
 
15
 * Q. Version 0.1? It doesn't sound like Andy, he used to assign real
 
16
 *    versions, like 1.0...
 
17
 * A. Well, that's because this code is basically a quick-n-dirty
 
18
 *    proof-of-concept hack. As you can see it's implemented with
 
19
 *    inline assembler, which means that you're bound to GCC and that
 
20
 *    there might be enough room for further improvement.
 
21
 *
 
22
 * Q. Why inline assembler?
 
23
 * A. x86_64 features own ABI which I'm not familiar with. This is
 
24
 *    why I decided to let the compiler take care of subroutine
 
25
 *    prologue/epilogue as well as register allocation. For reference.
 
26
 *    Win64 implements different ABI for AMD64, different from Linux.
 
27
 *
 
28
 * Q. How much faster does it get?
 
29
 * A. 'apps/openssl speed rsa dsa' output with no-asm:
 
30
 *
 
31
 *                        sign    verify    sign/s verify/s
 
32
 *      rsa  512 bits   0.0006s   0.0001s   1683.8  18456.2
 
33
 *      rsa 1024 bits   0.0028s   0.0002s    356.0   6407.0
 
34
 *      rsa 2048 bits   0.0172s   0.0005s     58.0   1957.8
 
35
 *      rsa 4096 bits   0.1155s   0.0018s      8.7    555.6
 
36
 *                        sign    verify    sign/s verify/s
 
37
 *      dsa  512 bits   0.0005s   0.0006s   2100.8   1768.3
 
38
 *      dsa 1024 bits   0.0014s   0.0018s    692.3    559.2
 
39
 *      dsa 2048 bits   0.0049s   0.0061s    204.7    165.0
 
40
 *
 
41
 *    'apps/openssl speed rsa dsa' output with this module:
 
42
 *
 
43
 *                        sign    verify    sign/s verify/s
 
44
 *      rsa  512 bits   0.0004s   0.0000s   2767.1  33297.9
 
45
 *      rsa 1024 bits   0.0012s   0.0001s    867.4  14674.7
 
46
 *      rsa 2048 bits   0.0061s   0.0002s    164.0   5270.0
 
47
 *      rsa 4096 bits   0.0384s   0.0006s     26.1   1650.8
 
48
 *                        sign    verify    sign/s verify/s
 
49
 *      dsa  512 bits   0.0002s   0.0003s   4442.2   3786.3
 
50
 *      dsa 1024 bits   0.0005s   0.0007s   1835.1   1497.4
 
51
 *      dsa 2048 bits   0.0016s   0.0020s    620.4    504.6
 
52
 *
 
53
 *    For the reference. IA-32 assembler implementation performs
 
54
 *    very much like 64-bit code compiled with no-asm on the same
 
55
 *    machine.
 
56
 */
 
57
 
 
58
#ifdef _WIN64
 
59
#define BN_ULONG unsigned long long
 
60
#else
 
61
#define BN_ULONG unsigned long
 
62
#endif
 
63
 
 
64
#undef mul
 
65
#undef mul_add
 
66
#undef sqr
 
67
 
 
68
/*
 
69
 * "m"(a), "+m"(r)      is the way to favor DirectPath �-code;
 
70
 * "g"(0)               let the compiler to decide where does it
 
71
 *                      want to keep the value of zero;
 
72
 */
 
73
#define mul_add(r,a,word,carry) do {    \
 
74
        register BN_ULONG high,low;     \
 
75
        asm ("mulq %3"                  \
 
76
                : "=a"(low),"=d"(high)  \
 
77
                : "a"(word),"m"(a)      \
 
78
                : "cc");                \
 
79
        asm ("addq %2,%0; adcq %3,%1"   \
 
80
                : "+r"(carry),"+d"(high)\
 
81
                : "a"(low),"g"(0)       \
 
82
                : "cc");                \
 
83
        asm ("addq %2,%0; adcq %3,%1"   \
 
84
                : "+m"(r),"+d"(high)    \
 
85
                : "r"(carry),"g"(0)     \
 
86
                : "cc");                \
 
87
        carry=high;                     \
 
88
        } while (0)
 
89
 
 
90
#define mul(r,a,word,carry) do {        \
 
91
        register BN_ULONG high,low;     \
 
92
        asm ("mulq %3"                  \
 
93
                : "=a"(low),"=d"(high)  \
 
94
                : "a"(word),"g"(a)      \
 
95
                : "cc");                \
 
96
        asm ("addq %2,%0; adcq %3,%1"   \
 
97
                : "+r"(carry),"+d"(high)\
 
98
                : "a"(low),"g"(0)       \
 
99
                : "cc");                \
 
100
        (r)=carry, carry=high;          \
 
101
        } while (0)
 
102
 
 
103
#define sqr(r0,r1,a)                    \
 
104
        asm ("mulq %2"                  \
 
105
                : "=a"(r0),"=d"(r1)     \
 
106
                : "a"(a)                \
 
107
                : "cc");
 
108
 
 
109
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
 
110
        {
 
111
        BN_ULONG c1=0;
 
112
 
 
113
        if (num <= 0) return(c1);
 
114
 
 
115
        while (num&~3)
 
116
                {
 
117
                mul_add(rp[0],ap[0],w,c1);
 
118
                mul_add(rp[1],ap[1],w,c1);
 
119
                mul_add(rp[2],ap[2],w,c1);
 
120
                mul_add(rp[3],ap[3],w,c1);
 
121
                ap+=4; rp+=4; num-=4;
 
122
                }
 
123
        if (num)
 
124
                {
 
125
                mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
 
126
                mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
 
127
                mul_add(rp[2],ap[2],w,c1); return c1;
 
128
                }
 
129
        
 
130
        return(c1);
 
131
        } 
 
132
 
 
133
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
 
134
        {
 
135
        BN_ULONG c1=0;
 
136
 
 
137
        if (num <= 0) return(c1);
 
138
 
 
139
        while (num&~3)
 
140
                {
 
141
                mul(rp[0],ap[0],w,c1);
 
142
                mul(rp[1],ap[1],w,c1);
 
143
                mul(rp[2],ap[2],w,c1);
 
144
                mul(rp[3],ap[3],w,c1);
 
145
                ap+=4; rp+=4; num-=4;
 
146
                }
 
147
        if (num)
 
148
                {
 
149
                mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
 
150
                mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
 
151
                mul(rp[2],ap[2],w,c1);
 
152
                }
 
153
        return(c1);
 
154
        } 
 
155
 
 
156
void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
 
157
        {
 
158
        if (n <= 0) return;
 
159
 
 
160
        while (n&~3)
 
161
                {
 
162
                sqr(r[0],r[1],a[0]);
 
163
                sqr(r[2],r[3],a[1]);
 
164
                sqr(r[4],r[5],a[2]);
 
165
                sqr(r[6],r[7],a[3]);
 
166
                a+=4; r+=8; n-=4;
 
167
                }
 
168
        if (n)
 
169
                {
 
170
                sqr(r[0],r[1],a[0]); if (--n == 0) return;
 
171
                sqr(r[2],r[3],a[1]); if (--n == 0) return;
 
172
                sqr(r[4],r[5],a[2]);
 
173
                }
 
174
        }
 
175
 
 
176
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
 
177
{       BN_ULONG ret,waste;
 
178
 
 
179
        asm ("divq      %4"
 
180
                : "=a"(ret),"=d"(waste)
 
181
                : "a"(l),"d"(h),"g"(d)
 
182
                : "cc");
 
183
 
 
184
        return ret;
 
185
}
 
186
 
 
187
BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
 
188
{ BN_ULONG ret=0,i=0;
 
189
 
 
190
        if (n <= 0) return 0;
 
191
 
 
192
        asm (
 
193
        "       subq    %2,%2           \n"
 
194
        ".p2align 4                     \n"
 
195
        "1:     movq    (%4,%2,8),%0    \n"
 
196
        "       adcq    (%5,%2,8),%0    \n"
 
197
        "       movq    %0,(%3,%2,8)    \n"
 
198
        "       leaq    1(%2),%2        \n"
 
199
        "       loop    1b              \n"
 
200
        "       sbbq    %0,%0           \n"
 
201
                : "=&a"(ret),"+c"(n),"=&r"(i)
 
202
                : "r"(rp),"r"(ap),"r"(bp)
 
203
                : "cc"
 
204
        );
 
205
 
 
206
  return ret&1;
 
207
}
 
208
 
 
209
#ifndef SIMICS
 
210
BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
 
211
{ BN_ULONG ret=0,i=0;
 
212
 
 
213
        if (n <= 0) return 0;
 
214
 
 
215
        asm (
 
216
        "       subq    %2,%2           \n"
 
217
        ".p2align 4                     \n"
 
218
        "1:     movq    (%4,%2,8),%0    \n"
 
219
        "       sbbq    (%5,%2,8),%0    \n"
 
220
        "       movq    %0,(%3,%2,8)    \n"
 
221
        "       leaq    1(%2),%2        \n"
 
222
        "       loop    1b              \n"
 
223
        "       sbbq    %0,%0           \n"
 
224
                : "=&a"(ret),"+c"(n),"=&r"(i)
 
225
                : "r"(rp),"r"(ap),"r"(bp)
 
226
                : "cc"
 
227
        );
 
228
 
 
229
  return ret&1;
 
230
}
 
231
#else
 
232
/* Simics 1.4<7 has buggy sbbq:-( */
 
233
#define BN_MASK2 0xffffffffffffffffL
 
234
BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
 
235
        {
 
236
        BN_ULONG t1,t2;
 
237
        int c=0;
 
238
 
 
239
        if (n <= 0) return((BN_ULONG)0);
 
240
 
 
241
        for (;;)
 
242
                {
 
243
                t1=a[0]; t2=b[0];
 
244
                r[0]=(t1-t2-c)&BN_MASK2;
 
245
                if (t1 != t2) c=(t1 < t2);
 
246
                if (--n <= 0) break;
 
247
 
 
248
                t1=a[1]; t2=b[1];
 
249
                r[1]=(t1-t2-c)&BN_MASK2;
 
250
                if (t1 != t2) c=(t1 < t2);
 
251
                if (--n <= 0) break;
 
252
 
 
253
                t1=a[2]; t2=b[2];
 
254
                r[2]=(t1-t2-c)&BN_MASK2;
 
255
                if (t1 != t2) c=(t1 < t2);
 
256
                if (--n <= 0) break;
 
257
 
 
258
                t1=a[3]; t2=b[3];
 
259
                r[3]=(t1-t2-c)&BN_MASK2;
 
260
                if (t1 != t2) c=(t1 < t2);
 
261
                if (--n <= 0) break;
 
262
 
 
263
                a+=4;
 
264
                b+=4;
 
265
                r+=4;
 
266
                }
 
267
        return(c);
 
268
        }
 
269
#endif
 
270
 
 
271
/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
 
272
/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
 
273
/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
 
274
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
 
275
 
 
276
#if 0
 
277
/* original macros are kept for reference purposes */
 
278
#define mul_add_c(a,b,c0,c1,c2) {       \
 
279
        BN_ULONG ta=(a),tb=(b);         \
 
280
        t1 = ta * tb;                   \
 
281
        t2 = BN_UMULT_HIGH(ta,tb);      \
 
282
        c0 += t1; t2 += (c0<t1)?1:0;    \
 
283
        c1 += t2; c2 += (c1<t2)?1:0;    \
 
284
        }
 
285
 
 
286
#define mul_add_c2(a,b,c0,c1,c2) {      \
 
287
        BN_ULONG ta=(a),tb=(b),t0;      \
 
288
        t1 = BN_UMULT_HIGH(ta,tb);      \
 
289
        t0 = ta * tb;                   \
 
290
        t2 = t1+t1; c2 += (t2<t1)?1:0;  \
 
291
        t1 = t0+t0; t2 += (t1<t0)?1:0;  \
 
292
        c0 += t1; t2 += (c0<t1)?1:0;    \
 
293
        c1 += t2; c2 += (c1<t2)?1:0;    \
 
294
        }
 
295
#else
 
296
#define mul_add_c(a,b,c0,c1,c2) do {    \
 
297
        asm ("mulq %3"                  \
 
298
                : "=a"(t1),"=d"(t2)     \
 
299
                : "a"(a),"m"(b)         \
 
300
                : "cc");                \
 
301
        asm ("addq %2,%0; adcq %3,%1"   \
 
302
                : "+r"(c0),"+d"(t2)     \
 
303
                : "a"(t1),"g"(0)        \
 
304
                : "cc");                \
 
305
        asm ("addq %2,%0; adcq %3,%1"   \
 
306
                : "+r"(c1),"+r"(c2)     \
 
307
                : "d"(t2),"g"(0)        \
 
308
                : "cc");                \
 
309
        } while (0)
 
310
 
 
311
#define sqr_add_c(a,i,c0,c1,c2) do {    \
 
312
        asm ("mulq %2"                  \
 
313
                : "=a"(t1),"=d"(t2)     \
 
314
                : "a"(a[i])             \
 
315
                : "cc");                \
 
316
        asm ("addq %2,%0; adcq %3,%1"   \
 
317
                : "+r"(c0),"+d"(t2)     \
 
318
                : "a"(t1),"g"(0)        \
 
319
                : "cc");                \
 
320
        asm ("addq %2,%0; adcq %3,%1"   \
 
321
                : "+r"(c1),"+r"(c2)     \
 
322
                : "d"(t2),"g"(0)        \
 
323
                : "cc");                \
 
324
        } while (0)
 
325
 
 
326
#define mul_add_c2(a,b,c0,c1,c2) do {   \
 
327
        asm ("mulq %3"                  \
 
328
                : "=a"(t1),"=d"(t2)     \
 
329
                : "a"(a),"m"(b)         \
 
330
                : "cc");                \
 
331
        asm ("addq %0,%0; adcq %2,%1"   \
 
332
                : "+d"(t2),"+r"(c2)     \
 
333
                : "g"(0)                \
 
334
                : "cc");                \
 
335
        asm ("addq %0,%0; adcq %2,%1"   \
 
336
                : "+a"(t1),"+d"(t2)     \
 
337
                : "g"(0)                \
 
338
                : "cc");                \
 
339
        asm ("addq %2,%0; adcq %3,%1"   \
 
340
                : "+r"(c0),"+d"(t2)     \
 
341
                : "a"(t1),"g"(0)        \
 
342
                : "cc");                \
 
343
        asm ("addq %2,%0; adcq %3,%1"   \
 
344
                : "+r"(c1),"+r"(c2)     \
 
345
                : "d"(t2),"g"(0)        \
 
346
                : "cc");                \
 
347
        } while (0)
 
348
#endif
 
349
 
 
350
#define sqr_add_c2(a,i,j,c0,c1,c2)      \
 
351
        mul_add_c2((a)[i],(a)[j],c0,c1,c2)
 
352
 
 
353
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
 
354
        {
 
355
        BN_ULONG t1,t2;
 
356
        BN_ULONG c1,c2,c3;
 
357
 
 
358
        c1=0;
 
359
        c2=0;
 
360
        c3=0;
 
361
        mul_add_c(a[0],b[0],c1,c2,c3);
 
362
        r[0]=c1;
 
363
        c1=0;
 
364
        mul_add_c(a[0],b[1],c2,c3,c1);
 
365
        mul_add_c(a[1],b[0],c2,c3,c1);
 
366
        r[1]=c2;
 
367
        c2=0;
 
368
        mul_add_c(a[2],b[0],c3,c1,c2);
 
369
        mul_add_c(a[1],b[1],c3,c1,c2);
 
370
        mul_add_c(a[0],b[2],c3,c1,c2);
 
371
        r[2]=c3;
 
372
        c3=0;
 
373
        mul_add_c(a[0],b[3],c1,c2,c3);
 
374
        mul_add_c(a[1],b[2],c1,c2,c3);
 
375
        mul_add_c(a[2],b[1],c1,c2,c3);
 
376
        mul_add_c(a[3],b[0],c1,c2,c3);
 
377
        r[3]=c1;
 
378
        c1=0;
 
379
        mul_add_c(a[4],b[0],c2,c3,c1);
 
380
        mul_add_c(a[3],b[1],c2,c3,c1);
 
381
        mul_add_c(a[2],b[2],c2,c3,c1);
 
382
        mul_add_c(a[1],b[3],c2,c3,c1);
 
383
        mul_add_c(a[0],b[4],c2,c3,c1);
 
384
        r[4]=c2;
 
385
        c2=0;
 
386
        mul_add_c(a[0],b[5],c3,c1,c2);
 
387
        mul_add_c(a[1],b[4],c3,c1,c2);
 
388
        mul_add_c(a[2],b[3],c3,c1,c2);
 
389
        mul_add_c(a[3],b[2],c3,c1,c2);
 
390
        mul_add_c(a[4],b[1],c3,c1,c2);
 
391
        mul_add_c(a[5],b[0],c3,c1,c2);
 
392
        r[5]=c3;
 
393
        c3=0;
 
394
        mul_add_c(a[6],b[0],c1,c2,c3);
 
395
        mul_add_c(a[5],b[1],c1,c2,c3);
 
396
        mul_add_c(a[4],b[2],c1,c2,c3);
 
397
        mul_add_c(a[3],b[3],c1,c2,c3);
 
398
        mul_add_c(a[2],b[4],c1,c2,c3);
 
399
        mul_add_c(a[1],b[5],c1,c2,c3);
 
400
        mul_add_c(a[0],b[6],c1,c2,c3);
 
401
        r[6]=c1;
 
402
        c1=0;
 
403
        mul_add_c(a[0],b[7],c2,c3,c1);
 
404
        mul_add_c(a[1],b[6],c2,c3,c1);
 
405
        mul_add_c(a[2],b[5],c2,c3,c1);
 
406
        mul_add_c(a[3],b[4],c2,c3,c1);
 
407
        mul_add_c(a[4],b[3],c2,c3,c1);
 
408
        mul_add_c(a[5],b[2],c2,c3,c1);
 
409
        mul_add_c(a[6],b[1],c2,c3,c1);
 
410
        mul_add_c(a[7],b[0],c2,c3,c1);
 
411
        r[7]=c2;
 
412
        c2=0;
 
413
        mul_add_c(a[7],b[1],c3,c1,c2);
 
414
        mul_add_c(a[6],b[2],c3,c1,c2);
 
415
        mul_add_c(a[5],b[3],c3,c1,c2);
 
416
        mul_add_c(a[4],b[4],c3,c1,c2);
 
417
        mul_add_c(a[3],b[5],c3,c1,c2);
 
418
        mul_add_c(a[2],b[6],c3,c1,c2);
 
419
        mul_add_c(a[1],b[7],c3,c1,c2);
 
420
        r[8]=c3;
 
421
        c3=0;
 
422
        mul_add_c(a[2],b[7],c1,c2,c3);
 
423
        mul_add_c(a[3],b[6],c1,c2,c3);
 
424
        mul_add_c(a[4],b[5],c1,c2,c3);
 
425
        mul_add_c(a[5],b[4],c1,c2,c3);
 
426
        mul_add_c(a[6],b[3],c1,c2,c3);
 
427
        mul_add_c(a[7],b[2],c1,c2,c3);
 
428
        r[9]=c1;
 
429
        c1=0;
 
430
        mul_add_c(a[7],b[3],c2,c3,c1);
 
431
        mul_add_c(a[6],b[4],c2,c3,c1);
 
432
        mul_add_c(a[5],b[5],c2,c3,c1);
 
433
        mul_add_c(a[4],b[6],c2,c3,c1);
 
434
        mul_add_c(a[3],b[7],c2,c3,c1);
 
435
        r[10]=c2;
 
436
        c2=0;
 
437
        mul_add_c(a[4],b[7],c3,c1,c2);
 
438
        mul_add_c(a[5],b[6],c3,c1,c2);
 
439
        mul_add_c(a[6],b[5],c3,c1,c2);
 
440
        mul_add_c(a[7],b[4],c3,c1,c2);
 
441
        r[11]=c3;
 
442
        c3=0;
 
443
        mul_add_c(a[7],b[5],c1,c2,c3);
 
444
        mul_add_c(a[6],b[6],c1,c2,c3);
 
445
        mul_add_c(a[5],b[7],c1,c2,c3);
 
446
        r[12]=c1;
 
447
        c1=0;
 
448
        mul_add_c(a[6],b[7],c2,c3,c1);
 
449
        mul_add_c(a[7],b[6],c2,c3,c1);
 
450
        r[13]=c2;
 
451
        c2=0;
 
452
        mul_add_c(a[7],b[7],c3,c1,c2);
 
453
        r[14]=c3;
 
454
        r[15]=c1;
 
455
        }
 
456
 
 
457
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
 
458
        {
 
459
        BN_ULONG t1,t2;
 
460
        BN_ULONG c1,c2,c3;
 
461
 
 
462
        c1=0;
 
463
        c2=0;
 
464
        c3=0;
 
465
        mul_add_c(a[0],b[0],c1,c2,c3);
 
466
        r[0]=c1;
 
467
        c1=0;
 
468
        mul_add_c(a[0],b[1],c2,c3,c1);
 
469
        mul_add_c(a[1],b[0],c2,c3,c1);
 
470
        r[1]=c2;
 
471
        c2=0;
 
472
        mul_add_c(a[2],b[0],c3,c1,c2);
 
473
        mul_add_c(a[1],b[1],c3,c1,c2);
 
474
        mul_add_c(a[0],b[2],c3,c1,c2);
 
475
        r[2]=c3;
 
476
        c3=0;
 
477
        mul_add_c(a[0],b[3],c1,c2,c3);
 
478
        mul_add_c(a[1],b[2],c1,c2,c3);
 
479
        mul_add_c(a[2],b[1],c1,c2,c3);
 
480
        mul_add_c(a[3],b[0],c1,c2,c3);
 
481
        r[3]=c1;
 
482
        c1=0;
 
483
        mul_add_c(a[3],b[1],c2,c3,c1);
 
484
        mul_add_c(a[2],b[2],c2,c3,c1);
 
485
        mul_add_c(a[1],b[3],c2,c3,c1);
 
486
        r[4]=c2;
 
487
        c2=0;
 
488
        mul_add_c(a[2],b[3],c3,c1,c2);
 
489
        mul_add_c(a[3],b[2],c3,c1,c2);
 
490
        r[5]=c3;
 
491
        c3=0;
 
492
        mul_add_c(a[3],b[3],c1,c2,c3);
 
493
        r[6]=c1;
 
494
        r[7]=c2;
 
495
        }
 
496
 
 
497
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
 
498
        {
 
499
        BN_ULONG t1,t2;
 
500
        BN_ULONG c1,c2,c3;
 
501
 
 
502
        c1=0;
 
503
        c2=0;
 
504
        c3=0;
 
505
        sqr_add_c(a,0,c1,c2,c3);
 
506
        r[0]=c1;
 
507
        c1=0;
 
508
        sqr_add_c2(a,1,0,c2,c3,c1);
 
509
        r[1]=c2;
 
510
        c2=0;
 
511
        sqr_add_c(a,1,c3,c1,c2);
 
512
        sqr_add_c2(a,2,0,c3,c1,c2);
 
513
        r[2]=c3;
 
514
        c3=0;
 
515
        sqr_add_c2(a,3,0,c1,c2,c3);
 
516
        sqr_add_c2(a,2,1,c1,c2,c3);
 
517
        r[3]=c1;
 
518
        c1=0;
 
519
        sqr_add_c(a,2,c2,c3,c1);
 
520
        sqr_add_c2(a,3,1,c2,c3,c1);
 
521
        sqr_add_c2(a,4,0,c2,c3,c1);
 
522
        r[4]=c2;
 
523
        c2=0;
 
524
        sqr_add_c2(a,5,0,c3,c1,c2);
 
525
        sqr_add_c2(a,4,1,c3,c1,c2);
 
526
        sqr_add_c2(a,3,2,c3,c1,c2);
 
527
        r[5]=c3;
 
528
        c3=0;
 
529
        sqr_add_c(a,3,c1,c2,c3);
 
530
        sqr_add_c2(a,4,2,c1,c2,c3);
 
531
        sqr_add_c2(a,5,1,c1,c2,c3);
 
532
        sqr_add_c2(a,6,0,c1,c2,c3);
 
533
        r[6]=c1;
 
534
        c1=0;
 
535
        sqr_add_c2(a,7,0,c2,c3,c1);
 
536
        sqr_add_c2(a,6,1,c2,c3,c1);
 
537
        sqr_add_c2(a,5,2,c2,c3,c1);
 
538
        sqr_add_c2(a,4,3,c2,c3,c1);
 
539
        r[7]=c2;
 
540
        c2=0;
 
541
        sqr_add_c(a,4,c3,c1,c2);
 
542
        sqr_add_c2(a,5,3,c3,c1,c2);
 
543
        sqr_add_c2(a,6,2,c3,c1,c2);
 
544
        sqr_add_c2(a,7,1,c3,c1,c2);
 
545
        r[8]=c3;
 
546
        c3=0;
 
547
        sqr_add_c2(a,7,2,c1,c2,c3);
 
548
        sqr_add_c2(a,6,3,c1,c2,c3);
 
549
        sqr_add_c2(a,5,4,c1,c2,c3);
 
550
        r[9]=c1;
 
551
        c1=0;
 
552
        sqr_add_c(a,5,c2,c3,c1);
 
553
        sqr_add_c2(a,6,4,c2,c3,c1);
 
554
        sqr_add_c2(a,7,3,c2,c3,c1);
 
555
        r[10]=c2;
 
556
        c2=0;
 
557
        sqr_add_c2(a,7,4,c3,c1,c2);
 
558
        sqr_add_c2(a,6,5,c3,c1,c2);
 
559
        r[11]=c3;
 
560
        c3=0;
 
561
        sqr_add_c(a,6,c1,c2,c3);
 
562
        sqr_add_c2(a,7,5,c1,c2,c3);
 
563
        r[12]=c1;
 
564
        c1=0;
 
565
        sqr_add_c2(a,7,6,c2,c3,c1);
 
566
        r[13]=c2;
 
567
        c2=0;
 
568
        sqr_add_c(a,7,c3,c1,c2);
 
569
        r[14]=c3;
 
570
        r[15]=c1;
 
571
        }
 
572
 
 
573
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
 
574
        {
 
575
        BN_ULONG t1,t2;
 
576
        BN_ULONG c1,c2,c3;
 
577
 
 
578
        c1=0;
 
579
        c2=0;
 
580
        c3=0;
 
581
        sqr_add_c(a,0,c1,c2,c3);
 
582
        r[0]=c1;
 
583
        c1=0;
 
584
        sqr_add_c2(a,1,0,c2,c3,c1);
 
585
        r[1]=c2;
 
586
        c2=0;
 
587
        sqr_add_c(a,1,c3,c1,c2);
 
588
        sqr_add_c2(a,2,0,c3,c1,c2);
 
589
        r[2]=c3;
 
590
        c3=0;
 
591
        sqr_add_c2(a,3,0,c1,c2,c3);
 
592
        sqr_add_c2(a,2,1,c1,c2,c3);
 
593
        r[3]=c1;
 
594
        c1=0;
 
595
        sqr_add_c(a,2,c2,c3,c1);
 
596
        sqr_add_c2(a,3,1,c2,c3,c1);
 
597
        r[4]=c2;
 
598
        c2=0;
 
599
        sqr_add_c2(a,3,2,c3,c1,c2);
 
600
        r[5]=c3;
 
601
        c3=0;
 
602
        sqr_add_c(a,3,c1,c2,c3);
 
603
        r[6]=c1;
 
604
        r[7]=c2;
 
605
        }
 
606
#endif