Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0d021c5 authored by David Zeuthen's avatar David Zeuthen Committed by Automerger Merge Worker
Browse files

Merge "Identity Credential: Switch default implementation to use libeic." am: 8f4cc703

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1245367

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ia45caf741fde9e0dafd2d21acd9e5abe60146bf9
parents 8d00d734 8f4cc703
Loading
Loading
Loading
Loading
+78 −7
Original line number Original line Diff line number Diff line
cc_library_static {
    name: "android.hardware.identity-libeic-hal-common",
    vendor_available: true,
    srcs: [
        "common/IdentityCredential.cpp",
        "common/IdentityCredentialStore.cpp",
        "common/WritableIdentityCredential.cpp",
    ],
    export_include_dirs: [
        "common",
    ],
    cflags: [
        "-Wall",
        "-Wextra",
    ],
    shared_libs: [
        "liblog",
        "libcrypto",
        "libbinder_ndk",
        "libkeymaster_messages",
    ],
    static_libs: [
        "libbase",
        "libcppbor",
        "libutils",
        "libsoft_attestation_cert",
        "libkeymaster_portable",
        "libsoft_attestation_cert",
        "libpuresoftkeymasterdevice",
        "android.hardware.identity-support-lib",
        "android.hardware.identity-ndk_platform",
        "android.hardware.keymaster-ndk_platform",
    ],
}

cc_library_static {
    name: "android.hardware.identity-libeic-library",
    vendor_available: true,
    srcs: [
        "libeic/EicCbor.c",
        "libeic/EicPresentation.c",
        "libeic/EicProvisioning.c",
        "EicOpsImpl.cc",
    ],
    export_include_dirs: [
        "libeic",
    ],
    cflags: [
        "-DEIC_COMPILATION",
        "-Wall",
        "-Wextra",
        "-DEIC_DEBUG",
        // Allow using C2x extensions such as omitting parameter names
        "-Wno-c2x-extensions",
    ],
    shared_libs: [
        "libbase",
        "libcrypto",
    ],
    static_libs: [
        "android.hardware.identity-support-lib",
    ],
}

cc_binary {
cc_binary {
    name: "android.hardware.identity-service.example",
    name: "android.hardware.identity-service.example",
    relative_install_path: "hw",
    relative_install_path: "hw",
@@ -7,23 +71,30 @@ cc_binary {
    cflags: [
    cflags: [
        "-Wall",
        "-Wall",
        "-Wextra",
        "-Wextra",
        "-g",
    ],
    ],
    shared_libs: [
    shared_libs: [
        "libbase",
        "liblog",
        "libcrypto",
        "libbinder_ndk",
        "libbinder_ndk",
        "libkeymaster_messages",
    ],
    static_libs: [
        "libbase",
        "libcppbor",
        "libcppbor",
        "libcrypto",
        "liblog",
        "libutils",
        "libutils",
        "libsoft_attestation_cert",
        "libkeymaster_portable",
        "libsoft_attestation_cert",
        "libpuresoftkeymasterdevice",
        "android.hardware.identity-support-lib",
        "android.hardware.identity-support-lib",
        "android.hardware.identity-ndk_platform",
        "android.hardware.identity-ndk_platform",
        "android.hardware.keymaster-ndk_platform",
        "android.hardware.keymaster-ndk_platform",
        "android.hardware.identity-libeic-hal-common",
        "android.hardware.identity-libeic-library",
    ],
    ],
    srcs: [
    srcs: [
        "IdentityCredential.cpp",
        "IdentityCredentialStore.cpp",
        "WritableIdentityCredential.cpp",
        "Util.cpp",
        "service.cpp",
        "service.cpp",
        "FakeSecureHardwareProxy.cpp",
    ],
    ],
}
}
+506 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2020, 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.
 */

#define LOG_TAG "EicOpsImpl"

#include <optional>
#include <tuple>
#include <vector>

#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <string.h>

#include <android/hardware/identity/support/IdentityCredentialSupport.h>

#include <openssl/sha.h>

#include <openssl/aes.h>
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hkdf.h>
#include <openssl/hmac.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

#include "EicOps.h"

using ::std::optional;
using ::std::string;
using ::std::tuple;
using ::std::vector;

void* eicMemSet(void* s, int c, size_t n) {
    return memset(s, c, n);
}

void* eicMemCpy(void* dest, const void* src, size_t n) {
    return memcpy(dest, src, n);
}

size_t eicStrLen(const char* s) {
    return strlen(s);
}

int eicCryptoMemCmp(const void* s1, const void* s2, size_t n) {
    return CRYPTO_memcmp(s1, s2, n);
}

void eicOpsHmacSha256Init(EicHmacSha256Ctx* ctx, const uint8_t* key, size_t keySize) {
    HMAC_CTX* realCtx = (HMAC_CTX*)ctx;
    HMAC_CTX_init(realCtx);
    if (HMAC_Init_ex(realCtx, key, keySize, EVP_sha256(), nullptr /* impl */) != 1) {
        LOG(ERROR) << "Error initializing HMAC_CTX";
    }
}

void eicOpsHmacSha256Update(EicHmacSha256Ctx* ctx, const uint8_t* data, size_t len) {
    HMAC_CTX* realCtx = (HMAC_CTX*)ctx;
    if (HMAC_Update(realCtx, data, len) != 1) {
        LOG(ERROR) << "Error updating HMAC_CTX";
    }
}

void eicOpsHmacSha256Final(EicHmacSha256Ctx* ctx, uint8_t digest[EIC_SHA256_DIGEST_SIZE]) {
    HMAC_CTX* realCtx = (HMAC_CTX*)ctx;
    unsigned int size = 0;
    if (HMAC_Final(realCtx, digest, &size) != 1) {
        LOG(ERROR) << "Error finalizing HMAC_CTX";
    }
    if (size != EIC_SHA256_DIGEST_SIZE) {
        LOG(ERROR) << "Expected 32 bytes from HMAC_Final, got " << size;
    }
}

void eicOpsSha256Init(EicSha256Ctx* ctx) {
    SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
    SHA256_Init(realCtx);
}

void eicOpsSha256Update(EicSha256Ctx* ctx, const uint8_t* data, size_t len) {
    SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
    SHA256_Update(realCtx, data, len);
}

void eicOpsSha256Final(EicSha256Ctx* ctx, uint8_t digest[EIC_SHA256_DIGEST_SIZE]) {
    SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
    SHA256_Final(digest, realCtx);
}

bool eicOpsRandom(uint8_t* buf, size_t numBytes) {
    optional<vector<uint8_t>> bytes = ::android::hardware::identity::support::getRandom(numBytes);
    if (!bytes.has_value()) {
        return false;
    }
    memcpy(buf, bytes.value().data(), numBytes);
    return true;
}

bool eicOpsEncryptAes128Gcm(
        const uint8_t* key,    // Must be 16 bytes
        const uint8_t* nonce,  // Must be 12 bytes
        const uint8_t* data,   // May be NULL if size is 0
        size_t dataSize,
        const uint8_t* additionalAuthenticationData,  // May be NULL if size is 0
        size_t additionalAuthenticationDataSize, uint8_t* encryptedData) {
    vector<uint8_t> cppKey;
    cppKey.resize(16);
    memcpy(cppKey.data(), key, 16);

    vector<uint8_t> cppData;
    cppData.resize(dataSize);
    if (dataSize > 0) {
        memcpy(cppData.data(), data, dataSize);
    }

    vector<uint8_t> cppAAD;
    cppAAD.resize(additionalAuthenticationDataSize);
    if (additionalAuthenticationDataSize > 0) {
        memcpy(cppAAD.data(), additionalAuthenticationData, additionalAuthenticationDataSize);
    }

    vector<uint8_t> cppNonce;
    cppNonce.resize(12);
    memcpy(cppNonce.data(), nonce, 12);

    optional<vector<uint8_t>> cppEncryptedData =
            android::hardware::identity::support::encryptAes128Gcm(cppKey, cppNonce, cppData,
                                                                   cppAAD);
    if (!cppEncryptedData.has_value()) {
        return false;
    }

    memcpy(encryptedData, cppEncryptedData.value().data(), cppEncryptedData.value().size());
    return true;
}

// Decrypts |encryptedData| using |key| and |additionalAuthenticatedData|,
// returns resulting plaintext in |data| must be of size |encryptedDataSize| - 28.
//
// The format of |encryptedData| must be as specified in the
// encryptAes128Gcm() function.
bool eicOpsDecryptAes128Gcm(const uint8_t* key,  // Must be 16 bytes
                            const uint8_t* encryptedData, size_t encryptedDataSize,
                            const uint8_t* additionalAuthenticationData,
                            size_t additionalAuthenticationDataSize, uint8_t* data) {
    vector<uint8_t> keyVec;
    keyVec.resize(16);
    memcpy(keyVec.data(), key, 16);

    vector<uint8_t> encryptedDataVec;
    encryptedDataVec.resize(encryptedDataSize);
    if (encryptedDataSize > 0) {
        memcpy(encryptedDataVec.data(), encryptedData, encryptedDataSize);
    }

    vector<uint8_t> aadVec;
    aadVec.resize(additionalAuthenticationDataSize);
    if (additionalAuthenticationDataSize > 0) {
        memcpy(aadVec.data(), additionalAuthenticationData, additionalAuthenticationDataSize);
    }

    optional<vector<uint8_t>> decryptedDataVec =
            android::hardware::identity::support::decryptAes128Gcm(keyVec, encryptedDataVec,
                                                                   aadVec);
    if (!decryptedDataVec.has_value()) {
        eicDebug("Error decrypting data");
        return false;
    }
    if (decryptedDataVec.value().size() != encryptedDataSize - 28) {
        eicDebug("Decrypted data is size %zd, expected %zd", decryptedDataVec.value().size(),
                 encryptedDataSize - 28);
        return false;
    }

    if (decryptedDataVec.value().size() > 0) {
        memcpy(data, decryptedDataVec.value().data(), decryptedDataVec.value().size());
    }
    return true;
}

bool eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
                       uint8_t publicKey[EIC_P256_PUB_KEY_SIZE]) {
    optional<vector<uint8_t>> keyPair = android::hardware::identity::support::createEcKeyPair();
    if (!keyPair) {
        eicDebug("Error creating EC keypair");
        return false;
    }
    optional<vector<uint8_t>> privKey =
            android::hardware::identity::support::ecKeyPairGetPrivateKey(keyPair.value());
    if (!privKey) {
        eicDebug("Error extracting private key");
        return false;
    }
    if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) {
        eicDebug("Private key is not %zd bytes long as expected", (size_t)EIC_P256_PRIV_KEY_SIZE);
        return false;
    }

    optional<vector<uint8_t>> pubKey =
            android::hardware::identity::support::ecKeyPairGetPublicKey(keyPair.value());
    if (!pubKey) {
        eicDebug("Error extracting public key");
        return false;
    }
    // ecKeyPairGetPublicKey() returns 0x04 | x | y, we don't want the leading 0x04.
    if (pubKey.value().size() != EIC_P256_PUB_KEY_SIZE + 1) {
        eicDebug("Private key is %zd bytes long, expected %zd", pubKey.value().size(),
                 (size_t)EIC_P256_PRIV_KEY_SIZE + 1);
        return false;
    }

    memcpy(privateKey, privKey.value().data(), EIC_P256_PRIV_KEY_SIZE);
    memcpy(publicKey, pubKey.value().data() + 1, EIC_P256_PUB_KEY_SIZE);

    return true;
}

bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
                               size_t challengeSize, const uint8_t* applicationId,
                               size_t applicationIdSize, bool testCredential, uint8_t* cert,
                               size_t* certSize) {
    vector<uint8_t> challengeVec(challengeSize);
    memcpy(challengeVec.data(), challenge, challengeSize);

    vector<uint8_t> applicationIdVec(applicationIdSize);
    memcpy(applicationIdVec.data(), applicationId, applicationIdSize);

    optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
            android::hardware::identity::support::createEcKeyPairAndAttestation(
                    challengeVec, applicationIdVec, testCredential);
    if (!ret) {
        eicDebug("Error generating CredentialKey and attestation");
        return false;
    }

    // Extract certificate chain.
    vector<uint8_t> flatChain =
            android::hardware::identity::support::certificateChainJoin(ret.value().second);
    if (*certSize < flatChain.size()) {
        eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes", *certSize,
                 flatChain.size());
        return false;
    }
    memcpy(cert, flatChain.data(), flatChain.size());
    *certSize = flatChain.size();

    // Extract private key.
    optional<vector<uint8_t>> privKey =
            android::hardware::identity::support::ecKeyPairGetPrivateKey(ret.value().first);
    if (!privKey) {
        eicDebug("Error extracting private key");
        return false;
    }
    if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) {
        eicDebug("Private key is not %zd bytes long as expected", (size_t)EIC_P256_PRIV_KEY_SIZE);
        return false;
    }

    memcpy(privateKey, privKey.value().data(), EIC_P256_PRIV_KEY_SIZE);

    return true;
}

bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
                     const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE], unsigned int serial,
                     const char* issuerName, const char* subjectName, time_t validityNotBefore,
                     time_t validityNotAfter, uint8_t* cert,
                     size_t* certSize) {  // inout
    vector<uint8_t> signingKeyVec(EIC_P256_PRIV_KEY_SIZE);
    memcpy(signingKeyVec.data(), signingKey, EIC_P256_PRIV_KEY_SIZE);

    vector<uint8_t> pubKeyVec(EIC_P256_PUB_KEY_SIZE + 1);
    pubKeyVec[0] = 0x04;
    memcpy(pubKeyVec.data() + 1, publicKey, EIC_P256_PUB_KEY_SIZE);

    std::string serialDecimal = android::base::StringPrintf("%d", serial);

    optional<vector<uint8_t>> certVec =
            android::hardware::identity::support::ecPublicKeyGenerateCertificate(
                    pubKeyVec, signingKeyVec, serialDecimal, issuerName, subjectName,
                    validityNotBefore, validityNotAfter);
    if (!certVec) {
        eicDebug("Error generating certificate");
        return false;
    }

    if (*certSize < certVec.value().size()) {
        eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes", *certSize,
                 certVec.value().size());
        return false;
    }
    memcpy(cert, certVec.value().data(), certVec.value().size());
    *certSize = certVec.value().size();

    return true;
}

bool eicOpsEcDsa(const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
                 const uint8_t digestOfData[EIC_SHA256_DIGEST_SIZE],
                 uint8_t signature[EIC_ECDSA_P256_SIGNATURE_SIZE]) {
    vector<uint8_t> privKeyVec(EIC_P256_PRIV_KEY_SIZE);
    memcpy(privKeyVec.data(), privateKey, EIC_P256_PRIV_KEY_SIZE);

    vector<uint8_t> digestVec(EIC_SHA256_DIGEST_SIZE);
    memcpy(digestVec.data(), digestOfData, EIC_SHA256_DIGEST_SIZE);

    optional<vector<uint8_t>> derSignature =
            android::hardware::identity::support::signEcDsaDigest(privKeyVec, digestVec);
    if (!derSignature) {
        eicDebug("Error signing data");
        return false;
    }

    ECDSA_SIG* sig;
    const unsigned char* p = derSignature.value().data();
    sig = d2i_ECDSA_SIG(nullptr, &p, derSignature.value().size());
    if (sig == nullptr) {
        eicDebug("Error decoding DER signature");
        return false;
    }

    if (BN_bn2binpad(sig->r, signature, 32) != 32) {
        eicDebug("Error encoding r");
        return false;
    }
    if (BN_bn2binpad(sig->s, signature + 32, 32) != 32) {
        eicDebug("Error encoding s");
        return false;
    }

    return true;
}

static const uint8_t hbkTest[16] = {0};
static const uint8_t hbkReal[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

const uint8_t* eicOpsGetHardwareBoundKey(bool testCredential) {
    if (testCredential) {
        return hbkTest;
    }
    return hbkReal;
}

bool eicOpsValidateAuthToken(uint64_t /* challenge */, uint64_t /* secureUserId */,
                             uint64_t /* authenticatorId */, int /* hardwareAuthenticatorType */,
                             uint64_t /* timeStamp */, const uint8_t* /* mac */,
                             size_t /* macSize */, uint64_t /* verificationTokenChallenge */,
                             uint64_t /* verificationTokenTimeStamp */,
                             int /* verificationTokenSecurityLevel */,
                             const uint8_t* /* verificationTokenMac */,
                             size_t /* verificationTokenMacSize */) {
    // Here's where we would validate the passed-in |authToken| to assure ourselves
    // that it comes from the e.g. biometric hardware and wasn't made up by an attacker.
    //
    // However this involves calculating the MAC which requires access to the to
    // a pre-shared key which we don't have...
    //
    return true;
}

bool eicOpsX509GetPublicKey(const uint8_t* x509Cert, size_t x509CertSize, uint8_t* publicKey,
                            size_t* publicKeySize) {
    vector<uint8_t> chain;
    chain.resize(x509CertSize);
    memcpy(chain.data(), x509Cert, x509CertSize);
    optional<vector<uint8_t>> res =
            android::hardware::identity::support::certificateChainGetTopMostKey(chain);
    if (!res) {
        return false;
    }
    if (res.value().size() > *publicKeySize) {
        eicDebug("Public key size is %zd but buffer only has room for %zd bytes",
                 res.value().size(), *publicKeySize);
        return false;
    }
    *publicKeySize = res.value().size();
    memcpy(publicKey, res.value().data(), *publicKeySize);
    eicDebug("Extracted %zd bytes public key from %zd bytes X.509 cert", *publicKeySize,
             x509CertSize);
    return true;
}

bool eicOpsX509CertSignedByPublicKey(const uint8_t* x509Cert, size_t x509CertSize,
                                     const uint8_t* publicKey, size_t publicKeySize) {
    vector<uint8_t> certVec(x509Cert, x509Cert + x509CertSize);
    vector<uint8_t> publicKeyVec(publicKey, publicKey + publicKeySize);
    return android::hardware::identity::support::certificateSignedByPublicKey(certVec,
                                                                              publicKeyVec);
}

bool eicOpsEcDsaVerifyWithPublicKey(const uint8_t* digest, size_t digestSize,
                                    const uint8_t* signature, size_t signatureSize,
                                    const uint8_t* publicKey, size_t publicKeySize) {
    vector<uint8_t> digestVec(digest, digest + digestSize);
    vector<uint8_t> signatureVec(signature, signature + signatureSize);
    vector<uint8_t> publicKeyVec(publicKey, publicKey + publicKeySize);

    vector<uint8_t> derSignature;
    if (!android::hardware::identity::support::ecdsaSignatureCoseToDer(signatureVec,
                                                                       derSignature)) {
        LOG(ERROR) << "Error convering signature to DER format";
        return false;
    }

    if (!android::hardware::identity::support::checkEcDsaSignature(digestVec, derSignature,
                                                                   publicKeyVec)) {
        LOG(ERROR) << "Signature check failed";
        return false;
    }
    return true;
}

bool eicOpsEcdh(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
                const uint8_t privateKey[EIC_P256_PUB_KEY_SIZE],
                uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE]) {
    vector<uint8_t> pubKeyVec(EIC_P256_PUB_KEY_SIZE + 1);
    pubKeyVec[0] = 0x04;
    memcpy(pubKeyVec.data() + 1, publicKey, EIC_P256_PUB_KEY_SIZE);

    vector<uint8_t> privKeyVec(EIC_P256_PRIV_KEY_SIZE);
    memcpy(privKeyVec.data(), privateKey, EIC_P256_PRIV_KEY_SIZE);

    optional<vector<uint8_t>> shared =
            android::hardware::identity::support::ecdh(pubKeyVec, privKeyVec);
    if (!shared) {
        LOG(ERROR) << "Error performing ECDH";
        return false;
    }
    if (shared.value().size() != EIC_P256_COORDINATE_SIZE) {
        LOG(ERROR) << "Unexpected size of shared secret " << shared.value().size() << " expected "
                   << EIC_P256_COORDINATE_SIZE << " bytes";
        return false;
    }
    memcpy(sharedSecret, shared.value().data(), EIC_P256_COORDINATE_SIZE);
    return true;
}

bool eicOpsHkdf(const uint8_t* sharedSecret, size_t sharedSecretSize, const uint8_t* salt,
                size_t saltSize, const uint8_t* info, size_t infoSize, uint8_t* output,
                size_t outputSize) {
    vector<uint8_t> sharedSecretVec(sharedSecretSize);
    memcpy(sharedSecretVec.data(), sharedSecret, sharedSecretSize);
    vector<uint8_t> saltVec(saltSize);
    memcpy(saltVec.data(), salt, saltSize);
    vector<uint8_t> infoVec(infoSize);
    memcpy(infoVec.data(), info, infoSize);

    optional<vector<uint8_t>> result = android::hardware::identity::support::hkdf(
            sharedSecretVec, saltVec, infoVec, outputSize);
    if (!result) {
        LOG(ERROR) << "Error performing HKDF";
        return false;
    }
    if (result.value().size() != outputSize) {
        LOG(ERROR) << "Unexpected size of HKDF " << result.value().size() << " expected "
                   << outputSize;
        return false;
    }
    memcpy(output, result.value().data(), outputSize);
    return true;
}

#ifdef EIC_DEBUG

void eicPrint(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
}

void eicHexdump(const char* message, const uint8_t* data, size_t dataSize) {
    vector<uint8_t> dataVec(dataSize);
    memcpy(dataVec.data(), data, dataSize);
    android::hardware::identity::support::hexdump(message, dataVec);
}

void eicCborPrettyPrint(const uint8_t* cborData, size_t cborDataSize, size_t maxBStrSize) {
    vector<uint8_t> cborDataVec(cborDataSize);
    memcpy(cborDataVec.data(), cborData, cborDataSize);
    string str =
            android::hardware::identity::support::cborPrettyPrint(cborDataVec, maxBStrSize, {});
    fprintf(stderr, "%s\n", str.c_str());
}

#endif  // EIC_DEBUG
+46 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2020, 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.
 */

#ifndef ANDROID_HARDWARE_IDENTITY_EIC_OPS_IMPL_H
#define ANDROID_HARDWARE_IDENTITY_EIC_OPS_IMPL_H

#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>

// Add whatever includes are needed for definitions below.
//

#include <openssl/hmac.h>
#include <openssl/sha.h>

#ifdef __cplusplus
extern "C" {
#endif

// Set the following defines to match the implementation of the supplied
// eicOps*() operations. See EicOps.h for details.
//

#define EIC_SHA256_CONTEXT_SIZE sizeof(SHA256_CTX)

#define EIC_HMAC_SHA256_CONTEXT_SIZE sizeof(HMAC_CTX)

#ifdef __cplusplus
}
#endif

#endif  // ANDROID_HARDWARE_IDENTITY_EMBEDDED_IC_H
Loading