/* * 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. */ #if !defined(EIC_INSIDE_LIBEIC_H) && !defined(EIC_COMPILATION) #error "Never include this file directly, include libeic.h instead." #endif #ifndef ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H #define ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H #ifdef __cplusplus extern "C" { #endif #include "EicOps.h" typedef enum { EIC_CBOR_DIGEST_TYPE_SHA256, EIC_CBOR_DIGEST_TYPE_HMAC_SHA256, } EicCborDigestType; /* EicCbor is a utility class to build CBOR data structures and calculate * digests on the fly. */ typedef struct { // Contains the size of the built CBOR, even if it exceeds bufferSize (will // never write to buffer beyond bufferSize though) size_t size; // The size of the buffer. Is zero if no data is recorded in which case // only digesting is performed. size_t bufferSize; // Whether we're producing a SHA-256 or HMAC-SHA256 digest. EicCborDigestType digestType; // The SHA-256 digester object. union { EicSha256Ctx sha256; EicHmacSha256Ctx hmacSha256; } digester; // The secondary digester, may be unset. EicSha256Ctx* secondaryDigesterSha256; // The buffer used for building up CBOR or NULL if bufferSize is 0. uint8_t* buffer; } EicCbor; /* Initializes an EicCbor. * * The given buffer will be used, up to bufferSize. * * If bufferSize is 0, buffer may be NULL. */ void eicCborInit(EicCbor* cbor, uint8_t* buffer, size_t bufferSize); /* Like eicCborInit() but uses HMAC-SHA256 instead of SHA-256. */ void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize, const uint8_t* hmacKey, size_t hmacKeySize); /* Enables a secondary digester. * * May be enabled midway through processing, this can be used to e.g. calculate * a digest of Sig_structure (for COSE_Sign1) and a separate digest of its * payload. */ void eicCborEnableSecondaryDigesterSha256(EicCbor* cbor, EicSha256Ctx* sha256); /* Finishes building CBOR and returns the digest. */ void eicCborFinal(EicCbor* cbor, uint8_t digest[EIC_SHA256_DIGEST_SIZE]); /* Appends CBOR data to the EicCbor. */ void eicCborAppend(EicCbor* cbor, const uint8_t* data, size_t size); #define EIC_CBOR_MAJOR_TYPE_UNSIGNED 0 #define EIC_CBOR_MAJOR_TYPE_NEGATIVE 1 #define EIC_CBOR_MAJOR_TYPE_BYTE_STRING 2 #define EIC_CBOR_MAJOR_TYPE_STRING 3 #define EIC_CBOR_MAJOR_TYPE_ARRAY 4 #define EIC_CBOR_MAJOR_TYPE_MAP 5 #define EIC_CBOR_MAJOR_TYPE_SEMANTIC 6 #define EIC_CBOR_MAJOR_TYPE_SIMPLE 7 #define EIC_CBOR_SIMPLE_VALUE_FALSE 20 #define EIC_CBOR_SIMPLE_VALUE_TRUE 21 #define EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR 24 /* Begins a new CBOR value. */ void eicCborBegin(EicCbor* cbor, int majorType, size_t size); /* Appends a bytestring. */ void eicCborAppendByteString(EicCbor* cbor, const uint8_t* data, size_t dataSize); /* Appends a NUL-terminated UTF-8 string. */ void eicCborAppendString(EicCbor* cbor, const char* str); /* Appends a simple value. */ void eicCborAppendSimple(EicCbor* cbor, uint8_t simpleValue); /* Appends a boolean. */ void eicCborAppendBool(EicCbor* cbor, bool value); /* Appends a semantic */ void eicCborAppendSemantic(EicCbor* cbor, uint64_t value); /* Appends an unsigned number. */ void eicCborAppendUnsigned(EicCbor* cbor, uint64_t value); /* Appends a number. */ void eicCborAppendNumber(EicCbor* cbor, int64_t value); /* Starts appending an array. * * After this numElements CBOR elements must follow. */ void eicCborAppendArray(EicCbor* cbor, size_t numElements); /* Starts appending a map. * * After this numPairs pairs of CBOR elements must follow. */ void eicCborAppendMap(EicCbor* cbor, size_t numPairs); /* Calculates how many bytes are needed to store a size. */ size_t eicCborAdditionalLengthBytesFor(size_t size); bool eicCborCalcAccessControl(EicCbor* cborBuilder, int id, const uint8_t* readerCertificate, size_t readerCertificateSize, bool userAuthenticationRequired, uint64_t timeoutMillis, uint64_t secureUserId); bool eicCborCalcEntryAdditionalData(const int* accessControlProfileIds, size_t numAccessControlProfileIds, const char* nameSpace, const char* name, uint8_t* cborBuffer, size_t cborBufferSize, size_t* outAdditionalDataCborSize, uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]); // The maximum size of an encoded Secure Access Control Profile that we // support. Since the SACP may contain a reader certificate chain these can get // pretty big. // // Currently we allocate space on the stack for this structure which is why we // have a maximum size. We can get rid of the maximum size by incrementally // building/verifying the SACP. TODO: actually do this. // #define EIC_MAX_CBOR_SIZE_FOR_ACCESS_CONTROL_PROFILE 512 #ifdef __cplusplus } #endif #endif // ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H