1 /****************************************************************************** 2 * 3 * Copyright 2019 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #include "security/ecdh_keys.h" 20 21 /********************************************************************************************************************** 22 TODO: We should have random number management in separate file, and we 23 should honour all the random number requirements from the spec!! 24 **********************************************************************************************************************/ 25 #include <string.h> 26 #include <chrono> 27 #include <cstdlib> 28 29 #include "security/ecc/p_256_ecc_pp.h" 30 31 namespace { 32 33 static bool srand_initiated = false; 34 35 template <size_t SIZE> 36 static std::array<uint8_t, SIZE> GenerateRandom() { 37 if (!srand_initiated) { 38 srand_initiated = true; 39 // TODO: We need a proper random number generator here. 40 // use current time as seed for random generator 41 std::srand(std::time(nullptr)); 42 } 43 44 std::array<uint8_t, SIZE> r; 45 for (size_t i = 0; i < SIZE; i++) r[i] = std::rand(); 46 return r; 47 } 48 } // namespace 49 /*********************************************************************************************************************/ 50 51 namespace bluetooth { 52 namespace security { 53 54 std::pair<std::array<uint8_t, 32>, EcdhPublicKey> GenerateECDHKeyPair() { 55 std::array<uint8_t, 32> private_key = GenerateRandom<32>(); 56 std::array<uint8_t, 32> private_key_copy = private_key; 57 ecc::Point public_key; 58 59 ECC_PointMult(&public_key, &(ecc::curve_p256.G), (uint32_t*)private_key_copy.data()); 60 61 EcdhPublicKey pk; 62 memcpy(pk.x.data(), public_key.x, 32); 63 memcpy(pk.y.data(), public_key.y, 32); 64 65 /* private_key, public key pair */ 66 return std::make_pair<std::array<uint8_t, 32>, EcdhPublicKey>(std::move(private_key), std::move(pk)); 67 } 68 69 bool ValidateECDHPoint(EcdhPublicKey pk) { 70 ecc::Point public_key; 71 memcpy(public_key.x, pk.x.data(), 32); 72 memcpy(public_key.y, pk.y.data(), 32); 73 memset(public_key.z, 0, 32); 74 return ECC_ValidatePoint(public_key); 75 } 76 77 std::array<uint8_t, 32> ComputeDHKey(std::array<uint8_t, 32> my_private_key, EcdhPublicKey remote_public_key) { 78 ecc::Point peer_publ_key, new_publ_key; 79 uint32_t private_key[8]; 80 memcpy(private_key, my_private_key.data(), 32); 81 memcpy(peer_publ_key.x, remote_public_key.x.data(), 32); 82 memcpy(peer_publ_key.y, remote_public_key.y.data(), 32); 83 memset(peer_publ_key.z, 0, 32); 84 peer_publ_key.z[0] = 1; 85 86 ECC_PointMult(&new_publ_key, &peer_publ_key, (uint32_t*)private_key); 87 88 std::array<uint8_t, 32> dhkey; 89 memcpy(dhkey.data(), new_publ_key.x, 32); 90 return dhkey; 91 } 92 93 } // namespace security 94 } // namespace bluetooth 95