Commit 1c5100a2 authored by Eric Biggers's avatar Eric Biggers

fscrypt: clean up base64 encoding/decoding

Some minor cleanups for the code that base64 encodes and decodes
encrypted filenames and long name digests:

- Rename "digest_{encode,decode}()" => "base64_{encode,decode}()" since
  they are used for filenames too, not just for long name digests.
- Replace 'while' loops with more conventional 'for' loops.
- Use 'u8' for binary data.  Keep 'char' for string data.
- Fully constify the lookup table (pointer was not const).
- Improve comment.

No actual change in behavior.
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
parent 75798f85
...@@ -127,44 +127,45 @@ static int fname_decrypt(struct inode *inode, ...@@ -127,44 +127,45 @@ static int fname_decrypt(struct inode *inode,
return 0; return 0;
} }
static const char *lookup_table = static const char lookup_table[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
#define BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3) #define BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3)
/** /**
* digest_encode() - * base64_encode() -
* *
* Encodes the input digest using characters from the set [a-zA-Z0-9_+]. * Encodes the input string using characters from the set [A-Za-z0-9+,].
* The encoded string is roughly 4/3 times the size of the input string. * The encoded string is roughly 4/3 times the size of the input string.
*
* Return: length of the encoded string
*/ */
static int digest_encode(const char *src, int len, char *dst) static int base64_encode(const u8 *src, int len, char *dst)
{ {
int i = 0, bits = 0, ac = 0; int i, bits = 0, ac = 0;
char *cp = dst; char *cp = dst;
while (i < len) { for (i = 0; i < len; i++) {
ac += (((unsigned char) src[i]) << bits); ac += src[i] << bits;
bits += 8; bits += 8;
do { do {
*cp++ = lookup_table[ac & 0x3f]; *cp++ = lookup_table[ac & 0x3f];
ac >>= 6; ac >>= 6;
bits -= 6; bits -= 6;
} while (bits >= 6); } while (bits >= 6);
i++;
} }
if (bits) if (bits)
*cp++ = lookup_table[ac & 0x3f]; *cp++ = lookup_table[ac & 0x3f];
return cp - dst; return cp - dst;
} }
static int digest_decode(const char *src, int len, char *dst) static int base64_decode(const char *src, int len, u8 *dst)
{ {
int i = 0, bits = 0, ac = 0; int i, bits = 0, ac = 0;
const char *p; const char *p;
char *cp = dst; u8 *cp = dst;
while (i < len) { for (i = 0; i < len; i++) {
p = strchr(lookup_table, src[i]); p = strchr(lookup_table, src[i]);
if (p == NULL || src[i] == 0) if (p == NULL || src[i] == 0)
return -2; return -2;
...@@ -175,7 +176,6 @@ static int digest_decode(const char *src, int len, char *dst) ...@@ -175,7 +176,6 @@ static int digest_decode(const char *src, int len, char *dst)
ac >>= 8; ac >>= 8;
bits -= 8; bits -= 8;
} }
i++;
} }
if (ac) if (ac)
return -1; return -1;
...@@ -272,7 +272,7 @@ int fscrypt_fname_disk_to_usr(struct inode *inode, ...@@ -272,7 +272,7 @@ int fscrypt_fname_disk_to_usr(struct inode *inode,
return fname_decrypt(inode, iname, oname); return fname_decrypt(inode, iname, oname);
if (iname->len <= FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE) { if (iname->len <= FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE) {
oname->len = digest_encode(iname->name, iname->len, oname->len = base64_encode(iname->name, iname->len,
oname->name); oname->name);
return 0; return 0;
} }
...@@ -287,7 +287,7 @@ int fscrypt_fname_disk_to_usr(struct inode *inode, ...@@ -287,7 +287,7 @@ int fscrypt_fname_disk_to_usr(struct inode *inode,
FSCRYPT_FNAME_DIGEST(iname->name, iname->len), FSCRYPT_FNAME_DIGEST(iname->name, iname->len),
FSCRYPT_FNAME_DIGEST_SIZE); FSCRYPT_FNAME_DIGEST_SIZE);
oname->name[0] = '_'; oname->name[0] = '_';
oname->len = 1 + digest_encode((const char *)&digested_name, oname->len = 1 + base64_encode((const u8 *)&digested_name,
sizeof(digested_name), oname->name + 1); sizeof(digested_name), oname->name + 1);
return 0; return 0;
} }
...@@ -380,8 +380,8 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname, ...@@ -380,8 +380,8 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
if (fname->crypto_buf.name == NULL) if (fname->crypto_buf.name == NULL)
return -ENOMEM; return -ENOMEM;
ret = digest_decode(iname->name + digested, iname->len - digested, ret = base64_decode(iname->name + digested, iname->len - digested,
fname->crypto_buf.name); fname->crypto_buf.name);
if (ret < 0) { if (ret < 0) {
ret = -ENOENT; ret = -ENOENT;
goto errout; goto errout;
......
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