1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #define NVOC_CONF_COMPUTE_H_PRIVATE_ACCESS_ALLOWED
25 
26 #include "kernel/gpu/conf_compute/conf_compute.h"
27 #include "class/cl2080.h"
28 #include "libraries/nvport/nvport.h"
29 #include "kernel/gpu/spdm/libspdm_includes.h"
30 #include "hal/library/cryptlib.h"
31 
32 //#include "hopper/gh100/dev_se_seb.h"
33 
34 //
35 // The keystore holds keys, IV masks, and IVs for the LCE, SEC2, and GSP channels. It owns the channel
36 // counter for each key and helps prevent IV reuse. The keystore is comprised of key slots. A key
37 // slot holds either AES (key, IV mask, IV) or HMAC (key, nonce) secrets. Key slots are paired
38 // so that the even-numbered key slot typically holds the host-to-device secrets and the subsequent
39 // odd-numbered key slot typically holds the device-to-host secrets. The flow for accessing
40 // the keystore is:
41 //
42 // 1. confComputeKeyStoreInit()
43 // 2. confComputeKeyStoreGetExportMasterKey()
44 //      a. Caller copies the Export Master Key into the keystore.
45 // 4. confComputeKeyStoreDeriveKey() as needed.
46 //      a. Caller retrieves IV masks from GSP and calls confComputeKeyStoreDepositIvMask() as needed.
47 // 5. confComputeKeyStoreClearExportMasterKey() once all keys have been derived.
48 // 6. confComputeKeyStoreRetrieveVia*() as needed.
49 // 7. confComputeKeyStoreUpdateKey() as needed.
50 // 8. confComputeKeyStoreDeinit() at the end of the confidential compute session.
51 //
52 
53 #define CONCAT64(hi, low) ((((NvU64)(hi) << 32)) | ((NvU64)(low)))
54 
55 typedef struct cryptoBundle_t
56 {
57     union
58     {
59         CC_AES_CRYPTOBUNDLE  cryptBundle;
60         CC_HMAC_CRYPTOBUNDLE hmacBundle;
61     };
62     enum {NO_CHAN_COUNTER, CRYPT_COUNTER, HMAC_COUNTER} type;
63 } cryptoBundle_t;
64 
65 typedef cryptoBundle_t keySlot_t[CC_KEYSPACE_TOTAL_SIZE];
66 
67 static NV_STATUS checkSlot(ConfidentialCompute *pConfCompute, NvU32 slotNumber);
68 static void incrementChannelCounter(ConfidentialCompute *pConfCompute, NvU32 slotNumber);
69 static NvU64 getChannelCounter(ConfidentialCompute *pConfCompute, NvU32 slotNumber);
70 static NV_STATUS getKeyIdLce(KernelChannel *pKernelChannel, ROTATE_IV_TYPE rotateOperation,
71                              NvU16 *keyId);
72 static NV_STATUS getKeyIdSec2(KernelChannel *pKernelChannel, ROTATE_IV_TYPE rotateOperation,
73                               NvU16 *keyId);
74 static NV_STATUS getKeyspaceLce(KernelChannel *pKernelChannel, NvU16 *keyspace);
75 
76 NV_STATUS
77 confComputeKeyStoreInit_GH100(ConfidentialCompute *pConfCompute)
78 {
79     NvU32          index;
80     cryptoBundle_t (*pKeyStore)[];
81 
82     NV_PRINTF(LEVEL_INFO, "Initializing keystore.\n");
83 
84     pConfCompute->m_keySlot = portMemAllocNonPaged((NvLength) sizeof(keySlot_t));
85 
86     if (pConfCompute->m_keySlot == NULL)
87     {
88         return NV_ERR_NO_MEMORY;
89     }
90 
91     portMemSet(pConfCompute->m_keySlot, 0, (NvLength) sizeof(keySlot_t));
92 
93     pKeyStore = pConfCompute->m_keySlot;
94 
95     // GSP key slots don't have a channel counter.
96     for (index = 0; index < CC_KEYSPACE_GSP_SIZE; index++)
97     {
98         (*pKeyStore)[index].type = NO_CHAN_COUNTER;
99     }
100 
101     // SEC2 key slots are a mix of encryption / decryption with channel counter and HMAC.
102     ct_assert(CC_KEYSPACE_SEC2_SIZE == 4);
103 
104     (*pKeyStore)[index++].type = CRYPT_COUNTER;
105     (*pKeyStore)[index++].type = HMAC_COUNTER;
106     (*pKeyStore)[index++].type = CRYPT_COUNTER;
107     (*pKeyStore)[index++].type = HMAC_COUNTER;
108 
109     // The remaining LCE key slots are all encryption / decryption with channel counter.
110     for (; index < CC_KEYSPACE_TOTAL_SIZE; index++)
111     {
112         (*pKeyStore)[index].type = CRYPT_COUNTER;
113     }
114 
115     return NV_OK;
116 }
117 
118 void
119 confComputeKeyStoreDeinit_GH100(ConfidentialCompute *pConfCompute)
120 {
121     NV_PRINTF(LEVEL_INFO, "Deinitializing keystore.\n");
122 
123     if (pConfCompute->m_keySlot != NULL)
124     {
125         portMemSet(pConfCompute->m_keySlot, 0, (NvLength) sizeof(keySlot_t));
126         confComputeKeyStoreClearExportMasterKey_HAL(pConfCompute);
127         portMemFree(pConfCompute->m_keySlot);
128     }
129 }
130 
131 void
132 *confComputeKeyStoreGetExportMasterKey_GH100
133 (
134     ConfidentialCompute *pConfCompute
135 )
136 {
137     return pConfCompute->m_exportMasterKey;
138 }
139 
140 NV_STATUS
141 confComputeKeyStoreDeriveKey_GH100(ConfidentialCompute *pConfCompute, NvU32 globalKeyId)
142 {
143     NvU32 slotIndex;
144     cryptoBundle_t (*pKeyStore)[];
145     uint8_t *pKey = NULL;
146     size_t keySize = 0;
147 
148     pKeyStore = pConfCompute->m_keySlot;
149     NV_ASSERT_OK_OR_RETURN(confComputeGetKeySlotFromGlobalKeyId(pConfCompute, globalKeyId, &slotIndex));
150     NV_PRINTF(LEVEL_INFO, "Deriving key for global key ID %x.\n", globalKeyId);
151 
152     if ((globalKeyId == CC_GKEYID_GEN(CC_KEYSPACE_SEC2, CC_LKEYID_CPU_SEC2_HMAC_USER)) ||
153         (globalKeyId == CC_GKEYID_GEN(CC_KEYSPACE_SEC2, CC_LKEYID_CPU_SEC2_HMAC_KERN)))
154     {
155         pKey = (uint8_t *)(*pKeyStore)[slotIndex].hmacBundle.key;
156         keySize = sizeof((*pKeyStore)[slotIndex].hmacBundle.key);
157     }
158     else
159     {
160         pKey = (uint8_t *)(*pKeyStore)[slotIndex].cryptBundle.key;
161         keySize = sizeof((*pKeyStore)[slotIndex].cryptBundle.key);
162     }
163 
164     if (!libspdm_hkdf_sha256_expand(pConfCompute->m_exportMasterKey,
165                                 sizeof(pConfCompute->m_exportMasterKey),
166                                 (const uint8_t *)(CC_GKEYID_GET_STR(globalKeyId)),
167                                 (size_t)portStringLength(CC_GKEYID_GET_STR(globalKeyId)),
168                                 pKey,
169                                 keySize))
170     {
171         return NV_ERR_FATAL_ERROR;
172     }
173 
174     // LCEs will return an error / interrupt if the key is all 0s.
175     if ((CC_GKEYID_GET_KEYSPACE(globalKeyId) >= CC_KEYSPACE_LCE0) &&
176         (CC_GKEYID_GET_KEYSPACE(globalKeyId) <= CC_KEYSPACE_LCE7))
177     {
178         for (NvU32 index = 0; index < CC_AES_256_GCM_KEY_SIZE_DWORD; index++)
179         {
180             if ((*pKeyStore)[slotIndex].cryptBundle.key[index] != 0)
181             {
182                 return NV_OK;
183             }
184         }
185 
186         return NV_ERR_FATAL_ERROR;
187     }
188     return NV_OK;
189     return NV_ERR_NOT_SUPPORTED;
190 }
191 
192 void
193 confComputeKeyStoreDepositIvMask_GH100
194 (
195     ConfidentialCompute *pConfCompute,
196     NvU32                globalKeyId,
197     void                *ivMask
198 )
199 {
200     NvU32 slotNumber;
201     cryptoBundle_t (*pKeyStore)[];
202 
203     pKeyStore = pConfCompute->m_keySlot;
204     NV_ASSERT_OR_RETURN_VOID(confComputeGetKeySlotFromGlobalKeyId(pConfCompute, globalKeyId, &slotNumber) == NV_OK);
205     NV_PRINTF(LEVEL_INFO, "Depositing IV mask for global key ID %x.\n", globalKeyId);
206 
207     portMemCopy((*pKeyStore)[slotNumber].cryptBundle.ivMask,
208                 sizeof((*pKeyStore)[slotNumber].cryptBundle.ivMask),
209                 ivMask, CC_AES_256_GCM_IV_SIZE_BYTES);
210 }
211 
212 void
213 confComputeKeyStoreClearExportMasterKey_GH100(ConfidentialCompute *pConfCompute)
214 {
215     NV_PRINTF(LEVEL_INFO, "Clearing the Export Master Key.\n");
216 
217     portMemSet(pConfCompute->m_exportMasterKey, 0, (NvLength) sizeof(pConfCompute->m_exportMasterKey));
218 }
219 
220 NV_STATUS
221 confComputeKeyStoreRetrieveViaChannel_GH100
222 (
223     ConfidentialCompute *pConfCompute,
224     KernelChannel       *pKernelChannel,
225     ROTATE_IV_TYPE       rotateOperation,
226     NvBool               bIncludeIvOrNonce,
227     CC_KMB              *keyMaterialBundle
228 )
229 {
230     NvU32 globalKeyId;
231     NvU16 keyId;
232 
233     if (RM_ENGINE_TYPE_IS_COPY(kchannelGetEngineType(pKernelChannel)))
234     {
235         NvU16 keyspace;
236 
237         if (getKeyspaceLce(pKernelChannel, &keyspace) != NV_OK)
238         {
239             return NV_ERR_INVALID_PARAMETER;
240         }
241 
242         if (getKeyIdLce(pKernelChannel, rotateOperation, &keyId) != NV_OK)
243         {
244             return NV_ERR_INVALID_PARAMETER;
245         }
246 
247         globalKeyId = CC_GKEYID_GEN(keyspace, keyId);
248     }
249     else if (kchannelGetEngineType(pKernelChannel) == RM_ENGINE_TYPE_SEC2)
250     {
251         if (getKeyIdSec2(pKernelChannel, rotateOperation, &keyId) != NV_OK)
252         {
253             return NV_ERR_INVALID_PARAMETER;
254         }
255 
256         globalKeyId = CC_GKEYID_GEN(CC_KEYSPACE_SEC2, keyId);
257     }
258     else
259     {
260         return NV_ERR_INVALID_PARAMETER;
261     }
262 
263     return confComputeKeyStoreRetrieveViaKeyId_GH100(pConfCompute, globalKeyId, rotateOperation,
264                                                      bIncludeIvOrNonce, keyMaterialBundle);
265 }
266 
267 NV_STATUS
268 confComputeKeyStoreRetrieveViaKeyId_GH100
269 (
270     ConfidentialCompute *pConfCompute,
271     NvU32                globalKeyId,
272     ROTATE_IV_TYPE       rotateOperation,
273     NvBool               bIncludeIvOrNonce,
274     CC_KMB              *keyMaterialBundle
275 )
276 {
277     NvU32          slotNumber;
278     cryptoBundle_t (*pKeyStore)[];
279 
280     pKeyStore = pConfCompute->m_keySlot;
281 
282     NV_ASSERT_OK_OR_RETURN(confComputeGetKeySlotFromGlobalKeyId(pConfCompute, globalKeyId, &slotNumber));
283     NV_PRINTF(LEVEL_INFO, "Retrieving KMB from slot number = %d and type is %d.\n",
284               slotNumber, (*pKeyStore)[slotNumber].type);
285 
286     if ((slotNumber % 2) == 1)
287     {
288         slotNumber--;
289     }
290 
291     if (bIncludeIvOrNonce &&
292         ((rotateOperation == ROTATE_IV_ENCRYPT) || (rotateOperation == ROTATE_IV_ALL_VALID)))
293     {
294         if (checkSlot(pConfCompute, slotNumber) != NV_OK)
295         {
296             // Right now returns error to caller. Depending on how the re-keying flow is designed
297             // this may initiate re-keying.
298             return NV_ERR_INSUFFICIENT_RESOURCES;
299         }
300     }
301 
302     if (bIncludeIvOrNonce &&
303         ((rotateOperation == ROTATE_IV_DECRYPT) || (rotateOperation == ROTATE_IV_ALL_VALID) ||
304          (rotateOperation == ROTATE_IV_HMAC)))
305     {
306         if (checkSlot(pConfCompute, slotNumber + 1) != NV_OK)
307         {
308             // Right now returns error to caller. Depending on how the re-keying flow is designed
309             // this may initiate re-keying.
310             return NV_ERR_INSUFFICIENT_RESOURCES;
311         }
312     }
313 
314     if ((rotateOperation == ROTATE_IV_ENCRYPT) || (rotateOperation == ROTATE_IV_ALL_VALID))
315     {
316         if (bIncludeIvOrNonce)
317         {
318             incrementChannelCounter(pConfCompute, slotNumber);
319         }
320 
321         if (bIncludeIvOrNonce)
322         {
323             keyMaterialBundle->encryptBundle = (*pKeyStore)[slotNumber].cryptBundle;
324         }
325         else
326         {
327             portMemCopy(keyMaterialBundle->encryptBundle.key,
328                         sizeof(keyMaterialBundle->encryptBundle.key),
329                         (*pKeyStore)[slotNumber].cryptBundle.key,
330                         sizeof((*pKeyStore)[slotNumber].cryptBundle.key));
331             portMemCopy(keyMaterialBundle->encryptBundle.ivMask,
332                         sizeof(keyMaterialBundle->encryptBundle.ivMask),
333                         (*pKeyStore)[slotNumber].cryptBundle.ivMask,
334                         sizeof((*pKeyStore)[slotNumber].cryptBundle.ivMask));
335         }
336     }
337 
338     if ((rotateOperation == ROTATE_IV_DECRYPT) || (rotateOperation == ROTATE_IV_ALL_VALID) ||
339         (rotateOperation == ROTATE_IV_HMAC))
340     {
341         if (bIncludeIvOrNonce)
342         {
343             incrementChannelCounter(pConfCompute, slotNumber + 1);
344         }
345 
346         switch ((*pKeyStore)[slotNumber + 1].type)
347         {
348             case NO_CHAN_COUNTER:
349             case CRYPT_COUNTER:
350                 if (bIncludeIvOrNonce)
351                 {
352                     keyMaterialBundle->decryptBundle = (*pKeyStore)[slotNumber + 1].cryptBundle;
353                 }
354                 else
355                 {
356                     portMemCopy(keyMaterialBundle->encryptBundle.key,
357                                 sizeof(keyMaterialBundle->encryptBundle.key),
358                                 (*pKeyStore)[slotNumber + 1].cryptBundle.key,
359                                 sizeof((*pKeyStore)[slotNumber + 1].cryptBundle.key));
360                     portMemCopy(keyMaterialBundle->encryptBundle.ivMask,
361                                 sizeof(keyMaterialBundle->encryptBundle.ivMask),
362                                 (*pKeyStore)[slotNumber + 1].cryptBundle.ivMask,
363                                 sizeof((*pKeyStore)[slotNumber + 1].cryptBundle.ivMask));
364                 }
365                 keyMaterialBundle->bIsWorkLaunch = NV_FALSE;
366                 break;
367             case HMAC_COUNTER:
368                 if (bIncludeIvOrNonce)
369                 {
370                     keyMaterialBundle->hmacBundle = (*pKeyStore)[slotNumber + 1].hmacBundle;
371                 }
372                 else
373                 {
374                     portMemCopy(keyMaterialBundle->hmacBundle.key,
375                                 sizeof(keyMaterialBundle->hmacBundle.key),
376                                 (*pKeyStore)[slotNumber + 1].hmacBundle.key,
377                                 sizeof((*pKeyStore)[slotNumber + 1].hmacBundle.key));
378                 }
379                 keyMaterialBundle->bIsWorkLaunch = NV_TRUE;
380                 break;
381         }
382     }
383 
384     return NV_OK;
385 }
386 
387 NV_STATUS
388 confComputeKeyStoreUpdateKey_GH100(ConfidentialCompute *pConfCompute, NvU32 globalKeyId)
389 {
390     NvU32           slotIndex;
391     cryptoBundle_t (*pKeyStore)[];
392     NvU8            tempMem[CC_AES_256_GCM_KEY_SIZE_BYTES];
393     NvU8           *pKey;
394     NvU32           keySize;
395 
396     NV_ASSERT_OK_OR_RETURN(confComputeGetKeySlotFromGlobalKeyId(pConfCompute, globalKeyId, &slotIndex));
397     NV_PRINTF(LEVEL_INFO, "Updating key with global key ID %x.\n", globalKeyId);
398 
399     pKeyStore = pConfCompute->m_keySlot;
400 
401     if ((globalKeyId == CC_GKEYID_GEN(CC_KEYSPACE_SEC2, CC_LKEYID_CPU_SEC2_HMAC_USER)) ||
402         (globalKeyId == CC_GKEYID_GEN(CC_KEYSPACE_SEC2, CC_LKEYID_CPU_SEC2_HMAC_KERN)))
403     {
404         pKey = (uint8_t *)(*pKeyStore)[slotIndex].hmacBundle.key;
405         keySize = sizeof((*pKeyStore)[slotIndex].hmacBundle.key);
406     }
407     else
408     {
409         pKey = (uint8_t *)(*pKeyStore)[slotIndex].cryptBundle.key;
410         keySize = sizeof((*pKeyStore)[slotIndex].cryptBundle.key);
411     }
412 
413     if (!libspdm_sha256_hash_all((const void *)pKey, keySize, tempMem))
414     {
415         return NV_ERR_FATAL_ERROR;
416     }
417 
418     if (!libspdm_hkdf_sha256_expand(tempMem,
419                                     sizeof(tempMem),
420                                     (const uint8_t *)(CC_GKEYID_GET_STR(globalKeyId)),
421                                     (size_t)portStringLength(CC_GKEYID_GET_STR(globalKeyId)),
422                                     pKey,
423                                     keySize));
424     {
425         return NV_ERR_FATAL_ERROR;
426     }
427 
428     portMemSet(tempMem, 0, (NvLength) sizeof(tempMem));
429 
430     // LCEs will return an error / interrupt if the key is all 0s.
431     if ((CC_GKEYID_GET_KEYSPACE(globalKeyId) >= CC_KEYSPACE_LCE0) &&
432         (CC_GKEYID_GET_KEYSPACE(globalKeyId) <= CC_KEYSPACE_LCE7))
433     {
434         for (NvU32 index = 0; index < CC_AES_256_GCM_KEY_SIZE_DWORD; index++)
435         {
436             if ((*pKeyStore)[slotIndex].cryptBundle.key[index] != 0)
437             {
438                 return NV_OK;
439             }
440         }
441 
442         return NV_ERR_FATAL_ERROR;
443     }
444 
445     return NV_OK;
446 }
447 
448 /*!
449  * Get key pair from channel
450  *
451  * @param[in]   pGpu            : OBJGPU pointer
452  * @param[in]   pConfCompute    : conf comp pointer
453  * @param[in]   pKernelChannel  : KernelChannel pointer
454  * @param[out]  pH2DKey         : pointer to h2d key
455  * @param[out]  pD2HKey         : pointer to d2h key
456  */
457 NV_STATUS
458 confComputeGetKeyPairByChannel_GH100
459 (
460     OBJGPU *pGpu,
461     ConfidentialCompute *pConfCompute,
462     KernelChannel *pKernelChannel,
463     NvU32 *pH2DKey,
464     NvU32 *pD2HKey
465 )
466 {
467     NvU16 keySpace = 0;
468     NvU16 lh2dKeyId = 0;
469     NvU16 ld2hKeyId = 0;
470     RM_ENGINE_TYPE engineType = kchannelGetEngineType(pKernelChannel);
471     if (engineType == RM_ENGINE_TYPE_SEC2)
472     {
473         keySpace = CC_KEYSPACE_SEC2;
474         NV_ASSERT_OK_OR_RETURN(getKeyIdSec2(pKernelChannel, ROTATE_IV_ENCRYPT, &lh2dKeyId));
475         NV_ASSERT_OK_OR_RETURN(getKeyIdSec2(pKernelChannel, ROTATE_IV_HMAC, &ld2hKeyId));
476     }
477     else
478     {
479         NV_ASSERT_OK_OR_RETURN(getKeyspaceLce(pKernelChannel, &keySpace));
480         NV_ASSERT_OK_OR_RETURN(getKeyIdLce(pKernelChannel, ROTATE_IV_ENCRYPT, &lh2dKeyId));
481         NV_ASSERT_OK_OR_RETURN(getKeyIdLce(pKernelChannel, ROTATE_IV_DECRYPT, &ld2hKeyId));
482     }
483 
484     if (pH2DKey != NULL)
485     {
486         *pH2DKey = CC_GKEYID_GEN(keySpace, lh2dKeyId);
487     }
488     if (pD2HKey != NULL)
489     {
490         *pD2HKey = CC_GKEYID_GEN(keySpace, ld2hKeyId);
491     }
492     return NV_OK;
493 }
494 
495 //
496 // Return the key ID for a given LCE channel and rotation operation.
497 // If rotateOperation is ROTATE_IV_ALL_VALID then it will return the least
498 // key ID of the key pair; ie the one that corresponds to an even numbered slot.
499 //
500 static NV_STATUS
501 getKeyIdLce
502 (
503     KernelChannel  *pKernelChannel,
504     ROTATE_IV_TYPE  rotateOperation,
505     NvU16          *keyId
506 )
507 {
508     if (kchannelCheckIsUserMode(pKernelChannel))
509     {
510         if ((rotateOperation == ROTATE_IV_ENCRYPT) || (rotateOperation == ROTATE_IV_ALL_VALID))
511         {
512             *keyId = CC_LKEYID_LCE_H2D_USER;
513         }
514         else
515         {
516             *keyId = CC_LKEYID_LCE_D2H_USER;
517         }
518 
519         return NV_OK;
520     }
521     else if (kchannelCheckIsKernel(pKernelChannel))
522     {
523         if ((rotateOperation == ROTATE_IV_ENCRYPT) || (rotateOperation == ROTATE_IV_ALL_VALID))
524         {
525             *keyId = CC_LKEYID_LCE_H2D_KERN;
526         }
527         else
528         {
529             *keyId = CC_LKEYID_LCE_D2H_KERN;
530         }
531 
532         return NV_OK;
533     }
534 
535     return NV_ERR_GENERIC;
536 }
537 
538 //
539 // Return the key ID for a given SEC2 channel and rotation operation.
540 // If rotateOperation is ROTATE_IV_ALL_VALID then it will return the least
541 // key ID of the key pair; ie the one that corresponds to an even numbered slot.
542 //
543 static NV_STATUS
544 getKeyIdSec2
545 (
546     KernelChannel  *pKernelChannel,
547     ROTATE_IV_TYPE  rotateOperation,
548     NvU16          *keyId
549 )
550 {
551     if (kchannelCheckIsUserMode(pKernelChannel))
552     {
553         if ((rotateOperation == ROTATE_IV_ENCRYPT) || (rotateOperation == ROTATE_IV_ALL_VALID))
554         {
555             *keyId = CC_LKEYID_CPU_SEC2_DATA_USER;
556         }
557         else
558         {
559             *keyId = CC_LKEYID_CPU_SEC2_HMAC_USER;
560         }
561 
562         return NV_OK;
563     }
564     else if (kchannelCheckIsKernel(pKernelChannel))
565     {
566         if ((rotateOperation == ROTATE_IV_ENCRYPT) || (rotateOperation == ROTATE_IV_ALL_VALID))
567         {
568             *keyId = CC_LKEYID_CPU_SEC2_DATA_KERN;
569         }
570         else
571         {
572             *keyId = CC_LKEYID_CPU_SEC2_HMAC_KERN;
573         }
574 
575         return NV_OK;
576     }
577 
578     return NV_ERR_GENERIC;
579 }
580 
581 static NV_STATUS
582 getKeyspaceLce
583 (
584     KernelChannel *pKernelChannel,
585     NvU16         *keyspace
586 )
587 {
588     // The actual copy engine (2 through 9) is normalized to start at 0.
589     switch (kchannelGetEngineType(pKernelChannel))
590     {
591         case RM_ENGINE_TYPE_COPY2:
592             *keyspace = CC_KEYSPACE_LCE0;
593             break;
594         case RM_ENGINE_TYPE_COPY3:
595             *keyspace = CC_KEYSPACE_LCE1;
596             break;
597         case RM_ENGINE_TYPE_COPY4:
598             *keyspace = CC_KEYSPACE_LCE2;
599             break;
600         case RM_ENGINE_TYPE_COPY5:
601             *keyspace = CC_KEYSPACE_LCE3;
602             break;
603         case RM_ENGINE_TYPE_COPY6:
604             *keyspace = CC_KEYSPACE_LCE4;
605             break;
606         case RM_ENGINE_TYPE_COPY7:
607             *keyspace = CC_KEYSPACE_LCE5;
608             break;
609         case RM_ENGINE_TYPE_COPY8:
610             *keyspace = CC_KEYSPACE_LCE6;
611             break;
612         case RM_ENGINE_TYPE_COPY9:
613             *keyspace = CC_KEYSPACE_LCE7;
614             break;
615         default:
616             return NV_ERR_GENERIC;
617     }
618 
619     return NV_OK;
620 }
621 
622 static NV_STATUS
623 checkSlot
624 (
625     ConfidentialCompute *pConfCompute,
626     NvU32                slotNumber
627 )
628 {
629     if (getChannelCounter(pConfCompute, slotNumber) == NV_U64_MAX)
630     {
631         return NV_ERR_GENERIC;
632     }
633 
634     return NV_OK;
635 }
636 
637 static void
638 incrementChannelCounter
639 (
640     ConfidentialCompute *pConfCompute,
641     NvU32                slotNumber
642 )
643 {
644     NvU64          channelCounter = getChannelCounter(pConfCompute, slotNumber);
645     cryptoBundle_t (*pKeyStore)[];
646 
647     pKeyStore = pConfCompute->m_keySlot;
648 
649     channelCounter++;
650 
651     switch ((*pKeyStore)[slotNumber].type)
652     {
653         case NO_CHAN_COUNTER:
654             break;
655         case CRYPT_COUNTER:
656             (*pKeyStore)[slotNumber].cryptBundle.iv[2] = NvU64_HI32(channelCounter);
657             (*pKeyStore)[slotNumber].cryptBundle.iv[1] = NvU64_LO32(channelCounter);
658             break;
659         case HMAC_COUNTER:
660             (*pKeyStore)[slotNumber].hmacBundle.nonce[7] = NvU64_HI32(channelCounter);
661             (*pKeyStore)[slotNumber].hmacBundle.nonce[6] = NvU64_LO32(channelCounter);
662             break;
663     }
664 }
665 
666 static NvU64
667 getChannelCounter
668 (
669     ConfidentialCompute *pConfCompute,
670     NvU32                slotNumber
671 )
672 {
673     cryptoBundle_t (*pKeyStore)[];
674 
675     pKeyStore = pConfCompute->m_keySlot;
676 
677     switch ((*pKeyStore)[slotNumber].type)
678     {
679         case NO_CHAN_COUNTER:
680             return 0;
681         case CRYPT_COUNTER:
682             return CONCAT64((*pKeyStore)[slotNumber].cryptBundle.iv[2],
683                             (*pKeyStore)[slotNumber].cryptBundle.iv[1]);
684         case HMAC_COUNTER:
685             return CONCAT64((*pKeyStore)[slotNumber].hmacBundle.nonce[7],
686                             (*pKeyStore)[slotNumber].hmacBundle.nonce[6]);
687         default:
688             NV_ASSERT_OR_RETURN(NV_FALSE, 0);
689     }
690 }
691