2019-07-31 19:55:16 +08:00
|
|
|
|
|
|
|
/*
|
2020-06-25 21:13:12 +08:00
|
|
|
* Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
2019-07-31 19:55:16 +08:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
|
|
* in the file LICENSE in the source distribution or at
|
|
|
|
* https://www.openssl.org/source/license.html
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <openssl/aes.h>
|
2019-12-04 02:41:05 +08:00
|
|
|
#include "ciphercommon_aead.h"
|
2019-07-31 19:55:16 +08:00
|
|
|
|
|
|
|
typedef struct prov_gcm_hw_st PROV_GCM_HW;
|
|
|
|
|
2019-09-05 09:23:57 +08:00
|
|
|
#define GCM_IV_DEFAULT_SIZE 12 /* IV's for AES_GCM should normally be 12 bytes */
|
2019-07-31 19:55:16 +08:00
|
|
|
#define GCM_IV_MAX_SIZE 64
|
|
|
|
#define GCM_TAG_MAX_SIZE 16
|
|
|
|
|
2019-08-20 06:54:41 +08:00
|
|
|
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
|
|
|
|
/*-
|
|
|
|
* KMA-GCM-AES parameter block - begin
|
|
|
|
* (see z/Architecture Principles of Operation >= SA22-7832-11)
|
|
|
|
*/
|
|
|
|
typedef struct S390X_kma_params_st {
|
|
|
|
unsigned char reserved[12];
|
|
|
|
union {
|
|
|
|
unsigned int w;
|
|
|
|
unsigned char b[4];
|
|
|
|
} cv; /* 32 bit counter value */
|
|
|
|
union {
|
|
|
|
unsigned long long g[2];
|
|
|
|
unsigned char b[16];
|
|
|
|
} t; /* tag */
|
|
|
|
unsigned char h[16]; /* hash subkey */
|
|
|
|
unsigned long long taadl; /* total AAD length */
|
|
|
|
unsigned long long tpcl; /* total plaintxt/ciphertxt len */
|
|
|
|
union {
|
|
|
|
unsigned long long g[2];
|
|
|
|
unsigned int w[4];
|
|
|
|
} j0; /* initial counter value */
|
|
|
|
unsigned char k[32]; /* key */
|
|
|
|
} S390X_KMA_PARAMS;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2019-07-31 19:55:16 +08:00
|
|
|
typedef struct prov_gcm_ctx_st {
|
2019-09-05 09:23:57 +08:00
|
|
|
unsigned int mode; /* The mode that we are using */
|
2019-07-31 19:55:16 +08:00
|
|
|
size_t keylen;
|
2019-09-05 09:23:57 +08:00
|
|
|
size_t ivlen;
|
2019-07-31 19:55:16 +08:00
|
|
|
size_t ivlen_min;
|
2019-09-05 09:23:57 +08:00
|
|
|
size_t taglen;
|
|
|
|
size_t tls_aad_pad_sz;
|
|
|
|
size_t tls_aad_len; /* TLS AAD length */
|
2019-07-31 19:55:16 +08:00
|
|
|
uint64_t tls_enc_records; /* Number of TLS records encrypted */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* num contains the number of bytes of |iv| which are valid for modes that
|
|
|
|
* manage partial blocks themselves.
|
|
|
|
*/
|
|
|
|
size_t num;
|
2019-09-05 09:23:57 +08:00
|
|
|
size_t bufsz; /* Number of bytes in buf */
|
2019-07-31 19:55:16 +08:00
|
|
|
uint64_t flags;
|
|
|
|
|
2019-09-05 09:23:57 +08:00
|
|
|
unsigned int iv_state; /* set to one of IV_STATE_XXX */
|
|
|
|
unsigned int enc:1; /* Set to 1 if we are encrypting or 0 otherwise */
|
|
|
|
unsigned int pad:1; /* Whether padding should be used or not */
|
|
|
|
unsigned int key_set:1; /* Set if key initialised */
|
|
|
|
unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */
|
|
|
|
unsigned int iv_gen:1; /* It is OK to generate IVs */
|
2019-07-31 19:55:16 +08:00
|
|
|
|
|
|
|
unsigned char iv[GCM_IV_MAX_SIZE]; /* Buffer to use for IV's */
|
2019-09-05 09:23:57 +08:00
|
|
|
unsigned char buf[AES_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */
|
2019-07-31 19:55:16 +08:00
|
|
|
|
|
|
|
OPENSSL_CTX *libctx; /* needed for rand calls */
|
|
|
|
const PROV_GCM_HW *hw; /* hardware specific methods */
|
|
|
|
GCM128_CONTEXT gcm;
|
|
|
|
ctr128_f ctr;
|
|
|
|
const void *ks;
|
|
|
|
} PROV_GCM_CTX;
|
|
|
|
|
2019-08-20 06:54:41 +08:00
|
|
|
PROV_CIPHER_FUNC(int, GCM_setkey, (PROV_GCM_CTX *ctx, const unsigned char *key,
|
2019-07-31 19:55:16 +08:00
|
|
|
size_t keylen));
|
2019-08-20 06:54:41 +08:00
|
|
|
PROV_CIPHER_FUNC(int, GCM_setiv, (PROV_GCM_CTX *dat, const unsigned char *iv,
|
2019-07-31 19:55:16 +08:00
|
|
|
size_t ivlen));
|
2019-08-20 06:54:41 +08:00
|
|
|
PROV_CIPHER_FUNC(int, GCM_aadupdate, (PROV_GCM_CTX *ctx,
|
2019-07-31 19:55:16 +08:00
|
|
|
const unsigned char *aad, size_t aadlen));
|
2019-08-20 06:54:41 +08:00
|
|
|
PROV_CIPHER_FUNC(int, GCM_cipherupdate, (PROV_GCM_CTX *ctx,
|
2019-07-31 19:55:16 +08:00
|
|
|
const unsigned char *in, size_t len,
|
|
|
|
unsigned char *out));
|
2019-08-20 06:54:41 +08:00
|
|
|
PROV_CIPHER_FUNC(int, GCM_cipherfinal, (PROV_GCM_CTX *ctx, unsigned char *tag));
|
|
|
|
PROV_CIPHER_FUNC(int, GCM_oneshot, (PROV_GCM_CTX *ctx, unsigned char *aad,
|
2019-07-31 19:55:16 +08:00
|
|
|
size_t aad_len, const unsigned char *in,
|
|
|
|
size_t in_len, unsigned char *out,
|
|
|
|
unsigned char *tag, size_t taglen));
|
|
|
|
struct prov_gcm_hw_st {
|
|
|
|
OSSL_GCM_setkey_fn setkey;
|
|
|
|
OSSL_GCM_setiv_fn setiv;
|
|
|
|
OSSL_GCM_aadupdate_fn aadupdate;
|
|
|
|
OSSL_GCM_cipherupdate_fn cipherupdate;
|
|
|
|
OSSL_GCM_cipherfinal_fn cipherfinal;
|
|
|
|
OSSL_GCM_oneshot_fn oneshot;
|
|
|
|
};
|
|
|
|
|
2020-06-21 07:19:16 +08:00
|
|
|
OSSL_FUNC_cipher_encrypt_init_fn gcm_einit;
|
|
|
|
OSSL_FUNC_cipher_decrypt_init_fn gcm_dinit;
|
|
|
|
OSSL_FUNC_cipher_get_ctx_params_fn gcm_get_ctx_params;
|
|
|
|
OSSL_FUNC_cipher_set_ctx_params_fn gcm_set_ctx_params;
|
|
|
|
OSSL_FUNC_cipher_cipher_fn gcm_cipher;
|
|
|
|
OSSL_FUNC_cipher_update_fn gcm_stream_update;
|
|
|
|
OSSL_FUNC_cipher_final_fn gcm_stream_final;
|
2019-08-22 09:42:54 +08:00
|
|
|
void gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits,
|
|
|
|
const PROV_GCM_HW *hw, size_t ivlen_min);
|
|
|
|
|
2019-08-26 15:05:08 +08:00
|
|
|
int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen);
|
|
|
|
int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad,
|
|
|
|
size_t aad_len);
|
|
|
|
int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag);
|
|
|
|
int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len,
|
|
|
|
const unsigned char *in, size_t in_len,
|
|
|
|
unsigned char *out, unsigned char *tag, size_t tag_len);
|
|
|
|
int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
|
|
|
|
size_t len, unsigned char *out);
|
|
|
|
|
2019-09-05 09:23:57 +08:00
|
|
|
#define GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \
|
2019-08-26 15:05:08 +08:00
|
|
|
ctx->ks = ks; \
|
|
|
|
fn_set_enc_key(key, keylen * 8, ks); \
|
|
|
|
CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block); \
|
|
|
|
ctx->ctr = (ctr128_f)fn_ctr; \
|
|
|
|
ctx->key_set = 1;
|