File: gcrypt.c

package info (click to toggle)
cryptsetup 20050111-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 252 kB
  • ctags: 156
  • sloc: ansic: 1,305; sh: 675; makefile: 159
file content (101 lines) | stat: -rw-r--r-- 1,875 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <string.h>
#include <ctype.h>
#include <gcrypt.h>

#include "libcryptsetup.h"
#include "internal.h"

#define MAX_DIGESTS		64
#define GCRYPT_REQ_VERSION	"1.1.42"

static int gcrypt_hash(void *data, int size, char *key, const char *passphrase)
{
	gcry_md_hd_t md;
	int algo = (int)data;
	int len = gcry_md_get_algo_dlen(algo);
	int round, i;

	if (gcry_md_open(&md, algo, 0))
		return -1;

	for(round = 0; size; round++) {
		/* hack from hashalot to avoid null bytes in key */
		for(i = 0; i < round; i++)
			gcry_md_write(md, "A", 1);

		gcry_md_write(md, passphrase, strlen(passphrase));

		if (len > size)
			len = size;
		memcpy(key, gcry_md_read(md, algo), len);

		key += len;
		size -= len;
		if (size)
			gcry_md_reset(md);
	}

	gcry_md_close(md);
	return 0;
}

static struct hash_type *gcrypt_get_hashes(void)
{
	struct hash_type *hashes;
	int size = MAX_DIGESTS;
	int *list;
	int i;
	gcry_error_t r;

	if (!gcry_check_version(GCRYPT_REQ_VERSION))
		return NULL;

	list = (int *)malloc(sizeof(*list) * size);
	if (!list)
		return NULL;

	r = gcry_md_list(list, &size);
	if (r || !size) {
		free(list);
		return NULL;
	}

	hashes = malloc(sizeof(*hashes) * (size + 1));
	if (!hashes) {
		free(list);
		return NULL;
	}

	for(i = 0; i < size; i++) {
		char *p;

		hashes[i].name = strdup(gcry_md_algo_name(list[i]));
		for(p = (char *)hashes[i].name; *p; p++)
			*p = tolower(*p);
		hashes[i].private = (void *)list[i];
		hashes[i].fn = gcrypt_hash;
	}
	hashes[i].name = NULL;
	hashes[i].private = NULL;
	hashes[i].fn = NULL;

	free(list);

	return hashes;
}

static void gcrypt_free_hashes(struct hash_type *hashes)
{
	struct hash_type *hash;

	for(hash = hashes; hash->name; hash++)
		free(hash->name);

	free(hashes);
}

struct hash_backend hash_gcrypt_backend = {
	.name = "libgcrypt",
	.get_hashes = gcrypt_get_hashes,
	.free_hashes = gcrypt_free_hashes
};