1 |
|
---|
2 | /*
|
---|
3 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
|
---|
4 | *
|
---|
5 | * Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
6 | * this file except in compliance with the License. You can obtain a copy
|
---|
7 | * in the file LICENSE in the source distribution or at
|
---|
8 | * https://www.openssl.org/source/license.html
|
---|
9 | */
|
---|
10 |
|
---|
11 | #include <openssl/aes.h>
|
---|
12 | #include "ciphercommon_aead.h"
|
---|
13 |
|
---|
14 | typedef struct prov_gcm_hw_st PROV_GCM_HW;
|
---|
15 |
|
---|
16 | #define GCM_IV_DEFAULT_SIZE 12 /* IV's for AES_GCM should normally be 12 bytes */
|
---|
17 | #define GCM_IV_MAX_SIZE (1024 / 8)
|
---|
18 | #define GCM_TAG_MAX_SIZE 16
|
---|
19 |
|
---|
20 | #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
|
---|
21 | /*-
|
---|
22 | * KMA-GCM-AES parameter block - begin
|
---|
23 | * (see z/Architecture Principles of Operation >= SA22-7832-11)
|
---|
24 | */
|
---|
25 | typedef struct S390X_kma_params_st {
|
---|
26 | unsigned char reserved[12];
|
---|
27 | union {
|
---|
28 | unsigned int w;
|
---|
29 | unsigned char b[4];
|
---|
30 | } cv; /* 32 bit counter value */
|
---|
31 | union {
|
---|
32 | unsigned long long g[2];
|
---|
33 | unsigned char b[16];
|
---|
34 | } t; /* tag */
|
---|
35 | unsigned char h[16]; /* hash subkey */
|
---|
36 | unsigned long long taadl; /* total AAD length */
|
---|
37 | unsigned long long tpcl; /* total plaintxt/ciphertxt len */
|
---|
38 | union {
|
---|
39 | unsigned long long g[2];
|
---|
40 | unsigned int w[4];
|
---|
41 | } j0; /* initial counter value */
|
---|
42 | unsigned char k[32]; /* key */
|
---|
43 | } S390X_KMA_PARAMS;
|
---|
44 |
|
---|
45 | #endif
|
---|
46 |
|
---|
47 | typedef struct prov_gcm_ctx_st {
|
---|
48 | unsigned int mode; /* The mode that we are using */
|
---|
49 | size_t keylen;
|
---|
50 | size_t ivlen;
|
---|
51 | size_t taglen;
|
---|
52 | size_t tls_aad_pad_sz;
|
---|
53 | size_t tls_aad_len; /* TLS AAD length */
|
---|
54 | uint64_t tls_enc_records; /* Number of TLS records encrypted */
|
---|
55 |
|
---|
56 | /*
|
---|
57 | * num contains the number of bytes of |iv| which are valid for modes that
|
---|
58 | * manage partial blocks themselves.
|
---|
59 | */
|
---|
60 | size_t num;
|
---|
61 | size_t bufsz; /* Number of bytes in buf */
|
---|
62 | uint64_t flags;
|
---|
63 |
|
---|
64 | unsigned int iv_state; /* set to one of IV_STATE_XXX */
|
---|
65 | unsigned int enc:1; /* Set to 1 if we are encrypting or 0 otherwise */
|
---|
66 | unsigned int pad:1; /* Whether padding should be used or not */
|
---|
67 | unsigned int key_set:1; /* Set if key initialised */
|
---|
68 | unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */
|
---|
69 | unsigned int iv_gen:1; /* It is OK to generate IVs */
|
---|
70 |
|
---|
71 | unsigned char iv[GCM_IV_MAX_SIZE]; /* Buffer to use for IV's */
|
---|
72 | unsigned char buf[AES_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */
|
---|
73 |
|
---|
74 | OSSL_LIB_CTX *libctx; /* needed for rand calls */
|
---|
75 | const PROV_GCM_HW *hw; /* hardware specific methods */
|
---|
76 | GCM128_CONTEXT gcm;
|
---|
77 | ctr128_f ctr;
|
---|
78 | const void *ks;
|
---|
79 | } PROV_GCM_CTX;
|
---|
80 |
|
---|
81 | PROV_CIPHER_FUNC(int, GCM_setkey, (PROV_GCM_CTX *ctx, const unsigned char *key,
|
---|
82 | size_t keylen));
|
---|
83 | PROV_CIPHER_FUNC(int, GCM_setiv, (PROV_GCM_CTX *dat, const unsigned char *iv,
|
---|
84 | size_t ivlen));
|
---|
85 | PROV_CIPHER_FUNC(int, GCM_aadupdate, (PROV_GCM_CTX *ctx,
|
---|
86 | const unsigned char *aad, size_t aadlen));
|
---|
87 | PROV_CIPHER_FUNC(int, GCM_cipherupdate, (PROV_GCM_CTX *ctx,
|
---|
88 | const unsigned char *in, size_t len,
|
---|
89 | unsigned char *out));
|
---|
90 | PROV_CIPHER_FUNC(int, GCM_cipherfinal, (PROV_GCM_CTX *ctx, unsigned char *tag));
|
---|
91 | PROV_CIPHER_FUNC(int, GCM_oneshot, (PROV_GCM_CTX *ctx, unsigned char *aad,
|
---|
92 | size_t aad_len, const unsigned char *in,
|
---|
93 | size_t in_len, unsigned char *out,
|
---|
94 | unsigned char *tag, size_t taglen));
|
---|
95 | struct prov_gcm_hw_st {
|
---|
96 | OSSL_GCM_setkey_fn setkey;
|
---|
97 | OSSL_GCM_setiv_fn setiv;
|
---|
98 | OSSL_GCM_aadupdate_fn aadupdate;
|
---|
99 | OSSL_GCM_cipherupdate_fn cipherupdate;
|
---|
100 | OSSL_GCM_cipherfinal_fn cipherfinal;
|
---|
101 | OSSL_GCM_oneshot_fn oneshot;
|
---|
102 | };
|
---|
103 |
|
---|
104 | OSSL_FUNC_cipher_encrypt_init_fn ossl_gcm_einit;
|
---|
105 | OSSL_FUNC_cipher_decrypt_init_fn ossl_gcm_dinit;
|
---|
106 | OSSL_FUNC_cipher_get_ctx_params_fn ossl_gcm_get_ctx_params;
|
---|
107 | OSSL_FUNC_cipher_set_ctx_params_fn ossl_gcm_set_ctx_params;
|
---|
108 | OSSL_FUNC_cipher_cipher_fn ossl_gcm_cipher;
|
---|
109 | OSSL_FUNC_cipher_update_fn ossl_gcm_stream_update;
|
---|
110 | OSSL_FUNC_cipher_final_fn ossl_gcm_stream_final;
|
---|
111 | void ossl_gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits,
|
---|
112 | const PROV_GCM_HW *hw);
|
---|
113 |
|
---|
114 | int ossl_gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen);
|
---|
115 | int ossl_gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad,
|
---|
116 | size_t aad_len);
|
---|
117 | int ossl_gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag);
|
---|
118 | int ossl_gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len,
|
---|
119 | const unsigned char *in, size_t in_len,
|
---|
120 | unsigned char *out, unsigned char *tag, size_t tag_len);
|
---|
121 | int ossl_gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
|
---|
122 | size_t len, unsigned char *out);
|
---|
123 |
|
---|
124 | #define GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \
|
---|
125 | ctx->ks = ks; \
|
---|
126 | fn_set_enc_key(key, keylen * 8, ks); \
|
---|
127 | CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block); \
|
---|
128 | ctx->ctr = (ctr128_f)fn_ctr; \
|
---|
129 | ctx->key_set = 1;
|
---|