cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ctx_sha.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib SHA Hash Routines *
4 * Copyright Peter Gutmann 1992-2005 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "context.h"
11  #include "sha.h"
12 #else
13  #include "crypt.h"
14  #include "context/context.h"
15  #include "crypt/sha.h"
16 #endif /* Compiler-specific includes */
17 
18 #define HASH_STATE_SIZE sizeof( SHA_CTX )
19 
20 /****************************************************************************
21 * *
22 * SHA Self-test Routines *
23 * *
24 ****************************************************************************/
25 
26 #ifndef CONFIG_NO_SELFTEST
27 
28 /* Test the SHA output against the test vectors given in FIPS 180-1. We skip
29  the third test since this takes several seconds to execute, which leads to
30  an unacceptable delay */
31 
32 static const struct {
33  const char FAR_BSS *data; /* Data to hash */
34  const int length; /* Length of data */
35  const BYTE digest[ SHA_DIGEST_LENGTH ]; /* Digest of data */
36  } FAR_BSS digestValues[] = {
37  { "abc", 3,
38  { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
39  0xBA, 0x3E, 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C,
40  0x9C, 0xD0, 0xD8, 0x9D } },
41  { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
42  { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
43  0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
44  0xE5, 0x46, 0x70, 0xF1 } },
45 /* { "aaaaa...", 1000000L,
46  { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4,
47  0xF6, 0x1E, 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31,
48  0x65, 0x34, 0x01, 0x6F } }, */
49  { NULL, 0, { 0 } }
50  };
51 
52 static int selfTest( void )
53  {
54  const CAPABILITY_INFO *capabilityInfo = getSHA1Capability();
55  BYTE hashState[ HASH_STATE_SIZE + 8 ];
56  int i, status;
57 
58  /* Test SHA-1 against values given in FIPS 180-1 */
59  for( i = 0; digestValues[ i ].data != NULL; i++ )
60  {
61  status = testHash( capabilityInfo, hashState, digestValues[ i ].data,
62  digestValues[ i ].length, digestValues[ i ].digest );
63  if( cryptStatusError( status ) )
64  return( status );
65  }
66 
67  return( CRYPT_OK );
68  }
69 #else
70  #define selfTest NULL
71 #endif /* !CONFIG_NO_SELFTEST */
72 
73 /****************************************************************************
74 * *
75 * Control Routines *
76 * *
77 ****************************************************************************/
78 
79 /* Return context subtype-specific information */
80 
82 static int getInfo( IN_ENUM( CAPABILITY_INFO ) const CAPABILITY_INFO_TYPE type,
84  OUT void *data,
85  IN_INT_Z const int length )
86  {
87  assert( contextInfoPtr == NULL || \
88  isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
89  assert( ( length == 0 && isWritePtr( data, sizeof( int ) ) ) || \
90  ( length > 0 && isWritePtr( data, length ) ) );
91 
93 
94  if( type == CAPABILITY_INFO_STATESIZE )
95  {
96  int *valuePtr = ( int * ) data;
97 
98  *valuePtr = HASH_STATE_SIZE;
99 
100  return( CRYPT_OK );
101  }
102 
103  return( getDefaultInfo( type, contextInfoPtr, data, length ) );
104  }
105 
106 /****************************************************************************
107 * *
108 * SHA Hash Routines *
109 * *
110 ****************************************************************************/
111 
112 /* Hash data using SHA */
113 
114 static int hash( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int noBytes )
115  {
116  SHA_CTX *shaInfo = ( SHA_CTX * ) contextInfoPtr->ctxHash->hashInfo;
117 
118  /* If the hash state was reset to allow another round of hashing,
119  reinitialise things */
120  if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_INITED ) )
121  SHA1_Init( shaInfo );
122 
123  if( noBytes > 0 )
124  {
125  SHA1_Update( shaInfo, buffer, noBytes );
126  }
127  else
128  SHA1_Final( contextInfoPtr->ctxHash->hash, shaInfo );
129 
130  return( CRYPT_OK );
131  }
132 
133 /* Internal API: Hash a single block of memory without the overhead of
134  creating an encryption context. This always uses SHA1 */
135 
137  const int outBufMaxLength, const void *inBuffer,
138  const int inLength, const HASH_STATE hashState )
139  {
140  SHA_CTX *shaInfo = ( SHA_CTX * ) hashInfo;
141 
142  assert( isWritePtr( hashInfo, sizeof( HASHINFO ) ) );
143  assert( ( hashState != HASH_STATE_END && \
144  outBuffer == NULL && outBufMaxLength == 0 ) || \
145  ( hashState == HASH_STATE_END && \
146  isWritePtr( outBuffer, outBufMaxLength ) && \
147  outBufMaxLength >= 20 ) );
148  assert( inBuffer == NULL || isReadPtr( inBuffer, inLength ) );
149 
150  if( ( hashState == HASH_STATE_END && outBufMaxLength < 20 ) || \
151  ( hashState != HASH_STATE_END && inLength <= 0 ) )
153 
154  switch( hashState )
155  {
156  case HASH_STATE_START:
157  SHA1_Init( shaInfo );
158  /* Drop through */
159 
160  case HASH_STATE_CONTINUE:
161  SHA1_Update( shaInfo, ( BYTE * ) inBuffer, inLength );
162  break;
163 
164  case HASH_STATE_END:
165  if( inBuffer != NULL )
166  SHA1_Update( shaInfo, ( BYTE * ) inBuffer, inLength );
167  SHA1_Final( outBuffer, shaInfo );
168  break;
169 
170  default:
172  }
173  }
174 
176  const void *inBuffer, const int inLength )
177  {
178  SHA_CTX shaInfo;
179 
180  assert( isWritePtr( outBuffer, outBufMaxLength ) && \
181  outBufMaxLength >= 20 );
182  assert( isReadPtr( inBuffer, inLength ) );
183 
184  if( outBufMaxLength < 20 || inLength <= 0 )
186 
187  SHA1_Init( &shaInfo );
188  SHA1_Update( &shaInfo, ( BYTE * ) inBuffer, inLength );
189  SHA1_Final( outBuffer, &shaInfo );
190  zeroise( &shaInfo, sizeof( SHA_CTX ) );
191  }
192 
193 /****************************************************************************
194 * *
195 * Capability Access Routines *
196 * *
197 ****************************************************************************/
198 
199 static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
200  CRYPT_ALGO_SHA1, bitsToBytes( 160 ), "SHA-1", 5,
201  bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ),
202  selfTest, getInfo, NULL, NULL, NULL, NULL, hash, hash
203  };
204 
206  {
207  return( &capabilityInfo );
208  }