Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
/*
2
 *	FIPS-197 compliant AES implementation
3
 *
4
 *	Copyright (C) 2006-2007 Christophe Devine
5
 *
6
 *	Redistribution and use in source and binary forms, with or without
7
 *	modification, are permitted provided that the following conditions
8
 *	are met:
9
 *
10
 *	* Redistributions of source code _must_ retain the above copyright
11
 *		notice, this list of conditions and the following disclaimer.
12
 *	* Redistributions in binary form may or may not reproduce the above
13
 *		copyright notice, this list of conditions and the following
14
 *		disclaimer in the documentation and/or other materials provided
15
 *		with the distribution.
16
 *	* Neither the name of XySSL nor the names of its contributors may be
17
 *		used to endorse or promote products derived from this software
18
 *		without specific prior written permission.
19
 *
20
 *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
 *	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
 *	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23
 *	FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
 *	OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
 *	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26
 *	TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
 *	PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
 *	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
 *	NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
 */
32
/*
33
 *	The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
34
 *
35
 *	http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
36
 *	http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
37
 */
38
 
39
#include "fitz.h"
40
 
41
#define aes_context fz_aes
42
 
43
/* AES block cipher implementation from XYSSL */
44
 
45
/*
46
 * 32-bit integer manipulation macros (little endian)
47
 */
48
#ifndef GET_ULONG_LE
49
#define GET_ULONG_LE(n,b,i)					\
50
{								\
51
	(n) = ( (unsigned long) (b)[(i)] )			\
52
		| ( (unsigned long) (b)[(i) + 1] << 8 )		\
53
		| ( (unsigned long) (b)[(i) + 2] << 16 )	\
54
		| ( (unsigned long) (b)[(i) + 3] << 24 );	\
55
}
56
#endif
57
 
58
#ifndef PUT_ULONG_LE
59
#define PUT_ULONG_LE(n,b,i)				\
60
{							\
61
	(b)[(i) ] = (unsigned char) ( (n) );		\
62
	(b)[(i) + 1] = (unsigned char) ( (n) >> 8 );	\
63
	(b)[(i) + 2] = (unsigned char) ( (n) >> 16 );	\
64
	(b)[(i) + 3] = (unsigned char) ( (n) >> 24 );	\
65
}
66
#endif
67
 
68
/*
69
 * Forward S-box & tables
70
 */
71
static unsigned char FSb[256];
72
static unsigned long FT0[256];
73
static unsigned long FT1[256];
74
static unsigned long FT2[256];
75
static unsigned long FT3[256];
76
 
77
/*
78
 * Reverse S-box & tables
79
 */
80
static unsigned char RSb[256];
81
static unsigned long RT0[256];
82
static unsigned long RT1[256];
83
static unsigned long RT2[256];
84
static unsigned long RT3[256];
85
 
86
/*
87
 * Round constants
88
 */
89
static unsigned long RCON[10];
90
 
91
/*
92
 * Tables generation code
93
 */
94
#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
95
#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
96
#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
97
 
98
static int aes_init_done = 0;
99
 
100
static void aes_gen_tables( void )
101
{
102
	int i, x, y, z;
103
	int pow[256];
104
	int log[256];
105
 
106
	/*
107
	 * compute pow and log tables over GF(2^8)
108
	 */
109
	for( i = 0, x = 1; i < 256; i++ )
110
	{
111
		pow[i] = x;
112
		log[x] = i;
113
		x = ( x ^ XTIME( x ) ) & 0xFF;
114
	}
115
 
116
	/*
117
	 * calculate the round constants
118
	 */
119
	for( i = 0, x = 1; i < 10; i++ )
120
	{
121
		RCON[i] = (unsigned long) x;
122
		x = XTIME( x ) & 0xFF;
123
	}
124
 
125
	/*
126
	 * generate the forward and reverse S-boxes
127
	 */
128
	FSb[0x00] = 0x63;
129
	RSb[0x63] = 0x00;
130
 
131
	for( i = 1; i < 256; i++ )
132
	{
133
		x = pow[255 - log[i]];
134
 
135
		y = x; y = ( (y << 1) | (y >> 7) ) & 0xFF;
136
		x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
137
		x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
138
		x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
139
		x ^= y ^ 0x63;
140
 
141
		FSb[i] = (unsigned char) x;
142
		RSb[x] = (unsigned char) i;
143
	}
144
 
145
	/*
146
	 * generate the forward and reverse tables
147
	 */
148
	for( i = 0; i < 256; i++ )
149
	{
150
		x = FSb[i];
151
		y = XTIME( x ) & 0xFF;
152
		z = ( y ^ x ) & 0xFF;
153
 
154
		FT0[i] = ( (unsigned long) y ) ^
155
		( (unsigned long) x <<	8 ) ^
156
		( (unsigned long) x << 16 ) ^
157
		( (unsigned long) z << 24 );
158
 
159
		FT1[i] = ROTL8( FT0[i] );
160
		FT2[i] = ROTL8( FT1[i] );
161
		FT3[i] = ROTL8( FT2[i] );
162
 
163
		x = RSb[i];
164
 
165
		RT0[i] = ( (unsigned long) MUL( 0x0E, x ) ) ^
166
		( (unsigned long) MUL( 0x09, x ) << 8 ) ^
167
		( (unsigned long) MUL( 0x0D, x ) << 16 ) ^
168
		( (unsigned long) MUL( 0x0B, x ) << 24 );
169
 
170
		RT1[i] = ROTL8( RT0[i] );
171
		RT2[i] = ROTL8( RT1[i] );
172
		RT3[i] = ROTL8( RT2[i] );
173
	}
174
}
175
 
176
/*
177
 * AES key schedule (encryption)
178
 */
179
void aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize )
180
{
181
	int i;
182
	unsigned long *RK;
183
 
184
#if !defined(XYSSL_AES_ROM_TABLES)
185
	if( aes_init_done == 0 )
186
	{
187
		aes_gen_tables();
188
		aes_init_done = 1;
189
	}
190
#endif
191
 
192
	switch( keysize )
193
	{
194
	case 128: ctx->nr = 10; break;
195
	case 192: ctx->nr = 12; break;
196
	case 256: ctx->nr = 14; break;
197
	default : return;
198
	}
199
 
200
#if defined(PADLOCK_ALIGN16)
201
	ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
202
#else
203
	ctx->rk = RK = ctx->buf;
204
#endif
205
 
206
	for( i = 0; i < (keysize >> 5); i++ )
207
	{
208
		GET_ULONG_LE( RK[i], key, i << 2 );
209
	}
210
 
211
	switch( ctx->nr )
212
	{
213
	case 10:
214
 
215
		for( i = 0; i < 10; i++, RK += 4 )
216
		{
217
			RK[4] = RK[0] ^ RCON[i] ^
218
				( FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
219
				( FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
220
				( FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
221
				( FSb[ ( RK[3] ) & 0xFF ] << 24 );
222
 
223
			RK[5] = RK[1] ^ RK[4];
224
			RK[6] = RK[2] ^ RK[5];
225
			RK[7] = RK[3] ^ RK[6];
226
		}
227
		break;
228
 
229
	case 12:
230
 
231
		for( i = 0; i < 8; i++, RK += 6 )
232
		{
233
			RK[6] = RK[0] ^ RCON[i] ^
234
				( FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
235
				( FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
236
				( FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
237
				( FSb[ ( RK[5] ) & 0xFF ] << 24 );
238
 
239
			RK[7] = RK[1] ^ RK[6];
240
			RK[8] = RK[2] ^ RK[7];
241
			RK[9] = RK[3] ^ RK[8];
242
			RK[10] = RK[4] ^ RK[9];
243
			RK[11] = RK[5] ^ RK[10];
244
		}
245
		break;
246
 
247
	case 14:
248
 
249
		for( i = 0; i < 7; i++, RK += 8 )
250
		{
251
			RK[8] = RK[0] ^ RCON[i] ^
252
				( FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
253
				( FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
254
				( FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
255
				( FSb[ ( RK[7] ) & 0xFF ] << 24 );
256
 
257
			RK[9] = RK[1] ^ RK[8];
258
			RK[10] = RK[2] ^ RK[9];
259
			RK[11] = RK[3] ^ RK[10];
260
 
261
			RK[12] = RK[4] ^
262
				( FSb[ ( RK[11] ) & 0xFF ] ) ^
263
				( FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
264
				( FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
265
				( FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
266
 
267
			RK[13] = RK[5] ^ RK[12];
268
			RK[14] = RK[6] ^ RK[13];
269
			RK[15] = RK[7] ^ RK[14];
270
		}
271
		break;
272
 
273
	default:
274
 
275
		break;
276
	}
277
}
278
 
279
/*
280
 * AES key schedule (decryption)
281
 */
282
void aes_setkey_dec( aes_context *ctx, const unsigned char *key, int keysize )
283
{
284
	int i, j;
285
	aes_context cty;
286
	unsigned long *RK;
287
	unsigned long *SK;
288
 
289
	switch( keysize )
290
	{
291
	case 128: ctx->nr = 10; break;
292
	case 192: ctx->nr = 12; break;
293
	case 256: ctx->nr = 14; break;
294
	default : return;
295
	}
296
 
297
#if defined(PADLOCK_ALIGN16)
298
	ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
299
#else
300
	ctx->rk = RK = ctx->buf;
301
#endif
302
 
303
	aes_setkey_enc( &cty, key, keysize );
304
	SK = cty.rk + cty.nr * 4;
305
 
306
	*RK++ = *SK++;
307
	*RK++ = *SK++;
308
	*RK++ = *SK++;
309
	*RK++ = *SK++;
310
 
311
	for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
312
	{
313
		for( j = 0; j < 4; j++, SK++ )
314
		{
315
			*RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
316
				RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
317
				RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
318
				RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
319
		}
320
	}
321
 
322
	*RK++ = *SK++;
323
	*RK++ = *SK++;
324
	*RK++ = *SK++;
325
	*RK++ = *SK++;
326
 
327
	memset( &cty, 0, sizeof( aes_context ) );
328
}
329
 
330
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)	\
331
{						\
332
	X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^	\
333
		FT1[ ( Y1 >> 8 ) & 0xFF ] ^	\
334
		FT2[ ( Y2 >> 16 ) & 0xFF ] ^	\
335
		FT3[ ( Y3 >> 24 ) & 0xFF ];	\
336
						\
337
	X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^	\
338
		FT1[ ( Y2 >> 8 ) & 0xFF ] ^	\
339
		FT2[ ( Y3 >> 16 ) & 0xFF ] ^	\
340
		FT3[ ( Y0 >> 24 ) & 0xFF ];	\
341
						\
342
	X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^	\
343
		FT1[ ( Y3 >> 8 ) & 0xFF ] ^	\
344
		FT2[ ( Y0 >> 16 ) & 0xFF ] ^	\
345
		FT3[ ( Y1 >> 24 ) & 0xFF ];	\
346
						\
347
	X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^	\
348
		FT1[ ( Y0 >> 8 ) & 0xFF ] ^	\
349
		FT2[ ( Y1 >> 16 ) & 0xFF ] ^	\
350
		FT3[ ( Y2 >> 24 ) & 0xFF ];	\
351
}
352
 
353
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)	\
354
{						\
355
	X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^	\
356
		RT1[ ( Y3 >> 8 ) & 0xFF ] ^	\
357
		RT2[ ( Y2 >> 16 ) & 0xFF ] ^	\
358
		RT3[ ( Y1 >> 24 ) & 0xFF ];	\
359
						\
360
	X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^	\
361
		RT1[ ( Y0 >> 8 ) & 0xFF ] ^	\
362
		RT2[ ( Y3 >> 16 ) & 0xFF ] ^	\
363
		RT3[ ( Y2 >> 24 ) & 0xFF ];	\
364
						\
365
	X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^	\
366
		RT1[ ( Y1 >> 8 ) & 0xFF ] ^	\
367
		RT2[ ( Y0 >> 16 ) & 0xFF ] ^	\
368
		RT3[ ( Y3 >> 24 ) & 0xFF ];	\
369
						\
370
	X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^	\
371
		RT1[ ( Y2 >> 8 ) & 0xFF ] ^	\
372
		RT2[ ( Y1 >> 16 ) & 0xFF ] ^	\
373
		RT3[ ( Y0 >> 24 ) & 0xFF ];	\
374
}
375
 
376
/*
377
 * AES-ECB block encryption/decryption
378
 */
379
void aes_crypt_ecb( aes_context *ctx,
380
	int mode,
381
	const unsigned char input[16],
382
	unsigned char output[16] )
383
{
384
	int i;
385
	unsigned long *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
386
 
387
#if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
388
	if( padlock_supports( PADLOCK_ACE ) )
389
	{
390
		if( padlock_xcryptecb( ctx, mode, input, output ) == 0 )
391
			return;
392
	}
393
#endif
394
 
395
	RK = ctx->rk;
396
 
397
	GET_ULONG_LE( X0, input, 0 ); X0 ^= *RK++;
398
	GET_ULONG_LE( X1, input, 4 ); X1 ^= *RK++;
399
	GET_ULONG_LE( X2, input, 8 ); X2 ^= *RK++;
400
	GET_ULONG_LE( X3, input, 12 ); X3 ^= *RK++;
401
 
402
	if( mode == AES_DECRYPT )
403
	{
404
		for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
405
		{
406
			AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
407
			AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
408
		}
409
 
410
		AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
411
 
412
		X0 = *RK++ ^ ( RSb[ ( Y0 ) & 0xFF ] ) ^
413
			( RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
414
			( RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
415
			( RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
416
 
417
		X1 = *RK++ ^ ( RSb[ ( Y1 ) & 0xFF ] ) ^
418
			( RSb[ ( Y0 >>8 ) & 0xFF ] << 8 ) ^
419
			( RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
420
			( RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
421
 
422
		X2 = *RK++ ^ ( RSb[ ( Y2 ) & 0xFF ] ) ^
423
			( RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
424
			( RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
425
			( RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
426
 
427
		X3 = *RK++ ^ ( RSb[ ( Y3 ) & 0xFF ] ) ^
428
			( RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
429
			( RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
430
			( RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
431
	}
432
	else /* AES_ENCRYPT */
433
	{
434
		for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
435
		{
436
			AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
437
			AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
438
		}
439
 
440
		AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
441
 
442
		X0 = *RK++ ^ ( FSb[ ( Y0 ) & 0xFF ] ) ^
443
			( FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
444
			( FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
445
			( FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
446
 
447
		X1 = *RK++ ^ ( FSb[ ( Y1 ) & 0xFF ] ) ^
448
			( FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
449
			( FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
450
			( FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
451
 
452
		X2 = *RK++ ^ ( FSb[ ( Y2 ) & 0xFF ] ) ^
453
			( FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
454
			( FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
455
			( FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
456
 
457
		X3 = *RK++ ^ ( FSb[ ( Y3 ) & 0xFF ] ) ^
458
			( FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
459
			( FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
460
			( FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
461
	}
462
 
463
	PUT_ULONG_LE( X0, output, 0 );
464
	PUT_ULONG_LE( X1, output, 4 );
465
	PUT_ULONG_LE( X2, output, 8 );
466
	PUT_ULONG_LE( X3, output, 12 );
467
}
468
 
469
/*
470
 * AES-CBC buffer encryption/decryption
471
 */
472
void aes_crypt_cbc( aes_context *ctx,
473
	int mode,
474
	int length,
475
	unsigned char iv[16],
476
	const unsigned char *input,
477
	unsigned char *output )
478
{
479
	int i;
480
	unsigned char temp[16];
481
 
482
#if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
483
	if( padlock_supports( PADLOCK_ACE ) )
484
	{
485
		if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
486
			return;
487
	}
488
#endif
489
 
490
	if( mode == AES_DECRYPT )
491
	{
492
		while( length > 0 )
493
		{
494
			memcpy( temp, input, 16 );
495
			aes_crypt_ecb( ctx, mode, input, output );
496
 
497
			for( i = 0; i < 16; i++ )
498
				output[i] = (unsigned char)( output[i] ^ iv[i] );
499
 
500
			memcpy( iv, temp, 16 );
501
 
502
			input += 16;
503
			output += 16;
504
			length -= 16;
505
		}
506
	}
507
	else
508
	{
509
		while( length > 0 )
510
		{
511
			for( i = 0; i < 16; i++ )
512
				output[i] = (unsigned char)( input[i] ^ iv[i] );
513
 
514
			aes_crypt_ecb( ctx, mode, output, output );
515
			memcpy( iv, output, 16 );
516
 
517
			input += 16;
518
			output += 16;
519
			length -= 16;
520
		}
521
	}
522
}
523
 
524
/*
525
 * AES-CFB buffer encryption/decryption
526
 */
527
void aes_crypt_cfb( aes_context *ctx,
528
	int mode,
529
	int length,
530
	int *iv_off,
531
	unsigned char iv[16],
532
	const unsigned char *input,
533
	unsigned char *output )
534
{
535
	int c, n = *iv_off;
536
 
537
	if( mode == AES_DECRYPT )
538
	{
539
		while( length-- )
540
		{
541
			if( n == 0 )
542
				aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
543
 
544
			c = *input++;
545
			*output++ = (unsigned char)( c ^ iv[n] );
546
			iv[n] = (unsigned char) c;
547
 
548
			n = (n + 1) & 0x0F;
549
		}
550
	}
551
	else
552
	{
553
		while( length-- )
554
		{
555
			if( n == 0 )
556
				aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
557
 
558
			iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
559
 
560
			n = (n + 1) & 0x0F;
561
		}
562
	}
563
 
564
	*iv_off = n;
565
}