PolarSSL v1.2.5
sha1.c
Go to the documentation of this file.
1 /*
2  * FIPS-180-1 compliant SHA-1 implementation
3  *
4  * Copyright (C) 2006-2010, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 /*
26  * The SHA-1 standard was published by NIST in 1993.
27  *
28  * http://www.itl.nist.gov/fipspubs/fip180-1.htm
29  */
30 
31 #include "polarssl/config.h"
32 
33 #if defined(POLARSSL_SHA1_C)
34 
35 #include "polarssl/sha1.h"
36 
37 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
38 #include <stdio.h>
39 #endif
40 
41 /*
42  * 32-bit integer manipulation macros (big endian)
43  */
44 #ifndef GET_UINT32_BE
45 #define GET_UINT32_BE(n,b,i) \
46 { \
47  (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
48  | ( (uint32_t) (b)[(i) + 1] << 16 ) \
49  | ( (uint32_t) (b)[(i) + 2] << 8 ) \
50  | ( (uint32_t) (b)[(i) + 3] ); \
51 }
52 #endif
53 
54 #ifndef PUT_UINT32_BE
55 #define PUT_UINT32_BE(n,b,i) \
56 { \
57  (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
58  (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
59  (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
60  (b)[(i) + 3] = (unsigned char) ( (n) ); \
61 }
62 #endif
63 
64 /*
65  * SHA-1 context setup
66  */
67 void sha1_starts( sha1_context *ctx )
68 {
69  ctx->total[0] = 0;
70  ctx->total[1] = 0;
71 
72  ctx->state[0] = 0x67452301;
73  ctx->state[1] = 0xEFCDAB89;
74  ctx->state[2] = 0x98BADCFE;
75  ctx->state[3] = 0x10325476;
76  ctx->state[4] = 0xC3D2E1F0;
77 }
78 
79 static void sha1_process( sha1_context *ctx, const unsigned char data[64] )
80 {
81  uint32_t temp, W[16], A, B, C, D, E;
82 
83  GET_UINT32_BE( W[ 0], data, 0 );
84  GET_UINT32_BE( W[ 1], data, 4 );
85  GET_UINT32_BE( W[ 2], data, 8 );
86  GET_UINT32_BE( W[ 3], data, 12 );
87  GET_UINT32_BE( W[ 4], data, 16 );
88  GET_UINT32_BE( W[ 5], data, 20 );
89  GET_UINT32_BE( W[ 6], data, 24 );
90  GET_UINT32_BE( W[ 7], data, 28 );
91  GET_UINT32_BE( W[ 8], data, 32 );
92  GET_UINT32_BE( W[ 9], data, 36 );
93  GET_UINT32_BE( W[10], data, 40 );
94  GET_UINT32_BE( W[11], data, 44 );
95  GET_UINT32_BE( W[12], data, 48 );
96  GET_UINT32_BE( W[13], data, 52 );
97  GET_UINT32_BE( W[14], data, 56 );
98  GET_UINT32_BE( W[15], data, 60 );
99 
100 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
101 
102 #define R(t) \
103 ( \
104  temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
105  W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
106  ( W[t & 0x0F] = S(temp,1) ) \
107 )
108 
109 #define P(a,b,c,d,e,x) \
110 { \
111  e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
112 }
113 
114  A = ctx->state[0];
115  B = ctx->state[1];
116  C = ctx->state[2];
117  D = ctx->state[3];
118  E = ctx->state[4];
119 
120 #define F(x,y,z) (z ^ (x & (y ^ z)))
121 #define K 0x5A827999
122 
123  P( A, B, C, D, E, W[0] );
124  P( E, A, B, C, D, W[1] );
125  P( D, E, A, B, C, W[2] );
126  P( C, D, E, A, B, W[3] );
127  P( B, C, D, E, A, W[4] );
128  P( A, B, C, D, E, W[5] );
129  P( E, A, B, C, D, W[6] );
130  P( D, E, A, B, C, W[7] );
131  P( C, D, E, A, B, W[8] );
132  P( B, C, D, E, A, W[9] );
133  P( A, B, C, D, E, W[10] );
134  P( E, A, B, C, D, W[11] );
135  P( D, E, A, B, C, W[12] );
136  P( C, D, E, A, B, W[13] );
137  P( B, C, D, E, A, W[14] );
138  P( A, B, C, D, E, W[15] );
139  P( E, A, B, C, D, R(16) );
140  P( D, E, A, B, C, R(17) );
141  P( C, D, E, A, B, R(18) );
142  P( B, C, D, E, A, R(19) );
143 
144 #undef K
145 #undef F
146 
147 #define F(x,y,z) (x ^ y ^ z)
148 #define K 0x6ED9EBA1
149 
150  P( A, B, C, D, E, R(20) );
151  P( E, A, B, C, D, R(21) );
152  P( D, E, A, B, C, R(22) );
153  P( C, D, E, A, B, R(23) );
154  P( B, C, D, E, A, R(24) );
155  P( A, B, C, D, E, R(25) );
156  P( E, A, B, C, D, R(26) );
157  P( D, E, A, B, C, R(27) );
158  P( C, D, E, A, B, R(28) );
159  P( B, C, D, E, A, R(29) );
160  P( A, B, C, D, E, R(30) );
161  P( E, A, B, C, D, R(31) );
162  P( D, E, A, B, C, R(32) );
163  P( C, D, E, A, B, R(33) );
164  P( B, C, D, E, A, R(34) );
165  P( A, B, C, D, E, R(35) );
166  P( E, A, B, C, D, R(36) );
167  P( D, E, A, B, C, R(37) );
168  P( C, D, E, A, B, R(38) );
169  P( B, C, D, E, A, R(39) );
170 
171 #undef K
172 #undef F
173 
174 #define F(x,y,z) ((x & y) | (z & (x | y)))
175 #define K 0x8F1BBCDC
176 
177  P( A, B, C, D, E, R(40) );
178  P( E, A, B, C, D, R(41) );
179  P( D, E, A, B, C, R(42) );
180  P( C, D, E, A, B, R(43) );
181  P( B, C, D, E, A, R(44) );
182  P( A, B, C, D, E, R(45) );
183  P( E, A, B, C, D, R(46) );
184  P( D, E, A, B, C, R(47) );
185  P( C, D, E, A, B, R(48) );
186  P( B, C, D, E, A, R(49) );
187  P( A, B, C, D, E, R(50) );
188  P( E, A, B, C, D, R(51) );
189  P( D, E, A, B, C, R(52) );
190  P( C, D, E, A, B, R(53) );
191  P( B, C, D, E, A, R(54) );
192  P( A, B, C, D, E, R(55) );
193  P( E, A, B, C, D, R(56) );
194  P( D, E, A, B, C, R(57) );
195  P( C, D, E, A, B, R(58) );
196  P( B, C, D, E, A, R(59) );
197 
198 #undef K
199 #undef F
200 
201 #define F(x,y,z) (x ^ y ^ z)
202 #define K 0xCA62C1D6
203 
204  P( A, B, C, D, E, R(60) );
205  P( E, A, B, C, D, R(61) );
206  P( D, E, A, B, C, R(62) );
207  P( C, D, E, A, B, R(63) );
208  P( B, C, D, E, A, R(64) );
209  P( A, B, C, D, E, R(65) );
210  P( E, A, B, C, D, R(66) );
211  P( D, E, A, B, C, R(67) );
212  P( C, D, E, A, B, R(68) );
213  P( B, C, D, E, A, R(69) );
214  P( A, B, C, D, E, R(70) );
215  P( E, A, B, C, D, R(71) );
216  P( D, E, A, B, C, R(72) );
217  P( C, D, E, A, B, R(73) );
218  P( B, C, D, E, A, R(74) );
219  P( A, B, C, D, E, R(75) );
220  P( E, A, B, C, D, R(76) );
221  P( D, E, A, B, C, R(77) );
222  P( C, D, E, A, B, R(78) );
223  P( B, C, D, E, A, R(79) );
224 
225 #undef K
226 #undef F
227 
228  ctx->state[0] += A;
229  ctx->state[1] += B;
230  ctx->state[2] += C;
231  ctx->state[3] += D;
232  ctx->state[4] += E;
233 }
234 
235 /*
236  * SHA-1 process buffer
237  */
238 void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen )
239 {
240  size_t fill;
241  uint32_t left;
242 
243  if( ilen <= 0 )
244  return;
245 
246  left = ctx->total[0] & 0x3F;
247  fill = 64 - left;
248 
249  ctx->total[0] += (uint32_t) ilen;
250  ctx->total[0] &= 0xFFFFFFFF;
251 
252  if( ctx->total[0] < (uint32_t) ilen )
253  ctx->total[1]++;
254 
255  if( left && ilen >= fill )
256  {
257  memcpy( (void *) (ctx->buffer + left),
258  (void *) input, fill );
259  sha1_process( ctx, ctx->buffer );
260  input += fill;
261  ilen -= fill;
262  left = 0;
263  }
264 
265  while( ilen >= 64 )
266  {
267  sha1_process( ctx, input );
268  input += 64;
269  ilen -= 64;
270  }
271 
272  if( ilen > 0 )
273  {
274  memcpy( (void *) (ctx->buffer + left),
275  (void *) input, ilen );
276  }
277 }
278 
279 static const unsigned char sha1_padding[64] =
280 {
281  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
282  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
284  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
285 };
286 
287 /*
288  * SHA-1 final digest
289  */
290 void sha1_finish( sha1_context *ctx, unsigned char output[20] )
291 {
292  uint32_t last, padn;
293  uint32_t high, low;
294  unsigned char msglen[8];
295 
296  high = ( ctx->total[0] >> 29 )
297  | ( ctx->total[1] << 3 );
298  low = ( ctx->total[0] << 3 );
299 
300  PUT_UINT32_BE( high, msglen, 0 );
301  PUT_UINT32_BE( low, msglen, 4 );
302 
303  last = ctx->total[0] & 0x3F;
304  padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
305 
306  sha1_update( ctx, (unsigned char *) sha1_padding, padn );
307  sha1_update( ctx, msglen, 8 );
308 
309  PUT_UINT32_BE( ctx->state[0], output, 0 );
310  PUT_UINT32_BE( ctx->state[1], output, 4 );
311  PUT_UINT32_BE( ctx->state[2], output, 8 );
312  PUT_UINT32_BE( ctx->state[3], output, 12 );
313  PUT_UINT32_BE( ctx->state[4], output, 16 );
314 }
315 
316 /*
317  * output = SHA-1( input buffer )
318  */
319 void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
320 {
321  sha1_context ctx;
322 
323  sha1_starts( &ctx );
324  sha1_update( &ctx, input, ilen );
325  sha1_finish( &ctx, output );
326 
327  memset( &ctx, 0, sizeof( sha1_context ) );
328 }
329 
330 #if defined(POLARSSL_FS_IO)
331 /*
332  * output = SHA-1( file contents )
333  */
334 int sha1_file( const char *path, unsigned char output[20] )
335 {
336  FILE *f;
337  size_t n;
338  sha1_context ctx;
339  unsigned char buf[1024];
340 
341  if( ( f = fopen( path, "rb" ) ) == NULL )
343 
344  sha1_starts( &ctx );
345 
346  while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
347  sha1_update( &ctx, buf, n );
348 
349  sha1_finish( &ctx, output );
350 
351  memset( &ctx, 0, sizeof( sha1_context ) );
352 
353  if( ferror( f ) != 0 )
354  {
355  fclose( f );
357  }
358 
359  fclose( f );
360  return( 0 );
361 }
362 #endif /* POLARSSL_FS_IO */
363 
364 /*
365  * SHA-1 HMAC context setup
366  */
367 void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, size_t keylen )
368 {
369  size_t i;
370  unsigned char sum[20];
371 
372  if( keylen > 64 )
373  {
374  sha1( key, keylen, sum );
375  keylen = 20;
376  key = sum;
377  }
378 
379  memset( ctx->ipad, 0x36, 64 );
380  memset( ctx->opad, 0x5C, 64 );
381 
382  for( i = 0; i < keylen; i++ )
383  {
384  ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
385  ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
386  }
387 
388  sha1_starts( ctx );
389  sha1_update( ctx, ctx->ipad, 64 );
390 
391  memset( sum, 0, sizeof( sum ) );
392 }
393 
394 /*
395  * SHA-1 HMAC process buffer
396  */
397 void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, size_t ilen )
398 {
399  sha1_update( ctx, input, ilen );
400 }
401 
402 /*
403  * SHA-1 HMAC final digest
404  */
405 void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
406 {
407  unsigned char tmpbuf[20];
408 
409  sha1_finish( ctx, tmpbuf );
410  sha1_starts( ctx );
411  sha1_update( ctx, ctx->opad, 64 );
412  sha1_update( ctx, tmpbuf, 20 );
413  sha1_finish( ctx, output );
414 
415  memset( tmpbuf, 0, sizeof( tmpbuf ) );
416 }
417 
418 /*
419  * SHA1 HMAC context reset
420  */
421 void sha1_hmac_reset( sha1_context *ctx )
422 {
423  sha1_starts( ctx );
424  sha1_update( ctx, ctx->ipad, 64 );
425 }
426 
427 /*
428  * output = HMAC-SHA-1( hmac key, input buffer )
429  */
430 void sha1_hmac( const unsigned char *key, size_t keylen,
431  const unsigned char *input, size_t ilen,
432  unsigned char output[20] )
433 {
434  sha1_context ctx;
435 
436  sha1_hmac_starts( &ctx, key, keylen );
437  sha1_hmac_update( &ctx, input, ilen );
438  sha1_hmac_finish( &ctx, output );
439 
440  memset( &ctx, 0, sizeof( sha1_context ) );
441 }
442 
443 #if defined(POLARSSL_SELF_TEST)
444 /*
445  * FIPS-180-1 test vectors
446  */
447 static unsigned char sha1_test_buf[3][57] =
448 {
449  { "abc" },
450  { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
451  { "" }
452 };
453 
454 static const int sha1_test_buflen[3] =
455 {
456  3, 56, 1000
457 };
458 
459 static const unsigned char sha1_test_sum[3][20] =
460 {
461  { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
462  0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
463  { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
464  0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
465  { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
466  0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
467 };
468 
469 /*
470  * RFC 2202 test vectors
471  */
472 static unsigned char sha1_hmac_test_key[7][26] =
473 {
474  { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
475  "\x0B\x0B\x0B\x0B" },
476  { "Jefe" },
477  { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
478  "\xAA\xAA\xAA\xAA" },
479  { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
480  "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
481  { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
482  "\x0C\x0C\x0C\x0C" },
483  { "" }, /* 0xAA 80 times */
484  { "" }
485 };
486 
487 static const int sha1_hmac_test_keylen[7] =
488 {
489  20, 4, 20, 25, 20, 80, 80
490 };
491 
492 static unsigned char sha1_hmac_test_buf[7][74] =
493 {
494  { "Hi There" },
495  { "what do ya want for nothing?" },
496  { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
497  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
498  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
499  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
500  "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
501  { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
502  "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
503  "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
504  "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
505  "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
506  { "Test With Truncation" },
507  { "Test Using Larger Than Block-Size Key - Hash Key First" },
508  { "Test Using Larger Than Block-Size Key and Larger"
509  " Than One Block-Size Data" }
510 };
511 
512 static const int sha1_hmac_test_buflen[7] =
513 {
514  8, 28, 50, 50, 20, 54, 73
515 };
516 
517 static const unsigned char sha1_hmac_test_sum[7][20] =
518 {
519  { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
520  0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
521  { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
522  0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
523  { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
524  0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
525  { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
526  0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
527  { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
528  0x7B, 0xE1 },
529  { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
530  0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
531  { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
532  0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
533 };
534 
535 /*
536  * Checkup routine
537  */
538 int sha1_self_test( int verbose )
539 {
540  int i, j, buflen;
541  unsigned char buf[1024];
542  unsigned char sha1sum[20];
543  sha1_context ctx;
544 
545  /*
546  * SHA-1
547  */
548  for( i = 0; i < 3; i++ )
549  {
550  if( verbose != 0 )
551  printf( " SHA-1 test #%d: ", i + 1 );
552 
553  sha1_starts( &ctx );
554 
555  if( i == 2 )
556  {
557  memset( buf, 'a', buflen = 1000 );
558 
559  for( j = 0; j < 1000; j++ )
560  sha1_update( &ctx, buf, buflen );
561  }
562  else
563  sha1_update( &ctx, sha1_test_buf[i],
564  sha1_test_buflen[i] );
565 
566  sha1_finish( &ctx, sha1sum );
567 
568  if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
569  {
570  if( verbose != 0 )
571  printf( "failed\n" );
572 
573  return( 1 );
574  }
575 
576  if( verbose != 0 )
577  printf( "passed\n" );
578  }
579 
580  if( verbose != 0 )
581  printf( "\n" );
582 
583  for( i = 0; i < 7; i++ )
584  {
585  if( verbose != 0 )
586  printf( " HMAC-SHA-1 test #%d: ", i + 1 );
587 
588  if( i == 5 || i == 6 )
589  {
590  memset( buf, '\xAA', buflen = 80 );
591  sha1_hmac_starts( &ctx, buf, buflen );
592  }
593  else
594  sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
595  sha1_hmac_test_keylen[i] );
596 
597  sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
598  sha1_hmac_test_buflen[i] );
599 
600  sha1_hmac_finish( &ctx, sha1sum );
601 
602  buflen = ( i == 4 ) ? 12 : 20;
603 
604  if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
605  {
606  if( verbose != 0 )
607  printf( "failed\n" );
608 
609  return( 1 );
610  }
611 
612  if( verbose != 0 )
613  printf( "passed\n" );
614  }
615 
616  if( verbose != 0 )
617  printf( "\n" );
618 
619  return( 0 );
620 }
621 
622 #endif
623 
624 #endif