This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 66703d09573e30f81083bb36ac3d58c50712facb Author: Jukka Laitinen <[email protected]> AuthorDate: Fri Sep 18 18:23:09 2026 +0300 tools/imxrt1180: Add a standalone C program for simple AHAB container creation Add a standalone tool to create AHAB container for imxrt118x. This can generate a trivial unsigned image without appending ELE. The tool can be used to create bootable images for m33. To do anything more complicated, the user needs to use the official SPSDK tool from NXP. Assisted-by: Claude Code:claude-opus-5-0 Signed-off-by: Jukka Laitinen <[email protected]> --- boards/arm/imxrt/imxrt1180-evk/scripts/Make.defs | 28 +- tools/imxrt1180/Makefile.host | 45 +++ tools/imxrt1180/mkahab.c | 359 +++++++++++++++++++++++ tools/imxrt1180/sha256.c | 239 +++++++++++++++ tools/imxrt1180/sha256.h | 70 +++++ 5 files changed, 729 insertions(+), 12 deletions(-) diff --git a/boards/arm/imxrt/imxrt1180-evk/scripts/Make.defs b/boards/arm/imxrt/imxrt1180-evk/scripts/Make.defs index fe524e1b900..b23943a5dd9 100644 --- a/boards/arm/imxrt/imxrt1180-evk/scripts/Make.defs +++ b/boards/arm/imxrt/imxrt1180-evk/scripts/Make.defs @@ -53,12 +53,10 @@ AFLAGS := $(CFLAGS) -D__ASSEMBLY__ # Programmed at FlexSPI offset 0 (flash address 0x28000000). The M33 # image is confined to the first 512 KB of NOR. # -# The AHAB container is assembled by NXP SPSDK "nxpimage". The build -# script bootstraps a private SPSDK venv on first run (see -# tools/imxrt1180/build_flash_image.sh for the license note and cache -# location). - -FLASH_BUILDER = $(TOPDIR)$(DELIM)tools$(DELIM)imxrt1180$(DELIM)build_flash_image.sh +# The AHAB container is a single, unsigned application container. +# In the simples case, use a standalone tools/imxrt1180/mkahab host tool +# to create the container. If ELE FW is needed, download and use the the +# full SPSDK toolkit. ifeq ($(CONFIG_IMXRT_ELE_FW),y) include $(TOPDIR)/tools/imxrt1180/Config.mk @@ -70,13 +68,17 @@ include $(TOPDIR)/tools/imxrt1180/Config.mk endif ifeq ($(CONFIG_IMXRT_ELE_FW),y) -ifeq ($(CONFIG_IMXRT_ELE_LOAD_FW),y) -FLASH_BUILDER_ELE_FW_ARGS = -else -FLASH_BUILDER_ELE_FW_ARGS = --ele-fw $(IMXRT_ELE_FW_ABS) +ifneq ($(CONFIG_IMXRT_ELE_LOAD_FW),y) +FLASH_BUILDER_NEEDS_SPSDK = 1 endif +endif + +ifeq ($(FLASH_BUILDER_NEEDS_SPSDK),1) +FLASH_BUILDER = $(TOPDIR)$(DELIM)tools$(DELIM)imxrt1180$(DELIM)build_flash_image.sh +FLASH_BUILDER_ARGS = --ele-fw $(IMXRT_ELE_FW_ABS) else -FLASH_BUILDER_ELE_FW_ARGS = +FLASH_BUILDER = $(TOPDIR)$(DELIM)tools$(DELIM)imxrt1180$(DELIM)mkahab$(HOSTEXEEXT) +FLASH_BUILDER_ARGS = endif ifeq ($(CONFIG_ARCH_CORTEXM33),y) @@ -84,10 +86,12 @@ define POSTBUILD $(Q) echo "Assembling MIMXRT1180-EVK FlexSPI NOR image (CM33 target)" $(Q) $(OBJCOPY) -O binary -R .bss -R .initstack $(BIN) nuttx.bin $(if $(IMXRT_ELE_FW_ABS),$(Q) $(MAKE) $(IMXRT_ELE_FW_ABS)) + $(if $(filter 1,$(FLASH_BUILDER_NEEDS_SPSDK)),,+$(Q) $(MAKE) -C $(TOPDIR)$(DELIM)tools$(DELIM)imxrt1180 -f Makefile.host) $(Q) $(FLASH_BUILDER) \ --m33 nuttx.bin \ --out flash.bin \ - $(FLASH_BUILDER_ELE_FW_ARGS) + $(FLASH_BUILDER_ARGS) + $(if $(filter 1,$(FLASH_BUILDER_NEEDS_SPSDK)),,+$(Q) $(MAKE) -C $(TOPDIR)$(DELIM)tools$(DELIM)imxrt1180 -f Makefile.host clean) $(Q) echo "flash.bin" >> nuttx.manifest endef else diff --git a/tools/imxrt1180/Makefile.host b/tools/imxrt1180/Makefile.host new file mode 100644 index 00000000000..c121ce809c3 --- /dev/null +++ b/tools/imxrt1180/Makefile.host @@ -0,0 +1,45 @@ +############################################################################ +# tools/imxrt1180/Makefile.host +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +all: mkahab +default: mkahab +.PHONY: clean + +# Add CFLAGS=-g on the make command line to build debug versions + +CFLAGS = -g -O2 -Wall -Wextra -std=c99 + +# mkahab - assemble the unsigned RT1180 AHAB container + flash.bin +# entirely natively (no Python/pip/network dependency); see +# mkahab.c for details. + +mkahab: mkahab.c sha256.c sha256.h + @gcc $(CFLAGS) -o mkahab mkahab.c sha256.c + +clean: +ifneq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) rm -rf *.dSYM +endif + $(call DELFILE, mkahab) + $(call DELFILE, mkahab.exe) + $(call CLEAN) diff --git a/tools/imxrt1180/mkahab.c b/tools/imxrt1180/mkahab.c new file mode 100644 index 00000000000..399e0d744b0 --- /dev/null +++ b/tools/imxrt1180/mkahab.c @@ -0,0 +1,359 @@ +/**************************************************************************** + * tools/imxrt1180/mkahab.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* mkahab - assemble the MIMXRT1180-EVK bootable FlexSPI NOR image + * (flash.bin) from the freshly built Cortex-M33 NuttX image, by + * writing a single, unsigned NXP AHAB container directly. + * + * This is a native, dependency-free replacement for the "nxpimage ahab + * export" step of tools/imxrt1180/build_flash_image.sh, covering exactly + * the case that board configuration actually needs today: a single + * unencrypted, unsigned application container (srk_set: none) holding + * the M33 image, with no bundled NXP EdgeLock Enclave firmware + * container. + * + * If a build needs to bundle the proprietary ELE firmware AHAB container + * as well (CONFIG_IMXRT_ELE_FW=y with CONFIG_IMXRT_ELE_LOAD_FW unset), + * tools/imxrt1180/build_flash_image.sh (which drives NXP's SPSDK + * "nxpimage") is used instead; see boards/arm/imxrt/imxrt1180-evk/ + * scripts/Make.defs. + * + * The on-disk container layout (tag, field offsets, sizes) mirrors the + * NXP AHAB "container header" / "image array entry" structures used + * across the i.MX8/i.MX9/RT117x/RT118x families, as documented in the + * RT1180 Reference Manual (ch. 12) and cross-checked byte-for-byte + * against the output of "nxpimage ahab export" for this board's + * configuration. This file is an original implementation of that + * (hardware-mandated, non-copyrightable) layout - it is not derived + * from any NXP or SPSDK source code. + * + * Usage: + * + * mkahab --m33 nuttx.bin --out flash.bin + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <stdbool.h> +#include <sys/stat.h> + +#include "sha256.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Flash layout constants (must match flash-m33.ld). */ + +#define M33_LOAD_ADDR 0x2800b000u +#define FLASH_ORIGIN 0x28000000u +#define M33_MAX_SIZE (512u * 1024u) + +#define FCB_SIZE 512u +#define FCB_FLASH_OFFSET 0x400u +#define AHAB_FLASH_OFFSET 0x1000u + +/* Where the code starts inside the raw M33 input binary: the linker + * places the FCB at VMA 0x28000400 and the XIP code at VMA 0x2800b000, + * and arm-none-eabi-objcopy lays these out as a flat binary starting + * from the lowest section VMA, so the FCB sits at file offset 0 and the + * code sits at file offset (0xb000 - 0x400). + */ + +#define CODE_FILE_OFFSET (0xb000u - 0x400u) + +/* AHAB container header ("flash_header_v3") field layout. */ + +#define AHAB_TAG 0x87u +#define AHAB_HDR_SIZE 16u + +/* Signature block header tag: present (with a valid length/tag) even + * for an unsigned container - only the SRK table/cert/blob/signature + * offsets and payload are empty. + */ + +#define AHAB_SIGBLK_TAG 0x90u + +/* Image array entry ("boot_img") field layout. */ + +#define AHAB_IMG_HASH_LEN 64u +#define AHAB_IMG_IV_LEN 32u +#define AHAB_IMG_SIZE (4u + 4u + 8u + 8u + 4u + 4u + \ + AHAB_IMG_HASH_LEN + AHAB_IMG_IV_LEN) + +/* Signature block header, present (but empty/zero) even for an unsigned + * container. + */ + +#define AHAB_SIGBLK_HDR_SIZE 16u + +#define AHAB_CONTAINER_SIZE (AHAB_HDR_SIZE + AHAB_IMG_SIZE + \ + AHAB_SIGBLK_HDR_SIZE) + +/* Image array entry flags: image type EXECUTABLE, core id CORTEX-M33 + * (RT118x AHAB core id 1 - distinct from the i.MX8/9 core id space), + * hash type SHA-256, not encrypted. + */ + +#define AHAB_IMG_TYPE_EXEC 0x03u +#define AHAB_CORE_ID_M33 0x01u +#define AHAB_HASH_TYPE_SHA256 0x00u + +#define AHAB_IMG_FLAGS \ + (AHAB_IMG_TYPE_EXEC | (AHAB_CORE_ID_M33 << 4) | \ + (AHAB_HASH_TYPE_SHA256 << 8)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void err(const char *msg) +{ + fprintf(stderr, "error: %s\n", msg); + exit(1); +} + +static void put_u16(uint8_t *p, uint16_t v) +{ + p[0] = (uint8_t)(v); + p[1] = (uint8_t)(v >> 8); +} + +static void put_u32(uint8_t *p, uint32_t v) +{ + p[0] = (uint8_t)(v); + p[1] = (uint8_t)(v >> 8); + p[2] = (uint8_t)(v >> 16); + p[3] = (uint8_t)(v >> 24); +} + +static void put_u64(uint8_t *p, uint64_t v) +{ + put_u32(p, (uint32_t)v); + put_u32(p + 4, (uint32_t)(v >> 32)); +} + +static uint8_t *read_file(const char *path, size_t *size) +{ + FILE *f; + uint8_t *buf; + long len; + + f = fopen(path, "rb"); + if (f == NULL) + { + fprintf(stderr, "error: cannot open '%s'\n", path); + exit(1); + } + + if (fseek(f, 0, SEEK_END) != 0) + { + err("fseek failed"); + } + + len = ftell(f); + if (len < 0) + { + err("ftell failed"); + } + + rewind(f); + + buf = malloc((size_t)len); + if (buf == NULL && len > 0) + { + err("out of memory"); + } + + if (len > 0 && fread(buf, 1, (size_t)len, f) != (size_t)len) + { + err("short read"); + } + + fclose(f); + + *size = (size_t)len; + return buf; +} + +/* Build the 160-byte AHAB container (header + one image array entry + + * empty signature block header) covering the M33 XIP code image. + */ + +static void build_ahab_container(uint8_t *out, const uint8_t *code, + size_t code_size, uint32_t image_offset) +{ + uint8_t digest[SHA256_DIGEST_SIZE]; + uint8_t *hdr = out; + uint8_t *img = out + AHAB_HDR_SIZE; + uint8_t *sig = img + AHAB_IMG_SIZE; + + memset(out, 0, AHAB_CONTAINER_SIZE); + + /* Container header: version(u8) length(u16) tag(u8) flags(u32) + * sw_version(u16) fuse_version(u8) num_images(u8) + * sig_blk_offset(u16) reserved(u16) + */ + + hdr[0] = 0; + put_u16(hdr + 1, (uint16_t)AHAB_CONTAINER_SIZE); + hdr[3] = AHAB_TAG; + put_u32(hdr + 4, 0); + put_u16(hdr + 8, 0); + hdr[10] = 0; + hdr[11] = 1; + put_u16(hdr + 12, (uint16_t)(AHAB_HDR_SIZE + AHAB_IMG_SIZE)); + put_u16(hdr + 14, 0); + + /* Image array entry: offset(u32) size(u32) dst(u64) entry(u64) + * flags(u32) meta(u32) hash[64] iv[32] + */ + + put_u32(img, image_offset); + put_u32(img + 4, (uint32_t)code_size); + put_u64(img + 8, M33_LOAD_ADDR); + put_u64(img + 16, M33_LOAD_ADDR); + put_u32(img + 24, AHAB_IMG_FLAGS); + put_u32(img + 28, 0); + + sha256_buffer(code, code_size, digest); + memcpy(img + 32, digest, SHA256_DIGEST_SIZE); + + /* The remaining hash bytes and the iv[] field stay zero */ + + /* Signature block header: version(u8) length(u16) tag(u8) + * srk_table_offset(u16) cert_offset(u16) blob_offset(u16) + * signature_offset(u16) reserved(u32). Only the length and tag are + * non-zero: there is no SRK table, cert, blob or signature (matches + * srk_set: none - unsigned container). + */ + + sig[0] = 0; + put_u16(sig + 1, (uint16_t)AHAB_SIGBLK_HDR_SIZE); + sig[3] = AHAB_SIGBLK_TAG; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, char *argv[]) +{ + const char *m33_path = NULL; + const char *out_path = "flash.bin"; + uint8_t *src; + size_t src_size; + uint32_t code_flash_offset; + uint32_t image_offset; + uint8_t *code; + size_t code_size; + uint8_t ahab[AHAB_CONTAINER_SIZE]; + uint8_t *out; + size_t total; + FILE *f; + int i; + + for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "--m33") == 0 && i + 1 < argc) + { + m33_path = argv[++i]; + } + else if (strcmp(argv[i], "--out") == 0 && i + 1 < argc) + { + out_path = argv[++i]; + } + else + { + fprintf(stderr, "usage: %s --m33 <nuttx.bin> --out <flash.bin>\n", + argv[0]); + return 1; + } + } + + if (m33_path == NULL) + { + err("--m33 <nuttx.bin> is required"); + } + + src = read_file(m33_path, &src_size); + + if (src_size <= CODE_FILE_OFFSET) + { + err("input binary shorter than expected"); + } + + code = src + CODE_FILE_OFFSET; + code_size = src_size - CODE_FILE_OFFSET; + + code_flash_offset = M33_LOAD_ADDR - FLASH_ORIGIN; + image_offset = code_flash_offset - AHAB_FLASH_OFFSET; + + build_ahab_container(ahab, code, code_size, image_offset); + + total = AHAB_FLASH_OFFSET + image_offset + code_size; + if (total > M33_MAX_SIZE) + { + fprintf(stderr, + "error: M33 image (%zu B) exceeds the %u B reserve; it " + "would overlap the Cortex-M7 image at flash offset " + "0x80000.\n", total, M33_MAX_SIZE); + return 1; + } + + out = calloc(1, total); + if (out == NULL) + { + err("out of memory"); + } + + memcpy(out + FCB_FLASH_OFFSET, src, FCB_SIZE); + memcpy(out + AHAB_FLASH_OFFSET, ahab, AHAB_CONTAINER_SIZE); + memcpy(out + AHAB_FLASH_OFFSET + image_offset, code, code_size); + + f = fopen(out_path, "wb"); + if (f == NULL) + { + fprintf(stderr, "error: cannot create '%s'\n", out_path); + return 1; + } + + if (fwrite(out, 1, total, f) != total) + { + err("short write"); + } + + fclose(f); + + printf("Wrote %s (FCB@0x%x, M33 AHAB@0x%x, %zu B)\n", + out_path, FCB_FLASH_OFFSET, AHAB_FLASH_OFFSET, total); + + free(src); + free(out); + return 0; +} diff --git a/tools/imxrt1180/sha256.c b/tools/imxrt1180/sha256.c new file mode 100644 index 00000000000..9c368335f71 --- /dev/null +++ b/tools/imxrt1180/sha256.c @@ -0,0 +1,239 @@ +/**************************************************************************** + * tools/imxrt1180/sha256.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Straightforward implementation of the SHA-256 algorithm as specified in + * FIPS 180-4. Only used to compute the image digest embedded in the + * RT1180 AHAB container header (see mkahab.c), so it favors clarity over + * speed. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <string.h> + +#include "sha256.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) + +#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z))) +#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#define BSIG0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define BSIG1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define SSIG0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3)) +#define SSIG1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10)) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint32_t g_sha256_k[64] = +{ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void sha256_transform(struct sha256_ctx_s *ctx, + const uint8_t block[64]) +{ + uint32_t w[64]; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t e; + uint32_t f; + uint32_t g; + uint32_t h; + uint32_t t1; + uint32_t t2; + int i; + + for (i = 0; i < 16; i++) + { + w[i] = ((uint32_t)block[i * 4] << 24) | + ((uint32_t)block[i * 4 + 1] << 16) | + ((uint32_t)block[i * 4 + 2] << 8) | + ((uint32_t)block[i * 4 + 3]); + } + + for (i = 16; i < 64; i++) + { + w[i] = SSIG1(w[i - 2]) + w[i - 7] + SSIG0(w[i - 15]) + w[i - 16]; + } + + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; + + for (i = 0; i < 64; i++) + { + t1 = h + BSIG1(e) + CH(e, f, g) + g_sha256_k[i] + w[i]; + t2 = BSIG0(a) + MAJ(a, b, c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void sha256_init(struct sha256_ctx_s *ctx) +{ + ctx->state[0] = 0x6a09e667; + ctx->state[1] = 0xbb67ae85; + ctx->state[2] = 0x3c6ef372; + ctx->state[3] = 0xa54ff53a; + ctx->state[4] = 0x510e527f; + ctx->state[5] = 0x9b05688c; + ctx->state[6] = 0x1f83d9ab; + ctx->state[7] = 0x5be0cd19; + ctx->bitcount = 0; +} + +void sha256_update(struct sha256_ctx_s *ctx, const void *data, size_t len) +{ + const uint8_t *p = data; + size_t buf_used = (size_t)((ctx->bitcount / 8) % 64); + + ctx->bitcount += (uint64_t)len * 8; + + while (len > 0) + { + size_t n = 64 - buf_used; + + if (n > len) + { + n = len; + } + + memcpy(ctx->buf + buf_used, p, n); + buf_used += n; + p += n; + len -= n; + + if (buf_used == 64) + { + sha256_transform(ctx, ctx->buf); + buf_used = 0; + } + } +} + +void sha256_final(struct sha256_ctx_s *ctx, + uint8_t digest[SHA256_DIGEST_SIZE]) +{ + size_t buf_used = (size_t)((ctx->bitcount / 8) % 64); + uint64_t bitcount = ctx->bitcount; + uint8_t pad = 0x80; + int i; + + sha256_update(ctx, &pad, 1); + + buf_used = (size_t)((ctx->bitcount / 8) % 64); + while (buf_used != 56) + { + uint8_t zero = 0; + + sha256_update(ctx, &zero, 1); + buf_used = (size_t)((ctx->bitcount / 8) % 64); + } + + { + uint8_t lenbytes[8]; + + for (i = 0; i < 8; i++) + { + lenbytes[i] = (uint8_t)(bitcount >> (56 - i * 8)); + } + + /* Append length directly without going through sha256_update()'s + * bitcount accounting (the length field itself is not counted). + */ + + memcpy(ctx->buf + 56, lenbytes, 8); + sha256_transform(ctx, ctx->buf); + } + + for (i = 0; i < 8; i++) + { + digest[i * 4] = (uint8_t)(ctx->state[i] >> 24); + digest[i * 4 + 1] = (uint8_t)(ctx->state[i] >> 16); + digest[i * 4 + 2] = (uint8_t)(ctx->state[i] >> 8); + digest[i * 4 + 3] = (uint8_t)(ctx->state[i]); + } +} + +void sha256_buffer(const void *data, size_t len, + uint8_t digest[SHA256_DIGEST_SIZE]) +{ + struct sha256_ctx_s ctx; + + sha256_init(&ctx); + sha256_update(&ctx, data, len); + sha256_final(&ctx, digest); +} diff --git a/tools/imxrt1180/sha256.h b/tools/imxrt1180/sha256.h new file mode 100644 index 00000000000..71af46055b5 --- /dev/null +++ b/tools/imxrt1180/sha256.h @@ -0,0 +1,70 @@ +/**************************************************************************** + * tools/imxrt1180/sha256.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* A minimal, self-contained SHA-256 implementation (FIPS 180-4) for the + * host-side "mkahab" tool. Written from the published algorithm + * specification so this host build tool has no dependency on OpenSSL or + * any other third-party library. + */ + +#ifndef __TOOLS_IMXRT1180_SHA256_H +#define __TOOLS_IMXRT1180_SHA256_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stddef.h> +#include <stdint.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SHA256_DIGEST_SIZE 32 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct sha256_ctx_s +{ + uint32_t state[8]; + uint64_t bitcount; + uint8_t buf[64]; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void sha256_init(struct sha256_ctx_s *ctx); +void sha256_update(struct sha256_ctx_s *ctx, const void *data, size_t len); +void sha256_final(struct sha256_ctx_s *ctx, + uint8_t digest[SHA256_DIGEST_SIZE]); + +/* Convenience one-shot helper */ + +void sha256_buffer(const void *data, size_t len, + uint8_t digest[SHA256_DIGEST_SIZE]); + +#endif /* __TOOLS_IMXRT1180_SHA256_H */
