Roy Want / Mbed OS beaconCompileReadyFork
Committer:
roywant
Date:
Mon Sep 19 00:59:11 2016 +0000
Revision:
0:ed0152b5c495
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
roywant 0:ed0152b5c495 1 /*
roywant 0:ed0152b5c495 2 * Copyright (c) 2016, Google Inc, All Rights Reserved
roywant 0:ed0152b5c495 3 * SPDX-License-Identifier: Apache-2.0
roywant 0:ed0152b5c495 4 *
roywant 0:ed0152b5c495 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
roywant 0:ed0152b5c495 6 * not use this file except in compliance with the License.
roywant 0:ed0152b5c495 7 * You may obtain a copy of the License at
roywant 0:ed0152b5c495 8 *
roywant 0:ed0152b5c495 9 * http://www.apache.org/licenses/LICENSE-2.0
roywant 0:ed0152b5c495 10 *
roywant 0:ed0152b5c495 11 * Unless required by applicable law or agreed to in writing, software
roywant 0:ed0152b5c495 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
roywant 0:ed0152b5c495 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
roywant 0:ed0152b5c495 14 * See the License for the specific language governing permissions and
roywant 0:ed0152b5c495 15 * limitations under the License.
roywant 0:ed0152b5c495 16 */
roywant 0:ed0152b5c495 17
roywant 0:ed0152b5c495 18 #ifndef __EIDFRAME_H__
roywant 0:ed0152b5c495 19 #define __EIDFRAME_H__
roywant 0:ed0152b5c495 20
roywant 0:ed0152b5c495 21 #include <string.h>
roywant 0:ed0152b5c495 22 #include "EddystoneTypes.h"
roywant 0:ed0152b5c495 23 #include "mbedtls/aes.h"
roywant 0:ed0152b5c495 24 #include "mbedtls/ecdh.h"
roywant 0:ed0152b5c495 25 #include "mbedtls/md.h"
roywant 0:ed0152b5c495 26 #include "mbedtls/entropy.h"
roywant 0:ed0152b5c495 27 #include "mbedtls/ctr_drbg.h"
roywant 0:ed0152b5c495 28 #include "aes_eax.h"
roywant 0:ed0152b5c495 29
roywant 0:ed0152b5c495 30 /**
roywant 0:ed0152b5c495 31 * Class that encapsulates data that belongs to the Eddystone-EID frame. For
roywant 0:ed0152b5c495 32 * more information refer to https://github.com/google/eddystone/tree/master/eddystone-EID.
roywant 0:ed0152b5c495 33 */
roywant 0:ed0152b5c495 34 class EIDFrame
roywant 0:ed0152b5c495 35 {
roywant 0:ed0152b5c495 36 public:
roywant 0:ed0152b5c495 37 static const uint8_t SALT = 0xff;
roywant 0:ed0152b5c495 38 static const uint8_t EID_LENGTH = 8;
roywant 0:ed0152b5c495 39 static const int EID_SUCCESS = 0;
roywant 0:ed0152b5c495 40 static const int EID_RC_SS_IS_ZERO = -1;
roywant 0:ed0152b5c495 41 static const int EID_RND_FAIL = -2;
roywant 0:ed0152b5c495 42 static const int EID_GRP_FAIL = -3;
roywant 0:ed0152b5c495 43 static const int EID_GENKEY_FAIL = -4;
roywant 0:ed0152b5c495 44
roywant 0:ed0152b5c495 45 /**
roywant 0:ed0152b5c495 46 * Construct a new instance of this class.
roywant 0:ed0152b5c495 47 */
roywant 0:ed0152b5c495 48 EIDFrame();
roywant 0:ed0152b5c495 49
roywant 0:ed0152b5c495 50 /**
roywant 0:ed0152b5c495 51 * Clear frame (intervally indicated by length = 0 )
roywant 0:ed0152b5c495 52 */
roywant 0:ed0152b5c495 53 void clearFrame(uint8_t* frame);
roywant 0:ed0152b5c495 54
roywant 0:ed0152b5c495 55 /**
roywant 0:ed0152b5c495 56 * Construct the raw bytes of the Eddystone-EID frame that will be directly
roywant 0:ed0152b5c495 57 * used in the advertising packets.
roywant 0:ed0152b5c495 58 *
roywant 0:ed0152b5c495 59 * @param[in] rawFrame
roywant 0:ed0152b5c495 60 * Pointer to the location where the raw frame will be stored.
roywant 0:ed0152b5c495 61 * @param[in] advPowerLevel
roywant 0:ed0152b5c495 62 * Power level value included in the raw frame.
roywant 0:ed0152b5c495 63 * @param[in] eidData
roywant 0:ed0152b5c495 64 * The actual 16-byte EID data in the raw frame.
roywant 0:ed0152b5c495 65 */
roywant 0:ed0152b5c495 66 void setData(uint8_t* rawFrame, int8_t advTxPower, const uint8_t* eidData);
roywant 0:ed0152b5c495 67
roywant 0:ed0152b5c495 68 /**
roywant 0:ed0152b5c495 69 * Get the EID frame data from the Eddystone-EID frame.
roywant 0:ed0152b5c495 70 *
roywant 0:ed0152b5c495 71 * @param[in] rawFrame
roywant 0:ed0152b5c495 72 * Pointer to the location where the raw frame will be stored.
roywant 0:ed0152b5c495 73 *
roywant 0:ed0152b5c495 74 * @return A pointer to the bytes of the Eddystone-EID frame data.
roywant 0:ed0152b5c495 75 */
roywant 0:ed0152b5c495 76 uint8_t* getData(uint8_t* rawFrame);
roywant 0:ed0152b5c495 77
roywant 0:ed0152b5c495 78 /**
roywant 0:ed0152b5c495 79 * Get the length of the EID frame data from the Eddystone-EID frame.
roywant 0:ed0152b5c495 80 *
roywant 0:ed0152b5c495 81 * @param[in] rawFrame
roywant 0:ed0152b5c495 82 * Pointer to the location where the raw frame will be stored.
roywant 0:ed0152b5c495 83 *
roywant 0:ed0152b5c495 84 * @return The size in bytes of the Eddystone-EID frame.
roywant 0:ed0152b5c495 85 */
roywant 0:ed0152b5c495 86 uint8_t getDataLength(uint8_t* rawFrame);
roywant 0:ed0152b5c495 87
roywant 0:ed0152b5c495 88 /**
roywant 0:ed0152b5c495 89 * Get the EID Adv data from the Eddystone-EID frame.
roywant 0:ed0152b5c495 90 * This is the full service data included in the BLE service data params
roywant 0:ed0152b5c495 91 *
roywant 0:ed0152b5c495 92 * @param[in] rawFrame
roywant 0:ed0152b5c495 93 * Pointer to the location where the raw frame will be stored.
roywant 0:ed0152b5c495 94 *
roywant 0:ed0152b5c495 95 * @return A pointer to the bytes of the Eddystone-EID Adv frame data.
roywant 0:ed0152b5c495 96 */
roywant 0:ed0152b5c495 97 uint8_t* getAdvFrame(uint8_t* rawFrame);
roywant 0:ed0152b5c495 98
roywant 0:ed0152b5c495 99 /**
roywant 0:ed0152b5c495 100 * Get the length of the EID Adv data from the Eddystone-EID frame.
roywant 0:ed0152b5c495 101 *
roywant 0:ed0152b5c495 102 * @param[in] rawFrame
roywant 0:ed0152b5c495 103 * Pointer to the location where the raw frame will be stored.
roywant 0:ed0152b5c495 104 *
roywant 0:ed0152b5c495 105 * @return The size in bytes of the Eddystone-EID Adv frame data.
roywant 0:ed0152b5c495 106 */
roywant 0:ed0152b5c495 107 uint8_t getAdvFrameLength(uint8_t* rawFrame);
roywant 0:ed0152b5c495 108
roywant 0:ed0152b5c495 109 /**
roywant 0:ed0152b5c495 110 * Get just the EID data from the Eddystone-EID frame.
roywant 0:ed0152b5c495 111 *
roywant 0:ed0152b5c495 112 * @param[in] rawFrame
roywant 0:ed0152b5c495 113 * Pointer to the location where the raw frame will be stored.
roywant 0:ed0152b5c495 114 *
roywant 0:ed0152b5c495 115 * @return A pointer to the bytes of the EID in the Eddystone-EID frame.
roywant 0:ed0152b5c495 116 */
roywant 0:ed0152b5c495 117 uint8_t* getEid(uint8_t* rawFrame);
roywant 0:ed0152b5c495 118
roywant 0:ed0152b5c495 119 /**
roywant 0:ed0152b5c495 120 * Get the length of just the EID data from the Eddystone-EID frame.
roywant 0:ed0152b5c495 121 *
roywant 0:ed0152b5c495 122 * @param[in] rawFrame
roywant 0:ed0152b5c495 123 * Pointer to the location where the raw frame will be stored.
roywant 0:ed0152b5c495 124 *
roywant 0:ed0152b5c495 125 * @return The size in bytes of the EID in the Eddystone-EID frame.
roywant 0:ed0152b5c495 126 */
roywant 0:ed0152b5c495 127 uint8_t getEidLength(uint8_t* rawFrame);
roywant 0:ed0152b5c495 128
roywant 0:ed0152b5c495 129 /**
roywant 0:ed0152b5c495 130 * Set the Adv TX Power in the frame. This is necessary because the adv
roywant 0:ed0152b5c495 131 * Tx Power might be updated independent of the data bytes
roywant 0:ed0152b5c495 132 *
roywant 0:ed0152b5c495 133 * @param[in] rawFrame
roywant 0:ed0152b5c495 134 * Pointer to the location where the raw frame will be stored.
roywant 0:ed0152b5c495 135 * @param[in] advPowerLevel
roywant 0:ed0152b5c495 136 * Power level value included in the raw frame.
roywant 0:ed0152b5c495 137 *
roywant 0:ed0152b5c495 138 */
roywant 0:ed0152b5c495 139 void setAdvTxPower(uint8_t* rawFrame, int8_t advTxPower);
roywant 0:ed0152b5c495 140
roywant 0:ed0152b5c495 141
roywant 0:ed0152b5c495 142 /**
roywant 0:ed0152b5c495 143 * Generate the beacon private and public keys. This should be called on
roywant 0:ed0152b5c495 144 * every restart of the beacon.
roywant 0:ed0152b5c495 145 *
roywant 0:ed0152b5c495 146 * @param[out] beaconPrivateEcdhKey
roywant 0:ed0152b5c495 147 * Pointer to the beacon private key array.
roywant 0:ed0152b5c495 148 * @param[out] beaconPublicEcdhKey
roywant 0:ed0152b5c495 149 * Pointer to the beacon public key array.
roywant 0:ed0152b5c495 150 *
roywant 0:ed0152b5c495 151 */
roywant 0:ed0152b5c495 152 int genBeaconKeys(PrivateEcdhKey_t beaconPrivateEcdhKey, PublicEcdhKey_t beaconPublicEcdhKey);
roywant 0:ed0152b5c495 153
roywant 0:ed0152b5c495 154 /**
roywant 0:ed0152b5c495 155 * Update the EID frame. Tests if its time to rotate the EID payload, and if due, calculates and establishes the new value
roywant 0:ed0152b5c495 156 *
roywant 0:ed0152b5c495 157 * @param[in] *rawFrame
roywant 0:ed0152b5c495 158 * Pointer to the location where the raw frame will be stored.
roywant 0:ed0152b5c495 159 * @param[in] *eidIdentityKey
roywant 0:ed0152b5c495 160 * Eid key used to regenerate the EID id.
roywant 0:ed0152b5c495 161 * @param[in] rotationPeriodExp
roywant 0:ed0152b5c495 162 * EID rotation time as an exponent k : 2^k seconds
roywant 0:ed0152b5c495 163 * @param[in] timeSecs
roywant 0:ed0152b5c495 164 * time in seconds
roywant 0:ed0152b5c495 165 *
roywant 0:ed0152b5c495 166 */
roywant 0:ed0152b5c495 167 void update(uint8_t* rawFrame, uint8_t* eidIdentityKey, uint8_t rotationPeriodExp, uint32_t timeSecs);
roywant 0:ed0152b5c495 168
roywant 0:ed0152b5c495 169 /**
roywant 0:ed0152b5c495 170 * genEcdhSharedKey generates the eik value for inclusion in the EID ADV packet
roywant 0:ed0152b5c495 171 *
roywant 0:ed0152b5c495 172 * @param[in] beaconPrivateEcdhKey
roywant 0:ed0152b5c495 173 * The beacon's private ECDH key, generated by genBeaconKeys()
roywant 0:ed0152b5c495 174 * @param[in] beaconPublicEcdhKey
roywant 0:ed0152b5c495 175 * The beacon's public ECDH key, generated by genBeaconKeys()
roywant 0:ed0152b5c495 176 * @param[in] serverPublicEcdhKey
roywant 0:ed0152b5c495 177 * The server's public ECDH key
roywant 0:ed0152b5c495 178 * @param[out] eidIdentityKey
roywant 0:ed0152b5c495 179 * Identity key for this beacon and server combination
roywant 0:ed0152b5c495 180 */
roywant 0:ed0152b5c495 181 int genEcdhSharedKey(PrivateEcdhKey_t beaconPrivateEcdhKey, PublicEcdhKey_t beaconPublicEcdhKey, PublicEcdhKey_t serverPublicEcdhKey, EidIdentityKey_t eidIdentityKey);
roywant 0:ed0152b5c495 182
roywant 0:ed0152b5c495 183 /**
roywant 0:ed0152b5c495 184 * The byte ID of an Eddystone-EID frame.
roywant 0:ed0152b5c495 185 */
roywant 0:ed0152b5c495 186 static const uint8_t FRAME_TYPE_EID = 0x30;
roywant 0:ed0152b5c495 187
roywant 0:ed0152b5c495 188 private:
roywant 0:ed0152b5c495 189
roywant 0:ed0152b5c495 190 // Declare context for crypto functions
roywant 0:ed0152b5c495 191 mbedtls_entropy_context entropy;
roywant 0:ed0152b5c495 192 mbedtls_ctr_drbg_context ctr_drbg;
roywant 0:ed0152b5c495 193 mbedtls_ecdh_context ecdh_ctx;
roywant 0:ed0152b5c495 194 mbedtls_md_context_t md_ctx;
roywant 0:ed0152b5c495 195
roywant 0:ed0152b5c495 196 /**
roywant 0:ed0152b5c495 197 * The size (in bytes) of an Eddystone-EID frame.
roywant 0:ed0152b5c495 198 * This is the some of the Eddystone UUID(2 bytes), FrameType, AdvTxPower,
roywant 0:ed0152b5c495 199 * EID Value
roywant 0:ed0152b5c495 200 */
roywant 0:ed0152b5c495 201 static const uint8_t EID_FRAME_LEN = 18;
roywant 0:ed0152b5c495 202 static const uint8_t FRAME_LEN_OFFSET = 0;
roywant 0:ed0152b5c495 203 static const uint8_t EDDYSTONE_UUID_LEN = 2;
roywant 0:ed0152b5c495 204 static const uint8_t EID_DATA_OFFSET = 3;
roywant 0:ed0152b5c495 205 static const uint8_t ADV_FRAME_OFFSET = 1;
roywant 0:ed0152b5c495 206 static const uint8_t EID_VALUE_OFFSET = 5;
roywant 0:ed0152b5c495 207 static const uint8_t EID_HEADER_LEN = 4;
roywant 0:ed0152b5c495 208 static const uint8_t EID_TXPOWER_OFFSET = 4;
roywant 0:ed0152b5c495 209
roywant 0:ed0152b5c495 210 /**
roywant 0:ed0152b5c495 211 * AES128 ECB Encrypts a 16-byte input array with a key, to an output array
roywant 0:ed0152b5c495 212 *
roywant 0:ed0152b5c495 213 * @param[in] *key
roywant 0:ed0152b5c495 214 * The encryption key
roywant 0:ed0152b5c495 215 * @param[in] *input
roywant 0:ed0152b5c495 216 * The input array
roywant 0:ed0152b5c495 217 * @param[in] *output
roywant 0:ed0152b5c495 218 * The output array (contains the encrypted data)
roywant 0:ed0152b5c495 219 */
roywant 0:ed0152b5c495 220 void aes128Encrypt(uint8_t *key, uint8_t *input, uint8_t *output);
roywant 0:ed0152b5c495 221
roywant 0:ed0152b5c495 222 };
roywant 0:ed0152b5c495 223
roywant 0:ed0152b5c495 224 #endif /* __EIDFRAME_H__ */