iPXE
x25519.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 /** @file
28  *
29  * X25519 key exchange
30  *
31  * This implementation is inspired by and partially based upon the
32  * paper "Implementing Curve25519/X25519: A Tutorial on Elliptic Curve
33  * Cryptography" by Martin Kleppmann, available for download from
34  * https://www.cl.cam.ac.uk/teaching/2122/Crypto/curve25519.pdf
35  *
36  * The underlying modular addition, subtraction, and multiplication
37  * operations are completely redesigned for substantially improved
38  * efficiency compared to the TweetNaCl implementation studied in that
39  * paper.
40  *
41  * TweetNaCl iPXE
42  * --------- ----
43  *
44  * Storage size of each big integer 128 40
45  * (in bytes)
46  *
47  * Stack usage for key exchange 1144 360
48  * (in bytes, large objects only)
49  *
50  * Cost of big integer addition 16 5
51  * (in number of 64-bit additions)
52  *
53  * Cost of big integer multiplication 273 31
54  * (in number of 64-bit multiplications)
55  *
56  * The implementation is constant-time (provided that the underlying
57  * big integer operations are also constant-time).
58  */
59 
60 #include <stdint.h>
61 #include <string.h>
62 #include <assert.h>
63 #include <errno.h>
64 #include <ipxe/init.h>
65 #include <ipxe/crypto.h>
66 #include <ipxe/x25519.h>
67 
68 /** X25519 reduction constant
69  *
70  * The X25519 field prime is p=2^255-19. This gives us:
71  *
72  * p = 2^255 - 19
73  * 2^255 = p + 19
74  * 2^255 = 19 (mod p)
75  * k * 2^255 = k * 19 (mod p)
76  *
77  * We can therefore reduce a value modulo p by taking the high-order
78  * bits of the value from bit 255 and above, multiplying by 19, and
79  * adding this to the low-order 255 bits of the value.
80  *
81  * This would be cumbersome to do in practice since it would require
82  * partitioning the value at a 255-bit boundary (and hence would
83  * require some shifting and masking operations). However, we can
84  * note that:
85  *
86  * k * 2^255 = k * 19 (mod p)
87  * k * 2 * 2^255 = k * 2 * 19 (mod p)
88  * k * 2^256 = k * 38 (mod p)
89  *
90  * We can therefore simplify the reduction to taking the high order
91  * bits of the value from bit 256 and above, multiplying by 38, and
92  * adding this to the low-order 256 bits of the value.
93  *
94  * Since 256 will inevitably be a multiple of the big integer element
95  * size (typically 32 or 64 bits), this avoids the need to perform any
96  * shifting or masking operations.
97  */
98 #define X25519_REDUCE_256 38
99 
100 /** X25519 multiplication step 1 result
101  *
102  * Step 1 of X25519 multiplication is to compute the product of two
103  * X25519 unsigned 258-bit integers.
104  *
105  * Both multiplication inputs are limited to 258 bits, and so the
106  * product will have at most 516 bits.
107  */
109  /** Raw product
110  *
111  * Big integer multiplication produces a result with a number
112  * of elements equal to the sum of the number of elements in
113  * each input.
114  */
116  /** Partition into low-order and high-order bits
117  *
118  * Reduction modulo p requires separating the low-order 256
119  * bits from the remaining high-order bits.
120  *
121  * Since the value will never exceed 516 bits (see above),
122  * there will be at most 260 high-order bits.
123  */
124  struct {
125  /** Low-order 256 bits */
126  bigint_t ( bigint_required_size ( ( 256 /* bits */ + 7 ) / 8 ) )
127  low_256bit;
128  /** High-order 260 bits */
129  bigint_t ( bigint_required_size ( ( 260 /* bits */ + 7 ) / 8 ) )
130  high_260bit;
131  } __attribute__ (( packed )) parts;
132 };
133 
134 /** X25519 multiplication step 2 result
135  *
136  * Step 2 of X25519 multiplication is to multiply the high-order 260
137  * bits from step 1 with the 6-bit reduction constant 38, and to add
138  * this to the low-order 256 bits from step 1.
139  *
140  * The multiplication inputs are limited to 260 and 6 bits
141  * respectively, and so the product will have at most 266 bits. After
142  * adding the low-order 256 bits from step 1, the result will have at
143  * most 267 bits.
144  */
146  /** Raw product
147  *
148  * Big integer multiplication produces a result with a number
149  * of elements equal to the sum of the number of elements in
150  * each input.
151  */
152  bigint_t ( bigint_required_size ( ( 260 /* bits */ + 7 ) / 8 ) +
153  bigint_required_size ( ( 6 /* bits */ + 7 ) / 8 ) ) product;
154  /** Big integer value
155  *
156  * The value will never exceed 267 bits (see above), and so
157  * may be consumed as a normal X25519 big integer.
158  */
159  x25519_t value;
160  /** Partition into low-order and high-order bits
161  *
162  * Reduction modulo p requires separating the low-order 256
163  * bits from the remaining high-order bits.
164  *
165  * Since the value will never exceed 267 bits (see above),
166  * there will be at most 11 high-order bits.
167  */
168  struct {
169  /** Low-order 256 bits */
170  bigint_t ( bigint_required_size ( ( 256 /* bits */ + 7 ) / 8 ) )
171  low_256bit;
172  /** High-order 11 bits */
173  bigint_t ( bigint_required_size ( ( 11 /* bits */ + 7 ) / 8 ) )
174  high_11bit;
175  } __attribute__ (( packed )) parts;
176 };
177 
178 /** X25519 multiplication step 3 result
179  *
180  * Step 3 of X25519 multiplication is to multiply the high-order 11
181  * bits from step 2 with the 6-bit reduction constant 38, and to add
182  * this to the low-order 256 bits from step 2.
183  *
184  * The multiplication inputs are limited to 11 and 6 bits
185  * respectively, and so the product will have at most 17 bits. After
186  * adding the low-order 256 bits from step 2, the result will have at
187  * most 257 bits.
188  */
190  /** Raw product
191  *
192  * Big integer multiplication produces a result with a number
193  * of elements equal to the sum of the number of elements in
194  * each input.
195  */
196  bigint_t ( bigint_required_size ( ( 11 /* bits */ + 7 ) / 8 ) +
197  bigint_required_size ( ( 6 /* bits */ + 7 ) / 8 ) ) product;
198  /** Big integer value
199  *
200  * The value will never exceed 267 bits (see above), and so
201  * may be consumed as a normal X25519 big integer.
202  */
203  x25519_t value;
204 };
205 
206 /** X25519 multiplication temporary working space
207  *
208  * We overlap the buffers used by each step of the multiplication
209  * calculation to reduce the total stack space required:
210  *
211  * |--------------------------------------------------------|
212  * | <- pad -> | <------------ step 1 result -------------> |
213  * | | <- low 256 bits -> | <-- high 260 bits --> |
214  * | <------- step 2 result ------> | <-- step 3 result --> |
215  * |--------------------------------------------------------|
216  */
218  /** Step 1 result */
219  struct {
220  /** Padding to avoid collision between steps 1 and 2
221  *
222  * The step 2 multiplication consumes the high 260
223  * bits of step 1, and so the step 2 multiplication
224  * result must not overlap this portion of the step 1
225  * result.
226  */
227  uint8_t pad[ sizeof ( union x25519_multiply_step2 ) -
229  parts.high_260bit ) ];
230  /** Step 1 result */
232  } __attribute__ (( packed ));
233  /** Steps 2 and 3 results */
234  struct {
235  /** Step 2 result */
237  /** Step 3 result */
239  } __attribute__ (( packed ));
240 };
241 
242 /** An X25519 elliptic curve point in projective coordinates
243  *
244  * A point (x,y) on the Montgomery curve used in X25519 is represented
245  * using projective coordinates (X/Z,Y/Z) so that intermediate
246  * calculations may be performed on both numerator and denominator
247  * separately, with the division step performed only once at the end
248  * of the calculation.
249  *
250  * The group operation calculation is performed using a Montgomery
251  * ladder as:
252  *
253  * X[2i] = ( X[i]^2 - Z[i]^2 )^2
254  * X[2i+1] = ( X[i] * X[i+1] - Z[i] * Z[i+1] )^2
255  * Z[2i] = 4 * X[i] * Z[i] * ( X[i]^2 + A * X[i] * Z[i] + Z[i]^2 )
256  * Z[2i+1] = X[0] * ( X[i] * Z[i+1] - X[i+1] * Z[i] ) ^ 2
257  *
258  * It is therefore not necessary to store (or use) the value of Y.
259  */
261  /** X coordinate */
263  /** Z coordinate */
265 };
266 
267 /** An X25519 Montgomery ladder step */
268 struct x25519_step {
269  /** X[n]/Z[n] */
271  /** X[n+1]/Z[n+1] */
273 };
274 
275 /** Constant p=2^255-19 (the finite field prime) */
276 static const uint8_t x25519_p_raw[] = {
277  0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
278  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
279  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
280  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed
281 };
282 
283 /** Constant p=2^255-19 (the finite field prime) */
284 static x25519_t x25519_p;
285 
286 /** Constant 2p=2^256-38 */
287 static x25519_t x25519_2p;
288 
289 /** Constant 4p=2^257-76 */
290 static x25519_t x25519_4p;
291 
292 /** Reduction constant (used during multiplication) */
294 
295 /** Reduction constant (used during multiplication) */
297  x25519_reduce_256;
298 
299 /** Constant 121665 (used in the Montgomery ladder) */
300 static const uint8_t x25519_121665_raw[] = { 0x01, 0xdb, 0x41 };
301 
302 /** Constant 121665 (used in the Montgomery ladder) */
304 
305 /** Constant g=9 (the group generator) */
307  .raw = { 9, }
308 };
309 
310 /**
311  * Initialise constants
312  *
313  */
314 static void x25519_init_constants ( void ) {
315 
316  /* Construct constant p */
317  bigint_init ( &x25519_p, x25519_p_raw, sizeof ( x25519_p_raw ) );
318 
319  /* Construct constant 2p */
322 
323  /* Construct constant 4p */
326 
327  /* Construct reduction constant */
328  bigint_init ( &x25519_reduce_256, x25519_reduce_256_raw,
329  sizeof ( x25519_reduce_256_raw ) );
330 
331  /* Construct constant 121665 */
332  bigint_init ( &x25519_121665.value, x25519_121665_raw,
333  sizeof ( x25519_121665_raw ) );
334 }
335 
336 /** Initialisation function */
337 struct init_fn x25519_init_fn __init_fn ( INIT_NORMAL ) = {
338  .name = "x25519",
339  .initialise = x25519_init_constants,
340 };
341 
342 /**
343  * Add big integers modulo field prime
344  *
345  * @v augend Big integer to add
346  * @v addend Big integer to add
347  * @v result Big integer to hold result (may overlap augend)
348  */
349 static inline __attribute__ (( always_inline )) void
350 x25519_add ( const union x25519_quad257 *augend,
351  const union x25519_quad257 *addend,
352  union x25519_oct258 *result ) {
353  int copy;
354 
355  /* Copy augend if necessary */
356  copy = ( result != &augend->oct258 );
357  build_assert ( __builtin_constant_p ( copy ) );
358  if ( copy ) {
359  build_assert ( result != &addend->oct258 );
360  bigint_copy ( &augend->oct258.value, &result->value );
361  }
362 
363  /* Perform addition
364  *
365  * Both inputs are in the range [0,4p-1] and the resulting
366  * sum is therefore in the range [0,8p-2].
367  *
368  * This range lies within the range [0,8p-1] and the result is
369  * therefore a valid X25519 unsigned 258-bit integer, as
370  * required.
371  */
372  bigint_add ( &addend->value, &result->value );
373 }
374 
375 /**
376  * Subtract big integers modulo field prime
377  *
378  * @v minuend Big integer from which to subtract
379  * @v subtrahend Big integer to subtract
380  * @v result Big integer to hold result (may overlap minuend)
381  */
382 static inline __attribute__ (( always_inline )) void
383 x25519_subtract ( const union x25519_quad257 *minuend,
384  const union x25519_quad257 *subtrahend,
385  union x25519_oct258 *result ) {
386  int copy;
387 
388  /* Copy minuend if necessary */
389  copy = ( result != &minuend->oct258 );
390  build_assert ( __builtin_constant_p ( copy ) );
391  if ( copy ) {
392  build_assert ( result != &subtrahend->oct258 );
393  bigint_copy ( &minuend->oct258.value, &result->value );
394  }
395 
396  /* Perform subtraction
397  *
398  * Both inputs are in the range [0,4p-1] and the resulting
399  * difference is therefore in the range [1-4p,4p-1].
400  *
401  * This range lies partially outside the range [0,8p-1] and
402  * the result is therefore not yet a valid X25519 unsigned
403  * 258-bit integer.
404  */
405  bigint_subtract ( &subtrahend->value, &result->value );
406 
407  /* Add constant multiple of field prime p
408  *
409  * Add the constant 4p to the result. This brings the result
410  * within the range [1,8p-1] (without changing the value
411  * modulo p).
412  *
413  * This range lies within the range [0,8p-1] and the result is
414  * therefore now a valid X25519 unsigned 258-bit integer, as
415  * required.
416  */
417  bigint_add ( &x25519_4p, &result->value );
418 }
419 
420 /**
421  * Multiply big integers modulo field prime
422  *
423  * @v multiplicand Big integer to be multiplied
424  * @v multiplier Big integer to be multiplied
425  * @v result Big integer to hold result (may overlap either input)
426  */
427 void x25519_multiply ( const union x25519_oct258 *multiplicand,
428  const union x25519_oct258 *multiplier,
429  union x25519_quad257 *result ) {
431  union x25519_multiply_step1 *step1 = &tmp.step1;
432  union x25519_multiply_step2 *step2 = &tmp.step2;
433  union x25519_multiply_step3 *step3 = &tmp.step3;
434 
435  /* Step 1: perform raw multiplication
436  *
437  * step1 = multiplicand * multiplier
438  *
439  * Both inputs are 258-bit numbers and the step 1 result is
440  * therefore 258+258=516 bits.
441  */
442  static_assert ( sizeof ( step1->product ) >= sizeof ( step1->parts ) );
443  bigint_multiply ( &multiplicand->value, &multiplier->value,
444  &step1->product );
445 
446  /* Step 2: reduce high-order 516-256=260 bits of step 1 result
447  *
448  * Use the identity 2^256=38 (mod p) to reduce the high-order
449  * bits of the step 1 result. We split the 516-bit result
450  * from step 1 into its low-order 256 bits and high-order 260
451  * bits:
452  *
453  * step1 = step1(low 256 bits) + step1(high 260 bits) * 2^256
454  *
455  * and then perform the calculation:
456  *
457  * step2 = step1 (mod p)
458  * = step1(low 256 bits) + step1(high 260 bits) * 2^256 (mod p)
459  * = step1(low 256 bits) + step1(high 260 bits) * 38 (mod p)
460  *
461  * There are 6 bits in the constant value 38. The step 2
462  * multiplication product will therefore have 260+6=266 bits,
463  * and the step 2 result (after the addition) will therefore
464  * have 267 bits.
465  */
466  static_assert ( sizeof ( step2->product ) >= sizeof ( step2->value ) );
467  static_assert ( sizeof ( step2->product ) >= sizeof ( step2->parts ) );
468  bigint_grow ( &step1->parts.low_256bit, &result->value );
469  bigint_multiply ( &step1->parts.high_260bit, &x25519_reduce_256,
470  &step2->product );
471  bigint_add ( &result->value, &step2->value );
472 
473  /* Step 3: reduce high-order 267-256=11 bits of step 2 result
474  *
475  * Use the identity 2^256=38 (mod p) again to reduce the
476  * high-order bits of the step 2 result. As before, we split
477  * the 267-bit result from step 2 into its low-order 256 bits
478  * and high-order 11 bits:
479  *
480  * step2 = step2(low 256 bits) + step2(high 11 bits) * 2^256
481  *
482  * and then perform the calculation:
483  *
484  * step3 = step2 (mod p)
485  * = step2(low 256 bits) + step2(high 11 bits) * 2^256 (mod p)
486  * = step2(low 256 bits) + step2(high 11 bits) * 38 (mod p)
487  *
488  * There are 6 bits in the constant value 38. The step 3
489  * multiplication product will therefore have 11+6=19 bits,
490  * and the step 3 result (after the addition) will therefore
491  * have 257 bits.
492  *
493  * A loose upper bound for the step 3 result (after the
494  * addition) is given by:
495  *
496  * step3 < ( 2^256 - 1 ) + ( 2^19 - 1 )
497  * < ( 2^257 - 2^256 - 1 ) + ( 2^19 - 1 )
498  * < ( 2^257 - 76 ) - 2^256 + 2^19 + 74
499  * < 4 * ( 2^255 - 19 ) - 2^256 + 2^19 + 74
500  * < 4p - 2^256 + 2^19 + 74
501  *
502  * and so the step 3 result is strictly less than 4p, and
503  * therefore lies within the range [0,4p-1].
504  */
505  memset ( &step3->value, 0, sizeof ( step3->value ) );
506  bigint_grow ( &step2->parts.low_256bit, &result->value );
507  bigint_multiply ( &step2->parts.high_11bit, &x25519_reduce_256,
508  &step3->product );
509  bigint_add ( &step3->value, &result->value );
510 
511  /* Step 1 calculates the product of the input operands, and
512  * each subsequent step reduces the number of bits in the
513  * result while preserving this value (modulo p). The final
514  * result is therefore equal to the product of the input
515  * operands (modulo p), as required.
516  *
517  * The step 3 result lies within the range [0,4p-1] and the
518  * final result is therefore a valid X25519 unsigned 257-bit
519  * integer, as required.
520  */
521 }
522 
523 /**
524  * Compute multiplicative inverse
525  *
526  * @v invertend Big integer to be inverted
527  * @v result Big integer to hold result (may not overlap input)
528  */
529 void x25519_invert ( const union x25519_oct258 *invertend,
530  union x25519_quad257 *result ) {
531  int i;
532 
533  /* Sanity check */
534  assert ( invertend != &result->oct258 );
535 
536  /* Calculate inverse as x^(-1)=x^(p-2) where p is the field prime
537  *
538  * The field prime is p=2^255-19 and so:
539  *
540  * p - 2 = 2^255 - 21
541  * = (2^255 - 1) - 2^4 - 2^2
542  *
543  * i.e. p-2 is a 254-bit number in which all bits are set
544  * apart from bit 2 and bit 4.
545  *
546  * We use the square-and-multiply method to compute x^(p-2).
547  */
548  bigint_copy ( &invertend->value, &result->value );
549  for ( i = 253 ; i >= 0 ; i-- ) {
550 
551  /* Square running total */
552  x25519_multiply ( &result->oct258, &result->oct258, result );
553 
554  /* For each set bit in the exponent, multiply by invertend */
555  if ( ( i != 2 ) && ( i != 4 ) ) {
556  x25519_multiply ( invertend, &result->oct258, result );
557  }
558  }
559 }
560 
561 /**
562  * Reduce big integer via conditional subtraction
563  *
564  * @v subtrahend Big integer to subtract
565  * @v value Big integer to be subtracted from, if possible
566  */
567 static void x25519_reduce_by ( const x25519_t *subtrahend, x25519_t *value ) {
568  x25519_t tmp;
569  int underflow;
570 
571  /* Conditionally subtract subtrahend
572  *
573  * Subtract the subtrahend, discarding the result (in constant
574  * time) if the subtraction underflows.
575  */
576  bigint_copy ( value, &tmp );
577  underflow = bigint_subtract ( subtrahend, value );
578  bigint_swap ( value, &tmp, underflow );
579 }
580 
581 /**
582  * Reduce big integer to canonical range
583  *
584  * @v value Big integer to be reduced
585  */
587 
588  /* Conditionally subtract 2p
589  *
590  * Subtract twice the field prime, discarding the result (in
591  * constant time) if the subtraction underflows.
592  *
593  * The input value is in the range [0,4p-1]. After this
594  * conditional subtraction, the value is in the range
595  * [0,2p-1].
596  */
597  x25519_reduce_by ( &x25519_2p, &value->value );
598 
599  /* Conditionally subtract p
600  *
601  * Subtract the field prime, discarding the result (in
602  * constant time) if the subtraction underflows.
603  *
604  * The value is already in the range [0,2p-1]. After this
605  * conditional subtraction, the value is in the range [0,p-1]
606  * and is therefore the canonical representation.
607  */
608  x25519_reduce_by ( &x25519_p, &value->value );
609 }
610 
611 /**
612  * Compute next step of the Montgomery ladder
613  *
614  * @v base Base point
615  * @v bit Bit value
616  * @v step Ladder step
617  */
618 static void x25519_step ( const union x25519_quad257 *base, int bit,
619  struct x25519_step *step ) {
620  union x25519_quad257 *a = &step->x_n.X;
621  union x25519_quad257 *b = &step->x_n1.X;
622  union x25519_quad257 *c = &step->x_n.Z;
623  union x25519_quad257 *d = &step->x_n1.Z;
624  union x25519_oct258 e;
625  union x25519_quad257 f;
626  union x25519_oct258 *v1_e;
627  union x25519_oct258 *v2_a;
628  union x25519_oct258 *v3_c;
629  union x25519_oct258 *v4_b;
630  union x25519_quad257 *v5_d;
631  union x25519_quad257 *v6_f;
632  union x25519_quad257 *v7_a;
633  union x25519_quad257 *v8_c;
634  union x25519_oct258 *v9_e;
635  union x25519_oct258 *v10_a;
636  union x25519_quad257 *v11_b;
637  union x25519_oct258 *v12_c;
638  union x25519_quad257 *v13_a;
639  union x25519_oct258 *v14_a;
640  union x25519_quad257 *v15_c;
641  union x25519_quad257 *v16_a;
642  union x25519_quad257 *v17_d;
643  union x25519_quad257 *v18_b;
644 
645  /* See the referenced paper "Implementing Curve25519/X25519: A
646  * Tutorial on Elliptic Curve Cryptography" for the reasoning
647  * behind this calculation.
648  */
649 
650  /* Reuse storage locations for intermediate results where possible */
651  v1_e = &e;
652  v2_a = container_of ( &a->value, union x25519_oct258, value );
653  v3_c = container_of ( &c->value, union x25519_oct258, value );
654  v4_b = container_of ( &b->value, union x25519_oct258, value );
655  v5_d = d;
656  v6_f = &f;
657  v7_a = a;
658  v8_c = c;
659  v9_e = &e;
660  v10_a = container_of ( &a->value, union x25519_oct258, value );
661  v11_b = b;
662  v12_c = container_of ( &c->value, union x25519_oct258, value );
663  v13_a = a;
664  v14_a = container_of ( &a->value, union x25519_oct258, value );
665  v15_c = c;
666  v16_a = a;
667  v17_d = d;
668  v18_b = b;
669 
670  /* Select inputs */
671  bigint_swap ( &a->value, &b->value, bit );
672  bigint_swap ( &c->value, &d->value, bit );
673 
674  /* v1 = a + c */
675  x25519_add ( a, c, v1_e );
676 
677  /* v2 = a - c */
678  x25519_subtract ( a, c, v2_a );
679 
680  /* v3 = b + d */
681  x25519_add ( b, d, v3_c );
682 
683  /* v4 = b - d */
684  x25519_subtract ( b, d, v4_b );
685 
686  /* v5 = v1^2 = (a + c)^2 = a^2 + 2ac + c^2 */
687  x25519_multiply ( v1_e, v1_e, v5_d );
688 
689  /* v6 = v2^2 = (a - c)^2 = a^2 - 2ac + c^2 */
690  x25519_multiply ( v2_a, v2_a, v6_f );
691 
692  /* v7 = v3 * v2 = (b + d) * (a - c) = ab - bc + ad - cd */
693  x25519_multiply ( v3_c, v2_a, v7_a );
694 
695  /* v8 = v4 * v1 = (b - d) * (a + c) = ab + bc - ad - cd */
696  x25519_multiply ( v4_b, v1_e, v8_c );
697 
698  /* v9 = v7 + v8 = 2 * (ab - cd) */
699  x25519_add ( v7_a, v8_c, v9_e );
700 
701  /* v10 = v7 - v8 = 2 * (ad - bc) */
702  x25519_subtract ( v7_a, v8_c, v10_a );
703 
704  /* v11 = v10^2 = 4 * (ad - bc)^2 */
705  x25519_multiply ( v10_a, v10_a, v11_b );
706 
707  /* v12 = v5 - v6 = (a + c)^2 - (a - c)^2 = 4ac */
708  x25519_subtract ( v5_d, v6_f, v12_c );
709 
710  /* v13 = v12 * 121665 = 486660ac = (A-2) * ac */
711  x25519_multiply ( v12_c, &x25519_121665, v13_a );
712 
713  /* v14 = v13 + v5 = (A-2) * ac + a^2 + 2ac + c^2 = a^2 + A * ac + c^2 */
714  x25519_add ( v13_a, v5_d, v14_a );
715 
716  /* v15 = v12 * v14 = 4ac * (a^2 + A * ac + c^2) */
717  x25519_multiply ( v12_c, v14_a, v15_c );
718 
719  /* v16 = v5 * v6 = (a + c)^2 * (a - c)^2 = (a^2 - c^2)^2 */
720  x25519_multiply ( &v5_d->oct258, &v6_f->oct258, v16_a );
721 
722  /* v17 = v11 * base = 4 * base * (ad - bc)^2 */
723  x25519_multiply ( &v11_b->oct258, &base->oct258, v17_d );
724 
725  /* v18 = v9^2 = 4 * (ab - cd)^2 */
726  x25519_multiply ( v9_e, v9_e, v18_b );
727 
728  /* Select outputs */
729  bigint_swap ( &a->value, &b->value, bit );
730  bigint_swap ( &c->value, &d->value, bit );
731 }
732 
733 /**
734  * Multiply X25519 elliptic curve point
735  *
736  * @v base Base point
737  * @v scalar Scalar multiple
738  * @v result Point to hold result (may overlap base point)
739  */
740 static void x25519_ladder ( const union x25519_quad257 *base,
741  struct x25519_value *scalar,
742  union x25519_quad257 *result ) {
743  static const uint8_t zero[] = { 0 };
744  static const uint8_t one[] = { 1 };
745  struct x25519_step step;
746  union x25519_quad257 *tmp;
747  int bit;
748  int i;
749 
750  /* Initialise ladder */
751  bigint_init ( &step.x_n.X.value, one, sizeof ( one ) );
752  bigint_init ( &step.x_n.Z.value, zero, sizeof ( zero ) );
753  bigint_copy ( &base->value, &step.x_n1.X.value );
754  bigint_init ( &step.x_n1.Z.value, one, sizeof ( one ) );
755 
756  /* Use ladder */
757  for ( i = 254 ; i >= 0 ; i-- ) {
758  bit = ( ( scalar->raw[ i / 8 ] >> ( i % 8 ) ) & 1 );
759  x25519_step ( base, bit, &step );
760  }
761 
762  /* Convert back to affine coordinate */
763  tmp = &step.x_n1.X;
764  x25519_invert ( &step.x_n.Z.oct258, tmp );
765  x25519_multiply ( &step.x_n.X.oct258, &tmp->oct258, result );
766  x25519_reduce ( result );
767 }
768 
769 /**
770  * Reverse X25519 value endianness
771  *
772  * @v value Value to reverse
773  */
774 static void x25519_reverse ( struct x25519_value *value ) {
775  uint8_t *low = value->raw;
776  uint8_t *high = &value->raw[ sizeof ( value->raw ) - 1 ];
777  uint8_t tmp;
778 
779  /* Reverse bytes */
780  do {
781  tmp = *low;
782  *low = *high;
783  *high = tmp;
784  } while ( ++low < --high );
785 }
786 
787 /**
788  * Check if X25519 value is zero
789  *
790  * @v value Value to check
791  * @ret is_zero Value is zero
792  */
793 int x25519_is_zero ( const struct x25519_value *value ) {
794  x25519_t point;
795 
796  /* Check if value is zero */
797  bigint_init ( &point, value->raw, sizeof ( value->raw ) );
798  return bigint_is_zero ( &point );
799 }
800 
801 /**
802  * Calculate X25519 key
803  *
804  * @v base Base point
805  * @v scalar Scalar multiple
806  * @v result Point to hold result (may overlap base point)
807  */
808 void x25519_key ( const struct x25519_value *base,
809  const struct x25519_value *scalar,
810  struct x25519_value *result ) {
811  struct x25519_value *tmp = result;
812  union x25519_quad257 point;
813 
814  /* Reverse base point and clear high bit as required by RFC7748 */
815  memcpy ( tmp, base, sizeof ( *tmp ) );
816  x25519_reverse ( tmp );
817  tmp->raw[0] &= 0x7f;
818  bigint_init ( &point.value, tmp->raw, sizeof ( tmp->raw ) );
819 
820  /* Clamp scalar as required by RFC7748 */
821  memcpy ( tmp, scalar, sizeof ( *tmp ) );
822  tmp->raw[0] &= 0xf8;
823  tmp->raw[31] |= 0x40;
824 
825  /* Multiply elliptic curve point */
826  x25519_ladder ( &point, tmp, &point );
827 
828  /* Reverse result */
829  bigint_done ( &point.value, result->raw, sizeof ( result->raw ) );
831 }
832 
833 /**
834  * Check if this is the point at infinity
835  *
836  * @v point Curve point
837  * @ret is_infinity This is the point at infinity
838  */
839 static int x25519_curve_is_infinity ( const void *point ) {
840 
841  /* We use all zeroes for the point at infinity (as per RFC8422) */
842  return x25519_is_zero ( point );
843 }
844 
845 /**
846  * Multiply scalar by curve point
847  *
848  * @v base Base point
849  * @v scalar Scalar multiple
850  * @v result Result point to fill in
851  * @ret rc Return status code
852  */
853 static int x25519_curve_multiply ( const void *base, const void *scalar,
854  void *result ) {
855 
856  x25519_key ( base, scalar, result );
857  return 0;
858 }
859 
860 /**
861  * Add curve points (as a one-off operation)
862  *
863  * @v addend Curve point to add
864  * @v augend Curve point to add
865  * @v result Curve point to hold result
866  * @ret rc Return status code
867  */
868 static int x25519_curve_add ( const void *addend __unused,
869  const void *augend __unused,
870  void *result __unused ) {
871 
872  return -ENOTTY;
873 }
874 
875 /** X25519 elliptic curve */
877  .name = "x25519",
878  .pointsize = sizeof ( struct x25519_value ),
879  .keysize = sizeof ( struct x25519_value ),
881  .is_infinity = x25519_curve_is_infinity,
882  .multiply = x25519_curve_multiply,
883  .add = x25519_curve_add,
884 };
bigint_t(bigint_required_size((260+7)/8)+bigint_required_size((6+7)/8))
Raw product.
Definition: x25519.c:152
#define __attribute__(x)
Definition: compiler.h:10
uint32_t base
Base.
Definition: librm.h:138
static void x25519_step(const union x25519_quad257 *base, int bit, struct x25519_step *step)
Compute next step of the Montgomery ladder.
Definition: x25519.c:618
void x25519_reduce(union x25519_quad257 *value)
Reduce big integer to canonical range.
Definition: x25519.c:586
uint32_t low
Low 16 bits of address.
Definition: myson.h:19
static int x25519_curve_is_infinity(const void *point)
Check if this is the point at infinity.
Definition: x25519.c:839
void x25519_multiply(const union x25519_oct258 *multiplicand, const union x25519_oct258 *multiplier, union x25519_quad257 *result)
Multiply big integers modulo field prime.
Definition: x25519.c:427
const union x25519_oct258 oct258
X25519 unsigned 258-bit integer.
Definition: x25519.h:74
struct elliptic_curve x25519_curve
X25519 elliptic curve.
Definition: x25519.c:876
Error codes.
struct x25519_multiply_step1::@442 parts
Partition into low-order and high-order bits.
static void x25519_init_constants(void)
Initialise constants.
Definition: x25519.c:314
An X25519 unsigned 257-bit integer.
Definition: x25519.h:65
static const uint8_t x25519_reduce_256_raw[]
Reduction constant (used during multiplication)
Definition: x25519.c:293
An X25519 Montgomery ladder step.
Definition: x25519.c:268
struct x25519_projective x_n
X[n]/Z[n].
Definition: x25519.c:270
#define bigint_grow(source, dest)
Grow big integer.
Definition: bigint.h:209
union x25519_multiply_step3 step3
Step 3 result.
Definition: x25519.c:238
An X25519 unsigned 258-bit integer.
Definition: x25519.h:46
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
Cryptographic API.
static unsigned int unsigned int bit
Definition: bigint.h:392
void x25519_key(const struct x25519_value *base, const struct x25519_value *scalar, struct x25519_value *result)
Calculate X25519 key.
Definition: x25519.c:808
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:25
#define static_assert(x)
Assert a condition at build time.
Definition: assert.h:66
union x25519_quad257 Z
Z coordinate.
Definition: x25519.c:264
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:134
static x25519_t x25519_4p
Constant 4p=2^257-76.
Definition: x25519.c:290
static x25519_t x25519_p
Constant p=2^255-19 (the finite field prime)
Definition: x25519.c:284
unsigned long tmp
Definition: linux_pci.h:65
static int x25519_curve_add(const void *addend __unused, const void *augend __unused, void *result __unused)
Add curve points (as a one-off operation)
Definition: x25519.c:868
static bigint_t(bigint_required_size(sizeof(x25519_reduce_256_raw)))
Reduction constant (used during multiplication)
Definition: x25519.c:296
#define INIT_NORMAL
Normal initialisation.
Definition: init.h:32
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void x25519_reduce_by(const x25519_t *subtrahend, x25519_t *value)
Reduce big integer via conditional subtraction.
Definition: x25519.c:567
static void x25519_ladder(const union x25519_quad257 *base, struct x25519_value *scalar, union x25519_quad257 *result)
Multiply X25519 elliptic curve point.
Definition: x25519.c:740
An initialisation function.
Definition: init.h:15
static void x25519_subtract(const union x25519_quad257 *minuend, const union x25519_quad257 *subtrahend, union x25519_oct258 *result)
Subtract big integers modulo field prime.
Definition: x25519.c:383
Assertions.
X25519 multiplication step 2 result.
Definition: x25519.c:145
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
X25519 key exchange.
uint8_t pad[sizeof(union x25519_multiply_step2) - offsetof(union x25519_multiply_step1, parts.high_260bit)]
Padding to avoid collision between steps 1 and 2.
Definition: x25519.c:229
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
bigint_t(X25519_SIZE+X25519_SIZE) product
Raw product.
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:235
static void x25519_add(const union x25519_quad257 *augend, const union x25519_quad257 *addend, union x25519_oct258 *result)
Add big integers modulo field prime.
Definition: x25519.c:350
const char * name
Definition: init.h:16
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
Definition: assert.h:77
static x25519_t x25519_2p
Constant 2p=2^256-38.
Definition: x25519.c:287
x25519_t value
Big integer value.
Definition: x25519.h:67
static void x25519_reverse(struct x25519_value *value)
Reverse X25519 value endianness.
Definition: x25519.c:774
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:75
const char * name
Curve name.
Definition: crypto.h:180
uint32_t high
High 32 bits of address.
Definition: myson.h:20
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition: bigint.h:31
union x25519_quad257 X
X coordinate.
Definition: x25519.c:262
X25519 multiplication step 3 result.
Definition: x25519.c:189
unsigned char uint8_t
Definition: stdint.h:10
#define X25519_REDUCE_256
X25519 reduction constant.
Definition: x25519.c:98
X25519 multiplication step 1 result.
Definition: x25519.c:108
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
#define bigint_swap(first, second, swap)
Conditionally swap big integers (in constant time)
Definition: bigint.h:247
static const uint8_t x25519_p_raw[]
Constant p=2^255-19 (the finite field prime)
Definition: x25519.c:276
int x25519_is_zero(const struct x25519_value *value)
Check if X25519 value is zero.
Definition: x25519.c:793
X25519 multiplication temporary working space.
Definition: x25519.c:217
static int x25519_curve_multiply(const void *base, const void *scalar, void *result)
Multiply scalar by curve point.
Definition: x25519.c:853
uint16_t result
Definition: hyperv.h:33
union x25519_multiply_step2 step2
Step 2 result.
Definition: x25519.c:236
static const uint32_t multiplier
Port multiplier number.
Definition: bigint.h:335
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
An elliptic curve.
Definition: crypto.h:178
#define X25519_SIZE
X25519 unsigned big integer size.
Definition: x25519.h:27
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:595
static struct x25519_value x25519_generator
Constant g=9 (the group generator)
Definition: x25519.c:306
struct x25519_projective x_n1
X[n+1]/Z[n+1].
Definition: x25519.c:272
void step(void)
Single-step a single process.
Definition: process.c:99
An X25519 elliptic curve point in projective coordinates.
Definition: x25519.c:260
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
uint8_t raw[32]
Raw value.
Definition: x25519.h:80
uint8_t product
Product string.
Definition: smbios.h:17
void x25519_invert(const union x25519_oct258 *invertend, union x25519_quad257 *result)
Compute multiplicative inverse.
Definition: x25519.c:529
struct init_fn x25519_init_fn __init_fn(INIT_NORMAL)
Initialisation function.
FILE_SECBOOT(PERMITTED)
union x25519_multiply_step1 step1
Step 1 result.
Definition: x25519.c:231
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:99
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:87
String functions.
static union x25519_oct258 x25519_121665
Constant 121665 (used in the Montgomery ladder)
Definition: x25519.c:303
An X25519 32-byte value.
Definition: x25519.h:78
x25519_t value
Big integer value.
Definition: x25519.h:48
void * memset(void *dest, int character, size_t len) __nonnull