1 /* SPDX-License-Identifier: GPL-2.0-or-later * 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* mpi-internal.h - Internal to the Multi Pr 2 /* mpi-internal.h - Internal to the Multi Precision Integers 3 * Copyright (C) 1994, 1996 Free Software 3 * Copyright (C) 1994, 1996 Free Software Foundation, Inc. 4 * Copyright (C) 1998, 2000 Free Software 4 * Copyright (C) 1998, 2000 Free Software Foundation, Inc. 5 * 5 * 6 * This file is part of GnuPG. 6 * This file is part of GnuPG. 7 * 7 * 8 * Note: This code is heavily based on the GNU 8 * Note: This code is heavily based on the GNU MP Library. 9 * Actually it's the same code with only 9 * Actually it's the same code with only minor changes in the 10 * way the data is stored; this is to su 10 * way the data is stored; this is to support the abstraction 11 * of an optional secure memory allocati 11 * of an optional secure memory allocation which may be used 12 * to avoid revealing of sensitive data 12 * to avoid revealing of sensitive data due to paging etc. 13 * The GNU MP Library itself is publishe 13 * The GNU MP Library itself is published under the LGPL; 14 * however I decided to publish this cod 14 * however I decided to publish this code under the plain GPL. 15 */ 15 */ 16 16 17 #ifndef G10_MPI_INTERNAL_H 17 #ifndef G10_MPI_INTERNAL_H 18 #define G10_MPI_INTERNAL_H 18 #define G10_MPI_INTERNAL_H 19 19 20 #include <linux/module.h> 20 #include <linux/module.h> 21 #include <linux/kernel.h> 21 #include <linux/kernel.h> 22 #include <linux/slab.h> 22 #include <linux/slab.h> 23 #include <linux/string.h> 23 #include <linux/string.h> 24 #include <linux/mpi.h> 24 #include <linux/mpi.h> 25 #include <linux/errno.h> 25 #include <linux/errno.h> 26 26 27 #define log_debug printk 27 #define log_debug printk 28 #define log_bug printk 28 #define log_bug printk 29 29 30 #define assert(x) \ 30 #define assert(x) \ 31 do { \ 31 do { \ 32 if (!x) \ 32 if (!x) \ 33 log_bug("failed assert 33 log_bug("failed assertion\n"); \ 34 } while (0); 34 } while (0); 35 35 36 /* If KARATSUBA_THRESHOLD is not already defin 36 /* If KARATSUBA_THRESHOLD is not already defined, define it to a 37 * value which is good on most machines. */ 37 * value which is good on most machines. */ 38 38 39 /* tested 4, 16, 32 and 64, where 16 gave the 39 /* tested 4, 16, 32 and 64, where 16 gave the best performance when 40 * checking a 768 and a 1024 bit ElGamal signa 40 * checking a 768 and a 1024 bit ElGamal signature. 41 * (wk 22.12.97) */ 41 * (wk 22.12.97) */ 42 #ifndef KARATSUBA_THRESHOLD 42 #ifndef KARATSUBA_THRESHOLD 43 #define KARATSUBA_THRESHOLD 16 43 #define KARATSUBA_THRESHOLD 16 44 #endif 44 #endif 45 45 46 /* The code can't handle KARATSUBA_THRESHOLD s 46 /* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */ 47 #if KARATSUBA_THRESHOLD < 2 47 #if KARATSUBA_THRESHOLD < 2 48 #undef KARATSUBA_THRESHOLD 48 #undef KARATSUBA_THRESHOLD 49 #define KARATSUBA_THRESHOLD 2 49 #define KARATSUBA_THRESHOLD 2 50 #endif 50 #endif 51 51 52 typedef mpi_limb_t *mpi_ptr_t; /* pointer to 52 typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */ 53 typedef int mpi_size_t; /* (must be a 53 typedef int mpi_size_t; /* (must be a signed type) */ 54 54 55 static inline int RESIZE_IF_NEEDED(MPI a, unsi !! 55 #define RESIZE_IF_NEEDED(a, b) \ 56 { !! 56 do { \ 57 if (a->alloced < b) !! 57 if ((a)->alloced < (b)) \ 58 return mpi_resize(a, b); !! 58 mpi_resize((a), (b)); \ 59 return 0; !! 59 } while (0) 60 } << 61 60 62 /* Copy N limbs from S to D. */ 61 /* Copy N limbs from S to D. */ 63 #define MPN_COPY(d, s, n) \ 62 #define MPN_COPY(d, s, n) \ 64 do { 63 do { \ 65 mpi_size_t _i; 64 mpi_size_t _i; \ 66 for (_i = 0; _i < (n); _i++) 65 for (_i = 0; _i < (n); _i++) \ 67 (d)[_i] = (s)[_i]; 66 (d)[_i] = (s)[_i]; \ 68 } while (0) 67 } while (0) 69 68 >> 69 #define MPN_COPY_INCR(d, s, n) \ >> 70 do { \ >> 71 mpi_size_t _i; \ >> 72 for (_i = 0; _i < (n); _i++) \ >> 73 (d)[_i] = (s)[_i]; \ >> 74 } while (0) >> 75 >> 76 70 #define MPN_COPY_DECR(d, s, n) \ 77 #define MPN_COPY_DECR(d, s, n) \ 71 do { 78 do { \ 72 mpi_size_t _i; 79 mpi_size_t _i; \ 73 for (_i = (n)-1; _i >= 0; _i-- 80 for (_i = (n)-1; _i >= 0; _i--) \ 74 (d)[_i] = (s)[_i]; 81 (d)[_i] = (s)[_i]; \ 75 } while (0) 82 } while (0) 76 83 77 /* Zero N limbs at D */ 84 /* Zero N limbs at D */ 78 #define MPN_ZERO(d, n) \ 85 #define MPN_ZERO(d, n) \ 79 do { 86 do { \ 80 int _i; 87 int _i; \ 81 for (_i = 0; _i < (n); _i++) 88 for (_i = 0; _i < (n); _i++) \ 82 (d)[_i] = 0; 89 (d)[_i] = 0; \ 83 } while (0) 90 } while (0) 84 91 85 #define MPN_NORMALIZE(d, n) \ 92 #define MPN_NORMALIZE(d, n) \ 86 do { 93 do { \ 87 while ((n) > 0) { 94 while ((n) > 0) { \ 88 if ((d)[(n)-1]) 95 if ((d)[(n)-1]) \ 89 break; 96 break; \ 90 (n)--; 97 (n)--; \ 91 } 98 } \ 92 } while (0) 99 } while (0) 93 100 94 #define MPN_MUL_N_RECURSE(prodp, up, vp, size, 101 #define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \ 95 do { 102 do { \ 96 if ((size) < KARATSUBA_THRESHO 103 if ((size) < KARATSUBA_THRESHOLD) \ 97 mul_n_basecase(prodp, 104 mul_n_basecase(prodp, up, vp, size); \ 98 else 105 else \ 99 mul_n(prodp, up, vp, s 106 mul_n(prodp, up, vp, size, tspace); \ 100 } while (0); 107 } while (0); 101 108 102 /* Divide the two-limb number in (NH,,NL) by D 109 /* Divide the two-limb number in (NH,,NL) by D, with DI being the largest 103 * limb not larger than (2**(2*BITS_PER_MP_LIM 110 * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB). 104 * If this would yield overflow, DI should be 111 * If this would yield overflow, DI should be the largest possible number 105 * (i.e., only ones). For correct operation, 112 * (i.e., only ones). For correct operation, the most significant bit of D 106 * has to be set. Put the quotient in Q and t 113 * has to be set. Put the quotient in Q and the remainder in R. 107 */ 114 */ 108 #define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) 115 #define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \ 109 do { 116 do { \ 110 mpi_limb_t _ql __maybe_unused; 117 mpi_limb_t _ql __maybe_unused; \ 111 mpi_limb_t _q, _r; 118 mpi_limb_t _q, _r; \ 112 mpi_limb_t _xh, _xl; 119 mpi_limb_t _xh, _xl; \ 113 umul_ppmm(_q, _ql, (nh), (di)) 120 umul_ppmm(_q, _ql, (nh), (di)); \ 114 _q += (nh); /* DI is 2**BI 121 _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \ 115 umul_ppmm(_xh, _xl, _q, (d)); 122 umul_ppmm(_xh, _xl, _q, (d)); \ 116 sub_ddmmss(_xh, _r, (nh), (nl) 123 sub_ddmmss(_xh, _r, (nh), (nl), _xh, _xl); \ 117 if (_xh) { 124 if (_xh) { \ 118 sub_ddmmss(_xh, _r, _x 125 sub_ddmmss(_xh, _r, _xh, _r, 0, (d)); \ 119 _q++; 126 _q++; \ 120 if (_xh) { 127 if (_xh) { \ 121 sub_ddmmss(_xh 128 sub_ddmmss(_xh, _r, _xh, _r, 0, (d)); \ 122 _q++; 129 _q++; \ 123 } 130 } \ 124 } 131 } \ 125 if (_r >= (d)) { 132 if (_r >= (d)) { \ 126 _r -= (d); 133 _r -= (d); \ 127 _q++; 134 _q++; \ 128 } 135 } \ 129 (r) = _r; 136 (r) = _r; \ 130 (q) = _q; 137 (q) = _q; \ 131 } while (0) 138 } while (0) 132 139 133 140 134 /*-- mpiutil.c --*/ 141 /*-- mpiutil.c --*/ 135 mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs 142 mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs); 136 void mpi_free_limb_space(mpi_ptr_t a); 143 void mpi_free_limb_space(mpi_ptr_t a); 137 void mpi_assign_limb_space(MPI a, mpi_ptr_t ap 144 void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs); 138 145 139 static inline mpi_limb_t mpihelp_add_1(mpi_ptr 146 static inline mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 140 mpi_size_t s1_size, m 147 mpi_size_t s1_size, mpi_limb_t s2_limb); 141 mpi_limb_t mpihelp_add_n(mpi_ptr_t res_ptr, mp 148 mpi_limb_t mpihelp_add_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 142 mpi_ptr_t s2_ptr, mpi 149 mpi_ptr_t s2_ptr, mpi_size_t size); 143 static inline mpi_limb_t mpihelp_add(mpi_ptr_t 150 static inline mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, 144 mpi_ptr_t s2_ptr, mpi_s 151 mpi_ptr_t s2_ptr, mpi_size_t s2_size); 145 152 146 static inline mpi_limb_t mpihelp_sub_1(mpi_ptr 153 static inline mpi_limb_t mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 147 mpi_size_t s1_size, m 154 mpi_size_t s1_size, mpi_limb_t s2_limb); 148 mpi_limb_t mpihelp_sub_n(mpi_ptr_t res_ptr, mp 155 mpi_limb_t mpihelp_sub_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 149 mpi_ptr_t s2_ptr, mpi 156 mpi_ptr_t s2_ptr, mpi_size_t size); 150 static inline mpi_limb_t mpihelp_sub(mpi_ptr_t 157 static inline mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, 151 mpi_ptr_t s2_ptr, mpi_s 158 mpi_ptr_t s2_ptr, mpi_size_t s2_size); 152 159 153 /*-- mpih-cmp.c --*/ 160 /*-- mpih-cmp.c --*/ 154 int mpihelp_cmp(mpi_ptr_t op1_ptr, mpi_ptr_t o 161 int mpihelp_cmp(mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size); 155 162 156 /*-- mpih-mul.c --*/ 163 /*-- mpih-mul.c --*/ 157 164 158 struct karatsuba_ctx { 165 struct karatsuba_ctx { 159 struct karatsuba_ctx *next; 166 struct karatsuba_ctx *next; 160 mpi_ptr_t tspace; 167 mpi_ptr_t tspace; 161 mpi_size_t tspace_size; 168 mpi_size_t tspace_size; 162 mpi_ptr_t tp; 169 mpi_ptr_t tp; 163 mpi_size_t tp_size; 170 mpi_size_t tp_size; 164 }; 171 }; 165 172 166 void mpihelp_release_karatsuba_ctx(struct kara 173 void mpihelp_release_karatsuba_ctx(struct karatsuba_ctx *ctx); 167 174 168 mpi_limb_t mpihelp_addmul_1(mpi_ptr_t res_ptr, 175 mpi_limb_t mpihelp_addmul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 169 mpi_size_t s1_size 176 mpi_size_t s1_size, mpi_limb_t s2_limb); 170 mpi_limb_t mpihelp_submul_1(mpi_ptr_t res_ptr, 177 mpi_limb_t mpihelp_submul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 171 mpi_size_t s1_size 178 mpi_size_t s1_size, mpi_limb_t s2_limb); 172 int mpihelp_mul(mpi_ptr_t prodp, mpi_ptr_t up, 179 int mpihelp_mul(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, 173 mpi_ptr_t vp, mpi_size_t vsize 180 mpi_ptr_t vp, mpi_size_t vsize, mpi_limb_t *_result); 174 void mpih_sqr_n_basecase(mpi_ptr_t prodp, mpi_ 181 void mpih_sqr_n_basecase(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size); 175 void mpih_sqr_n(mpi_ptr_t prodp, mpi_ptr_t up, 182 void mpih_sqr_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, 176 mpi_ptr_t tspace); 183 mpi_ptr_t tspace); >> 184 void mpihelp_mul_n(mpi_ptr_t prodp, >> 185 mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size); 177 186 178 int mpihelp_mul_karatsuba_case(mpi_ptr_t prodp 187 int mpihelp_mul_karatsuba_case(mpi_ptr_t prodp, 179 mpi_ptr_t up, m 188 mpi_ptr_t up, mpi_size_t usize, 180 mpi_ptr_t vp, m 189 mpi_ptr_t vp, mpi_size_t vsize, 181 struct karatsub 190 struct karatsuba_ctx *ctx); 182 191 183 /*-- generic_mpih-mul1.c --*/ 192 /*-- generic_mpih-mul1.c --*/ 184 mpi_limb_t mpihelp_mul_1(mpi_ptr_t res_ptr, mp 193 mpi_limb_t mpihelp_mul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 185 mpi_size_t s1_size, m 194 mpi_size_t s1_size, mpi_limb_t s2_limb); 186 195 187 /*-- mpih-div.c --*/ 196 /*-- mpih-div.c --*/ 188 mpi_limb_t mpihelp_mod_1(mpi_ptr_t dividend_pt 197 mpi_limb_t mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, 189 mpi_limb_t divisor_li 198 mpi_limb_t divisor_limb); 190 mpi_limb_t mpihelp_divrem(mpi_ptr_t qp, mpi_si 199 mpi_limb_t mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs, 191 mpi_ptr_t np, mpi_si 200 mpi_ptr_t np, mpi_size_t nsize, 192 mpi_ptr_t dp, mpi_si 201 mpi_ptr_t dp, mpi_size_t dsize); 193 mpi_limb_t mpihelp_divmod_1(mpi_ptr_t quot_ptr 202 mpi_limb_t mpihelp_divmod_1(mpi_ptr_t quot_ptr, 194 mpi_ptr_t dividend 203 mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, 195 mpi_limb_t divisor 204 mpi_limb_t divisor_limb); 196 205 197 /*-- generic_mpih-[lr]shift.c --*/ 206 /*-- generic_mpih-[lr]shift.c --*/ 198 mpi_limb_t mpihelp_lshift(mpi_ptr_t wp, mpi_pt 207 mpi_limb_t mpihelp_lshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, 199 unsigned cnt); 208 unsigned cnt); 200 mpi_limb_t mpihelp_rshift(mpi_ptr_t wp, mpi_pt 209 mpi_limb_t mpihelp_rshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, 201 unsigned cnt); 210 unsigned cnt); 202 211 203 /* Define stuff for longlong.h. */ 212 /* Define stuff for longlong.h. */ 204 #define W_TYPE_SIZE BITS_PER_MPI_LIMB 213 #define W_TYPE_SIZE BITS_PER_MPI_LIMB 205 typedef mpi_limb_t UWtype; 214 typedef mpi_limb_t UWtype; 206 typedef unsigned int UHWtype; 215 typedef unsigned int UHWtype; 207 #if defined(__GNUC__) 216 #if defined(__GNUC__) 208 typedef unsigned int UQItype __attribute__ ((m 217 typedef unsigned int UQItype __attribute__ ((mode(QI))); 209 typedef int SItype __attribute__ ((mode(SI))); 218 typedef int SItype __attribute__ ((mode(SI))); 210 typedef unsigned int USItype __attribute__ ((m 219 typedef unsigned int USItype __attribute__ ((mode(SI))); 211 typedef int DItype __attribute__ ((mode(DI))); 220 typedef int DItype __attribute__ ((mode(DI))); 212 typedef unsigned int UDItype __attribute__ ((m 221 typedef unsigned int UDItype __attribute__ ((mode(DI))); 213 #else 222 #else 214 typedef unsigned char UQItype; 223 typedef unsigned char UQItype; 215 typedef long SItype; 224 typedef long SItype; 216 typedef unsigned long USItype; 225 typedef unsigned long USItype; 217 #endif 226 #endif 218 227 219 #ifdef __GNUC__ 228 #ifdef __GNUC__ 220 #include "mpi-inline.h" 229 #include "mpi-inline.h" 221 #endif 230 #endif 222 231 223 #endif /*G10_MPI_INTERNAL_H */ 232 #endif /*G10_MPI_INTERNAL_H */ 224 233
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.