LCOV - code coverage report
Current view: top level - drivers/common/cnxk - roc_aes.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 93 0.0 %
Date: 2025-02-01 18:54:23 Functions: 0 7 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 44 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (c) 2021 Marvell.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "roc_api.h"
       6                 :            : 
       7                 :            : #define KEY128_ROUNDS           10              /* (Nr+1)*Nb */
       8                 :            : #define KEY256_ROUNDS           14              /* (Nr+1)*Nb */
       9                 :            : #define KEY_SCHEDULE_LEN(nr)    ((nr + 1) * 4)  /* (Nr+1)*Nb words */
      10                 :            : #define AES_HASH_KEY_LEN        16
      11                 :            : 
      12                 :            : /*
      13                 :            :  * AES 128 implementation based on NIST FIPS 197 suitable for LittleEndian
      14                 :            :  * https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf
      15                 :            :  */
      16                 :            : 
      17                 :            : /* Sbox from NIST FIPS 197 */
      18                 :            : static uint8_t Sbox[] = {
      19                 :            :         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
      20                 :            :         0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
      21                 :            :         0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
      22                 :            :         0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
      23                 :            :         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
      24                 :            :         0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
      25                 :            :         0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
      26                 :            :         0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
      27                 :            :         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
      28                 :            :         0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
      29                 :            :         0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
      30                 :            :         0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
      31                 :            :         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
      32                 :            :         0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
      33                 :            :         0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
      34                 :            :         0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
      35                 :            :         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
      36                 :            :         0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
      37                 :            :         0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
      38                 :            :         0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
      39                 :            :         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
      40                 :            :         0xb0, 0x54, 0xbb, 0x16,
      41                 :            : };
      42                 :            : 
      43                 :            : /* Substitute a byte with Sbox[byte]. Do it for a word for 4 bytes */
      44                 :            : static uint32_t
      45                 :          0 : sub_word(uint32_t word)
      46                 :            : {
      47                 :          0 :         word = (Sbox[(word >> 24) & 0xFF] << 24) |
      48                 :          0 :                (Sbox[(word >> 16) & 0xFF] << 16) |
      49                 :          0 :                (Sbox[(word >> 8) & 0xFF] << 8) | Sbox[word & 0xFF];
      50                 :          0 :         return word;
      51                 :            : }
      52                 :            : 
      53                 :            : /* Rotate a word by one byte */
      54                 :            : static uint32_t
      55                 :            : rot_word(uint32_t word)
      56                 :            : {
      57                 :          0 :         return ((word >> 8) & 0xFFFFFF) | (word << 24);
      58                 :            : }
      59                 :            : 
      60                 :            : /*
      61                 :            :  * Multiply with power of 2 and polynomial reduce the result using AES
      62                 :            :  * polynomial
      63                 :            :  */
      64                 :            : static uint8_t
      65                 :            : Xtime(uint8_t byte, uint8_t pow)
      66                 :            : {
      67                 :          0 :         uint32_t w = byte;
      68                 :            : 
      69         [ #  # ]:          0 :         while (pow) {
      70                 :          0 :                 w = w << 1;
      71         [ #  # ]:          0 :                 if (w >> 8)
      72                 :          0 :                         w ^= 0x11b;
      73                 :          0 :                 pow--;
      74                 :            :         }
      75                 :            : 
      76                 :          0 :         return (uint8_t)w;
      77                 :            : }
      78                 :            : 
      79                 :            : /*
      80                 :            :  * Multiply a byte with another number such that the result is polynomial
      81                 :            :  * reduced in the GF8 space
      82                 :            :  */
      83                 :            : static uint8_t
      84                 :          0 : GF8mul(uint8_t byte, uint32_t mp)
      85                 :            : {
      86                 :            :         uint8_t pow, mul = 0;
      87                 :            : 
      88         [ #  # ]:          0 :         while (mp) {
      89                 :          0 :                 pow = ffs(mp) - 1;
      90                 :          0 :                 mul ^= Xtime(byte, pow);
      91                 :          0 :                 mp ^= (1 << pow);
      92                 :            :         }
      93                 :          0 :         return mul;
      94                 :            : }
      95                 :            : 
      96                 :            : static void
      97                 :          0 : aes_key_expand(const uint8_t *key, uint32_t len, uint32_t *ks)
      98                 :            : {
      99                 :          0 :         uint32_t len_words = len / sizeof(uint32_t);
     100                 :            :         unsigned int schedule_len;
     101                 :            :         unsigned int i = len_words;
     102                 :            :         uint32_t temp;
     103                 :            : 
     104         [ #  # ]:          0 :         schedule_len = (len == ROC_CPT_AES128_KEY_LEN) ? KEY_SCHEDULE_LEN(KEY128_ROUNDS) :
     105                 :            :                                                          KEY_SCHEDULE_LEN(KEY256_ROUNDS);
     106                 :            :         /* Skip key in ks */
     107                 :          0 :         memcpy(ks, key, len);
     108                 :            : 
     109         [ #  # ]:          0 :         while (i < schedule_len) {
     110                 :          0 :                 temp = ks[i - 1];
     111         [ #  # ]:          0 :                 if ((i & (len_words - 1)) == 0) {
     112                 :            :                         temp = rot_word(temp);
     113                 :          0 :                         temp = sub_word(temp);
     114                 :          0 :                         temp ^= (uint32_t)GF8mul(1, 1 << ((i / len_words) - 1));
     115                 :            :                 }
     116         [ #  # ]:          0 :                 if (len == ROC_CPT_AES256_KEY_LEN) {
     117         [ #  # ]:          0 :                         if ((i % len_words) == 4)
     118                 :          0 :                                 temp = sub_word(temp);
     119                 :            :                 }
     120                 :          0 :                 ks[i] = ks[i - len_words] ^ temp;
     121                 :          0 :                 i++;
     122                 :            :         }
     123                 :          0 : }
     124                 :            : 
     125                 :            : /* Shift Rows(columns in state in this implementation) */
     126                 :            : static void
     127                 :            : shift_word(uint8_t *sRc, uint8_t c, int count)
     128                 :            : {
     129                 :            :         /* rotate across non-consecutive locations */
     130   [ #  #  #  # ]:          0 :         while (count) {
     131                 :          0 :                 uint8_t t = sRc[c];
     132                 :            : 
     133                 :          0 :                 sRc[c] = sRc[0x4 + c];
     134                 :          0 :                 sRc[0x4 + c] = sRc[0x8 + c];
     135                 :          0 :                 sRc[0x8 + c] = sRc[0xc + c];
     136                 :          0 :                 sRc[0xc + c] = t;
     137                 :          0 :                 count--;
     138                 :            :         }
     139                 :            : }
     140                 :            : 
     141                 :            : /* Mix Columns(rows in state in this implementation) */
     142                 :            : static void
     143                 :          0 : mix_columns(uint8_t *sRc)
     144                 :            : {
     145                 :            :         uint8_t new_st[4];
     146                 :            :         int i;
     147                 :            : 
     148         [ #  # ]:          0 :         for (i = 0; i < 4; i++)
     149                 :          0 :                 new_st[i] = GF8mul(sRc[i], 0x2) ^
     150                 :          0 :                             GF8mul(sRc[(i + 1) & 0x3], 0x3) ^
     151                 :          0 :                             sRc[(i + 2) & 0x3] ^ sRc[(i + 3) & 0x3];
     152         [ #  # ]:          0 :         for (i = 0; i < 4; i++)
     153                 :          0 :                 sRc[i] = new_st[i];
     154                 :          0 : }
     155                 :            : 
     156                 :            : static void
     157                 :          0 : cipher(uint8_t *in, uint8_t *out, uint32_t *ks, uint32_t key_rounds, uint8_t in_len)
     158                 :          0 : {
     159                 :          0 :         uint8_t data_word_len = in_len / sizeof(uint32_t);
     160                 :          0 :         uint32_t state[data_word_len];
     161                 :            :         unsigned int i, round;
     162                 :            : 
     163                 :            :         memcpy(state, in, sizeof(state));
     164                 :            : 
     165                 :            :         /* AddRoundKey(state, w[0, Nb-1]) // See Sec. 5.1.4 */
     166         [ #  # ]:          0 :         for (i = 0; i < data_word_len; i++)
     167                 :          0 :                 state[i] ^= ks[i];
     168                 :            : 
     169         [ #  # ]:          0 :         for (round = 1; round < key_rounds; round++) {
     170                 :            :                 /* SubBytes(state) // See Sec. 5.1.1 */
     171         [ #  # ]:          0 :                 for (i = 0; i < data_word_len; i++)
     172                 :          0 :                         state[i] = sub_word(state[i]);
     173                 :            : 
     174                 :            :                 /* ShiftRows(state) // See Sec. 5.1.2 */
     175         [ #  # ]:          0 :                 for (i = 0; i < data_word_len; i++)
     176                 :          0 :                         shift_word((uint8_t *)state, i, i);
     177                 :            : 
     178                 :            :                 /* MixColumns(state) // See Sec. 5.1.3 */
     179         [ #  # ]:          0 :                 for (i = 0; i < data_word_len; i++)
     180                 :          0 :                         mix_columns((uint8_t *)&state[i]);
     181                 :            : 
     182                 :            :                 /* AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) */
     183         [ #  # ]:          0 :                 for (i = 0; i < data_word_len; i++)
     184                 :          0 :                         state[i] ^= ks[round * data_word_len + i];
     185                 :            :         }
     186                 :            : 
     187                 :            :         /* SubBytes(state) */
     188         [ #  # ]:          0 :         for (i = 0; i < data_word_len; i++)
     189                 :          0 :                 state[i] = sub_word(state[i]);
     190                 :            : 
     191                 :            :         /* ShiftRows(state) */
     192         [ #  # ]:          0 :         for (i = 0; i < data_word_len; i++)
     193                 :          0 :                 shift_word((uint8_t *)state, i, i);
     194                 :            : 
     195                 :            :         /* AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) */
     196         [ #  # ]:          0 :         for (i = 0; i < data_word_len; i++)
     197                 :          0 :                 state[i] ^= ks[key_rounds * data_word_len + i];
     198                 :            :         memcpy(out, state, data_word_len * sizeof(uint32_t));
     199                 :          0 : }
     200                 :            : 
     201                 :            : void
     202                 :          0 : roc_aes_xcbc_key_derive(const uint8_t *auth_key, uint8_t *derived_key)
     203                 :            : {
     204                 :          0 :         uint32_t aes_ks[KEY_SCHEDULE_LEN(KEY128_ROUNDS)] = {0};
     205                 :          0 :         uint8_t k1[16] = {[0 ... 15] = 0x01};
     206                 :          0 :         uint8_t k2[16] = {[0 ... 15] = 0x02};
     207                 :          0 :         uint8_t k3[16] = {[0 ... 15] = 0x03};
     208                 :            : 
     209                 :          0 :         aes_key_expand(auth_key, ROC_CPT_AES_XCBC_KEY_LENGTH, aes_ks);
     210                 :            : 
     211                 :          0 :         cipher(k1, derived_key, aes_ks, KEY128_ROUNDS, sizeof(k1));
     212                 :          0 :         derived_key += sizeof(k1);
     213                 :            : 
     214                 :          0 :         cipher(k2, derived_key, aes_ks, KEY128_ROUNDS, sizeof(k2));
     215                 :          0 :         derived_key += sizeof(k2);
     216                 :            : 
     217                 :          0 :         cipher(k3, derived_key, aes_ks, KEY128_ROUNDS, sizeof(k3));
     218                 :          0 : }
     219                 :            : 
     220                 :            : void
     221                 :          0 : roc_aes_hash_key_derive(const uint8_t *key, uint16_t len, uint8_t hash_key[])
     222                 :            : {
     223                 :          0 :         uint8_t data[AES_HASH_KEY_LEN] = {0x0};
     224                 :            : 
     225         [ #  # ]:          0 :         if (len == ROC_CPT_AES128_KEY_LEN) {
     226                 :          0 :                 uint32_t aes_ks[KEY_SCHEDULE_LEN(KEY128_ROUNDS)] = {0};
     227                 :            : 
     228                 :          0 :                 aes_key_expand(key, ROC_CPT_AES128_KEY_LEN, aes_ks);
     229                 :          0 :                 cipher(data, hash_key, aes_ks, KEY128_ROUNDS, sizeof(data));
     230                 :            :         } else {
     231                 :          0 :                 uint32_t aes_ks[KEY_SCHEDULE_LEN(KEY256_ROUNDS)] = {0};
     232                 :            : 
     233                 :          0 :                 aes_key_expand(key, ROC_CPT_AES256_KEY_LEN, aes_ks);
     234                 :          0 :                 cipher(data, hash_key, aes_ks, KEY256_ROUNDS, sizeof(data));
     235                 :            :         }
     236                 :          0 : }

Generated by: LCOV version 1.14