xref: /freebsd/sys/contrib/openzfs/module/icp/algs/modes/gcm_generic.c (revision 271171e0d97b88ba2a7c3bf750c9672b484c1c13)
1eda14cbcSMatt Macy /*
2eda14cbcSMatt Macy  * CDDL HEADER START
3eda14cbcSMatt Macy  *
4eda14cbcSMatt Macy  * The contents of this file are subject to the terms of the
5eda14cbcSMatt Macy  * Common Development and Distribution License (the "License").
6eda14cbcSMatt Macy  * You may not use this file except in compliance with the License.
7eda14cbcSMatt Macy  *
8eda14cbcSMatt Macy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*271171e0SMartin Matuska  * or https://opensource.org/licenses/CDDL-1.0.
10eda14cbcSMatt Macy  * See the License for the specific language governing permissions
11eda14cbcSMatt Macy  * and limitations under the License.
12eda14cbcSMatt Macy  *
13eda14cbcSMatt Macy  * When distributing Covered Code, include this CDDL HEADER in each
14eda14cbcSMatt Macy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15eda14cbcSMatt Macy  * If applicable, add the following below this CDDL HEADER, with the
16eda14cbcSMatt Macy  * fields enclosed by brackets "[]" replaced with your own identifying
17eda14cbcSMatt Macy  * information: Portions Copyright [yyyy] [name of copyright owner]
18eda14cbcSMatt Macy  *
19eda14cbcSMatt Macy  * CDDL HEADER END
20eda14cbcSMatt Macy  */
21eda14cbcSMatt Macy /*
22eda14cbcSMatt Macy  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23eda14cbcSMatt Macy  */
24eda14cbcSMatt Macy 
25eda14cbcSMatt Macy #include <modes/gcm_impl.h>
26eda14cbcSMatt Macy 
27eda14cbcSMatt Macy struct aes_block {
28eda14cbcSMatt Macy 	uint64_t a;
29eda14cbcSMatt Macy 	uint64_t b;
30eda14cbcSMatt Macy };
31eda14cbcSMatt Macy 
32eda14cbcSMatt Macy /*
33eda14cbcSMatt Macy  * Perform a carry-less multiplication (that is, use XOR instead of the
34eda14cbcSMatt Macy  * multiply operator) on *x_in and *y and place the result in *res.
35eda14cbcSMatt Macy  *
36eda14cbcSMatt Macy  * Byte swap the input (*x_in and *y) and the output (*res).
37eda14cbcSMatt Macy  *
38eda14cbcSMatt Macy  * Note: x_in, y, and res all point to 16-byte numbers (an array of two
39eda14cbcSMatt Macy  * 64-bit integers).
40eda14cbcSMatt Macy  */
41eda14cbcSMatt Macy static void
gcm_generic_mul(uint64_t * x_in,uint64_t * y,uint64_t * res)42eda14cbcSMatt Macy gcm_generic_mul(uint64_t *x_in, uint64_t *y, uint64_t *res)
43eda14cbcSMatt Macy {
44eda14cbcSMatt Macy 	static const uint64_t R = 0xe100000000000000ULL;
45eda14cbcSMatt Macy 	struct aes_block z = {0, 0};
46eda14cbcSMatt Macy 	struct aes_block v;
47eda14cbcSMatt Macy 	uint64_t x;
48eda14cbcSMatt Macy 	int i, j;
49eda14cbcSMatt Macy 
50eda14cbcSMatt Macy 	v.a = ntohll(y[0]);
51eda14cbcSMatt Macy 	v.b = ntohll(y[1]);
52eda14cbcSMatt Macy 
53eda14cbcSMatt Macy 	for (j = 0; j < 2; j++) {
54eda14cbcSMatt Macy 		x = ntohll(x_in[j]);
55eda14cbcSMatt Macy 		for (i = 0; i < 64; i++, x <<= 1) {
56eda14cbcSMatt Macy 			if (x & 0x8000000000000000ULL) {
57eda14cbcSMatt Macy 				z.a ^= v.a;
58eda14cbcSMatt Macy 				z.b ^= v.b;
59eda14cbcSMatt Macy 			}
60eda14cbcSMatt Macy 			if (v.b & 1ULL) {
61eda14cbcSMatt Macy 				v.b = (v.a << 63)|(v.b >> 1);
62eda14cbcSMatt Macy 				v.a = (v.a >> 1) ^ R;
63eda14cbcSMatt Macy 			} else {
64eda14cbcSMatt Macy 				v.b = (v.a << 63)|(v.b >> 1);
65eda14cbcSMatt Macy 				v.a = v.a >> 1;
66eda14cbcSMatt Macy 			}
67eda14cbcSMatt Macy 		}
68eda14cbcSMatt Macy 	}
69eda14cbcSMatt Macy 	res[0] = htonll(z.a);
70eda14cbcSMatt Macy 	res[1] = htonll(z.b);
71eda14cbcSMatt Macy }
72eda14cbcSMatt Macy 
73eda14cbcSMatt Macy static boolean_t
gcm_generic_will_work(void)74eda14cbcSMatt Macy gcm_generic_will_work(void)
75eda14cbcSMatt Macy {
76eda14cbcSMatt Macy 	return (B_TRUE);
77eda14cbcSMatt Macy }
78eda14cbcSMatt Macy 
79eda14cbcSMatt Macy const gcm_impl_ops_t gcm_generic_impl = {
80eda14cbcSMatt Macy 	.mul = &gcm_generic_mul,
81eda14cbcSMatt Macy 	.is_supported = &gcm_generic_will_work,
82eda14cbcSMatt Macy 	.name = "generic"
83eda14cbcSMatt Macy };
84