1/*- 2 * Copyright (c) 2017-2019 Chelsio Communications, Inc. 3 * All rights reserved. 4 * Written by: John Baldwin <jhb@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD$"); 30 31#include <sys/types.h> 32#include <sys/malloc.h> 33 34#include <opencrypto/cryptodev.h> 35#include <opencrypto/xform.h> 36 37#include "common/common.h" 38#include "crypto/t4_crypto.h" 39 40/* 41 * Crypto operations use a key context to store cipher keys and 42 * partial hash digests. They can either be passed inline as part of 43 * a work request using crypto or they can be stored in card RAM. For 44 * the latter case, work requests must replace the inline key context 45 * with a request to read the context from card RAM. 46 * 47 * The format of a key context: 48 * 49 * +-------------------------------+ 50 * | key context header | 51 * +-------------------------------+ 52 * | AES key | ----- For requests with AES 53 * +-------------------------------+ 54 * | Hash state | ----- For hash-only requests 55 * +-------------------------------+ - 56 * | IPAD (16-byte aligned) | \ 57 * +-------------------------------+ +---- For requests with HMAC 58 * | OPAD (16-byte aligned) | / 59 * +-------------------------------+ - 60 * | GMAC H | ----- For AES-GCM 61 * +-------------------------------+ - 62 */ 63 64/* 65 * Generate the initial GMAC hash state for a AES-GCM key. 66 * 67 * Borrowed from AES_GMAC_Setkey(). 68 */ 69void 70t4_init_gmac_hash(const char *key, int klen, char *ghash) 71{ 72 static char zeroes[GMAC_BLOCK_LEN]; 73 uint32_t keysched[4 * (RIJNDAEL_MAXNR + 1)]; 74 int rounds; 75 76 rounds = rijndaelKeySetupEnc(keysched, key, klen); 77 rijndaelEncrypt(keysched, rounds, zeroes, ghash); 78 explicit_bzero(keysched, sizeof(keysched)); 79} 80 81/* Copy out the partial hash state from a software hash implementation. */ 82void 83t4_copy_partial_hash(int alg, union authctx *auth_ctx, void *dst) 84{ 85 uint32_t *u32; 86 uint64_t *u64; 87 u_int i; 88 89 u32 = (uint32_t *)dst; 90 u64 = (uint64_t *)dst; 91 switch (alg) { 92 case CRYPTO_SHA1: 93 case CRYPTO_SHA1_HMAC: 94 for (i = 0; i < SHA1_HASH_LEN / 4; i++) 95 u32[i] = htobe32(auth_ctx->sha1ctx.h.b32[i]); 96 break; 97 case CRYPTO_SHA2_224: 98 case CRYPTO_SHA2_224_HMAC: 99 for (i = 0; i < SHA2_256_HASH_LEN / 4; i++) 100 u32[i] = htobe32(auth_ctx->sha224ctx.state[i]); 101 break; 102 case CRYPTO_SHA2_256: 103 case CRYPTO_SHA2_256_HMAC: 104 for (i = 0; i < SHA2_256_HASH_LEN / 4; i++) 105 u32[i] = htobe32(auth_ctx->sha256ctx.state[i]); 106 break; 107 case CRYPTO_SHA2_384: 108 case CRYPTO_SHA2_384_HMAC: 109 for (i = 0; i < SHA2_512_HASH_LEN / 8; i++) 110 u64[i] = htobe64(auth_ctx->sha384ctx.state[i]); 111 break; 112 case CRYPTO_SHA2_512: 113 case CRYPTO_SHA2_512_HMAC: 114 for (i = 0; i < SHA2_512_HASH_LEN / 8; i++) 115 u64[i] = htobe64(auth_ctx->sha512ctx.state[i]); 116 break; 117 } 118} 119 120void 121t4_init_hmac_digest(struct auth_hash *axf, u_int partial_digest_len, 122 char *key, int klen, char *dst) 123{ 124 union authctx auth_ctx; 125 char ipad[SHA2_512_BLOCK_LEN], opad[SHA2_512_BLOCK_LEN]; 126 u_int i; 127 128 /* 129 * If the key is larger than the block size, use the digest of 130 * the key as the key instead. 131 */ 132 klen /= 8; 133 if (klen > axf->blocksize) { 134 axf->Init(&auth_ctx); 135 axf->Update(&auth_ctx, key, klen); 136 axf->Final(ipad, &auth_ctx); 137 klen = axf->hashsize; 138 } else 139 memcpy(ipad, key, klen); 140 141 memset(ipad + klen, 0, axf->blocksize - klen); 142 memcpy(opad, ipad, axf->blocksize); 143 144 for (i = 0; i < axf->blocksize; i++) { 145 ipad[i] ^= HMAC_IPAD_VAL; 146 opad[i] ^= HMAC_OPAD_VAL; 147 } 148 149 /* 150 * Hash the raw ipad and opad and store the partial results in 151 * the key context. 152 */ 153 axf->Init(&auth_ctx); 154 axf->Update(&auth_ctx, ipad, axf->blocksize); 155 t4_copy_partial_hash(axf->type, &auth_ctx, dst); 156 157 dst += roundup2(partial_digest_len, 16); 158 axf->Init(&auth_ctx); 159 axf->Update(&auth_ctx, opad, axf->blocksize); 160 t4_copy_partial_hash(axf->type, &auth_ctx, dst); 161} 162 163/* 164 * Borrowed from cesa_prep_aes_key(). 165 * 166 * NB: The crypto engine wants the words in the decryption key in reverse 167 * order. 168 */ 169void 170t4_aes_getdeckey(void *dec_key, const void *enc_key, unsigned int kbits) 171{ 172 uint32_t ek[4 * (RIJNDAEL_MAXNR + 1)]; 173 uint32_t *dkey; 174 int i; 175 176 rijndaelKeySetupEnc(ek, enc_key, kbits); 177 dkey = dec_key; 178 dkey += (kbits / 8) / 4; 179 180 switch (kbits) { 181 case 128: 182 for (i = 0; i < 4; i++) 183 *--dkey = htobe32(ek[4 * 10 + i]); 184 break; 185 case 192: 186 for (i = 0; i < 2; i++) 187 *--dkey = htobe32(ek[4 * 11 + 2 + i]); 188 for (i = 0; i < 4; i++) 189 *--dkey = htobe32(ek[4 * 12 + i]); 190 break; 191 case 256: 192 for (i = 0; i < 4; i++) 193 *--dkey = htobe32(ek[4 * 13 + i]); 194 for (i = 0; i < 4; i++) 195 *--dkey = htobe32(ek[4 * 14 + i]); 196 break; 197 } 198 MPASS(dkey == dec_key); 199 explicit_bzero(ek, sizeof(ek)); 200} 201