1 // 2 // Copyright (C) 2014 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "trunks/error_codes.h" 18 19 #include <sstream> 20 #include <string> 21 22 #include <base/logging.h> 23 24 namespace { 25 26 // Masks out the P and N bits (see TPM 2.0 Part 2 Table 14). 27 const trunks::TPM_RC kFormatOneErrorMask = 0x0BF; 28 // Selects just the N bits that identify the subject index. 29 const trunks::TPM_RC kFormatOneSubjectMask = 0x700; 30 const trunks::TPM_RC kLayerMask = 0xFFFFF000; 31 32 // Returns a known error code or the empty string if unknown. 33 std::string GetErrorStringInternal(trunks::TPM_RC error) { 34 switch (error) { 35 case trunks::TPM_RC_SUCCESS: 36 return "TPM_RC_SUCCESS"; 37 case trunks::TPM_RC_BAD_TAG: 38 return "TPM_RC_BAD_TAG"; 39 case trunks::TPM_RC_INITIALIZE: 40 return "TPM_RC_INITIALIZE"; 41 case trunks::TPM_RC_FAILURE: 42 return "TPM_RC_FAILURE"; 43 case trunks::TPM_RC_SEQUENCE: 44 return "TPM_RC_SEQUENCE"; 45 case trunks::TPM_RC_PRIVATE: 46 return "TPM_RC_PRIVATE"; 47 case trunks::TPM_RC_HMAC: 48 return "TPM_RC_HMAC"; 49 case trunks::TPM_RC_DISABLED: 50 return "TPM_RC_DISABLED"; 51 case trunks::TPM_RC_EXCLUSIVE: 52 return "TPM_RC_EXCLUSIVE"; 53 case trunks::TPM_RC_AUTH_TYPE: 54 return "TPM_RC_AUTH_TYPE"; 55 case trunks::TPM_RC_AUTH_MISSING: 56 return "TPM_RC_AUTH_MISSING"; 57 case trunks::TPM_RC_POLICY: 58 return "TPM_RC_POLICY"; 59 case trunks::TPM_RC_PCR: 60 return "TPM_RC_PCR"; 61 case trunks::TPM_RC_PCR_CHANGED: 62 return "TPM_RC_PCR_CHANGED"; 63 case trunks::TPM_RC_UPGRADE: 64 return "TPM_RC_UPGRADE"; 65 case trunks::TPM_RC_TOO_MANY_CONTEXTS: 66 return "TPM_RC_TOO_MANY_CONTEXTS"; 67 case trunks::TPM_RC_AUTH_UNAVAILABLE: 68 return "TPM_RC_AUTH_UNAVAILABLE"; 69 case trunks::TPM_RC_REBOOT: 70 return "TPM_RC_REBOOT"; 71 case trunks::TPM_RC_UNBALANCED: 72 return "TPM_RC_UNBALANCED"; 73 case trunks::TPM_RC_COMMAND_SIZE: 74 return "TPM_RC_COMMAND_SIZE"; 75 case trunks::TPM_RC_COMMAND_CODE: 76 return "TPM_RC_COMMAND_CODE"; 77 case trunks::TPM_RC_AUTHSIZE: 78 return "TPM_RC_AUTHSIZE"; 79 case trunks::TPM_RC_AUTH_CONTEXT: 80 return "TPM_RC_AUTH_CONTEXT"; 81 case trunks::TPM_RC_NV_RANGE: 82 return "TPM_RC_NV_RANGE"; 83 case trunks::TPM_RC_NV_SIZE: 84 return "TPM_RC_NV_SIZE"; 85 case trunks::TPM_RC_NV_LOCKED: 86 return "TPM_RC_NV_LOCKED"; 87 case trunks::TPM_RC_NV_AUTHORIZATION: 88 return "TPM_RC_NV_AUTHORIZATION"; 89 case trunks::TPM_RC_NV_UNINITIALIZED: 90 return "TPM_RC_NV_UNINITIALIZED"; 91 case trunks::TPM_RC_NV_SPACE: 92 return "TPM_RC_NV_SPACE"; 93 case trunks::TPM_RC_NV_DEFINED: 94 return "TPM_RC_NV_DEFINED"; 95 case trunks::TPM_RC_BAD_CONTEXT: 96 return "TPM_RC_BAD_CONTEXT"; 97 case trunks::TPM_RC_CPHASH: 98 return "TPM_RC_CPHASH"; 99 case trunks::TPM_RC_PARENT: 100 return "TPM_RC_PARENT"; 101 case trunks::TPM_RC_NEEDS_TEST: 102 return "TPM_RC_NEEDS_TEST"; 103 case trunks::TPM_RC_NO_RESULT: 104 return "TPM_RC_NO_RESULT"; 105 case trunks::TPM_RC_SENSITIVE: 106 return "TPM_RC_SENSITIVE"; 107 case trunks::TPM_RC_ASYMMETRIC: 108 return "TPM_RC_ASYMMETRIC"; 109 case trunks::TPM_RC_ATTRIBUTES: 110 return "TPM_RC_ATTRIBUTES"; 111 case trunks::TPM_RC_HASH: 112 return "TPM_RC_HASH"; 113 case trunks::TPM_RC_VALUE: 114 return "TPM_RC_VALUE"; 115 case trunks::TPM_RC_HIERARCHY: 116 return "TPM_RC_HIERARCHY"; 117 case trunks::TPM_RC_KEY_SIZE: 118 return "TPM_RC_KEY_SIZE"; 119 case trunks::TPM_RC_MGF: 120 return "TPM_RC_MGF"; 121 case trunks::TPM_RC_MODE: 122 return "TPM_RC_MODE"; 123 case trunks::TPM_RC_TYPE: 124 return "TPM_RC_TYPE"; 125 case trunks::TPM_RC_HANDLE: 126 return "TPM_RC_HANDLE"; 127 case trunks::TPM_RC_KDF: 128 return "TPM_RC_KDF"; 129 case trunks::TPM_RC_RANGE: 130 return "TPM_RC_RANGE"; 131 case trunks::TPM_RC_AUTH_FAIL: 132 return "TPM_RC_AUTH_FAIL"; 133 case trunks::TPM_RC_NONCE: 134 return "TPM_RC_NONCE"; 135 case trunks::TPM_RC_PP: 136 return "TPM_RC_PP"; 137 case trunks::TPM_RC_SCHEME: 138 return "TPM_RC_SCHEME"; 139 case trunks::TPM_RC_SIZE: 140 return "TPM_RC_SIZE"; 141 case trunks::TPM_RC_SYMMETRIC: 142 return "TPM_RC_SYMMETRIC"; 143 case trunks::TPM_RC_TAG: 144 return "TPM_RC_TAG"; 145 case trunks::TPM_RC_SELECTOR: 146 return "TPM_RC_SELECTOR"; 147 case trunks::TPM_RC_INSUFFICIENT: 148 return "TPM_RC_INSUFFICIENT"; 149 case trunks::TPM_RC_SIGNATURE: 150 return "TPM_RC_SIGNATURE"; 151 case trunks::TPM_RC_KEY: 152 return "TPM_RC_KEY"; 153 case trunks::TPM_RC_POLICY_FAIL: 154 return "TPM_RC_POLICY_FAIL"; 155 case trunks::TPM_RC_INTEGRITY: 156 return "TPM_RC_INTEGRITY"; 157 case trunks::TPM_RC_TICKET: 158 return "TPM_RC_TICKET"; 159 case trunks::TPM_RC_RESERVED_BITS: 160 return "TPM_RC_RESERVED_BITS"; 161 case trunks::TPM_RC_BAD_AUTH: 162 return "TPM_RC_BAD_AUTH"; 163 case trunks::TPM_RC_EXPIRED: 164 return "TPM_RC_EXPIRED"; 165 case trunks::TPM_RC_POLICY_CC: 166 return "TPM_RC_POLICY_CC"; 167 case trunks::TPM_RC_BINDING: 168 return "TPM_RC_BINDING"; 169 case trunks::TPM_RC_CURVE: 170 return "TPM_RC_CURVE"; 171 case trunks::TPM_RC_ECC_POINT: 172 return "TPM_RC_ECC_POINT"; 173 case trunks::TPM_RC_CONTEXT_GAP: 174 return "TPM_RC_CONTEXT_GAP"; 175 case trunks::TPM_RC_OBJECT_MEMORY: 176 return "TPM_RC_OBJECT_MEMORY"; 177 case trunks::TPM_RC_SESSION_MEMORY: 178 return "TPM_RC_SESSION_MEMORY"; 179 case trunks::TPM_RC_MEMORY: 180 return "TPM_RC_MEMORY"; 181 case trunks::TPM_RC_SESSION_HANDLES: 182 return "TPM_RC_SESSION_HANDLES"; 183 case trunks::TPM_RC_OBJECT_HANDLES: 184 return "TPM_RC_OBJECT_HANDLES"; 185 case trunks::TPM_RC_LOCALITY: 186 return "TPM_RC_LOCALITY"; 187 case trunks::TPM_RC_YIELDED: 188 return "TPM_RC_YIELDED"; 189 case trunks::TPM_RC_CANCELED: 190 return "TPM_RC_CANCELED"; 191 case trunks::TPM_RC_TESTING: 192 return "TPM_RC_TESTING"; 193 case trunks::TPM_RC_REFERENCE_H0: 194 return "TPM_RC_REFERENCE_H0"; 195 case trunks::TPM_RC_REFERENCE_H1: 196 return "TPM_RC_REFERENCE_H1"; 197 case trunks::TPM_RC_REFERENCE_H2: 198 return "TPM_RC_REFERENCE_H2"; 199 case trunks::TPM_RC_REFERENCE_H3: 200 return "TPM_RC_REFERENCE_H3"; 201 case trunks::TPM_RC_REFERENCE_H4: 202 return "TPM_RC_REFERENCE_H4"; 203 case trunks::TPM_RC_REFERENCE_H5: 204 return "TPM_RC_REFERENCE_H5"; 205 case trunks::TPM_RC_REFERENCE_H6: 206 return "TPM_RC_REFERENCE_H6"; 207 case trunks::TPM_RC_REFERENCE_S0: 208 return "TPM_RC_REFERENCE_S0"; 209 case trunks::TPM_RC_REFERENCE_S1: 210 return "TPM_RC_REFERENCE_S1"; 211 case trunks::TPM_RC_REFERENCE_S2: 212 return "TPM_RC_REFERENCE_S2"; 213 case trunks::TPM_RC_REFERENCE_S3: 214 return "TPM_RC_REFERENCE_S3"; 215 case trunks::TPM_RC_REFERENCE_S4: 216 return "TPM_RC_REFERENCE_S4"; 217 case trunks::TPM_RC_REFERENCE_S5: 218 return "TPM_RC_REFERENCE_S5"; 219 case trunks::TPM_RC_REFERENCE_S6: 220 return "TPM_RC_REFERENCE_S6"; 221 case trunks::TPM_RC_NV_RATE: 222 return "TPM_RC_NV_RATE"; 223 case trunks::TPM_RC_LOCKOUT: 224 return "TPM_RC_LOCKOUT"; 225 case trunks::TPM_RC_RETRY: 226 return "TPM_RC_RETRY"; 227 case trunks::TPM_RC_NV_UNAVAILABLE: 228 return "TPM_RC_NV_UNAVAILABLE"; 229 case trunks::TPM_RC_NOT_USED: 230 return "TPM_RC_NOT_USED"; 231 case trunks::TRUNKS_RC_AUTHORIZATION_FAILED: 232 return "TRUNKS_RC_AUTHORIZATION_FAILED"; 233 case trunks::TRUNKS_RC_ENCRYPTION_FAILED: 234 return "TRUNKS_RC_ENCRYPTION_FAILED"; 235 case trunks::TRUNKS_RC_READ_ERROR: 236 return "TRUNKS_RC_READ_ERROR"; 237 case trunks::TRUNKS_RC_WRITE_ERROR: 238 return "TRUNKS_RC_WRITE_ERROR"; 239 case trunks::TRUNKS_RC_IPC_ERROR: 240 return "TRUNKS_RC_IPC_ERROR"; 241 case trunks::TRUNKS_RC_SESSION_SETUP_ERROR: 242 return "TRUNKS_RC_SESSION_SETUP_ERROR"; 243 case trunks::TCTI_RC_TRY_AGAIN: 244 return "TCTI_RC_TRY_AGAIN"; 245 case trunks::TCTI_RC_GENERAL_FAILURE: 246 return "TCTI_RC_GENERAL_FAILURE"; 247 case trunks::TCTI_RC_BAD_CONTEXT: 248 return "TCTI_RC_BAD_CONTEXT"; 249 case trunks::TCTI_RC_WRONG_ABI_VERSION: 250 return "TCTI_RC_WRONG_ABI_VERSION"; 251 case trunks::TCTI_RC_NOT_IMPLEMENTED: 252 return "TCTI_RC_NOT_IMPLEMENTED"; 253 case trunks::TCTI_RC_BAD_PARAMETER: 254 return "TCTI_RC_BAD_PARAMETER"; 255 case trunks::TCTI_RC_INSUFFICIENT_BUFFER: 256 return "TCTI_RC_INSUFFICIENT_BUFFER"; 257 case trunks::TCTI_RC_NO_CONNECTION: 258 return "TCTI_RC_NO_CONNECTION"; 259 case trunks::TCTI_RC_DRIVER_NOT_FOUND: 260 return "TCTI_RC_DRIVER_NOT_FOUND"; 261 case trunks::TCTI_RC_DRIVERINFO_NOT_FOUND: 262 return "TCTI_RC_DRIVERINFO_NOT_FOUND"; 263 case trunks::TCTI_RC_NO_RESPONSE: 264 return "TCTI_RC_NO_RESPONSE"; 265 case trunks::TCTI_RC_BAD_VALUE: 266 return "TCTI_RC_BAD_VALUE"; 267 case trunks::SAPI_RC_INVALID_SESSIONS: 268 return "SAPI_RC_INVALID_SESSIONS"; 269 case trunks::SAPI_RC_ABI_MISMATCH: 270 return "SAPI_RC_ABI_MISMATCH"; 271 case trunks::SAPI_RC_INSUFFICIENT_BUFFER: 272 return "SAPI_RC_INSUFFICIENT_BUFFER"; 273 case trunks::SAPI_RC_BAD_PARAMETER: 274 return "SAPI_RC_BAD_PARAMETER"; 275 case trunks::SAPI_RC_BAD_SEQUENCE: 276 return "SAPI_RC_BAD_SEQUENCE"; 277 case trunks::SAPI_RC_NO_DECRYPT_PARAM: 278 return "SAPI_RC_NO_DECRYPT_PARAM"; 279 case trunks::SAPI_RC_NO_ENCRYPT_PARAM: 280 return "SAPI_RC_NO_ENCRYPT_PARAM"; 281 case trunks::SAPI_RC_NO_RESPONSE_RECEIVED: 282 return "SAPI_RC_NO_RESPONSE_RECEIVED"; 283 case trunks::SAPI_RC_BAD_SIZE: 284 return "SAPI_RC_BAD_SIZE"; 285 case trunks::SAPI_RC_CORRUPTED_DATA: 286 return "SAPI_RC_CORRUPTED_DATA"; 287 case trunks::SAPI_RC_INSUFFICIENT_CONTEXT: 288 return "SAPI_RC_INSUFFICIENT_CONTEXT"; 289 case trunks::SAPI_RC_INSUFFICIENT_RESPONSE: 290 return "SAPI_RC_INSUFFICIENT_RESPONSE"; 291 case trunks::SAPI_RC_INCOMPATIBLE_TCTI: 292 return "SAPI_RC_INCOMPATIBLE_TCTI"; 293 case trunks::SAPI_RC_MALFORMED_RESPONSE: 294 return "SAPI_RC_MALFORMED_RESPONSE"; 295 case trunks::SAPI_RC_BAD_TCTI_STRUCTURE: 296 return "SAPI_RC_BAD_TCTI_STRUCTURE"; 297 default: 298 return std::string(); 299 } 300 NOTREACHED(); 301 return std::string(); 302 } 303 304 bool IsFormatOne(trunks::TPM_RC error) { 305 return (error & kLayerMask) == 0 && (error & trunks::RC_FMT1) != 0; 306 } 307 308 } // namespace 309 310 namespace trunks { 311 312 std::string GetErrorString(TPM_RC error) { 313 std::string error_string = GetErrorStringInternal(error); 314 if (!error_string.empty()) { 315 return error_string; 316 } 317 std::stringstream ss; 318 if ((error & kLayerMask) == kResourceManagerTpmErrorBase) { 319 error &= ~kLayerMask; 320 error_string = GetErrorStringInternal(error); 321 ss << "Resource Manager: "; 322 } 323 // Check if we have a TPM 'Format-One' response code. 324 if (IsFormatOne(error)) { 325 if (error & TPM_RC_P) { 326 ss << "Parameter "; 327 } else if (error & TPM_RC_S) { 328 ss << "Session "; 329 } else { 330 ss << "Handle "; 331 } 332 // Bits 8-10 specify which handle / parameter / session. 333 ss << ((error & kFormatOneSubjectMask) >> 8) << ": "; 334 // Mask out everything but the format bit and error number. 335 error_string = GetErrorStringInternal(error & kFormatOneErrorMask); 336 if (!error_string.empty()) { 337 ss << error_string; 338 } 339 } 340 if (error_string.empty()) { 341 ss << "Unknown error: " << error << " (0x" << std::hex << error << ")"; 342 } 343 return ss.str(); 344 } 345 346 TPM_RC GetFormatOneError(TPM_RC error) { 347 if (IsFormatOne(error)) { 348 return (error & kFormatOneErrorMask); 349 } 350 return error; 351 } 352 353 std::string CreateErrorResponse(TPM_RC error_code) { 354 const uint32_t kErrorResponseSize = 10; 355 std::string response; 356 CHECK_EQ(Serialize_TPM_ST(TPM_ST_NO_SESSIONS, &response), TPM_RC_SUCCESS); 357 CHECK_EQ(Serialize_UINT32(kErrorResponseSize, &response), TPM_RC_SUCCESS); 358 CHECK_EQ(Serialize_TPM_RC(error_code, &response), TPM_RC_SUCCESS); 359 return response; 360 } 361 362 } // namespace trunks 363