• Main Page
  • Modules
  • Index
  • File List
  • Globals

gazell/common/gzp.c

Go to the documentation of this file.
00001 /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is confidential property of Nordic 
00004  * Semiconductor ASA.Terms and conditions of usage are described in detail 
00005  * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRENTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *              
00011  * $LastChangedRevision: 2471 $
00012  */
00013 
00019 #include "gzp.h"
00020 #include "gzll.h"
00021 #include "hal_aes.h"
00022 #include <string.h>
00023 #include <stdint.h>
00024 #include "memdefs.h"
00025 
00026 //-----------------------------------------------------------------------------
00027 // Global variables
00028 //-----------------------------------------------------------------------------
00032 static code const uint8_t pairing_address[] = {0, GZP_ADDRESS};
00033 
00037 static code const uint8_t gzp_validation_id[GZP_VALIDATION_ID_LENGTH] = GZP_VALIDATION_ID;
00038 
00042 static code const uint8_t gzp_secret_key[16] = GZP_SECRET_KEY;
00043 
00047 static xdata gzp_key_select_t gzp_key_select;
00048 
00049 //-----------------------------------------------------------------------------
00050 // Misc. external variables. 
00051 //-----------------------------------------------------------------------------
00052 
00053 static xdata uint8_t gzp_session_token[GZP_SESSION_TOKEN_LENGTH];
00054 static xdata uint8_t gzp_dyn_key[GZP_DYN_KEY_LENGTH];
00055 
00056 //-----------------------------------------------------------------------------
00057 // Implementation common internal function
00058 //-----------------------------------------------------------------------------
00059 void gzp_update_radio_params(const uint8_t* system_address)
00060 {
00061   uint8_t i;
00062   uint8_t channels[GZLL_MAX_CHANNEL_TAB_SIZE];
00063   uint8_t temp_address[GZLL_ADDRESS_WIDTH];
00064 
00065   // Configure "global" pairing address
00066   gzll_set_address(HAL_NRF_PIPE0, (uint8_t const*)pairing_address);
00067 
00068   if(system_address != NULL)
00069   {
00070     for(i = 0; i < GZP_SYSTEM_ADDRESS_WIDTH; i++)
00071     {
00072       temp_address[i + 1] = *(system_address + i);  
00073     }
00074 
00075     // Configure address for pipe 1 - 5. Address byte set to equal pipe number.
00076     for(i = 1; i < 6; i++)
00077     {
00078       temp_address[0] = i; 
00079       gzll_set_address((hal_nrf_address_t)i, temp_address);     
00080     }
00081   }
00082 
00083   gzp_generate_channels(&channels[0], &temp_address[1], gzll_get_channel_tab_size());                       
00084   
00085   // Write generated channel subset to Gazell Link Layer   
00086   gzll_set_channels(&channels[0], gzll_get_channel_tab_size());
00087 }
00088 
00089 void gzp_generate_channels(uint8_t* ch_dst, const uint8_t* system_address, uint8_t channel_tab_size)
00090 {
00091   uint8_t binsize, spacing, i;
00092 
00093   binsize = (GZP_CHANNEL_MAX - GZP_CHANNEL_MIN) / channel_tab_size;
00094 
00095   ch_dst[0] = GZP_CHANNEL_LOW;
00096   ch_dst[channel_tab_size - 1] = GZP_CHANNEL_HIGH;
00097 
00098   for(i = 1; i < (channel_tab_size - 1); i++)
00099   {
00100     ch_dst[i] = (binsize * i) + (system_address[i % 4] % binsize);  
00101   }
00102 
00103   for(i = 1; i < channel_tab_size; i++)
00104   {
00105     spacing = (ch_dst[i] - ch_dst[i - 1]); 
00106     if(spacing < GZP_CHANNEL_SPACING_MIN)
00107     {
00108       ch_dst[i] += (GZP_CHANNEL_SPACING_MIN - spacing); 
00109     }
00110   } 
00111 }
00112 
00113 #ifndef GZP_CRYPT_DISABLE
00114 
00115 void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_t length)
00116 {
00117   uint8_t i;
00118 
00119   for(i = 0; i < length; i++)
00120   {
00121     *dst = *src ^ *pad;
00122     dst++;
00123     src++;
00124     pad++;   
00125   }
00126 }
00127 
00128 bool gzp_validate_id(const uint8_t* id)
00129 {
00130   return (memcmp(id, (void*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH) == 0);
00131 }
00132 
00133 void gzp_add_validation_id(uint8_t* dst)
00134 {
00135   memcpy(dst, (void const*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH); 
00136 }
00137 
00138 void gzp_crypt_set_session_token(const uint8_t * token)
00139 {
00140   memcpy(gzp_session_token, (void const*)token, GZP_SESSION_TOKEN_LENGTH);
00141 }
00142 
00143 void gzp_crypt_set_dyn_key(const uint8_t* key)
00144 {
00145   memcpy(gzp_dyn_key, (void const*)key, GZP_DYN_KEY_LENGTH); 
00146 }
00147 
00148 void gzp_crypt_get_session_token(uint8_t * dst_token)
00149 {
00150   memcpy(dst_token, (void const*)gzp_session_token, GZP_SESSION_TOKEN_LENGTH);
00151 }
00152 
00153 void gzp_crypt_get_dyn_key(uint8_t* dst_key)
00154 {
00155   memcpy(dst_key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH); 
00156 }
00157 
00158 void gzp_crypt_select_key(gzp_key_select_t key_select)
00159 {
00160   gzp_key_select = key_select;
00161 }
00162 
00163 void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length)
00164 {
00165   uint8_t i;
00166   uint8_t key[16];
00167   uint8_t iv[16];
00168 
00169   // Build AES key based on "gzp_key_select"
00170   switch(gzp_key_select)
00171   {
00172     case GZP_ID_EXCHANGE:
00173       memcpy(key, (void const*)gzp_secret_key, 16);
00174       break;
00175     case GZP_KEY_EXCHANGE:
00176       memcpy(key, (void const*)gzp_secret_key, 16);
00177       gzp_get_host_id(key);
00178       break;
00179     case GZP_DATA_EXCHANGE:
00180       memcpy(key, (void const*)gzp_secret_key, 16);
00181       memcpy(key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH);
00182       break;
00183     default: 
00184       break;
00185   }  
00186   
00187   // Build init vector from "gzp_session_token"
00188   for(i = 0; i < 16; i++)
00189   {
00190     if(i < GZP_SESSION_TOKEN_LENGTH)
00191     {
00192       iv[i] = gzp_session_token[i];
00193     }
00194     else
00195     {
00196       iv[i] = 0;
00197     }
00198   }
00199 
00200   // Set up hal_aes using new key and init vector
00201   hal_aes_setup(false, ECB, key, NULL); // Note, here we skip the IV as we use ECB mode
00202 
00203   // Encrypt IV using ECB mode
00204   hal_aes_crypt(iv, iv);
00205 
00206   // Encrypt data by XOR'ing with AES output
00207   gzp_xor_cipher(dst, src, iv, length);
00208 }
00209 
00210 #endif                       

Generated on Fri Apr 20 2012 14:11:44 for nRFGo SDK by  doxygen 1.7.2