You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
5.5 KiB
168 lines
5.5 KiB
/*
|
|
* 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
|