1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* mpi-internal.h - Internal to the Multi Precision Integers 3 * Copyright (C) 1994, 1996 Free Software Foundation, Inc. 4 * Copyright (C) 1998, 2000 Free Software Foundation, Inc. 5 * 6 * This file is part of GnuPG. 7 * 8 * Note: This code is heavily based on the GNU MP Library. 9 * Actually it's the same code with only minor changes in the 10 * way the data is stored; this is to support the abstraction 11 * of an optional secure memory allocation which may be used 12 * to avoid revealing of sensitive data due to paging etc. 13 * The GNU MP Library itself is published under the LGPL; 14 * however I decided to publish this code under the plain GPL. 15 */ 16 17 #ifndef G10_MPI_INTERNAL_H 18 #define G10_MPI_INTERNAL_H 19 20 #include <linux/module.h> 21 #include <linux/kernel.h> 22 #include <linux/slab.h> 23 #include <linux/string.h> 24 #include <linux/mpi.h> 25 #include <linux/errno.h> 26 27 #define log_debug printk 28 #define log_bug printk 29 30 #define assert(x) \ 31 do { \ 32 if (!x) \ 33 log_bug("failed assertion\n"); \ 34 } while (0); 35 36 /* If KARATSUBA_THRESHOLD is not already defined, define it to a 37 * value which is good on most machines. */ 38 39 /* tested 4, 16, 32 and 64, where 16 gave the best performance when 40 * checking a 768 and a 1024 bit ElGamal signature. 41 * (wk 22.12.97) */ 42 #ifndef KARATSUBA_THRESHOLD 43 #define KARATSUBA_THRESHOLD 16 44 #endif 45 46 /* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */ 47 #if KARATSUBA_THRESHOLD < 2 48 #undef KARATSUBA_THRESHOLD 49 #define KARATSUBA_THRESHOLD 2 50 #endif 51 52 typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */ 53 typedef int mpi_size_t; /* (must be a signed type) */ 54 55 /* Copy N limbs from S to D. */ 56 #define MPN_COPY(d, s, n) \ 57 do { \ 58 mpi_size_t _i; \ 59 for (_i = 0; _i < (n); _i++) \ 60 (d)[_i] = (s)[_i]; \ 61 } while (0) 62 63 #define MPN_COPY_DECR(d, s, n) \ 64 do { \ 65 mpi_size_t _i; \ 66 for (_i = (n)-1; _i >= 0; _i--) \ 67 (d)[_i] = (s)[_i]; \ 68 } while (0) 69 70 /* Zero N limbs at D */ 71 #define MPN_ZERO(d, n) \ 72 do { \ 73 int _i; \ 74 for (_i = 0; _i < (n); _i++) \ 75 (d)[_i] = 0; \ 76 } while (0) 77 78 #define MPN_NORMALIZE(d, n) \ 79 do { \ 80 while ((n) > 0) { \ 81 if ((d)[(n)-1]) \ 82 break; \ 83 (n)--; \ 84 } \ 85 } while (0) 86 87 #define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \ 88 do { \ 89 if ((size) < KARATSUBA_THRESHOLD) \ 90 mul_n_basecase(prodp, up, vp, size); \ 91 else \ 92 mul_n(prodp, up, vp, size, tspace); \ 93 } while (0); 94 95 /*-- mpiutil.c --*/ 96 mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs); 97 void mpi_free_limb_space(mpi_ptr_t a); 98 void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs); 99 100 static inline mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 101 mpi_size_t s1_size, mpi_limb_t s2_limb); 102 mpi_limb_t mpihelp_add_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 103 mpi_ptr_t s2_ptr, mpi_size_t size); 104 static inline mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, 105 mpi_ptr_t s2_ptr, mpi_size_t s2_size); 106 107 static inline mpi_limb_t mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 108 mpi_size_t s1_size, mpi_limb_t s2_limb); 109 mpi_limb_t mpihelp_sub_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 110 mpi_ptr_t s2_ptr, mpi_size_t size); 111 static inline mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, 112 mpi_ptr_t s2_ptr, mpi_size_t s2_size); 113 114 /*-- mpih-cmp.c --*/ 115 int mpihelp_cmp(mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size); 116 117 /*-- mpih-mul.c --*/ 118 119 struct karatsuba_ctx { 120 struct karatsuba_ctx *next; 121 mpi_ptr_t tspace; 122 mpi_size_t tspace_size; 123 mpi_ptr_t tp; 124 mpi_size_t tp_size; 125 }; 126 127 void mpihelp_release_karatsuba_ctx(struct karatsuba_ctx *ctx); 128 129 mpi_limb_t mpihelp_addmul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 130 mpi_size_t s1_size, mpi_limb_t s2_limb); 131 mpi_limb_t mpihelp_submul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 132 mpi_size_t s1_size, mpi_limb_t s2_limb); 133 int mpihelp_mul(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, 134 mpi_ptr_t vp, mpi_size_t vsize, mpi_limb_t *_result); 135 void mpih_sqr_n_basecase(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size); 136 void mpih_sqr_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, 137 mpi_ptr_t tspace); 138 139 int mpihelp_mul_karatsuba_case(mpi_ptr_t prodp, 140 mpi_ptr_t up, mpi_size_t usize, 141 mpi_ptr_t vp, mpi_size_t vsize, 142 struct karatsuba_ctx *ctx); 143 144 /*-- generic_mpih-mul1.c --*/ 145 mpi_limb_t mpihelp_mul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 146 mpi_size_t s1_size, mpi_limb_t s2_limb); 147 148 /*-- mpih-div.c --*/ 149 mpi_limb_t mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs, 150 mpi_ptr_t np, mpi_size_t nsize, 151 mpi_ptr_t dp, mpi_size_t dsize); 152 153 /*-- generic_mpih-[lr]shift.c --*/ 154 mpi_limb_t mpihelp_lshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, 155 unsigned cnt); 156 mpi_limb_t mpihelp_rshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, 157 unsigned cnt); 158 159 /* Define stuff for longlong.h. */ 160 #define W_TYPE_SIZE BITS_PER_MPI_LIMB 161 typedef mpi_limb_t UWtype; 162 typedef unsigned int UHWtype; 163 #if defined(__GNUC__) 164 typedef unsigned int UQItype __attribute__ ((mode(QI))); 165 typedef int SItype __attribute__ ((mode(SI))); 166 typedef unsigned int USItype __attribute__ ((mode(SI))); 167 typedef int DItype __attribute__ ((mode(DI))); 168 typedef unsigned int UDItype __attribute__ ((mode(DI))); 169 #else 170 typedef unsigned char UQItype; 171 typedef long SItype; 172 typedef unsigned long USItype; 173 #endif 174 175 #ifdef __GNUC__ 176 #include "mpi-inline.h" 177 #endif 178 179 #endif /*G10_MPI_INTERNAL_H */ 180