1*09f455dcSMasahiro Yamada /* 2*09f455dcSMasahiro Yamada * Copyright (c) 2011 The Chromium OS Authors. 3*09f455dcSMasahiro Yamada * (C) Copyright 2010 - 2011 NVIDIA Corporation <www.nvidia.com> 4*09f455dcSMasahiro Yamada * 5*09f455dcSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 6*09f455dcSMasahiro Yamada */ 7*09f455dcSMasahiro Yamada 8*09f455dcSMasahiro Yamada #include <common.h> 9*09f455dcSMasahiro Yamada #include <asm/errno.h> 10*09f455dcSMasahiro Yamada #include "crypto.h" 11*09f455dcSMasahiro Yamada #include "aes.h" 12*09f455dcSMasahiro Yamada 13*09f455dcSMasahiro Yamada static u8 zero_key[16]; 14*09f455dcSMasahiro Yamada 15*09f455dcSMasahiro Yamada #define AES_CMAC_CONST_RB 0x87 /* from RFC 4493, Figure 2.2 */ 16*09f455dcSMasahiro Yamada 17*09f455dcSMasahiro Yamada enum security_op { 18*09f455dcSMasahiro Yamada SECURITY_SIGN = 1 << 0, /* Sign the data */ 19*09f455dcSMasahiro Yamada SECURITY_ENCRYPT = 1 << 1, /* Encrypt the data */ 20*09f455dcSMasahiro Yamada }; 21*09f455dcSMasahiro Yamada 22*09f455dcSMasahiro Yamada /** 23*09f455dcSMasahiro Yamada * Shift a vector left by one bit 24*09f455dcSMasahiro Yamada * 25*09f455dcSMasahiro Yamada * \param in Input vector 26*09f455dcSMasahiro Yamada * \param out Output vector 27*09f455dcSMasahiro Yamada * \param size Length of vector in bytes 28*09f455dcSMasahiro Yamada */ 29*09f455dcSMasahiro Yamada static void left_shift_vector(u8 *in, u8 *out, int size) 30*09f455dcSMasahiro Yamada { 31*09f455dcSMasahiro Yamada int carry = 0; 32*09f455dcSMasahiro Yamada int i; 33*09f455dcSMasahiro Yamada 34*09f455dcSMasahiro Yamada for (i = size - 1; i >= 0; i--) { 35*09f455dcSMasahiro Yamada out[i] = (in[i] << 1) | carry; 36*09f455dcSMasahiro Yamada carry = in[i] >> 7; /* get most significant bit */ 37*09f455dcSMasahiro Yamada } 38*09f455dcSMasahiro Yamada } 39*09f455dcSMasahiro Yamada 40*09f455dcSMasahiro Yamada /** 41*09f455dcSMasahiro Yamada * Sign a block of data, putting the result into dst. 42*09f455dcSMasahiro Yamada * 43*09f455dcSMasahiro Yamada * \param key Input AES key, length AES_KEY_LENGTH 44*09f455dcSMasahiro Yamada * \param key_schedule Expanded key to use 45*09f455dcSMasahiro Yamada * \param src Source data of length 'num_aes_blocks' blocks 46*09f455dcSMasahiro Yamada * \param dst Destination buffer, length AES_KEY_LENGTH 47*09f455dcSMasahiro Yamada * \param num_aes_blocks Number of AES blocks to encrypt 48*09f455dcSMasahiro Yamada */ 49*09f455dcSMasahiro Yamada static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst, 50*09f455dcSMasahiro Yamada u32 num_aes_blocks) 51*09f455dcSMasahiro Yamada { 52*09f455dcSMasahiro Yamada u8 tmp_data[AES_KEY_LENGTH]; 53*09f455dcSMasahiro Yamada u8 left[AES_KEY_LENGTH]; 54*09f455dcSMasahiro Yamada u8 k1[AES_KEY_LENGTH]; 55*09f455dcSMasahiro Yamada u8 *cbc_chain_data; 56*09f455dcSMasahiro Yamada unsigned i; 57*09f455dcSMasahiro Yamada 58*09f455dcSMasahiro Yamada cbc_chain_data = zero_key; /* Convenient array of 0's for IV */ 59*09f455dcSMasahiro Yamada 60*09f455dcSMasahiro Yamada /* compute K1 constant needed by AES-CMAC calculation */ 61*09f455dcSMasahiro Yamada for (i = 0; i < AES_KEY_LENGTH; i++) 62*09f455dcSMasahiro Yamada tmp_data[i] = 0; 63*09f455dcSMasahiro Yamada 64*09f455dcSMasahiro Yamada aes_cbc_encrypt_blocks(key_schedule, tmp_data, left, 1); 65*09f455dcSMasahiro Yamada 66*09f455dcSMasahiro Yamada left_shift_vector(left, k1, sizeof(left)); 67*09f455dcSMasahiro Yamada 68*09f455dcSMasahiro Yamada if ((left[0] >> 7) != 0) /* get MSB of L */ 69*09f455dcSMasahiro Yamada k1[AES_KEY_LENGTH-1] ^= AES_CMAC_CONST_RB; 70*09f455dcSMasahiro Yamada 71*09f455dcSMasahiro Yamada /* compute the AES-CMAC value */ 72*09f455dcSMasahiro Yamada for (i = 0; i < num_aes_blocks; i++) { 73*09f455dcSMasahiro Yamada /* Apply the chain data */ 74*09f455dcSMasahiro Yamada aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data); 75*09f455dcSMasahiro Yamada 76*09f455dcSMasahiro Yamada /* for the final block, XOR K1 into the IV */ 77*09f455dcSMasahiro Yamada if (i == num_aes_blocks - 1) 78*09f455dcSMasahiro Yamada aes_apply_cbc_chain_data(tmp_data, k1, tmp_data); 79*09f455dcSMasahiro Yamada 80*09f455dcSMasahiro Yamada /* encrypt the AES block */ 81*09f455dcSMasahiro Yamada aes_encrypt(tmp_data, key_schedule, dst); 82*09f455dcSMasahiro Yamada 83*09f455dcSMasahiro Yamada debug("sign_obj: block %d of %d\n", i, num_aes_blocks); 84*09f455dcSMasahiro Yamada 85*09f455dcSMasahiro Yamada /* Update pointers for next loop. */ 86*09f455dcSMasahiro Yamada cbc_chain_data = dst; 87*09f455dcSMasahiro Yamada src += AES_KEY_LENGTH; 88*09f455dcSMasahiro Yamada } 89*09f455dcSMasahiro Yamada } 90*09f455dcSMasahiro Yamada 91*09f455dcSMasahiro Yamada /** 92*09f455dcSMasahiro Yamada * Encrypt and sign a block of data (depending on security mode). 93*09f455dcSMasahiro Yamada * 94*09f455dcSMasahiro Yamada * \param key Input AES key, length AES_KEY_LENGTH 95*09f455dcSMasahiro Yamada * \param oper Security operations mask to perform (enum security_op) 96*09f455dcSMasahiro Yamada * \param src Source data 97*09f455dcSMasahiro Yamada * \param length Size of source data 98*09f455dcSMasahiro Yamada * \param sig_dst Destination address for signature, AES_KEY_LENGTH bytes 99*09f455dcSMasahiro Yamada */ 100*09f455dcSMasahiro Yamada static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src, 101*09f455dcSMasahiro Yamada u32 length, u8 *sig_dst) 102*09f455dcSMasahiro Yamada { 103*09f455dcSMasahiro Yamada u32 num_aes_blocks; 104*09f455dcSMasahiro Yamada u8 key_schedule[AES_EXPAND_KEY_LENGTH]; 105*09f455dcSMasahiro Yamada 106*09f455dcSMasahiro Yamada debug("encrypt_and_sign: length = %d\n", length); 107*09f455dcSMasahiro Yamada 108*09f455dcSMasahiro Yamada /* 109*09f455dcSMasahiro Yamada * The only need for a key is for signing/checksum purposes, so 110*09f455dcSMasahiro Yamada * if not encrypting, expand a key of 0s. 111*09f455dcSMasahiro Yamada */ 112*09f455dcSMasahiro Yamada aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key, key_schedule); 113*09f455dcSMasahiro Yamada 114*09f455dcSMasahiro Yamada num_aes_blocks = (length + AES_KEY_LENGTH - 1) / AES_KEY_LENGTH; 115*09f455dcSMasahiro Yamada 116*09f455dcSMasahiro Yamada if (oper & SECURITY_ENCRYPT) { 117*09f455dcSMasahiro Yamada /* Perform this in place, resulting in src being encrypted. */ 118*09f455dcSMasahiro Yamada debug("encrypt_and_sign: begin encryption\n"); 119*09f455dcSMasahiro Yamada aes_cbc_encrypt_blocks(key_schedule, src, src, num_aes_blocks); 120*09f455dcSMasahiro Yamada debug("encrypt_and_sign: end encryption\n"); 121*09f455dcSMasahiro Yamada } 122*09f455dcSMasahiro Yamada 123*09f455dcSMasahiro Yamada if (oper & SECURITY_SIGN) { 124*09f455dcSMasahiro Yamada /* encrypt the data, overwriting the result in signature. */ 125*09f455dcSMasahiro Yamada debug("encrypt_and_sign: begin signing\n"); 126*09f455dcSMasahiro Yamada sign_object(key, key_schedule, src, sig_dst, num_aes_blocks); 127*09f455dcSMasahiro Yamada debug("encrypt_and_sign: end signing\n"); 128*09f455dcSMasahiro Yamada } 129*09f455dcSMasahiro Yamada 130*09f455dcSMasahiro Yamada return 0; 131*09f455dcSMasahiro Yamada } 132*09f455dcSMasahiro Yamada 133*09f455dcSMasahiro Yamada int sign_data_block(u8 *source, unsigned length, u8 *signature) 134*09f455dcSMasahiro Yamada { 135*09f455dcSMasahiro Yamada return encrypt_and_sign(zero_key, SECURITY_SIGN, source, 136*09f455dcSMasahiro Yamada length, signature); 137*09f455dcSMasahiro Yamada } 138