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>
GenerateRandom()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
GenerateECDHKeyPair()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
ValidateECDHPoint(EcdhPublicKey pk)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
ComputeDHKey(std::array<uint8_t,32> my_private_key,EcdhPublicKey remote_public_key)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