Roy Want / Mbed OS beaconCompileReadyFork
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EIDFrame.h Source File

EIDFrame.h

00001 /*
00002  * Copyright (c) 2016, Google Inc, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #ifndef __EIDFRAME_H__
00019 #define __EIDFRAME_H__
00020 
00021 #include <string.h>
00022 #include "EddystoneTypes.h"
00023 #include "mbedtls/aes.h"
00024 #include "mbedtls/ecdh.h"
00025 #include "mbedtls/md.h"
00026 #include "mbedtls/entropy.h"
00027 #include "mbedtls/ctr_drbg.h"
00028 #include "aes_eax.h"
00029 
00030 /**
00031  * Class that encapsulates data that belongs to the Eddystone-EID frame. For
00032  * more information refer to https://github.com/google/eddystone/tree/master/eddystone-EID.
00033  */
00034 class EIDFrame
00035 {
00036 public:
00037     static const uint8_t SALT = 0xff;
00038     static const uint8_t EID_LENGTH = 8;
00039     static const int EID_SUCCESS = 0;
00040     static const int EID_RC_SS_IS_ZERO = -1;
00041     static const int EID_RND_FAIL = -2;
00042     static const int EID_GRP_FAIL = -3;
00043     static const int EID_GENKEY_FAIL = -4;
00044 
00045     /**
00046      * Construct a new instance of this class.
00047      */
00048     EIDFrame();
00049     
00050     /**
00051      * Clear frame (intervally indicated by length = 0 )
00052      */
00053     void clearFrame(uint8_t* frame);
00054     
00055     /**
00056      * Construct the raw bytes of the Eddystone-EID frame that will be directly
00057      * used in the advertising packets.
00058      *
00059      * @param[in] rawFrame
00060      *              Pointer to the location where the raw frame will be stored.
00061      * @param[in] advPowerLevel
00062      *              Power level value included in the raw frame.
00063      * @param[in] eidData
00064      *              The actual 16-byte EID data in the raw frame.
00065      */
00066     void setData(uint8_t* rawFrame, int8_t advTxPower, const uint8_t* eidData);
00067     
00068     /**
00069      * Get the EID frame data from the Eddystone-EID frame.
00070      * 
00071      * @param[in] rawFrame
00072      *              Pointer to the location where the raw frame will be stored.
00073      *
00074      * @return A pointer to the bytes of the Eddystone-EID frame data.
00075      */
00076     uint8_t* getData(uint8_t* rawFrame);
00077     
00078     /**
00079      * Get the length of the EID frame data from the Eddystone-EID frame.
00080      * 
00081      * @param[in] rawFrame
00082      *              Pointer to the location where the raw frame will be stored.
00083      *
00084      * @return The size in bytes of the Eddystone-EID frame.
00085      */
00086     uint8_t  getDataLength(uint8_t* rawFrame);
00087     
00088     /**
00089      * Get the EID Adv data from the Eddystone-EID frame.
00090      * This is the full service data included in the BLE service data params
00091      * 
00092      * @param[in] rawFrame
00093      *              Pointer to the location where the raw frame will be stored.
00094      *
00095      * @return A pointer to the bytes of the Eddystone-EID Adv frame data.
00096      */
00097     uint8_t* getAdvFrame(uint8_t* rawFrame);
00098     
00099     /**
00100      * Get the length of the EID Adv data from the Eddystone-EID frame.
00101      * 
00102      * @param[in] rawFrame
00103      *              Pointer to the location where the raw frame will be stored.
00104      *
00105      * @return The size in bytes of the Eddystone-EID Adv frame data.
00106      */
00107     uint8_t getAdvFrameLength(uint8_t* rawFrame);
00108 
00109     /**
00110      * Get just the EID data from the Eddystone-EID frame.
00111      * 
00112      * @param[in] rawFrame
00113      *              Pointer to the location where the raw frame will be stored.
00114      *
00115      * @return A pointer to the bytes of the EID in the Eddystone-EID frame.
00116      */
00117     uint8_t* getEid(uint8_t* rawFrame);
00118     
00119     /**
00120      * Get the length of just the EID data from the Eddystone-EID frame.
00121      * 
00122      * @param[in] rawFrame
00123      *              Pointer to the location where the raw frame will be stored.
00124      *
00125      * @return The size in bytes of the EID in the Eddystone-EID frame.
00126      */
00127     uint8_t getEidLength(uint8_t* rawFrame);
00128     
00129     /**
00130      * Set the Adv TX Power in the frame. This is necessary because the adv
00131      * Tx Power might be updated independent of the data bytes
00132      * 
00133      * @param[in] rawFrame
00134      *              Pointer to the location where the raw frame will be stored.
00135      * @param[in] advPowerLevel
00136      *              Power level value included in the raw frame.
00137      *
00138      */
00139     void setAdvTxPower(uint8_t* rawFrame, int8_t advTxPower);
00140     
00141 
00142     /**
00143      * Generate the beacon private and public keys. This should be called on
00144      * every restart of the beacon.
00145      * 
00146      * @param[out] beaconPrivateEcdhKey
00147      *              Pointer to the beacon private key array.
00148      * @param[out] beaconPublicEcdhKey
00149      *              Pointer to the beacon public key array.
00150      *
00151      */
00152     int genBeaconKeys(PrivateEcdhKey_t beaconPrivateEcdhKey, PublicEcdhKey_t beaconPublicEcdhKey);
00153 
00154     /**
00155      * Update the EID frame. Tests if its time to rotate the EID payload, and if due, calculates and establishes the new value
00156      * 
00157      * @param[in] *rawFrame
00158      *              Pointer to the location where the raw frame will be stored.
00159      * @param[in] *eidIdentityKey
00160      *              Eid key used to regenerate the EID id.
00161      * @param[in] rotationPeriodExp
00162      *              EID rotation time as an exponent k : 2^k seconds
00163      * @param[in] timeSecs
00164      *              time in seconds
00165      *
00166      */
00167     void update(uint8_t* rawFrame, uint8_t* eidIdentityKey, uint8_t rotationPeriodExp,  uint32_t timeSecs);
00168     
00169     /**
00170      * genEcdhSharedKey generates the eik value for inclusion in the EID ADV packet
00171      *
00172      * @param[in] beaconPrivateEcdhKey
00173      *              The beacon's private ECDH key, generated by genBeaconKeys()
00174      * @param[in] beaconPublicEcdhKey
00175      *              The beacon's public ECDH key, generated by genBeaconKeys()
00176      * @param[in] serverPublicEcdhKey
00177      *              The server's public ECDH key
00178      * @param[out] eidIdentityKey
00179      *              Identity key for this beacon and server combination
00180      */
00181     int genEcdhSharedKey(PrivateEcdhKey_t beaconPrivateEcdhKey, PublicEcdhKey_t beaconPublicEcdhKey, PublicEcdhKey_t serverPublicEcdhKey, EidIdentityKey_t eidIdentityKey);
00182     
00183     /**
00184      *  The byte ID of an Eddystone-EID frame.
00185      */
00186     static const uint8_t FRAME_TYPE_EID = 0x30;
00187 
00188 private:
00189     
00190     // Declare context for crypto functions
00191     mbedtls_entropy_context entropy;
00192     mbedtls_ctr_drbg_context ctr_drbg;
00193     mbedtls_ecdh_context ecdh_ctx;
00194     mbedtls_md_context_t md_ctx;
00195 
00196     /**
00197      * The size (in bytes) of an Eddystone-EID frame.
00198      * This is the some of the Eddystone UUID(2 bytes), FrameType, AdvTxPower,
00199      * EID Value
00200      */
00201     static const uint8_t EID_FRAME_LEN = 18;
00202     static const uint8_t FRAME_LEN_OFFSET = 0;
00203     static const uint8_t EDDYSTONE_UUID_LEN = 2;
00204     static const uint8_t EID_DATA_OFFSET = 3;
00205     static const uint8_t ADV_FRAME_OFFSET = 1;
00206     static const uint8_t EID_VALUE_OFFSET = 5;
00207     static const uint8_t EID_HEADER_LEN = 4;
00208     static const uint8_t EID_TXPOWER_OFFSET = 4;
00209     
00210     /**
00211      * AES128 ECB Encrypts a 16-byte input array with a key, to an output array
00212      *
00213      * @param[in] *key
00214      *              The encryption key
00215      * @param[in] *input
00216      *              The input array
00217      * @param[in] *output
00218      *              The output array (contains the encrypted data)
00219      */
00220     void aes128Encrypt(uint8_t *key, uint8_t *input, uint8_t *output);
00221  
00222 };
00223 
00224 #endif  /* __EIDFRAME_H__ */