Browse Source

[base16] Add generic base16 encoding and decoding routines

Base16 encoding is currently implemented in both iSCSI and SRP.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
bc83e4b5d3
3 changed files with 145 additions and 0 deletions
  1. 106
    0
      src/core/base16.c
  2. 38
    0
      src/include/ipxe/base16.h
  3. 1
    0
      src/include/ipxe/errfile.h

+ 106
- 0
src/core/base16.c View File

@@ -0,0 +1,106 @@
1
+/*
2
+ * Copyright (C) 2010 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <stdint.h>
22
+#include <stdlib.h>
23
+#include <stdio.h>
24
+#include <errno.h>
25
+#include <ipxe/base16.h>
26
+
27
+/** @file
28
+ *
29
+ * Base16 encoding
30
+ *
31
+ */
32
+
33
+/**
34
+ * Base16-encode data
35
+ *
36
+ * @v raw		Raw data
37
+ * @v len		Length of raw data
38
+ * @v encoded		Buffer for encoded string
39
+ *
40
+ * The buffer must be the correct length for the encoded string.  Use
41
+ * something like
42
+ *
43
+ *     char buf[ base16_encoded_len ( len ) + 1 ];
44
+ *
45
+ * (the +1 is for the terminating NUL) to provide a buffer of the
46
+ * correct size.
47
+ */
48
+void base16_encode ( const uint8_t *raw, size_t len, char *encoded ) {
49
+	const uint8_t *raw_bytes = raw;
50
+	char *encoded_bytes = encoded;
51
+	size_t remaining = len;
52
+
53
+	for ( ; remaining-- ; encoded_bytes += 2 ) {
54
+		sprintf ( encoded_bytes, "%02x", *(raw_bytes++) );
55
+	}
56
+
57
+	DBG ( "Base16-encoded to \"%s\":\n", encoded );
58
+	DBG_HDA ( 0, raw, len );
59
+	assert ( strlen ( encoded ) == base16_encoded_len ( len ) );
60
+}
61
+
62
+/**
63
+ * Base16-decode data
64
+ *
65
+ * @v encoded		Encoded string
66
+ * @v raw		Raw data
67
+ * @ret len		Length of raw data, or negative error
68
+ *
69
+ * The buffer must be large enough to contain the decoded data.  Use
70
+ * something like
71
+ *
72
+ *     char buf[ base16_decoded_max_len ( encoded ) ];
73
+ *
74
+ * to provide a buffer of the correct size.
75
+ */
76
+int base16_decode ( const char *encoded, uint8_t *raw ) {
77
+	const char *encoded_bytes = encoded;
78
+	uint8_t *raw_bytes = raw;
79
+	char buf[3];
80
+	char *endp;
81
+	size_t len;
82
+
83
+	while ( encoded_bytes[0] ) {
84
+		if ( ! encoded_bytes[1] ) {
85
+			DBG ( "Base16-encoded string \"%s\" has invalid "
86
+			      "length\n", encoded );
87
+			return -EINVAL;
88
+		}
89
+		memcpy ( buf, encoded_bytes, 2 );
90
+		buf[2] = '\0';
91
+		*(raw_bytes++) = strtoul ( buf, &endp, 16 );
92
+		if ( *endp != '\0' ) {
93
+			DBG ( "Base16-encoded string \"%s\" has invalid "
94
+			      "byte \"%s\"\n", encoded, buf );
95
+			return -EINVAL;
96
+		}
97
+		encoded_bytes += 2;
98
+	}
99
+	len = ( raw_bytes - raw );
100
+
101
+	DBG ( "Base16-decoded \"%s\" to:\n", encoded );
102
+	DBG_HDA ( 0, raw, len );
103
+	assert ( len <= base16_decoded_max_len ( encoded ) );
104
+
105
+	return ( len );
106
+}

+ 38
- 0
src/include/ipxe/base16.h View File

@@ -0,0 +1,38 @@
1
+#ifndef _IPXE_BASE16_H
2
+#define _IPXE_BASE16_H
3
+
4
+/** @file
5
+ *
6
+ * Base16 encoding
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+#include <stdint.h>
13
+#include <string.h>
14
+
15
+/**
16
+ * Calculate length of base16-encoded data
17
+ *
18
+ * @v raw_len		Raw data length
19
+ * @ret encoded_len	Encoded string length (excluding NUL)
20
+ */
21
+static inline size_t base16_encoded_len ( size_t raw_len ) {
22
+	return ( 2 * raw_len );
23
+}
24
+
25
+/**
26
+ * Calculate maximum length of base16-decoded string
27
+ *
28
+ * @v encoded		Encoded string
29
+ * @v max_raw_len	Maximum length of raw data
30
+ */
31
+static inline size_t base16_decoded_max_len ( const char *encoded ) {
32
+	return ( ( strlen ( encoded ) + 1 ) / 2 );
33
+}
34
+
35
+extern void base16_encode ( const uint8_t *raw, size_t len, char *encoded );
36
+extern int base16_decode ( const char *encoded, uint8_t *raw );
37
+
38
+#endif /* _IPXE_BASE16_H */

+ 1
- 0
src/include/ipxe/errfile.h View File

@@ -54,6 +54,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
54 54
 #define ERRFILE_xfer		       ( ERRFILE_CORE | 0x000e0000 )
55 55
 #define ERRFILE_bitmap		       ( ERRFILE_CORE | 0x000f0000 )
56 56
 #define ERRFILE_base64		       ( ERRFILE_CORE | 0x00100000 )
57
+#define ERRFILE_base16		       ( ERRFILE_CORE | 0x00110000 )
57 58
 
58 59
 #define ERRFILE_eisa		     ( ERRFILE_DRIVER | 0x00000000 )
59 60
 #define ERRFILE_isa		     ( ERRFILE_DRIVER | 0x00010000 )

Loading…
Cancel
Save