- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/ip/umac/src/me/me_mic.c

Go to the documentation of this file.

    00001
    00017 /*
    00018  * INCLUDE FILES
    00019  ****************************************************************************************
    00020  */
    00021
    00022 #include "me_mic.h"
    00023 #include "co_utils.h"
    00024 #include "dbg_assert.h"
    00025 #if NX_HSU
    00026 #include "hsu.h"
    00027 #endif
    00028
    00029 /*
    00030  * DEFINES
    00031  ****************************************************************************************
    00032  */
    00033
    00039 #define MIC_END_SIGNATURE   (0x0000005A)
    00040
    00044 #define MIC_TID_MASK        (0x00000007)
    00045
    00046 // If NX_HSU == 2, don't include software implementation
    00047 #if NX_HSU < 2
    00048
    00049 /*
    00050  * MACROS
    00051  ****************************************************************************************
    00052  */
    00053
    00065 #define ROR32(L,Q)  ( ( (uint32_t)(L) >> (Q) ) | ( (uint32_t)(L) << (32-(Q)) ) )
    00066
    00078 #define ROL32(L,Q)  ( ( (uint32_t)(L) << (Q) ) | ( (uint32_t)(L) >> (32-(Q)) ) )
    00079
    00090 #define XSWAP32(L)    ( ( ( L & 0xFF00FF00 ) >> 8 ) | \
    00091                         ( ( L & 0x00FF00FF ) << 8 ) )
    00092
    00111 #define LEN_IN_BITS(X) ( (X) << 3 )
    00112
    00123 #define SHIFTR(X, S) (((S) == 32)? 0 : ((X) >> (S)) )
    00124
    00125 /*
    00126  * PRIVATE FUNCTION IMPLEMENTATIONS
    00127  ****************************************************************************************
    00128  */
    00129
    00159 static void michael_block(struct mic_calc *mic_calc_ptr, uint32_t block)
    00160 {
    00161     uint32_t l = mic_calc_ptr->mic_key_least;
    00162     uint32_t r = mic_calc_ptr->mic_key_most;
    00163
    00164     l   ^= block;
    00165     r   ^=  ROL32(l, 17);
    00166     l   +=  r;
    00167     r   ^=  XSWAP32(l);
    00168     l   +=  r;
    00169     r   ^=  ROL32(l, 3);
    00170     l   +=  r;
    00171     r   ^=  ROR32(l, 2);
    00172     l   +=  r;
    00173
    00174     mic_calc_ptr->mic_key_most  = r;
    00175     mic_calc_ptr->mic_key_least = l;
    00176 }
    00177
    00188 static void michael_init(struct mic_calc *mic_calc_ptr, uint32_t *mic_key_ptr,
    00189                          uint32_t *aad)
    00190 {
    00191     // Initialize MIC value
    00192     mic_calc_ptr->mic_key_least = mic_key_ptr[0];
    00193     mic_calc_ptr->mic_key_most  = mic_key_ptr[1];
    00194     mic_calc_ptr->last_m_i      = 0;
    00195     mic_calc_ptr->last_m_i_len  = 0;
    00196
    00197     // Apply Michael on AAD
    00198     michael_block(mic_calc_ptr, aad[0]);
    00199     michael_block(mic_calc_ptr, aad[1]);
    00200     michael_block(mic_calc_ptr, aad[2]);
    00201     michael_block(mic_calc_ptr, aad[3]);
    00202 }
    00203
    00215 static void michael_calc(struct mic_calc *mic_calc_ptr, uint32_t start_ptr,
    00216                          uint32_t data_len)
    00217 {
    00218     // M(i) block
    00219     uint32_t m_i;
    00220     // Remaining length to proceed
    00221     uint32_t rem_len = data_len;
    00222     // Number of 32-bit blocks
    00223     uint32_t nb_blocks;
    00224     // Pointer to the payload
    00225     uint32_t *u32_ptr = HW2CPU(start_ptr & ~0x03);
    00226     uint32_t val = *u32_ptr++;
    00227     uint8_t cut = start_ptr & 0x03;
    00228     uint8_t valid = 4 - cut;
    00229     uint32_t last_m_i_len = mic_calc_ptr->last_m_i_len;
    00230     uint32_t last_m_i = mic_calc_ptr->last_m_i;
    00231
    00232     val >>= LEN_IN_BITS(cut);
    00233     if (data_len < valid)
    00234     {
    00235         val &= 0xFFFFFFFF >> LEN_IN_BITS(4 - data_len);
    00236         valid = data_len;
    00237         rem_len = 0;
    00238     }
    00239     else
    00240     {
    00241         rem_len -= valid;
    00242     }
    00243
    00244     if ((last_m_i_len + valid) < 4)
    00245     {
    00246         last_m_i |= val << LEN_IN_BITS(last_m_i_len);
    00247         last_m_i_len += valid;
    00248     }
    00249     else
    00250     {
    00251         m_i = last_m_i | (val << LEN_IN_BITS(last_m_i_len));
    00252
    00253         last_m_i = SHIFTR(val, LEN_IN_BITS(4 - last_m_i_len));
    00254         last_m_i_len += valid - 4;
    00255
    00256         // Apply Michael block function
    00257         michael_block(mic_calc_ptr, m_i);
    00258     }
    00259
    00260     // Compute the number of remaining blocks
    00261     nb_blocks = (rem_len >> 2);
    00262
    00263     for (uint32_t block_cnt = 0; block_cnt < nb_blocks; block_cnt++)
    00264     {
    00265         // Read memory
    00266         val = *u32_ptr++;
    00267
    00268         // Extract the block value
    00269         m_i = last_m_i | (val << LEN_IN_BITS(last_m_i_len));
    00270
    00271         // Save last MI
    00272         last_m_i = SHIFTR(val, LEN_IN_BITS(4 - last_m_i_len));
    00273
    00274         // Apply Michael block function
    00275         michael_block(mic_calc_ptr, m_i);
    00276     }
    00277
    00278     // If pending bytes store them inside the mic_calc structure
    00279     if (rem_len > (nb_blocks << 2))
    00280     {
    00281         uint32_t add_bytes = rem_len - (nb_blocks << 2);
    00282
    00283         val = (*u32_ptr) & (SHIFTR(0xFFFFFFFF, LEN_IN_BITS(4 - add_bytes)));
    00284         if ((last_m_i_len + add_bytes) > 3)
    00285         {
    00286             // Extract the block value
    00287             m_i = last_m_i | (val << LEN_IN_BITS(last_m_i_len));
    00288
    00289             // Save last MI
    00290             last_m_i = SHIFTR(val, LEN_IN_BITS(4 - last_m_i_len));
    00291             last_m_i_len += add_bytes - 4;
    00292
    00293             // Apply Michael block function
    00294             michael_block(mic_calc_ptr, m_i);
    00295         }
    00296         else
    00297         {
    00298             last_m_i |= val << LEN_IN_BITS(last_m_i_len);
    00299             last_m_i_len += add_bytes;
    00300         }
    00301     }
    00302
    00303     mic_calc_ptr->last_m_i     = last_m_i;
    00304     mic_calc_ptr->last_m_i_len = last_m_i_len;
    00305 }
    00306
    00316 static void michael_end(struct mic_calc *mic_calc_ptr)
    00317 {
    00318     // M(n-2) block
    00319     uint32_t m_n_2 = mic_calc_ptr->last_m_i;
    00320
    00321     ASSERT_ERR(mic_calc_ptr->last_m_i_len < 4);
    00322
    00323     m_n_2 |= (MIC_END_SIGNATURE << LEN_IN_BITS(mic_calc_ptr->last_m_i_len));
    00324
    00325     // Apply Michael block function to the last 2 blocks
    00326     michael_block(mic_calc_ptr, m_n_2);
    00327     // M(n-1) = 0 by construction
    00328     michael_block(mic_calc_ptr, 0);
    00329 }
    00330 #endif /* NX_HSU < 2 */
    00331
    00332 /*
    00333  * PUBLIC FUNCTION IMPLEMENTATIONS
    00334  ******************************************************************************
    00335  */
    00336
    00337 #if NX_HSU
    00340 uint32_t mic_aad[4] __SHAREDRAM;
    00341 #endif
    00342
    00343 void me_mic_init(struct mic_calc *mic_calc_ptr, uint32_t *mic_key_ptr,
    00344                  struct mac_addr *da, struct mac_addr *sa, uint8_t tid)
    00345 {
    00346     #if !NX_HSU
    00347     uint32_t mic_aad[4];
    00348     #endif
    00349
    00350     /* prepare AAD vector = DA SA Prio Padding */
    00351     mic_aad[0] = (uint32_t)da->array[0] | (((uint32_t)da->array[1]) << 16);
    00352     mic_aad[1] = (uint32_t)da->array[2] | (((uint32_t)sa->array[0]) << 16);
    00353     mic_aad[2] = (uint32_t)sa->array[1] | (((uint32_t)sa->array[2]) << 16);
    00354     if (tid == 0xFF)
    00355         mic_aad[3] = 0;
    00356     else
    00357         mic_aad[3] = (uint32_t)tid & MIC_TID_MASK;
    00358
    00359     #if NX_HSU
    00360     if (hsu_michael_init(mic_calc_ptr, mic_key_ptr, mic_aad))
    00361         return;
    00362     #endif
    00363
    00364     #if NX_HSU < 2
    00365     michael_init(mic_calc_ptr, mic_key_ptr, mic_aad);
    00366     #endif
    00367 }
    00368
    00369 void me_mic_calc(struct mic_calc *mic_calc_ptr, uint32_t start_ptr,
    00370                  uint32_t data_len)
    00371 {
    00372     #if NX_HSU
    00373     if (hsu_michael_calc(mic_calc_ptr, start_ptr, data_len))
    00374         return;
    00375     #endif
    00376
    00377     #if NX_HSU < 2
    00378     michael_calc(mic_calc_ptr, start_ptr, data_len);
    00379     #endif
    00380 }
    00381
    00382 void me_mic_end(struct mic_calc *mic_calc_ptr)
    00383 {
    00384     #if NX_HSU
    00385     if (hsu_michael_end(mic_calc_ptr))
    00386         return;
    00387     #endif
    00388
    00389     #if NX_HSU < 2
    00390     michael_end(mic_calc_ptr);
    00391     #endif
    00392 }
    00393