Я работаю над проектом, использующим gmp для реализации базового обмена DH. В этом обмене есть две основные функции: одна для создания открытого ключа из закрытого ключа, а другая для генерации общего секрета с помощью закрытого ключа и открытого ключа.
Во время первой функции мои вызовы в gmp lib работают как положено. Во время второй функции мой вызов mpz_init_set_str либо вызывает ошибку сегмента, либо прерывает работу с сообщением
realloc (): неверный старый размер
Прервано (ядро сброшено)
или
malloc.c: 2868: mremap_chunk: Ошибка утверждения `((размер + смещение) & (GLRO (dl_pagesize) - 1)) == 0 '.
Строка, вызывающая это, дословно используется в первой функции, и я не могу понять, что вызывает это.
Ниже приведен пример программы, которая демонстрирует проблему при запуске на моем компьютере.
Я использую gcc (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) 7.4.0. и libgmp10 версия 2: 6.1.2 + dfsg-2
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "gmp.h"
#include "time.h"
#define SECRET_KEY_SIZE 64
#define PRIVATE_KEY_SIZE 512
#define DH_KEY_EXCHANGE_P "96C99B60C4F823707B47A848472345230C5B25103DC37412A701833E8FF5C567A53A41D0B37B10F0060D50F4131C57CF1FD11B6A6CB958F36B1E7D878A4C4BC7"
#define DH_KEY_EXCHANGE_G "2C900DF142E2B839E521725585A92DC0C45D6702A48004A917F74B73DB26391F20AEAE4C6797DD5ABFF0BFCAECB29554248233B5E6682CE1C73DD2148DED76C3"
#define BASE_HEX 16
#define BASE_RADIX 32
char intToCharBase32(int input)
{
char ret = 0;
if(input <= 9)
{
ret = '0' + input;
}
else if(input < 32)
{
ret = (input - 10) + 'A';
}
return ret;
}
void generateRandomKey(char *random_number_buffer, int len)
{
short int n;
srand(time(0));
for(int i=0; i<len; i++)
{
n = rand() % BASE_RADIX;
random_number_buffer[i] = intToCharBase32(n);
}
random_number_buffer[len] = '\0';
}
void calculateDHPublicKey(char *public_key, char *private_key)
{
mpz_t p;
mpz_t g;
mpz_t b;
mpz_t B;
mpz_init (B);
mpz_init_set_str (p, DH_KEY_EXCHANGE_P, BASE_HEX);
mpz_init_set_str (g, DH_KEY_EXCHANGE_G, BASE_HEX);
mpz_init_set_str (b, private_key, BASE_RADIX);
mpz_powm (B, g, b, p);
mpz_get_str(public_key, BASE_RADIX, B);
mpz_clear (p);
mpz_clear (g);
mpz_clear (b);
mpz_clear (B);
}
void calculateDHSharedSecret(unsigned char *dh_key_buffer, char *own_private_key, char *other_public_key)
{
mpz_t p;
mpz_t b;
mpz_t A;
mpz_t SS;
mpz_init (SS);
mpz_init_set_str (p, DH_KEY_EXCHANGE_P, BASE_HEX); // <--This line crashes
mpz_init_set_str (b, own_private_key, BASE_RADIX);
mpz_init_set_str (A, other_public_key, BASE_RADIX);
mpz_powm (SS, A, b, p);
size_t size = 0;
//todo: move this to the right place (add leading zeros as needed);
mpz_export(dh_key_buffer, &size, 1, -1, 0, 0, SS);
mpz_clear (p);
mpz_clear (b);
mpz_clear (A);
mpz_clear (SS);
}
int main (){
char* private_key = malloc(sizeof(char) * (PRIVATE_KEY_SIZE / BASE_RADIX + 2));
generateRandomKey(private_key, PRIVATE_KEY_SIZE / BASE_RADIX);
fprintf(stderr, "Private Key: %s\n", private_key);
//step 2: generate public key
char* public_key = malloc(sizeof(char) * (2048 / BASE_RADIX + 1));
calculateDHPublicKey(public_key, private_key);
//step 3: share the public key
fprintf(stderr, "Public Key: %s\n", public_key);
//step 4: Calculate shared secret
unsigned char* sharedSecret = malloc(sizeof(unsigned char) * SECRET_KEY_SIZE);
memset(sharedSecret, 0, SECRET_KEY_SIZE);
char* other_pk = "1";
//for debugging just use 1 as the other side of dh handshake
calculateDHSharedSecret(sharedSecret, private_key, other_pk);
//step 5: release resources
free(private_key);
free(public_key);
return 0;
}
Я попытался использовать mpz_init, а затем mpz_set_str вместо mpz_init_set_str, и функция все еще прерывается.
Мне удалось использовать mpz_init2 и предоставить начальный размер в качестве обходного пути, но позже в моем проекте я не буду знать требуемый размер и хотел бы избежать необходимости определять его как дополнительный шаг.
(Мне хорошо известно, что есть гораздо лучшие способы генерирования случайных ключей, и rand () криптографически небезопасен, но этот проект будет использоваться для демонстрации этого, а также других проблем безопасности, которые обычно встречаются)