Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/module/icp/algs/aes/aes_modes.c
48775 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or https://opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
/*
23
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24
* Use is subject to license terms.
25
*/
26
27
#include <sys/zfs_context.h>
28
#include <modes/modes.h>
29
#include <aes/aes_impl.h>
30
31
/* Copy a 16-byte AES block from "in" to "out" */
32
void
33
aes_copy_block(uint8_t *in, uint8_t *out)
34
{
35
if (IS_P2ALIGNED2(in, out, sizeof (uint32_t))) {
36
/* LINTED: pointer alignment */
37
*(uint32_t *)&out[0] = *(uint32_t *)&in[0];
38
/* LINTED: pointer alignment */
39
*(uint32_t *)&out[4] = *(uint32_t *)&in[4];
40
/* LINTED: pointer alignment */
41
*(uint32_t *)&out[8] = *(uint32_t *)&in[8];
42
/* LINTED: pointer alignment */
43
*(uint32_t *)&out[12] = *(uint32_t *)&in[12];
44
} else {
45
AES_COPY_BLOCK(in, out);
46
}
47
}
48
49
50
/* XOR a 16-byte AES block of data into dst */
51
void
52
aes_xor_block(uint8_t *data, uint8_t *dst)
53
{
54
if (IS_P2ALIGNED2(dst, data, sizeof (uint32_t))) {
55
/* LINTED: pointer alignment */
56
*(uint32_t *)&dst[0] ^= *(uint32_t *)&data[0];
57
/* LINTED: pointer alignment */
58
*(uint32_t *)&dst[4] ^= *(uint32_t *)&data[4];
59
/* LINTED: pointer alignment */
60
*(uint32_t *)&dst[8] ^= *(uint32_t *)&data[8];
61
/* LINTED: pointer alignment */
62
*(uint32_t *)&dst[12] ^= *(uint32_t *)&data[12];
63
} else {
64
AES_XOR_BLOCK(data, dst);
65
}
66
}
67
68
69
/*
70
* Encrypt multiple blocks of data according to mode.
71
*/
72
int
73
aes_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
74
crypto_data_t *out)
75
{
76
aes_ctx_t *aes_ctx = ctx;
77
int rv;
78
79
if (aes_ctx->ac_flags & CCM_MODE) {
80
rv = ccm_mode_encrypt_contiguous_blocks(ctx, data, length,
81
out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
82
aes_xor_block);
83
} else if (aes_ctx->ac_flags & GCM_MODE) {
84
rv = gcm_mode_encrypt_contiguous_blocks(ctx, data, length,
85
out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
86
aes_xor_block);
87
}
88
else
89
__builtin_unreachable();
90
return (rv);
91
}
92
93
94
/*
95
* Decrypt multiple blocks of data according to mode.
96
*/
97
int
98
aes_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
99
crypto_data_t *out)
100
{
101
aes_ctx_t *aes_ctx = ctx;
102
int rv;
103
104
if (aes_ctx->ac_flags & CCM_MODE) {
105
rv = ccm_mode_decrypt_contiguous_blocks(ctx, data, length,
106
out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
107
aes_xor_block);
108
} else if (aes_ctx->ac_flags & GCM_MODE) {
109
rv = gcm_mode_decrypt_contiguous_blocks(ctx, data, length,
110
out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
111
aes_xor_block);
112
} else
113
__builtin_unreachable();
114
return (rv);
115
}
116
117