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