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:
     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