Commit Graph

80 Commits

Author SHA1 Message Date
Shiji Yang
961e260cdc lib: rsa: fix compilation error without openssl
The symbol TOOLS_IMAGE_PRE_LOAD doesn't depend on TOOLS_LIBCRYPTO.
If we choose to build tools without openssl, rsa_verify_openssl()
will attempt to call the unavailable openssl library functions.

Fixes: 942c8c8e66 ("rsa: Add rsa_verify_openssl() to use openssl for host builds")
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
2025-06-22 10:16:39 -06:00
Tom Rini
5bc4240eb6 Merge patch series "rsa: Add rsa_verify_openssl() to use openssl for host builds"
Paul HENRYS <paul.henrys_ext@softathome.com> says:

This serie of patches adds a new tool to authenticate files signed with
a preload header.  This tool is also used in the tests to actually
verify the authenticity of the file signed with such a preload header.

Link: https://lore.kernel.org/r/20250224212055.2992852-1-paul.henrys_ext@softathome.com
2025-02-28 16:51:10 -06:00
Paul HENRYS
942c8c8e66 rsa: Add rsa_verify_openssl() to use openssl for host builds
rsa_verify_openssl() is used in lib/rsa/rsa-verify.c to authenticate data
when building host tools.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
2025-02-28 16:51:01 -06:00
Tom Rini
3ecda19009 Prepare v2025.04-rc3
-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEEGjx/cOCPqxcHgJu/FHw5/5Y0tywFAme8+MQACgkQFHw5/5Y0
 tywiiQv+IQhGDnt1knghs1f3N/ImsAof4EG44MuuaYFFIb25NC4WO55rG2J5Jmd/
 zrUEKnwMWjDUmKqt9BneQ+NfsOTKfnUWiSdTv2KOsI/FJGOj0KhU8TDA6qdiR6Ev
 thfN5QKLtSrIgg3ua19LUT1+AComjD6w86GRwpQ2iSy6WuPlqlU3VDB1JndXMDh1
 VIz1wuGp8CFgZWb1h8yznajObqK6PBnGwX3MVkPrV7oUSJgVq7dNid/1NFDl+EsV
 SDKEjUJbnAoWiXbW3q+lBfpyxZ7jnTNl6d5nssnmjTlpOradaEOsaj7Y3MRliSQs
 1Fe6rRd4rEr7jI8jBvyveXEJ8ahocTP0haC5MRhin8R6ZO0faQbm1UVVKINuvVIn
 nNU62IInPJXTVPUBFTnZGnwtowmzSdOyBaLcjzFCGD4M9MOikWNwzymIMN7tinyO
 yAy3eJIwqLJ/AtuqYGIbs5wkRcwZnLz0QM9ebBl8lYzmezsx21Z3LpUqAjhUb9Nr
 nJJrzI2/
 =ExnJ
 -----END PGP SIGNATURE-----

Merge tag 'v2025.04-rc3' into next

Prepare v2025.04-rc3
2025-02-24 17:15:14 -06:00
Tom Rini
523a56cc54 Revert "Merge patch series "Add preload_check_sign tool""
This reverts commit c8750efe02, reversing
changes made to 8c6cf8aeea.

Unfortunately these changes do not build on macOS hosts.

Signed-off-by: Tom Rini <trini@konsulko.com>
2025-02-24 10:32:04 -06:00
Tom Rini
c8750efe02 Merge patch series "Add preload_check_sign tool"
Paul HENRYS <paul.henrys_ext@softathome.com> says:

This serie of patches adds a new tool to authenticate files signed
with a preload header.
This tool is also used in the tests to actually verify the
authenticity of the file signed with such a preload header.

Link: https://lore.kernel.org/r/20250212093126.3722186-1-paul.henrys_ext@softathome.com
2025-02-21 11:37:27 -06:00
Paul HENRYS
7771843786 rsa: Add rsa_verify_openssl() to use openssl for host builds
rsa_verify_openssl() is used in lib/rsa/rsa-verify.c to authenticate data
when building host tools.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
2025-02-21 08:34:21 -06:00
Heinrich Schuchardt
50e8089c1d tools: use cryptographically safe RNG
The PRNG implementing the random() function only has 2^31 states and
therefore is unsafe to use for cryptography. Use arc4random() instead.

Fixes: cc34f04efd ("tools: image-host.c: use random instead of rand")
Addresses-Coverity-ID: 312953 Calling risky function
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
2025-02-18 12:30:32 -06:00
Anton Moryakov
25c03648e9 tools: fix NULL_AFTER_DEREF in image-host.c
Report of the static analyzer:
1. NULL_AFTER_DEREF Pointer 'str', which is dereferenced at
   image-host.c:688 by calling function 'strdup', is compared to a NULL
   value at image-host.c:691.
2. NULL_AFTER_DEREF Pointer 'list', which is dereferenced at
   image-host.c:689, is compared to a NULL value at image-host.c:691.

Corrections explained:
1. Checking for NULL before using pointers: The if (!list || !str) check
   is now performed before calling strdup and realloc, which prevents
   null pointer dereferences.
2. Checking the result of strdup: strdup can return NULL if memory
   allocation fails. This also needs to be checked.
3. Checking the result of realloc: If realloc returns NULL, then memory
   has not been allocated and dup must be freed to avoid memory leaks.

Triggers found by static analyzer Svace.

Signed-off-by: Anton Moryakov <ant.v.moryakov@gmail.com>
2025-02-11 08:17:22 -06:00
Tom Rini
a3b71cc6f5 Merge patch series "upl: Prerequite patches for updated spec"
Simon Glass <sjg@chromium.org> says:

The current UPL spec[1] has been tidied up and improved over the last
year, since U-Boot's original UPL support was written.

This series includes some prerequisite patches needed for the real UPL
patches. It is split from [2]

[1] https://github.com/UniversalPayload/spec/tree/3f1450d
[2] https://patchwork.ozlabs.org/project/uboot/list/?series=438574&state=*

Link: https://lore.kernel.org/r/20250111000029.245022-1-sjg@chromium.org
2025-01-22 17:08:47 -06:00
Simon Glass
dc39ce8d90 boot: Rename fit_image_get_data()
This function can only be used with FITs that use embedded data. Rename
it so this is clear.

Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2025-01-22 15:58:04 -06:00
Paul HENRYS
79d7b11102 aes: Allow to store randomly generated IV in the FIT
When the initialisation vector is randomly generated, its value shall be
stored in the FIT together with the encrypted data. The changes allow to
store the IV in the FIT also in the case where the key is not stored in
the DTB but retrieved somewhere else at runtime.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2024-12-19 09:10:34 -06:00
Alexander Kochetkov
9e81f13dbb image-host: fix 'unknown error' error message
Fix error message like this:
Can't add verification data for node 'fdt-1' (<unknown error>)

We get unknown error because we decode error as fdt error
but actually it is system error.

Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2024-10-18 14:10:22 -06:00
Alexander Dahl
6074f6e857 mkimage: Allow 'auto-conf' signing of scripts
U-Boot configured for verified boot with the "required" option set to
"conf" also checks scripts put in FIT images for a valid signature, and
refuses to source and run such a script if the signature for the
configuration is bad or missing.  Such a script could not be packaged
before, because mkimage failed like this:

    % tools/mkimage -T script -C none -d tmp/my.scr -f auto-conf -k tmp -g dev -o sha256,rsa4096 my.uimg
    Failed to find any images for configuration 'conf-1/signature'
    tools/mkimage Can't add hashes to FIT blob: -1
    Error: Bad parameters for FIT image type

This is especially unfortunate if LEGACY_IMAGE_FORMAT is disabled as
recommended.

Listing the script configuration in a "sign-images" subnode instead,
would have added even more complexity to the already complex auto fit
generation code.

Signed-off-by: Alexander Dahl <ada@thorsis.com>
2024-07-05 13:57:01 -06:00
Hugo Cornelis
55a7d60f8f image-host: Fix error value paths and emit error messages to stderr.
A recent refactoring in image-host.c messed up the return values of
the function that reads the encryptiong keys.  This patch fixes this
and also makes sure that error output goes to stderr instead of to
stdout.

Signed-off-by: Hugo Cornelis <hugo.cornelis@essensium.com>
2024-04-12 08:53:31 -06:00
Hugo Cornelis
bc01d9ff93 image-host: refactor and protect for very long filenames
This patch adds a function fit_image_read_key_iv_data that checks the
return value of snprintf and allows to generate a sensible error
message when generating binary images using filenames that are too
long for the OS to handle.

This is especially relevant for automated builds such as Buildroot and
Yocto builds.

Signed-off-by: Hugo Cornelis <hugo.cornelis@essensium.com>
2024-01-18 17:50:27 -05:00
Paul-Erwan Rio
03e598263e tools: fix build without LIBCRYPTO support
Commit cb9faa6f98 ("tools: Use a single target-independent config to
enable OpenSSL") introduced a target-independent configuration to build
crypto features in host tools.

But since commit 2c21256b27 ("hash: Use Kconfig to enable hashing in
host tools and SPL") the build without OpenSSL is broken, due to FIT
signature/encryption features. Add missing conditional compilation
tokens to fix this.

Signed-off-by: Paul-Erwan Rio <paulerwan.rio@gmail.com>
Tested-by: Alexander Dahl <ada@thorsis.com>
Cc: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2024-01-11 22:09:11 -05:00
Oleksandr Suvorov
8d8851e8fd tools: image-host: print error messages to stderr
The make by default cuts off the stdout output from external tools,
so all error messages from the image-host are not shown in a make
output. Besides that, it is a common approach to use stderr stream
for error messages.
Use stderr for all error messages in image-host.

Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@foundries.io>
Reviewed-by: Simon Glass <sjg@chromium.org>
2023-08-30 11:47:43 -04:00
Simon Glass
90cfae2ade mkimage: Add a few more messages for FIT failures
Add messages to make it clearer which part of the FIT creation is failing.
This can happen when an invalid 'algo' property is provided in the .its
file.

Signed-off-by: Simon Glass <sjg@chromium.org>
2023-01-18 11:49:13 -07:00
Sean Anderson
0abe3323f5 mkimage: fit: Fix signing of configs with external data
Just like we exclude data-size, data-position, and data-offset from
fit_config_check_sig, we must exclude them while signing as well.

While we're at it, use the FIT_DATA_* defines for fit_config_check_sig
as welll.

Fixes: 8edecd3110 ("fit: Fix verification of images with external data")
Fixes: c522949a29 ("rsa: sig: fix config signature check for fit with padding")
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2022-10-26 11:36:06 -04:00
Steven Lawrance
7c5eeb8309 image-pre-load: Move macros/definitions to image.h
Putting these definitions in a header will allow signatures to be
validated independently of bootm.

Signed-off-by: Steven Lawrance <steven.lawrance@softathome.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2022-10-11 15:40:48 -04:00
Mark Kettenis
616571804a tools: mkimage: Avoid ENODATA in host tools
ENODATA isn't part of POSIX.  Use EINVAL instead.

Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
2022-05-05 19:37:11 -04:00
Philippe Reynes
6e052d1cba mkimage: add public key for image pre-load stage
This commit enhances mkimage to update the node
/image/pre-load/sig with the public key.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
2022-03-31 14:12:01 -04:00
Simon Glass
2d2384bbaf tools: mkimage: Show where signatures/keys are written
At present mkimage displays the node information but it is not clear what
signing action was taken. Add a message that shows it. For now it only
supports showing a single signing action, since that is the common case.

Sample:

   Signature written to 'sha1-basic/test.fit',
       node '/configurations/conf-1/signature'
   Public key written to 'sha1-basic/sandbox-u-boot.dtb',
       node '/signature/key-dev'

Signed-off-by: Simon Glass <sjg@chromium.org>
2022-01-26 08:50:44 -07:00
Simon Glass
9737c2d1eb tools: Pass public-key node through to caller
Update the two functions that call add_verify_data() so that the caller
can see the node that was written to.

Signed-off-by: Simon Glass <sjg@chromium.org>
2022-01-26 08:50:44 -07:00
Simon Glass
c033dc8c0c image: Return destination node for add_verify_data() method
It is useful to know where the verification data was written. Update the
API to return this.

Signed-off-by: Simon Glass <sjg@chromium.org>
2022-01-26 08:50:44 -07:00
Simon Glass
48422343c8 tools: Drop unused name in image-host
The name is created but never used. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
2022-01-26 08:50:43 -07:00
Simon Glass
70e6bcc43f tools: Improve comments in signing functions
Add some more comments to explain what is going on in the signing
functions. Fix two repeated typos.

Signed-off-by: Simon Glass <sjg@chromium.org>
2022-01-26 08:50:43 -07:00
Jan Kiszka
5902a397d0 mkimage: Allow to specify the signature algorithm on the command line
This permits to prepare FIT image description that do not hard-code the
final choice of the signature algorithm, possibly requiring the user to
patch the sources.

When -o <algo> is specified, this information is used in favor of the
'algo' property in the signature node. Furthermore, that property is set
accordingly when writing the image.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
2022-01-24 10:35:10 -05:00
Jan Kiszka
4550ce9be0 image-fit: Make string of algo parameter constant
Modifications would be invalid.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2022-01-24 10:35:10 -05:00
Heinrich Schuchardt
185f812c41 doc: replace @return by Return:
Sphinx expects Return: and not @return to indicate a return value.

find . -name '*.c' -exec \
sed -i 's/^\(\s\)\*\(\s*\)@return\(\s\)/\1*\2Return:\3/' {} \;

find . -name '*.h' -exec \
sed -i 's/^\(\s\)\*\(\s*\)@return\(\s\)/\1*\2Return:\3/' {} \;

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
2022-01-19 18:11:34 +01:00
Vagrant Cascadian
2c6bcab6e6 tools/image-host.c: Fix spelling of "expected".
Signed-off-by: Vagrant Cascadian <vagrant@debian.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
2021-10-12 16:49:21 -04:00
Simon Glass
7f0f4e1825 tools: Avoid showing return value of clock_gettime()
This value is either 0 for success or -1 for error. Coverity reports that
"ret" is passed to a parameter that cannot be negative, pointing to the
condition 'if (ret < 0)'.

Adjust it to just check for non-zero and avoid showing -1 in the error
message, which is pointless. Perhaps these changes will molify Coverity.

Reported-by: Coverity (CID: 312956)
Signed-off-by: Simon Glass <sjg@chromium.org>
2021-07-15 18:42:05 -04:00
Ming Liu
7c39799dec tools: image-host: fix wrong return value
The return value '-ENOSPC' of fit_set_timestamp function does not match
the caller fit_image_write_sig's expection which is '-FDT_ERR_NOSPACE'.

Fix it by not calling fit_set_timestamp, but call fdt_setprop instead.

This fixes a following mkimage error:
| Can't write signature for 'signature@1' signature node in
| 'conf@imx6ull-colibri-wifi-eval-v3.dtb' conf node: <unknown error>
| mkimage Can't add hashes to FIT blob: -1

Signed-off-by: Ming Liu <liu.ming50@gmail.com>
Tested-by: Igor Opaniuk <igor.opaniuk@foundries.io>
2021-07-14 16:57:35 -04:00
Alexandru Gagniuc
36bfcb62b3 mkimage: Add a 'keyfile' argument for image signing
It's not always desirable to use 'keydir' and some ad-hoc heuristics
to get the filename of the signing key. More often, just passing the
filename is the simpler, easier, and logical thing to do.

Since mkimage doesn't use long options, we're slowly running out of
letters. I've chosen '-G' because it was available.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2021-04-14 15:23:01 -04:00
Philippe Reynes
edfeba7538 tools: image-host: add support for several sub-images
The propoerty sign-images points to images in the configuration
node. But thoses images may references severals "sub-images" (for
example for images loadable). This commit adds the support of
severals sub-images.

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
2021-01-22 16:17:52 -05:00
Philippe Reynes
5a4116f1a2 tools: image-host: clean function fit_config_get_hash_list
This commit creates a function fit_config_add_hash that will be
used in the next commit to support several 'sub-images'.

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2021-01-22 16:17:52 -05:00
Philippe Reynes
2692749316 tools: image-host.c: use correct variable for strerrno
In the function get_random_data, strerrno is called with
the variable ret (which is the return of the function
clock_gettime). It should be called with errnor. This
commit fixes this mistake.

Reported-by: Coverity (CID: 312956)
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2020-11-19 09:45:49 -05:00
Philippe Reynes
cc34f04efd tools: image-host.c: use random instead of rand
According to the manpage of rand, it is recommended
to use random instead of rand. This commit updates
the function get_random_data to use random.

Reported-by: Coverity (CID: 312953)
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2020-11-19 09:45:49 -05:00
Heinrich Schuchardt
3311eda658 tools: image-host.c: use correct output format
When building on a 32bit host the following warning occurs:

tools/image-host.c: In function ‘fit_image_read_data’:
tools/image-host.c:296:56: warning: format ‘%ld’ expects argument of
type ‘long int’, but argument 3 has type ‘__off64_t’
{aka ‘long long int’} [-Wformat=]
   printf("File %s don't have the expected size (size=%ld, expected=%d)\n",
                                                      ~~^
                                                      %lld
          filename, sbuf.st_size, expected_size);
                    ~~~~~~~~~~~~
tools/image-host.c:311:62: warning: format ‘%ld’ expects argument of
type ‘long int’, but argument 4 has type ‘__off64_t’
{aka ‘long long int’} [-Wformat=]
   printf("Can't read all file %s (read %zd bytes, expexted %ld)\n",
                                                            ~~^
                                                            %lld
          filename, n, sbuf.st_size);
                       ~~~~~~~~~~~~

Fix the format strings.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
2020-10-22 09:54:54 -04:00
Philippe Reynes
a6982a6f76 fit: cipher: aes: allow to store the IV in the FIT image
Binaries may be encrypted in a FIT image with AES. This
algo needs a key and an IV (Initialization Vector). The
IV is provided in a file (pointer by iv-name-hint in the
ITS file) when building the ITB file.

This commits adds provide an alternative way to manage
the IV. If the property iv-name-hint is not provided in
the ITS file, the tool mkimage will generate an random
IV and store it in the FIT image.

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
2020-10-12 21:30:37 -04:00
Patrick Oppenlander
ef40129c33 mkimage: fit: include image cipher in configuration signature
This patch addresses issue #2 for signed configurations.

-----8<-----

Including the image cipher properties in the configuration signature
prevents an attacker from modifying cipher, key or iv properties.

Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
Reviewed-by: Philippe Reynes <philippe.reynes@softathome.com>
2020-08-07 11:47:18 -04:00
Patrick Oppenlander
b33e5cc182 mkimage: fit: don't cipher ciphered data
Previously, mkimage -F could be run multiple times causing already
ciphered image data to be ciphered again.

Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
Reviewed-by: Philippe Reynes <philippe.reynes@softathome.com>
2020-08-07 11:47:18 -04:00
Patrick Oppenlander
04aeebb131 mkimage: fit: handle FDT_ERR_NOSPACE when ciphering
Also replace fdt_delprop/fdt_setprop with fdt_setprop as fdt_setprop can
replace an existing property value.

Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
Reviewed-by: Philippe Reynes <philippe.reynes@softathome.com>
2020-08-07 11:47:18 -04:00
Patrick Oppenlander
c520266f9a mkimage: fit: only process one cipher node
Previously mkimage would process any node matching the regex cipher.*
and apply the ciphers to the image data in the order they appeared in
the FDT. This meant that data could be inadvertently ciphered multiple
times.

Switch to processing a single cipher node which exactly matches
FIT_CIPHER_NODENAME.

Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
Reviewed-by: Philippe Reynes <philippe.reynes@softathome.com>
2020-08-07 11:47:18 -04:00
Masahiro Yamada
64045a6a17 libfdt: split fdt_region declarations out to <fdt_region.h>
fdt_region APIs are not part of libfdt. They are U-Boot extension
for the verified boot. Split the declarations related to fdt_region
out of <fdt_region.h>. This allows <linux/libfdt.h> to become a
simple wrapper file, like Linux does.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
2020-04-26 14:24:08 -06:00
Heinrich Schuchardt
b21c08a12b tools: image-host.c: use correct output format
When building on a 32bit host the following warning occurs:

tools/image-host.c: In function ‘fit_image_read_data’:
tools/image-host.c:310:42: warning: format ‘%ld’ expects argument of type
‘long int’, but argument 3 has type ‘ssize_t’ {aka ‘int’} [-Wformat=]
   printf("Can't read all file %s (read %ld bytes, expexted %ld)\n",
                                        ~~^
                                        %d
          filename, n, sbuf.st_size);
                    ~

n is of type ssize_t so we should use %zd for printing.

Fixes: 7298e42250 ("mkimage: fit: add support to encrypt image with aes")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
2020-04-24 10:51:32 -04:00
Simon Glass
72188f5462 image: Use constants for 'required' and 'key-name-hint'
These are used in multiple places so update them to use a shared #define.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Philippe Reynes <philippe.reynes@softathome.com>
2020-04-01 07:45:09 -06:00
Simon Glass
c3aa81e35c fit_check_sign: Allow selecting the configuration to verify
This tool always verifies the default configuration. It is useful to be
able to verify a specific one. Add a command-line flag for this and plumb
the logic through.

Signed-off-by: Simon Glass <sjg@chromium.org>
2020-04-01 07:45:09 -06:00
Simon Glass
382cf62039 image: Be a little more verbose when checking signatures
It is useful to be a little more specific about what is being checked.
Update a few messages to help with this.

Signed-off-by: Simon Glass <sjg@chromium.org>
2020-04-01 07:45:09 -06:00