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