1*d7869cecSEddie James // SPDX-License-Identifier: GPL-2.0+ 2*d7869cecSEddie James /* 3*d7869cecSEddie James * Copyright 2019 Google LLC 4*d7869cecSEddie James */ 5*d7869cecSEddie James 6*d7869cecSEddie James #include <common.h> 7*d7869cecSEddie James #include <dm.h> 8*d7869cecSEddie James #include <log.h> 9*d7869cecSEddie James #include <tpm_api.h> 10*d7869cecSEddie James #include <tpm-v1.h> 11*d7869cecSEddie James #include <tpm-v2.h> 12*d7869cecSEddie James #include <tpm_api.h> 13*d7869cecSEddie James 14*d7869cecSEddie James u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode) 15*d7869cecSEddie James { 16*d7869cecSEddie James if (tpm_is_v1(dev)) { 17*d7869cecSEddie James return tpm1_startup(dev, mode); 18*d7869cecSEddie James } else if (tpm_is_v2(dev)) { 19*d7869cecSEddie James enum tpm2_startup_types type; 20*d7869cecSEddie James 21*d7869cecSEddie James switch (mode) { 22*d7869cecSEddie James case TPM_ST_CLEAR: 23*d7869cecSEddie James type = TPM2_SU_CLEAR; 24*d7869cecSEddie James break; 25*d7869cecSEddie James case TPM_ST_STATE: 26*d7869cecSEddie James type = TPM2_SU_STATE; 27*d7869cecSEddie James break; 28*d7869cecSEddie James default: 29*d7869cecSEddie James case TPM_ST_DEACTIVATED: 30*d7869cecSEddie James return -EINVAL; 31*d7869cecSEddie James } 32*d7869cecSEddie James return tpm2_startup(dev, type); 33*d7869cecSEddie James } else { 34*d7869cecSEddie James return -ENOSYS; 35*d7869cecSEddie James } 36*d7869cecSEddie James } 37*d7869cecSEddie James 38*d7869cecSEddie James u32 tpm_resume(struct udevice *dev) 39*d7869cecSEddie James { 40*d7869cecSEddie James if (tpm_is_v1(dev)) 41*d7869cecSEddie James return tpm1_startup(dev, TPM_ST_STATE); 42*d7869cecSEddie James else if (tpm_is_v2(dev)) 43*d7869cecSEddie James return tpm2_startup(dev, TPM2_SU_STATE); 44*d7869cecSEddie James else 45*d7869cecSEddie James return -ENOSYS; 46*d7869cecSEddie James } 47*d7869cecSEddie James 48*d7869cecSEddie James u32 tpm_self_test_full(struct udevice *dev) 49*d7869cecSEddie James { 50*d7869cecSEddie James if (tpm_is_v1(dev)) 51*d7869cecSEddie James return tpm1_self_test_full(dev); 52*d7869cecSEddie James else if (tpm_is_v2(dev)) 53*d7869cecSEddie James return tpm2_self_test(dev, TPMI_YES); 54*d7869cecSEddie James else 55*d7869cecSEddie James return -ENOSYS; 56*d7869cecSEddie James } 57*d7869cecSEddie James 58*d7869cecSEddie James u32 tpm_continue_self_test(struct udevice *dev) 59*d7869cecSEddie James { 60*d7869cecSEddie James if (tpm_is_v1(dev)) 61*d7869cecSEddie James return tpm1_continue_self_test(dev); 62*d7869cecSEddie James else if (tpm_is_v2(dev)) 63*d7869cecSEddie James return tpm2_self_test(dev, TPMI_NO); 64*d7869cecSEddie James else 65*d7869cecSEddie James return -ENOSYS; 66*d7869cecSEddie James } 67*d7869cecSEddie James 68*d7869cecSEddie James u32 tpm_clear_and_reenable(struct udevice *dev) 69*d7869cecSEddie James { 70*d7869cecSEddie James u32 ret; 71*d7869cecSEddie James 72*d7869cecSEddie James log_info("TPM: Clear and re-enable\n"); 73*d7869cecSEddie James ret = tpm_force_clear(dev); 74*d7869cecSEddie James if (ret != TPM_SUCCESS) { 75*d7869cecSEddie James log_err("Can't initiate a force clear\n"); 76*d7869cecSEddie James return ret; 77*d7869cecSEddie James } 78*d7869cecSEddie James 79*d7869cecSEddie James if (tpm_is_v1(dev)) { 80*d7869cecSEddie James ret = tpm1_physical_enable(dev); 81*d7869cecSEddie James if (ret != TPM_SUCCESS) { 82*d7869cecSEddie James log_err("TPM: Can't set enabled state\n"); 83*d7869cecSEddie James return ret; 84*d7869cecSEddie James } 85*d7869cecSEddie James 86*d7869cecSEddie James ret = tpm1_physical_set_deactivated(dev, 0); 87*d7869cecSEddie James if (ret != TPM_SUCCESS) { 88*d7869cecSEddie James log_err("TPM: Can't set deactivated state\n"); 89*d7869cecSEddie James return ret; 90*d7869cecSEddie James } 91*d7869cecSEddie James } 92*d7869cecSEddie James 93*d7869cecSEddie James return TPM_SUCCESS; 94*d7869cecSEddie James } 95*d7869cecSEddie James 96*d7869cecSEddie James u32 tpm_nv_enable_locking(struct udevice *dev) 97*d7869cecSEddie James { 98*d7869cecSEddie James if (tpm_is_v1(dev)) 99*d7869cecSEddie James return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0); 100*d7869cecSEddie James else if (tpm_is_v2(dev)) 101*d7869cecSEddie James return -ENOSYS; 102*d7869cecSEddie James else 103*d7869cecSEddie James return -ENOSYS; 104*d7869cecSEddie James } 105*d7869cecSEddie James 106*d7869cecSEddie James u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count) 107*d7869cecSEddie James { 108*d7869cecSEddie James if (tpm_is_v1(dev)) 109*d7869cecSEddie James return tpm1_nv_read_value(dev, index, data, count); 110*d7869cecSEddie James else if (tpm_is_v2(dev)) 111*d7869cecSEddie James return tpm2_nv_read_value(dev, index, data, count); 112*d7869cecSEddie James else 113*d7869cecSEddie James return -ENOSYS; 114*d7869cecSEddie James } 115*d7869cecSEddie James 116*d7869cecSEddie James u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data, 117*d7869cecSEddie James u32 count) 118*d7869cecSEddie James { 119*d7869cecSEddie James if (tpm_is_v1(dev)) 120*d7869cecSEddie James return tpm1_nv_write_value(dev, index, data, count); 121*d7869cecSEddie James else if (tpm_is_v2(dev)) 122*d7869cecSEddie James return tpm2_nv_write_value(dev, index, data, count); 123*d7869cecSEddie James else 124*d7869cecSEddie James return -ENOSYS; 125*d7869cecSEddie James } 126*d7869cecSEddie James 127*d7869cecSEddie James u32 tpm_set_global_lock(struct udevice *dev) 128*d7869cecSEddie James { 129*d7869cecSEddie James return tpm_nv_write_value(dev, TPM_NV_INDEX_0, NULL, 0); 130*d7869cecSEddie James } 131*d7869cecSEddie James 132*d7869cecSEddie James u32 tpm_write_lock(struct udevice *dev, u32 index) 133*d7869cecSEddie James { 134*d7869cecSEddie James if (tpm_is_v1(dev)) 135*d7869cecSEddie James return -ENOSYS; 136*d7869cecSEddie James else if (tpm_is_v2(dev)) 137*d7869cecSEddie James return tpm2_write_lock(dev, index); 138*d7869cecSEddie James else 139*d7869cecSEddie James return -ENOSYS; 140*d7869cecSEddie James } 141*d7869cecSEddie James 142*d7869cecSEddie James u32 tpm_pcr_extend(struct udevice *dev, u32 index, const void *in_digest, 143*d7869cecSEddie James uint size, void *out_digest, const char *name) 144*d7869cecSEddie James { 145*d7869cecSEddie James if (tpm_is_v1(dev)) { 146*d7869cecSEddie James return tpm1_extend(dev, index, in_digest, out_digest); 147*d7869cecSEddie James } else if (tpm_is_v2(dev)) { 148*d7869cecSEddie James return tpm2_pcr_extend(dev, index, TPM2_ALG_SHA256, in_digest, 149*d7869cecSEddie James TPM2_DIGEST_LEN); 150*d7869cecSEddie James /* @name is ignored as we do not support the TPM log here */ 151*d7869cecSEddie James } else { 152*d7869cecSEddie James return -ENOSYS; 153*d7869cecSEddie James } 154*d7869cecSEddie James } 155*d7869cecSEddie James 156*d7869cecSEddie James u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count) 157*d7869cecSEddie James { 158*d7869cecSEddie James if (tpm_is_v1(dev)) 159*d7869cecSEddie James return tpm1_pcr_read(dev, index, data, count); 160*d7869cecSEddie James else if (tpm_is_v2(dev)) 161*d7869cecSEddie James return -ENOSYS; 162*d7869cecSEddie James else 163*d7869cecSEddie James return -ENOSYS; 164*d7869cecSEddie James } 165*d7869cecSEddie James 166*d7869cecSEddie James u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence) 167*d7869cecSEddie James { 168*d7869cecSEddie James if (tpm_is_v1(dev)) 169*d7869cecSEddie James return tpm1_tsc_physical_presence(dev, presence); 170*d7869cecSEddie James 171*d7869cecSEddie James /* 172*d7869cecSEddie James * Nothing to do on TPM2 for this; use platform hierarchy availability 173*d7869cecSEddie James * instead. 174*d7869cecSEddie James */ 175*d7869cecSEddie James else if (tpm_is_v2(dev)) 176*d7869cecSEddie James return 0; 177*d7869cecSEddie James else 178*d7869cecSEddie James return -ENOSYS; 179*d7869cecSEddie James } 180*d7869cecSEddie James 181*d7869cecSEddie James u32 tpm_finalise_physical_presence(struct udevice *dev) 182*d7869cecSEddie James { 183*d7869cecSEddie James if (tpm_is_v1(dev)) 184*d7869cecSEddie James return tpm1_finalise_physical_presence(dev); 185*d7869cecSEddie James 186*d7869cecSEddie James /* Nothing needs to be done with tpm2 */ 187*d7869cecSEddie James else if (tpm_is_v2(dev)) 188*d7869cecSEddie James return 0; 189*d7869cecSEddie James else 190*d7869cecSEddie James return -ENOSYS; 191*d7869cecSEddie James } 192*d7869cecSEddie James 193*d7869cecSEddie James u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count) 194*d7869cecSEddie James { 195*d7869cecSEddie James if (tpm_is_v1(dev)) 196*d7869cecSEddie James return tpm1_read_pubek(dev, data, count); 197*d7869cecSEddie James else if (tpm_is_v2(dev)) 198*d7869cecSEddie James return -ENOSYS; /* not implemented yet */ 199*d7869cecSEddie James else 200*d7869cecSEddie James return -ENOSYS; 201*d7869cecSEddie James } 202*d7869cecSEddie James 203*d7869cecSEddie James u32 tpm_force_clear(struct udevice *dev) 204*d7869cecSEddie James { 205*d7869cecSEddie James if (tpm_is_v1(dev)) 206*d7869cecSEddie James return tpm1_force_clear(dev); 207*d7869cecSEddie James else if (tpm_is_v2(dev)) 208*d7869cecSEddie James return tpm2_clear(dev, TPM2_RH_PLATFORM, NULL, 0); 209*d7869cecSEddie James else 210*d7869cecSEddie James return -ENOSYS; 211*d7869cecSEddie James } 212*d7869cecSEddie James 213*d7869cecSEddie James u32 tpm_physical_enable(struct udevice *dev) 214*d7869cecSEddie James { 215*d7869cecSEddie James if (tpm_is_v1(dev)) 216*d7869cecSEddie James return tpm1_physical_enable(dev); 217*d7869cecSEddie James 218*d7869cecSEddie James /* Nothing needs to be done with tpm2 */ 219*d7869cecSEddie James else if (tpm_is_v2(dev)) 220*d7869cecSEddie James return 0; 221*d7869cecSEddie James else 222*d7869cecSEddie James return -ENOSYS; 223*d7869cecSEddie James } 224*d7869cecSEddie James 225*d7869cecSEddie James u32 tpm_physical_disable(struct udevice *dev) 226*d7869cecSEddie James { 227*d7869cecSEddie James if (tpm_is_v1(dev)) 228*d7869cecSEddie James return tpm1_physical_disable(dev); 229*d7869cecSEddie James 230*d7869cecSEddie James /* Nothing needs to be done with tpm2 */ 231*d7869cecSEddie James else if (tpm_is_v2(dev)) 232*d7869cecSEddie James return 0; 233*d7869cecSEddie James else 234*d7869cecSEddie James return -ENOSYS; 235*d7869cecSEddie James } 236*d7869cecSEddie James 237*d7869cecSEddie James u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state) 238*d7869cecSEddie James { 239*d7869cecSEddie James if (tpm_is_v1(dev)) 240*d7869cecSEddie James return tpm1_physical_set_deactivated(dev, state); 241*d7869cecSEddie James /* Nothing needs to be done with tpm2 */ 242*d7869cecSEddie James else if (tpm_is_v2(dev)) 243*d7869cecSEddie James return 0; 244*d7869cecSEddie James else 245*d7869cecSEddie James return -ENOSYS; 246*d7869cecSEddie James } 247*d7869cecSEddie James 248*d7869cecSEddie James u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap, 249*d7869cecSEddie James void *cap, size_t count) 250*d7869cecSEddie James { 251*d7869cecSEddie James if (tpm_is_v1(dev)) 252*d7869cecSEddie James return tpm1_get_capability(dev, cap_area, sub_cap, cap, count); 253*d7869cecSEddie James else if (tpm_is_v2(dev)) 254*d7869cecSEddie James return tpm2_get_capability(dev, cap_area, sub_cap, cap, count); 255*d7869cecSEddie James else 256*d7869cecSEddie James return -ENOSYS; 257*d7869cecSEddie James } 258*d7869cecSEddie James 259*d7869cecSEddie James u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm) 260*d7869cecSEddie James { 261*d7869cecSEddie James if (tpm_is_v1(dev)) 262*d7869cecSEddie James return tpm1_get_permissions(dev, index, perm); 263*d7869cecSEddie James else if (tpm_is_v2(dev)) 264*d7869cecSEddie James return -ENOSYS; /* not implemented yet */ 265*d7869cecSEddie James else 266*d7869cecSEddie James return -ENOSYS; 267*d7869cecSEddie James } 268*d7869cecSEddie James 269*d7869cecSEddie James u32 tpm_get_random(struct udevice *dev, void *data, u32 count) 270*d7869cecSEddie James { 271*d7869cecSEddie James if (tpm_is_v1(dev)) 272*d7869cecSEddie James return tpm1_get_random(dev, data, count); 273*d7869cecSEddie James else if (tpm_is_v2(dev)) 274*d7869cecSEddie James return tpm2_get_random(dev, data, count); 275*d7869cecSEddie James 276*d7869cecSEddie James return -ENOSYS; 277*d7869cecSEddie James } 278