Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(668)

Side by Side Diff: net/third_party/nss/patches/tls-srp.patch

Issue 6804032: Add TLS-SRP (RFC 5054) support Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 diff --git a/net/third_party/nss/ssl/mpi/logtab.h b/net/third_party/nss/ssl/mpi/ logtab.h
2 new file mode 100644
3 index 0000000..41badfc
4 --- /dev/null
5 +++ b/net/third_party/nss/ssl/mpi/logtab.h
6 @@ -0,0 +1,62 @@
7 +/*
8 + * logtab.h
9 + *
10 + * Arbitrary precision integer arithmetic library
11 + *
12 + * ***** BEGIN LICENSE BLOCK *****
13 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
14 + *
15 + * The contents of this file are subject to the Mozilla Public License Version
16 + * 1.1 (the "License"); you may not use this file except in compliance with
17 + * the License. You may obtain a copy of the License at
18 + * http://www.mozilla.org/MPL/
19 + *
20 + * Software distributed under the License is distributed on an "AS IS" basis,
21 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
22 + * for the specific language governing rights and limitations under the
23 + * License.
24 + *
25 + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
26 + *
27 + * The Initial Developer of the Original Code is
28 + * Michael J. Fromberger.
29 + * Portions created by the Initial Developer are Copyright (C) 1998
30 + * the Initial Developer. All Rights Reserved.
31 + *
32 + * Contributor(s):
33 + *
34 + * Alternatively, the contents of this file may be used under the terms of
35 + * either the GNU General Public License Version 2 or later (the "GPL"), or
36 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
37 + * in which case the provisions of the GPL or the LGPL are applicable instead
38 + * of those above. If you wish to allow use of your version of this file only
39 + * under the terms of either the GPL or the LGPL, and not to allow others to
40 + * use your version of this file under the terms of the MPL, indicate your
41 + * decision by deleting the provisions above and replace them with the notice
42 + * and other provisions required by the GPL or the LGPL. If you do not delete
43 + * the provisions above, a recipient may use your version of this file under
44 + * the terms of any one of the MPL, the GPL or the LGPL.
45 + *
46 + * ***** END LICENSE BLOCK ***** */
47 +/* $Id: logtab.h,v 1.5 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
48 +
49 +const float s_logv_2[] = {
50 + 0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f, /* 0 1 2 3 */
51 + 0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f, /* 4 5 6 7 */
52 + 0.333333333f, 0.315464877f, 0.301029996f, 0.289064826f, /* 8 9 10 11 */
53 + 0.278942946f, 0.270238154f, 0.262649535f, 0.255958025f, /* 12 13 14 15 */
54 + 0.250000000f, 0.244650542f, 0.239812467f, 0.235408913f, /* 16 17 18 19 */
55 + 0.231378213f, 0.227670249f, 0.224243824f, 0.221064729f, /* 20 21 22 23 */
56 + 0.218104292f, 0.215338279f, 0.212746054f, 0.210309918f, /* 24 25 26 27 */
57 + 0.208014598f, 0.205846832f, 0.203795047f, 0.201849087f, /* 28 29 30 31 */
58 + 0.200000000f, 0.198239863f, 0.196561632f, 0.194959022f, /* 32 33 34 35 */
59 + 0.193426404f, 0.191958720f, 0.190551412f, 0.189200360f, /* 36 37 38 39 */
60 + 0.187901825f, 0.186652411f, 0.185449023f, 0.184288833f, /* 40 41 42 43 */
61 + 0.183169251f, 0.182087900f, 0.181042597f, 0.180031327f, /* 44 45 46 47 */
62 + 0.179052232f, 0.178103594f, 0.177183820f, 0.176291434f, /* 48 49 50 51 */
63 + 0.175425064f, 0.174583430f, 0.173765343f, 0.172969690f, /* 52 53 54 55 */
64 + 0.172195434f, 0.171441601f, 0.170707280f, 0.169991616f, /* 56 57 58 59 */
65 + 0.169293808f, 0.168613099f, 0.167948779f, 0.167300179f, /* 60 61 62 63 */
66 + 0.166666667f
67 +};
68 +
69 diff --git a/net/third_party/nss/ssl/mpi/mpcpucache.c b/net/third_party/nss/ssl/ mpi/mpcpucache.c
70 new file mode 100644
71 index 0000000..6efa072
72 --- /dev/null
73 +++ b/net/third_party/nss/ssl/mpi/mpcpucache.c
74 @@ -0,0 +1,838 @@
75 +/* ***** BEGIN LICENSE BLOCK *****
76 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
77 + *
78 + * The contents of this file are subject to the Mozilla Public License Version
79 + * 1.1 (the "License"); you may not use this file except in compliance with
80 + * the License. You may obtain a copy of the License at
81 + * http://www.mozilla.org/MPL/
82 + *
83 + * Software distributed under the License is distributed on an "AS IS" basis,
84 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
85 + * for the specific language governing rights and limitations under the
86 + * License.
87 + *
88 + * The Original Code is the Netscape security libraries.
89 + *
90 + * The Initial Developer of the Original Code is
91 + * Red Hat, Inc
92 + * Portions created by the Initial Developer are Copyright (C) 2005
93 + * the Initial Developer. All Rights Reserved.
94 + *
95 + * Contributor(s):
96 + * Robert Relyea <rrelyea@redhat.com>
97 + *
98 + * Alternatively, the contents of this file may be used under the terms of
99 + * either the GNU General Public License Version 2 or later (the "GPL"), or
100 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
101 + * in which case the provisions of the GPL or the LGPL are applicable instead
102 + * of those above. If you wish to allow use of your version of this file only
103 + * under the terms of either the GPL or the LGPL, and not to allow others to
104 + * use your version of this file under the terms of the MPL, indicate your
105 + * decision by deleting the provisions above and replace them with the notice
106 + * and other provisions required by the GPL or the LGPL. If you do not delete
107 + * the provisions above, a recipient may use your version of this file under
108 + * the terms of any one of the MPL, the GPL or the LGPL.
109 + *
110 + * ***** END LICENSE BLOCK ***** */
111 +
112 +#include "mpi.h"
113 +
114 +/*
115 + * This file implements a single function: s_mpi_getProcessorLineSize();
116 + * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line
117 + * if a cache exists, or zero if there is no cache. If more than one
118 + * cache line exists, it should return the smallest line size (which is
119 + * usually the L1 cache).
120 + *
121 + * mp_modexp uses this information to make sure that private key information
122 + * isn't being leaked through the cache.
123 + *
124 + * Currently the file returns good data for most modern x86 processors, and
125 + * reasonable data on 64-bit ppc processors. All other processors are assumed
126 + * to have a cache line size of 32 bytes unless modified by target.mk.
127 + *
128 + */
129 +
130 +#if defined(i386) || defined(__i386) || defined(__X86__) || defined (_M_IX86) | | defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64)
131 +/* X86 processors have special instructions that tell us about the cache */
132 +#include "string.h"
133 +
134 +#if defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64)
135 +#define AMD_64 1
136 +#endif
137 +
138 +/* Generic CPUID function */
139 +#if defined(AMD_64)
140 +
141 +#if defined(__GNUC__)
142 +
143 +void freebl_cpuid(unsigned long op, unsigned long *eax,
144 + unsigned long *ebx, unsigned long *ecx,
145 + unsigned long *edx)
146 +{
147 + __asm__("cpuid\n\t"
148 + : "=a" (*eax),
149 + "=b" (*ebx),
150 + "=c" (*ecx),
151 + "=d" (*edx)
152 + : "0" (op));
153 +}
154 +
155 +#elif defined(_MSC_VER)
156 +
157 +#include <intrin.h>
158 +
159 +void freebl_cpuid(unsigned long op, unsigned long *eax,
160 + unsigned long *ebx, unsigned long *ecx,
161 + unsigned long *edx)
162 +{
163 + int intrinsic_out[4];
164 +
165 + __cpuid(intrinsic_out, op);
166 + *eax = intrinsic_out[0];
167 + *ebx = intrinsic_out[1];
168 + *ecx = intrinsic_out[2];
169 + *edx = intrinsic_out[3];
170 +}
171 +
172 +#endif
173 +
174 +#else /* !defined(AMD_64) */
175 +
176 +/* x86 */
177 +
178 +#if defined(__GNUC__)
179 +void freebl_cpuid(unsigned long op, unsigned long *eax,
180 + unsigned long *ebx, unsigned long *ecx,
181 + unsigned long *edx)
182 +{
183 +/* sigh GCC isn't smart enough to save the ebx PIC register on it's own
184 + * in this case, so do it by hand. */
185 + __asm__("pushl %%ebx\n\t"
186 + "cpuid\n\t"
187 + "mov %%ebx,%1\n\t"
188 + "popl %%ebx\n\t"
189 + : "=a" (*eax),
190 + "=r" (*ebx),
191 + "=c" (*ecx),
192 + "=d" (*edx)
193 + : "0" (op));
194 +}
195 +
196 +/*
197 + * try flipping a processor flag to determine CPU type
198 + */
199 +static unsigned long changeFlag(unsigned long flag)
200 +{
201 + unsigned long changedFlags, originalFlags;
202 + __asm__("pushfl\n\t" /* get the flags */
203 + "popl %0\n\t"
204 + "movl %0,%1\n\t" /* save the original flags */
205 + "xorl %2,%0\n\t" /* flip the bit */
206 + "pushl %0\n\t" /* set the flags */
207 + "popfl\n\t"
208 + "pushfl\n\t" /* get the flags again (for return) */
209 + "popl %0\n\t"
210 + "pushl %1\n\t" /* restore the original flags */
211 + "popfl\n\t"
212 + : "=r" (changedFlags),
213 + "=r" (originalFlags),
214 + "=r" (flag)
215 + : "2" (flag));
216 + return changedFlags ^ originalFlags;
217 +}
218 +
219 +#elif defined(_MSC_VER)
220 +
221 +/*
222 + * windows versions of the above assembler
223 + */
224 +#define wcpuid __asm __emit 0fh __asm __emit 0a2h
225 +void freebl_cpuid(unsigned long op, unsigned long *Reax,
226 + unsigned long *Rebx, unsigned long *Recx, unsigned long *Redx)
227 +{
228 + unsigned long Leax, Lebx, Lecx, Ledx;
229 + __asm {
230 + pushad
231 + mov eax,op
232 + wcpuid
233 + mov Leax,eax
234 + mov Lebx,ebx
235 + mov Lecx,ecx
236 + mov Ledx,edx
237 + popad
238 + }
239 + *Reax = Leax;
240 + *Rebx = Lebx;
241 + *Recx = Lecx;
242 + *Redx = Ledx;
243 +}
244 +
245 +static unsigned long changeFlag(unsigned long flag)
246 +{
247 + unsigned long changedFlags, originalFlags;
248 + __asm {
249 + push eax
250 + push ebx
251 + pushfd /* get the flags */
252 + pop eax
253 + push eax /* save the flags on the stack */
254 + mov originalFlags,eax /* save the original flags */
255 + mov ebx,flag
256 + xor eax,ebx /* flip the bit */
257 + push eax /* set the flags */
258 + popfd
259 + pushfd /* get the flags again (for return) */
260 + pop eax
261 + popfd /* restore the original flags */
262 + mov changedFlags,eax
263 + pop ebx
264 + pop eax
265 + }
266 + return changedFlags ^ originalFlags;
267 +}
268 +#endif
269 +
270 +#endif
271 +
272 +#if !defined(AMD_64)
273 +#define AC_FLAG 0x40000
274 +#define ID_FLAG 0x200000
275 +
276 +/* 386 processors can't flip the AC_FLAG, intel AP Note AP-485 */
277 +static int is386()
278 +{
279 + return changeFlag(AC_FLAG) == 0;
280 +}
281 +
282 +/* 486 processors can't flip the ID_FLAG, intel AP Note AP-485 */
283 +static int is486()
284 +{
285 + return changeFlag(ID_FLAG) == 0;
286 +}
287 +#endif
288 +
289 +
290 +/*
291 + * table for Intel Cache.
292 + * See Intel Application Note AP-485 for more information
293 + */
294 +
295 +typedef unsigned char CacheTypeEntry;
296 +
297 +typedef enum {
298 + Cache_NONE = 0,
299 + Cache_UNKNOWN = 1,
300 + Cache_TLB = 2,
301 + Cache_TLBi = 3,
302 + Cache_TLBd = 4,
303 + Cache_Trace = 5,
304 + Cache_L1 = 6,
305 + Cache_L1i = 7,
306 + Cache_L1d = 8,
307 + Cache_L2 = 9 ,
308 + Cache_L2i = 10 ,
309 + Cache_L2d = 11 ,
310 + Cache_L3 = 12 ,
311 + Cache_L3i = 13,
312 + Cache_L3d = 14
313 +} CacheType;
314 +
315 +struct _cache {
316 + CacheTypeEntry type;
317 + unsigned char lineSize;
318 +};
319 +static const struct _cache CacheMap[256] = {
320 +/* 00 */ {Cache_NONE, 0 },
321 +/* 01 */ {Cache_TLBi, 0 },
322 +/* 02 */ {Cache_TLBi, 0 },
323 +/* 03 */ {Cache_TLBd, 0 },
324 +/* 04 */ {Cache_TLBd, },
325 +/* 05 */ {Cache_UNKNOWN, 0 },
326 +/* 06 */ {Cache_L1i, 32 },
327 +/* 07 */ {Cache_UNKNOWN, 0 },
328 +/* 08 */ {Cache_L1i, 32 },
329 +/* 09 */ {Cache_UNKNOWN, 0 },
330 +/* 0a */ {Cache_L1d, 32 },
331 +/* 0b */ {Cache_UNKNOWN, 0 },
332 +/* 0c */ {Cache_L1d, 32 },
333 +/* 0d */ {Cache_UNKNOWN, 0 },
334 +/* 0e */ {Cache_UNKNOWN, 0 },
335 +/* 0f */ {Cache_UNKNOWN, 0 },
336 +/* 10 */ {Cache_UNKNOWN, 0 },
337 +/* 11 */ {Cache_UNKNOWN, 0 },
338 +/* 12 */ {Cache_UNKNOWN, 0 },
339 +/* 13 */ {Cache_UNKNOWN, 0 },
340 +/* 14 */ {Cache_UNKNOWN, 0 },
341 +/* 15 */ {Cache_UNKNOWN, 0 },
342 +/* 16 */ {Cache_UNKNOWN, 0 },
343 +/* 17 */ {Cache_UNKNOWN, 0 },
344 +/* 18 */ {Cache_UNKNOWN, 0 },
345 +/* 19 */ {Cache_UNKNOWN, 0 },
346 +/* 1a */ {Cache_UNKNOWN, 0 },
347 +/* 1b */ {Cache_UNKNOWN, 0 },
348 +/* 1c */ {Cache_UNKNOWN, 0 },
349 +/* 1d */ {Cache_UNKNOWN, 0 },
350 +/* 1e */ {Cache_UNKNOWN, 0 },
351 +/* 1f */ {Cache_UNKNOWN, 0 },
352 +/* 20 */ {Cache_UNKNOWN, 0 },
353 +/* 21 */ {Cache_UNKNOWN, 0 },
354 +/* 22 */ {Cache_L3, 64 },
355 +/* 23 */ {Cache_L3, 64 },
356 +/* 24 */ {Cache_UNKNOWN, 0 },
357 +/* 25 */ {Cache_L3, 64 },
358 +/* 26 */ {Cache_UNKNOWN, 0 },
359 +/* 27 */ {Cache_UNKNOWN, 0 },
360 +/* 28 */ {Cache_UNKNOWN, 0 },
361 +/* 29 */ {Cache_L3, 64 },
362 +/* 2a */ {Cache_UNKNOWN, 0 },
363 +/* 2b */ {Cache_UNKNOWN, 0 },
364 +/* 2c */ {Cache_L1d, 64 },
365 +/* 2d */ {Cache_UNKNOWN, 0 },
366 +/* 2e */ {Cache_UNKNOWN, 0 },
367 +/* 2f */ {Cache_UNKNOWN, 0 },
368 +/* 30 */ {Cache_L1i, 64 },
369 +/* 31 */ {Cache_UNKNOWN, 0 },
370 +/* 32 */ {Cache_UNKNOWN, 0 },
371 +/* 33 */ {Cache_UNKNOWN, 0 },
372 +/* 34 */ {Cache_UNKNOWN, 0 },
373 +/* 35 */ {Cache_UNKNOWN, 0 },
374 +/* 36 */ {Cache_UNKNOWN, 0 },
375 +/* 37 */ {Cache_UNKNOWN, 0 },
376 +/* 38 */ {Cache_UNKNOWN, 0 },
377 +/* 39 */ {Cache_L2, 64 },
378 +/* 3a */ {Cache_UNKNOWN, 0 },
379 +/* 3b */ {Cache_L2, 64 },
380 +/* 3c */ {Cache_L2, 64 },
381 +/* 3d */ {Cache_UNKNOWN, 0 },
382 +/* 3e */ {Cache_UNKNOWN, 0 },
383 +/* 3f */ {Cache_UNKNOWN, 0 },
384 +/* 40 */ {Cache_L2, 0 },
385 +/* 41 */ {Cache_L2, 32 },
386 +/* 42 */ {Cache_L2, 32 },
387 +/* 43 */ {Cache_L2, 32 },
388 +/* 44 */ {Cache_L2, 32 },
389 +/* 45 */ {Cache_L2, 32 },
390 +/* 46 */ {Cache_UNKNOWN, 0 },
391 +/* 47 */ {Cache_UNKNOWN, 0 },
392 +/* 48 */ {Cache_UNKNOWN, 0 },
393 +/* 49 */ {Cache_UNKNOWN, 0 },
394 +/* 4a */ {Cache_UNKNOWN, 0 },
395 +/* 4b */ {Cache_UNKNOWN, 0 },
396 +/* 4c */ {Cache_UNKNOWN, 0 },
397 +/* 4d */ {Cache_UNKNOWN, 0 },
398 +/* 4e */ {Cache_UNKNOWN, 0 },
399 +/* 4f */ {Cache_UNKNOWN, 0 },
400 +/* 50 */ {Cache_TLBi, 0 },
401 +/* 51 */ {Cache_TLBi, 0 },
402 +/* 52 */ {Cache_TLBi, 0 },
403 +/* 53 */ {Cache_UNKNOWN, 0 },
404 +/* 54 */ {Cache_UNKNOWN, 0 },
405 +/* 55 */ {Cache_UNKNOWN, 0 },
406 +/* 56 */ {Cache_UNKNOWN, 0 },
407 +/* 57 */ {Cache_UNKNOWN, 0 },
408 +/* 58 */ {Cache_UNKNOWN, 0 },
409 +/* 59 */ {Cache_UNKNOWN, 0 },
410 +/* 5a */ {Cache_UNKNOWN, 0 },
411 +/* 5b */ {Cache_TLBd, 0 },
412 +/* 5c */ {Cache_TLBd, 0 },
413 +/* 5d */ {Cache_TLBd, 0 },
414 +/* 5e */ {Cache_UNKNOWN, 0 },
415 +/* 5f */ {Cache_UNKNOWN, 0 },
416 +/* 60 */ {Cache_UNKNOWN, 0 },
417 +/* 61 */ {Cache_UNKNOWN, 0 },
418 +/* 62 */ {Cache_UNKNOWN, 0 },
419 +/* 63 */ {Cache_UNKNOWN, 0 },
420 +/* 64 */ {Cache_UNKNOWN, 0 },
421 +/* 65 */ {Cache_UNKNOWN, 0 },
422 +/* 66 */ {Cache_L1d, 64 },
423 +/* 67 */ {Cache_L1d, 64 },
424 +/* 68 */ {Cache_L1d, 64 },
425 +/* 69 */ {Cache_UNKNOWN, 0 },
426 +/* 6a */ {Cache_UNKNOWN, 0 },
427 +/* 6b */ {Cache_UNKNOWN, 0 },
428 +/* 6c */ {Cache_UNKNOWN, 0 },
429 +/* 6d */ {Cache_UNKNOWN, 0 },
430 +/* 6e */ {Cache_UNKNOWN, 0 },
431 +/* 6f */ {Cache_UNKNOWN, 0 },
432 +/* 70 */ {Cache_Trace, 1 },
433 +/* 71 */ {Cache_Trace, 1 },
434 +/* 72 */ {Cache_Trace, 1 },
435 +/* 73 */ {Cache_UNKNOWN, 0 },
436 +/* 74 */ {Cache_UNKNOWN, 0 },
437 +/* 75 */ {Cache_UNKNOWN, 0 },
438 +/* 76 */ {Cache_UNKNOWN, 0 },
439 +/* 77 */ {Cache_UNKNOWN, 0 },
440 +/* 78 */ {Cache_UNKNOWN, 0 },
441 +/* 79 */ {Cache_L2, 64 },
442 +/* 7a */ {Cache_L2, 64 },
443 +/* 7b */ {Cache_L2, 64 },
444 +/* 7c */ {Cache_L2, 64 },
445 +/* 7d */ {Cache_UNKNOWN, 0 },
446 +/* 7e */ {Cache_UNKNOWN, 0 },
447 +/* 7f */ {Cache_UNKNOWN, 0 },
448 +/* 80 */ {Cache_UNKNOWN, 0 },
449 +/* 81 */ {Cache_UNKNOWN, 0 },
450 +/* 82 */ {Cache_L2, 32 },
451 +/* 83 */ {Cache_L2, 32 },
452 +/* 84 */ {Cache_L2, 32 },
453 +/* 85 */ {Cache_L2, 32 },
454 +/* 86 */ {Cache_L2, 64 },
455 +/* 87 */ {Cache_L2, 64 },
456 +/* 88 */ {Cache_UNKNOWN, 0 },
457 +/* 89 */ {Cache_UNKNOWN, 0 },
458 +/* 8a */ {Cache_UNKNOWN, 0 },
459 +/* 8b */ {Cache_UNKNOWN, 0 },
460 +/* 8c */ {Cache_UNKNOWN, 0 },
461 +/* 8d */ {Cache_UNKNOWN, 0 },
462 +/* 8e */ {Cache_UNKNOWN, 0 },
463 +/* 8f */ {Cache_UNKNOWN, 0 },
464 +/* 90 */ {Cache_UNKNOWN, 0 },
465 +/* 91 */ {Cache_UNKNOWN, 0 },
466 +/* 92 */ {Cache_UNKNOWN, 0 },
467 +/* 93 */ {Cache_UNKNOWN, 0 },
468 +/* 94 */ {Cache_UNKNOWN, 0 },
469 +/* 95 */ {Cache_UNKNOWN, 0 },
470 +/* 96 */ {Cache_UNKNOWN, 0 },
471 +/* 97 */ {Cache_UNKNOWN, 0 },
472 +/* 98 */ {Cache_UNKNOWN, 0 },
473 +/* 99 */ {Cache_UNKNOWN, 0 },
474 +/* 9a */ {Cache_UNKNOWN, 0 },
475 +/* 9b */ {Cache_UNKNOWN, 0 },
476 +/* 9c */ {Cache_UNKNOWN, 0 },
477 +/* 9d */ {Cache_UNKNOWN, 0 },
478 +/* 9e */ {Cache_UNKNOWN, 0 },
479 +/* 9f */ {Cache_UNKNOWN, 0 },
480 +/* a0 */ {Cache_UNKNOWN, 0 },
481 +/* a1 */ {Cache_UNKNOWN, 0 },
482 +/* a2 */ {Cache_UNKNOWN, 0 },
483 +/* a3 */ {Cache_UNKNOWN, 0 },
484 +/* a4 */ {Cache_UNKNOWN, 0 },
485 +/* a5 */ {Cache_UNKNOWN, 0 },
486 +/* a6 */ {Cache_UNKNOWN, 0 },
487 +/* a7 */ {Cache_UNKNOWN, 0 },
488 +/* a8 */ {Cache_UNKNOWN, 0 },
489 +/* a9 */ {Cache_UNKNOWN, 0 },
490 +/* aa */ {Cache_UNKNOWN, 0 },
491 +/* ab */ {Cache_UNKNOWN, 0 },
492 +/* ac */ {Cache_UNKNOWN, 0 },
493 +/* ad */ {Cache_UNKNOWN, 0 },
494 +/* ae */ {Cache_UNKNOWN, 0 },
495 +/* af */ {Cache_UNKNOWN, 0 },
496 +/* b0 */ {Cache_TLBi, 0 },
497 +/* b1 */ {Cache_UNKNOWN, 0 },
498 +/* b2 */ {Cache_UNKNOWN, 0 },
499 +/* b3 */ {Cache_TLBd, 0 },
500 +/* b4 */ {Cache_UNKNOWN, 0 },
501 +/* b5 */ {Cache_UNKNOWN, 0 },
502 +/* b6 */ {Cache_UNKNOWN, 0 },
503 +/* b7 */ {Cache_UNKNOWN, 0 },
504 +/* b8 */ {Cache_UNKNOWN, 0 },
505 +/* b9 */ {Cache_UNKNOWN, 0 },
506 +/* ba */ {Cache_UNKNOWN, 0 },
507 +/* bb */ {Cache_UNKNOWN, 0 },
508 +/* bc */ {Cache_UNKNOWN, 0 },
509 +/* bd */ {Cache_UNKNOWN, 0 },
510 +/* be */ {Cache_UNKNOWN, 0 },
511 +/* bf */ {Cache_UNKNOWN, 0 },
512 +/* c0 */ {Cache_UNKNOWN, 0 },
513 +/* c1 */ {Cache_UNKNOWN, 0 },
514 +/* c2 */ {Cache_UNKNOWN, 0 },
515 +/* c3 */ {Cache_UNKNOWN, 0 },
516 +/* c4 */ {Cache_UNKNOWN, 0 },
517 +/* c5 */ {Cache_UNKNOWN, 0 },
518 +/* c6 */ {Cache_UNKNOWN, 0 },
519 +/* c7 */ {Cache_UNKNOWN, 0 },
520 +/* c8 */ {Cache_UNKNOWN, 0 },
521 +/* c9 */ {Cache_UNKNOWN, 0 },
522 +/* ca */ {Cache_UNKNOWN, 0 },
523 +/* cb */ {Cache_UNKNOWN, 0 },
524 +/* cc */ {Cache_UNKNOWN, 0 },
525 +/* cd */ {Cache_UNKNOWN, 0 },
526 +/* ce */ {Cache_UNKNOWN, 0 },
527 +/* cf */ {Cache_UNKNOWN, 0 },
528 +/* d0 */ {Cache_UNKNOWN, 0 },
529 +/* d1 */ {Cache_UNKNOWN, 0 },
530 +/* d2 */ {Cache_UNKNOWN, 0 },
531 +/* d3 */ {Cache_UNKNOWN, 0 },
532 +/* d4 */ {Cache_UNKNOWN, 0 },
533 +/* d5 */ {Cache_UNKNOWN, 0 },
534 +/* d6 */ {Cache_UNKNOWN, 0 },
535 +/* d7 */ {Cache_UNKNOWN, 0 },
536 +/* d8 */ {Cache_UNKNOWN, 0 },
537 +/* d9 */ {Cache_UNKNOWN, 0 },
538 +/* da */ {Cache_UNKNOWN, 0 },
539 +/* db */ {Cache_UNKNOWN, 0 },
540 +/* dc */ {Cache_UNKNOWN, 0 },
541 +/* dd */ {Cache_UNKNOWN, 0 },
542 +/* de */ {Cache_UNKNOWN, 0 },
543 +/* df */ {Cache_UNKNOWN, 0 },
544 +/* e0 */ {Cache_UNKNOWN, 0 },
545 +/* e1 */ {Cache_UNKNOWN, 0 },
546 +/* e2 */ {Cache_UNKNOWN, 0 },
547 +/* e3 */ {Cache_UNKNOWN, 0 },
548 +/* e4 */ {Cache_UNKNOWN, 0 },
549 +/* e5 */ {Cache_UNKNOWN, 0 },
550 +/* e6 */ {Cache_UNKNOWN, 0 },
551 +/* e7 */ {Cache_UNKNOWN, 0 },
552 +/* e8 */ {Cache_UNKNOWN, 0 },
553 +/* e9 */ {Cache_UNKNOWN, 0 },
554 +/* ea */ {Cache_UNKNOWN, 0 },
555 +/* eb */ {Cache_UNKNOWN, 0 },
556 +/* ec */ {Cache_UNKNOWN, 0 },
557 +/* ed */ {Cache_UNKNOWN, 0 },
558 +/* ee */ {Cache_UNKNOWN, 0 },
559 +/* ef */ {Cache_UNKNOWN, 0 },
560 +/* f0 */ {Cache_UNKNOWN, 0 },
561 +/* f1 */ {Cache_UNKNOWN, 0 },
562 +/* f2 */ {Cache_UNKNOWN, 0 },
563 +/* f3 */ {Cache_UNKNOWN, 0 },
564 +/* f4 */ {Cache_UNKNOWN, 0 },
565 +/* f5 */ {Cache_UNKNOWN, 0 },
566 +/* f6 */ {Cache_UNKNOWN, 0 },
567 +/* f7 */ {Cache_UNKNOWN, 0 },
568 +/* f8 */ {Cache_UNKNOWN, 0 },
569 +/* f9 */ {Cache_UNKNOWN, 0 },
570 +/* fa */ {Cache_UNKNOWN, 0 },
571 +/* fb */ {Cache_UNKNOWN, 0 },
572 +/* fc */ {Cache_UNKNOWN, 0 },
573 +/* fd */ {Cache_UNKNOWN, 0 },
574 +/* fe */ {Cache_UNKNOWN, 0 },
575 +/* ff */ {Cache_UNKNOWN, 0 }
576 +};
577 +
578 +
579 +/*
580 + * use the above table to determine the CacheEntryLineSize.
581 + */
582 +static void
583 +getIntelCacheEntryLineSize(unsigned long val, int *level,
584 + unsigned long *lineSize)
585 +{
586 + CacheType type;
587 +
588 + type = CacheMap[val].type;
589 + /* only interested in data caches */
590 + /* NOTE val = 0x40 is a special value that means no L2 or L3 cache.
591 + * this data check has the side effect of rejecting that entry. If
592 + * that wasn't the case, we could have to reject it explicitly */
593 + if (CacheMap[val].lineSize == 0) {
594 + return;
595 + }
596 + /* look at the caches, skip types we aren't interested in.
597 + * if we already have a value for a lower level cache, skip the
598 + * current entry */
599 + if ((type == Cache_L1)|| (type == Cache_L1d)) {
600 + *level = 1;
601 + *lineSize = CacheMap[val].lineSize;
602 + } else if ((*level >= 2) && ((type == Cache_L2) || (type == Cache_L2d))) {
603 + *level = 2;
604 + *lineSize = CacheMap[val].lineSize;
605 + } else if ((*level >= 3) && ((type == Cache_L3) || (type == Cache_L3d))) {
606 + *level = 3;
607 + *lineSize = CacheMap[val].lineSize;
608 + }
609 + return;
610 +}
611 +
612 +
613 +static void
614 +getIntelRegisterCacheLineSize(unsigned long val,
615 + int *level, unsigned long *lineSize)
616 +{
617 + getIntelCacheEntryLineSize(val >> 24 & 0xff, level, lineSize);
618 + getIntelCacheEntryLineSize(val >> 16 & 0xff, level, lineSize);
619 + getIntelCacheEntryLineSize(val >> 8 & 0xff, level, lineSize);
620 + getIntelCacheEntryLineSize(val & 0xff, level, lineSize);
621 +}
622 +
623 +/*
624 + * returns '0' if no recognized cache is found, or if the cache
625 + * information is supported by this processor
626 + */
627 +static unsigned long
628 +getIntelCacheLineSize(int cpuidLevel)
629 +{
630 + int level = 4;
631 + unsigned long lineSize = 0;
632 + unsigned long eax, ebx, ecx, edx;
633 + int repeat, count;
634 +
635 + if (cpuidLevel < 2) {
636 + return 0;
637 + }
638 +
639 + /* command '2' of the cpuid is intel's cache info call. Each byte of the
640 + * 4 registers contain a potential descriptor for the cache. The CacheMap
641 + * table maps the cache entry with the processor cache. Register 'al'
642 + * contains a count value that cpuid '2' needs to be called in order to
643 + * find all the cache descriptors. Only registers with the high bit set
644 + * to 'zero' have valid descriptors. This code loops through all the
645 + * required calls to cpuid '2' and passes any valid descriptors it finds
646 + * to the getIntelRegisterCacheLineSize code, which breaks the registers
647 + * down into their component descriptors. In the end the lineSize of the
648 + * lowest level cache data cache is returned. */
649 + freebl_cpuid(2, &eax, &ebx, &ecx, &edx);
650 + repeat = eax & 0xf;
651 + for (count = 0; count < repeat; count++) {
652 + if ((eax & 0x80000000) == 0) {
653 + getIntelRegisterCacheLineSize(eax & 0xffffff00, &level, &lineSize);
654 + }
655 + if ((ebx & 0x80000000) == 0) {
656 + getIntelRegisterCacheLineSize(ebx, &level, &lineSize);
657 + }
658 + if ((ecx & 0x80000000) == 0) {
659 + getIntelRegisterCacheLineSize(ecx, &level, &lineSize);
660 + }
661 + if ((edx & 0x80000000) == 0) {
662 + getIntelRegisterCacheLineSize(edx, &level, &lineSize);
663 + }
664 + if (count+1 != repeat) {
665 + freebl_cpuid(2, &eax, &ebx, &ecx, &edx);
666 + }
667 + }
668 + return lineSize;
669 +}
670 +
671 +/*
672 + * returns '0' if the cache info is not supported by this processor.
673 + * This is based on the AMD extended cache commands for cpuid.
674 + * (see "AMD Processor Recognition Application Note" Publication 20734).
675 + * Some other processors use the identical scheme.
676 + * (see "Processor Recognition, Transmeta Corporation").
677 + */
678 +static unsigned long
679 +getOtherCacheLineSize(unsigned long cpuidLevel)
680 +{
681 + unsigned long lineSize = 0;
682 + unsigned long eax, ebx, ecx, edx;
683 +
684 + /* get the Extended CPUID level */
685 + freebl_cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
686 + cpuidLevel = eax;
687 +
688 + if (cpuidLevel >= 0x80000005) {
689 + freebl_cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
690 + lineSize = ecx & 0xff; /* line Size, L1 Data Cache */
691 + }
692 + return lineSize;
693 +}
694 +
695 +static const char * const manMap[] = {
696 +#define INTEL 0
697 + "GenuineIntel",
698 +#define AMD 1
699 + "AuthenticAMD",
700 +#define CYRIX 2
701 + "CyrixInstead",
702 +#define CENTAUR 2
703 + "CentaurHauls",
704 +#define NEXGEN 3
705 + "NexGenDriven",
706 +#define TRANSMETA 4
707 + "GenuineTMx86",
708 +#define RISE 5
709 + "RiseRiseRise",
710 +#define UMC 6
711 + "UMC UMC UMC ",
712 +#define SIS 7
713 + "Sis Sis Sis ",
714 +#define NATIONAL 8
715 + "Geode by NSC",
716 +};
717 +
718 +static const int n_manufacturers = sizeof(manMap)/sizeof(manMap[0]);
719 +
720 +
721 +#define MAN_UNKNOWN 9
722 +
723 +#if !defined(AMD_64)
724 +#define SSE2_FLAG (1<<26)
725 +unsigned long
726 +s_mpi_is_sse2()
727 +{
728 + unsigned long eax, ebx, ecx, edx;
729 + int manufacturer = MAN_UNKNOWN;
730 + int i;
731 + char string[13];
732 +
733 + if (is386() || is486()) {
734 + return 0;
735 + }
736 + freebl_cpuid(0, &eax, &ebx, &ecx, &edx);
737 + *(int *)string = ebx;
738 + *(int *)&string[4] = edx;
739 + *(int *)&string[8] = ecx;
740 + string[12] = 0;
741 +
742 + /* has no SSE2 extensions */
743 + if (eax == 0) {
744 + return 0;
745 + }
746 +
747 + for (i=0; i < n_manufacturers; i++) {
748 + if ( strcmp(manMap[i],string) == 0) {
749 + manufacturer = i;
750 + break;
751 + }
752 + }
753 +
754 + freebl_cpuid(1,&eax,&ebx,&ecx,&edx);
755 + return (edx & SSE2_FLAG) == SSE2_FLAG;
756 +}
757 +#endif
758 +
759 +unsigned long
760 +s_mpi_getProcessorLineSize()
761 +{
762 + unsigned long eax, ebx, ecx, edx;
763 + unsigned long cpuidLevel;
764 + unsigned long cacheLineSize = 0;
765 + int manufacturer = MAN_UNKNOWN;
766 + int i;
767 + char string[65];
768 +
769 +#if !defined(AMD_64)
770 + if (is386()) {
771 + return 0; /* 386 had no cache */
772 + } if (is486()) {
773 + return 32; /* really? need more info */
774 + }
775 +#endif
776 +
777 + /* Pentium, cpuid command is available */
778 + freebl_cpuid(0, &eax, &ebx, &ecx, &edx);
779 + cpuidLevel = eax;
780 + *(int *)string = ebx;
781 + *(int *)&string[4] = edx;
782 + *(int *)&string[8] = ecx;
783 + string[12] = 0;
784 +
785 + manufacturer = MAN_UNKNOWN;
786 + for (i=0; i < n_manufacturers; i++) {
787 + if ( strcmp(manMap[i],string) == 0) {
788 + manufacturer = i;
789 + }
790 + }
791 +
792 + if (manufacturer == INTEL) {
793 + cacheLineSize = getIntelCacheLineSize(cpuidLevel);
794 + } else {
795 + cacheLineSize = getOtherCacheLineSize(cpuidLevel);
796 + }
797 + /* doesn't support cache info based on cpuid. This means
798 + * an old pentium class processor, which have cache lines of
799 + * 32. If we learn differently, we can use a switch based on
800 + * the Manufacturer id */
801 + if (cacheLineSize == 0) {
802 + cacheLineSize = 32;
803 + }
804 + return cacheLineSize;
805 +}
806 +#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
807 +#endif
808 +
809 +#if defined(__ppc64__)
810 +/*
811 + * Sigh, The PPC has some really nice features to help us determine cache
812 + * size, since it had lots of direct control functions to do so. The POWER
813 + * processor even has an instruction to do this, but it was dropped in
814 + * PowerPC. Unfortunately most of them are not available in user mode.
815 + *
816 + * The dcbz function would be a great way to determine cache line size except
817 + * 1) it only works on write-back memory (it throws an exception otherwise),
818 + * and 2) because so many mac programs 'knew' the processor cache size was
819 + * 32 bytes, they used this instruction as a fast 'zero 32 bytes'. Now the new
820 + * G5 processor has 128 byte cache, but dcbz only clears 32 bytes to keep
821 + * these programs happy. dcbzl work if 64 bit instructions are supported.
822 + * If you know 64 bit instructions are supported, and that stack is
823 + * write-back, you can use this code.
824 + */
825 +#include "memory.h"
826 +
827 +/* clear the cache line that contains 'array' */
828 +static inline void dcbzl(char *array)
829 +{
830 + register char *a asm("r2") = array;
831 + __asm__ __volatile__( "dcbzl %0,r0" : "=r" (a): "0"(a) );
832 +}
833 +
834 +
835 +#define PPC_DO_ALIGN(x,y) ((char *)\
836 + ((((long long) (x))+((y)-1))&~((y)-1)))
837 +
838 +#define PPC_MAX_LINE_SIZE 256
839 +unsigned long
840 +s_mpi_getProcessorLineSize()
841 +{
842 + char testArray[2*PPC_MAX_LINE_SIZE+1];
843 + char *test;
844 + int i;
845 +
846 + /* align the array on a maximum line size boundary, so we
847 + * know we are starting to clear from the first address */
848 + test = PPC_DO_ALIGN(testArray, PPC_MAX_LINE_SIZE);
849 + /* set all the values to 1's */
850 + memset(test, 0xff, PPC_MAX_LINE_SIZE);
851 + /* clear one cache block starting at 'test' */
852 + dcbzl(test);
853 +
854 + /* find the size of the cleared area, that's our block size */
855 + for (i=PPC_MAX_LINE_SIZE; i != 0; i = i/2) {
856 + if (test[i-1] == 0) {
857 + return i;
858 + }
859 + }
860 + return 0;
861 +}
862 +
863 +#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
864 +#endif
865 +
866 +
867 +/*
868 + * put other processor and platform specific cache code here
869 + * return the smallest cache line size in bytes on the processor
870 + * (usually the L1 cache). If the OS has a call, this would be
871 + * a greate place to put it.
872 + *
873 + * If there is no cache, return 0;
874 + *
875 + * define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED so the generic functions
876 + * below aren't compiled.
877 + *
878 + */
879 +
880 +
881 +/* target.mk can define MPI_CACHE_LINE_SIZE if it's common for the family or
882 + * OS */
883 +#if defined(MPI_CACHE_LINE_SIZE) && !defined(MPI_GET_PROCESSOR_LINE_SIZE_DEFINE D)
884 +
885 +unsigned long
886 +s_mpi_getProcessorLineSize()
887 +{
888 + return MPI_CACHE_LINE_SIZE;
889 +}
890 +#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
891 +#endif
892 +
893 +
894 +/* If no way to get the processor cache line size has been defined, assume
895 + * it's 32 bytes (most common value, does not significantly impact performance)
896 + */
897 +#ifndef MPI_GET_PROCESSOR_LINE_SIZE_DEFINED
898 +unsigned long
899 +s_mpi_getProcessorLineSize()
900 +{
901 + return 32;
902 +}
903 +#endif
904 +
905 +#ifdef TEST_IT
906 +#include <stdio.h>
907 +
908 +main()
909 +{
910 + printf("line size = %d\n", s_mpi_getProcessorLineSize());
911 +}
912 +#endif
913 diff --git a/net/third_party/nss/ssl/mpi/mpi-config.h b/net/third_party/nss/ssl/ mpi/mpi-config.h
914 new file mode 100644
915 index 0000000..00a0acf
916 --- /dev/null
917 +++ b/net/third_party/nss/ssl/mpi/mpi-config.h
918 @@ -0,0 +1,112 @@
919 +/* Default configuration for MPI library
920 + *
921 + * ***** BEGIN LICENSE BLOCK *****
922 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
923 + *
924 + * The contents of this file are subject to the Mozilla Public License Version
925 + * 1.1 (the "License"); you may not use this file except in compliance with
926 + * the License. You may obtain a copy of the License at
927 + * http://www.mozilla.org/MPL/
928 + *
929 + * Software distributed under the License is distributed on an "AS IS" basis,
930 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
931 + * for the specific language governing rights and limitations under the
932 + * License.
933 + *
934 + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
935 + *
936 + * The Initial Developer of the Original Code is
937 + * Michael J. Fromberger.
938 + * Portions created by the Initial Developer are Copyright (C) 1997
939 + * the Initial Developer. All Rights Reserved.
940 + *
941 + * Contributor(s):
942 + * Netscape Communications Corporation
943 + *
944 + * Alternatively, the contents of this file may be used under the terms of
945 + * either the GNU General Public License Version 2 or later (the "GPL"), or
946 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
947 + * in which case the provisions of the GPL or the LGPL are applicable instead
948 + * of those above. If you wish to allow use of your version of this file only
949 + * under the terms of either the GPL or the LGPL, and not to allow others to
950 + * use your version of this file under the terms of the MPL, indicate your
951 + * decision by deleting the provisions above and replace them with the notice
952 + * and other provisions required by the GPL or the LGPL. If you do not delete
953 + * the provisions above, a recipient may use your version of this file under
954 + * the terms of any one of the MPL, the GPL or the LGPL.
955 + *
956 + * ***** END LICENSE BLOCK ***** */
957 +/* $Id: mpi-config.h,v 1.5 2004/04/25 15:03:10 gerv%gerv.net Exp $ */
958 +
959 +#ifndef MPI_CONFIG_H_
960 +#define MPI_CONFIG_H_
961 +
962 +/*
963 + For boolean options,
964 + 0 = no
965 + 1 = yes
966 +
967 + Other options are documented individually.
968 +
969 + */
970 +
971 +#ifndef MP_IOFUNC
972 +#define MP_IOFUNC 0 /* include mp_print() ? */
973 +#endif
974 +
975 +#ifndef MP_MODARITH
976 +#define MP_MODARITH 1 /* include modular arithmetic ? */
977 +#endif
978 +
979 +#ifndef MP_NUMTH
980 +#define MP_NUMTH 1 /* include number theoretic functions? */
981 +#endif
982 +
983 +#ifndef MP_LOGTAB
984 +#define MP_LOGTAB 1 /* use table of logs instead of log()? */
985 +#endif
986 +
987 +#ifndef MP_MEMSET
988 +#define MP_MEMSET 1 /* use memset() to zero buffers? */
989 +#endif
990 +
991 +#ifndef MP_MEMCPY
992 +#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */
993 +#endif
994 +
995 +#ifndef MP_CRYPTO
996 +#define MP_CRYPTO 1 /* erase memory on free? */
997 +#endif
998 +
999 +#ifndef MP_ARGCHK
1000 +/*
1001 + 0 = no parameter checks
1002 + 1 = runtime checks, continue execution and return an error to caller
1003 + 2 = assertions; dump core on parameter errors
1004 + */
1005 +#ifdef DEBUG
1006 +#define MP_ARGCHK 2 /* how to check input arguments */
1007 +#else
1008 +#define MP_ARGCHK 1 /* how to check input arguments */
1009 +#endif
1010 +#endif
1011 +
1012 +#ifndef MP_DEBUG
1013 +#define MP_DEBUG 0 /* print diagnostic output? */
1014 +#endif
1015 +
1016 +#ifndef MP_DEFPREC
1017 +#define MP_DEFPREC 64 /* default precision, in digits */
1018 +#endif
1019 +
1020 +#ifndef MP_MACRO
1021 +#define MP_MACRO 0 /* use macros for frequent calls? */
1022 +#endif
1023 +
1024 +#ifndef MP_SQUARE
1025 +#define MP_SQUARE 1 /* use separate squaring code? */
1026 +#endif
1027 +
1028 +#endif /* ifndef MPI_CONFIG_H_ */
1029 +
1030 +
1031 diff --git a/net/third_party/nss/ssl/mpi/mpi-priv.h b/net/third_party/nss/ssl/mp i/mpi-priv.h
1032 new file mode 100644
1033 index 0000000..8efaf3c
1034 --- /dev/null
1035 +++ b/net/third_party/nss/ssl/mpi/mpi-priv.h
1036 @@ -0,0 +1,320 @@
1037 +/*
1038 + * mpi-priv.h - Private header file for MPI
1039 + * Arbitrary precision integer arithmetic library
1040 + *
1041 + * NOTE WELL: the content of this header file is NOT part of the "public"
1042 + * API for the MPI library, and may change at any time.
1043 + * Application programs that use libmpi should NOT include this header file.
1044 + *
1045 + * ***** BEGIN LICENSE BLOCK *****
1046 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
1047 + *
1048 + * The contents of this file are subject to the Mozilla Public License Version
1049 + * 1.1 (the "License"); you may not use this file except in compliance with
1050 + * the License. You may obtain a copy of the License at
1051 + * http://www.mozilla.org/MPL/
1052 + *
1053 + * Software distributed under the License is distributed on an "AS IS" basis,
1054 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1055 + * for the specific language governing rights and limitations under the
1056 + * License.
1057 + *
1058 + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
1059 + *
1060 + * The Initial Developer of the Original Code is
1061 + * Michael J. Fromberger.
1062 + * Portions created by the Initial Developer are Copyright (C) 1998
1063 + * the Initial Developer. All Rights Reserved.
1064 + *
1065 + * Contributor(s):
1066 + * Netscape Communications Corporation
1067 + *
1068 + * Alternatively, the contents of this file may be used under the terms of
1069 + * either the GNU General Public License Version 2 or later (the "GPL"), or
1070 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1071 + * in which case the provisions of the GPL or the LGPL are applicable instead
1072 + * of those above. If you wish to allow use of your version of this file only
1073 + * under the terms of either the GPL or the LGPL, and not to allow others to
1074 + * use your version of this file under the terms of the MPL, indicate your
1075 + * decision by deleting the provisions above and replace them with the notice
1076 + * and other provisions required by the GPL or the LGPL. If you do not delete
1077 + * the provisions above, a recipient may use your version of this file under
1078 + * the terms of any one of the MPL, the GPL or the LGPL.
1079 + *
1080 + * ***** END LICENSE BLOCK ***** */
1081 +/* $Id: mpi-priv.h,v 1.23 2010/05/02 22:36:41 nelson%bolyard.com Exp $ */
1082 +#ifndef _MPI_PRIV_H_
1083 +#define _MPI_PRIV_H_ 1
1084 +
1085 +#include "mpi.h"
1086 +#include <stdlib.h>
1087 +#include <string.h>
1088 +#include <ctype.h>
1089 +
1090 +#if MP_DEBUG
1091 +#include <stdio.h>
1092 +
1093 +#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
1094 +#else
1095 +#define DIAG(T,V)
1096 +#endif
1097 +
1098 +/* If we aren't using a wired-in logarithm table, we need to include
1099 + the math library to get the log() function
1100 + */
1101 +
1102 +/* {{{ s_logv_2[] - log table for 2 in various bases */
1103 +
1104 +#if MP_LOGTAB
1105 +/*
1106 + A table of the logs of 2 for various bases (the 0 and 1 entries of
1107 + this table are meaningless and should not be referenced).
1108 +
1109 + This table is used to compute output lengths for the mp_toradix()
1110 + function. Since a number n in radix r takes up about log_r(n)
1111 + digits, we estimate the output size by taking the least integer
1112 + greater than log_r(n), where:
1113 +
1114 + log_r(n) = log_2(n) * log_r(2)
1115 +
1116 + This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
1117 + which are the output bases supported.
1118 + */
1119 +
1120 +extern const float s_logv_2[];
1121 +#define LOG_V_2(R) s_logv_2[(R)]
1122 +
1123 +#else
1124 +
1125 +/*
1126 + If MP_LOGTAB is not defined, use the math library to compute the
1127 + logarithms on the fly. Otherwise, use the table.
1128 + Pick which works best for your system.
1129 + */
1130 +
1131 +#include <math.h>
1132 +#define LOG_V_2(R) (log(2.0)/log(R))
1133 +
1134 +#endif /* if MP_LOGTAB */
1135 +
1136 +/* }}} */
1137 +
1138 +/* {{{ Digit arithmetic macros */
1139 +
1140 +/*
1141 + When adding and multiplying digits, the results can be larger than
1142 + can be contained in an mp_digit. Thus, an mp_word is used. These
1143 + macros mask off the upper and lower digits of the mp_word (the
1144 + mp_word may be more than 2 mp_digits wide, but we only concern
1145 + ourselves with the low-order 2 mp_digits)
1146 + */
1147 +
1148 +#define CARRYOUT(W) (mp_digit)((W)>>DIGIT_BIT)
1149 +#define ACCUM(W) (mp_digit)(W)
1150 +
1151 +#define MP_MIN(a,b) (((a) < (b)) ? (a) : (b))
1152 +#define MP_MAX(a,b) (((a) > (b)) ? (a) : (b))
1153 +#define MP_HOWMANY(a,b) (((a) + (b) - 1)/(b))
1154 +#define MP_ROUNDUP(a,b) (MP_HOWMANY(a,b) * (b))
1155 +
1156 +/* }}} */
1157 +
1158 +/* {{{ Comparison constants */
1159 +
1160 +#define MP_LT -1
1161 +#define MP_EQ 0
1162 +#define MP_GT 1
1163 +
1164 +/* }}} */
1165 +
1166 +/* {{{ private function declarations */
1167 +
1168 +/*
1169 + If MP_MACRO is false, these will be defined as actual functions;
1170 + otherwise, suitable macro definitions will be used. This works
1171 + around the fact that ANSI C89 doesn't support an 'inline' keyword
1172 + (although I hear C9x will ... about bloody time). At present, the
1173 + macro definitions are identical to the function bodies, but they'll
1174 + expand in place, instead of generating a function call.
1175 +
1176 + I chose these particular functions to be made into macros because
1177 + some profiling showed they are called a lot on a typical workload,
1178 + and yet they are primarily housekeeping.
1179 + */
1180 +#if MP_MACRO == 0
1181 + void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */
1182 + void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count); /* copy * /
1183 + void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */
1184 + void s_mp_free(void *ptr); /* general free function */
1185 +extern unsigned long mp_allocs;
1186 +extern unsigned long mp_frees;
1187 +extern unsigned long mp_copies;
1188 +#else
1189 +
1190 + /* Even if these are defined as macros, we need to respect the settings
1191 + of the MP_MEMSET and MP_MEMCPY configuration options...
1192 + */
1193 + #if MP_MEMSET == 0
1194 + #define s_mp_setz(dp, count) \
1195 + {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;}
1196 + #else
1197 + #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit))
1198 + #endif /* MP_MEMSET */
1199 +
1200 + #if MP_MEMCPY == 0
1201 + #define s_mp_copy(sp, dp, count) \
1202 + {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];}
1203 + #else
1204 + #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit))
1205 + #endif /* MP_MEMCPY */
1206 +
1207 + #define s_mp_alloc(nb, ni) calloc(nb, ni)
1208 + #define s_mp_free(ptr) {if(ptr) free(ptr);}
1209 +#endif /* MP_MACRO */
1210 +
1211 +mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */
1212 +mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */
1213 +
1214 +#if MP_MACRO == 0
1215 + void s_mp_clamp(mp_int *mp); /* clip leading zeroes */
1216 +#else
1217 + #define s_mp_clamp(mp)\
1218 + { mp_size used = MP_USED(mp); \
1219 + while (used > 1 && DIGIT(mp, used - 1) == 0) --used; \
1220 + MP_USED(mp) = used; \
1221 + }
1222 +#endif /* MP_MACRO */
1223 +
1224 +void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */
1225 +
1226 +mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */
1227 +void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */
1228 +mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place */
1229 +void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */
1230 +void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */
1231 +void s_mp_div_2(mp_int *mp); /* divide by 2 in place */
1232 +mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */
1233 +mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd);
1234 + /* normalize for division */
1235 +mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */
1236 +mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */
1237 +mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */
1238 +mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r);
1239 + /* unsigned digit divide */
1240 +mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu);
1241 + /* Barrett reduction */
1242 +mp_err s_mp_add(mp_int *a, const mp_int *b); /* magnitude addition */
1243 +mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c);
1244 +mp_err s_mp_sub(mp_int *a, const mp_int *b); /* magnitude subtract */
1245 +mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c);
1246 +mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset);
1247 + /* a += b * RADIX^offset */
1248 +mp_err s_mp_mul(mp_int *a, const mp_int *b); /* magnitude multiply */
1249 +#if MP_SQUARE
1250 +mp_err s_mp_sqr(mp_int *a); /* magnitude square */
1251 +#else
1252 +#define s_mp_sqr(a) s_mp_mul(a, a)
1253 +#endif
1254 +mp_err s_mp_div(mp_int *rem, mp_int *div, mp_int *quot); /* magnitude div */
1255 +mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
1256 +mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */
1257 +int s_mp_cmp(const mp_int *a, const mp_int *b); /* magnitude comparison */
1258 +int s_mp_cmp_d(const mp_int *a, mp_digit d); /* magnitude digit compare */
1259 +int s_mp_ispow2(const mp_int *v); /* is v a power of 2? */
1260 +int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */
1261 +
1262 +int s_mp_tovalue(char ch, int r); /* convert ch to value */
1263 +char s_mp_todigit(mp_digit val, int r, int low); /* convert val to digit */
1264 +int s_mp_outlen(int bits, int r); /* output length in bytes */
1265 +mp_digit s_mp_invmod_radix(mp_digit P); /* returns (P ** -1) mod RADIX */
1266 +mp_err s_mp_invmod_odd_m( const mp_int *a, const mp_int *m, mp_int *c);
1267 +mp_err s_mp_invmod_2d( const mp_int *a, mp_size k, mp_int *c);
1268 +mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c);
1269 +
1270 +#ifdef NSS_USE_COMBA
1271 +
1272 +#define IS_POWER_OF_2(a) ((a) && !((a) & ((a)-1)))
1273 +
1274 +void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C);
1275 +void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C);
1276 +void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C);
1277 +void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C);
1278 +
1279 +void s_mp_sqr_comba_4(const mp_int *A, mp_int *B);
1280 +void s_mp_sqr_comba_8(const mp_int *A, mp_int *B);
1281 +void s_mp_sqr_comba_16(const mp_int *A, mp_int *B);
1282 +void s_mp_sqr_comba_32(const mp_int *A, mp_int *B);
1283 +
1284 +#endif /* end NSS_USE_COMBA */
1285 +
1286 +/* ------ mpv functions, operate on arrays of digits, not on mp_int's ------ */
1287 +#if defined (__OS2__) && defined (__IBMC__)
1288 +#define MPI_ASM_DECL __cdecl
1289 +#else
1290 +#define MPI_ASM_DECL
1291 +#endif
1292 +
1293 +#ifdef MPI_AMD64
1294 +
1295 +mp_digit MPI_ASM_DECL s_mpv_mul_set_vec64(mp_digit*, mp_digit *, mp_size, mp_di git);
1296 +mp_digit MPI_ASM_DECL s_mpv_mul_add_vec64(mp_digit*, const mp_digit*, mp_size, mp_digit);
1297 +
1298 +/* c = a * b */
1299 +#define s_mpv_mul_d(a, a_len, b, c) \
1300 + ((mp_digit *)c)[a_len] = s_mpv_mul_set_vec64(c, a, a_len, b)
1301 +
1302 +/* c += a * b */
1303 +#define s_mpv_mul_d_add(a, a_len, b, c) \
1304 + ((mp_digit *)c)[a_len] = s_mpv_mul_add_vec64(c, a, a_len, b)
1305 +
1306 +
1307 +#else
1308 +
1309 +void MPI_ASM_DECL s_mpv_mul_d(const mp_digit *a, mp_size a_len,
1310 + mp_digit b, mp_digit *c);
1311 +void MPI_ASM_DECL s_mpv_mul_d_add(const mp_digit *a, mp_size a_len,
1312 + mp_digit b, mp_digit *c);
1313 +
1314 +#endif
1315 +
1316 +void MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a,
1317 + mp_size a_len, mp_digit b,
1318 + mp_digit *c);
1319 +void MPI_ASM_DECL s_mpv_sqr_add_prop(const mp_digit *a,
1320 + mp_size a_len,
1321 + mp_digit *sqrs);
1322 +
1323 +mp_err MPI_ASM_DECL s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo,
1324 + mp_digit divisor, mp_digit *quot, mp_digit *rem);
1325 +
1326 +/* c += a * b * (MP_RADIX ** offset); */
1327 +#define s_mp_mul_d_add_offset(a, b, c, off) \
1328 +(s_mpv_mul_d_add_prop(MP_DIGITS(a), MP_USED(a), b, MP_DIGITS(c) + off), MP_OKAY )
1329 +
1330 +typedef struct {
1331 + mp_int N; /* modulus N */
1332 + mp_digit n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */
1333 + mp_size b; /* R == 2 ** b, also b = # significant bits in N */
1334 +} mp_mont_modulus;
1335 +
1336 +mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
1337 + mp_mont_modulus *mmm);
1338 +mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm);
1339 +
1340 +/*
1341 + * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line
1342 + * if a cache exists, or zero if there is no cache. If more than one
1343 + * cache line exists, it should return the smallest line size (which is
1344 + * usually the L1 cache).
1345 + *
1346 + * mp_modexp uses this information to make sure that private key information
1347 + * isn't being leaked through the cache.
1348 + *
1349 + * see mpcpucache.c for the implementation.
1350 + */
1351 +unsigned long s_mpi_getProcessorLineSize();
1352 +
1353 +/* }}} */
1354 +#endif
1355 +
1356 +
1357 diff --git a/net/third_party/nss/ssl/mpi/mpi.c b/net/third_party/nss/ssl/mpi/mpi .c
1358 new file mode 100644
1359 index 0000000..8cd6ca6
1360 --- /dev/null
1361 +++ b/net/third_party/nss/ssl/mpi/mpi.c
1362 @@ -0,0 +1,4852 @@
1363 +/*
1364 + * mpi.c
1365 + *
1366 + * Arbitrary precision integer arithmetic library
1367 + *
1368 + * ***** BEGIN LICENSE BLOCK *****
1369 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
1370 + *
1371 + * The contents of this file are subject to the Mozilla Public License Version
1372 + * 1.1 (the "License"); you may not use this file except in compliance with
1373 + * the License. You may obtain a copy of the License at
1374 + * http://www.mozilla.org/MPL/
1375 + *
1376 + * Software distributed under the License is distributed on an "AS IS" basis,
1377 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1378 + * for the specific language governing rights and limitations under the
1379 + * License.
1380 + *
1381 + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
1382 + *
1383 + * The Initial Developer of the Original Code is
1384 + * Michael J. Fromberger.
1385 + * Portions created by the Initial Developer are Copyright (C) 1998
1386 + * the Initial Developer. All Rights Reserved.
1387 + *
1388 + * Contributor(s):
1389 + * Netscape Communications Corporation
1390 + * Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
1391 + *
1392 + * Alternatively, the contents of this file may be used under the terms of
1393 + * either the GNU General Public License Version 2 or later (the "GPL"), or
1394 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1395 + * in which case the provisions of the GPL or the LGPL are applicable instead
1396 + * of those above. If you wish to allow use of your version of this file only
1397 + * under the terms of either the GPL or the LGPL, and not to allow others to
1398 + * use your version of this file under the terms of the MPL, indicate your
1399 + * decision by deleting the provisions above and replace them with the notice
1400 + * and other provisions required by the GPL or the LGPL. If you do not delete
1401 + * the provisions above, a recipient may use your version of this file under
1402 + * the terms of any one of the MPL, the GPL or the LGPL.
1403 + *
1404 + * ***** END LICENSE BLOCK ***** */
1405 +/* $Id: mpi.c,v 1.47 2010/05/02 22:36:41 nelson%bolyard.com Exp $ */
1406 +
1407 +#define MP_API_COMPATIBLE 1
1408 +#include "mpi-priv.h"
1409 +#if defined(OSF1)
1410 +#include <c_asm.h>
1411 +#endif
1412 +
1413 +#if MP_LOGTAB
1414 +/*
1415 + A table of the logs of 2 for various bases (the 0 and 1 entries of
1416 + this table are meaningless and should not be referenced).
1417 +
1418 + This table is used to compute output lengths for the mp_toradix()
1419 + function. Since a number n in radix r takes up about log_r(n)
1420 + digits, we estimate the output size by taking the least integer
1421 + greater than log_r(n), where:
1422 +
1423 + log_r(n) = log_2(n) * log_r(2)
1424 +
1425 + This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
1426 + which are the output bases supported.
1427 + */
1428 +#include "logtab.h"
1429 +#endif
1430 +
1431 +/* {{{ Constant strings */
1432 +
1433 +/* Constant strings returned by mp_strerror() */
1434 +static const char *mp_err_string[] = {
1435 + "unknown result code", /* say what? */
1436 + "boolean true", /* MP_OKAY, MP_YES */
1437 + "boolean false", /* MP_NO */
1438 + "out of memory", /* MP_MEM */
1439 + "argument out of range", /* MP_RANGE */
1440 + "invalid input parameter", /* MP_BADARG */
1441 + "result is undefined" /* MP_UNDEF */
1442 +};
1443 +
1444 +/* Value to digit maps for radix conversion */
1445 +
1446 +/* s_dmap_1 - standard digits and letters */
1447 +static const char *s_dmap_1 =
1448 + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
1449 +
1450 +/* }}} */
1451 +
1452 +unsigned long mp_allocs;
1453 +unsigned long mp_frees;
1454 +unsigned long mp_copies;
1455 +
1456 +/* {{{ Default precision manipulation */
1457 +
1458 +/* Default precision for newly created mp_int's */
1459 +static mp_size s_mp_defprec = MP_DEFPREC;
1460 +
1461 +mp_size mp_get_prec(void)
1462 +{
1463 + return s_mp_defprec;
1464 +
1465 +} /* end mp_get_prec() */
1466 +
1467 +void mp_set_prec(mp_size prec)
1468 +{
1469 + if(prec == 0)
1470 + s_mp_defprec = MP_DEFPREC;
1471 + else
1472 + s_mp_defprec = prec;
1473 +
1474 +} /* end mp_set_prec() */
1475 +
1476 +/* }}} */
1477 +
1478 +/*------------------------------------------------------------------------*/
1479 +/* {{{ mp_init(mp) */
1480 +
1481 +/*
1482 + mp_init(mp)
1483 +
1484 + Initialize a new zero-valued mp_int. Returns MP_OKAY if successful,
1485 + MP_MEM if memory could not be allocated for the structure.
1486 + */
1487 +
1488 +mp_err mp_init(mp_int *mp)
1489 +{
1490 + return mp_init_size(mp, s_mp_defprec);
1491 +
1492 +} /* end mp_init() */
1493 +
1494 +/* }}} */
1495 +
1496 +/* {{{ mp_init_size(mp, prec) */
1497 +
1498 +/*
1499 + mp_init_size(mp, prec)
1500 +
1501 + Initialize a new zero-valued mp_int with at least the given
1502 + precision; returns MP_OKAY if successful, or MP_MEM if memory could
1503 + not be allocated for the structure.
1504 + */
1505 +
1506 +mp_err mp_init_size(mp_int *mp, mp_size prec)
1507 +{
1508 + ARGCHK(mp != NULL && prec > 0, MP_BADARG);
1509 +
1510 + prec = MP_ROUNDUP(prec, s_mp_defprec);
1511 + if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL)
1512 + return MP_MEM;
1513 +
1514 + SIGN(mp) = ZPOS;
1515 + USED(mp) = 1;
1516 + ALLOC(mp) = prec;
1517 +
1518 + return MP_OKAY;
1519 +
1520 +} /* end mp_init_size() */
1521 +
1522 +/* }}} */
1523 +
1524 +/* {{{ mp_init_copy(mp, from) */
1525 +
1526 +/*
1527 + mp_init_copy(mp, from)
1528 +
1529 + Initialize mp as an exact copy of from. Returns MP_OKAY if
1530 + successful, MP_MEM if memory could not be allocated for the new
1531 + structure.
1532 + */
1533 +
1534 +mp_err mp_init_copy(mp_int *mp, const mp_int *from)
1535 +{
1536 + ARGCHK(mp != NULL && from != NULL, MP_BADARG);
1537 +
1538 + if(mp == from)
1539 + return MP_OKAY;
1540 +
1541 + if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL)
1542 + return MP_MEM;
1543 +
1544 + s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
1545 + USED(mp) = USED(from);
1546 + ALLOC(mp) = ALLOC(from);
1547 + SIGN(mp) = SIGN(from);
1548 +
1549 + return MP_OKAY;
1550 +
1551 +} /* end mp_init_copy() */
1552 +
1553 +/* }}} */
1554 +
1555 +/* {{{ mp_copy(from, to) */
1556 +
1557 +/*
1558 + mp_copy(from, to)
1559 +
1560 + Copies the mp_int 'from' to the mp_int 'to'. It is presumed that
1561 + 'to' has already been initialized (if not, use mp_init_copy()
1562 + instead). If 'from' and 'to' are identical, nothing happens.
1563 + */
1564 +
1565 +mp_err mp_copy(const mp_int *from, mp_int *to)
1566 +{
1567 + ARGCHK(from != NULL && to != NULL, MP_BADARG);
1568 +
1569 + if(from == to)
1570 + return MP_OKAY;
1571 +
1572 + ++mp_copies;
1573 + { /* copy */
1574 + mp_digit *tmp;
1575 +
1576 + /*
1577 + If the allocated buffer in 'to' already has enough space to hold
1578 + all the used digits of 'from', we'll re-use it to avoid hitting
1579 + the memory allocater more than necessary; otherwise, we'd have
1580 + to grow anyway, so we just allocate a hunk and make the copy as
1581 + usual
1582 + */
1583 + if(ALLOC(to) >= USED(from)) {
1584 + s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
1585 + s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
1586 +
1587 + } else {
1588 + if((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL)
1589 + return MP_MEM;
1590 +
1591 + s_mp_copy(DIGITS(from), tmp, USED(from));
1592 +
1593 + if(DIGITS(to) != NULL) {
1594 +#if MP_CRYPTO
1595 + s_mp_setz(DIGITS(to), ALLOC(to));
1596 +#endif
1597 + s_mp_free(DIGITS(to));
1598 + }
1599 +
1600 + DIGITS(to) = tmp;
1601 + ALLOC(to) = ALLOC(from);
1602 + }
1603 +
1604 + /* Copy the precision and sign from the original */
1605 + USED(to) = USED(from);
1606 + SIGN(to) = SIGN(from);
1607 + } /* end copy */
1608 +
1609 + return MP_OKAY;
1610 +
1611 +} /* end mp_copy() */
1612 +
1613 +/* }}} */
1614 +
1615 +/* {{{ mp_exch(mp1, mp2) */
1616 +
1617 +/*
1618 + mp_exch(mp1, mp2)
1619 +
1620 + Exchange mp1 and mp2 without allocating any intermediate memory
1621 + (well, unless you count the stack space needed for this call and the
1622 + locals it creates...). This cannot fail.
1623 + */
1624 +
1625 +void mp_exch(mp_int *mp1, mp_int *mp2)
1626 +{
1627 +#if MP_ARGCHK == 2
1628 + assert(mp1 != NULL && mp2 != NULL);
1629 +#else
1630 + if(mp1 == NULL || mp2 == NULL)
1631 + return;
1632 +#endif
1633 +
1634 + s_mp_exch(mp1, mp2);
1635 +
1636 +} /* end mp_exch() */
1637 +
1638 +/* }}} */
1639 +
1640 +/* {{{ mp_clear(mp) */
1641 +
1642 +/*
1643 + mp_clear(mp)
1644 +
1645 + Release the storage used by an mp_int, and void its fields so that
1646 + if someone calls mp_clear() again for the same int later, we won't
1647 + get tollchocked.
1648 + */
1649 +
1650 +void mp_clear(mp_int *mp)
1651 +{
1652 + if(mp == NULL)
1653 + return;
1654 +
1655 + if(DIGITS(mp) != NULL) {
1656 +#if MP_CRYPTO
1657 + s_mp_setz(DIGITS(mp), ALLOC(mp));
1658 +#endif
1659 + s_mp_free(DIGITS(mp));
1660 + DIGITS(mp) = NULL;
1661 + }
1662 +
1663 + USED(mp) = 0;
1664 + ALLOC(mp) = 0;
1665 +
1666 +} /* end mp_clear() */
1667 +
1668 +/* }}} */
1669 +
1670 +/* {{{ mp_zero(mp) */
1671 +
1672 +/*
1673 + mp_zero(mp)
1674 +
1675 + Set mp to zero. Does not change the allocated size of the structure,
1676 + and therefore cannot fail (except on a bad argument, which we ignore)
1677 + */
1678 +void mp_zero(mp_int *mp)
1679 +{
1680 + if(mp == NULL)
1681 + return;
1682 +
1683 + s_mp_setz(DIGITS(mp), ALLOC(mp));
1684 + USED(mp) = 1;
1685 + SIGN(mp) = ZPOS;
1686 +
1687 +} /* end mp_zero() */
1688 +
1689 +/* }}} */
1690 +
1691 +/* {{{ mp_set(mp, d) */
1692 +
1693 +void mp_set(mp_int *mp, mp_digit d)
1694 +{
1695 + if(mp == NULL)
1696 + return;
1697 +
1698 + mp_zero(mp);
1699 + DIGIT(mp, 0) = d;
1700 +
1701 +} /* end mp_set() */
1702 +
1703 +/* }}} */
1704 +
1705 +/* {{{ mp_set_int(mp, z) */
1706 +
1707 +mp_err mp_set_int(mp_int *mp, long z)
1708 +{
1709 + int ix;
1710 + unsigned long v = labs(z);
1711 + mp_err res;
1712 +
1713 + ARGCHK(mp != NULL, MP_BADARG);
1714 +
1715 + mp_zero(mp);
1716 + if(z == 0)
1717 + return MP_OKAY; /* shortcut for zero */
1718 +
1719 + if (sizeof v <= sizeof(mp_digit)) {
1720 + DIGIT(mp,0) = v;
1721 + } else {
1722 + for (ix = sizeof(long) - 1; ix >= 0; ix--) {
1723 + if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
1724 + return res;
1725 +
1726 + res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
1727 + if (res != MP_OKAY)
1728 + return res;
1729 + }
1730 + }
1731 + if(z < 0)
1732 + SIGN(mp) = NEG;
1733 +
1734 + return MP_OKAY;
1735 +
1736 +} /* end mp_set_int() */
1737 +
1738 +/* }}} */
1739 +
1740 +/* {{{ mp_set_ulong(mp, z) */
1741 +
1742 +mp_err mp_set_ulong(mp_int *mp, unsigned long z)
1743 +{
1744 + int ix;
1745 + mp_err res;
1746 +
1747 + ARGCHK(mp != NULL, MP_BADARG);
1748 +
1749 + mp_zero(mp);
1750 + if(z == 0)
1751 + return MP_OKAY; /* shortcut for zero */
1752 +
1753 + if (sizeof z <= sizeof(mp_digit)) {
1754 + DIGIT(mp,0) = z;
1755 + } else {
1756 + for (ix = sizeof(long) - 1; ix >= 0; ix--) {
1757 + if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
1758 + return res;
1759 +
1760 + res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX));
1761 + if (res != MP_OKAY)
1762 + return res;
1763 + }
1764 + }
1765 + return MP_OKAY;
1766 +} /* end mp_set_ulong() */
1767 +
1768 +/* }}} */
1769 +
1770 +/*------------------------------------------------------------------------*/
1771 +/* {{{ Digit arithmetic */
1772 +
1773 +/* {{{ mp_add_d(a, d, b) */
1774 +
1775 +/*
1776 + mp_add_d(a, d, b)
1777 +
1778 + Compute the sum b = a + d, for a single digit d. Respects the sign of
1779 + its primary addend (single digits are unsigned anyway).
1780 + */
1781 +
1782 +mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b)
1783 +{
1784 + mp_int tmp;
1785 + mp_err res;
1786 +
1787 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
1788 +
1789 + if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
1790 + return res;
1791 +
1792 + if(SIGN(&tmp) == ZPOS) {
1793 + if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
1794 + goto CLEANUP;
1795 + } else if(s_mp_cmp_d(&tmp, d) >= 0) {
1796 + if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
1797 + goto CLEANUP;
1798 + } else {
1799 + mp_neg(&tmp, &tmp);
1800 +
1801 + DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
1802 + }
1803 +
1804 + if(s_mp_cmp_d(&tmp, 0) == 0)
1805 + SIGN(&tmp) = ZPOS;
1806 +
1807 + s_mp_exch(&tmp, b);
1808 +
1809 +CLEANUP:
1810 + mp_clear(&tmp);
1811 + return res;
1812 +
1813 +} /* end mp_add_d() */
1814 +
1815 +/* }}} */
1816 +
1817 +/* {{{ mp_sub_d(a, d, b) */
1818 +
1819 +/*
1820 + mp_sub_d(a, d, b)
1821 +
1822 + Compute the difference b = a - d, for a single digit d. Respects the
1823 + sign of its subtrahend (single digits are unsigned anyway).
1824 + */
1825 +
1826 +mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b)
1827 +{
1828 + mp_int tmp;
1829 + mp_err res;
1830 +
1831 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
1832 +
1833 + if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
1834 + return res;
1835 +
1836 + if(SIGN(&tmp) == NEG) {
1837 + if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
1838 + goto CLEANUP;
1839 + } else if(s_mp_cmp_d(&tmp, d) >= 0) {
1840 + if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
1841 + goto CLEANUP;
1842 + } else {
1843 + mp_neg(&tmp, &tmp);
1844 +
1845 + DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
1846 + SIGN(&tmp) = NEG;
1847 + }
1848 +
1849 + if(s_mp_cmp_d(&tmp, 0) == 0)
1850 + SIGN(&tmp) = ZPOS;
1851 +
1852 + s_mp_exch(&tmp, b);
1853 +
1854 +CLEANUP:
1855 + mp_clear(&tmp);
1856 + return res;
1857 +
1858 +} /* end mp_sub_d() */
1859 +
1860 +/* }}} */
1861 +
1862 +/* {{{ mp_mul_d(a, d, b) */
1863 +
1864 +/*
1865 + mp_mul_d(a, d, b)
1866 +
1867 + Compute the product b = a * d, for a single digit d. Respects the sign
1868 + of its multiplicand (single digits are unsigned anyway)
1869 + */
1870 +
1871 +mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)
1872 +{
1873 + mp_err res;
1874 +
1875 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
1876 +
1877 + if(d == 0) {
1878 + mp_zero(b);
1879 + return MP_OKAY;
1880 + }
1881 +
1882 + if((res = mp_copy(a, b)) != MP_OKAY)
1883 + return res;
1884 +
1885 + res = s_mp_mul_d(b, d);
1886 +
1887 + return res;
1888 +
1889 +} /* end mp_mul_d() */
1890 +
1891 +/* }}} */
1892 +
1893 +/* {{{ mp_mul_2(a, c) */
1894 +
1895 +mp_err mp_mul_2(const mp_int *a, mp_int *c)
1896 +{
1897 + mp_err res;
1898 +
1899 + ARGCHK(a != NULL && c != NULL, MP_BADARG);
1900 +
1901 + if((res = mp_copy(a, c)) != MP_OKAY)
1902 + return res;
1903 +
1904 + return s_mp_mul_2(c);
1905 +
1906 +} /* end mp_mul_2() */
1907 +
1908 +/* }}} */
1909 +
1910 +/* {{{ mp_div_d(a, d, q, r) */
1911 +
1912 +/*
1913 + mp_div_d(a, d, q, r)
1914 +
1915 + Compute the quotient q = a / d and remainder r = a mod d, for a
1916 + single digit d. Respects the sign of its divisor (single digits are
1917 + unsigned anyway).
1918 + */
1919 +
1920 +mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
1921 +{
1922 + mp_err res;
1923 + mp_int qp;
1924 + mp_digit rem;
1925 + int pow;
1926 +
1927 + ARGCHK(a != NULL, MP_BADARG);
1928 +
1929 + if(d == 0)
1930 + return MP_RANGE;
1931 +
1932 + /* Shortcut for powers of two ... */
1933 + if((pow = s_mp_ispow2d(d)) >= 0) {
1934 + mp_digit mask;
1935 +
1936 + mask = ((mp_digit)1 << pow) - 1;
1937 + rem = DIGIT(a, 0) & mask;
1938 +
1939 + if(q) {
1940 + mp_copy(a, q);
1941 + s_mp_div_2d(q, pow);
1942 + }
1943 +
1944 + if(r)
1945 + *r = rem;
1946 +
1947 + return MP_OKAY;
1948 + }
1949 +
1950 + if((res = mp_init_copy(&qp, a)) != MP_OKAY)
1951 + return res;
1952 +
1953 + res = s_mp_div_d(&qp, d, &rem);
1954 +
1955 + if(s_mp_cmp_d(&qp, 0) == 0)
1956 + SIGN(q) = ZPOS;
1957 +
1958 + if(r)
1959 + *r = rem;
1960 +
1961 + if(q)
1962 + s_mp_exch(&qp, q);
1963 +
1964 + mp_clear(&qp);
1965 + return res;
1966 +
1967 +} /* end mp_div_d() */
1968 +
1969 +/* }}} */
1970 +
1971 +/* {{{ mp_div_2(a, c) */
1972 +
1973 +/*
1974 + mp_div_2(a, c)
1975 +
1976 + Compute c = a / 2, disregarding the remainder.
1977 + */
1978 +
1979 +mp_err mp_div_2(const mp_int *a, mp_int *c)
1980 +{
1981 + mp_err res;
1982 +
1983 + ARGCHK(a != NULL && c != NULL, MP_BADARG);
1984 +
1985 + if((res = mp_copy(a, c)) != MP_OKAY)
1986 + return res;
1987 +
1988 + s_mp_div_2(c);
1989 +
1990 + return MP_OKAY;
1991 +
1992 +} /* end mp_div_2() */
1993 +
1994 +/* }}} */
1995 +
1996 +/* {{{ mp_expt_d(a, d, b) */
1997 +
1998 +mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)
1999 +{
2000 + mp_int s, x;
2001 + mp_err res;
2002 +
2003 + ARGCHK(a != NULL && c != NULL, MP_BADARG);
2004 +
2005 + if((res = mp_init(&s)) != MP_OKAY)
2006 + return res;
2007 + if((res = mp_init_copy(&x, a)) != MP_OKAY)
2008 + goto X;
2009 +
2010 + DIGIT(&s, 0) = 1;
2011 +
2012 + while(d != 0) {
2013 + if(d & 1) {
2014 + if((res = s_mp_mul(&s, &x)) != MP_OKAY)
2015 + goto CLEANUP;
2016 + }
2017 +
2018 + d /= 2;
2019 +
2020 + if((res = s_mp_sqr(&x)) != MP_OKAY)
2021 + goto CLEANUP;
2022 + }
2023 +
2024 + s_mp_exch(&s, c);
2025 +
2026 +CLEANUP:
2027 + mp_clear(&x);
2028 +X:
2029 + mp_clear(&s);
2030 +
2031 + return res;
2032 +
2033 +} /* end mp_expt_d() */
2034 +
2035 +/* }}} */
2036 +
2037 +/* }}} */
2038 +
2039 +/*------------------------------------------------------------------------*/
2040 +/* {{{ Full arithmetic */
2041 +
2042 +/* {{{ mp_abs(a, b) */
2043 +
2044 +/*
2045 + mp_abs(a, b)
2046 +
2047 + Compute b = |a|. 'a' and 'b' may be identical.
2048 + */
2049 +
2050 +mp_err mp_abs(const mp_int *a, mp_int *b)
2051 +{
2052 + mp_err res;
2053 +
2054 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
2055 +
2056 + if((res = mp_copy(a, b)) != MP_OKAY)
2057 + return res;
2058 +
2059 + SIGN(b) = ZPOS;
2060 +
2061 + return MP_OKAY;
2062 +
2063 +} /* end mp_abs() */
2064 +
2065 +/* }}} */
2066 +
2067 +/* {{{ mp_neg(a, b) */
2068 +
2069 +/*
2070 + mp_neg(a, b)
2071 +
2072 + Compute b = -a. 'a' and 'b' may be identical.
2073 + */
2074 +
2075 +mp_err mp_neg(const mp_int *a, mp_int *b)
2076 +{
2077 + mp_err res;
2078 +
2079 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
2080 +
2081 + if((res = mp_copy(a, b)) != MP_OKAY)
2082 + return res;
2083 +
2084 + if(s_mp_cmp_d(b, 0) == MP_EQ)
2085 + SIGN(b) = ZPOS;
2086 + else
2087 + SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG;
2088 +
2089 + return MP_OKAY;
2090 +
2091 +} /* end mp_neg() */
2092 +
2093 +/* }}} */
2094 +
2095 +/* {{{ mp_add(a, b, c) */
2096 +
2097 +/*
2098 + mp_add(a, b, c)
2099 +
2100 + Compute c = a + b. All parameters may be identical.
2101 + */
2102 +
2103 +mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
2104 +{
2105 + mp_err res;
2106 +
2107 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
2108 +
2109 + if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */
2110 + MP_CHECKOK( s_mp_add_3arg(a, b, c) );
2111 + } else if(s_mp_cmp(a, b) >= 0) { /* different sign: |a| >= |b| */
2112 + MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
2113 + } else { /* different sign: |a| < |b| */
2114 + MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
2115 + }
2116 +
2117 + if (s_mp_cmp_d(c, 0) == MP_EQ)
2118 + SIGN(c) = ZPOS;
2119 +
2120 +CLEANUP:
2121 + return res;
2122 +
2123 +} /* end mp_add() */
2124 +
2125 +/* }}} */
2126 +
2127 +/* {{{ mp_sub(a, b, c) */
2128 +
2129 +/*
2130 + mp_sub(a, b, c)
2131 +
2132 + Compute c = a - b. All parameters may be identical.
2133 + */
2134 +
2135 +mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
2136 +{
2137 + mp_err res;
2138 + int magDiff;
2139 +
2140 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
2141 +
2142 + if (a == b) {
2143 + mp_zero(c);
2144 + return MP_OKAY;
2145 + }
2146 +
2147 + if (MP_SIGN(a) != MP_SIGN(b)) {
2148 + MP_CHECKOK( s_mp_add_3arg(a, b, c) );
2149 + } else if (!(magDiff = s_mp_cmp(a, b))) {
2150 + mp_zero(c);
2151 + res = MP_OKAY;
2152 + } else if (magDiff > 0) {
2153 + MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
2154 + } else {
2155 + MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
2156 + MP_SIGN(c) = !MP_SIGN(a);
2157 + }
2158 +
2159 + if (s_mp_cmp_d(c, 0) == MP_EQ)
2160 + MP_SIGN(c) = MP_ZPOS;
2161 +
2162 +CLEANUP:
2163 + return res;
2164 +
2165 +} /* end mp_sub() */
2166 +
2167 +/* }}} */
2168 +
2169 +/* {{{ mp_mul(a, b, c) */
2170 +
2171 +/*
2172 + mp_mul(a, b, c)
2173 +
2174 + Compute c = a * b. All parameters may be identical.
2175 + */
2176 +mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int * c)
2177 +{
2178 + mp_digit *pb;
2179 + mp_int tmp;
2180 + mp_err res;
2181 + mp_size ib;
2182 + mp_size useda, usedb;
2183 +
2184 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
2185 +
2186 + if (a == c) {
2187 + if ((res = mp_init_copy(&tmp, a)) != MP_OKAY)
2188 + return res;
2189 + if (a == b)
2190 + b = &tmp;
2191 + a = &tmp;
2192 + } else if (b == c) {
2193 + if ((res = mp_init_copy(&tmp, b)) != MP_OKAY)
2194 + return res;
2195 + b = &tmp;
2196 + } else {
2197 + MP_DIGITS(&tmp) = 0;
2198 + }
2199 +
2200 + if (MP_USED(a) < MP_USED(b)) {
2201 + const mp_int *xch = b; /* switch a and b, to do fewer outer loops */
2202 + b = a;
2203 + a = xch;
2204 + }
2205 +
2206 + MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
2207 + if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY)
2208 + goto CLEANUP;
2209 +
2210 +#ifdef NSS_USE_COMBA
2211 + if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
2212 + if (MP_USED(a) == 4) {
2213 + s_mp_mul_comba_4(a, b, c);
2214 + goto CLEANUP;
2215 + }
2216 + if (MP_USED(a) == 8) {
2217 + s_mp_mul_comba_8(a, b, c);
2218 + goto CLEANUP;
2219 + }
2220 + if (MP_USED(a) == 16) {
2221 + s_mp_mul_comba_16(a, b, c);
2222 + goto CLEANUP;
2223 + }
2224 + if (MP_USED(a) == 32) {
2225 + s_mp_mul_comba_32(a, b, c);
2226 + goto CLEANUP;
2227 + }
2228 + }
2229 +#endif
2230 +
2231 + pb = MP_DIGITS(b);
2232 + s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
2233 +
2234 + /* Outer loop: Digits of b */
2235 + useda = MP_USED(a);
2236 + usedb = MP_USED(b);
2237 + for (ib = 1; ib < usedb; ib++) {
2238 + mp_digit b_i = *pb++;
2239 +
2240 + /* Inner product: Digits of a */
2241 + if (b_i)
2242 + s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
2243 + else
2244 + MP_DIGIT(c, ib + useda) = b_i;
2245 + }
2246 +
2247 + s_mp_clamp(c);
2248 +
2249 + if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)
2250 + SIGN(c) = ZPOS;
2251 + else
2252 + SIGN(c) = NEG;
2253 +
2254 +CLEANUP:
2255 + mp_clear(&tmp);
2256 + return res;
2257 +} /* end mp_mul() */
2258 +
2259 +/* }}} */
2260 +
2261 +/* {{{ mp_sqr(a, sqr) */
2262 +
2263 +#if MP_SQUARE
2264 +/*
2265 + Computes the square of a. This can be done more
2266 + efficiently than a general multiplication, because many of the
2267 + computation steps are redundant when squaring. The inner product
2268 + step is a bit more complicated, but we save a fair number of
2269 + iterations of the multiplication loop.
2270 + */
2271 +
2272 +/* sqr = a^2; Caller provides both a and tmp; */
2273 +mp_err mp_sqr(const mp_int *a, mp_int *sqr)
2274 +{
2275 + mp_digit *pa;
2276 + mp_digit d;
2277 + mp_err res;
2278 + mp_size ix;
2279 + mp_int tmp;
2280 + int count;
2281 +
2282 + ARGCHK(a != NULL && sqr != NULL, MP_BADARG);
2283 +
2284 + if (a == sqr) {
2285 + if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
2286 + return res;
2287 + a = &tmp;
2288 + } else {
2289 + DIGITS(&tmp) = 0;
2290 + res = MP_OKAY;
2291 + }
2292 +
2293 + ix = 2 * MP_USED(a);
2294 + if (ix > MP_ALLOC(sqr)) {
2295 + MP_USED(sqr) = 1;
2296 + MP_CHECKOK( s_mp_grow(sqr, ix) );
2297 + }
2298 + MP_USED(sqr) = ix;
2299 + MP_DIGIT(sqr, 0) = 0;
2300 +
2301 +#ifdef NSS_USE_COMBA
2302 + if (IS_POWER_OF_2(MP_USED(a))) {
2303 + if (MP_USED(a) == 4) {
2304 + s_mp_sqr_comba_4(a, sqr);
2305 + goto CLEANUP;
2306 + }
2307 + if (MP_USED(a) == 8) {
2308 + s_mp_sqr_comba_8(a, sqr);
2309 + goto CLEANUP;
2310 + }
2311 + if (MP_USED(a) == 16) {
2312 + s_mp_sqr_comba_16(a, sqr);
2313 + goto CLEANUP;
2314 + }
2315 + if (MP_USED(a) == 32) {
2316 + s_mp_sqr_comba_32(a, sqr);
2317 + goto CLEANUP;
2318 + }
2319 + }
2320 +#endif
2321 +
2322 + pa = MP_DIGITS(a);
2323 + count = MP_USED(a) - 1;
2324 + if (count > 0) {
2325 + d = *pa++;
2326 + s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1);
2327 + for (ix = 3; --count > 0; ix += 2) {
2328 + d = *pa++;
2329 + s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix);
2330 + } /* for(ix ...) */
2331 + MP_DIGIT(sqr, MP_USED(sqr)-1) = 0; /* above loop stopped short of this. */
2332 +
2333 + /* now sqr *= 2 */
2334 + s_mp_mul_2(sqr);
2335 + } else {
2336 + MP_DIGIT(sqr, 1) = 0;
2337 + }
2338 +
2339 + /* now add the squares of the digits of a to sqr. */
2340 + s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr));
2341 +
2342 + SIGN(sqr) = ZPOS;
2343 + s_mp_clamp(sqr);
2344 +
2345 +CLEANUP:
2346 + mp_clear(&tmp);
2347 + return res;
2348 +
2349 +} /* end mp_sqr() */
2350 +#endif
2351 +
2352 +/* }}} */
2353 +
2354 +/* {{{ mp_div(a, b, q, r) */
2355 +
2356 +/*
2357 + mp_div(a, b, q, r)
2358 +
2359 + Compute q = a / b and r = a mod b. Input parameters may be re-used
2360 + as output parameters. If q or r is NULL, that portion of the
2361 + computation will be discarded (although it will still be computed)
2362 + */
2363 +mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
2364 +{
2365 + mp_err res;
2366 + mp_int *pQ, *pR;
2367 + mp_int qtmp, rtmp, btmp;
2368 + int cmp;
2369 + mp_sign signA;
2370 + mp_sign signB;
2371 +
2372 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
2373 +
2374 + signA = MP_SIGN(a);
2375 + signB = MP_SIGN(b);
2376 +
2377 + if(mp_cmp_z(b) == MP_EQ)
2378 + return MP_RANGE;
2379 +
2380 + DIGITS(&qtmp) = 0;
2381 + DIGITS(&rtmp) = 0;
2382 + DIGITS(&btmp) = 0;
2383 +
2384 + /* Set up some temporaries... */
2385 + if (!r || r == a || r == b) {
2386 + MP_CHECKOK( mp_init_copy(&rtmp, a) );
2387 + pR = &rtmp;
2388 + } else {
2389 + MP_CHECKOK( mp_copy(a, r) );
2390 + pR = r;
2391 + }
2392 +
2393 + if (!q || q == a || q == b) {
2394 + MP_CHECKOK( mp_init_size(&qtmp, MP_USED(a)) );
2395 + pQ = &qtmp;
2396 + } else {
2397 + MP_CHECKOK( s_mp_pad(q, MP_USED(a)) );
2398 + pQ = q;
2399 + mp_zero(pQ);
2400 + }
2401 +
2402 + /*
2403 + If |a| <= |b|, we can compute the solution without division;
2404 + otherwise, we actually do the work required.
2405 + */
2406 + if ((cmp = s_mp_cmp(a, b)) <= 0) {
2407 + if (cmp) {
2408 + /* r was set to a above. */
2409 + mp_zero(pQ);
2410 + } else {
2411 + mp_set(pQ, 1);
2412 + mp_zero(pR);
2413 + }
2414 + } else {
2415 + MP_CHECKOK( mp_init_copy(&btmp, b) );
2416 + MP_CHECKOK( s_mp_div(pR, &btmp, pQ) );
2417 + }
2418 +
2419 + /* Compute the signs for the output */
2420 + MP_SIGN(pR) = signA; /* Sr = Sa */
2421 + /* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */
2422 + MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG;
2423 +
2424 + if(s_mp_cmp_d(pQ, 0) == MP_EQ)
2425 + SIGN(pQ) = ZPOS;
2426 + if(s_mp_cmp_d(pR, 0) == MP_EQ)
2427 + SIGN(pR) = ZPOS;
2428 +
2429 + /* Copy output, if it is needed */
2430 + if(q && q != pQ)
2431 + s_mp_exch(pQ, q);
2432 +
2433 + if(r && r != pR)
2434 + s_mp_exch(pR, r);
2435 +
2436 +CLEANUP:
2437 + mp_clear(&btmp);
2438 + mp_clear(&rtmp);
2439 + mp_clear(&qtmp);
2440 +
2441 + return res;
2442 +
2443 +} /* end mp_div() */
2444 +
2445 +/* }}} */
2446 +
2447 +/* {{{ mp_div_2d(a, d, q, r) */
2448 +
2449 +mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r)
2450 +{
2451 + mp_err res;
2452 +
2453 + ARGCHK(a != NULL, MP_BADARG);
2454 +
2455 + if(q) {
2456 + if((res = mp_copy(a, q)) != MP_OKAY)
2457 + return res;
2458 + }
2459 + if(r) {
2460 + if((res = mp_copy(a, r)) != MP_OKAY)
2461 + return res;
2462 + }
2463 + if(q) {
2464 + s_mp_div_2d(q, d);
2465 + }
2466 + if(r) {
2467 + s_mp_mod_2d(r, d);
2468 + }
2469 +
2470 + return MP_OKAY;
2471 +
2472 +} /* end mp_div_2d() */
2473 +
2474 +/* }}} */
2475 +
2476 +/* {{{ mp_expt(a, b, c) */
2477 +
2478 +/*
2479 + mp_expt(a, b, c)
2480 +
2481 + Compute c = a ** b, that is, raise a to the b power. Uses a
2482 + standard iterative square-and-multiply technique.
2483 + */
2484 +
2485 +mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
2486 +{
2487 + mp_int s, x;
2488 + mp_err res;
2489 + mp_digit d;
2490 + int dig, bit;
2491 +
2492 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
2493 +
2494 + if(mp_cmp_z(b) < 0)
2495 + return MP_RANGE;
2496 +
2497 + if((res = mp_init(&s)) != MP_OKAY)
2498 + return res;
2499 +
2500 + mp_set(&s, 1);
2501 +
2502 + if((res = mp_init_copy(&x, a)) != MP_OKAY)
2503 + goto X;
2504 +
2505 + /* Loop over low-order digits in ascending order */
2506 + for(dig = 0; dig < (USED(b) - 1); dig++) {
2507 + d = DIGIT(b, dig);
2508 +
2509 + /* Loop over bits of each non-maximal digit */
2510 + for(bit = 0; bit < DIGIT_BIT; bit++) {
2511 + if(d & 1) {
2512 + if((res = s_mp_mul(&s, &x)) != MP_OKAY)
2513 + goto CLEANUP;
2514 + }
2515 +
2516 + d >>= 1;
2517 +
2518 + if((res = s_mp_sqr(&x)) != MP_OKAY)
2519 + goto CLEANUP;
2520 + }
2521 + }
2522 +
2523 + /* Consider now the last digit... */
2524 + d = DIGIT(b, dig);
2525 +
2526 + while(d) {
2527 + if(d & 1) {
2528 + if((res = s_mp_mul(&s, &x)) != MP_OKAY)
2529 + goto CLEANUP;
2530 + }
2531 +
2532 + d >>= 1;
2533 +
2534 + if((res = s_mp_sqr(&x)) != MP_OKAY)
2535 + goto CLEANUP;
2536 + }
2537 +
2538 + if(mp_iseven(b))
2539 + SIGN(&s) = SIGN(a);
2540 +
2541 + res = mp_copy(&s, c);
2542 +
2543 +CLEANUP:
2544 + mp_clear(&x);
2545 +X:
2546 + mp_clear(&s);
2547 +
2548 + return res;
2549 +
2550 +} /* end mp_expt() */
2551 +
2552 +/* }}} */
2553 +
2554 +/* {{{ mp_2expt(a, k) */
2555 +
2556 +/* Compute a = 2^k */
2557 +
2558 +mp_err mp_2expt(mp_int *a, mp_digit k)
2559 +{
2560 + ARGCHK(a != NULL, MP_BADARG);
2561 +
2562 + return s_mp_2expt(a, k);
2563 +
2564 +} /* end mp_2expt() */
2565 +
2566 +/* }}} */
2567 +
2568 +/* {{{ mp_mod(a, m, c) */
2569 +
2570 +/*
2571 + mp_mod(a, m, c)
2572 +
2573 + Compute c = a (mod m). Result will always be 0 <= c < m.
2574 + */
2575 +
2576 +mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
2577 +{
2578 + mp_err res;
2579 + int mag;
2580 +
2581 + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
2582 +
2583 + if(SIGN(m) == NEG)
2584 + return MP_RANGE;
2585 +
2586 + /*
2587 + If |a| > m, we need to divide to get the remainder and take the
2588 + absolute value.
2589 +
2590 + If |a| < m, we don't need to do any division, just copy and adjust
2591 + the sign (if a is negative).
2592 +
2593 + If |a| == m, we can simply set the result to zero.
2594 +
2595 + This order is intended to minimize the average path length of the
2596 + comparison chain on common workloads -- the most frequent cases are
2597 + that |a| != m, so we do those first.
2598 + */
2599 + if((mag = s_mp_cmp(a, m)) > 0) {
2600 + if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
2601 + return res;
2602 +
2603 + if(SIGN(c) == NEG) {
2604 + if((res = mp_add(c, m, c)) != MP_OKAY)
2605 + return res;
2606 + }
2607 +
2608 + } else if(mag < 0) {
2609 + if((res = mp_copy(a, c)) != MP_OKAY)
2610 + return res;
2611 +
2612 + if(mp_cmp_z(a) < 0) {
2613 + if((res = mp_add(c, m, c)) != MP_OKAY)
2614 + return res;
2615 +
2616 + }
2617 +
2618 + } else {
2619 + mp_zero(c);
2620 +
2621 + }
2622 +
2623 + return MP_OKAY;
2624 +
2625 +} /* end mp_mod() */
2626 +
2627 +/* }}} */
2628 +
2629 +/* {{{ mp_mod_d(a, d, c) */
2630 +
2631 +/*
2632 + mp_mod_d(a, d, c)
2633 +
2634 + Compute c = a (mod d). Result will always be 0 <= c < d
2635 + */
2636 +mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c)
2637 +{
2638 + mp_err res;
2639 + mp_digit rem;
2640 +
2641 + ARGCHK(a != NULL && c != NULL, MP_BADARG);
2642 +
2643 + if(s_mp_cmp_d(a, d) > 0) {
2644 + if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
2645 + return res;
2646 +
2647 + } else {
2648 + if(SIGN(a) == NEG)
2649 + rem = d - DIGIT(a, 0);
2650 + else
2651 + rem = DIGIT(a, 0);
2652 + }
2653 +
2654 + if(c)
2655 + *c = rem;
2656 +
2657 + return MP_OKAY;
2658 +
2659 +} /* end mp_mod_d() */
2660 +
2661 +/* }}} */
2662 +
2663 +/* {{{ mp_sqrt(a, b) */
2664 +
2665 +/*
2666 + mp_sqrt(a, b)
2667 +
2668 + Compute the integer square root of a, and store the result in b.
2669 + Uses an integer-arithmetic version of Newton's iterative linear
2670 + approximation technique to determine this value; the result has the
2671 + following two properties:
2672 +
2673 + b^2 <= a
2674 + (b+1)^2 >= a
2675 +
2676 + It is a range error to pass a negative value.
2677 + */
2678 +mp_err mp_sqrt(const mp_int *a, mp_int *b)
2679 +{
2680 + mp_int x, t;
2681 + mp_err res;
2682 + mp_size used;
2683 +
2684 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
2685 +
2686 + /* Cannot take square root of a negative value */
2687 + if(SIGN(a) == NEG)
2688 + return MP_RANGE;
2689 +
2690 + /* Special cases for zero and one, trivial */
2691 + if(mp_cmp_d(a, 1) <= 0)
2692 + return mp_copy(a, b);
2693 +
2694 + /* Initialize the temporaries we'll use below */
2695 + if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
2696 + return res;
2697 +
2698 + /* Compute an initial guess for the iteration as a itself */
2699 + if((res = mp_init_copy(&x, a)) != MP_OKAY)
2700 + goto X;
2701 +
2702 + used = MP_USED(&x);
2703 + if (used > 1) {
2704 + s_mp_rshd(&x, used / 2);
2705 + }
2706 +
2707 + for(;;) {
2708 + /* t = (x * x) - a */
2709 + mp_copy(&x, &t); /* can't fail, t is big enough for original x */
2710 + if((res = mp_sqr(&t, &t)) != MP_OKAY ||
2711 + (res = mp_sub(&t, a, &t)) != MP_OKAY)
2712 + goto CLEANUP;
2713 +
2714 + /* t = t / 2x */
2715 + s_mp_mul_2(&x);
2716 + if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
2717 + goto CLEANUP;
2718 + s_mp_div_2(&x);
2719 +
2720 + /* Terminate the loop, if the quotient is zero */
2721 + if(mp_cmp_z(&t) == MP_EQ)
2722 + break;
2723 +
2724 + /* x = x - t */
2725 + if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
2726 + goto CLEANUP;
2727 +
2728 + }
2729 +
2730 + /* Copy result to output parameter */
2731 + mp_sub_d(&x, 1, &x);
2732 + s_mp_exch(&x, b);
2733 +
2734 + CLEANUP:
2735 + mp_clear(&x);
2736 + X:
2737 + mp_clear(&t);
2738 +
2739 + return res;
2740 +
2741 +} /* end mp_sqrt() */
2742 +
2743 +/* }}} */
2744 +
2745 +/* }}} */
2746 +
2747 +/*------------------------------------------------------------------------*/
2748 +/* {{{ Modular arithmetic */
2749 +
2750 +#if MP_MODARITH
2751 +/* {{{ mp_addmod(a, b, m, c) */
2752 +
2753 +/*
2754 + mp_addmod(a, b, m, c)
2755 +
2756 + Compute c = (a + b) mod m
2757 + */
2758 +
2759 +mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
2760 +{
2761 + mp_err res;
2762 +
2763 + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
2764 +
2765 + if((res = mp_add(a, b, c)) != MP_OKAY)
2766 + return res;
2767 + if((res = mp_mod(c, m, c)) != MP_OKAY)
2768 + return res;
2769 +
2770 + return MP_OKAY;
2771 +
2772 +}
2773 +
2774 +/* }}} */
2775 +
2776 +/* {{{ mp_submod(a, b, m, c) */
2777 +
2778 +/*
2779 + mp_submod(a, b, m, c)
2780 +
2781 + Compute c = (a - b) mod m
2782 + */
2783 +
2784 +mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
2785 +{
2786 + mp_err res;
2787 +
2788 + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
2789 +
2790 + if((res = mp_sub(a, b, c)) != MP_OKAY)
2791 + return res;
2792 + if((res = mp_mod(c, m, c)) != MP_OKAY)
2793 + return res;
2794 +
2795 + return MP_OKAY;
2796 +
2797 +}
2798 +
2799 +/* }}} */
2800 +
2801 +/* {{{ mp_mulmod(a, b, m, c) */
2802 +
2803 +/*
2804 + mp_mulmod(a, b, m, c)
2805 +
2806 + Compute c = (a * b) mod m
2807 + */
2808 +
2809 +mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
2810 +{
2811 + mp_err res;
2812 +
2813 + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
2814 +
2815 + if((res = mp_mul(a, b, c)) != MP_OKAY)
2816 + return res;
2817 + if((res = mp_mod(c, m, c)) != MP_OKAY)
2818 + return res;
2819 +
2820 + return MP_OKAY;
2821 +
2822 +}
2823 +
2824 +/* }}} */
2825 +
2826 +/* {{{ mp_sqrmod(a, m, c) */
2827 +
2828 +#if MP_SQUARE
2829 +mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c)
2830 +{
2831 + mp_err res;
2832 +
2833 + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
2834 +
2835 + if((res = mp_sqr(a, c)) != MP_OKAY)
2836 + return res;
2837 + if((res = mp_mod(c, m, c)) != MP_OKAY)
2838 + return res;
2839 +
2840 + return MP_OKAY;
2841 +
2842 +} /* end mp_sqrmod() */
2843 +#endif
2844 +
2845 +/* }}} */
2846 +
2847 +/* {{{ s_mp_exptmod(a, b, m, c) */
2848 +
2849 +/*
2850 + s_mp_exptmod(a, b, m, c)
2851 +
2852 + Compute c = (a ** b) mod m. Uses a standard square-and-multiply
2853 + method with modular reductions at each step. (This is basically the
2854 + same code as mp_expt(), except for the addition of the reductions)
2855 +
2856 + The modular reductions are done using Barrett's algorithm (see
2857 + s_mp_reduce() below for details)
2858 + */
2859 +
2860 +mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int * c)
2861 +{
2862 + mp_int s, x, mu;
2863 + mp_err res;
2864 + mp_digit d;
2865 + int dig, bit;
2866 +
2867 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
2868 +
2869 + if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
2870 + return MP_RANGE;
2871 +
2872 + if((res = mp_init(&s)) != MP_OKAY)
2873 + return res;
2874 + if((res = mp_init_copy(&x, a)) != MP_OKAY ||
2875 + (res = mp_mod(&x, m, &x)) != MP_OKAY)
2876 + goto X;
2877 + if((res = mp_init(&mu)) != MP_OKAY)
2878 + goto MU;
2879 +
2880 + mp_set(&s, 1);
2881 +
2882 + /* mu = b^2k / m */
2883 + s_mp_add_d(&mu, 1);
2884 + s_mp_lshd(&mu, 2 * USED(m));
2885 + if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
2886 + goto CLEANUP;
2887 +
2888 + /* Loop over digits of b in ascending order, except highest order */
2889 + for(dig = 0; dig < (USED(b) - 1); dig++) {
2890 + d = DIGIT(b, dig);
2891 +
2892 + /* Loop over the bits of the lower-order digits */
2893 + for(bit = 0; bit < DIGIT_BIT; bit++) {
2894 + if(d & 1) {
2895 + if((res = s_mp_mul(&s, &x)) != MP_OKAY)
2896 + goto CLEANUP;
2897 + if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
2898 + goto CLEANUP;
2899 + }
2900 +
2901 + d >>= 1;
2902 +
2903 + if((res = s_mp_sqr(&x)) != MP_OKAY)
2904 + goto CLEANUP;
2905 + if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
2906 + goto CLEANUP;
2907 + }
2908 + }
2909 +
2910 + /* Now do the last digit... */
2911 + d = DIGIT(b, dig);
2912 +
2913 + while(d) {
2914 + if(d & 1) {
2915 + if((res = s_mp_mul(&s, &x)) != MP_OKAY)
2916 + goto CLEANUP;
2917 + if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
2918 + goto CLEANUP;
2919 + }
2920 +
2921 + d >>= 1;
2922 +
2923 + if((res = s_mp_sqr(&x)) != MP_OKAY)
2924 + goto CLEANUP;
2925 + if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
2926 + goto CLEANUP;
2927 + }
2928 +
2929 + s_mp_exch(&s, c);
2930 +
2931 + CLEANUP:
2932 + mp_clear(&mu);
2933 + MU:
2934 + mp_clear(&x);
2935 + X:
2936 + mp_clear(&s);
2937 +
2938 + return res;
2939 +
2940 +} /* end s_mp_exptmod() */
2941 +
2942 +/* }}} */
2943 +
2944 +/* {{{ mp_exptmod_d(a, d, m, c) */
2945 +
2946 +mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c)
2947 +{
2948 + mp_int s, x;
2949 + mp_err res;
2950 +
2951 + ARGCHK(a != NULL && c != NULL, MP_BADARG);
2952 +
2953 + if((res = mp_init(&s)) != MP_OKAY)
2954 + return res;
2955 + if((res = mp_init_copy(&x, a)) != MP_OKAY)
2956 + goto X;
2957 +
2958 + mp_set(&s, 1);
2959 +
2960 + while(d != 0) {
2961 + if(d & 1) {
2962 + if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
2963 + (res = mp_mod(&s, m, &s)) != MP_OKAY)
2964 + goto CLEANUP;
2965 + }
2966 +
2967 + d /= 2;
2968 +
2969 + if((res = s_mp_sqr(&x)) != MP_OKAY ||
2970 + (res = mp_mod(&x, m, &x)) != MP_OKAY)
2971 + goto CLEANUP;
2972 + }
2973 +
2974 + s_mp_exch(&s, c);
2975 +
2976 +CLEANUP:
2977 + mp_clear(&x);
2978 +X:
2979 + mp_clear(&s);
2980 +
2981 + return res;
2982 +
2983 +} /* end mp_exptmod_d() */
2984 +
2985 +/* }}} */
2986 +#endif /* if MP_MODARITH */
2987 +
2988 +/* }}} */
2989 +
2990 +/*------------------------------------------------------------------------*/
2991 +/* {{{ Comparison functions */
2992 +
2993 +/* {{{ mp_cmp_z(a) */
2994 +
2995 +/*
2996 + mp_cmp_z(a)
2997 +
2998 + Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0.
2999 + */
3000 +
3001 +int mp_cmp_z(const mp_int *a)
3002 +{
3003 + if(SIGN(a) == NEG)
3004 + return MP_LT;
3005 + else if(USED(a) == 1 && DIGIT(a, 0) == 0)
3006 + return MP_EQ;
3007 + else
3008 + return MP_GT;
3009 +
3010 +} /* end mp_cmp_z() */
3011 +
3012 +/* }}} */
3013 +
3014 +/* {{{ mp_cmp_d(a, d) */
3015 +
3016 +/*
3017 + mp_cmp_d(a, d)
3018 +
3019 + Compare a <=> d. Returns <0 if a<d, 0 if a=d, >0 if a>d
3020 + */
3021 +
3022 +int mp_cmp_d(const mp_int *a, mp_digit d)
3023 +{
3024 + ARGCHK(a != NULL, MP_EQ);
3025 +
3026 + if(SIGN(a) == NEG)
3027 + return MP_LT;
3028 +
3029 + return s_mp_cmp_d(a, d);
3030 +
3031 +} /* end mp_cmp_d() */
3032 +
3033 +/* }}} */
3034 +
3035 +/* {{{ mp_cmp(a, b) */
3036 +
3037 +int mp_cmp(const mp_int *a, const mp_int *b)
3038 +{
3039 + ARGCHK(a != NULL && b != NULL, MP_EQ);
3040 +
3041 + if(SIGN(a) == SIGN(b)) {
3042 + int mag;
3043 +
3044 + if((mag = s_mp_cmp(a, b)) == MP_EQ)
3045 + return MP_EQ;
3046 +
3047 + if(SIGN(a) == ZPOS)
3048 + return mag;
3049 + else
3050 + return -mag;
3051 +
3052 + } else if(SIGN(a) == ZPOS) {
3053 + return MP_GT;
3054 + } else {
3055 + return MP_LT;
3056 + }
3057 +
3058 +} /* end mp_cmp() */
3059 +
3060 +/* }}} */
3061 +
3062 +/* {{{ mp_cmp_mag(a, b) */
3063 +
3064 +/*
3065 + mp_cmp_mag(a, b)
3066 +
3067 + Compares |a| <=> |b|, and returns an appropriate comparison result
3068 + */
3069 +
3070 +int mp_cmp_mag(mp_int *a, mp_int *b)
3071 +{
3072 + ARGCHK(a != NULL && b != NULL, MP_EQ);
3073 +
3074 + return s_mp_cmp(a, b);
3075 +
3076 +} /* end mp_cmp_mag() */
3077 +
3078 +/* }}} */
3079 +
3080 +/* {{{ mp_cmp_int(a, z) */
3081 +
3082 +/*
3083 + This just converts z to an mp_int, and uses the existing comparison
3084 + routines. This is sort of inefficient, but it's not clear to me how
3085 + frequently this wil get used anyway. For small positive constants,
3086 + you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
3087 + */
3088 +int mp_cmp_int(const mp_int *a, long z)
3089 +{
3090 + mp_int tmp;
3091 + int out;
3092 +
3093 + ARGCHK(a != NULL, MP_EQ);
3094 +
3095 + mp_init(&tmp); mp_set_int(&tmp, z);
3096 + out = mp_cmp(a, &tmp);
3097 + mp_clear(&tmp);
3098 +
3099 + return out;
3100 +
3101 +} /* end mp_cmp_int() */
3102 +
3103 +/* }}} */
3104 +
3105 +/* {{{ mp_isodd(a) */
3106 +
3107 +/*
3108 + mp_isodd(a)
3109 +
3110 + Returns a true (non-zero) value if a is odd, false (zero) otherwise.
3111 + */
3112 +int mp_isodd(const mp_int *a)
3113 +{
3114 + ARGCHK(a != NULL, 0);
3115 +
3116 + return (int)(DIGIT(a, 0) & 1);
3117 +
3118 +} /* end mp_isodd() */
3119 +
3120 +/* }}} */
3121 +
3122 +/* {{{ mp_iseven(a) */
3123 +
3124 +int mp_iseven(const mp_int *a)
3125 +{
3126 + return !mp_isodd(a);
3127 +
3128 +} /* end mp_iseven() */
3129 +
3130 +/* }}} */
3131 +
3132 +/* }}} */
3133 +
3134 +/*------------------------------------------------------------------------*/
3135 +/* {{{ Number theoretic functions */
3136 +
3137 +#if MP_NUMTH
3138 +/* {{{ mp_gcd(a, b, c) */
3139 +
3140 +/*
3141 + Like the old mp_gcd() function, except computes the GCD using the
3142 + binary algorithm due to Josef Stein in 1961 (via Knuth).
3143 + */
3144 +mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
3145 +{
3146 + mp_err res;
3147 + mp_int u, v, t;
3148 + mp_size k = 0;
3149 +
3150 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
3151 +
3152 + if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
3153 + return MP_RANGE;
3154 + if(mp_cmp_z(a) == MP_EQ) {
3155 + return mp_copy(b, c);
3156 + } else if(mp_cmp_z(b) == MP_EQ) {
3157 + return mp_copy(a, c);
3158 + }
3159 +
3160 + if((res = mp_init(&t)) != MP_OKAY)
3161 + return res;
3162 + if((res = mp_init_copy(&u, a)) != MP_OKAY)
3163 + goto U;
3164 + if((res = mp_init_copy(&v, b)) != MP_OKAY)
3165 + goto V;
3166 +
3167 + SIGN(&u) = ZPOS;
3168 + SIGN(&v) = ZPOS;
3169 +
3170 + /* Divide out common factors of 2 until at least 1 of a, b is even */
3171 + while(mp_iseven(&u) && mp_iseven(&v)) {
3172 + s_mp_div_2(&u);
3173 + s_mp_div_2(&v);
3174 + ++k;
3175 + }
3176 +
3177 + /* Initialize t */
3178 + if(mp_isodd(&u)) {
3179 + if((res = mp_copy(&v, &t)) != MP_OKAY)
3180 + goto CLEANUP;
3181 +
3182 + /* t = -v */
3183 + if(SIGN(&v) == ZPOS)
3184 + SIGN(&t) = NEG;
3185 + else
3186 + SIGN(&t) = ZPOS;
3187 +
3188 + } else {
3189 + if((res = mp_copy(&u, &t)) != MP_OKAY)
3190 + goto CLEANUP;
3191 +
3192 + }
3193 +
3194 + for(;;) {
3195 + while(mp_iseven(&t)) {
3196 + s_mp_div_2(&t);
3197 + }
3198 +
3199 + if(mp_cmp_z(&t) == MP_GT) {
3200 + if((res = mp_copy(&t, &u)) != MP_OKAY)
3201 + goto CLEANUP;
3202 +
3203 + } else {
3204 + if((res = mp_copy(&t, &v)) != MP_OKAY)
3205 + goto CLEANUP;
3206 +
3207 + /* v = -t */
3208 + if(SIGN(&t) == ZPOS)
3209 + SIGN(&v) = NEG;
3210 + else
3211 + SIGN(&v) = ZPOS;
3212 + }
3213 +
3214 + if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
3215 + goto CLEANUP;
3216 +
3217 + if(s_mp_cmp_d(&t, 0) == MP_EQ)
3218 + break;
3219 + }
3220 +
3221 + s_mp_2expt(&v, k); /* v = 2^k */
3222 + res = mp_mul(&u, &v, c); /* c = u * v */
3223 +
3224 + CLEANUP:
3225 + mp_clear(&v);
3226 + V:
3227 + mp_clear(&u);
3228 + U:
3229 + mp_clear(&t);
3230 +
3231 + return res;
3232 +
3233 +} /* end mp_gcd() */
3234 +
3235 +/* }}} */
3236 +
3237 +/* {{{ mp_lcm(a, b, c) */
3238 +
3239 +/* We compute the least common multiple using the rule:
3240 +
3241 + ab = [a, b](a, b)
3242 +
3243 + ... by computing the product, and dividing out the gcd.
3244 + */
3245 +
3246 +mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
3247 +{
3248 + mp_int gcd, prod;
3249 + mp_err res;
3250 +
3251 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
3252 +
3253 + /* Set up temporaries */
3254 + if((res = mp_init(&gcd)) != MP_OKAY)
3255 + return res;
3256 + if((res = mp_init(&prod)) != MP_OKAY)
3257 + goto GCD;
3258 +
3259 + if((res = mp_mul(a, b, &prod)) != MP_OKAY)
3260 + goto CLEANUP;
3261 + if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
3262 + goto CLEANUP;
3263 +
3264 + res = mp_div(&prod, &gcd, c, NULL);
3265 +
3266 + CLEANUP:
3267 + mp_clear(&prod);
3268 + GCD:
3269 + mp_clear(&gcd);
3270 +
3271 + return res;
3272 +
3273 +} /* end mp_lcm() */
3274 +
3275 +/* }}} */
3276 +
3277 +/* {{{ mp_xgcd(a, b, g, x, y) */
3278 +
3279 +/*
3280 + mp_xgcd(a, b, g, x, y)
3281 +
3282 + Compute g = (a, b) and values x and y satisfying Bezout's identity
3283 + (that is, ax + by = g). This uses the binary extended GCD algorithm
3284 + based on the Stein algorithm used for mp_gcd()
3285 + See algorithm 14.61 in Handbook of Applied Cryptogrpahy.
3286 + */
3287 +
3288 +mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int * y)
3289 +{
3290 + mp_int gx, xc, yc, u, v, A, B, C, D;
3291 + mp_int *clean[9];
3292 + mp_err res;
3293 + int last = -1;
3294 +
3295 + if(mp_cmp_z(b) == 0)
3296 + return MP_RANGE;
3297 +
3298 + /* Initialize all these variables we need */
3299 + MP_CHECKOK( mp_init(&u) );
3300 + clean[++last] = &u;
3301 + MP_CHECKOK( mp_init(&v) );
3302 + clean[++last] = &v;
3303 + MP_CHECKOK( mp_init(&gx) );
3304 + clean[++last] = &gx;
3305 + MP_CHECKOK( mp_init(&A) );
3306 + clean[++last] = &A;
3307 + MP_CHECKOK( mp_init(&B) );
3308 + clean[++last] = &B;
3309 + MP_CHECKOK( mp_init(&C) );
3310 + clean[++last] = &C;
3311 + MP_CHECKOK( mp_init(&D) );
3312 + clean[++last] = &D;
3313 + MP_CHECKOK( mp_init_copy(&xc, a) );
3314 + clean[++last] = &xc;
3315 + mp_abs(&xc, &xc);
3316 + MP_CHECKOK( mp_init_copy(&yc, b) );
3317 + clean[++last] = &yc;
3318 + mp_abs(&yc, &yc);
3319 +
3320 + mp_set(&gx, 1);
3321 +
3322 + /* Divide by two until at least one of them is odd */
3323 + while(mp_iseven(&xc) && mp_iseven(&yc)) {
3324 + mp_size nx = mp_trailing_zeros(&xc);
3325 + mp_size ny = mp_trailing_zeros(&yc);
3326 + mp_size n = MP_MIN(nx, ny);
3327 + s_mp_div_2d(&xc,n);
3328 + s_mp_div_2d(&yc,n);
3329 + MP_CHECKOK( s_mp_mul_2d(&gx,n) );
3330 + }
3331 +
3332 + mp_copy(&xc, &u);
3333 + mp_copy(&yc, &v);
3334 + mp_set(&A, 1); mp_set(&D, 1);
3335 +
3336 + /* Loop through binary GCD algorithm */
3337 + do {
3338 + while(mp_iseven(&u)) {
3339 + s_mp_div_2(&u);
3340 +
3341 + if(mp_iseven(&A) && mp_iseven(&B)) {
3342 + s_mp_div_2(&A); s_mp_div_2(&B);
3343 + } else {
3344 + MP_CHECKOK( mp_add(&A, &yc, &A) );
3345 + s_mp_div_2(&A);
3346 + MP_CHECKOK( mp_sub(&B, &xc, &B) );
3347 + s_mp_div_2(&B);
3348 + }
3349 + }
3350 +
3351 + while(mp_iseven(&v)) {
3352 + s_mp_div_2(&v);
3353 +
3354 + if(mp_iseven(&C) && mp_iseven(&D)) {
3355 + s_mp_div_2(&C); s_mp_div_2(&D);
3356 + } else {
3357 + MP_CHECKOK( mp_add(&C, &yc, &C) );
3358 + s_mp_div_2(&C);
3359 + MP_CHECKOK( mp_sub(&D, &xc, &D) );
3360 + s_mp_div_2(&D);
3361 + }
3362 + }
3363 +
3364 + if(mp_cmp(&u, &v) >= 0) {
3365 + MP_CHECKOK( mp_sub(&u, &v, &u) );
3366 + MP_CHECKOK( mp_sub(&A, &C, &A) );
3367 + MP_CHECKOK( mp_sub(&B, &D, &B) );
3368 + } else {
3369 + MP_CHECKOK( mp_sub(&v, &u, &v) );
3370 + MP_CHECKOK( mp_sub(&C, &A, &C) );
3371 + MP_CHECKOK( mp_sub(&D, &B, &D) );
3372 + }
3373 + } while (mp_cmp_z(&u) != 0);
3374 +
3375 + /* copy results to output */
3376 + if(x)
3377 + MP_CHECKOK( mp_copy(&C, x) );
3378 +
3379 + if(y)
3380 + MP_CHECKOK( mp_copy(&D, y) );
3381 +
3382 + if(g)
3383 + MP_CHECKOK( mp_mul(&gx, &v, g) );
3384 +
3385 + CLEANUP:
3386 + while(last >= 0)
3387 + mp_clear(clean[last--]);
3388 +
3389 + return res;
3390 +
3391 +} /* end mp_xgcd() */
3392 +
3393 +/* }}} */
3394 +
3395 +mp_size mp_trailing_zeros(const mp_int *mp)
3396 +{
3397 + mp_digit d;
3398 + mp_size n = 0;
3399 + int ix;
3400 +
3401 + if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
3402 + return n;
3403 +
3404 + for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix)
3405 + n += MP_DIGIT_BIT;
3406 + if (!d)
3407 + return 0; /* shouldn't happen, but ... */
3408 +#if !defined(MP_USE_UINT_DIGIT)
3409 + if (!(d & 0xffffffffU)) {
3410 + d >>= 32;
3411 + n += 32;
3412 + }
3413 +#endif
3414 + if (!(d & 0xffffU)) {
3415 + d >>= 16;
3416 + n += 16;
3417 + }
3418 + if (!(d & 0xffU)) {
3419 + d >>= 8;
3420 + n += 8;
3421 + }
3422 + if (!(d & 0xfU)) {
3423 + d >>= 4;
3424 + n += 4;
3425 + }
3426 + if (!(d & 0x3U)) {
3427 + d >>= 2;
3428 + n += 2;
3429 + }
3430 + if (!(d & 0x1U)) {
3431 + d >>= 1;
3432 + n += 1;
3433 + }
3434 +#if MP_ARGCHK == 2
3435 + assert(0 != (d & 1));
3436 +#endif
3437 + return n;
3438 +}
3439 +
3440 +/* Given a and prime p, computes c and k such that a*c == 2**k (mod p).
3441 +** Returns k (positive) or error (negative).
3442 +** This technique from the paper "Fast Modular Reciprocals" (unpublished)
3443 +** by Richard Schroeppel (a.k.a. Captain Nemo).
3444 +*/
3445 +mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
3446 +{
3447 + mp_err res;
3448 + mp_err k = 0;
3449 + mp_int d, f, g;
3450 +
3451 + ARGCHK(a && p && c, MP_BADARG);
3452 +
3453 + MP_DIGITS(&d) = 0;
3454 + MP_DIGITS(&f) = 0;
3455 + MP_DIGITS(&g) = 0;
3456 + MP_CHECKOK( mp_init(&d) );
3457 + MP_CHECKOK( mp_init_copy(&f, a) ); /* f = a */
3458 + MP_CHECKOK( mp_init_copy(&g, p) ); /* g = p */
3459 +
3460 + mp_set(c, 1);
3461 + mp_zero(&d);
3462 +
3463 + if (mp_cmp_z(&f) == 0) {
3464 + res = MP_UNDEF;
3465 + } else
3466 + for (;;) {
3467 + int diff_sign;
3468 + while (mp_iseven(&f)) {
3469 + mp_size n = mp_trailing_zeros(&f);
3470 + if (!n) {
3471 + res = MP_UNDEF;
3472 + goto CLEANUP;
3473 + }
3474 + s_mp_div_2d(&f, n);
3475 + MP_CHECKOK( s_mp_mul_2d(&d, n) );
3476 + k += n;
3477 + }
3478 + if (mp_cmp_d(&f, 1) == MP_EQ) { /* f == 1 */
3479 + res = k;
3480 + break;
3481 + }
3482 + diff_sign = mp_cmp(&f, &g);
3483 + if (diff_sign < 0) { /* f < g */
3484 + s_mp_exch(&f, &g);
3485 + s_mp_exch(c, &d);
3486 + } else if (diff_sign == 0) { /* f == g */
3487 + res = MP_UNDEF; /* a and p are not relatively prime */
3488 + break;
3489 + }
3490 + if ((MP_DIGIT(&f,0) % 4) == (MP_DIGIT(&g,0) % 4)) {
3491 + MP_CHECKOK( mp_sub(&f, &g, &f) ); /* f = f - g */
3492 + MP_CHECKOK( mp_sub(c, &d, c) ); /* c = c - d */
3493 + } else {
3494 + MP_CHECKOK( mp_add(&f, &g, &f) ); /* f = f + g */
3495 + MP_CHECKOK( mp_add(c, &d, c) ); /* c = c + d */
3496 + }
3497 + }
3498 + if (res >= 0) {
3499 + while (MP_SIGN(c) != MP_ZPOS) {
3500 + MP_CHECKOK( mp_add(c, p, c) );
3501 + }
3502 + res = k;
3503 + }
3504 +
3505 +CLEANUP:
3506 + mp_clear(&d);
3507 + mp_clear(&f);
3508 + mp_clear(&g);
3509 + return res;
3510 +}
3511 +
3512 +/* Compute T = (P ** -1) mod MP_RADIX. Also works for 16-bit mp_digits.
3513 +** This technique from the paper "Fast Modular Reciprocals" (unpublished)
3514 +** by Richard Schroeppel (a.k.a. Captain Nemo).
3515 +*/
3516 +mp_digit s_mp_invmod_radix(mp_digit P)
3517 +{
3518 + mp_digit T = P;
3519 + T *= 2 - (P * T);
3520 + T *= 2 - (P * T);
3521 + T *= 2 - (P * T);
3522 + T *= 2 - (P * T);
3523 +#if !defined(MP_USE_UINT_DIGIT)
3524 + T *= 2 - (P * T);
3525 + T *= 2 - (P * T);
3526 +#endif
3527 + return T;
3528 +}
3529 +
3530 +/* Given c, k, and prime p, where a*c == 2**k (mod p),
3531 +** Compute x = (a ** -1) mod p. This is similar to Montgomery reduction.
3532 +** This technique from the paper "Fast Modular Reciprocals" (unpublished)
3533 +** by Richard Schroeppel (a.k.a. Captain Nemo).
3534 +*/
3535 +mp_err s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int * x)
3536 +{
3537 + int k_orig = k;
3538 + mp_digit r;
3539 + mp_size ix;
3540 + mp_err res;
3541 +
3542 + if (mp_cmp_z(c) < 0) { /* c < 0 */
3543 + MP_CHECKOK( mp_add(c, p, x) ); /* x = c + p */
3544 + } else {
3545 + MP_CHECKOK( mp_copy(c, x) ); /* x = c */
3546 + }
3547 +
3548 + /* make sure x is large enough */
3549 + ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1;
3550 + ix = MP_MAX(ix, MP_USED(x));
3551 + MP_CHECKOK( s_mp_pad(x, ix) );
3552 +
3553 + r = 0 - s_mp_invmod_radix(MP_DIGIT(p,0));
3554 +
3555 + for (ix = 0; k > 0; ix++) {
3556 + int j = MP_MIN(k, MP_DIGIT_BIT);
3557 + mp_digit v = r * MP_DIGIT(x, ix);
3558 + if (j < MP_DIGIT_BIT) {
3559 + v &= ((mp_digit)1 << j) - 1; /* v = v mod (2 ** j) */
3560 + }
3561 + s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */
3562 + k -= j;
3563 + }
3564 + s_mp_clamp(x);
3565 + s_mp_div_2d(x, k_orig);
3566 + res = MP_OKAY;
3567 +
3568 +CLEANUP:
3569 + return res;
3570 +}
3571 +
3572 +/* compute mod inverse using Schroeppel's method, only if m is odd */
3573 +mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)
3574 +{
3575 + int k;
3576 + mp_err res;
3577 + mp_int x;
3578 +
3579 + ARGCHK(a && m && c, MP_BADARG);
3580 +
3581 + if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
3582 + return MP_RANGE;
3583 + if (mp_iseven(m))
3584 + return MP_UNDEF;
3585 +
3586 + MP_DIGITS(&x) = 0;
3587 +
3588 + if (a == c) {
3589 + if ((res = mp_init_copy(&x, a)) != MP_OKAY)
3590 + return res;
3591 + if (a == m)
3592 + m = &x;
3593 + a = &x;
3594 + } else if (m == c) {
3595 + if ((res = mp_init_copy(&x, m)) != MP_OKAY)
3596 + return res;
3597 + m = &x;
3598 + } else {
3599 + MP_DIGITS(&x) = 0;
3600 + }
3601 +
3602 + MP_CHECKOK( s_mp_almost_inverse(a, m, c) );
3603 + k = res;
3604 + MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );
3605 +CLEANUP:
3606 + mp_clear(&x);
3607 + return res;
3608 +}
3609 +
3610 +/* Known good algorithm for computing modular inverse. But slow. */
3611 +mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
3612 +{
3613 + mp_int g, x;
3614 + mp_err res;
3615 +
3616 + ARGCHK(a && m && c, MP_BADARG);
3617 +
3618 + if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
3619 + return MP_RANGE;
3620 +
3621 + MP_DIGITS(&g) = 0;
3622 + MP_DIGITS(&x) = 0;
3623 + MP_CHECKOK( mp_init(&x) );
3624 + MP_CHECKOK( mp_init(&g) );
3625 +
3626 + MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) );
3627 +
3628 + if (mp_cmp_d(&g, 1) != MP_EQ) {
3629 + res = MP_UNDEF;
3630 + goto CLEANUP;
3631 + }
3632 +
3633 + res = mp_mod(&x, m, c);
3634 + SIGN(c) = SIGN(a);
3635 +
3636 +CLEANUP:
3637 + mp_clear(&x);
3638 + mp_clear(&g);
3639 +
3640 + return res;
3641 +}
3642 +
3643 +/* modular inverse where modulus is 2**k. */
3644 +/* c = a**-1 mod 2**k */
3645 +mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c)
3646 +{
3647 + mp_err res;
3648 + mp_size ix = k + 4;
3649 + mp_int t0, t1, val, tmp, two2k;
3650 +
3651 + static const mp_digit d2 = 2;
3652 + static const mp_int two = { MP_ZPOS, 1, 1, (mp_digit *)&d2 };
3653 +
3654 + if (mp_iseven(a))
3655 + return MP_UNDEF;
3656 + if (k <= MP_DIGIT_BIT) {
3657 + mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0));
3658 + if (k < MP_DIGIT_BIT)
3659 + i &= ((mp_digit)1 << k) - (mp_digit)1;
3660 + mp_set(c, i);
3661 + return MP_OKAY;
3662 + }
3663 + MP_DIGITS(&t0) = 0;
3664 + MP_DIGITS(&t1) = 0;
3665 + MP_DIGITS(&val) = 0;
3666 + MP_DIGITS(&tmp) = 0;
3667 + MP_DIGITS(&two2k) = 0;
3668 + MP_CHECKOK( mp_init_copy(&val, a) );
3669 + s_mp_mod_2d(&val, k);
3670 + MP_CHECKOK( mp_init_copy(&t0, &val) );
3671 + MP_CHECKOK( mp_init_copy(&t1, &t0) );
3672 + MP_CHECKOK( mp_init(&tmp) );
3673 + MP_CHECKOK( mp_init(&two2k) );
3674 + MP_CHECKOK( s_mp_2expt(&two2k, k) );
3675 + do {
3676 + MP_CHECKOK( mp_mul(&val, &t1, &tmp) );
3677 + MP_CHECKOK( mp_sub(&two, &tmp, &tmp) );
3678 + MP_CHECKOK( mp_mul(&t1, &tmp, &t1) );
3679 + s_mp_mod_2d(&t1, k);
3680 + while (MP_SIGN(&t1) != MP_ZPOS) {
3681 + MP_CHECKOK( mp_add(&t1, &two2k, &t1) );
3682 + }
3683 + if (mp_cmp(&t1, &t0) == MP_EQ)
3684 + break;
3685 + MP_CHECKOK( mp_copy(&t1, &t0) );
3686 + } while (--ix > 0);
3687 + if (!ix) {
3688 + res = MP_UNDEF;
3689 + } else {
3690 + mp_exch(c, &t1);
3691 + }
3692 +
3693 +CLEANUP:
3694 + mp_clear(&t0);
3695 + mp_clear(&t1);
3696 + mp_clear(&val);
3697 + mp_clear(&tmp);
3698 + mp_clear(&two2k);
3699 + return res;
3700 +}
3701 +
3702 +mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)
3703 +{
3704 + mp_err res;
3705 + mp_size k;
3706 + mp_int oddFactor, evenFactor; /* factors of the modulus */
3707 + mp_int oddPart, evenPart; /* parts to combine via CRT. */
3708 + mp_int C2, tmp1, tmp2;
3709 +
3710 + /*static const mp_digit d1 = 1; */
3711 + /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */
3712 +
3713 + if ((res = s_mp_ispow2(m)) >= 0) {
3714 + k = res;
3715 + return s_mp_invmod_2d(a, k, c);
3716 + }
3717 + MP_DIGITS(&oddFactor) = 0;
3718 + MP_DIGITS(&evenFactor) = 0;
3719 + MP_DIGITS(&oddPart) = 0;
3720 + MP_DIGITS(&evenPart) = 0;
3721 + MP_DIGITS(&C2) = 0;
3722 + MP_DIGITS(&tmp1) = 0;
3723 + MP_DIGITS(&tmp2) = 0;
3724 +
3725 + MP_CHECKOK( mp_init_copy(&oddFactor, m) ); /* oddFactor = m */
3726 + MP_CHECKOK( mp_init(&evenFactor) );
3727 + MP_CHECKOK( mp_init(&oddPart) );
3728 + MP_CHECKOK( mp_init(&evenPart) );
3729 + MP_CHECKOK( mp_init(&C2) );
3730 + MP_CHECKOK( mp_init(&tmp1) );
3731 + MP_CHECKOK( mp_init(&tmp2) );
3732 +
3733 + k = mp_trailing_zeros(m);
3734 + s_mp_div_2d(&oddFactor, k);
3735 + MP_CHECKOK( s_mp_2expt(&evenFactor, k) );
3736 +
3737 + /* compute a**-1 mod oddFactor. */
3738 + MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) );
3739 + /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */
3740 + MP_CHECKOK( s_mp_invmod_2d( a, k, &evenPart) );
3741 +
3742 + /* Use Chinese Remainer theorem to compute a**-1 mod m. */
3743 + /* let m1 = oddFactor, v1 = oddPart,
3744 + * let m2 = evenFactor, v2 = evenPart.
3745 + */
3746 +
3747 + /* Compute C2 = m1**-1 mod m2. */
3748 + MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k, &C2) );
3749 +
3750 + /* compute u = (v2 - v1)*C2 mod m2 */
3751 + MP_CHECKOK( mp_sub(&evenPart, &oddPart, &tmp1) );
3752 + MP_CHECKOK( mp_mul(&tmp1, &C2, &tmp2) );
3753 + s_mp_mod_2d(&tmp2, k);
3754 + while (MP_SIGN(&tmp2) != MP_ZPOS) {
3755 + MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) );
3756 + }
3757 +
3758 + /* compute answer = v1 + u*m1 */
3759 + MP_CHECKOK( mp_mul(&tmp2, &oddFactor, c) );
3760 + MP_CHECKOK( mp_add(&oddPart, c, c) );
3761 + /* not sure this is necessary, but it's low cost if not. */
3762 + MP_CHECKOK( mp_mod(c, m, c) );
3763 +
3764 +CLEANUP:
3765 + mp_clear(&oddFactor);
3766 + mp_clear(&evenFactor);
3767 + mp_clear(&oddPart);
3768 + mp_clear(&evenPart);
3769 + mp_clear(&C2);
3770 + mp_clear(&tmp1);
3771 + mp_clear(&tmp2);
3772 + return res;
3773 +}
3774 +
3775 +
3776 +/* {{{ mp_invmod(a, m, c) */
3777 +
3778 +/*
3779 + mp_invmod(a, m, c)
3780 +
3781 + Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
3782 + This is equivalent to the question of whether (a, m) = 1. If not,
3783 + MP_UNDEF is returned, and there is no inverse.
3784 + */
3785 +
3786 +mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
3787 +{
3788 +
3789 + ARGCHK(a && m && c, MP_BADARG);
3790 +
3791 + if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
3792 + return MP_RANGE;
3793 +
3794 + if (mp_isodd(m)) {
3795 + return s_mp_invmod_odd_m(a, m, c);
3796 + }
3797 + if (mp_iseven(a))
3798 + return MP_UNDEF; /* not invertable */
3799 +
3800 + return s_mp_invmod_even_m(a, m, c);
3801 +
3802 +} /* end mp_invmod() */
3803 +
3804 +/* }}} */
3805 +#endif /* if MP_NUMTH */
3806 +
3807 +/* }}} */
3808 +
3809 +/*------------------------------------------------------------------------*/
3810 +/* {{{ mp_print(mp, ofp) */
3811 +
3812 +#if MP_IOFUNC
3813 +/*
3814 + mp_print(mp, ofp)
3815 +
3816 + Print a textual representation of the given mp_int on the output
3817 + stream 'ofp'. Output is generated using the internal radix.
3818 + */
3819 +
3820 +void mp_print(mp_int *mp, FILE *ofp)
3821 +{
3822 + int ix;
3823 +
3824 + if(mp == NULL || ofp == NULL)
3825 + return;
3826 +
3827 + fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);
3828 +
3829 + for(ix = USED(mp) - 1; ix >= 0; ix--) {
3830 + fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
3831 + }
3832 +
3833 +} /* end mp_print() */
3834 +
3835 +#endif /* if MP_IOFUNC */
3836 +
3837 +/* }}} */
3838 +
3839 +/*------------------------------------------------------------------------*/
3840 +/* {{{ More I/O Functions */
3841 +
3842 +/* {{{ mp_read_raw(mp, str, len) */
3843 +
3844 +/*
3845 + mp_read_raw(mp, str, len)
3846 +
3847 + Read in a raw value (base 256) into the given mp_int
3848 + */
3849 +
3850 +mp_err mp_read_raw(mp_int *mp, char *str, int len)
3851 +{
3852 + int ix;
3853 + mp_err res;
3854 + unsigned char *ustr = (unsigned char *)str;
3855 +
3856 + ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
3857 +
3858 + mp_zero(mp);
3859 +
3860 + /* Get sign from first byte */
3861 + if(ustr[0])
3862 + SIGN(mp) = NEG;
3863 + else
3864 + SIGN(mp) = ZPOS;
3865 +
3866 + /* Read the rest of the digits */
3867 + for(ix = 1; ix < len; ix++) {
3868 + if((res = mp_mul_d(mp, 256, mp)) != MP_OKAY)
3869 + return res;
3870 + if((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY)
3871 + return res;
3872 + }
3873 +
3874 + return MP_OKAY;
3875 +
3876 +} /* end mp_read_raw() */
3877 +
3878 +/* }}} */
3879 +
3880 +/* {{{ mp_raw_size(mp) */
3881 +
3882 +int mp_raw_size(mp_int *mp)
3883 +{
3884 + ARGCHK(mp != NULL, 0);
3885 +
3886 + return (USED(mp) * sizeof(mp_digit)) + 1;
3887 +
3888 +} /* end mp_raw_size() */
3889 +
3890 +/* }}} */
3891 +
3892 +/* {{{ mp_toraw(mp, str) */
3893 +
3894 +mp_err mp_toraw(mp_int *mp, char *str)
3895 +{
3896 + int ix, jx, pos = 1;
3897 +
3898 + ARGCHK(mp != NULL && str != NULL, MP_BADARG);
3899 +
3900 + str[0] = (char)SIGN(mp);
3901 +
3902 + /* Iterate over each digit... */
3903 + for(ix = USED(mp) - 1; ix >= 0; ix--) {
3904 + mp_digit d = DIGIT(mp, ix);
3905 +
3906 + /* Unpack digit bytes, high order first */
3907 + for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
3908 + str[pos++] = (char)(d >> (jx * CHAR_BIT));
3909 + }
3910 + }
3911 +
3912 + return MP_OKAY;
3913 +
3914 +} /* end mp_toraw() */
3915 +
3916 +/* }}} */
3917 +
3918 +/* {{{ mp_read_radix(mp, str, radix) */
3919 +
3920 +/*
3921 + mp_read_radix(mp, str, radix)
3922 +
3923 + Read an integer from the given string, and set mp to the resulting
3924 + value. The input is presumed to be in base 10. Leading non-digit
3925 + characters are ignored, and the function reads until a non-digit
3926 + character or the end of the string.
3927 + */
3928 +
3929 +mp_err mp_read_radix(mp_int *mp, const char *str, int radix)
3930 +{
3931 + int ix = 0, val = 0;
3932 + mp_err res;
3933 + mp_sign sig = ZPOS;
3934 +
3935 + ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
3936 + MP_BADARG);
3937 +
3938 + mp_zero(mp);
3939 +
3940 + /* Skip leading non-digit characters until a digit or '-' or '+' */
3941 + while(str[ix] &&
3942 + (s_mp_tovalue(str[ix], radix) < 0) &&
3943 + str[ix] != '-' &&
3944 + str[ix] != '+') {
3945 + ++ix;
3946 + }
3947 +
3948 + if(str[ix] == '-') {
3949 + sig = NEG;
3950 + ++ix;
3951 + } else if(str[ix] == '+') {
3952 + sig = ZPOS; /* this is the default anyway... */
3953 + ++ix;
3954 + }
3955 +
3956 + while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
3957 + if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
3958 + return res;
3959 + if((res = s_mp_add_d(mp, val)) != MP_OKAY)
3960 + return res;
3961 + ++ix;
3962 + }
3963 +
3964 + if(s_mp_cmp_d(mp, 0) == MP_EQ)
3965 + SIGN(mp) = ZPOS;
3966 + else
3967 + SIGN(mp) = sig;
3968 +
3969 + return MP_OKAY;
3970 +
3971 +} /* end mp_read_radix() */
3972 +
3973 +mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix)
3974 +{
3975 + int radix = default_radix;
3976 + int cx;
3977 + mp_sign sig = ZPOS;
3978 + mp_err res;
3979 +
3980 + /* Skip leading non-digit characters until a digit or '-' or '+' */
3981 + while ((cx = *str) != 0 &&
3982 + (s_mp_tovalue(cx, radix) < 0) &&
3983 + cx != '-' &&
3984 + cx != '+') {
3985 + ++str;
3986 + }
3987 +
3988 + if (cx == '-') {
3989 + sig = NEG;
3990 + ++str;
3991 + } else if (cx == '+') {
3992 + sig = ZPOS; /* this is the default anyway... */
3993 + ++str;
3994 + }
3995 +
3996 + if (str[0] == '0') {
3997 + if ((str[1] | 0x20) == 'x') {
3998 + radix = 16;
3999 + str += 2;
4000 + } else {
4001 + radix = 8;
4002 + str++;
4003 + }
4004 + }
4005 + res = mp_read_radix(a, str, radix);
4006 + if (res == MP_OKAY) {
4007 + MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig;
4008 + }
4009 + return res;
4010 +}
4011 +
4012 +/* }}} */
4013 +
4014 +/* {{{ mp_radix_size(mp, radix) */
4015 +
4016 +int mp_radix_size(mp_int *mp, int radix)
4017 +{
4018 + int bits;
4019 +
4020 + if(!mp || radix < 2 || radix > MAX_RADIX)
4021 + return 0;
4022 +
4023 + bits = USED(mp) * DIGIT_BIT - 1;
4024 +
4025 + return s_mp_outlen(bits, radix);
4026 +
4027 +} /* end mp_radix_size() */
4028 +
4029 +/* }}} */
4030 +
4031 +/* {{{ mp_toradix(mp, str, radix) */
4032 +
4033 +mp_err mp_toradix(mp_int *mp, char *str, int radix)
4034 +{
4035 + int ix, pos = 0;
4036 +
4037 + ARGCHK(mp != NULL && str != NULL, MP_BADARG);
4038 + ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
4039 +
4040 + if(mp_cmp_z(mp) == MP_EQ) {
4041 + str[0] = '0';
4042 + str[1] = '\0';
4043 + } else {
4044 + mp_err res;
4045 + mp_int tmp;
4046 + mp_sign sgn;
4047 + mp_digit rem, rdx = (mp_digit)radix;
4048 + char ch;
4049 +
4050 + if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
4051 + return res;
4052 +
4053 + /* Save sign for later, and take absolute value */
4054 + sgn = SIGN(&tmp); SIGN(&tmp) = ZPOS;
4055 +
4056 + /* Generate output digits in reverse order */
4057 + while(mp_cmp_z(&tmp) != 0) {
4058 + if((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) {
4059 + mp_clear(&tmp);
4060 + return res;
4061 + }
4062 +
4063 + /* Generate digits, use capital letters */
4064 + ch = s_mp_todigit(rem, radix, 0);
4065 +
4066 + str[pos++] = ch;
4067 + }
4068 +
4069 + /* Add - sign if original value was negative */
4070 + if(sgn == NEG)
4071 + str[pos++] = '-';
4072 +
4073 + /* Add trailing NUL to end the string */
4074 + str[pos--] = '\0';
4075 +
4076 + /* Reverse the digits and sign indicator */
4077 + ix = 0;
4078 + while(ix < pos) {
4079 + char tmp = str[ix];
4080 +
4081 + str[ix] = str[pos];
4082 + str[pos] = tmp;
4083 + ++ix;
4084 + --pos;
4085 + }
4086 +
4087 + mp_clear(&tmp);
4088 + }
4089 +
4090 + return MP_OKAY;
4091 +
4092 +} /* end mp_toradix() */
4093 +
4094 +/* }}} */
4095 +
4096 +/* {{{ mp_tovalue(ch, r) */
4097 +
4098 +int mp_tovalue(char ch, int r)
4099 +{
4100 + return s_mp_tovalue(ch, r);
4101 +
4102 +} /* end mp_tovalue() */
4103 +
4104 +/* }}} */
4105 +
4106 +/* }}} */
4107 +
4108 +/* {{{ mp_strerror(ec) */
4109 +
4110 +/*
4111 + mp_strerror(ec)
4112 +
4113 + Return a string describing the meaning of error code 'ec'. The
4114 + string returned is allocated in static memory, so the caller should
4115 + not attempt to modify or free the memory associated with this
4116 + string.
4117 + */
4118 +const char *mp_strerror(mp_err ec)
4119 +{
4120 + int aec = (ec < 0) ? -ec : ec;
4121 +
4122 + /* Code values are negative, so the senses of these comparisons
4123 + are accurate */
4124 + if(ec < MP_LAST_CODE || ec > MP_OKAY) {
4125 + return mp_err_string[0]; /* unknown error code */
4126 + } else {
4127 + return mp_err_string[aec + 1];
4128 + }
4129 +
4130 +} /* end mp_strerror() */
4131 +
4132 +/* }}} */
4133 +
4134 +/*========================================================================*/
4135 +/*------------------------------------------------------------------------*/
4136 +/* Static function definitions (internal use only) */
4137 +
4138 +/* {{{ Memory management */
4139 +
4140 +/* {{{ s_mp_grow(mp, min) */
4141 +
4142 +/* Make sure there are at least 'min' digits allocated to mp */
4143 +mp_err s_mp_grow(mp_int *mp, mp_size min)
4144 +{
4145 + if(min > ALLOC(mp)) {
4146 + mp_digit *tmp;
4147 +
4148 + /* Set min to next nearest default precision block size */
4149 + min = MP_ROUNDUP(min, s_mp_defprec);
4150 +
4151 + if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL)
4152 + return MP_MEM;
4153 +
4154 + s_mp_copy(DIGITS(mp), tmp, USED(mp));
4155 +
4156 +#if MP_CRYPTO
4157 + s_mp_setz(DIGITS(mp), ALLOC(mp));
4158 +#endif
4159 + s_mp_free(DIGITS(mp));
4160 + DIGITS(mp) = tmp;
4161 + ALLOC(mp) = min;
4162 + }
4163 +
4164 + return MP_OKAY;
4165 +
4166 +} /* end s_mp_grow() */
4167 +
4168 +/* }}} */
4169 +
4170 +/* {{{ s_mp_pad(mp, min) */
4171 +
4172 +/* Make sure the used size of mp is at least 'min', growing if needed */
4173 +mp_err s_mp_pad(mp_int *mp, mp_size min)
4174 +{
4175 + if(min > USED(mp)) {
4176 + mp_err res;
4177 +
4178 + /* Make sure there is room to increase precision */
4179 + if (min > ALLOC(mp)) {
4180 + if ((res = s_mp_grow(mp, min)) != MP_OKAY)
4181 + return res;
4182 + } else {
4183 + s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp));
4184 + }
4185 +
4186 + /* Increase precision; should already be 0-filled */
4187 + USED(mp) = min;
4188 + }
4189 +
4190 + return MP_OKAY;
4191 +
4192 +} /* end s_mp_pad() */
4193 +
4194 +/* }}} */
4195 +
4196 +/* {{{ s_mp_setz(dp, count) */
4197 +
4198 +#if MP_MACRO == 0
4199 +/* Set 'count' digits pointed to by dp to be zeroes */
4200 +void s_mp_setz(mp_digit *dp, mp_size count)
4201 +{
4202 +#if MP_MEMSET == 0
4203 + int ix;
4204 +
4205 + for(ix = 0; ix < count; ix++)
4206 + dp[ix] = 0;
4207 +#else
4208 + memset(dp, 0, count * sizeof(mp_digit));
4209 +#endif
4210 +
4211 +} /* end s_mp_setz() */
4212 +#endif
4213 +
4214 +/* }}} */
4215 +
4216 +/* {{{ s_mp_copy(sp, dp, count) */
4217 +
4218 +#if MP_MACRO == 0
4219 +/* Copy 'count' digits from sp to dp */
4220 +void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count)
4221 +{
4222 +#if MP_MEMCPY == 0
4223 + int ix;
4224 +
4225 + for(ix = 0; ix < count; ix++)
4226 + dp[ix] = sp[ix];
4227 +#else
4228 + memcpy(dp, sp, count * sizeof(mp_digit));
4229 +#endif
4230 +
4231 +} /* end s_mp_copy() */
4232 +#endif
4233 +
4234 +/* }}} */
4235 +
4236 +/* {{{ s_mp_alloc(nb, ni) */
4237 +
4238 +#if MP_MACRO == 0
4239 +/* Allocate ni records of nb bytes each, and return a pointer to that */
4240 +void *s_mp_alloc(size_t nb, size_t ni)
4241 +{
4242 + ++mp_allocs;
4243 + return calloc(nb, ni);
4244 +
4245 +} /* end s_mp_alloc() */
4246 +#endif
4247 +
4248 +/* }}} */
4249 +
4250 +/* {{{ s_mp_free(ptr) */
4251 +
4252 +#if MP_MACRO == 0
4253 +/* Free the memory pointed to by ptr */
4254 +void s_mp_free(void *ptr)
4255 +{
4256 + if(ptr) {
4257 + ++mp_frees;
4258 + free(ptr);
4259 + }
4260 +} /* end s_mp_free() */
4261 +#endif
4262 +
4263 +/* }}} */
4264 +
4265 +/* {{{ s_mp_clamp(mp) */
4266 +
4267 +#if MP_MACRO == 0
4268 +/* Remove leading zeroes from the given value */
4269 +void s_mp_clamp(mp_int *mp)
4270 +{
4271 + mp_size used = MP_USED(mp);
4272 + while (used > 1 && DIGIT(mp, used - 1) == 0)
4273 + --used;
4274 + MP_USED(mp) = used;
4275 +} /* end s_mp_clamp() */
4276 +#endif
4277 +
4278 +/* }}} */
4279 +
4280 +/* {{{ s_mp_exch(a, b) */
4281 +
4282 +/* Exchange the data for a and b; (b, a) = (a, b) */
4283 +void s_mp_exch(mp_int *a, mp_int *b)
4284 +{
4285 + mp_int tmp;
4286 +
4287 + tmp = *a;
4288 + *a = *b;
4289 + *b = tmp;
4290 +
4291 +} /* end s_mp_exch() */
4292 +
4293 +/* }}} */
4294 +
4295 +/* }}} */
4296 +
4297 +/* {{{ Arithmetic helpers */
4298 +
4299 +/* {{{ s_mp_lshd(mp, p) */
4300 +
4301 +/*
4302 + Shift mp leftward by p digits, growing if needed, and zero-filling
4303 + the in-shifted digits at the right end. This is a convenient
4304 + alternative to multiplication by powers of the radix
4305 + The value of USED(mp) must already have been set to the value for
4306 + the shifted result.
4307 + */
4308 +
4309 +mp_err s_mp_lshd(mp_int *mp, mp_size p)
4310 +{
4311 + mp_err res;
4312 + mp_size pos;
4313 + int ix;
4314 +
4315 + if(p == 0)
4316 + return MP_OKAY;
4317 +
4318 + if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0)
4319 + return MP_OKAY;
4320 +
4321 + if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
4322 + return res;
4323 +
4324 + pos = USED(mp) - 1;
4325 +
4326 + /* Shift all the significant figures over as needed */
4327 + for(ix = pos - p; ix >= 0; ix--)
4328 + DIGIT(mp, ix + p) = DIGIT(mp, ix);
4329 +
4330 + /* Fill the bottom digits with zeroes */
4331 + for(ix = 0; ix < p; ix++)
4332 + DIGIT(mp, ix) = 0;
4333 +
4334 + return MP_OKAY;
4335 +
4336 +} /* end s_mp_lshd() */
4337 +
4338 +/* }}} */
4339 +
4340 +/* {{{ s_mp_mul_2d(mp, d) */
4341 +
4342 +/*
4343 + Multiply the integer by 2^d, where d is a number of bits. This
4344 + amounts to a bitwise shift of the value.
4345 + */
4346 +mp_err s_mp_mul_2d(mp_int *mp, mp_digit d)
4347 +{
4348 + mp_err res;
4349 + mp_digit dshift, bshift;
4350 + mp_digit mask;
4351 +
4352 + ARGCHK(mp != NULL, MP_BADARG);
4353 +
4354 + dshift = d / MP_DIGIT_BIT;
4355 + bshift = d % MP_DIGIT_BIT;
4356 + /* bits to be shifted out of the top word */
4357 + mask = ((mp_digit)~0 << (MP_DIGIT_BIT - bshift));
4358 + mask &= MP_DIGIT(mp, MP_USED(mp) - 1);
4359 +
4360 + if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) )))
4361 + return res;
4362 +
4363 + if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift)))
4364 + return res;
4365 +
4366 + if (bshift) {
4367 + mp_digit *pa = MP_DIGITS(mp);
4368 + mp_digit *alim = pa + MP_USED(mp);
4369 + mp_digit prev = 0;
4370 +
4371 + for (pa += dshift; pa < alim; ) {
4372 + mp_digit x = *pa;
4373 + *pa++ = (x << bshift) | prev;
4374 + prev = x >> (DIGIT_BIT - bshift);
4375 + }
4376 + }
4377 +
4378 + s_mp_clamp(mp);
4379 + return MP_OKAY;
4380 +} /* end s_mp_mul_2d() */
4381 +
4382 +/* {{{ s_mp_rshd(mp, p) */
4383 +
4384 +/*
4385 + Shift mp rightward by p digits. Maintains the invariant that
4386 + digits above the precision are all zero. Digits shifted off the
4387 + end are lost. Cannot fail.
4388 + */
4389 +
4390 +void s_mp_rshd(mp_int *mp, mp_size p)
4391 +{
4392 + mp_size ix;
4393 + mp_digit *src, *dst;
4394 +
4395 + if(p == 0)
4396 + return;
4397 +
4398 + /* Shortcut when all digits are to be shifted off */
4399 + if(p >= USED(mp)) {
4400 + s_mp_setz(DIGITS(mp), ALLOC(mp));
4401 + USED(mp) = 1;
4402 + SIGN(mp) = ZPOS;
4403 + return;
4404 + }
4405 +
4406 + /* Shift all the significant figures over as needed */
4407 + dst = MP_DIGITS(mp);
4408 + src = dst + p;
4409 + for (ix = USED(mp) - p; ix > 0; ix--)
4410 + *dst++ = *src++;
4411 +
4412 + MP_USED(mp) -= p;
4413 + /* Fill the top digits with zeroes */
4414 + while (p-- > 0)
4415 + *dst++ = 0;
4416 +
4417 +#if 0
4418 + /* Strip off any leading zeroes */
4419 + s_mp_clamp(mp);
4420 +#endif
4421 +
4422 +} /* end s_mp_rshd() */
4423 +
4424 +/* }}} */
4425 +
4426 +/* {{{ s_mp_div_2(mp) */
4427 +
4428 +/* Divide by two -- take advantage of radix properties to do it fast */
4429 +void s_mp_div_2(mp_int *mp)
4430 +{
4431 + s_mp_div_2d(mp, 1);
4432 +
4433 +} /* end s_mp_div_2() */
4434 +
4435 +/* }}} */
4436 +
4437 +/* {{{ s_mp_mul_2(mp) */
4438 +
4439 +mp_err s_mp_mul_2(mp_int *mp)
4440 +{
4441 + mp_digit *pd;
4442 + int ix, used;
4443 + mp_digit kin = 0;
4444 +
4445 + /* Shift digits leftward by 1 bit */
4446 + used = MP_USED(mp);
4447 + pd = MP_DIGITS(mp);
4448 + for (ix = 0; ix < used; ix++) {
4449 + mp_digit d = *pd;
4450 + *pd++ = (d << 1) | kin;
4451 + kin = (d >> (DIGIT_BIT - 1));
4452 + }
4453 +
4454 + /* Deal with rollover from last digit */
4455 + if (kin) {
4456 + if (ix >= ALLOC(mp)) {
4457 + mp_err res;
4458 + if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
4459 + return res;
4460 + }
4461 +
4462 + DIGIT(mp, ix) = kin;
4463 + USED(mp) += 1;
4464 + }
4465 +
4466 + return MP_OKAY;
4467 +
4468 +} /* end s_mp_mul_2() */
4469 +
4470 +/* }}} */
4471 +
4472 +/* {{{ s_mp_mod_2d(mp, d) */
4473 +
4474 +/*
4475 + Remainder the integer by 2^d, where d is a number of bits. This
4476 + amounts to a bitwise AND of the value, and does not require the full
4477 + division code
4478 + */
4479 +void s_mp_mod_2d(mp_int *mp, mp_digit d)
4480 +{
4481 + mp_size ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
4482 + mp_size ix;
4483 + mp_digit dmask;
4484 +
4485 + if(ndig >= USED(mp))
4486 + return;
4487 +
4488 + /* Flush all the bits above 2^d in its digit */
4489 + dmask = ((mp_digit)1 << nbit) - 1;
4490 + DIGIT(mp, ndig) &= dmask;
4491 +
4492 + /* Flush all digits above the one with 2^d in it */
4493 + for(ix = ndig + 1; ix < USED(mp); ix++)
4494 + DIGIT(mp, ix) = 0;
4495 +
4496 + s_mp_clamp(mp);
4497 +
4498 +} /* end s_mp_mod_2d() */
4499 +
4500 +/* }}} */
4501 +
4502 +/* {{{ s_mp_div_2d(mp, d) */
4503 +
4504 +/*
4505 + Divide the integer by 2^d, where d is a number of bits. This
4506 + amounts to a bitwise shift of the value, and does not require the
4507 + full division code (used in Barrett reduction, see below)
4508 + */
4509 +void s_mp_div_2d(mp_int *mp, mp_digit d)
4510 +{
4511 + int ix;
4512 + mp_digit save, next, mask;
4513 +
4514 + s_mp_rshd(mp, d / DIGIT_BIT);
4515 + d %= DIGIT_BIT;
4516 + if (d) {
4517 + mask = ((mp_digit)1 << d) - 1;
4518 + save = 0;
4519 + for(ix = USED(mp) - 1; ix >= 0; ix--) {
4520 + next = DIGIT(mp, ix) & mask;
4521 + DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d));
4522 + save = next;
4523 + }
4524 + }
4525 + s_mp_clamp(mp);
4526 +
4527 +} /* end s_mp_div_2d() */
4528 +
4529 +/* }}} */
4530 +
4531 +/* {{{ s_mp_norm(a, b, *d) */
4532 +
4533 +/*
4534 + s_mp_norm(a, b, *d)
4535 +
4536 + Normalize a and b for division, where b is the divisor. In order
4537 + that we might make good guesses for quotient digits, we want the
4538 + leading digit of b to be at least half the radix, which we
4539 + accomplish by multiplying a and b by a power of 2. The exponent
4540 + (shift count) is placed in *pd, so that the remainder can be shifted
4541 + back at the end of the division process.
4542 + */
4543 +
4544 +mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd)
4545 +{
4546 + mp_digit d;
4547 + mp_digit mask;
4548 + mp_digit b_msd;
4549 + mp_err res = MP_OKAY;
4550 +
4551 + d = 0;
4552 + mask = DIGIT_MAX & ~(DIGIT_MAX >> 1); /* mask is msb of digit */
4553 + b_msd = DIGIT(b, USED(b) - 1);
4554 + while (!(b_msd & mask)) {
4555 + b_msd <<= 1;
4556 + ++d;
4557 + }
4558 +
4559 + if (d) {
4560 + MP_CHECKOK( s_mp_mul_2d(a, d) );
4561 + MP_CHECKOK( s_mp_mul_2d(b, d) );
4562 + }
4563 +
4564 + *pd = d;
4565 +CLEANUP:
4566 + return res;
4567 +
4568 +} /* end s_mp_norm() */
4569 +
4570 +/* }}} */
4571 +
4572 +/* }}} */
4573 +
4574 +/* {{{ Primitive digit arithmetic */
4575 +
4576 +/* {{{ s_mp_add_d(mp, d) */
4577 +
4578 +/* Add d to |mp| in place */
4579 +mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */
4580 +{
4581 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
4582 + mp_word w, k = 0;
4583 + mp_size ix = 1;
4584 +
4585 + w = (mp_word)DIGIT(mp, 0) + d;
4586 + DIGIT(mp, 0) = ACCUM(w);
4587 + k = CARRYOUT(w);
4588 +
4589 + while(ix < USED(mp) && k) {
4590 + w = (mp_word)DIGIT(mp, ix) + k;
4591 + DIGIT(mp, ix) = ACCUM(w);
4592 + k = CARRYOUT(w);
4593 + ++ix;
4594 + }
4595 +
4596 + if(k != 0) {
4597 + mp_err res;
4598 +
4599 + if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
4600 + return res;
4601 +
4602 + DIGIT(mp, ix) = (mp_digit)k;
4603 + }
4604 +
4605 + return MP_OKAY;
4606 +#else
4607 + mp_digit * pmp = MP_DIGITS(mp);
4608 + mp_digit sum, mp_i, carry = 0;
4609 + mp_err res = MP_OKAY;
4610 + int used = (int)MP_USED(mp);
4611 +
4612 + mp_i = *pmp;
4613 + *pmp++ = sum = d + mp_i;
4614 + carry = (sum < d);
4615 + while (carry && --used > 0) {
4616 + mp_i = *pmp;
4617 + *pmp++ = sum = carry + mp_i;
4618 + carry = !sum;
4619 + }
4620 + if (carry && !used) {
4621 + /* mp is growing */
4622 + used = MP_USED(mp);
4623 + MP_CHECKOK( s_mp_pad(mp, used + 1) );
4624 + MP_DIGIT(mp, used) = carry;
4625 + }
4626 +CLEANUP:
4627 + return res;
4628 +#endif
4629 +} /* end s_mp_add_d() */
4630 +
4631 +/* }}} */
4632 +
4633 +/* {{{ s_mp_sub_d(mp, d) */
4634 +
4635 +/* Subtract d from |mp| in place, assumes |mp| > d */
4636 +mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */
4637 +{
4638 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
4639 + mp_word w, b = 0;
4640 + mp_size ix = 1;
4641 +
4642 + /* Compute initial subtraction */
4643 + w = (RADIX + (mp_word)DIGIT(mp, 0)) - d;
4644 + b = CARRYOUT(w) ? 0 : 1;
4645 + DIGIT(mp, 0) = ACCUM(w);
4646 +
4647 + /* Propagate borrows leftward */
4648 + while(b && ix < USED(mp)) {
4649 + w = (RADIX + (mp_word)DIGIT(mp, ix)) - b;
4650 + b = CARRYOUT(w) ? 0 : 1;
4651 + DIGIT(mp, ix) = ACCUM(w);
4652 + ++ix;
4653 + }
4654 +
4655 + /* Remove leading zeroes */
4656 + s_mp_clamp(mp);
4657 +
4658 + /* If we have a borrow out, it's a violation of the input invariant */
4659 + if(b)
4660 + return MP_RANGE;
4661 + else
4662 + return MP_OKAY;
4663 +#else
4664 + mp_digit *pmp = MP_DIGITS(mp);
4665 + mp_digit mp_i, diff, borrow;
4666 + mp_size used = MP_USED(mp);
4667 +
4668 + mp_i = *pmp;
4669 + *pmp++ = diff = mp_i - d;
4670 + borrow = (diff > mp_i);
4671 + while (borrow && --used) {
4672 + mp_i = *pmp;
4673 + *pmp++ = diff = mp_i - borrow;
4674 + borrow = (diff > mp_i);
4675 + }
4676 + s_mp_clamp(mp);
4677 + return (borrow && !used) ? MP_RANGE : MP_OKAY;
4678 +#endif
4679 +} /* end s_mp_sub_d() */
4680 +
4681 +/* }}} */
4682 +
4683 +/* {{{ s_mp_mul_d(a, d) */
4684 +
4685 +/* Compute a = a * d, single digit multiplication */
4686 +mp_err s_mp_mul_d(mp_int *a, mp_digit d)
4687 +{
4688 + mp_err res;
4689 + mp_size used;
4690 + int pow;
4691 +
4692 + if (!d) {
4693 + mp_zero(a);
4694 + return MP_OKAY;
4695 + }
4696 + if (d == 1)
4697 + return MP_OKAY;
4698 + if (0 <= (pow = s_mp_ispow2d(d))) {
4699 + return s_mp_mul_2d(a, (mp_digit)pow);
4700 + }
4701 +
4702 + used = MP_USED(a);
4703 + MP_CHECKOK( s_mp_pad(a, used + 1) );
4704 +
4705 + s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a));
4706 +
4707 + s_mp_clamp(a);
4708 +
4709 +CLEANUP:
4710 + return res;
4711 +
4712 +} /* end s_mp_mul_d() */
4713 +
4714 +/* }}} */
4715 +
4716 +/* {{{ s_mp_div_d(mp, d, r) */
4717 +
4718 +/*
4719 + s_mp_div_d(mp, d, r)
4720 +
4721 + Compute the quotient mp = mp / d and remainder r = mp mod d, for a
4722 + single digit d. If r is null, the remainder will be discarded.
4723 + */
4724 +
4725 +mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
4726 +{
4727 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
4728 + mp_word w = 0, q;
4729 +#else
4730 + mp_digit w, q;
4731 +#endif
4732 + int ix;
4733 + mp_err res;
4734 + mp_int quot;
4735 + mp_int rem;
4736 +
4737 + if(d == 0)
4738 + return MP_RANGE;
4739 + if (d == 1) {
4740 + if (r)
4741 + *r = 0;
4742 + return MP_OKAY;
4743 + }
4744 + /* could check for power of 2 here, but mp_div_d does that. */
4745 + if (MP_USED(mp) == 1) {
4746 + mp_digit n = MP_DIGIT(mp,0);
4747 + mp_digit rem;
4748 +
4749 + q = n / d;
4750 + rem = n % d;
4751 + MP_DIGIT(mp,0) = q;
4752 + if (r)
4753 + *r = rem;
4754 + return MP_OKAY;
4755 + }
4756 +
4757 + MP_DIGITS(&rem) = 0;
4758 + MP_DIGITS(&quot) = 0;
4759 + /* Make room for the quotient */
4760 + MP_CHECKOK( mp_init_size(&quot, USED(mp)) );
4761 +
4762 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
4763 + for(ix = USED(mp) - 1; ix >= 0; ix--) {
4764 + w = (w << DIGIT_BIT) | DIGIT(mp, ix);
4765 +
4766 + if(w >= d) {
4767 + q = w / d;
4768 + w = w % d;
4769 + } else {
4770 + q = 0;
4771 + }
4772 +
4773 + s_mp_lshd(&quot, 1);
4774 + DIGIT(&quot, 0) = (mp_digit)q;
4775 + }
4776 +#else
4777 + {
4778 + mp_digit p;
4779 +#if !defined(MP_ASSEMBLY_DIV_2DX1D)
4780 + mp_digit norm;
4781 +#endif
4782 +
4783 + MP_CHECKOK( mp_init_copy(&rem, mp) );
4784 +
4785 +#if !defined(MP_ASSEMBLY_DIV_2DX1D)
4786 + MP_DIGIT(&quot, 0) = d;
4787 + MP_CHECKOK( s_mp_norm(&rem, &quot, &norm) );
4788 + if (norm)
4789 + d <<= norm;
4790 + MP_DIGIT(&quot, 0) = 0;
4791 +#endif
4792 +
4793 + p = 0;
4794 + for (ix = USED(&rem) - 1; ix >= 0; ix--) {
4795 + w = DIGIT(&rem, ix);
4796 +
4797 + if (p) {
4798 + MP_CHECKOK( s_mpv_div_2dx1d(p, w, d, &q, &w) );
4799 + } else if (w >= d) {
4800 + q = w / d;
4801 + w = w % d;
4802 + } else {
4803 + q = 0;
4804 + }
4805 +
4806 + MP_CHECKOK( s_mp_lshd(&quot, 1) );
4807 + DIGIT(&quot, 0) = q;
4808 + p = w;
4809 + }
4810 +#if !defined(MP_ASSEMBLY_DIV_2DX1D)
4811 + if (norm)
4812 + w >>= norm;
4813 +#endif
4814 + }
4815 +#endif
4816 +
4817 + /* Deliver the remainder, if desired */
4818 + if(r)
4819 + *r = (mp_digit)w;
4820 +
4821 + s_mp_clamp(&quot);
4822 + mp_exch(&quot, mp);
4823 +CLEANUP:
4824 + mp_clear(&quot);
4825 + mp_clear(&rem);
4826 +
4827 + return res;
4828 +} /* end s_mp_div_d() */
4829 +
4830 +/* }}} */
4831 +
4832 +
4833 +/* }}} */
4834 +
4835 +/* {{{ Primitive full arithmetic */
4836 +
4837 +/* {{{ s_mp_add(a, b) */
4838 +
4839 +/* Compute a = |a| + |b| */
4840 +mp_err s_mp_add(mp_int *a, const mp_int *b) /* magnitude addition */
4841 +{
4842 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
4843 + mp_word w = 0;
4844 +#else
4845 + mp_digit d, sum, carry = 0;
4846 +#endif
4847 + mp_digit *pa, *pb;
4848 + mp_size ix;
4849 + mp_size used;
4850 + mp_err res;
4851 +
4852 + /* Make sure a has enough precision for the output value */
4853 + if((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY)
4854 + return res;
4855 +
4856 + /*
4857 + Add up all digits up to the precision of b. If b had initially
4858 + the same precision as a, or greater, we took care of it by the
4859 + padding step above, so there is no problem. If b had initially
4860 + less precision, we'll have to make sure the carry out is duly
4861 + propagated upward among the higher-order digits of the sum.
4862 + */
4863 + pa = MP_DIGITS(a);
4864 + pb = MP_DIGITS(b);
4865 + used = MP_USED(b);
4866 + for(ix = 0; ix < used; ix++) {
4867 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
4868 + w = w + *pa + *pb++;
4869 + *pa++ = ACCUM(w);
4870 + w = CARRYOUT(w);
4871 +#else
4872 + d = *pa;
4873 + sum = d + *pb++;
4874 + d = (sum < d); /* detect overflow */
4875 + *pa++ = sum += carry;
4876 + carry = d + (sum < carry); /* detect overflow */
4877 +#endif
4878 + }
4879 +
4880 + /* If we run out of 'b' digits before we're actually done, make
4881 + sure the carries get propagated upward...
4882 + */
4883 + used = MP_USED(a);
4884 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
4885 + while (w && ix < used) {
4886 + w = w + *pa;
4887 + *pa++ = ACCUM(w);
4888 + w = CARRYOUT(w);
4889 + ++ix;
4890 + }
4891 +#else
4892 + while (carry && ix < used) {
4893 + sum = carry + *pa;
4894 + *pa++ = sum;
4895 + carry = !sum;
4896 + ++ix;
4897 + }
4898 +#endif
4899 +
4900 + /* If there's an overall carry out, increase precision and include
4901 + it. We could have done this initially, but why touch the memory
4902 + allocator unless we're sure we have to?
4903 + */
4904 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
4905 + if (w) {
4906 + if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
4907 + return res;
4908 +
4909 + DIGIT(a, ix) = (mp_digit)w;
4910 + }
4911 +#else
4912 + if (carry) {
4913 + if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
4914 + return res;
4915 +
4916 + DIGIT(a, used) = carry;
4917 + }
4918 +#endif
4919 +
4920 + return MP_OKAY;
4921 +} /* end s_mp_add() */
4922 +
4923 +/* }}} */
4924 +
4925 +/* Compute c = |a| + |b| */ /* magnitude addition */
4926 +mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c)
4927 +{
4928 + mp_digit *pa, *pb, *pc;
4929 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
4930 + mp_word w = 0;
4931 +#else
4932 + mp_digit sum, carry = 0, d;
4933 +#endif
4934 + mp_size ix;
4935 + mp_size used;
4936 + mp_err res;
4937 +
4938 + MP_SIGN(c) = MP_SIGN(a);
4939 + if (MP_USED(a) < MP_USED(b)) {
4940 + const mp_int *xch = a;
4941 + a = b;
4942 + b = xch;
4943 + }
4944 +
4945 + /* Make sure a has enough precision for the output value */
4946 + if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
4947 + return res;
4948 +
4949 + /*
4950 + Add up all digits up to the precision of b. If b had initially
4951 + the same precision as a, or greater, we took care of it by the
4952 + exchange step above, so there is no problem. If b had initially
4953 + less precision, we'll have to make sure the carry out is duly
4954 + propagated upward among the higher-order digits of the sum.
4955 + */
4956 + pa = MP_DIGITS(a);
4957 + pb = MP_DIGITS(b);
4958 + pc = MP_DIGITS(c);
4959 + used = MP_USED(b);
4960 + for (ix = 0; ix < used; ix++) {
4961 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
4962 + w = w + *pa++ + *pb++;
4963 + *pc++ = ACCUM(w);
4964 + w = CARRYOUT(w);
4965 +#else
4966 + d = *pa++;
4967 + sum = d + *pb++;
4968 + d = (sum < d); /* detect overflow */
4969 + *pc++ = sum += carry;
4970 + carry = d + (sum < carry); /* detect overflow */
4971 +#endif
4972 + }
4973 +
4974 + /* If we run out of 'b' digits before we're actually done, make
4975 + sure the carries get propagated upward...
4976 + */
4977 + for (used = MP_USED(a); ix < used; ++ix) {
4978 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
4979 + w = w + *pa++;
4980 + *pc++ = ACCUM(w);
4981 + w = CARRYOUT(w);
4982 +#else
4983 + *pc++ = sum = carry + *pa++;
4984 + carry = (sum < carry);
4985 +#endif
4986 + }
4987 +
4988 + /* If there's an overall carry out, increase precision and include
4989 + it. We could have done this initially, but why touch the memory
4990 + allocator unless we're sure we have to?
4991 + */
4992 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
4993 + if (w) {
4994 + if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
4995 + return res;
4996 +
4997 + DIGIT(c, used) = (mp_digit)w;
4998 + ++used;
4999 + }
5000 +#else
5001 + if (carry) {
5002 + if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
5003 + return res;
5004 +
5005 + DIGIT(c, used) = carry;
5006 + ++used;
5007 + }
5008 +#endif
5009 + MP_USED(c) = used;
5010 + return MP_OKAY;
5011 +}
5012 +/* {{{ s_mp_add_offset(a, b, offset) */
5013 +
5014 +/* Compute a = |a| + ( |b| * (RADIX ** offset) ) */
5015 +mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset)
5016 +{
5017 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
5018 + mp_word w, k = 0;
5019 +#else
5020 + mp_digit d, sum, carry = 0;
5021 +#endif
5022 + mp_size ib;
5023 + mp_size ia;
5024 + mp_size lim;
5025 + mp_err res;
5026 +
5027 + /* Make sure a has enough precision for the output value */
5028 + lim = MP_USED(b) + offset;
5029 + if((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY)
5030 + return res;
5031 +
5032 + /*
5033 + Add up all digits up to the precision of b. If b had initially
5034 + the same precision as a, or greater, we took care of it by the
5035 + padding step above, so there is no problem. If b had initially
5036 + less precision, we'll have to make sure the carry out is duly
5037 + propagated upward among the higher-order digits of the sum.
5038 + */
5039 + lim = USED(b);
5040 + for(ib = 0, ia = offset; ib < lim; ib++, ia++) {
5041 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
5042 + w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k;
5043 + DIGIT(a, ia) = ACCUM(w);
5044 + k = CARRYOUT(w);
5045 +#else
5046 + d = MP_DIGIT(a, ia);
5047 + sum = d + MP_DIGIT(b, ib);
5048 + d = (sum < d);
5049 + MP_DIGIT(a,ia) = sum += carry;
5050 + carry = d + (sum < carry);
5051 +#endif
5052 + }
5053 +
5054 + /* If we run out of 'b' digits before we're actually done, make
5055 + sure the carries get propagated upward...
5056 + */
5057 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
5058 + for (lim = MP_USED(a); k && (ia < lim); ++ia) {
5059 + w = (mp_word)DIGIT(a, ia) + k;
5060 + DIGIT(a, ia) = ACCUM(w);
5061 + k = CARRYOUT(w);
5062 + }
5063 +#else
5064 + for (lim = MP_USED(a); carry && (ia < lim); ++ia) {
5065 + d = MP_DIGIT(a, ia);
5066 + MP_DIGIT(a,ia) = sum = d + carry;
5067 + carry = (sum < d);
5068 + }
5069 +#endif
5070 +
5071 + /* If there's an overall carry out, increase precision and include
5072 + it. We could have done this initially, but why touch the memory
5073 + allocator unless we're sure we have to?
5074 + */
5075 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
5076 + if(k) {
5077 + if((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY)
5078 + return res;
5079 +
5080 + DIGIT(a, ia) = (mp_digit)k;
5081 + }
5082 +#else
5083 + if (carry) {
5084 + if((res = s_mp_pad(a, lim + 1)) != MP_OKAY)
5085 + return res;
5086 +
5087 + DIGIT(a, lim) = carry;
5088 + }
5089 +#endif
5090 + s_mp_clamp(a);
5091 +
5092 + return MP_OKAY;
5093 +
5094 +} /* end s_mp_add_offset() */
5095 +
5096 +/* }}} */
5097 +
5098 +/* {{{ s_mp_sub(a, b) */
5099 +
5100 +/* Compute a = |a| - |b|, assumes |a| >= |b| */
5101 +mp_err s_mp_sub(mp_int *a, const mp_int *b) /* magnitude subtract */
5102 +{
5103 + mp_digit *pa, *pb, *limit;
5104 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
5105 + mp_sword w = 0;
5106 +#else
5107 + mp_digit d, diff, borrow = 0;
5108 +#endif
5109 +
5110 + /*
5111 + Subtract and propagate borrow. Up to the precision of b, this
5112 + accounts for the digits of b; after that, we just make sure the
5113 + carries get to the right place. This saves having to pad b out to
5114 + the precision of a just to make the loops work right...
5115 + */
5116 + pa = MP_DIGITS(a);
5117 + pb = MP_DIGITS(b);
5118 + limit = pb + MP_USED(b);
5119 + while (pb < limit) {
5120 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
5121 + w = w + *pa - *pb++;
5122 + *pa++ = ACCUM(w);
5123 + w >>= MP_DIGIT_BIT;
5124 +#else
5125 + d = *pa;
5126 + diff = d - *pb++;
5127 + d = (diff > d); /* detect borrow */
5128 + if (borrow && --diff == MP_DIGIT_MAX)
5129 + ++d;
5130 + *pa++ = diff;
5131 + borrow = d;
5132 +#endif
5133 + }
5134 + limit = MP_DIGITS(a) + MP_USED(a);
5135 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
5136 + while (w && pa < limit) {
5137 + w = w + *pa;
5138 + *pa++ = ACCUM(w);
5139 + w >>= MP_DIGIT_BIT;
5140 + }
5141 +#else
5142 + while (borrow && pa < limit) {
5143 + d = *pa;
5144 + *pa++ = diff = d - borrow;
5145 + borrow = (diff > d);
5146 + }
5147 +#endif
5148 +
5149 + /* Clobber any leading zeroes we created */
5150 + s_mp_clamp(a);
5151 +
5152 + /*
5153 + If there was a borrow out, then |b| > |a| in violation
5154 + of our input invariant. We've already done the work,
5155 + but we'll at least complain about it...
5156 + */
5157 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
5158 + return w ? MP_RANGE : MP_OKAY;
5159 +#else
5160 + return borrow ? MP_RANGE : MP_OKAY;
5161 +#endif
5162 +} /* end s_mp_sub() */
5163 +
5164 +/* }}} */
5165 +
5166 +/* Compute c = |a| - |b|, assumes |a| >= |b| */ /* magnitude subtract */
5167 +mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c)
5168 +{
5169 + mp_digit *pa, *pb, *pc;
5170 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
5171 + mp_sword w = 0;
5172 +#else
5173 + mp_digit d, diff, borrow = 0;
5174 +#endif
5175 + int ix, limit;
5176 + mp_err res;
5177 +
5178 + MP_SIGN(c) = MP_SIGN(a);
5179 +
5180 + /* Make sure a has enough precision for the output value */
5181 + if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
5182 + return res;
5183 +
5184 + /*
5185 + Subtract and propagate borrow. Up to the precision of b, this
5186 + accounts for the digits of b; after that, we just make sure the
5187 + carries get to the right place. This saves having to pad b out to
5188 + the precision of a just to make the loops work right...
5189 + */
5190 + pa = MP_DIGITS(a);
5191 + pb = MP_DIGITS(b);
5192 + pc = MP_DIGITS(c);
5193 + limit = MP_USED(b);
5194 + for (ix = 0; ix < limit; ++ix) {
5195 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
5196 + w = w + *pa++ - *pb++;
5197 + *pc++ = ACCUM(w);
5198 + w >>= MP_DIGIT_BIT;
5199 +#else
5200 + d = *pa++;
5201 + diff = d - *pb++;
5202 + d = (diff > d);
5203 + if (borrow && --diff == MP_DIGIT_MAX)
5204 + ++d;
5205 + *pc++ = diff;
5206 + borrow = d;
5207 +#endif
5208 + }
5209 + for (limit = MP_USED(a); ix < limit; ++ix) {
5210 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
5211 + w = w + *pa++;
5212 + *pc++ = ACCUM(w);
5213 + w >>= MP_DIGIT_BIT;
5214 +#else
5215 + d = *pa++;
5216 + *pc++ = diff = d - borrow;
5217 + borrow = (diff > d);
5218 +#endif
5219 + }
5220 +
5221 + /* Clobber any leading zeroes we created */
5222 + MP_USED(c) = ix;
5223 + s_mp_clamp(c);
5224 +
5225 + /*
5226 + If there was a borrow out, then |b| > |a| in violation
5227 + of our input invariant. We've already done the work,
5228 + but we'll at least complain about it...
5229 + */
5230 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
5231 + return w ? MP_RANGE : MP_OKAY;
5232 +#else
5233 + return borrow ? MP_RANGE : MP_OKAY;
5234 +#endif
5235 +}
5236 +/* {{{ s_mp_mul(a, b) */
5237 +
5238 +/* Compute a = |a| * |b| */
5239 +mp_err s_mp_mul(mp_int *a, const mp_int *b)
5240 +{
5241 + return mp_mul(a, b, a);
5242 +} /* end s_mp_mul() */
5243 +
5244 +/* }}} */
5245 +
5246 +#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
5247 +/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
5248 +#define MP_MUL_DxD(a, b, Phi, Plo) \
5249 + { unsigned long long product = (unsigned long long)a * b; \
5250 + Plo = (mp_digit)product; \
5251 + Phi = (mp_digit)(product >> MP_DIGIT_BIT); }
5252 +#elif defined(OSF1)
5253 +#define MP_MUL_DxD(a, b, Phi, Plo) \
5254 + { Plo = asm ("mulq %a0, %a1, %v0", a, b);\
5255 + Phi = asm ("umulh %a0, %a1, %v0", a, b); }
5256 +#else
5257 +#define MP_MUL_DxD(a, b, Phi, Plo) \
5258 + { mp_digit a0b1, a1b0; \
5259 + Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \
5260 + Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \
5261 + a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \
5262 + a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \
5263 + a1b0 += a0b1; \
5264 + Phi += a1b0 >> MP_HALF_DIGIT_BIT; \
5265 + if (a1b0 < a0b1) \
5266 + Phi += MP_HALF_RADIX; \
5267 + a1b0 <<= MP_HALF_DIGIT_BIT; \
5268 + Plo += a1b0; \
5269 + if (Plo < a1b0) \
5270 + ++Phi; \
5271 + }
5272 +#endif
5273 +
5274 +#if !defined(MP_ASSEMBLY_MULTIPLY)
5275 +/* c = a * b */
5276 +void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
5277 +{
5278 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
5279 + mp_digit d = 0;
5280 +
5281 + /* Inner product: Digits of a */
5282 + while (a_len--) {
5283 + mp_word w = ((mp_word)b * *a++) + d;
5284 + *c++ = ACCUM(w);
5285 + d = CARRYOUT(w);
5286 + }
5287 + *c = d;
5288 +#else
5289 + mp_digit carry = 0;
5290 + while (a_len--) {
5291 + mp_digit a_i = *a++;
5292 + mp_digit a0b0, a1b1;
5293 +
5294 + MP_MUL_DxD(a_i, b, a1b1, a0b0);
5295 +
5296 + a0b0 += carry;
5297 + if (a0b0 < carry)
5298 + ++a1b1;
5299 + *c++ = a0b0;
5300 + carry = a1b1;
5301 + }
5302 + *c = carry;
5303 +#endif
5304 +}
5305 +
5306 +/* c += a * b */
5307 +void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,
5308 + mp_digit *c)
5309 +{
5310 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
5311 + mp_digit d = 0;
5312 +
5313 + /* Inner product: Digits of a */
5314 + while (a_len--) {
5315 + mp_word w = ((mp_word)b * *a++) + *c + d;
5316 + *c++ = ACCUM(w);
5317 + d = CARRYOUT(w);
5318 + }
5319 + *c = d;
5320 +#else
5321 + mp_digit carry = 0;
5322 + while (a_len--) {
5323 + mp_digit a_i = *a++;
5324 + mp_digit a0b0, a1b1;
5325 +
5326 + MP_MUL_DxD(a_i, b, a1b1, a0b0);
5327 +
5328 + a0b0 += carry;
5329 + if (a0b0 < carry)
5330 + ++a1b1;
5331 + a0b0 += a_i = *c;
5332 + if (a0b0 < a_i)
5333 + ++a1b1;
5334 + *c++ = a0b0;
5335 + carry = a1b1;
5336 + }
5337 + *c = carry;
5338 +#endif
5339 +}
5340 +
5341 +/* Presently, this is only used by the Montgomery arithmetic code. */
5342 +/* c += a * b */
5343 +void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digi t *c)
5344 +{
5345 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
5346 + mp_digit d = 0;
5347 +
5348 + /* Inner product: Digits of a */
5349 + while (a_len--) {
5350 + mp_word w = ((mp_word)b * *a++) + *c + d;
5351 + *c++ = ACCUM(w);
5352 + d = CARRYOUT(w);
5353 + }
5354 +
5355 + while (d) {
5356 + mp_word w = (mp_word)*c + d;
5357 + *c++ = ACCUM(w);
5358 + d = CARRYOUT(w);
5359 + }
5360 +#else
5361 + mp_digit carry = 0;
5362 + while (a_len--) {
5363 + mp_digit a_i = *a++;
5364 + mp_digit a0b0, a1b1;
5365 +
5366 + MP_MUL_DxD(a_i, b, a1b1, a0b0);
5367 +
5368 + a0b0 += carry;
5369 + if (a0b0 < carry)
5370 + ++a1b1;
5371 +
5372 + a0b0 += a_i = *c;
5373 + if (a0b0 < a_i)
5374 + ++a1b1;
5375 +
5376 + *c++ = a0b0;
5377 + carry = a1b1;
5378 + }
5379 + while (carry) {
5380 + mp_digit c_i = *c;
5381 + carry += c_i;
5382 + *c++ = carry;
5383 + carry = carry < c_i;
5384 + }
5385 +#endif
5386 +}
5387 +#endif
5388 +
5389 +#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
5390 +/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
5391 +#define MP_SQR_D(a, Phi, Plo) \
5392 + { unsigned long long square = (unsigned long long)a * a; \
5393 + Plo = (mp_digit)square; \
5394 + Phi = (mp_digit)(square >> MP_DIGIT_BIT); }
5395 +#elif defined(OSF1)
5396 +#define MP_SQR_D(a, Phi, Plo) \
5397 + { Plo = asm ("mulq %a0, %a0, %v0", a);\
5398 + Phi = asm ("umulh %a0, %a0, %v0", a); }
5399 +#else
5400 +#define MP_SQR_D(a, Phi, Plo) \
5401 + { mp_digit Pmid; \
5402 + Plo = (a & MP_HALF_DIGIT_MAX) * (a & MP_HALF_DIGIT_MAX); \
5403 + Phi = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \
5404 + Pmid = (a & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \
5405 + Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1); \
5406 + Pmid <<= (MP_HALF_DIGIT_BIT + 1); \
5407 + Plo += Pmid; \
5408 + if (Plo < Pmid) \
5409 + ++Phi; \
5410 + }
5411 +#endif
5412 +
5413 +#if !defined(MP_ASSEMBLY_SQUARE)
5414 +/* Add the squares of the digits of a to the digits of b. */
5415 +void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
5416 +{
5417 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
5418 + mp_word w;
5419 + mp_digit d;
5420 + mp_size ix;
5421 +
5422 + w = 0;
5423 +#define ADD_SQUARE(n) \
5424 + d = pa[n]; \
5425 + w += (d * (mp_word)d) + ps[2*n]; \
5426 + ps[2*n] = ACCUM(w); \
5427 + w = (w >> DIGIT_BIT) + ps[2*n+1]; \
5428 + ps[2*n+1] = ACCUM(w); \
5429 + w = (w >> DIGIT_BIT)
5430 +
5431 + for (ix = a_len; ix >= 4; ix -= 4) {
5432 + ADD_SQUARE(0);
5433 + ADD_SQUARE(1);
5434 + ADD_SQUARE(2);
5435 + ADD_SQUARE(3);
5436 + pa += 4;
5437 + ps += 8;
5438 + }
5439 + if (ix) {
5440 + ps += 2*ix;
5441 + pa += ix;
5442 + switch (ix) {
5443 + case 3: ADD_SQUARE(-3); /* FALLTHRU */
5444 + case 2: ADD_SQUARE(-2); /* FALLTHRU */
5445 + case 1: ADD_SQUARE(-1); /* FALLTHRU */
5446 + case 0: break;
5447 + }
5448 + }
5449 + while (w) {
5450 + w += *ps;
5451 + *ps++ = ACCUM(w);
5452 + w = (w >> DIGIT_BIT);
5453 + }
5454 +#else
5455 + mp_digit carry = 0;
5456 + while (a_len--) {
5457 + mp_digit a_i = *pa++;
5458 + mp_digit a0a0, a1a1;
5459 +
5460 + MP_SQR_D(a_i, a1a1, a0a0);
5461 +
5462 + /* here a1a1 and a0a0 constitute a_i ** 2 */
5463 + a0a0 += carry;
5464 + if (a0a0 < carry)
5465 + ++a1a1;
5466 +
5467 + /* now add to ps */
5468 + a0a0 += a_i = *ps;
5469 + if (a0a0 < a_i)
5470 + ++a1a1;
5471 + *ps++ = a0a0;
5472 + a1a1 += a_i = *ps;
5473 + carry = (a1a1 < a_i);
5474 + *ps++ = a1a1;
5475 + }
5476 + while (carry) {
5477 + mp_digit s_i = *ps;
5478 + carry += s_i;
5479 + *ps++ = carry;
5480 + carry = carry < s_i;
5481 + }
5482 +#endif
5483 +}
5484 +#endif
5485 +
5486 +#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) \
5487 +&& !defined(MP_ASSEMBLY_DIV_2DX1D)
5488 +/*
5489 +** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
5490 +** so its high bit is 1. This code is from NSPR.
5491 +*/
5492 +mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
5493 + mp_digit *qp, mp_digit *rp)
5494 +{
5495 + mp_digit d1, d0, q1, q0;
5496 + mp_digit r1, r0, m;
5497 +
5498 + d1 = divisor >> MP_HALF_DIGIT_BIT;
5499 + d0 = divisor & MP_HALF_DIGIT_MAX;
5500 + r1 = Nhi % d1;
5501 + q1 = Nhi / d1;
5502 + m = q1 * d0;
5503 + r1 = (r1 << MP_HALF_DIGIT_BIT) | (Nlo >> MP_HALF_DIGIT_BIT);
5504 + if (r1 < m) {
5505 + q1--, r1 += divisor;
5506 + if (r1 >= divisor && r1 < m) {
5507 + q1--, r1 += divisor;
5508 + }
5509 + }
5510 + r1 -= m;
5511 + r0 = r1 % d1;
5512 + q0 = r1 / d1;
5513 + m = q0 * d0;
5514 + r0 = (r0 << MP_HALF_DIGIT_BIT) | (Nlo & MP_HALF_DIGIT_MAX);
5515 + if (r0 < m) {
5516 + q0--, r0 += divisor;
5517 + if (r0 >= divisor && r0 < m) {
5518 + q0--, r0 += divisor;
5519 + }
5520 + }
5521 + if (qp)
5522 + *qp = (q1 << MP_HALF_DIGIT_BIT) | q0;
5523 + if (rp)
5524 + *rp = r0 - m;
5525 + return MP_OKAY;
5526 +}
5527 +#endif
5528 +
5529 +#if MP_SQUARE
5530 +/* {{{ s_mp_sqr(a) */
5531 +
5532 +mp_err s_mp_sqr(mp_int *a)
5533 +{
5534 + mp_err res;
5535 + mp_int tmp;
5536 +
5537 + if((res = mp_init_size(&tmp, 2 * USED(a))) != MP_OKAY)
5538 + return res;
5539 + res = mp_sqr(a, &tmp);
5540 + if (res == MP_OKAY) {
5541 + s_mp_exch(&tmp, a);
5542 + }
5543 + mp_clear(&tmp);
5544 + return res;
5545 +}
5546 +
5547 +/* }}} */
5548 +#endif
5549 +
5550 +/* {{{ s_mp_div(a, b) */
5551 +
5552 +/*
5553 + s_mp_div(a, b)
5554 +
5555 + Compute a = a / b and b = a mod b. Assumes b > a.
5556 + */
5557 +
5558 +mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
5559 + mp_int *div, /* i: divisor */
5560 + mp_int *quot) /* i: 0; o: quotient */
5561 +{
5562 + mp_int part, t;
5563 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
5564 + mp_word q_msd;
5565 +#else
5566 + mp_digit q_msd;
5567 +#endif
5568 + mp_err res;
5569 + mp_digit d;
5570 + mp_digit div_msd;
5571 + int ix;
5572 +
5573 + if(mp_cmp_z(div) == 0)
5574 + return MP_RANGE;
5575 +
5576 + /* Shortcut if divisor is power of two */
5577 + if((ix = s_mp_ispow2(div)) >= 0) {
5578 + MP_CHECKOK( mp_copy(rem, quot) );
5579 + s_mp_div_2d(quot, (mp_digit)ix);
5580 + s_mp_mod_2d(rem, (mp_digit)ix);
5581 +
5582 + return MP_OKAY;
5583 + }
5584 +
5585 + DIGITS(&t) = 0;
5586 + MP_SIGN(rem) = ZPOS;
5587 + MP_SIGN(div) = ZPOS;
5588 +
5589 + /* A working temporary for division */
5590 + MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem)));
5591 +
5592 + /* Normalize to optimize guessing */
5593 + MP_CHECKOK( s_mp_norm(rem, div, &d) );
5594 +
5595 + part = *rem;
5596 +
5597 + /* Perform the division itself...woo! */
5598 + MP_USED(quot) = MP_ALLOC(quot);
5599 +
5600 + /* Find a partial substring of rem which is at least div */
5601 + /* If we didn't find one, we're finished dividing */
5602 + while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
5603 + int i;
5604 + int unusedRem;
5605 +
5606 + unusedRem = MP_USED(rem) - MP_USED(div);
5607 + MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
5608 + MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem;
5609 + MP_USED(&part) = MP_USED(div);
5610 + if (s_mp_cmp(&part, div) < 0) {
5611 + -- unusedRem;
5612 +#if MP_ARGCHK == 2
5613 + assert(unusedRem >= 0);
5614 +#endif
5615 + -- MP_DIGITS(&part);
5616 + ++ MP_USED(&part);
5617 + ++ MP_ALLOC(&part);
5618 + }
5619 +
5620 + /* Compute a guess for the next quotient digit */
5621 + q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
5622 + div_msd = MP_DIGIT(div, MP_USED(div) - 1);
5623 + if (q_msd >= div_msd) {
5624 + q_msd = 1;
5625 + } else if (MP_USED(&part) > 1) {
5626 +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
5627 + q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
5628 + q_msd /= div_msd;
5629 + if (q_msd == RADIX)
5630 + --q_msd;
5631 +#else
5632 + mp_digit r;
5633 + MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
5634 + div_msd, &q_msd, &r) );
5635 +#endif
5636 + } else {
5637 + q_msd = 0;
5638 + }
5639 +#if MP_ARGCHK == 2
5640 + assert(q_msd > 0); /* This case should never occur any more. */
5641 +#endif
5642 + if (q_msd <= 0)
5643 + break;
5644 +
5645 + /* See what that multiplies out to */
5646 + mp_copy(div, &t);
5647 + MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) );
5648 +
5649 + /*
5650 + If it's too big, back it off. We should not have to do this
5651 + more than once, or, in rare cases, twice. Knuth describes a
5652 + method by which this could be reduced to a maximum of once, but
5653 + I didn't implement that here.
5654 + * When using s_mpv_div_2dx1d, we may have to do this 3 times.
5655 + */
5656 + for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
5657 + --q_msd;
5658 + s_mp_sub(&t, div); /* t -= div */
5659 + }
5660 + if (i < 0) {
5661 + res = MP_RANGE;
5662 + goto CLEANUP;
5663 + }
5664 +
5665 + /* At this point, q_msd should be the right next digit */
5666 + MP_CHECKOK( s_mp_sub(&part, &t) ); /* part -= t */
5667 + s_mp_clamp(rem);
5668 +
5669 + /*
5670 + Include the digit in the quotient. We allocated enough memory
5671 + for any quotient we could ever possibly get, so we should not
5672 + have to check for failures here
5673 + */
5674 + MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd;
5675 + }
5676 +
5677 + /* Denormalize remainder */
5678 + if (d) {
5679 + s_mp_div_2d(rem, d);
5680 + }
5681 +
5682 + s_mp_clamp(quot);
5683 +
5684 +CLEANUP:
5685 + mp_clear(&t);
5686 +
5687 + return res;
5688 +
5689 +} /* end s_mp_div() */
5690 +
5691 +
5692 +/* }}} */
5693 +
5694 +/* {{{ s_mp_2expt(a, k) */
5695 +
5696 +mp_err s_mp_2expt(mp_int *a, mp_digit k)
5697 +{
5698 + mp_err res;
5699 + mp_size dig, bit;
5700 +
5701 + dig = k / DIGIT_BIT;
5702 + bit = k % DIGIT_BIT;
5703 +
5704 + mp_zero(a);
5705 + if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
5706 + return res;
5707 +
5708 + DIGIT(a, dig) |= ((mp_digit)1 << bit);
5709 +
5710 + return MP_OKAY;
5711 +
5712 +} /* end s_mp_2expt() */
5713 +
5714 +/* }}} */
5715 +
5716 +/* {{{ s_mp_reduce(x, m, mu) */
5717 +
5718 +/*
5719 + Compute Barrett reduction, x (mod m), given a precomputed value for
5720 + mu = b^2k / m, where b = RADIX and k = #digits(m). This should be
5721 + faster than straight division, when many reductions by the same
5722 + value of m are required (such as in modular exponentiation). This
5723 + can nearly halve the time required to do modular exponentiation,
5724 + as compared to using the full integer divide to reduce.
5725 +
5726 + This algorithm was derived from the _Handbook of Applied
5727 + Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
5728 + pp. 603-604.
5729 + */
5730 +
5731 +mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
5732 +{
5733 + mp_int q;
5734 + mp_err res;
5735 +
5736 + if((res = mp_init_copy(&q, x)) != MP_OKAY)
5737 + return res;
5738 +
5739 + s_mp_rshd(&q, USED(m) - 1); /* q1 = x / b^(k-1) */
5740 + s_mp_mul(&q, mu); /* q2 = q1 * mu */
5741 + s_mp_rshd(&q, USED(m) + 1); /* q3 = q2 / b^(k+1) */
5742 +
5743 + /* x = x mod b^(k+1), quick (no division) */
5744 + s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1));
5745 +
5746 + /* q = q * m mod b^(k+1), quick (no division) */
5747 + s_mp_mul(&q, m);
5748 + s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1));
5749 +
5750 + /* x = x - q */
5751 + if((res = mp_sub(x, &q, x)) != MP_OKAY)
5752 + goto CLEANUP;
5753 +
5754 + /* If x < 0, add b^(k+1) to it */
5755 + if(mp_cmp_z(x) < 0) {
5756 + mp_set(&q, 1);
5757 + if((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY)
5758 + goto CLEANUP;
5759 + if((res = mp_add(x, &q, x)) != MP_OKAY)
5760 + goto CLEANUP;
5761 + }
5762 +
5763 + /* Back off if it's too big */
5764 + while(mp_cmp(x, m) >= 0) {
5765 + if((res = s_mp_sub(x, m)) != MP_OKAY)
5766 + break;
5767 + }
5768 +
5769 + CLEANUP:
5770 + mp_clear(&q);
5771 +
5772 + return res;
5773 +
5774 +} /* end s_mp_reduce() */
5775 +
5776 +/* }}} */
5777 +
5778 +/* }}} */
5779 +
5780 +/* {{{ Primitive comparisons */
5781 +
5782 +/* {{{ s_mp_cmp(a, b) */
5783 +
5784 +/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b */
5785 +int s_mp_cmp(const mp_int *a, const mp_int *b)
5786 +{
5787 + mp_size used_a = MP_USED(a);
5788 + {
5789 + mp_size used_b = MP_USED(b);
5790 +
5791 + if (used_a > used_b)
5792 + goto IS_GT;
5793 + if (used_a < used_b)
5794 + goto IS_LT;
5795 + }
5796 + {
5797 + mp_digit *pa, *pb;
5798 + mp_digit da = 0, db = 0;
5799 +
5800 +#define CMP_AB(n) if ((da = pa[n]) != (db = pb[n])) goto done
5801 +
5802 + pa = MP_DIGITS(a) + used_a;
5803 + pb = MP_DIGITS(b) + used_a;
5804 + while (used_a >= 4) {
5805 + pa -= 4;
5806 + pb -= 4;
5807 + used_a -= 4;
5808 + CMP_AB(3);
5809 + CMP_AB(2);
5810 + CMP_AB(1);
5811 + CMP_AB(0);
5812 + }
5813 + while (used_a-- > 0 && ((da = *--pa) == (db = *--pb)))
5814 + /* do nothing */;
5815 +done:
5816 + if (da > db)
5817 + goto IS_GT;
5818 + if (da < db)
5819 + goto IS_LT;
5820 + }
5821 + return MP_EQ;
5822 +IS_LT:
5823 + return MP_LT;
5824 +IS_GT:
5825 + return MP_GT;
5826 +} /* end s_mp_cmp() */
5827 +
5828 +/* }}} */
5829 +
5830 +/* {{{ s_mp_cmp_d(a, d) */
5831 +
5832 +/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d */
5833 +int s_mp_cmp_d(const mp_int *a, mp_digit d)
5834 +{
5835 + if(USED(a) > 1)
5836 + return MP_GT;
5837 +
5838 + if(DIGIT(a, 0) < d)
5839 + return MP_LT;
5840 + else if(DIGIT(a, 0) > d)
5841 + return MP_GT;
5842 + else
5843 + return MP_EQ;
5844 +
5845 +} /* end s_mp_cmp_d() */
5846 +
5847 +/* }}} */
5848 +
5849 +/* {{{ s_mp_ispow2(v) */
5850 +
5851 +/*
5852 + Returns -1 if the value is not a power of two; otherwise, it returns
5853 + k such that v = 2^k, i.e. lg(v).
5854 + */
5855 +int s_mp_ispow2(const mp_int *v)
5856 +{
5857 + mp_digit d;
5858 + int extra = 0, ix;
5859 +
5860 + ix = MP_USED(v) - 1;
5861 + d = MP_DIGIT(v, ix); /* most significant digit of v */
5862 +
5863 + extra = s_mp_ispow2d(d);
5864 + if (extra < 0 || ix == 0)
5865 + return extra;
5866 +
5867 + while (--ix >= 0) {
5868 + if (DIGIT(v, ix) != 0)
5869 + return -1; /* not a power of two */
5870 + extra += MP_DIGIT_BIT;
5871 + }
5872 +
5873 + return extra;
5874 +
5875 +} /* end s_mp_ispow2() */
5876 +
5877 +/* }}} */
5878 +
5879 +/* {{{ s_mp_ispow2d(d) */
5880 +
5881 +int s_mp_ispow2d(mp_digit d)
5882 +{
5883 + if ((d != 0) && ((d & (d-1)) == 0)) { /* d is a power of 2 */
5884 + int pow = 0;
5885 +#if defined (MP_USE_UINT_DIGIT)
5886 + if (d & 0xffff0000U)
5887 + pow += 16;
5888 + if (d & 0xff00ff00U)
5889 + pow += 8;
5890 + if (d & 0xf0f0f0f0U)
5891 + pow += 4;
5892 + if (d & 0xccccccccU)
5893 + pow += 2;
5894 + if (d & 0xaaaaaaaaU)
5895 + pow += 1;
5896 +#elif defined(MP_USE_LONG_LONG_DIGIT)
5897 + if (d & 0xffffffff00000000ULL)
5898 + pow += 32;
5899 + if (d & 0xffff0000ffff0000ULL)
5900 + pow += 16;
5901 + if (d & 0xff00ff00ff00ff00ULL)
5902 + pow += 8;
5903 + if (d & 0xf0f0f0f0f0f0f0f0ULL)
5904 + pow += 4;
5905 + if (d & 0xccccccccccccccccULL)
5906 + pow += 2;
5907 + if (d & 0xaaaaaaaaaaaaaaaaULL)
5908 + pow += 1;
5909 +#elif defined(MP_USE_LONG_DIGIT)
5910 + if (d & 0xffffffff00000000UL)
5911 + pow += 32;
5912 + if (d & 0xffff0000ffff0000UL)
5913 + pow += 16;
5914 + if (d & 0xff00ff00ff00ff00UL)
5915 + pow += 8;
5916 + if (d & 0xf0f0f0f0f0f0f0f0UL)
5917 + pow += 4;
5918 + if (d & 0xccccccccccccccccUL)
5919 + pow += 2;
5920 + if (d & 0xaaaaaaaaaaaaaaaaUL)
5921 + pow += 1;
5922 +#else
5923 +#error "unknown type for mp_digit"
5924 +#endif
5925 + return pow;
5926 + }
5927 + return -1;
5928 +
5929 +} /* end s_mp_ispow2d() */
5930 +
5931 +/* }}} */
5932 +
5933 +/* }}} */
5934 +
5935 +/* {{{ Primitive I/O helpers */
5936 +
5937 +/* {{{ s_mp_tovalue(ch, r) */
5938 +
5939 +/*
5940 + Convert the given character to its digit value, in the given radix.
5941 + If the given character is not understood in the given radix, -1 is
5942 + returned. Otherwise the digit's numeric value is returned.
5943 +
5944 + The results will be odd if you use a radix < 2 or > 62, you are
5945 + expected to know what you're up to.
5946 + */
5947 +int s_mp_tovalue(char ch, int r)
5948 +{
5949 + int val, xch;
5950 +
5951 + if(r > 36)
5952 + xch = ch;
5953 + else
5954 + xch = toupper(ch);
5955 +
5956 + if(isdigit(xch))
5957 + val = xch - '0';
5958 + else if(isupper(xch))
5959 + val = xch - 'A' + 10;
5960 + else if(islower(xch))
5961 + val = xch - 'a' + 36;
5962 + else if(xch == '+')
5963 + val = 62;
5964 + else if(xch == '/')
5965 + val = 63;
5966 + else
5967 + return -1;
5968 +
5969 + if(val < 0 || val >= r)
5970 + return -1;
5971 +
5972 + return val;
5973 +
5974 +} /* end s_mp_tovalue() */
5975 +
5976 +/* }}} */
5977 +
5978 +/* {{{ s_mp_todigit(val, r, low) */
5979 +
5980 +/*
5981 + Convert val to a radix-r digit, if possible. If val is out of range
5982 + for r, returns zero. Otherwise, returns an ASCII character denoting
5983 + the value in the given radix.
5984 +
5985 + The results may be odd if you use a radix < 2 or > 64, you are
5986 + expected to know what you're doing.
5987 + */
5988 +
5989 +char s_mp_todigit(mp_digit val, int r, int low)
5990 +{
5991 + char ch;
5992 +
5993 + if(val >= r)
5994 + return 0;
5995 +
5996 + ch = s_dmap_1[val];
5997 +
5998 + if(r <= 36 && low)
5999 + ch = tolower(ch);
6000 +
6001 + return ch;
6002 +
6003 +} /* end s_mp_todigit() */
6004 +
6005 +/* }}} */
6006 +
6007 +/* {{{ s_mp_outlen(bits, radix) */
6008 +
6009 +/*
6010 + Return an estimate for how long a string is needed to hold a radix
6011 + r representation of a number with 'bits' significant bits, plus an
6012 + extra for a zero terminator (assuming C style strings here)
6013 + */
6014 +int s_mp_outlen(int bits, int r)
6015 +{
6016 + return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;
6017 +
6018 +} /* end s_mp_outlen() */
6019 +
6020 +/* }}} */
6021 +
6022 +/* }}} */
6023 +
6024 +/* {{{ mp_read_unsigned_octets(mp, str, len) */
6025 +/* mp_read_unsigned_octets(mp, str, len)
6026 + Read in a raw value (base 256) into the given mp_int
6027 + No sign bit, number is positive. Leading zeros ignored.
6028 + */
6029 +
6030 +mp_err
6031 +mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)
6032 +{
6033 + int count;
6034 + mp_err res;
6035 + mp_digit d;
6036 +
6037 + ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
6038 +
6039 + mp_zero(mp);
6040 +
6041 + count = len % sizeof(mp_digit);
6042 + if (count) {
6043 + for (d = 0; count-- > 0; --len) {
6044 + d = (d << 8) | *str++;
6045 + }
6046 + MP_DIGIT(mp, 0) = d;
6047 + }
6048 +
6049 + /* Read the rest of the digits */
6050 + for(; len > 0; len -= sizeof(mp_digit)) {
6051 + for (d = 0, count = sizeof(mp_digit); count > 0; --count) {
6052 + d = (d << 8) | *str++;
6053 + }
6054 + if (MP_EQ == mp_cmp_z(mp)) {
6055 + if (!d)
6056 + continue;
6057 + } else {
6058 + if((res = s_mp_lshd(mp, 1)) != MP_OKAY)
6059 + return res;
6060 + }
6061 + MP_DIGIT(mp, 0) = d;
6062 + }
6063 + return MP_OKAY;
6064 +} /* end mp_read_unsigned_octets() */
6065 +/* }}} */
6066 +
6067 +/* {{{ mp_unsigned_octet_size(mp) */
6068 +int
6069 +mp_unsigned_octet_size(const mp_int *mp)
6070 +{
6071 + int bytes;
6072 + int ix;
6073 + mp_digit d = 0;
6074 +
6075 + ARGCHK(mp != NULL, MP_BADARG);
6076 + ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG);
6077 +
6078 + bytes = (USED(mp) * sizeof(mp_digit));
6079 +
6080 + /* subtract leading zeros. */
6081 + /* Iterate over each digit... */
6082 + for(ix = USED(mp) - 1; ix >= 0; ix--) {
6083 + d = DIGIT(mp, ix);
6084 + if (d)
6085 + break;
6086 + bytes -= sizeof(d);
6087 + }
6088 + if (!bytes)
6089 + return 1;
6090 +
6091 + /* Have MSD, check digit bytes, high order first */
6092 + for(ix = sizeof(mp_digit) - 1; ix >= 0; ix--) {
6093 + unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT));
6094 + if (x)
6095 + break;
6096 + --bytes;
6097 + }
6098 + return bytes;
6099 +} /* end mp_unsigned_octet_size() */
6100 +/* }}} */
6101 +
6102 +/* {{{ mp_to_unsigned_octets(mp, str) */
6103 +/* output a buffer of big endian octets no longer than specified. */
6104 +mp_err
6105 +mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
6106 +{
6107 + int ix, pos = 0;
6108 + int bytes;
6109 +
6110 + ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
6111 +
6112 + bytes = mp_unsigned_octet_size(mp);
6113 + ARGCHK(bytes <= maxlen, MP_BADARG);
6114 +
6115 + /* Iterate over each digit... */
6116 + for(ix = USED(mp) - 1; ix >= 0; ix--) {
6117 + mp_digit d = DIGIT(mp, ix);
6118 + int jx;
6119 +
6120 + /* Unpack digit bytes, high order first */
6121 + for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
6122 + unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
6123 + if (!pos && !x) /* suppress leading zeros */
6124 + continue;
6125 + str[pos++] = x;
6126 + }
6127 + }
6128 + if (!pos)
6129 + str[pos++] = 0;
6130 + return pos;
6131 +} /* end mp_to_unsigned_octets() */
6132 +/* }}} */
6133 +
6134 +/* {{{ mp_to_signed_octets(mp, str) */
6135 +/* output a buffer of big endian octets no longer than specified. */
6136 +mp_err
6137 +mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
6138 +{
6139 + int ix, pos = 0;
6140 + int bytes;
6141 +
6142 + ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
6143 +
6144 + bytes = mp_unsigned_octet_size(mp);
6145 + ARGCHK(bytes <= maxlen, MP_BADARG);
6146 +
6147 + /* Iterate over each digit... */
6148 + for(ix = USED(mp) - 1; ix >= 0; ix--) {
6149 + mp_digit d = DIGIT(mp, ix);
6150 + int jx;
6151 +
6152 + /* Unpack digit bytes, high order first */
6153 + for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
6154 + unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
6155 + if (!pos) {
6156 + if (!x) /* suppress leading zeros */
6157 + continue;
6158 + if (x & 0x80) { /* add one leading zero to make output positive. */
6159 + ARGCHK(bytes + 1 <= maxlen, MP_BADARG);
6160 + if (bytes + 1 > maxlen)
6161 + return MP_BADARG;
6162 + str[pos++] = 0;
6163 + }
6164 + }
6165 + str[pos++] = x;
6166 + }
6167 + }
6168 + if (!pos)
6169 + str[pos++] = 0;
6170 + return pos;
6171 +} /* end mp_to_signed_octets() */
6172 +/* }}} */
6173 +
6174 +/* {{{ mp_to_fixlen_octets(mp, str) */
6175 +/* output a buffer of big endian octets exactly as long as requested. */
6176 +mp_err
6177 +mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
6178 +{
6179 + int ix, pos = 0;
6180 + int bytes;
6181 +
6182 + ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
6183 +
6184 + bytes = mp_unsigned_octet_size(mp);
6185 + ARGCHK(bytes <= length, MP_BADARG);
6186 +
6187 + /* place any needed leading zeros */
6188 + for (;length > bytes; --length) {
6189 + *str++ = 0;
6190 + }
6191 +
6192 + /* Iterate over each digit... */
6193 + for(ix = USED(mp) - 1; ix >= 0; ix--) {
6194 + mp_digit d = DIGIT(mp, ix);
6195 + int jx;
6196 +
6197 + /* Unpack digit bytes, high order first */
6198 + for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
6199 + unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
6200 + if (!pos && !x) /* suppress leading zeros */
6201 + continue;
6202 + str[pos++] = x;
6203 + }
6204 + }
6205 + if (!pos)
6206 + str[pos++] = 0;
6207 + return MP_OKAY;
6208 +} /* end mp_to_fixlen_octets() */
6209 +/* }}} */
6210 +
6211 +
6212 +/*------------------------------------------------------------------------*/
6213 +/* HERE THERE BE DRAGONS */
6214 +
6215 diff --git a/net/third_party/nss/ssl/mpi/mpi.h b/net/third_party/nss/ssl/mpi/mpi .h
6216 new file mode 100644
6217 index 0000000..79503f3
6218 --- /dev/null
6219 +++ b/net/third_party/nss/ssl/mpi/mpi.h
6220 @@ -0,0 +1,340 @@
6221 +/*
6222 + * mpi.h
6223 + *
6224 + * Arbitrary precision integer arithmetic library
6225 + *
6226 + * ***** BEGIN LICENSE BLOCK *****
6227 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6228 + *
6229 + * The contents of this file are subject to the Mozilla Public License Version
6230 + * 1.1 (the "License"); you may not use this file except in compliance with
6231 + * the License. You may obtain a copy of the License at
6232 + * http://www.mozilla.org/MPL/
6233 + *
6234 + * Software distributed under the License is distributed on an "AS IS" basis,
6235 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
6236 + * for the specific language governing rights and limitations under the
6237 + * License.
6238 + *
6239 + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
6240 + *
6241 + * The Initial Developer of the Original Code is
6242 + * Michael J. Fromberger.
6243 + * Portions created by the Initial Developer are Copyright (C) 1998
6244 + * the Initial Developer. All Rights Reserved.
6245 + *
6246 + * Contributor(s):
6247 + * Netscape Communications Corporation
6248 + *
6249 + * Alternatively, the contents of this file may be used under the terms of
6250 + * either the GNU General Public License Version 2 or later (the "GPL"), or
6251 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
6252 + * in which case the provisions of the GPL or the LGPL are applicable instead
6253 + * of those above. If you wish to allow use of your version of this file only
6254 + * under the terms of either the GPL or the LGPL, and not to allow others to
6255 + * use your version of this file under the terms of the MPL, indicate your
6256 + * decision by deleting the provisions above and replace them with the notice
6257 + * and other provisions required by the GPL or the LGPL. If you do not delete
6258 + * the provisions above, a recipient may use your version of this file under
6259 + * the terms of any one of the MPL, the GPL or the LGPL.
6260 + *
6261 + * ***** END LICENSE BLOCK ***** */
6262 +/* $Id: mpi.h,v 1.23 2008/12/04 18:16:34 rrelyea%redhat.com Exp $ */
6263 +
6264 +#ifndef _H_MPI_
6265 +#define _H_MPI_
6266 +
6267 +#include "mpi-config.h"
6268 +
6269 +#if MP_DEBUG
6270 +#undef MP_IOFUNC
6271 +#define MP_IOFUNC 1
6272 +#endif
6273 +
6274 +#if MP_IOFUNC
6275 +#include <stdio.h>
6276 +#include <ctype.h>
6277 +#endif
6278 +
6279 +#include <limits.h>
6280 +
6281 +#if defined(BSDI)
6282 +#undef ULLONG_MAX
6283 +#endif
6284 +
6285 +#if defined( macintosh )
6286 +#include <Types.h>
6287 +#elif defined( _WIN32_WCE)
6288 +/* #include <sys/types.h> What do we need here ?? */
6289 +#else
6290 +#include <sys/types.h>
6291 +#endif
6292 +
6293 +#define MP_NEG 1
6294 +#define MP_ZPOS 0
6295 +
6296 +#define MP_OKAY 0 /* no error, all is well */
6297 +#define MP_YES 0 /* yes (boolean result) */
6298 +#define MP_NO -1 /* no (boolean result) */
6299 +#define MP_MEM -2 /* out of memory */
6300 +#define MP_RANGE -3 /* argument out of range */
6301 +#define MP_BADARG -4 /* invalid parameter */
6302 +#define MP_UNDEF -5 /* answer is undefined */
6303 +#define MP_LAST_CODE MP_UNDEF
6304 +
6305 +typedef unsigned int mp_sign;
6306 +typedef unsigned int mp_size;
6307 +typedef int mp_err;
6308 +
6309 +#define MP_32BIT_MAX 4294967295U
6310 +
6311 +#if !defined(ULONG_MAX)
6312 +#error "ULONG_MAX not defined"
6313 +#elif !defined(UINT_MAX)
6314 +#error "UINT_MAX not defined"
6315 +#elif !defined(USHRT_MAX)
6316 +#error "USHRT_MAX not defined"
6317 +#endif
6318 +
6319 +#if defined(ULONG_LONG_MAX) /* GCC, HPUX */
6320 +#define MP_ULONG_LONG_MAX ULONG_LONG_MAX
6321 +#elif defined(ULLONG_MAX) /* Solaris */
6322 +#define MP_ULONG_LONG_MAX ULLONG_MAX
6323 +/* MP_ULONG_LONG_MAX was defined to be ULLONG_MAX */
6324 +#elif defined(ULONGLONG_MAX) /* IRIX, AIX */
6325 +#define MP_ULONG_LONG_MAX ULONGLONG_MAX
6326 +#endif
6327 +
6328 +/* We only use unsigned long for mp_digit iff long is more than 32 bits. */
6329 +#if !defined(MP_USE_UINT_DIGIT) && ULONG_MAX > MP_32BIT_MAX
6330 +typedef unsigned long mp_digit;
6331 +#define MP_DIGIT_MAX ULONG_MAX
6332 +#define MP_DIGIT_FMT "%016lX" /* printf() format for 1 digit */
6333 +#define MP_HALF_DIGIT_MAX UINT_MAX
6334 +#undef MP_NO_MP_WORD
6335 +#define MP_NO_MP_WORD 1
6336 +#undef MP_USE_LONG_DIGIT
6337 +#define MP_USE_LONG_DIGIT 1
6338 +#undef MP_USE_LONG_LONG_DIGIT
6339 +
6340 +#elif !defined(MP_USE_UINT_DIGIT) && defined(MP_ULONG_LONG_MAX)
6341 +typedef unsigned long long mp_digit;
6342 +#define MP_DIGIT_MAX MP_ULONG_LONG_MAX
6343 +#define MP_DIGIT_FMT "%016llX" /* printf() format for 1 digit */
6344 +#define MP_HALF_DIGIT_MAX UINT_MAX
6345 +#undef MP_NO_MP_WORD
6346 +#define MP_NO_MP_WORD 1
6347 +#undef MP_USE_LONG_LONG_DIGIT
6348 +#define MP_USE_LONG_LONG_DIGIT 1
6349 +#undef MP_USE_LONG_DIGIT
6350 +
6351 +#else
6352 +typedef unsigned int mp_digit;
6353 +#define MP_DIGIT_MAX UINT_MAX
6354 +#define MP_DIGIT_FMT "%08X" /* printf() format for 1 digit */
6355 +#define MP_HALF_DIGIT_MAX USHRT_MAX
6356 +#undef MP_USE_UINT_DIGIT
6357 +#define MP_USE_UINT_DIGIT 1
6358 +#undef MP_USE_LONG_LONG_DIGIT
6359 +#undef MP_USE_LONG_DIGIT
6360 +#endif
6361 +
6362 +#if !defined(MP_NO_MP_WORD)
6363 +#if defined(MP_USE_UINT_DIGIT) && \
6364 + (defined(MP_ULONG_LONG_MAX) || (ULONG_MAX > UINT_MAX))
6365 +
6366 +#if (ULONG_MAX > UINT_MAX)
6367 +typedef unsigned long mp_word;
6368 +typedef long mp_sword;
6369 +#define MP_WORD_MAX ULONG_MAX
6370 +
6371 +#else
6372 +typedef unsigned long long mp_word;
6373 +typedef long long mp_sword;
6374 +#define MP_WORD_MAX MP_ULONG_LONG_MAX
6375 +#endif
6376 +
6377 +#else
6378 +#define MP_NO_MP_WORD 1
6379 +#endif
6380 +#endif /* !defined(MP_NO_MP_WORD) */
6381 +
6382 +#if !defined(MP_WORD_MAX) && defined(MP_DEFINE_SMALL_WORD)
6383 +typedef unsigned int mp_word;
6384 +typedef int mp_sword;
6385 +#define MP_WORD_MAX UINT_MAX
6386 +#endif
6387 +
6388 +#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit))
6389 +#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word))
6390 +#define MP_RADIX (1+(mp_word)MP_DIGIT_MAX)
6391 +
6392 +#define MP_HALF_DIGIT_BIT (MP_DIGIT_BIT/2)
6393 +#define MP_HALF_RADIX (1+(mp_digit)MP_HALF_DIGIT_MAX)
6394 +/* MP_HALF_RADIX really ought to be called MP_SQRT_RADIX, but it's named
6395 +** MP_HALF_RADIX because it's the radix for MP_HALF_DIGITs, and it's
6396 +** consistent with the other _HALF_ names.
6397 +*/
6398 +
6399 +
6400 +/* Macros for accessing the mp_int internals */
6401 +#define MP_SIGN(MP) ((MP)->sign)
6402 +#define MP_USED(MP) ((MP)->used)
6403 +#define MP_ALLOC(MP) ((MP)->alloc)
6404 +#define MP_DIGITS(MP) ((MP)->dp)
6405 +#define MP_DIGIT(MP,N) (MP)->dp[(N)]
6406 +
6407 +/* This defines the maximum I/O base (minimum is 2) */
6408 +#define MP_MAX_RADIX 64
6409 +
6410 +typedef struct {
6411 + mp_sign sign; /* sign of this quantity */
6412 + mp_size alloc; /* how many digits allocated */
6413 + mp_size used; /* how many digits used */
6414 + mp_digit *dp; /* the digits themselves */
6415 +} mp_int;
6416 +
6417 +/* Default precision */
6418 +mp_size mp_get_prec(void);
6419 +void mp_set_prec(mp_size prec);
6420 +
6421 +/* Memory management */
6422 +mp_err mp_init(mp_int *mp);
6423 +mp_err mp_init_size(mp_int *mp, mp_size prec);
6424 +mp_err mp_init_copy(mp_int *mp, const mp_int *from);
6425 +mp_err mp_copy(const mp_int *from, mp_int *to);
6426 +void mp_exch(mp_int *mp1, mp_int *mp2);
6427 +void mp_clear(mp_int *mp);
6428 +void mp_zero(mp_int *mp);
6429 +void mp_set(mp_int *mp, mp_digit d);
6430 +mp_err mp_set_int(mp_int *mp, long z);
6431 +#define mp_set_long(mp,z) mp_set_int(mp,z)
6432 +mp_err mp_set_ulong(mp_int *mp, unsigned long z);
6433 +
6434 +/* Single digit arithmetic */
6435 +mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b);
6436 +mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b);
6437 +mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b);
6438 +mp_err mp_mul_2(const mp_int *a, mp_int *c);
6439 +mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r);
6440 +mp_err mp_div_2(const mp_int *a, mp_int *c);
6441 +mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c);
6442 +
6443 +/* Sign manipulations */
6444 +mp_err mp_abs(const mp_int *a, mp_int *b);
6445 +mp_err mp_neg(const mp_int *a, mp_int *b);
6446 +
6447 +/* Full arithmetic */
6448 +mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c);
6449 +mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
6450 +mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c);
6451 +#if MP_SQUARE
6452 +mp_err mp_sqr(const mp_int *a, mp_int *b);
6453 +#else
6454 +#define mp_sqr(a, b) mp_mul(a, a, b)
6455 +#endif
6456 +mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r);
6457 +mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r);
6458 +mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
6459 +mp_err mp_2expt(mp_int *a, mp_digit k);
6460 +mp_err mp_sqrt(const mp_int *a, mp_int *b);
6461 +
6462 +/* Modular arithmetic */
6463 +#if MP_MODARITH
6464 +mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c);
6465 +mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c);
6466 +mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
6467 +mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
6468 +mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
6469 +#if MP_SQUARE
6470 +mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c);
6471 +#else
6472 +#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
6473 +#endif
6474 +mp_err mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) ;
6475 +mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c);
6476 +#endif /* MP_MODARITH */
6477 +
6478 +/* Comparisons */
6479 +int mp_cmp_z(const mp_int *a);
6480 +int mp_cmp_d(const mp_int *a, mp_digit d);
6481 +int mp_cmp(const mp_int *a, const mp_int *b);
6482 +int mp_cmp_mag(mp_int *a, mp_int *b);
6483 +int mp_cmp_int(const mp_int *a, long z);
6484 +int mp_isodd(const mp_int *a);
6485 +int mp_iseven(const mp_int *a);
6486 +
6487 +/* Number theoretic */
6488 +#if MP_NUMTH
6489 +mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
6490 +mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
6491 +mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int * y);
6492 +mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c);
6493 +mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c);
6494 +#endif /* end MP_NUMTH */
6495 +
6496 +/* Input and output */
6497 +#if MP_IOFUNC
6498 +void mp_print(mp_int *mp, FILE *ofp);
6499 +#endif /* end MP_IOFUNC */
6500 +
6501 +/* Base conversion */
6502 +mp_err mp_read_raw(mp_int *mp, char *str, int len);
6503 +int mp_raw_size(mp_int *mp);
6504 +mp_err mp_toraw(mp_int *mp, char *str);
6505 +mp_err mp_read_radix(mp_int *mp, const char *str, int radix);
6506 +mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix);
6507 +int mp_radix_size(mp_int *mp, int radix);
6508 +mp_err mp_toradix(mp_int *mp, char *str, int radix);
6509 +int mp_tovalue(char ch, int r);
6510 +
6511 +#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
6512 +#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
6513 +#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
6514 +#define mp_tohex(M, S) mp_toradix((M), (S), 16)
6515 +
6516 +/* Error strings */
6517 +const char *mp_strerror(mp_err ec);
6518 +
6519 +/* Octet string conversion functions */
6520 +mp_err mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size le n);
6521 +int mp_unsigned_octet_size(const mp_int *mp);
6522 +mp_err mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxl en);
6523 +mp_err mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen );
6524 +mp_err mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size len);
6525 +
6526 +/* Miscellaneous */
6527 +mp_size mp_trailing_zeros(const mp_int *mp);
6528 +void freebl_cpuid(unsigned long op, unsigned long *eax,
6529 + unsigned long *ebx, unsigned long *ecx,
6530 + unsigned long *edx);
6531 +
6532 +
6533 +#define MP_CHECKOK(x) if (MP_OKAY > (res = (x))) goto CLEANUP
6534 +#define MP_CHECKERR(x) if (MP_OKAY > (res = (x))) goto CLEANUP
6535 +
6536 +#if defined(MP_API_COMPATIBLE)
6537 +#define NEG MP_NEG
6538 +#define ZPOS MP_ZPOS
6539 +#define DIGIT_MAX MP_DIGIT_MAX
6540 +#define DIGIT_BIT MP_DIGIT_BIT
6541 +#define DIGIT_FMT MP_DIGIT_FMT
6542 +#define RADIX MP_RADIX
6543 +#define MAX_RADIX MP_MAX_RADIX
6544 +#define SIGN(MP) MP_SIGN(MP)
6545 +#define USED(MP) MP_USED(MP)
6546 +#define ALLOC(MP) MP_ALLOC(MP)
6547 +#define DIGITS(MP) MP_DIGITS(MP)
6548 +#define DIGIT(MP,N) MP_DIGIT(MP,N)
6549 +
6550 +#if MP_ARGCHK == 1
6551 +#define ARGCHK(X,Y) {if(!(X)){return (Y);}}
6552 +#elif MP_ARGCHK == 2
6553 +#include <assert.h>
6554 +#define ARGCHK(X,Y) assert(X)
6555 +#else
6556 +#define ARGCHK(X,Y) /* */
6557 +#endif
6558 +#endif /* defined MP_API_COMPATIBLE */
6559 +
6560 +#endif /* end _H_MPI_ */
6561 diff --git a/net/third_party/nss/ssl/mpi/mplogic.c b/net/third_party/nss/ssl/mpi /mplogic.c
6562 new file mode 100644
6563 index 0000000..216f07a
6564 --- /dev/null
6565 +++ b/net/third_party/nss/ssl/mpi/mplogic.c
6566 @@ -0,0 +1,466 @@
6567 +/*
6568 + * mplogic.c
6569 + *
6570 + * Bitwise logical operations on MPI values
6571 + *
6572 + * ***** BEGIN LICENSE BLOCK *****
6573 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6574 + *
6575 + * The contents of this file are subject to the Mozilla Public License Version
6576 + * 1.1 (the "License"); you may not use this file except in compliance with
6577 + * the License. You may obtain a copy of the License at
6578 + * http://www.mozilla.org/MPL/
6579 + *
6580 + * Software distributed under the License is distributed on an "AS IS" basis,
6581 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
6582 + * for the specific language governing rights and limitations under the
6583 + * License.
6584 + *
6585 + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
6586 + *
6587 + * The Initial Developer of the Original Code is
6588 + * Michael J. Fromberger.
6589 + * Portions created by the Initial Developer are Copyright (C) 1998
6590 + * the Initial Developer. All Rights Reserved.
6591 + *
6592 + * Contributor(s):
6593 + *
6594 + * Alternatively, the contents of this file may be used under the terms of
6595 + * either the GNU General Public License Version 2 or later (the "GPL"), or
6596 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
6597 + * in which case the provisions of the GPL or the LGPL are applicable instead
6598 + * of those above. If you wish to allow use of your version of this file only
6599 + * under the terms of either the GPL or the LGPL, and not to allow others to
6600 + * use your version of this file under the terms of the MPL, indicate your
6601 + * decision by deleting the provisions above and replace them with the notice
6602 + * and other provisions required by the GPL or the LGPL. If you do not delete
6603 + * the provisions above, a recipient may use your version of this file under
6604 + * the terms of any one of the MPL, the GPL or the LGPL.
6605 + *
6606 + * ***** END LICENSE BLOCK ***** */
6607 +/* $Id: mplogic.c,v 1.15 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
6608 +
6609 +#define MP_API_COMPATIBLE 1
6610 +#include "mpi-priv.h"
6611 +#include "mplogic.h"
6612 +
6613 +/* {{{ Lookup table for population count */
6614 +
6615 +static unsigned char bitc[] = {
6616 + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
6617 + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
6618 + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
6619 + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
6620 + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
6621 + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
6622 + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
6623 + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
6624 + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
6625 + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
6626 + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
6627 + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
6628 + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
6629 + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
6630 + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
6631 + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
6632 +};
6633 +
6634 +/* }}} */
6635 +
6636 +/*------------------------------------------------------------------------*/
6637 +/*
6638 + mpl_not(a, b) - compute b = ~a
6639 + mpl_and(a, b, c) - compute c = a & b
6640 + mpl_or(a, b, c) - compute c = a | b
6641 + mpl_xor(a, b, c) - compute c = a ^ b
6642 + */
6643 +
6644 +/* {{{ mpl_not(a, b) */
6645 +
6646 +mp_err mpl_not(mp_int *a, mp_int *b)
6647 +{
6648 + mp_err res;
6649 + unsigned int ix;
6650 +
6651 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
6652 +
6653 + if((res = mp_copy(a, b)) != MP_OKAY)
6654 + return res;
6655 +
6656 + /* This relies on the fact that the digit type is unsigned */
6657 + for(ix = 0; ix < USED(b); ix++)
6658 + DIGIT(b, ix) = ~DIGIT(b, ix);
6659 +
6660 + s_mp_clamp(b);
6661 +
6662 + return MP_OKAY;
6663 +
6664 +} /* end mpl_not() */
6665 +
6666 +/* }}} */
6667 +
6668 +/* {{{ mpl_and(a, b, c) */
6669 +
6670 +mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c)
6671 +{
6672 + mp_int *which, *other;
6673 + mp_err res;
6674 + unsigned int ix;
6675 +
6676 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
6677 +
6678 + if(USED(a) <= USED(b)) {
6679 + which = a;
6680 + other = b;
6681 + } else {
6682 + which = b;
6683 + other = a;
6684 + }
6685 +
6686 + if((res = mp_copy(which, c)) != MP_OKAY)
6687 + return res;
6688 +
6689 + for(ix = 0; ix < USED(which); ix++)
6690 + DIGIT(c, ix) &= DIGIT(other, ix);
6691 +
6692 + s_mp_clamp(c);
6693 +
6694 + return MP_OKAY;
6695 +
6696 +} /* end mpl_and() */
6697 +
6698 +/* }}} */
6699 +
6700 +/* {{{ mpl_or(a, b, c) */
6701 +
6702 +mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c)
6703 +{
6704 + mp_int *which, *other;
6705 + mp_err res;
6706 + unsigned int ix;
6707 +
6708 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
6709 +
6710 + if(USED(a) >= USED(b)) {
6711 + which = a;
6712 + other = b;
6713 + } else {
6714 + which = b;
6715 + other = a;
6716 + }
6717 +
6718 + if((res = mp_copy(which, c)) != MP_OKAY)
6719 + return res;
6720 +
6721 + for(ix = 0; ix < USED(which); ix++)
6722 + DIGIT(c, ix) |= DIGIT(other, ix);
6723 +
6724 + return MP_OKAY;
6725 +
6726 +} /* end mpl_or() */
6727 +
6728 +/* }}} */
6729 +
6730 +/* {{{ mpl_xor(a, b, c) */
6731 +
6732 +mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c)
6733 +{
6734 + mp_int *which, *other;
6735 + mp_err res;
6736 + unsigned int ix;
6737 +
6738 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
6739 +
6740 + if(USED(a) >= USED(b)) {
6741 + which = a;
6742 + other = b;
6743 + } else {
6744 + which = b;
6745 + other = a;
6746 + }
6747 +
6748 + if((res = mp_copy(which, c)) != MP_OKAY)
6749 + return res;
6750 +
6751 + for(ix = 0; ix < USED(which); ix++)
6752 + DIGIT(c, ix) ^= DIGIT(other, ix);
6753 +
6754 + s_mp_clamp(c);
6755 +
6756 + return MP_OKAY;
6757 +
6758 +} /* end mpl_xor() */
6759 +
6760 +/* }}} */
6761 +
6762 +/*------------------------------------------------------------------------*/
6763 +/*
6764 + mpl_rsh(a, b, d) - b = a >> d
6765 + mpl_lsh(a, b, d) - b = a << d
6766 + */
6767 +
6768 +/* {{{ mpl_rsh(a, b, d) */
6769 +
6770 +mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
6771 +{
6772 + mp_err res;
6773 +
6774 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
6775 +
6776 + if((res = mp_copy(a, b)) != MP_OKAY)
6777 + return res;
6778 +
6779 + s_mp_div_2d(b, d);
6780 +
6781 + return MP_OKAY;
6782 +
6783 +} /* end mpl_rsh() */
6784 +
6785 +/* }}} */
6786 +
6787 +/* {{{ mpl_lsh(a, b, d) */
6788 +
6789 +mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
6790 +{
6791 + mp_err res;
6792 +
6793 + ARGCHK(a != NULL && b != NULL, MP_BADARG);
6794 +
6795 + if((res = mp_copy(a, b)) != MP_OKAY)
6796 + return res;
6797 +
6798 + return s_mp_mul_2d(b, d);
6799 +
6800 +} /* end mpl_lsh() */
6801 +
6802 +/* }}} */
6803 +
6804 +/*------------------------------------------------------------------------*/
6805 +/*
6806 + mpl_num_set(a, num)
6807 +
6808 + Count the number of set bits in the binary representation of a.
6809 + Returns MP_OKAY and sets 'num' to be the number of such bits, if
6810 + possible. If num is NULL, the result is thrown away, but it is
6811 + not considered an error.
6812 +
6813 + mpl_num_clear() does basically the same thing for clear bits.
6814 + */
6815 +
6816 +/* {{{ mpl_num_set(a, num) */
6817 +
6818 +mp_err mpl_num_set(mp_int *a, int *num)
6819 +{
6820 + unsigned int ix;
6821 + int db, nset = 0;
6822 + mp_digit cur;
6823 + unsigned char reg;
6824 +
6825 + ARGCHK(a != NULL, MP_BADARG);
6826 +
6827 + for(ix = 0; ix < USED(a); ix++) {
6828 + cur = DIGIT(a, ix);
6829 +
6830 + for(db = 0; db < sizeof(mp_digit); db++) {
6831 + reg = (unsigned char)(cur >> (CHAR_BIT * db));
6832 +
6833 + nset += bitc[reg];
6834 + }
6835 + }
6836 +
6837 + if(num)
6838 + *num = nset;
6839 +
6840 + return MP_OKAY;
6841 +
6842 +} /* end mpl_num_set() */
6843 +
6844 +/* }}} */
6845 +
6846 +/* {{{ mpl_num_clear(a, num) */
6847 +
6848 +mp_err mpl_num_clear(mp_int *a, int *num)
6849 +{
6850 + unsigned int ix;
6851 + int db, nset = 0;
6852 + mp_digit cur;
6853 + unsigned char reg;
6854 +
6855 + ARGCHK(a != NULL, MP_BADARG);
6856 +
6857 + for(ix = 0; ix < USED(a); ix++) {
6858 + cur = DIGIT(a, ix);
6859 +
6860 + for(db = 0; db < sizeof(mp_digit); db++) {
6861 + reg = (unsigned char)(cur >> (CHAR_BIT * db));
6862 +
6863 + nset += bitc[UCHAR_MAX - reg];
6864 + }
6865 + }
6866 +
6867 + if(num)
6868 + *num = nset;
6869 +
6870 + return MP_OKAY;
6871 +
6872 +
6873 +} /* end mpl_num_clear() */
6874 +
6875 +/* }}} */
6876 +
6877 +/*------------------------------------------------------------------------*/
6878 +/*
6879 + mpl_parity(a)
6880 +
6881 + Determines the bitwise parity of the value given. Returns MP_EVEN
6882 + if an even number of digits are set, MP_ODD if an odd number are
6883 + set.
6884 + */
6885 +
6886 +/* {{{ mpl_parity(a) */
6887 +
6888 +mp_err mpl_parity(mp_int *a)
6889 +{
6890 + unsigned int ix;
6891 + int par = 0;
6892 + mp_digit cur;
6893 +
6894 + ARGCHK(a != NULL, MP_BADARG);
6895 +
6896 + for(ix = 0; ix < USED(a); ix++) {
6897 + int shft = (sizeof(mp_digit) * CHAR_BIT) / 2;
6898 +
6899 + cur = DIGIT(a, ix);
6900 +
6901 + /* Compute parity for current digit */
6902 + while(shft != 0) {
6903 + cur ^= (cur >> shft);
6904 + shft >>= 1;
6905 + }
6906 + cur &= 1;
6907 +
6908 + /* XOR with running parity so far */
6909 + par ^= cur;
6910 + }
6911 +
6912 + if(par)
6913 + return MP_ODD;
6914 + else
6915 + return MP_EVEN;
6916 +
6917 +} /* end mpl_parity() */
6918 +
6919 +/* }}} */
6920 +
6921 +/*
6922 + mpl_set_bit
6923 +
6924 + Returns MP_OKAY or some error code.
6925 + Grows a if needed to set a bit to 1.
6926 + */
6927 +mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value)
6928 +{
6929 + mp_size ix;
6930 + mp_err rv;
6931 + mp_digit mask;
6932 +
6933 + ARGCHK(a != NULL, MP_BADARG);
6934 +
6935 + ix = bitNum / MP_DIGIT_BIT;
6936 + if (ix + 1 > MP_USED(a)) {
6937 + rv = s_mp_pad(a, ix + 1);
6938 + if (rv != MP_OKAY)
6939 + return rv;
6940 + }
6941 +
6942 + bitNum = bitNum % MP_DIGIT_BIT;
6943 + mask = (mp_digit)1 << bitNum;
6944 + if (value)
6945 + MP_DIGIT(a,ix) |= mask;
6946 + else
6947 + MP_DIGIT(a,ix) &= ~mask;
6948 + s_mp_clamp(a);
6949 + return MP_OKAY;
6950 +}
6951 +
6952 +/*
6953 + mpl_get_bit
6954 +
6955 + returns 0 or 1 or some (negative) error code.
6956 + */
6957 +mp_err mpl_get_bit(const mp_int *a, mp_size bitNum)
6958 +{
6959 + mp_size bit, ix;
6960 + mp_err rv;
6961 +
6962 + ARGCHK(a != NULL, MP_BADARG);
6963 +
6964 + ix = bitNum / MP_DIGIT_BIT;
6965 + ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE);
6966 +
6967 + bit = bitNum % MP_DIGIT_BIT;
6968 + rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1;
6969 + return rv;
6970 +}
6971 +
6972 +/*
6973 + mpl_get_bits
6974 + - Extracts numBits bits from a, where the least significant extracted bit
6975 + is bit lsbNum. Returns a negative value if error occurs.
6976 + - Because sign bit is used to indicate error, maximum number of bits to
6977 + be returned is the lesser of (a) the number of bits in an mp_digit, or
6978 + (b) one less than the number of bits in an mp_err.
6979 + - lsbNum + numbits can be greater than the number of significant bits in
6980 + integer a, as long as bit lsbNum is in the high order digit of a.
6981 + */
6982 +mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits)
6983 +{
6984 + mp_size rshift = (lsbNum % MP_DIGIT_BIT);
6985 + mp_size lsWndx = (lsbNum / MP_DIGIT_BIT);
6986 + mp_digit * digit = MP_DIGITS(a) + lsWndx;
6987 + mp_digit mask = ((1 << numBits) - 1);
6988 +
6989 + ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG);
6990 + ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE);
6991 +
6992 + if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) ||
6993 + (lsWndx + 1 >= MP_USED(a))) {
6994 + mask &= (digit[0] >> rshift);
6995 + } else {
6996 + mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift)));
6997 + }
6998 + return (mp_err)mask;
6999 +}
7000 +
7001 +/*
7002 + mpl_significant_bits
7003 + returns number of significnant bits in abs(a).
7004 + returns 1 if value is zero.
7005 + */
7006 +mp_err mpl_significant_bits(const mp_int *a)
7007 +{
7008 + mp_err bits = 0;
7009 + int ix;
7010 +
7011 + ARGCHK(a != NULL, MP_BADARG);
7012 +
7013 + ix = MP_USED(a);
7014 + for (ix = MP_USED(a); ix > 0; ) {
7015 + mp_digit d;
7016 + d = MP_DIGIT(a, --ix);
7017 + if (d) {
7018 + while (d) {
7019 + ++bits;
7020 + d >>= 1;
7021 + }
7022 + break;
7023 + }
7024 + }
7025 + bits += ix * MP_DIGIT_BIT;
7026 + if (!bits)
7027 + bits = 1;
7028 + return bits;
7029 +}
7030 +
7031 +/*------------------------------------------------------------------------*/
7032 +/* HERE THERE BE DRAGONS */
7033 diff --git a/net/third_party/nss/ssl/mpi/mplogic.h b/net/third_party/nss/ssl/mpi /mplogic.h
7034 new file mode 100644
7035 index 0000000..de831dc
7036 --- /dev/null
7037 +++ b/net/third_party/nss/ssl/mpi/mplogic.h
7038 @@ -0,0 +1,85 @@
7039 +/*
7040 + * mplogic.h
7041 + *
7042 + * Bitwise logical operations on MPI values
7043 + *
7044 + * ***** BEGIN LICENSE BLOCK *****
7045 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7046 + *
7047 + * The contents of this file are subject to the Mozilla Public License Version
7048 + * 1.1 (the "License"); you may not use this file except in compliance with
7049 + * the License. You may obtain a copy of the License at
7050 + * http://www.mozilla.org/MPL/
7051 + *
7052 + * Software distributed under the License is distributed on an "AS IS" basis,
7053 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
7054 + * for the specific language governing rights and limitations under the
7055 + * License.
7056 + *
7057 + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
7058 + *
7059 + * The Initial Developer of the Original Code is
7060 + * Michael J. Fromberger.
7061 + * Portions created by the Initial Developer are Copyright (C) 1998
7062 + * the Initial Developer. All Rights Reserved.
7063 + *
7064 + * Contributor(s):
7065 + *
7066 + * Alternatively, the contents of this file may be used under the terms of
7067 + * either the GNU General Public License Version 2 or later (the "GPL"), or
7068 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
7069 + * in which case the provisions of the GPL or the LGPL are applicable instead
7070 + * of those above. If you wish to allow use of your version of this file only
7071 + * under the terms of either the GPL or the LGPL, and not to allow others to
7072 + * use your version of this file under the terms of the MPL, indicate your
7073 + * decision by deleting the provisions above and replace them with the notice
7074 + * and other provisions required by the GPL or the LGPL. If you do not delete
7075 + * the provisions above, a recipient may use your version of this file under
7076 + * the terms of any one of the MPL, the GPL or the LGPL.
7077 + *
7078 + * ***** END LICENSE BLOCK ***** */
7079 +/* $Id: mplogic.h,v 1.7 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
7080 +
7081 +#ifndef _H_MPLOGIC_
7082 +#define _H_MPLOGIC_
7083 +
7084 +#include "mpi.h"
7085 +
7086 +/*
7087 + The logical operations treat an mp_int as if it were a bit vector,
7088 + without regard to its sign (an mp_int is represented in a signed
7089 + magnitude format). Values are treated as if they had an infinite
7090 + string of zeros left of the most-significant bit.
7091 + */
7092 +
7093 +/* Parity results */
7094 +
7095 +#define MP_EVEN MP_YES
7096 +#define MP_ODD MP_NO
7097 +
7098 +/* Bitwise functions */
7099 +
7100 +mp_err mpl_not(mp_int *a, mp_int *b); /* one's complement */
7101 +mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c); /* bitwise AND */
7102 +mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c); /* bitwise OR */
7103 +mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c); /* bitwise XOR */
7104 +
7105 +/* Shift functions */
7106 +
7107 +mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d); /* right shift */
7108 +mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d); /* left shift */
7109 +
7110 +/* Bit count and parity */
7111 +
7112 +mp_err mpl_num_set(mp_int *a, int *num); /* count set bits */
7113 +mp_err mpl_num_clear(mp_int *a, int *num); /* count clear bits */
7114 +mp_err mpl_parity(mp_int *a); /* determine parity */
7115 +
7116 +/* Get & Set the value of a bit */
7117 +
7118 +mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value);
7119 +mp_err mpl_get_bit(const mp_int *a, mp_size bitNum);
7120 +mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits);
7121 +mp_err mpl_significant_bits(const mp_int *a);
7122 +
7123 +#endif /* end _H_MPLOGIC_ */
7124 diff --git a/net/third_party/nss/ssl/mpi/mpmontg.c b/net/third_party/nss/ssl/mpi /mpmontg.c
7125 new file mode 100644
7126 index 0000000..088b7eb
7127 --- /dev/null
7128 +++ b/net/third_party/nss/ssl/mpi/mpmontg.c
7129 @@ -0,0 +1,1210 @@
7130 +/* ***** BEGIN LICENSE BLOCK *****
7131 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7132 + *
7133 + * The contents of this file are subject to the Mozilla Public License Version
7134 + * 1.1 (the "License"); you may not use this file except in compliance with
7135 + * the License. You may obtain a copy of the License at
7136 + * http://www.mozilla.org/MPL/
7137 + *
7138 + * Software distributed under the License is distributed on an "AS IS" basis,
7139 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
7140 + * for the specific language governing rights and limitations under the
7141 + * License.
7142 + *
7143 + * The Original Code is the Netscape security libraries.
7144 + *
7145 + * The Initial Developer of the Original Code is
7146 + * Netscape Communications Corporation.
7147 + * Portions created by the Initial Developer are Copyright (C) 2000
7148 + * the Initial Developer. All Rights Reserved.
7149 + *
7150 + * Contributor(s):
7151 + * Sheueling Chang Shantz <sheueling.chang@sun.com>,
7152 + * Stephen Fung <stephen.fung@sun.com>, and
7153 + * Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
7154 + *
7155 + * Alternatively, the contents of this file may be used under the terms of
7156 + * either the GNU General Public License Version 2 or later (the "GPL"), or
7157 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
7158 + * in which case the provisions of the GPL or the LGPL are applicable instead
7159 + * of those above. If you wish to allow use of your version of this file only
7160 + * under the terms of either the GPL or the LGPL, and not to allow others to
7161 + * use your version of this file under the terms of the MPL, indicate your
7162 + * decision by deleting the provisions above and replace them with the notice
7163 + * and other provisions required by the GPL or the LGPL. If you do not delete
7164 + * the provisions above, a recipient may use your version of this file under
7165 + * the terms of any one of the MPL, the GPL or the LGPL.
7166 + *
7167 + * ***** END LICENSE BLOCK ***** */
7168 +/* $Id: mpmontg.c,v 1.22 2010/05/02 22:36:41 nelson%bolyard.com Exp $ */
7169 +
7170 +/* This file implements moduluar exponentiation using Montgomery's
7171 + * method for modular reduction. This file implements the method
7172 + * described as "Improvement 1" in the paper "A Cryptogrpahic Library for
7173 + * the Motorola DSP56000" by Stephen R. Dusse' and Burton S. Kaliski Jr.
7174 + * published in "Advances in Cryptology: Proceedings of EUROCRYPT '90"
7175 + * "Lecture Notes in Computer Science" volume 473, 1991, pg 230-244,
7176 + * published by Springer Verlag.
7177 + */
7178 +
7179 +#define MP_API_COMPATIBLE 1
7180 +#define MP_USING_CACHE_SAFE_MOD_EXP 1
7181 +#include <string.h>
7182 +#include "mpi-priv.h"
7183 +#include "mplogic.h"
7184 +#include "mpprime.h"
7185 +#ifdef MP_USING_MONT_MULF
7186 +#include "montmulf.h"
7187 +#endif
7188 +#include <stddef.h> /* ptrdiff_t */
7189 +
7190 +/* if MP_CHAR_STORE_SLOW is defined, we */
7191 +/* need to know endianness of this platform. */
7192 +#ifdef MP_CHAR_STORE_SLOW
7193 +#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN)
7194 +#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \
7195 + " if you define MP_CHAR_STORE_SLOW."
7196 +#endif
7197 +#endif
7198 +
7199 +#define STATIC
7200 +
7201 +#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */
7202 +
7203 +#if defined(_WIN32_WCE)
7204 +#define ABORT res = MP_UNDEF; goto CLEANUP
7205 +#else
7206 +#define ABORT abort()
7207 +#endif
7208 +
7209 +/* computes T = REDC(T), 2^b == R */
7210 +mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm)
7211 +{
7212 + mp_err res;
7213 + mp_size i;
7214 +
7215 + i = MP_USED(T) + MP_USED(&mmm->N) + 2;
7216 + MP_CHECKOK( s_mp_pad(T, i) );
7217 + for (i = 0; i < MP_USED(&mmm->N); ++i ) {
7218 + mp_digit m_i = MP_DIGIT(T, i) * mmm->n0prime;
7219 + /* T += N * m_i * (MP_RADIX ** i); */
7220 + MP_CHECKOK( s_mp_mul_d_add_offset(&mmm->N, m_i, T, i) );
7221 + }
7222 + s_mp_clamp(T);
7223 +
7224 + /* T /= R */
7225 + s_mp_div_2d(T, mmm->b);
7226 +
7227 + if ((res = s_mp_cmp(T, &mmm->N)) >= 0) {
7228 + /* T = T - N */
7229 + MP_CHECKOK( s_mp_sub(T, &mmm->N) );
7230 +#ifdef DEBUG
7231 + if ((res = mp_cmp(T, &mmm->N)) >= 0) {
7232 + res = MP_UNDEF;
7233 + goto CLEANUP;
7234 + }
7235 +#endif
7236 + }
7237 + res = MP_OKAY;
7238 +CLEANUP:
7239 + return res;
7240 +}
7241 +
7242 +#if !defined(MP_ASSEMBLY_MUL_MONT) && !defined(MP_MONT_USE_MP_MUL)
7243 +mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
7244 + mp_mont_modulus *mmm)
7245 +{
7246 + mp_digit *pb;
7247 + mp_digit m_i;
7248 + mp_err res;
7249 + mp_size ib;
7250 + mp_size useda, usedb;
7251 +
7252 + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
7253 +
7254 + if (MP_USED(a) < MP_USED(b)) {
7255 + const mp_int *xch = b; /* switch a and b, to do fewer outer loops */
7256 + b = a;
7257 + a = xch;
7258 + }
7259 +
7260 + MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
7261 + ib = MP_USED(a) + MP_MAX(MP_USED(b), MP_USED(&mmm->N)) + 2;
7262 + if((res = s_mp_pad(c, ib)) != MP_OKAY)
7263 + goto CLEANUP;
7264 +
7265 + useda = MP_USED(a);
7266 + pb = MP_DIGITS(b);
7267 + s_mpv_mul_d(MP_DIGITS(a), useda, *pb++, MP_DIGITS(c));
7268 + s_mp_setz(MP_DIGITS(c) + useda + 1, ib - (useda + 1));
7269 + m_i = MP_DIGIT(c, 0) * mmm->n0prime;
7270 + s_mp_mul_d_add_offset(&mmm->N, m_i, c, 0);
7271 +
7272 + /* Outer loop: Digits of b */
7273 + usedb = MP_USED(b);
7274 + for (ib = 1; ib < usedb; ib++) {
7275 + mp_digit b_i = *pb++;
7276 +
7277 + /* Inner product: Digits of a */
7278 + if (b_i)
7279 + s_mpv_mul_d_add_prop(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
7280 + m_i = MP_DIGIT(c, ib) * mmm->n0prime;
7281 + s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
7282 + }
7283 + if (usedb < MP_USED(&mmm->N)) {
7284 + for (usedb = MP_USED(&mmm->N); ib < usedb; ++ib ) {
7285 + m_i = MP_DIGIT(c, ib) * mmm->n0prime;
7286 + s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
7287 + }
7288 + }
7289 + s_mp_clamp(c);
7290 + s_mp_div_2d(c, mmm->b);
7291 + if (s_mp_cmp(c, &mmm->N) >= 0) {
7292 + MP_CHECKOK( s_mp_sub(c, &mmm->N) );
7293 + }
7294 + res = MP_OKAY;
7295 +
7296 +CLEANUP:
7297 + return res;
7298 +}
7299 +#endif
7300 +
7301 +STATIC
7302 +mp_err s_mp_to_mont(const mp_int *x, mp_mont_modulus *mmm, mp_int *xMont)
7303 +{
7304 + mp_err res;
7305 +
7306 + /* xMont = x * R mod N where N is modulus */
7307 + MP_CHECKOK( mpl_lsh(x, xMont, mmm->b) ); /* xMont = x << b */
7308 + MP_CHECKOK( mp_div(xMont, &mmm->N, 0, xMont) ); /* mod N */
7309 +CLEANUP:
7310 + return res;
7311 +}
7312 +
7313 +#ifdef MP_USING_MONT_MULF
7314 +
7315 +/* the floating point multiply is already cache safe,
7316 + * don't turn on cache safe unless we specifically
7317 + * force it */
7318 +#ifndef MP_FORCE_CACHE_SAFE
7319 +#undef MP_USING_CACHE_SAFE_MOD_EXP
7320 +#endif
7321 +
7322 +unsigned int mp_using_mont_mulf = 1;
7323 +
7324 +/* computes montgomery square of the integer in mResult */
7325 +#define SQR \
7326 + conv_i32_to_d32_and_d16(dm1, d16Tmp, mResult, nLen); \
7327 + mont_mulf_noconv(mResult, dm1, d16Tmp, \
7328 + dTmp, dn, MP_DIGITS(modulus), nLen, dn0)
7329 +
7330 +/* computes montgomery product of x and the integer in mResult */
7331 +#define MUL(x) \
7332 + conv_i32_to_d32(dm1, mResult, nLen); \
7333 + mont_mulf_noconv(mResult, dm1, oddPowers[x], \
7334 + dTmp, dn, MP_DIGITS(modulus), nLen, dn0)
7335 +
7336 +/* Do modular exponentiation using floating point multiply code. */
7337 +mp_err mp_exptmod_f(const mp_int * montBase,
7338 + const mp_int * exponent,
7339 + const mp_int * modulus,
7340 + mp_int * result,
7341 + mp_mont_modulus *mmm,
7342 + int nLen,
7343 + mp_size bits_in_exponent,
7344 + mp_size window_bits,
7345 + mp_size odd_ints)
7346 +{
7347 + mp_digit *mResult;
7348 + double *dBuf = 0, *dm1, *dn, *dSqr, *d16Tmp, *dTmp;
7349 + double dn0;
7350 + mp_size i;
7351 + mp_err res;
7352 + int expOff;
7353 + int dSize = 0, oddPowSize, dTmpSize;
7354 + mp_int accum1;
7355 + double *oddPowers[MAX_ODD_INTS];
7356 +
7357 + /* function for computing n0prime only works if n0 is odd */
7358 +
7359 + MP_DIGITS(&accum1) = 0;
7360 +
7361 + for (i = 0; i < MAX_ODD_INTS; ++i)
7362 + oddPowers[i] = 0;
7363 +
7364 + MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) );
7365 +
7366 + mp_set(&accum1, 1);
7367 + MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) );
7368 + MP_CHECKOK( s_mp_pad(&accum1, nLen) );
7369 +
7370 + oddPowSize = 2 * nLen + 1;
7371 + dTmpSize = 2 * oddPowSize;
7372 + dSize = sizeof(double) * (nLen * 4 + 1 +
7373 + ((odd_ints + 1) * oddPowSize) + dTmpSize);
7374 + dBuf = (double *)malloc(dSize);
7375 + dm1 = dBuf; /* array of d32 */
7376 + dn = dBuf + nLen; /* array of d32 */
7377 + dSqr = dn + nLen; /* array of d32 */
7378 + d16Tmp = dSqr + nLen; /* array of d16 */
7379 + dTmp = d16Tmp + oddPowSize;
7380 +
7381 + for (i = 0; i < odd_ints; ++i) {
7382 + oddPowers[i] = dTmp;
7383 + dTmp += oddPowSize;
7384 + }
7385 + mResult = (mp_digit *)(dTmp + dTmpSize); /* size is nLen + 1 */
7386 +
7387 + /* Make dn and dn0 */
7388 + conv_i32_to_d32(dn, MP_DIGITS(modulus), nLen);
7389 + dn0 = (double)(mmm->n0prime & 0xffff);
7390 +
7391 + /* Make dSqr */
7392 + conv_i32_to_d32_and_d16(dm1, oddPowers[0], MP_DIGITS(montBase), nLen);
7393 + mont_mulf_noconv(mResult, dm1, oddPowers[0],
7394 + dTmp, dn, MP_DIGITS(modulus), nLen, dn0);
7395 + conv_i32_to_d32(dSqr, mResult, nLen);
7396 +
7397 + for (i = 1; i < odd_ints; ++i) {
7398 + mont_mulf_noconv(mResult, dSqr, oddPowers[i - 1],
7399 + dTmp, dn, MP_DIGITS(modulus), nLen, dn0);
7400 + conv_i32_to_d16(oddPowers[i], mResult, nLen);
7401 + }
7402 +
7403 + s_mp_copy(MP_DIGITS(&accum1), mResult, nLen); /* from, to, len */
7404 +
7405 + for (expOff = bits_in_exponent - window_bits; expOff >= 0; expOff -= window_b its) {
7406 + mp_size smallExp;
7407 + MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) );
7408 + smallExp = (mp_size)res;
7409 +
7410 + if (window_bits == 1) {
7411 + if (!smallExp) {
7412 + SQR;
7413 + } else if (smallExp & 1) {
7414 + SQR; MUL(0);
7415 + } else {
7416 + ABORT;
7417 + }
7418 + } else if (window_bits == 4) {
7419 + if (!smallExp) {
7420 + SQR; SQR; SQR; SQR;
7421 + } else if (smallExp & 1) {
7422 + SQR; SQR; SQR; SQR; MUL(smallExp/2);
7423 + } else if (smallExp & 2) {
7424 + SQR; SQR; SQR; MUL(smallExp/4); SQR;
7425 + } else if (smallExp & 4) {
7426 + SQR; SQR; MUL(smallExp/8); SQR; SQR;
7427 + } else if (smallExp & 8) {
7428 + SQR; MUL(smallExp/16); SQR; SQR; SQR;
7429 + } else {
7430 + ABORT;
7431 + }
7432 + } else if (window_bits == 5) {
7433 + if (!smallExp) {
7434 + SQR; SQR; SQR; SQR; SQR;
7435 + } else if (smallExp & 1) {
7436 + SQR; SQR; SQR; SQR; SQR; MUL(smallExp/2);
7437 + } else if (smallExp & 2) {
7438 + SQR; SQR; SQR; SQR; MUL(smallExp/4); SQR;
7439 + } else if (smallExp & 4) {
7440 + SQR; SQR; SQR; MUL(smallExp/8); SQR; SQR;
7441 + } else if (smallExp & 8) {
7442 + SQR; SQR; MUL(smallExp/16); SQR; SQR; SQR;
7443 + } else if (smallExp & 0x10) {
7444 + SQR; MUL(smallExp/32); SQR; SQR; SQR; SQR;
7445 + } else {
7446 + ABORT;
7447 + }
7448 + } else if (window_bits == 6) {
7449 + if (!smallExp) {
7450 + SQR; SQR; SQR; SQR; SQR; SQR;
7451 + } else if (smallExp & 1) {
7452 + SQR; SQR; SQR; SQR; SQR; SQR; MUL(smallExp/2);
7453 + } else if (smallExp & 2) {
7454 + SQR; SQR; SQR; SQR; SQR; MUL(smallExp/4); SQR;
7455 + } else if (smallExp & 4) {
7456 + SQR; SQR; SQR; SQR; MUL(smallExp/8); SQR; SQR;
7457 + } else if (smallExp & 8) {
7458 + SQR; SQR; SQR; MUL(smallExp/16); SQR; SQR; SQR;
7459 + } else if (smallExp & 0x10) {
7460 + SQR; SQR; MUL(smallExp/32); SQR; SQR; SQR; SQR;
7461 + } else if (smallExp & 0x20) {
7462 + SQR; MUL(smallExp/64); SQR; SQR; SQR; SQR; SQR;
7463 + } else {
7464 + ABORT;
7465 + }
7466 + } else {
7467 + ABORT;
7468 + }
7469 + }
7470 +
7471 + s_mp_copy(mResult, MP_DIGITS(&accum1), nLen); /* from, to, len */
7472 +
7473 + res = s_mp_redc(&accum1, mmm);
7474 + mp_exch(&accum1, result);
7475 +
7476 +CLEANUP:
7477 + mp_clear(&accum1);
7478 + if (dBuf) {
7479 + if (dSize)
7480 + memset(dBuf, 0, dSize);
7481 + free(dBuf);
7482 + }
7483 +
7484 + return res;
7485 +}
7486 +#undef SQR
7487 +#undef MUL
7488 +#endif
7489 +
7490 +#define SQR(a,b) \
7491 + MP_CHECKOK( mp_sqr(a, b) );\
7492 + MP_CHECKOK( s_mp_redc(b, mmm) )
7493 +
7494 +#if defined(MP_MONT_USE_MP_MUL)
7495 +#define MUL(x,a,b) \
7496 + MP_CHECKOK( mp_mul(a, oddPowers + (x), b) ); \
7497 + MP_CHECKOK( s_mp_redc(b, mmm) )
7498 +#else
7499 +#define MUL(x,a,b) \
7500 + MP_CHECKOK( s_mp_mul_mont(a, oddPowers + (x), b, mmm) )
7501 +#endif
7502 +
7503 +#define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp
7504 +
7505 +/* Do modular exponentiation using integer multiply code. */
7506 +mp_err mp_exptmod_i(const mp_int * montBase,
7507 + const mp_int * exponent,
7508 + const mp_int * modulus,
7509 + mp_int * result,
7510 + mp_mont_modulus *mmm,
7511 + int nLen,
7512 + mp_size bits_in_exponent,
7513 + mp_size window_bits,
7514 + mp_size odd_ints)
7515 +{
7516 + mp_int *pa1, *pa2, *ptmp;
7517 + mp_size i;
7518 + mp_err res;
7519 + int expOff;
7520 + mp_int accum1, accum2, power2, oddPowers[MAX_ODD_INTS];
7521 +
7522 + /* power2 = base ** 2; oddPowers[i] = base ** (2*i + 1); */
7523 + /* oddPowers[i] = base ** (2*i + 1); */
7524 +
7525 + MP_DIGITS(&accum1) = 0;
7526 + MP_DIGITS(&accum2) = 0;
7527 + MP_DIGITS(&power2) = 0;
7528 + for (i = 0; i < MAX_ODD_INTS; ++i) {
7529 + MP_DIGITS(oddPowers + i) = 0;
7530 + }
7531 +
7532 + MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) );
7533 + MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) );
7534 +
7535 + MP_CHECKOK( mp_init_copy(&oddPowers[0], montBase) );
7536 +
7537 + mp_init_size(&power2, nLen + 2 * MP_USED(montBase) + 2);
7538 + MP_CHECKOK( mp_sqr(montBase, &power2) ); /* power2 = montBase ** 2 */
7539 + MP_CHECKOK( s_mp_redc(&power2, mmm) );
7540 +
7541 + for (i = 1; i < odd_ints; ++i) {
7542 + mp_init_size(oddPowers + i, nLen + 2 * MP_USED(&power2) + 2);
7543 + MP_CHECKOK( mp_mul(oddPowers + (i - 1), &power2, oddPowers + i) );
7544 + MP_CHECKOK( s_mp_redc(oddPowers + i, mmm) );
7545 + }
7546 +
7547 + /* set accumulator to montgomery residue of 1 */
7548 + mp_set(&accum1, 1);
7549 + MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) );
7550 + pa1 = &accum1;
7551 + pa2 = &accum2;
7552 +
7553 + for (expOff = bits_in_exponent - window_bits; expOff >= 0; expOff -= window_b its) {
7554 + mp_size smallExp;
7555 + MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) );
7556 + smallExp = (mp_size)res;
7557 +
7558 + if (window_bits == 1) {
7559 + if (!smallExp) {
7560 + SQR(pa1,pa2); SWAPPA;
7561 + } else if (smallExp & 1) {
7562 + SQR(pa1,pa2); MUL(0,pa2,pa1);
7563 + } else {
7564 + ABORT;
7565 + }
7566 + } else if (window_bits == 4) {
7567 + if (!smallExp) {
7568 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7569 + } else if (smallExp & 1) {
7570 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7571 + MUL(smallExp/2, pa1,pa2); SWAPPA;
7572 + } else if (smallExp & 2) {
7573 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2);
7574 + MUL(smallExp/4,pa2,pa1); SQR(pa1,pa2); SWAPPA;
7575 + } else if (smallExp & 4) {
7576 + SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/8,pa1,pa2);
7577 + SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
7578 + } else if (smallExp & 8) {
7579 + SQR(pa1,pa2); MUL(smallExp/16,pa2,pa1); SQR(pa1,pa2);
7580 + SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
7581 + } else {
7582 + ABORT;
7583 + }
7584 + } else if (window_bits == 5) {
7585 + if (!smallExp) {
7586 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7587 + SQR(pa1,pa2); SWAPPA;
7588 + } else if (smallExp & 1) {
7589 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7590 + SQR(pa1,pa2); MUL(smallExp/2,pa2,pa1);
7591 + } else if (smallExp & 2) {
7592 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7593 + MUL(smallExp/4,pa1,pa2); SQR(pa2,pa1);
7594 + } else if (smallExp & 4) {
7595 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2);
7596 + MUL(smallExp/8,pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7597 + } else if (smallExp & 8) {
7598 + SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/16,pa1,pa2);
7599 + SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7600 + } else if (smallExp & 0x10) {
7601 + SQR(pa1,pa2); MUL(smallExp/32,pa2,pa1); SQR(pa1,pa2);
7602 + SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7603 + } else {
7604 + ABORT;
7605 + }
7606 + } else if (window_bits == 6) {
7607 + if (!smallExp) {
7608 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7609 + SQR(pa1,pa2); SQR(pa2,pa1);
7610 + } else if (smallExp & 1) {
7611 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7612 + SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/2,pa1,pa2); SWAPPA;
7613 + } else if (smallExp & 2) {
7614 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7615 + SQR(pa1,pa2); MUL(smallExp/4,pa2,pa1); SQR(pa1,pa2); SWAPPA;
7616 + } else if (smallExp & 4) {
7617 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7618 + MUL(smallExp/8,pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
7619 + } else if (smallExp & 8) {
7620 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2);
7621 + MUL(smallExp/16,pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
7622 + SQR(pa1,pa2); SWAPPA;
7623 + } else if (smallExp & 0x10) {
7624 + SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/32,pa1,pa2);
7625 + SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
7626 + } else if (smallExp & 0x20) {
7627 + SQR(pa1,pa2); MUL(smallExp/64,pa2,pa1); SQR(pa1,pa2);
7628 + SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
7629 + } else {
7630 + ABORT;
7631 + }
7632 + } else {
7633 + ABORT;
7634 + }
7635 + }
7636 +
7637 + res = s_mp_redc(pa1, mmm);
7638 + mp_exch(pa1, result);
7639 +
7640 +CLEANUP:
7641 + mp_clear(&accum1);
7642 + mp_clear(&accum2);
7643 + mp_clear(&power2);
7644 + for (i = 0; i < odd_ints; ++i) {
7645 + mp_clear(oddPowers + i);
7646 + }
7647 + return res;
7648 +}
7649 +#undef SQR
7650 +#undef MUL
7651 +
7652 +#ifdef MP_USING_CACHE_SAFE_MOD_EXP
7653 +unsigned int mp_using_cache_safe_exp = 1;
7654 +#endif
7655 +
7656 +mp_err mp_set_safe_modexp(int value)
7657 +{
7658 +#ifdef MP_USING_CACHE_SAFE_MOD_EXP
7659 + mp_using_cache_safe_exp = value;
7660 + return MP_OKAY;
7661 +#else
7662 + if (value == 0) {
7663 + return MP_OKAY;
7664 + }
7665 + return MP_BADARG;
7666 +#endif
7667 +}
7668 +
7669 +#ifdef MP_USING_CACHE_SAFE_MOD_EXP
7670 +#define WEAVE_WORD_SIZE 4
7671 +
7672 +#ifndef MP_CHAR_STORE_SLOW
7673 +/*
7674 + * mpi_to_weave takes an array of bignums, a matrix in which each bignum
7675 + * occupies all the columns of a row, and transposes it into a matrix in
7676 + * which each bignum occupies a column of every row. The first row of the
7677 + * input matrix becomes the first column of the output matrix. The n'th
7678 + * row of input becomes the n'th column of output. The input data is said
7679 + * to be "interleaved" or "woven" into the output matrix.
7680 + *
7681 + * The array of bignums is left in this woven form. Each time a single
7682 + * bignum value is needed, it is recreated by fetching the n'th column,
7683 + * forming a single row which is the new bignum.
7684 + *
7685 + * The purpose of this interleaving is make it impossible to determine which
7686 + * of the bignums is being used in any one operation by examining the pattern
7687 + * of cache misses.
7688 + *
7689 + * The weaving function does not transpose the entire input matrix in one call.
7690 + * It transposes 4 rows of mp_ints into their respective columns of output.
7691 + *
7692 + * There are two different implementations of the weaving and unweaving code
7693 + * in this file. One uses byte loads and stores. The second uses loads and
7694 + * stores of mp_weave_word size values. The weaved forms of these two
7695 + * implementations differ. Consequently, each one has its own explanation.
7696 + *
7697 + * Here is the explanation for the byte-at-a-time implementation.
7698 + *
7699 + * This implementation treats each mp_int bignum as an array of bytes,
7700 + * rather than as an array of mp_digits. It stores those bytes as a
7701 + * column of bytes in the output matrix. It doesn't care if the machine
7702 + * uses big-endian or little-endian byte ordering within mp_digits.
7703 + * The first byte of the mp_digit array becomes the first byte in the output
7704 + * column, regardless of whether that byte is the MSB or LSB of the mp_digit.
7705 + *
7706 + * "bignums" is an array of mp_ints.
7707 + * It points to four rows, four mp_ints, a subset of a larger array of mp_ints.
7708 + *
7709 + * "weaved" is the weaved output matrix.
7710 + * The first byte of bignums[0] is stored in weaved[0].
7711 + *
7712 + * "nBignums" is the total number of bignums in the array of which "bignums"
7713 + * is a part.
7714 + *
7715 + * "nDigits" is the size in mp_digits of each mp_int in the "bignums" array.
7716 + * mp_ints that use less than nDigits digits are logically padded with zeros
7717 + * while being stored in the weaved array.
7718 + */
7719 +mp_err mpi_to_weave(const mp_int *bignums,
7720 + unsigned char *weaved,
7721 + mp_size nDigits, /* in each mp_int of input */
7722 + mp_size nBignums) /* in the entire source array */
7723 +{
7724 + mp_size i;
7725 + unsigned char * endDest = weaved + (nDigits * nBignums * sizeof(mp_digit));
7726 +
7727 + for (i=0; i < WEAVE_WORD_SIZE; i++) {
7728 + mp_size used = MP_USED(&bignums[i]);
7729 + unsigned char *pSrc = (unsigned char *)MP_DIGITS(&bignums[i]);
7730 + unsigned char *endSrc = pSrc + (used * sizeof(mp_digit));
7731 + unsigned char *pDest = weaved + i;
7732 +
7733 + ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG);
7734 + ARGCHK(used <= nDigits, MP_BADARG);
7735 +
7736 + for (; pSrc < endSrc; pSrc++) {
7737 + *pDest = *pSrc;
7738 + pDest += nBignums;
7739 + }
7740 + while (pDest < endDest) {
7741 + *pDest = 0;
7742 + pDest += nBignums;
7743 + }
7744 + }
7745 +
7746 + return MP_OKAY;
7747 +}
7748 +
7749 +/* Reverse the operation above for one mp_int.
7750 + * Reconstruct one mp_int from its column in the weaved array.
7751 + * "pSrc" points to the offset into the weave array of the bignum we
7752 + * are going to reconstruct.
7753 + */
7754 +mp_err weave_to_mpi(mp_int *a, /* output, result */
7755 + const unsigned char *pSrc, /* input, byte matrix */
7756 + mp_size nDigits, /* per mp_int output */
7757 + mp_size nBignums) /* bignums in weaved matrix */
7758 +{
7759 + unsigned char *pDest = (unsigned char *)MP_DIGITS(a);
7760 + unsigned char *endDest = pDest + (nDigits * sizeof(mp_digit));
7761 +
7762 + MP_SIGN(a) = MP_ZPOS;
7763 + MP_USED(a) = nDigits;
7764 +
7765 + for (; pDest < endDest; pSrc += nBignums, pDest++) {
7766 + *pDest = *pSrc;
7767 + }
7768 + s_mp_clamp(a);
7769 + return MP_OKAY;
7770 +}
7771 +
7772 +#else
7773 +
7774 +/* Need a primitive that we know is 32 bits long... */
7775 +/* this is true on all modern processors we know of today*/
7776 +typedef unsigned int mp_weave_word;
7777 +
7778 +/*
7779 + * on some platforms character stores into memory is very expensive since they
7780 + * generate a read/modify/write operation on the bus. On those platforms
7781 + * we need to do integer writes to the bus. Because of some unrolled code,
7782 + * in this current code the size of mp_weave_word must be four. The code that
7783 + * makes this assumption explicity is called out. (on some platforms a write
7784 + * of 4 bytes still requires a single read-modify-write operation.
7785 + *
7786 + * This function is takes the identical parameters as the function above,
7787 + * however it lays out the final array differently. Where the previous function
7788 + * treats the mpi_int as an byte array, this function treats it as an array of
7789 + * mp_digits where each digit is stored in big endian order.
7790 + *
7791 + * since we need to interleave on a byte by byte basis, we need to collect
7792 + * several mpi structures together into a single uint32 before we write. We
7793 + * also need to make sure the uint32 is arranged so that the first value of
7794 + * the first array winds up in b[0]. This means construction of that uint32
7795 + * is endian specific (even though the layout of the mp_digits in the array
7796 + * is always big endian).
7797 + *
7798 + * The final data is stored as follows :
7799 + *
7800 + * Our same logical array p array, m is sizeof(mp_digit),
7801 + * N is still count and n is now b_size. If we define p[i].digit[j]0 as the
7802 + * most significant byte of the word p[i].digit[j], p[i].digit[j]1 as
7803 + * the next most significant byte of p[i].digit[j], ... and p[i].digit[j]m-1
7804 + * is the least significant byte.
7805 + * Our array would look like:
7806 + * p[0].digit[0]0 p[1].digit[0]0 ... p[N-2].digit[0]0 p[N-1].digit[0 ]0
7807 + * p[0].digit[0]1 p[1].digit[0]1 ... p[N-2].digit[0]1 p[N-1].digit[0 ]1
7808 + * . .
7809 + * p[0].digit[0]m-1 p[1].digit[0]m-1 ... p[N-2].digit[0]m-1 p[N-1].digit[0 ]m-1
7810 + * p[0].digit[1]0 p[1].digit[1]0 ... p[N-2].digit[1]0 p[N-1].digit[1 ]0
7811 + * . .
7812 + * . .
7813 + * p[0].digit[n-1]m-2 p[1].digit[n-1]m-2 ... p[N-2].digit[n-1]m-2 p[N-1].digit[ n-1]m-2
7814 + * p[0].digit[n-1]m-1 p[1].digit[n-1]m-1 ... p[N-2].digit[n-1]m-1 p[N-1].digit[ n-1]m-1
7815 + *
7816 + */
7817 +mp_err mpi_to_weave(const mp_int *a, unsigned char *b,
7818 + mp_size b_size, mp_size count)
7819 +{
7820 + mp_size i;
7821 + mp_digit *digitsa0;
7822 + mp_digit *digitsa1;
7823 + mp_digit *digitsa2;
7824 + mp_digit *digitsa3;
7825 + mp_size useda0;
7826 + mp_size useda1;
7827 + mp_size useda2;
7828 + mp_size useda3;
7829 + mp_weave_word *weaved = (mp_weave_word *)b;
7830 +
7831 + count = count/sizeof(mp_weave_word);
7832 +
7833 + /* this code pretty much depends on this ! */
7834 +#if MP_ARGCHK == 2
7835 + assert(WEAVE_WORD_SIZE == 4);
7836 + assert(sizeof(mp_weave_word) == 4);
7837 +#endif
7838 +
7839 + digitsa0 = MP_DIGITS(&a[0]);
7840 + digitsa1 = MP_DIGITS(&a[1]);
7841 + digitsa2 = MP_DIGITS(&a[2]);
7842 + digitsa3 = MP_DIGITS(&a[3]);
7843 + useda0 = MP_USED(&a[0]);
7844 + useda1 = MP_USED(&a[1]);
7845 + useda2 = MP_USED(&a[2]);
7846 + useda3 = MP_USED(&a[3]);
7847 +
7848 + ARGCHK(MP_SIGN(&a[0]) == MP_ZPOS, MP_BADARG);
7849 + ARGCHK(MP_SIGN(&a[1]) == MP_ZPOS, MP_BADARG);
7850 + ARGCHK(MP_SIGN(&a[2]) == MP_ZPOS, MP_BADARG);
7851 + ARGCHK(MP_SIGN(&a[3]) == MP_ZPOS, MP_BADARG);
7852 + ARGCHK(useda0 <= b_size, MP_BADARG);
7853 + ARGCHK(useda1 <= b_size, MP_BADARG);
7854 + ARGCHK(useda2 <= b_size, MP_BADARG);
7855 + ARGCHK(useda3 <= b_size, MP_BADARG);
7856 +
7857 +#define SAFE_FETCH(digit, used, word) ((word) < (used) ? (digit[word]) : 0)
7858 +
7859 + for (i=0; i < b_size; i++) {
7860 + mp_digit d0 = SAFE_FETCH(digitsa0,useda0,i);
7861 + mp_digit d1 = SAFE_FETCH(digitsa1,useda1,i);
7862 + mp_digit d2 = SAFE_FETCH(digitsa2,useda2,i);
7863 + mp_digit d3 = SAFE_FETCH(digitsa3,useda3,i);
7864 + register mp_weave_word acc;
7865 +
7866 +/*
7867 + * ONE_STEP takes the MSB of each of our current digits and places that
7868 + * byte in the appropriate position for writing to the weaved array.
7869 + * On little endian:
7870 + * b3 b2 b1 b0
7871 + * On big endian:
7872 + * b0 b1 b2 b3
7873 + * When the data is written it would always wind up:
7874 + * b[0] = b0
7875 + * b[1] = b1
7876 + * b[2] = b2
7877 + * b[3] = b3
7878 + *
7879 + * Once we've written the MSB, we shift the whole digit up left one
7880 + * byte, putting the Next Most Significant Byte in the MSB position,
7881 + * so we we repeat the next one step that byte will be written.
7882 + * NOTE: This code assumes sizeof(mp_weave_word) and MP_WEAVE_WORD_SIZE
7883 + * is 4.
7884 + */
7885 +#ifdef MP_IS_LITTLE_ENDIAN
7886 +#define MPI_WEAVE_ONE_STEP \
7887 + acc = (d0 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \
7888 + acc |= (d1 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \
7889 + acc |= (d2 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \
7890 + acc |= (d3 >> (MP_DIGIT_BIT-32)) & 0xff000000; d3 <<= 8; /*b3*/ \
7891 + *weaved = acc; weaved += count;
7892 +#else
7893 +#define MPI_WEAVE_ONE_STEP \
7894 + acc = (d0 >> (MP_DIGIT_BIT-32)) & 0xff000000; d0 <<= 8; /*b0*/ \
7895 + acc |= (d1 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \
7896 + acc |= (d2 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \
7897 + acc |= (d3 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \
7898 + *weaved = acc; weaved += count;
7899 +#endif
7900 + switch (sizeof(mp_digit)) {
7901 + case 32:
7902 + MPI_WEAVE_ONE_STEP
7903 + MPI_WEAVE_ONE_STEP
7904 + MPI_WEAVE_ONE_STEP
7905 + MPI_WEAVE_ONE_STEP
7906 + MPI_WEAVE_ONE_STEP
7907 + MPI_WEAVE_ONE_STEP
7908 + MPI_WEAVE_ONE_STEP
7909 + MPI_WEAVE_ONE_STEP
7910 + MPI_WEAVE_ONE_STEP
7911 + MPI_WEAVE_ONE_STEP
7912 + MPI_WEAVE_ONE_STEP
7913 + MPI_WEAVE_ONE_STEP
7914 + MPI_WEAVE_ONE_STEP
7915 + MPI_WEAVE_ONE_STEP
7916 + MPI_WEAVE_ONE_STEP
7917 + MPI_WEAVE_ONE_STEP
7918 + case 16:
7919 + MPI_WEAVE_ONE_STEP
7920 + MPI_WEAVE_ONE_STEP
7921 + MPI_WEAVE_ONE_STEP
7922 + MPI_WEAVE_ONE_STEP
7923 + MPI_WEAVE_ONE_STEP
7924 + MPI_WEAVE_ONE_STEP
7925 + MPI_WEAVE_ONE_STEP
7926 + MPI_WEAVE_ONE_STEP
7927 + case 8:
7928 + MPI_WEAVE_ONE_STEP
7929 + MPI_WEAVE_ONE_STEP
7930 + MPI_WEAVE_ONE_STEP
7931 + MPI_WEAVE_ONE_STEP
7932 + case 4:
7933 + MPI_WEAVE_ONE_STEP
7934 + MPI_WEAVE_ONE_STEP
7935 + case 2:
7936 + MPI_WEAVE_ONE_STEP
7937 + case 1:
7938 + MPI_WEAVE_ONE_STEP
7939 + break;
7940 + }
7941 + }
7942 +
7943 + return MP_OKAY;
7944 +}
7945 +
7946 +/* reverse the operation above for one entry.
7947 + * b points to the offset into the weave array of the power we are
7948 + * calculating */
7949 +mp_err weave_to_mpi(mp_int *a, const unsigned char *b,
7950 + mp_size b_size, mp_size count)
7951 +{
7952 + mp_digit *pb = MP_DIGITS(a);
7953 + mp_digit *end = &pb[b_size];
7954 +
7955 + MP_SIGN(a) = MP_ZPOS;
7956 + MP_USED(a) = b_size;
7957 +
7958 + for (; pb < end; pb++) {
7959 + register mp_digit digit;
7960 +
7961 + digit = *b << 8; b += count;
7962 +#define MPI_UNWEAVE_ONE_STEP digit |= *b; b += count; digit = digit << 8;
7963 + switch (sizeof(mp_digit)) {
7964 + case 32:
7965 + MPI_UNWEAVE_ONE_STEP
7966 + MPI_UNWEAVE_ONE_STEP
7967 + MPI_UNWEAVE_ONE_STEP
7968 + MPI_UNWEAVE_ONE_STEP
7969 + MPI_UNWEAVE_ONE_STEP
7970 + MPI_UNWEAVE_ONE_STEP
7971 + MPI_UNWEAVE_ONE_STEP
7972 + MPI_UNWEAVE_ONE_STEP
7973 + MPI_UNWEAVE_ONE_STEP
7974 + MPI_UNWEAVE_ONE_STEP
7975 + MPI_UNWEAVE_ONE_STEP
7976 + MPI_UNWEAVE_ONE_STEP
7977 + MPI_UNWEAVE_ONE_STEP
7978 + MPI_UNWEAVE_ONE_STEP
7979 + MPI_UNWEAVE_ONE_STEP
7980 + MPI_UNWEAVE_ONE_STEP
7981 + case 16:
7982 + MPI_UNWEAVE_ONE_STEP
7983 + MPI_UNWEAVE_ONE_STEP
7984 + MPI_UNWEAVE_ONE_STEP
7985 + MPI_UNWEAVE_ONE_STEP
7986 + MPI_UNWEAVE_ONE_STEP
7987 + MPI_UNWEAVE_ONE_STEP
7988 + MPI_UNWEAVE_ONE_STEP
7989 + MPI_UNWEAVE_ONE_STEP
7990 + case 8:
7991 + MPI_UNWEAVE_ONE_STEP
7992 + MPI_UNWEAVE_ONE_STEP
7993 + MPI_UNWEAVE_ONE_STEP
7994 + MPI_UNWEAVE_ONE_STEP
7995 + case 4:
7996 + MPI_UNWEAVE_ONE_STEP
7997 + MPI_UNWEAVE_ONE_STEP
7998 + case 2:
7999 + break;
8000 + }
8001 + digit |= *b; b += count;
8002 +
8003 + *pb = digit;
8004 + }
8005 + s_mp_clamp(a);
8006 + return MP_OKAY;
8007 +}
8008 +#endif
8009 +
8010 +
8011 +#define SQR(a,b) \
8012 + MP_CHECKOK( mp_sqr(a, b) );\
8013 + MP_CHECKOK( s_mp_redc(b, mmm) )
8014 +
8015 +#if defined(MP_MONT_USE_MP_MUL)
8016 +#define MUL_NOWEAVE(x,a,b) \
8017 + MP_CHECKOK( mp_mul(a, x, b) ); \
8018 + MP_CHECKOK( s_mp_redc(b, mmm) )
8019 +#else
8020 +#define MUL_NOWEAVE(x,a,b) \
8021 + MP_CHECKOK( s_mp_mul_mont(a, x, b, mmm) )
8022 +#endif
8023 +
8024 +#define MUL(x,a,b) \
8025 + MP_CHECKOK( weave_to_mpi(&tmp, powers + (x), nLen, num_powers) ); \
8026 + MUL_NOWEAVE(&tmp,a,b)
8027 +
8028 +#define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp
8029 +#define MP_ALIGN(x,y) ((((ptrdiff_t)(x))+((y)-1))&(((ptrdiff_t)0)-(y)))
8030 +
8031 +/* Do modular exponentiation using integer multiply code. */
8032 +mp_err mp_exptmod_safe_i(const mp_int * montBase,
8033 + const mp_int * exponent,
8034 + const mp_int * modulus,
8035 + mp_int * result,
8036 + mp_mont_modulus *mmm,
8037 + int nLen,
8038 + mp_size bits_in_exponent,
8039 + mp_size window_bits,
8040 + mp_size num_powers)
8041 +{
8042 + mp_int *pa1, *pa2, *ptmp;
8043 + mp_size i;
8044 + mp_size first_window;
8045 + mp_err res;
8046 + int expOff;
8047 + mp_int accum1, accum2, accum[WEAVE_WORD_SIZE];
8048 + mp_int tmp;
8049 + unsigned char *powersArray;
8050 + unsigned char *powers;
8051 +
8052 + MP_DIGITS(&accum1) = 0;
8053 + MP_DIGITS(&accum2) = 0;
8054 + MP_DIGITS(&accum[0]) = 0;
8055 + MP_DIGITS(&accum[1]) = 0;
8056 + MP_DIGITS(&accum[2]) = 0;
8057 + MP_DIGITS(&accum[3]) = 0;
8058 + MP_DIGITS(&tmp) = 0;
8059 +
8060 + powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1));
8061 + if (powersArray == NULL) {
8062 + res = MP_MEM;
8063 + goto CLEANUP;
8064 + }
8065 +
8066 + /* powers[i] = base ** (i); */
8067 + powers = (unsigned char *)MP_ALIGN(powersArray,num_powers);
8068 +
8069 + /* grab the first window value. This allows us to preload accumulator1
8070 + * and save a conversion, some squares and a multiple*/
8071 + MP_CHECKOK( mpl_get_bits(exponent,
8072 + bits_in_exponent-window_bits, window_bits) );
8073 + first_window = (mp_size)res;
8074 +
8075 + MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) );
8076 + MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) );
8077 + MP_CHECKOK( mp_init_size(&tmp, 3 * nLen + 2) );
8078 +
8079 + /* build the first WEAVE_WORD powers inline */
8080 + /* if WEAVE_WORD_SIZE is not 4, this code will have to change */
8081 + if (num_powers > 2) {
8082 + MP_CHECKOK( mp_init_size(&accum[0], 3 * nLen + 2) );
8083 + MP_CHECKOK( mp_init_size(&accum[1], 3 * nLen + 2) );
8084 + MP_CHECKOK( mp_init_size(&accum[2], 3 * nLen + 2) );
8085 + MP_CHECKOK( mp_init_size(&accum[3], 3 * nLen + 2) );
8086 + mp_set(&accum[0], 1);
8087 + MP_CHECKOK( s_mp_to_mont(&accum[0], mmm, &accum[0]) );
8088 + MP_CHECKOK( mp_copy(montBase, &accum[1]) );
8089 + SQR(montBase, &accum[2]);
8090 + MUL_NOWEAVE(montBase, &accum[2], &accum[3]);
8091 + MP_CHECKOK( mpi_to_weave(accum, powers, nLen, num_powers) );
8092 + if (first_window < 4) {
8093 + MP_CHECKOK( mp_copy(&accum[first_window], &accum1) );
8094 + first_window = num_powers;
8095 + }
8096 + } else {
8097 + if (first_window == 0) {
8098 + mp_set(&accum1, 1);
8099 + MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) );
8100 + } else {
8101 + /* assert first_window == 1? */
8102 + MP_CHECKOK( mp_copy(montBase, &accum1) );
8103 + }
8104 + }
8105 +
8106 + /*
8107 + * calculate all the powers in the powers array.
8108 + * this adds 2**(k-1)-2 square operations over just calculating the
8109 + * odd powers where k is the window size in the two other mp_modexpt
8110 + * implementations in this file. We will get some of that
8111 + * back by not needing the first 'k' squares and one multiply for the
8112 + * first window */
8113 + for (i = WEAVE_WORD_SIZE; i < num_powers; i++) {
8114 + int acc_index = i & (WEAVE_WORD_SIZE-1); /* i % WEAVE_WORD_SIZE */
8115 + if ( i & 1 ) {
8116 + MUL_NOWEAVE(montBase, &accum[acc_index-1] , &accum[acc_index]);
8117 + /* we've filled the array do our 'per array' processing */
8118 + if (acc_index == (WEAVE_WORD_SIZE-1)) {
8119 + MP_CHECKOK( mpi_to_weave(accum, powers + i - (WEAVE_WORD_SIZE-1),
8120 + nLen, num_powers) );
8121 +
8122 + if (first_window <= i) {
8123 + MP_CHECKOK( mp_copy(&accum[first_window & (WEAVE_WORD_SIZE-1)],
8124 + &accum1) );
8125 + first_window = num_powers;
8126 + }
8127 + }
8128 + } else {
8129 + /* up to 8 we can find 2^i-1 in the accum array, but at 8 we our source
8130 + * and target are the same so we need to copy.. After that, the
8131 + * value is overwritten, so we need to fetch it from the stored
8132 + * weave array */
8133 + if (i > 2* WEAVE_WORD_SIZE) {
8134 + MP_CHECKOK(weave_to_mpi(&accum2, powers+i/2, nLen, num_powers));
8135 + SQR(&accum2, &accum[acc_index]);
8136 + } else {
8137 + int half_power_index = (i/2) & (WEAVE_WORD_SIZE-1);
8138 + if (half_power_index == acc_index) {
8139 + /* copy is cheaper than weave_to_mpi */
8140 + MP_CHECKOK(mp_copy(&accum[half_power_index], &accum2));
8141 + SQR(&accum2,&accum[acc_index]);
8142 + } else {
8143 + SQR(&accum[half_power_index],&accum[acc_index]);
8144 + }
8145 + }
8146 + }
8147 + }
8148 + /* if the accum1 isn't set, Then there is something wrong with our logic
8149 + * above and is an internal programming error.
8150 + */
8151 +#if MP_ARGCHK == 2
8152 + assert(MP_USED(&accum1) != 0);
8153 +#endif
8154 +
8155 + /* set accumulator to montgomery residue of 1 */
8156 + pa1 = &accum1;
8157 + pa2 = &accum2;
8158 +
8159 + for (expOff = bits_in_exponent - window_bits*2; expOff >= 0; expOff -= window _bits) {
8160 + mp_size smallExp;
8161 + MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) );
8162 + smallExp = (mp_size)res;
8163 +
8164 + /* handle unroll the loops */
8165 + switch (window_bits) {
8166 + case 1:
8167 + if (!smallExp) {
8168 + SQR(pa1,pa2); SWAPPA;
8169 + } else if (smallExp & 1) {
8170 + SQR(pa1,pa2); MUL_NOWEAVE(montBase,pa2,pa1);
8171 + } else {
8172 + ABORT;
8173 + }
8174 + break;
8175 + case 6:
8176 + SQR(pa1,pa2); SQR(pa2,pa1);
8177 + /* fall through */
8178 + case 4:
8179 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
8180 + MUL(smallExp, pa1,pa2); SWAPPA;
8181 + break;
8182 + case 5:
8183 + SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
8184 + SQR(pa1,pa2); MUL(smallExp,pa2,pa1);
8185 + break;
8186 + default:
8187 + ABORT; /* could do a loop? */
8188 + }
8189 + }
8190 +
8191 + res = s_mp_redc(pa1, mmm);
8192 + mp_exch(pa1, result);
8193 +
8194 +CLEANUP:
8195 + mp_clear(&accum1);
8196 + mp_clear(&accum2);
8197 + mp_clear(&accum[0]);
8198 + mp_clear(&accum[1]);
8199 + mp_clear(&accum[2]);
8200 + mp_clear(&accum[3]);
8201 + mp_clear(&tmp);
8202 + /* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */
8203 + free(powersArray);
8204 + return res;
8205 +}
8206 +#undef SQR
8207 +#undef MUL
8208 +#endif
8209 +
8210 +mp_err mp_exptmod(const mp_int *inBase, const mp_int *exponent,
8211 + const mp_int *modulus, mp_int *result)
8212 +{
8213 + const mp_int *base;
8214 + mp_size bits_in_exponent, i, window_bits, odd_ints;
8215 + mp_err res;
8216 + int nLen;
8217 + mp_int montBase, goodBase;
8218 + mp_mont_modulus mmm;
8219 +#ifdef MP_USING_CACHE_SAFE_MOD_EXP
8220 + static unsigned int max_window_bits;
8221 +#endif
8222 +
8223 + /* function for computing n0prime only works if n0 is odd */
8224 + if (!mp_isodd(modulus))
8225 + return s_mp_exptmod(inBase, exponent, modulus, result);
8226 +
8227 + MP_DIGITS(&montBase) = 0;
8228 + MP_DIGITS(&goodBase) = 0;
8229 +
8230 + if (mp_cmp(inBase, modulus) < 0) {
8231 + base = inBase;
8232 + } else {
8233 + MP_CHECKOK( mp_init(&goodBase) );
8234 + base = &goodBase;
8235 + MP_CHECKOK( mp_mod(inBase, modulus, &goodBase) );
8236 + }
8237 +
8238 + nLen = MP_USED(modulus);
8239 + MP_CHECKOK( mp_init_size(&montBase, 2 * nLen + 2) );
8240 +
8241 + mmm.N = *modulus; /* a copy of the mp_int struct */
8242 + i = mpl_significant_bits(modulus);
8243 + i += MP_DIGIT_BIT - 1;
8244 + mmm.b = i - i % MP_DIGIT_BIT;
8245 +
8246 + /* compute n0', given n0, n0' = -(n0 ** -1) mod MP_RADIX
8247 + ** where n0 = least significant mp_digit of N, the modulus.
8248 + */
8249 + mmm.n0prime = 0 - s_mp_invmod_radix( MP_DIGIT(modulus, 0) );
8250 +
8251 + MP_CHECKOK( s_mp_to_mont(base, &mmm, &montBase) );
8252 +
8253 + bits_in_exponent = mpl_significant_bits(exponent);
8254 +#ifdef MP_USING_CACHE_SAFE_MOD_EXP
8255 + if (mp_using_cache_safe_exp) {
8256 + if (bits_in_exponent > 780)
8257 + window_bits = 6;
8258 + else if (bits_in_exponent > 256)
8259 + window_bits = 5;
8260 + else if (bits_in_exponent > 20)
8261 + window_bits = 4;
8262 + /* RSA public key exponents are typically under 20 bits (common values
8263 + * are: 3, 17, 65537) and a 4-bit window is inefficient
8264 + */
8265 + else
8266 + window_bits = 1;
8267 + } else
8268 +#endif
8269 + if (bits_in_exponent > 480)
8270 + window_bits = 6;
8271 + else if (bits_in_exponent > 160)
8272 + window_bits = 5;
8273 + else if (bits_in_exponent > 20)
8274 + window_bits = 4;
8275 + /* RSA public key exponents are typically under 20 bits (common values
8276 + * are: 3, 17, 65537) and a 4-bit window is inefficient
8277 + */
8278 + else
8279 + window_bits = 1;
8280 +
8281 +#ifdef MP_USING_CACHE_SAFE_MOD_EXP
8282 + /*
8283 + * clamp the window size based on
8284 + * the cache line size.
8285 + */
8286 + if (!max_window_bits) {
8287 + unsigned long cache_size = s_mpi_getProcessorLineSize();
8288 + /* processor has no cache, use 'fast' code always */
8289 + if (cache_size == 0) {
8290 + mp_using_cache_safe_exp = 0;
8291 + }
8292 + if ((cache_size == 0) || (cache_size >= 64)) {
8293 + max_window_bits = 6;
8294 + } else if (cache_size >= 32) {
8295 + max_window_bits = 5;
8296 + } else if (cache_size >= 16) {
8297 + max_window_bits = 4;
8298 + } else max_window_bits = 1; /* should this be an assert? */
8299 + }
8300 +
8301 + /* clamp the window size down before we caclulate bits_in_exponent */
8302 + if (mp_using_cache_safe_exp) {
8303 + if (window_bits > max_window_bits) {
8304 + window_bits = max_window_bits;
8305 + }
8306 + }
8307 +#endif
8308 +
8309 + odd_ints = 1 << (window_bits - 1);
8310 + i = bits_in_exponent % window_bits;
8311 + if (i != 0) {
8312 + bits_in_exponent += window_bits - i;
8313 + }
8314 +
8315 +#ifdef MP_USING_MONT_MULF
8316 + if (mp_using_mont_mulf) {
8317 + MP_CHECKOK( s_mp_pad(&montBase, nLen) );
8318 + res = mp_exptmod_f(&montBase, exponent, modulus, result, &mmm, nLen,
8319 + bits_in_exponent, window_bits, odd_ints);
8320 + } else
8321 +#endif
8322 +#ifdef MP_USING_CACHE_SAFE_MOD_EXP
8323 + if (mp_using_cache_safe_exp) {
8324 + res = mp_exptmod_safe_i(&montBase, exponent, modulus, result, &mmm, nLen,
8325 + bits_in_exponent, window_bits, 1 << window_bits);
8326 + } else
8327 +#endif
8328 + res = mp_exptmod_i(&montBase, exponent, modulus, result, &mmm, nLen,
8329 + bits_in_exponent, window_bits, odd_ints);
8330 +
8331 +CLEANUP:
8332 + mp_clear(&montBase);
8333 + mp_clear(&goodBase);
8334 + /* Don't mp_clear mmm.N because it is merely a copy of modulus.
8335 + ** Just zap it.
8336 + */
8337 + memset(&mmm, 0, sizeof mmm);
8338 + return res;
8339 +}
8340 diff --git a/net/third_party/nss/ssl/mpi/mpprime.c b/net/third_party/nss/ssl/mpi /mpprime.c
8341 new file mode 100644
8342 index 0000000..ae8e496
8343 --- /dev/null
8344 +++ b/net/third_party/nss/ssl/mpi/mpprime.c
8345 @@ -0,0 +1,617 @@
8346 +/*
8347 + * mpprime.c
8348 + *
8349 + * Utilities for finding and working with prime and pseudo-prime
8350 + * integers
8351 + *
8352 + * ***** BEGIN LICENSE BLOCK *****
8353 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8354 + *
8355 + * The contents of this file are subject to the Mozilla Public License Version
8356 + * 1.1 (the "License"); you may not use this file except in compliance with
8357 + * the License. You may obtain a copy of the License at
8358 + * http://www.mozilla.org/MPL/
8359 + *
8360 + * Software distributed under the License is distributed on an "AS IS" basis,
8361 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
8362 + * for the specific language governing rights and limitations under the
8363 + * License.
8364 + *
8365 + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
8366 + *
8367 + * The Initial Developer of the Original Code is
8368 + * Michael J. Fromberger.
8369 + * Portions created by the Initial Developer are Copyright (C) 1997
8370 + * the Initial Developer. All Rights Reserved.
8371 + *
8372 + * Contributor(s):
8373 + * Netscape Communications Corporation
8374 + *
8375 + * Alternatively, the contents of this file may be used under the terms of
8376 + * either the GNU General Public License Version 2 or later (the "GPL"), or
8377 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
8378 + * in which case the provisions of the GPL or the LGPL are applicable instead
8379 + * of those above. If you wish to allow use of your version of this file only
8380 + * under the terms of either the GPL or the LGPL, and not to allow others to
8381 + * use your version of this file under the terms of the MPL, indicate your
8382 + * decision by deleting the provisions above and replace them with the notice
8383 + * and other provisions required by the GPL or the LGPL. If you do not delete
8384 + * the provisions above, a recipient may use your version of this file under
8385 + * the terms of any one of the MPL, the GPL or the LGPL.
8386 + *
8387 + * ***** END LICENSE BLOCK ***** */
8388 +
8389 +#include "mpi-priv.h"
8390 +#include "mpprime.h"
8391 +#include "mplogic.h"
8392 +#include <stdlib.h>
8393 +#include <string.h>
8394 +
8395 +#define SMALL_TABLE 0 /* determines size of hard-wired prime table */
8396 +
8397 +#define RANDOM() rand()
8398 +
8399 +#include "primes.c" /* pull in the prime digit table */
8400 +
8401 +/*
8402 + Test if any of a given vector of digits divides a. If not, MP_NO
8403 + is returned; otherwise, MP_YES is returned and 'which' is set to
8404 + the index of the integer in the vector which divided a.
8405 + */
8406 +mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which);
8407 +
8408 +/* {{{ mpp_divis(a, b) */
8409 +
8410 +/*
8411 + mpp_divis(a, b)
8412 +
8413 + Returns MP_YES if a is divisible by b, or MP_NO if it is not.
8414 + */
8415 +
8416 +mp_err mpp_divis(mp_int *a, mp_int *b)
8417 +{
8418 + mp_err res;
8419 + mp_int rem;
8420 +
8421 + if((res = mp_init(&rem)) != MP_OKAY)
8422 + return res;
8423 +
8424 + if((res = mp_mod(a, b, &rem)) != MP_OKAY)
8425 + goto CLEANUP;
8426 +
8427 + if(mp_cmp_z(&rem) == 0)
8428 + res = MP_YES;
8429 + else
8430 + res = MP_NO;
8431 +
8432 +CLEANUP:
8433 + mp_clear(&rem);
8434 + return res;
8435 +
8436 +} /* end mpp_divis() */
8437 +
8438 +/* }}} */
8439 +
8440 +/* {{{ mpp_divis_d(a, d) */
8441 +
8442 +/*
8443 + mpp_divis_d(a, d)
8444 +
8445 + Return MP_YES if a is divisible by d, or MP_NO if it is not.
8446 + */
8447 +
8448 +mp_err mpp_divis_d(mp_int *a, mp_digit d)
8449 +{
8450 + mp_err res;
8451 + mp_digit rem;
8452 +
8453 + ARGCHK(a != NULL, MP_BADARG);
8454 +
8455 + if(d == 0)
8456 + return MP_NO;
8457 +
8458 + if((res = mp_mod_d(a, d, &rem)) != MP_OKAY)
8459 + return res;
8460 +
8461 + if(rem == 0)
8462 + return MP_YES;
8463 + else
8464 + return MP_NO;
8465 +
8466 +} /* end mpp_divis_d() */
8467 +
8468 +/* }}} */
8469 +
8470 +/* {{{ mpp_random(a) */
8471 +
8472 +/*
8473 + mpp_random(a)
8474 +
8475 + Assigns a random value to a. This value is generated using the
8476 + standard C library's rand() function, so it should not be used for
8477 + cryptographic purposes, but it should be fine for primality testing,
8478 + since all we really care about there is good statistical properties.
8479 +
8480 + As many digits as a currently has are filled with random digits.
8481 + */
8482 +
8483 +mp_err mpp_random(mp_int *a)
8484 +
8485 +{
8486 + mp_digit next = 0;
8487 + unsigned int ix, jx;
8488 +
8489 + ARGCHK(a != NULL, MP_BADARG);
8490 +
8491 + for(ix = 0; ix < USED(a); ix++) {
8492 + for(jx = 0; jx < sizeof(mp_digit); jx++) {
8493 + next = (next << CHAR_BIT) | (RANDOM() & UCHAR_MAX);
8494 + }
8495 + DIGIT(a, ix) = next;
8496 + }
8497 +
8498 + return MP_OKAY;
8499 +
8500 +} /* end mpp_random() */
8501 +
8502 +/* }}} */
8503 +
8504 +/* {{{ mpp_random_size(a, prec) */
8505 +
8506 +mp_err mpp_random_size(mp_int *a, mp_size prec)
8507 +{
8508 + mp_err res;
8509 +
8510 + ARGCHK(a != NULL && prec > 0, MP_BADARG);
8511 +
8512 + if((res = s_mp_pad(a, prec)) != MP_OKAY)
8513 + return res;
8514 +
8515 + return mpp_random(a);
8516 +
8517 +} /* end mpp_random_size() */
8518 +
8519 +/* }}} */
8520 +
8521 +/* {{{ mpp_divis_vector(a, vec, size, which) */
8522 +
8523 +/*
8524 + mpp_divis_vector(a, vec, size, which)
8525 +
8526 + Determines if a is divisible by any of the 'size' digits in vec.
8527 + Returns MP_YES and sets 'which' to the index of the offending digit,
8528 + if it is; returns MP_NO if it is not.
8529 + */
8530 +
8531 +mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which)
8532 +{
8533 + ARGCHK(a != NULL && vec != NULL && size > 0, MP_BADARG);
8534 +
8535 + return s_mpp_divp(a, vec, size, which);
8536 +
8537 +} /* end mpp_divis_vector() */
8538 +
8539 +/* }}} */
8540 +
8541 +/* {{{ mpp_divis_primes(a, np) */
8542 +
8543 +/*
8544 + mpp_divis_primes(a, np)
8545 +
8546 + Test whether a is divisible by any of the first 'np' primes. If it
8547 + is, returns MP_YES and sets *np to the value of the digit that did
8548 + it. If not, returns MP_NO.
8549 + */
8550 +mp_err mpp_divis_primes(mp_int *a, mp_digit *np)
8551 +{
8552 + int size, which;
8553 + mp_err res;
8554 +
8555 + ARGCHK(a != NULL && np != NULL, MP_BADARG);
8556 +
8557 + size = (int)*np;
8558 + if(size > prime_tab_size)
8559 + size = prime_tab_size;
8560 +
8561 + res = mpp_divis_vector(a, prime_tab, size, &which);
8562 + if(res == MP_YES)
8563 + *np = prime_tab[which];
8564 +
8565 + return res;
8566 +
8567 +} /* end mpp_divis_primes() */
8568 +
8569 +/* }}} */
8570 +
8571 +/* {{{ mpp_fermat(a, w) */
8572 +
8573 +/*
8574 + Using w as a witness, try pseudo-primality testing based on Fermat's
8575 + little theorem. If a is prime, and (w, a) = 1, then w^a == w (mod
8576 + a). So, we compute z = w^a (mod a) and compare z to w; if they are
8577 + equal, the test passes and we return MP_YES. Otherwise, we return
8578 + MP_NO.
8579 + */
8580 +mp_err mpp_fermat(mp_int *a, mp_digit w)
8581 +{
8582 + mp_int base, test;
8583 + mp_err res;
8584 +
8585 + if((res = mp_init(&base)) != MP_OKAY)
8586 + return res;
8587 +
8588 + mp_set(&base, w);
8589 +
8590 + if((res = mp_init(&test)) != MP_OKAY)
8591 + goto TEST;
8592 +
8593 + /* Compute test = base^a (mod a) */
8594 + if((res = mp_exptmod(&base, a, a, &test)) != MP_OKAY)
8595 + goto CLEANUP;
8596 +
8597 +
8598 + if(mp_cmp(&base, &test) == 0)
8599 + res = MP_YES;
8600 + else
8601 + res = MP_NO;
8602 +
8603 + CLEANUP:
8604 + mp_clear(&test);
8605 + TEST:
8606 + mp_clear(&base);
8607 +
8608 + return res;
8609 +
8610 +} /* end mpp_fermat() */
8611 +
8612 +/* }}} */
8613 +
8614 +/*
8615 + Perform the fermat test on each of the primes in a list until
8616 + a) one of them shows a is not prime, or
8617 + b) the list is exhausted.
8618 + Returns: MP_YES if it passes tests.
8619 + MP_NO if fermat test reveals it is composite
8620 + Some MP error code if some other error occurs.
8621 + */
8622 +mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes)
8623 +{
8624 + mp_err rv = MP_YES;
8625 +
8626 + while (nPrimes-- > 0 && rv == MP_YES) {
8627 + rv = mpp_fermat(a, *primes++);
8628 + }
8629 + return rv;
8630 +}
8631 +
8632 +/* {{{ mpp_pprime(a, nt) */
8633 +
8634 +/*
8635 + mpp_pprime(a, nt)
8636 +
8637 + Performs nt iteration of the Miller-Rabin probabilistic primality
8638 + test on a. Returns MP_YES if the tests pass, MP_NO if one fails.
8639 + If MP_NO is returned, the number is definitely composite. If MP_YES
8640 + is returned, it is probably prime (but that is not guaranteed).
8641 + */
8642 +
8643 +mp_err mpp_pprime(mp_int *a, int nt)
8644 +{
8645 + mp_err res;
8646 + mp_int x, amo, m, z; /* "amo" = "a minus one" */
8647 + int iter;
8648 + unsigned int jx;
8649 + mp_size b;
8650 +
8651 + ARGCHK(a != NULL, MP_BADARG);
8652 +
8653 + MP_DIGITS(&x) = 0;
8654 + MP_DIGITS(&amo) = 0;
8655 + MP_DIGITS(&m) = 0;
8656 + MP_DIGITS(&z) = 0;
8657 +
8658 + /* Initialize temporaries... */
8659 + MP_CHECKOK( mp_init(&amo));
8660 + /* Compute amo = a - 1 for what follows... */
8661 + MP_CHECKOK( mp_sub_d(a, 1, &amo) );
8662 +
8663 + b = mp_trailing_zeros(&amo);
8664 + if (!b) { /* a was even ? */
8665 + res = MP_NO;
8666 + goto CLEANUP;
8667 + }
8668 +
8669 + MP_CHECKOK( mp_init_size(&x, MP_USED(a)) );
8670 + MP_CHECKOK( mp_init(&z) );
8671 + MP_CHECKOK( mp_init(&m) );
8672 + MP_CHECKOK( mp_div_2d(&amo, b, &m, 0) );
8673 +
8674 + /* Do the test nt times... */
8675 + for(iter = 0; iter < nt; iter++) {
8676 +
8677 + /* Choose a random value for 1 < x < a */
8678 + s_mp_pad(&x, USED(a));
8679 + mpp_random(&x);
8680 + MP_CHECKOK( mp_mod(&x, a, &x) );
8681 + if(mp_cmp_d(&x, 1) <= 0) {
8682 + iter--; /* don't count this iteration */
8683 + continue; /* choose a new x */
8684 + }
8685 +
8686 + /* Compute z = (x ** m) mod a */
8687 + MP_CHECKOK( mp_exptmod(&x, &m, a, &z) );
8688 +
8689 + if(mp_cmp_d(&z, 1) == 0 || mp_cmp(&z, &amo) == 0) {
8690 + res = MP_YES;
8691 + continue;
8692 + }
8693 +
8694 + res = MP_NO; /* just in case the following for loop never executes. */
8695 + for (jx = 1; jx < b; jx++) {
8696 + /* z = z^2 (mod a) */
8697 + MP_CHECKOK( mp_sqrmod(&z, a, &z) );
8698 + res = MP_NO; /* previous line set res to MP_YES */
8699 +
8700 + if(mp_cmp_d(&z, 1) == 0) {
8701 + break;
8702 + }
8703 + if(mp_cmp(&z, &amo) == 0) {
8704 + res = MP_YES;
8705 + break;
8706 + }
8707 + } /* end testing loop */
8708 +
8709 + /* If the test passes, we will continue iterating, but a failed
8710 + test means the candidate is definitely NOT prime, so we will
8711 + immediately break out of this loop
8712 + */
8713 + if(res == MP_NO)
8714 + break;
8715 +
8716 + } /* end iterations loop */
8717 +
8718 +CLEANUP:
8719 + mp_clear(&m);
8720 + mp_clear(&z);
8721 + mp_clear(&x);
8722 + mp_clear(&amo);
8723 + return res;
8724 +
8725 +} /* end mpp_pprime() */
8726 +
8727 +/* }}} */
8728 +
8729 +/* Produce table of composites from list of primes and trial value.
8730 +** trial must be odd. List of primes must not include 2.
8731 +** sieve should have dimension >= MAXPRIME/2, where MAXPRIME is largest
8732 +** prime in list of primes. After this function is finished,
8733 +** if sieve[i] is non-zero, then (trial + 2*i) is composite.
8734 +** Each prime used in the sieve costs one division of trial, and eliminates
8735 +** one or more values from the search space. (3 eliminates 1/3 of the values
8736 +** alone!) Each value left in the search space costs 1 or more modular
8737 +** exponentations. So, these divisions are a bargain!
8738 +*/
8739 +mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
8740 + unsigned char *sieve, mp_size nSieve)
8741 +{
8742 + mp_err res;
8743 + mp_digit rem;
8744 + mp_size ix;
8745 + unsigned long offset;
8746 +
8747 + memset(sieve, 0, nSieve);
8748 +
8749 + for(ix = 0; ix < nPrimes; ix++) {
8750 + mp_digit prime = primes[ix];
8751 + mp_size i;
8752 + if((res = mp_mod_d(trial, prime, &rem)) != MP_OKAY)
8753 + return res;
8754 +
8755 + if (rem == 0) {
8756 + offset = 0;
8757 + } else {
8758 + offset = prime - (rem / 2);
8759 + }
8760 + for (i = offset; i < nSieve ; i += prime) {
8761 + sieve[i] = 1;
8762 + }
8763 + }
8764 +
8765 + return MP_OKAY;
8766 +}
8767 +
8768 +#define SIEVE_SIZE 32*1024
8769 +
8770 +mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
8771 + unsigned long * nTries)
8772 +{
8773 + mp_digit np;
8774 + mp_err res;
8775 + int i = 0;
8776 + mp_int trial;
8777 + mp_int q;
8778 + mp_size num_tests;
8779 + unsigned char *sieve;
8780 +
8781 + ARGCHK(start != 0, MP_BADARG);
8782 + ARGCHK(nBits > 16, MP_RANGE);
8783 +
8784 + sieve = malloc(SIEVE_SIZE);
8785 + ARGCHK(sieve != NULL, MP_MEM);
8786 +
8787 + MP_DIGITS(&trial) = 0;
8788 + MP_DIGITS(&q) = 0;
8789 + MP_CHECKOK( mp_init(&trial) );
8790 + MP_CHECKOK( mp_init(&q) );
8791 + /* values taken from table 4.4, HandBook of Applied Cryptography */
8792 + if (nBits >= 1300) {
8793 + num_tests = 2;
8794 + } else if (nBits >= 850) {
8795 + num_tests = 3;
8796 + } else if (nBits >= 650) {
8797 + num_tests = 4;
8798 + } else if (nBits >= 550) {
8799 + num_tests = 5;
8800 + } else if (nBits >= 450) {
8801 + num_tests = 6;
8802 + } else if (nBits >= 400) {
8803 + num_tests = 7;
8804 + } else if (nBits >= 350) {
8805 + num_tests = 8;
8806 + } else if (nBits >= 300) {
8807 + num_tests = 9;
8808 + } else if (nBits >= 250) {
8809 + num_tests = 12;
8810 + } else if (nBits >= 200) {
8811 + num_tests = 15;
8812 + } else if (nBits >= 150) {
8813 + num_tests = 18;
8814 + } else if (nBits >= 100) {
8815 + num_tests = 27;
8816 + } else
8817 + num_tests = 50;
8818 +
8819 + if (strong)
8820 + --nBits;
8821 + MP_CHECKOK( mpl_set_bit(start, nBits - 1, 1) );
8822 + MP_CHECKOK( mpl_set_bit(start, 0, 1) );
8823 + for (i = mpl_significant_bits(start) - 1; i >= nBits; --i) {
8824 + MP_CHECKOK( mpl_set_bit(start, i, 0) );
8825 + }
8826 + /* start sieveing with prime value of 3. */
8827 + MP_CHECKOK(mpp_sieve(start, prime_tab + 1, prime_tab_size - 1,
8828 + sieve, SIEVE_SIZE) );
8829 +
8830 +#ifdef DEBUG_SIEVE
8831 + res = 0;
8832 + for (i = 0; i < SIEVE_SIZE; ++i) {
8833 + if (!sieve[i])
8834 + ++res;
8835 + }
8836 + fprintf(stderr,"sieve found %d potential primes.\n", res);
8837 +#define FPUTC(x,y) fputc(x,y)
8838 +#else
8839 +#define FPUTC(x,y)
8840 +#endif
8841 +
8842 + res = MP_NO;
8843 + for(i = 0; i < SIEVE_SIZE; ++i) {
8844 + if (sieve[i]) /* this number is composite */
8845 + continue;
8846 + MP_CHECKOK( mp_add_d(start, 2 * i, &trial) );
8847 + FPUTC('.', stderr);
8848 + /* run a Fermat test */
8849 + res = mpp_fermat(&trial, 2);
8850 + if (res != MP_OKAY) {
8851 + if (res == MP_NO)
8852 + continue; /* was composite */
8853 + goto CLEANUP;
8854 + }
8855 +
8856 + FPUTC('+', stderr);
8857 + /* If that passed, run some Miller-Rabin tests */
8858 + res = mpp_pprime(&trial, num_tests);
8859 + if (res != MP_OKAY) {
8860 + if (res == MP_NO)
8861 + continue; /* was composite */
8862 + goto CLEANUP;
8863 + }
8864 + FPUTC('!', stderr);
8865 +
8866 + if (!strong)
8867 + break; /* success !! */
8868 +
8869 + /* At this point, we have strong evidence that our candidate
8870 + is itself prime. If we want a strong prime, we need now
8871 + to test q = 2p + 1 for primality...
8872 + */
8873 + MP_CHECKOK( mp_mul_2(&trial, &q) );
8874 + MP_CHECKOK( mp_add_d(&q, 1, &q) );
8875 +
8876 + /* Test q for small prime divisors ... */
8877 + np = prime_tab_size;
8878 + res = mpp_divis_primes(&q, &np);
8879 + if (res == MP_YES) { /* is composite */
8880 + mp_clear(&q);
8881 + continue;
8882 + }
8883 + if (res != MP_NO)
8884 + goto CLEANUP;
8885 +
8886 + /* And test with Fermat, as with its parent ... */
8887 + res = mpp_fermat(&q, 2);
8888 + if (res != MP_YES) {
8889 + mp_clear(&q);
8890 + if (res == MP_NO)
8891 + continue; /* was composite */
8892 + goto CLEANUP;
8893 + }
8894 +
8895 + /* And test with Miller-Rabin, as with its parent ... */
8896 + res = mpp_pprime(&q, num_tests);
8897 + if (res != MP_YES) {
8898 + mp_clear(&q);
8899 + if (res == MP_NO)
8900 + continue; /* was composite */
8901 + goto CLEANUP;
8902 + }
8903 +
8904 + /* If it passed, we've got a winner */
8905 + mp_exch(&q, &trial);
8906 + mp_clear(&q);
8907 + break;
8908 +
8909 + } /* end of loop through sieved values */
8910 + if (res == MP_YES)
8911 + mp_exch(&trial, start);
8912 +CLEANUP:
8913 + mp_clear(&trial);
8914 + mp_clear(&q);
8915 + if (nTries)
8916 + *nTries += i;
8917 + if (sieve != NULL) {
8918 + memset(sieve, 0, SIEVE_SIZE);
8919 + free (sieve);
8920 + }
8921 + return res;
8922 +}
8923 +
8924 +/*========================================================================*/
8925 +/*------------------------------------------------------------------------*/
8926 +/* Static functions visible only to the library internally */
8927 +
8928 +/* {{{ s_mpp_divp(a, vec, size, which) */
8929 +
8930 +/*
8931 + Test for divisibility by members of a vector of digits. Returns
8932 + MP_NO if a is not divisible by any of them; returns MP_YES and sets
8933 + 'which' to the index of the offender, if it is. Will stop on the
8934 + first digit against which a is divisible.
8935 + */
8936 +
8937 +mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which)
8938 +{
8939 + mp_err res;
8940 + mp_digit rem;
8941 +
8942 + int ix;
8943 +
8944 + for(ix = 0; ix < size; ix++) {
8945 + if((res = mp_mod_d(a, vec[ix], &rem)) != MP_OKAY)
8946 + return res;
8947 +
8948 + if(rem == 0) {
8949 + if(which)
8950 + *which = ix;
8951 + return MP_YES;
8952 + }
8953 + }
8954 +
8955 + return MP_NO;
8956 +
8957 +} /* end s_mpp_divp() */
8958 +
8959 +/* }}} */
8960 +
8961 +/*------------------------------------------------------------------------*/
8962 +/* HERE THERE BE DRAGONS */
8963 diff --git a/net/third_party/nss/ssl/mpi/mpprime.h b/net/third_party/nss/ssl/mpi /mpprime.h
8964 new file mode 100644
8965 index 0000000..486d4a1
8966 --- /dev/null
8967 +++ b/net/third_party/nss/ssl/mpi/mpprime.h
8968 @@ -0,0 +1,70 @@
8969 +/*
8970 + * mpprime.h
8971 + *
8972 + * Utilities for finding and working with prime and pseudo-prime
8973 + * integers
8974 + *
8975 + * ***** BEGIN LICENSE BLOCK *****
8976 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8977 + *
8978 + * The contents of this file are subject to the Mozilla Public License Version
8979 + * 1.1 (the "License"); you may not use this file except in compliance with
8980 + * the License. You may obtain a copy of the License at
8981 + * http://www.mozilla.org/MPL/
8982 + *
8983 + * Software distributed under the License is distributed on an "AS IS" basis,
8984 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
8985 + * for the specific language governing rights and limitations under the
8986 + * License.
8987 + *
8988 + * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
8989 + *
8990 + * The Initial Developer of the Original Code is
8991 + * Michael J. Fromberger.
8992 + * Portions created by the Initial Developer are Copyright (C) 1997
8993 + * the Initial Developer. All Rights Reserved.
8994 + *
8995 + * Contributor(s):
8996 + *
8997 + * Alternatively, the contents of this file may be used under the terms of
8998 + * either the GNU General Public License Version 2 or later (the "GPL"), or
8999 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
9000 + * in which case the provisions of the GPL or the LGPL are applicable instead
9001 + * of those above. If you wish to allow use of your version of this file only
9002 + * under the terms of either the GPL or the LGPL, and not to allow others to
9003 + * use your version of this file under the terms of the MPL, indicate your
9004 + * decision by deleting the provisions above and replace them with the notice
9005 + * and other provisions required by the GPL or the LGPL. If you do not delete
9006 + * the provisions above, a recipient may use your version of this file under
9007 + * the terms of any one of the MPL, the GPL or the LGPL.
9008 + *
9009 + * ***** END LICENSE BLOCK ***** */
9010 +
9011 +#ifndef _H_MP_PRIME_
9012 +#define _H_MP_PRIME_
9013 +
9014 +#include "mpi.h"
9015 +
9016 +extern const int prime_tab_size; /* number of primes available */
9017 +extern const mp_digit prime_tab[];
9018 +
9019 +/* Tests for divisibility */
9020 +mp_err mpp_divis(mp_int *a, mp_int *b);
9021 +mp_err mpp_divis_d(mp_int *a, mp_digit d);
9022 +
9023 +/* Random selection */
9024 +mp_err mpp_random(mp_int *a);
9025 +mp_err mpp_random_size(mp_int *a, mp_size prec);
9026 +
9027 +/* Pseudo-primality testing */
9028 +mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which);
9029 +mp_err mpp_divis_primes(mp_int *a, mp_digit *np);
9030 +mp_err mpp_fermat(mp_int *a, mp_digit w);
9031 +mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes);
9032 +mp_err mpp_pprime(mp_int *a, int nt);
9033 +mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
9034 + unsigned char *sieve, mp_size nSieve);
9035 +mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
9036 + unsigned long * nTries);
9037 +
9038 +#endif /* end _H_MP_PRIME_ */
9039 diff --git a/net/third_party/nss/ssl/mpi/secmpi.h b/net/third_party/nss/ssl/mpi/ secmpi.h
9040 new file mode 100644
9041 index 0000000..e343fb8
9042 --- /dev/null
9043 +++ b/net/third_party/nss/ssl/mpi/secmpi.h
9044 @@ -0,0 +1,61 @@
9045 +/* ***** BEGIN LICENSE BLOCK *****
9046 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
9047 + *
9048 + * The contents of this file are subject to the Mozilla Public License Version
9049 + * 1.1 (the "License"); you may not use this file except in compliance with
9050 + * the License. You may obtain a copy of the License at
9051 + * http://www.mozilla.org/MPL/
9052 + *
9053 + * Software distributed under the License is distributed on an "AS IS" basis,
9054 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
9055 + * for the specific language governing rights and limitations under the
9056 + * License.
9057 + *
9058 + * The Original Code is the Netscape security libraries.
9059 + *
9060 + * The Initial Developer of the Original Code is
9061 + * Netscape Communications Corporation.
9062 + * Portions created by the Initial Developer are Copyright (C) 1994-2000
9063 + * the Initial Developer. All Rights Reserved.
9064 + *
9065 + * Contributor(s):
9066 + *
9067 + * Alternatively, the contents of this file may be used under the terms of
9068 + * either the GNU General Public License Version 2 or later (the "GPL"), or
9069 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
9070 + * in which case the provisions of the GPL or the LGPL are applicable instead
9071 + * of those above. If you wish to allow use of your version of this file only
9072 + * under the terms of either the GPL or the LGPL, and not to allow others to
9073 + * use your version of this file under the terms of the MPL, indicate your
9074 + * decision by deleting the provisions above and replace them with the notice
9075 + * and other provisions required by the GPL or the LGPL. If you do not delete
9076 + * the provisions above, a recipient may use your version of this file under
9077 + * the terms of any one of the MPL, the GPL or the LGPL.
9078 + *
9079 + * ***** END LICENSE BLOCK ***** */
9080 +
9081 +#include "mpi.h"
9082 +
9083 +#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
9084 +
9085 +#define CHECK_MPI_OK(func) if (MP_OKAY > (err = func)) goto cleanup
9086 +
9087 +#define OCTETS_TO_MPINT(oc, mp, len) \
9088 + CHECK_MPI_OK(mp_read_unsigned_octets((mp), oc, len))
9089 +
9090 +#define SECITEM_TO_MPINT(it, mp) \
9091 + CHECK_MPI_OK(mp_read_unsigned_octets((mp), (it).data, (it).len))
9092 +
9093 +#define MPINT_TO_SECITEM(mp, it, arena) \
9094 + SECITEM_AllocItem(arena, (it), mp_unsigned_octet_size(mp)); \
9095 + if ((it)->data == NULL) {err = MP_MEM; goto cleanup;} \
9096 + err = mp_to_unsigned_octets(mp, (it)->data, (it)->len); \
9097 + if (err < 0) goto cleanup; else err = MP_OKAY;
9098 +
9099 +#define MP_TO_SEC_ERROR(err) \
9100 + switch (err) { \
9101 + case MP_MEM: PORT_SetError(SEC_ERROR_NO_MEMORY); break; \
9102 + case MP_RANGE: PORT_SetError(SEC_ERROR_BAD_DATA); break; \
9103 + case MP_BADARG: PORT_SetError(SEC_ERROR_INVALID_ARGS); break; \
9104 + default: PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); break; \
9105 + }
9106 diff --git a/net/third_party/nss/ssl/srp.c b/net/third_party/nss/ssl/srp.c
9107 new file mode 100644
9108 index 0000000..a1cb96c
9109 --- /dev/null
9110 +++ b/net/third_party/nss/ssl/srp.c
9111 @@ -0,0 +1,550 @@
9112 +/* ***** BEGIN LICENSE BLOCK *****
9113 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
9114 + *
9115 + * The contents of this file are subject to the Mozilla Public License Version
9116 + * 1.1 (the "License"); you may not use this file except in compliance with
9117 + * the License. You may obtain a copy of the License at
9118 + * http://www.mozilla.org/MPL/
9119 + *
9120 + * Software distributed under the License is distributed on an "AS IS" basis,
9121 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
9122 + * for the specific language governing rights and limitations under the
9123 + * License.
9124 + *
9125 + * The Initial Developer of the Original Code is
9126 + * Steffen Schulz - pepe (at) cbg.dyndns.org
9127 + *
9128 + * Portions created by the Initial Developer are Copyright (C) 2007
9129 + * the Initial Developer. All Rights Reserved.
9130 + *
9131 + * Contributor(s):
9132 + *
9133 + * Alternatively, the contents of this file may be used under the terms of
9134 + * either the GNU General Public License Version 2 or later (the "GPL"), or
9135 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
9136 + * in which case the provisions of the GPL or the LGPL are applicable instead
9137 + * of those above. If you wish to allow use of your version of this file only
9138 + * under the terms of either the GPL or the LGPL, and not to allow others to
9139 + * use your version of this file under the terms of the MPL, indicate your
9140 + * decision by deleting the provisions above and replace them with the notice
9141 + * and other provisions required by the GPL or the LGPL. If you do not delete
9142 + * the provisions above, a recipient may use your version of this file under
9143 + * the terms of any one of the MPL, the GPL or the LGPL.
9144 + *
9145 + * ***** END LICENSE BLOCK ***** */
9146 +
9147 +/*
9148 + * This file implements the core SRP algorithms described in rfc 5054
9149 + * for enabling secure password based authentication in TLS via SRP.
9150 + *
9151 + * See also:
9152 + * Wu, T., "SRP-6: Improvements and Refinements to the Secure
9153 + * Remote Password Protocol", October 2002,
9154 + * <http://srp.stanford.edu/srp6.ps>.
9155 + */
9156 +
9157 +#ifdef FREEBL_NO_DEPEND
9158 +#include "stubs.h"
9159 +#endif
9160 +
9161 +#include "secerr.h"
9162 +#include "blapi.h"
9163 +#include "mpi/mpi.h"
9164 +#include "mpi/secmpi.h"
9165 +#include "secitem.h"
9166 +#include "keythi.h"
9167 +#include "plbase64.h"
9168 +
9169 +#include "srp_groups.h"
9170 +
9171 +/* length of srp secret keys in byte */
9172 +#define SRP_SECRET_KEY_LEN 32
9173 +
9174 +
9175 +/* check if (N,g) are among the known-good group params */
9176 +static SECStatus check_srp_group(const mp_int *N, const mp_int *g) {
9177 + int i;
9178 + char *N_str;
9179 + char *g_str;
9180 + mp_err err;
9181 + SECStatus rv = SECFailure;
9182 +
9183 + N_str = PORT_Alloc(mp_radix_size(N, 16));
9184 + g_str = PORT_Alloc(mp_radix_size(g, 16));
9185 +
9186 + CHECK_MPI_OK(mp_toradix(N, N_str, 16));
9187 + CHECK_MPI_OK(mp_toradix(g, g_str, 16));
9188 +
9189 + /* compare bytes and length */
9190 + for ( i=0; i < SRP_KNOWN_GROUPS; i++)
9191 + if (PORT_Strcmp(N_str, known_srp_groups[i].modulus))
9192 + if (PORT_Strcmp(g_str, known_srp_groups[i].generator)) {
9193 + rv = SECSuccess;
9194 + break;
9195 + }
9196 +
9197 + if (rv !=SECSuccess)
9198 + PORT_SetError(SEC_ERROR_SRP_UNSUPPORTED_GROUP);
9199 +
9200 +cleanup:
9201 + PORT_Free(N_str);
9202 + PORT_Free(g_str);
9203 + if (err) {
9204 + MP_TO_SEC_ERROR(err);
9205 + rv = SECFailure;
9206 + }
9207 +
9208 + return rv;
9209 +}
9210 +
9211 +/* check if B%N = 0 -> trapdoor */
9212 +static SECStatus srp_backdoor_check(const mp_int *N, const mp_int *B) {
9213 +
9214 + mp_int res;
9215 + mp_err err;
9216 +
9217 + CHECK_MPI_OK(mp_init(&res));
9218 + CHECK_MPI_OK(mp_mod(B, N, &res));
9219 +
9220 +
9221 + if ( mp_cmp_z(&res) == 0) {
9222 + PORT_SetError(SEC_ERROR_SRP_ILLEGAL_PARAMETER);
9223 + return SECFailure;
9224 + }
9225 +cleanup:
9226 + mp_clear(&res);
9227 + if (err) {
9228 + MP_TO_SEC_ERROR(err);
9229 + return SECFailure;
9230 + }
9231 + return SECSuccess;
9232 +}
9233 +
9234 +/* SRP_DeriveKey computes common key 'pms'
9235 + *
9236 + * The pre-master secret is calculated as follows:
9237 + *
9238 + * u = SHA1(PAD(A) | PAD(B))
9239 + * k = SHA1(N | PAD(g))
9240 + * pms = (A * v^u) ^ b % N
9241 + *
9242 + * PAD() left-paddes with \0 until length of N
9243 + */
9244 +
9245 +SECStatus SRP_ServerDerive(SRPPrivateKey *prvKey, SRPDeriveParams *srp,
9246 + SECItem *pms) {
9247 + mp_int mp_pms, mp_res;
9248 + mp_int mp_A, mp_b, mp_v;
9249 + mp_int mp_N, mp_g, mp_u, mp_k;
9250 + SECItem *it_u, *it_k;
9251 + unsigned char *zero;
9252 + unsigned int len = srp->N.len;
9253 + SHA1Context *ctx = SHA1_NewContext();
9254 + SECStatus rv = SECFailure;
9255 + mp_err err = MP_OKAY;
9256 +
9257 + CHECK_MPI_OK(mp_init(&mp_N));
9258 + CHECK_MPI_OK(mp_init(&mp_g));
9259 + CHECK_MPI_OK(mp_init(&mp_u));
9260 + CHECK_MPI_OK(mp_init(&mp_k));
9261 + CHECK_MPI_OK(mp_init(&mp_v));
9262 + CHECK_MPI_OK(mp_init(&mp_b));
9263 + CHECK_MPI_OK(mp_init(&mp_A));
9264 + CHECK_MPI_OK(mp_init(&mp_res));
9265 + CHECK_MPI_OK(mp_init(&mp_pms));
9266 +
9267 + zero = PORT_ZAlloc(len);
9268 + it_u = SECITEM_AllocItem(NULL, NULL, SHA1_LENGTH);
9269 + it_k = SECITEM_AllocItem(NULL, NULL, SHA1_LENGTH);
9270 +
9271 + if (!zero || !it_u || !it_k) {
9272 + PORT_SetError(SEC_ERROR_NO_MEMORY);
9273 + goto cleanup;
9274 + }
9275 +
9276 + /* u = SHA1( PAD(A) | PAD(B) ) */
9277 + SHA1_Begin(ctx);
9278 + SHA1_Update(ctx, zero, len - srp->ppub.len);
9279 + SHA1_Update(ctx, srp->ppub.data, srp->ppub.len);
9280 + SHA1_Update(ctx, zero, len - prvKey->pubKey.len);
9281 + SHA1_Update(ctx, prvKey->pubKey.data, prvKey->pubKey.len);
9282 + SHA1_End(ctx, it_u->data, &it_u->len, SHA1_LENGTH);
9283 +
9284 + /* k = SHA1( N | PAD(g) ) */
9285 + SHA1_Begin(ctx);
9286 + SHA1_Update(ctx, srp->N.data, srp->N.len);
9287 + SHA1_Update(ctx, zero, len - srp->g.len);
9288 + SHA1_Update(ctx, srp->g.data, srp->g.len);
9289 + SHA1_End(ctx, it_k->data, &it_k->len, SHA1_LENGTH);
9290 +
9291 + /*
9292 + * calculate pms = (A * v^u) ^ b % N
9293 + */
9294 +
9295 + SECITEM_TO_MPINT(*it_u, &mp_u);
9296 + SECITEM_TO_MPINT(*it_k, &mp_k);
9297 + SECITEM_TO_MPINT(srp->N, &mp_N);
9298 + SECITEM_TO_MPINT(srp->g, &mp_g);
9299 + SECITEM_TO_MPINT(srp->ppub,&mp_A);
9300 + SECITEM_TO_MPINT(prvKey->secret, &mp_v);
9301 + SECITEM_TO_MPINT(prvKey->prvKey, &mp_b);
9302 +
9303 + CHECK_MPI_OK(mp_exptmod(&mp_v, &mp_u, &mp_N, &mp_res));
9304 + CHECK_MPI_OK(mp_mulmod(&mp_A, &mp_res, &mp_N, &mp_res));
9305 + CHECK_MPI_OK(mp_exptmod(&mp_res, &mp_b, &mp_N, &mp_pms));
9306 +
9307 + MPINT_TO_SECITEM(&mp_pms, pms, NULL);
9308 +
9309 + rv = SECSuccess;
9310 +cleanup:
9311 + PORT_Free(zero);
9312 + SECITEM_FreeItem(it_u, PR_TRUE);
9313 + SECITEM_FreeItem(it_k, PR_TRUE);
9314 + SHA1_DestroyContext(ctx, PR_TRUE);
9315 + mp_clear(&mp_N);
9316 + mp_clear(&mp_g);
9317 + mp_clear(&mp_b);
9318 + mp_clear(&mp_A);
9319 + mp_clear(&mp_k);
9320 + mp_clear(&mp_u);
9321 + mp_clear(&mp_v);
9322 + mp_clear(&mp_pms);
9323 + mp_clear(&mp_res);
9324 + if (err) {
9325 + MP_TO_SEC_ERROR(err);
9326 + rv = SECFailure;
9327 + }
9328 + return rv;
9329 +}
9330 +
9331 +/* SRP_ClientDerive, computes common key 'pms'
9332 + *
9333 + * The pre-master secret is calculated as follows:
9334 + *
9335 + * u = SHA1(PAD(A) | PAD(B))
9336 + * k = SHA1(N | PAD(g))
9337 + * x = SHA1(s | SHA1(I | ":" | P))
9338 + * pms = (B - (k * g^x)) ^ (a + (u * x)) % N
9339 + *
9340 + * PAD() left-paddes with \0 until length of N
9341 + */
9342 +SECStatus SRP_ClientDerive(SRPPrivateKey *prvKey, SRPDeriveParams *srp,
9343 + SECItem * pms) {
9344 +
9345 + /* mp_int use pointers*/
9346 + unsigned char *zero = NULL;
9347 + mp_int mp_pms, mp_res1, mp_res2;
9348 + mp_int mp_B, mp_a, mp_A;
9349 + mp_int mp_N, mp_g, mp_u;
9350 + mp_int mp_k, mp_x;
9351 + mp_err err = MP_OKAY;
9352 + SECItem *it_u = NULL;
9353 + SECItem *it_k = NULL;
9354 + SECItem *it_x = NULL;
9355 + SHA1Context *ctx = SHA1_NewContext();
9356 + unsigned int len = srp->N.len;
9357 + SECStatus rv = SECFailure;
9358 +
9359 + if (prvKey->secret.len == 0) {
9360 + /* XXX this error is probably meant for token passwords
9361 + * anyway, we use it to show missing password in bypass mode*/
9362 + PORT_SetError(SEC_ERROR_BAD_PASSWORD);
9363 + return SECFailure;
9364 + }
9365 +
9366 + CHECK_MPI_OK(mp_init(&mp_N));
9367 + CHECK_MPI_OK(mp_init(&mp_g));
9368 + CHECK_MPI_OK(mp_init(&mp_u));
9369 + CHECK_MPI_OK(mp_init(&mp_k));
9370 + CHECK_MPI_OK(mp_init(&mp_x));
9371 + CHECK_MPI_OK(mp_init(&mp_A));
9372 + CHECK_MPI_OK(mp_init(&mp_a));
9373 + CHECK_MPI_OK(mp_init(&mp_B));
9374 + CHECK_MPI_OK(mp_init(&mp_res1));
9375 + CHECK_MPI_OK(mp_init(&mp_res2));
9376 + CHECK_MPI_OK(mp_init(&mp_pms));
9377 +
9378 + /* check server-supplied parameters */
9379 + SECITEM_TO_MPINT(srp->N, &mp_N);
9380 + SECITEM_TO_MPINT(srp->g, &mp_g);
9381 + SECITEM_TO_MPINT(srp->ppub,&mp_B);
9382 +
9383 + CHECK_SEC_OK(srp_backdoor_check(&mp_N, &mp_B));
9384 +
9385 + /*
9386 + * create hashed variables u, k, x
9387 + */
9388 +
9389 + zero = PORT_ZAlloc(len);
9390 + it_u = SECITEM_AllocItem(NULL, NULL, SHA1_LENGTH);
9391 + it_k = SECITEM_AllocItem(NULL, NULL, SHA1_LENGTH);
9392 + it_x = SECITEM_AllocItem(NULL, NULL, SHA1_LENGTH);
9393 +
9394 + if (!zero || !it_u || !it_k || !it_x) {
9395 + PORT_SetError(SEC_ERROR_NO_MEMORY);
9396 + goto cleanup;
9397 + }
9398 +
9399 + /* u = SHA1( PAD(A) | PAD(B) ) */
9400 + SHA1_Begin(ctx);
9401 + SHA1_Update(ctx, zero, len - prvKey->pubKey.len);
9402 + SHA1_Update(ctx, prvKey->pubKey.data, prvKey->pubKey.len);
9403 + SHA1_Update(ctx, zero, len - srp->ppub.len);
9404 + SHA1_Update(ctx, srp->ppub.data, srp->ppub.len);
9405 + SHA1_End(ctx, it_u->data, &it_u->len, SHA1_LENGTH);
9406 +
9407 + /* k = SHA1( N | PAD(g) ) */
9408 + SHA1_Begin(ctx);
9409 + SHA1_Update(ctx, srp->N.data, srp->N.len);
9410 + SHA1_Update(ctx, zero, len - srp->g.len);
9411 + SHA1_Update(ctx, srp->g.data, srp->g.len);
9412 + SHA1_End(ctx, it_k->data, &it_k->len, SHA1_LENGTH);
9413 +
9414 + /* x = SHA1(s | SHA1(I | ":" | P)) */
9415 + SHA1_Begin(ctx);
9416 + SHA1_Update(ctx, srp->u.data, srp->u.len);
9417 + SHA1_Update(ctx,(unsigned char *)":",1);
9418 + SHA1_Update(ctx, prvKey->secret.data, prvKey->secret.len);
9419 + SHA1_End(ctx, it_x->data, &it_x->len, SHA1_LENGTH);
9420 +
9421 + SHA1_Begin(ctx);
9422 + SHA1_Update(ctx, srp->s.data, srp->s.len);
9423 + SHA1_Update(ctx, it_x->data, it_x->len);
9424 + SHA1_End(ctx, it_x->data, &it_x->len, SHA1_LENGTH);
9425 +
9426 + /*
9427 + * compute pms = (B - (k * g^x)) ^ (a + (u * x)) % N
9428 + */
9429 +
9430 + SECITEM_TO_MPINT(*it_u, &mp_u);
9431 + SECITEM_TO_MPINT(*it_k, &mp_k);
9432 + SECITEM_TO_MPINT(*it_x, &mp_x);
9433 + SECITEM_TO_MPINT(prvKey->prvKey, &mp_a);
9434 +
9435 + CHECK_MPI_OK(mp_exptmod(&mp_g,&mp_x,&mp_N,&mp_res2));
9436 + CHECK_MPI_OK(mp_mulmod(&mp_res2,&mp_k,&mp_N,&mp_res2));
9437 + CHECK_MPI_OK(mp_submod(&mp_B,&mp_res2,&mp_N,&mp_res2));
9438 + CHECK_MPI_OK(mp_mul(&mp_u, &mp_x, &mp_res1));
9439 + CHECK_MPI_OK(mp_add(&mp_res1,&mp_a,&mp_res1));
9440 + CHECK_MPI_OK(mp_exptmod(&mp_res2,&mp_res1,&mp_N,&mp_pms));
9441 +
9442 + MPINT_TO_SECITEM(&mp_pms, pms, NULL);
9443 + rv = SECSuccess;
9444 +cleanup:
9445 + PORT_Free(zero);
9446 + SECITEM_FreeItem(it_u, PR_TRUE);
9447 + SECITEM_FreeItem(it_k, PR_TRUE);
9448 + SECITEM_FreeItem(it_x, PR_TRUE);
9449 + SHA1_DestroyContext(ctx, PR_TRUE);
9450 + mp_clear(&mp_N);
9451 + mp_clear(&mp_g);
9452 + mp_clear(&mp_a);
9453 + mp_clear(&mp_A);
9454 + mp_clear(&mp_B);
9455 + mp_clear(&mp_k);
9456 + mp_clear(&mp_u);
9457 + mp_clear(&mp_x);
9458 + mp_clear(&mp_pms);
9459 + mp_clear(&mp_res1);
9460 + mp_clear(&mp_res2);
9461 + if (err) {
9462 + MP_TO_SEC_ERROR(err);
9463 + rv = SECFailure;
9464 + }
9465 + return rv;
9466 +}
9467 +
9468 +
9469 +/* SRP_NewServerKeyPair
9470 + * creates a new srp key pair for the server
9471 + *
9472 + * k = SHA1(N | PAD(g))
9473 + * pubKey = k*v + g^prvKey % N
9474 + */
9475 +SECStatus SRP_NewServerKeyPair(SRPPrivateKey **prvKey, SRPKeyPairParams *srp) {
9476 +
9477 + mp_int mp_N, mp_g, mp_pub, mp_prv, mp_k, mp_v, mp_res;
9478 + PRArenaPool *arena;
9479 + SRPPrivateKey *key;
9480 + SECItem *it_k;
9481 + unsigned char *zero;
9482 + mp_err err = MP_OKAY;
9483 + SECStatus rv = SECFailure;
9484 + SHA1Context *ctx = SHA1_NewContext();
9485 +
9486 +
9487 + if (!srp || !prvKey) {
9488 + PORT_SetError(SEC_ERROR_INVALID_ARGS);
9489 + return SECFailure;
9490 + }
9491 + arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
9492 + if (!arena) {
9493 + PORT_SetError(SEC_ERROR_NO_MEMORY);
9494 + return SECFailure;
9495 + }
9496 + key = (SRPPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(SRPPrivateKey));
9497 + if (!key) {
9498 + PORT_FreeArena(arena, PR_TRUE);
9499 + PORT_SetError(SEC_ERROR_NO_MEMORY);
9500 + return SECFailure;
9501 + }
9502 + key->arena = arena;
9503 +
9504 + /* prv=rand() */
9505 + SECITEM_AllocItem(arena, &key->prvKey, SRP_SECRET_KEY_LEN);
9506 + rv = RNG_GenerateGlobalRandomBytes(key->prvKey.data, key->prvKey.len);
9507 +
9508 + if (rv != SECSuccess || !(&key->prvKey)) {
9509 + PORT_SetError(SEC_ERROR_NO_MEMORY);
9510 + PORT_FreeArena(arena, PR_TRUE);
9511 + return SECFailure;
9512 + }
9513 +
9514 + it_k = SECITEM_AllocItem(NULL, NULL, SHA1_LENGTH);
9515 + zero = PORT_ZAlloc(srp->N.len);
9516 +
9517 + if (!zero || !it_k) {
9518 + PORT_SetError(SEC_ERROR_NO_MEMORY);
9519 + goto cleanup;
9520 + }
9521 +
9522 + /* k = SHA1( N | PAD(g) ) */
9523 + SHA1_Begin(ctx);
9524 + SHA1_Update(ctx, srp->N.data, srp->N.len);
9525 + SHA1_Update(ctx, zero, srp->N.len - srp->g.len);
9526 + SHA1_Update(ctx, srp->g.data, srp->g.len);
9527 + SHA1_End(ctx, it_k->data, &it_k->len, SHA1_LENGTH);
9528 +
9529 + /*
9530 + * create key pair
9531 + */
9532 + CHECK_MPI_OK( mp_init(&mp_N) );
9533 + CHECK_MPI_OK( mp_init(&mp_g) );
9534 + CHECK_MPI_OK( mp_init(&mp_k) );
9535 + CHECK_MPI_OK( mp_init(&mp_v) );
9536 + CHECK_MPI_OK( mp_init(&mp_pub));
9537 + CHECK_MPI_OK( mp_init(&mp_prv));
9538 + CHECK_MPI_OK( mp_init(&mp_res));
9539 + SECITEM_TO_MPINT(*it_k, &mp_k);
9540 + SECITEM_TO_MPINT(srp->N, &mp_N);
9541 + SECITEM_TO_MPINT(srp->g, &mp_g);
9542 + SECITEM_TO_MPINT(srp->secret, &mp_v);
9543 + SECITEM_TO_MPINT(key->prvKey, &mp_prv);
9544 +
9545 + char *N_str;
9546 + char *g_str;
9547 + printf("X\n");
9548 + N_str = PORT_ZAlloc(mp_radix_size(&mp_N,16));
9549 + mp_toradix(&mp_N,N_str,16);
9550 + printf("%s\n",N_str);
9551 + g_str = PORT_ZAlloc(mp_radix_size(&mp_g,16));
9552 + mp_toradix(&mp_g,g_str,16);
9553 + printf("%s\n",g_str);
9554 + printf("X\n");
9555 +
9556 +
9557 + /* pub = k*v + g^prv % N */
9558 + CHECK_MPI_OK(mp_exptmod(&mp_g, &mp_prv, &mp_N, &mp_pub));
9559 + CHECK_MPI_OK(mp_mulmod(&mp_k, &mp_v, &mp_N, &mp_res));
9560 + CHECK_MPI_OK(mp_addmod(&mp_res, &mp_pub, &mp_N, &mp_pub));
9561 +
9562 + MPINT_TO_SECITEM(&mp_pub, &key->pubKey, arena);
9563 + CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->secret, &srp->secret));
9564 + *prvKey = key;
9565 +
9566 +cleanup:
9567 + PORT_Free(zero);
9568 + SECITEM_FreeItem(it_k,PR_TRUE);
9569 + SHA1_DestroyContext(ctx, PR_TRUE);
9570 + mp_clear(&mp_N);
9571 + mp_clear(&mp_g);
9572 + mp_clear(&mp_k);
9573 + mp_clear(&mp_v);
9574 + mp_clear(&mp_pub);
9575 + mp_clear(&mp_prv);
9576 + mp_clear(&mp_res);
9577 + if (err) {
9578 + PORT_FreeArena(arena, PR_TRUE); /* not zeroized!! */
9579 + MP_TO_SEC_ERROR(err);
9580 + rv = SECFailure;
9581 + }
9582 + return rv;
9583 +}
9584 +
9585 +/* SRP_NewClientKeyPair
9586 + * creates a new srp key pair for the client
9587 + *
9588 + * prv = rand()
9589 + * pub = g^prv % N, with prv at least 256bit random
9590 + * prvKey->secret = srp->secret
9591 + */
9592 +
9593 +SECStatus SRP_NewClientKeyPair(SRPPrivateKey **prvKey, SRPKeyPairParams *srp) {
9594 +
9595 +
9596 + SRPPrivateKey *key;
9597 + PRArenaPool *arena;
9598 + mp_int mp_N, mp_g, mp_prv, mp_pub;
9599 + mp_err err = MP_OKAY;
9600 + SECStatus rv = SECFailure;
9601 +
9602 + if (!srp || !prvKey) {
9603 + PORT_SetError(SEC_ERROR_INVALID_ARGS);
9604 + return SECFailure;
9605 + }
9606 +
9607 + arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
9608 + if (!arena) {
9609 + PORT_SetError(SEC_ERROR_NO_MEMORY);
9610 + return SECFailure;
9611 + }
9612 +
9613 + key = (SRPPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(SRPPrivateKey));
9614 + if (!key) {
9615 + PORT_SetError(SEC_ERROR_NO_MEMORY);
9616 + PORT_FreeArena(arena, PR_TRUE);
9617 + return SECFailure;
9618 + }
9619 + key->arena = arena;
9620 +
9621 + /* prv=rand() */
9622 + SECITEM_AllocItem(arena, &key->prvKey, SRP_SECRET_KEY_LEN);
9623 + rv = RNG_GenerateGlobalRandomBytes(key->prvKey.data, key->prvKey.len);
9624 +
9625 + if (rv != SECSuccess || !(&key->prvKey)) {
9626 + PORT_SetError(SEC_ERROR_NO_MEMORY);
9627 + PORT_FreeArena(arena, PR_TRUE);
9628 + return SECFailure;
9629 + }
9630 +
9631 + /* pub = g^prv % N */
9632 + CHECK_MPI_OK( mp_init(&mp_N) );
9633 + CHECK_MPI_OK( mp_init(&mp_g) );
9634 + CHECK_MPI_OK( mp_init(&mp_pub));
9635 + CHECK_MPI_OK( mp_init(&mp_prv));
9636 + SECITEM_TO_MPINT(srp->N, &mp_N);
9637 + SECITEM_TO_MPINT(srp->g, &mp_g);
9638 + SECITEM_TO_MPINT(key->prvKey, &mp_prv);
9639 +
9640 + if (SECSuccess != check_srp_group(&mp_N, &mp_g))
9641 + goto cleanup;
9642 +
9643 + CHECK_MPI_OK( mp_exptmod(&mp_g, &mp_prv, &mp_N, &mp_pub) );
9644 +
9645 + MPINT_TO_SECITEM(&mp_pub, &key->pubKey, key->arena);
9646 + CHECK_SEC_OK( SECITEM_CopyItem(arena, &key->secret, &srp->secret) );
9647 + *prvKey = key;
9648 +
9649 +cleanup:
9650 + mp_clear(&mp_g);
9651 + mp_clear(&mp_N);
9652 + mp_clear(&mp_pub);
9653 + mp_clear(&mp_prv);
9654 + if (err) {
9655 + PORT_FreeArena(arena, PR_TRUE); /* not zeroized!! */
9656 + MP_TO_SEC_ERROR(err);
9657 + rv = SECFailure;
9658 + }
9659 + return rv;
9660 +}
9661 +
9662 diff --git a/net/third_party/nss/ssl/srp_groups.h b/net/third_party/nss/ssl/srp_ groups.h
9663 new file mode 100644
9664 index 0000000..e327a0f
9665 --- /dev/null
9666 +++ b/net/third_party/nss/ssl/srp_groups.h
9667 @@ -0,0 +1,58 @@
9668 +/* ***** BEGIN LICENSE BLOCK *****
9669 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
9670 + *
9671 + * The contents of this file are subject to the Mozilla Public License Version
9672 + * 1.1 (the "License"); you may not use this file except in compliance with
9673 + * the License. You may obtain a copy of the License at
9674 + * http://www.mozilla.org/MPL/
9675 + *
9676 + * Software distributed under the License is distributed on an "AS IS" basis,
9677 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
9678 + * for the specific language governing rights and limitations under the
9679 + * License.
9680 + *
9681 + * The Initial Developer of the Original Code is
9682 + * Steffen Schulz - pepe (at) cbg.dyndns.org
9683 + *
9684 + * Portions created by the Initial Developer are Copyright (C) 2007
9685 + * the Initial Developer. All Rights Reserved.
9686 + *
9687 + * Contributor(s):
9688 + *
9689 + * Alternatively, the contents of this file may be used under the terms of
9690 + * either the GNU General Public License Version 2 or later (the "GPL"), or
9691 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
9692 + * in which case the provisions of the GPL or the LGPL are applicable instead
9693 + * of those above. If you wish to allow use of your version of this file only
9694 + * under the terms of either the GPL or the LGPL, and not to allow others to
9695 + * use your version of this file under the terms of the MPL, indicate your
9696 + * decision by deleting the provisions above and replace them with the notice
9697 + * and other provisions required by the GPL or the LGPL. If you do not delete
9698 + * the provisions above, a recipient may use your version of this file under
9699 + * the terms of any one of the MPL, the GPL or the LGPL.
9700 + *
9701 + * ***** END LICENSE BLOCK ***** */
9702 +
9703 +/* number of known groups */
9704 +#define SRP_KNOWN_GROUPS 7
9705 +
9706 +/* Whitelist of known-good group parameters, taken from RFC 5054. The client
9707 + * checks supplied params against this whitelist. There is currently no support
9708 + * for application specified group parameters.
9709 + */
9710 +
9711 +struct srp_group {
9712 + char *modulus;
9713 + char *generator;
9714 +};
9715 +
9716 +const struct srp_group known_srp_groups[SRP_KNOWN_GROUPS] = {
9717 + { "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF74 96EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD 69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE 8376435B9FC61D2FC0EB06E3", "2"},
9718 + { "9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19CC4D5F4F5F55 6E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A22E8DCDF028A7CEC67F0D08134B1C8 B97989149B609E0BE3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF0195 39349627DB2FD53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87F8A2FE9 B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB", "2"},
9719 + { "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CB B4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF609517 9A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041 D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E6 88F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E73 03CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D 525F54759B65E372FCD68EF20FA7111F9E4AFF73", "2"},
9720 + { "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA6 3B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576 625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651 ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356 208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C 180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D22618 98FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA7157 5D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06 D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA0 74E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", "5"},
9721 + { "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA6 3B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576 625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651 ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356 208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C 180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D22618 98FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA7157 5D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06 D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA0 74E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C32718 6AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C5947 4E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127 D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", "5",} ,
9722 + { "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA6 3B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576 625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651 ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356 208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C 180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D22618 98FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA7157 5D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06 D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA0 74E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C32718 6AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C5947 4E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127 D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2 602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0 865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401 378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031 900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7E BF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1 A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E 6DCC4024FFFFFFFFFFFFFFFF", "5"},
9723 + { "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA6 3B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576 625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651 ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356 208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C 180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D22618 98FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA7157 5D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06 D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA0 74E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C32718 6AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C5947 4E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127 D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2 602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0 865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401 378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031 900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7E BF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1 A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E 6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF 8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BE FC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7F A2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899 A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4 EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2 765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF", "13"}
9724 +};
9725 +
9726 diff --git a/net/third_party/nss/ssl/ssl.def b/net/third_party/nss/ssl/ssl.def
9727 index 76417d0..0af96ba 100644
9728 --- a/net/third_party/nss/ssl/ssl.def
9729 +++ b/net/third_party/nss/ssl/ssl.def
9730 @@ -136,6 +136,10 @@ SSL_ReHandshakeWithTimeout;
9731 ;+NSS_3.11.8 { # NSS 3.11.8 release
9732 ;+ global:
9733 SSL_CanBypass;
9734 +
9735 +SSL_SetUserLogin;
9736 +SSL_UserPasswdHook;
9737 +SSL_GetSRPParamsHook;
9738 ;+ local:
9739 ;+*;
9740 ;+};
9741 diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
9742 index 21d7c8d..8a8d53f 100644
9743 --- a/net/third_party/nss/ssl/ssl.h
9744 +++ b/net/third_party/nss/ssl/ssl.h
9745 @@ -437,6 +437,41 @@ SSL_IMPORT PRFileDesc *SSL_ReconfigFD(PRFileDesc *model, PR FileDesc *fd);
9746 */
9747 SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a);
9748
9749 +
9750 +/*
9751 + * Set the client side user name and password non-interactively.
9752 + */
9753 +SSL_IMPORT SECStatus SSL_SetUserLogin(PRFileDesc *fd, char *u, char *p);
9754 +
9755 +/*
9756 + * This sets the client side callback for SSL to retrieve the user password.
9757 + * fd - the file descriptor for the connection in question
9758 + * func - callback function pointer
9759 + * pw - user password
9760 + */
9761 +
9762 +typedef SECStatus (PR_CALLBACK *SSLUserPasswdCB)(PRFileDesc *fd,
9763 + SECItem *pw, void *arg);
9764 +
9765 +SSL_IMPORT SECStatus SSL_UserPasswdHook(PRFileDesc *fd, SSLUserPasswdCB func,
9766 + void *arg);
9767 +
9768 +/*
9769 + * This sets the server side callback function for SSL to retrieve the SRP
9770 + * authentication parameters associated with a specific user login.
9771 + * fd - the file descriptor of the connection
9772 + * func - pointer to the callback function
9773 + * user - username to lookup in app database
9774 + * srp - SRP auth paramters supplied to SSL by app
9775 + */
9776 +
9777 +typedef SECStatus (PR_CALLBACK *SSLGetSRPParamsCB)(PRFileDesc *fd,
9778 + SECKEYSRPParams *srp,
9779 + void *arg);
9780 +
9781 +SSL_IMPORT SECStatus SSL_GetSRPParamsHook(PRFileDesc *fd,
9782 + SSLGetSRPParamsCB func, void *arg);
9783 +
9784 /*
9785 ** This is a callback for dealing with server certs that are not authenticated
9786 ** by the client. The client app can decide that it actually likes the
9787 diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con .c
9788 index f5c0880..8f1f9e4 100644
9789 --- a/net/third_party/nss/ssl/ssl3con.c
9790 +++ b/net/third_party/nss/ssl/ssl3con.c
9791 @@ -118,6 +118,9 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEME NTED] = {
9792 #endif /* NSS_ENABLE_ECC */
9793 { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_ FALSE},
9794 { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9795 + { TLS_SRP_SHA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9796 + { TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9797 + { TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9798
9799 #ifdef NSS_ENABLE_ECC
9800 { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9801 @@ -141,11 +144,15 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLE MENTED] = {
9802 { SSL_RSA_WITH_RC4_128_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
9803 { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9804 { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9805 + { TLS_SRP_SHA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9806 + { TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9807 + { TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9808
9809 #ifdef NSS_ENABLE_ECC
9810 { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9811 { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9812 #endif /* NSS_ENABLE_ECC */
9813 + { TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9814 { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9815 { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9816 #ifdef NSS_ENABLE_ECC
9817 @@ -154,6 +161,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEME NTED] = {
9818 #endif /* NSS_ENABLE_ECC */
9819 { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
9820 { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
9821 + { TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9822 + { TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9823
9824
9825 { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
9826 @@ -283,6 +292,9 @@ static const ssl3KEADef kea_defs[] =
9827 {kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE},
9828 {kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE},
9829 {kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE },
9830 + {kea_srp, kt_srp, sign_null, PR_FALSE, 0, PR_FALSE},
9831 + {kea_srp_rsa, kt_srp, sign_rsa, PR_FALSE, 0, PR_FALSE},
9832 + {kea_srp_dss, kt_srp, sign_dsa, PR_FALSE, 0, PR_FALSE},
9833 #ifdef NSS_ENABLE_ECC
9834 {kea_ecdh_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE},
9835 {kea_ecdhe_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE},
9836 @@ -344,6 +356,21 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] =
9837
9838
9839 /* New TLS cipher suites */
9840 + {TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_srp},
9841 + {TLS_SRP_SHA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_srp},
9842 + {TLS_SRP_SHA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_srp},
9843 + {TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
9844 + cipher_3des, mac_sha, kea_srp_rsa},
9845 + {TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
9846 + cipher_3des, mac_sha, kea_srp_dss},
9847 + {TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
9848 + cipher_aes_128, mac_sha, kea_srp_rsa},
9849 + {TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
9850 + cipher_aes_128, mac_sha, kea_srp_dss},
9851 + {TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
9852 + cipher_aes_256, mac_sha, kea_srp_rsa},
9853 + {TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
9854 + cipher_aes_256, mac_sha, kea_srp_dss},
9855 {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa },
9856 {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe _dss},
9857 {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe _rsa},
9858 @@ -420,7 +447,8 @@ static const CK_MECHANISM_TYPE kea_alg_defs[] = {
9859 CKM_RSA_PKCS,
9860 CKM_DH_PKCS_DERIVE,
9861 CKM_KEA_KEY_DERIVE,
9862 - CKM_ECDH1_DERIVE
9863 + CKM_ECDH1_DERIVE,
9864 + CKM_NSS_SRP_DERIVE
9865 };
9866
9867 typedef struct SSLCipher2MechStr {
9868 @@ -695,12 +723,27 @@ ssl3_config_match_init(sslSocket *ss)
9869 }
9870 #endif /* NSS_ENABLE_ECC */
9871
9872 + /* XXX this should be merged with switch(kea) from above */
9873 + switch (cipher_def->key_exchange_alg) {
9874 + case kea_srp_rsa:
9875 + svrAuth = ss->serverCerts + kt_rsa;
9876 + break;
9877 + case kea_srp_dss:
9878 + svrAuth = ss->serverCerts + kt_null; /* don't ask me..*/
9879 + break;
9880 + default:
9881 + svrAuth = ss->serverCerts + exchKeyType;
9882 + break;
9883 + }
9884 +
9885 +
9886 /* Mark the suites that are backed by real tokens, certs and keys */
9887 suite->isPresent = (PRBool)
9888 (((exchKeyType == kt_null) ||
9889 ((!isServer || (svrAuth->serverKeyPair &&
9890 svrAuth->SERVERKEY &&
9891 - svrAuth->serverCertChain)) &&
9892 + svrAuth->serverCertChain) ||
9893 + cipher_def->key_exchange_alg == kea_srp) &&
9894 PK11_TokenExists(kea_alg_defs[exchKeyType]))) &&
9895 ((cipher_alg == calg_null) || PK11_TokenExists(cipher_mech)));
9896 if (suite->isPresent)
9897 @@ -1080,6 +1123,57 @@ ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem pub licExponent,
9898 return rv;
9899 }
9900
9901 +/* Caller must set hiLevel error code.
9902 + * Called from ssl3_SendSRPServerKeyExchange */
9903 +static SECStatus
9904 +ssl3_ComputeSRPKeyHash(SECItem *N, SECItem *g, SECItem *s, SECItem *B,
9905 + SSL3Random *client_rand, SSL3Random *server_rand,
9906 + SSL3Hashes *hashes, PRBool bypassPKCS11)
9907 +{
9908 + PRUint8 * hashBuf;
9909 + PRUint8 * pBuf;
9910 + SECStatus rv = SECFailure;
9911 + unsigned int bufLen;
9912 +
9913 + bufLen = 2*SSL3_RANDOM_LENGTH + N->len + 2 + g->len + 2
9914 + + s->len + 1 + B->len + 2;
9915 +
9916 + hashBuf = PORT_Alloc(bufLen);
9917 + if (!hashBuf) {
9918 + return SECFailure;
9919 + }
9920 +
9921 + memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
9922 + pBuf = hashBuf + SSL3_RANDOM_LENGTH;
9923 + memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
9924 + pBuf += SSL3_RANDOM_LENGTH;
9925 + pBuf[0] = (PRUint8)(N->len >> 8);
9926 + pBuf[1] = (PRUint8)(N->len);
9927 + pBuf+=2;
9928 + memcpy(pBuf, N->data, N->len);
9929 + pBuf += N->len;
9930 + pBuf[0] = (PRUint8)(g->len >> 8);
9931 + pBuf[1] = (PRUint8)(g->len);
9932 + pBuf+=2;
9933 + memcpy(pBuf, g->data, g->len);
9934 + pBuf += g->len;
9935 + pBuf[0] = (PRUint8)(s->len);
9936 + pBuf+=1;
9937 + memcpy(pBuf, s->data, s->len);
9938 + pBuf += s->len;
9939 + pBuf[0] = (PRUint8)(B->len >> 8);
9940 + pBuf[1] = (PRUint8)(B->len);
9941 + pBuf+=2;
9942 + memcpy(pBuf, B->data, B->len);
9943 + pBuf += B->len;
9944 +
9945 + rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
9946 +
9947 + if (hashBuf)
9948 + PORT_Free(hashBuf);
9949 + return rv;
9950 +}
9951 +
9952 /* Caller must set hiLevel error code. */
9953 /* Called from ssl3_HandleServerKeyExchange. */
9954 static SECStatus
9955 @@ -2663,6 +2757,8 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
9956 error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break;
9957 case bad_certificate_hash_value:
9958 error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT; break;
9959 + case unknown_psk_identity:
9960 + error = SSL_ERROR_UNKNOWN_PSK_IDENTITY_ALERT; break;
9961 default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break;
9962 }
9963 if (level == alert_fatal) {
9964 @@ -2828,7 +2924,8 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
9965 * data into a 48-byte value.
9966 */
9967 PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
9968 - (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
9969 + (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh) ||
9970 + (ss->ssl3.hs.kea_def->exchKeyType == kt_srp));
9971 SECStatus rv = SECFailure;
9972 CK_MECHANISM_TYPE master_derive;
9973 CK_MECHANISM_TYPE key_derive;
9974 @@ -4733,8 +4830,242 @@ loser:
9975 return rv;
9976 }
9977
9978 +/* Read srp values from datastream and verify the signature
9979 + * if requiried by cipher. Save parameters to ss->sec.peerKey.
9980 + *
9981 + * called from ssl3_HandleServerKeyExchange
9982 + */
9983 +static SECStatus
9984 +ssl3_HandleSRPServerKeyExchange(sslSocket *ss, SSL3Opaque *b,
9985 + PRUint32 length) {
9986 +
9987 + SECItem signature = {siBuffer, NULL, 0};
9988 + PRArenaPool *arena = NULL;
9989 + SECKEYPublicKey *peerKey = NULL;
9990 + SECStatus rv;
9991 + SSL3Hashes hashes;
9992 + SECItem srp_N, srp_g, srp_s, srp_ppub;
9993 + int errCode;
9994 +
9995 + rv = ssl3_ConsumeHandshakeVariable(ss, &srp_N, 2, &b, &length);
9996 + if (rv != SECSuccess) {
9997 + goto loser; /* malformed. */
9998 + }
9999 + rv = ssl3_ConsumeHandshakeVariable(ss, &srp_g, 2, &b, &length);
10000 + if (rv != SECSuccess) {
10001 + goto loser; /* malformed. */
10002 + }
10003 + rv = ssl3_ConsumeHandshakeVariable(ss, &srp_s, 1, &b, &length);
10004 + if (rv != SECSuccess) {
10005 + goto loser; /* malformed. */
10006 + }
10007 + rv = ssl3_ConsumeHandshakeVariable(ss, &srp_ppub, 2, &b, &length);
10008 + if (rv != SECSuccess) {
10009 + goto loser; /* malformed. */
10010 + }
10011 +
10012 + if (ss->ssl3.hs.kea_def->kea != kea_srp) { /* there MUST be a signature */
10013 + rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
10014 + if (rv != SECSuccess) {
10015 + goto loser; /* malformed. */
10016 + }
10017 + rv = ssl3_ComputeSRPKeyHash(&srp_N, &srp_g, &srp_s, &srp_ppub,
10018 + &ss->ssl3.hs.client_random,
10019 + &ss->ssl3.hs.server_random,
10020 + &hashes, ss->opt.bypassPKCS11);
10021 + if (rv != SECSuccess) {
10022 + errCode = ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE );
10023 + goto alert_loser;
10024 + }
10025 + rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
10026 + PR_TRUE, ss->pkcs11P inArg);
10027 + if (rv != SECSuccess) {
10028 + errCode = ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE );
10029 + goto alert_loser;
10030 + }
10031 + }
10032 +
10033 + /* all ok, save and return */
10034 + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
10035 + if (arena == NULL) {
10036 + return SECFailure;
10037 + }
10038 + ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
10039 + if (peerKey == NULL) {
10040 + return SECFailure;
10041 + }
10042 + peerKey->arena = arena;
10043 + peerKey->keyType = srpKey;
10044 + peerKey->pkcs11Slot = NULL;
10045 + peerKey->pkcs11ID = CK_INVALID_HANDLE;
10046 +
10047 + if (SECITEM_CopyItem(arena, &peerKey->u.srp.N, &srp_N) ||
10048 + SECITEM_CopyItem(arena, &peerKey->u.srp.g, &srp_g) ||
10049 + SECITEM_CopyItem(arena, &peerKey->u.srp.s, &srp_s) ||
10050 + SECITEM_CopyItem(arena, &peerKey->u.srp.ppub, &srp_ppub)) {
10051 + return SECFailure;
10052 + }
10053 + return SECSuccess;
10054 +
10055 +alert_loser:
10056 + (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
10057 +loser:
10058 + PORT_SetError(errCode);
10059 + return SECFailure;
10060 +}
10061 +
10062 +/* Calculate ClientKeyExchange and Pre-Master-Secret via SRP_GenKeys(),
10063 + * then send ClientKeyExchange and derive SSL master key
10064 + *
10065 + * called from ssl3_SendClientKeyExchange()
10066 + */
10067 +static SECStatus
10068 +ssl3_SendSRPClientKeyExchange(sslSocket *ss, SECKEYPublicKey * pubKey) {
10069 +
10070 + SECKEYSRPParams *srpParam;
10071 + SECStatus rv;
10072 +
10073 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
10074 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
10075 +
10076 + srpParam = PORT_ZAlloc(sizeof(SECKEYSRPParams));
10077 + if (!srpParam) {
10078 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
10079 + goto loser;
10080 + }
10081 +
10082 + /* PW-Callback overrides SSL_SetUserLogin. If both fail to
10083 + * provide a password, the token must know it or fail. */
10084 + if (ss->getUserPasswd) {
10085 + if (!ss->sec.userPasswd)
10086 + ss->sec.userPasswd = SECITEM_AllocItem(NULL,NULL,0);
10087 + SECITEM_FreeItem(ss->sec.userPasswd, PR_FALSE);
10088 + ss->getUserPasswd(ss->fd, ss->sec.userPasswd, ss->getUserPasswdArg);
10089 + }
10090 + if (ss->sec.userPasswd) {
10091 + srpParam->secret.data = ss->sec.userPasswd->data;
10092 + srpParam->secret.len = ss->sec.userPasswd->len;
10093 + ss->sec.userPasswd = NULL;
10094 + }
10095
10096 + /* calculate client key pair and PMS, then send key exchange data */
10097 + if (ss->opt.bypassPKCS11) {
10098 + SECItem pms = {0, NULL, 0};
10099 + SRPPrivateKey *prvKey;
10100 + SRPKeyPairParams keyPairParam;
10101 + keyPairParam.N.data = pubKey->u.srp.N.data;
10102 + keyPairParam.N.len = pubKey->u.srp.N.len;
10103 + keyPairParam.g.data = pubKey->u.srp.g.data;
10104 + keyPairParam.g.len = pubKey->u.srp.g.len;
10105 + keyPairParam.secret.data = srpParam->secret.data;
10106 + keyPairParam.secret.len = srpParam->secret.len;
10107 +
10108 + rv = SRP_NewClientKeyPair(&prvKey, &keyPairParam);
10109 + if (rv != SECSuccess) goto loser; /* err set by SRP_ClientDerive */
10110 +
10111 + SRPDeriveParams deriveParam;
10112 + deriveParam.N.data = pubKey->u.srp.N.data;
10113 + deriveParam.N.len = pubKey->u.srp.N.len;
10114 + deriveParam.g.data = pubKey->u.srp.g.data;
10115 + deriveParam.g.len = pubKey->u.srp.g.len;
10116 + deriveParam.s.data = pubKey->u.srp.s.data;
10117 + deriveParam.s.len = pubKey->u.srp.s.len;
10118 + deriveParam.u.data = ss->sec.userName->data;
10119 + deriveParam.u.len = ss->sec.userName->len;
10120 + deriveParam.ppub.data= pubKey->u.srp.ppub.data;
10121 + deriveParam.ppub.len = pubKey->u.srp.ppub.len;
10122 +
10123 +
10124 + if (SECSuccess != SRP_ClientDerive(prvKey, &deriveParam, &pms)) {
10125 + goto derive_fail;
10126 + }
10127 +
10128 + /* client key exchange data */
10129 + rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
10130 + prvKey->pubKey.len + 2);
10131 + if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* * /
10132 + rv = ssl3_AppendHandshakeVariable(ss, prvKey->pubKey.data,
10133 + prvKey->pubKey.len, 2);
10134 + if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* * /
10135 +
10136 + /* init pending cipher spec*/
10137 + rv = ssl3_MasterKeyDeriveBypass(ss->ssl3.pwSpec,
10138 + (unsigned char *)&ss->ssl3.hs.client_random,
10139 + (unsigned char *)&ss->ssl3.hs.server_random,
10140 + &pms, PR_TRUE, PR_FALSE);
10141 + if (rv != SECSuccess) {
10142 + ss->ssl3.pwSpec->msItem.data = ss->ssl3.pwSpec->raw_master_secret;
10143 + ss->ssl3.pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
10144 + PK11_GenerateRandom(ss->ssl3.pwSpec->msItem.data,
10145 + SSL3_MASTER_SECRET_LENGTH);
10146 + }
10147 + rv = ssl3_InitPendingCipherSpec(ss, NULL);
10148 +
10149 + SECITEM_FreeItem(&pms, PR_FALSE);
10150 + PORT_FreeArena(prvKey->arena, PR_TRUE);
10151 + } else { /* PK11 path */
10152 + PK11SymKey *pms = NULL;
10153 + SECKEYPrivateKey *prvKey = NULL;
10154 + SECKEYPublicKey *newPub = NULL;
10155 +
10156 + srpParam->N.data = pubKey->u.srp.N.data;
10157 + srpParam->N.len = pubKey->u.srp.N.len;
10158 + srpParam->g.data = pubKey->u.srp.g.data;
10159 + srpParam->g.len = pubKey->u.srp.g.len;
10160 + srpParam->s.data = pubKey->u.srp.s.data;
10161 + srpParam->s.len = pubKey->u.srp.s.len;
10162 + srpParam->u.data = ss->sec.userName->data;
10163 + srpParam->u.len = ss->sec.userName->len;
10164 +
10165 + /* The token handles (missing) info supplied in srpParam
10166 + * The template not actually involved in key generation,
10167 + * but it's important in the server key exchange */
10168 +
10169 + prvKey = SECKEY_CreateSRPPrivateKey(srpParam, &newPub, PR_FALSE, NULL);
10170 + if (!prvKey) {
10171 + ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
10172 + rv = SECFailure;
10173 + goto loser;
10174 + }
10175 + SECITEM_CopyItem(newPub->arena, &newPub->u.srp.ppub, &pubKey->u.srp.ppu b);
10176 +
10177 + /* Now all data is in newPub and prvKey, compute pms with them */
10178 + pms = PK11_PubDerive(prvKey, newPub, PR_FALSE, NULL, NULL,
10179 + CKM_NSS_SRP_DERIVE, CKM_TLS_MASTER_KEY_DERIVE, CKF_D ERIVE, 0, NULL);
10180
10181 + if (!pms) {
10182 + goto derive_fail;
10183 + }
10184 +
10185 + /* init pending cipher spec*/
10186 + rv = ssl3_InitPendingCipherSpec(ss, pms);
10187 +
10188 +
10189 + /* client key exchange data */
10190 + rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
10191 + newPub->u.srp.pub.len + 2);
10192 + if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* * /
10193 + rv = ssl3_AppendHandshakeVariable(ss, newPub->u.srp.pub.data,
10194 + newPub->u.srp.pub.len, 2);
10195 + if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* * /
10196 +
10197 + if (pms) PK11_FreeSymKey(pms);
10198 + SECKEY_DestroyPublicKey(newPub);
10199 + } /* end of PK11 path */
10200 +
10201 +loser:
10202 + SECITEM_FreeItem(ss->sec.userName, PR_TRUE);
10203 + SECITEM_ZfreeItem(ss->sec.userPasswd, PR_TRUE);
10204 + PORT_Free(srpParam);
10205 + /* caller frees pubKey */
10206 + return rv;
10207 +derive_fail:
10208 + if (PORT_GetError() == SEC_ERROR_SRP_UNSUPPORTED_GROUP)
10209 + SSL3_SendAlert(ss, alert_fatal, insufficient_security);
10210 + if (PORT_GetError() == SEC_ERROR_SRP_ILLEGAL_PARAMETER)
10211 + SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
10212 + return SECFailure;
10213 +}
10214
10215
10216 /* Called from ssl3_HandleServerHelloDone(). */
10217 @@ -4794,7 +5125,9 @@ ssl3_SendClientKeyExchange(sslSocket *ss)
10218 rv = ssl3_SendECDHClientKeyExchange(ss, serverKey);
10219 break;
10220 #endif /* NSS_ENABLE_ECC */
10221 -
10222 + case kt_srp:
10223 + rv = ssl3_SendSRPClientKeyExchange(ss, serverKey);
10224 + break;
10225 default:
10226 /* got an unknown or unsupported Key Exchange Algorithm. */
10227 SEND_ALERT
10228 @@ -5284,7 +5617,8 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
10229 desc = unexpected_message;
10230 goto alert_loser;
10231 }
10232 - if (ss->sec.peerCert == NULL) {
10233 + if (ss->sec.peerCert == NULL &&
10234 + ss->ssl3.hs.suite_def->key_exchange_alg != kea_srp) {
10235 errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
10236 desc = unexpected_message;
10237 goto alert_loser;
10238 @@ -5473,6 +5807,13 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b , PRUint32 length)
10239 rv = ssl3_HandleECDHServerKeyExchange(ss, b, length);
10240 return rv;
10241 #endif /* NSS_ENABLE_ECC */
10242 + case kt_srp:
10243 + rv = ssl3_HandleSRPServerKeyExchange(ss, b, length);
10244 + if (rv != SECSuccess) {
10245 + errCode = ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE );
10246 + goto alert_loser;
10247 + }
10248 + return rv;
10249
10250 default:
10251 desc = handshake_failure;
10252 @@ -6034,16 +6375,20 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
10253 if (rv != SECSuccess) {
10254 return rv; /* err code is set. */
10255 }
10256 - rv = ssl3_SendCertificate(ss);
10257 - if (rv != SECSuccess) {
10258 - return rv; /* error code is set. */
10259 - }
10260 /* We have to do this after the call to ssl3_SendServerHello,
10261 * because kea_def is set up by ssl3_SendServerHello().
10262 */
10263 kea_def = ss->ssl3.hs.kea_def;
10264 ss->ssl3.hs.usedStepDownKey = PR_FALSE;
10265
10266 +
10267 + if (kea_def->kea != kea_srp) { /* SRP auth only */
10268 + rv = ssl3_SendCertificate(ss);
10269 + if (rv != SECSuccess) {
10270 + return rv; /* error code is set. */
10271 + }
10272 + }
10273 +
10274 if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
10275 /* see if we can legally use the key in the cert. */
10276 int keyLen; /* bytes */
10277 @@ -6075,6 +6420,11 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
10278 return rv; /* err code was set. */
10279 }
10280 #endif /* NSS_ENABLE_ECC */
10281 + } else if ( kea_def->exchKeyType == kt_srp ) {
10282 + rv = ssl3_SendServerKeyExchange(ss);
10283 + if (rv != SECSuccess) {
10284 + return rv; /* err code was set. */
10285 + }
10286 }
10287
10288 if (ss->opt.requestCertificate) {
10289 @@ -7099,6 +7449,196 @@ ssl3_SendServerHello(sslSocket *ss)
10290 return SECSuccess;
10291 }
10292
10293 +/* ssl3_SendSRPServerKeyExchange()
10294 + * called by ssl3_SendServerKeyExchange()
10295 + *
10296 + * - make sure we got a userid in the srp client hello extension
10297 + * - retrieve verifier and parameters for the user via callback func
10298 + * - if user nonexistant, CB makes something up if it wants to
10299 + * - continue by creating and sending the SRP key exchange data:
10300 + *
10301 + * N, g, s, v = <read from password file>
10302 + * b = random()
10303 + * k = SHA1(N | PAD(g))
10304 + * B = k*v + g^b % N
10305 + * send (N,g,s,B)
10306 + *
10307 + * save values b,v,N for calculation of pms in ssl3_HandleSRPClientKeyExchange
10308 + */
10309 +
10310 +SECStatus
10311 +ssl3_SendSRPServerKeyExchange(sslSocket *ss) {
10312 +
10313 + int bytes = 0;
10314 + const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def;
10315 + SECItem signed_hash = {siBuffer, NULL, 0};
10316 + SECStatus rv = SECFailure;
10317 + SECKEYSRPPublicKey *srp = NULL;
10318 + SECKEYPublicKey *pubKey = NULL;
10319 + SECKEYPrivateKey *prvKey = NULL;
10320 + SECKEYSRPParams *srpParams;
10321 + SSL3Hashes hashes;
10322 +
10323 + /* send error if no userid was supplied in Client Hello */
10324 + if (!ss->sec.userName || !ss->sec.userName->data)
10325 + goto unknown_id;
10326 +
10327 + /* Ask application for SRP parameters for specified username.
10328 + * Information provided via callback overrides data set on token.
10329 + * If no params provided, the token must supply them or fail.
10330 + * Callback may fail for nonexistant user.
10331 + */
10332 +
10333 + srpParams = PORT_ZAlloc(sizeof(SECKEYSRPParams));
10334 + if (!srpParams) goto no_memory;
10335 +
10336 + srpParams->u.data = ss->sec.userName->data;
10337 + srpParams->u.len = ss->sec.userName->len;
10338 +
10339 + if (ss->getSRPParams) {
10340 + rv = ss->getSRPParams(ss->fd, srpParams, ss->getSRPParamsArg);
10341 + if (rv != SECSuccess) {
10342 + SECITEM_FreeItem(&srpParams->N, PR_FALSE);
10343 + SECITEM_FreeItem(&srpParams->g, PR_FALSE);
10344 + SECITEM_FreeItem(&srpParams->s, PR_FALSE);
10345 + SECITEM_ZfreeItem(&srpParams->secret, PR_FALSE);
10346 + PORT_Free(srpParams);
10347 + goto unknown_id;
10348 + }
10349 + }
10350 +
10351 + /* create SRP server key pair */
10352 + if (ss->opt.bypassPKCS11) {
10353 + /* srpParams, keyPairParams are temporary. pubKey and prvKey have
10354 + * own arenas and are saved for ssl3_HandleSRPClientKeyExchange */
10355 + SRPPrivateKey *srpPrv;
10356 + SRPKeyPairParams keyPairParams;
10357 +
10358 + PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
10359 + if (!arena) goto no_memory;
10360 +
10361 + keyPairParams.N.data = srpParams->N.data;
10362 + keyPairParams.N.len = srpParams->N.len;
10363 + keyPairParams.g.data = srpParams->g.data;
10364 + keyPairParams.g.len = srpParams->g.len;
10365 + keyPairParams.secret.data = srpParams->secret.data;
10366 + keyPairParams.secret.len = srpParams->secret.len;
10367 +
10368 + rv = SRP_NewServerKeyPair(&srpPrv, &keyPairParams);
10369 + if (rv != SECSuccess) {
10370 + ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
10371 + return rv;
10372 + }
10373 + prvKey = (SECKEYPrivateKey *)srpPrv;
10374 +
10375 + /* create pubKey from temporary stuff */
10376 + pubKey = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
10377 + if (!pubKey) goto no_memory;
10378 + pubKey->arena = arena;
10379 + srp = &pubKey->u.srp;
10380 +
10381 + SECITEM_CopyItem(arena, &srp->N, &srpParams->N);
10382 + SECITEM_CopyItem(arena, &srp->g, &srpParams->g);
10383 + SECITEM_CopyItem(arena, &srp->s, &srpParams->s);
10384 + SECITEM_CopyItem(arena, &srp->u, &srpParams->u);
10385 + SECITEM_CopyItem(arena, &srp->pub, &srpPrv->pubKey);
10386 +
10387 + } else {
10388 +
10389 + /* input: srpParams, output: prvKey = b,B,v, pubKey = N,g,s,u,B */
10390 + prvKey = SECKEY_CreateSRPPrivateKey(srpParams, &pubKey, PR_TRUE, NULL);
10391 + if (!prvKey) {
10392 + ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
10393 + rv = SECFailure;
10394 + goto cleanup;
10395 + }
10396 + srp = &pubKey->u.srp;
10397 + }
10398 +
10399 + /* send N,g,s,B as ServerKeyExchange to Client */
10400 + /* optionally include signature for additional DSS/RSA auth */
10401 +
10402 + if (kea_def->kea != kea_srp) { /* we need a RSA/DSA signature */
10403 + rv = ssl3_ComputeSRPKeyHash(&srp->N, &srp->g, &srp->s, &srp->pub,
10404 + &ss->ssl3.hs.client _random,
10405 + &ss->ssl3.hs.server _random,
10406 + &hashes, ss->opt.by passPKCS11);
10407 + if (rv != SECSuccess) {
10408 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
10409 + goto loser;
10410 + }
10411 + /* look if we have a certificate for selected algo */
10412 + if (kea_def->kea == kea_srp_rsa)
10413 + bytes = kt_rsa;
10414 + else
10415 + bytes = kt_null;
10416 +
10417 + if (!(&ss->serverCerts[bytes])) {
10418 + /* ciphersuite signing algo does not match supplied certificate */
10419 + PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH);
10420 + return SECFailure;
10421 + }
10422 + rv = ssl3_SignHashes(&hashes, ss->serverCerts[bytes].SERVERKEY,
10423 + &signed_hash, PR_TRUE);
10424 + bytes = 2 + signed_hash.len;
10425 + }
10426 +
10427 + bytes += srp->N.len + srp->g.len + srp->s.len + srp->pub.len + 7;
10428 +
10429 + rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, bytes);
10430 + if (rv != SECSuccess)
10431 + return rv; /* err set by AppendHandshake. */
10432 +
10433 + rv = ssl3_AppendHandshakeVariable(ss, srp->N.data, srp->N.len, 2);
10434 + if (rv != SECSuccess)
10435 + return rv; /* err set by AppendHandshake. */
10436 +
10437 + rv = ssl3_AppendHandshakeVariable(ss, srp->g.data, srp->g.len, 2);
10438 + if (rv != SECSuccess)
10439 + return rv; /* err set by AppendHandshake. */
10440 +
10441 + rv = ssl3_AppendHandshakeVariable(ss, srp->s.data, srp->s.len, 1);
10442 + if (rv != SECSuccess)
10443 + return rv; /* err set by AppendHandshake. */
10444 +
10445 + rv = ssl3_AppendHandshakeVariable(ss, srp->pub.data, srp->pub.len, 2);
10446 + if (rv != SECSuccess)
10447 + return rv; /* err set by AppendHandshake. */
10448 +
10449 + if (kea_def->kea != kea_srp) {
10450 + rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
10451 + signed_hash.len, 2);
10452 + if (rv != SECSuccess) {
10453 + return rv; /* err set by AppendHandshake. */
10454 + }
10455 + SECITEM_FreeItem(&signed_hash, PR_FALSE);
10456 + }
10457 +
10458 + /* save prvKey / pubKey for use in HandleSRPClientExchange
10459 + * XXX in bypassPK11, prvKey is no PK11 object and must be casted */
10460 + ssl3KeyPair *srpPair = ssl3_NewKeyPair(prvKey, pubKey);
10461 + ss->serverCerts[kt_srp].serverKeyPair = srpPair;
10462 +
10463 +cleanup:
10464 + SECITEM_FreeItem(&srpParams->N, PR_FALSE);
10465 + SECITEM_FreeItem(&srpParams->g, PR_FALSE);
10466 + SECITEM_FreeItem(&srpParams->s, PR_FALSE);
10467 + SECITEM_ZfreeItem(&srpParams->secret, PR_FALSE);
10468 + SECITEM_FreeItem(ss->sec.userName, PR_TRUE);
10469 + if (srpParams) PORT_Free(srpParams);
10470 + return rv;
10471 +loser:
10472 + PORT_SetError(SSL_ERROR_INTERNAL_ERROR_ALERT);
10473 + (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
10474 + return SECFailure;
10475 +unknown_id:
10476 + PORT_SetError(SSL_ERROR_UNKNOWN_PSK_IDENTITY_ALERT);
10477 + (void)SSL3_SendAlert(ss, alert_fatal, unknown_psk_identity);
10478 + return SECFailure;
10479 +no_memory:
10480 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
10481 + return SECFailure;
10482 +}
10483
10484 static SECStatus
10485 ssl3_SendServerKeyExchange(sslSocket *ss)
10486 @@ -7183,7 +7723,9 @@ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
10487 return rv;
10488 }
10489 #endif /* NSS_ENABLE_ECC */
10490 -
10491 + case kt_srp:
10492 + rv = ssl3_SendSRPServerKeyExchange(ss);
10493 + return rv;
10494 case kt_dh:
10495 case kt_null:
10496 default:
10497 @@ -7536,6 +8078,101 @@ double_bypass:
10498 return SECSuccess;
10499 }
10500
10501 +/*
10502 + * extract SRP value A from ClientKeyExchange
10503 + * calculate pre-master-secret and init cipher specs
10504 + *
10505 + * called by ssl3_HandleClientKeyExchange
10506 + */
10507 +SECStatus
10508 +ssl3_HandleSRPClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
10509 + PRUint32 length) {
10510 +
10511 + SECItem ppub; /* peers public key ('A') */
10512 + sslServerCerts sc;
10513 + SECStatus rv = SECFailure;
10514 + SECKEYPublicKey *pubKey = NULL;
10515 +
10516 +
10517 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
10518 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
10519 +
10520 + rv = ssl3_ConsumeHandshakeVariable(ss, &ppub, 2, &b, &length);
10521 + if (rv != SECSuccess) {
10522 + PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
10523 + return SECFailure;
10524 + }
10525 +
10526 + sc = ss->serverCerts[kt_srp];
10527 + pubKey = sc.serverKeyPair->pubKey;
10528 +
10529 + SECITEM_CopyItem(pubKey->arena, &pubKey->u.srp.ppub, &ppub);
10530 +
10531 + if (ss->opt.bypassPKCS11) {
10532 + SRPPrivateKey *prvKey = NULL;
10533 + SECItem pms = { 0, NULL, 0 };
10534 + SRPDeriveParams param;
10535 +
10536 + prvKey = (SRPPrivateKey *)sc.serverKeyPair->privKey;
10537 +
10538 + param.N.data = pubKey->u.srp.N.data;
10539 + param.N.len = pubKey->u.srp.N.len;
10540 + param.g.data = pubKey->u.srp.g.data;
10541 + param.g.len = pubKey->u.srp.g.len;
10542 + param.ppub.data = pubKey->u.srp.ppub.data;
10543 + param.ppub.len = pubKey->u.srp.ppub.len;
10544 +
10545 + if (SECSuccess != SRP_ServerDerive(prvKey, &param, &pms))
10546 + goto derive_fail;
10547 +
10548 + ssl_GetSpecWriteLock(ss);
10549 + /* create MS out of MS, bypassing PKCS11 */
10550 + rv = ssl3_MasterKeyDeriveBypass(ss->ssl3.pwSpec,
10551 + (unsigned char *)&ss->ssl3.hs.client_random,
10552 + (unsigned char *)&ss->ssl3.hs.server_random,
10553 + &pms, PR_TRUE, PR_FALSE);
10554 + if (rv != SECSuccess) {
10555 + ss->ssl3.pwSpec->msItem.data = ss->ssl3.pwSpec->raw_master_secret;
10556 + ss->ssl3.pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
10557 + PK11_GenerateRandom(ss->ssl3.pwSpec->msItem.data, ss->ssl3.pwSpec-> msItem.len);
10558 + }
10559 +
10560 + rv = ssl3_InitPendingCipherSpec(ss, NULL);
10561 +
10562 + SECITEM_ZfreeItem(&pms, PR_FALSE);
10563 + PORT_FreeArena(prvKey->arena, PR_TRUE); /* XXX FreeArena does not zeroi ze! */
10564 + sc.serverKeyPair->privKey = NULL;
10565 +
10566 + } else {
10567 + SECKEYPrivateKey *prvKey = NULL;
10568 + PK11SymKey *pms = NULL; /* pre-master secret */
10569 +
10570 + prvKey = sc.serverKeyPair->privKey;
10571 +
10572 + /* Calculate PMS based on clntKey and public params */
10573 + pms = PK11_PubDerive(prvKey, pubKey, PR_TRUE, NULL, NULL,
10574 + CKM_NSS_SRP_DERIVE, CKM_TLS_MASTER_KEY_DERIVE, CKF_D ERIVE, 0, NULL);
10575 +
10576 + if (!pms) {
10577 + goto derive_fail;
10578 + }
10579 +
10580 + ssl_GetSpecWriteLock(ss);
10581 + /* derive master secret from pms */
10582 + rv = ssl3_InitPendingCipherSpec(ss, pms);
10583 + ssl_ReleaseSpecWriteLock(ss);
10584 +
10585 + PK11_FreeSymKey(pms);
10586 + /*SECKEY_DestroyPrivateKey(prvKey);*/
10587 + }
10588 +
10589 + return rv;
10590 +derive_fail:
10591 + if (PORT_GetError() == SEC_ERROR_SRP_ILLEGAL_PARAMETER)
10592 + SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
10593 + return rv;
10594 +}
10595 +
10596
10597 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
10598 * ssl3 ClientKeyExchange message from the remote client
10599 @@ -7608,7 +8245,8 @@ skip:
10600 serverKey = serverKeyPair->privKey;
10601 }
10602
10603 - if (serverKey == NULL) {
10604 + /* XXX hack, figure out this serverKey thing..*/
10605 + if (serverKey == NULL && kea_def->exchKeyType != kt_srp) {
10606 SEND_ALERT
10607 PORT_SetError(SSL_ERROR_NO_SERVER_KEY_FOR_ALG);
10608 return SECFailure;
10609 @@ -7649,7 +8287,12 @@ skip:
10610 }
10611 break;
10612 #endif /* NSS_ENABLE_ECC */
10613 -
10614 + case kt_srp:
10615 + rv = ssl3_HandleSRPClientKeyExchange(ss, b, length);
10616 + if (rv != SECSuccess) {
10617 + return SECFailure; /* error code set */
10618 + }
10619 + break;
10620 default:
10621 (void) ssl3_HandshakeFailure(ss);
10622 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
10623 @@ -7823,8 +8466,12 @@ ssl3_SendCertificate(sslSocket *ss)
10624 * using EC certificates.
10625 */
10626 if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) ||
10627 - (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) {
10628 + (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) ||
10629 + (ss->ssl3.hs.kea_def->kea == kea_srp_rsa)) {
10630 certIndex = kt_rsa;
10631 + } else if
10632 + (ss->ssl3.hs.kea_def->kea == kea_srp_dss) {
10633 + certIndex = kt_null;
10634 } else {
10635 certIndex = ss->ssl3.hs.kea_def->exchKeyType;
10636 }
10637 @@ -8244,7 +8891,9 @@ cert_block:
10638 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
10639 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
10640 #endif /* NSS_ENABLE_ECC */
10641 - ss->ssl3.hs.kea_def->exchKeyType == kt_dh) {
10642 + ss->ssl3.hs.kea_def->exchKeyType == kt_dh ||
10643 + ss->ssl3.hs.kea_def->kea == kea_srp_dss ||
10644 + ss->ssl3.hs.kea_def->kea == kea_srp_rsa) {
10645 ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */
10646 }
10647 }
10648 diff --git a/net/third_party/nss/ssl/ssl3ecc.c b/net/third_party/nss/ssl/ssl3ecc .c
10649 index 778c7ab..b899038 100644
10650 --- a/net/third_party/nss/ssl/ssl3ecc.c
10651 +++ b/net/third_party/nss/ssl/ssl3ecc.c
10652 @@ -1191,3 +1191,60 @@ loser:
10653 }
10654
10655 #endif /* NSS_ENABLE_ECC */
10656 +
10657 +/* send user mapping indication using info from ss->sec.userlogin
10658 + * called from ssl3_CallHelloExtensionSenders */
10659 +PRInt32
10660 +ssl3_SendSRPHelloExtension(sslSocket * ss, PRBool append,
10661 + PRUint32 maxBytes)
10662 +{
10663 + SECItem * user = ss->sec.userName;
10664 +
10665 + if (user == NULL)
10666 + return 0; /* no credentials, no extension */
10667 +
10668 + if (append && maxBytes >= user->len + 5) {
10669 + SECStatus rv;
10670 + /* extension_type 6 */
10671 + rv = ssl3_AppendHandshakeNumber(ss, 12, 2);
10672 + if (rv != SECSuccess) return 0;
10673 + /* length of extension */
10674 + rv = ssl3_AppendHandshakeNumber(ss, user->len + 1, 2);
10675 + if (rv != SECSuccess) return 0;
10676 + /* length of data */
10677 + rv = ssl3_AppendHandshakeNumber(ss, user->len, 1);
10678 + if (rv != SECSuccess) return 0;
10679 + /* extension_data = srp user name */
10680 + rv = ssl3_AppendHandshake(ss, user->data, user->len);
10681 + if (rv != SECSuccess) return 0;
10682 + }
10683 + return user->len+5;
10684 +}
10685 +
10686 +SECStatus
10687 +ssl3_HandleSRPHelloExtension(sslSocket *ss, PRUint16 ext, SECItem *data)
10688 +{
10689 + SECStatus rv;
10690 + SECItem username;
10691 +
10692 + rv = ssl3_ConsumeHandshakeVariable(ss, &username, 1, &data->data, &data- >len);
10693 + if (rv != SECSuccess)
10694 + return rv;
10695 +
10696 + /* enforce SRP username length constrain */
10697 + if (data->len > MAX_SRP_USERNAME_LENGTH)
10698 + data->len = MAX_SRP_USERNAME_LENGTH;
10699 +
10700 + ss->sec.userName = PORT_ZAlloc(sizeof(SECItem));
10701 + if (!ss->sec.userName)
10702 + goto no_memory;
10703 +
10704 + rv = SECITEM_CopyItem(NULL, ss->sec.userName, &username);
10705 + if (rv != SECSuccess)
10706 + goto no_memory;
10707 +
10708 + return rv;
10709 +no_memory:
10710 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
10711 + return SECFailure;
10712 +}
10713 diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext .c
10714 index b93671e..c2a27b4 100644
10715 --- a/net/third_party/nss/ssl/ssl3ext.c
10716 +++ b/net/third_party/nss/ssl/ssl3ext.c
10717 @@ -78,6 +78,11 @@ static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
10718 PRBool append, PRUint32 maxBytes);
10719 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
10720 PRUint16 ex_type, SECItem *data);
10721 +static SECStatus ssl3_HandleSRPHelloXtn(sslSocket *ss, PRUint16 ext,
10722 + SECItem *data);
10723 +PRInt32 ssl3_SendSRPHelloXtn(sslSocket * ss, PRBool append,
10724 + PRUint32 maxBytes);
10725 +
10726
10727 /*
10728 * Write bytes. Using this function means the SECItem structure
10729 @@ -254,6 +259,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL S[] = {
10730
10731 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
10732 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
10733 + { ssl_srp_hello_xtn, &ssl3_HandleSRPHelloXtn },
10734 { -1, NULL }
10735 };
10736
10737 @@ -272,6 +278,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN SIONS] = {
10738 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
10739 #endif
10740 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
10741 + { ssl_srp_hello_xtn, &ssl3_SendSRPHelloXtn },
10742 { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn },
10743 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
10744 { ssl_snap_start_xtn, &ssl3_SendSnapStartXtn }
10745 @@ -1720,3 +1727,59 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 e x_type, SECItem *data)
10746 return rv;
10747 }
10748
10749 +/* send user mapping indication using info from ss->sec.userlogin
10750 + * called from ssl3_CallHelloExtensionSenders */
10751 +PRInt32
10752 +ssl3_SendSRPHelloXtn(sslSocket * ss, PRBool append,
10753 + PRUint32 maxBytes)
10754 +{
10755 + SECItem * user = ss->sec.userName;
10756 +
10757 + if (user == NULL)
10758 + return 0; /* no credentials, no extension */
10759 +
10760 + if (append && maxBytes >= user->len + 5) {
10761 + SECStatus rv;
10762 + /* extension_type 6 */
10763 + rv = ssl3_AppendHandshakeNumber(ss, 12, 2);
10764 + if (rv != SECSuccess) return 0;
10765 + /* length of extension */
10766 + rv = ssl3_AppendHandshakeNumber(ss, user->len + 1, 2);
10767 + if (rv != SECSuccess) return 0;
10768 + /* length of data */
10769 + rv = ssl3_AppendHandshakeNumber(ss, user->len, 1);
10770 + if (rv != SECSuccess) return 0;
10771 + /* extension_data = srp user name */
10772 + rv = ssl3_AppendHandshake(ss, user->data, user->len);
10773 + if (rv != SECSuccess) return 0;
10774 + }
10775 + return user->len+5;
10776 +}
10777 +
10778 +SECStatus
10779 +ssl3_HandleSRPHelloXtn(sslSocket *ss, PRUint16 ext, SECItem *data)
10780 +{
10781 + SECStatus rv;
10782 + SECItem username;
10783 +
10784 + rv = ssl3_ConsumeHandshakeVariable(ss, &username, 1, &data->data, &data- >len);
10785 + if (rv != SECSuccess)
10786 + return rv;
10787 +
10788 + /* enforce SRP username length constrain */
10789 + if (data->len > MAX_SRP_USERNAME_LENGTH)
10790 + data->len = MAX_SRP_USERNAME_LENGTH;
10791 +
10792 + ss->sec.userName = PORT_ZAlloc(sizeof(SECItem));
10793 + if (!ss->sec.userName)
10794 + goto no_memory;
10795 +
10796 + rv = SECITEM_CopyItem(NULL, ss->sec.userName, &username);
10797 + if (rv != SECSuccess)
10798 + goto no_memory;
10799 +
10800 + return rv;
10801 +no_memory:
10802 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
10803 + return SECFailure;
10804 +}
10805 diff --git a/net/third_party/nss/ssl/ssl3prot.h b/net/third_party/nss/ssl/ssl3pr ot.h
10806 index aeaacdd..a043577 100644
10807 --- a/net/third_party/nss/ssl/ssl3prot.h
10808 +++ b/net/third_party/nss/ssl/ssl3prot.h
10809 @@ -63,6 +63,8 @@ typedef uint16 ssl3CipherSuite;
10810
10811 #define MAX_FRAGMENT_LENGTH 16384
10812
10813 +#define MAX_SRP_USERNAME_LENGTH 255
10814 +
10815 typedef enum {
10816 content_change_cipher_spec = 20,
10817 content_alert = 21,
10818 @@ -137,7 +139,9 @@ typedef enum {
10819 certificate_unobtainable = 111,
10820 unrecognized_name = 112,
10821 bad_certificate_status_response = 113,
10822 - bad_certificate_hash_value = 114
10823 + bad_certificate_hash_value = 114,
10824 +
10825 + unknown_psk_identity = 115
10826
10827 } SSL3AlertDescription;
10828
10829 @@ -215,6 +219,9 @@ typedef enum {
10830 kea_dh_anon,
10831 kea_dh_anon_export,
10832 kea_rsa_fips,
10833 + kea_srp,
10834 + kea_srp_rsa,
10835 + kea_srp_dss,
10836 kea_ecdh_ecdsa,
10837 kea_ecdhe_ecdsa,
10838 kea_ecdh_rsa,
10839 diff --git a/net/third_party/nss/ssl/sslauth.c b/net/third_party/nss/ssl/sslauth .c
10840 index 3f4924d..12c9a12 100644
10841 --- a/net/third_party/nss/ssl/sslauth.c
10842 +++ b/net/third_party/nss/ssl/sslauth.c
10843 @@ -291,6 +291,80 @@ SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
10844 return SECSuccess;
10845 }
10846
10847 +/* register callback function to provide the user password */
10848 +SECStatus
10849 +SSL_UserPasswdHook(PRFileDesc *s, SSLUserPasswdCB func, void *arg)
10850 +{
10851 + sslSocket *ss;
10852 +
10853 + ss = ssl_FindSocket(s);
10854 + if (!ss) {
10855 + SSL_DBG(("%d: SSL[%d]: bad socket in UserPasswdHook",
10856 + SSL_GETPID(), s));
10857 + return SECFailure;
10858 + }
10859 +
10860 + ss->getUserPasswd = func;
10861 + ss->getUserPasswdArg = arg;
10862 + return SECSuccess;
10863 +}
10864 +
10865 +/* used by client to provide user credentials non-interactively */
10866 +SECStatus
10867 +SSL_SetUserLogin(PRFileDesc *s, char *user, char *passwd)
10868 +{
10869 + sslSocket *ss = NULL;
10870 + int len;
10871 +
10872 + ss = ssl_FindSocket(s);
10873 + if (!ss) {
10874 + SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
10875 + SSL_GETPID(), s));
10876 + return SECFailure;
10877 + }
10878 +
10879 + if (user) {
10880 + len = PORT_Strlen(user);
10881 + if (len > MAX_SRP_USERNAME_LENGTH)
10882 + len = MAX_SRP_USERNAME_LENGTH;
10883 + ss->sec.userName = SECITEM_AllocItem(NULL, NULL, len);
10884 + if (!ss->sec.userName) {
10885 + PORT_SetError(SEC_ERROR_NO_MEMORY);
10886 + return SECFailure;
10887 + }
10888 + PORT_Memcpy(ss->sec.userName->data, user, ss->sec.userName->len);
10889 + }
10890 +
10891 + if (passwd) {
10892 + len = PORT_Strlen(passwd);
10893 + ss->sec.userPasswd = SECITEM_AllocItem(NULL, NULL, len);
10894 + if (!ss->sec.userPasswd) {
10895 + PORT_SetError(SEC_ERROR_NO_MEMORY);
10896 + return SECFailure;
10897 + }
10898 + PORT_Memcpy(ss->sec.userPasswd->data, passwd, ss->sec.userPasswd->len);
10899 + }
10900 +
10901 + return SECSuccess;
10902 +}
10903 +
10904 +/* register callback function to provide SRP user authentication params */
10905 +SECStatus
10906 +SSL_GetSRPParamsHook(PRFileDesc *s, SSLGetSRPParamsCB func, void *arg)
10907 +{
10908 + sslSocket *ss;
10909 +
10910 + ss = ssl_FindSocket(s);
10911 + if (!ss) {
10912 + SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
10913 + SSL_GETPID(), s));
10914 + return SECFailure;
10915 + }
10916 +
10917 + ss->getSRPParams = func;
10918 + ss->getSRPParamsArg = arg;
10919 + return SECSuccess;
10920 +}
10921
10922 /* This is the "default" authCert callback function. It is called when a
10923 * certificate message is received from the peer and the local application
10924 diff --git a/net/third_party/nss/ssl/sslenum.c b/net/third_party/nss/ssl/sslenum .c
10925 index b8aa8cc..196ed30 100644
10926 --- a/net/third_party/nss/ssl/sslenum.c
10927 +++ b/net/third_party/nss/ssl/sslenum.c
10928 @@ -74,6 +74,9 @@ const PRUint16 SSL_ImplementedCiphers[] = {
10929 #endif /* NSS_ENABLE_ECC */
10930 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
10931 TLS_RSA_WITH_AES_256_CBC_SHA,
10932 + TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
10933 + TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
10934 + TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
10935
10936 /* 128-bit */
10937 #ifdef NSS_ENABLE_ECC
10938 @@ -98,12 +101,16 @@ const PRUint16 SSL_ImplementedCiphers[] = {
10939 SSL_RSA_WITH_RC4_128_MD5,
10940 SSL_RSA_WITH_RC4_128_SHA,
10941 TLS_RSA_WITH_AES_128_CBC_SHA,
10942 + TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
10943 + TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
10944 + TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
10945
10946 /* 112-bit 3DES */
10947 #ifdef NSS_ENABLE_ECC
10948 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
10949 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
10950 #endif /* NSS_ENABLE_ECC */
10951 + TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
10952 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
10953 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
10954 #ifdef NSS_ENABLE_ECC
10955 @@ -112,6 +119,8 @@ const PRUint16 SSL_ImplementedCiphers[] = {
10956 #endif /* NSS_ENABLE_ECC */
10957 SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
10958 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
10959 + TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
10960 + TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
10961
10962 /* 56-bit DES "domestic" cipher suites */
10963 SSL_DHE_RSA_WITH_DES_CBC_SHA,
10964 diff --git a/net/third_party/nss/ssl/sslerr.h b/net/third_party/nss/ssl/sslerr.h
10965 index eb56ea9..a0c4b9d 100644
10966 --- a/net/third_party/nss/ssl/sslerr.h
10967 +++ b/net/third_party/nss/ssl/sslerr.h
10968 @@ -205,6 +205,8 @@ SSL_ERROR_WEAK_SERVER_KEY = (SSL_ERROR_BASE + 115),
10969
10970 SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 116),
10971
10972 +SSL_ERROR_UNKNOWN_PSK_IDENTITY_ALERT = (SSL_ERROR_BASE + 116),
10973 +
10974 SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
10975 } SSLErrorCodes;
10976 #endif /* NO_SECURITY_ERROR_ENUM */
10977 diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl .h
10978 index 1ea82da..9eed38b 100644
10979 --- a/net/third_party/nss/ssl/sslimpl.h
10980 +++ b/net/third_party/nss/ssl/sslimpl.h
10981 @@ -317,9 +317,10 @@ typedef struct {
10982 } ssl3CipherSuiteCfg;
10983
10984 #ifdef NSS_ENABLE_ECC
10985 -#define ssl_V3_SUITES_IMPLEMENTED 50
10986 +#define ssl_V3_SUITES_IMPLEMENTED 60
10987 #else
10988 -#define ssl_V3_SUITES_IMPLEMENTED 30
10989 +#define ssl_V3_SUITES_IMPLEMENTED 60
10990 +/* TODO(sqs): where do these #s come from? I think sslsock.c, where we added 9 more SRP suites. before tls-srp patch, these were 59 and 39. */
10991 #endif /* NSS_ENABLE_ECC */
10992
10993 typedef struct sslOptionsStr {
10994 @@ -1050,6 +1051,8 @@ struct sslSecurityInfoStr {
10995 CERTCertificate *localCert; /* ssl 2 & 3 */
10996 CERTCertificate *peerCert; /* ssl 2 & 3 */
10997 SECKEYPublicKey *peerKey; /* ssl3 only */
10998 + SECItem *userName; /* SSL username credential */
10999 + SECItem *userPasswd; /* SSL userpasswd credential */
11000
11001 SSLSignType authAlgorithm;
11002 PRUint32 authKeyBits;
11003 @@ -1159,6 +1162,10 @@ const unsigned char * preferredCipher;
11004 SSLHandshakeCallback handshakeCallback;
11005 void *handshakeCallbackData;
11006 void *pkcs11PinArg;
11007 + SSLUserPasswdCB getUserPasswd;
11008 + void *getUserPasswdArg;
11009 + SSLGetSRPParamsCB getSRPParams;
11010 + void *getSRPParamsArg;
11011
11012 PRIntervalTime rTimeout; /* timeout for NSPR I/O */
11013 PRIntervalTime wTimeout; /* timeout for NSPR I/O */
11014 diff --git a/net/third_party/nss/ssl/sslproto.h b/net/third_party/nss/ssl/sslpro to.h
11015 index b534d0b..cbf6250 100644
11016 --- a/net/third_party/nss/ssl/sslproto.h
11017 +++ b/net/third_party/nss/ssl/sslproto.h
11018 @@ -220,6 +220,16 @@
11019 #define TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018
11020 #define TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019
11021
11022 +#define TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0xC01A
11023 +#define TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0xC01B
11024 +#define TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0xC01C
11025 +#define TLS_SRP_SHA_WITH_AES_128_CBC_SHA 0xC01D
11026 +#define TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0xC01E
11027 +#define TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0xC01F
11028 +#define TLS_SRP_SHA_WITH_AES_256_CBC_SHA 0xC020
11029 +#define TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0xC021
11030 +#define TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0xC022
11031 +
11032 /* Netscape "experimental" cipher suites. */
11033 #define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
11034 #define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1
11035 diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock .c
11036 index b14a935..18ee612 100644
11037 --- a/net/third_party/nss/ssl/sslsock.c
11038 +++ b/net/third_party/nss/ssl/sslsock.c
11039 @@ -102,6 +102,15 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */
11040 { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11041 { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALL OWED },
11042 { TLS_RSA_WITH_SEED_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11043 + { TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11044 + { TLS_SRP_SHA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11045 + { TLS_SRP_SHA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11046 + { TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11047 + { TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11048 + { TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11049 + { TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11050 + { TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11051 + { TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
11052 { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
11053 { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
11054 #ifdef NSS_ENABLE_ECC
11055 diff --git a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h
11056 index 3fa3f9b..172364c 100644
11057 --- a/net/third_party/nss/ssl/sslt.h
11058 +++ b/net/third_party/nss/ssl/sslt.h
11059 @@ -74,6 +74,7 @@ typedef enum {
11060 ssl_kea_dh = 2,
11061 ssl_kea_fortezza = 3, /* deprecated, now unused */
11062 ssl_kea_ecdh = 4,
11063 + ssl_kea_srp = 5,
11064 ssl_kea_size /* number of ssl_kea_ algorithms */
11065 } SSLKEAType;
11066
11067 @@ -88,6 +89,7 @@ typedef enum {
11068 #define kt_fortezza ssl_kea_fortezza /* deprecated, now unused */
11069 #define kt_ecdh ssl_kea_ecdh
11070 #define kt_kea_size ssl_kea_size
11071 +#define kt_srp ssl_kea_srp
11072
11073 typedef enum {
11074 ssl_sign_null = 0,
11075 @@ -203,13 +205,14 @@ typedef enum {
11076 ssl_elliptic_curves_xtn = 10,
11077 ssl_ec_point_formats_xtn = 11,
11078 #endif
11079 + ssl_srp_hello_xtn = 12,
11080 ssl_session_ticket_xtn = 35,
11081 ssl_next_proto_neg_xtn = 13172,
11082 ssl_snap_start_xtn = 13174,
11083 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
11084 } SSLExtensionType;
11085
11086 -#define SSL_MAX_EXTENSIONS 8
11087 +#define SSL_MAX_EXTENSIONS 9
11088
11089 typedef enum {
11090 /* No Snap Start handshake was attempted. */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698