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