Coverage Report

Created: 2024-11-21 07:03

/src/SymCrypt/lib/pbkdf2.c
Line
Count
Source (jump to first uncovered line)
1
//
2
// pbkdf2.c
3
//
4
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5
//
6
7
//
8
// This module contains the routines to implement the pbkdf2 function
9
//
10
//
11
12
#include "precomp.h"
13
14
SYMCRYPT_ERROR
15
SYMCRYPT_CALL
16
SymCryptPbkdf2Derive(
17
    _In_                    PCSYMCRYPT_PBKDF2_EXPANDED_KEY  pExpandedKey,
18
    _In_reads_opt_(cbSalt)  PCBYTE                          pbSalt,
19
                            SIZE_T                          cbSalt,
20
                            UINT64                          iterationCnt,
21
    _Out_writes_(cbResult)  PBYTE                           pbResult,
22
                            SIZE_T                          cbResult)
23
337
{
24
337
    SYMCRYPT_MAC_STATE  macState;
25
337
    UINT32 iBlock;
26
337
    SIZE_T bytes;
27
337
    SIZE_T blockSize = pExpandedKey->macAlg->resultSize;
28
337
    UINT64 iterations;
29
337
    SYMCRYPT_ALIGN BYTE  rbBlockResult[SYMCRYPT_MAC_MAX_RESULT_SIZE];
30
337
    SYMCRYPT_ALIGN BYTE  rbWorkBuffer[SYMCRYPT_MAC_MAX_RESULT_SIZE];
31
32
337
    SYMCRYPT_ASSERT(
33
337
        blockSize <= SYMCRYPT_MAC_MAX_RESULT_SIZE &&
34
337
        cbResult > 0 );
35
36
337
    if (iterationCnt == 0)
37
43
    {
38
43
        return SYMCRYPT_WRONG_ITERATION_COUNT;
39
43
    }
40
41
294
    iBlock = 0;
42
5.14k
    while( cbResult > 0 )
43
4.85k
    {
44
4.85k
        iBlock += 1;
45
4.85k
        SYMCRYPT_STORE_MSBFIRST32( &rbBlockResult[0], iBlock );      // use result buf as temp
46
47
4.85k
        pExpandedKey->macAlg->initFunc  ( &macState, &pExpandedKey->macKey);
48
4.85k
        pExpandedKey->macAlg->appendFunc( &macState, pbSalt, cbSalt);
49
4.85k
        pExpandedKey->macAlg->appendFunc( &macState, &rbBlockResult[0], 4 );         // block count encoded in 4 bytes
50
4.85k
        pExpandedKey->macAlg->resultFunc( &macState, rbWorkBuffer);
51
52
4.85k
#pragma warning(suppress: 22105)
53
4.85k
        memcpy( rbBlockResult, rbWorkBuffer, blockSize );
54
12.5k
        for( iterations = 1; iterations < iterationCnt; iterations++ )
55
7.65k
        {
56
7.65k
            pExpandedKey->macAlg->initFunc  ( &macState, &pExpandedKey->macKey );
57
7.65k
            pExpandedKey->macAlg->appendFunc( &macState, rbWorkBuffer, blockSize );
58
7.65k
            pExpandedKey->macAlg->resultFunc( &macState, rbWorkBuffer );
59
7.65k
            SymCryptXorBytes( &rbWorkBuffer[0], &rbBlockResult[0], &rbBlockResult[0], blockSize );
60
7.65k
        }
61
62
4.85k
        bytes = SYMCRYPT_MIN( cbResult, blockSize );
63
4.85k
        memcpy( pbResult, rbBlockResult, bytes );
64
4.85k
        pbResult += bytes;
65
4.85k
        cbResult -= bytes;
66
4.85k
    }
67
68
294
    SymCryptWipeKnownSize( &rbWorkBuffer[0], sizeof( rbWorkBuffer ) );
69
294
    SymCryptWipeKnownSize( &rbBlockResult[0], sizeof( rbBlockResult ) );
70
294
    return SYMCRYPT_NO_ERROR;
71
337
}
72
73
SYMCRYPT_ERROR
74
SYMCRYPT_CALL
75
SymCryptPbkdf2ExpandKey(
76
    _Out_               PSYMCRYPT_PBKDF2_EXPANDED_KEY   pExpandedKey,
77
    _In_                PCSYMCRYPT_MAC                  macAlgorithm,
78
    _In_reads_(cbKey)   PCBYTE                          pbKey,
79
                        SIZE_T                          cbKey )
80
337
{
81
337
    SYMCRYPT_ASSERT( macAlgorithm->expandedKeySize <= sizeof( pExpandedKey->macKey ) );
82
83
337
    pExpandedKey->macAlg = macAlgorithm;
84
337
    return macAlgorithm->expandKeyFunc(&pExpandedKey->macKey, pbKey, cbKey );
85
337
}
86
87
SYMCRYPT_ERROR
88
SYMCRYPT_CALL
89
SymCryptPbkdf2(
90
                            PCSYMCRYPT_MAC  macAlgorithm,
91
    _In_reads_(cbKey)       PCBYTE          pbKey,
92
                            SIZE_T          cbKey,
93
    _In_reads_opt_(cbSalt)  PCBYTE          pbSalt,
94
                            SIZE_T          cbSalt,
95
                            UINT64          iterationCnt,
96
    _Out_writes_(cbResult)  PBYTE           pbResult,
97
                            SIZE_T          cbResult)
98
337
{
99
337
    SYMCRYPT_PBKDF2_EXPANDED_KEY key;
100
337
    SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
101
102
337
    scError = SymCryptPbkdf2ExpandKey( &key, macAlgorithm, pbKey, cbKey );
103
337
    if( scError != SYMCRYPT_NO_ERROR )
104
0
    {
105
0
        goto cleanup;
106
0
    }
107
108
337
    scError = SymCryptPbkdf2Derive( &key, pbSalt, cbSalt, iterationCnt, pbResult, cbResult );
109
337
    if( scError != SYMCRYPT_NO_ERROR )
110
43
    {
111
43
        goto cleanup;
112
43
    }
113
114
337
cleanup:
115
116
337
    SymCryptWipeKnownSize( &key, sizeof( key ) );
117
118
337
    return scError;
119
120
337
}
121
122
//
123
// Self tests are in pbkdf_*.c files
124
// to avoid pulling in SHA-1 when only PBKDF-SHA256 is used and
125
// similar scenarios.
126
//
127