Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: lib/mpi - Add error checks to extension

The remaining functions added by commit
a8ea8bdd9df92a0e5db5b43900abb7a288b8a53e did not check for memory
allocation errors. Add the checks and change the API to allow errors
to be returned.

Fixes: a8ea8bdd9df9 ("lib/mpi: Extend the MPI library")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+128 -58
+11 -11
include/linux/mpi.h
··· 59 59 int *sign); 60 60 61 61 /*-- mpi-mod.c --*/ 62 - void mpi_mod(MPI rem, MPI dividend, MPI divisor); 62 + int mpi_mod(MPI rem, MPI dividend, MPI divisor); 63 63 64 64 /*-- mpi-pow.c --*/ 65 65 int mpi_powm(MPI res, MPI base, MPI exp, MPI mod); ··· 75 75 void mpi_normalize(MPI a); 76 76 unsigned mpi_get_nbits(MPI a); 77 77 int mpi_test_bit(MPI a, unsigned int n); 78 - void mpi_set_bit(MPI a, unsigned int n); 79 - void mpi_rshift(MPI x, MPI a, unsigned int n); 78 + int mpi_set_bit(MPI a, unsigned int n); 79 + int mpi_rshift(MPI x, MPI a, unsigned int n); 80 80 81 81 /*-- mpi-add.c --*/ 82 - void mpi_add(MPI w, MPI u, MPI v); 83 - void mpi_sub(MPI w, MPI u, MPI v); 84 - void mpi_addm(MPI w, MPI u, MPI v, MPI m); 85 - void mpi_subm(MPI w, MPI u, MPI v, MPI m); 82 + int mpi_add(MPI w, MPI u, MPI v); 83 + int mpi_sub(MPI w, MPI u, MPI v); 84 + int mpi_addm(MPI w, MPI u, MPI v, MPI m); 85 + int mpi_subm(MPI w, MPI u, MPI v, MPI m); 86 86 87 87 /*-- mpi-mul.c --*/ 88 - void mpi_mul(MPI w, MPI u, MPI v); 89 - void mpi_mulm(MPI w, MPI u, MPI v, MPI m); 88 + int mpi_mul(MPI w, MPI u, MPI v); 89 + int mpi_mulm(MPI w, MPI u, MPI v, MPI m); 90 90 91 91 /*-- mpi-div.c --*/ 92 - void mpi_tdiv_r(MPI rem, MPI num, MPI den); 93 - void mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor); 92 + int mpi_tdiv_r(MPI rem, MPI num, MPI den); 93 + int mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor); 94 94 95 95 /* inline functions */ 96 96
+26 -12
lib/crypto/mpi/mpi-add.c
··· 13 13 14 14 #include "mpi-internal.h" 15 15 16 - void mpi_add(MPI w, MPI u, MPI v) 16 + int mpi_add(MPI w, MPI u, MPI v) 17 17 { 18 18 mpi_ptr_t wp, up, vp; 19 19 mpi_size_t usize, vsize, wsize; 20 20 int usign, vsign, wsign; 21 + int err; 21 22 22 23 if (u->nlimbs < v->nlimbs) { /* Swap U and V. */ 23 24 usize = v->nlimbs; ··· 26 25 vsize = u->nlimbs; 27 26 vsign = u->sign; 28 27 wsize = usize + 1; 29 - RESIZE_IF_NEEDED(w, wsize); 28 + err = RESIZE_IF_NEEDED(w, wsize); 29 + if (err) 30 + return err; 30 31 /* These must be after realloc (u or v may be the same as w). */ 31 32 up = v->d; 32 33 vp = u->d; ··· 38 35 vsize = v->nlimbs; 39 36 vsign = v->sign; 40 37 wsize = usize + 1; 41 - RESIZE_IF_NEEDED(w, wsize); 38 + err = RESIZE_IF_NEEDED(w, wsize); 39 + if (err) 40 + return err; 42 41 /* These must be after realloc (u or v may be the same as w). */ 43 42 up = u->d; 44 43 vp = v->d; ··· 82 77 83 78 w->nlimbs = wsize; 84 79 w->sign = wsign; 80 + return 0; 85 81 } 86 82 EXPORT_SYMBOL_GPL(mpi_add); 87 83 88 - void mpi_sub(MPI w, MPI u, MPI v) 84 + int mpi_sub(MPI w, MPI u, MPI v) 89 85 { 90 - MPI vv = mpi_copy(v); 86 + int err; 87 + MPI vv; 88 + 89 + vv = mpi_copy(v); 90 + if (!vv) 91 + return -ENOMEM; 92 + 91 93 vv->sign = !vv->sign; 92 - mpi_add(w, u, vv); 94 + err = mpi_add(w, u, vv); 93 95 mpi_free(vv); 96 + 97 + return err; 94 98 } 95 99 EXPORT_SYMBOL_GPL(mpi_sub); 96 100 97 - void mpi_addm(MPI w, MPI u, MPI v, MPI m) 101 + int mpi_addm(MPI w, MPI u, MPI v, MPI m) 98 102 { 99 - mpi_add(w, u, v); 100 - mpi_mod(w, w, m); 103 + return mpi_add(w, u, v) ?: 104 + mpi_mod(w, w, m); 101 105 } 102 106 EXPORT_SYMBOL_GPL(mpi_addm); 103 107 104 - void mpi_subm(MPI w, MPI u, MPI v, MPI m) 108 + int mpi_subm(MPI w, MPI u, MPI v, MPI m) 105 109 { 106 - mpi_sub(w, u, v); 107 - mpi_mod(w, w, m); 110 + return mpi_sub(w, u, v) ?: 111 + mpi_mod(w, w, m); 108 112 } 109 113 EXPORT_SYMBOL_GPL(mpi_subm);
+18 -7
lib/crypto/mpi/mpi-bit.c
··· 76 76 /**************** 77 77 * Set bit N of A. 78 78 */ 79 - void mpi_set_bit(MPI a, unsigned int n) 79 + int mpi_set_bit(MPI a, unsigned int n) 80 80 { 81 81 unsigned int i, limbno, bitno; 82 + int err; 82 83 83 84 limbno = n / BITS_PER_MPI_LIMB; 84 85 bitno = n % BITS_PER_MPI_LIMB; ··· 87 86 if (limbno >= a->nlimbs) { 88 87 for (i = a->nlimbs; i < a->alloced; i++) 89 88 a->d[i] = 0; 90 - mpi_resize(a, limbno+1); 89 + err = mpi_resize(a, limbno+1); 90 + if (err) 91 + return err; 91 92 a->nlimbs = limbno+1; 92 93 } 93 94 a->d[limbno] |= (A_LIMB_1<<bitno); 95 + return 0; 94 96 } 95 97 96 98 /* 97 99 * Shift A by N bits to the right. 98 100 */ 99 - void mpi_rshift(MPI x, MPI a, unsigned int n) 101 + int mpi_rshift(MPI x, MPI a, unsigned int n) 100 102 { 101 103 mpi_size_t xsize; 102 104 unsigned int i; 103 105 unsigned int nlimbs = (n/BITS_PER_MPI_LIMB); 104 106 unsigned int nbits = (n%BITS_PER_MPI_LIMB); 107 + int err; 105 108 106 109 if (x == a) { 107 110 /* In-place operation. */ 108 111 if (nlimbs >= x->nlimbs) { 109 112 x->nlimbs = 0; 110 - return; 113 + return 0; 111 114 } 112 115 113 116 if (nlimbs) { ··· 126 121 /* Copy and shift by more or equal bits than in a limb. */ 127 122 xsize = a->nlimbs; 128 123 x->sign = a->sign; 129 - RESIZE_IF_NEEDED(x, xsize); 124 + err = RESIZE_IF_NEEDED(x, xsize); 125 + if (err) 126 + return err; 130 127 x->nlimbs = xsize; 131 128 for (i = 0; i < a->nlimbs; i++) 132 129 x->d[i] = a->d[i]; ··· 136 129 137 130 if (nlimbs >= x->nlimbs) { 138 131 x->nlimbs = 0; 139 - return; 132 + return 0; 140 133 } 141 134 142 135 for (i = 0; i < x->nlimbs - nlimbs; i++) ··· 150 143 /* Copy and shift by less than bits in a limb. */ 151 144 xsize = a->nlimbs; 152 145 x->sign = a->sign; 153 - RESIZE_IF_NEEDED(x, xsize); 146 + err = RESIZE_IF_NEEDED(x, xsize); 147 + if (err) 148 + return err; 154 149 x->nlimbs = xsize; 155 150 156 151 if (xsize) { ··· 168 159 } 169 160 } 170 161 MPN_NORMALIZE(x->d, x->nlimbs); 162 + 163 + return 0; 171 164 } 172 165 EXPORT_SYMBOL_GPL(mpi_rshift);
+40 -15
lib/crypto/mpi/mpi-div.c
··· 14 14 #include "mpi-internal.h" 15 15 #include "longlong.h" 16 16 17 - void mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den); 17 + int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den); 18 18 19 - void mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor) 19 + int mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor) 20 20 { 21 21 int divisor_sign = divisor->sign; 22 22 MPI temp_divisor = NULL; 23 + int err; 23 24 24 25 /* We need the original value of the divisor after the remainder has been 25 26 * preliminary calculated. We have to copy it to temporary space if it's ··· 28 27 */ 29 28 if (rem == divisor) { 30 29 temp_divisor = mpi_copy(divisor); 30 + if (!temp_divisor) 31 + return -ENOMEM; 31 32 divisor = temp_divisor; 32 33 } 33 34 34 - mpi_tdiv_r(rem, dividend, divisor); 35 + err = mpi_tdiv_r(rem, dividend, divisor); 36 + if (err) 37 + goto free_temp_divisor; 35 38 36 39 if (((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs) 37 - mpi_add(rem, rem, divisor); 40 + err = mpi_add(rem, rem, divisor); 38 41 39 - if (temp_divisor) 40 - mpi_free(temp_divisor); 42 + free_temp_divisor: 43 + mpi_free(temp_divisor); 44 + 45 + return err; 41 46 } 42 47 43 48 /* If den == quot, den needs temporary storage. ··· 53 46 * i.e no extra storage should be allocated. 54 47 */ 55 48 56 - void mpi_tdiv_r(MPI rem, MPI num, MPI den) 49 + int mpi_tdiv_r(MPI rem, MPI num, MPI den) 57 50 { 58 - mpi_tdiv_qr(NULL, rem, num, den); 51 + return mpi_tdiv_qr(NULL, rem, num, den); 59 52 } 60 53 61 - void mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) 54 + int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) 62 55 { 63 56 mpi_ptr_t np, dp; 64 57 mpi_ptr_t qp, rp; ··· 71 64 mpi_limb_t q_limb; 72 65 mpi_ptr_t marker[5]; 73 66 int markidx = 0; 67 + int err; 74 68 75 69 /* Ensure space is enough for quotient and remainder. 76 70 * We need space for an extra limb in the remainder, because it's 77 71 * up-shifted (normalized) below. 78 72 */ 79 73 rsize = nsize + 1; 80 - mpi_resize(rem, rsize); 74 + err = mpi_resize(rem, rsize); 75 + if (err) 76 + return err; 81 77 82 78 qsize = rsize - dsize; /* qsize cannot be bigger than this. */ 83 79 if (qsize <= 0) { ··· 96 86 quot->nlimbs = 0; 97 87 quot->sign = 0; 98 88 } 99 - return; 89 + return 0; 100 90 } 101 91 102 - if (quot) 103 - mpi_resize(quot, qsize); 92 + if (quot) { 93 + err = mpi_resize(quot, qsize); 94 + if (err) 95 + return err; 96 + } 104 97 105 98 /* Read pointers here, when reallocation is finished. */ 106 99 np = num->d; ··· 125 112 rsize = rlimb != 0?1:0; 126 113 rem->nlimbs = rsize; 127 114 rem->sign = sign_remainder; 128 - return; 115 + return 0; 129 116 } 130 117 131 - 118 + err = -ENOMEM; 132 119 if (quot) { 133 120 qp = quot->d; 134 121 /* Make sure QP and NP point to different objects. Otherwise the ··· 136 123 */ 137 124 if (qp == np) { /* Copy NP object to temporary space. */ 138 125 np = marker[markidx++] = mpi_alloc_limb_space(nsize); 126 + if (!np) 127 + goto out_free_marker; 139 128 MPN_COPY(np, qp, nsize); 140 129 } 141 130 } else /* Put quotient at top of remainder. */ ··· 158 143 * the original contents of the denominator. 159 144 */ 160 145 tp = marker[markidx++] = mpi_alloc_limb_space(dsize); 146 + if (!tp) 147 + goto out_free_marker; 161 148 mpihelp_lshift(tp, dp, dsize, normalization_steps); 162 149 dp = tp; 163 150 ··· 181 164 mpi_ptr_t tp; 182 165 183 166 tp = marker[markidx++] = mpi_alloc_limb_space(dsize); 167 + if (!tp) 168 + goto out_free_marker; 184 169 MPN_COPY(tp, dp, dsize); 185 170 dp = tp; 186 171 } ··· 217 198 218 199 rem->nlimbs = rsize; 219 200 rem->sign = sign_remainder; 201 + 202 + err = 0; 203 + 204 + out_free_marker: 220 205 while (markidx) { 221 206 markidx--; 222 207 mpi_free_limb_space(marker[markidx]); 223 208 } 209 + 210 + return err; 224 211 }
+6 -5
lib/crypto/mpi/mpi-internal.h
··· 52 52 typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */ 53 53 typedef int mpi_size_t; /* (must be a signed type) */ 54 54 55 - #define RESIZE_IF_NEEDED(a, b) \ 56 - do { \ 57 - if ((a)->alloced < (b)) \ 58 - mpi_resize((a), (b)); \ 59 - } while (0) 55 + static inline int RESIZE_IF_NEEDED(MPI a, unsigned b) 56 + { 57 + if (a->alloced < b) 58 + return mpi_resize(a, b); 59 + return 0; 60 + } 60 61 61 62 /* Copy N limbs from S to D. */ 62 63 #define MPN_COPY(d, s, n) \
+2 -2
lib/crypto/mpi/mpi-mod.c
··· 7 7 8 8 #include "mpi-internal.h" 9 9 10 - void mpi_mod(MPI rem, MPI dividend, MPI divisor) 10 + int mpi_mod(MPI rem, MPI dividend, MPI divisor) 11 11 { 12 - mpi_fdiv_r(rem, dividend, divisor); 12 + return mpi_fdiv_r(rem, dividend, divisor); 13 13 }
+23 -6
lib/crypto/mpi/mpi-mul.c
··· 13 13 14 14 #include "mpi-internal.h" 15 15 16 - void mpi_mul(MPI w, MPI u, MPI v) 16 + int mpi_mul(MPI w, MPI u, MPI v) 17 17 { 18 18 mpi_size_t usize, vsize, wsize; 19 19 mpi_ptr_t up, vp, wp; ··· 21 21 int usign, vsign, sign_product; 22 22 int assign_wp = 0; 23 23 mpi_ptr_t tmp_limb = NULL; 24 + int err; 24 25 25 26 if (u->nlimbs < v->nlimbs) { 26 27 /* Swap U and V. */ ··· 47 46 if (w->alloced < wsize) { 48 47 if (wp == up || wp == vp) { 49 48 wp = mpi_alloc_limb_space(wsize); 49 + if (!wp) 50 + return -ENOMEM; 50 51 assign_wp = 1; 51 52 } else { 52 - mpi_resize(w, wsize); 53 + err = mpi_resize(w, wsize); 54 + if (err) 55 + return err; 53 56 wp = w->d; 54 57 } 55 58 } else { /* Make U and V not overlap with W. */ 56 59 if (wp == up) { 57 60 /* W and U are identical. Allocate temporary space for U. */ 58 61 up = tmp_limb = mpi_alloc_limb_space(usize); 62 + if (!up) 63 + return -ENOMEM; 59 64 /* Is V identical too? Keep it identical with U. */ 60 65 if (wp == vp) 61 66 vp = up; ··· 70 63 } else if (wp == vp) { 71 64 /* W and V are identical. Allocate temporary space for V. */ 72 65 vp = tmp_limb = mpi_alloc_limb_space(vsize); 66 + if (!vp) 67 + return -ENOMEM; 73 68 /* Copy to the temporary space. */ 74 69 MPN_COPY(vp, wp, vsize); 75 70 } ··· 80 71 if (!vsize) 81 72 wsize = 0; 82 73 else { 83 - mpihelp_mul(wp, up, usize, vp, vsize, &cy); 74 + err = mpihelp_mul(wp, up, usize, vp, vsize, &cy); 75 + if (err) { 76 + if (assign_wp) 77 + mpi_free_limb_space(wp); 78 + goto free_tmp_limb; 79 + } 84 80 wsize -= cy ? 0:1; 85 81 } 86 82 ··· 93 79 mpi_assign_limb_space(w, wp, wsize); 94 80 w->nlimbs = wsize; 95 81 w->sign = sign_product; 82 + 83 + free_tmp_limb: 96 84 if (tmp_limb) 97 85 mpi_free_limb_space(tmp_limb); 86 + return err; 98 87 } 99 88 EXPORT_SYMBOL_GPL(mpi_mul); 100 89 101 - void mpi_mulm(MPI w, MPI u, MPI v, MPI m) 90 + int mpi_mulm(MPI w, MPI u, MPI v, MPI m) 102 91 { 103 - mpi_mul(w, u, v); 104 - mpi_tdiv_r(w, w, m); 92 + return mpi_mul(w, u, v) ?: 93 + mpi_tdiv_r(w, w, m); 105 94 } 106 95 EXPORT_SYMBOL_GPL(mpi_mulm);
+2
lib/crypto/mpi/mpiutil.c
··· 133 133 134 134 if (a) { 135 135 b = mpi_alloc(a->nlimbs); 136 + if (!b) 137 + return NULL; 136 138 b->nlimbs = a->nlimbs; 137 139 b->sign = a->sign; 138 140 b->flags = a->flags;