1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2017-2020, Linaro Limited 4 * 5 */ 6 7 #ifndef __CRYPTO_INTERNAL_AES_GCM_H 8 #define __CRYPTO_INTERNAL_AES_GCM_H 9 10 #include <tee_api_types.h> 11 #include <utee_defines.h> 12 13 #ifdef CFG_CRYPTO_WITH_CE 14 #include <crypto/ghash-ce-core.h> 15 #else 16 struct internal_ghash_key { 17 #ifdef CFG_AES_GCM_TABLE_BASED 18 uint64_t HL[16]; 19 uint64_t HH[16]; 20 #else 21 uint64_t hash_subkey[2]; 22 #endif 23 }; 24 #endif 25 26 struct internal_aes_gcm_key { 27 /* AES (CTR) encryption key and number of rounds */ 28 uint64_t data[30]; 29 unsigned int rounds; 30 }; 31 32 struct internal_aes_gcm_state { 33 uint64_t ctr[2]; 34 35 struct internal_ghash_key ghash_key; 36 uint8_t hash_state[TEE_AES_BLOCK_SIZE]; 37 38 uint8_t buf_tag[TEE_AES_BLOCK_SIZE]; 39 uint8_t buf_hash[TEE_AES_BLOCK_SIZE]; 40 uint8_t buf_cryp[TEE_AES_BLOCK_SIZE]; 41 42 unsigned int tag_len; 43 unsigned int aad_bytes; 44 unsigned int payload_bytes; 45 unsigned int buf_pos; 46 }; 47 48 struct internal_aes_gcm_ctx { 49 struct internal_aes_gcm_state state; 50 struct internal_aes_gcm_key key; 51 }; 52 53 TEE_Result internal_aes_gcm_init(struct internal_aes_gcm_ctx *ctx, 54 TEE_OperationMode mode, const void *key, 55 size_t key_len, const void *nonce, 56 size_t nonce_len, size_t tag_len); 57 TEE_Result internal_aes_gcm_update_aad(struct internal_aes_gcm_ctx *ctx, 58 const void *data, size_t len); 59 TEE_Result internal_aes_gcm_update_payload(struct internal_aes_gcm_ctx *ctx, 60 TEE_OperationMode mode, 61 const void *src, size_t len, 62 void *dst); 63 TEE_Result internal_aes_gcm_enc_final(struct internal_aes_gcm_ctx *ctx, 64 const void *src, size_t len, void *dst, 65 void *tag, size_t *tag_len); 66 TEE_Result internal_aes_gcm_dec_final(struct internal_aes_gcm_ctx *ctx, 67 const void *src, size_t len, void *dst, 68 const void *tag, size_t tag_len); 69 70 void internal_aes_gcm_inc_ctr(struct internal_aes_gcm_state *state); 71 72 TEE_Result internal_aes_gcm_enc(const struct internal_aes_gcm_key *enc_key, 73 const void *nonce, size_t nonce_len, 74 const void *aad, size_t aad_len, 75 const void *src, size_t len, void *dst, 76 void *tag, size_t *tag_len); 77 78 TEE_Result internal_aes_gcm_dec(const struct internal_aes_gcm_key *enc_key, 79 const void *nonce, size_t nonce_len, 80 const void *aad, size_t aad_len, 81 const void *src, size_t len, void *dst, 82 const void *tag, size_t tag_len); 83 84 TEE_Result 85 internal_aes_gcm_expand_enc_key(const void *key, size_t key_len, 86 struct internal_aes_gcm_key *enc_key); 87 88 void internal_aes_gcm_gfmul(const uint64_t X[2], const uint64_t Y[2], 89 uint64_t product[2]); 90 91 static inline void internal_aes_gcm_xor_block(void *dst, const void *src) 92 { 93 uint64_t *d = dst; 94 const uint64_t *s = src; 95 96 d[0] ^= s[0]; 97 d[1] ^= s[1]; 98 } 99 100 static inline bool internal_aes_gcm_ptr_is_block_aligned(const void *p) 101 { 102 return !((vaddr_t)p & (TEE_AES_BLOCK_SIZE - 1)); 103 } 104 105 #ifdef CFG_AES_GCM_TABLE_BASED 106 void internal_aes_gcm_ghash_gen_tbl(struct internal_ghash_key *ghash_key, 107 const struct internal_aes_gcm_key *enc_key); 108 void internal_aes_gcm_ghash_mult_tbl(struct internal_ghash_key *ghash_key, 109 const unsigned char x[16], 110 unsigned char output[16]); 111 #endif 112 113 /* 114 * Must be implemented in core/arch/arm/crypto/ if CFG_CRYPTO_WITH_CE=y 115 */ 116 void internal_aes_gcm_set_key(struct internal_aes_gcm_state *state, 117 const struct internal_aes_gcm_key *enc_key); 118 119 void internal_aes_gcm_ghash_update(struct internal_aes_gcm_state *state, 120 const void *head, const void *data, 121 size_t num_blocks); 122 void internal_aes_gcm_encrypt_block(const struct internal_aes_gcm_key *enc_key, 123 const void *src, void *dst); 124 125 /* 126 * Internal weak function that can be overridden with hardware specific 127 * implementation. 128 */ 129 void internal_aes_gcm_update_payload_block_aligned( 130 struct internal_aes_gcm_state *state, 131 const struct internal_aes_gcm_key *enc_key, 132 TEE_OperationMode mode, const void *src, 133 size_t num_blocks, void *dst); 134 135 #endif /*__CRYPTO_INTERNAL_AES_GCM_H*/ 136