New files.
authorNiels Möller <nisse@lysator.liu.se>
Wed, 30 Oct 2002 20:43:29 +0000 (21:43 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Wed, 30 Oct 2002 20:43:29 +0000 (21:43 +0100)
Rev: src/nettle/base16-decode.c:1.1
Rev: src/nettle/base16-encode.c:1.1
Rev: src/nettle/base16-meta.c:1.1
Rev: src/nettle/base16.h:1.1

base16-decode.c [new file with mode: 0644]
base16-encode.c [new file with mode: 0644]
base16-meta.c [new file with mode: 0644]
base16.h [new file with mode: 0644]

diff --git a/base16-decode.c b/base16-decode.c
new file mode 100644 (file)
index 0000000..a5e6185
--- /dev/null
@@ -0,0 +1,127 @@
+/* base16-encode.c
+ *
+ * Hex decoding.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#include "base16.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+void
+base16_decode_init(struct base16_decode_ctx *ctx)
+{
+  ctx->word = ctx->bits = 0;
+}
+
+enum { HEX_INVALID = -1, HEX_SPACE=-2 };
+
+static const signed char
+hex_decode_table[0x80] =
+  {
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -1, -1, -2, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
+    -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  };
+
+/* Decodes a single byte. Returns amount of output (0 or 1), or -1 on
+ * errors. */
+int
+base16_decode_single(struct base16_decode_ctx *ctx,
+                    uint8_t *dst,
+                    uint8_t src)
+{
+  int digit;
+
+  if (src >= 0x80)
+    return -1;
+
+  /* FIXME: This code could use more clever choices of constants. */
+  digit = hex_decode_table[src];
+  switch (digit)
+    {
+    case -1:
+      return -1;
+    case -2:
+      return 0;
+    default:
+      assert(digit >= 0);
+      assert(digit < 0x10);
+
+      if (ctx->bits)
+       {
+         *dst = (ctx->word << 4) | digit;
+         ctx->bits = 0;
+         return 1;
+       }
+      else
+       {
+         ctx->word = digit;
+         ctx->bits = 4;
+         return 0;
+       }
+    }
+}
+
+int
+base16_decode_update(struct base16_decode_ctx *ctx,
+                    unsigned *dst_length,
+                    uint8_t *dst,
+                    unsigned src_length,
+                    const uint8_t *src)
+{
+  unsigned done;
+  unsigned i;
+
+  assert(*dst_length >= BASE16_DECODE_LENGTH(src_length));
+  
+  for (i = 0, done = 0; i<src_length; i++)
+    switch(base16_decode_single(ctx, dst + done, src[i]))
+      {
+      case -1:
+       return 0;
+      case 1:
+       done++;
+       /* Fall through */
+      case 0:
+       break;
+      default:
+       abort();
+      }
+  
+  assert(done <= BASE16_DECODE_LENGTH(src_length));
+
+  *dst_length = done;
+  return 1;
+}
+
+int
+base16_decode_final(struct base16_decode_ctx *ctx)
+{
+  return ctx->bits == 0;
+}
diff --git a/base16-encode.c b/base16-encode.c
new file mode 100644 (file)
index 0000000..48ce300
--- /dev/null
@@ -0,0 +1,54 @@
+/* base16-encode.c
+ *
+ * Hex encoding.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#include "base16.h"
+
+
+static const uint8_t
+hex_digits[16] = "0123456789abcdef";
+
+#define DIGIT(x) (hex_digits[(x) & 0xf])
+
+/* FIXME: Is this really needed? */
+/* Encodes a single byte. Always stores two digits in dst[0] and dst[1]. */
+void
+base16_encode_single(uint8_t *dst,
+                    uint8_t src)
+{
+  dst[0] = DIGIT(src/0x10);
+  dst[1] = DIGIT(src);
+}
+
+/* Always stores BASE16_ENCODE_LENGTH(length) digits in dst. */
+void
+base16_encode_update(uint8_t *dst,
+                    unsigned length,
+                    const uint8_t *src)
+{
+  unsigned i;
+  
+  for (i = 0, dst; i<length; i++, dst += 2)
+    base16_encode_single(dst, src[i]);
+}
diff --git a/base16-meta.c b/base16-meta.c
new file mode 100644 (file)
index 0000000..ebfb7e2
--- /dev/null
@@ -0,0 +1,64 @@
+/* base16-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#include "nettle-meta.h"
+
+#include "base16.h"
+
+/* Same as the macros with the same name */
+static unsigned
+base16_encode_length(unsigned length)
+{
+  return BASE16_ENCODE_LENGTH(length);
+}
+
+static unsigned
+base16_decode_length(unsigned length)
+{
+  return BASE16_DECODE_LENGTH(length);
+}
+
+static void
+base16_encode_init(void *ctx)
+{ (void) ctx; }
+
+static unsigned
+base16_encode_update_wrapper(void *ctx, uint8_t *dst,
+                            unsigned length, const uint8_t *src)
+{
+  (void) ctx;
+  
+  base16_encode_update(dst, length, src);
+  return BASE16_ENCODE_LENGTH(length);
+}
+
+#define base16_encode_update base16_encode_update_wrapper
+
+static unsigned
+base16_encode_final(void *ctx, uint8_t *dst)
+{ (void) ctx; (void) dst; return 0; }
+
+
+#define BASE16_ENCODE_FINAL_LENGTH 0
+
+const struct nettle_armor nettle_base16
+= _NETTLE_ARMOR_0(base16, BASE16);
diff --git a/base16.h b/base16.h
new file mode 100644 (file)
index 0000000..b00bc86
--- /dev/null
+++ b/base16.h
@@ -0,0 +1,91 @@
+/* base16.h
+ *
+ * Hex encoding and decoding, following spki conventions (i.e.
+ * allowing whitespace between digits).
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2002 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+#ifndef NETTLE_BASE16_H_INCLUDED
+#define NETTLE_BASE16_H_INCLUDED
+
+#include <inttypes.h>
+
+
+/* Base16 encoding */
+
+/* Maximum length of output for base16_encode_update. */
+#define BASE16_ENCODE_LENGTH(length) ((length) * 2)
+
+/* Encodes a single byte. Always stores two digits in dst[0] and dst[1]. */
+void
+base16_encode_single(uint8_t *dst,
+                    uint8_t src);
+
+/* Always stores BASE16_ENCODE_LENGTH(length) digits in dst. */
+void
+base16_encode_update(uint8_t *dst,
+                    unsigned length,
+                    const uint8_t *src);
+
+
+/* Base16 decoding */
+
+/* Maximum length of output for base16_decode_update. */
+/* We have at most 4 buffered bits, and a total of (length + 1) * 4 bits. */
+#define BASE16_DECODE_LENGTH(length) (((length) + 1) / 2)
+
+struct base16_decode_ctx
+{
+  unsigned word;   /* Leftover bits */
+  unsigned bits;   /* Number buffered bits */
+};
+
+void
+base16_decode_init(struct base16_decode_ctx *ctx);
+
+/* Decodes a single byte. Returns amount of output (0 or 1), or -1 on
+ * errors. */
+int
+base16_decode_single(struct base16_decode_ctx *ctx,
+                    uint8_t *dst,
+                    uint8_t src);
+
+/* Returns 1 on success, 0 on error. DST should point to an area of
+ * size at least BASE16_DECODE_LENGTH(length), and for sanity
+ * checking, *DST_LENGTH should be initialized to the size of that
+ * area before the call. *DST_LENGTH is updated to the amount of
+ * decoded output. */
+
+/* FIXME: Currently results in an assertion failure if *DST_LENGTH is
+ * too small. Return some error instead? */
+int
+base16_decode_update(struct base16_decode_ctx *ctx,
+                    unsigned *dst_length,
+                    uint8_t *dst,
+                    unsigned src_length,
+                    const uint8_t *src);
+
+/* Returns 1 on success. */
+int
+base16_decode_final(struct base16_decode_ctx *ctx);
+
+#endif /* NETTLE_BASE16_H_INCLUDED */