2

I am trying to understand what is going wrong while I compile my application ang got the following error:

security.cpp: In member function ‘void Crypt::load()’:
security.cpp:16:21: warning: ‘void OPENSSL_config(const char*)’ is deprecated [-Wdeprecated-declarations]
  OPENSSL_config(NULL);
                     ^
In file included from /usr/local/include/openssl/e_os2.h:13:0,
                 from /usr/local/include/openssl/bio.h:13,
                 from /usr/local/include/openssl/conf.h:13,
                 from security.h:5,
                 from security.cpp:1:
/usr/local/include/openssl/conf.h:91:25: note: declared here
 DEPRECATEDIN_1_1_0(void OPENSSL_config(const char *config_name))
                         ^
security.cpp: In member function ‘void Integrity::get_hmac(uint8_t*, int, uint8_t*, uint64_t)’:
security.cpp:112:11: error: aggregate ‘HMAC_CTX ctx’ has incomplete type and cannot be defined
  HMAC_CTX ctx;
           ^~~
security.cpp:115:2: error: ‘HMAC_CTX_init’ was not declared in this scope
  HMAC_CTX_init(&ctx);
  ^~~~~~~~~~~~~
security.cpp:115:2: note: suggested alternative: ‘HMAC_CTX_new’
  HMAC_CTX_init(&ctx);
  ^~~~~~~~~~~~~
  HMAC_CTX_new
security.cpp:119:2: error: ‘HMAC_CTX_cleanup’ was not declared in this scope
  HMAC_CTX_cleanup(&ctx);
  ^~~~~~~~~~~~~~~~
security.cpp:119:2: note: suggested alternative: ‘HMAC_CTX_get_md’
  HMAC_CTX_cleanup(&ctx);
  ^~~~~~~~~~~~~~~~
  HMAC_CTX_get_md
Makefile:25: recipe for target 'security.o' failed
make: *** [security.o] Error 1

Some code parts of my cpp files:

security.cpp:

Crypt g_crypt;
Integrity g_integrity;

Crypt::Crypt() {
        key = (uint8_t *)"01234567890123456789012345678901";
        iv = (uint8_t *)"01234567890123456";
        load();
}

void Crypt::load() {    
        ERR_load_crypto_strings();
        OpenSSL_add_all_algorithms();
        OPENSSL_config(NULL);
}

......
......
......
......
void Integrity::get_hmac(uint8_t *data, int data_len, uint8_t *hmac, uint64_t k_nas_int) {
        HMAC_CTX ctx;
        int res_len;

        HMAC_CTX_init(&ctx);
        HMAC_Init_ex(&ctx, key, strlen((const char*)key), EVP_sha1(), NULL);
        HMAC_Update(&ctx, data, data_len);
        HMAC_Final(&ctx, hmac, (unsigned int*)&res_len);
        HMAC_CTX_cleanup(&ctx);
}

security.h:

#ifndef SECURITY_H
#define SECURITY_H

/* (C) OPENSSL_config */
#include </usr/local/include/openssl/conf.h>

/* (C) EVP_* */
#include </usr/local/include/openssl/evp.h>

/* (C) ERR_* */
#include </usr/local/include/openssl/err.h>

/* (C) HMAC_* */
#include </usr/local/include/openssl/hmac.h>

#include "packet.h"
#include "utils.h"

#define HMAC_ON 1
#define ENC_ON 1

const int HMAC_LEN = 20;

class Crypt {
private:
        uint8_t *key;
        uint8_t *iv;

        void load();
        int enc_data(uint8_t*, int, uint8_t*, uint64_t);
        int dec_data(uint8_t*, int, uint8_t*, uint64_t);
        void handle_crypt_error();

public:
        Crypt();
        void enc(Packet&, uint64_t);
        void dec(Packet&, uint64_t);
        ~Crypt();
};

class Integrity {
private:
        uint8_t *key;

public:
        Integrity();
        void add_hmac(Packet&, uint64_t);
        void get_hmac(uint8_t*, int, uint8_t*, uint64_t);
        void rem_hmac(Packet&, uint8_t*);
        bool hmac_check(Packet&, uint64_t);
        bool cmp_hmacs(uint8_t*, uint8_t*);
        void print_hmac(uint8_t*);
        ~Integrity();
};

extern Crypt g_crypt;
extern Integrity g_integrity;
void encrypt_add_hmac(Packet &pkt);
void decrypt_remove_hmac(Packet &pkt);

Now I have seen that for OpenSSL version>1.1.0 there are some changes as suggested SHA256 HMAC using OpenSSL 1.1 not compiling but when I do that I get a DWARF error eventhough I do a

make clean

and then

make

By the way my Makefile (where it stops) looks like this

G++ = g++ -std=c++0x -std=c++11 -std=gnu++0x -ggdb -O3 -fpermissive -Wno-narrowing
security.o: packet.h security.cpp security.h utils.h
        $(G++) -c -o security.o security.cpp -lcrypto

I would appreciaty any suggested solution since I am stucked in that for two days

kr90
  • 23
  • 1
  • 3

1 Answers1

4

In recent versions of OpenSSL (as of 1.1.0, I think), a number of structures which were previously declared publicly have now become private and appear in the public header files as incomplete types only. In consequence, you cannot use them directly in your code (you can only use pointers).

So the way you generate your HMAC has changed slightly. It would also make more sense to declare res_len as an unsigned int to get rid of that ugly cast:

void Integrity::get_hmac(uint8_t *data, int data_len, uint8_t *hmac, uint64_t k_nas_int) {
        HMAC_CTX *ctx;
        unsigned int res_len;

        ctx = HMAC_CTX_new();
        HMAC_Init_ex(ctx, key, strlen((const char*)key), EVP_sha1(), NULL);
        HMAC_Update(ctx, data, data_len);
        HMAC_Final(ctx, hmac, &res_len);
        HMAC_CTX_free(ctx);
}

Documentation here.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • Welc. You will find similar changes in other OpenSSL functions. I don't know these off by heart but you will know what to do now, should a similar problem arise. – Paul Sanders Aug 04 '20 at 23:42