ReactOS 0.4.17-dev-1005-g171e1de
ssh_kdf.c
Go to the documentation of this file.
1//
2// ssh_kdf.c
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6
7//
8// This module implements SSH-KDF specified in RFC 4253 Section 7.2.
9//
10
11#include "precomp.h"
12
13
14
19 _In_ PCSYMCRYPT_HASH pHashFunc,
22{
23 pExpandedKey->pHashFunc = pHashFunc;
24
25 SymCryptHashInit(pHashFunc, &pExpandedKey->hashState);
26 SymCryptHashAppend(pHashFunc, &pExpandedKey->hashState, pbKey, cbKey);
27
28 return SYMCRYPT_NO_ERROR;
29}
30
35 _In_reads_(cbHashValue) PCBYTE pbHashValue,
36 SIZE_T cbHashValue,
37 BYTE label,
38 _In_reads_(cbSessionId) PCBYTE pbSessionId,
39 SIZE_T cbSessionId,
40 _Inout_updates_(cbOutput) PBYTE pbOutput,
41 SIZE_T cbOutput)
42{
43 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
44 SYMCRYPT_HASH_STATE hashState;
45
46 PCBYTE pcbOutputSave = pbOutput;
47 PCSYMCRYPT_HASH pHashFunc = pExpandedKey->pHashFunc;
48 SIZE_T cbHashResultSize = SymCryptHashResultSize(pHashFunc);
49
50
51 while (cbOutput > 0)
52 {
53 SIZE_T cbGeneratedOutput = pbOutput - pcbOutputSave;
54
55 SymCryptHashStateCopy(pHashFunc, &pExpandedKey->hashState, &hashState);
56 SymCryptHashAppend(pHashFunc, &hashState, pbHashValue, cbHashValue); // hashState has (K || H)
57
58 // label and session ID are appended only in the first iteration
59 if (cbGeneratedOutput == 0)
60 {
61 SymCryptHashAppend(pHashFunc, &hashState, &label, 1);
62 SymCryptHashAppend(pHashFunc, &hashState, pbSessionId, cbSessionId);
63 }
64 else
65 {
66 // We break the read-once write-once rule here by appending data to a
67 // hash computation from pbOutput that was written by SymCryptHashResult()
68 // below.
69 // Modification of data in pbOutput buffer after it's written and before
70 // used again will have uncontrolled disturbances in the hash output and cannot
71 // be used to gain knowledge about the secret key.
72 SymCryptHashAppend(pHashFunc, &hashState, pcbOutputSave, cbGeneratedOutput); // hashState has (K || H || K1 .. Ki)
73 }
74
75 SymCryptHashResult(pHashFunc, &hashState, pbOutput, cbOutput);
76
77 SIZE_T bytesCopied = SYMCRYPT_MIN(cbOutput, cbHashResultSize);
78
79 pbOutput += bytesCopied;
80 cbOutput -= bytesCopied;
81 }
82
83 return scError;
84}
85
86
90 _In_ PCSYMCRYPT_HASH pHashFunc,
93 _In_reads_(cbHashValue) PCBYTE pbHashValue,
94 SIZE_T cbHashValue,
95 BYTE label,
96 _In_reads_(cbSessionId) PCBYTE pbSessionId,
97 SIZE_T cbSessionId,
98 _Out_writes_(cbOutput) PBYTE pbOutput,
99 SIZE_T cbOutput)
100{
102 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
103
104 scError = SymCryptSshKdfExpandKey(&expandedKey, pHashFunc, pbKey, cbKey);
105
106 if (scError != SYMCRYPT_NO_ERROR)
107 {
108 goto cleanup;
109 }
110
111 scError = SymCryptSshKdfDerive(&expandedKey,
112 pbHashValue, cbHashValue,
113 label,
114 pbSessionId, cbSessionId,
115 pbOutput, cbOutput);
116
117 cleanup:
118
119 SymCryptWipeKnownSize(&expandedKey, sizeof(expandedKey));
120
121 return scError;
122}
static void cleanup(void)
Definition: main.c:1335
static const WCHAR label[]
Definition: itemdlg.c:1608
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Inout_updates_(s)
Definition: no_sal2.h:182
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
BYTE * PBYTE
Definition: pedump.c:66
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSshKdfExpandKey(_Out_ PSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey, _In_ PCSYMCRYPT_HASH pHashFunc, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey)
Definition: ssh_kdf.c:17
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSshKdf(_In_ PCSYMCRYPT_HASH pHashFunc, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey, _In_reads_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, BYTE label, _In_reads_(cbSessionId) PCBYTE pbSessionId, SIZE_T cbSessionId, _Out_writes_(cbOutput) PBYTE pbOutput, SIZE_T cbOutput)
Definition: ssh_kdf.c:89
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSshKdfDerive(_In_ PCSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey, _In_reads_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, BYTE label, _In_reads_(cbSessionId) PCBYTE pbSessionId, SIZE_T cbSessionId, _Inout_updates_(cbOutput) PBYTE pbOutput, SIZE_T cbOutput)
Definition: ssh_kdf.c:33
static const BYTE pbSessionId[]
VOID SYMCRYPT_CALL SymCryptHashAppend(_In_ PCSYMCRYPT_HASH pHash, _Inout_updates_bytes_(pHash->stateSize) PVOID pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: hash.c:182
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
VOID SYMCRYPT_CALL SymCryptHashInit(_In_ PCSYMCRYPT_HASH pHash, _Out_writes_bytes_(pHash->stateSize) PVOID pState)
Definition: hash.c:173
SIZE_T SYMCRYPT_CALL SymCryptHashResultSize(_In_ PCSYMCRYPT_HASH pHash)
Definition: hash.c:132
VOID SYMCRYPT_CALL SymCryptHashStateCopy(_In_ PCSYMCRYPT_HASH pHash, _In_reads_(pHash->stateSize) PCVOID pSrc, _Out_writes_(pHash->stateSize) PVOID pDst)
Definition: hash.c:210
VOID SYMCRYPT_CALL SymCryptHashResult(_In_ PCSYMCRYPT_HASH pHash, _Inout_updates_bytes_(pHash->stateSize) PVOID pState, _Out_writes_(SYMCRYPT_MIN(cbResult, pHash->resultSize)) PBYTE pbResult, SIZE_T cbResult)
Definition: hash.c:193
SYMCRYPT_ERROR
Definition: symcrypt.h:227
#define SYMCRYPT_CALL
PCBYTE pbKey
PCBYTE SIZE_T cbKey
const SYMCRYPT_HASH * PCSYMCRYPT_HASH
#define SYMCRYPT_MIN(_a, _b)
const BYTE * PCBYTE
PCVOID pExpandedKey
ULONG_PTR SIZE_T
Definition: typedefs.h:80
unsigned char BYTE
Definition: xxhash.c:193