mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
fs: btrfs: Add more checksum algorithms
This mostly crossports crypto/hash.[ch] from btrfs-progs. The differences are: - No blake2 support No blake2 related library in U-Boot yet. - Use uboot xxhash/sha256 directly No need to implement the code as U-Boot has already provided the interface. This adds the support for the following csums: - SHA256 - XXHASH Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Marek Behún <marek.behun@nic.cz>
This commit is contained in:
parent
3b4b40c0d6
commit
565a4147d1
10 changed files with 130 additions and 62 deletions
|
@ -3,4 +3,4 @@
|
||||||
# 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
|
# 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
|
||||||
|
|
||||||
obj-y := btrfs.o chunk-map.o compression.o ctree.o dev.o dir-item.o \
|
obj-y := btrfs.o chunk-map.o compression.o ctree.o dev.o dir-item.o \
|
||||||
extent-io.o hash.o inode.o root.o subvolume.o super.o
|
extent-io.o inode.o root.o subvolume.o super.o crypto/hash.o disk-io.o
|
||||||
|
|
|
@ -5,11 +5,12 @@
|
||||||
* 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
|
* 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "btrfs.h"
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <uuid.h>
|
#include <uuid.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
|
#include "btrfs.h"
|
||||||
|
#include "crypto/hash.h"
|
||||||
|
|
||||||
struct btrfs_info btrfs_info;
|
struct btrfs_info btrfs_info;
|
||||||
|
|
||||||
|
|
|
@ -23,17 +23,6 @@ struct btrfs_info {
|
||||||
|
|
||||||
extern struct btrfs_info btrfs_info;
|
extern struct btrfs_info btrfs_info;
|
||||||
|
|
||||||
/* hash.c */
|
|
||||||
void btrfs_hash_init(void);
|
|
||||||
u32 btrfs_crc32c(u32, const void *, size_t);
|
|
||||||
u32 btrfs_csum_data(char *, u32, size_t);
|
|
||||||
void btrfs_csum_final(u32, void *);
|
|
||||||
|
|
||||||
static inline u64 btrfs_name_hash(const char *name, int len)
|
|
||||||
{
|
|
||||||
return btrfs_crc32c((u32) ~1, name, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dev.c */
|
/* dev.c */
|
||||||
extern struct blk_desc *btrfs_blk_desc;
|
extern struct blk_desc *btrfs_blk_desc;
|
||||||
extern struct disk_partition *btrfs_part_info;
|
extern struct disk_partition *btrfs_part_info;
|
||||||
|
|
55
fs/btrfs/crypto/hash.c
Normal file
55
fs/btrfs/crypto/hash.c
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
#include <linux/xxhash.h>
|
||||||
|
#include <linux/unaligned/access_ok.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <u-boot/sha256.h>
|
||||||
|
#include <u-boot/crc.h>
|
||||||
|
|
||||||
|
static u32 btrfs_crc32c_table[256];
|
||||||
|
|
||||||
|
void btrfs_hash_init(void)
|
||||||
|
{
|
||||||
|
static int inited = 0;
|
||||||
|
|
||||||
|
if (!inited) {
|
||||||
|
crc32c_init(btrfs_crc32c_table, 0x82F63B78);
|
||||||
|
inited = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int hash_sha256(const u8 *buf, size_t length, u8 *out)
|
||||||
|
{
|
||||||
|
sha256_context ctx;
|
||||||
|
|
||||||
|
sha256_starts(&ctx);
|
||||||
|
sha256_update(&ctx, buf, length);
|
||||||
|
sha256_finish(&ctx, out);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hash_xxhash(const u8 *buf, size_t length, u8 *out)
|
||||||
|
{
|
||||||
|
u64 hash;
|
||||||
|
|
||||||
|
hash = xxh64(buf, length, 0);
|
||||||
|
put_unaligned_le64(hash, out);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hash_crc32c(const u8 *buf, size_t length, u8 *out)
|
||||||
|
{
|
||||||
|
u32 crc;
|
||||||
|
|
||||||
|
crc = crc32c_cal((u32)~0, (char *)buf, length, btrfs_crc32c_table);
|
||||||
|
put_unaligned_le32(~crc, out);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 crc32c(u32 seed, const void * data, size_t len)
|
||||||
|
{
|
||||||
|
return crc32c_cal(seed, data, len, btrfs_crc32c_table);
|
||||||
|
}
|
17
fs/btrfs/crypto/hash.h
Normal file
17
fs/btrfs/crypto/hash.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef CRYPTO_HASH_H
|
||||||
|
#define CRYPTO_HASH_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#define CRYPTO_HASH_SIZE_MAX 32
|
||||||
|
|
||||||
|
void btrfs_hash_init(void);
|
||||||
|
int hash_crc32c(const u8 *buf, size_t length, u8 *out);
|
||||||
|
int hash_xxhash(const u8 *buf, size_t length, u8 *out);
|
||||||
|
int hash_sha256(const u8 *buf, size_t length, u8 *out);
|
||||||
|
|
||||||
|
u32 crc32c(u32 seed, const void * data, size_t len);
|
||||||
|
|
||||||
|
/* Blake2B is not yet supported due to lack of library */
|
||||||
|
|
||||||
|
#endif
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "btrfs.h"
|
#include "btrfs.h"
|
||||||
|
#include "disk-io.h"
|
||||||
|
|
||||||
static int verify_dir_item(struct btrfs_dir_item *item, u32 start, u32 total)
|
static int verify_dir_item(struct btrfs_dir_item *item, u32 start, u32 total)
|
||||||
{
|
{
|
||||||
|
|
22
fs/btrfs/disk-io.c
Normal file
22
fs/btrfs/disk-io.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
#include <common.h>
|
||||||
|
#include <fs_internal.h>
|
||||||
|
#include "disk-io.h"
|
||||||
|
#include "crypto/hash.h"
|
||||||
|
|
||||||
|
int btrfs_csum_data(u16 csum_type, const u8 *data, u8 *out, size_t len)
|
||||||
|
{
|
||||||
|
memset(out, 0, BTRFS_CSUM_SIZE);
|
||||||
|
|
||||||
|
switch (csum_type) {
|
||||||
|
case BTRFS_CSUM_TYPE_CRC32:
|
||||||
|
return hash_crc32c(data, len, out);
|
||||||
|
case BTRFS_CSUM_TYPE_XXHASH:
|
||||||
|
return hash_xxhash(data, len, out);
|
||||||
|
case BTRFS_CSUM_TYPE_SHA256:
|
||||||
|
return hash_sha256(data, len, out);
|
||||||
|
default:
|
||||||
|
printf("Unknown csum type %d\n", csum_type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
20
fs/btrfs/disk-io.h
Normal file
20
fs/btrfs/disk-io.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
#ifndef __BTRFS_DISK_IO_H__
|
||||||
|
#define __BTRFS_DISK_IO_H__
|
||||||
|
|
||||||
|
#include "crypto/hash.h"
|
||||||
|
#include "ctree.h"
|
||||||
|
#include "disk-io.h"
|
||||||
|
|
||||||
|
static inline u64 btrfs_name_hash(const char *name, int len)
|
||||||
|
{
|
||||||
|
u32 crc;
|
||||||
|
|
||||||
|
crc = crc32c((u32)~1, (unsigned char *)name, len);
|
||||||
|
|
||||||
|
return (u64)crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int btrfs_csum_data(u16 csum_type, const u8 *data, u8 *out, size_t len);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,38 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0+
|
|
||||||
/*
|
|
||||||
* BTRFS filesystem implementation for U-Boot
|
|
||||||
*
|
|
||||||
* 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "btrfs.h"
|
|
||||||
#include <u-boot/crc.h>
|
|
||||||
#include <asm/unaligned.h>
|
|
||||||
|
|
||||||
static u32 btrfs_crc32c_table[256];
|
|
||||||
|
|
||||||
void btrfs_hash_init(void)
|
|
||||||
{
|
|
||||||
static int inited = 0;
|
|
||||||
|
|
||||||
if (!inited) {
|
|
||||||
crc32c_init(btrfs_crc32c_table, 0x82F63B78);
|
|
||||||
inited = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 btrfs_crc32c(u32 crc, const void *data, size_t length)
|
|
||||||
{
|
|
||||||
return crc32c_cal(crc, (const char *) data, length,
|
|
||||||
btrfs_crc32c_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 btrfs_csum_data(char *data, u32 seed, size_t len)
|
|
||||||
{
|
|
||||||
return btrfs_crc32c(seed, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void btrfs_csum_final(u32 crc, void *result)
|
|
||||||
{
|
|
||||||
put_unaligned(cpu_to_le32(~crc), (u32 *)result);
|
|
||||||
}
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include "btrfs.h"
|
#include "btrfs.h"
|
||||||
|
#include "disk-io.h"
|
||||||
|
|
||||||
#define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN \
|
#define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN \
|
||||||
| BTRFS_HEADER_FLAG_RELOC \
|
| BTRFS_HEADER_FLAG_RELOC \
|
||||||
|
@ -61,19 +62,19 @@ static int btrfs_check_super_csum(char *raw_disk_sb)
|
||||||
(struct btrfs_super_block *) raw_disk_sb;
|
(struct btrfs_super_block *) raw_disk_sb;
|
||||||
u16 csum_type = le16_to_cpu(disk_sb->csum_type);
|
u16 csum_type = le16_to_cpu(disk_sb->csum_type);
|
||||||
|
|
||||||
if (csum_type == BTRFS_CSUM_TYPE_CRC32) {
|
if (csum_type == BTRFS_CSUM_TYPE_CRC32 ||
|
||||||
u32 crc = ~(u32) 0;
|
csum_type == BTRFS_CSUM_TYPE_SHA256 ||
|
||||||
const int csum_size = sizeof(crc);
|
csum_type == BTRFS_CSUM_TYPE_XXHASH) {
|
||||||
char result[csum_size];
|
u8 result[BTRFS_CSUM_SIZE];
|
||||||
|
|
||||||
crc = btrfs_csum_data(raw_disk_sb + BTRFS_CSUM_SIZE, crc,
|
btrfs_csum_data(csum_type, (u8 *)raw_disk_sb + BTRFS_CSUM_SIZE,
|
||||||
BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
|
result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
|
||||||
btrfs_csum_final(crc, result);
|
|
||||||
|
|
||||||
if (memcmp(raw_disk_sb, result, csum_size))
|
if (memcmp(raw_disk_sb, result, BTRFS_CSUM_SIZE))
|
||||||
return -1;
|
return -EIO;
|
||||||
} else {
|
} else if (csum_type == BTRFS_CSUM_TYPE_BLAKE2) {
|
||||||
return -1;
|
printf("Blake2 csum type is not supported yet\n");
|
||||||
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue