"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "Add support for SM3 secure hash"

Heiko Schocher <hs@nabladev.com> says:

Add SM3 secure hash, as specified by OSCCA GM/T 0004-2012 SM3 and described
at https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02

TPMv2 defines hash algo sm3_256, which is currently
not supported and prevented TPMv2 chip with newer
firmware to work with U-Boot. Seen this on a ST33TPHF2XI2C

u-boot=> tpm2 init
u-boot=> tpm2 autostart
tpm2_get_pcr_info: too many pcrs: 5
Error: -90
u-boot=>

Implement sm3 hash, so we can fix this problem.

Link: https://lore.kernel.org/r/20251118043042.27726-1-hs@nabladev.com

Tom Rini 33750d8d 8eed8a35

+554 -4
+7
MAINTAINERS
··· 1698 1698 F: lib/slre.c 1699 1699 F: test/lib/slre.c 1700 1700 1701 + SM3 1702 + M: Heiko Schocher <hs@nabladev.com> 1703 + S: Maintained 1704 + F: cmd/sm3sum.c 1705 + F: include/u-boot/sm3.h 1706 + F: lib/sm3.c 1707 + 1701 1708 SMCCC TRNG 1702 1709 M: Etienne Carriere <etienne.carriere@linaro.org> 1703 1710 S: Maintained
+1
boot/Kconfig
··· 1022 1022 select SHA256 1023 1023 select SHA384 1024 1024 select SHA512 1025 + select SM3 1025 1026 help 1026 1027 This option enables measurement of the boot process when booting 1027 1028 without UEFI . Measurement involves creating cryptographic hashes
+15
cmd/Kconfig
··· 264 264 help 265 265 Display information about the SBI implementation. 266 266 267 + config CMD_SM3SUM 268 + bool "sm3sum" 269 + select SM3 270 + select HASH 271 + help 272 + Compute SM3 checksum. 273 + add SM3 hash functionality 274 + 275 + config SM3SUM_VERIFY 276 + bool "sm3sum -v" 277 + depends on CMD_SM3SUM 278 + help 279 + Add for the sm3sum command the -v option 280 + to verify data against an SM3 checksum. 281 + 267 282 config CMD_SMBIOS 268 283 bool "smbios" 269 284 depends on SMBIOS
+1
cmd/Makefile
··· 177 177 obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o 178 178 obj-$(CONFIG_CMD_SPI) += spi.o 179 179 obj-$(CONFIG_CMD_STRINGS) += strings.o 180 + obj-$(CONFIG_CMD_SM3SUM) += sm3sum.o 180 181 obj-$(CONFIG_CMD_SMBIOS) += smbios.o 181 182 obj-$(CONFIG_CMD_SMC) += smccc.o 182 183 obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o
+48
cmd/sm3sum.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * (C) Copyright 2025 4 + * Heiko Schocher, Nabladev Software Engineering, hs@nabladev.com 5 + * 6 + * based on code from cmd/md5sum.c 7 + */ 8 + 9 + #include <command.h> 10 + #include <env.h> 11 + #include <hash.h> 12 + 13 + static int do_sm3sum(struct cmd_tbl *cmdtp, int flag, int argc, 14 + char *const argv[]) 15 + { 16 + int flags = HASH_FLAG_ENV; 17 + int ac; 18 + char *const *av; 19 + 20 + if (argc < 3) 21 + return CMD_RET_USAGE; 22 + 23 + av = argv + 1; 24 + ac = argc - 1; 25 + if (IS_ENABLED(CONFIG_SM3SUM_VERIFY) && strcmp(*av, "-v") == 0) { 26 + flags |= HASH_FLAG_VERIFY; 27 + av++; 28 + ac--; 29 + } 30 + 31 + return hash_command("sm3_256", flags, cmdtp, flag, ac, av); 32 + } 33 + 34 + #if IS_ENABLED(CONFIG_SM3SUM_VERIFY) 35 + U_BOOT_CMD(sm3sum, 5, 1, do_sm3sum, 36 + "compute SM3 message digest", 37 + "address count [[*]sum]\n" 38 + " - compute SM3 message digest [save to sum]\n" 39 + "sm3sum -v address count [*]sum\n" 40 + " - verify sm3sum of memory area" 41 + ); 42 + #else 43 + U_BOOT_CMD(sm3sum, 4, 1, do_sm3sum, 44 + "compute SM3 message digest", 45 + "address count [[*]sum]\n" 46 + " - compute SM3 message digest [save to sum]" 47 + ); 48 + #endif /* IS_ENABLED(CONFIG_SM3SUM_VERIFY) */
+1
cmd/tpm-v2.c
··· 589 589 " * sha256\n" 590 590 " * sha384\n" 591 591 " * sha512\n" 592 + " * sm3_256\n" 592 593 " <on|off> is one of:\n" 593 594 " * on - Select all available PCRs associated with the specified\n" 594 595 " algorithm (bank)\n"
+41 -1
common/hash.c
··· 34 34 #include <u-boot/sha256.h> 35 35 #include <u-boot/sha512.h> 36 36 #include <u-boot/md5.h> 37 + #include <u-boot/sm3.h> 37 38 38 39 static int __maybe_unused hash_init_sha1(struct hash_algo *algo, void **ctxp) 39 40 { ··· 143 144 return 0; 144 145 } 145 146 147 + static int __maybe_unused hash_init_sm3(struct hash_algo *algo, void **ctxp) 148 + { 149 + struct sm3_context *ctx = malloc(sizeof(struct sm3_context)); 150 + 151 + sm3_init(ctx); 152 + *ctxp = ctx; 153 + return 0; 154 + } 155 + 156 + static int __maybe_unused hash_update_sm3(struct hash_algo *algo, void *ctx, 157 + const void *buf, uint size, 158 + int is_last) 159 + { 160 + sm3_update((struct sm3_context *)ctx, buf, size); 161 + return 0; 162 + } 163 + 164 + static int __maybe_unused hash_finish_sm3(struct hash_algo *algo, void *ctx, 165 + void *dest_buf, int size) 166 + { 167 + if (size < algo->digest_size) 168 + return -1; 169 + 170 + sm3_final((struct sm3_context *)ctx, dest_buf); 171 + free(ctx); 172 + return 0; 173 + } 174 + 146 175 static int __maybe_unused hash_init_crc16_ccitt(struct hash_algo *algo, 147 176 void **ctxp) 148 177 { ··· 298 327 #endif 299 328 }, 300 329 #endif 330 + #if CONFIG_IS_ENABLED(SM3) 331 + { 332 + .name = "sm3_256", 333 + .digest_size = SM3_DIGEST_SIZE, 334 + .chunk_size = SM3_BLOCK_SIZE, 335 + .hash_func_ws = sm3_csum_wd, 336 + .hash_init = hash_init_sm3, 337 + .hash_update = hash_update_sm3, 338 + .hash_finish = hash_finish_sm3, 339 + }, 340 + #endif 301 341 #if CONFIG_IS_ENABLED(CRC16) 302 342 { 303 343 .name = "crc16-ccitt", ··· 334 374 #if CONFIG_IS_ENABLED(SHA256) || IS_ENABLED(CONFIG_CMD_SHA1SUM) || \ 335 375 CONFIG_IS_ENABLED(CRC32_VERIFY) || IS_ENABLED(CONFIG_CMD_HASH) || \ 336 376 CONFIG_IS_ENABLED(SHA384) || CONFIG_IS_ENABLED(SHA512) || \ 337 - IS_ENABLED(CONFIG_CMD_MD5SUM) 377 + IS_ENABLED(CONFIG_CMD_MD5SUM) || CONFIG_IS_ENABLED(SM3) 338 378 #define multi_hash() 1 339 379 #else 340 380 #define multi_hash() 0
+11
include/linux/bitops.h
··· 148 148 return sizeof(w) == 4 ? generic_hweight32(w) : generic_hweight64(w); 149 149 } 150 150 151 + /** 152 + * rol32 - rotate a 32-bit value left 153 + * @word: value to rotate 154 + * @shift: bits to roll 155 + */ 156 + 157 + static inline __u32 rol32(__u32 word, unsigned int shift) 158 + { 159 + return (word << (shift & 31)) | (word >> ((-shift) & 31)); 160 + } 161 + 151 162 #include <asm/bitops.h> 152 163 153 164 /* linux/include/asm-generic/bitops/non-atomic.h */
+12
include/tpm-v2.h
··· 345 345 false, 346 346 #endif 347 347 }, 348 + { 349 + "sm3_256", 350 + TPM2_ALG_SM3_256, 351 + TCG2_BOOT_HASH_ALG_SM3_256, 352 + TPM2_SM3_256_DIGEST_SIZE, 353 + #if IS_ENABLED(CONFIG_SM3) 354 + true, 355 + #else 356 + false, 357 + #endif 358 + }, 359 + 348 360 }; 349 361 350 362 /* NV index attributes */
+35
include/u-boot/sm3.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #ifndef _SM3_H 3 + #define _SM3_H 4 + 5 + #define SM3_DIGEST_SIZE 32 /* 256 bits */ 6 + #define SM3_BLOCK_SIZE 64 /* 512 bits */ 7 + #define SM3_PAD_UNIT 56 /* 448 bits */ 8 + 9 + #define SM3_T1 0x79CC4519 10 + #define SM3_T2 0x7A879D8A 11 + 12 + #define SM3_IVA 0x7380166f 13 + #define SM3_IVB 0x4914b2b9 14 + #define SM3_IVC 0x172442d7 15 + #define SM3_IVD 0xda8a0600 16 + #define SM3_IVE 0xa96f30bc 17 + #define SM3_IVF 0x163138aa 18 + #define SM3_IVG 0xe38dee4d 19 + #define SM3_IVH 0xb0fb0e4e 20 + 21 + struct sm3_context { 22 + uint32_t state[SM3_DIGEST_SIZE / 4]; 23 + uint64_t count; /* Message length in bits */ 24 + uint8_t buffer[SM3_BLOCK_SIZE]; 25 + int buflen; 26 + }; 27 + 28 + void sm3_init(struct sm3_context *sctx); 29 + void sm3_update(struct sm3_context *sctx, const uint8_t *input, size_t ilen); 30 + void sm3_final(struct sm3_context *sctx, uint8_t output[SM3_DIGEST_SIZE]); 31 + void sm3_hash(const uint8_t *input, size_t ilen, uint8_t output[SM3_DIGEST_SIZE]); 32 + 33 + void sm3_csum_wd(const unsigned char *input, uint32_t len, 34 + unsigned char *output, unsigned int chunk_sz); 35 + #endif
+7
lib/Kconfig
··· 606 606 The SHA384 algorithm produces a 384-bit (48-byte) hash value 607 607 (digest). 608 608 609 + config SM3 610 + bool "Enable SM3 support" 611 + help 612 + This option enables support of hashing using 613 + SM3 (ShangMi 3) secure hash function (OSCCA GM/T 0004-2012, ISO/IEC 10118-3) 614 + The hash is calculated in software. 615 + 609 616 config SHA_HW_ACCEL 610 617 bool "Enable hardware acceleration for SHA hash functions" 611 618 help
+1
lib/Makefile
··· 81 81 obj-$(CONFIG_$(PHASE_)SHA256) += sha256_common.o 82 82 obj-$(CONFIG_$(PHASE_)SHA256_LEGACY) += sha256.o 83 83 obj-$(CONFIG_$(PHASE_)SHA512_LEGACY) += sha512.o 84 + obj-$(CONFIG_$(PHASE_)SM3) += sm3.o 84 85 85 86 obj-$(CONFIG_CRYPT_PW) += crypt/ 86 87 obj-$(CONFIG_$(PHASE_)ASN1_DECODER_LEGACY) += asn1_decoder.o
+3
lib/efi_loader/efi_tcg2.c
··· 430 430 case TPM2_ALG_SHA512: 431 431 hash_calculate("sha512", regs->reg, regs->num, hash); 432 432 break; 433 + case TPM2_ALG_SM3_256: 434 + hash_calculate("sm3_256", regs->reg, regs->num, hash); 435 + break; 433 436 default: 434 437 continue; 435 438 }
+312
lib/sm3.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * SM3_256 Hash Algorithm Implementation for U-Boot 4 + * based on linux implementation: 5 + * 6 + * f83a4f2a4d8c 7 + * Merge tag 'erofs-for-6.17-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs 8 + * 9 + * SM3 secure hash, as specified by OSCCA GM/T 0004-2012 SM3 and described 10 + * at https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02 11 + * 12 + * Copyright (c) 2025 Heiko Schocher <hs@nabladev.com> 13 + */ 14 + 15 + #include <stdint.h> 16 + #include <stdlib.h> 17 + #include <string.h> 18 + #include <asm/unaligned.h> 19 + #include <linux/bitops.h> 20 + 21 + #include <u-boot/sm3.h> 22 + #ifndef USE_HOSTCC 23 + #include <u-boot/schedule.h> 24 + #endif 25 + 26 + static const u32 K[64] = { 27 + 0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb, 28 + 0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc, 29 + 0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce, 30 + 0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6, 31 + 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c, 32 + 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce, 33 + 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec, 34 + 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5, 35 + 0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53, 36 + 0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d, 37 + 0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4, 38 + 0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43, 39 + 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c, 40 + 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce, 41 + 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec, 42 + 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5 43 + }; 44 + 45 + /* 46 + * Transform the message X which consists of 16 32-bit-words. See 47 + * GM/T 004-2012 for details. 48 + */ 49 + #define R(i, a, b, c, d, e, f, g, h, t, w1, w2) \ 50 + do { \ 51 + ss1 = rol32((rol32((a), 12) + (e) + (t)), 7); \ 52 + ss2 = ss1 ^ rol32((a), 12); \ 53 + d += FF ## i(a, b, c) + ss2 + ((w1) ^ (w2)); \ 54 + h += GG ## i(e, f, g) + ss1 + (w1); \ 55 + b = rol32((b), 9); \ 56 + f = rol32((f), 19); \ 57 + h = P0((h)); \ 58 + } while (0) 59 + 60 + #define R1(a, b, c, d, e, f, g, h, t, w1, w2) \ 61 + R(1, a, b, c, d, e, f, g, h, t, w1, w2) 62 + #define R2(a, b, c, d, e, f, g, h, t, w1, w2) \ 63 + R(2, a, b, c, d, e, f, g, h, t, w1, w2) 64 + 65 + #define FF1(x, y, z) (x ^ y ^ z) 66 + #define FF2(x, y, z) ((x & y) | (x & z) | (y & z)) 67 + 68 + #define GG1(x, y, z) FF1(x, y, z) 69 + #define GG2(x, y, z) ((x & y) | (~x & z)) 70 + 71 + /* Message expansion */ 72 + #define P0(x) ((x) ^ rol32((x), 9) ^ rol32((x), 17)) 73 + #define P1(x) ((x) ^ rol32((x), 15) ^ rol32((x), 23)) 74 + #define I(i) (W[i] = get_unaligned_be32(data + i * 4)) 75 + #define W1(i) (W[i & 0x0f]) 76 + #define W2(i) (W[i & 0x0f] = \ 77 + P1(W[i & 0x0f] \ 78 + ^ W[(i-9) & 0x0f] \ 79 + ^ rol32(W[(i-3) & 0x0f], 15)) \ 80 + ^ rol32(W[(i-13) & 0x0f], 7) \ 81 + ^ W[(i-6) & 0x0f]) 82 + 83 + static void sm3_transform(struct sm3_context *sctx, u8 const *data, u32 W[16]) 84 + { 85 + u32 a, b, c, d, e, f, g, h, ss1, ss2; 86 + 87 + a = sctx->state[0]; 88 + b = sctx->state[1]; 89 + c = sctx->state[2]; 90 + d = sctx->state[3]; 91 + e = sctx->state[4]; 92 + f = sctx->state[5]; 93 + g = sctx->state[6]; 94 + h = sctx->state[7]; 95 + 96 + R1(a, b, c, d, e, f, g, h, K[0], I(0), I(4)); 97 + R1(d, a, b, c, h, e, f, g, K[1], I(1), I(5)); 98 + R1(c, d, a, b, g, h, e, f, K[2], I(2), I(6)); 99 + R1(b, c, d, a, f, g, h, e, K[3], I(3), I(7)); 100 + R1(a, b, c, d, e, f, g, h, K[4], W1(4), I(8)); 101 + R1(d, a, b, c, h, e, f, g, K[5], W1(5), I(9)); 102 + R1(c, d, a, b, g, h, e, f, K[6], W1(6), I(10)); 103 + R1(b, c, d, a, f, g, h, e, K[7], W1(7), I(11)); 104 + R1(a, b, c, d, e, f, g, h, K[8], W1(8), I(12)); 105 + R1(d, a, b, c, h, e, f, g, K[9], W1(9), I(13)); 106 + R1(c, d, a, b, g, h, e, f, K[10], W1(10), I(14)); 107 + R1(b, c, d, a, f, g, h, e, K[11], W1(11), I(15)); 108 + R1(a, b, c, d, e, f, g, h, K[12], W1(12), W2(16)); 109 + R1(d, a, b, c, h, e, f, g, K[13], W1(13), W2(17)); 110 + R1(c, d, a, b, g, h, e, f, K[14], W1(14), W2(18)); 111 + R1(b, c, d, a, f, g, h, e, K[15], W1(15), W2(19)); 112 + 113 + R2(a, b, c, d, e, f, g, h, K[16], W1(16), W2(20)); 114 + R2(d, a, b, c, h, e, f, g, K[17], W1(17), W2(21)); 115 + R2(c, d, a, b, g, h, e, f, K[18], W1(18), W2(22)); 116 + R2(b, c, d, a, f, g, h, e, K[19], W1(19), W2(23)); 117 + R2(a, b, c, d, e, f, g, h, K[20], W1(20), W2(24)); 118 + R2(d, a, b, c, h, e, f, g, K[21], W1(21), W2(25)); 119 + R2(c, d, a, b, g, h, e, f, K[22], W1(22), W2(26)); 120 + R2(b, c, d, a, f, g, h, e, K[23], W1(23), W2(27)); 121 + R2(a, b, c, d, e, f, g, h, K[24], W1(24), W2(28)); 122 + R2(d, a, b, c, h, e, f, g, K[25], W1(25), W2(29)); 123 + R2(c, d, a, b, g, h, e, f, K[26], W1(26), W2(30)); 124 + R2(b, c, d, a, f, g, h, e, K[27], W1(27), W2(31)); 125 + R2(a, b, c, d, e, f, g, h, K[28], W1(28), W2(32)); 126 + R2(d, a, b, c, h, e, f, g, K[29], W1(29), W2(33)); 127 + R2(c, d, a, b, g, h, e, f, K[30], W1(30), W2(34)); 128 + R2(b, c, d, a, f, g, h, e, K[31], W1(31), W2(35)); 129 + 130 + R2(a, b, c, d, e, f, g, h, K[32], W1(32), W2(36)); 131 + R2(d, a, b, c, h, e, f, g, K[33], W1(33), W2(37)); 132 + R2(c, d, a, b, g, h, e, f, K[34], W1(34), W2(38)); 133 + R2(b, c, d, a, f, g, h, e, K[35], W1(35), W2(39)); 134 + R2(a, b, c, d, e, f, g, h, K[36], W1(36), W2(40)); 135 + R2(d, a, b, c, h, e, f, g, K[37], W1(37), W2(41)); 136 + R2(c, d, a, b, g, h, e, f, K[38], W1(38), W2(42)); 137 + R2(b, c, d, a, f, g, h, e, K[39], W1(39), W2(43)); 138 + R2(a, b, c, d, e, f, g, h, K[40], W1(40), W2(44)); 139 + R2(d, a, b, c, h, e, f, g, K[41], W1(41), W2(45)); 140 + R2(c, d, a, b, g, h, e, f, K[42], W1(42), W2(46)); 141 + R2(b, c, d, a, f, g, h, e, K[43], W1(43), W2(47)); 142 + R2(a, b, c, d, e, f, g, h, K[44], W1(44), W2(48)); 143 + R2(d, a, b, c, h, e, f, g, K[45], W1(45), W2(49)); 144 + R2(c, d, a, b, g, h, e, f, K[46], W1(46), W2(50)); 145 + R2(b, c, d, a, f, g, h, e, K[47], W1(47), W2(51)); 146 + 147 + R2(a, b, c, d, e, f, g, h, K[48], W1(48), W2(52)); 148 + R2(d, a, b, c, h, e, f, g, K[49], W1(49), W2(53)); 149 + R2(c, d, a, b, g, h, e, f, K[50], W1(50), W2(54)); 150 + R2(b, c, d, a, f, g, h, e, K[51], W1(51), W2(55)); 151 + R2(a, b, c, d, e, f, g, h, K[52], W1(52), W2(56)); 152 + R2(d, a, b, c, h, e, f, g, K[53], W1(53), W2(57)); 153 + R2(c, d, a, b, g, h, e, f, K[54], W1(54), W2(58)); 154 + R2(b, c, d, a, f, g, h, e, K[55], W1(55), W2(59)); 155 + R2(a, b, c, d, e, f, g, h, K[56], W1(56), W2(60)); 156 + R2(d, a, b, c, h, e, f, g, K[57], W1(57), W2(61)); 157 + R2(c, d, a, b, g, h, e, f, K[58], W1(58), W2(62)); 158 + R2(b, c, d, a, f, g, h, e, K[59], W1(59), W2(63)); 159 + R2(a, b, c, d, e, f, g, h, K[60], W1(60), W2(64)); 160 + R2(d, a, b, c, h, e, f, g, K[61], W1(61), W2(65)); 161 + R2(c, d, a, b, g, h, e, f, K[62], W1(62), W2(66)); 162 + R2(b, c, d, a, f, g, h, e, K[63], W1(63), W2(67)); 163 + 164 + sctx->state[0] ^= a; 165 + sctx->state[1] ^= b; 166 + sctx->state[2] ^= c; 167 + sctx->state[3] ^= d; 168 + sctx->state[4] ^= e; 169 + sctx->state[5] ^= f; 170 + sctx->state[6] ^= g; 171 + sctx->state[7] ^= h; 172 + } 173 + #undef R 174 + #undef R1 175 + #undef R2 176 + #undef I 177 + #undef W1 178 + #undef W2 179 + 180 + static inline void sm3_block(struct sm3_context *sctx, 181 + u8 const *data, int blocks, u32 W[16]) 182 + { 183 + while (blocks--) { 184 + sm3_transform(sctx, data, W); 185 + data += SM3_BLOCK_SIZE; 186 + } 187 + } 188 + 189 + void sm3_init(struct sm3_context *sctx) 190 + { 191 + memset(sctx, 0, sizeof(*sctx)); 192 + 193 + /* Load initial values */ 194 + sctx->state[0] = SM3_IVA; 195 + sctx->state[1] = SM3_IVB; 196 + sctx->state[2] = SM3_IVC; 197 + sctx->state[3] = SM3_IVD; 198 + sctx->state[4] = SM3_IVE; 199 + sctx->state[5] = SM3_IVF; 200 + sctx->state[6] = SM3_IVG; 201 + sctx->state[7] = SM3_IVH; 202 + sctx->count = 0; 203 + } 204 + 205 + void sm3_update(struct sm3_context *sctx, const uint8_t *input, size_t ilen) 206 + { 207 + unsigned int partial = sctx->count % SM3_BLOCK_SIZE; 208 + u32 W[16]; 209 + 210 + sctx->count += ilen; 211 + 212 + if ((partial + ilen) >= SM3_BLOCK_SIZE) { 213 + int blocks; 214 + 215 + if (partial) { 216 + int p = SM3_BLOCK_SIZE - partial; 217 + 218 + memcpy(sctx->buffer + partial, input, p); 219 + input += p; 220 + ilen -= p; 221 + 222 + sm3_block(sctx, sctx->buffer, 1, W); 223 + } 224 + 225 + blocks = ilen / SM3_BLOCK_SIZE; 226 + ilen %= SM3_BLOCK_SIZE; 227 + 228 + if (blocks) { 229 + sm3_block(sctx, input, blocks, W); 230 + input += blocks * SM3_BLOCK_SIZE; 231 + } 232 + 233 + memset(W, 0, sizeof(W)); 234 + 235 + partial = 0; 236 + } 237 + if (ilen) 238 + memcpy(sctx->buffer + partial, input, ilen); 239 + } 240 + 241 + void sm3_final(struct sm3_context *sctx, uint8_t output[SM3_DIGEST_SIZE]) 242 + { 243 + const int bit_offset = SM3_BLOCK_SIZE - sizeof(u64); 244 + __be64 *bits = (__be64 *)(sctx->buffer + bit_offset); 245 + __be32 *digest = (__be32 *)&output[0]; 246 + unsigned int partial = sctx->count % SM3_BLOCK_SIZE; 247 + u32 W[16]; 248 + int i; 249 + 250 + sctx->buffer[partial++] = 0x80; 251 + if (partial > bit_offset) { 252 + memset(sctx->buffer + partial, 0, SM3_BLOCK_SIZE - partial); 253 + partial = 0; 254 + 255 + sm3_block(sctx, sctx->buffer, 1, W); 256 + } 257 + 258 + memset(sctx->buffer + partial, 0, bit_offset - partial); 259 + *bits = cpu_to_be64(sctx->count << 3); 260 + sm3_block(sctx, sctx->buffer, 1, W); 261 + 262 + for (i = 0; i < 8; i++) 263 + put_unaligned_be32(sctx->state[i], digest++); 264 + 265 + /* Zeroize sensitive information. */ 266 + memset(W, 0, sizeof(W)); 267 + memset(sctx, 0, sizeof(*sctx)); 268 + } 269 + 270 + /** 271 + * sm3_hash - Calculate SM3 hash of input data 272 + * @input: Input data 273 + * @ilen: Input data length in bytes 274 + * @output: Output buffer for hash (32 bytes) 275 + */ 276 + void sm3_hash(const uint8_t *input, size_t ilen, uint8_t output[SM3_DIGEST_SIZE]) 277 + { 278 + struct sm3_context sctx; 279 + 280 + sm3_init(&sctx); 281 + sm3_update(&sctx, input, ilen); 282 + sm3_final(&sctx, output); 283 + } 284 + 285 + /** 286 + * sm3_csum_wd - Calculate SM3 checksum on memory region using watchdog 287 + * @addr: Starting address 288 + * @len: Length in bytes 289 + * @output: Output buffer for checksum (32 bytes) 290 + * @flags: Flags for watchdog behavior 291 + * 292 + * This is the U-Boot API entry function for SM3 hash calculation 293 + */ 294 + void sm3_csum_wd(const unsigned char *input, uint32_t len, 295 + unsigned char *output, unsigned int chunk_sz) 296 + { 297 + struct sm3_context ctx; 298 + uint32_t chunk; 299 + 300 + sm3_init(&ctx); 301 + 302 + /* Process data in chunks, kicking watchdog between chunks */ 303 + while (len > 0) { 304 + chunk = (len > chunk_sz) ? chunk_sz : len; 305 + sm3_update(&ctx, input, chunk); 306 + input += chunk; 307 + len -= chunk; 308 + 309 + schedule(); 310 + } 311 + sm3_final(&ctx, output); 312 + }
+2 -2
lib/tpm-v2.c
··· 686 686 687 687 pcrs->count = get_unaligned_be32(response); 688 688 /* 689 - * We only support 4 algorithms for now so check against that 689 + * check against the supported algorithms in hash_algo_list, 690 690 * instead of TPM2_NUM_PCR_BANKS 691 691 */ 692 - if (pcrs->count > 4 || pcrs->count < 1) { 692 + if (pcrs->count > ARRAY_SIZE(hash_algo_list) || pcrs->count < 1) { 693 693 printf("%s: too many pcrs: %u\n", __func__, pcrs->count); 694 694 return -EMSGSIZE; 695 695 }
+9
lib/tpm_tcg2.c
··· 12 12 #include <u-boot/sha1.h> 13 13 #include <u-boot/sha256.h> 14 14 #include <u-boot/sha512.h> 15 + #include <u-boot/sm3.h> 15 16 #include <version_string.h> 16 17 #include <asm/io.h> 17 18 #include <linux/bitops.h> ··· 144 145 len = TPM2_SHA512_DIGEST_SIZE; 145 146 break; 146 147 #endif 148 + #if IS_ENABLED(CONFIG_SM3) 149 + case TPM2_ALG_SM3_256: 150 + sm3_hash(input, length, final); 151 + len = TPM2_SM3_256_DIGEST_SIZE; 152 + break; 153 + #endif 147 154 default: 148 155 printf("%s: unsupported algorithm %x\n", __func__, 149 156 priv->active_banks[i]); ··· 319 326 case TPM2_ALG_SHA256: 320 327 case TPM2_ALG_SHA384: 321 328 case TPM2_ALG_SHA512: 329 + case TPM2_ALG_SM3_256: 322 330 len = tpm2_algorithm_to_len(algo); 323 331 break; 324 332 default: ··· 431 439 case TPM2_ALG_SHA256: 432 440 case TPM2_ALG_SHA384: 433 441 case TPM2_ALG_SHA512: 442 + case TPM2_ALG_SM3_256: 434 443 len = get_unaligned_le16(&event->digest_sizes[i].digest_size); 435 444 if (tpm2_algorithm_to_len(algo) != len) { 436 445 log_err("EventLog invalid algorithm length\n");
+48 -1
test/cmd/hash.c
··· 9 9 #include <env.h> 10 10 #include <dm.h> 11 11 #include <dm/test.h> 12 + #include <test/cmd.h> 12 13 #include <test/test.h> 13 14 #include <test/ut.h> 14 15 ··· 38 39 "d41d8cd98f00b204e9800998ecf8427e")); 39 40 40 41 if (!CONFIG_IS_ENABLED(HASH_VERIFY)) { 41 - ut_assert(run_command("hash -v sha256 $loadaddr 0 foo", 0)); 42 + ut_assert(run_command("hash -v md5 $loadaddr 0 foo", 0)); 42 43 ut_assertok(ut_check_console_line( 43 44 uts, "hash - compute hash message digest")); 44 45 ··· 103 104 return 0; 104 105 } 105 106 DM_TEST(dm_test_cmd_hash_sha256, UTF_CONSOLE); 107 + 108 + static int cmd_test_hash_sm3_256(struct unit_test_state *uts) 109 + { 110 + const char *sum = "1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b"; 111 + 112 + if (!CONFIG_IS_ENABLED(SM3)) { 113 + ut_assert(run_command("hash sm3_256 $loadaddr 0", 0)); 114 + 115 + return 0; 116 + } 117 + 118 + ut_assertok(run_command("hash sm3_256 $loadaddr 0", 0)); 119 + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); 120 + ut_asserteq_ptr(uts->actual_str, 121 + strstr(uts->actual_str, "sm3_256 for ")); 122 + ut_assert(strstr(uts->actual_str, sum)); 123 + ut_assert_console_end(); 124 + 125 + ut_assertok(run_command("hash sm3_256 $loadaddr 0 foo; echo $foo", 0)); 126 + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); 127 + ut_asserteq_ptr(uts->actual_str, 128 + strstr(uts->actual_str, "sm3_256 for ")); 129 + ut_assert(strstr(uts->actual_str, sum)); 130 + ut_assertok(ut_check_console_line(uts, sum)); 131 + 132 + if (!CONFIG_IS_ENABLED(HASH_VERIFY)) { 133 + ut_assert(run_command("hash -v sm3_256 $loadaddr 0 foo", 0)); 134 + ut_assertok(ut_check_console_line(uts, 135 + "hash - compute hash message digest")); 136 + 137 + return 0; 138 + } 139 + 140 + ut_assertok(run_command("hash -v sm3_256 $loadaddr 0 foo", 0)); 141 + ut_assert_console_end(); 142 + 143 + env_set("foo", 144 + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); 145 + ut_assert(run_command("hash -v sm3_256 $loadaddr 0 foo", 0)); 146 + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); 147 + ut_assert(strstr(uts->actual_str, "!=")); 148 + ut_assert_console_end(); 149 + 150 + return 0; 151 + } 152 + CMD_TEST(cmd_test_hash_sm3_256, UTF_CONSOLE);