first batch of license fixes (boring)
[oweals/gnunet.git] / src / util / crypto_mpi.c
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 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
16 /**
17  * @file util/crypto_mpi.c
18  * @brief Helper functions for libgcrypt MPIs
19  * @author Christian Grothoff
20  * @author Florian Dold
21  */
22 #include "platform.h"
23 #include <gcrypt.h>
24 #include "gnunet_crypto_lib.h"
25
26
27 #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-mpi", __VA_ARGS__)
28
29 /**
30  * Log an error message at log-level 'level' that indicates
31  * a failure of the command 'cmd' with the message given
32  * by gcry_strerror(rc).
33  */
34 #define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0)
35
36
37 /**
38  * If target != size, move @a target bytes to the end of the size-sized
39  * buffer and zero out the first @a target - @a size bytes.
40  *
41  * @param buf original buffer
42  * @param size number of bytes in @a buf
43  * @param target target size of the buffer
44  */
45 static void
46 adjust (void *buf,
47         size_t size,
48         size_t target)
49 {
50   char *p = buf;
51
52   if (size < target)
53   {
54     memmove (&p[target - size], buf, size);
55     memset (buf, 0, target - size);
56   }
57 }
58
59
60 /**
61  * Output the given MPI value to the given buffer in
62  * network byte order.
63  * The MPI @a val may not be negative.
64  *
65  * @param buf where to output to
66  * @param size number of bytes in @a buf
67  * @param val value to write to @a buf
68  */
69 void
70 GNUNET_CRYPTO_mpi_print_unsigned (void *buf,
71                                   size_t size,
72                                   gcry_mpi_t val)
73 {
74   size_t rsize;
75   int rc;
76
77   if (gcry_mpi_get_flag (val, GCRYMPI_FLAG_OPAQUE))
78   {
79     /* Store opaque MPIs left aligned into the buffer.  */
80     unsigned int nbits;
81     const void *p;
82
83     p = gcry_mpi_get_opaque (val, &nbits);
84     GNUNET_assert (p);
85     rsize = (nbits+7)/8;
86     if (rsize > size)
87       rsize = size;
88     GNUNET_memcpy (buf, p, rsize);
89     if (rsize < size)
90       memset (buf+rsize, 0, size - rsize);
91   }
92   else
93   {
94     /* Store regular MPIs as unsigned integers right aligned into
95        the buffer.  */
96     rsize = size;
97     if (0 !=
98         (rc = gcry_mpi_print (GCRYMPI_FMT_USG,
99                               buf,
100                               rsize, &rsize,
101                               val)))
102     {
103       LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
104                 "gcry_mpi_print",
105                 rc);
106       GNUNET_assert (0);
107     }
108     adjust (buf, rsize, size);
109   }
110 }
111
112
113 /**
114  * Convert data buffer into MPI value.
115  * The buffer is interpreted as network
116  * byte order, unsigned integer.
117  *
118  * @param result where to store MPI value (allocated)
119  * @param data raw data (GCRYMPI_FMT_USG)
120  * @param size number of bytes in @a data
121  */
122 void
123 GNUNET_CRYPTO_mpi_scan_unsigned (gcry_mpi_t *result,
124                                  const void *data,
125                                  size_t size)
126 {
127   int rc;
128
129   if (0 != (rc = gcry_mpi_scan (result,
130                                 GCRYMPI_FMT_USG,
131                                 data, size, &size)))
132   {
133     LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
134               "gcry_mpi_scan",
135               rc);
136     GNUNET_assert (0);
137   }
138 }
139
140 /* end of crypto_mpi.c */