aboutsummaryrefslogtreecommitdiff
path: root/src/lib/util/crypto_mpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/util/crypto_mpi.c')
-rw-r--r--src/lib/util/crypto_mpi.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/lib/util/crypto_mpi.c b/src/lib/util/crypto_mpi.c
new file mode 100644
index 000000000..06f2fd786
--- /dev/null
+++ b/src/lib/util/crypto_mpi.c
@@ -0,0 +1,178 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file util/crypto_mpi.c
23 * @brief Helper functions for libgcrypt MPIs
24 * @author Christian Grothoff
25 * @author Florian Dold
26 */
27
28#include "platform.h"
29#include <gcrypt.h>
30#include "gnunet_util_lib.h"
31
32
33#define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-mpi", __VA_ARGS__)
34
35/**
36 * Log an error message at log-level 'level' that indicates
37 * a failure of the command 'cmd' with the message given
38 * by gcry_strerror(rc).
39 */
40#define LOG_GCRY(level, cmd, rc) do { LOG (level, _ ( \
41 "`%s' failed at %s:%d with error: %s\n"), \
42 cmd, __FILE__, __LINE__, \
43 gcry_strerror (rc)); } while (0)
44
45
46/**
47 * If target != size, move @a target bytes to the end of the size-sized
48 * buffer and zero out the first @a target - @a size bytes.
49 *
50 * @param buf original buffer
51 * @param size number of bytes in @a buf
52 * @param target target size of the buffer
53 */
54static void
55adjust (void *buf,
56 size_t size,
57 size_t target)
58{
59 char *p = buf;
60
61 if (size < target)
62 {
63 memmove (&p[target - size], buf, size);
64 memset (buf, 0, target - size);
65 }
66}
67
68
69/**
70 * Output the given MPI value to the given buffer in
71 * network byte order.
72 * The MPI @a val may not be negative.
73 *
74 * @param buf where to output to
75 * @param size number of bytes in @a buf
76 * @param val value to write to @a buf
77 */
78void
79GNUNET_CRYPTO_mpi_print_unsigned (void *buf,
80 size_t size,
81 gcry_mpi_t val)
82{
83 size_t rsize;
84 int rc;
85
86 if (gcry_mpi_get_flag (val, GCRYMPI_FLAG_OPAQUE))
87 {
88 /* Store opaque MPIs left aligned into the buffer. */
89 unsigned int nbits;
90 const void *p;
91
92 p = gcry_mpi_get_opaque (val, &nbits);
93 GNUNET_assert (p);
94 rsize = (nbits + 7) / 8;
95 if (rsize > size)
96 rsize = size;
97 GNUNET_memcpy (buf, p, rsize);
98 if (rsize < size)
99 memset (buf + rsize, 0, size - rsize);
100 }
101 else
102 {
103 /* Store regular MPIs as unsigned integers right aligned into
104 the buffer. */
105 rsize = size;
106 if (0 !=
107 (rc = gcry_mpi_print (GCRYMPI_FMT_USG,
108 buf,
109 rsize, &rsize,
110 val)))
111 {
112 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
113 "gcry_mpi_print",
114 rc);
115 GNUNET_assert (0);
116 }
117 adjust (buf, rsize, size);
118 }
119}
120
121
122/**
123 * Convert data buffer into MPI value.
124 * The buffer is interpreted as network
125 * byte order, unsigned integer.
126 *
127 * @param result where to store MPI value (allocated)
128 * @param data raw data (GCRYMPI_FMT_USG)
129 * @param size number of bytes in @a data
130 */
131void
132GNUNET_CRYPTO_mpi_scan_unsigned (gcry_mpi_t *result,
133 const void *data,
134 size_t size)
135{
136 int rc;
137
138 if (0 != (rc = gcry_mpi_scan (result,
139 GCRYMPI_FMT_USG,
140 data, size, &size)))
141 {
142 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
143 "gcry_mpi_scan",
144 rc);
145 GNUNET_assert (0);
146 }
147}
148
149
150/**
151 * Convert little endian data buffer into MPI value.
152 * The buffer is interpreted as network
153 * byte order, unsigned integer.
154 *
155 * @param result where to store MPI value (allocated)
156 * @param data raw data (GCRYMPI_FMT_USG)
157 * @param size number of bytes in @a data
158 */
159void
160GNUNET_CRYPTO_mpi_scan_unsigned_le (gcry_mpi_t *result,
161 const void *data,
162 size_t size)
163{
164 int rc;
165
166 if (0 != (rc = gcry_mpi_scan (result,
167 GCRYMPI_FMT_USG,
168 data, size, &size)))
169 {
170 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
171 "gcry_mpi_scan",
172 rc);
173 GNUNET_assert (0);
174 }
175}
176
177
178/* end of crypto_mpi.c */