ReactOS 0.4.17-dev-1005-g171e1de
md2.c
Go to the documentation of this file.
1//
2// Md2.c
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6//
7// This module contains the routines to implement MD2 from RFC 1319
8//
9// This is a new implementation, NOT based on the existing one in RSA32.lib,
10// which is the one from RSA data security.
11//
12// The implementation had to be refreshed anyway to conform to our coding
13// guidelines for cryptographic functions.
14// Re-implementing the function along the lines of our SHA-family implementations
15// was easy, and it removes a file with RSA copyright from our system.
16//
17// The only data copied for this implementation is the S table from the
18// RFC.
19//
20
21#include "precomp.h"
22
23//
24// See the symcrypt.h file for documentation on what the various functions do.
25//
26
33 sizeof( SYMCRYPT_MD2_STATE ),
38};
39
41
42//
43// These entries are called S[i] in RFC1319
44//
45const BYTE SymCryptMd2STable[256] = {
46 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
47 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
48 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
49 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
50 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
51 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
52 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
53 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
54 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
55 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
56 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
57 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
58 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
59 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
60 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
61 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
62 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
63 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
64};
65
66
67//
68// SymCryptMd2
69//
70#define ALG MD2
71#define Alg Md2
72#include "hash_pattern.c"
73#undef ALG
74#undef Alg
75
76
77//
78// SymCryptMd2Init
79//
80VOID
83{
84 //
85 // We use the secure wipe as the init routine is also used to re-initialize
86 // (and wipe) the state after a hash computation.
87 // In that case the compiler might conclude that this wipe can be optimized
88 // away, and that would leak data.
89 //
90 SymCryptWipeKnownSize( pState, sizeof( *pState ) );
92}
93
94
95//
96// SymCryptMd2Append
97//
98VOID
102 SIZE_T cbData )
103{
105}
106
107
108//
109// SymCryptMd2Result
110//
111VOID
115{
116 //
117 // The buffer is never completely full, so it is easy to compute the actual padding.
118 //
119 SIZE_T tmp;
120 SIZE_T paddingBytes = 16 - state->bytesInBuffer;
121
122
124
125 memset( &state->buffer[state->bytesInBuffer], (BYTE)paddingBytes, paddingBytes );
126
128
129 //
130 // Append the checksum
131 //
133
135
136 //
137 // Wipe & re-initialize
138 //
139 // (Our init code wipes the buffer too, so we don't have to.)
140 //
142}
143
144
145VOID
151 _Out_ SIZE_T * pcbRemaining )
152{
153 //
154 // For variable names see RFC 1319.
155 //
156 unsigned int t;
157 int j,k;
158
160 {
161 BYTE L;
162 //
163 // read the data once into our structure
164 //
165 memcpy( &pChain->X[16], pbData, SYMCRYPT_MD2_INPUT_BLOCK_SIZE );
166
167 //
168 // Update the checksum block.
169 // The L value at the end of the previous block is in the last byte of the checksum
170 //
171 L = pChain->C[15];
172
173 for( j=0; j<16; j++ )
174 {
175 pChain->C[j] = L = pChain->C[j] ^ SymCryptMd2STable[ L ^ pChain->X[16+j] ];
176 }
177
178 //
179 // Now we compute the actual hash
180 //
181 SymCryptXorBytes( &pChain->X[0], &pChain->X[16], &pChain->X[32], 16 );
182
183 t = 0;
184 for( j=0; j<18; j++ )
185 {
186 for( k=0; k<48; k++ )
187 {
188 t = pChain->X[k] ^ SymCryptMd2STable[t];
189 pChain->X[k] = (BYTE) t;
190 }
191 t = (t + j)& 0xff;
192 }
193
196 }
197
198 *pcbRemaining = cbData;
199}
200
201
202VOID
207{
208 SYMCRYPT_ALIGN SYMCRYPT_MD2_STATE_EXPORT_BLOB blob; // local copy to have proper alignment.
210
212
213 SymCryptWipeKnownSize( &blob, sizeof( blob ) ); // wipe to avoid any data leakage
214
215 blob.header.magic = SYMCRYPT_BLOB_MAGIC;
217 blob.header.type = SymCryptBlobTypeMd2State;
218
219 //
220 // Copy the relevant data. Buffer will be 0-padded.
221 //
222 memcpy( &blob.C[0], &pState->chain.C[0], 16 );
223 memcpy( &blob.X[0], &pState->chain.X[0], 16 );
224 blob.bytesInBuffer = (UINT32) pState->bytesInBuffer;
225 memcpy( &blob.buffer[0], &pState->buffer[0], blob.bytesInBuffer );
226
227 SYMCRYPT_ASSERT( (PCBYTE) &blob + sizeof( blob ) - sizeof( SYMCRYPT_BLOB_TRAILER ) == (PCBYTE) &blob.trailer );
228 SymCryptMarvin32( SymCryptMarvin32DefaultSeed, (PCBYTE) &blob, sizeof( blob ) - sizeof( SYMCRYPT_BLOB_TRAILER ), &blob.trailer.checksum[0] );
229
230 memcpy( pbBlob, &blob, sizeof( blob ) );
231
232//cleanup:
233 SymCryptWipeKnownSize( &blob, sizeof( blob ) );
234 return;
235}
236
242{
243 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
244 SYMCRYPT_ALIGN SYMCRYPT_MD2_STATE_EXPORT_BLOB blob; // local copy to have proper alignment.
245 BYTE checksum[8];
246
248 memcpy( &blob, pbBlob, sizeof( blob ) );
249
250 if( blob.header.magic != SYMCRYPT_BLOB_MAGIC ||
251 blob.header.size != SYMCRYPT_MD2_STATE_EXPORT_SIZE ||
252 blob.header.type != SymCryptBlobTypeMd2State )
253 {
254 scError = SYMCRYPT_INVALID_BLOB;
255 goto cleanup;
256 }
257
259 if( memcmp( checksum, &blob.trailer.checksum[0], 8 ) != 0 )
260 {
261 scError = SYMCRYPT_INVALID_BLOB;
262 goto cleanup;
263 }
264
265 memcpy( &pState->chain.C[0], &blob.C[0], 16 );
266 memcpy( &pState->chain.X[0], &blob.X[0], 16 );
267 memcpy( &pState->buffer[0], &blob.buffer[0], 16 );
268 pState->bytesInBuffer = blob.bytesInBuffer;
269
270 pState->dataLengthL = blob.bytesInBuffer;
271 pState->dataLengthH = 1;
272
274
275cleanup:
276 SymCryptWipeKnownSize( &blob, sizeof(blob) );
277 return scError;
278}
279
280
281
282
283
284
285//
286// Simple test vector for FIPS module testing
287//
288
289static const BYTE md2KATAnswer[ 16 ] = {
290 0xda, 0x85, 0x3b, 0x0d, 0x3f, 0x88, 0xd9, 0x9b,
291 0x30, 0x28, 0x3a, 0x69, 0xe6, 0xde, 0xd6, 0xbb,
292} ;
293
294VOID
297{
299
301
302 SymCryptInjectError( result, sizeof( result ) );
303
304 if( memcmp( result, md2KATAnswer, sizeof( result ) ) != 0 ) {
305 SymCryptFatal( 'MD2t' );
306 }
307}
static int state
Definition: maze.c:121
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
static void cleanup(void)
Definition: main.c:1335
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
#define L(x)
Definition: resources.c:13
static const uint32_t k[]
Definition: sha256.c:24
GLdouble GLdouble t
Definition: gl.h:2047
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define C_ASSERT(e)
Definition: intsafe.h:73
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Inout_
Definition: no_sal2.h:162
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
BYTE * PBYTE
Definition: pedump.c:66
#define SYMCRYPT_BLOB_MAGIC
Definition: sc_lib.h:1077
@ SymCryptBlobTypeMd2State
Definition: sc_lib.h:1061
VOID SYMCRYPT_CALL SymCryptInjectError(PBYTE pbData, SIZE_T cbData)
const BYTE SymCryptTestMsg3[3]
Definition: selftest.c:8
VOID SYMCRYPT_CALL SymCryptHashAppendInternal(_In_ PCSYMCRYPT_HASH pHash, _Inout_ PSYMCRYPT_COMMON_HASH_STATE pState, _In_reads_bytes_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: hash.c:10
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptMd2StateImport(_Out_ PSYMCRYPT_MD2_STATE pState, _In_reads_bytes_(SYMCRYPT_MD2_STATE_EXPORT_SIZE) PCBYTE pbBlob)
Definition: md2.c:239
const BYTE SymCryptMd2STable[256]
Definition: md2.c:45
static const BYTE md2KATAnswer[16]
Definition: md2.c:289
VOID SYMCRYPT_CALL SymCryptMd2Append(_Inout_ PSYMCRYPT_MD2_STATE pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: md2.c:100
VOID SYMCRYPT_CALL SymCryptMd2AppendBlocks(_Inout_ PSYMCRYPT_MD2_CHAINING_STATE pChain, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData, _Out_ SIZE_T *pcbRemaining)
Definition: md2.c:147
const SYMCRYPT_HASH SymCryptMd2Algorithm_default
Definition: md2.c:27
const PCSYMCRYPT_HASH SymCryptMd2Algorithm
Definition: md2.c:40
VOID SYMCRYPT_CALL SymCryptMd2Selftest(void)
Definition: md2.c:296
VOID SYMCRYPT_CALL SymCryptMd2Init(_Out_ PSYMCRYPT_MD2_STATE pState)
Definition: md2.c:82
VOID SYMCRYPT_CALL SymCryptMd2StateExport(_In_ PCSYMCRYPT_MD2_STATE pState, _Out_writes_bytes_(SYMCRYPT_MD2_STATE_EXPORT_SIZE) PBYTE pbBlob)
Definition: md2.c:204
VOID SYMCRYPT_CALL SymCryptMd2Result(_Inout_ PSYMCRYPT_MD2_STATE state, _Out_writes_(SYMCRYPT_MD2_RESULT_SIZE) PBYTE pbResult)
Definition: md2.c:113
#define memset(x, y, z)
Definition: compat.h:39
static const BYTE pbResult[]
Definition: image.c:229
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
VOID SYMCRYPT_CALL SymCryptMarvin32(_In_ PCSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData, _Out_writes_(SYMCRYPT_MARVIN32_RESULT_SIZE) PBYTE pbResult)
Definition: marvin32.c:239
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
VOID SYMCRYPT_CALL SymCryptMd2(_In_reads_(cbData) PCBYTE pbData, SIZE_T cbData, _Out_writes_(SYMCRYPT_MD2_RESULT_SIZE) PBYTE pbResult)
_Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatal(UINT32 fatalCode)
VOID SYMCRYPT_CALL SymCryptXorBytes(_In_reads_(cbBytes) PCBYTE pbSrc1, _In_reads_(cbBytes) PCBYTE pbSrc2, _Out_writes_(cbBytes) PBYTE pbResult, SIZE_T cbBytes)
Definition: libmain.c:236
VOID SYMCRYPT_CALL SymCryptMd2StateCopy(_In_ PCSYMCRYPT_MD2_STATE pSrc, _Out_ PSYMCRYPT_MD2_STATE pDst)
PCSYMCRYPT_MARVIN32_EXPANDED_SEED const SymCryptMarvin32DefaultSeed
Definition: marvin32.c:29
#define SYMCRYPT_MD2_RESULT_SIZE
Definition: symcrypt.h:891
#define SYMCRYPT_MD2_INPUT_BLOCK_SIZE
Definition: symcrypt.h:892
SYMCRYPT_ERROR
Definition: symcrypt.h:227
* PSYMCRYPT_MD2_STATE
#define SYMCRYPT_ALIGN
#define SYMCRYPT_CALL
struct _SYMCRYPT_HASH SYMCRYPT_HASH
#define SYMCRYPT_FIELD_SIZE(type, field)
#define SYMCRYPT_MD2_STATE_EXPORT_SIZE
SYMCRYPT_MD2_STATE
const SYMCRYPT_HASH * PCSYMCRYPT_HASH
PCBYTE PBYTE SIZE_T cbData
#define SYMCRYPT_SET_MAGIC(p)
#define SYMCRYPT_FIELD_OFFSET(type, field)
* PSYMCRYPT_COMMON_HASH_STATE
* PSYMCRYPT_MD2_CHAINING_STATE
const SYMCRYPT_MD2_STATE * PCSYMCRYPT_MD2_STATE
PSYMCRYPT_COMMON_HASH_STATE pState
const BYTE * PCBYTE
PCBYTE pbData
#define SYMCRYPT_CHECK_MAGIC(p)
struct sock * chain
Definition: tcpcore.h:1
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
unsigned char BYTE
Definition: xxhash.c:193