1 /* 2 * Copyright (C) 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 #include "adb/pairing/pairing_auth.h" 18 19 #include <android-base/logging.h> 20 21 #include <openssl/curve25519.h> 22 #include <openssl/mem.h> 23 24 #include <iomanip> 25 #include <sstream> 26 #include <vector> 27 28 #include "adb/pairing/aes_128_gcm.h" 29 30 using namespace adb::pairing; 31 32 static constexpr spake2_role_t kClientRole = spake2_role_alice; 33 static constexpr spake2_role_t kServerRole = spake2_role_bob; 34 35 static const uint8_t kClientName[] = "adb pair client"; 36 static const uint8_t kServerName[] = "adb pair server"; 37 38 // This class is basically a wrapper around the SPAKE2 protocol + initializing a 39 // cipher with the generated key material for encryption. 40 struct PairingAuthCtx { 41 public: 42 using Data = std::vector<uint8_t>; 43 enum class Role { 44 Client, 45 Server, 46 }; 47 48 explicit PairingAuthCtx(Role role, const Data& pswd); 49 50 // Returns the message to exchange with the other party. This is guaranteed 51 // to have a non-empty message if creating this object with 52 // |PairingAuthCtx::Create|, so you won't need to check. 53 const Data& msg() const; 54 55 // Processes the peer's |msg| and attempts to initialize the cipher for 56 // encryption. You can only call this method ONCE with a non-empty |msg|, 57 // regardless of success or failure. Subsequent calls will always return 58 // false. On success, you can use the |decrypt| 59 // and |encrypt| methods to exchange any further information securely. 60 // 61 // Note: Once you call this with a non-empty key, the state is locked, which 62 // means that you cannot try and register another key, regardless of the 63 // return value. In order to register another key, you have to create a new 64 // instance of PairingAuthCtx. 65 bool InitCipher(const Data& their_msg); 66 67 // Encrypts |data| and returns the result. If encryption fails, the return 68 // will be an empty vector. 69 Data Encrypt(const Data& data); 70 71 // Decrypts |data| and returns the result. If decryption fails, the return 72 // will be an empty vector. 73 Data Decrypt(const Data& data); 74 75 // Returns a safe buffer size for encrypting a buffer of size |len|. 76 size_t SafeEncryptedSize(size_t len); 77 78 // Returns a safe buffer size for decrypting a buffer of size |len|. 79 size_t SafeDecryptedSize(size_t len); 80 81 private: 82 Data our_msg_; 83 Role role_; 84 bssl::UniquePtr<SPAKE2_CTX> spake2_ctx_; 85 std::unique_ptr<Aes128Gcm> cipher_; 86 }; // PairingAuthCtx 87 88 PairingAuthCtx::PairingAuthCtx(Role role, const Data& pswd) : role_(role) { 89 CHECK(!pswd.empty()); 90 // Try to create the spake2 context and generate the public key. 91 spake2_role_t spake_role; 92 const uint8_t* my_name = nullptr; 93 const uint8_t* their_name = nullptr; 94 size_t my_len = 0; 95 size_t their_len = 0; 96 97 // Create the SPAKE2 context 98 switch (role_) { 99 case Role::Client: 100 spake_role = kClientRole; 101 my_name = kClientName; 102 my_len = sizeof(kClientName); 103 their_name = kServerName; 104 their_len = sizeof(kServerName); 105 break; 106 case Role::Server: 107 spake_role = kServerRole; 108 my_name = kServerName; 109 my_len = sizeof(kServerName); 110 their_name = kClientName; 111 their_len = sizeof(kClientName); 112 break; 113 } 114 spake2_ctx_.reset(SPAKE2_CTX_new(spake_role, my_name, my_len, their_name, their_len)); 115 if (spake2_ctx_ == nullptr) { 116 LOG(ERROR) << "Unable to create a SPAKE2 context."; 117 return; 118 } 119 120 // Generate the SPAKE2 public key 121 size_t key_size = 0; 122 uint8_t key[SPAKE2_MAX_MSG_SIZE]; 123 int status = SPAKE2_generate_msg(spake2_ctx_.get(), key, &key_size, SPAKE2_MAX_MSG_SIZE, 124 pswd.data(), pswd.size()); 125 if (status != 1 || key_size == 0) { 126 LOG(ERROR) << "Unable to generate the SPAKE2 public key."; 127 return; 128 } 129 our_msg_.assign(key, key + key_size); 130 } 131 132 const PairingAuthCtx::Data& PairingAuthCtx::msg() const { 133 return our_msg_; 134 } 135 136 bool PairingAuthCtx::InitCipher(const PairingAuthCtx::Data& their_msg) { 137 // You can only register a key once. 138 CHECK(!their_msg.empty()); 139 CHECK(!cipher_); 140 141 // Don't even try to process a message over the SPAKE2_MAX_MSG_SIZE 142 if (their_msg.size() > SPAKE2_MAX_MSG_SIZE) { 143 LOG(ERROR) << "their_msg size [" << their_msg.size() << "] greater then max size [" 144 << SPAKE2_MAX_MSG_SIZE << "]."; 145 return false; 146 } 147 148 size_t key_material_len = 0; 149 uint8_t key_material[SPAKE2_MAX_KEY_SIZE]; 150 int status = SPAKE2_process_msg(spake2_ctx_.get(), key_material, &key_material_len, 151 sizeof(key_material), their_msg.data(), their_msg.size()); 152 if (status != 1) { 153 LOG(ERROR) << "Unable to process their public key"; 154 return false; 155 } 156 157 // Once SPAKE2_process_msg returns successfully, you can't do anything else 158 // with the context, besides destroy it. 159 cipher_.reset(new Aes128Gcm(key_material, key_material_len)); 160 161 return true; 162 } 163 164 PairingAuthCtx::Data PairingAuthCtx::Encrypt(const PairingAuthCtx::Data& data) { 165 CHECK(cipher_); 166 CHECK(!data.empty()); 167 168 // Determine the size for the encrypted data based on the raw data. 169 Data encrypted(cipher_->EncryptedSize(data.size())); 170 auto out_size = cipher_->Encrypt(data.data(), data.size(), encrypted.data(), encrypted.size()); 171 if (!out_size.has_value() || *out_size == 0) { 172 LOG(ERROR) << "Unable to encrypt data"; 173 return Data(); 174 } 175 encrypted.resize(*out_size); 176 177 return encrypted; 178 } 179 180 PairingAuthCtx::Data PairingAuthCtx::Decrypt(const PairingAuthCtx::Data& data) { 181 CHECK(cipher_); 182 CHECK(!data.empty()); 183 184 // Determine the size for the decrypted data based on the raw data. 185 Data decrypted(cipher_->DecryptedSize(data.size())); 186 size_t decrypted_size = decrypted.size(); 187 auto out_size = cipher_->Decrypt(data.data(), data.size(), decrypted.data(), decrypted_size); 188 if (!out_size.has_value() || *out_size == 0) { 189 LOG(ERROR) << "Unable to decrypt data"; 190 return Data(); 191 } 192 decrypted.resize(*out_size); 193 194 return decrypted; 195 } 196 197 size_t PairingAuthCtx::SafeEncryptedSize(size_t len) { 198 CHECK(cipher_); 199 return cipher_->EncryptedSize(len); 200 } 201 202 size_t PairingAuthCtx::SafeDecryptedSize(size_t len) { 203 CHECK(cipher_); 204 return cipher_->DecryptedSize(len); 205 } 206 207 PairingAuthCtx* pairing_auth_server_new(const uint8_t* pswd, size_t len) { 208 CHECK(pswd); 209 CHECK_GT(len, 0U); 210 std::vector<uint8_t> p(pswd, pswd + len); 211 auto* ret = new PairingAuthCtx(PairingAuthCtx::Role::Server, std::move(p)); 212 CHECK(!ret->msg().empty()); 213 return ret; 214 } 215 216 PairingAuthCtx* pairing_auth_client_new(const uint8_t* pswd, size_t len) { 217 CHECK(pswd); 218 CHECK_GT(len, 0U); 219 std::vector<uint8_t> p(pswd, pswd + len); 220 auto* ret = new PairingAuthCtx(PairingAuthCtx::Role::Client, std::move(p)); 221 CHECK(!ret->msg().empty()); 222 return ret; 223 } 224 225 size_t pairing_auth_msg_size(PairingAuthCtx* ctx) { 226 CHECK(ctx); 227 return ctx->msg().size(); 228 } 229 230 void pairing_auth_get_spake2_msg(PairingAuthCtx* ctx, uint8_t* out_buf) { 231 CHECK(ctx); 232 CHECK(out_buf); 233 auto& msg = ctx->msg(); 234 memcpy(out_buf, msg.data(), msg.size()); 235 } 236 237 bool pairing_auth_init_cipher(PairingAuthCtx* ctx, const uint8_t* their_msg, size_t msg_len) { 238 CHECK(ctx); 239 CHECK(their_msg); 240 CHECK_GT(msg_len, 0U); 241 242 std::vector<uint8_t> p(their_msg, their_msg + msg_len); 243 return ctx->InitCipher(p); 244 } 245 246 size_t pairing_auth_safe_encrypted_size(PairingAuthCtx* ctx, size_t len) { 247 CHECK(ctx); 248 return ctx->SafeEncryptedSize(len); 249 } 250 251 bool pairing_auth_encrypt(PairingAuthCtx* ctx, const uint8_t* inbuf, size_t inlen, uint8_t* outbuf, 252 size_t* outlen) { 253 CHECK(ctx); 254 CHECK(inbuf); 255 CHECK(outbuf); 256 CHECK(outlen); 257 CHECK_GT(inlen, 0U); 258 259 std::vector<uint8_t> in(inbuf, inbuf + inlen); 260 auto out = ctx->Encrypt(in); 261 if (out.empty()) { 262 return false; 263 } 264 265 memcpy(outbuf, out.data(), out.size()); 266 *outlen = out.size(); 267 return true; 268 } 269 270 size_t pairing_auth_safe_decrypted_size(PairingAuthCtx* ctx, const uint8_t* buf, size_t len) { 271 CHECK(ctx); 272 CHECK(buf); 273 CHECK_GT(len, 0U); 274 // We no longer need buf for EVP_AEAD 275 return ctx->SafeDecryptedSize(len); 276 } 277 278 bool pairing_auth_decrypt(PairingAuthCtx* ctx, const uint8_t* inbuf, size_t inlen, uint8_t* outbuf, 279 size_t* outlen) { 280 CHECK(ctx); 281 CHECK(inbuf); 282 CHECK(outbuf); 283 CHECK(outlen); 284 CHECK_GT(inlen, 0U); 285 286 std::vector<uint8_t> in(inbuf, inbuf + inlen); 287 auto out = ctx->Decrypt(in); 288 if (out.empty()) { 289 return false; 290 } 291 292 memcpy(outbuf, out.data(), out.size()); 293 *outlen = out.size(); 294 return true; 295 } 296 297 void pairing_auth_destroy(PairingAuthCtx* ctx) { 298 CHECK(ctx); 299 delete ctx; 300 } 301