/* * 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 #include #include 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(tag & (0xF << 28)); } static nosapp::TagType type_from_tag(nosapp::Tag tag) { return static_cast(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( (((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( (((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( 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(param.integer()), &kp->f.purpose) != ErrorCode::OK) { return ErrorCode::UNKNOWN_ERROR; } break; case nosapp::Tag::ALGORITHM: // (TagType:ENUM | 2) if (translate_algorithm(static_cast(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(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(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(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(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(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(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( const_cast(param.blob().data())), param.blob().size());; break; case nosapp::Tag::APPLICATION_DATA: // (TagType:BYTES | 700) kp->blob.setToExternal( reinterpret_cast( const_cast(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(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( const_cast(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( const_cast(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( const_cast(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( const_cast(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& 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& 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; } FALLTHROUGH_INTENDED; case TagType::ENUM_REP: FALLTHROUGH_INTENDED; case TagType::UINT_REP: FALLTHROUGH_INTENDED; case TagType::ULONG_REP: if (tag_map->find(params[i].tag) == tag_map->end()) { vector v{params[i]}; tag_map->insert( std::pair >( 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 *params) { std::vector 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