Commit 0384fc6f authored by Niels Möller's avatar Niels Möller

(base64_encode): Encode from the end of the data

towards the start, in order to support overlapping areas.

Rev: src/nettle/base64.c:1.3
Rev: src/nettle/base64.h:1.5
parent d889111d
......@@ -26,6 +26,7 @@
#include "base64.h"
#include <assert.h>
#include <stdlib.h>
#define TABLE_INVALID -1
#define TABLE_SPACE -2
......@@ -56,42 +57,55 @@ static const signed char decode_table[256] =
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
#define ENCODE(x) (encode_table[0x3F & (x)])
unsigned
base64_encode(uint8_t *dst,
unsigned src_length,
const uint8_t *src)
{
uint8_t *out = dst;
unsigned dst_length = BASE64_ENCODE_LENGTH(src_length);
const uint8_t *in = src + src_length;
uint8_t *out = dst + dst_length;
unsigned left_over = src_length % 3;
while (src_length >= 3)
if (left_over)
{
*out++ = encode_table[0x3F & (src[0] >> 2)];
*out++ = encode_table[0x3F & ((src[0] << 4) | (src[1] >> 4))];
*out++ = encode_table[0x3F & ((src[1] << 2) | (src[2] >> 6))];
*out++ = encode_table[0x3F & src[2]];
src += 3;
src_length -= 3;
}
switch (src_length)
switch(left_over)
{
case 2:
*out++ = encode_table[0x3F & (src[0] >> 2)];
*out++ = encode_table[0x3F & ((src[0] << 4) | (src[1] >> 4))];
*out++ = encode_table[0x3F & (src[1] << 2)];
*out++ = '=';
break;
case 1:
*out++ = encode_table[0x3F & (src[0] >> 2)];
*out++ = encode_table[0x3F & (src[0] << 4)];
*out++ = '=';
*out++ = '=';
in--;
*--out = '=';
*--out = '=';
*--out = ENCODE(in[0] << 4);
*--out = ENCODE(in[0] >> 2);
break;
case 0:
case 2:
in-= 2;
*--out = '=';
*--out = ENCODE( in[1] << 2);
*--out = ENCODE((in[0] << 4) | (in[1] >> 4));
*--out = ENCODE( in[0] >> 2);
break;
default:
abort();
}
}
while (in > src)
{
in -= 3;
*--out = ENCODE( in[2]);
*--out = ENCODE((in[1] << 2) | (in[2] >> 6));
*--out = ENCODE((in[0] << 4) | (in[1] >> 4));
*--out = ENCODE( in[0] >> 2);
}
assert(out == dst);
return out - dst;
return dst_length;
}
void
......
......@@ -33,6 +33,9 @@
#define BASE64_BINARY_BLOCK_SIZE 3
#define BASE64_TEXT_BLOCK_SIZE 4
/* Overlapping source and destination is allowed, as long as the start
* of the source area is not later than the start of the destination
* area. */
unsigned /* Returns the length of encoded data */
base64_encode(uint8_t *dst,
unsigned src_length,
......@@ -53,6 +56,9 @@ struct base64_ctx /* Internal, do not modify */
void
base64_decode_init(struct base64_ctx *ctx);
/* Overlapping source and destination is allowed, as long as the start
* of the source area is not before the start of the destination
* area. */
unsigned /* Returns the length of decoded data */
base64_decode_update(struct base64_ctx *ctx,
uint8_t *dst,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment