mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-02-04 07:10:19 +00:00
1267 lines
49 KiB
C
1267 lines
49 KiB
C
/*
|
|
* SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
/* ------------------------ Includes --------------------------------------- */
|
|
|
|
#include "common_nvswitch.h"
|
|
#include "haldef_nvswitch.h"
|
|
#include "ls10/ls10.h"
|
|
#include "ls10/soe_ls10.h"
|
|
|
|
#include "nvswitch/ls10/dev_nvlsaw_ip.h"
|
|
#include "nvswitch/ls10/dev_nvlsaw_ip_addendum.h"
|
|
#include "nvswitch/ls10/dev_ctrl_ip.h"
|
|
#include "nvswitch/ls10/dev_ctrl_ip_addendum.h"
|
|
#include "nvswitch/ls10/dev_cpr_ip.h"
|
|
#include "nvswitch/ls10/dev_npg_ip.h"
|
|
#include "nvswitch/ls10/dev_fsp_pri.h"
|
|
#include "nvswitch/ls10/dev_soe_ip.h"
|
|
#include "nvswitch/ls10/ptop_discovery_ip.h"
|
|
#include "nvswitch/ls10/dev_minion_ip.h"
|
|
|
|
#include <stddef.h>
|
|
|
|
/* ------------------------ Macros ----------------------------------------- */
|
|
#define TNVL_MAX_CERT_CHAIN_SIZE (0x1000)
|
|
#define TNVL_MAX_ENCODED_CERT_CHAIN_SIZE (0x1400)
|
|
|
|
#define DER_LONG_FORM_LENGTH_FIELD_BIT (0x80)
|
|
#define DER_CERT_SIZE_FIELD_LENGTH (0x4)
|
|
|
|
#define TNVL_PEM_BEGIN_CERTIFICATE "-----BEGIN CERTIFICATE-----\n"
|
|
#define TNVL_PEM_END_CERTIFICATE "-----END CERTIFICATE-----\n"
|
|
|
|
#define TNVL_MAX_MEASUREMENT_SIZE (0x2000)
|
|
|
|
#define TNVL_L1_CERTIFICATE_PEM "-----BEGIN CERTIFICATE-----\n"\
|
|
"MIICCzCCAZCgAwIBAgIQLTZwscoQBBHB/sDoKgZbVDAKBggqhkjOPQQDAzA1MSIw\n"\
|
|
"IAYDVQQDDBlOVklESUEgRGV2aWNlIElkZW50aXR5IENBMQ8wDQYDVQQKDAZOVklE\n"\
|
|
"SUEwIBcNMjExMTA1MDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMDUxIjAgBgNVBAMM\n"\
|
|
"GU5WSURJQSBEZXZpY2UgSWRlbnRpdHkgQ0ExDzANBgNVBAoMBk5WSURJQTB2MBAG\n"\
|
|
"ByqGSM49AgEGBSuBBAAiA2IABA5MFKM7+KViZljbQSlgfky/RRnEQScW9NDZF8SX\n"\
|
|
"gAW96r6u/Ve8ZggtcYpPi2BS4VFu6KfEIrhN6FcHG7WP05W+oM+hxj7nyA1r1jkB\n"\
|
|
"2Ry70YfThX3Ba1zOryOP+MJ9vaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"\
|
|
"Af8EBAMCAQYwHQYDVR0OBBYEFFeF/4PyY8xlfWi3Olv0jUrL+0lfMB8GA1UdIwQY\n"\
|
|
"MBaAFFeF/4PyY8xlfWi3Olv0jUrL+0lfMAoGCCqGSM49BAMDA2kAMGYCMQCPeFM3\n"\
|
|
"TASsKQVaT+8S0sO9u97PVGCpE9d/I42IT7k3UUOLSR/qvJynVOD1vQKVXf0CMQC+\n"\
|
|
"EY55WYoDBvs2wPAH1Gw4LbcwUN8QCff8bFmV4ZxjCRr4WXTLFHBKjbfneGSBWwA=\n"\
|
|
"-----END CERTIFICATE-----\n"
|
|
|
|
#define TNVL_L2_CERTIFICATE_PEM "-----BEGIN CERTIFICATE-----\n"\
|
|
"MIICijCCAhCgAwIBAgIQTCVe3jvQAb8/SjtgX8qJijAKBggqhkjOPQQDAzA1MSIw\n"\
|
|
"IAYDVQQDDBlOVklESUEgRGV2aWNlIElkZW50aXR5IENBMQ8wDQYDVQQKDAZOVklE\n"\
|
|
"SUEwIBcNMjIwMTEyMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMD0xHjAcBgNVBAMM\n"\
|
|
"FU5WSURJQSBHSDEwMCBJZGVudGl0eTEbMBkGA1UECgwSTlZJRElBIENvcnBvcmF0\n"\
|
|
"aW9uMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE+pg+tDUuILlZILk5wg22YEJ9Oh6c\n"\
|
|
"yPcsv3IvgRWcV4LeZK1pTCoQDIplZ0E4qsLG3G04pxsbMhxbqkiz9pqlTV2rtuVg\n"\
|
|
"SmIqnSYkU1jWXsPS9oVLCGE8VRLl1JvqyOxUo4HaMIHXMA8GA1UdEwEB/wQFMAMB\n"\
|
|
"Af8wDgYDVR0PAQH/BAQDAgEGMDsGA1UdHwQ0MDIwMKAuoCyGKmh0dHA6Ly9jcmwu\n"\
|
|
"bmRpcy5udmlkaWEuY29tL2NybC9sMS1yb290LmNybDA3BggrBgEFBQcBAQQrMCkw\n"\
|
|
"JwYIKwYBBQUHMAGGG2h0dHA6Ly9vY3NwLm5kaXMubnZpZGlhLmNvbTAdBgNVHQ4E\n"\
|
|
"FgQUB0Kg6wOcgGB7oUFhmU2uJffCmx4wHwYDVR0jBBgwFoAUV4X/g/JjzGV9aLc6\n"\
|
|
"W/SNSsv7SV8wCgYIKoZIzj0EAwMDaAAwZQIxAPIQhnveFxYIrPzBqViT2I34SfS4\n"\
|
|
"JGWFnk/1UcdmgJmp+7l6rH/C4qxwntYSgeYrlQIwdjQuofHnhd1RL09OBO34566J\n"\
|
|
"C9bYAosT/86cCojiGjhLnal9hJOH0nS/lrbaoc5a\n"\
|
|
"-----END CERTIFICATE-----\n"
|
|
|
|
#define TNVL_L3_CERTIFICATE_PEM "-----BEGIN CERTIFICATE-----\n"\
|
|
"MIICqTCCAi+gAwIBAgIQcidIXMg4KYZ1y7ooFz5gUjAKBggqhkjOPQQDAzA9MR4w\n"\
|
|
"HAYDVQQDDBVOVklESUEgR0gxMDAgSWRlbnRpdHkxGzAZBgNVBAoMEk5WSURJQSBD\n"\
|
|
"b3Jwb3JhdGlvbjAgFw0yMjAzMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowUzEn\n"\
|
|
"MCUGA1UEAwweTlZJRElBIExTXzEwIFByb3Zpc2lvbmVyIElDQSAxMRswGQYDVQQK\n"\
|
|
"DBJOVklESUEgQ29ycG9yYXRpb24xCzAJBgNVBAYTAlVTMHYwEAYHKoZIzj0CAQYF\n"\
|
|
"K4EEACIDYgAEyGbP8B2aF0Zd0V5GhWfcnC8K8BXUJMGPhAWQo88WymU0Az+u2Y7B\n"\
|
|
"zI9li0TyXhth18dB1yqodYgH3KKU1c0beV1OkAUvnlx3JpNPhx8nfdlhpM9jqsXG\n"\
|
|
"JXeJixW5+VOlo4HbMIHYMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG\n"\
|
|
"MDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwubmRpcy5udmlkaWEuY29tL2Ny\n"\
|
|
"bC9sMi1naDEwMC5jcmwwNwYIKwYBBQUHAQEEKzApMCcGCCsGAQUFBzABhhtodHRw\n"\
|
|
"Oi8vb2NzcC5uZGlzLm52aWRpYS5jb20wHQYDVR0OBBYEFBFA9xSZ0ALwvOeei4fR\n"\
|
|
"von435VEMB8GA1UdIwQYMBaAFAdCoOsDnIBge6FBYZlNriX3wpseMAoGCCqGSM49\n"\
|
|
"BAMDA2gAMGUCMQDWLHcBKxi9QVrfMoDcIg3gLBRe5oEo/Q4KR3WaUMz9ABxMHK9Y\n"\
|
|
"K4xPtjXW4Bup5FwCMBhLpTQqsly8gQ6w1CIyMEC4n/LSjM65TC4pGVokSyjpoyp0\n"\
|
|
"gWjuEBq1vBNs76Ge8A==\n"\
|
|
"-----END CERTIFICATE-----\n"
|
|
|
|
const static NvU8 TNVL_L1_CERTIFICATE_DER[527] =
|
|
{
|
|
0x30, 0x82, 0x02, 0x0b, 0x30, 0x82, 0x01, 0x90, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x2d,
|
|
0x36, 0x70, 0xb1, 0xca, 0x10, 0x04, 0x11, 0xc1, 0xfe, 0xc0, 0xe8, 0x2a, 0x06, 0x5b, 0x54, 0x30,
|
|
0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, 0x30, 0x35, 0x31, 0x22, 0x30,
|
|
0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x19, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x20, 0x44,
|
|
0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x43,
|
|
0x41, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x4e, 0x56, 0x49, 0x44,
|
|
0x49, 0x41, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30,
|
|
0x30, 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35,
|
|
0x39, 0x35, 0x39, 0x5a, 0x30, 0x35, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
|
|
0x19, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x49,
|
|
0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x43, 0x41, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03,
|
|
0x55, 0x04, 0x0a, 0x0c, 0x06, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x30, 0x76, 0x30, 0x10, 0x06,
|
|
0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03,
|
|
0x62, 0x00, 0x04, 0x0e, 0x4c, 0x14, 0xa3, 0x3b, 0xf8, 0xa5, 0x62, 0x66, 0x58, 0xdb, 0x41, 0x29,
|
|
0x60, 0x7e, 0x4c, 0xbf, 0x45, 0x19, 0xc4, 0x41, 0x27, 0x16, 0xf4, 0xd0, 0xd9, 0x17, 0xc4, 0x97,
|
|
0x80, 0x05, 0xbd, 0xea, 0xbe, 0xae, 0xfd, 0x57, 0xbc, 0x66, 0x08, 0x2d, 0x71, 0x8a, 0x4f, 0x8b,
|
|
0x60, 0x52, 0xe1, 0x51, 0x6e, 0xe8, 0xa7, 0xc4, 0x22, 0xb8, 0x4d, 0xe8, 0x57, 0x07, 0x1b, 0xb5,
|
|
0x8f, 0xd3, 0x95, 0xbe, 0xa0, 0xcf, 0xa1, 0xc6, 0x3e, 0xe7, 0xc8, 0x0d, 0x6b, 0xd6, 0x39, 0x01,
|
|
0xd9, 0x1c, 0xbb, 0xd1, 0x87, 0xd3, 0x85, 0x7d, 0xc1, 0x6b, 0x5c, 0xce, 0xaf, 0x23, 0x8f, 0xf8,
|
|
0xc2, 0x7d, 0xbd, 0xa3, 0x63, 0x30, 0x61, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
|
|
0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
|
|
0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
|
|
0x16, 0x04, 0x14, 0x57, 0x85, 0xff, 0x83, 0xf2, 0x63, 0xcc, 0x65, 0x7d, 0x68, 0xb7, 0x3a, 0x5b,
|
|
0xf4, 0x8d, 0x4a, 0xcb, 0xfb, 0x49, 0x5f, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
|
|
0x30, 0x16, 0x80, 0x14, 0x57, 0x85, 0xff, 0x83, 0xf2, 0x63, 0xcc, 0x65, 0x7d, 0x68, 0xb7, 0x3a,
|
|
0x5b, 0xf4, 0x8d, 0x4a, 0xcb, 0xfb, 0x49, 0x5f, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
|
|
0x3d, 0x04, 0x03, 0x03, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0x8f, 0x78, 0x53, 0x37,
|
|
0x4c, 0x04, 0xac, 0x29, 0x05, 0x5a, 0x4f, 0xef, 0x12, 0xd2, 0xc3, 0xbd, 0xbb, 0xde, 0xcf, 0x54,
|
|
0x60, 0xa9, 0x13, 0xd7, 0x7f, 0x23, 0x8d, 0x88, 0x4f, 0xb9, 0x37, 0x51, 0x43, 0x8b, 0x49, 0x1f,
|
|
0xea, 0xbc, 0x9c, 0xa7, 0x54, 0xe0, 0xf5, 0xbd, 0x02, 0x95, 0x5d, 0xfd, 0x02, 0x31, 0x00, 0xbe,
|
|
0x11, 0x8e, 0x79, 0x59, 0x8a, 0x03, 0x06, 0xfb, 0x36, 0xc0, 0xf0, 0x07, 0xd4, 0x6c, 0x38, 0x2d,
|
|
0xb7, 0x30, 0x50, 0xdf, 0x10, 0x09, 0xf7, 0xfc, 0x6c, 0x59, 0x95, 0xe1, 0x9c, 0x63, 0x09, 0x1a,
|
|
0xf8, 0x59, 0x74, 0xcb, 0x14, 0x70, 0x4a, 0x8d, 0xb7, 0xe7, 0x78, 0x64, 0x81, 0x5b, 0x00
|
|
};
|
|
|
|
const static NvU8 TNVL_L2_CERTIFICATE_DER[654] =
|
|
{
|
|
0x30, 0x82, 0x02, 0x8a, 0x30, 0x82, 0x02, 0x10, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x4c,
|
|
0x25, 0x5e, 0xde, 0x3b, 0xd0, 0x01, 0xbf, 0x3f, 0x4a, 0x3b, 0x60, 0x5f, 0xca, 0x89, 0x8a, 0x30,
|
|
0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, 0x30, 0x35, 0x31, 0x22, 0x30,
|
|
0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x19, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x20, 0x44,
|
|
0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x43,
|
|
0x41, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x4e, 0x56, 0x49, 0x44,
|
|
0x49, 0x41, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x31, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30,
|
|
0x30, 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35,
|
|
0x39, 0x35, 0x39, 0x5a, 0x30, 0x3d, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
|
|
0x15, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x20, 0x47, 0x48, 0x31, 0x30, 0x30, 0x20, 0x49, 0x64,
|
|
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
|
|
0x12, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
|
|
0x69, 0x6f, 0x6e, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
|
|
0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0xfa, 0x98, 0x3e, 0xb4, 0x35,
|
|
0x2e, 0x20, 0xb9, 0x59, 0x20, 0xb9, 0x39, 0xc2, 0x0d, 0xb6, 0x60, 0x42, 0x7d, 0x3a, 0x1e, 0x9c,
|
|
0xc8, 0xf7, 0x2c, 0xbf, 0x72, 0x2f, 0x81, 0x15, 0x9c, 0x57, 0x82, 0xde, 0x64, 0xad, 0x69, 0x4c,
|
|
0x2a, 0x10, 0x0c, 0x8a, 0x65, 0x67, 0x41, 0x38, 0xaa, 0xc2, 0xc6, 0xdc, 0x6d, 0x38, 0xa7, 0x1b,
|
|
0x1b, 0x32, 0x1c, 0x5b, 0xaa, 0x48, 0xb3, 0xf6, 0x9a, 0xa5, 0x4d, 0x5d, 0xab, 0xb6, 0xe5, 0x60,
|
|
0x4a, 0x62, 0x2a, 0x9d, 0x26, 0x24, 0x53, 0x58, 0xd6, 0x5e, 0xc3, 0xd2, 0xf6, 0x85, 0x4b, 0x08,
|
|
0x61, 0x3c, 0x55, 0x12, 0xe5, 0xd4, 0x9b, 0xea, 0xc8, 0xec, 0x54, 0xa3, 0x81, 0xda, 0x30, 0x81,
|
|
0xd7, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
|
|
0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
|
|
0x01, 0x06, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0xa0,
|
|
0x2e, 0xa0, 0x2c, 0x86, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
|
|
0x6e, 0x64, 0x69, 0x73, 0x2e, 0x6e, 0x76, 0x69, 0x64, 0x69, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
|
0x63, 0x72, 0x6c, 0x2f, 0x6c, 0x31, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30,
|
|
0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2b, 0x30, 0x29, 0x30,
|
|
0x27, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68, 0x74, 0x74,
|
|
0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x6e, 0x64, 0x69, 0x73, 0x2e, 0x6e, 0x76,
|
|
0x69, 0x64, 0x69, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
|
|
0x16, 0x04, 0x14, 0x07, 0x42, 0xa0, 0xeb, 0x03, 0x9c, 0x80, 0x60, 0x7b, 0xa1, 0x41, 0x61, 0x99,
|
|
0x4d, 0xae, 0x25, 0xf7, 0xc2, 0x9b, 0x1e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
|
|
0x30, 0x16, 0x80, 0x14, 0x57, 0x85, 0xff, 0x83, 0xf2, 0x63, 0xcc, 0x65, 0x7d, 0x68, 0xb7, 0x3a,
|
|
0x5b, 0xf4, 0x8d, 0x4a, 0xcb, 0xfb, 0x49, 0x5f, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
|
|
0x3d, 0x04, 0x03, 0x03, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x31, 0x00, 0xf2, 0x10, 0x86, 0x7b,
|
|
0xde, 0x17, 0x16, 0x08, 0xac, 0xfc, 0xc1, 0xa9, 0x58, 0x93, 0xd8, 0x8d, 0xf8, 0x49, 0xf4, 0xb8,
|
|
0x24, 0x65, 0x85, 0x9e, 0x4f, 0xf5, 0x51, 0xc7, 0x66, 0x80, 0x99, 0xa9, 0xfb, 0xb9, 0x7a, 0xac,
|
|
0x7f, 0xc2, 0xe2, 0xac, 0x70, 0x9e, 0xd6, 0x12, 0x81, 0xe6, 0x2b, 0x95, 0x02, 0x30, 0x76, 0x34,
|
|
0x2e, 0xa1, 0xf1, 0xe7, 0x85, 0xdd, 0x51, 0x2f, 0x4f, 0x4e, 0x04, 0xed, 0xf8, 0xe7, 0xae, 0x89,
|
|
0x0b, 0xd6, 0xd8, 0x02, 0x8b, 0x13, 0xff, 0xce, 0x9c, 0x0a, 0x88, 0xe2, 0x1a, 0x38, 0x4b, 0x9d,
|
|
0xa9, 0x7d, 0x84, 0x93, 0x87, 0xd2, 0x74, 0xbf, 0x96, 0xb6, 0xda, 0xa1, 0xce, 0x5a,
|
|
};
|
|
|
|
const static NvU8 TNVL_L3_CERTIFICATE_DER[686] =
|
|
{
|
|
0x30, 0x82, 0x02, 0xaa, 0x30, 0x82, 0x02, 0x2f, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x6a,
|
|
0xfe, 0x71, 0x84, 0xf9, 0x22, 0x32, 0xc8, 0xdf, 0x7b, 0x24, 0x22, 0x61, 0x77, 0x6e, 0x56, 0x30,
|
|
0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, 0x30, 0x3d, 0x31, 0x1e, 0x30,
|
|
0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x20, 0x47,
|
|
0x48, 0x31, 0x30, 0x30, 0x20, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x31, 0x1b, 0x30,
|
|
0x19, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x12, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x20, 0x43,
|
|
0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x32,
|
|
0x30, 0x33, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39,
|
|
0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x53, 0x31, 0x27,
|
|
0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1e, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x20,
|
|
0x47, 0x48, 0x31, 0x30, 0x30, 0x20, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
|
|
0x72, 0x20, 0x49, 0x43, 0x41, 0x20, 0x31, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
|
0x0c, 0x12, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61,
|
|
0x74, 0x69, 0x6f, 0x6e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
|
|
0x53, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05,
|
|
0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0xcd, 0x47, 0x56, 0xaa, 0x39, 0xf5, 0x3a,
|
|
0x55, 0xe1, 0x2d, 0xf1, 0x4e, 0x28, 0x01, 0x53, 0x82, 0x1a, 0x86, 0xf9, 0x0d, 0xf3, 0x17, 0x8c,
|
|
0x60, 0x48, 0x16, 0xd9, 0xb1, 0x41, 0x32, 0x59, 0x80, 0x82, 0xde, 0xb2, 0xa3, 0x13, 0xd3, 0x67,
|
|
0xa3, 0xcf, 0x19, 0xa4, 0x14, 0x31, 0xf3, 0x93, 0xa8, 0xd0, 0xf9, 0x2a, 0x3f, 0x67, 0x70, 0xa0,
|
|
0xc5, 0x4d, 0x4d, 0x03, 0x2f, 0xe5, 0xcb, 0xf2, 0xf6, 0x32, 0xda, 0x4e, 0xf4, 0x93, 0x5d, 0x9c,
|
|
0x0d, 0xd8, 0x74, 0x07, 0x13, 0xdb, 0xbb, 0xc7, 0xb0, 0x48, 0x62, 0xb5, 0xa2, 0xd2, 0xc1, 0xb7,
|
|
0xe6, 0xad, 0x48, 0x24, 0xd4, 0x8e, 0x18, 0xee, 0x4b, 0xa3, 0x81, 0xdb, 0x30, 0x81, 0xd8, 0x30,
|
|
0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
|
|
0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
|
|
0x30, 0x3c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x35, 0x30, 0x33, 0x30, 0x31, 0xa0, 0x2f, 0xa0,
|
|
0x2d, 0x86, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x6e, 0x64,
|
|
0x69, 0x73, 0x2e, 0x6e, 0x76, 0x69, 0x64, 0x69, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
|
|
0x6c, 0x2f, 0x6c, 0x32, 0x2d, 0x67, 0x68, 0x31, 0x30, 0x30, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x37,
|
|
0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27,
|
|
0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68, 0x74, 0x74, 0x70,
|
|
0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x6e, 0x64, 0x69, 0x73, 0x2e, 0x6e, 0x76, 0x69,
|
|
0x64, 0x69, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
|
|
0x04, 0x14, 0x29, 0x68, 0xcb, 0x16, 0x2c, 0xd0, 0x77, 0x95, 0x72, 0xa2, 0x79, 0x10, 0x03, 0xe6,
|
|
0x9e, 0xba, 0x0c, 0xcc, 0x0a, 0x94, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
|
|
0x16, 0x80, 0x14, 0x07, 0x42, 0xa0, 0xeb, 0x03, 0x9c, 0x80, 0x60, 0x7b, 0xa1, 0x41, 0x61, 0x99,
|
|
0x4d, 0xae, 0x25, 0xf7, 0xc2, 0x9b, 0x1e, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
|
|
0x04, 0x03, 0x03, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0xca, 0xd0, 0x10, 0xab, 0xe3,
|
|
0xd0, 0xcd, 0x27, 0x8f, 0x18, 0x87, 0x9c, 0x2e, 0xdf, 0xcf, 0x1b, 0x66, 0x27, 0xc3, 0x17, 0x10,
|
|
0x2c, 0x89, 0x44, 0xb8, 0x53, 0x57, 0xc6, 0x9a, 0x92, 0x59, 0x16, 0x10, 0x9b, 0x38, 0x31, 0xfa,
|
|
0x99, 0x1c, 0x1c, 0x33, 0x1a, 0x7a, 0x10, 0xe6, 0xb2, 0x66, 0xe6, 0x02, 0x31, 0x00, 0xd8, 0x29,
|
|
0x3c, 0x8d, 0x73, 0x61, 0x71, 0x58, 0x5b, 0xa1, 0x1e, 0xd7, 0x42, 0x13, 0x79, 0x6c, 0xe1, 0x2e,
|
|
0xd2, 0x22, 0x77, 0xa1, 0x74, 0x4a, 0xd3, 0x64, 0xdb, 0xa1, 0x17, 0x29, 0x9c, 0xe1, 0x83, 0x8c,
|
|
0xe9, 0x59, 0x4b, 0x59, 0x36, 0x3f, 0x08, 0xcf, 0xab, 0x7a, 0xc8, 0xe3, 0xab, 0x14,
|
|
};
|
|
|
|
/* ------------------------ Static Functions ------------------------------- */
|
|
/*!
|
|
@param pCert : The pointer to certification chain start
|
|
@param bufferEnd : The pointer to certification chain end
|
|
@parsm pCertLength : The pointer to store return certification size
|
|
|
|
@return Return NV-OK if no error.
|
|
|
|
* Static function that calculates the length of the X509 certificate in DER/TLV
|
|
* format. It assumes that the certificate is valid.
|
|
*/
|
|
static NvlStatus
|
|
_calc_x509_cert_size_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NvU8 *pCert,
|
|
NvU8 *bufferEnd,
|
|
NvU32 *pCertLength
|
|
)
|
|
{
|
|
// The cert is in TLV format.
|
|
NvU32 certSize = pCert[1];
|
|
|
|
// Check to make sure that some data exists after TNVL header, and it is enough to check cert size.
|
|
if (pCert + DER_CERT_SIZE_FIELD_LENGTH >= bufferEnd ||
|
|
pCert + DER_CERT_SIZE_FIELD_LENGTH <= pCert)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: pCert + DER_CERT_SIZE_FIELD_LENGTH(0x%x) is not valid value !! \n",
|
|
__FUNCTION__, DER_CERT_SIZE_FIELD_LENGTH);
|
|
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
// Check if the length is in DER longform.
|
|
// MSB in the length field is set for long form notation.
|
|
// fields.
|
|
if (certSize & DER_LONG_FORM_LENGTH_FIELD_BIT)
|
|
{
|
|
//
|
|
// The remaining bits in the length field indicate the
|
|
// number of following bytes used to represent the length.
|
|
// in base 256, most significant digit first.
|
|
//
|
|
NvU32 numLenBytes = certSize & 0x3f;
|
|
NvU8 *pStart = &pCert[2];
|
|
NvU8 *pEnd = pStart + numLenBytes; // NOTE: Don't need to subtract numLenBytes 1 here.
|
|
|
|
// Checking for buffer overflow.
|
|
if (pEnd > bufferEnd)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
certSize = *pStart;
|
|
while (++pStart < pEnd)
|
|
{
|
|
certSize = (certSize << 8) + *pStart ;
|
|
}
|
|
// Total cert length includes the Tag + length
|
|
// Adding it here.
|
|
certSize += 2 + numLenBytes;
|
|
}
|
|
|
|
//
|
|
// Check to make sure we have not hit end of buffer, and there is space for AK cert.
|
|
// Check for underflow as well. This makes sure we haven't missed the calculation to
|
|
// go past the end of the buffer
|
|
//
|
|
if (pCert + (certSize - 1) > bufferEnd ||
|
|
pCert + (certSize - 1) <= pCert)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: pCert + (certSize(0x%x) - 1) is not a valid value !! \n",
|
|
__FUNCTION__, certSize);
|
|
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
*pCertLength = certSize;
|
|
return NVL_SUCCESS;
|
|
}
|
|
|
|
static NvlStatus
|
|
_pem_write_buffer_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NvU8 const *der,
|
|
NvU64 derLen,
|
|
NvU8 *buffer,
|
|
NvU64 bufferLen,
|
|
NvU64 *bufferUsed
|
|
)
|
|
{
|
|
static const NvU8 base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
NvU64 i, tmp, size;
|
|
NvU64 printed = 0;
|
|
NvU8 *ptr = buffer;
|
|
|
|
// Base64 encoded size
|
|
size = (derLen + 2) / 3 * 4;
|
|
|
|
// Add 1 byte per 64 for newline
|
|
size = size + (size + 63) / 64;
|
|
|
|
// Add header excluding the terminating null and footer including the null
|
|
size += sizeof(TNVL_PEM_BEGIN_CERTIFICATE) - 1 +
|
|
sizeof(TNVL_PEM_END_CERTIFICATE);
|
|
|
|
if (bufferLen < size)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
nvswitch_os_memcpy(ptr, TNVL_PEM_BEGIN_CERTIFICATE, sizeof(TNVL_PEM_BEGIN_CERTIFICATE) - 1);
|
|
ptr += sizeof(TNVL_PEM_BEGIN_CERTIFICATE) - 1;
|
|
|
|
for (i = 0; (i + 2) < derLen; i += 3)
|
|
{
|
|
tmp = (der[i] << 16) | (der[i + 1] << 8) | (der[i + 2]);
|
|
*ptr++ = base64[(tmp >> 18) & 63];
|
|
*ptr++ = base64[(tmp >> 12) & 63];
|
|
*ptr++ = base64[(tmp >> 6) & 63];
|
|
*ptr++ = base64[(tmp >> 0) & 63];
|
|
|
|
printed += 4;
|
|
if (printed == 64)
|
|
{
|
|
*ptr++ = '\n';
|
|
printed = 0;
|
|
}
|
|
}
|
|
|
|
if ((i == derLen) && (printed != 0))
|
|
{
|
|
*ptr++ = '\n';
|
|
}
|
|
|
|
// 1 byte extra
|
|
if (i == (derLen - 1))
|
|
{
|
|
tmp = der[i] << 4;
|
|
*ptr++ = base64[(tmp >> 6) & 63];
|
|
*ptr++ = base64[(tmp >> 0) & 63];
|
|
*ptr++ = '=';
|
|
*ptr++ = '=';
|
|
*ptr++ = '\n';
|
|
}
|
|
|
|
// 2 byte extra
|
|
if (i == (derLen - 2))
|
|
{
|
|
tmp = ((der[i] << 8) | (der[i + 1])) << 2;
|
|
*ptr++ = base64[(tmp >> 12) & 63];
|
|
*ptr++ = base64[(tmp >> 6) & 63];
|
|
*ptr++ = base64[(tmp >> 0) & 63];
|
|
*ptr++ = '=';
|
|
*ptr++ = '\n';
|
|
}
|
|
|
|
nvswitch_os_memcpy(ptr, TNVL_PEM_END_CERTIFICATE, sizeof(TNVL_PEM_END_CERTIFICATE));
|
|
ptr += sizeof(TNVL_PEM_END_CERTIFICATE);
|
|
|
|
*bufferUsed = size;
|
|
return NVL_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
* Static function builds the cert chain in DER format. It is assumed that
|
|
* the all the certificates are valid. Also it is assumed that there is a valid
|
|
* tnvl session already established.
|
|
*/
|
|
static NvlStatus
|
|
_tnvl_build_cert_chain_der_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NvU8 *pFirstCert,
|
|
NvU32 firstCertSize,
|
|
NvU8 *pSecondCert,
|
|
NvU32 secondCertSize,
|
|
NvU8 *pOutBuffer,
|
|
size_t *outBufferSize
|
|
)
|
|
{
|
|
NvU64 remainingOutBufferSize = 0;
|
|
NvU64 totalSize = 0;
|
|
void *pPortMemCopyStatus = NULL;
|
|
|
|
if (pFirstCert == NULL || pSecondCert == NULL || pOutBuffer == NULL || outBufferSize == NULL)
|
|
{
|
|
return -NVL_BAD_ARGS;
|
|
}
|
|
|
|
// Calculate the total size of the certificate chain (in DER).
|
|
totalSize = sizeof(TNVL_L1_CERTIFICATE_DER) +
|
|
sizeof(TNVL_L2_CERTIFICATE_DER) +
|
|
sizeof(TNVL_L3_CERTIFICATE_DER) +
|
|
secondCertSize +
|
|
firstCertSize;
|
|
|
|
remainingOutBufferSize = *outBufferSize;
|
|
if (remainingOutBufferSize < totalSize)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
//
|
|
// Write the L1 DER certificate to the output buffer
|
|
//
|
|
pPortMemCopyStatus = nvswitch_os_memcpy(pOutBuffer,
|
|
TNVL_L1_CERTIFICATE_DER,
|
|
sizeof(TNVL_L1_CERTIFICATE_DER));
|
|
if (pPortMemCopyStatus == NULL)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
remainingOutBufferSize -= sizeof(TNVL_L1_CERTIFICATE_DER);
|
|
pOutBuffer += sizeof(TNVL_L1_CERTIFICATE_DER);
|
|
|
|
//
|
|
// Write the L2 DER certificate to the output buffer
|
|
//
|
|
pPortMemCopyStatus = nvswitch_os_memcpy(pOutBuffer,
|
|
TNVL_L2_CERTIFICATE_DER,
|
|
sizeof(TNVL_L2_CERTIFICATE_DER));
|
|
if (pPortMemCopyStatus == NULL)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
remainingOutBufferSize -= sizeof(TNVL_L2_CERTIFICATE_DER);
|
|
pOutBuffer += sizeof(TNVL_L2_CERTIFICATE_DER);
|
|
|
|
//
|
|
// Write the L3 DER certificate to the output buffer
|
|
//
|
|
pPortMemCopyStatus = nvswitch_os_memcpy(pOutBuffer,
|
|
TNVL_L3_CERTIFICATE_DER,
|
|
sizeof(TNVL_L3_CERTIFICATE_DER));
|
|
if (pPortMemCopyStatus == NULL)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
remainingOutBufferSize -= sizeof(TNVL_L3_CERTIFICATE_DER);
|
|
pOutBuffer += sizeof(TNVL_L3_CERTIFICATE_DER);
|
|
|
|
//
|
|
// Write the IK certificate in DER to the output buffer
|
|
//
|
|
pPortMemCopyStatus = nvswitch_os_memcpy(pOutBuffer,
|
|
pSecondCert,
|
|
secondCertSize);
|
|
if (pPortMemCopyStatus == NULL)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
remainingOutBufferSize -= secondCertSize;
|
|
pOutBuffer += secondCertSize;
|
|
|
|
//
|
|
// Write the AK certificate in DER to the output buffer
|
|
//
|
|
pPortMemCopyStatus = nvswitch_os_memcpy(pOutBuffer,
|
|
pFirstCert,
|
|
firstCertSize);
|
|
if (pPortMemCopyStatus == NULL)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
remainingOutBufferSize -= firstCertSize;
|
|
pOutBuffer += firstCertSize;
|
|
|
|
// Output the total certificate chain size
|
|
*outBufferSize = totalSize;
|
|
|
|
return NVL_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
* Static function that first converts the IK and AK certificates from DER to
|
|
* PEM format. Then it builds the cert chain in PEM format. It is assumed that
|
|
* the all the certificates are valid. Also it is assumed that there is a valid
|
|
* tnvl session already established.
|
|
*/
|
|
static NvlStatus
|
|
_tnvl_build_cert_chain_pem_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NvU8 *pFirstCert,
|
|
NvU32 firstCertSize,
|
|
NvU8 *pSecondCert,
|
|
NvU32 secondCertSize,
|
|
NvU8 *pOutBuffer,
|
|
size_t *outBufferSize
|
|
)
|
|
{
|
|
NvU64 firstCertOutputSize = 0;
|
|
NvU64 secondCertOutputSize = 0;
|
|
NvU64 remainingOutBufferSize = 0;
|
|
void *pPortMemCopyStatus = NULL;
|
|
NvlStatus status;
|
|
|
|
if (pFirstCert == NULL || pSecondCert == NULL || pOutBuffer == NULL || outBufferSize == NULL)
|
|
{
|
|
return -NVL_BAD_ARGS;
|
|
}
|
|
|
|
remainingOutBufferSize = *outBufferSize;
|
|
|
|
//
|
|
// Write the AK certificate to the output buffer
|
|
//
|
|
status = _pem_write_buffer_ls10(device, pFirstCert, firstCertSize, pOutBuffer,
|
|
remainingOutBufferSize, &firstCertOutputSize);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Keep track how much space we have left in the output buffer
|
|
// and where the next certificate should start.
|
|
// Clear the last byte (NULL).
|
|
//
|
|
remainingOutBufferSize -= firstCertOutputSize - 1;
|
|
pOutBuffer += firstCertOutputSize - 1;
|
|
|
|
//
|
|
// Write the IK certificate to the output buffer
|
|
//
|
|
status = _pem_write_buffer_ls10(device, pSecondCert, secondCertSize, pOutBuffer,
|
|
remainingOutBufferSize, &secondCertOutputSize);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
remainingOutBufferSize -= secondCertOutputSize - 1;
|
|
pOutBuffer += secondCertOutputSize - 1;
|
|
|
|
// Checking if the available size of buffer is enough to keep the whole
|
|
// certificate chain otherwise raise error.
|
|
if (remainingOutBufferSize < sizeof(TNVL_L1_CERTIFICATE_PEM)
|
|
+ sizeof(TNVL_L2_CERTIFICATE_PEM)
|
|
+ sizeof(TNVL_L3_CERTIFICATE_PEM))
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
//
|
|
// Write the L3 certificate to the output buffer
|
|
//
|
|
pPortMemCopyStatus = nvswitch_os_memcpy(pOutBuffer,
|
|
TNVL_L3_CERTIFICATE_PEM,
|
|
sizeof(TNVL_L3_CERTIFICATE_PEM) - 1);
|
|
if (pPortMemCopyStatus == NULL)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
remainingOutBufferSize -= sizeof(TNVL_L3_CERTIFICATE_PEM) - 1;
|
|
pOutBuffer += sizeof(TNVL_L3_CERTIFICATE_PEM) - 1;
|
|
|
|
//
|
|
// Write the L2 certificate to the output buffer
|
|
//
|
|
pPortMemCopyStatus = nvswitch_os_memcpy(pOutBuffer,
|
|
TNVL_L2_CERTIFICATE_PEM,
|
|
sizeof(TNVL_L2_CERTIFICATE_PEM) - 1);
|
|
if (pPortMemCopyStatus == NULL)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
remainingOutBufferSize -= sizeof(TNVL_L2_CERTIFICATE_PEM) - 1;
|
|
pOutBuffer += sizeof(TNVL_L2_CERTIFICATE_PEM) - 1;
|
|
|
|
//
|
|
// Write the L1 certificate to the output buffer
|
|
//
|
|
pPortMemCopyStatus = nvswitch_os_memcpy(pOutBuffer,
|
|
TNVL_L1_CERTIFICATE_PEM,
|
|
sizeof(TNVL_L1_CERTIFICATE_PEM) - 1);
|
|
if (pPortMemCopyStatus == NULL)
|
|
{
|
|
return -NVL_NO_MEM;
|
|
}
|
|
|
|
//
|
|
// Output the total certificate chain size
|
|
// Do not count the NULL bytes.
|
|
//
|
|
*outBufferSize = firstCertOutputSize - 1 +
|
|
secondCertOutputSize - 1 +
|
|
sizeof(TNVL_L3_CERTIFICATE_PEM) - 1 +
|
|
sizeof(TNVL_L2_CERTIFICATE_PEM) - 1 +
|
|
sizeof(TNVL_L1_CERTIFICATE_PEM) - 1;
|
|
|
|
return NVL_SUCCESS;
|
|
}
|
|
|
|
/* ------------------------ Public Functions ------------------------------- */
|
|
|
|
static NvlStatus
|
|
_nvswitch_tnvl_get_cert_chain_from_fsp_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NvU8 *pCertChain,
|
|
size_t *pCertChainLength
|
|
)
|
|
{
|
|
NvlStatus status;
|
|
TNVL_GET_ATT_CERTS_CMD_PAYLOAD *pCmdPayload = nvswitch_os_malloc(sizeof(TNVL_GET_ATT_CERTS_CMD_PAYLOAD));
|
|
TNVL_GET_ATT_CERTS_RSP_PAYLOAD *pRspPayload = nvswitch_os_malloc(sizeof(TNVL_GET_ATT_CERTS_RSP_PAYLOAD));
|
|
NVSWITCH_TIMEOUT timeout;
|
|
|
|
if (pCmdPayload == NULL || pRspPayload == NULL)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Failed to allocate memory\n",
|
|
__FUNCTION__);
|
|
status = -NVL_NO_MEM;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
pCmdPayload->subMessageId = TNVL_GET_ATT_CERTS_SUBMESSAGE_ID;
|
|
pCmdPayload->minorVersion = 0;
|
|
pCmdPayload->majorVersion = 1;
|
|
|
|
nvswitch_timeout_create(5 * NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
|
|
|
|
status = nvswitch_fsp_send_and_read_message(device,
|
|
(NvU8*) pCmdPayload, sizeof(TNVL_GET_ATT_CERTS_CMD_PAYLOAD), NVDM_TYPE_TNVL,
|
|
(NvU8*) pRspPayload, sizeof(TNVL_GET_ATT_CERTS_RSP_PAYLOAD), &timeout);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: RPC failed for FSP cert query\n",
|
|
__FUNCTION__);
|
|
status = -NVL_ERR_INVALID_STATE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// Validate response
|
|
if (pRspPayload->subMessageId != TNVL_GET_ATT_CERTS_SUBMESSAGE_ID)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Unknown submessage Id %d, Expected %d\n",
|
|
__FUNCTION__,
|
|
pRspPayload->subMessageId, TNVL_GET_ATT_CERTS_SUBMESSAGE_ID);
|
|
status = -NVL_ERR_INVALID_STATE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
nvswitch_os_memcpy(pCertChain, pRspPayload->certChain, pRspPayload->certChainLength);
|
|
*pCertChainLength = pRspPayload->certChainLength;
|
|
|
|
ErrorExit:
|
|
nvswitch_os_free(pCmdPayload);
|
|
nvswitch_os_free(pRspPayload);
|
|
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* This function retrieves nvswitch certificates.
|
|
*
|
|
* @param device nvswitch device pointer
|
|
* @param params certificate params
|
|
*
|
|
* @return Returns NVL_SUCCESS on success. Anything else should be considered a failure.
|
|
*/
|
|
NvlStatus
|
|
nvswitch_tnvl_get_attestation_certificate_chain_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NVSWITCH_GET_ATTESTATION_CERTIFICATE_CHAIN_PARAMS *params
|
|
)
|
|
{
|
|
NvlStatus status = NVL_SUCCESS;
|
|
NvU8 *pIkCertificate = NULL;
|
|
NvU32 ikCertificateSize = 0;
|
|
NvU8 *pAkCertificate = NULL;
|
|
NvU32 akCertificateSize = 0;
|
|
NvU8 *pCertChain = NULL;
|
|
size_t certChainLength = 0;
|
|
NvU8 *pDerCertChain = NULL;
|
|
size_t derCertChainSize = 0;
|
|
NvU8 *pCertChainBufferEnd = NULL;
|
|
NvU8 *pAttestationCertChain = NULL;
|
|
size_t attestationCertChainSize = 0;
|
|
NvU32 totalSize = 0;
|
|
|
|
if (params == NULL)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Bad args!\n",
|
|
__FUNCTION__);
|
|
return -NVL_BAD_ARGS;
|
|
}
|
|
|
|
if (!nvswitch_is_tnvl_mode_enabled(device))
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: TNVL is not enabled\n",
|
|
__FUNCTION__);
|
|
return -NVL_ERR_NOT_SUPPORTED;
|
|
}
|
|
|
|
// Allocate buffer for certificates.
|
|
certChainLength = TNVL_MAX_CERT_CHAIN_SIZE;
|
|
pCertChain = nvswitch_os_malloc(certChainLength);
|
|
derCertChainSize = TNVL_MAX_ENCODED_CERT_CHAIN_SIZE;
|
|
pDerCertChain = nvswitch_os_malloc(derCertChainSize);
|
|
attestationCertChainSize = TNVL_MAX_ENCODED_CERT_CHAIN_SIZE;
|
|
pAttestationCertChain = nvswitch_os_malloc(attestationCertChainSize);
|
|
|
|
if (pCertChain == NULL || pDerCertChain == NULL || pAttestationCertChain == NULL)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Failed to allocate memory\n",
|
|
__FUNCTION__);
|
|
status = -NVL_NO_MEM;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
nvswitch_os_memset(pCertChain, 0, certChainLength);
|
|
nvswitch_os_memset(pDerCertChain, 0, derCertChainSize);
|
|
nvswitch_os_memset(pAttestationCertChain, 0, attestationCertChainSize);
|
|
|
|
// Fetch Attestation cert chain from FSP
|
|
status = _nvswitch_tnvl_get_cert_chain_from_fsp_ls10(device, pCertChain, &certChainLength);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Failed to get nvswitch certs from FSP\n",
|
|
__FUNCTION__);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
certChainLength = certChainLength -
|
|
NVSWITCH_IK_HASH_LENGTH -
|
|
NVSWITCH_ATT_CERT_SIZE_FIELD_LENGTH -
|
|
NVSWITCH_ATT_RSVD1_FIELD_LENGTH;
|
|
//
|
|
// pCertChainBufferEnd represents last valid byte for cert buffer.
|
|
//
|
|
pCertChainBufferEnd = pCertChain + certChainLength - 1;
|
|
pIkCertificate = (NvU8 *)pCertChain;
|
|
|
|
// Calculate the size of the IK cert, and skip past it to get the AK cert.
|
|
status = _calc_x509_cert_size_ls10(device, pIkCertificate, pCertChainBufferEnd, &ikCertificateSize);
|
|
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Failed to calculate IK size\n",
|
|
__FUNCTION__);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
pAkCertificate = (NvU8 *)pIkCertificate + ikCertificateSize;
|
|
|
|
// Calculate the size of the AK certificate.
|
|
status = _calc_x509_cert_size_ls10(device, pAkCertificate, pCertChainBufferEnd, &akCertificateSize);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Failed to calculate AK size\n",
|
|
__FUNCTION__);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// Make sure we have calculated the size correctly.
|
|
if ((pAkCertificate + akCertificateSize - 1) != pCertChainBufferEnd)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Error in calculating AK size\n",
|
|
__FUNCTION__);
|
|
status = -NVL_ERR_INVALID_STATE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// Retrieve the entire certificate chain in DER format in order to validate it.
|
|
status = _tnvl_build_cert_chain_der_ls10(device,
|
|
pAkCertificate, akCertificateSize,
|
|
pIkCertificate, ikCertificateSize,
|
|
pDerCertChain,
|
|
&derCertChainSize);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
totalSize = sizeof(TNVL_L1_CERTIFICATE_DER) +
|
|
sizeof(TNVL_L2_CERTIFICATE_DER) +
|
|
sizeof(TNVL_L3_CERTIFICATE_DER) +
|
|
akCertificateSize +
|
|
ikCertificateSize;
|
|
|
|
if (derCertChainSize != totalSize)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: derCertChainSize(%llu) != totalSize(0x%x) !! \n",
|
|
__FUNCTION__, ((NvU64)derCertChainSize), totalSize);
|
|
status = -NVL_ERR_INVALID_STATE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Now that the cert chain is valid, retrieve the cert chain in PEM format,
|
|
// as the Verifier can only parse PEM format.
|
|
//
|
|
status = _tnvl_build_cert_chain_pem_ls10(device,
|
|
pAkCertificate, akCertificateSize,
|
|
pIkCertificate, ikCertificateSize,
|
|
pAttestationCertChain,
|
|
&attestationCertChainSize);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Failed to build PEM cert chain\n",
|
|
__FUNCTION__);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
nvswitch_os_memcpy(params->attestationCertChain, pAttestationCertChain, attestationCertChainSize);
|
|
params->attestationCertChainSize = attestationCertChainSize;
|
|
|
|
ErrorExit:
|
|
nvswitch_os_free(pCertChain);
|
|
nvswitch_os_free(pDerCertChain);
|
|
nvswitch_os_free(pAttestationCertChain);
|
|
|
|
return status;
|
|
}
|
|
|
|
NvlStatus
|
|
nvswitch_tnvl_get_attestation_report_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NVSWITCH_GET_ATTESTATION_REPORT_PARAMS *params
|
|
)
|
|
{
|
|
NvlStatus status;
|
|
TNVL_GET_ATT_REPORT_CMD_PAYLOAD *pCmdPayload;
|
|
TNVL_GET_ATT_REPORT_RSP_PAYLOAD *pRspPayload;
|
|
NVSWITCH_TIMEOUT timeout;
|
|
|
|
if (!nvswitch_is_tnvl_mode_enabled(device))
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: TNVL is not enabled\n",
|
|
__FUNCTION__);
|
|
return -NVL_ERR_NOT_SUPPORTED;
|
|
}
|
|
|
|
pCmdPayload = nvswitch_os_malloc(sizeof(TNVL_GET_ATT_REPORT_CMD_PAYLOAD));
|
|
pRspPayload = nvswitch_os_malloc(sizeof(TNVL_GET_ATT_REPORT_RSP_PAYLOAD));
|
|
|
|
if (pCmdPayload == NULL || pRspPayload == NULL)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Failed to allocate memory\n",
|
|
__FUNCTION__);
|
|
status = -NVL_NO_MEM;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// Request the Attestation Report using the provided nonce, signed by the AK cert.
|
|
pCmdPayload->subMessageId = TNVL_GET_ATT_REPORT_SUBMESSAGE_ID;
|
|
pCmdPayload->minorVersion = 0;
|
|
pCmdPayload->majorVersion = 1;
|
|
nvswitch_os_memcpy(pCmdPayload->nonce, params->nonce, NVSWITCH_NONCE_SIZE);
|
|
|
|
nvswitch_timeout_create(10 * NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
|
|
|
|
status = nvswitch_fsp_send_and_read_message(device,
|
|
(NvU8*) pCmdPayload, sizeof(TNVL_GET_ATT_REPORT_CMD_PAYLOAD), NVDM_TYPE_TNVL,
|
|
(NvU8*) pRspPayload, sizeof(TNVL_GET_ATT_REPORT_RSP_PAYLOAD), &timeout);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Failed to get nvswitch measurements from FSP\n",
|
|
__FUNCTION__);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// Validate response
|
|
if (pRspPayload->subMessageId != TNVL_GET_ATT_REPORT_SUBMESSAGE_ID)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Unknown submessage Id %d, Expected %d\n",
|
|
__FUNCTION__,
|
|
pRspPayload->subMessageId, TNVL_GET_ATT_REPORT_SUBMESSAGE_ID);
|
|
status = -NVL_ERR_INVALID_STATE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
nvswitch_os_memcpy(params->attestationReport,
|
|
pRspPayload->measurementBuffer, pRspPayload->measurementSize);
|
|
params->attestationReportSize = pRspPayload->measurementSize;
|
|
|
|
ErrorExit:
|
|
nvswitch_os_free(pCmdPayload);
|
|
nvswitch_os_free(pRspPayload);
|
|
|
|
return status;
|
|
}
|
|
|
|
NvlStatus
|
|
nvswitch_detect_tnvl_mode_ls10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
NvU32 val;
|
|
|
|
// Detect for TNVL mode
|
|
val = NVSWITCH_SAW_RD32_LS10(device, _NVLSAW, _TNVL_MODE);
|
|
if (FLD_TEST_DRF(_NVLSAW, _TNVL_MODE, _STATUS, _ENABLED, val))
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: TNVL Mode Detected\n",
|
|
__FUNCTION__);
|
|
device->tnvl_mode = NVSWITCH_DEVICE_TNVL_MODE_ENABLED;
|
|
}
|
|
|
|
return NVL_SUCCESS;
|
|
}
|
|
|
|
NvBool
|
|
nvswitch_is_tnvl_mode_enabled_ls10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
return (device->tnvl_mode != NVSWITCH_DEVICE_TNVL_MODE_DISABLED);
|
|
}
|
|
|
|
NvBool
|
|
nvswitch_is_tnvl_mode_locked_ls10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
return (device->tnvl_mode == NVSWITCH_DEVICE_TNVL_MODE_LOCKED);
|
|
}
|
|
|
|
NvlStatus
|
|
nvswitch_tnvl_send_fsp_lock_config_ls10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
NvlStatus status;
|
|
TNVL_LOCK_CONFIG_CMD_PAYLOAD *pCmdPayload;
|
|
TNVL_LOCK_CONFIG_RSP_PAYLOAD *pRspPayload;
|
|
NVSWITCH_TIMEOUT timeout;
|
|
|
|
if (!nvswitch_is_tnvl_mode_enabled(device))
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: TNVL is not enabled\n",
|
|
__FUNCTION__);
|
|
return -NVL_ERR_NOT_SUPPORTED;
|
|
}
|
|
|
|
pCmdPayload = nvswitch_os_malloc(sizeof(TNVL_LOCK_CONFIG_CMD_PAYLOAD));
|
|
pRspPayload = nvswitch_os_malloc(sizeof(TNVL_LOCK_CONFIG_RSP_PAYLOAD));
|
|
|
|
if (pCmdPayload == NULL || pRspPayload == NULL)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Failed to allocate memory\n",
|
|
__FUNCTION__);
|
|
status = -NVL_NO_MEM;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
pCmdPayload->subMessageId = TNVL_LOCK_CONFIG_SUBMESSAGE_ID;
|
|
pCmdPayload->minorVersion = 0;
|
|
pCmdPayload->majorVersion = 1;
|
|
|
|
nvswitch_timeout_create(5 * NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
|
|
|
|
status = nvswitch_fsp_send_and_read_message(device,
|
|
(NvU8*) pCmdPayload, sizeof(TNVL_LOCK_CONFIG_CMD_PAYLOAD), NVDM_TYPE_TNVL,
|
|
(NvU8*) pRspPayload, sizeof(TNVL_LOCK_CONFIG_RSP_PAYLOAD), &timeout);
|
|
if (status != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: RPC failed for FSP lock config command\n",
|
|
__FUNCTION__);
|
|
status = -NVL_ERR_INVALID_STATE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// Validate response
|
|
if (pRspPayload->subMessageId != TNVL_LOCK_CONFIG_SUBMESSAGE_ID)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: Unknown submessage Id %d, Expected %d\n",
|
|
__FUNCTION__,
|
|
pRspPayload->subMessageId, TNVL_LOCK_CONFIG_SUBMESSAGE_ID);
|
|
status = -NVL_ERR_INVALID_STATE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
ErrorExit:
|
|
nvswitch_os_free(pCmdPayload);
|
|
nvswitch_os_free(pRspPayload);
|
|
|
|
return status;
|
|
}
|
|
|
|
NvlStatus
|
|
nvswitch_tnvl_get_status_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NVSWITCH_GET_TNVL_STATUS_PARAMS *params
|
|
)
|
|
{
|
|
params->status = device->tnvl_mode;
|
|
return NVL_SUCCESS;
|
|
}
|
|
|
|
static NvBool
|
|
_nvswitch_tnvl_eng_wr_cpu_allow_list_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NVSWITCH_ENGINE_ID eng_id,
|
|
NvU32 offset
|
|
)
|
|
{
|
|
switch (eng_id)
|
|
{
|
|
case NVSWITCH_ENGINE_ID_SOE:
|
|
case NVSWITCH_ENGINE_ID_GIN:
|
|
case NVSWITCH_ENGINE_ID_FSP:
|
|
return NV_TRUE;
|
|
case NVSWITCH_ENGINE_ID_SAW:
|
|
{
|
|
if (offset == NV_NVLSAW_DRIVER_ATTACH_DETACH)
|
|
return NV_TRUE;
|
|
break;
|
|
}
|
|
case NVSWITCH_ENGINE_ID_NPG:
|
|
{
|
|
if ((offset == NV_NPG_INTR_RETRIGGER(0)) ||
|
|
(offset == NV_NPG_INTR_RETRIGGER(1)))
|
|
return NV_TRUE;
|
|
break;
|
|
}
|
|
case NVSWITCH_ENGINE_ID_CPR:
|
|
{
|
|
if ((offset == NV_CPR_SYS_INTR_RETRIGGER(0)) ||
|
|
(offset == NV_CPR_SYS_INTR_RETRIGGER(1)))
|
|
return NV_TRUE;
|
|
break;
|
|
}
|
|
case NVSWITCH_ENGINE_ID_MINION:
|
|
{
|
|
if ((offset == NV_MINION_NVLINK_DL_STAT(0)) ||
|
|
(offset == NV_MINION_NVLINK_DL_STAT(1)) ||
|
|
(offset == NV_MINION_NVLINK_DL_STAT(2)) ||
|
|
(offset == NV_MINION_NVLINK_DL_STAT(3)))
|
|
return NV_TRUE;
|
|
break;
|
|
}
|
|
default :
|
|
return NV_FALSE;
|
|
}
|
|
|
|
return NV_FALSE;
|
|
}
|
|
|
|
void
|
|
nvswitch_tnvl_eng_wr_32_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NVSWITCH_ENGINE_ID eng_id,
|
|
NvU32 eng_bcast,
|
|
NvU32 eng_instance,
|
|
NvU32 base_addr,
|
|
NvU32 offset,
|
|
NvU32 data
|
|
)
|
|
{
|
|
if (device->nvlink_device->pciInfo.bars[0].pBar == NULL)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: register write failed at offset 0x%x\n",
|
|
__FUNCTION__, offset);
|
|
return;
|
|
}
|
|
|
|
if (!nvswitch_is_tnvl_mode_enabled(device))
|
|
{
|
|
NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_TNVL_ERROR,
|
|
"ENG reg-write failed. TNVL mode is not enabled\n");
|
|
return;
|
|
}
|
|
|
|
if (_nvswitch_tnvl_eng_wr_cpu_allow_list_ls10(device, eng_id, offset))
|
|
{
|
|
nvswitch_os_mem_write32((NvU8 *)device->nvlink_device->pciInfo.bars[0].pBar + base_addr + offset, data);
|
|
return;
|
|
}
|
|
|
|
if (nvswitch_is_tnvl_mode_locked(device))
|
|
{
|
|
NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_TNVL_ERROR,
|
|
"TNVL ENG_WR failure - 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
|
eng_id, eng_instance, eng_bcast, base_addr, offset, data);
|
|
|
|
NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_TNVL_ERROR,
|
|
"TNVL mode is locked\n");
|
|
return;
|
|
}
|
|
|
|
if (nvswitch_soe_eng_wr_32_ls10(device, eng_id, eng_bcast, eng_instance, base_addr, offset, data) != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_TNVL_ERROR,
|
|
"TNVL ENG_WR failure - 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
|
eng_id, eng_instance, eng_bcast, base_addr, offset, data);
|
|
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: SOE ENG_WR failed for 0x%x[%d] %s @0x%08x+0x%06x = 0x%08x\n",
|
|
__FUNCTION__,
|
|
eng_id, eng_instance,
|
|
(
|
|
(eng_bcast == NVSWITCH_GET_ENG_DESC_TYPE_UNICAST) ? "UC" :
|
|
(eng_bcast == NVSWITCH_GET_ENG_DESC_TYPE_BCAST) ? "BC" :
|
|
(eng_bcast == NVSWITCH_GET_ENG_DESC_TYPE_MULTICAST) ? "MC" :
|
|
"??"
|
|
),
|
|
base_addr, offset, data);
|
|
}
|
|
}
|
|
|
|
static NvBool
|
|
_nvswitch_tnvl_reg_wr_cpu_allow_list_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NvU32 offset
|
|
)
|
|
{
|
|
if ((offset >= DRF_BASE(NV_PFSP)) &&
|
|
(offset <= DRF_EXTENT(NV_PFSP)))
|
|
{
|
|
return NV_TRUE;
|
|
}
|
|
|
|
if ((offset >= NV_PTOP_UNICAST_SW_DEVICE_BASE_SOE_0 + DRF_BASE(NV_SOE)) &&
|
|
(offset <= NV_PTOP_UNICAST_SW_DEVICE_BASE_SOE_0 + DRF_EXTENT(NV_SOE)))
|
|
{
|
|
return NV_TRUE;
|
|
}
|
|
|
|
return NV_FALSE;
|
|
}
|
|
|
|
void
|
|
nvswitch_tnvl_reg_wr_32_ls10
|
|
(
|
|
nvswitch_device *device,
|
|
NvU32 offset,
|
|
NvU32 data
|
|
)
|
|
{
|
|
if (device->nvlink_device->pciInfo.bars[0].pBar == NULL)
|
|
{
|
|
NVSWITCH_PRINT(device, ERROR,
|
|
"%s: register write failed at offset 0x%x\n",
|
|
__FUNCTION__, offset);
|
|
NVSWITCH_ASSERT(0);
|
|
return;
|
|
}
|
|
|
|
if (!nvswitch_is_tnvl_mode_enabled(device))
|
|
{
|
|
NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_TNVL_ERROR,
|
|
"Reg-write failed. TNVL mode is not enabled\n");
|
|
return;
|
|
}
|
|
|
|
if (_nvswitch_tnvl_reg_wr_cpu_allow_list_ls10(device, offset))
|
|
{
|
|
nvswitch_os_mem_write32((NvU8 *)device->nvlink_device->pciInfo.bars[0].pBar + offset, data);
|
|
return;
|
|
}
|
|
|
|
if (nvswitch_is_tnvl_mode_locked(device))
|
|
{
|
|
NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_TNVL_ERROR,
|
|
"TNVL REG_WR failure - 0x%08x, 0x%08x\n", offset, data);
|
|
|
|
NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_TNVL_ERROR,
|
|
"TNVL mode is locked\n");
|
|
return;
|
|
}
|
|
|
|
if (nvswitch_soe_reg_wr_32_ls10(device, offset, data) != NVL_SUCCESS)
|
|
{
|
|
NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_TNVL_ERROR,
|
|
"TNVL REG_WR failure - 0x%08x, 0x%08x\n", offset, data);
|
|
}
|
|
}
|
|
|
|
void
|
|
nvswitch_tnvl_disable_interrupts_ls10
|
|
(
|
|
nvswitch_device *device
|
|
)
|
|
{
|
|
//
|
|
// In TNVL locked disable non-fatal NVLW, NPG, and legacy interrupt,
|
|
// disable additional non-fatals on those partitions.
|
|
//
|
|
NVSWITCH_ENG_WR32(device, GIN, , 0, _CTRL, _CPU_INTR_LEAF_EN_CLEAR(NV_CTRL_CPU_INTR_NVLW_NON_FATAL_IDX),
|
|
0xFFFF);
|
|
|
|
NVSWITCH_ENG_WR32(device, GIN, , 0, _CTRL, _CPU_INTR_LEAF_EN_CLEAR(NV_CTRL_CPU_INTR_NPG_NON_FATAL_IDX),
|
|
0xFFFF);
|
|
|
|
NVSWITCH_ENG_WR32(device, GIN, , 0, _CTRL, _CPU_INTR_LEAF_EN_CLEAR(NV_CTRL_CPU_INTR_UNITS_IDX),
|
|
0xFFFFFFFF);
|
|
}
|
|
|