Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
aes_cmac.c
Go to the documentation of this file.
1/*
2 * Copyright 2015-2018 Yubico AB
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// AES-CMAC implementation as defined in SP-800-38B
18// AES key length can be one of 128, 192, 256
19// Output length is one full block (16 bytes)
20
21#include <stdlib.h>
22#include <stdint.h>
23#include <string.h>
24
25#include "aes_cmac.h"
27
28static uint8_t zero[AES_BLOCK_SIZE];
29
30/*#include <stdio.h>
31static void dump_hex(char *msg, const unsigned char *buf, unsigned int len) {
32 unsigned int i;
33 if (strcmp(msg, "") != 0)
34 fprintf(stderr, "%s\n", msg);
35
36 for (i = 0; i < len; i++) {
37 fprintf(stderr, "%02x ", buf[i]);
38 }
39
40 fprintf(stderr, "\n");
41}
42*/
43
44static void do_pad(uint8_t *data, uint8_t len) {
45
46 uint8_t i;
47
48 for (i = len; i < AES_BLOCK_SIZE; i++)
49 if (i == len)
50 data[i] = 0x80;
51 else
52 data[i] = 0x00;
53}
54
55static void do_xor(const uint8_t *a, uint8_t *b) {
56
57 uint8_t i = 0;
58
59 for (i = 0; i < AES_BLOCK_SIZE; i++) {
60 b[i] ^= a[i];
61 }
62}
63
64static void do_shift_one_bit_left(const uint8_t *a, uint8_t *b,
65 uint8_t *carry) {
66
67 int8_t i;
68
69 for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
70 b[i] = (a[i] << 1) | *carry;
71
72 *carry = a[i] >> 7;
73 }
74}
75
76static void cmac_generate_subkey(const uint8_t *key, uint8_t *subkey) {
77
78 uint8_t carry = 0;
79
80 do_shift_one_bit_left(key, subkey, &carry);
81
82 subkey[AES_BLOCK_SIZE - 1] ^= 0x87 >> (8 - (carry * 8));
83}
84
85void aes_cmac_encrypt(const aes_cmac_context_t *ctx, const uint8_t *message,
86 const uint16_t message_len, uint8_t *mac) {
87
88 uint8_t n_blocks;
89 uint8_t i;
90 uint8_t remaining_bytes;
91
93 uint8_t *ptr = (uint8_t *) message;
94
95 memcpy(mac, zero, AES_BLOCK_SIZE);
97
98 if (message_len == 0)
99 n_blocks = 0;
100 else
101 n_blocks = (message_len + (AES_BLOCK_SIZE - 1)) / AES_BLOCK_SIZE - 1;
102
103 remaining_bytes = (message_len % AES_BLOCK_SIZE);
104
105 for (i = 0; i < n_blocks; i++) {
106 do_xor(ptr, mac);
107 aes_encrypt(mac, mac, &ctx->aes_ctx);
108 ptr += AES_BLOCK_SIZE;
109 }
110
111 if (remaining_bytes == 0) {
112 if (message != NULL && message_len != 0) {
113 memcpy(M, ptr, AES_BLOCK_SIZE);
114 do_xor(ctx->k1, M);
115 } else {
116 do_pad(M, 0);
117 do_xor(ctx->k2, M);
118 }
119 } else {
120 memcpy(M, ptr, remaining_bytes);
121 do_pad(M, remaining_bytes);
122 do_xor(ctx->k2, M);
123 }
124
125 do_xor(M, mac);
126
127 aes_encrypt(mac, mac, &ctx->aes_ctx);
128}
129
131
133
135
137 aes_encrypt(zero, L, &ctx->aes_ctx);
138
139 cmac_generate_subkey(L, ctx->k1);
140 cmac_generate_subkey(ctx->k1, ctx->k2);
141
142 aes_cmac_encrypt(ctx, zero, AES_BLOCK_SIZE, ctx->mac);
143
144 return 0;
145}
146
148 if (!ctx)
149 return;
150 aes_destroy(&(ctx->aes_ctx));
152}
uint8_t aes_set_encrypt_key(uint8_t *key, uint16_t key_len, aes_context *ctx)
Definition aes.c:172
void aes_destroy(aes_context *ctx)
Definition aes.c:330
uint8_t aes_encrypt(uint8_t *in, uint8_t *out, const aes_context *ctx)
Definition aes.c:229
#define AES_BLOCK_SIZE
Definition aes.h:35
uint8_t aes_cmac_init(uint8_t *key, uint16_t key_len, aes_cmac_context_t *ctx)
Definition aes_cmac.c:130
void aes_cmac_destroy(aes_cmac_context_t *ctx)
Definition aes_cmac.c:147
void aes_cmac_encrypt(const aes_cmac_context_t *ctx, const uint8_t *message, const uint16_t message_len, uint8_t *mac)
Definition aes_cmac.c:85
#define insecure_memzero(buf, len)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
unsigned short uint16_t
Definition stdint.h:125
unsigned char uint8_t
Definition stdint.h:124
signed char int8_t
Definition stdint.h:121
uint8_t mac[AES_BLOCK_SIZE]
Definition aes_cmac.h:23
uint8_t k1[AES_BLOCK_SIZE]
Definition aes_cmac.h:21
uint8_t k2[AES_BLOCK_SIZE]
Definition aes_cmac.h:22
aes_context aes_ctx
Definition aes_cmac.h:20
size_t len
session operation op sign key_len
memcpy((char *) pInfo->slotDescription, s, l)