/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 |