summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_word.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn/bn_word.c')
-rw-r--r--src/lib/libcrypto/bn/bn_word.c65
1 files changed, 55 insertions, 10 deletions
diff --git a/src/lib/libcrypto/bn/bn_word.c b/src/lib/libcrypto/bn/bn_word.c
index 988e0ca7b3..ee7b87c45c 100644
--- a/src/lib/libcrypto/bn/bn_word.c
+++ b/src/lib/libcrypto/bn/bn_word.c
@@ -69,6 +69,10 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
69#endif 69#endif
70 int i; 70 int i;
71 71
72 if (w == 0)
73 return (BN_ULONG)-1;
74
75 bn_check_top(a);
72 w&=BN_MASK2; 76 w&=BN_MASK2;
73 for (i=a->top-1; i>=0; i--) 77 for (i=a->top-1; i>=0; i--)
74 { 78 {
@@ -85,12 +89,24 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
85 89
86BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) 90BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
87 { 91 {
88 BN_ULONG ret; 92 BN_ULONG ret = 0;
89 int i; 93 int i, j;
94
95 bn_check_top(a);
96 w &= BN_MASK2;
97
98 if (!w)
99 /* actually this an error (division by zero) */
100 return (BN_ULONG)-1;
101 if (a->top == 0)
102 return 0;
103
104 /* normalize input (so bn_div_words doesn't complain) */
105 j = BN_BITS2 - BN_num_bits_word(w);
106 w <<= j;
107 if (!BN_lshift(a, a, j))
108 return (BN_ULONG)-1;
90 109
91 if (a->top == 0) return(0);
92 ret=0;
93 w&=BN_MASK2;
94 for (i=a->top-1; i>=0; i--) 110 for (i=a->top-1; i>=0; i--)
95 { 111 {
96 BN_ULONG l,d; 112 BN_ULONG l,d;
@@ -102,6 +118,8 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
102 } 118 }
103 if ((a->top > 0) && (a->d[a->top-1] == 0)) 119 if ((a->top > 0) && (a->d[a->top-1] == 0))
104 a->top--; 120 a->top--;
121 ret >>= j;
122 bn_check_top(a);
105 return(ret); 123 return(ret);
106 } 124 }
107 125
@@ -110,6 +128,14 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
110 BN_ULONG l; 128 BN_ULONG l;
111 int i; 129 int i;
112 130
131 bn_check_top(a);
132 w &= BN_MASK2;
133
134 /* degenerate case: w is zero */
135 if (!w) return 1;
136 /* degenerate case: a is zero */
137 if(BN_is_zero(a)) return BN_set_word(a, w);
138 /* handle 'a' when negative */
113 if (a->neg) 139 if (a->neg)
114 { 140 {
115 a->neg=0; 141 a->neg=0;
@@ -118,15 +144,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
118 a->neg=!(a->neg); 144 a->neg=!(a->neg);
119 return(i); 145 return(i);
120 } 146 }
121 w&=BN_MASK2; 147 /* Only expand (and risk failing) if it's possibly necessary */
122 if (bn_wexpand(a,a->top+1) == NULL) return(0); 148 if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) &&
149 (bn_wexpand(a,a->top+1) == NULL))
150 return(0);
123 i=0; 151 i=0;
124 for (;;) 152 for (;;)
125 { 153 {
126 if (i >= a->top) 154 if (i >= a->top)
127 l=w; 155 l=w;
128 else 156 else
129 l=(a->d[i]+(BN_ULONG)w)&BN_MASK2; 157 l=(a->d[i]+w)&BN_MASK2;
130 a->d[i]=l; 158 a->d[i]=l;
131 if (w > l) 159 if (w > l)
132 w=1; 160 w=1;
@@ -136,6 +164,7 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
136 } 164 }
137 if (i >= a->top) 165 if (i >= a->top)
138 a->top++; 166 a->top++;
167 bn_check_top(a);
139 return(1); 168 return(1);
140 } 169 }
141 170
@@ -143,7 +172,21 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
143 { 172 {
144 int i; 173 int i;
145 174
146 if (BN_is_zero(a) || a->neg) 175 bn_check_top(a);
176 w &= BN_MASK2;
177
178 /* degenerate case: w is zero */
179 if (!w) return 1;
180 /* degenerate case: a is zero */
181 if(BN_is_zero(a))
182 {
183 i = BN_set_word(a,w);
184 if (i != 0)
185 BN_set_negative(a, 1);
186 return i;
187 }
188 /* handle 'a' when negative */
189 if (a->neg)
147 { 190 {
148 a->neg=0; 191 a->neg=0;
149 i=BN_add_word(a,w); 192 i=BN_add_word(a,w);
@@ -151,7 +194,6 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
151 return(i); 194 return(i);
152 } 195 }
153 196
154 w&=BN_MASK2;
155 if ((a->top == 1) && (a->d[0] < w)) 197 if ((a->top == 1) && (a->d[0] < w))
156 { 198 {
157 a->d[0]=w-a->d[0]; 199 a->d[0]=w-a->d[0];
@@ -175,6 +217,7 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
175 } 217 }
176 if ((a->d[i] == 0) && (i == (a->top-1))) 218 if ((a->d[i] == 0) && (i == (a->top-1)))
177 a->top--; 219 a->top--;
220 bn_check_top(a);
178 return(1); 221 return(1);
179 } 222 }
180 223
@@ -182,6 +225,7 @@ int BN_mul_word(BIGNUM *a, BN_ULONG w)
182 { 225 {
183 BN_ULONG ll; 226 BN_ULONG ll;
184 227
228 bn_check_top(a);
185 w&=BN_MASK2; 229 w&=BN_MASK2;
186 if (a->top) 230 if (a->top)
187 { 231 {
@@ -197,6 +241,7 @@ int BN_mul_word(BIGNUM *a, BN_ULONG w)
197 } 241 }
198 } 242 }
199 } 243 }
244 bn_check_top(a);
200 return(1); 245 return(1);
201 } 246 }
202 247