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 #include "securec.h" 23 24 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) 25 #include <linux/fscrypt.h> 26 #define SUPPORT_FSCRYPT_V2 27 #else 28 #include "libfscrypt/fscrypt_uapi.h" 29 #endif 30 31 namespace OHOS { 32 namespace StorageDaemon { 33 constexpr uint32_t CRYPTO_KEY_SECDISC_SIZE = 16384; 34 constexpr uint32_t CRYPTO_AES_256_XTS_KEY_SIZE = 64; 35 36 using key_serial_t = int; 37 constexpr uint32_t CRYPTO_KEY_DESC_SIZE = FSCRYPT_KEY_DESCRIPTOR_SIZE; 38 constexpr const char *MNT_DATA = "/data"; 39 constexpr const char *PATH_LATEST = "/latest"; 40 constexpr const char *PATH_SHIELD = "/shield"; 41 constexpr const char *PATH_SECDISC = "/sec_discard"; 42 constexpr const char *PATH_ENCRYPTED = "/encrypted"; 43 constexpr const char *PATH_KEYID = "/key_id"; 44 constexpr const char *PATH_KEYDESC = "/key_desc"; 45 46 constexpr const char *DATA_EL0_DIR = "/data/service/el0"; 47 constexpr const char *STORAGE_DAEMON_DIR = "/data/service/el0/storage_daemon"; 48 constexpr const char *DEVICE_EL1_DIR = "/data/service/el0/storage_daemon/sd"; 49 50 class KeyBlob { 51 public: 52 KeyBlob() = default; KeyBlob(KeyBlob const & blob)53 KeyBlob(KeyBlob const &blob) 54 { 55 Alloc(blob.size); 56 auto ret = memcpy_s(data.get(), size, blob.data.get(), blob.size); 57 if (ret != EOK) { 58 Clear(); 59 } 60 } ~KeyBlob()61 ~KeyBlob() 62 { 63 Clear(); 64 } KeyBlob(uint32_t len)65 KeyBlob(uint32_t len) 66 { 67 Alloc(len); 68 // may fail, need check IsEmpty() if needed 69 } KeyBlob(KeyBlob && right)70 KeyBlob(KeyBlob &&right) 71 { 72 data = std::move(right.data); 73 size = right.size; 74 } KeyBlob(const std::vector<uint8_t> & vec)75 KeyBlob(const std::vector<uint8_t> &vec) 76 { 77 if (Alloc(vec.size())) { 78 auto ret = memcpy_s(data.get(), size, vec.data(), vec.size()); 79 if (ret != EOK) { 80 Clear(); 81 } 82 } 83 } 84 KeyBlob& operator=(KeyBlob &&right) 85 { 86 data = std::move(right.data); 87 size = right.size; 88 return *this; 89 } Alloc(uint32_t len)90 bool Alloc(uint32_t len) 91 { 92 if (len > CRYPTO_KEY_SECDISC_SIZE) { 93 return false; 94 } 95 if (!IsEmpty()) { 96 Clear(); 97 } 98 99 data = std::make_unique<uint8_t[]>(len); 100 size = len; 101 (void)memset_s(data.get(), size, 0, size); 102 return true; 103 } Clear()104 void Clear() 105 { 106 if (data != nullptr && size != 0) { 107 (void)memset_s(data.get(), size, 0, size); 108 } 109 size = 0; 110 data.reset(nullptr); 111 } IsEmpty()112 bool IsEmpty() const 113 { 114 return size == 0 || data.get() == nullptr; 115 } ToString()116 std::string ToString() const 117 { 118 std::string hex; 119 if (IsEmpty()) { 120 return hex; 121 } 122 const char *hexMap = "0123456789abcdef"; 123 static_assert(sizeof(data[0]) == sizeof(char)); 124 for (size_t i = 0; i < size; i++) { 125 hex = hex + hexMap[(data[i] & 0xF0) >> 4] + hexMap[data[i] & 0x0F]; // higher 4 bits 126 } 127 return hex; 128 } ToHksBlob()129 HksBlob ToHksBlob() const 130 { 131 return {size, data.get()}; 132 } 133 uint32_t size { 0 }; 134 std::unique_ptr<uint8_t[]> data { nullptr }; 135 }; 136 137 struct KeyInfo { 138 uint8_t version { 0 }; 139 KeyBlob key; 140 // the legacy interface use key_spec.u.descriptor 141 KeyBlob keyDesc; 142 // the v2 interface use the key_spec.u.identifier 143 KeyBlob keyId; 144 }; 145 146 struct KeyContext { 147 // secure discardable keyblob 148 KeyBlob secDiscard; 149 // encrypted huks key for encrypt/decrypt 150 KeyBlob shield; 151 // encrypted blob of rawkey 152 KeyBlob rndEnc; 153 // aes_gcm tags 154 KeyBlob nonce; 155 KeyBlob aad; 156 }; 157 158 struct UserAuth { 159 // when secure access enabled, token is needed to authenticate the user 160 KeyBlob token; 161 KeyBlob secret; 162 uint64_t secureUid { 0 }; 163 }; 164 } // namespace StorageDaemon 165 } // namespace OHOS 166 167 #endif // STORAGE_DAEMON_CRYPTO_KEY_UTILS_H 168