Home | History | Annotate | Line # | Download | only in prov
      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;
    130