commit
f4afa5d5bb
@ -6631,7 +6631,7 @@ The library provides functions to encode and decode a Base16 a.k.a Hex string.
|
||||
|
||||
To encode a binary string in base16 call:
|
||||
|
||||
\index{base32\_encode()}
|
||||
\index{base16\_encode()}
|
||||
\begin{verbatim}
|
||||
int base16_encode(const unsigned char *in, unsigned long inlen,
|
||||
char *out, unsigned long *outlen,
|
||||
@ -6644,9 +6644,9 @@ and \textit{caps} is either $0$ to use lower-letter \textit{a..f} or else to use
|
||||
|
||||
To decode a base16 string call:
|
||||
|
||||
\index{base32\_decode()}
|
||||
\index{base16\_decode()}
|
||||
\begin{verbatim}
|
||||
int base16_decode(const char *in,
|
||||
int base16_decode(const char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
\end{verbatim}
|
||||
|
||||
|
@ -51,7 +51,7 @@ int base32_decode(const char *in, unsigned long inlen,
|
||||
int base16_encode(const unsigned char *in, unsigned long inlen,
|
||||
char *out, unsigned long *outlen,
|
||||
int caps);
|
||||
int base16_decode(const char *in,
|
||||
int base16_decode(const char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
#endif
|
||||
|
||||
|
@ -25,33 +25,42 @@
|
||||
@param outlen [in/out] The max size and resulting size of the decoded data
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int base16_decode(const char *in,
|
||||
int base16_decode(const char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long pos, in_len, out_len;
|
||||
unsigned char idx0;
|
||||
unsigned char idx1;
|
||||
unsigned long pos, out_len;
|
||||
unsigned char idx0, idx1;
|
||||
char in0, in1;
|
||||
|
||||
const unsigned char hashmap[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */
|
||||
0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */
|
||||
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* @ABCDEFG */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* HIJKLMNO */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* PQRSTUVW */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ[\]^_ */
|
||||
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* `abcdefg */
|
||||
0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */
|
||||
0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* @ABCDEFG */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* HIJKLMNO */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* PQRSTUVW */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */
|
||||
0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* `abcdefg */
|
||||
};
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
in_len = strlen(in);
|
||||
if ((in_len % 2) == 1) return CRYPT_INVALID_PACKET;
|
||||
if ((inlen % 2) == 1) return CRYPT_INVALID_PACKET;
|
||||
out_len = *outlen * 2;
|
||||
for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < in_len)); pos += 2) {
|
||||
idx0 = (unsigned char) (in[pos + 0] & 0x1F) ^ 0x10;
|
||||
idx1 = (unsigned char) (in[pos + 1] & 0x1F) ^ 0x10;
|
||||
for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < inlen)); pos += 2) {
|
||||
in0 = in[pos + 0];
|
||||
in1 = in[pos + 1];
|
||||
|
||||
if ((in0 < '0') || (in0 > 'g')) return CRYPT_INVALID_PACKET;
|
||||
if ((in1 < '0') || (in1 > 'g')) return CRYPT_INVALID_PACKET;
|
||||
|
||||
idx0 = (unsigned char) (in0 & 0x1F) ^ 0x10;
|
||||
idx1 = (unsigned char) (in1 & 0x1F) ^ 0x10;
|
||||
|
||||
if (hashmap[idx0] == 0xff) return CRYPT_INVALID_PACKET;
|
||||
if (hashmap[idx1] == 0xff) return CRYPT_INVALID_PACKET;
|
||||
|
||||
out[pos / 2] = (unsigned char) (hashmap[idx0] << 4) | hashmap[idx1];
|
||||
}
|
||||
*outlen = pos / 2;
|
||||
|
@ -20,6 +20,7 @@ int base16_test(void)
|
||||
"0123456789abcdef",
|
||||
"0123456789ABCDEF",
|
||||
};
|
||||
const char *failing_decode = "test";
|
||||
unsigned long x, l1, l2;
|
||||
int idx;
|
||||
|
||||
@ -28,8 +29,9 @@ int base16_test(void)
|
||||
yarrow_read(in, x, &yarrow_prng);
|
||||
l1 = sizeof(out);
|
||||
DO(base16_encode(in, x, out, &l1, idx));
|
||||
l1--;
|
||||
l2 = sizeof(tmp);
|
||||
DO(base16_decode(out, tmp, &l2));
|
||||
DO(base16_decode(out, l1, tmp, &l2));
|
||||
DO(do_compare_testvector(tmp, l2, in, x, "random base16", idx * 100 + x));
|
||||
}
|
||||
}
|
||||
@ -38,11 +40,16 @@ int base16_test(void)
|
||||
l1 = sizeof(out);
|
||||
DO(base16_encode(testin, sizeof(testin), out, &l1, idx));
|
||||
DO(do_compare_testvector(out, strlen(out), testout[idx], strlen(testout[idx]), "testout base16", idx));
|
||||
l1--;
|
||||
l2 = sizeof(tmp);
|
||||
DO(base16_decode(out, tmp, &l2));
|
||||
DO(base16_decode(out, l1, tmp, &l2));
|
||||
DO(do_compare_testvector(tmp, l2, testin, sizeof(testin), "testin base16", idx));
|
||||
}
|
||||
|
||||
l1 = 4;
|
||||
l2 = sizeof(tmp);
|
||||
DO(base16_decode(failing_decode, l1, tmp, &l2) == CRYPT_OK ? CRYPT_FAIL_TESTVECTOR : CRYPT_OK);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user