UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
openssl_decrypt.c File Reference
#include "crypto/openssl_decrypt.h"
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include "crypto/crc.h"
#include "crypto/md5.h"
#include "crypto/openssl_encrypt.h"
#include "debug.h"
#include "lib_common.h"
#include "utils/macros.h"
Include dependency graph for openssl_decrypt.c:

Go to the source code of this file.

Classes

struct  openssl_decrypt
 

Macros

#define CHECK(action, errmsg)
 
#define GCM_TAG_LEN   16
 
#define MOD_NAME   "[decrypt] "
 

Functions

static int openssl_decrypt (struct openssl_decrypt *decrypt, const char *ciphertext, int ciphertext_len, const char *aad, int aad_len, char *plaintext, enum openssl_mode mode)
 
static void openssl_decrypt_destroy (struct openssl_decrypt *s)
 
static int openssl_decrypt_init (struct openssl_decrypt **state, const char *passphrase)
 
 REGISTER_MODULE (openssl_decrypt, &functions, LIBRARY_CLASS_UNDEFINED, OPENSSL_DECRYPT_ABI_VERSION)
 

Variables

static const struct openssl_decrypt_info functions
 

Macro Definition Documentation

◆ CHECK

#define CHECK ( action,
errmsg )
Value:
do { int rc = action; if (rc != 1) { log_msg(LOG_LEVEL_ERROR, MOD_NAME errmsg ": %s\n", ERR_error_string(ERR_get_error(), NULL)); return 0; } } while(0)
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define MOD_NAME

Definition at line 117 of file openssl_decrypt.c.

Referenced by openssl_decrypt().

◆ GCM_TAG_LEN

#define GCM_TAG_LEN   16

Definition at line 69 of file openssl_decrypt.c.

Referenced by openssl_decrypt().

◆ MOD_NAME

#define MOD_NAME   "[decrypt] "

Definition at line 70 of file openssl_decrypt.c.

Referenced by openssl_decrypt(), and openssl_decrypt_init().

Function Documentation

◆ openssl_decrypt()

static int openssl_decrypt ( struct openssl_decrypt * decrypt,
const char * ciphertext,
int ciphertext_len,
const char * aad,
int aad_len,
char * plaintext,
enum openssl_mode mode )
static

Definition at line 119 of file openssl_decrypt.c.

123{
124 const EVP_CIPHER *cipher = get_cipher(mode);
125 if (cipher == NULL) {
126 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Cipher %d not available!\n", (int) mode);
127 return 0;
128 }
129 uint32_t data_len;
130 memcpy(&data_len, ciphertext, sizeof(uint32_t));
131 assert ((size_t) ciphertext_len >= data_len + sizeof(uint32_t) + 16 + sizeof(uint32_t));
132 ciphertext += sizeof(uint32_t);
133 const unsigned char *iv = (const unsigned char *) ciphertext;
134 ciphertext += 16;
135 ciphertext_len -= 20;
136
137 CHECK(EVP_CipherInit(decrypt->ctx, cipher, decrypt->key_hash, iv, 0), "Unable to initialize cipher");
138 CHECK(EVP_CIPHER_CTX_ctrl(decrypt->ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL), "set IV len"); // default IV len is presumably 12 bytes
139
140 int out_len = 0;
141 if (mode == MODE_AES128_GCM) {
142 ciphertext_len -= GCM_TAG_LEN;
143 if (aad && aad_len > 0) {
144 if (!EVP_DecryptUpdate(decrypt->ctx, NULL, &out_len, (void *) aad, aad_len)) {
145 log_msg(LOG_LEVEL_ERROR, MOD_NAME "AAD processing: %s\n", ERR_error_string(ERR_get_error(), NULL));
146 }
147 }
148 }
149 CHECK(EVP_CipherUpdate(decrypt->ctx, (unsigned char *) plaintext, &out_len, (const unsigned char *) ciphertext, ciphertext_len), "EVP_CipherUpdate");
150 int total_len = out_len;
151 if (mode == MODE_AES128_GCM) {
152 CHECK(EVP_CIPHER_CTX_ctrl(decrypt->ctx, EVP_CTRL_GCM_SET_TAG, GCM_TAG_LEN, (void *) (ciphertext + ciphertext_len)), "GCM set tag");
153 }
154 CHECK(EVP_CipherFinal(decrypt->ctx, (unsigned char *) plaintext + out_len, &out_len), "EVP_CipherFinal");
155 total_len += out_len;
156
157 if (mode != MODE_AES128_GCM) {
158 uint32_t expected_crc = 0;
159 assert((size_t) total_len >= data_len + sizeof expected_crc);
160 memcpy(&expected_crc, plaintext + data_len, sizeof expected_crc);
161 uint32_t crc = crc32buf(aad, aad_len);
162 crc = crc32buf_with_oldcrc(plaintext, data_len, crc);
163 if (crc != expected_crc) {
164 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Warning: Packet dropped AES - wrong CRC!\n");
165 return 0;
166 }
167 }
168
169 return data_len;
170}
uint32_t crc32buf(const char *buf, size_t len)
Definition crc_32.c:176
uint32_t crc32buf_with_oldcrc(const char *buf, size_t len, uint32_t oldcrc)
Definition crc_32.c:162
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
#define GCM_TAG_LEN
#define CHECK(action, errmsg)
enum openssl_mode mode
const EVP_CIPHER *(* get_cipher)(void)
@ MODE_AES128_GCM
EVP_CIPHER_CTX * ctx
unsigned char key_hash[16]

References CHECK, crc32buf(), crc32buf_with_oldcrc(), openssl_decrypt::ctx, GCM_TAG_LEN, get_cipher, openssl_decrypt::key_hash, LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, log_msg(), MOD_NAME, mode, and MODE_AES128_GCM.

Here is the call graph for this function:

◆ openssl_decrypt_destroy()

static void openssl_decrypt_destroy ( struct openssl_decrypt * s)
static

Definition at line 108 of file openssl_decrypt.c.

109{
110 if(!s) {
111 return;
112 }
113 EVP_CIPHER_CTX_free(s->ctx);
114 free(s);
115}

References openssl_decrypt::ctx.

◆ openssl_decrypt_init()

static int openssl_decrypt_init ( struct openssl_decrypt ** state,
const char * passphrase )
static

Definition at line 81 of file openssl_decrypt.c.

83{
84 struct openssl_decrypt *s =
85 calloc(1, sizeof(struct openssl_decrypt));
86
87 char pass[STR_LEN];
88 snprintf_ch(pass, "%s", passphrase);
89 // used only by encrypt, drop option
90 if (strstr(pass, ":cipher=")) {
91 *strstr(pass, ":cipher=") = '\0';
92 }
93
94 MD5CTX context;
95
96 MD5Init(&context);
97 MD5Update(&context, (const unsigned char *) pass,
98 strlen(pass));
99 MD5Final(s->key_hash, &context);
100
101 s->ctx = EVP_CIPHER_CTX_new();
102 log_msg(LOG_LEVEL_INFO, MOD_NAME "Enabled stream decryption.\n");
103
104 *state = s;
105 return 0;
106}
void ** state
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
#define snprintf_ch(str,...)
shortcut for snprintf(var, sizeof var...), var must be a char array
Definition macros.h:101
@ STR_LEN
"standard" string length placeholder
Definition macros.h:134
void MD5Update(MD5CTX *context, const unsigned char *input, unsigned int inputLen)
Definition md5.c:249
void MD5Final(unsigned char digest[16], MD5CTX *context)
Definition md5.c:295
void MD5Init(MD5CTX *context)
Definition md5.c:229
Definition md5.h:34

References openssl_decrypt::ctx, openssl_decrypt::key_hash, LOG_LEVEL_INFO, log_msg(), MD5Final(), MD5Init(), MD5Update(), MOD_NAME, snprintf_ch, state, and STR_LEN.

Here is the call graph for this function:

◆ REGISTER_MODULE()

Variable Documentation

◆ functions

const struct openssl_decrypt_info functions
static
Initial value:
= {
}
static int openssl_decrypt(struct openssl_decrypt *decrypt, const char *ciphertext, int ciphertext_len, const char *aad, int aad_len, char *plaintext, enum openssl_mode mode)
static int openssl_decrypt_init(struct openssl_decrypt **state, const char *passphrase)
static void openssl_decrypt_destroy(struct openssl_decrypt *s)

Definition at line 172 of file openssl_decrypt.c.