1 /* 2 * Copyright 2020, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #if !defined(EIC_INSIDE_LIBEIC_H) && !defined(EIC_COMPILATION) 18 #error "Never include this file directly, include libeic.h instead." 19 #endif 20 21 #ifndef ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H 22 #define ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 #include "EicOps.h" 29 30 typedef enum { 31 EIC_CBOR_DIGEST_TYPE_SHA256, 32 EIC_CBOR_DIGEST_TYPE_HMAC_SHA256, 33 } EicCborDigestType; 34 35 /* EicCbor is a utility class to build CBOR data structures and calculate 36 * digests on the fly. 37 */ 38 typedef struct { 39 // Contains the size of the built CBOR, even if it exceeds bufferSize (will 40 // never write to buffer beyond bufferSize though) 41 size_t size; 42 43 // The size of the buffer. Is zero if no data is recorded in which case 44 // only digesting is performed. 45 size_t bufferSize; 46 47 // Whether we're producing a SHA-256 or HMAC-SHA256 digest. 48 EicCborDigestType digestType; 49 50 // The SHA-256 digester object. 51 union { 52 EicSha256Ctx sha256; 53 EicHmacSha256Ctx hmacSha256; 54 } digester; 55 56 // The secondary digester, may be unset. 57 EicSha256Ctx* secondaryDigesterSha256; 58 59 // The buffer used for building up CBOR or NULL if bufferSize is 0. 60 uint8_t* buffer; 61 } EicCbor; 62 63 /* Initializes an EicCbor. 64 * 65 * The given buffer will be used, up to bufferSize. 66 * 67 * If bufferSize is 0, buffer may be NULL. 68 */ 69 void eicCborInit(EicCbor* cbor, uint8_t* buffer, size_t bufferSize); 70 71 /* Like eicCborInit() but uses HMAC-SHA256 instead of SHA-256. 72 */ 73 void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize, 74 const uint8_t* hmacKey, size_t hmacKeySize); 75 76 /* Enables a secondary digester. 77 * 78 * May be enabled midway through processing, this can be used to e.g. calculate 79 * a digest of Sig_structure (for COSE_Sign1) and a separate digest of its 80 * payload. 81 */ 82 void eicCborEnableSecondaryDigesterSha256(EicCbor* cbor, EicSha256Ctx* sha256); 83 84 /* Finishes building CBOR and returns the digest. */ 85 void eicCborFinal(EicCbor* cbor, uint8_t digest[EIC_SHA256_DIGEST_SIZE]); 86 87 /* Appends CBOR data to the EicCbor. */ 88 void eicCborAppend(EicCbor* cbor, const uint8_t* data, size_t size); 89 90 #define EIC_CBOR_MAJOR_TYPE_UNSIGNED 0 91 #define EIC_CBOR_MAJOR_TYPE_NEGATIVE 1 92 #define EIC_CBOR_MAJOR_TYPE_BYTE_STRING 2 93 #define EIC_CBOR_MAJOR_TYPE_STRING 3 94 #define EIC_CBOR_MAJOR_TYPE_ARRAY 4 95 #define EIC_CBOR_MAJOR_TYPE_MAP 5 96 #define EIC_CBOR_MAJOR_TYPE_SEMANTIC 6 97 #define EIC_CBOR_MAJOR_TYPE_SIMPLE 7 98 99 #define EIC_CBOR_SIMPLE_VALUE_FALSE 20 100 #define EIC_CBOR_SIMPLE_VALUE_TRUE 21 101 102 #define EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR 24 103 104 /* Begins a new CBOR value. */ 105 void eicCborBegin(EicCbor* cbor, int majorType, uint64_t size); 106 107 /* Appends a bytestring. */ 108 void eicCborAppendByteString(EicCbor* cbor, const uint8_t* data, size_t dataSize); 109 110 /* Appends a UTF-8 string. */ 111 void eicCborAppendString(EicCbor* cbor, const char* str, size_t strLength); 112 113 /* Appends a NUL-terminated UTF-8 string. */ 114 void eicCborAppendStringZ(EicCbor* cbor, const char* str); 115 116 /* Appends a simple value. */ 117 void eicCborAppendSimple(EicCbor* cbor, uint8_t simpleValue); 118 119 /* Appends a boolean. */ 120 void eicCborAppendBool(EicCbor* cbor, bool value); 121 122 /* Appends a semantic */ 123 void eicCborAppendSemantic(EicCbor* cbor, uint64_t value); 124 125 /* Appends an unsigned number. */ 126 void eicCborAppendUnsigned(EicCbor* cbor, uint64_t value); 127 128 /* Appends a number. */ 129 void eicCborAppendNumber(EicCbor* cbor, int64_t value); 130 131 /* Starts appending an array. 132 * 133 * After this numElements CBOR elements must follow. 134 */ 135 void eicCborAppendArray(EicCbor* cbor, size_t numElements); 136 137 /* Starts appending a map. 138 * 139 * After this numPairs pairs of CBOR elements must follow. 140 */ 141 void eicCborAppendMap(EicCbor* cbor, size_t numPairs); 142 143 /* Calculates how many bytes are needed to store a size. */ 144 size_t eicCborAdditionalLengthBytesFor(size_t size); 145 146 bool eicCborCalcAccessControl(EicCbor* cborBuilder, int id, const uint8_t* readerCertificate, 147 size_t readerCertificateSize, bool userAuthenticationRequired, 148 uint64_t timeoutMillis, uint64_t secureUserId); 149 150 bool eicCborCalcEntryAdditionalData(const uint8_t* accessControlProfileIds, 151 size_t numAccessControlProfileIds, const char* nameSpace, 152 size_t nameSpaceLength, const char* name, 153 size_t nameLength, uint8_t* cborBuffer, 154 size_t cborBufferSize, size_t* outAdditionalDataCborSize, 155 uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]); 156 157 #ifdef __cplusplus 158 } 159 #endif 160 161 #endif // ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H 162