summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_prime.c
diff options
context:
space:
mode:
authorbeck <>2000-03-19 11:13:58 +0000
committerbeck <>2000-03-19 11:13:58 +0000
commit796d609550df3a33fc11468741c5d2f6d3df4c11 (patch)
tree6c6d539061caa20372dad0ac4ddb1dfae2fbe7fe /src/lib/libcrypto/bn/bn_prime.c
parent5be3114c1fd7e0dfea1e38d3abb4cbba75244419 (diff)
downloadopenbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.gz
openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.bz2
openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.zip
OpenSSL 0.9.5 merge
*warning* this bumps shared lib minors for libssl and libcrypto from 2.1 to 2.2 if you are using the ssl26 packages for ssh and other things to work you will need to get new ones (see ~beck/libsslsnap/<arch>) on cvs or ~beck/src-patent.tar.gz on cvs
Diffstat (limited to 'src/lib/libcrypto/bn/bn_prime.c')
-rw-r--r--src/lib/libcrypto/bn/bn_prime.c378
1 files changed, 198 insertions, 180 deletions
diff --git a/src/lib/libcrypto/bn/bn_prime.c b/src/lib/libcrypto/bn/bn_prime.c
index 6fa0f9be1e..a5f01b92eb 100644
--- a/src/lib/libcrypto/bn/bn_prime.c
+++ b/src/lib/libcrypto/bn/bn_prime.c
@@ -55,6 +55,59 @@
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ====================================================================
59 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
58 111
59#include <stdio.h> 112#include <stdio.h>
60#include <time.h> 113#include <time.h>
@@ -62,26 +115,29 @@
62#include "bn_lcl.h" 115#include "bn_lcl.h"
63#include <openssl/rand.h> 116#include <openssl/rand.h>
64 117
65/* The quick seive algorithm approach to weeding out primes is 118/* The quick sieve algorithm approach to weeding out primes is
66 * Philip Zimmermann's, as implemented in PGP. I have had a read of 119 * Philip Zimmermann's, as implemented in PGP. I have had a read of
67 * his comments and implemented my own version. 120 * his comments and implemented my own version.
68 */ 121 */
69#include "bn_prime.h" 122#include "bn_prime.h"
70 123
71static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx,BN_CTX *ctx2, 124static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
72 BN_MONT_CTX *mont); 125 const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
73static int probable_prime(BIGNUM *rnd, int bits); 126static int probable_prime(BIGNUM *rnd, int bits);
74static int probable_prime_dh(BIGNUM *rnd, int bits, 127static int probable_prime_dh(BIGNUM *rnd, int bits,
75 BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); 128 BIGNUM *add, BIGNUM *rem, BN_CTX *ctx);
76static int probable_prime_dh_strong(BIGNUM *rnd, int bits, 129static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
77 BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); 130 BIGNUM *add, BIGNUM *rem, BN_CTX *ctx);
78BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int strong, BIGNUM *add, 131
132BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, BIGNUM *add,
79 BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg) 133 BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg)
80 { 134 {
81 BIGNUM *rnd=NULL; 135 BIGNUM *rnd=NULL;
82 BIGNUM t; 136 BIGNUM t;
137 int found=0;
83 int i,j,c1=0; 138 int i,j,c1=0;
84 BN_CTX *ctx; 139 BN_CTX *ctx;
140 int checks = BN_prime_checks_for_size(bits);
85 141
86 ctx=BN_CTX_new(); 142 ctx=BN_CTX_new();
87 if (ctx == NULL) goto err; 143 if (ctx == NULL) goto err;
@@ -100,9 +156,9 @@ loop:
100 } 156 }
101 else 157 else
102 { 158 {
103 if (strong) 159 if (safe)
104 { 160 {
105 if (!probable_prime_dh_strong(rnd,bits,add,rem,ctx)) 161 if (!probable_prime_dh_safe(rnd,bits,add,rem,ctx))
106 goto err; 162 goto err;
107 } 163 }
108 else 164 else
@@ -114,160 +170,185 @@ loop:
114 /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */ 170 /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */
115 if (callback != NULL) callback(0,c1++,cb_arg); 171 if (callback != NULL) callback(0,c1++,cb_arg);
116 172
117 if (!strong) 173 if (!safe)
118 { 174 {
119 i=BN_is_prime(rnd,BN_prime_checks,callback,ctx,cb_arg); 175 i=BN_is_prime_fasttest(rnd,checks,callback,ctx,cb_arg,0);
120 if (i == -1) goto err; 176 if (i == -1) goto err;
121 if (i == 0) goto loop; 177 if (i == 0) goto loop;
122 } 178 }
123 else 179 else
124 { 180 {
125 /* for a strong prime generation, 181 /* for "safe prime" generation,
126 * check that (p-1)/2 is prime. 182 * check that (p-1)/2 is prime.
127 * Since a prime is odd, We just 183 * Since a prime is odd, We just
128 * need to divide by 2 */ 184 * need to divide by 2 */
129 if (!BN_rshift1(&t,rnd)) goto err; 185 if (!BN_rshift1(&t,rnd)) goto err;
130 186
131 for (i=0; i<BN_prime_checks; i++) 187 for (i=0; i<checks; i++)
132 { 188 {
133 j=BN_is_prime(rnd,1,callback,ctx,cb_arg); 189 j=BN_is_prime_fasttest(rnd,1,callback,ctx,cb_arg,0);
134 if (j == -1) goto err; 190 if (j == -1) goto err;
135 if (j == 0) goto loop; 191 if (j == 0) goto loop;
136 192
137 j=BN_is_prime(&t,1,callback,ctx,cb_arg); 193 j=BN_is_prime_fasttest(&t,1,callback,ctx,cb_arg,0);
138 if (j == -1) goto err; 194 if (j == -1) goto err;
139 if (j == 0) goto loop; 195 if (j == 0) goto loop;
140 196
141 if (callback != NULL) callback(2,c1-1,cb_arg); 197 if (callback != NULL) callback(2,c1-1,cb_arg);
142 /* We have a strong prime test pass */ 198 /* We have a safe prime test pass */
143 } 199 }
144 } 200 }
145 /* we have a prime :-) */ 201 /* we have a prime :-) */
146 ret=rnd; 202 found = 1;
147err: 203err:
148 if ((ret == NULL) && (rnd != NULL)) BN_free(rnd); 204 if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd);
149 BN_free(&t); 205 BN_free(&t);
150 if (ctx != NULL) BN_CTX_free(ctx); 206 if (ctx != NULL) BN_CTX_free(ctx);
151 return(ret); 207 return(found ? rnd : NULL);
152 } 208 }
153 209
154int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *), 210int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *),
155 BN_CTX *ctx_passed, void *cb_arg) 211 BN_CTX *ctx_passed, void *cb_arg)
156 { 212 {
157 int i,j,c2=0,ret= -1; 213 return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0);
158 BIGNUM *check; 214 }
159 BN_CTX *ctx=NULL,*ctx2=NULL;
160 BN_MONT_CTX *mont=NULL;
161 215
216int BN_is_prime_fasttest(const BIGNUM *a, int checks,
217 void (*callback)(int,int,void *),
218 BN_CTX *ctx_passed, void *cb_arg,
219 int do_trial_division)
220 {
221 int i, j, ret = -1;
222 int k;
223 BN_CTX *ctx = NULL;
224 BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
225 BN_MONT_CTX *mont = NULL;
226 const BIGNUM *A = NULL;
227
228 if (checks == BN_prime_checks)
229 checks = BN_prime_checks_for_size(BN_num_bits(a));
230
231 /* first look for small factors */
162 if (!BN_is_odd(a)) 232 if (!BN_is_odd(a))
163 return(0); 233 return(0);
234 if (do_trial_division)
235 {
236 for (i = 1; i < NUMPRIMES; i++)
237 if (BN_mod_word(a, primes[i]) == 0)
238 return 0;
239 if (callback != NULL) callback(1, -1, cb_arg);
240 }
241
164 if (ctx_passed != NULL) 242 if (ctx_passed != NULL)
165 ctx=ctx_passed; 243 ctx = ctx_passed;
166 else 244 else
167 if ((ctx=BN_CTX_new()) == NULL) goto err; 245 if ((ctx=BN_CTX_new()) == NULL)
168 246 goto err;
169 if ((ctx2=BN_CTX_new()) == NULL) goto err; 247 BN_CTX_start(ctx);
170 if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
171
172 check= &(ctx->bn[ctx->tos++]);
173 248
174 /* Setup the montgomery structure */ 249 /* A := abs(a) */
175 if (!BN_MONT_CTX_set(mont,a,ctx2)) goto err; 250 if (a->neg)
251 {
252 BIGNUM *t;
253 if ((t = BN_CTX_get(ctx)) == NULL) goto err;
254 BN_copy(t, a);
255 t->neg = 0;
256 A = t;
257 }
258 else
259 A = a;
260 A1 = BN_CTX_get(ctx);
261 A1_odd = BN_CTX_get(ctx);
262 check = BN_CTX_get(ctx);
263 if (check == NULL) goto err;
264
265 /* compute A1 := A - 1 */
266 if (!BN_copy(A1, A))
267 goto err;
268 if (!BN_sub_word(A1, 1))
269 goto err;
270 if (BN_is_zero(A1))
271 {
272 ret = 0;
273 goto err;
274 }
176 275
177 for (i=0; i<checks; i++) 276 /* write A1 as A1_odd * 2^k */
277 k = 1;
278 while (!BN_is_bit_set(A1, k))
279 k++;
280 if (!BN_rshift(A1_odd, A1, k))
281 goto err;
282
283 /* Montgomery setup for computations mod A */
284 mont = BN_MONT_CTX_new();
285 if (mont == NULL)
286 goto err;
287 if (!BN_MONT_CTX_set(mont, A, ctx))
288 goto err;
289
290 for (i = 0; i < checks; i++)
178 { 291 {
179 if (!BN_rand(check,BN_num_bits(a)-1,0,0)) goto err; 292 if (!BN_pseudo_rand(check, BN_num_bits(A1), 0, 0))
180 j=witness(check,a,ctx,ctx2,mont); 293 goto err;
294 if (BN_cmp(check, A1) >= 0)
295 if (!BN_sub(check, check, A1))
296 goto err;
297 if (!BN_add_word(check, 1))
298 goto err;
299 /* now 1 <= check < A */
300
301 j = witness(check, A, A1, A1_odd, k, ctx, mont);
181 if (j == -1) goto err; 302 if (j == -1) goto err;
182 if (j) 303 if (j)
183 { 304 {
184 ret=0; 305 ret=0;
185 goto err; 306 goto err;
186 } 307 }
187 if (callback != NULL) callback(1,c2++,cb_arg); 308 if (callback != NULL) callback(1,i,cb_arg);
188 } 309 }
189 ret=1; 310 ret=1;
190err: 311err:
191 ctx->tos--; 312 if (ctx != NULL)
192 if ((ctx_passed == NULL) && (ctx != NULL)) 313 {
193 BN_CTX_free(ctx); 314 BN_CTX_end(ctx);
194 if (ctx2 != NULL) 315 if (ctx_passed == NULL)
195 BN_CTX_free(ctx2); 316 BN_CTX_free(ctx);
196 if (mont != NULL) BN_MONT_CTX_free(mont); 317 }
197 318 if (mont != NULL)
319 BN_MONT_CTX_free(mont);
320
198 return(ret); 321 return(ret);
199 } 322 }
200 323
201#define RECP_MUL_MOD 324static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
202 325 const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont)
203static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx, BN_CTX *ctx2,
204 BN_MONT_CTX *mont)
205 { 326 {
206 int k,i,ret= -1,good; 327 if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
207 BIGNUM *d,*dd,*tmp,*d1,*d2,*n1; 328 return -1;
208 BIGNUM *mont_one,*mont_n1,*mont_a; 329 if (BN_is_one(w))
209 330 return 0; /* probably prime */
210 d1= &(ctx->bn[ctx->tos]); 331 if (BN_cmp(w, a1) == 0)
211 d2= &(ctx->bn[ctx->tos+1]); 332 return 0; /* w == -1 (mod a), 'a' is probably prime */
212 n1= &(ctx->bn[ctx->tos+2]); 333 while (--k)
213 ctx->tos+=3;
214
215 mont_one= &(ctx2->bn[ctx2->tos]);
216 mont_n1= &(ctx2->bn[ctx2->tos+1]);
217 mont_a= &(ctx2->bn[ctx2->tos+2]);
218 ctx2->tos+=3;
219
220 d=d1;
221 dd=d2;
222 if (!BN_one(d)) goto err;
223 if (!BN_sub(n1,n,d)) goto err; /* n1=n-1; */
224 k=BN_num_bits(n1);
225
226 if (!BN_to_montgomery(mont_one,BN_value_one(),mont,ctx2)) goto err;
227 if (!BN_to_montgomery(mont_n1,n1,mont,ctx2)) goto err;
228 if (!BN_to_montgomery(mont_a,a,mont,ctx2)) goto err;
229
230 BN_copy(d,mont_one);
231 for (i=k-1; i>=0; i--)
232 { 334 {
233 if ( (BN_cmp(d,mont_one) != 0) && 335 if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
234 (BN_cmp(d,mont_n1) != 0)) 336 return -1;
235 good=1; 337 if (BN_is_one(w))
236 else 338 return 1; /* 'a' is composite, otherwise a previous 'w' would
237 good=0; 339 * have been == -1 (mod 'a') */
238 340 if (BN_cmp(w, a1) == 0)
239 BN_mod_mul_montgomery(dd,d,d,mont,ctx2); 341 return 0; /* w == -1 (mod a), 'a' is probably prime */
240
241 if (good && (BN_cmp(dd,mont_one) == 0))
242 {
243 ret=1;
244 goto err;
245 }
246 if (BN_is_bit_set(n1,i))
247 {
248 BN_mod_mul_montgomery(d,dd,mont_a,mont,ctx2);
249 }
250 else
251 {
252 tmp=d;
253 d=dd;
254 dd=tmp;
255 }
256 } 342 }
257 if (BN_cmp(d,mont_one) == 0) 343 /* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
258 i=0; 344 * and it is neither -1 nor +1 -- so 'a' cannot be prime */
259 else i=1; 345 return 1;
260 ret=i;
261err:
262 ctx->tos-=3;
263 ctx2->tos-=3;
264 return(ret);
265 } 346 }
266 347
267static int probable_prime(BIGNUM *rnd, int bits) 348static int probable_prime(BIGNUM *rnd, int bits)
268 { 349 {
269 int i; 350 int i;
270 MS_STATIC BN_ULONG mods[NUMPRIMES]; 351 BN_ULONG mods[NUMPRIMES];
271 BN_ULONG delta,d; 352 BN_ULONG delta,d;
272 353
273again: 354again:
@@ -285,7 +366,7 @@ again:
285 d=delta; 366 d=delta;
286 delta+=2; 367 delta+=2;
287 /* perhaps need to check for overflow of 368 /* perhaps need to check for overflow of
288 * delta (but delta can be upto 2^32) 369 * delta (but delta can be up to 2^32)
289 * 21-May-98 eay - added overflow check */ 370 * 21-May-98 eay - added overflow check */
290 if (delta < d) goto again; 371 if (delta < d) goto again;
291 goto loop; 372 goto loop;
@@ -301,7 +382,8 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem,
301 int i,ret=0; 382 int i,ret=0;
302 BIGNUM *t1; 383 BIGNUM *t1;
303 384
304 t1= &(ctx->bn[ctx->tos++]); 385 BN_CTX_start(ctx);
386 if ((t1 = BN_CTX_get(ctx)) == NULL) goto err;
305 387
306 if (!BN_rand(rnd,bits,0,1)) goto err; 388 if (!BN_rand(rnd,bits,0,1)) goto err;
307 389
@@ -327,20 +409,22 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem,
327 } 409 }
328 ret=1; 410 ret=1;
329err: 411err:
330 ctx->tos--; 412 BN_CTX_end(ctx);
331 return(ret); 413 return(ret);
332 } 414 }
333 415
334static int probable_prime_dh_strong(BIGNUM *p, int bits, BIGNUM *padd, 416static int probable_prime_dh_safe(BIGNUM *p, int bits, BIGNUM *padd,
335 BIGNUM *rem, BN_CTX *ctx) 417 BIGNUM *rem, BN_CTX *ctx)
336 { 418 {
337 int i,ret=0; 419 int i,ret=0;
338 BIGNUM *t1,*qadd=NULL,*q=NULL; 420 BIGNUM *t1,*qadd,*q;
339 421
340 bits--; 422 bits--;
341 t1= &(ctx->bn[ctx->tos++]); 423 BN_CTX_start(ctx);
342 q= &(ctx->bn[ctx->tos++]); 424 t1 = BN_CTX_get(ctx);
343 qadd= &(ctx->bn[ctx->tos++]); 425 q = BN_CTX_get(ctx);
426 qadd = BN_CTX_get(ctx);
427 if (qadd == NULL) goto err;
344 428
345 if (!BN_rshift1(qadd,padd)) goto err; 429 if (!BN_rshift1(qadd,padd)) goto err;
346 430
@@ -376,72 +460,6 @@ static int probable_prime_dh_strong(BIGNUM *p, int bits, BIGNUM *padd,
376 } 460 }
377 ret=1; 461 ret=1;
378err: 462err:
379 ctx->tos-=3; 463 BN_CTX_end(ctx);
380 return(ret);
381 }
382
383#if 0
384static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx)
385 {
386 int k,i,nb,ret= -1;
387 BIGNUM *d,*dd,*tmp;
388 BIGNUM *d1,*d2,*x,*n1,*inv;
389
390 d1= &(ctx->bn[ctx->tos]);
391 d2= &(ctx->bn[ctx->tos+1]);
392 x= &(ctx->bn[ctx->tos+2]);
393 n1= &(ctx->bn[ctx->tos+3]);
394 inv=&(ctx->bn[ctx->tos+4]);
395 ctx->tos+=5;
396
397 d=d1;
398 dd=d2;
399 if (!BN_one(d)) goto err;
400 if (!BN_sub(n1,n,d)) goto err; /* n1=n-1; */
401 k=BN_num_bits(n1);
402
403 /* i=BN_num_bits(n); */
404#ifdef RECP_MUL_MOD
405 nb=BN_reciprocal(inv,n,ctx); /**/
406 if (nb == -1) goto err;
407#endif
408
409 for (i=k-1; i>=0; i--)
410 {
411 if (BN_copy(x,d) == NULL) goto err;
412#ifndef RECP_MUL_MOD
413 if (!BN_mod_mul(dd,d,d,n,ctx)) goto err;
414#else
415 if (!BN_mod_mul_reciprocal(dd,d,d,n,inv,nb,ctx)) goto err;
416#endif
417 if ( BN_is_one(dd) &&
418 !BN_is_one(x) &&
419 (BN_cmp(x,n1) != 0))
420 {
421 ret=1;
422 goto err;
423 }
424 if (BN_is_bit_set(n1,i))
425 {
426#ifndef RECP_MUL_MOD
427 if (!BN_mod_mul(d,dd,a,n,ctx)) goto err;
428#else
429 if (!BN_mod_mul_reciprocal(d,dd,a,n,inv,nb,ctx)) goto err;
430#endif
431 }
432 else
433 {
434 tmp=d;
435 d=dd;
436 dd=tmp;
437 }
438 }
439 if (BN_is_one(d))
440 i=0;
441 else i=1;
442 ret=i;
443err:
444 ctx->tos-=5;
445 return(ret); 464 return(ret);
446 } 465 }
447#endif