1 /*
2  * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <openssl/aes.h>
11 #include "prov/ciphercommon.h"
12 #include "crypto/aes_platform.h"
13 
14 #define BLOCK_SIZE 16
15 #define NONCE_SIZE 12
16 #define TAG_SIZE   16
17 
18 /* AAD manipulation macros */
19 #define UP16(x) (((x) + 15) & ~0x0F)
20 #define DOWN16(x) ((x) & ~0x0F)
21 #define REMAINDER16(x) ((x) & 0x0F)
22 #define IS16(x) (((x) & 0x0F) == 0)
23 
24 typedef struct prov_cipher_hw_aes_gcm_siv_st {
25     int (*initkey)(void *vctx);
26     int (*cipher)(void *vctx, unsigned char *out, const unsigned char *in,
27                   size_t len);
28     int (*dup_ctx)(void *vdst, void *vsrc);
29     void (*clean_ctx)(void *vctx);
30 } PROV_CIPHER_HW_AES_GCM_SIV;
31 
32 /* Arranged for alignment purposes */
33 typedef struct prov_aes_gcm_siv_ctx_st {
34     EVP_CIPHER_CTX *ecb_ctx;
35     const PROV_CIPHER_HW_AES_GCM_SIV *hw; /* maybe not used, yet? */
36     uint8_t *aad;            /* Allocated, rounded up to 16 bytes, from user */
37     OSSL_LIB_CTX *libctx;
38     OSSL_PROVIDER *provctx;
39     size_t aad_len;          /* actual AAD length */
40     size_t key_len;
41     uint8_t key_gen_key[32]; /* from user */
42     uint8_t msg_enc_key[32]; /* depends on key size */
43     uint8_t msg_auth_key[BLOCK_SIZE];
44     uint8_t tag[TAG_SIZE];          /* generated tag, given to user or compared to user */
45     uint8_t user_tag[TAG_SIZE];     /* from user */
46     uint8_t nonce[NONCE_SIZE];       /* from user */
47     u128 Htable[16];         /* Polyval calculations via ghash */
48     unsigned int enc : 1;    /* Set to 1 if we are encrypting or 0 otherwise */
49     unsigned int have_user_tag : 1;
50     unsigned int generated_tag : 1;
51     unsigned int used_enc : 1;
52     unsigned int used_dec : 1;
53     unsigned int speed : 1;
54 } PROV_AES_GCM_SIV_CTX;
55 
56 const PROV_CIPHER_HW_AES_GCM_SIV *ossl_prov_cipher_hw_aes_gcm_siv(size_t keybits);
57 
58 void ossl_polyval_ghash_init(u128 Htable[16], const uint64_t H[2]);
59 void ossl_polyval_ghash_hash(const u128 Htable[16], uint8_t *tag,  const uint8_t *inp, size_t len);
60 
61 /* Define GSWAP8/GSWAP4 - used for BOTH little and big endian architectures */
GSWAP4(uint32_t n)62 static ossl_inline uint32_t GSWAP4(uint32_t n)
63 {
64     return (((n & 0x000000FF) << 24)
65             | ((n & 0x0000FF00) << 8)
66             | ((n & 0x00FF0000) >> 8)
67             | ((n & 0xFF000000) >> 24));
68 }
GSWAP8(uint64_t n)69 static ossl_inline uint64_t GSWAP8(uint64_t n)
70 {
71     uint64_t result;
72 
73     result = GSWAP4(n & 0x0FFFFFFFF);
74     result <<= 32;
75     return result | GSWAP4(n >> 32);
76 }
77