1fb7ef469SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */
21fca7e26SJens Wiklander /*
3b314df1fSJens Wiklander * Copyright (c) 2017-2020, Linaro Limited
41fca7e26SJens Wiklander *
51fca7e26SJens Wiklander */
61fca7e26SJens Wiklander
71fca7e26SJens Wiklander #ifndef __CRYPTO_INTERNAL_AES_GCM_H
81fca7e26SJens Wiklander #define __CRYPTO_INTERNAL_AES_GCM_H
91fca7e26SJens Wiklander
10d7fd8f87SJens Wiklander #include <assert.h>
111fca7e26SJens Wiklander #include <tee_api_types.h>
121fca7e26SJens Wiklander #include <utee_defines.h>
13d7fd8f87SJens Wiklander #include <util.h>
141fca7e26SJens Wiklander
15b314df1fSJens Wiklander #ifdef CFG_CRYPTO_WITH_CE
16b314df1fSJens Wiklander #include <crypto/ghash-ce-core.h>
17b314df1fSJens Wiklander #else
18b314df1fSJens Wiklander struct internal_ghash_key {
19b314df1fSJens Wiklander #ifdef CFG_AES_GCM_TABLE_BASED
20b314df1fSJens Wiklander uint64_t HL[16];
21b314df1fSJens Wiklander uint64_t HH[16];
22b314df1fSJens Wiklander #else
23b314df1fSJens Wiklander uint64_t hash_subkey[2];
24b314df1fSJens Wiklander #endif
25b314df1fSJens Wiklander };
26b314df1fSJens Wiklander #endif
27b314df1fSJens Wiklander
2854af8d67SJens Wiklander struct internal_aes_gcm_key {
2954af8d67SJens Wiklander /* AES (CTR) encryption key and number of rounds */
3054af8d67SJens Wiklander uint64_t data[30];
3154af8d67SJens Wiklander unsigned int rounds;
3254af8d67SJens Wiklander };
3354af8d67SJens Wiklander
3454af8d67SJens Wiklander struct internal_aes_gcm_state {
351fca7e26SJens Wiklander uint64_t ctr[2];
361fca7e26SJens Wiklander
37b314df1fSJens Wiklander struct internal_ghash_key ghash_key;
381fca7e26SJens Wiklander uint8_t hash_state[TEE_AES_BLOCK_SIZE];
391fca7e26SJens Wiklander
401fca7e26SJens Wiklander uint8_t buf_tag[TEE_AES_BLOCK_SIZE];
411fca7e26SJens Wiklander uint8_t buf_hash[TEE_AES_BLOCK_SIZE];
421fca7e26SJens Wiklander uint8_t buf_cryp[TEE_AES_BLOCK_SIZE];
431fca7e26SJens Wiklander
441fca7e26SJens Wiklander unsigned int tag_len;
451fca7e26SJens Wiklander unsigned int aad_bytes;
461fca7e26SJens Wiklander unsigned int payload_bytes;
471fca7e26SJens Wiklander unsigned int buf_pos;
481fca7e26SJens Wiklander };
491fca7e26SJens Wiklander
5054af8d67SJens Wiklander struct internal_aes_gcm_ctx {
5154af8d67SJens Wiklander struct internal_aes_gcm_state state;
5254af8d67SJens Wiklander struct internal_aes_gcm_key key;
5354af8d67SJens Wiklander };
5454af8d67SJens Wiklander
551fca7e26SJens Wiklander TEE_Result internal_aes_gcm_init(struct internal_aes_gcm_ctx *ctx,
561fca7e26SJens Wiklander TEE_OperationMode mode, const void *key,
571fca7e26SJens Wiklander size_t key_len, const void *nonce,
581fca7e26SJens Wiklander size_t nonce_len, size_t tag_len);
591fca7e26SJens Wiklander TEE_Result internal_aes_gcm_update_aad(struct internal_aes_gcm_ctx *ctx,
601fca7e26SJens Wiklander const void *data, size_t len);
611fca7e26SJens Wiklander TEE_Result internal_aes_gcm_update_payload(struct internal_aes_gcm_ctx *ctx,
621fca7e26SJens Wiklander TEE_OperationMode mode,
631fca7e26SJens Wiklander const void *src, size_t len,
641fca7e26SJens Wiklander void *dst);
651fca7e26SJens Wiklander TEE_Result internal_aes_gcm_enc_final(struct internal_aes_gcm_ctx *ctx,
661fca7e26SJens Wiklander const void *src, size_t len, void *dst,
671fca7e26SJens Wiklander void *tag, size_t *tag_len);
681fca7e26SJens Wiklander TEE_Result internal_aes_gcm_dec_final(struct internal_aes_gcm_ctx *ctx,
691fca7e26SJens Wiklander const void *src, size_t len, void *dst,
701fca7e26SJens Wiklander const void *tag, size_t tag_len);
711fca7e26SJens Wiklander
7254af8d67SJens Wiklander void internal_aes_gcm_inc_ctr(struct internal_aes_gcm_state *state);
738a15c688SJens Wiklander void internal_aes_gcm_dec_ctr(struct internal_aes_gcm_state *state);
7454af8d67SJens Wiklander
75043411e5SJens Wiklander TEE_Result internal_aes_gcm_enc(const struct internal_aes_gcm_key *enc_key,
76043411e5SJens Wiklander const void *nonce, size_t nonce_len,
77043411e5SJens Wiklander const void *aad, size_t aad_len,
78043411e5SJens Wiklander const void *src, size_t len, void *dst,
79043411e5SJens Wiklander void *tag, size_t *tag_len);
80043411e5SJens Wiklander
81043411e5SJens Wiklander TEE_Result internal_aes_gcm_dec(const struct internal_aes_gcm_key *enc_key,
82043411e5SJens Wiklander const void *nonce, size_t nonce_len,
83043411e5SJens Wiklander const void *aad, size_t aad_len,
84043411e5SJens Wiklander const void *src, size_t len, void *dst,
85043411e5SJens Wiklander const void *tag, size_t tag_len);
86043411e5SJens Wiklander
87b314df1fSJens Wiklander void internal_aes_gcm_gfmul(const uint64_t X[2], const uint64_t Y[2],
88b314df1fSJens Wiklander uint64_t product[2]);
89b314df1fSJens Wiklander
internal_aes_gcm_xor_block(void * dst,const void * src)90b314df1fSJens Wiklander static inline void internal_aes_gcm_xor_block(void *dst, const void *src)
91b314df1fSJens Wiklander {
92b314df1fSJens Wiklander uint64_t *d = dst;
93b314df1fSJens Wiklander const uint64_t *s = src;
94b314df1fSJens Wiklander
95*be501eb1SJorge Ramirez-Ortiz assert(IS_ALIGNED_WITH_TYPE(dst, uint64_t));
96*be501eb1SJorge Ramirez-Ortiz assert(IS_ALIGNED_WITH_TYPE(src, uint64_t));
97d7fd8f87SJens Wiklander
98b314df1fSJens Wiklander d[0] ^= s[0];
99b314df1fSJens Wiklander d[1] ^= s[1];
100b314df1fSJens Wiklander }
101b314df1fSJens Wiklander
internal_aes_gcm_ptr_is_block_aligned(const void * p)102b314df1fSJens Wiklander static inline bool internal_aes_gcm_ptr_is_block_aligned(const void *p)
103b314df1fSJens Wiklander {
104b314df1fSJens Wiklander return !((vaddr_t)p & (TEE_AES_BLOCK_SIZE - 1));
105b314df1fSJens Wiklander }
106b314df1fSJens Wiklander
107b314df1fSJens Wiklander #ifdef CFG_AES_GCM_TABLE_BASED
108b314df1fSJens Wiklander void internal_aes_gcm_ghash_gen_tbl(struct internal_ghash_key *ghash_key,
109b314df1fSJens Wiklander const struct internal_aes_gcm_key *enc_key);
110b314df1fSJens Wiklander void internal_aes_gcm_ghash_mult_tbl(struct internal_ghash_key *ghash_key,
111b314df1fSJens Wiklander const unsigned char x[16],
112b314df1fSJens Wiklander unsigned char output[16]);
113b314df1fSJens Wiklander #endif
114b314df1fSJens Wiklander
1151fca7e26SJens Wiklander /*
116b314df1fSJens Wiklander * Must be implemented in core/arch/arm/crypto/ if CFG_CRYPTO_WITH_CE=y
1171fca7e26SJens Wiklander */
11854af8d67SJens Wiklander void internal_aes_gcm_set_key(struct internal_aes_gcm_state *state,
11954af8d67SJens Wiklander const struct internal_aes_gcm_key *enc_key);
1201fca7e26SJens Wiklander
12154af8d67SJens Wiklander void internal_aes_gcm_ghash_update(struct internal_aes_gcm_state *state,
1221fca7e26SJens Wiklander const void *head, const void *data,
1231fca7e26SJens Wiklander size_t num_blocks);
124b314df1fSJens Wiklander /*
125b314df1fSJens Wiklander * Internal weak function that can be overridden with hardware specific
126b314df1fSJens Wiklander * implementation.
127b314df1fSJens Wiklander */
128d7fd8f87SJens Wiklander void
129d7fd8f87SJens Wiklander internal_aes_gcm_update_payload_blocks(struct internal_aes_gcm_state *state,
130d7fd8f87SJens Wiklander const struct internal_aes_gcm_key *ek,
13154af8d67SJens Wiklander TEE_OperationMode mode, const void *src,
1321fca7e26SJens Wiklander size_t num_blocks, void *dst);
13361b4cd9cSJens Wiklander
1341fca7e26SJens Wiklander #endif /*__CRYPTO_INTERNAL_AES_GCM_H*/
135