2 * Helper functions for libgcrypt
3 * By Erik de Jong <erikdejong@gmail.com>
4 * Copyright 2017 Erik de Jong
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0+
15 gcry_error_t ws_hmac_buffer(int algo, void *digest, const void *buffer, size_t length, const void *key, size_t keylen)
17 gcry_md_hd_t hmac_handle;
18 gcry_error_t result = gcry_md_open(&hmac_handle, algo, GCRY_MD_FLAG_HMAC);
22 result = gcry_md_setkey(hmac_handle, key, keylen);
24 gcry_md_close(hmac_handle);
27 gcry_md_write(hmac_handle, buffer, length);
28 memcpy(digest, gcry_md_read(hmac_handle, 0), gcry_md_get_algo_dlen(algo));
29 gcry_md_close(hmac_handle);
30 return GPG_ERR_NO_ERROR;
33 void crypt_des_ecb(guint8 *output, const guint8 *buffer, const guint8 *key56)
36 gcry_cipher_hd_t handle;
38 memset(output, 0x00, 8);
40 /* Transform 56 bits key into 64 bits DES key */
42 key64[1] = (key56[0] << 7) | (key56[1] >> 1);
43 key64[2] = (key56[1] << 6) | (key56[2] >> 2);
44 key64[3] = (key56[2] << 5) | (key56[3] >> 3);
45 key64[4] = (key56[3] << 4) | (key56[4] >> 4);
46 key64[5] = (key56[4] << 3) | (key56[5] >> 5);
47 key64[6] = (key56[5] << 2) | (key56[6] >> 6);
48 key64[7] = (key56[6] << 1);
50 if (gcry_cipher_open(&handle, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0)) {
53 if (gcry_cipher_setkey(handle, key64, 8)) {
54 gcry_cipher_close(handle);
57 gcry_cipher_encrypt(handle, output, 8, buffer, 8);
58 gcry_cipher_close(handle);
61 size_t rsa_decrypt_inplace(const guint len, guchar* data, gcry_sexp_t pk, gboolean pkcs1_padding, char **err)
64 size_t decr_len = 0, i = 0;
65 gcry_sexp_t s_data = NULL, s_plain = NULL;
66 gcry_mpi_t encr_mpi = NULL, text = NULL;
70 /* create mpi representation of encrypted data */
71 rc = gcry_mpi_scan(&encr_mpi, GCRYMPI_FMT_USG, data, len, NULL);
73 *err = g_strdup_printf("can't convert data to mpi (size %d):%s", len, gcry_strerror(rc));
77 /* put the data into a simple list */
78 rc = gcry_sexp_build(&s_data, NULL, "(enc-val(rsa(a%m)))", encr_mpi);
80 *err = g_strdup_printf("can't build encr_sexp:%s", gcry_strerror(rc));
85 /* pass it to libgcrypt */
86 rc = gcry_pk_decrypt(&s_plain, s_data, pk);
89 *err = g_strdup_printf("can't decrypt key:%s", gcry_strerror(rc));
94 /* convert plain text sexp to mpi format */
95 text = gcry_sexp_nth_mpi(s_plain, 0, 0);
97 *err = g_strdup("can't convert sexp to mpi");
102 /* compute size requested for plaintext buffer */
103 rc = gcry_mpi_print(GCRYMPI_FMT_USG, NULL, 0, &decr_len, text);
105 *err = g_strdup_printf("can't compute decr size:%s", gcry_strerror(rc));
110 /* sanity check on out buffer */
111 if (decr_len > len) {
112 *err = g_strdup_printf("decrypted data is too long ?!? (%" G_GSIZE_MODIFIER "u max %d)", decr_len, len);
117 /* write plain text to newly allocated buffer */
118 rc = gcry_mpi_print(GCRYMPI_FMT_USG, data, len, &decr_len, text);
120 *err = g_strdup_printf("can't print decr data to mpi (size %" G_GSIZE_MODIFIER "u):%s", decr_len, gcry_strerror(rc));
126 /* strip the padding*/
128 for (i = 1; i < decr_len; i++) {
136 memmove(data, data+rc, decr_len);
140 gcry_sexp_release(s_data);
141 gcry_sexp_release(s_plain);
142 gcry_mpi_release(encr_mpi);
143 gcry_mpi_release(text);
148 * Editor modelines - http://www.wireshark.org/tools/modelines.html
153 * indent-tabs-mode: t
156 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
157 * :indentSize=8:tabSize=8:noTabs=false: