-bringing copyright tags up to FSF standard
[oweals/gnunet.git] / src / util / crypto_mpi.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
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 #include "platform.h"
28 #include <gcrypt.h>
29 #include "gnunet_util_lib.h"
30
31
32 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
33
34 /**
35  * Log an error message at log-level 'level' that indicates
36  * a failure of the command 'cmd' with the message given
37  * by gcry_strerror(rc).
38  */
39 #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)
40
41
42 /**
43  * If target != size, move @a target bytes to the end of the size-sized
44  * buffer and zero out the first @a target - @a size bytes.
45  *
46  * @param buf original buffer
47  * @param size number of bytes in @a buf
48  * @param target target size of the buffer
49  */
50 static void
51 adjust (void *buf,
52         size_t size,
53         size_t target)
54 {
55   char *p = buf;
56
57   if (size < target)
58   {
59     memmove (&p[target - size], buf, size);
60     memset (buf, 0, target - size);
61   }
62 }
63
64
65 /**
66  * Output the given MPI value to the given buffer in
67  * network byte order.
68  * The MPI @a val may not be negative.
69  *
70  * @param buf where to output to
71  * @param size number of bytes in @a buf
72  * @param val value to write to @a buf
73  */
74 void
75 GNUNET_CRYPTO_mpi_print_unsigned (void *buf,
76                                   size_t size,
77                                   gcry_mpi_t val)
78 {
79   size_t rsize;
80
81   if (gcry_mpi_get_flag (val, GCRYMPI_FLAG_OPAQUE))
82   {
83     /* Store opaque MPIs left aligned into the buffer.  */
84     unsigned int nbits;
85     const void *p;
86
87     p = gcry_mpi_get_opaque (val, &nbits);
88     GNUNET_assert (p);
89     rsize = (nbits+7)/8;
90     if (rsize > size)
91       rsize = size;
92     memcpy (buf, p, rsize);
93     if (rsize < size)
94       memset (buf+rsize, 0, size - rsize);
95   }
96   else
97   {
98     /* Store regular MPIs as unsigned integers right aligned into
99        the buffer.  */
100     rsize = size;
101     GNUNET_assert (0 ==
102                    gcry_mpi_print (GCRYMPI_FMT_USG, buf, rsize, &rsize,
103                                    val));
104     adjust (buf, rsize, size);
105   }
106 }
107
108
109 /**
110  * Convert data buffer into MPI value.
111  * The buffer is interpreted as network
112  * byte order, unsigned integer.
113  *
114  * @param result where to store MPI value (allocated)
115  * @param data raw data (GCRYMPI_FMT_USG)
116  * @param size number of bytes in @a data
117  */
118 void
119 GNUNET_CRYPTO_mpi_scan_unsigned (gcry_mpi_t *result,
120                                  const void *data,
121                                  size_t size)
122 {
123   int rc;
124
125   if (0 != (rc = gcry_mpi_scan (result,
126                                 GCRYMPI_FMT_USG,
127                                 data, size, &size)))
128   {
129     LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
130     GNUNET_assert (0);
131   }
132 }
133
134 /* end of crypto_mpi.c */