1 /* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef STORAGE_DAEMON_CRYPTO_KEY_UTILS_H 16 #define STORAGE_DAEMON_CRYPTO_KEY_UTILS_H 17 18 #include <string> 19 #include <linux/version.h> 20 21 #include "hks_type.h" 22 #ifdef HUKS_IDL_ENVIRONMENT 23 #include "v1_1/ihuks_types.h" 24 #endif 25 #include "securec.h" 26 27 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) 28 #include <linux/fscrypt.h> 29 #define SUPPORT_FSCRYPT_V2 30 #else 31 #include "libfscrypt/fscrypt_uapi.h" 32 #endif 33 34 namespace OHOS { 35 namespace StorageDaemon { 36 constexpr uint32_t CRYPTO_KEY_SECDISC_SIZE = 16384; 37 constexpr uint32_t CRYPTO_AES_256_XTS_KEY_SIZE = 64; 38 39 using key_serial_t = int; 40 constexpr uint32_t CRYPTO_KEY_DESC_SIZE = FSCRYPT_KEY_DESCRIPTOR_SIZE; 41 constexpr const char *MNT_DATA = "/data"; 42 constexpr const char *PATH_LATEST = "/latest"; 43 constexpr const char *PATH_SHIELD = "/shield"; 44 constexpr const char *PATH_SECDISC = "/sec_discard"; 45 constexpr const char *PATH_ENCRYPTED = "/encrypted"; 46 constexpr const char *PATH_KEYID = "/key_id"; 47 constexpr const char *PATH_KEYDESC = "/key_desc"; 48 49 constexpr const char *DATA_EL0_DIR = "/data/service/el0"; 50 constexpr const char *STORAGE_DAEMON_DIR = "/data/service/el0/storage_daemon"; 51 constexpr const char *DEVICE_EL1_DIR = "/data/service/el0/storage_daemon/sd"; 52 constexpr const char *MAINTAIN_DEVICE_EL1_DIR = "/mnt/data_old/service/el0/storage_daemon/sd"; 53 54 class KeyBlob { 55 public: 56 KeyBlob() = default; KeyBlob(KeyBlob const & blob)57 KeyBlob(KeyBlob const &blob) 58 { 59 Alloc(blob.size); 60 auto ret = memcpy_s(data.get(), size, blob.data.get(), blob.size); 61 if (ret != EOK) { 62 Clear(); 63 } 64 } ~KeyBlob()65 ~KeyBlob() 66 { 67 Clear(); 68 } KeyBlob(uint32_t len)69 KeyBlob(uint32_t len) 70 { 71 Alloc(len); 72 // may fail, need check IsEmpty() if needed 73 } KeyBlob(KeyBlob && right)74 KeyBlob(KeyBlob &&right) 75 { 76 data = std::move(right.data); 77 size = right.size; 78 } KeyBlob(const std::vector<uint8_t> & vec)79 KeyBlob(const std::vector<uint8_t> &vec) 80 { 81 if (Alloc(vec.size())) { 82 auto ret = memcpy_s(data.get(), size, vec.data(), vec.size()); 83 if (ret != EOK) { 84 Clear(); 85 } 86 } 87 } 88 KeyBlob& operator=(KeyBlob &&right) 89 { 90 data = std::move(right.data); 91 size = right.size; 92 return *this; 93 } Alloc(uint32_t len)94 bool Alloc(uint32_t len) 95 { 96 if (len > CRYPTO_KEY_SECDISC_SIZE) { 97 return false; 98 } 99 if (!IsEmpty()) { 100 Clear(); 101 } 102 103 data = std::make_unique<uint8_t[]>(len); 104 size = len; 105 (void)memset_s(data.get(), size, 0, size); 106 return true; 107 } Clear()108 void Clear() 109 { 110 if (data != nullptr && size != 0) { 111 (void)memset_s(data.get(), size, 0, size); 112 } 113 size = 0; 114 data.reset(nullptr); 115 } IsEmpty()116 bool IsEmpty() const 117 { 118 return size == 0 || data.get() == nullptr; 119 } ToString()120 std::string ToString() const 121 { 122 std::string hex; 123 if (IsEmpty()) { 124 return hex; 125 } 126 const char *hexMap = "0123456789abcdef"; 127 static_assert(sizeof(data[0]) == sizeof(char)); 128 for (size_t i = 0; i < size; i++) { 129 hex = hex + hexMap[(data[i] & 0xF0) >> 4] + hexMap[data[i] & 0x0F]; // higher 4 bits 130 } 131 return hex; 132 } ToHksBlob()133 HksBlob ToHksBlob() const 134 { 135 return {size, data.get()}; 136 } 137 #ifdef HUKS_IDL_ENVIRONMENT ToHuksBlob()138 HuksBlob ToHuksBlob() const 139 { 140 return {data.get(), size}; 141 } 142 #endif 143 uint32_t size { 0 }; 144 std::unique_ptr<uint8_t[]> data { nullptr }; 145 }; 146 147 struct KeyInfo { 148 uint8_t version { 0 }; 149 KeyBlob key; 150 // the legacy interface use key_spec.u.descriptor 151 KeyBlob keyDesc; 152 // the v2 interface use the key_spec.u.identifier 153 KeyBlob keyId; 154 // SHA3-512 hash code: key and specify a prefix string 155 KeyBlob keyHash; 156 }; 157 158 struct KeyContext { 159 // secure discardable keyblob 160 KeyBlob secDiscard; 161 // encrypted huks key for encrypt/decrypt 162 KeyBlob shield; 163 // encrypted blob of rawkey 164 KeyBlob rndEnc; 165 // aes_gcm tags 166 KeyBlob nonce; 167 KeyBlob aad; 168 }; 169 170 struct UserAuth { 171 // when secure access enabled, token is needed to authenticate the user 172 KeyBlob token; 173 KeyBlob secret; 174 uint64_t secureUid { 0 }; 175 }; 176 } // namespace StorageDaemon 177 } // namespace OHOS 178 179 #endif // STORAGE_DAEMON_CRYPTO_KEY_UTILS_H 180