Coverage Report

Created: 2024-11-21 07:03

/src/SymCrypt/lib/xtsaes_pattern.c
Line
Count
Source (jump to first uncovered line)
1
//
2
// xtsaes_pattern.c
3
//
4
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5
//
6
7
VOID
8
SYMCRYPT_CALL
9
SYMCRYPT_XtsAesXxx(
10
    _In_                                    PCSYMCRYPT_XTS_AES_EXPANDED_KEY pExpandedKey,
11
                                            SIZE_T                          cbDataUnit,
12
    _In_reads_( SYMCRYPT_AES_BLOCK_SIZE )   PCBYTE                          pbTweak,
13
    _In_reads_( cbData )                    PCBYTE                          pbSrc,
14
    _Out_writes_( cbData )                  PBYTE                           pbDst,
15
                                            SIZE_T                          cbData,
16
                                            BOOLEAN                         bOverflow )
17
0
{
18
0
    SYMCRYPT_XTS_AES_LOCALSCRATCH_DEFN;
19
    // SYMCRYPT_ALIGN BYTE localScratch[N_PARALLEL_TWEAKS * SYMCRYPT_AES_BLOCK_SIZE];
20
    // or
21
    // /* Defining localScratch as a buffer of __m128is ensures there is required 16B alignment on x86 */
22
    // __m128i localScratch[ N_PARALLEL_TWEAKS + 16 ];
23
    // Note that the extra 16 __m128i space is used for internal scratch space for SymCryptXtsAesEncryptDataUnitXmm
24
    // This allows modified tweak generation to be performed in scalar registers in parallel with AES in Xmm register
25
    // which reduces register pressure and increases throughput
26
0
    PBYTE   tweakBuf    = (PBYTE) &localScratch[0];
27
0
    SIZE_T  i, tweakBytes;
28
0
    UINT64  tweakLow64  = SYMCRYPT_LOAD_LSBFIRST64(pbTweak);
29
0
    UINT64  tweakHigh64 = SYMCRYPT_LOAD_LSBFIRST64(pbTweak+8);
30
0
    UINT64  previousTweakLow64;
31
32
0
    SYMCRYPT_ASSERT( cbData % cbDataUnit == 0 );
33
34
0
    while( cbData >= cbDataUnit )
35
0
    {
36
        //
37
        // We encrypt the tweaks of many data units in parallel for best performance.
38
        // In the first loop we build the tweaks and decrement cbData.
39
        // In the second loop we use up all the tweaks, and update the pointers.
40
        // Both loops are executed the same number of times.
41
        //
42
0
        tweakBytes = 0;
43
0
        previousTweakLow64 = tweakLow64;
44
45
0
        do // do-while because we know we are going to go through at least once.
46
0
        {
47
0
            SYMCRYPT_STORE_LSBFIRST64(&tweakBuf[tweakBytes    ], tweakLow64);
48
0
            SYMCRYPT_STORE_LSBFIRST64(&tweakBuf[tweakBytes + 8], tweakHigh64);
49
0
            tweakLow64++;
50
0
            cbData -= cbDataUnit;
51
0
            tweakBytes += SYMCRYPT_AES_BLOCK_SIZE;
52
0
        } while( cbData >= cbDataUnit && tweakBytes < SYMCRYPT_AES_BLOCK_SIZE * N_PARALLEL_TWEAKS );
53
54
0
        if( bOverflow && previousTweakLow64 > tweakLow64 )
55
0
        {
56
            // Very rare fix-up of tweaks if tweakLow64 overflowed, and should have incremented tweakHigh64
57
            // bOverflow=FALSE allows backwards compatibility with old API which wrapped around at 64-bits
58
0
            SYMCRYPT_ASSERT( tweakLow64 < N_PARALLEL_TWEAKS );
59
60
            // Increment tweakHigh64 and store new value in high half of the previous tweakLow64 tweaks
61
0
            tweakHigh64++;
62
0
            for( i=0; i<tweakLow64; i++)
63
0
            {
64
0
                SYMCRYPT_STORE_LSBFIRST64(&tweakBuf[tweakBytes - (16*i) - 8], tweakHigh64);
65
0
            }
66
0
        }
67
68
0
        SYMCRYPT_AesEcbEncryptXxx( &pExpandedKey->key2, &tweakBuf[0], &tweakBuf[0], tweakBytes );
69
70
0
        i = 0;
71
0
        while( i < tweakBytes )
72
0
        {
73
0
            SYMCRYPT_XTSAESDATAUNIT_INVOKE;
74
            // SymCryptXtsAesXxcryptDataUnitXxx( &pExpandedKey->key1, &tweakBuf[i], pbSrc, pbDst, cbDataUnit );
75
            // or
76
            // SymCryptXtsAesXxcryptDataUnitXxx( &pExpandedKey->key1, &tweakBuf[i], (PBYTE) &localScratch[N_PARALLEL_TWEAKS], pbSrc, pbDst, cbDataUnit );
77
            // Note that the scratch space being provided to the DataUnit function is an offset into the localScratch buffer
78
79
0
            pbSrc += cbDataUnit;
80
0
            pbDst += cbDataUnit;
81
0
            i += SYMCRYPT_AES_BLOCK_SIZE;
82
0
        }
83
0
    }
84
85
0
    SymCryptWipeKnownSize( localScratch, sizeof( localScratch ) );
86
0
}
Unexecuted instantiation: SymCryptXtsAesEncryptInternalC
Unexecuted instantiation: SymCryptXtsAesDecryptInternalC
Unexecuted instantiation: SymCryptXtsAesEncryptInternalAsm
Unexecuted instantiation: SymCryptXtsAesDecryptInternalAsm
Unexecuted instantiation: SymCryptXtsAesEncryptInternalXmm
Unexecuted instantiation: SymCryptXtsAesDecryptInternalXmm
Unexecuted instantiation: SymCryptXtsAesEncryptInternalYmm
Unexecuted instantiation: SymCryptXtsAesDecryptInternalYmm