1 /****************************************************************************
2 * *
3 * Miscellaneous (Non-ASN.1) Read/Write Routines *
4 * Copyright Peter Gutmann 1992-2007 *
5 * *
6 ****************************************************************************/
7
8 #if defined( INC_ALL )
9 #include "crypt.h"
10 #include "bn.h"
11 #include "misc_rw.h"
12 #else
13 #include "crypt.h"
14 #include "bn/bn.h"
15 #include "enc_dec/misc_rw.h"
16 #endif /* Compiler-specific includes */
17
18 /****************************************************************************
19 * *
20 * Utility Routines *
21 * *
22 ****************************************************************************/
23
24 /* Read large integer data */
25
26 typedef enum {
27 LENGTH_NONE, /* No length type */
28 LENGTH_16U, /* Unsigned int, 16-bit length */
29 LENGTH_16U_BITS, /* Unsigned int, 16-bit length, length in bits */
30 LENGTH_32, /* Signed int, 32-bit length */
31 LENGTH_LAST /* Last possible length type */
32 } LENGTH_TYPE;
33
34 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
readInteger(INOUT STREAM * stream,OUT_BUFFER_OPT (maxLength,* integerLength)void * integer,OUT_LENGTH_BOUNDED_Z (maxLength)int * integerLength,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength,IN_ENUM (LENGTH)const LENGTH_TYPE lengthType,IN_ENUM_OPT (KEYSIZE_CHECK)const KEYSIZE_CHECK_TYPE checkType)35 static int readInteger( INOUT STREAM *stream,
36 OUT_BUFFER_OPT( maxLength, \
37 *integerLength ) void *integer,
38 OUT_LENGTH_BOUNDED_Z( maxLength ) int *integerLength,
39 IN_LENGTH_PKC const int minLength,
40 IN_LENGTH_PKC const int maxLength,
41 IN_ENUM( LENGTH ) const LENGTH_TYPE lengthType,
42 IN_ENUM_OPT( KEYSIZE_CHECK ) \
43 const KEYSIZE_CHECK_TYPE checkType )
44 {
45 int length;
46
47 assert( isWritePtr( stream, sizeof( STREAM ) ) );
48 assert( integer == NULL || isWritePtr( integer, maxLength ) );
49 assert( isWritePtr( integerLength, sizeof( int ) ) );
50
51 REQUIRES_S( minLength > 0 && minLength < maxLength && \
52 maxLength <= CRYPT_MAX_PKCSIZE );
53 REQUIRES_S( lengthType > LENGTH_NONE && lengthType < LENGTH_LAST );
54 REQUIRES_S( checkType >= KEYSIZE_CHECK_NONE && \
55 checkType < KEYSIZE_CHECK_LAST );
56
57 /* Clear return values */
58 if( integer != NULL )
59 memset( integer, 0, min( 16, maxLength ) );
60 *integerLength = 0;
61
62 /* Read the length and make sure that it's within range, with a 2-byte
63 allowance for extra zero-padding (the exact length will be checked
64 later after the padding is stripped) */
65 if( lengthType == LENGTH_16U || lengthType == LENGTH_16U_BITS )
66 length = readUint16( stream );
67 else
68 length = readUint32( stream );
69 if( cryptStatusError( length ) )
70 return( length );
71 if( lengthType == LENGTH_16U_BITS )
72 length = bitsToBytes( length );
73 if( checkType != KEYSIZE_CHECK_NONE )
74 {
75 REQUIRES( ( checkType == KEYSIZE_CHECK_ECC && \
76 minLength > bitsToBytes( 176 ) ) || \
77 ( checkType != KEYSIZE_CHECK_ECC && \
78 minLength > bitsToBytes( 256 ) ) );
79
80 /* If the length is below the minimum allowed but still looks at
81 least vaguely valid, report it as a too-short key rather than a
82 bad data error */
83 if( checkType == KEYSIZE_CHECK_ECC )
84 {
85 if( isShortECCKey( length ) )
86 return( CRYPT_ERROR_NOSECURE );
87 }
88 else
89 {
90 if( isShortPKCKey( length ) )
91 return( CRYPT_ERROR_NOSECURE );
92 }
93 }
94 if( length < minLength || length > maxLength + 2 )
95 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
96
97 /* If we're reading a signed integer then the sign bit can't be set
98 since this would produce a negative value. This differs from the
99 ASN.1 code, where the incorrect setting of the sign bit is so common
100 that we always treat integers as unsigned */
101 if( lengthType == LENGTH_32 && ( sPeek( stream ) & 0x80 ) )
102 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
103
104 /* Skip possible leading-zero padding and repeat the length check once
105 the zero-padding has been adjusted */
106 while( length > 0 && sPeek( stream ) == 0 )
107 {
108 int status;
109
110 status = sgetc( stream );
111 if( cryptStatusError( status ) )
112 return( status );
113 length--;
114 }
115 if( checkType != KEYSIZE_CHECK_NONE )
116 {
117 /* Repeat the earlier check on the adjusted value */
118 if( checkType == KEYSIZE_CHECK_ECC )
119 {
120 if( isShortECCKey( length ) )
121 return( CRYPT_ERROR_NOSECURE );
122 }
123 else
124 {
125 if( isShortPKCKey( length ) )
126 return( CRYPT_ERROR_NOSECURE );
127 }
128 }
129 if( length < minLength || length > maxLength )
130 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
131
132 /* Read the value */
133 *integerLength = length;
134 if( integer == NULL )
135 return( sSkip( stream, length, MAX_INTLENGTH_SHORT ) );
136 return( sread( stream, integer, length ) );
137 }
138
139 /****************************************************************************
140 * *
141 * Data Read Routines *
142 * *
143 ****************************************************************************/
144
145 /* Read 16- and 32-bit integer values */
146
147 RETVAL_RANGE( 0, 0xFFFF ) STDC_NONNULL_ARG( ( 1 ) ) \
readUint16(INOUT STREAM * stream)148 int readUint16( INOUT STREAM *stream )
149 {
150 BYTE buffer[ UINT16_SIZE + 8 ];
151 long value;
152 int status;
153
154 assert( isWritePtr( stream, sizeof( STREAM ) ) );
155
156 status = sread( stream, buffer, UINT16_SIZE );
157 if( cryptStatusError( status ) )
158 return( status );
159 value = ( ( long ) buffer[ 0 ] << 8 ) | buffer[ 1 ];
160 if( value < 0 || value > 0xFFFFL || value >= INT_MAX )
161 {
162 /* On 16-bit systems, INT_MAX may be less than 0xFFFFL */
163 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
164 }
165 return( value );
166 }
167
168 RETVAL_RANGE( 0, INT_MAX ) STDC_NONNULL_ARG( ( 1 ) ) \
readUint32(INOUT STREAM * stream)169 int readUint32( INOUT STREAM *stream )
170 {
171 BYTE buffer[ UINT32_SIZE + 8 ];
172 long value;
173 int status;
174
175 assert( isWritePtr( stream, sizeof( STREAM ) ) );
176
177 status = sread( stream, buffer, UINT32_SIZE );
178 if( cryptStatusError( status ) )
179 return( status );
180 if( buffer[ 0 ] & 0x80 )
181 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
182 value = ( ( long ) buffer[ 0 ] << 24 ) | \
183 ( ( long ) buffer[ 1 ] << 16 ) | \
184 ( ( long ) buffer[ 2 ] << 8 ) | \
185 buffer[ 3 ];
186 if( value < 0 || value >= MAX_INTLENGTH )
187 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
188 return( value );
189 }
190
191 /* Read 32-bit time values */
192
193 RETVAL_RANGE( 0, INT_MAX ) STDC_NONNULL_ARG( ( 1, 2 ) ) \
readUint32Time(INOUT STREAM * stream,OUT time_t * timeVal)194 int readUint32Time( INOUT STREAM *stream, OUT time_t *timeVal )
195 {
196 BYTE buffer[ UINT32_SIZE + 8 ];
197 long value;
198 int status;
199
200 assert( isWritePtr( stream, sizeof( STREAM ) ) );
201 assert( isWritePtr( timeVal, sizeof( time_t ) ) );
202
203 /* Clear return value */
204 *timeVal = 0;
205
206 status = sread( stream, buffer, UINT32_SIZE );
207 if( cryptStatusError( status ) )
208 return( status );
209 if( buffer[ 0 ] & 0x80 )
210 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
211 value = ( ( long ) buffer[ 0 ] << 24 ) | \
212 ( ( long ) buffer[ 1 ] << 16 ) | \
213 ( ( long ) buffer[ 2 ] << 8 ) | \
214 buffer[ 3 ];
215 if( value < MIN_STORED_TIME_VALUE || value >= 0x7FFFFFFFL )
216 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
217 *timeVal = ( time_t ) value;
218 return( CRYPT_OK );
219 }
220
221 #ifndef NDEBUG
222
223 /* Read 64-bit integer and time values, only used by SFTP so not needed */
224
225 RETVAL_RANGE( 0, INT_MAX ) STDC_NONNULL_ARG( ( 1 ) ) \
readUint64(INOUT STREAM * stream)226 int readUint64( INOUT STREAM *stream )
227 {
228 BYTE buffer[ ( UINT64_SIZE / 2 ) + 8 ];
229 int status;
230
231 assert( isWritePtr( stream, sizeof( STREAM ) ) );
232
233 /* This is never a 64-bit value but always an overprovisioned int/long,
234 so we verify that the top four bytes are zero and then read it as
235 a Uint32 */
236 status = sread( stream, buffer, UINT64_SIZE / 2 );
237 if( cryptStatusError( status ) )
238 return( status );
239 if( memcmp( buffer, "\x00\x00\x00\x00", UINT64_SIZE / 2 ) )
240 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
241 return( readUint32( stream ) );
242 }
243
244 RETVAL_RANGE( 0, INT_MAX ) STDC_NONNULL_ARG( ( 1, 2 ) ) \
readUint64Time(INOUT STREAM * stream,OUT time_t * timeVal)245 int readUint64Time( INOUT STREAM *stream, OUT time_t *timeVal )
246 {
247 int value, status;
248
249 assert( isWritePtr( stream, sizeof( STREAM ) ) );
250 assert( isWritePtr( timeVal, sizeof( time_t ) ) );
251
252 /* Clear return value */
253 *timeVal = 0;
254
255 status = value = readUint64( stream );
256 if( cryptStatusError( status ) )
257 return( status );
258 if( value < MIN_STORED_TIME_VALUE )
259 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
260 *timeVal = ( time_t ) value;
261 return( CRYPT_OK );
262 }
263 #endif /* NDEBUG */
264
265 /* Read a string preceded by a 32-bit length */
266
267 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
readData32(INOUT STREAM * stream,OUT_BUFFER (dataMaxLength,* dataLength)void * data,IN_LENGTH_SHORT const int dataMaxLength,OUT_LENGTH_BOUNDED_Z (dataMaxLength)int * dataLength,const BOOLEAN includeLengthField)268 static int readData32( INOUT STREAM *stream,
269 OUT_BUFFER( dataMaxLength, *dataLength ) void *data,
270 IN_LENGTH_SHORT const int dataMaxLength,
271 OUT_LENGTH_BOUNDED_Z( dataMaxLength ) int *dataLength,
272 const BOOLEAN includeLengthField )
273 {
274 BYTE *dataPtr = data;
275 const int headerSize = includeLengthField ? UINT32_SIZE : 0;
276 int length;
277
278 assert( isWritePtr( stream, sizeof( STREAM ) ) );
279 assert( isWritePtr( data, dataMaxLength ) );
280 assert( isWritePtr( dataLength, sizeof( int ) ) );
281
282 REQUIRES_S( dataMaxLength > 0 && dataMaxLength < MAX_INTLENGTH_SHORT );
283
284 /* Clear return values */
285 memset( data, 0, min( 16, dataMaxLength ) );
286 *dataLength = 0;
287
288 length = readUint32( stream );
289 if( length <= 0 )
290 {
291 /* Error or zero length. If it's zero length we don't return any
292 data */
293 return( length );
294 }
295 if( headerSize + length > dataMaxLength || length > MAX_INTLENGTH_SHORT )
296 return( sSetError( stream, CRYPT_ERROR_BADDATA ) );
297 if( includeLengthField )
298 {
299 dataPtr[ 0 ] = ( length >> 24 ) & 0xFF;
300 dataPtr[ 1 ] = ( length >> 16 ) & 0xFF;
301 dataPtr[ 2 ] = ( length >> 8 ) & 0xFF;
302 dataPtr[ 3 ] = length & 0xFF;
303 }
304 *dataLength = headerSize + length;
305 return( sread( stream, dataPtr + headerSize, length ) );
306 }
307
308 RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
readString32(INOUT STREAM * stream,OUT_BUFFER (stringMaxLength,* stringLength)void * string,IN_LENGTH_SHORT const int stringMaxLength,OUT_LENGTH_BOUNDED_Z (stringMaxLength)int * stringLength)309 int readString32( INOUT STREAM *stream,
310 OUT_BUFFER( stringMaxLength, \
311 *stringLength ) void *string,
312 IN_LENGTH_SHORT const int stringMaxLength,
313 OUT_LENGTH_BOUNDED_Z( stringMaxLength ) int *stringLength )
314 {
315 assert( isWritePtr( stream, sizeof( STREAM ) ) );
316 assert( isWritePtr( string, stringMaxLength ) );
317 assert( isWritePtr( stringLength, sizeof( int ) ) );
318
319 REQUIRES_S( stringMaxLength > 0 && stringMaxLength < MAX_INTLENGTH_SHORT );
320
321 /* Read the string, limiting the size to the maximum buffer size */
322 return( readData32( stream, string, stringMaxLength, stringLength, FALSE ) );
323 }
324
325 /* Read a raw object preceded by a 32-bit length */
326
327 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
328 int readRawObject32( INOUT STREAM *stream,
329 OUT_BUFFER( bufferMaxLength, *bufferLength ) \
330 void *buffer,
331 IN_LENGTH_SHORT_MIN( UINT32_SIZE + 1 ) \
332 const int bufferMaxLength,
333 OUT_LENGTH_BOUNDED_Z( bufferMaxLength ) \
334 int *bufferLength )
335 {
336 assert( isWritePtr( stream, sizeof( STREAM ) ) );
337 assert( isWritePtr( buffer, bufferMaxLength ) );
338 assert( isWritePtr( bufferLength, sizeof( int ) ) );
339
340 REQUIRES_S( bufferMaxLength >= UINT32_SIZE + 1 && \
341 bufferMaxLength < MAX_INTLENGTH_SHORT );
342
343 /* Read the string, limiting the size to the maximum buffer size */
344 return( readData32( stream, buffer, bufferMaxLength, bufferLength,
345 TRUE ) );
346 }
347
348 /* Read a universal type and discard it, used to skip unknown or unwanted
349 types. Since it's only used to skip short no-op fields, we limit the
350 maximum length to MAX_INTLENGTH_SHORT */
351
352 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
readUniversal(INOUT STREAM * stream,IN_ENUM (LENGTH)const LENGTH_TYPE lengthType)353 static int readUniversal( INOUT STREAM *stream,
354 IN_ENUM( LENGTH ) const LENGTH_TYPE lengthType )
355 {
356 int length, status;
357
358 assert( isWritePtr( stream, sizeof( STREAM ) ) );
359
360 REQUIRES_S( lengthType == LENGTH_16U || lengthType == LENGTH_32 );
361
362 /* Read the length and skip the data */
363 if( lengthType == LENGTH_16U )
364 status = length = readUint16( stream );
365 else
366 status = length = readUint32( stream );
367 if( cryptStatusError( status ) )
368 return( status );
369 if( length <= 0 )
370 return( CRYPT_OK ); /* Zero-length data */
371 if( length >= MAX_INTLENGTH_SHORT )
372 return( CRYPT_ERROR_BADDATA );
373 return( sSkip( stream, length, MAX_INTLENGTH_SHORT ) );
374 }
375
376 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
readUniversal16(INOUT STREAM * stream)377 int readUniversal16( INOUT STREAM *stream )
378 {
379 return( readUniversal( stream, LENGTH_16U ) );
380 }
381
382 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
readUniversal32(INOUT STREAM * stream)383 int readUniversal32( INOUT STREAM *stream )
384 {
385 return( readUniversal( stream, LENGTH_32 ) );
386 }
387
388 /* Read (large) integers in various formats */
389
390 RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
readInteger16U(INOUT STREAM * stream,OUT_BUFFER_OPT (maxLength,* integerLength)void * integer,OUT_LENGTH_BOUNDED_Z (maxLength)int * integerLength,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength)391 int readInteger16U( INOUT STREAM *stream,
392 OUT_BUFFER_OPT( maxLength, \
393 *integerLength ) void *integer,
394 OUT_LENGTH_BOUNDED_Z( maxLength ) \
395 int *integerLength,
396 IN_LENGTH_PKC const int minLength,
397 IN_LENGTH_PKC const int maxLength )
398 {
399 return( readInteger( stream, integer, integerLength, minLength,
400 maxLength, LENGTH_16U, KEYSIZE_CHECK_NONE ) );
401 }
402
403 RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
readInteger16Ubits(INOUT STREAM * stream,OUT_BUFFER_OPT (maxLength,* integerLength)void * integer,OUT_LENGTH_BOUNDED_Z (maxLength)int * integerLength,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength)404 int readInteger16Ubits( INOUT STREAM *stream,
405 OUT_BUFFER_OPT( maxLength, \
406 *integerLength ) void *integer,
407 OUT_LENGTH_BOUNDED_Z( maxLength ) \
408 int *integerLength,
409 IN_LENGTH_PKC const int minLength,
410 IN_LENGTH_PKC const int maxLength )
411 {
412 return( readInteger( stream, integer, integerLength, minLength,
413 maxLength, LENGTH_16U_BITS, KEYSIZE_CHECK_NONE ) );
414 }
415
416 RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
readInteger32(INOUT STREAM * stream,OUT_BUFFER_OPT (maxLength,* integerLength)void * integer,OUT_LENGTH_BOUNDED_Z (maxLength)int * integerLength,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength)417 int readInteger32( INOUT STREAM *stream,
418 OUT_BUFFER_OPT( maxLength, \
419 *integerLength ) void *integer,
420 OUT_LENGTH_BOUNDED_Z( maxLength ) int *integerLength,
421 IN_LENGTH_PKC const int minLength,
422 IN_LENGTH_PKC const int maxLength )
423 {
424 return( readInteger( stream, integer, integerLength, minLength,
425 maxLength, LENGTH_32, KEYSIZE_CHECK_NONE ) );
426 }
427
428 /* Special-case large integer read routines that explicitly check for a too-
429 short key and return CRYPT_ERROR_NOSECURE rather than the
430 CRYPT_ERROR_BADDATA that'd otherwise be returned */
431
432 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
readInteger16UChecked(INOUT STREAM * stream,OUT_BUFFER_OPT (maxLength,* integerLength)void * integer,OUT_LENGTH_BOUNDED_Z (maxLength)int * integerLength,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength)433 int readInteger16UChecked( INOUT STREAM *stream,
434 OUT_BUFFER_OPT( maxLength, *integerLength ) \
435 void *integer,
436 OUT_LENGTH_BOUNDED_Z( maxLength ) \
437 int *integerLength,
438 IN_LENGTH_PKC const int minLength,
439 IN_LENGTH_PKC const int maxLength )
440 {
441 return( readInteger( stream, integer, integerLength, minLength,
442 maxLength, LENGTH_16U, KEYSIZE_CHECK_PKC ) );
443 }
444
445 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
readInteger32Checked(INOUT STREAM * stream,OUT_BUFFER_OPT (maxLength,* integerLength)void * integer,OUT_LENGTH_BOUNDED_Z (maxLength)int * integerLength,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength)446 int readInteger32Checked( INOUT STREAM *stream,
447 OUT_BUFFER_OPT( maxLength, *integerLength ) \
448 void *integer,
449 OUT_LENGTH_BOUNDED_Z( maxLength ) \
450 int *integerLength,
451 IN_LENGTH_PKC const int minLength,
452 IN_LENGTH_PKC const int maxLength )
453 {
454 /* Perform the appropriate length check for the algorithm type. The
455 way that this is currently done is a bit of a nasty hack, but it
456 saves having to create a special-case ECC-only function that's only
457 used in one place */
458 if( minLength == MIN_PKCSIZE_ECCPOINT && \
459 maxLength == MAX_PKCSIZE_ECCPOINT )
460 {
461 return( readInteger( stream, integer, integerLength, minLength,
462 maxLength, LENGTH_32, KEYSIZE_CHECK_ECC ) );
463 }
464 return( readInteger( stream, integer, integerLength, minLength,
465 maxLength, LENGTH_32, KEYSIZE_CHECK_PKC ) );
466 }
467
468 #ifdef USE_PKC
469
470 /* Read integers as bignums in various formats */
471
472 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readBignumInteger(INOUT STREAM * stream,INOUT TYPECAST (BIGNUM *)void * bignum,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength,IN_OPT TYPECAST (BIGNUM *)const void * maxRange,IN_ENUM (LENGTH)const LENGTH_TYPE lengthType,IN_ENUM_OPT (KEYSIZE_CHECK)const KEYSIZE_CHECK_TYPE checkType)473 static int readBignumInteger( INOUT STREAM *stream,
474 INOUT TYPECAST( BIGNUM * ) void *bignum,
475 IN_LENGTH_PKC const int minLength,
476 IN_LENGTH_PKC const int maxLength,
477 IN_OPT TYPECAST( BIGNUM * ) const void *maxRange,
478 IN_ENUM( LENGTH ) const LENGTH_TYPE lengthType,
479 IN_ENUM_OPT( KEYSIZE_CHECK ) \
480 const KEYSIZE_CHECK_TYPE checkType )
481 {
482 BYTE buffer[ CRYPT_MAX_PKCSIZE + 8 ];
483 int length, status;
484
485 assert( isWritePtr( stream, sizeof( STREAM ) ) );
486 assert( isWritePtr( bignum, sizeof( BIGNUM ) ) );
487 assert( maxRange == NULL || isReadPtr( maxRange, sizeof( BIGNUM ) ) );
488
489 REQUIRES_S( minLength > 0 && minLength < maxLength && \
490 maxLength <= CRYPT_MAX_PKCSIZE );
491 REQUIRES_S( lengthType > LENGTH_NONE && lengthType < LENGTH_LAST );
492 REQUIRES( checkType >= KEYSIZE_CHECK_NONE && \
493 checkType < KEYSIZE_CHECK_LAST );
494
495 /* Read the integer data */
496 status = readInteger( stream, buffer, &length, minLength, maxLength,
497 lengthType, checkType );
498 if( cryptStatusError( status ) )
499 return( status );
500
501 /* Convert the value to a bignum. Note that we use the checkKEYSIZE
502 parameter for both readInteger() and importBignum(), since the
503 former merely checks the byte count while the latter actually parses
504 and processes the bignum */
505 status = importBignum( bignum, buffer, length, minLength, maxLength,
506 maxRange, checkType );
507 if( cryptStatusError( status ) )
508 status = sSetError( stream, status );
509 zeroise( buffer, CRYPT_MAX_PKCSIZE );
510 return( status );
511 }
512
513 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readBignumInteger16U(INOUT STREAM * stream,INOUT TYPECAST (BIGNUM *)void * bignum,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength,IN_OPT TYPECAST (BIGNUM *)const void * maxRange)514 int readBignumInteger16U( INOUT STREAM *stream,
515 INOUT TYPECAST( BIGNUM * ) void *bignum,
516 IN_LENGTH_PKC const int minLength,
517 IN_LENGTH_PKC const int maxLength,
518 IN_OPT TYPECAST( BIGNUM * ) const void *maxRange )
519 {
520 return( readBignumInteger( stream, bignum, minLength, maxLength,
521 maxRange, LENGTH_16U, KEYSIZE_CHECK_NONE ) );
522 }
523
524 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readBignumInteger16Ubits(INOUT STREAM * stream,INOUT TYPECAST (BIGNUM *)void * bignum,IN_LENGTH_PKC_BITS const int minBits,IN_LENGTH_PKC_BITS const int maxBits,IN_OPT TYPECAST (BIGNUM *)const void * maxRange)525 int readBignumInteger16Ubits( INOUT STREAM *stream,
526 INOUT TYPECAST( BIGNUM * ) void *bignum,
527 IN_LENGTH_PKC_BITS const int minBits,
528 IN_LENGTH_PKC_BITS const int maxBits,
529 IN_OPT TYPECAST( BIGNUM * ) const void *maxRange )
530 {
531 return( readBignumInteger( stream, bignum, bitsToBytes( minBits ),
532 bitsToBytes( maxBits ), maxRange,
533 LENGTH_16U_BITS, KEYSIZE_CHECK_NONE ) );
534 }
535
536 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readBignumInteger32(INOUT STREAM * stream,INOUT TYPECAST (BIGNUM *)void * bignum,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength,IN_OPT TYPECAST (BIGNUM *)const void * maxRange)537 int readBignumInteger32( INOUT STREAM *stream,
538 INOUT TYPECAST( BIGNUM * ) void *bignum,
539 IN_LENGTH_PKC const int minLength,
540 IN_LENGTH_PKC const int maxLength,
541 IN_OPT TYPECAST( BIGNUM * ) const void *maxRange )
542 {
543 return( readBignumInteger( stream, bignum, minLength, maxLength,
544 maxRange, LENGTH_32, KEYSIZE_CHECK_NONE ) );
545 }
546
547 /* Special-case bignum read routines that explicitly check for a too-short
548 key and return CRYPT_ERROR_NOSECURE rather than the CRYPT_ERROR_BADDATA
549 that'd otherwise be returned */
550
551 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readBignumInteger16UChecked(INOUT STREAM * stream,INOUT TYPECAST (BIGNUM *)void * bignum,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength)552 int readBignumInteger16UChecked( INOUT STREAM *stream,
553 INOUT TYPECAST( BIGNUM * ) void *bignum,
554 IN_LENGTH_PKC const int minLength,
555 IN_LENGTH_PKC const int maxLength )
556 {
557 return( readBignumInteger( stream, bignum, minLength, maxLength, NULL,
558 LENGTH_16U, KEYSIZE_CHECK_PKC ) );
559 }
560
561 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readBignumInteger16UbitsChecked(INOUT STREAM * stream,INOUT TYPECAST (BIGNUM *)void * bignum,IN_LENGTH_PKC_BITS const int minBits,IN_LENGTH_PKC_BITS const int maxBits)562 int readBignumInteger16UbitsChecked( INOUT STREAM *stream,
563 INOUT TYPECAST( BIGNUM * ) void *bignum,
564 IN_LENGTH_PKC_BITS const int minBits,
565 IN_LENGTH_PKC_BITS const int maxBits )
566 {
567 return( readBignumInteger( stream, bignum, bitsToBytes( minBits ),
568 bitsToBytes( maxBits ), NULL,
569 LENGTH_16U_BITS, KEYSIZE_CHECK_PKC ) );
570 }
571
572 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readBignumInteger32Checked(INOUT STREAM * stream,INOUT TYPECAST (BIGNUM *)void * bignum,IN_LENGTH_PKC const int minLength,IN_LENGTH_PKC const int maxLength)573 int readBignumInteger32Checked( INOUT STREAM *stream,
574 INOUT TYPECAST( BIGNUM * ) void *bignum,
575 IN_LENGTH_PKC const int minLength,
576 IN_LENGTH_PKC const int maxLength )
577 {
578 return( readBignumInteger( stream, bignum, minLength, maxLength,
579 NULL, LENGTH_32, KEYSIZE_CHECK_PKC ) );
580 }
581 #endif /* USE_PKC */
582
583 /****************************************************************************
584 * *
585 * Data Write Routines *
586 * *
587 ****************************************************************************/
588
589 /* Write 16-, 32- and 64-bit integer values */
590
591 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
592 int writeUint16( INOUT STREAM *stream,
593 IN_RANGE( 0, 0xFFFF ) const int value )
594 {
595 assert( isWritePtr( stream, sizeof( STREAM ) ) );
596
597 REQUIRES_S( value >= 0 && value <= 0xFFFFL );
598
599 sputc( stream, ( value >> 8 ) & 0xFF );
600 return( sputc( stream, value & 0xFF ) );
601 }
602
603 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
writeUint32(INOUT STREAM * stream,IN_INT_Z const long value)604 int writeUint32( INOUT STREAM *stream, IN_INT_Z const long value )
605 {
606 BYTE buffer[ UINT32_SIZE + 8 ];
607
608 assert( isWritePtr( stream, sizeof( STREAM ) ) );
609
610 REQUIRES_S( value >= 0 && value < MAX_INTLENGTH );
611
612 buffer[ 0 ] = ( value >> 24 ) & 0xFF;
613 buffer[ 1 ] = ( value >> 16 ) & 0xFF;
614 buffer[ 2 ] = ( value >> 8 ) & 0xFF;
615 buffer[ 3 ] = value & 0xFF;
616 return( swrite( stream, buffer, UINT32_SIZE ) );
617 }
618
619 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
writeUint64(INOUT STREAM * stream,IN_INT_Z const long value)620 int writeUint64( INOUT STREAM *stream, IN_INT_Z const long value )
621 {
622 assert( isWritePtr( stream, sizeof( STREAM ) ) );
623
624 REQUIRES_S( value >= 0 && value < MAX_INTLENGTH );
625
626 swrite( stream, "\x00\x00\x00\x00", UINT64_SIZE / 2 );
627 return( writeUint32( stream, value ) );
628 }
629
630 /* Write 32- and 64-bit time values */
631
632 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
writeUint32Time(INOUT STREAM * stream,const time_t timeVal)633 int writeUint32Time( INOUT STREAM *stream, const time_t timeVal )
634 {
635 REQUIRES_S( timeVal >= MIN_TIME_VALUE );
636
637 return( writeUint32( stream, ( int ) timeVal ) );
638 }
639
640 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
writeUint64Time(INOUT STREAM * stream,const time_t timeVal)641 int writeUint64Time( INOUT STREAM *stream, const time_t timeVal )
642 {
643 REQUIRES_S( timeVal >= MIN_TIME_VALUE );
644
645 return( writeUint64( stream, ( int ) timeVal ) );
646 }
647
648 /* Write a string preceded by a 32-bit length */
649
650 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
writeString32(INOUT STREAM * stream,IN_BUFFER (stringLength)const void * string,IN_LENGTH_SHORT const int stringLength)651 int writeString32( INOUT STREAM *stream,
652 IN_BUFFER( stringLength ) const void *string,
653 IN_LENGTH_SHORT const int stringLength )
654 {
655 assert( isWritePtr( stream, sizeof( STREAM ) ) );
656 assert( isReadPtr( string, stringLength ) );
657
658 REQUIRES_S( stringLength > 0 && stringLength < MAX_INTLENGTH );
659
660 writeUint32( stream, stringLength );
661 return( swrite( stream, string, stringLength ) );
662 }
663
664 /* Write large integers in various formats */
665
666 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
writeInteger(INOUT STREAM * stream,IN_BUFFER (integerLength)const void * integer,IN_LENGTH_PKC const int integerLength,IN_ENUM (LENGTH)const LENGTH_TYPE lengthType)667 static int writeInteger( INOUT STREAM *stream,
668 IN_BUFFER( integerLength ) const void *integer,
669 IN_LENGTH_PKC const int integerLength,
670 IN_ENUM( LENGTH ) const LENGTH_TYPE lengthType )
671 {
672 const BYTE *intPtr = integer;
673 int length = integerLength;
674
675 assert( isWritePtr( stream, sizeof( STREAM ) ) );
676 assert( isReadPtr( integer, integerLength ) );
677
678 REQUIRES_S( integerLength > 0 && integerLength <= CRYPT_MAX_PKCSIZE );
679 REQUIRES_S( lengthType > LENGTH_NONE && lengthType < LENGTH_LAST );
680
681 /* Integers may be passed to us from higher-level code with leading
682 zeroes as part of the encoding. Before we write them out we strip
683 out any superfluous leading zeroes that may be present */
684 while( length > 0 && *intPtr == 0 )
685 {
686 /* This is usually a problem since quietly changing the length of a
687 low-level internal value before writing it will cause problems
688 with higher-level code that doesn't expect to have the data
689 length if internal components changed */
690 assert( DEBUG_WARN );
691 intPtr++;
692 length--;
693 }
694 ENSURES( length > 0 );
695
696 switch( lengthType )
697 {
698 case LENGTH_16U:
699 writeUint16( stream, length );
700 break;
701
702 case LENGTH_16U_BITS:
703 writeUint16( stream, bytesToBits( length ) );
704 break;
705
706 case LENGTH_32:
707 {
708 const BOOLEAN leadingOneBit = *intPtr & 0x80;
709
710 writeUint32( stream, length + ( leadingOneBit ? 1 : 0 ) );
711 if( leadingOneBit )
712 sputc( stream, 0 ); /* MPIs are signed values */
713 break;
714 }
715
716 default:
717 retIntError_Stream( stream );
718 }
719 return( swrite( stream, intPtr, length ) );
720 }
721
722 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
writeInteger16U(INOUT STREAM * stream,IN_BUFFER (integerLength)const void * integer,IN_LENGTH_PKC const int integerLength)723 int writeInteger16U( INOUT STREAM *stream,
724 IN_BUFFER( integerLength ) const void *integer,
725 IN_LENGTH_PKC const int integerLength )
726 {
727 return( writeInteger( stream, integer, integerLength, LENGTH_16U ) );
728 }
729
730 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
writeInteger16Ubits(INOUT STREAM * stream,IN_BUFFER (integerLength)const void * integer,IN_LENGTH_PKC const int integerLength)731 int writeInteger16Ubits( INOUT STREAM *stream,
732 IN_BUFFER( integerLength ) const void *integer,
733 IN_LENGTH_PKC const int integerLength )
734 {
735 return( writeInteger( stream, integer, integerLength, LENGTH_16U_BITS ) );
736 }
737
738 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
writeInteger32(INOUT STREAM * stream,IN_BUFFER (integerLength)const void * integer,IN_LENGTH_PKC const int integerLength)739 int writeInteger32( INOUT STREAM *stream,
740 IN_BUFFER( integerLength ) const void *integer,
741 IN_LENGTH_PKC const int integerLength )
742 {
743 return( writeInteger( stream, integer, integerLength, LENGTH_32 ) );
744 }
745
746 #ifdef USE_PKC
747
748 /* Write integers from bignums in various formats */
749
CHECK_RETVAL_RANGE(UINT32_SIZE,MAX_INTLENGTH_SHORT)750 CHECK_RETVAL_RANGE( UINT32_SIZE, MAX_INTLENGTH_SHORT ) STDC_NONNULL_ARG( ( 1 ) ) \
751 int sizeofBignumInteger32( const void *bignum )
752 {
753 assert( isReadPtr( bignum, sizeof( BIGNUM ) ) );
754
755 return( UINT32_SIZE + BN_high_bit( ( BIGNUM * ) bignum ) + \
756 BN_num_bytes( bignum ) );
757 }
758
759 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
writeBignumInteger(INOUT STREAM * stream,TYPECAST (BIGNUM *)const void * bignum,IN_ENUM (LENGTH)const LENGTH_TYPE lengthType)760 static int writeBignumInteger( INOUT STREAM *stream,
761 TYPECAST( BIGNUM * ) const void *bignum,
762 IN_ENUM( LENGTH ) const LENGTH_TYPE lengthType )
763 {
764 BYTE buffer[ CRYPT_MAX_PKCSIZE + 8 ];
765 int bnLength, status;
766
767 assert( isWritePtr( stream, sizeof( STREAM ) ) );
768 assert( isReadPtr( bignum, sizeof( BIGNUM ) ) );
769
770 REQUIRES_S( lengthType > LENGTH_NONE && lengthType < LENGTH_LAST );
771
772 status = exportBignum( buffer, CRYPT_MAX_PKCSIZE, &bnLength, bignum );
773 ENSURES_S( cryptStatusOK( status ) );
774 if( lengthType == LENGTH_16U_BITS )
775 {
776 const int bitCount = BN_num_bits( bignum );
777
778 /* We can't call down to writeInteger() from here because we need to
779 write a precise length in bits rather than a value reconstructed
780 from the byte count. This also means that we can't easily
781 perform the leading-zero truncation that writeInteger() does
782 without a lot of low-level fiddling that duplicates code in
783 writeInteger() */
784 if( cryptStatusError( bitCount ) )
785 return( bitCount );
786 writeUint16( stream, bitCount );
787 status = swrite( stream, buffer, bnLength );
788 }
789 else
790 status = writeInteger( stream, buffer, bnLength, lengthType );
791 zeroise( buffer, CRYPT_MAX_PKCSIZE );
792 return( status );
793 }
794
795 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
writeBignumInteger16U(INOUT STREAM * stream,TYPECAST (BIGNUM *)const void * bignum)796 int writeBignumInteger16U( INOUT STREAM *stream,
797 TYPECAST( BIGNUM * ) const void *bignum )
798 {
799 return( writeBignumInteger( stream, bignum, LENGTH_16U ) );
800 }
801
802 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
writeBignumInteger16Ubits(INOUT STREAM * stream,TYPECAST (BIGNUM *)const void * bignum)803 int writeBignumInteger16Ubits( INOUT STREAM *stream,
804 TYPECAST( BIGNUM * ) const void *bignum )
805 {
806 return( writeBignumInteger( stream, bignum, LENGTH_16U_BITS ) );
807 }
808
809 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
writeBignumInteger32(INOUT STREAM * stream,TYPECAST (BIGNUM *)const void * bignum)810 int writeBignumInteger32( INOUT STREAM *stream,
811 TYPECAST( BIGNUM * ) const void *bignum )
812 {
813 return( writeBignumInteger( stream, bignum, LENGTH_32 ) );
814 }
815 #endif /* USE_PKC */
816