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 */ 69 void 70 t4_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 } 79 80 /* Copy out the partial hash state from a software hash implementation. */ 81 void 82 t4_copy_partial_hash(int alg, union authctx *auth_ctx, void *dst) 83 { 84 uint32_t *u32; 85 uint64_t *u64; 86 u_int i; 87 88 u32 = (uint32_t *)dst; 89 u64 = (uint64_t *)dst; 90 switch (alg) { 91 case CRYPTO_SHA1: 92 case CRYPTO_SHA1_HMAC: 93 for (i = 0; i < SHA1_HASH_LEN / 4; i++) 94 u32[i] = htobe32(auth_ctx->sha1ctx.h.b32[i]); 95 break; 96 case CRYPTO_SHA2_224: 97 case CRYPTO_SHA2_224_HMAC: 98 for (i = 0; i < SHA2_256_HASH_LEN / 4; i++) 99 u32[i] = htobe32(auth_ctx->sha224ctx.state[i]); 100 break; 101 case CRYPTO_SHA2_256: 102 case CRYPTO_SHA2_256_HMAC: 103 for (i = 0; i < SHA2_256_HASH_LEN / 4; i++) 104 u32[i] = htobe32(auth_ctx->sha256ctx.state[i]); 105 break; 106 case CRYPTO_SHA2_384: 107 case CRYPTO_SHA2_384_HMAC: 108 for (i = 0; i < SHA2_512_HASH_LEN / 8; i++) 109 u64[i] = htobe64(auth_ctx->sha384ctx.state[i]); 110 break; 111 case CRYPTO_SHA2_512: 112 case CRYPTO_SHA2_512_HMAC: 113 for (i = 0; i < SHA2_512_HASH_LEN / 8; i++) 114 u64[i] = htobe64(auth_ctx->sha512ctx.state[i]); 115 break; 116 } 117 } 118 119 void 120 t4_init_hmac_digest(struct auth_hash *axf, u_int partial_digest_len, 121 char *key, int klen, char *dst) 122 { 123 union authctx auth_ctx; 124 char ipad[SHA2_512_BLOCK_LEN], opad[SHA2_512_BLOCK_LEN]; 125 u_int i; 126 127 /* 128 * If the key is larger than the block size, use the digest of 129 * the key as the key instead. 130 */ 131 klen /= 8; 132 if (klen > axf->blocksize) { 133 axf->Init(&auth_ctx); 134 axf->Update(&auth_ctx, key, klen); 135 axf->Final(ipad, &auth_ctx); 136 klen = axf->hashsize; 137 } else 138 memcpy(ipad, key, klen); 139 140 memset(ipad + klen, 0, axf->blocksize - klen); 141 memcpy(opad, ipad, axf->blocksize); 142 143 for (i = 0; i < axf->blocksize; i++) { 144 ipad[i] ^= HMAC_IPAD_VAL; 145 opad[i] ^= HMAC_OPAD_VAL; 146 } 147 148 /* 149 * Hash the raw ipad and opad and store the partial results in 150 * the key context. 151 */ 152 axf->Init(&auth_ctx); 153 axf->Update(&auth_ctx, ipad, axf->blocksize); 154 t4_copy_partial_hash(axf->type, &auth_ctx, dst); 155 156 dst += roundup2(partial_digest_len, 16); 157 axf->Init(&auth_ctx); 158 axf->Update(&auth_ctx, opad, axf->blocksize); 159 t4_copy_partial_hash(axf->type, &auth_ctx, dst); 160 } 161 162 /* 163 * Borrowed from cesa_prep_aes_key(). 164 * 165 * NB: The crypto engine wants the words in the decryption key in reverse 166 * order. 167 */ 168 void 169 t4_aes_getdeckey(void *dec_key, const void *enc_key, unsigned int kbits) 170 { 171 uint32_t ek[4 * (RIJNDAEL_MAXNR + 1)]; 172 uint32_t *dkey; 173 int i; 174 175 rijndaelKeySetupEnc(ek, enc_key, kbits); 176 dkey = dec_key; 177 dkey += (kbits / 8) / 4; 178 179 switch (kbits) { 180 case 128: 181 for (i = 0; i < 4; i++) 182 *--dkey = htobe32(ek[4 * 10 + i]); 183 break; 184 case 192: 185 for (i = 0; i < 2; i++) 186 *--dkey = htobe32(ek[4 * 11 + 2 + i]); 187 for (i = 0; i < 4; i++) 188 *--dkey = htobe32(ek[4 * 12 + i]); 189 break; 190 case 256: 191 for (i = 0; i < 4; i++) 192 *--dkey = htobe32(ek[4 * 13 + i]); 193 for (i = 0; i < 4; i++) 194 *--dkey = htobe32(ek[4 * 14 + i]); 195 break; 196 } 197 MPASS(dkey == dec_key); 198 } 199