/* _NVRM_COPYRIGHT_BEGIN_ * * Copyright 2003-2016 by NVIDIA Corporation. All rights reserved. All * information contained herein is proprietary and confidential to NVIDIA * Corporation. Any use, reproduction, or disclosure without the written * permission of NVIDIA Corporation is prohibited. * * _NVRM_COPYRIGHT_END_ */ /* This file is autogenerated by ref2h.pl. Do not edit */ #ifndef BOOTROM_FUSEKEY_PARAS_H #define BOOTROM_FUSEKEY_PARAS_H #define AES_128_KEY_LEN_IN_BYTES 16u #define AES_128_SIG_LEN_IN_BYTES AES_128_KEY_LEN_IN_BYTES #define PROTECTINFO_LEN_IN_BYTES 4u #define SECRET_FOR_FUSEKEY_SIGN_1 34u #define SECRET_FOR_FUSEKEY_SIGN_2 35u #define SECRET_FOR_FUSEKEY_DEC 38u #define FUSE_NUM_OF_16B_KEY 3u #define FUSE_NUM_OF_32B_KEY 1u #define HEADER_RSVD_BYTES 13u #define VERIFY_ECDSA_P256_PASS 0xDA55u #define VERIFY_ECDSA_P256_FAIL 0xFA11u #define PASS VERIFY_ECDSA_P256_PASS #define FAIL VERIFY_ECDSA_P256_FAIL #define ECC_P256_SIZE_DWORDS 8u #define MAX_NUM_OF_FUSE_KEYS_IN_16B 11u typedef unsigned char AES_128_KEY[AES_128_KEY_LEN_IN_BYTES]; // AES_128_KEY is an array of 16 bytes typedef unsigned char ECC_256_KEY[AES_128_KEY_LEN_IN_BYTES * 2u]; // ECC_256_KEY is an array of 32 bytes typedef unsigned char AES_128_SIG[AES_128_SIG_LEN_IN_BYTES]; // AES_128_SIG is an array of 16 bytes typedef unsigned char ENC_FUSE_KEY_PROT_INFO[PROTECTINFO_LEN_IN_BYTES]; static const unsigned int CONST_USED_FOR_GENTK[4]={0x900du, 0u, 0u, 0u}; static const unsigned int CONST_USED_FOR_DECRYPT_MPK[4]={0x76543210u, 0xfedcba98u, 0x76543210u, 0xfedcba98u}; typedef enum { DRM_PLAYREADY, DRM_WIDEVINE } DRM_SCHEME; typedef struct { unsigned char version; //keyglob version unsigned char numOf16BKey; //numbler of 16Bytes unsigned char numOf32BKey; //numbler of 16Bytes unsigned char rsvd[HEADER_RSVD_BYTES]; // reserved field for future, These need to be zeroed out in Turing } ENC_FUSE_KEY_HEADER; /* * Paramter struct for FUNID==1: decryptFuseKeys * "decryptFuseKeys" performed: * 1. Verify the signature on the given keyglob, keyglob consist of header, keyArr and protInfoArr * Hash = DMHash of keyglob with first value to be encrypted being E(secret[34], 1) instead of 0 * SigKey = AES_ENC(secret[35], 1) * Sig = E(SigKey, Hash) * 2. If sig checking pass, decrypt the fuse keys and install the decrypted keys and their protectInfo to the KMEM. * eKey = AES_ENC(AES_ENC(scp_secrets[38], 0x1), PDI); * keyblob = AES_DEC(eKey, keyglob); keyblob is plain text of keys * 3. This API can be called by any ucode(NS/LS/HS) * 4. How to call this function * SW_PARAM_DECRYPT_FUSEKEYS* pointer_of_struct_for_dec_fuse_keys * then fill each element of above pointer * falc_strap(NV_CMSXXX_FALCON_BROM_FUNID_ID_DECFUSEKEY, pointer_of_struct_for_decrypt_fuse_keys); * * Arguments: * see below struct comments * Result: * check the result by csb register BROM_RETCODE * Alignment requirement * 32B aligned */ typedef struct { ENC_FUSE_KEY_HEADER header; //(in) needs to be 16 bytes aligned address AES_128_KEY keyArr[MAX_NUM_OF_FUSE_KEYS_IN_16B]; //(in) needs to be 16 bytes aligned address. Will increment in stride of 16 ENC_FUSE_KEY_PROT_INFO protInfoArr[MAX_NUM_OF_FUSE_KEYS_IN_16B]; //(in) needs to be 16 bytes aligned address, and the length must be multiple of 16 bytes, padding 0s if needed. unsigned char rsvd[4]; // reserved for future, making pSignature to be 16B aligned AES_128_SIG signature; //(in) needs to be 16 bytes aligned address } SW_PARAM_DECRYPT_FUSEKEYS __attribute__((aligned(32))); /* * Paramter struct for FUNID==2: genTK * "genTK" performed: * This function returns a TK given an ID. * * TK is generated as follows * tmpKey = Enc(dPDUK, CONST_USED_FOR_GENTK); * TKEncKey= Enc(tmpKey, IS_HS | DRM_SCHEME_ID | UCODE_ID | FAMILYIDID); * TK = Enc(TKEncKey, tkid) * where - IS_HS is 0 for LS and 1 for HS. - UCODE_ID is 0xFFFFFFFF for LS - ENG_ID is FALCON_ENGID_FAMILYID. - ENG_ID (32 bits): 31:0 - UCODE_ID (32 bits): 63:32 - DRM_SCHEME_ID (32 bits): 95:64 - IS_HS (1 bit): 127:96 - tkid = required version of TK - dPDUK is one of the fuse keys, after it is decrypted by BROM it is persisted in the KMEM * If tkid > CTKID, return failure by reg BROM_RETCODE * CTKID is from fuse, which starts at 0. It is field programmable fuses(aks FPF), and propagated to falcon FALCON_PR_CTKID register * non-secure code is not allowed to call this API, LS/HS is allowed * * Arguments: * See below comments * How to call this function: * falc_strap(NV_MSXXXFALCON_BROM_FUNID_ID_GENTK, pointer_of_struct_for_gen_tk); * Alignment Reqirement * 32 Bytes aligned * */ typedef struct { AES_128_KEY tk; //(out) Tell Brom the dmem address where to store the TK. BR will check whether the mem_ptr is stay in DMEM // If it is an invalid ptr, report ERR by BROM_RETCODE. unsigned int tkid; //(in) The ID of the required TK DRM_SCHEME drm_scheme_id; //(in) DRM scheme id, 0 for Playready, 1 for Widevine } SW_PARAM_GENTK __attribute__((aligned(32))); /* * Paramter struct for FUNID==3: decryptMPK * "decryptMPK" Synopsis: * This function decrypts the given eMPK and installs the result to KMEM keyslot. * It's protectInfo will be set as * disposable = 1 and the corresponding ucodeIdMask =1 * protectInfo of dMPK = 0x400 | (1<<(FALCON_BROM_CURR_UCODE_ID+15)) * Operations Performed: * tmpKey = Enc(PMUK, CONST_USED_FOR_DECRYPT_MPK) * Dkey = Enc(tmpKey, fuseVersionForCurrUcode || ucodeId || family_id); * dMPK = Dec(Dkey, eMPK); * where: * family_id(32 bits) : 31:0 from csb register FALCON_ENGID * ucodeId(32 bits) : 63:32 from csb register FALCON_BROM_CURR_UCODE_ID * fuseVersionForCurrUcode : 95:64 from csb register FALCON_UCODE_VERSION(ucodeID) * Arguments: * pMPK (in) Address of the encrypted MPK * * The output of plain text of MPK is installed by BROM to KMEM keyslot index NV_CMSDEC_FALCON_KMEM_MPK_LOW_IDX and NV_CMSDEC_FALCON_KMEM_MPK_HIGH_IDX * This API can only be called by HS code. * Check BROM_RETCODE to know the result of the function. * * Alignment requirement * 32 bytes aligned */ typedef struct { ECC_256_KEY mpk; //(in) Address of the encrypted MPK } SW_PARAM_DECRYPT_MPK __attribute__((aligned(32))); /* * Struct used for ECDSA sign or ECDSA verify */ typedef struct { unsigned int HASH[ECC_P256_SIZE_DWORDS]; // little-endian in a word } ECC_P256_HASH; typedef struct { unsigned int PRIVKEY[ECC_P256_SIZE_DWORDS]; // little-endian in a word } ECC_P256_PRIVKEY; typedef struct { unsigned int R[ECC_P256_SIZE_DWORDS]; // little-endian in a word unsigned int S[ECC_P256_SIZE_DWORDS]; // little-endian in a word } ECC_P256_SIGNATURE; typedef struct { unsigned int Qx[ECC_P256_SIZE_DWORDS]; // little-endian in a word unsigned int Qy[ECC_P256_SIZE_DWORDS]; // little-endian in a word } ECC_P256_PUBKEY; /* * Paramter struct for FUNID==6: sign_ECDSA_P256 * Alignment requirement * 4 bytes aligned */ typedef struct { ECC_P256_HASH hash; ECC_P256_PRIVKEY privKey; ECC_P256_SIGNATURE sig; } SW_PARAM_SIGN_ECDSA_P256; /* * Paramter struct for FUNID==4: signWithMPK * Alignment requirement * 4 bytes aligned */ typedef struct { ECC_P256_HASH hash; ECC_P256_SIGNATURE sig; } SW_PARAM_SIGN_WITH_MPK; /* * Paramter struct for FUNID==7: verify_ECDSA_P256 * Alignment requirement * 4 bytes aligned */ typedef struct { ECC_P256_HASH hash; ECC_P256_SIGNATURE sig; ECC_P256_PUBKEY pubKey; unsigned int result; //0xDA55: pass; 0xFA11: fail } SW_PARAM_VERIFY_ECDSA_P256; #endif