LCOV - code coverage report
Current view: top level - lib/crypto - aes_cmac_128.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 42 42 100.0 %
Date: 2024-06-13 04:01:37 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :    AES-CMAC-128 (rfc 4493)
       3             :    Copyright (C) Stefan Metzmacher 2012
       4             :    Copyright (C) Jeremy Allison 2012
       5             :    Copyright (C) Michael Adam 2012
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "replace.h"
      22             : #include "lib/crypto/aes.h"
      23             : #include "lib/crypto/aes_cmac_128.h"
      24             : 
      25             : static const uint8_t const_Zero[] = {
      26             :         0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
      27             :         0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00
      28             : };
      29             : 
      30             : static const uint8_t const_Rb[] = {
      31             :         0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
      32             :         0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x87
      33             : };
      34             : 
      35             : #define _MSB(x) (((x)[0] & 0x80)?1:0)
      36             : 
      37         303 : void aes_cmac_128_init(struct aes_cmac_128_context *ctx,
      38             :                        const uint8_t K[AES_BLOCK_SIZE])
      39             : {
      40         303 :         ZERO_STRUCTP(ctx);
      41             : 
      42         303 :         AES_set_encrypt_key(K, 128, &ctx->aes_key);
      43             : 
      44             :         /* step 1 - generate subkeys k1 and k2 */
      45             : 
      46         303 :         AES_encrypt(const_Zero, ctx->L, &ctx->aes_key);
      47             : 
      48         303 :         if (_MSB(ctx->L) == 0) {
      49         150 :                 aes_block_lshift(ctx->L, ctx->K1);
      50             :         } else {
      51         153 :                 aes_block_lshift(ctx->L, ctx->tmp);
      52         153 :                 aes_block_xor(ctx->tmp, const_Rb, ctx->K1);
      53             :         }
      54             : 
      55         303 :         if (_MSB(ctx->K1) == 0) {
      56         193 :                 aes_block_lshift(ctx->K1, ctx->K2);
      57             :         } else {
      58         110 :                 aes_block_lshift(ctx->K1, ctx->tmp);
      59         110 :                 aes_block_xor(ctx->tmp, const_Rb, ctx->K2);
      60             :         }
      61         303 : }
      62             : 
      63        1211 : void aes_cmac_128_update(struct aes_cmac_128_context *ctx,
      64             :                          const uint8_t *msg, size_t msg_len)
      65             : {
      66             :         /*
      67             :          * check if we expand the block
      68             :          */
      69        1211 :         if (ctx->last_len < AES_BLOCK_SIZE) {
      70         589 :                 size_t len = MIN(AES_BLOCK_SIZE - ctx->last_len, msg_len);
      71             : 
      72         589 :                 if (len > 0) {
      73         556 :                         memcpy(&ctx->last[ctx->last_len], msg, len);
      74         556 :                         msg += len;
      75         556 :                         msg_len -= len;
      76         556 :                         ctx->last_len += len;
      77             :                 }
      78             :         }
      79             : 
      80        1211 :         if (msg_len == 0) {
      81             :                 /* if it is still the last block, we are done */
      82         162 :                 return;
      83             :         }
      84             : 
      85             :         /*
      86             :          * now checksum everything but the last block
      87             :          */
      88        1049 :         aes_block_xor(ctx->X, ctx->last, ctx->Y);
      89        1049 :         AES_encrypt(ctx->Y, ctx->X, &ctx->aes_key);
      90             : 
      91       10841 :         while (msg_len > AES_BLOCK_SIZE) {
      92        8743 :                 aes_block_xor(ctx->X, msg, ctx->Y);
      93        8743 :                 AES_encrypt(ctx->Y, ctx->X, &ctx->aes_key);
      94        8743 :                 msg += AES_BLOCK_SIZE;
      95        8743 :                 msg_len -= AES_BLOCK_SIZE;
      96             :         }
      97             : 
      98             :         /*
      99             :          * copy the last block, it will be processed in
     100             :          * aes_cmac_128_final().
     101             :          */
     102        1049 :         ZERO_STRUCT(ctx->last);
     103        1049 :         memcpy(ctx->last, msg, msg_len);
     104        1049 :         ctx->last_len = msg_len;
     105             : }
     106             : 
     107         303 : void aes_cmac_128_final(struct aes_cmac_128_context *ctx,
     108             :                         uint8_t T[AES_BLOCK_SIZE])
     109             : {
     110         303 :         if (ctx->last_len < AES_BLOCK_SIZE) {
     111         253 :                 ctx->last[ctx->last_len] = 0x80;
     112         253 :                 aes_block_xor(ctx->last, ctx->K2, ctx->tmp);
     113             :         } else {
     114          50 :                 aes_block_xor(ctx->last, ctx->K1, ctx->tmp);
     115             :         }
     116             : 
     117         303 :         aes_block_xor(ctx->tmp, ctx->X, ctx->Y);
     118         303 :         AES_encrypt(ctx->Y, T, &ctx->aes_key);
     119             : 
     120         303 :         ZERO_STRUCTP(ctx);
     121         303 : }

Generated by: LCOV version 1.13