]>
Commit | Line | Data |
---|---|---|
985c33b1 TR |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
5 | * Common Development and Distribution License (the "License"). | |
6 | * You may not use this file except in compliance with the License. | |
7 | * | |
8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 | * or http://opensource.org/licenses/CDDL-1.0. | |
10 | * See the License for the specific language governing permissions | |
11 | * and limitations under the License. | |
12 | * | |
13 | * When distributing Covered Code, include this CDDL HEADER in each | |
14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 | * If applicable, add the following below this CDDL HEADER, with the | |
16 | * fields enclosed by brackets "[]" replaced with your own identifying | |
17 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 | * | |
19 | * CDDL HEADER END | |
20 | */ | |
21 | ||
22 | /* | |
23 | * Copyright 2022 Tino Reichardt <milky-zfs@mcmilk.de> | |
24 | */ | |
25 | ||
26 | #include <sys/zfs_context.h> | |
27 | #include <sys/zio_checksum.h> | |
28 | #include <sys/blake3.h> | |
29 | #include <sys/abd.h> | |
30 | ||
31 | static int | |
32 | blake3_incremental(void *buf, size_t size, void *arg) | |
33 | { | |
34 | BLAKE3_CTX *ctx = arg; | |
35 | ||
36 | Blake3_Update(ctx, buf, size); | |
37 | ||
38 | return (0); | |
39 | } | |
40 | ||
41 | /* | |
42 | * Computes a native 256-bit BLAKE3 MAC checksum. Please note that this | |
43 | * function requires the presence of a ctx_template that should be allocated | |
44 | * using abd_checksum_blake3_tmpl_init. | |
45 | */ | |
46 | void | |
47 | abd_checksum_blake3_native(abd_t *abd, uint64_t size, const void *ctx_template, | |
48 | zio_cksum_t *zcp) | |
49 | { | |
4ef69de3 | 50 | ASSERT(ctx_template != NULL); |
985c33b1 | 51 | |
deb12130 | 52 | #if defined(_KERNEL) |
e2a92d72 MG |
53 | kpreempt_disable(); |
54 | BLAKE3_CTX *ctx = blake3_per_cpu_ctx[CPU_SEQID]; | |
deb12130 TR |
55 | #else |
56 | BLAKE3_CTX *ctx = kmem_alloc(sizeof (*ctx), KM_SLEEP); | |
57 | #endif | |
58 | ||
985c33b1 TR |
59 | memcpy(ctx, ctx_template, sizeof (*ctx)); |
60 | (void) abd_iterate_func(abd, 0, size, blake3_incremental, ctx); | |
61 | Blake3_Final(ctx, (uint8_t *)zcp); | |
62 | ||
e2a92d72 MG |
63 | #if defined(_KERNEL) |
64 | kpreempt_enable(); | |
65 | #else | |
985c33b1 TR |
66 | memset(ctx, 0, sizeof (*ctx)); |
67 | kmem_free(ctx, sizeof (*ctx)); | |
deb12130 | 68 | #endif |
985c33b1 TR |
69 | } |
70 | ||
71 | /* | |
72 | * Byteswapped version of abd_checksum_blake3_native. This just invokes | |
73 | * the native checksum function and byteswaps the resulting checksum (since | |
74 | * BLAKE3 is internally endian-insensitive). | |
75 | */ | |
76 | void | |
77 | abd_checksum_blake3_byteswap(abd_t *abd, uint64_t size, | |
78 | const void *ctx_template, zio_cksum_t *zcp) | |
79 | { | |
80 | zio_cksum_t tmp; | |
81 | ||
4ef69de3 | 82 | ASSERT(ctx_template != NULL); |
985c33b1 TR |
83 | |
84 | abd_checksum_blake3_native(abd, size, ctx_template, &tmp); | |
85 | zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]); | |
86 | zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]); | |
87 | zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]); | |
88 | zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]); | |
89 | } | |
90 | ||
91 | /* | |
92 | * Allocates a BLAKE3 MAC template suitable for using in BLAKE3 MAC checksum | |
93 | * computations and returns a pointer to it. | |
94 | */ | |
95 | void * | |
96 | abd_checksum_blake3_tmpl_init(const zio_cksum_salt_t *salt) | |
97 | { | |
98 | BLAKE3_CTX *ctx; | |
99 | ||
100 | ASSERT(sizeof (salt->zcs_bytes) == 32); | |
101 | ||
102 | /* init reference object */ | |
103 | ctx = kmem_zalloc(sizeof (*ctx), KM_SLEEP); | |
104 | Blake3_InitKeyed(ctx, salt->zcs_bytes); | |
105 | ||
106 | return (ctx); | |
107 | } | |
108 | ||
109 | /* | |
110 | * Frees a BLAKE3 context template previously allocated using | |
111 | * zio_checksum_blake3_tmpl_init. | |
112 | */ | |
113 | void | |
114 | abd_checksum_blake3_tmpl_free(void *ctx_template) | |
115 | { | |
116 | BLAKE3_CTX *ctx = ctx_template; | |
117 | ||
118 | memset(ctx, 0, sizeof (*ctx)); | |
119 | kmem_free(ctx, sizeof (*ctx)); | |
120 | } |