summaryrefslogtreecommitdiff
path: root/digital/beacon/src/Bitcloud_stack/Components/APS/include/apsCryptoKeys.h
blob: 216cc70e5f552ce45c86f267ccd277c29e25b0e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
/**************************************************************************//**
  \file  apsCryptoKeys.h

  \brief Access interface to cryptographic keys.

  \author
    Atmel Corporation: http://www.atmel.com \n
    Support email: avr@atmel.com

  Copyright (c) 2008-2011, Atmel Corporation. All rights reserved.
  Licensed under Atmel's Limited License Agreement (BitCloudTM).

  \internal
   History:
    2010-10-31 Max Gekk - Created.
   Last change:
    $Id: apsCryptoKeys.h 18914 2011-10-18 09:13:36Z mgekk $
 ******************************************************************************/
#if !defined _APS_CRYPTO_KEYS_H
#define _APS_CRYPTO_KEYS_H

/******************************************************************************
                               Includes section
 ******************************************************************************/
#include <nwk.h>

/******************************************************************************
                              Define(s) section
 ******************************************************************************/
/** Macro returns true if crypto key handle is valid. */
#define APS_KEY_HANDLE_IS_VALID(handle) (0 <= (handle))
/** Macro returns true if key-pair handle is successfully found. */
#define APS_KEYS_FOUND(handle) APS_KEY_HANDLE_IS_VALID(handle)
/** Macro returns true if security status is related to any security with
 *  link key.*/
#define APS_SECURED_WITH_ANY_LINK_KEY_STATUS(securityStatus) \
  ((APS_SECURED_LINK_KEY_STATUS == securityStatus) || \
   (APS_SECURED_TRUST_CENTER_LINK_KEY_STATUS == securityStatus) || \
   (APS_SECURED_HASH_OF_TRUST_CENTER_LINK_KEY_STATUS == securityStatus))


/** List of invalid and service key handle values. */
/** Initial and finish value of key-pair iterator. */
#define APS_KEY_PAIR_INITIAL -1
#define APS_KEY_PAIR_FINISH  -2
/** Memory for key-pair descriptor is out. */
#define APS_KEY_PAIR_ALLOC_FAIL -3
/** Key-pair is not found by device address. */
#define APS_KEY_PAIR_NOT_FOUND  -4
/** Parameter is out of range. */
#define APS_KEY_PAIR_INVALID_PARAMETER  -5
/** APS Key-Pair Set is not initialized. */
#define APS_KEY_PAIR_NO_INIT  -6

/** Values of reset flag. These request reset master, link keys or counters.
 * Zero or more flags can be bitwise-or'd in argument of APS_ResetKeys. */
#define APS_RESET_MASTER_KEY 0x01 /*!< Set default master key (zero key). */
#define APS_RESET_LINK_KEY   0x02 /*!< Set default link key (zero key). */
#define APS_RESET_COUNTERS   0x04 /*!< Set 0 to incoming and outgoing counters.*/

/******************************************************************************
                                Types section
 ******************************************************************************/
/* Type of outgoing frame counter. See ZigBee spec r19, Table 4.37. */
typedef uint32_t ApsOutFrameCounter_t;

/* Type of incoming frame counter. See ZigBee spec r19, Table 4.37. */
typedef uint32_t ApsInFrameCounter_t;

/** Type of cryptographic key handle. */
typedef int16_t APS_KeyHandle_t;

/** Bit map of reset flags. */
typedef uint8_t APS_KeyResetFlags_t;

/******************************************************************************
                              Prototypes section
 ******************************************************************************/
/**************************************************************************//**
  \brief Sets a link key for the device with a given extended address

  This function inserts a new entry into the APS key-pair set containing provided
  link key value and extended address.

  The function shall be called to specify the trust center link key before performing 
  network start if high security is used with ::CS_ZDO_SECURITY_STATUS set to 1 or 
  standard security with link keys is used. 
  
  In high security, if the trust center link key is unavailable
  ::CS_ZDO_SECURITY_STATUS can be set to 2 or 3; in this case a master key is used to authenticate
  the joining device to launch link key establishment procedure with the trust center.

  For communication with a node different from the trust center a separate link key is also
  needed (an application link key). If it is known to the application it shall be set with 
  the use of this function. Otherwise, the application shall either apply a master key to 
  launch link key establishment procedure (SKKE) with the partner node or request for a link
  key from the trust center.

  A typical example of the function's usage is given below:
\code
APS_KeyHandle_t apsKeyHandle; //A variable to hold a key handle
//Set a link key variable to a 16-byte value
uint8_t linkKey[SECURITY_KEY_SIZE] = {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa};
//A variable for the trust center address predefined in ::CS_APS_TRUST_CENTER_ADDRESS.
ExtAddr_t trustCenterAddr;

//Read the trust center address
CS_ReadParameter(CS_APS_TRUST_CENTER_ADDRESS_ID, &trustCenterAddr);
//Set the trust center link key
apsKeyHandle = APS_SetLinkKey(&trustCenterAddr, linkKey);

//Check for errors
if (APS_KEY_HANDLE_IS_VALID(apsKeyHandle))
{
  ...
}
\endcode

  \param[in] deviceAddress \ref Endian "[LE]" - pointer to
                            extended (IEEE) device address
  \param[in] linkKey - pointer to a new link key

  \return A valid key handle if operation is successfully completed otherwise
          invalid key handle (Use APS_KEY_HANDLE_IS_VALID to check it out).
 ******************************************************************************/
APS_KeyHandle_t APS_SetLinkKey(const ExtAddr_t *const deviceAddress,
  const uint8_t *const linkKey);

/**************************************************************************//**
  \brief Sets a master key for the device with a given extended address

  This function inserts a new entry into the APS key-pair set containing provided
  master key value and extended address. Thus it specifies a master key used to launch
  link key establishment (SKKE) with the remote device with the corresponding extended address.

  The function is used in high security with ::CS_ZDO_SECURITY_STATUS set to 2 or 3.
  If ::CS_ZDO_SECURITY_STATUS is set to 2, then before joining the network the device
  shall specify a master key value corresponding to the trust center using this function. The
  master key in pair with the joining device's extended address must be set on the trust
  center via this function as well. If ::CS_ZDO_SECURITY_STATUS is set to 3, then the
  master key must be set only on the trust center. In this case the trust center
  trasfers the master key to the device at the beginning of the authentication procedure.

  The function can also be used to specify application master keys corresponding to devices
  different from the trust center. The need for this occurs when a link key for a remote device
  is unknown. The device shall set a master key value for a remote device with which it wishes to
  communicate and initiate the SKKE procedure to establish the link key by calling the
  APS_EstablishKeyReq() function before sending any data requests to the device. 

  See the example of usage below:
\code
APS_KeyHandle_t apsKeyHandle; //A variable to hold a key handle
//Set a master key variable to a 16-byte value
uint8_t masterKey[16] = {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa};
//Assume the remote node extended address is held by APP_EXT_ADDR constant
ExtAddr_t partnerExtAddr = APP_EXT_ADDR;

apsKeyHandle = APS_SetMasterKey(&partnerExtAddr, masterKey); //Set the master key

//Check for errors
if (APS_KEY_HANDLE_IS_VALID(apsKeyHandle))
{
  ...
}
\endcode
Note that the APP_EXT_ADDR constant shall contain a 64-bit value in the little endian
format. For this purpose in the definition of the constant convert a common value
to the little endian format using the CCPU_TO_LE64 format as follows:
\code
#define APP_EXT_ADDR     CCPU_TO_LE64(0xAAAAAAAAAAAAAAAALL)
\endcode

An extended address corresponding to a given short address can be obtained
through Device Discovery, while short addresses of devices supporting certain services can be
discovered using Service Discovery.

  \param[in] deviceAddress \ref Endian "[LE]" - pointer to extended
                                                IEEE device address.
  \param[in] masterKey - pointer to new cryptographic master key.

  \return Valid key handle if operation is successfully completed otherwise
          invalid key handle (Use APS_KEY_HANDLE_IS_VALID to check it out).
 ******************************************************************************/
APS_KeyHandle_t APS_SetMasterKey(const ExtAddr_t *const deviceAddress,
  const uint8_t *const masterKey);

/**************************************************************************//**
  \brief Find the master key or the link key corresponding to a given extended address

  The function is used to check whether the link key or the master key has been set for a given
  device identified by its extended address and to retrieve a handle to it if one exists. To
  check whether the key has been found use the APS_KEYS_FOUND macro. If the handle is
  valid an access to a key value is got via APS_GetMasterKey() or APS_GetLinkKey().

  See the example:
\code
//Assume that the extended address of interest is held by APP_EXT_ADDR constant
ExtAddr_t partnerExtAddr = APP_EXT_ADDR;

if (!APS_KEYS_FOUND(APS_FindKeys(&partnerExtAddr)))
{
  ... //Perform required action, e.g. request for a link key, using APS_RequestKeyReq()
}
\endcode

  \param[in] deviceAddress \ref Endian "[LE]" - pointer to extended IEEE
                                                device address.

  \return Valid key handle if any key is found otherwise
          invalid key handle (Use APS_KEYS_FOUND to check it out).
 ******************************************************************************/
APS_KeyHandle_t APS_FindKeys(const ExtAddr_t *const deviceAddress);

/**************************************************************************//**
  \brief Get a pointer to the master key value by a given key handle

  The function returns a pointer to the section of memory containing the master key value
  for a given key handle. A key handle points to a certain entry in the APS key-pair set
  corresponding to a specific extended address. To obtain a key handle for a given
  extended address use the APS_FindKeys() function.

  Note that the received pointer must be only used to read the value and not to
  modify it.

  Consider the example:
\code
//Search for keys associated with the provided extended address
const APS_KeyHandle_t keyHandle = APS_FindKeys(&extAddr);

uint8_t *masterKey;

if (APS_KEYS_FOUND(keyHandle) && NULL != (masterKey = APS_GetMasterKey(keyHandle)))
{
  ... //A pointer to the master key value has been successfully captured
}
\endcode


  \param[in] handle - valid key handle.

  \return A pointer to the master key or NULL if the key handle is invalid
 ******************************************************************************/
uint8_t* APS_GetMasterKey(const APS_KeyHandle_t handle);

/**************************************************************************//**
  \brief Get a pointer to the link key value by a given key handle

  The function returns a pointer to the section of memory containing the link key value
  for a given key handle. A key handle points to a certain entry in the APS key-pair set
  corresponding to a specific extended address. To obtain a key handle for a given
  extended address use the APS_FindKeys() function.

  Note that the received pointer must be only used to read the value and not to
  modify it.

  Consider the example:
\code
//Search for keys associated with the provided extended address
const APS_KeyHandle_t keyHandle = APS_FindKeys(&extAddr);

uint8_t *linkKey;

if (APS_KEYS_FOUND(keyHandle) && (linkKey = APS_GetLinkKey(keyHandle)))
{
  ... //A pointer to the link key value has been successfully captured
}
\endcode

  \param[in] handle - valid key handle.

  \return A pointer to the link key or NULL if the key handle is invalid
 ******************************************************************************/
uint8_t* APS_GetLinkKey(const APS_KeyHandle_t handle);

/**************************************************************************//**
  \brief Delete key-pair - master and link keys.

  \param[in] deviceAddress \ref Endian "[LE]" - pointer to extended
                                                IEEE device address.
  \param[in] notify - notify to upper layer or not.

  \return 'true' if the key-pair is removed otherwise false.
 ******************************************************************************/
bool APS_DeleteKeyPair(ExtAddr_t *const deviceAddress, const bool notify);

/**************************************************************************//**
  \brief Get next key handle.

  \code Example:
    APS_KeyHandle_t handle = APS_KEY_PAIR_INITIAL;

    while (APS_KEYS_FOUND(handle = APS_NextKeys(handle)))
    {
      linkKey = APS_GetLinkKey(handle);
      if (NULL != linkKey)
        ...
      ...
    }
  \endcode

  \param[in] handle - handle of previous key-pair or APS_KEY_PAIR_INITIAL
                      if it's initial call.

  \return if next key-pair is found then return valid key handle
          otherwise return APS_KEY_PAIR_FINISH.
 ******************************************************************************/
APS_KeyHandle_t APS_NextKeys(const APS_KeyHandle_t handle);

/**************************************************************************//**
  \brief (Un)authorize cryptographic key-pair of given device.

  \param[in] deviceAddress \ref Endian "[LE]" - pointer to extended IEEE
                                                device address.
  \param[in] status - 'true' for authorized keys otherwise 'false'.

  \return None.
 ******************************************************************************/
void APS_SetAuthorizedStatus(const ExtAddr_t *const deviceAddress,
  const bool status);

/**************************************************************************//**
  \brief Check authorization of crypthographic key-pair.

  \param[in] deviceAddress \ref Endian "[LE]" - pointer to extended
                                                IEEE device address.

  \return 'true' if key-pair is authorized otherwise 'false'.
 ******************************************************************************/
bool APS_AreKeysAuthorized(const ExtAddr_t *const deviceAddress);

/**************************************************************************//**
  \brief Reset device's keys and counters to default values.

  \param[in] deviceAddress \ref Endian "[LE]" - pointer to extended IEEE
                                                device address.
  \param[in] flags - bit map of APS Key-Pair reset flags. Current implementation
                     supported only APS_RESET_LINK_KEY and APS_RESET_COUNTERS.

  \return APS Key Handle of reseting key-pair or invalid key handle if
          key-pair is not found.
 ******************************************************************************/
APS_KeyHandle_t APS_ResetKeys(const ExtAddr_t *const deviceAddress,
  const APS_KeyResetFlags_t flags);

/**************************************************************************//**
  \brief Init APS key-pair set.

  \param[in] powerFailureControl - stack restoring after power failure control bitfield;
                                  affects on initialization procedure.

  \return None.
 ******************************************************************************/
void APS_InitKeyPairSet(const NWK_PowerFailureControl_t powerFailureControl);

/**************************************************************************//**
  \brief Get extended device address of key-pair.

  \param[in] handle - valid key handle.

  \return Pointer to device address or NULL if key-pair is not found..
 ******************************************************************************/
ExtAddr_t* APS_GetKeyPairDeviceAddress(const APS_KeyHandle_t handle);

/**************************************************************************//**
  \brief Find key-pair with old address and set new address.

  \param[in] oldAddress \ref Endian "[LE]" - extended IEEE device
                                             address of key-pair.
  \param[in] newAddress \ref Endian "[LE]" - new device address of key-pair.
  \return None.
 ******************************************************************************/
void APS_ChangeKeyPairDeviceAddress(const ExtAddr_t oldAddress,
  const ExtAddr_t newAddress);

#ifdef _TC_PROMISCUOUS_MODE_
/**************************************************************************//**
  \brief Get preinstalled link key.

  \param[in] handle - valid key handle.

  \return Pointer to preinstalled link key or NULL if handle is invalid.
 ******************************************************************************/
uint8_t* APS_GetPreinstalledLinkKey(const APS_KeyHandle_t handle);

/**************************************************************************//**
  \brief Set new preinstalled link key for given device.

   This function copies value of preinstalled link key to APS Key-Pair Set.

  \param[in] deviceAddress - pointer to extended IEEE device address.
  \param[in] preinstalledLinkKey - pointer to new cryptographic preinstalled
                                   link key.

  \return Valid key handle if operation is successfully completed otherwise
          invalid key handle (Use APS_KEY_HANDLE_IS_VALID to check it out).
 ******************************************************************************/
APS_KeyHandle_t APS_SetPreinstalledLinkKey(const ExtAddr_t *const deviceAddress,
  const uint8_t *const preinstalledLinkKey);

/**************************************************************************//**
  \brief Restores link key from preinstalled one.
         Uses to accept TC reestablishing keys with previously joined device.

  \param[in] deviceAddress - pointer to extended IEEE device address.

  \return None.
 ******************************************************************************/
void APS_RestorePreinstalledLinkKey(const ExtAddr_t *const deviceAddress);

#endif /* _TC_PROMISCUOUS_MODE_ */

#ifdef _LINK_SECURITY_ 
/**************************************************************************//**
  \brief Get current value of outgoing security frames counter.

  \param[in] keyHandle - valid key handle.

  \return Current value of outgoing frame counter.
 ******************************************************************************/
ApsOutFrameCounter_t APS_GetOutSecFrameCounter(const APS_KeyHandle_t keyHandle);
#endif /* _LINK_SECURITY_ */


#endif /* _APS_CRYPTO_KEYS_H */
/** eof apsCryptoKeys.h */