1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * LibTomCrypt is a library that provides various cryptographic
4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * algorithms in a highly modular and flexible manner.
5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The library is free for all purposes without any express
7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * guarantee it works.
8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "tomcrypt.h"
12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @file base64_decode.c
15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Compliant base64 code donated by Wayne Scott (wscott@bitmover.com)
16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef BASE64
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic const unsigned char map[256] = {
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project255, 255, 255, 255 };
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   base64 decode a block of memory
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param in       The base64 data to decode
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param inlen    The length of the base64 data
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param out      [out] The destination of the binary decoded data
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param outlen   [in/out] The max size and resulting size of the decoded data
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @return CRYPT_OK if successful
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint base64_decode(const unsigned char *in,  unsigned long inlen,
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project                        unsigned char *out, unsigned long *outlen)
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   unsigned long t, x, y, z;
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   unsigned char c;
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   int           g;
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(in     != NULL);
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(out    != NULL);
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(outlen != NULL);
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   g = 3;
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   for (x = y = z = t = 0; x < inlen; x++) {
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       c = map[in[x]&0xFF];
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       if (c == 255) continue;
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       /* the final = symbols are read and used to trim the remaining bytes */
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       if (c == 254) {
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          c = 0;
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          /* prevent g < 0 which would potentially allow an overflow later */
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          if (--g < 0) {
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project             return CRYPT_INVALID_PACKET;
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          }
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       } else if (g != 3) {
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          /* we only allow = to be at the end */
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          return CRYPT_INVALID_PACKET;
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       }
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       t = (t<<6)|c;
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       if (++y == 4) {
83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          if (z + g > *outlen) {
84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project             return CRYPT_BUFFER_OVERFLOW;
85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          }
86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          out[z++] = (unsigned char)((t>>16)&255);
87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          if (g > 2) out[z++] = (unsigned char)(t&255);
89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          y = t = 0;
90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       }
91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if (y != 0) {
93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       return CRYPT_INVALID_PACKET;
94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   *outlen = z;
96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return CRYPT_OK;
97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_decode.c,v $ */
103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.4 $ */
104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/03/31 14:15:35 $ */
105