Sarah Marsh / Mbed OS EddystoneBeacon
Committer:
sarahmarshy
Date:
Tue Nov 29 06:29:10 2016 +0000
Revision:
0:1c7da5f83647
Initial commit

Who changed what in which revision?

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