~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/ipxe/src/core/base64.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License as
 
6
 * published by the Free Software Foundation; either version 2 of the
 
7
 * License, or any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but
 
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
17
 * 02110-1301, USA.
 
18
 *
 
19
 * You can also choose to distribute this program under the terms of
 
20
 * the Unmodified Binary Distribution Licence (as given in the file
 
21
 * COPYING.UBDL), provided that you have satisfied its requirements.
 
22
 */
 
23
 
 
24
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
25
 
 
26
#include <stdint.h>
 
27
#include <string.h>
 
28
#include <ctype.h>
 
29
#include <errno.h>
 
30
#include <assert.h>
 
31
#include <ipxe/base64.h>
 
32
 
 
33
/** @file
 
34
 *
 
35
 * Base64 encoding
 
36
 *
 
37
 */
 
38
 
 
39
static const char base64[64] =
 
40
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
41
 
 
42
/**
 
43
 * Base64-encode data
 
44
 *
 
45
 * @v raw               Raw data
 
46
 * @v raw_len           Length of raw data
 
47
 * @v data              Buffer
 
48
 * @v len               Length of buffer
 
49
 * @ret len             Encoded length
 
50
 */
 
51
size_t base64_encode ( const void *raw, size_t raw_len, char *data,
 
52
                       size_t len ) {
 
53
        const uint8_t *raw_bytes = ( ( const uint8_t * ) raw );
 
54
        size_t raw_bit_len = ( 8 * raw_len );
 
55
        size_t used = 0;
 
56
        unsigned int bit;
 
57
        unsigned int byte;
 
58
        unsigned int shift;
 
59
        unsigned int tmp;
 
60
 
 
61
        for ( bit = 0 ; bit < raw_bit_len ; bit += 6, used++ ) {
 
62
                byte = ( bit / 8 );
 
63
                shift = ( bit % 8 );
 
64
                tmp = ( raw_bytes[byte] << shift );
 
65
                if ( ( byte + 1 ) < raw_len )
 
66
                        tmp |= ( raw_bytes[ byte + 1 ] >> ( 8 - shift ) );
 
67
                tmp = ( ( tmp >> 2 ) & 0x3f );
 
68
                if ( used < len )
 
69
                        data[used] = base64[tmp];
 
70
        }
 
71
        for ( ; ( bit % 8 ) != 0 ; bit += 6, used++ ) {
 
72
                if ( used < len )
 
73
                        data[used] = '=';
 
74
        }
 
75
        if ( used < len )
 
76
                data[used] = '\0';
 
77
        if ( len )
 
78
                data[ len - 1 ] = '\0'; /* Ensure terminator exists */
 
79
 
 
80
        return used;
 
81
}
 
82
 
 
83
/**
 
84
 * Base64-decode string
 
85
 *
 
86
 * @v encoded           Encoded string
 
87
 * @v data              Buffer
 
88
 * @v len               Length of buffer
 
89
 * @ret len             Length of data, or negative error
 
90
 */
 
91
int base64_decode ( const char *encoded, void *data, size_t len ) {
 
92
        const char *in = encoded;
 
93
        uint8_t *out = data;
 
94
        uint8_t in_char;
 
95
        char *match;
 
96
        int in_bits;
 
97
        unsigned int bit = 0;
 
98
        unsigned int pad_count = 0;
 
99
        size_t offset;
 
100
 
 
101
        /* Zero the output buffer */
 
102
        memset ( data, 0, len );
 
103
 
 
104
        /* Decode string */
 
105
        while ( ( in_char = *(in++) ) ) {
 
106
 
 
107
                /* Ignore whitespace characters */
 
108
                if ( isspace ( in_char ) )
 
109
                        continue;
 
110
 
 
111
                /* Process pad characters */
 
112
                if ( in_char == '=' ) {
 
113
                        if ( pad_count >= 2 ) {
 
114
                                DBG ( "Base64-encoded string \"%s\" has too "
 
115
                                      "many pad characters\n", encoded );
 
116
                                return -EINVAL;
 
117
                        }
 
118
                        pad_count++;
 
119
                        bit -= 2; /* unused_bits = ( 2 * pad_count ) */
 
120
                        continue;
 
121
                }
 
122
                if ( pad_count ) {
 
123
                        DBG ( "Base64-encoded string \"%s\" has invalid pad "
 
124
                              "sequence\n", encoded );
 
125
                        return -EINVAL;
 
126
                }
 
127
 
 
128
                /* Process normal characters */
 
129
                match = strchr ( base64, in_char );
 
130
                if ( ! match ) {
 
131
                        DBG ( "Base64-encoded string \"%s\" contains invalid "
 
132
                              "character '%c'\n", encoded, in_char );
 
133
                        return -EINVAL;
 
134
                }
 
135
                in_bits = ( match - base64 );
 
136
 
 
137
                /* Add to raw data */
 
138
                in_bits <<= 2;
 
139
                offset = ( bit / 8 );
 
140
                if ( offset < len )
 
141
                        out[offset] |= ( in_bits >> ( bit % 8 ) );
 
142
                offset++;
 
143
                if ( offset < len )
 
144
                        out[offset] |= ( in_bits << ( 8 - ( bit % 8 ) ) );
 
145
                bit += 6;
 
146
        }
 
147
 
 
148
        /* Check that we decoded a whole number of bytes */
 
149
        if ( ( bit % 8 ) != 0 ) {
 
150
                DBG ( "Base64-encoded string \"%s\" has invalid bit length "
 
151
                      "%d\n", encoded, bit );
 
152
                return -EINVAL;
 
153
        }
 
154
 
 
155
        /* Return length in bytes */
 
156
        return ( bit / 8 );
 
157
}