15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2008-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  This file contains the implementation of the AES128 CMAC algorithm.
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if SMP_INCLUDED == TRUE
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    #include <stdio.h>
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    #include <string.h>
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    #include "btm_ble_api.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    #include "smp_int.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    #include "hcimsgs.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8               *text;
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16              len;
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16              round;
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}tCMAC_CB;
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttCMAC_CB    cmac_cb;
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Rb for AES-128 as block cipher, LSB as [0] */
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBT_OCTET16 const_Rb = {
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project};
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid print128(BT_OCTET16 x, const UINT8 *key_name)
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if SMP_DEBUG == TRUE
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8  *p = (UINT8 *)x;
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8  i;
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
56b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_WARNING("%s(MSB ~ LSB) = ", key_name);
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < 4; i ++)
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
60b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        SMP_TRACE_WARNING("%02x %02x %02x %02x",
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                           p[BT_OCTET16_LEN - i*4 -1], p[BT_OCTET16_LEN - i*4 -2],
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                           p[BT_OCTET16_LEN - i*4 -3], p[BT_OCTET16_LEN - i*4 -4]);
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         padding
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      utility function to padding the given text to be a 128 bits
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  data. The parameter dest is input and output parameter, it
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  must point to a BT_OCTET16_LEN memory space; where include
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  length bytes valid data.
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void padding ( BT_OCTET16 dest, UINT8 length )
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   i, *p = dest;
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* original last block */
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for ( i = length ; i < BT_OCTET16_LEN; i++ )
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p[BT_OCTET16_LEN - i - 1] = ( i == length ) ? 0x80 : 0;
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         leftshift_onebit
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      utility function to left shift one bit for a 128 bits value.
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void leftshift_onebit(UINT8 *input, UINT8 *output)
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   i, overflow = 0 , next_overflow = 0;
98b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_EVENT ("leftshift_onebit ");
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* input[0] is LSB */
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for ( i = 0; i < BT_OCTET16_LEN ; i ++ )
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        next_overflow = (input[i] & 0x80) ? 1:0;
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        output[i] = (input[i] << 1) | overflow;
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        overflow = next_overflow;
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return;
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         cmac_aes_cleanup
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      clean up function for AES_CMAC algorithm.
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cmac_aes_cleanup(void)
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cmac_cb.text != NULL)
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf(cmac_cb.text);
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(&cmac_cb, 0, sizeof(tCMAC_CB));
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         cmac_aes_k_calculate
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is the calculation of block cipher using AES-128.
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN cmac_aes_k_calculate(BT_OCTET16 key, UINT8 *p_signature, UINT16 tlen)
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tSMP_ENC output;
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    i = 1, err = 0;
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    x[16] = {0};
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_mac;
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
142b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_EVENT ("cmac_aes_k_calculate ");
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (i <= cmac_cb.round)
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        smp_xor_128(&cmac_cb.text[(cmac_cb.round - i)*BT_OCTET16_LEN], x); /* Mi' := Mi (+) X  */
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!SMP_Encrypt(key, BT_OCTET16_LEN, &cmac_cb.text[(cmac_cb.round - i)*BT_OCTET16_LEN], BT_OCTET16_LEN, &output))
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            err = 1;
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memcpy(x, output.param_buf, BT_OCTET16_LEN);
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        i ++;
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!err)
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_mac = output.param_buf + (BT_OCTET16_LEN - tlen);
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memcpy(p_signature, p_mac, tlen);
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
163b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        SMP_TRACE_DEBUG("tlen = %d p_mac = %d", tlen, p_mac);
164b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        SMP_TRACE_DEBUG("p_mac[0] = 0x%02x p_mac[1] = 0x%02x p_mac[2] = 0x%02x p_mac[3] = 0x%02x",
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                         *p_mac, *(p_mac + 1), *(p_mac + 2), *(p_mac + 3));
166b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        SMP_TRACE_DEBUG("p_mac[4] = 0x%02x p_mac[5] = 0x%02x p_mac[6] = 0x%02x p_mac[7] = 0x%02x",
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                         *(p_mac + 4), *(p_mac + 5), *(p_mac + 6), *(p_mac + 7));
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return TRUE;
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return FALSE;
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         cmac_prepare_last_block
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function proceeed to prepare the last block of message
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Mn depending on the size of the message.
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cmac_prepare_last_block (BT_OCTET16 k1, BT_OCTET16 k2)
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//    UINT8       x[16] = {0};
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN      flag;
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
190b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_EVENT ("cmac_prepare_last_block ");
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* last block is a complete block set flag to 1 */
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    flag = ((cmac_cb.len % BT_OCTET16_LEN) == 0 && cmac_cb.len != 0)  ? TRUE : FALSE;
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
194b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_WARNING("flag = %d round = %d", flag, cmac_cb.round);
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( flag )
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    { /* last block is complete block */
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        smp_xor_128(&cmac_cb.text[0], k1);
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else /* padding then xor with k2 */
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        padding(&cmac_cb.text[0], (UINT8)(cmac_cb.len % 16));
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        smp_xor_128(&cmac_cb.text[0], k2);
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         cmac_subkey_cont
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This is the callback function when CIPHk(0[128]) is completed.
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cmac_subkey_cont(tSMP_ENC *p)
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 k1[BT_OCTET16_LEN], k2[BT_OCTET16_LEN];
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 *pp = p->param_buf;
220b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_EVENT ("cmac_subkey_cont ");
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    print128(pp, (const UINT8 *)"K1 before shift");
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If MSB(L) = 0, then K1 = L << 1 */
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (pp[BT_OCTET16_LEN - 1] & 0x80) != 0 )
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Else K1 = ( L << 1 ) (+) Rb */
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        leftshift_onebit(pp, k1);
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        smp_xor_128(k1, const_Rb);
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        leftshift_onebit(pp, k1);
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (k1[BT_OCTET16_LEN - 1] & 0x80) != 0 )
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* K2 =  (K1 << 1) (+) Rb */
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        leftshift_onebit(k1, k2);
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        smp_xor_128(k2, const_Rb);
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If MSB(K1) = 0, then K2 = K1 << 1 */
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        leftshift_onebit(k1, k2);
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    print128(k1, (const UINT8 *)"K1");
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    print128(k2, (const UINT8 *)"K2");
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cmac_prepare_last_block (k1, k2);
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         cmac_generate_subkey
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This is the function to generate the two subkeys.
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters       key - CMAC key, expect SRK when used by SMP.
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN cmac_generate_subkey(BT_OCTET16 key)
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_OCTET16 z = {0};
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     ret = TRUE;
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tSMP_ENC output;
268b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_EVENT (" cmac_generate_subkey");
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (SMP_Encrypt(key, BT_OCTET16_LEN, z, BT_OCTET16_LEN, &output))
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cmac_subkey_cont(&output);;
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ret = FALSE;
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         AES_CMAC
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This is the AES-CMAC Generation Function with tlen implemented.
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters       key - CMAC key in little endian order, expect SRK when used by SMP.
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  input - text to be signed in little endian byte order.
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  length - length of the input in byte.
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  tlen - lenth of mac desired
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_signature - data pointer to where signed data to be stored, tlen long.
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN AES_CMAC ( BT_OCTET16 key, UINT8 *input, UINT16 length,
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                UINT16 tlen, UINT8 *p_signature)
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  len, diff;
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  n = (length + BT_OCTET16_LEN - 1) / BT_OCTET16_LEN;       /* n is number of rounds */
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN ret = FALSE;
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
301b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_EVENT ("AES_CMAC  ");
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (n == 0)  n = 1;
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    len = n * BT_OCTET16_LEN;
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
306b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_WARNING("AES128_CMAC started, allocate buffer size = %d", len);
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* allocate a memory space of multiple of 16 bytes to hold text  */
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((cmac_cb.text = (UINT8 *)GKI_getbuf(len)) != NULL)
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cmac_cb.round = n;
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memset(cmac_cb.text, 0, len);
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        diff = len - length;
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (input != NULL && length > 0)
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy(&cmac_cb.text[diff] , input, (int)length);
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cmac_cb.len = length;
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cmac_cb.len = 0;
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* prepare calculation for subkey s and last block of data */
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (cmac_generate_subkey(key))
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* start calculation */
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ret = cmac_aes_k_calculate(key, p_signature, tlen);
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* clean up */
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cmac_aes_cleanup();
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ret = FALSE;
335b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        SMP_TRACE_ERROR("No resources");
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    #if 0 /* testing code, sample data from spec */
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid test_cmac_cback(UINT8 *p_mac, UINT16 tlen)
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
344b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_EVENT ("test_cmac_cback ");
345b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_ERROR("test_cmac_cback");
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid test_cmac(void)
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
350b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_EVENT ("test_cmac ");
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 M[64] = {
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    };
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 key[16] = {
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0x3c, 0x4f, 0xcf, 0x09, 0x88, 0x15, 0xf7, 0xab,
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        0xa6, 0xd2, 0xae, 0x28, 0x16, 0x15, 0x7e, 0x2b
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    };
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 i =0, tmp;
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16 len;
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    len = 64;
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < len/2; i ++)
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        tmp = M[i];
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        M[i] = M[len -1 - i];
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        M[len -1 - i] = tmp;
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(&cmac_cb, 0, sizeof(tCMAC_CB));
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
381b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    SMP_TRACE_WARNING("\n Example 1: len = %d\n", len);
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AES_CMAC(key, M, len, 128, test_cmac_cback, 0);
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    #endif
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
389