ReactOS 0.4.17-dev-1005-g171e1de
sp800_108.c
Go to the documentation of this file.
1//
2// sp800_108.c
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6
7//
8// This module contains the routines to implement the SP800-108 CTR KDF function
9//
10//
11
12#include "precomp.h"
13
18 _In_reads_opt_(cbLabel) PCBYTE pbLabel,
19 SIZE_T cbLabel,
20 _In_reads_opt_(cbContext) PCBYTE pbContext,
21 SIZE_T cbContext,
22 _Out_writes_(cbResult) PBYTE pbResult,
23 SIZE_T cbResult)
24{
25 SYMCRYPT_MAC_STATE macState;
26 UINT32 iBlock;
28 SIZE_T blockSize = pExpandedKey->macAlg->resultSize;
29 SIZE_T bytesRemaining = cbResult;
30 BYTE buf[4];
32
34 blockSize <= SYMCRYPT_MAC_MAX_RESULT_SIZE &&
35 bytesRemaining > 0 );
36
37 if( cbResult > UINT32_MAX/8 )
38 {
39 // SP800-108 requires the output size in bits to be encoded in a 32-bit value.
40 // cbResults that are too large are impossible.
41 return SYMCRYPT_INVALID_ARGUMENT;
42 }
43
44 iBlock = 0;
45 while( bytesRemaining > 0 )
46 {
47 iBlock += 1;
48 pExpandedKey->macAlg->initFunc ( &macState, &pExpandedKey->macKey);
49
50 //
51 // We append the pieces into the MAC function. This is inefficient but works always.
52 // If we need more speed for large outputs, we could use a fixed-size stack buffer to build the
53 // concatenation & do a single append. This reduces the # calls in the loop, but adds one memcpy to
54 // the parameters. For small output sizes this is probably a wash.
55 //
56
57 SYMCRYPT_STORE_MSBFIRST32( &buf[0], iBlock );
58 pExpandedKey->macAlg->appendFunc( &macState, &buf[0], 4 ); // block count encoded in 4 bytes
59
60 if( cbLabel != (SIZE_T) -1 )
61 {
62 //
63 // cbLabel == -1 signals a generic input in the Context field.
64 //
65 pExpandedKey->macAlg->appendFunc( &macState, pbLabel, cbLabel ); // label
66
67 buf[0] = 0;
68 pExpandedKey->macAlg->appendFunc( &macState, &buf[0], 1 ); // zero byte
69 }
70
71 pExpandedKey->macAlg->appendFunc( &macState, pbContext, cbContext); // Context
72
73 SYMCRYPT_STORE_MSBFIRST32( &buf[0], 8 * (UINT32)cbResult );
74 pExpandedKey->macAlg->appendFunc( &macState, &buf[0], 4 ); // output length, in bits
75
76 pExpandedKey->macAlg->resultFunc( &macState, rbBlockResult );
77
78 bytes = SYMCRYPT_MIN( bytesRemaining, blockSize );
79 memcpy( pbResult, rbBlockResult, bytes );
80 pbResult += bytes;
81 bytesRemaining -= bytes;
82 }
83
84 SymCryptWipeKnownSize( rbBlockResult, sizeof( rbBlockResult ) );
85 return SYMCRYPT_NO_ERROR;
86}
87
95{
97
98 pExpandedKey->macAlg = macAlgorithm;
100}
101
108 _In_reads_opt_(cbLabel) PCBYTE pbLabel,
109 SIZE_T cbLabel,
110 _In_reads_opt_(cbContext) PCBYTE pbContext,
111 SIZE_T cbContext,
112 _Out_writes_(cbResult) PBYTE pbResult,
113 SIZE_T cbResult)
114{
116 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
117
119 if( scError != SYMCRYPT_NO_ERROR )
120 {
121 goto cleanup;
122 }
123
124 scError = SymCryptSp800_108Derive( &key, pbLabel, cbLabel, pbContext, cbContext, pbResult, cbResult );
125 if( scError != SYMCRYPT_NO_ERROR )
126 {
127 goto cleanup;
128 }
129
130cleanup:
131
132 SymCryptWipeKnownSize( &key, sizeof( key ) );
133
134 return scError;
135
136}
137
138
139//
140// Self tests are in sp800_108_*.c files
141// to avoid pulling in SHA-1 when only SP800-108-SHA256 is used and
142// similar scenarios.
143//
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
static void cleanup(void)
Definition: main.c:1335
#define UINT32_MAX
Definition: stdint.h:85
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_reads_opt_(s)
Definition: no_sal2.h:222
#define _In_
Definition: no_sal2.h:158
BYTE * PBYTE
Definition: pedump.c:66
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSp800_108(PCSYMCRYPT_MAC macAlgorithm, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey, _In_reads_opt_(cbLabel) PCBYTE pbLabel, SIZE_T cbLabel, _In_reads_opt_(cbContext) PCBYTE pbContext, SIZE_T cbContext, _Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult)
Definition: sp800_108.c:104
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSp800_108ExpandKey(_Out_ PSYMCRYPT_SP800_108_EXPANDED_KEY pExpandedKey, _In_ PCSYMCRYPT_MAC macAlgorithm, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey)
Definition: sp800_108.c:90
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSp800_108Derive(_In_ PCSYMCRYPT_SP800_108_EXPANDED_KEY pExpandedKey, _In_reads_opt_(cbLabel) PCBYTE pbLabel, SIZE_T cbLabel, _In_reads_opt_(cbContext) PCBYTE pbContext, SIZE_T cbContext, _Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult)
Definition: sp800_108.c:16
static const BYTE pbResult[]
PSYMCRYPT_MAC_EXPAND_KEY expandKeyFunc
Definition: copy.c:22
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
#define SYMCRYPT_STORE_MSBFIRST32(p, v)
Definition: symcrypt.h:311
SYMCRYPT_ERROR
Definition: symcrypt.h:227
#define SYMCRYPT_ALIGN
#define SYMCRYPT_CALL
PCBYTE pbKey
PCBYTE SIZE_T cbKey
#define SYMCRYPT_MIN(_a, _b)
const BYTE * PCBYTE
#define SYMCRYPT_MAC_MAX_RESULT_SIZE
PCSYMCRYPT_MAC macAlgorithm
PCVOID pExpandedKey
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
unsigned char BYTE
Definition: xxhash.c:193