cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Committer:
ashleymills
Date:
Fri Apr 26 16:54:58 2013 +0000
Revision:
0:e979170e02e7
Basic operation of SSL with PSK working for cellular.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:e979170e02e7 1 /* coding.c
ashleymills 0:e979170e02e7 2 *
ashleymills 0:e979170e02e7 3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
ashleymills 0:e979170e02e7 4 *
ashleymills 0:e979170e02e7 5 * This file is part of CyaSSL.
ashleymills 0:e979170e02e7 6 *
ashleymills 0:e979170e02e7 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:e979170e02e7 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:e979170e02e7 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:e979170e02e7 10 * (at your option) any later version.
ashleymills 0:e979170e02e7 11 *
ashleymills 0:e979170e02e7 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:e979170e02e7 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:e979170e02e7 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:e979170e02e7 15 * GNU General Public License for more details.
ashleymills 0:e979170e02e7 16 *
ashleymills 0:e979170e02e7 17 * You should have received a copy of the GNU General Public License
ashleymills 0:e979170e02e7 18 * along with this program; if not, write to the Free Software
ashleymills 0:e979170e02e7 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:e979170e02e7 20 */
ashleymills 0:e979170e02e7 21
ashleymills 0:e979170e02e7 22 #ifdef HAVE_CONFIG_H
ashleymills 0:e979170e02e7 23 #include <config.h>
ashleymills 0:e979170e02e7 24 #endif
ashleymills 0:e979170e02e7 25
ashleymills 0:e979170e02e7 26 #include <cyassl/ctaocrypt/coding.h>
ashleymills 0:e979170e02e7 27 #include <cyassl/ctaocrypt/error.h>
ashleymills 0:e979170e02e7 28 #include <cyassl/ctaocrypt/logging.h>
ashleymills 0:e979170e02e7 29
ashleymills 0:e979170e02e7 30
ashleymills 0:e979170e02e7 31 enum {
ashleymills 0:e979170e02e7 32 BAD = 0xFF, /* invalid encoding */
ashleymills 0:e979170e02e7 33 PAD = '=',
ashleymills 0:e979170e02e7 34 PEM_LINE_SZ = 64
ashleymills 0:e979170e02e7 35 };
ashleymills 0:e979170e02e7 36
ashleymills 0:e979170e02e7 37
ashleymills 0:e979170e02e7 38 static
ashleymills 0:e979170e02e7 39 const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */
ashleymills 0:e979170e02e7 40 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
ashleymills 0:e979170e02e7 41 BAD, BAD, BAD, BAD, BAD, BAD, BAD,
ashleymills 0:e979170e02e7 42 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
ashleymills 0:e979170e02e7 43 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
ashleymills 0:e979170e02e7 44 20, 21, 22, 23, 24, 25,
ashleymills 0:e979170e02e7 45 BAD, BAD, BAD, BAD, BAD, BAD,
ashleymills 0:e979170e02e7 46 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
ashleymills 0:e979170e02e7 47 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
ashleymills 0:e979170e02e7 48 46, 47, 48, 49, 50, 51
ashleymills 0:e979170e02e7 49 };
ashleymills 0:e979170e02e7 50
ashleymills 0:e979170e02e7 51
ashleymills 0:e979170e02e7 52 int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
ashleymills 0:e979170e02e7 53 {
ashleymills 0:e979170e02e7 54 word32 i = 0;
ashleymills 0:e979170e02e7 55 word32 j = 0;
ashleymills 0:e979170e02e7 56 word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ );
ashleymills 0:e979170e02e7 57 const byte maxIdx = (byte)sizeof(base64Decode) + 0x2B - 1;
ashleymills 0:e979170e02e7 58
ashleymills 0:e979170e02e7 59 plainSz = (plainSz * 3 + 3) / 4;
ashleymills 0:e979170e02e7 60 if (plainSz > *outLen) return BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 61
ashleymills 0:e979170e02e7 62 while (inLen > 3) {
ashleymills 0:e979170e02e7 63 byte b1, b2, b3;
ashleymills 0:e979170e02e7 64 byte e1 = in[j++];
ashleymills 0:e979170e02e7 65 byte e2 = in[j++];
ashleymills 0:e979170e02e7 66 byte e3 = in[j++];
ashleymills 0:e979170e02e7 67 byte e4 = in[j++];
ashleymills 0:e979170e02e7 68
ashleymills 0:e979170e02e7 69 int pad3 = 0;
ashleymills 0:e979170e02e7 70 int pad4 = 0;
ashleymills 0:e979170e02e7 71
ashleymills 0:e979170e02e7 72 if (e1 == 0) /* end file 0's */
ashleymills 0:e979170e02e7 73 break;
ashleymills 0:e979170e02e7 74 if (e3 == PAD)
ashleymills 0:e979170e02e7 75 pad3 = 1;
ashleymills 0:e979170e02e7 76 if (e4 == PAD)
ashleymills 0:e979170e02e7 77 pad4 = 1;
ashleymills 0:e979170e02e7 78
ashleymills 0:e979170e02e7 79 if (e1 < 0x2B || e2 < 0x2B || e3 < 0x2B || e4 < 0x2B) {
ashleymills 0:e979170e02e7 80 CYASSL_MSG("Bad Base64 Decode data, too small");
ashleymills 0:e979170e02e7 81 return ASN_INPUT_E;
ashleymills 0:e979170e02e7 82 }
ashleymills 0:e979170e02e7 83
ashleymills 0:e979170e02e7 84 if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) {
ashleymills 0:e979170e02e7 85 CYASSL_MSG("Bad Base64 Decode data, too big");
ashleymills 0:e979170e02e7 86 return ASN_INPUT_E;
ashleymills 0:e979170e02e7 87 }
ashleymills 0:e979170e02e7 88
ashleymills 0:e979170e02e7 89 e1 = base64Decode[e1 - 0x2B];
ashleymills 0:e979170e02e7 90 e2 = base64Decode[e2 - 0x2B];
ashleymills 0:e979170e02e7 91 e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B];
ashleymills 0:e979170e02e7 92 e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B];
ashleymills 0:e979170e02e7 93
ashleymills 0:e979170e02e7 94 b1 = (e1 << 2) | (e2 >> 4);
ashleymills 0:e979170e02e7 95 b2 = ((e2 & 0xF) << 4) | (e3 >> 2);
ashleymills 0:e979170e02e7 96 b3 = ((e3 & 0x3) << 6) | e4;
ashleymills 0:e979170e02e7 97
ashleymills 0:e979170e02e7 98 out[i++] = b1;
ashleymills 0:e979170e02e7 99 if (!pad3)
ashleymills 0:e979170e02e7 100 out[i++] = b2;
ashleymills 0:e979170e02e7 101 if (!pad4)
ashleymills 0:e979170e02e7 102 out[i++] = b3;
ashleymills 0:e979170e02e7 103 else
ashleymills 0:e979170e02e7 104 break;
ashleymills 0:e979170e02e7 105
ashleymills 0:e979170e02e7 106 inLen -= 4;
ashleymills 0:e979170e02e7 107 if (in[j] == ' ' || in[j] == '\r' || in[j] == '\n') {
ashleymills 0:e979170e02e7 108 byte endLine = in[j++];
ashleymills 0:e979170e02e7 109 inLen--;
ashleymills 0:e979170e02e7 110 while (endLine == ' ') { /* allow trailing whitespace */
ashleymills 0:e979170e02e7 111 endLine = in[j++];
ashleymills 0:e979170e02e7 112 inLen--;
ashleymills 0:e979170e02e7 113 }
ashleymills 0:e979170e02e7 114 if (endLine == '\r') {
ashleymills 0:e979170e02e7 115 endLine = in[j++];
ashleymills 0:e979170e02e7 116 inLen--;
ashleymills 0:e979170e02e7 117 }
ashleymills 0:e979170e02e7 118 if (endLine != '\n') {
ashleymills 0:e979170e02e7 119 CYASSL_MSG("Bad end of line in Base64 Decode");
ashleymills 0:e979170e02e7 120 return ASN_INPUT_E;
ashleymills 0:e979170e02e7 121 }
ashleymills 0:e979170e02e7 122 }
ashleymills 0:e979170e02e7 123 }
ashleymills 0:e979170e02e7 124 *outLen = i;
ashleymills 0:e979170e02e7 125
ashleymills 0:e979170e02e7 126 return 0;
ashleymills 0:e979170e02e7 127 }
ashleymills 0:e979170e02e7 128
ashleymills 0:e979170e02e7 129
ashleymills 0:e979170e02e7 130 #if defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER)
ashleymills 0:e979170e02e7 131
ashleymills 0:e979170e02e7 132 static
ashleymills 0:e979170e02e7 133 const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
ashleymills 0:e979170e02e7 134 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
ashleymills 0:e979170e02e7 135 'U', 'V', 'W', 'X', 'Y', 'Z',
ashleymills 0:e979170e02e7 136 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
ashleymills 0:e979170e02e7 137 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
ashleymills 0:e979170e02e7 138 'u', 'v', 'w', 'x', 'y', 'z',
ashleymills 0:e979170e02e7 139 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
ashleymills 0:e979170e02e7 140 '+', '/'
ashleymills 0:e979170e02e7 141 };
ashleymills 0:e979170e02e7 142
ashleymills 0:e979170e02e7 143
ashleymills 0:e979170e02e7 144 /* porting assistance from yaSSL by Raphael HUCK */
ashleymills 0:e979170e02e7 145 int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
ashleymills 0:e979170e02e7 146 {
ashleymills 0:e979170e02e7 147 word32 i = 0,
ashleymills 0:e979170e02e7 148 j = 0,
ashleymills 0:e979170e02e7 149 n = 0; /* new line counter */
ashleymills 0:e979170e02e7 150
ashleymills 0:e979170e02e7 151 word32 outSz = (inLen + 3 - 1) / 3 * 4;
ashleymills 0:e979170e02e7 152 outSz += (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */
ashleymills 0:e979170e02e7 153
ashleymills 0:e979170e02e7 154 if (outSz > *outLen) return BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 155
ashleymills 0:e979170e02e7 156 while (inLen > 2) {
ashleymills 0:e979170e02e7 157 byte b1 = in[j++];
ashleymills 0:e979170e02e7 158 byte b2 = in[j++];
ashleymills 0:e979170e02e7 159 byte b3 = in[j++];
ashleymills 0:e979170e02e7 160
ashleymills 0:e979170e02e7 161 /* encoded idx */
ashleymills 0:e979170e02e7 162 byte e1 = b1 >> 2;
ashleymills 0:e979170e02e7 163 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
ashleymills 0:e979170e02e7 164 byte e3 = ((b2 & 0xF) << 2) | (b3 >> 6);
ashleymills 0:e979170e02e7 165 byte e4 = b3 & 0x3F;
ashleymills 0:e979170e02e7 166
ashleymills 0:e979170e02e7 167 /* store */
ashleymills 0:e979170e02e7 168 out[i++] = base64Encode[e1];
ashleymills 0:e979170e02e7 169 out[i++] = base64Encode[e2];
ashleymills 0:e979170e02e7 170 out[i++] = base64Encode[e3];
ashleymills 0:e979170e02e7 171 out[i++] = base64Encode[e4];
ashleymills 0:e979170e02e7 172
ashleymills 0:e979170e02e7 173 inLen -= 3;
ashleymills 0:e979170e02e7 174
ashleymills 0:e979170e02e7 175 if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen)
ashleymills 0:e979170e02e7 176 out[i++] = '\n';
ashleymills 0:e979170e02e7 177 }
ashleymills 0:e979170e02e7 178
ashleymills 0:e979170e02e7 179 /* last integral */
ashleymills 0:e979170e02e7 180 if (inLen) {
ashleymills 0:e979170e02e7 181 int twoBytes = (inLen == 2);
ashleymills 0:e979170e02e7 182
ashleymills 0:e979170e02e7 183 byte b1 = in[j++];
ashleymills 0:e979170e02e7 184 byte b2 = (twoBytes) ? in[j++] : 0;
ashleymills 0:e979170e02e7 185
ashleymills 0:e979170e02e7 186 byte e1 = b1 >> 2;
ashleymills 0:e979170e02e7 187 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
ashleymills 0:e979170e02e7 188 byte e3 = (b2 & 0xF) << 2;
ashleymills 0:e979170e02e7 189
ashleymills 0:e979170e02e7 190 out[i++] = base64Encode[e1];
ashleymills 0:e979170e02e7 191 out[i++] = base64Encode[e2];
ashleymills 0:e979170e02e7 192 out[i++] = (twoBytes) ? base64Encode[e3] : PAD;
ashleymills 0:e979170e02e7 193 out[i++] = PAD;
ashleymills 0:e979170e02e7 194 }
ashleymills 0:e979170e02e7 195
ashleymills 0:e979170e02e7 196 out[i++] = '\n';
ashleymills 0:e979170e02e7 197 if (i != outSz)
ashleymills 0:e979170e02e7 198 return ASN_INPUT_E;
ashleymills 0:e979170e02e7 199 *outLen = outSz;
ashleymills 0:e979170e02e7 200
ashleymills 0:e979170e02e7 201 return 0;
ashleymills 0:e979170e02e7 202 }
ashleymills 0:e979170e02e7 203
ashleymills 0:e979170e02e7 204
ashleymills 0:e979170e02e7 205 static
ashleymills 0:e979170e02e7 206 const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
ashleymills 0:e979170e02e7 207 BAD, BAD, BAD, BAD, BAD, BAD, BAD,
ashleymills 0:e979170e02e7 208 10, 11, 12, 13, 14, 15
ashleymills 0:e979170e02e7 209 }; /* A starts at 0x41 not 0x3A */
ashleymills 0:e979170e02e7 210
ashleymills 0:e979170e02e7 211 int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
ashleymills 0:e979170e02e7 212 {
ashleymills 0:e979170e02e7 213 word32 inIdx = 0;
ashleymills 0:e979170e02e7 214 word32 outIdx = 0;
ashleymills 0:e979170e02e7 215
ashleymills 0:e979170e02e7 216 if (inLen == 1 && *outLen && in) {
ashleymills 0:e979170e02e7 217 byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */
ashleymills 0:e979170e02e7 218
ashleymills 0:e979170e02e7 219 /* sanity check */
ashleymills 0:e979170e02e7 220 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
ashleymills 0:e979170e02e7 221 return ASN_INPUT_E;
ashleymills 0:e979170e02e7 222
ashleymills 0:e979170e02e7 223 b = hexDecode[b];
ashleymills 0:e979170e02e7 224
ashleymills 0:e979170e02e7 225 if (b == BAD)
ashleymills 0:e979170e02e7 226 return ASN_INPUT_E;
ashleymills 0:e979170e02e7 227
ashleymills 0:e979170e02e7 228 out[outIdx++] = b;
ashleymills 0:e979170e02e7 229
ashleymills 0:e979170e02e7 230 *outLen = outIdx;
ashleymills 0:e979170e02e7 231 return 0;
ashleymills 0:e979170e02e7 232 }
ashleymills 0:e979170e02e7 233
ashleymills 0:e979170e02e7 234 if (inLen % 2)
ashleymills 0:e979170e02e7 235 return BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 236
ashleymills 0:e979170e02e7 237 if (*outLen < (inLen / 2))
ashleymills 0:e979170e02e7 238 return BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 239
ashleymills 0:e979170e02e7 240 while (inLen) {
ashleymills 0:e979170e02e7 241 byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */
ashleymills 0:e979170e02e7 242 byte b2 = in[inIdx++] - 0x30;
ashleymills 0:e979170e02e7 243
ashleymills 0:e979170e02e7 244 /* sanity checks */
ashleymills 0:e979170e02e7 245 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
ashleymills 0:e979170e02e7 246 return ASN_INPUT_E;
ashleymills 0:e979170e02e7 247 if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0]))
ashleymills 0:e979170e02e7 248 return ASN_INPUT_E;
ashleymills 0:e979170e02e7 249
ashleymills 0:e979170e02e7 250 b = hexDecode[b];
ashleymills 0:e979170e02e7 251 b2 = hexDecode[b2];
ashleymills 0:e979170e02e7 252
ashleymills 0:e979170e02e7 253 if (b == BAD || b2 == BAD)
ashleymills 0:e979170e02e7 254 return ASN_INPUT_E;
ashleymills 0:e979170e02e7 255
ashleymills 0:e979170e02e7 256 out[outIdx++] = (b << 4) | b2;
ashleymills 0:e979170e02e7 257 inLen -= 2;
ashleymills 0:e979170e02e7 258 }
ashleymills 0:e979170e02e7 259
ashleymills 0:e979170e02e7 260 *outLen = outIdx;
ashleymills 0:e979170e02e7 261 return 0;
ashleymills 0:e979170e02e7 262 }
ashleymills 0:e979170e02e7 263
ashleymills 0:e979170e02e7 264
ashleymills 0:e979170e02e7 265 #endif /* defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) */