Home | History | Annotate | Download | only in trunks
      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: return "TPM_RC_SUCCESS";
     36     case trunks::TPM_RC_BAD_TAG: return "TPM_RC_BAD_TAG";
     37     case trunks::TPM_RC_INITIALIZE: return "TPM_RC_INITIALIZE";
     38     case trunks::TPM_RC_FAILURE: return "TPM_RC_FAILURE";
     39     case trunks::TPM_RC_SEQUENCE: return "TPM_RC_SEQUENCE";
     40     case trunks::TPM_RC_PRIVATE: return "TPM_RC_PRIVATE";
     41     case trunks::TPM_RC_HMAC: return "TPM_RC_HMAC";
     42     case trunks::TPM_RC_DISABLED: return "TPM_RC_DISABLED";
     43     case trunks::TPM_RC_EXCLUSIVE: return "TPM_RC_EXCLUSIVE";
     44     case trunks::TPM_RC_AUTH_TYPE: return "TPM_RC_AUTH_TYPE";
     45     case trunks::TPM_RC_AUTH_MISSING: return "TPM_RC_AUTH_MISSING";
     46     case trunks::TPM_RC_POLICY: return "TPM_RC_POLICY";
     47     case trunks::TPM_RC_PCR: return "TPM_RC_PCR";
     48     case trunks::TPM_RC_PCR_CHANGED: return "TPM_RC_PCR_CHANGED";
     49     case trunks::TPM_RC_UPGRADE: return "TPM_RC_UPGRADE";
     50     case trunks::TPM_RC_TOO_MANY_CONTEXTS: return "TPM_RC_TOO_MANY_CONTEXTS";
     51     case trunks::TPM_RC_AUTH_UNAVAILABLE: return "TPM_RC_AUTH_UNAVAILABLE";
     52     case trunks::TPM_RC_REBOOT: return "TPM_RC_REBOOT";
     53     case trunks::TPM_RC_UNBALANCED: return "TPM_RC_UNBALANCED";
     54     case trunks::TPM_RC_COMMAND_SIZE: return "TPM_RC_COMMAND_SIZE";
     55     case trunks::TPM_RC_COMMAND_CODE: return "TPM_RC_COMMAND_CODE";
     56     case trunks::TPM_RC_AUTHSIZE: return "TPM_RC_AUTHSIZE";
     57     case trunks::TPM_RC_AUTH_CONTEXT: return "TPM_RC_AUTH_CONTEXT";
     58     case trunks::TPM_RC_NV_RANGE: return "TPM_RC_NV_RANGE";
     59     case trunks::TPM_RC_NV_SIZE: return "TPM_RC_NV_SIZE";
     60     case trunks::TPM_RC_NV_LOCKED: return "TPM_RC_NV_LOCKED";
     61     case trunks::TPM_RC_NV_AUTHORIZATION: return "TPM_RC_NV_AUTHORIZATION";
     62     case trunks::TPM_RC_NV_UNINITIALIZED: return "TPM_RC_NV_UNINITIALIZED";
     63     case trunks::TPM_RC_NV_SPACE: return "TPM_RC_NV_SPACE";
     64     case trunks::TPM_RC_NV_DEFINED: return "TPM_RC_NV_DEFINED";
     65     case trunks::TPM_RC_BAD_CONTEXT: return "TPM_RC_BAD_CONTEXT";
     66     case trunks::TPM_RC_CPHASH: return "TPM_RC_CPHASH";
     67     case trunks::TPM_RC_PARENT: return "TPM_RC_PARENT";
     68     case trunks::TPM_RC_NEEDS_TEST: return "TPM_RC_NEEDS_TEST";
     69     case trunks::TPM_RC_NO_RESULT: return "TPM_RC_NO_RESULT";
     70     case trunks::TPM_RC_SENSITIVE: return "TPM_RC_SENSITIVE";
     71     case trunks::TPM_RC_ASYMMETRIC: return "TPM_RC_ASYMMETRIC";
     72     case trunks::TPM_RC_ATTRIBUTES: return "TPM_RC_ATTRIBUTES";
     73     case trunks::TPM_RC_HASH: return "TPM_RC_HASH";
     74     case trunks::TPM_RC_VALUE: return "TPM_RC_VALUE";
     75     case trunks::TPM_RC_HIERARCHY: return "TPM_RC_HIERARCHY";
     76     case trunks::TPM_RC_KEY_SIZE: return "TPM_RC_KEY_SIZE";
     77     case trunks::TPM_RC_MGF: return "TPM_RC_MGF";
     78     case trunks::TPM_RC_MODE: return "TPM_RC_MODE";
     79     case trunks::TPM_RC_TYPE: return "TPM_RC_TYPE";
     80     case trunks::TPM_RC_HANDLE: return "TPM_RC_HANDLE";
     81     case trunks::TPM_RC_KDF: return "TPM_RC_KDF";
     82     case trunks::TPM_RC_RANGE: return "TPM_RC_RANGE";
     83     case trunks::TPM_RC_AUTH_FAIL: return "TPM_RC_AUTH_FAIL";
     84     case trunks::TPM_RC_NONCE: return "TPM_RC_NONCE";
     85     case trunks::TPM_RC_PP: return "TPM_RC_PP";
     86     case trunks::TPM_RC_SCHEME: return "TPM_RC_SCHEME";
     87     case trunks::TPM_RC_SIZE: return "TPM_RC_SIZE";
     88     case trunks::TPM_RC_SYMMETRIC: return "TPM_RC_SYMMETRIC";
     89     case trunks::TPM_RC_TAG: return "TPM_RC_TAG";
     90     case trunks::TPM_RC_SELECTOR: return "TPM_RC_SELECTOR";
     91     case trunks::TPM_RC_INSUFFICIENT: return "TPM_RC_INSUFFICIENT";
     92     case trunks::TPM_RC_SIGNATURE: return "TPM_RC_SIGNATURE";
     93     case trunks::TPM_RC_KEY: return "TPM_RC_KEY";
     94     case trunks::TPM_RC_POLICY_FAIL: return "TPM_RC_POLICY_FAIL";
     95     case trunks::TPM_RC_INTEGRITY: return "TPM_RC_INTEGRITY";
     96     case trunks::TPM_RC_TICKET: return "TPM_RC_TICKET";
     97     case trunks::TPM_RC_RESERVED_BITS: return "TPM_RC_RESERVED_BITS";
     98     case trunks::TPM_RC_BAD_AUTH: return "TPM_RC_BAD_AUTH";
     99     case trunks::TPM_RC_EXPIRED: return "TPM_RC_EXPIRED";
    100     case trunks::TPM_RC_POLICY_CC: return "TPM_RC_POLICY_CC";
    101     case trunks::TPM_RC_BINDING: return "TPM_RC_BINDING";
    102     case trunks::TPM_RC_CURVE: return "TPM_RC_CURVE";
    103     case trunks::TPM_RC_ECC_POINT: return "TPM_RC_ECC_POINT";
    104     case trunks::TPM_RC_CONTEXT_GAP: return "TPM_RC_CONTEXT_GAP";
    105     case trunks::TPM_RC_OBJECT_MEMORY: return "TPM_RC_OBJECT_MEMORY";
    106     case trunks::TPM_RC_SESSION_MEMORY: return "TPM_RC_SESSION_MEMORY";
    107     case trunks::TPM_RC_MEMORY: return "TPM_RC_MEMORY";
    108     case trunks::TPM_RC_SESSION_HANDLES: return "TPM_RC_SESSION_HANDLES";
    109     case trunks::TPM_RC_OBJECT_HANDLES: return "TPM_RC_OBJECT_HANDLES";
    110     case trunks::TPM_RC_LOCALITY: return "TPM_RC_LOCALITY";
    111     case trunks::TPM_RC_YIELDED: return "TPM_RC_YIELDED";
    112     case trunks::TPM_RC_CANCELED: return "TPM_RC_CANCELED";
    113     case trunks::TPM_RC_TESTING: return "TPM_RC_TESTING";
    114     case trunks::TPM_RC_REFERENCE_H0: return "TPM_RC_REFERENCE_H0";
    115     case trunks::TPM_RC_REFERENCE_H1: return "TPM_RC_REFERENCE_H1";
    116     case trunks::TPM_RC_REFERENCE_H2: return "TPM_RC_REFERENCE_H2";
    117     case trunks::TPM_RC_REFERENCE_H3: return "TPM_RC_REFERENCE_H3";
    118     case trunks::TPM_RC_REFERENCE_H4: return "TPM_RC_REFERENCE_H4";
    119     case trunks::TPM_RC_REFERENCE_H5: return "TPM_RC_REFERENCE_H5";
    120     case trunks::TPM_RC_REFERENCE_H6: return "TPM_RC_REFERENCE_H6";
    121     case trunks::TPM_RC_REFERENCE_S0: return "TPM_RC_REFERENCE_S0";
    122     case trunks::TPM_RC_REFERENCE_S1: return "TPM_RC_REFERENCE_S1";
    123     case trunks::TPM_RC_REFERENCE_S2: return "TPM_RC_REFERENCE_S2";
    124     case trunks::TPM_RC_REFERENCE_S3: return "TPM_RC_REFERENCE_S3";
    125     case trunks::TPM_RC_REFERENCE_S4: return "TPM_RC_REFERENCE_S4";
    126     case trunks::TPM_RC_REFERENCE_S5: return "TPM_RC_REFERENCE_S5";
    127     case trunks::TPM_RC_REFERENCE_S6: return "TPM_RC_REFERENCE_S6";
    128     case trunks::TPM_RC_NV_RATE: return "TPM_RC_NV_RATE";
    129     case trunks::TPM_RC_LOCKOUT: return "TPM_RC_LOCKOUT";
    130     case trunks::TPM_RC_RETRY: return "TPM_RC_RETRY";
    131     case trunks::TPM_RC_NV_UNAVAILABLE: return "TPM_RC_NV_UNAVAILABLE";
    132     case trunks::TPM_RC_NOT_USED: return "TPM_RC_NOT_USED";
    133     case trunks::TRUNKS_RC_AUTHORIZATION_FAILED:
    134       return "TRUNKS_RC_AUTHORIZATION_FAILED";
    135     case trunks::TRUNKS_RC_ENCRYPTION_FAILED:
    136       return "TRUNKS_RC_ENCRYPTION_FAILED";
    137     case trunks::TRUNKS_RC_READ_ERROR: return "TRUNKS_RC_READ_ERROR";
    138     case trunks::TRUNKS_RC_WRITE_ERROR: return "TRUNKS_RC_WRITE_ERROR";
    139     case trunks::TRUNKS_RC_IPC_ERROR: return "TRUNKS_RC_IPC_ERROR";
    140     case trunks::TCTI_RC_TRY_AGAIN: return "TCTI_RC_TRY_AGAIN";
    141     case trunks::TCTI_RC_GENERAL_FAILURE: return "TCTI_RC_GENERAL_FAILURE";
    142     case trunks::TCTI_RC_BAD_CONTEXT: return "TCTI_RC_BAD_CONTEXT";
    143     case trunks::TCTI_RC_WRONG_ABI_VERSION: return "TCTI_RC_WRONG_ABI_VERSION";
    144     case trunks::TCTI_RC_NOT_IMPLEMENTED: return "TCTI_RC_NOT_IMPLEMENTED";
    145     case trunks::TCTI_RC_BAD_PARAMETER: return "TCTI_RC_BAD_PARAMETER";
    146     case trunks::TCTI_RC_INSUFFICIENT_BUFFER:
    147       return "TCTI_RC_INSUFFICIENT_BUFFER";
    148     case trunks::TCTI_RC_NO_CONNECTION: return "TCTI_RC_NO_CONNECTION";
    149     case trunks::TCTI_RC_DRIVER_NOT_FOUND: return "TCTI_RC_DRIVER_NOT_FOUND";
    150     case trunks::TCTI_RC_DRIVERINFO_NOT_FOUND:
    151       return "TCTI_RC_DRIVERINFO_NOT_FOUND";
    152     case trunks::TCTI_RC_NO_RESPONSE: return "TCTI_RC_NO_RESPONSE";
    153     case trunks::TCTI_RC_BAD_VALUE: return "TCTI_RC_BAD_VALUE";
    154     case trunks::SAPI_RC_INVALID_SESSIONS: return "SAPI_RC_INVALID_SESSIONS";
    155     case trunks::SAPI_RC_ABI_MISMATCH: return "SAPI_RC_ABI_MISMATCH";
    156     case trunks::SAPI_RC_INSUFFICIENT_BUFFER:
    157       return "SAPI_RC_INSUFFICIENT_BUFFER";
    158     case trunks::SAPI_RC_BAD_PARAMETER: return "SAPI_RC_BAD_PARAMETER";
    159     case trunks::SAPI_RC_BAD_SEQUENCE: return "SAPI_RC_BAD_SEQUENCE";
    160     case trunks::SAPI_RC_NO_DECRYPT_PARAM: return "SAPI_RC_NO_DECRYPT_PARAM";
    161     case trunks::SAPI_RC_NO_ENCRYPT_PARAM: return "SAPI_RC_NO_ENCRYPT_PARAM";
    162     case trunks::SAPI_RC_NO_RESPONSE_RECEIVED:
    163       return "SAPI_RC_NO_RESPONSE_RECEIVED";
    164     case trunks::SAPI_RC_BAD_SIZE: return "SAPI_RC_BAD_SIZE";
    165     case trunks::SAPI_RC_CORRUPTED_DATA: return "SAPI_RC_CORRUPTED_DATA";
    166     case trunks::SAPI_RC_INSUFFICIENT_CONTEXT:
    167       return "SAPI_RC_INSUFFICIENT_CONTEXT";
    168     case trunks::SAPI_RC_INSUFFICIENT_RESPONSE:
    169       return "SAPI_RC_INSUFFICIENT_RESPONSE";
    170     case trunks::SAPI_RC_INCOMPATIBLE_TCTI: return "SAPI_RC_INCOMPATIBLE_TCTI";
    171     case trunks::SAPI_RC_MALFORMED_RESPONSE:
    172       return "SAPI_RC_MALFORMED_RESPONSE";
    173     case trunks::SAPI_RC_BAD_TCTI_STRUCTURE:
    174       return "SAPI_RC_BAD_TCTI_STRUCTURE";
    175     default: return std::string();
    176   }
    177   NOTREACHED();
    178   return std::string();
    179 }
    180 
    181 bool IsFormatOne(trunks::TPM_RC error) {
    182   return (error & kLayerMask) == 0 && (error & trunks::RC_FMT1) != 0;
    183 }
    184 
    185 }  // namespace
    186 
    187 namespace trunks {
    188 
    189 std::string GetErrorString(TPM_RC error) {
    190   std::string error_string = GetErrorStringInternal(error);
    191   if (!error_string.empty()) {
    192     return error_string;
    193   }
    194   std::stringstream ss;
    195   if ((error & kLayerMask) == kResourceManagerTpmErrorBase) {
    196     error &= ~kLayerMask;
    197     error_string = GetErrorStringInternal(error);
    198     ss << "Resource Manager: ";
    199   }
    200   // Check if we have a TPM 'Format-One' response code.
    201   if (IsFormatOne(error)) {
    202     if (error & TPM_RC_P) {
    203       ss << "Parameter ";
    204     } else if (error & TPM_RC_S) {
    205       ss << "Session ";
    206     } else {
    207       ss << "Handle ";
    208     }
    209     // Bits 8-10 specify which handle / parameter / session.
    210     ss << ((error & kFormatOneSubjectMask) >> 8) << ": ";
    211     // Mask out everything but the format bit and error number.
    212     error_string = GetErrorStringInternal(error & kFormatOneErrorMask);
    213     if (!error_string.empty()) {
    214       ss << error_string;
    215     }
    216   }
    217   if (error_string.empty()) {
    218     ss << "Unknown error: " << error << " (0x" << std::hex << error << ")";
    219   }
    220   return ss.str();
    221 }
    222 
    223 TPM_RC GetFormatOneError(TPM_RC error) {
    224   if (IsFormatOne(error)) {
    225     return (error & kFormatOneErrorMask);
    226   }
    227   return error;
    228 }
    229 
    230 std::string CreateErrorResponse(TPM_RC error_code) {
    231   const uint32_t kErrorResponseSize = 10;
    232   std::string response;
    233   CHECK_EQ(Serialize_TPM_ST(TPM_ST_NO_SESSIONS, &response), TPM_RC_SUCCESS);
    234   CHECK_EQ(Serialize_UINT32(kErrorResponseSize, &response), TPM_RC_SUCCESS);
    235   CHECK_EQ(Serialize_TPM_RC(error_code, &response), TPM_RC_SUCCESS);
    236   return response;
    237 }
    238 
    239 }  // namespace trunks
    240