cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ctx_sha2.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib SHA2 Hash Routines *
4 * Copyright Peter Gutmann 1999-2005 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "context.h"
11  #include "sha2.h"
12 #else
13  #include "crypt.h"
14  #include "context/context.h"
15  #include "crypt/sha2.h"
16 #endif /* Compiler-specific includes */
17 
18 #ifdef USE_SHA2
19 
20 #define HASH_STATE_SIZE sizeof( sha2_ctx )
21 
22 #if defined( USE_SHA2_EXT ) && !defined( SHA512_DIGEST_SIZE )
23  #error SHA2-384/512 can only be used on a system with 64-bit data type support
24 #endif /* Extended SHA-2 variants on system without 64-bit data type */
25 
26 #ifndef SHA384_DIGEST_SIZE
27  /* These may not be defined on non 64-bit systems */
28  #define SHA384_DIGEST_SIZE 48
29  #define SHA512_DIGEST_SIZE 64
30  #define sha2_begin( size, ctx ) sha256_begin( ( ctx )->uu->ctx256 )
31  #define sha2_hash( data, len, ctx ) sha256_hash( data, len, ( ctx )->uu->ctx256 )
32  #define sha2_end( hash, ctx ) sha256_end( hash, ( ctx )->uu->ctx256 )
33 #endif /* SHA384_DIGEST_SIZE */
34 
35 /****************************************************************************
36 * *
37 * SHA2 Self-test Routines *
38 * *
39 ****************************************************************************/
40 
41 #ifndef CONFIG_NO_SELFTEST
42 
43 /* Test the SHA output against the test vectors given in FIPS 180-2. We skip
44  the third test since this takes several seconds to execute, which leads
45  to an unacceptable delay */
46 
47 static const struct {
48  const char *data; /* Data to hash */
49  const int length; /* Length of data */
50  const BYTE dig256[ SHA256_DIGEST_SIZE ]; /* Digest of data */
51  const BYTE dig384[ SHA384_DIGEST_SIZE ]; /* Digest of data */
52  const BYTE dig512[ SHA512_DIGEST_SIZE ]; /* Digest of data */
53  } FAR_BSS digestValues[] = {
54  { "abc", 3,
55  { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
56  0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
57  0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
58  0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad },
59  { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
60  0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
61  0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
62  0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
63  0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
64  0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 },
65  { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
66  0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
67  0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
68  0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
69  0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
70  0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
71  0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
72  0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
73  },
74  { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
75  { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
76  0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
77  0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
78  0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 },
79  { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39,
80  0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39,
81  0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab,
82  0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6,
83  0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f,
84  0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b },
85  { 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a,
86  0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16,
87  0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8,
88  0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35,
89  0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9,
90  0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0,
91  0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03,
92  0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 }
93  },
94 #if 0
95  { "aaaaa...", 1000000L,
96  { 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92,
97  0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67,
98  0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e,
99  0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 },
100  { 0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb,
101  0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a, 0x4a, 0x1c,
102  0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52,
103  0x79, 0x72, 0xce, 0xc5, 0x70, 0x4c, 0x2a, 0x5b,
104  0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb,
105  0xae, 0x97, 0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85 },
106  { 0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64,
107  0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63,
108  0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28,
109  0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb,
110  0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a,
111  0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b,
112  0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e,
113  0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b } }
114 #endif
115  { NULL, 0, { 0 }, { 0 }, { 0 } }
116  };
117 
118 static int selfTest( void )
119  {
120  const CAPABILITY_INFO *capabilityInfo = getSHA2Capability();
121  BYTE hashState[ HASH_STATE_SIZE + 8 ];
122  int i, status;
123 
124  /* SHA-2 requires the largest amount of context state so we check to
125  make sure that the HASHINFO is large enough. Unfortunately the
126  terminology is a bit confusing here, HASHINFO is an opaque memory
127  block used to contain the low-level hash algorithm state, HASH_INFO
128  is the high-level hash info held inside a CONTEXT_INFO */
129  assert( sizeof( HASHINFO ) >= HASH_STATE_SIZE );
130 
131  for( i = 0; digestValues[ i ].data != NULL; i++ )
132  {
133  status = testHash( capabilityInfo, hashState, digestValues[ i ].data,
134  digestValues[ i ].length, digestValues[ i ].dig256 );
135  if( cryptStatusError( status ) )
136  return( status );
137  }
138  return( CRYPT_OK );
139  }
140 #else
141  #define selfTest NULL
142 #endif /* !CONFIG_NO_SELFTEST */
143 
144 /****************************************************************************
145 * *
146 * Control Routines *
147 * *
148 ****************************************************************************/
149 
150 /* Return context subtype-specific information */
151 
153 static int getInfo( IN_ENUM( CAPABILITY_INFO ) const CAPABILITY_INFO_TYPE type,
155  OUT void *data,
156  IN_INT_Z const int length )
157  {
158  assert( contextInfoPtr == NULL || \
159  isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
160  assert( ( length == 0 && isWritePtr( data, sizeof( int ) ) ) || \
161  ( length > 0 && isWritePtr( data, length ) ) );
162 
164 
165  if( type == CAPABILITY_INFO_STATESIZE )
166  {
167  int *valuePtr = ( int * ) data;
168 
169  *valuePtr = HASH_STATE_SIZE;
170 
171  return( CRYPT_OK );
172  }
173 
174  return( getDefaultInfo( type, contextInfoPtr, data, length ) );
175  }
176 
177 /****************************************************************************
178 * *
179 * SHA Hash Routines *
180 * *
181 ****************************************************************************/
182 
183 /* Hash data using SHA */
184 
185 static int hash( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int noBytes )
186  {
187  sha2_ctx *shaInfo = ( sha2_ctx * ) contextInfoPtr->ctxHash->hashInfo;
188 
189  /* If the hash state was reset to allow another round of hashing,
190  reinitialise things */
191  if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_INITED ) )
192  sha2_begin( contextInfoPtr->capabilityInfo->blockSize, shaInfo );
193 
194  if( noBytes > 0 )
195  {
196  sha2_hash( buffer, noBytes, shaInfo );
197  }
198  else
199  {
200  sha2_end( contextInfoPtr->ctxHash->hash, shaInfo );
201  }
202 
203  return( CRYPT_OK );
204  }
205 
206 /* Internal API: Hash a single block of memory without the overhead of
207  creating an encryption context.*/
208 
209 void sha2HashBuffer( HASHINFO hashInfo, BYTE *outBuffer,
210  const int outBufMaxLength, const void *inBuffer,
211  const int inLength, const HASH_STATE hashState )
212  {
213  sha2_ctx *shaInfo = ( sha2_ctx * ) hashInfo;
214 
215  assert( sizeof( HASHINFO ) >= HASH_STATE_SIZE );
216  assert( isWritePtr( hashInfo, sizeof( HASHINFO ) ) );
217  assert( ( hashState != HASH_STATE_END && \
218  outBuffer == NULL && outBufMaxLength == 0 ) || \
219  ( hashState == HASH_STATE_END && \
220  isWritePtr( outBuffer, outBufMaxLength ) && \
221  outBufMaxLength >= 32 ) );
222  assert( inBuffer == NULL || isReadPtr( inBuffer, inLength ) );
223 
224  if( ( hashState == HASH_STATE_END && outBufMaxLength < 32 ) || \
225  ( hashState != HASH_STATE_END && inLength <= 0 ) )
227 
228  switch( hashState )
229  {
230  case HASH_STATE_START:
231  sha2_begin( SHA256_DIGEST_SIZE, shaInfo );
232  /* Drop through */
233 
234  case HASH_STATE_CONTINUE:
235  sha2_hash( ( BYTE * ) inBuffer, inLength, shaInfo );
236  break;
237 
238  case HASH_STATE_END:
239  if( inBuffer != NULL )
240  sha2_hash( ( BYTE * ) inBuffer, inLength, shaInfo );
241  sha2_end( outBuffer, shaInfo );
242  break;
243 
244  default:
246  }
247  }
248 
249 void sha2HashBufferAtomic( BYTE *outBuffer, const int outBufMaxLength,
250  const void *inBuffer, const int inLength )
251  {
252  sha2_ctx shaInfo;
253 
254  assert( isWritePtr( outBuffer, outBufMaxLength ) && \
255  outBufMaxLength >= 32 );
256  assert( isReadPtr( inBuffer, inLength ) );
257 
258  if( outBufMaxLength < 32 || inLength <= 0 )
260 
261  sha2_begin( SHA256_DIGEST_SIZE, &shaInfo );
262  sha2_hash( ( BYTE * ) inBuffer, inLength, &shaInfo );
263  sha2_end( outBuffer, &shaInfo );
264  zeroise( &shaInfo, sizeof( sha2_ctx ) );
265  }
266 
267 #ifdef USE_SHA2_EXT
268 
269 #if defined( CONFIG_SUITEB )
270  #define SHA2EXT_DIGEST_SIZE SHA384_DIGEST_SIZE
271 #else
272  #define SHA2EXT_DIGEST_SIZE SHA512_DIGEST_SIZE
273 #endif /* Suite B vs. generic use */
274 
275 void sha2_ExtHashBuffer( HASHINFO hashInfo, BYTE *outBuffer,
276  const int outBufMaxLength, const void *inBuffer,
277  const int inLength, const HASH_STATE hashState )
278  {
279  sha2_ctx *shaInfo = ( sha2_ctx * ) hashInfo;
280 
281  assert( sizeof( HASHINFO ) >= HASH_STATE_SIZE );
282  assert( isWritePtr( hashInfo, sizeof( HASHINFO ) ) );
283  assert( ( hashState != HASH_STATE_END && \
284  outBuffer == NULL && outBufMaxLength == 0 ) || \
285  ( hashState == HASH_STATE_END && \
286  isWritePtr( outBuffer, outBufMaxLength ) && \
287  outBufMaxLength >= SHA2EXT_DIGEST_SIZE ) );
288  assert( inBuffer == NULL || isReadPtr( inBuffer, inLength ) );
289 
290  if( ( hashState == HASH_STATE_END && \
291  outBufMaxLength < SHA2EXT_DIGEST_SIZE ) || \
292  ( hashState != HASH_STATE_END && inLength <= 0 ) )
294 
295  switch( hashState )
296  {
297  case HASH_STATE_START:
298  if( sha2_begin( SHA2EXT_DIGEST_SIZE, shaInfo ) != EXIT_SUCCESS )
300  /* Drop through */
301 
302  case HASH_STATE_CONTINUE:
303  sha2_hash( ( BYTE * ) inBuffer, inLength, shaInfo );
304  break;
305 
306  case HASH_STATE_END:
307  if( inBuffer != NULL )
308  sha2_hash( ( BYTE * ) inBuffer, inLength, shaInfo );
309  sha2_end( outBuffer, shaInfo );
310  break;
311 
312  default:
314  }
315  }
316 
317 void sha2_ExtHashBufferAtomic( BYTE *outBuffer, const int outBufMaxLength,
318  const void *inBuffer, const int inLength )
319  {
320  sha2_ctx shaInfo;
321 
322  assert( isWritePtr( outBuffer, outBufMaxLength ) && \
323  outBufMaxLength >= 64 );
324  assert( isReadPtr( inBuffer, inLength ) );
325 
326  if( outBufMaxLength < 64 || inLength <= 0 )
328 
329  if( sha2_begin( SHA2EXT_DIGEST_SIZE, &shaInfo ) != EXIT_SUCCESS )
330  {
331  memset( outBuffer, 0, outBufMaxLength );
333  }
334  sha2_hash( ( BYTE * ) inBuffer, inLength, &shaInfo );
335  sha2_end( outBuffer, &shaInfo );
336  zeroise( &shaInfo, sizeof( sha2_ctx ) );
337  }
338 #endif /* USE_SHA2_EXT */
339 
340 /****************************************************************************
341 * *
342 * SHA2 Key Management Routines *
343 * *
344 ****************************************************************************/
345 
346 /* Initialise algorithm parameters */
347 
349 static int initParams( INOUT CONTEXT_INFO *contextInfoPtr,
350  IN_ENUM( KEYPARAM ) const KEYPARAM_TYPE paramType,
351  IN_OPT const void *data,
352  IN_INT const int dataLength )
353  {
354  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
355 
356  REQUIRES( contextInfoPtr->type == CONTEXT_HASH );
357  REQUIRES( paramType > KEYPARAM_NONE && paramType < KEYPARAM_LAST );
358 
359  /* SHA-2 has a variable-length output, selectable by setting the
360  blocksize attribute */
361  if( paramType == KEYPARAM_BLOCKSIZE )
362  {
363 #ifdef USE_SHA2_EXT
364  #ifdef CONFIG_SUITEB
365  static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
366  CRYPT_ALGO_SHA2, bitsToBytes( 384 ), "SHA-384", 7,
367  bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ),
368  selfTest, getInfo, NULL, NULL, NULL, NULL, hash, hash
369  };
370  #else
371  static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
372  CRYPT_ALGO_SHA2, bitsToBytes( 512 ), "SHA-512", 7,
373  bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ),
374  selfTest, getInfo, NULL, NULL, NULL, NULL, hash, hash
375  };
376  #endif /* CONFIG_SUITEB */
377 #endif /* USE_SHA2_EXT */
378 
379  /* The default SHA-2 variant is SHA-256, so an attempt to set this
380  size is a no-op */
381  if( dataLength == SHA256_DIGEST_SIZE )
382  return( CRYPT_OK );
383 
384 #ifdef USE_SHA2_EXT
385  /* Switch to the appropriate variant of SHA-2. Note that the
386  initParamsFunction pointer for this version is NULL rather than
387  pointing to this function, so once the output size has been set
388  it can't be changed again */
389  #ifdef CONFIG_SUITEB
390  if( dataLength != SHA384_DIGEST_SIZE )
391  return( CRYPT_ARGERROR_NUM1 );
392  contextInfoPtr->capabilityInfo = &capabilityInfo;
393  #else
394  if( dataLength != SHA512_DIGEST_SIZE )
395  return( CRYPT_ARGERROR_NUM1 );
396  contextInfoPtr->capabilityInfo = &capabilityInfo;
397  #endif /* CONFIG_SUITEB */
398 
399  return( CRYPT_OK );
400 #else
401  return( CRYPT_ARGERROR_NUM1 );
402 #endif /* USE_SHA2_EXT */
403  }
404 
405  /* Pass the call on down to the global parameter-handling function */
406  return( initGenericParams( contextInfoPtr, paramType, data,
407  dataLength ) );
408  }
409 
410 /****************************************************************************
411 * *
412 * Capability Access Routines *
413 * *
414 ****************************************************************************/
415 
416 static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
417  CRYPT_ALGO_SHA2, bitsToBytes( 256 ), "SHA-2", 5,
418  bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ),
419  selfTest, getInfo, NULL, initParams, NULL, NULL, hash, hash
420  };
421 
422 const CAPABILITY_INFO *getSHA2Capability( void )
423  {
424  return( &capabilityInfo );
425  }
426 #endif /* USE_SHA2 */