]>
git.ipfire.org Git - thirdparty/hostap.git/blob - src/crypto/aes-siv.c
3 * Copyright (c) 2013 Cozybit, Inc.
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
17 static const u8 zero
[AES_BLOCK_SIZE
];
20 static void dbl(u8
*pad
)
24 carry
= pad
[0] & 0x80;
25 for (i
= 0; i
< AES_BLOCK_SIZE
- 1; i
++)
26 pad
[i
] = (pad
[i
] << 1) | (pad
[i
+ 1] >> 7);
27 pad
[AES_BLOCK_SIZE
- 1] <<= 1;
29 pad
[AES_BLOCK_SIZE
- 1] ^= 0x87;
33 static void xor(u8
*a
, const u8
*b
)
37 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
42 static void xorend(u8
*a
, int alen
, const u8
*b
, int blen
)
49 for (i
= 0; i
< blen
; i
++)
50 a
[alen
- blen
+ i
] ^= b
[i
];
54 static void pad_block(u8
*pad
, const u8
*addr
, size_t len
)
56 os_memset(pad
, 0, AES_BLOCK_SIZE
);
57 os_memcpy(pad
, addr
, len
);
59 if (len
< AES_BLOCK_SIZE
)
64 static int aes_s2v(const u8
*key
, size_t key_len
,
65 size_t num_elem
, const u8
*addr
[], size_t *len
, u8
*mac
)
67 u8 tmp
[AES_BLOCK_SIZE
], tmp2
[AES_BLOCK_SIZE
];
75 os_memcpy(tmp
, zero
, sizeof(zero
));
76 tmp
[AES_BLOCK_SIZE
- 1] = 1;
78 data_len
[0] = sizeof(tmp
);
79 return omac1_aes_vector(key
, key_len
, 1, data
, data_len
, mac
);
83 data_len
[0] = sizeof(zero
);
84 ret
= omac1_aes_vector(key
, key_len
, 1, data
, data_len
, tmp
);
88 for (i
= 0; i
< num_elem
- 1; i
++) {
89 ret
= omac1_aes_vector(key
, key_len
, 1, &addr
[i
], &len
[i
],
97 if (len
[i
] >= AES_BLOCK_SIZE
) {
98 buf
= os_memdup(addr
[i
], len
[i
]);
102 xorend(buf
, len
[i
], tmp
, AES_BLOCK_SIZE
);
104 ret
= omac1_aes_vector(key
, key_len
, 1, data
, &len
[i
], mac
);
105 bin_clear_free(buf
, len
[i
]);
110 pad_block(tmp2
, addr
[i
], len
[i
]);
114 data_len
[0] = sizeof(tmp
);
115 return omac1_aes_vector(key
, key_len
, 1, data
, data_len
, mac
);
119 int aes_siv_encrypt(const u8
*key
, size_t key_len
,
120 const u8
*pw
, size_t pwlen
,
121 size_t num_elem
, const u8
*addr
[], const size_t *len
,
127 u8 v
[AES_BLOCK_SIZE
];
131 if (num_elem
> ARRAY_SIZE(_addr
) - 1 ||
132 (key_len
!= 32 && key_len
!= 48 && key_len
!= 64))
139 for (i
= 0; i
< num_elem
; i
++) {
143 _addr
[num_elem
] = pw
;
144 _len
[num_elem
] = pwlen
;
146 if (aes_s2v(k1
, key_len
, num_elem
+ 1, _addr
, _len
, v
))
150 crypt_pw
= out
+ AES_BLOCK_SIZE
;
152 os_memcpy(iv
, v
, AES_BLOCK_SIZE
);
153 os_memcpy(crypt_pw
, pw
, pwlen
);
155 /* zero out 63rd and 31st bits of ctr (from right) */
158 return aes_ctr_encrypt(k2
, key_len
, v
, crypt_pw
, pwlen
);
162 int aes_siv_decrypt(const u8
*key
, size_t key_len
,
163 const u8
*iv_crypt
, size_t iv_c_len
,
164 size_t num_elem
, const u8
*addr
[], const size_t *len
,
173 u8 iv
[AES_BLOCK_SIZE
];
174 u8 check
[AES_BLOCK_SIZE
];
176 if (iv_c_len
< AES_BLOCK_SIZE
|| num_elem
> ARRAY_SIZE(_addr
) - 1 ||
177 (key_len
!= 32 && key_len
!= 48 && key_len
!= 64))
179 crypt_len
= iv_c_len
- AES_BLOCK_SIZE
;
184 for (i
= 0; i
< num_elem
; i
++) {
188 _addr
[num_elem
] = out
;
189 _len
[num_elem
] = crypt_len
;
191 os_memcpy(iv
, iv_crypt
, AES_BLOCK_SIZE
);
192 os_memcpy(out
, iv_crypt
+ AES_BLOCK_SIZE
, crypt_len
);
197 ret
= aes_ctr_encrypt(k2
, key_len
, iv
, out
, crypt_len
);
201 ret
= aes_s2v(k1
, key_len
, num_elem
+ 1, _addr
, _len
, check
);
204 if (os_memcmp(check
, iv_crypt
, AES_BLOCK_SIZE
) == 0)