| /* |
| * Copyright 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "proto_utils.h" |
| |
| #include <android-base/logging.h> |
| #include <android/hardware/keymaster/4.0/types.h> |
| #include <keymasterV4_0/key_param_output.h> |
| |
| namespace android { |
| namespace hardware { |
| namespace keymaster { |
| |
| // HAL |
| using ::android::hardware::keymaster::V4_0::Algorithm; |
| using ::android::hardware::keymaster::V4_0::BlockMode; |
| using ::android::hardware::keymaster::V4_0::Digest; |
| using ::android::hardware::keymaster::V4_0::EcCurve; |
| using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType; |
| using ::android::hardware::keymaster::V4_0::KeyDerivationFunction; |
| using ::android::hardware::keymaster::V4_0::KeyOrigin; |
| using ::android::hardware::keymaster::V4_0::KeyPurpose; |
| using ::android::hardware::keymaster::V4_0::KeyBlobUsageRequirements; |
| using ::android::hardware::keymaster::V4_0::PaddingMode; |
| using ::android::hardware::keymaster::V4_0::Tag; |
| using ::android::hardware::keymaster::V4_0::TagType; |
| |
| static TagType type_from_tag(Tag tag) |
| { |
| return static_cast<TagType>(tag & (0xF << 28)); |
| } |
| |
| static nosapp::TagType type_from_tag(nosapp::Tag tag) |
| { |
| return static_cast<nosapp::TagType>(tag & (0xF << 16)); |
| } |
| |
| static nosapp::Tag translate_tag(Tag tag) |
| { |
| enum TagType tag_type = type_from_tag(tag); |
| |
| /* TODO: This is gross. The alternative is to have a complete table. */ |
| return static_cast<nosapp::Tag>( |
| (((uint32_t)tag_type >> 28) << 16) | (tag & 0xffff)); |
| } |
| |
| static Tag translate_tag(nosapp::Tag tag) |
| { |
| enum nosapp::TagType tag_type = type_from_tag(tag); |
| |
| /* TODO: This is gross. The alternative is to have a complete table. */ |
| return static_cast<Tag>( |
| (((uint32_t)tag_type >> 16) << 28) | (tag & 0xffff)); |
| } |
| |
| static nosapp::KeyPurpose translate_purpose(KeyPurpose purpose) |
| { |
| switch (purpose) { |
| case KeyPurpose::ENCRYPT: |
| return nosapp::KeyPurpose::ENCRYPT; |
| case KeyPurpose::DECRYPT: |
| return nosapp::KeyPurpose::DECRYPT; |
| case KeyPurpose::SIGN: |
| return nosapp::KeyPurpose::SIGN; |
| case KeyPurpose::VERIFY: |
| return nosapp::KeyPurpose::VERIFY; |
| case KeyPurpose::WRAP_KEY: |
| return nosapp::KeyPurpose::WRAP_KEY; |
| default: |
| return nosapp::KeyPurpose::PURPOSE_MAX; |
| } |
| } |
| |
| static ErrorCode translate_purpose(nosapp::KeyPurpose purpose, KeyPurpose *out) |
| { |
| switch (purpose) { |
| case nosapp::KeyPurpose::ENCRYPT: |
| *out = KeyPurpose::ENCRYPT; |
| break; |
| case nosapp::KeyPurpose::DECRYPT: |
| *out = KeyPurpose::DECRYPT; |
| break; |
| case nosapp::KeyPurpose::SIGN: |
| *out = KeyPurpose::SIGN; |
| break; |
| case nosapp::KeyPurpose::VERIFY: |
| *out = KeyPurpose::VERIFY; |
| break; |
| case nosapp::KeyPurpose::WRAP_KEY: |
| *out = KeyPurpose::WRAP_KEY; |
| break; |
| default: |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| static nosapp::Algorithm translate_algorithm(Algorithm algorithm) |
| { |
| switch (algorithm) { |
| case Algorithm::RSA: |
| return nosapp::Algorithm::RSA; |
| case Algorithm::EC: |
| return nosapp::Algorithm::EC; |
| case Algorithm::AES: |
| return nosapp::Algorithm::AES; |
| case Algorithm::TRIPLE_DES: |
| return nosapp::Algorithm::DES; |
| case Algorithm::HMAC: |
| return nosapp::Algorithm::HMAC; |
| default: |
| return nosapp::Algorithm::ALGORITHM_MAX; |
| } |
| } |
| |
| ErrorCode translate_algorithm(nosapp::Algorithm algorithm, |
| Algorithm *out) |
| { |
| switch (algorithm) { |
| case nosapp::Algorithm::RSA: |
| *out = Algorithm::RSA; |
| break; |
| case nosapp::Algorithm::EC: |
| *out = Algorithm::EC; |
| break; |
| case nosapp::Algorithm::AES: |
| *out = Algorithm::AES; |
| break; |
| case nosapp::Algorithm::DES: |
| *out = Algorithm::TRIPLE_DES; |
| break; |
| case nosapp::Algorithm::HMAC: |
| *out = Algorithm::HMAC; |
| break; |
| default: |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| static nosapp::BlockMode translate_block_mode(BlockMode block_mode) |
| { |
| switch (block_mode) { |
| case BlockMode::ECB: |
| return nosapp::BlockMode::ECB; |
| case BlockMode::CBC: |
| return nosapp::BlockMode::CBC; |
| case BlockMode::CTR: |
| return nosapp::BlockMode::CTR; |
| case BlockMode::GCM: |
| return nosapp::BlockMode::GCM; |
| default: |
| return nosapp::BlockMode::BLOCK_MODE_MAX; |
| } |
| } |
| |
| static ErrorCode translate_block_mode(nosapp::BlockMode block_mode, |
| BlockMode *out) |
| { |
| switch (block_mode) { |
| case nosapp::BlockMode::ECB: |
| *out = BlockMode::ECB; |
| break; |
| case nosapp::BlockMode::CBC: |
| *out = BlockMode::CBC; |
| break; |
| case nosapp::BlockMode::CTR: |
| *out = BlockMode::CTR; |
| break; |
| case nosapp::BlockMode::GCM: |
| *out = BlockMode::GCM; |
| break; |
| default: |
| return ErrorCode::UNKNOWN_ERROR; |
| break; |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| static nosapp::Digest translate_digest(Digest digest) |
| { |
| switch (digest) { |
| case Digest::NONE: |
| return nosapp::Digest::DIGEST_NONE; |
| case Digest::MD5: |
| return nosapp::Digest::DIGEST_MD5; |
| case Digest::SHA1: |
| return nosapp::Digest::DIGEST_SHA1; |
| case Digest::SHA_2_224: |
| return nosapp::Digest::DIGEST_SHA_2_224; |
| case Digest::SHA_2_256: |
| return nosapp::Digest::DIGEST_SHA_2_256; |
| case Digest::SHA_2_384: |
| return nosapp::Digest::DIGEST_SHA_2_384; |
| case Digest::SHA_2_512: |
| return nosapp::Digest::DIGEST_SHA_2_512; |
| default: |
| return nosapp::Digest::DIGEST_MAX; |
| } |
| } |
| |
| static ErrorCode translate_digest(nosapp::Digest digest, |
| Digest *out) |
| { |
| switch (digest) { |
| case nosapp::Digest::DIGEST_NONE: |
| *out = Digest::NONE; |
| break; |
| case nosapp::Digest::DIGEST_MD5: |
| *out = Digest::MD5; |
| break; |
| case nosapp::Digest::DIGEST_SHA1: |
| *out = Digest::SHA1; |
| break; |
| case nosapp::Digest::DIGEST_SHA_2_224: |
| *out = Digest::SHA_2_224; |
| break; |
| case nosapp::Digest::DIGEST_SHA_2_256: |
| *out = Digest::SHA_2_256; |
| break; |
| case nosapp::Digest::DIGEST_SHA_2_384: |
| *out = Digest::SHA_2_384; |
| break; |
| case nosapp::Digest::DIGEST_SHA_2_512: |
| *out = Digest::SHA_2_512; |
| break; |
| default: |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| static nosapp::PaddingMode translate_padding_mode(PaddingMode padding_mode) |
| { |
| switch (padding_mode) { |
| case PaddingMode::NONE: |
| return nosapp::PaddingMode::PADDING_NONE; |
| case PaddingMode::RSA_OAEP: |
| return nosapp::PaddingMode::PADDING_RSA_OAEP; |
| case PaddingMode::RSA_PSS: |
| return nosapp::PaddingMode::PADDING_RSA_PSS; |
| case PaddingMode::RSA_PKCS1_1_5_ENCRYPT: |
| return nosapp::PaddingMode::PADDING_RSA_PKCS1_1_5_ENCRYPT; |
| case PaddingMode::RSA_PKCS1_1_5_SIGN: |
| return nosapp::PaddingMode::PADDING_RSA_PKCS1_1_5_SIGN; |
| case PaddingMode::PKCS7: |
| return nosapp::PaddingMode::PADDING_PKCS7; |
| default: |
| return nosapp::PaddingMode::PADDING_MODE_MAX; |
| } |
| } |
| |
| static ErrorCode translate_padding_mode(nosapp::PaddingMode padding_mode, |
| PaddingMode *out) |
| { |
| switch (padding_mode) { |
| case nosapp::PaddingMode::PADDING_NONE: |
| *out = PaddingMode::NONE; |
| break; |
| case nosapp::PaddingMode::PADDING_RSA_OAEP: |
| *out = PaddingMode::RSA_OAEP; |
| break; |
| case nosapp::PaddingMode::PADDING_RSA_PSS: |
| *out = PaddingMode::RSA_PSS; |
| break; |
| case nosapp::PaddingMode::PADDING_RSA_PKCS1_1_5_ENCRYPT: |
| *out = PaddingMode::RSA_PKCS1_1_5_ENCRYPT; |
| break; |
| case nosapp::PaddingMode::PADDING_RSA_PKCS1_1_5_SIGN: |
| *out = PaddingMode::RSA_PKCS1_1_5_SIGN; |
| break; |
| case nosapp::PaddingMode::PADDING_PKCS7: |
| *out = PaddingMode::PKCS7; |
| break; |
| default: |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| static nosapp::EcCurve translate_ec_curve(EcCurve ec_curve) |
| { |
| switch (ec_curve) { |
| case EcCurve::P_224: |
| return nosapp::EcCurve::P_224; |
| case EcCurve::P_256: |
| return nosapp::EcCurve::P_256; |
| case EcCurve::P_384: |
| return nosapp::EcCurve::P_384; |
| case EcCurve::P_521: |
| return nosapp::EcCurve::P_521; |
| default: |
| return nosapp::EcCurve::EC_CURVE_MAX; |
| } |
| } |
| |
| ErrorCode translate_ec_curve(nosapp::EcCurve ec_curve, EcCurve *out) |
| { |
| switch (ec_curve) { |
| case nosapp::EcCurve::P_224: |
| *out = EcCurve::P_224; |
| break; |
| case nosapp::EcCurve::P_256: |
| *out = EcCurve::P_256; |
| break; |
| case nosapp::EcCurve::P_384: |
| *out = EcCurve::P_384; |
| break; |
| case nosapp::EcCurve::P_521: |
| *out = EcCurve::P_521; |
| break; |
| default: |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| static nosapp::KeyBlobUsageRequirements translate_key_blob_usage_requirements( |
| KeyBlobUsageRequirements usage) |
| { |
| switch (usage) { |
| case KeyBlobUsageRequirements::STANDALONE: |
| return nosapp::KeyBlobUsageRequirements::STANDALONE; |
| case KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM: |
| return nosapp::KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM; |
| default: |
| return nosapp::KeyBlobUsageRequirements::KEY_USAGE_MAX; |
| break; |
| } |
| } |
| |
| static ErrorCode translate_key_blob_usage_requirements( |
| nosapp::KeyBlobUsageRequirements usage, KeyBlobUsageRequirements *out) |
| { |
| switch (usage) { |
| case nosapp::KeyBlobUsageRequirements::STANDALONE: |
| *out = KeyBlobUsageRequirements::STANDALONE; |
| break; |
| case nosapp::KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM: |
| *out = KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM; |
| break; |
| default: |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| static nosapp::KeyOrigin translate_key_origin(KeyOrigin key_origin) |
| { |
| switch (key_origin) { |
| case KeyOrigin::GENERATED: |
| return nosapp::KeyOrigin::GENERATED; |
| case KeyOrigin::DERIVED: |
| return nosapp::KeyOrigin::DERIVED; |
| case KeyOrigin::IMPORTED: |
| return nosapp::KeyOrigin::IMPORTED; |
| case KeyOrigin::UNKNOWN: |
| return nosapp::KeyOrigin::UNKNOWN; |
| default: |
| return nosapp::KeyOrigin::KEY_ORIGIN_MAX; |
| } |
| } |
| |
| static ErrorCode translate_key_origin(nosapp::KeyOrigin key_origin, |
| KeyOrigin *out) |
| { |
| switch (key_origin) { |
| case nosapp::KeyOrigin::GENERATED: |
| *out = KeyOrigin::GENERATED; |
| break; |
| case nosapp::KeyOrigin::DERIVED: |
| *out = KeyOrigin::DERIVED; |
| break; |
| case nosapp::KeyOrigin::IMPORTED: |
| *out = KeyOrigin::IMPORTED; |
| break; |
| case nosapp::KeyOrigin::UNKNOWN: |
| *out = KeyOrigin::UNKNOWN; |
| break; |
| default: |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| ErrorCode translate_auth_token(const HardwareAuthToken& auth_token, |
| nosapp::HardwareAuthToken *out) |
| { |
| out->set_challenge(auth_token.challenge); |
| out->set_user_id(auth_token.userId); |
| out->set_authenticator_id(auth_token.authenticatorId); |
| out->set_authenticator_type((uint32_t)auth_token.authenticatorType); |
| out->set_timestamp(auth_token.timestamp); |
| out->set_mac(&auth_token.mac[0], auth_token.mac.size()); |
| |
| return ErrorCode::OK; |
| } |
| |
| void translate_verification_token( |
| const VerificationToken& verification_token, |
| nosapp::VerificationToken *out) |
| { |
| out->set_challenge(verification_token.challenge); |
| out->set_timestamp(verification_token.timestamp); |
| hidl_params_to_pb(verification_token.parametersVerified, |
| out->mutable_params_verified()); |
| out->set_security_level(static_cast<nosapp::SecurityLevel>( |
| verification_token.securityLevel)); |
| out->set_mac(verification_token.mac.data(), |
| verification_token.mac.size()); |
| } |
| |
| ErrorCode key_parameter_to_pb(const KeyParameter& param, |
| nosapp::KeyParameter *pb) |
| { |
| switch (param.tag) { |
| case Tag::INVALID: |
| LOG(ERROR) << "key_parameter_to_pb: invalid Tag received: " |
| << (uint32_t)param.tag; |
| return ErrorCode::INVALID_ARGUMENT; |
| break; |
| case Tag::PURPOSE: // (TagType:ENUM_REP | 1) |
| pb->set_integer((uint32_t)translate_purpose(param.f.purpose)); |
| break; |
| case Tag::ALGORITHM: // (TagType:ENUM | 2) |
| pb->set_integer((uint32_t)translate_algorithm(param.f.algorithm)); |
| break; |
| case Tag::KEY_SIZE: // (TagType:UINT | 3) |
| pb->set_integer(param.f.integer); |
| break; |
| case Tag::BLOCK_MODE: // (TagType:ENUM_REP | 4) |
| pb->set_integer((uint32_t)translate_block_mode(param.f.blockMode)); |
| break; |
| case Tag::DIGEST: // (TagType:ENUM_REP | 5) |
| pb->set_integer((uint32_t)translate_digest(param.f.digest)); |
| break; |
| case Tag::PADDING:; // (TagType:ENUM_REP | 6) |
| pb->set_integer((uint32_t)translate_padding_mode(param.f.paddingMode)); |
| break; |
| case Tag::CALLER_NONCE: // (TagType:BOOL | 7) |
| pb->set_integer(param.f.boolValue); |
| break; |
| case Tag::MIN_MAC_LENGTH: // (TagType:UINT | 8) |
| pb->set_integer(param.f.integer); |
| break; |
| case Tag::EC_CURVE: // (TagType:ENUM | 10) |
| pb->set_integer((uint32_t)translate_ec_curve(param.f.ecCurve)); |
| break; |
| case Tag::RSA_PUBLIC_EXPONENT: // (TagType:ULONG | 200) |
| pb->set_long_integer(param.f.longInteger); |
| break; |
| case Tag::INCLUDE_UNIQUE_ID: // (TagType:BOOL | 202) |
| pb->set_integer(param.f.boolValue); |
| break; |
| case Tag::BLOB_USAGE_REQUIREMENTS: // (TagType:ENUM | 301) |
| pb->set_integer((uint32_t)translate_key_blob_usage_requirements( |
| param.f.keyBlobUsageRequirements)); |
| break; |
| case Tag::BOOTLOADER_ONLY: // (TagType:BOOL | 302) |
| pb->set_integer(param.f.boolValue); |
| break; |
| case Tag::ROLLBACK_RESISTANCE: // (TagType:BOOL | 303) |
| pb->set_integer(param.f.boolValue); |
| break; |
| case Tag::HARDWARE_TYPE: // (TagType:ENUM | 304) |
| break; |
| case Tag::ACTIVE_DATETIME: // (TagType:DATE | 400) |
| pb->set_long_integer(param.f.dateTime); |
| break; |
| case Tag::ORIGINATION_EXPIRE_DATETIME: // (TagType:DATE | 401) |
| case Tag::USAGE_EXPIRE_DATETIME: // (TagType:DATE | 402) |
| pb->set_long_integer(param.f.dateTime); |
| break; |
| case Tag::MIN_SECONDS_BETWEEN_OPS: // (TagType:UINT | 403) |
| case Tag::MAX_USES_PER_BOOT: // (TagType:UINT | 404) |
| pb->set_integer(param.f.integer); |
| break; |
| case Tag::USER_SECURE_ID: // (TagType:ULONG_REP | 502) |
| pb->set_long_integer(param.f.longInteger); |
| break; |
| case Tag::NO_AUTH_REQUIRED: // (TagType:BOOL | 503) |
| pb->set_integer(param.f.boolValue); |
| break; |
| case Tag::USER_AUTH_TYPE: // (TagType:ENUM | 504) |
| // This field is an OR'd bitfield of HAL enum values from |
| // ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType. |
| pb->set_integer((uint32_t)param.f.hardwareAuthenticatorType); |
| break; |
| case Tag::AUTH_TIMEOUT: // (TagType:UINT | 505) |
| pb->set_integer(param.f.integer); |
| break; |
| case Tag::ALLOW_WHILE_ON_BODY: // (TagType:BOOL | 506) |
| pb->set_integer(param.f.boolValue); |
| break; |
| case Tag::TRUSTED_USER_PRESENCE_REQUIRED: // (TagType:BOOL | 507) |
| pb->set_integer(param.f.boolValue); |
| break; |
| case Tag::TRUSTED_CONFIRMATION_REQUIRED: // (TagType:BOOL | 508) |
| pb->set_integer(param.f.boolValue); |
| break; |
| case Tag::APPLICATION_ID: // (TagType:BYTES | 601) |
| pb->set_blob(¶m.blob[0], param.blob.size()); |
| break; |
| case Tag::APPLICATION_DATA: // (TagType:BYTES | 700) |
| pb->set_blob(¶m.blob[0], param.blob.size()); |
| break; |
| case Tag::CREATION_DATETIME: // (TagType:DATE | 701) |
| pb->set_long_integer(param.f.dateTime); |
| break; |
| case Tag::ORIGIN: // (TagType:ENUM | 702) |
| pb->set_integer((uint32_t)translate_key_origin(param.f.origin)); |
| break; |
| case Tag::ROOT_OF_TRUST: // (TagType:BYTES | 704) |
| pb->set_blob(¶m.blob[0], param.blob.size()); |
| break; |
| case Tag::OS_VERSION: // (TagType:UINT | 705) |
| case Tag::OS_PATCHLEVEL: // (TagType:UINT | 706) |
| pb->set_integer(param.f.integer); |
| break; |
| case Tag::UNIQUE_ID: // (TagType:BYTES | 707) |
| case Tag::ATTESTATION_CHALLENGE: // (TagType:BYTES | 708) |
| case Tag::ATTESTATION_APPLICATION_ID: // (TagType:BYTES | 709) |
| case Tag::ATTESTATION_ID_BRAND: // (TagType:BYTES | 710) |
| case Tag::ATTESTATION_ID_DEVICE: // (TagType:BYTES | 711) |
| case Tag::ATTESTATION_ID_PRODUCT: // (TagType:BYTES | 712) |
| case Tag::ATTESTATION_ID_SERIAL: // (TagType:BYTES | 713) |
| case Tag::ATTESTATION_ID_IMEI: // (TagType:BYTES | 714) |
| case Tag::ATTESTATION_ID_MEID: // (TagType:BYTES | 715) |
| case Tag::ATTESTATION_ID_MANUFACTURER: // (TagType:BYTES | 716) |
| case Tag::ATTESTATION_ID_MODEL: // (TagType:BYTES | 717) |
| pb->set_blob(¶m.blob[0], param.blob.size()); |
| break; |
| case Tag::VENDOR_PATCHLEVEL: // (TagType:UINT | 718) |
| case Tag::BOOT_PATCHLEVEL: // (TagType:UINT | 719) |
| pb->set_integer(param.f.integer); |
| break; |
| case Tag::ASSOCIATED_DATA: // (TagType:BYTES | 1000) |
| case Tag::NONCE: // (TagType:BYTES | 1001) |
| case Tag::CONFIRMATION_TOKEN: // (TagType:BYTES | 1005) |
| pb->set_blob(¶m.blob[0], param.blob.size()); |
| break; |
| case Tag::MAC_LENGTH: // (TagType:UINT | 1003) |
| pb->set_integer(param.f.integer); |
| break; |
| case Tag::RESET_SINCE_ID_ROTATION: // (TagType:BOOL | 1004) |
| pb->set_integer(param.f.boolValue); |
| break; |
| default: |
| LOG(ERROR) << "Unhandled tag value in key_parameter_to_pb: " |
| << (uint32_t) param.tag; |
| } |
| |
| pb->set_tag(translate_tag(param.tag)); |
| return ErrorCode::OK; |
| } |
| |
| ErrorCode pb_to_key_parameter(const nosapp::KeyParameter& param, |
| KeyParameter *kp) |
| { |
| switch (param.tag()) { |
| case nosapp::Tag::TAG_INVALID: |
| LOG(ERROR) << "pb_to_key_parameter: invalid Tag received: " |
| << (uint32_t)param.tag(); |
| return ErrorCode::UNKNOWN_ERROR; |
| break; |
| case nosapp::Tag::PURPOSE: // (TagType:ENUM_REP | 1) |
| if (translate_purpose(static_cast<nosapp::KeyPurpose>(param.integer()), |
| &kp->f.purpose) != ErrorCode::OK) { |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| break; |
| case nosapp::Tag::ALGORITHM: // (TagType:ENUM | 2) |
| if (translate_algorithm(static_cast<nosapp::Algorithm>(param.integer()), |
| &kp->f.algorithm) != ErrorCode::OK) { |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| break; |
| case nosapp::Tag::KEY_SIZE: // (TagType:UINT | 3) |
| kp->f.integer = param.integer(); |
| break; |
| case nosapp::Tag::BLOCK_MODE: // (TagType:ENUM_REP | 4) |
| if (translate_block_mode( |
| static_cast<nosapp::BlockMode>(param.integer()), |
| &kp->f.blockMode) != ErrorCode::OK) { |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| break; |
| case nosapp::Tag::DIGEST: // (TagType:ENUM_REP | 5) |
| if (translate_digest( |
| static_cast<nosapp::Digest>(param.integer()), |
| &kp->f.digest) != ErrorCode::OK) { |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| break; |
| case nosapp::Tag::PADDING:; // (TagType:ENUM_REP | 6) |
| if (translate_padding_mode( |
| static_cast<nosapp::PaddingMode>(param.integer()), |
| &kp->f.paddingMode) != ErrorCode::OK) { |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| break; |
| case nosapp::Tag::CALLER_NONCE: // (TagType:BOOL | 7) |
| kp->f.boolValue = (bool)param.integer(); |
| break; |
| case nosapp::Tag::MIN_MAC_LENGTH: // (TagType:UINT | 8) |
| kp->f.integer = param.integer(); |
| break; |
| case nosapp::Tag::EC_CURVE: // (TagType:ENUM | 10) |
| if (translate_ec_curve( |
| static_cast<nosapp::EcCurve>(param.integer()), |
| &kp->f.ecCurve) != ErrorCode::OK) { |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| break; |
| case nosapp::Tag::RSA_PUBLIC_EXPONENT: // (TagType:ULONG | 200) |
| kp->f.longInteger = param.long_integer(); |
| break; |
| case nosapp::Tag::INCLUDE_UNIQUE_ID: // (TagType:BOOL | 202) |
| kp->f.boolValue = (bool)param.integer(); |
| break; |
| case nosapp::Tag::BLOB_USAGE_REQUIREMENTS: // (TagType:ENUM | 301) |
| if (translate_key_blob_usage_requirements( |
| static_cast<nosapp::KeyBlobUsageRequirements>(param.integer()), |
| &kp->f.keyBlobUsageRequirements) != ErrorCode::OK) { |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| break; |
| case nosapp::Tag::BOOTLOADER_ONLY: // (TagType:BOOL | 302) |
| case nosapp::Tag::ROLLBACK_RESISTANCE: // (TagType:BOOL | 303) |
| kp->f.boolValue = (bool)param.integer(); |
| break; |
| case nosapp::Tag::ACTIVE_DATETIME: // (TagType:DATE | 400) |
| case nosapp::Tag::ORIGINATION_EXPIRE_DATETIME: // (TagType:DATE | 401) |
| case nosapp::Tag::USAGE_EXPIRE_DATETIME: // (TagType:DATE | 402) |
| kp->f.dateTime = param.long_integer(); |
| break; |
| case nosapp::Tag::MIN_SECONDS_BETWEEN_OPS: // (TagType:UINT | 403) |
| case nosapp::Tag::MAX_USES_PER_BOOT: // (TagType:UINT | 404) |
| kp->f.integer = param.integer(); |
| break; |
| case nosapp::Tag::USER_SECURE_ID: // (TagType:ULONG_REP | 502) |
| kp->f.longInteger = param.long_integer(); |
| break; |
| case nosapp::Tag::NO_AUTH_REQUIRED: // (TagType:BOOL | 503) |
| kp->f.boolValue = (bool)param.integer(); |
| break; |
| case nosapp::Tag::USER_AUTH_TYPE: // (TagType:ENUM | 504) |
| // This field is an OR'd bitfield of HAL enum values from |
| // ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType. |
| kp->f.hardwareAuthenticatorType = |
| static_cast<HardwareAuthenticatorType>(param.integer()); |
| break; |
| case nosapp::Tag::AUTH_TIMEOUT: // (TagType:UINT | 505) |
| kp->f.integer = param.integer(); |
| break; |
| case nosapp::Tag::ALLOW_WHILE_ON_BODY: // (TagType:BOOL | 506) |
| kp->f.boolValue = (bool)param.integer(); |
| break; |
| case nosapp::Tag::TRUSTED_USER_PRESENCE_REQUIRED: // (TagType:BOOL | 507) |
| kp->f.boolValue = (bool)param.integer(); |
| break; |
| case nosapp::Tag::TRUSTED_CONFIRMATION_REQUIRED: // (TagType:BOOL | 508) |
| kp->f.boolValue = (bool)param.integer(); |
| break; |
| case nosapp::Tag::APPLICATION_ID: // (TagType:BYTES | 601) |
| kp->blob.setToExternal( |
| reinterpret_cast<uint8_t *>( |
| const_cast<char *>(param.blob().data())), param.blob().size());; |
| break; |
| case nosapp::Tag::APPLICATION_DATA: // (TagType:BYTES | 700) |
| kp->blob.setToExternal( |
| reinterpret_cast<uint8_t *>( |
| const_cast<char *>(param.blob().data())), param.blob().size());; |
| break; |
| case nosapp::Tag::CREATION_DATETIME: // (TagType:DATE | 701) |
| kp->f.dateTime = param.long_integer(); |
| break; |
| case nosapp::Tag::ORIGIN: // (TagType:ENUM | 702) |
| if (translate_key_origin( |
| static_cast<nosapp::KeyOrigin>(param.integer()), |
| &kp->f.origin) != ErrorCode::OK) { |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| break; |
| case nosapp::Tag::ROOT_OF_TRUST: // (TagType:BYTES | 704) |
| kp->blob.setToExternal( |
| reinterpret_cast<uint8_t *>( |
| const_cast<char *>(param.blob().data())), param.blob().size()); |
| break; |
| case nosapp::Tag::OS_VERSION: // (TagType:UINT | 705) |
| case nosapp::Tag::OS_PATCHLEVEL: // (TagType:UINT | 706) |
| kp->f.integer = param.integer(); |
| break; |
| case nosapp::Tag::UNIQUE_ID: // (TagType:BYTES | 707) |
| case nosapp::Tag::ATTESTATION_CHALLENGE: // (TagType:BYTES | 708) |
| case nosapp::Tag::ATTESTATION_APPLICATION_ID: // (TagType:BYTES | 709) |
| case nosapp::Tag::ATTESTATION_ID_BRAND: // (TagType:BYTES | 710) |
| case nosapp::Tag::ATTESTATION_ID_DEVICE: // (TagType:BYTES | 711) |
| case nosapp::Tag::ATTESTATION_ID_PRODUCT: // (TagType:BYTES | 712) |
| case nosapp::Tag::ATTESTATION_ID_SERIAL: // (TagType:BYTES | 713) |
| case nosapp::Tag::ATTESTATION_ID_IMEI: // (TagType:BYTES | 714) |
| case nosapp::Tag::ATTESTATION_ID_MEID: // (TagType:BYTES | 715) |
| case nosapp::Tag::ATTESTATION_ID_MANUFACTURER: // (TagType:BYTES | 716) |
| case nosapp::Tag::ATTESTATION_ID_MODEL: // (TagType:BYTES | 717) |
| kp->blob.setToExternal( |
| reinterpret_cast<uint8_t *>( |
| const_cast<char *>(param.blob().data())), param.blob().size()); |
| break; |
| case nosapp::Tag::VENDOR_PATCHLEVEL: // (TagType:UINT | 718) |
| case nosapp::Tag::BOOT_PATCHLEVEL: // (TagType:UINT | 719) |
| kp->f.integer = param.integer(); |
| break; |
| case nosapp::Tag::ASSOCIATED_DATA: // (TagType:BYTES | 1000) |
| case nosapp::Tag::NONCE: // (TagType:BYTES | 1001) |
| kp->blob.setToExternal( |
| reinterpret_cast<uint8_t *>( |
| const_cast<char *>(param.blob().data())), param.blob().size()); |
| break; |
| case nosapp::Tag::MAC_LENGTH: // (TagType:UINT | 1003) |
| kp->f.integer = param.integer(); |
| break; |
| case nosapp::Tag::RESET_SINCE_ID_ROTATION: // (TagType:BOOL | 1004) |
| kp->f.boolValue = (bool)param.integer(); |
| break; |
| case nosapp::Tag::CONFIRMATION_TOKEN: // (TagType:BOOL | 1005) |
| kp->blob.setToExternal( |
| reinterpret_cast<uint8_t *>( |
| const_cast<char *>(param.blob().data())), param.blob().size()); |
| break; |
| default: |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| kp->tag = translate_tag(param.tag()); |
| return ErrorCode::OK; |
| } |
| |
| ErrorCode hidl_params_to_pb(const hidl_vec<KeyParameter>& params, |
| nosapp::KeyParameters *pb) |
| { |
| for (size_t i = 0; i < params.size(); i++) { |
| nosapp::KeyParameter *param = pb->add_params(); |
| ErrorCode error = key_parameter_to_pb(params[i], param); |
| if (error != ErrorCode::OK) { |
| return ErrorCode::INVALID_ARGUMENT; |
| } |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| ErrorCode hidl_params_to_map(const hidl_vec<KeyParameter>& params, |
| tag_map_t *tag_map) |
| { |
| for (size_t i = 0; i < params.size(); i++) { |
| switch (type_from_tag(params[i].tag)) { |
| case TagType::INVALID: |
| return ErrorCode::INVALID_ARGUMENT; |
| break; |
| case TagType::ENUM: |
| case TagType::UINT: |
| case TagType::ULONG: |
| case TagType::DATE: |
| case TagType::BOOL: |
| case TagType::BIGNUM: |
| case TagType::BYTES: |
| if (tag_map->find(params[i].tag) != tag_map->end()) { |
| // Duplicates not allowed for these tags types. |
| return ErrorCode::INVALID_ARGUMENT; |
| } |
| /* Fall-through! */ |
| case TagType::ENUM_REP: |
| case TagType::UINT_REP: |
| case TagType::ULONG_REP: |
| if (tag_map->find(params[i].tag) == tag_map->end()) { |
| vector<KeyParameter> v{params[i]}; |
| tag_map->insert( |
| std::pair<Tag, vector<KeyParameter> >( |
| params[i].tag, v)); |
| } else { |
| (*tag_map)[params[i].tag].push_back(params[i]); |
| } |
| break; |
| default: |
| /* Unrecognized TagType. */ |
| return ErrorCode::INVALID_ARGUMENT; |
| break; |
| } |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| ErrorCode map_params_to_pb(const tag_map_t& params, |
| nosapp::KeyParameters *pbParams) |
| { |
| for (const auto& it : params) { |
| for (const auto& pt : it.second) { |
| nosapp::KeyParameter *param = pbParams->add_params(); |
| ErrorCode error = key_parameter_to_pb(pt, param); |
| if (error != ErrorCode::OK) { |
| return error; |
| } |
| } |
| } |
| |
| return ErrorCode::OK; |
| } |
| |
| ErrorCode pb_to_hidl_params(const nosapp::KeyParameters& pbParams, |
| hidl_vec<KeyParameter> *params) |
| { |
| std::vector<KeyParameter> kpv; |
| for (size_t i = 0; i < (size_t)pbParams.params_size(); i++) { |
| KeyParameter kp; |
| const nosapp::KeyParameter& param = pbParams.params(i); |
| |
| ErrorCode error = pb_to_key_parameter(param, &kp); |
| if (error != ErrorCode::OK) { |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| |
| kpv.push_back(kp); |
| } |
| |
| *params = kpv; |
| return ErrorCode::OK; |
| } |
| |
| ErrorCode translate_error_code(nosapp::ErrorCode error_code) |
| { |
| switch (error_code) { |
| case nosapp::ErrorCode::OK: |
| return ErrorCode::OK; |
| case nosapp::ErrorCode::ROOT_OF_TRUST_ALREADY_SET: |
| return ErrorCode::ROOT_OF_TRUST_ALREADY_SET; |
| case nosapp::ErrorCode::UNSUPPORTED_PURPOSE: |
| return ErrorCode::UNSUPPORTED_PURPOSE; |
| case nosapp::ErrorCode::INCOMPATIBLE_PURPOSE: |
| return ErrorCode::INCOMPATIBLE_PURPOSE; |
| case nosapp::ErrorCode::UNSUPPORTED_ALGORITHM: |
| return ErrorCode::UNSUPPORTED_ALGORITHM; |
| case nosapp::ErrorCode::INCOMPATIBLE_ALGORITHM: |
| return ErrorCode::INCOMPATIBLE_ALGORITHM; |
| case nosapp::ErrorCode::UNSUPPORTED_KEY_SIZE: |
| return ErrorCode::UNSUPPORTED_KEY_SIZE; |
| case nosapp::ErrorCode::UNSUPPORTED_BLOCK_MODE: |
| return ErrorCode::UNSUPPORTED_BLOCK_MODE; |
| case nosapp::ErrorCode::INCOMPATIBLE_BLOCK_MODE: |
| return ErrorCode::INCOMPATIBLE_BLOCK_MODE; |
| case nosapp::ErrorCode::UNSUPPORTED_MAC_LENGTH: |
| return ErrorCode::UNSUPPORTED_MAC_LENGTH; |
| case nosapp::ErrorCode::UNSUPPORTED_PADDING_MODE: |
| return ErrorCode::UNSUPPORTED_PADDING_MODE; |
| case nosapp::ErrorCode::INCOMPATIBLE_PADDING_MODE: |
| return ErrorCode::INCOMPATIBLE_PADDING_MODE; |
| case nosapp::ErrorCode::UNSUPPORTED_DIGEST: |
| return ErrorCode::UNSUPPORTED_DIGEST; |
| case nosapp::ErrorCode::INCOMPATIBLE_DIGEST: |
| return ErrorCode::INCOMPATIBLE_DIGEST; |
| case nosapp::ErrorCode::INVALID_EXPIRATION_TIME: |
| return ErrorCode::INVALID_EXPIRATION_TIME; |
| case nosapp::ErrorCode::INVALID_USER_ID: |
| return ErrorCode::INVALID_USER_ID; |
| case nosapp::ErrorCode::INVALID_AUTHORIZATION_TIMEOUT: |
| return ErrorCode::INVALID_AUTHORIZATION_TIMEOUT; |
| case nosapp::ErrorCode::UNSUPPORTED_KEY_FORMAT: |
| return ErrorCode::UNSUPPORTED_KEY_FORMAT; |
| case nosapp::ErrorCode::INCOMPATIBLE_KEY_FORMAT: |
| return ErrorCode::INCOMPATIBLE_KEY_FORMAT; |
| case nosapp::ErrorCode::UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM: |
| return ErrorCode::UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM; |
| case nosapp::ErrorCode::UNSUPPORTED_KEY_VERIFICATION_ALGORITHM: |
| return ErrorCode::UNSUPPORTED_KEY_VERIFICATION_ALGORITHM; |
| case nosapp::ErrorCode::INVALID_INPUT_LENGTH: |
| return ErrorCode::INVALID_INPUT_LENGTH; |
| case nosapp::ErrorCode::KEY_EXPORT_OPTIONS_INVALID: |
| return ErrorCode::KEY_EXPORT_OPTIONS_INVALID; |
| case nosapp::ErrorCode::DELEGATION_NOT_ALLOWED: |
| return ErrorCode::DELEGATION_NOT_ALLOWED; |
| case nosapp::ErrorCode::KEY_NOT_YET_VALID: |
| return ErrorCode::KEY_NOT_YET_VALID; |
| case nosapp::ErrorCode::KEY_EXPIRED: |
| return ErrorCode::KEY_EXPIRED; |
| case nosapp::ErrorCode::KEY_USER_NOT_AUTHENTICATED: |
| return ErrorCode::KEY_USER_NOT_AUTHENTICATED; |
| case nosapp::ErrorCode::OUTPUT_PARAMETER_NULL: |
| return ErrorCode::OUTPUT_PARAMETER_NULL; |
| case nosapp::ErrorCode::INVALID_OPERATION_HANDLE: |
| return ErrorCode::INVALID_OPERATION_HANDLE; |
| case nosapp::ErrorCode::INSUFFICIENT_BUFFER_SPACE: |
| return ErrorCode::INSUFFICIENT_BUFFER_SPACE; |
| case nosapp::ErrorCode::VERIFICATION_FAILED: |
| return ErrorCode::VERIFICATION_FAILED; |
| case nosapp::ErrorCode::TOO_MANY_OPERATIONS: |
| return ErrorCode::TOO_MANY_OPERATIONS; |
| case nosapp::ErrorCode::UNEXPECTED_NULL_POINTER: |
| return ErrorCode::UNEXPECTED_NULL_POINTER; |
| case nosapp::ErrorCode::INVALID_KEY_BLOB: |
| return ErrorCode::INVALID_KEY_BLOB; |
| case nosapp::ErrorCode::IMPORTED_KEY_NOT_ENCRYPTED: |
| return ErrorCode::IMPORTED_KEY_NOT_ENCRYPTED; |
| case nosapp::ErrorCode::IMPORTED_KEY_DECRYPTION_FAILED: |
| return ErrorCode::IMPORTED_KEY_DECRYPTION_FAILED; |
| case nosapp::ErrorCode::IMPORTED_KEY_NOT_SIGNED: |
| return ErrorCode::IMPORTED_KEY_NOT_SIGNED; |
| case nosapp::ErrorCode::IMPORTED_KEY_VERIFICATION_FAILED: |
| return ErrorCode::IMPORTED_KEY_VERIFICATION_FAILED; |
| case nosapp::ErrorCode::INVALID_ARGUMENT: |
| return ErrorCode::INVALID_ARGUMENT; |
| case nosapp::ErrorCode::UNSUPPORTED_TAG: |
| return ErrorCode::UNSUPPORTED_TAG; |
| case nosapp::ErrorCode::INVALID_TAG: |
| return ErrorCode::INVALID_TAG; |
| case nosapp::ErrorCode::MEMORY_ALLOCATION_FAILED: |
| return ErrorCode::MEMORY_ALLOCATION_FAILED; |
| case nosapp::ErrorCode::IMPORT_PARAMETER_MISMATCH: |
| return ErrorCode::IMPORT_PARAMETER_MISMATCH; |
| case nosapp::ErrorCode::SECURE_HW_ACCESS_DENIED: |
| return ErrorCode::SECURE_HW_ACCESS_DENIED; |
| case nosapp::ErrorCode::OPERATION_CANCELLED: |
| return ErrorCode::OPERATION_CANCELLED; |
| case nosapp::ErrorCode::CONCURRENT_ACCESS_CONFLICT: |
| return ErrorCode::CONCURRENT_ACCESS_CONFLICT; |
| case nosapp::ErrorCode::SECURE_HW_BUSY: |
| return ErrorCode::SECURE_HW_BUSY; |
| case nosapp::ErrorCode::SECURE_HW_COMMUNICATION_FAILED: |
| return ErrorCode::SECURE_HW_COMMUNICATION_FAILED; |
| case nosapp::ErrorCode::UNSUPPORTED_EC_FIELD: |
| return ErrorCode::UNSUPPORTED_EC_FIELD; |
| case nosapp::ErrorCode::MISSING_NONCE: |
| return ErrorCode::MISSING_NONCE; |
| case nosapp::ErrorCode::INVALID_NONCE: |
| return ErrorCode::INVALID_NONCE; |
| case nosapp::ErrorCode::MISSING_MAC_LENGTH: |
| return ErrorCode::MISSING_MAC_LENGTH; |
| case nosapp::ErrorCode::KEY_RATE_LIMIT_EXCEEDED: |
| return ErrorCode::KEY_RATE_LIMIT_EXCEEDED; |
| case nosapp::ErrorCode::CALLER_NONCE_PROHIBITED: |
| return ErrorCode::CALLER_NONCE_PROHIBITED; |
| case nosapp::ErrorCode::KEY_MAX_OPS_EXCEEDED: |
| return ErrorCode::KEY_MAX_OPS_EXCEEDED; |
| case nosapp::ErrorCode::INVALID_MAC_LENGTH: |
| return ErrorCode::INVALID_MAC_LENGTH; |
| case nosapp::ErrorCode::MISSING_MIN_MAC_LENGTH: |
| return ErrorCode::MISSING_MIN_MAC_LENGTH; |
| case nosapp::ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH: |
| return ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH; |
| case nosapp::ErrorCode::UNSUPPORTED_KDF: |
| return ErrorCode::UNSUPPORTED_KDF; |
| case nosapp::ErrorCode::UNSUPPORTED_EC_CURVE: |
| return ErrorCode::UNSUPPORTED_EC_CURVE; |
| case nosapp::ErrorCode::KEY_REQUIRES_UPGRADE: |
| return ErrorCode::KEY_REQUIRES_UPGRADE; |
| case nosapp::ErrorCode::ATTESTATION_CHALLENGE_MISSING: |
| return ErrorCode::ATTESTATION_CHALLENGE_MISSING; |
| case nosapp::ErrorCode::KEYMASTER_NOT_CONFIGURED: |
| return ErrorCode::KEYMASTER_NOT_CONFIGURED; |
| case nosapp::ErrorCode::ATTESTATION_APPLICATION_ID_MISSING: |
| return ErrorCode::ATTESTATION_APPLICATION_ID_MISSING; |
| case nosapp::ErrorCode::CANNOT_ATTEST_IDS: |
| return ErrorCode::CANNOT_ATTEST_IDS; |
| case nosapp::ErrorCode::UNIMPLEMENTED: |
| return ErrorCode::UNIMPLEMENTED; |
| case nosapp::ErrorCode::VERSION_MISMATCH: |
| return ErrorCode::VERSION_MISMATCH; |
| case nosapp::ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE: |
| return ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE; |
| case nosapp::ErrorCode::HARDWARE_TYPE_UNAVAILABLE: |
| return ErrorCode::HARDWARE_TYPE_UNAVAILABLE; |
| case nosapp::ErrorCode::PROOF_OF_PRESENCE_REQUIRED: |
| return ErrorCode::PROOF_OF_PRESENCE_REQUIRED; |
| case nosapp::ErrorCode::CONCURRENT_PROOF_OF_PRESENCE_REQUESTED: |
| return ErrorCode::CONCURRENT_PROOF_OF_PRESENCE_REQUESTED; |
| case nosapp::ErrorCode::UNKNOWN_ERROR: |
| return ErrorCode::UNKNOWN_ERROR; |
| case nosapp::ErrorCode::NO_USER_CONFIRMATION: |
| return ErrorCode::NO_USER_CONFIRMATION; |
| |
| /* Private error codes, unused by HAL. */ |
| case nosapp::ErrorCode::INVALID_DEVICE_IDS: |
| case nosapp::ErrorCode::PRODUCTION_MODE_PROVISIONING: |
| case nosapp::ErrorCode::ErrorCode_INT_MIN_SENTINEL_DO_NOT_USE_: |
| case nosapp::ErrorCode::ErrorCode_INT_MAX_SENTINEL_DO_NOT_USE_: |
| default: |
| LOG(ERROR) << "Unrecognized error_code: " << error_code; |
| return ErrorCode::UNKNOWN_ERROR; |
| } |
| } |
| |
| } // namespace keymaster |
| } // hardware |
| } // android |