535.86.05

This commit is contained in:
Bernhard Stoeckner
2023-07-18 15:54:53 +02:00
parent 22a077c4fe
commit 337e28efda
264 changed files with 67251 additions and 107479 deletions

View File

@@ -2,6 +2,8 @@
## Release 535 Entries ## Release 535 Entries
### [535.86.05] 2023-07-18
### [535.54.03] 2023-06-14 ### [535.54.03] 2023-06-14
### [535.43.02] 2023-05-30 ### [535.43.02] 2023-05-30

View File

@@ -1,7 +1,7 @@
# NVIDIA Linux Open GPU Kernel Module Source # NVIDIA Linux Open GPU Kernel Module Source
This is the source release of the NVIDIA Linux open GPU kernel modules, This is the source release of the NVIDIA Linux open GPU kernel modules,
version 535.54.03. version 535.86.05.
## How to Build ## How to Build
@@ -17,7 +17,7 @@ as root:
Note that the kernel modules built here must be used with GSP Note that the kernel modules built here must be used with GSP
firmware and user-space NVIDIA GPU driver components from a corresponding firmware and user-space NVIDIA GPU driver components from a corresponding
535.54.03 driver release. This can be achieved by installing 535.86.05 driver release. This can be achieved by installing
the NVIDIA GPU driver from the .run file using the `--no-kernel-modules` the NVIDIA GPU driver from the .run file using the `--no-kernel-modules`
option. E.g., option. E.g.,
@@ -180,7 +180,7 @@ software applications.
## Compatible GPUs ## Compatible GPUs
The open-gpu-kernel-modules can be used on any Turing or later GPU The open-gpu-kernel-modules can be used on any Turing or later GPU
(see the table below). However, in the 535.54.03 release, (see the table below). However, in the 535.86.05 release,
GeForce and Workstation support is still considered alpha-quality. GeForce and Workstation support is still considered alpha-quality.
To enable use of the open kernel modules on GeForce and Workstation GPUs, To enable use of the open kernel modules on GeForce and Workstation GPUs,
@@ -188,7 +188,7 @@ set the "NVreg_OpenRmEnableUnsupportedGpus" nvidia.ko kernel module
parameter to 1. For more details, see the NVIDIA GPU driver end user parameter to 1. For more details, see the NVIDIA GPU driver end user
README here: README here:
https://us.download.nvidia.com/XFree86/Linux-x86_64/535.54.03/README/kernel_open.html https://us.download.nvidia.com/XFree86/Linux-x86_64/535.86.05/README/kernel_open.html
In the below table, if three IDs are listed, the first is the PCI Device In the below table, if three IDs are listed, the first is the PCI Device
ID, the second is the PCI Subsystem Vendor ID, and the third is the PCI ID, the second is the PCI Subsystem Vendor ID, and the third is the PCI
@@ -848,9 +848,11 @@ Subsystem Device ID.
| NVIDIA RTX 3500 Ada Generation Laptop GPU | 27BB | | NVIDIA RTX 3500 Ada Generation Laptop GPU | 27BB |
| NVIDIA GeForce RTX 4080 Laptop GPU | 27E0 | | NVIDIA GeForce RTX 4080 Laptop GPU | 27E0 |
| NVIDIA GeForce RTX 4060 Ti | 2803 | | NVIDIA GeForce RTX 4060 Ti | 2803 |
| NVIDIA GeForce RTX 4060 Ti | 2805 |
| NVIDIA GeForce RTX 4070 Laptop GPU | 2820 | | NVIDIA GeForce RTX 4070 Laptop GPU | 2820 |
| NVIDIA RTX 3000 Ada Generation Laptop GPU | 2838 | | NVIDIA RTX 3000 Ada Generation Laptop GPU | 2838 |
| NVIDIA GeForce RTX 4070 Laptop GPU | 2860 | | NVIDIA GeForce RTX 4070 Laptop GPU | 2860 |
| NVIDIA GeForce RTX 4060 | 2882 |
| NVIDIA GeForce RTX 4060 Laptop GPU | 28A0 | | NVIDIA GeForce RTX 4060 Laptop GPU | 28A0 |
| NVIDIA GeForce RTX 4050 Laptop GPU | 28A1 | | NVIDIA GeForce RTX 4050 Laptop GPU | 28A1 |
| NVIDIA RTX 2000 Ada Generation Laptop GPU | 28B8 | | NVIDIA RTX 2000 Ada Generation Laptop GPU | 28B8 |

View File

@@ -72,7 +72,7 @@ EXTRA_CFLAGS += -I$(src)/common/inc
EXTRA_CFLAGS += -I$(src) EXTRA_CFLAGS += -I$(src)
EXTRA_CFLAGS += -Wall $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-error -Wno-format-extra-args EXTRA_CFLAGS += -Wall $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-error -Wno-format-extra-args
EXTRA_CFLAGS += -D__KERNEL__ -DMODULE -DNVRM EXTRA_CFLAGS += -D__KERNEL__ -DMODULE -DNVRM
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"535.54.03\" EXTRA_CFLAGS += -DNV_VERSION_STRING=\"535.86.05\"
ifneq ($(SYSSRCHOST1X),) ifneq ($(SYSSRCHOST1X),)
EXTRA_CFLAGS += -I$(SYSSRCHOST1X) EXTRA_CFLAGS += -I$(SYSSRCHOST1X)

View File

@@ -211,6 +211,7 @@
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/nodemask.h> #include <linux/nodemask.h>
#include <linux/memory.h>
#include <linux/workqueue.h> /* workqueue */ #include <linux/workqueue.h> /* workqueue */
#include "nv-kthread-q.h" /* kthread based queue */ #include "nv-kthread-q.h" /* kthread based queue */

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: Copyright (c) 2016-2017 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-FileCopyrightText: Copyright (c) 2016-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
@@ -36,12 +36,21 @@ typedef int vm_fault_t;
* pin_user_pages() was added by commit eddb1c228f7951d399240 * pin_user_pages() was added by commit eddb1c228f7951d399240
* ("mm/gup: introduce pin_user_pages*() and FOLL_PIN") in v5.6-rc1 (2020-01-30) * ("mm/gup: introduce pin_user_pages*() and FOLL_PIN") in v5.6-rc1 (2020-01-30)
* *
* Removed vmas parameter from pin_user_pages() by commit 40896a02751
* ("mm/gup: remove vmas parameter from pin_user_pages()")
* in linux-next, expected in v6.5-rc1 (2023-05-17)
*
*/ */
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/sched.h> #include <linux/sched.h>
#if defined(NV_PIN_USER_PAGES_PRESENT) #if defined(NV_PIN_USER_PAGES_PRESENT)
#define NV_PIN_USER_PAGES pin_user_pages #if defined(NV_PIN_USER_PAGES_HAS_ARGS_VMAS)
#define NV_PIN_USER_PAGES pin_user_pages
#else
#define NV_PIN_USER_PAGES(start, nr_pages, gup_flags, pages, vmas) \
pin_user_pages(start, nr_pages, gup_flags, pages)
#endif // NV_PIN_USER_PAGES_HAS_ARGS_VMAS
#define NV_UNPIN_USER_PAGE unpin_user_page #define NV_UNPIN_USER_PAGE unpin_user_page
#else #else
#define NV_PIN_USER_PAGES NV_GET_USER_PAGES #define NV_PIN_USER_PAGES NV_GET_USER_PAGES
@@ -64,11 +73,18 @@ typedef int vm_fault_t;
* commit 8e50b8b07f462ab4b91bc1491b1c91bd75e4ad40 which cherry-picked the * commit 8e50b8b07f462ab4b91bc1491b1c91bd75e4ad40 which cherry-picked the
* replacement of the write and force parameters with gup_flags * replacement of the write and force parameters with gup_flags
* *
* Removed vmas parameter from get_user_pages() by commit 7bbf9c8c99
* ("mm/gup: remove unused vmas parameter from get_user_pages()")
* in linux-next, expected in v6.5-rc1 (2023-05-17)
*
*/ */
#if defined(NV_GET_USER_PAGES_HAS_ARGS_FLAGS) #if defined(NV_GET_USER_PAGES_HAS_ARGS_FLAGS)
#define NV_GET_USER_PAGES(start, nr_pages, flags, pages, vmas) \
get_user_pages(start, nr_pages, flags, pages)
#elif defined(NV_GET_USER_PAGES_HAS_ARGS_FLAGS_VMAS)
#define NV_GET_USER_PAGES get_user_pages #define NV_GET_USER_PAGES get_user_pages
#elif defined(NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS) #elif defined(NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS_VMAS)
#define NV_GET_USER_PAGES(start, nr_pages, flags, pages, vmas) \ #define NV_GET_USER_PAGES(start, nr_pages, flags, pages, vmas) \
get_user_pages(current, current->mm, start, nr_pages, flags, pages, vmas) get_user_pages(current, current->mm, start, nr_pages, flags, pages, vmas)
#else #else
@@ -81,13 +97,13 @@ typedef int vm_fault_t;
int write = flags & FOLL_WRITE; int write = flags & FOLL_WRITE;
int force = flags & FOLL_FORCE; int force = flags & FOLL_FORCE;
#if defined(NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE) #if defined(NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE_VMAS)
return get_user_pages(start, nr_pages, write, force, pages, vmas); return get_user_pages(start, nr_pages, write, force, pages, vmas);
#else #else
// NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE // NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE_VMAS
return get_user_pages(current, current->mm, start, nr_pages, write, return get_user_pages(current, current->mm, start, nr_pages, write,
force, pages, vmas); force, pages, vmas);
#endif // NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE #endif // NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE_VMAS
} }
#endif // NV_GET_USER_PAGES_HAS_ARGS_FLAGS #endif // NV_GET_USER_PAGES_HAS_ARGS_FLAGS
@@ -100,15 +116,22 @@ typedef int vm_fault_t;
* 64019a2e467a ("mm/gup: remove task_struct pointer for all gup code") * 64019a2e467a ("mm/gup: remove task_struct pointer for all gup code")
* in v5.9-rc1 (2020-08-11). * * in v5.9-rc1 (2020-08-11). *
* *
* Removed unused vmas parameter from pin_user_pages_remote() by commit
* 83bcc2e132("mm/gup: remove unused vmas parameter from pin_user_pages_remote()")
* in linux-next, expected in v6.5-rc1 (2023-05-14)
*
*/ */
#if defined(NV_PIN_USER_PAGES_REMOTE_PRESENT) #if defined(NV_PIN_USER_PAGES_REMOTE_PRESENT)
#if defined (NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK) #if defined(NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK_VMAS)
#define NV_PIN_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \ #define NV_PIN_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \
pin_user_pages_remote(NULL, mm, start, nr_pages, flags, pages, vmas, locked) pin_user_pages_remote(NULL, mm, start, nr_pages, flags, pages, vmas, locked)
#else #elif defined(NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_VMAS)
#define NV_PIN_USER_PAGES_REMOTE pin_user_pages_remote #define NV_PIN_USER_PAGES_REMOTE pin_user_pages_remote
#endif // NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK #else
#define NV_PIN_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \
pin_user_pages_remote(mm, start, nr_pages, flags, pages, locked)
#endif // NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK_VMAS
#else #else
#define NV_PIN_USER_PAGES_REMOTE NV_GET_USER_PAGES_REMOTE #define NV_PIN_USER_PAGES_REMOTE NV_GET_USER_PAGES_REMOTE
#endif // NV_PIN_USER_PAGES_REMOTE_PRESENT #endif // NV_PIN_USER_PAGES_REMOTE_PRESENT
@@ -135,22 +158,30 @@ typedef int vm_fault_t;
* commit 64019a2e467a ("mm/gup: remove task_struct pointer for * commit 64019a2e467a ("mm/gup: remove task_struct pointer for
* all gup code") in v5.9-rc1 (2020-08-11). * all gup code") in v5.9-rc1 (2020-08-11).
* *
* Removed vmas parameter from get_user_pages_remote() by commit a4bde14d549
* ("mm/gup: remove vmas parameter from get_user_pages_remote()")
* in linux-next, expected in v6.5-rc1 (2023-05-14)
*
*/ */
#if defined(NV_GET_USER_PAGES_REMOTE_PRESENT) #if defined(NV_GET_USER_PAGES_REMOTE_PRESENT)
#if defined(NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED) #if defined(NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED)
#define NV_GET_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \
get_user_pages_remote(mm, start, nr_pages, flags, pages, locked)
#elif defined(NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED_VMAS)
#define NV_GET_USER_PAGES_REMOTE get_user_pages_remote #define NV_GET_USER_PAGES_REMOTE get_user_pages_remote
#elif defined(NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED) #elif defined(NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED_VMAS)
#define NV_GET_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \ #define NV_GET_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \
get_user_pages_remote(NULL, mm, start, nr_pages, flags, pages, vmas, locked) get_user_pages_remote(NULL, mm, start, nr_pages, flags, pages, vmas, locked)
#elif defined(NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS) #elif defined(NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_VMAS)
#define NV_GET_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \ #define NV_GET_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \
get_user_pages_remote(NULL, mm, start, nr_pages, flags, pages, vmas) get_user_pages_remote(NULL, mm, start, nr_pages, flags, pages, vmas)
#else #else
// NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE // NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE_VMAS
static inline long NV_GET_USER_PAGES_REMOTE(struct mm_struct *mm, static inline long NV_GET_USER_PAGES_REMOTE(struct mm_struct *mm,
unsigned long start, unsigned long start,
unsigned long nr_pages, unsigned long nr_pages,
@@ -167,7 +198,7 @@ typedef int vm_fault_t;
} }
#endif // NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED #endif // NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED
#else #else
#if defined(NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE) #if defined(NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE_VMAS)
static inline long NV_GET_USER_PAGES_REMOTE(struct mm_struct *mm, static inline long NV_GET_USER_PAGES_REMOTE(struct mm_struct *mm,
unsigned long start, unsigned long start,
unsigned long nr_pages, unsigned long nr_pages,
@@ -185,7 +216,7 @@ typedef int vm_fault_t;
#else #else
#define NV_GET_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \ #define NV_GET_USER_PAGES_REMOTE(mm, start, nr_pages, flags, pages, vmas, locked) \
get_user_pages(NULL, mm, start, nr_pages, flags, pages, vmas) get_user_pages(NULL, mm, start, nr_pages, flags, pages, vmas)
#endif // NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE #endif // NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE_VMAS
#endif // NV_GET_USER_PAGES_REMOTE_PRESENT #endif // NV_GET_USER_PAGES_REMOTE_PRESENT
/* /*

View File

@@ -852,6 +852,14 @@ typedef union UvmFaultMetadataPacket_tag
NvU8 _padding[32]; NvU8 _padding[32];
} UvmFaultMetadataPacket; } UvmFaultMetadataPacket;
// This struct shall not be accessed nor modified directly by UVM as it is
// entirely managed by the RM layer
typedef struct UvmCslContext_tag
{
struct ccslContext_t *ctx;
void *nvidia_stack;
} UvmCslContext;
typedef struct UvmGpuFaultInfo_tag typedef struct UvmGpuFaultInfo_tag
{ {
struct struct
@@ -909,6 +917,10 @@ typedef struct UvmGpuFaultInfo_tag
// Confidential Computing is disabled. // Confidential Computing is disabled.
UvmFaultMetadataPacket *bufferMetadata; UvmFaultMetadataPacket *bufferMetadata;
// CSL context used for performing decryption of replayable faults when
// Confidential Computing is enabled.
UvmCslContext cslCtx;
// Indicates whether UVM owns the replayable fault buffer. // Indicates whether UVM owns the replayable fault buffer.
// The value of this field is always NV_TRUE When Confidential Computing // The value of this field is always NV_TRUE When Confidential Computing
// is disabled. // is disabled.
@@ -1047,14 +1059,6 @@ typedef UvmGpuPagingChannelInfo gpuPagingChannelInfo;
typedef UvmGpuPagingChannelAllocParams gpuPagingChannelAllocParams; typedef UvmGpuPagingChannelAllocParams gpuPagingChannelAllocParams;
typedef UvmPmaAllocationOptions gpuPmaAllocationOptions; typedef UvmPmaAllocationOptions gpuPmaAllocationOptions;
// This struct shall not be accessed nor modified directly by UVM as it is
// entirely managed by the RM layer
typedef struct UvmCslContext_tag
{
struct ccslContext_t *ctx;
void *nvidia_stack;
} UvmCslContext;
typedef struct UvmCslIv typedef struct UvmCslIv
{ {
NvU8 iv[12]; NvU8 iv[12];

View File

@@ -1135,6 +1135,23 @@ compile_test() {
compile_check_conftest "$CODE" "NV_VFIO_DEVICE_OPS_HAS_DMA_UNMAP" "" "types" compile_check_conftest "$CODE" "NV_VFIO_DEVICE_OPS_HAS_DMA_UNMAP" "" "types"
;; ;;
vfio_device_ops_has_bind_iommufd)
#
# Determine if 'vfio_device_ops' struct has 'bind_iommufd' field.
#
# Added by commit a4d1f91db5021 ("vfio-iommufd: Support iommufd
# for physical VFIO devices") in v6.2
#
CODE="
#include <linux/pci.h>
#include <linux/vfio.h>
int conftest_vfio_device_ops_has_bind_iommufd(void) {
return offsetof(struct vfio_device_ops, bind_iommufd);
}"
compile_check_conftest "$CODE" "NV_VFIO_DEVICE_OPS_HAS_BIND_IOMMUFD" "" "types"
;;
pci_irq_vector_helpers) pci_irq_vector_helpers)
# #
# Determine if pci_alloc_irq_vectors(), pci_free_irq_vectors() # Determine if pci_alloc_irq_vectors(), pci_free_irq_vectors()
@@ -2410,6 +2427,10 @@ compile_test() {
# commit 768ae309a961 ("mm: replace get_user_pages() write/force # commit 768ae309a961 ("mm: replace get_user_pages() write/force
# parameters with gup_flags") in v4.9 (2016-10-13) # parameters with gup_flags") in v4.9 (2016-10-13)
# #
# Removed vmas parameter from get_user_pages() by commit 7bbf9c8c99
# ("mm/gup: remove unused vmas parameter from get_user_pages()")
# in linux-next, expected in v6.5-rc1
#
# linux-4.4.168 cherry-picked commit 768ae309a961 without # linux-4.4.168 cherry-picked commit 768ae309a961 without
# c12d2da56d0e which is covered in Conftest #3. # c12d2da56d0e which is covered in Conftest #3.
# #
@@ -2419,22 +2440,28 @@ compile_test() {
# passing conftest's # passing conftest's
# #
set_get_user_pages_defines () { set_get_user_pages_defines () {
if [ "$1" = "NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE" ]; then if [ "$1" = "NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE_VMAS" ]; then
echo "#define NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE" | append_conftest "functions" echo "#define NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE_VMAS" | append_conftest "functions"
else else
echo "#undef NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE" | append_conftest "functions" echo "#undef NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE_VMAS" | append_conftest "functions"
fi fi
if [ "$1" = "NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE" ]; then if [ "$1" = "NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE_VMAS" ]; then
echo "#define NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE" | append_conftest "functions" echo "#define NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE_VMAS" | append_conftest "functions"
else else
echo "#undef NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE" | append_conftest "functions" echo "#undef NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE_VMAS" | append_conftest "functions"
fi fi
if [ "$1" = "NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS" ]; then if [ "$1" = "NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS_VMAS" ]; then
echo "#define NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS" | append_conftest "functions" echo "#define NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS_VMAS" | append_conftest "functions"
else else
echo "#undef NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS" | append_conftest "functions" echo "#undef NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS_VMAS" | append_conftest "functions"
fi
if [ "$1" = "NV_GET_USER_PAGES_HAS_ARGS_FLAGS_VMAS" ]; then
echo "#define NV_GET_USER_PAGES_HAS_ARGS_FLAGS_VMAS" | append_conftest "functions"
else
echo "#undef NV_GET_USER_PAGES_HAS_ARGS_FLAGS_VMAS" | append_conftest "functions"
fi fi
if [ "$1" = "NV_GET_USER_PAGES_HAS_ARGS_FLAGS" ]; then if [ "$1" = "NV_GET_USER_PAGES_HAS_ARGS_FLAGS" ]; then
@@ -2442,6 +2469,7 @@ compile_test() {
else else
echo "#undef NV_GET_USER_PAGES_HAS_ARGS_FLAGS" | append_conftest "functions" echo "#undef NV_GET_USER_PAGES_HAS_ARGS_FLAGS" | append_conftest "functions"
fi fi
} }
# Conftest #1: Check if get_user_pages accepts 6 arguments. # Conftest #1: Check if get_user_pages accepts 6 arguments.
@@ -2462,14 +2490,15 @@ compile_test() {
$CC $CFLAGS -c conftest$$.c > /dev/null 2>&1 $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
rm -f conftest$$.c rm -f conftest$$.c
if [ -f conftest$$.o ]; then if [ -f conftest$$.o ]; then
set_get_user_pages_defines "NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE" set_get_user_pages_defines "NV_GET_USER_PAGES_HAS_ARGS_WRITE_FORCE_VMAS"
rm -f conftest$$.o rm -f conftest$$.o
return return
fi fi
# Conftest #2: Check if get_user_pages has gup_flags instead of # Conftest #2: Check if get_user_pages has gup_flags instead of
# write and force parameters. And that gup doesn't accept a # write and force parameters. And that gup doesn't accept a
# task_struct and mm_struct as its first arguments. # task_struct and mm_struct as its first arguments. get_user_pages
# has vm_area_struct as its last argument.
# Return if available. # Return if available.
# Fall through to conftest #3 on failure. # Fall through to conftest #3 on failure.
@@ -2487,16 +2516,17 @@ compile_test() {
rm -f conftest$$.c rm -f conftest$$.c
if [ -f conftest$$.o ]; then if [ -f conftest$$.o ]; then
set_get_user_pages_defines "NV_GET_USER_PAGES_HAS_ARGS_FLAGS" set_get_user_pages_defines "NV_GET_USER_PAGES_HAS_ARGS_FLAGS_VMAS"
rm -f conftest$$.o rm -f conftest$$.o
return return
fi fi
# Conftest #3: Check if get_user_pages has gup_flags instead of # Conftest #3: Check if get_user_pages has gup_flags instead of
# write and force parameters AND that gup has task_struct and # write and force parameters. The gup has task_struct and
# mm_struct as its first arguments. # mm_struct as its first arguments. get_user_pages
# has vm_area_struct as its last argument.
# Return if available. # Return if available.
# Fall through to default case if absent. # Fall through to conftest #4 on failure.
echo "$CONFTEST_PREAMBLE echo "$CONFTEST_PREAMBLE
#include <linux/mm.h> #include <linux/mm.h>
@@ -2514,12 +2544,35 @@ compile_test() {
rm -f conftest$$.c rm -f conftest$$.c
if [ -f conftest$$.o ]; then if [ -f conftest$$.o ]; then
set_get_user_pages_defines "NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS" set_get_user_pages_defines "NV_GET_USER_PAGES_HAS_ARGS_TSK_FLAGS_VMAS"
rm -f conftest$$.o rm -f conftest$$.o
return return
fi fi
set_get_user_pages_defines "NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE" # Conftest #4: gup doesn't accept a task_struct and mm_struct as
# its first arguments. check if get_user_pages() does not take
# vmas argument.
# Fall through to default case otherwise.
echo "$CONFTEST_PREAMBLE
#include <linux/mm.h>
long get_user_pages(unsigned long start,
unsigned long nr_pages,
unsigned int gup_flags,
struct page **pages) {
return 0;
}" > conftest$$.c
$CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
rm -f conftest$$.c
if [ -f conftest$$.o ]; then
set_get_user_pages_defines "NV_GET_USER_PAGES_HAS_ARGS_FLAGS"
rm -f conftest$$.o
return
fi
set_get_user_pages_defines "NV_GET_USER_PAGES_HAS_ARGS_TSK_WRITE_FORCE_VMAS"
return return
;; ;;
@@ -2546,6 +2599,10 @@ compile_test() {
# commit 64019a2e467a ("mm/gup: remove task_struct pointer for # commit 64019a2e467a ("mm/gup: remove task_struct pointer for
# all gup code") in v5.9-rc1 (2020-08-11). # all gup code") in v5.9-rc1 (2020-08-11).
# #
# Removed vmas parameter from get_user_pages_remote() by commit
# a4bde14d549 ("mm/gup: remove vmas parameter from get_user_pages_remote()")
# in linux-next, expected in v6.5-rc1
#
# #
# This function sets the NV_GET_USER_PAGES_REMOTE_* macros as per # This function sets the NV_GET_USER_PAGES_REMOTE_* macros as per
@@ -2558,22 +2615,28 @@ compile_test() {
echo "#define NV_GET_USER_PAGES_REMOTE_PRESENT" | append_conftest "functions" echo "#define NV_GET_USER_PAGES_REMOTE_PRESENT" | append_conftest "functions"
fi fi
if [ "$1" = "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE" ]; then if [ "$1" = "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE_VMAS" ]; then
echo "#define NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE" | append_conftest "functions" echo "#define NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE_VMAS" | append_conftest "functions"
else else
echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE" | append_conftest "functions" echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE_VMAS" | append_conftest "functions"
fi fi
if [ "$1" = "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS" ]; then if [ "$1" = "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_VMAS" ]; then
echo "#define NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS" | append_conftest "functions" echo "#define NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_VMAS" | append_conftest "functions"
else else
echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS" | append_conftest "functions" echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_VMAS" | append_conftest "functions"
fi fi
if [ "$1" = "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED" ]; then if [ "$1" = "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED_VMAS" ]; then
echo "#define NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED" | append_conftest "functions" echo "#define NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED_VMAS" | append_conftest "functions"
else else
echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED" | append_conftest "functions" echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED_VMAS" | append_conftest "functions"
fi
if [ "$1" = "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED_VMAS" ]; then
echo "#define NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED_VMAS" | append_conftest "functions"
else
echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED_VMAS" | append_conftest "functions"
fi fi
if [ "$1" = "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED" ]; then if [ "$1" = "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED" ]; then
@@ -2581,6 +2644,7 @@ compile_test() {
else else
echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED" | append_conftest "functions" echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED" | append_conftest "functions"
fi fi
} }
# conftest #1: check if get_user_pages_remote() is available # conftest #1: check if get_user_pages_remote() is available
@@ -2603,8 +2667,8 @@ compile_test() {
fi fi
# #
# conftest #2: check if get_user_pages_remote() has write and # conftest #2: check if get_user_pages_remote() has write, force
# force arguments. Return if these arguments are present # and vmas arguments. Return if these arguments are present
# Fall through to conftest #3 if these args are absent. # Fall through to conftest #3 if these args are absent.
# #
echo "$CONFTEST_PREAMBLE echo "$CONFTEST_PREAMBLE
@@ -2624,14 +2688,14 @@ compile_test() {
rm -f conftest$$.c rm -f conftest$$.c
if [ -f conftest$$.o ]; then if [ -f conftest$$.o ]; then
set_get_user_pages_remote_defines "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE" set_get_user_pages_remote_defines "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_WRITE_FORCE_VMAS"
rm -f conftest$$.o rm -f conftest$$.o
return return
fi fi
# #
# conftest #3: check if get_user_pages_remote() has gpu_flags # conftest #3: check if get_user_pages_remote() has gpu_flags and
# arguments. Return if these arguments are present # vmas arguments. Return if these arguments are present
# Fall through to conftest #4 if these args are absent. # Fall through to conftest #4 if these args are absent.
# #
echo "$CONFTEST_PREAMBLE echo "$CONFTEST_PREAMBLE
@@ -2650,13 +2714,14 @@ compile_test() {
rm -f conftest$$.c rm -f conftest$$.c
if [ -f conftest$$.o ]; then if [ -f conftest$$.o ]; then
set_get_user_pages_remote_defines "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS" set_get_user_pages_remote_defines "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_VMAS"
rm -f conftest$$.o rm -f conftest$$.o
return return
fi fi
# #
# conftest #4: check if get_user_pages_remote() has locked argument # conftest #4: check if get_user_pages_remote() has locked and
# vmas argument
# Return if these arguments are present. Fall through to conftest #5 # Return if these arguments are present. Fall through to conftest #5
# if these args are absent. # if these args are absent.
# #
@@ -2677,7 +2742,7 @@ compile_test() {
rm -f conftest$$.c rm -f conftest$$.c
if [ -f conftest$$.o ]; then if [ -f conftest$$.o ]; then
set_get_user_pages_remote_defines "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED" set_get_user_pages_remote_defines "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_TSK_FLAGS_LOCKED_VMAS"
rm -f conftest$$.o rm -f conftest$$.o
return return
fi fi
@@ -2701,10 +2766,34 @@ compile_test() {
$CC $CFLAGS -c conftest$$.c > /dev/null 2>&1 $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
rm -f conftest$$.c rm -f conftest$$.c
if [ -f conftest$$.o ]; then
set_get_user_pages_remote_defines "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED_VMAS"
rm -f conftest$$.o
fi
#
# conftest #6: check if get_user_pages_remote() does not take
# vmas argument.
#
echo "$CONFTEST_PREAMBLE
#include <linux/mm.h>
long get_user_pages_remote(struct mm_struct *mm,
unsigned long start,
unsigned long nr_pages,
unsigned int gup_flags,
struct page **pages,
int *locked) {
return 0;
}" > conftest$$.c
$CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
rm -f conftest$$.c
if [ -f conftest$$.o ]; then if [ -f conftest$$.o ]; then
set_get_user_pages_remote_defines "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED" set_get_user_pages_remote_defines "NV_GET_USER_PAGES_REMOTE_HAS_ARGS_FLAGS_LOCKED"
rm -f conftest$$.o rm -f conftest$$.o
fi fi
;; ;;
pin_user_pages) pin_user_pages)
@@ -2716,17 +2805,65 @@ compile_test() {
# pin_user_pages() was added by commit eddb1c228f7951d399240 # pin_user_pages() was added by commit eddb1c228f7951d399240
# ("mm/gup: introduce pin_user_pages*() and FOLL_PIN") in # ("mm/gup: introduce pin_user_pages*() and FOLL_PIN") in
# v5.6-rc1 (2020-01-30) # v5.6-rc1 (2020-01-30)
#
# Removed vmas parameter from pin_user_pages() by commit
# 40896a02751("mm/gup: remove vmas parameter from pin_user_pages()")
# in linux-next, expected in v6.5-rc1
set_pin_user_pages_defines () {
if [ "$1" = "" ]; then
echo "#undef NV_PIN_USER_PAGES_PRESENT" | append_conftest "functions"
else
echo "#define NV_PIN_USER_PAGES_PRESENT" | append_conftest "functions"
fi
if [ "$1" = "NV_PIN_USER_PAGES_HAS_ARGS_VMAS" ]; then
echo "#define NV_PIN_USER_PAGES_HAS_ARGS_VMAS" | append_conftest "functions"
else
echo "#undef NV_PIN_USER_PAGES_HAS_ARGS_VMAS" | append_conftest "functions"
fi
}
# conftest #1: check if pin_user_pages() is available # conftest #1: check if pin_user_pages() is available
# return if not available. # return if not available.
# Fall through to conftest #2 if it is present
# #
CODE=" echo "$CONFTEST_PREAMBLE
#include <linux/mm.h> #include <linux/mm.h>
void conftest_pin_user_pages(void) { void conftest_pin_user_pages(void) {
pin_user_pages(); pin_user_pages();
}" }" > conftest$$.c
compile_check_conftest "$CODE" "NV_PIN_USER_PAGES_PRESENT" "" "functions" $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
rm -f conftest$$.c
if [ -f conftest$$.o ]; then
set_pin_user_pages_defines ""
rm -f conftest$$.o
return
fi
# conftest #2: Check if pin_user_pages() has vmas argument
echo "$CONFTEST_PREAMBLE
#include <linux/mm.h>
long pin_user_pages(unsigned long start,
unsigned long nr_pages,
unsigned int gup_flags,
struct page **pages,
struct vm_area_struct **vmas) {
return 0;
}" > conftest$$.c
$CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
rm -f conftest$$.c
if [ -f conftest$$.o ]; then
set_pin_user_pages_defines "NV_PIN_USER_PAGES_HAS_ARGS_VMAS"
rm -f conftest$$.o
else
set_pin_user_pages_defines "NV_PIN_USER_PAGES_PRESENT"
fi
;; ;;
pin_user_pages_remote) pin_user_pages_remote)
@@ -2739,6 +2876,10 @@ compile_test() {
# pin_user_pages_remote() removed 'tsk' parameter by # pin_user_pages_remote() removed 'tsk' parameter by
# commit 64019a2e467a ("mm/gup: remove task_struct pointer for # commit 64019a2e467a ("mm/gup: remove task_struct pointer for
# all gup code") in v5.9-rc1 (2020-08-11). # all gup code") in v5.9-rc1 (2020-08-11).
#
# Removed unused vmas parameter from pin_user_pages_remote() by
# commit 83bcc2e132 ("mm/gup: remove unused vmas parameter from
# pin_user_pages_remote()") in linux-next, expected in v6.5-rc1
# #
# This function sets the NV_PIN_USER_PAGES_REMOTE_* macros as per # This function sets the NV_PIN_USER_PAGES_REMOTE_* macros as per
@@ -2751,10 +2892,16 @@ compile_test() {
echo "#define NV_PIN_USER_PAGES_REMOTE_PRESENT" | append_conftest "functions" echo "#define NV_PIN_USER_PAGES_REMOTE_PRESENT" | append_conftest "functions"
fi fi
if [ "$1" = "NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK" ]; then if [ "$1" = "NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK_VMAS" ]; then
echo "#define NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK" | append_conftest "functions" echo "#define NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK_VMAS" | append_conftest "functions"
else else
echo "#undef NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK" | append_conftest "functions" echo "#undef NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK_VMAS" | append_conftest "functions"
fi
if [ "$1" = "NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_VMAS" ]; then
echo "#define NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_VMAS" | append_conftest "functions"
else
echo "#undef NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_VMAS" | append_conftest "functions"
fi fi
} }
@@ -2777,7 +2924,11 @@ compile_test() {
return return
fi fi
# conftest #2: Check if pin_user_pages_remote() has tsk argument # conftest #2: Check if pin_user_pages_remote() has tsk and
# vmas argument
# Return if these arguments are present else fall through to
# conftest #3
echo "$CONFTEST_PREAMBLE echo "$CONFTEST_PREAMBLE
#include <linux/mm.h> #include <linux/mm.h>
long pin_user_pages_remote(struct task_struct *tsk, long pin_user_pages_remote(struct task_struct *tsk,
@@ -2795,11 +2946,34 @@ compile_test() {
rm -f conftest$$.c rm -f conftest$$.c
if [ -f conftest$$.o ]; then if [ -f conftest$$.o ]; then
set_pin_user_pages_remote_defines "NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK" set_pin_user_pages_remote_defines "NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_TSK_VMAS"
rm -f conftest$$.o
return
fi
# conftest #3: Check if pin_user_pages_remote() has vmas argument
echo "$CONFTEST_PREAMBLE
#include <linux/mm.h>
long pin_user_pages_remote(struct mm_struct *mm,
unsigned long start,
unsigned long nr_pages,
unsigned int gup_flags,
struct page **pages,
struct vm_area_struct **vmas,
int *locked) {
return 0;
}" > conftest$$.c
$CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
rm -f conftest$$.c
if [ -f conftest$$.o ]; then
set_pin_user_pages_remote_defines "NV_PIN_USER_PAGES_REMOTE_HAS_ARGS_VMAS"
rm -f conftest$$.o rm -f conftest$$.o
else else
set_pin_user_pages_remote_defines "NV_PIN_USER_PAGES_REMOTE_PRESENT" set_pin_user_pages_remote_defines "NV_PIN_USER_PAGES_REMOTE_PRESENT"
fi fi
;; ;;
vfio_pin_pages_has_vfio_device_arg) vfio_pin_pages_has_vfio_device_arg)
@@ -6067,6 +6241,68 @@ compile_test() {
compile_check_conftest "$CODE" "NV_MEMORY_FAILURE_MF_SW_SIMULATED_DEFINED" "" "types" compile_check_conftest "$CODE" "NV_MEMORY_FAILURE_MF_SW_SIMULATED_DEFINED" "" "types"
;; ;;
crypto)
#
# Determine if we support various crypto functions.
# This test is not complete and may return false positive.
#
CODE="
#include <crypto/akcipher.h>
#include <crypto/algapi.h>
#include <crypto/ecc_curve.h>
#include <crypto/ecdh.h>
#include <crypto/hash.h>
#include <crypto/internal/ecc.h>
#include <crypto/kpp.h>
#include <crypto/public_key.h>
#include <crypto/sm3.h>
#include <keys/asymmetric-type.h>
#include <linux/crypto.h>
void conftest_crypto(void) {
struct shash_desc sd;
struct crypto_shash cs;
(void)crypto_shash_tfm_digest;
}"
compile_check_conftest "$CODE" "NV_CRYPTO_PRESENT" "" "symbols"
;;
mempolicy_has_unified_nodes)
#
# Determine if the 'mempolicy' structure has
# nodes union.
#
# nodes field was added by commit 269fbe72cd ("mm/mempolicy:
# use unified 'nodes' for bind/interleave/prefer policies") in
# v5.14 (2021-06-30).
#
CODE="
#include <linux/mempolicy.h>
int conftest_mempolicy_has_unified_nodes(void) {
return offsetof(struct mempolicy, nodes);
}"
compile_check_conftest "$CODE" "NV_MEMPOLICY_HAS_UNIFIED_NODES" "" "types"
;;
mempolicy_has_home_node)
#
# Determine if the 'mempolicy' structure has
# home_node field.
#
# home_node field was added by commit c6018b4b254
# ("mm/mempolicy: add set_mempolicy_home_node syscall") in v5.17
# (2022-01-14).
#
CODE="
#include <linux/mempolicy.h>
int conftest_mempolicy_has_home_node(void) {
return offsetof(struct mempolicy, home_node);
}"
compile_check_conftest "$CODE" "NV_MEMPOLICY_HAS_HOME_NODE" "" "types"
;;
# When adding a new conftest entry, please use the correct format for # When adding a new conftest entry, please use the correct format for
# specifying the relevant upstream Linux kernel commit. # specifying the relevant upstream Linux kernel commit.
# #

View File

@@ -65,6 +65,9 @@
static bool output_rounding_fix = true; static bool output_rounding_fix = true;
module_param_named(output_rounding_fix, output_rounding_fix, bool, 0400); module_param_named(output_rounding_fix, output_rounding_fix, bool, 0400);
static bool disable_vrr_memclk_switch = false;
module_param_named(disable_vrr_memclk_switch, disable_vrr_memclk_switch, bool, 0400);
/* These parameters are used for fault injection tests. Normally the defaults /* These parameters are used for fault injection tests. Normally the defaults
* should be used. */ * should be used. */
MODULE_PARM_DESC(fail_malloc, "Fail the Nth call to nvkms_alloc"); MODULE_PARM_DESC(fail_malloc, "Fail the Nth call to nvkms_alloc");
@@ -91,6 +94,11 @@ NvBool nvkms_output_rounding_fix(void)
return output_rounding_fix; return output_rounding_fix;
} }
NvBool nvkms_disable_vrr_memclk_switch(void)
{
return disable_vrr_memclk_switch;
}
#define NVKMS_SYNCPT_STUBS_NEEDED #define NVKMS_SYNCPT_STUBS_NEEDED
/************************************************************************* /*************************************************************************

View File

@@ -98,6 +98,8 @@ typedef struct {
NvBool nvkms_output_rounding_fix(void); NvBool nvkms_output_rounding_fix(void);
NvBool nvkms_disable_vrr_memclk_switch(void);
void nvkms_call_rm (void *ops); void nvkms_call_rm (void *ops);
void* nvkms_alloc (size_t size, void* nvkms_alloc (size_t size,
NvBool zero); NvBool zero);

View File

@@ -108,5 +108,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += migrate_device_range
NV_CONFTEST_TYPE_COMPILE_TESTS += vm_area_struct_has_const_vm_flags NV_CONFTEST_TYPE_COMPILE_TESTS += vm_area_struct_has_const_vm_flags
NV_CONFTEST_TYPE_COMPILE_TESTS += handle_mm_fault_has_mm_arg NV_CONFTEST_TYPE_COMPILE_TESTS += handle_mm_fault_has_mm_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += handle_mm_fault_has_pt_regs_arg NV_CONFTEST_TYPE_COMPILE_TESTS += handle_mm_fault_has_pt_regs_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += mempolicy_has_unified_nodes
NV_CONFTEST_TYPE_COMPILE_TESTS += mempolicy_has_home_node
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_int_active_memcg NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_int_active_memcg

View File

@@ -24,6 +24,7 @@
#include "uvm_va_range.h" #include "uvm_va_range.h"
#include "uvm_ats_faults.h" #include "uvm_ats_faults.h"
#include "uvm_migrate_pageable.h" #include "uvm_migrate_pageable.h"
#include <linux/mempolicy.h>
// TODO: Bug 2103669: Implement a real prefetching policy and remove or adapt // TODO: Bug 2103669: Implement a real prefetching policy and remove or adapt
// these experimental parameters. These are intended to help guide that policy. // these experimental parameters. These are intended to help guide that policy.
@@ -79,7 +80,7 @@ static NV_STATUS service_ats_faults(uvm_gpu_va_space_t *gpu_va_space,
NvU64 start, NvU64 start,
size_t length, size_t length,
uvm_fault_access_type_t access_type, uvm_fault_access_type_t access_type,
uvm_fault_client_type_t client_type) uvm_ats_fault_context_t *ats_context)
{ {
uvm_va_space_t *va_space = gpu_va_space->va_space; uvm_va_space_t *va_space = gpu_va_space->va_space;
struct mm_struct *mm = va_space->va_space_mm.mm; struct mm_struct *mm = va_space->va_space_mm.mm;
@@ -95,17 +96,18 @@ static NV_STATUS service_ats_faults(uvm_gpu_va_space_t *gpu_va_space,
// 2) guest physical -> host physical // 2) guest physical -> host physical
// //
// The overall ATS translation will fault if either of those translations is // The overall ATS translation will fault if either of those translations is
// invalid. The get_user_pages() call above handles translation #1, but not // invalid. The pin_user_pages() call within uvm_migrate_pageable() call
// #2. We don't know if we're running as a guest, but in case we are we can // below handles translation #1, but not #2. We don't know if we're running
// force that translation to be valid by touching the guest physical address // as a guest, but in case we are we can force that translation to be valid
// from the CPU. If the translation is not valid then the access will cause // by touching the guest physical address from the CPU. If the translation
// a hypervisor fault. Note that dma_map_page() can't establish mappings // is not valid then the access will cause a hypervisor fault. Note that
// used by GPU ATS SVA translations. GPU accesses to host physical addresses // dma_map_page() can't establish mappings used by GPU ATS SVA translations.
// obtained as a result of the address translation request uses the CPU // GPU accesses to host physical addresses obtained as a result of the
// address space instead of the IOMMU address space since the translated // address translation request uses the CPU address space instead of the
// host physical address isn't necessarily an IOMMU address. The only way to // IOMMU address space since the translated host physical address isn't
// establish guest physical to host physical mapping in the CPU address // necessarily an IOMMU address. The only way to establish guest physical to
// space is to touch the page from the CPU. // host physical mapping in the CPU address space is to touch the page from
// the CPU.
// //
// We assume that the hypervisor mappings are all VM_PFNMAP, VM_SHARED, and // We assume that the hypervisor mappings are all VM_PFNMAP, VM_SHARED, and
// VM_WRITE, meaning that the mappings are all granted write access on any // VM_WRITE, meaning that the mappings are all granted write access on any
@@ -116,20 +118,26 @@ static NV_STATUS service_ats_faults(uvm_gpu_va_space_t *gpu_va_space,
uvm_migrate_args_t uvm_migrate_args = uvm_migrate_args_t uvm_migrate_args =
{ {
.va_space = va_space, .va_space = va_space,
.mm = mm, .mm = mm,
.dst_id = gpu_va_space->gpu->parent->id, .dst_id = ats_context->residency_id,
.dst_node_id = -1, .dst_node_id = ats_context->residency_node,
.populate_permissions = write ? UVM_POPULATE_PERMISSIONS_WRITE : UVM_POPULATE_PERMISSIONS_ANY, .populate_permissions = write ? UVM_POPULATE_PERMISSIONS_WRITE : UVM_POPULATE_PERMISSIONS_ANY,
.touch = true, .touch = true,
.skip_mapped = true, .skip_mapped = true,
.user_space_start = &user_space_start, .populate_on_cpu_alloc_failures = true,
.user_space_length = &user_space_length, .user_space_start = &user_space_start,
.user_space_length = &user_space_length,
}; };
UVM_ASSERT(uvm_ats_can_service_faults(gpu_va_space, mm)); UVM_ASSERT(uvm_ats_can_service_faults(gpu_va_space, mm));
expand_fault_region(vma, start, length, client_type, &uvm_migrate_args.start, &uvm_migrate_args.length); expand_fault_region(vma,
start,
length,
ats_context->client_type,
&uvm_migrate_args.start,
&uvm_migrate_args.length);
// We are trying to use migrate_vma API in the kernel (if it exists) to // We are trying to use migrate_vma API in the kernel (if it exists) to
// populate and map the faulting region on the GPU. We want to do this only // populate and map the faulting region on the GPU. We want to do this only
@@ -165,6 +173,58 @@ static void flush_tlb_write_faults(uvm_gpu_va_space_t *gpu_va_space,
uvm_tlb_batch_invalidate(&ats_invalidate->write_faults_tlb_batch, addr, size, PAGE_SIZE, UVM_MEMBAR_NONE); uvm_tlb_batch_invalidate(&ats_invalidate->write_faults_tlb_batch, addr, size, PAGE_SIZE, UVM_MEMBAR_NONE);
} }
static void ats_batch_select_residency(uvm_gpu_va_space_t *gpu_va_space,
struct vm_area_struct *vma,
uvm_ats_fault_context_t *ats_context)
{
uvm_gpu_t *gpu = gpu_va_space->gpu;
int residency = uvm_gpu_numa_node(gpu);
#if defined(NV_MEMPOLICY_HAS_UNIFIED_NODES)
struct mempolicy *vma_policy = vma_policy(vma);
unsigned short mode;
if (!vma_policy)
goto done;
mode = vma_policy->mode;
if ((mode == MPOL_BIND) || (mode == MPOL_PREFERRED_MANY) || (mode == MPOL_PREFERRED)) {
int home_node = NUMA_NO_NODE;
#if defined(NV_MEMPOLICY_HAS_HOME_NODE)
if ((mode != MPOL_PREFERRED) && (vma_policy->home_node != NUMA_NO_NODE))
home_node = vma_policy->home_node;
#endif
// Prefer home_node if set. Otherwise, prefer the faulting GPU if it's
// in the list of preferred nodes, else prefer the closest_cpu_numa_node
// to the GPU if closest_cpu_numa_node is in the list of preferred
// nodes. Fallback to the faulting GPU if all else fails.
if (home_node != NUMA_NO_NODE) {
residency = home_node;
}
else if (!node_isset(residency, vma_policy->nodes)) {
int closest_cpu_numa_node = gpu->parent->closest_cpu_numa_node;
if ((closest_cpu_numa_node != NUMA_NO_NODE) && node_isset(closest_cpu_numa_node, vma_policy->nodes))
residency = gpu->parent->closest_cpu_numa_node;
else
residency = first_node(vma_policy->nodes);
}
}
// Update gpu if residency is not the faulting gpu.
if (residency != uvm_gpu_numa_node(gpu))
gpu = uvm_va_space_find_gpu_with_memory_node_id(gpu_va_space->va_space, residency);
done:
#endif
ats_context->residency_id = gpu ? gpu->parent->id : UVM_ID_CPU;
ats_context->residency_node = residency;
}
NV_STATUS uvm_ats_service_faults(uvm_gpu_va_space_t *gpu_va_space, NV_STATUS uvm_ats_service_faults(uvm_gpu_va_space_t *gpu_va_space,
struct vm_area_struct *vma, struct vm_area_struct *vma,
NvU64 base, NvU64 base,
@@ -205,6 +265,8 @@ NV_STATUS uvm_ats_service_faults(uvm_gpu_va_space_t *gpu_va_space,
uvm_page_mask_zero(write_fault_mask); uvm_page_mask_zero(write_fault_mask);
} }
ats_batch_select_residency(gpu_va_space, vma, ats_context);
for_each_va_block_subregion_in_mask(subregion, write_fault_mask, region) { for_each_va_block_subregion_in_mask(subregion, write_fault_mask, region) {
NvU64 start = base + (subregion.first * PAGE_SIZE); NvU64 start = base + (subregion.first * PAGE_SIZE);
size_t length = uvm_va_block_region_num_pages(subregion) * PAGE_SIZE; size_t length = uvm_va_block_region_num_pages(subregion) * PAGE_SIZE;
@@ -215,7 +277,7 @@ NV_STATUS uvm_ats_service_faults(uvm_gpu_va_space_t *gpu_va_space,
UVM_ASSERT(start >= vma->vm_start); UVM_ASSERT(start >= vma->vm_start);
UVM_ASSERT((start + length) <= vma->vm_end); UVM_ASSERT((start + length) <= vma->vm_end);
status = service_ats_faults(gpu_va_space, vma, start, length, access_type, client_type); status = service_ats_faults(gpu_va_space, vma, start, length, access_type, ats_context);
if (status != NV_OK) if (status != NV_OK)
return status; return status;
@@ -244,11 +306,12 @@ NV_STATUS uvm_ats_service_faults(uvm_gpu_va_space_t *gpu_va_space,
for_each_va_block_subregion_in_mask(subregion, read_fault_mask, region) { for_each_va_block_subregion_in_mask(subregion, read_fault_mask, region) {
NvU64 start = base + (subregion.first * PAGE_SIZE); NvU64 start = base + (subregion.first * PAGE_SIZE);
size_t length = uvm_va_block_region_num_pages(subregion) * PAGE_SIZE; size_t length = uvm_va_block_region_num_pages(subregion) * PAGE_SIZE;
uvm_fault_access_type_t access_type = UVM_FAULT_ACCESS_TYPE_READ;
UVM_ASSERT(start >= vma->vm_start); UVM_ASSERT(start >= vma->vm_start);
UVM_ASSERT((start + length) <= vma->vm_end); UVM_ASSERT((start + length) <= vma->vm_end);
status = service_ats_faults(gpu_va_space, vma, start, length, UVM_FAULT_ACCESS_TYPE_READ, client_type); status = service_ats_faults(gpu_va_space, vma, start, length, access_type, ats_context);
if (status != NV_OK) if (status != NV_OK)
return status; return status;

View File

@@ -152,7 +152,7 @@ static NvU32 uvm_channel_update_progress_with_max(uvm_channel_t *channel,
break; break;
if (entry->type == UVM_GPFIFO_ENTRY_TYPE_NORMAL) { if (entry->type == UVM_GPFIFO_ENTRY_TYPE_NORMAL) {
uvm_pushbuffer_mark_completed(channel->pool->manager->pushbuffer, entry); uvm_pushbuffer_mark_completed(channel, entry);
list_add_tail(&entry->push_info->available_list_node, &channel->available_push_infos); list_add_tail(&entry->push_info->available_list_node, &channel->available_push_infos);
} }
@@ -1035,6 +1035,57 @@ static NV_STATUS internal_channel_submit_work_indirect_sec2(uvm_push_t *push,
return status; return status;
} }
// When the Confidential Computing feature is enabled, the CPU is unable to
// access and read the pushbuffer. This is because it is located in the CPR of
// vidmem in this configuration. This function allows UVM to retrieve the
// content of the pushbuffer in an encrypted form for later decryption, hence,
// simulating the original access pattern. E.g, reading timestamp semaphores.
// See also: decrypt_push().
static void encrypt_push(uvm_push_t *push)
{
NvU64 push_protected_gpu_va;
NvU64 push_unprotected_gpu_va;
uvm_gpu_address_t auth_tag_gpu_va;
uvm_channel_t *channel = push->channel;
uvm_push_crypto_bundle_t *crypto_bundle;
uvm_gpu_t *gpu = uvm_push_get_gpu(push);
NvU32 push_size = uvm_push_get_size(push);
uvm_push_info_t *push_info = uvm_push_info_from_push(push);
uvm_pushbuffer_t *pushbuffer = channel->pool->manager->pushbuffer;
unsigned auth_tag_offset = UVM_CONF_COMPUTING_AUTH_TAG_SIZE * push->push_info_index;
if (!uvm_conf_computing_mode_enabled(gpu))
return;
if (!push_info->on_complete)
return;
if (!uvm_channel_is_ce(channel))
return;
if (push_size == 0)
return;
UVM_ASSERT(!uvm_channel_is_wlc(channel));
UVM_ASSERT(!uvm_channel_is_lcic(channel));
UVM_ASSERT(channel->conf_computing.push_crypto_bundles != NULL);
crypto_bundle = channel->conf_computing.push_crypto_bundles + push->push_info_index;
auth_tag_gpu_va = uvm_rm_mem_get_gpu_va(channel->conf_computing.push_crypto_bundle_auth_tags, gpu, false);
auth_tag_gpu_va.address += auth_tag_offset;
crypto_bundle->push_size = push_size;
push_protected_gpu_va = uvm_pushbuffer_get_gpu_va_for_push(pushbuffer, push);
push_unprotected_gpu_va = uvm_pushbuffer_get_unprotected_gpu_va_for_push(pushbuffer, push);
uvm_conf_computing_log_gpu_encryption(channel, &crypto_bundle->iv);
gpu->parent->ce_hal->encrypt(push,
uvm_gpu_address_virtual_unprotected(push_unprotected_gpu_va),
uvm_gpu_address_virtual(push_protected_gpu_va),
push_size,
auth_tag_gpu_va);
}
void uvm_channel_end_push(uvm_push_t *push) void uvm_channel_end_push(uvm_push_t *push)
{ {
uvm_channel_t *channel = push->channel; uvm_channel_t *channel = push->channel;
@@ -1051,6 +1102,8 @@ void uvm_channel_end_push(uvm_push_t *push)
channel_pool_lock(channel->pool); channel_pool_lock(channel->pool);
encrypt_push(push);
new_tracking_value = ++channel->tracking_sem.queued_value; new_tracking_value = ++channel->tracking_sem.queued_value;
new_payload = (NvU32)new_tracking_value; new_payload = (NvU32)new_tracking_value;
@@ -1561,11 +1614,15 @@ static void free_conf_computing_buffers(uvm_channel_t *channel)
uvm_rm_mem_free(channel->conf_computing.static_pb_protected_vidmem); uvm_rm_mem_free(channel->conf_computing.static_pb_protected_vidmem);
uvm_rm_mem_free(channel->conf_computing.static_pb_unprotected_sysmem); uvm_rm_mem_free(channel->conf_computing.static_pb_unprotected_sysmem);
uvm_rm_mem_free(channel->conf_computing.static_notifier_unprotected_sysmem); uvm_rm_mem_free(channel->conf_computing.static_notifier_unprotected_sysmem);
uvm_rm_mem_free(channel->conf_computing.push_crypto_bundle_auth_tags);
uvm_kvfree(channel->conf_computing.static_pb_protected_sysmem); uvm_kvfree(channel->conf_computing.static_pb_protected_sysmem);
uvm_kvfree(channel->conf_computing.push_crypto_bundles);
channel->conf_computing.static_pb_protected_vidmem = NULL; channel->conf_computing.static_pb_protected_vidmem = NULL;
channel->conf_computing.static_pb_unprotected_sysmem = NULL; channel->conf_computing.static_pb_unprotected_sysmem = NULL;
channel->conf_computing.static_notifier_unprotected_sysmem = NULL; channel->conf_computing.static_notifier_unprotected_sysmem = NULL;
channel->conf_computing.push_crypto_bundle_auth_tags = NULL;
channel->conf_computing.static_pb_protected_sysmem = NULL; channel->conf_computing.static_pb_protected_sysmem = NULL;
channel->conf_computing.push_crypto_bundles = NULL;
uvm_rm_mem_free(channel->tracking_sem.semaphore.conf_computing.encrypted_payload); uvm_rm_mem_free(channel->tracking_sem.semaphore.conf_computing.encrypted_payload);
uvm_rm_mem_free(channel->tracking_sem.semaphore.conf_computing.notifier); uvm_rm_mem_free(channel->tracking_sem.semaphore.conf_computing.notifier);
@@ -1702,14 +1759,34 @@ static NV_STATUS alloc_conf_computing_buffers(uvm_channel_t *channel)
{ {
NV_STATUS status; NV_STATUS status;
status = alloc_conf_computing_buffers_semaphore(channel); UVM_ASSERT(uvm_channel_is_secure_ce(channel));
status = alloc_conf_computing_buffers_semaphore(channel);
if (status != NV_OK) if (status != NV_OK)
return status; return status;
if (uvm_channel_is_wlc(channel)) if (uvm_channel_is_wlc(channel)) {
status = alloc_conf_computing_buffers_wlc(channel); status = alloc_conf_computing_buffers_wlc(channel);
else if (uvm_channel_is_lcic(channel)) }
else if (uvm_channel_is_lcic(channel)) {
status = alloc_conf_computing_buffers_lcic(channel); status = alloc_conf_computing_buffers_lcic(channel);
}
else {
uvm_gpu_t *gpu = channel->pool->manager->gpu;
void *push_crypto_bundles = uvm_kvmalloc_zero(sizeof(*channel->conf_computing.push_crypto_bundles) *
channel->num_gpfifo_entries);
if (push_crypto_bundles == NULL)
return NV_ERR_NO_MEMORY;
channel->conf_computing.push_crypto_bundles = push_crypto_bundles;
status = uvm_rm_mem_alloc_and_map_cpu(gpu,
UVM_RM_MEM_TYPE_SYS,
channel->num_gpfifo_entries * UVM_CONF_COMPUTING_AUTH_TAG_SIZE,
UVM_CONF_COMPUTING_BUF_ALIGNMENT,
&channel->conf_computing.push_crypto_bundle_auth_tags);
}
return status; return status;
} }

View File

@@ -355,6 +355,13 @@ struct uvm_channel_struct
// Encryption auth tags have to be located in unprotected sysmem. // Encryption auth tags have to be located in unprotected sysmem.
void *launch_auth_tag_cpu; void *launch_auth_tag_cpu;
NvU64 launch_auth_tag_gpu_va; NvU64 launch_auth_tag_gpu_va;
// Used to decrypt the push back to protected sysmem.
// This happens when profilers register callbacks for migration data.
uvm_push_crypto_bundle_t *push_crypto_bundles;
// Accompanying authentication tags for the crypto bundles
uvm_rm_mem_t *push_crypto_bundle_auth_tags;
} conf_computing; } conf_computing;
// RM channel information // RM channel information

View File

@@ -26,6 +26,7 @@
#include "uvm_conf_computing.h" #include "uvm_conf_computing.h"
#include "uvm_kvmalloc.h" #include "uvm_kvmalloc.h"
#include "uvm_gpu.h" #include "uvm_gpu.h"
#include "uvm_hal.h"
#include "uvm_mem.h" #include "uvm_mem.h"
#include "uvm_processors.h" #include "uvm_processors.h"
#include "uvm_tracker.h" #include "uvm_tracker.h"
@@ -60,8 +61,7 @@ NV_STATUS uvm_conf_computing_init_parent_gpu(const uvm_parent_gpu_t *parent)
uvm_assert_mutex_locked(&g_uvm_global.global_lock); uvm_assert_mutex_locked(&g_uvm_global.global_lock);
// TODO: Bug 2844714. // TODO: Bug 2844714: since we have no routine to traverse parent GPUs,
// Since we have no routine to traverse parent gpus,
// find first child GPU and get its parent. // find first child GPU and get its parent.
first = uvm_global_processor_mask_find_first_gpu(&g_uvm_global.retained_gpus); first = uvm_global_processor_mask_find_first_gpu(&g_uvm_global.retained_gpus);
if (!first) if (!first)
@@ -448,3 +448,51 @@ NV_STATUS uvm_conf_computing_cpu_decrypt(uvm_channel_t *channel,
return status; return status;
} }
NV_STATUS uvm_conf_computing_fault_decrypt(uvm_parent_gpu_t *parent_gpu,
void *dst_plain,
const void *src_cipher,
const void *auth_tag_buffer,
NvU8 valid)
{
NV_STATUS status;
// There is no dedicated lock for the CSL context associated with replayable
// faults. The mutual exclusion required by the RM CSL API is enforced by
// relying on the GPU replayable service lock (ISR lock), since fault
// decryption is invoked as part of fault servicing.
UVM_ASSERT(uvm_sem_is_locked(&parent_gpu->isr.replayable_faults.service_lock));
UVM_ASSERT(!uvm_parent_gpu_replayable_fault_buffer_is_uvm_owned(parent_gpu));
status = nvUvmInterfaceCslDecrypt(&parent_gpu->fault_buffer_info.rm_info.replayable.cslCtx,
parent_gpu->fault_buffer_hal->entry_size(parent_gpu),
(const NvU8 *) src_cipher,
NULL,
(NvU8 *) dst_plain,
&valid,
sizeof(valid),
(const NvU8 *) auth_tag_buffer);
if (status != NV_OK)
UVM_ERR_PRINT("nvUvmInterfaceCslDecrypt() failed: %s, GPU %s\n", nvstatusToString(status), parent_gpu->name);
return status;
}
void uvm_conf_computing_fault_increment_decrypt_iv(uvm_parent_gpu_t *parent_gpu, NvU64 increment)
{
NV_STATUS status;
// See comment in uvm_conf_computing_fault_decrypt
UVM_ASSERT(uvm_sem_is_locked(&parent_gpu->isr.replayable_faults.service_lock));
UVM_ASSERT(!uvm_parent_gpu_replayable_fault_buffer_is_uvm_owned(parent_gpu));
status = nvUvmInterfaceCslIncrementIv(&parent_gpu->fault_buffer_info.rm_info.replayable.cslCtx,
UVM_CSL_OPERATION_DECRYPT,
increment,
NULL);
UVM_ASSERT(status == NV_OK);
}

View File

@@ -177,4 +177,28 @@ NV_STATUS uvm_conf_computing_cpu_decrypt(uvm_channel_t *channel,
const UvmCslIv *src_iv, const UvmCslIv *src_iv,
size_t size, size_t size,
const void *auth_tag_buffer); const void *auth_tag_buffer);
// CPU decryption of a single replayable fault, encrypted by GSP-RM.
//
// Replayable fault decryption depends not only on the encrypted fault contents,
// and the authentication tag, but also on the plaintext valid bit associated
// with the fault.
//
// When decrypting data previously encrypted by the Copy Engine, use
// uvm_conf_computing_cpu_decrypt instead.
//
// Locking: this function must be invoked while holding the replayable ISR lock.
NV_STATUS uvm_conf_computing_fault_decrypt(uvm_parent_gpu_t *parent_gpu,
void *dst_plain,
const void *src_cipher,
const void *auth_tag_buffer,
NvU8 valid);
// Increment the CPU-side decrypt IV of the CSL context associated with
// replayable faults. The function is a no-op if the given increment is zero.
//
// The IV associated with a fault CSL context is a 64-bit counter.
//
// Locking: this function must be invoked while holding the replayable ISR lock.
void uvm_conf_computing_fault_increment_decrypt_iv(uvm_parent_gpu_t *parent_gpu, NvU64 increment);
#endif // __UVM_CONF_COMPUTING_H__ #endif // __UVM_CONF_COMPUTING_H__

View File

@@ -50,6 +50,7 @@ typedef struct uvm_channel_struct uvm_channel_t;
typedef struct uvm_user_channel_struct uvm_user_channel_t; typedef struct uvm_user_channel_struct uvm_user_channel_t;
typedef struct uvm_push_struct uvm_push_t; typedef struct uvm_push_struct uvm_push_t;
typedef struct uvm_push_info_struct uvm_push_info_t; typedef struct uvm_push_info_struct uvm_push_info_t;
typedef struct uvm_push_crypto_bundle_struct uvm_push_crypto_bundle_t;
typedef struct uvm_push_acquire_info_struct uvm_push_acquire_info_t; typedef struct uvm_push_acquire_info_struct uvm_push_acquire_info_t;
typedef struct uvm_pushbuffer_struct uvm_pushbuffer_t; typedef struct uvm_pushbuffer_struct uvm_pushbuffer_t;
typedef struct uvm_gpfifo_entry_struct uvm_gpfifo_entry_t; typedef struct uvm_gpfifo_entry_struct uvm_gpfifo_entry_t;

View File

@@ -198,6 +198,12 @@ typedef struct
// Client type of the service requestor. // Client type of the service requestor.
uvm_fault_client_type_t client_type; uvm_fault_client_type_t client_type;
// New residency ID of the faulting region.
uvm_processor_id_t residency_id;
// New residency NUMA node ID of the faulting region.
int residency_node;
} uvm_ats_fault_context_t; } uvm_ats_fault_context_t;
struct uvm_fault_service_batch_context_struct struct uvm_fault_service_batch_context_struct

View File

@@ -177,31 +177,34 @@ bool uvm_gpu_non_replayable_faults_pending(uvm_parent_gpu_t *parent_gpu)
return has_pending_faults == NV_TRUE; return has_pending_faults == NV_TRUE;
} }
static NvU32 fetch_non_replayable_fault_buffer_entries(uvm_gpu_t *gpu) static NV_STATUS fetch_non_replayable_fault_buffer_entries(uvm_parent_gpu_t *parent_gpu, NvU32 *cached_faults)
{ {
NV_STATUS status; NV_STATUS status;
NvU32 i = 0; NvU32 i;
NvU32 cached_faults = 0; NvU32 entry_size = parent_gpu->fault_buffer_hal->entry_size(parent_gpu);
uvm_fault_buffer_entry_t *fault_cache; uvm_non_replayable_fault_buffer_info_t *non_replayable_faults = &parent_gpu->fault_buffer_info.non_replayable;
NvU32 entry_size = gpu->parent->fault_buffer_hal->entry_size(gpu->parent);
uvm_non_replayable_fault_buffer_info_t *non_replayable_faults = &gpu->parent->fault_buffer_info.non_replayable;
char *current_hw_entry = (char *)non_replayable_faults->shadow_buffer_copy; char *current_hw_entry = (char *)non_replayable_faults->shadow_buffer_copy;
uvm_fault_buffer_entry_t *fault_entry = non_replayable_faults->fault_cache;
fault_cache = non_replayable_faults->fault_cache; UVM_ASSERT(uvm_sem_is_locked(&parent_gpu->isr.non_replayable_faults.service_lock));
UVM_ASSERT(parent_gpu->non_replayable_faults_supported);
UVM_ASSERT(uvm_sem_is_locked(&gpu->parent->isr.non_replayable_faults.service_lock)); status = nvUvmInterfaceGetNonReplayableFaults(&parent_gpu->fault_buffer_info.rm_info,
UVM_ASSERT(gpu->parent->non_replayable_faults_supported); current_hw_entry,
cached_faults);
status = nvUvmInterfaceGetNonReplayableFaults(&gpu->parent->fault_buffer_info.rm_info, if (status != NV_OK) {
non_replayable_faults->shadow_buffer_copy, UVM_ERR_PRINT("nvUvmInterfaceGetNonReplayableFaults() failed: %s, GPU %s\n",
&cached_faults); nvstatusToString(status),
UVM_ASSERT(status == NV_OK); parent_gpu->name);
uvm_global_set_fatal_error(status);
return status;
}
// Parse all faults // Parse all faults
for (i = 0; i < cached_faults; ++i) { for (i = 0; i < *cached_faults; ++i) {
uvm_fault_buffer_entry_t *fault_entry = &non_replayable_faults->fault_cache[i]; parent_gpu->fault_buffer_hal->parse_non_replayable_entry(parent_gpu, current_hw_entry, fault_entry);
gpu->parent->fault_buffer_hal->parse_non_replayable_entry(gpu->parent, current_hw_entry, fault_entry);
// The GPU aligns the fault addresses to 4k, but all of our tracking is // The GPU aligns the fault addresses to 4k, but all of our tracking is
// done in PAGE_SIZE chunks which might be larger. // done in PAGE_SIZE chunks which might be larger.
@@ -226,9 +229,10 @@ static NvU32 fetch_non_replayable_fault_buffer_entries(uvm_gpu_t *gpu)
} }
current_hw_entry += entry_size; current_hw_entry += entry_size;
fault_entry++;
} }
return cached_faults; return NV_OK;
} }
// In SRIOV, the UVM (guest) driver does not have access to the privileged // In SRIOV, the UVM (guest) driver does not have access to the privileged
@@ -705,21 +709,28 @@ exit_no_channel:
uvm_va_space_up_read(va_space); uvm_va_space_up_read(va_space);
uvm_va_space_mm_release_unlock(va_space, mm); uvm_va_space_mm_release_unlock(va_space, mm);
if (status != NV_OK)
UVM_DBG_PRINT("Error servicing non-replayable faults on GPU: %s\n", uvm_gpu_name(gpu));
return status; return status;
} }
void uvm_gpu_service_non_replayable_fault_buffer(uvm_gpu_t *gpu) void uvm_gpu_service_non_replayable_fault_buffer(uvm_gpu_t *gpu)
{ {
NV_STATUS status = NV_OK;
NvU32 cached_faults; NvU32 cached_faults;
// If this handler is modified to handle fewer than all of the outstanding // If this handler is modified to handle fewer than all of the outstanding
// faults, then special handling will need to be added to uvm_suspend() // faults, then special handling will need to be added to uvm_suspend()
// to guarantee that fault processing has completed before control is // to guarantee that fault processing has completed before control is
// returned to the RM. // returned to the RM.
while ((cached_faults = fetch_non_replayable_fault_buffer_entries(gpu)) > 0) { do {
NV_STATUS status;
NvU32 i; NvU32 i;
status = fetch_non_replayable_fault_buffer_entries(gpu->parent, &cached_faults);
if (status != NV_OK)
return;
// Differently to replayable faults, we do not batch up and preprocess // Differently to replayable faults, we do not batch up and preprocess
// non-replayable faults since getting multiple faults on the same // non-replayable faults since getting multiple faults on the same
// memory region is not very likely // memory region is not very likely
@@ -728,10 +739,7 @@ void uvm_gpu_service_non_replayable_fault_buffer(uvm_gpu_t *gpu)
for (i = 0; i < cached_faults; ++i) { for (i = 0; i < cached_faults; ++i) {
status = service_fault(gpu, &gpu->parent->fault_buffer_info.non_replayable.fault_cache[i]); status = service_fault(gpu, &gpu->parent->fault_buffer_info.non_replayable.fault_cache[i]);
if (status != NV_OK) if (status != NV_OK)
break; return;
} }
} } while (cached_faults > 0);
if (status != NV_OK)
UVM_DBG_PRINT("Error servicing non-replayable faults on GPU: %s\n", uvm_gpu_name(gpu));
} }

View File

@@ -486,7 +486,9 @@ static NV_STATUS cancel_fault_precise_va(uvm_gpu_t *gpu,
return status; return status;
} }
static NV_STATUS push_replay_on_gpu(uvm_gpu_t *gpu, uvm_fault_replay_type_t type, uvm_fault_service_batch_context_t *batch_context) static NV_STATUS push_replay_on_gpu(uvm_gpu_t *gpu,
uvm_fault_replay_type_t type,
uvm_fault_service_batch_context_t *batch_context)
{ {
NV_STATUS status; NV_STATUS status;
uvm_push_t push; uvm_push_t push;
@@ -572,6 +574,19 @@ static NV_STATUS hw_fault_buffer_flush_locked(uvm_parent_gpu_t *parent_gpu)
return status; return status;
} }
static void fault_buffer_skip_replayable_entry(uvm_parent_gpu_t *parent_gpu, NvU32 index)
{
UVM_ASSERT(parent_gpu->fault_buffer_hal->entry_is_valid(parent_gpu, index));
// Flushed faults are never decrypted, but the decryption IV associated with
// replayable faults still requires manual adjustment so it is kept in sync
// with the encryption IV on the GSP-RM's side.
if (!uvm_parent_gpu_replayable_fault_buffer_is_uvm_owned(parent_gpu))
uvm_conf_computing_fault_increment_decrypt_iv(parent_gpu, 1);
parent_gpu->fault_buffer_hal->entry_clear_valid(parent_gpu, index);
}
static NV_STATUS fault_buffer_flush_locked(uvm_gpu_t *gpu, static NV_STATUS fault_buffer_flush_locked(uvm_gpu_t *gpu,
uvm_gpu_buffer_flush_mode_t flush_mode, uvm_gpu_buffer_flush_mode_t flush_mode,
uvm_fault_replay_type_t fault_replay, uvm_fault_replay_type_t fault_replay,
@@ -610,7 +625,7 @@ static NV_STATUS fault_buffer_flush_locked(uvm_gpu_t *gpu,
// Wait until valid bit is set // Wait until valid bit is set
UVM_SPIN_WHILE(!parent_gpu->fault_buffer_hal->entry_is_valid(parent_gpu, get), &spin); UVM_SPIN_WHILE(!parent_gpu->fault_buffer_hal->entry_is_valid(parent_gpu, get), &spin);
parent_gpu->fault_buffer_hal->entry_clear_valid(parent_gpu, get); fault_buffer_skip_replayable_entry(parent_gpu, get);
++get; ++get;
if (get == replayable_faults->max_faults) if (get == replayable_faults->max_faults)
get = 0; get = 0;
@@ -785,9 +800,9 @@ static bool fetch_fault_buffer_try_merge_entry(uvm_fault_buffer_entry_t *current
// This optimization cannot be performed during fault cancel on Pascal GPUs // This optimization cannot be performed during fault cancel on Pascal GPUs
// (fetch_mode == FAULT_FETCH_MODE_ALL) since we need accurate tracking of all // (fetch_mode == FAULT_FETCH_MODE_ALL) since we need accurate tracking of all
// the faults in each uTLB in order to guarantee precise fault attribution. // the faults in each uTLB in order to guarantee precise fault attribution.
static void fetch_fault_buffer_entries(uvm_gpu_t *gpu, static NV_STATUS fetch_fault_buffer_entries(uvm_gpu_t *gpu,
uvm_fault_service_batch_context_t *batch_context, uvm_fault_service_batch_context_t *batch_context,
fault_fetch_mode_t fetch_mode) fault_fetch_mode_t fetch_mode)
{ {
NvU32 get; NvU32 get;
NvU32 put; NvU32 put;
@@ -796,6 +811,7 @@ static void fetch_fault_buffer_entries(uvm_gpu_t *gpu,
NvU32 utlb_id; NvU32 utlb_id;
uvm_fault_buffer_entry_t *fault_cache; uvm_fault_buffer_entry_t *fault_cache;
uvm_spin_loop_t spin; uvm_spin_loop_t spin;
NV_STATUS status = NV_OK;
uvm_replayable_fault_buffer_info_t *replayable_faults = &gpu->parent->fault_buffer_info.replayable; uvm_replayable_fault_buffer_info_t *replayable_faults = &gpu->parent->fault_buffer_info.replayable;
const bool in_pascal_cancel_path = (!gpu->parent->fault_cancel_va_supported && fetch_mode == FAULT_FETCH_MODE_ALL); const bool in_pascal_cancel_path = (!gpu->parent->fault_cancel_va_supported && fetch_mode == FAULT_FETCH_MODE_ALL);
const bool may_filter = uvm_perf_fault_coalesce && !in_pascal_cancel_path; const bool may_filter = uvm_perf_fault_coalesce && !in_pascal_cancel_path;
@@ -851,7 +867,9 @@ static void fetch_fault_buffer_entries(uvm_gpu_t *gpu,
smp_mb__after_atomic(); smp_mb__after_atomic();
// Got valid bit set. Let's cache. // Got valid bit set. Let's cache.
gpu->parent->fault_buffer_hal->parse_entry(gpu->parent, get, current_entry); status = gpu->parent->fault_buffer_hal->parse_replayable_entry(gpu->parent, get, current_entry);
if (status != NV_OK)
goto done;
// The GPU aligns the fault addresses to 4k, but all of our tracking is // The GPU aligns the fault addresses to 4k, but all of our tracking is
// done in PAGE_SIZE chunks which might be larger. // done in PAGE_SIZE chunks which might be larger.
@@ -918,6 +936,8 @@ done:
batch_context->num_cached_faults = fault_index; batch_context->num_cached_faults = fault_index;
batch_context->num_coalesced_faults = num_coalesced_faults; batch_context->num_coalesced_faults = num_coalesced_faults;
return status;
} }
// Sort comparator for pointers to fault buffer entries that sorts by // Sort comparator for pointers to fault buffer entries that sorts by
@@ -2475,7 +2495,10 @@ static NV_STATUS cancel_faults_precise_tlb(uvm_gpu_t *gpu, uvm_fault_service_bat
batch_context->has_throttled_faults = false; batch_context->has_throttled_faults = false;
// 5) Fetch all faults from buffer // 5) Fetch all faults from buffer
fetch_fault_buffer_entries(gpu, batch_context, FAULT_FETCH_MODE_ALL); status = fetch_fault_buffer_entries(gpu, batch_context, FAULT_FETCH_MODE_ALL);
if (status != NV_OK)
break;
++batch_context->batch_id; ++batch_context->batch_id;
UVM_ASSERT(batch_context->num_cached_faults == batch_context->num_coalesced_faults); UVM_ASSERT(batch_context->num_cached_faults == batch_context->num_coalesced_faults);
@@ -2612,7 +2635,10 @@ void uvm_gpu_service_replayable_faults(uvm_gpu_t *gpu)
batch_context->has_fatal_faults = false; batch_context->has_fatal_faults = false;
batch_context->has_throttled_faults = false; batch_context->has_throttled_faults = false;
fetch_fault_buffer_entries(gpu, batch_context, FAULT_FETCH_MODE_BATCH_READY); status = fetch_fault_buffer_entries(gpu, batch_context, FAULT_FETCH_MODE_BATCH_READY);
if (status != NV_OK)
break;
if (batch_context->num_cached_faults == 0) if (batch_context->num_cached_faults == 0)
break; break;

View File

@@ -373,7 +373,7 @@ static uvm_hal_class_ops_t fault_buffer_table[] =
.read_get = uvm_hal_maxwell_fault_buffer_read_get_unsupported, .read_get = uvm_hal_maxwell_fault_buffer_read_get_unsupported,
.write_get = uvm_hal_maxwell_fault_buffer_write_get_unsupported, .write_get = uvm_hal_maxwell_fault_buffer_write_get_unsupported,
.get_ve_id = uvm_hal_maxwell_fault_buffer_get_ve_id_unsupported, .get_ve_id = uvm_hal_maxwell_fault_buffer_get_ve_id_unsupported,
.parse_entry = uvm_hal_maxwell_fault_buffer_parse_entry_unsupported, .parse_replayable_entry = uvm_hal_maxwell_fault_buffer_parse_replayable_entry_unsupported,
.entry_is_valid = uvm_hal_maxwell_fault_buffer_entry_is_valid_unsupported, .entry_is_valid = uvm_hal_maxwell_fault_buffer_entry_is_valid_unsupported,
.entry_clear_valid = uvm_hal_maxwell_fault_buffer_entry_clear_valid_unsupported, .entry_clear_valid = uvm_hal_maxwell_fault_buffer_entry_clear_valid_unsupported,
.entry_size = uvm_hal_maxwell_fault_buffer_entry_size_unsupported, .entry_size = uvm_hal_maxwell_fault_buffer_entry_size_unsupported,
@@ -396,7 +396,7 @@ static uvm_hal_class_ops_t fault_buffer_table[] =
.read_put = uvm_hal_pascal_fault_buffer_read_put, .read_put = uvm_hal_pascal_fault_buffer_read_put,
.read_get = uvm_hal_pascal_fault_buffer_read_get, .read_get = uvm_hal_pascal_fault_buffer_read_get,
.write_get = uvm_hal_pascal_fault_buffer_write_get, .write_get = uvm_hal_pascal_fault_buffer_write_get,
.parse_entry = uvm_hal_pascal_fault_buffer_parse_entry, .parse_replayable_entry = uvm_hal_pascal_fault_buffer_parse_replayable_entry,
.entry_is_valid = uvm_hal_pascal_fault_buffer_entry_is_valid, .entry_is_valid = uvm_hal_pascal_fault_buffer_entry_is_valid,
.entry_clear_valid = uvm_hal_pascal_fault_buffer_entry_clear_valid, .entry_clear_valid = uvm_hal_pascal_fault_buffer_entry_clear_valid,
.entry_size = uvm_hal_pascal_fault_buffer_entry_size, .entry_size = uvm_hal_pascal_fault_buffer_entry_size,
@@ -411,7 +411,7 @@ static uvm_hal_class_ops_t fault_buffer_table[] =
.read_get = uvm_hal_volta_fault_buffer_read_get, .read_get = uvm_hal_volta_fault_buffer_read_get,
.write_get = uvm_hal_volta_fault_buffer_write_get, .write_get = uvm_hal_volta_fault_buffer_write_get,
.get_ve_id = uvm_hal_volta_fault_buffer_get_ve_id, .get_ve_id = uvm_hal_volta_fault_buffer_get_ve_id,
.parse_entry = uvm_hal_volta_fault_buffer_parse_entry, .parse_replayable_entry = uvm_hal_volta_fault_buffer_parse_replayable_entry,
.parse_non_replayable_entry = uvm_hal_volta_fault_buffer_parse_non_replayable_entry, .parse_non_replayable_entry = uvm_hal_volta_fault_buffer_parse_non_replayable_entry,
.get_fault_type = uvm_hal_volta_fault_buffer_get_fault_type, .get_fault_type = uvm_hal_volta_fault_buffer_get_fault_type,
} }

View File

@@ -485,11 +485,24 @@ typedef NvU32 (*uvm_hal_fault_buffer_read_get_t)(uvm_parent_gpu_t *parent_gpu);
typedef void (*uvm_hal_fault_buffer_write_get_t)(uvm_parent_gpu_t *parent_gpu, NvU32 get); typedef void (*uvm_hal_fault_buffer_write_get_t)(uvm_parent_gpu_t *parent_gpu, NvU32 get);
typedef NvU8 (*uvm_hal_fault_buffer_get_ve_id_t)(NvU16 mmu_engine_id, uvm_mmu_engine_type_t mmu_engine_type); typedef NvU8 (*uvm_hal_fault_buffer_get_ve_id_t)(NvU16 mmu_engine_id, uvm_mmu_engine_type_t mmu_engine_type);
// Parse the entry on the given buffer index. This also clears the valid bit of // Parse the replayable entry at the given buffer index. This also clears the
// the entry in the buffer. // valid bit of the entry in the buffer.
typedef void (*uvm_hal_fault_buffer_parse_entry_t)(uvm_parent_gpu_t *gpu, typedef NV_STATUS (*uvm_hal_fault_buffer_parse_replayable_entry_t)(uvm_parent_gpu_t *gpu,
NvU32 index, NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry); uvm_fault_buffer_entry_t *buffer_entry);
NV_STATUS uvm_hal_maxwell_fault_buffer_parse_replayable_entry_unsupported(uvm_parent_gpu_t *parent_gpu,
NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry);
NV_STATUS uvm_hal_pascal_fault_buffer_parse_replayable_entry(uvm_parent_gpu_t *parent_gpu,
NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry);
NV_STATUS uvm_hal_volta_fault_buffer_parse_replayable_entry(uvm_parent_gpu_t *parent_gpu,
NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry);
typedef bool (*uvm_hal_fault_buffer_entry_is_valid_t)(uvm_parent_gpu_t *parent_gpu, NvU32 index); typedef bool (*uvm_hal_fault_buffer_entry_is_valid_t)(uvm_parent_gpu_t *parent_gpu, NvU32 index);
typedef void (*uvm_hal_fault_buffer_entry_clear_valid_t)(uvm_parent_gpu_t *parent_gpu, NvU32 index); typedef void (*uvm_hal_fault_buffer_entry_clear_valid_t)(uvm_parent_gpu_t *parent_gpu, NvU32 index);
typedef NvU32 (*uvm_hal_fault_buffer_entry_size_t)(uvm_parent_gpu_t *parent_gpu); typedef NvU32 (*uvm_hal_fault_buffer_entry_size_t)(uvm_parent_gpu_t *parent_gpu);
@@ -508,9 +521,6 @@ NvU32 uvm_hal_maxwell_fault_buffer_read_put_unsupported(uvm_parent_gpu_t *parent
NvU32 uvm_hal_maxwell_fault_buffer_read_get_unsupported(uvm_parent_gpu_t *parent_gpu); NvU32 uvm_hal_maxwell_fault_buffer_read_get_unsupported(uvm_parent_gpu_t *parent_gpu);
void uvm_hal_maxwell_fault_buffer_write_get_unsupported(uvm_parent_gpu_t *parent_gpu, NvU32 index); void uvm_hal_maxwell_fault_buffer_write_get_unsupported(uvm_parent_gpu_t *parent_gpu, NvU32 index);
NvU8 uvm_hal_maxwell_fault_buffer_get_ve_id_unsupported(NvU16 mmu_engine_id, uvm_mmu_engine_type_t mmu_engine_type); NvU8 uvm_hal_maxwell_fault_buffer_get_ve_id_unsupported(NvU16 mmu_engine_id, uvm_mmu_engine_type_t mmu_engine_type);
void uvm_hal_maxwell_fault_buffer_parse_entry_unsupported(uvm_parent_gpu_t *parent_gpu,
NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry);
uvm_fault_type_t uvm_hal_maxwell_fault_buffer_get_fault_type_unsupported(const NvU32 *fault_entry); uvm_fault_type_t uvm_hal_maxwell_fault_buffer_get_fault_type_unsupported(const NvU32 *fault_entry);
void uvm_hal_pascal_enable_replayable_faults(uvm_parent_gpu_t *parent_gpu); void uvm_hal_pascal_enable_replayable_faults(uvm_parent_gpu_t *parent_gpu);
@@ -519,18 +529,14 @@ void uvm_hal_pascal_clear_replayable_faults(uvm_parent_gpu_t *parent_gpu, NvU32
NvU32 uvm_hal_pascal_fault_buffer_read_put(uvm_parent_gpu_t *parent_gpu); NvU32 uvm_hal_pascal_fault_buffer_read_put(uvm_parent_gpu_t *parent_gpu);
NvU32 uvm_hal_pascal_fault_buffer_read_get(uvm_parent_gpu_t *parent_gpu); NvU32 uvm_hal_pascal_fault_buffer_read_get(uvm_parent_gpu_t *parent_gpu);
void uvm_hal_pascal_fault_buffer_write_get(uvm_parent_gpu_t *parent_gpu, NvU32 index); void uvm_hal_pascal_fault_buffer_write_get(uvm_parent_gpu_t *parent_gpu, NvU32 index);
void uvm_hal_pascal_fault_buffer_parse_entry(uvm_parent_gpu_t *parent_gpu,
NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry);
uvm_fault_type_t uvm_hal_pascal_fault_buffer_get_fault_type(const NvU32 *fault_entry); uvm_fault_type_t uvm_hal_pascal_fault_buffer_get_fault_type(const NvU32 *fault_entry);
NvU32 uvm_hal_volta_fault_buffer_read_put(uvm_parent_gpu_t *parent_gpu); NvU32 uvm_hal_volta_fault_buffer_read_put(uvm_parent_gpu_t *parent_gpu);
NvU32 uvm_hal_volta_fault_buffer_read_get(uvm_parent_gpu_t *parent_gpu); NvU32 uvm_hal_volta_fault_buffer_read_get(uvm_parent_gpu_t *parent_gpu);
void uvm_hal_volta_fault_buffer_write_get(uvm_parent_gpu_t *parent_gpu, NvU32 index); void uvm_hal_volta_fault_buffer_write_get(uvm_parent_gpu_t *parent_gpu, NvU32 index);
NvU8 uvm_hal_volta_fault_buffer_get_ve_id(NvU16 mmu_engine_id, uvm_mmu_engine_type_t mmu_engine_type); NvU8 uvm_hal_volta_fault_buffer_get_ve_id(NvU16 mmu_engine_id, uvm_mmu_engine_type_t mmu_engine_type);
void uvm_hal_volta_fault_buffer_parse_entry(uvm_parent_gpu_t *parent_gpu,
NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry);
uvm_fault_type_t uvm_hal_volta_fault_buffer_get_fault_type(const NvU32 *fault_entry); uvm_fault_type_t uvm_hal_volta_fault_buffer_get_fault_type(const NvU32 *fault_entry);
void uvm_hal_turing_disable_replayable_faults(uvm_parent_gpu_t *parent_gpu); void uvm_hal_turing_disable_replayable_faults(uvm_parent_gpu_t *parent_gpu);
@@ -772,7 +778,7 @@ struct uvm_fault_buffer_hal_struct
uvm_hal_fault_buffer_read_get_t read_get; uvm_hal_fault_buffer_read_get_t read_get;
uvm_hal_fault_buffer_write_get_t write_get; uvm_hal_fault_buffer_write_get_t write_get;
uvm_hal_fault_buffer_get_ve_id_t get_ve_id; uvm_hal_fault_buffer_get_ve_id_t get_ve_id;
uvm_hal_fault_buffer_parse_entry_t parse_entry; uvm_hal_fault_buffer_parse_replayable_entry_t parse_replayable_entry;
uvm_hal_fault_buffer_entry_is_valid_t entry_is_valid; uvm_hal_fault_buffer_entry_is_valid_t entry_is_valid;
uvm_hal_fault_buffer_entry_clear_valid_t entry_clear_valid; uvm_hal_fault_buffer_entry_clear_valid_t entry_clear_valid;
uvm_hal_fault_buffer_entry_size_t entry_size; uvm_hal_fault_buffer_entry_size_t entry_size;

View File

@@ -128,6 +128,13 @@ static uvm_gpu_address_t uvm_gpu_address_virtual(NvU64 va)
return address; return address;
} }
static uvm_gpu_address_t uvm_gpu_address_virtual_unprotected(NvU64 va)
{
uvm_gpu_address_t address = uvm_gpu_address_virtual(va);
address.is_unprotected = true;
return address;
}
// Create a physical GPU address // Create a physical GPU address
static uvm_gpu_address_t uvm_gpu_address_physical(uvm_aperture_t aperture, NvU64 pa) static uvm_gpu_address_t uvm_gpu_address_physical(uvm_aperture_t aperture, NvU64 pa)
{ {

View File

@@ -153,6 +153,10 @@ static inline const struct cpumask *uvm_cpumask_of_node(int node)
#define VM_MIXEDMAP 0x00000000 #define VM_MIXEDMAP 0x00000000
#endif #endif
#if !defined(MPOL_PREFERRED_MANY)
#define MPOL_PREFERRED_MANY 5
#endif
// //
// printk.h already defined pr_fmt, so we have to redefine it so the pr_* // printk.h already defined pr_fmt, so we have to redefine it so the pr_*
// routines pick up our version // routines pick up our version

View File

@@ -68,11 +68,12 @@ uvm_fault_type_t uvm_hal_maxwell_fault_buffer_get_fault_type_unsupported(const N
return UVM_FAULT_TYPE_COUNT; return UVM_FAULT_TYPE_COUNT;
} }
void uvm_hal_maxwell_fault_buffer_parse_entry_unsupported(uvm_parent_gpu_t *parent_gpu, NV_STATUS uvm_hal_maxwell_fault_buffer_parse_replayable_entry_unsupported(uvm_parent_gpu_t *parent_gpu,
NvU32 index, NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry) uvm_fault_buffer_entry_t *buffer_entry)
{ {
UVM_ASSERT_MSG(false, "fault_buffer_parse_entry is not supported on GPU: %s.\n", parent_gpu->name); UVM_ASSERT_MSG(false, "fault_buffer_parse_entry is not supported on GPU: %s.\n", parent_gpu->name);
return NV_ERR_NOT_SUPPORTED;
} }
bool uvm_hal_maxwell_fault_buffer_entry_is_valid_unsupported(uvm_parent_gpu_t *parent_gpu, NvU32 index) bool uvm_hal_maxwell_fault_buffer_entry_is_valid_unsupported(uvm_parent_gpu_t *parent_gpu, NvU32 index)

View File

@@ -944,17 +944,18 @@ NV_STATUS uvm_api_migrate(UVM_MIGRATE_PARAMS *params, struct file *filp)
if (type == UVM_API_RANGE_TYPE_ATS) { if (type == UVM_API_RANGE_TYPE_ATS) {
uvm_migrate_args_t uvm_migrate_args = uvm_migrate_args_t uvm_migrate_args =
{ {
.va_space = va_space, .va_space = va_space,
.mm = mm, .mm = mm,
.start = params->base, .start = params->base,
.length = params->length, .length = params->length,
.dst_id = (dest_gpu ? dest_gpu->id : UVM_ID_CPU), .dst_id = (dest_gpu ? dest_gpu->id : UVM_ID_CPU),
.dst_node_id = (int)params->cpuNumaNode, .dst_node_id = (int)params->cpuNumaNode,
.populate_permissions = UVM_POPULATE_PERMISSIONS_INHERIT, .populate_permissions = UVM_POPULATE_PERMISSIONS_INHERIT,
.touch = false, .touch = false,
.skip_mapped = false, .skip_mapped = false,
.user_space_start = &params->userSpaceStart, .populate_on_cpu_alloc_failures = false,
.user_space_length = &params->userSpaceLength, .user_space_start = &params->userSpaceStart,
.user_space_length = &params->userSpaceLength,
}; };
status = uvm_migrate_pageable(&uvm_migrate_args); status = uvm_migrate_pageable(&uvm_migrate_args);

View File

@@ -507,6 +507,22 @@ static NV_STATUS migrate_vma_copy_pages(struct vm_area_struct *vma,
return NV_OK; return NV_OK;
} }
void migrate_vma_cleanup_pages(unsigned long *dst, unsigned long npages)
{
unsigned long i;
for (i = 0; i < npages; i++) {
struct page *dst_page = migrate_pfn_to_page(dst[i]);
if (!dst_page)
continue;
unlock_page(dst_page);
__free_page(dst_page);
dst[i] = 0;
}
}
void uvm_migrate_vma_alloc_and_copy(struct migrate_vma *args, migrate_vma_state_t *state) void uvm_migrate_vma_alloc_and_copy(struct migrate_vma *args, migrate_vma_state_t *state)
{ {
struct vm_area_struct *vma = args->vma; struct vm_area_struct *vma = args->vma;
@@ -531,6 +547,10 @@ void uvm_migrate_vma_alloc_and_copy(struct migrate_vma *args, migrate_vma_state_
if (state->status == NV_OK) if (state->status == NV_OK)
state->status = tracker_status; state->status = tracker_status;
// Mark all pages as not migrating if we're failing
if (state->status != NV_OK)
migrate_vma_cleanup_pages(args->dst, state->num_pages);
} }
void uvm_migrate_vma_alloc_and_copy_helper(struct vm_area_struct *vma, void uvm_migrate_vma_alloc_and_copy_helper(struct vm_area_struct *vma,
@@ -802,7 +822,7 @@ static NV_STATUS migrate_pageable_vma_region(struct vm_area_struct *vma,
// If the destination is the CPU, signal user-space to retry with a // If the destination is the CPU, signal user-space to retry with a
// different node. Otherwise, just try to populate anywhere in the // different node. Otherwise, just try to populate anywhere in the
// system // system
if (UVM_ID_IS_CPU(uvm_migrate_args->dst_id)) { if (UVM_ID_IS_CPU(uvm_migrate_args->dst_id) && !uvm_migrate_args->populate_on_cpu_alloc_failures) {
*next_addr = start + find_first_bit(state->scratch2_mask, num_pages) * PAGE_SIZE; *next_addr = start + find_first_bit(state->scratch2_mask, num_pages) * PAGE_SIZE;
return NV_ERR_MORE_PROCESSING_REQUIRED; return NV_ERR_MORE_PROCESSING_REQUIRED;
} }
@@ -961,13 +981,10 @@ NV_STATUS uvm_migrate_pageable(uvm_migrate_args_t *uvm_migrate_args)
// We only check that dst_node_id is a valid node in the system and it // We only check that dst_node_id is a valid node in the system and it
// doesn't correspond to a GPU node. This is fine because // doesn't correspond to a GPU node. This is fine because
// alloc_pages_node will clamp the allocation to // alloc_pages_node will clamp the allocation to
// cpuset_current_mems_allowed, and uvm_migrate_pageable is only called // cpuset_current_mems_allowed when uvm_migrate_pageable is called from
// from process context (uvm_migrate) when dst_id is CPU. UVM bottom // process context (uvm_migrate) when dst_id is CPU. UVM bottom half
// half never calls uvm_migrate_pageable when dst_id is CPU. So, assert // calls uvm_migrate_pageable with CPU dst_id only when the VMA memory
// that we're in a user thread. However, this would need to change if we // policy is set to dst_node_id and dst_node_id is not NUMA_NO_NODE.
// wanted to call this function from a bottom half with CPU dst_id.
UVM_ASSERT(!(current->flags & PF_KTHREAD));
if (!nv_numa_node_has_memory(dst_node_id) || if (!nv_numa_node_has_memory(dst_node_id) ||
uvm_va_space_find_gpu_with_memory_node_id(va_space, dst_node_id) != NULL) uvm_va_space_find_gpu_with_memory_node_id(va_space, dst_node_id) != NULL)
return NV_ERR_INVALID_ARGUMENT; return NV_ERR_INVALID_ARGUMENT;

View File

@@ -43,6 +43,7 @@ typedef struct
uvm_populate_permissions_t populate_permissions; uvm_populate_permissions_t populate_permissions;
bool touch : 1; bool touch : 1;
bool skip_mapped : 1; bool skip_mapped : 1;
bool populate_on_cpu_alloc_failures : 1;
NvU64 *user_space_start; NvU64 *user_space_start;
NvU64 *user_space_length; NvU64 *user_space_length;
} uvm_migrate_args_t; } uvm_migrate_args_t;

View File

@@ -214,9 +214,9 @@ static UvmFaultMetadataPacket *get_fault_buffer_entry_metadata(uvm_parent_gpu_t
return fault_entry_metadata + index; return fault_entry_metadata + index;
} }
void uvm_hal_pascal_fault_buffer_parse_entry(uvm_parent_gpu_t *parent_gpu, NV_STATUS uvm_hal_pascal_fault_buffer_parse_replayable_entry(uvm_parent_gpu_t *parent_gpu,
NvU32 index, NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry) uvm_fault_buffer_entry_t *buffer_entry)
{ {
NvU32 *fault_entry; NvU32 *fault_entry;
NvU64 addr_hi, addr_lo; NvU64 addr_hi, addr_lo;
@@ -280,6 +280,8 @@ void uvm_hal_pascal_fault_buffer_parse_entry(uvm_parent_gpu_t *parent_gpu,
// Automatically clear valid bit for the entry in the fault buffer // Automatically clear valid bit for the entry in the fault buffer
uvm_hal_pascal_fault_buffer_entry_clear_valid(parent_gpu, index); uvm_hal_pascal_fault_buffer_entry_clear_valid(parent_gpu, index);
return NV_OK;
} }
bool uvm_hal_pascal_fault_buffer_entry_is_valid(uvm_parent_gpu_t *parent_gpu, NvU32 index) bool uvm_hal_pascal_fault_buffer_entry_is_valid(uvm_parent_gpu_t *parent_gpu, NvU32 index)

View File

@@ -1455,7 +1455,18 @@ static uvm_perf_thrashing_hint_t get_hint_for_migration_thrashing(va_space_thras
hint.type = UVM_PERF_THRASHING_HINT_TYPE_NONE; hint.type = UVM_PERF_THRASHING_HINT_TYPE_NONE;
closest_resident_id = uvm_va_block_page_get_closest_resident(va_block, page_index, requester); closest_resident_id = uvm_va_block_page_get_closest_resident(va_block, page_index, requester);
UVM_ASSERT(UVM_ID_IS_VALID(closest_resident_id)); if (uvm_va_block_is_hmm(va_block)) {
// HMM pages always start out resident on the CPU but may not be
// recorded in the va_block state because hmm_range_fault() or
// similar functions haven't been called to get an accurate snapshot
// of the Linux state. We can assume pages are CPU resident for the
// purpose of deciding where to migrate to reduce thrashing.
if (UVM_ID_IS_INVALID(closest_resident_id))
closest_resident_id = UVM_ID_CPU;
}
else {
UVM_ASSERT(UVM_ID_IS_VALID(closest_resident_id));
}
if (thrashing_processors_can_access(va_space, page_thrashing, preferred_location)) { if (thrashing_processors_can_access(va_space, page_thrashing, preferred_location)) {
// The logic in uvm_va_block_select_residency chooses the preferred // The logic in uvm_va_block_select_residency chooses the preferred

View File

@@ -64,6 +64,14 @@ typedef enum
UVM_PUSH_FLAG_COUNT, UVM_PUSH_FLAG_COUNT,
} uvm_push_flag_t; } uvm_push_flag_t;
struct uvm_push_crypto_bundle_struct {
// Initialization vector used to decrypt the push
UvmCslIv iv;
// Size of the pushbuffer that is encrypted/decrypted
NvU32 push_size;
};
struct uvm_push_struct struct uvm_push_struct
{ {
// Location of the first method of the push // Location of the first method of the push

View File

@@ -776,15 +776,6 @@ static NV_STATUS test_timestamp_on_gpu(uvm_gpu_t *gpu)
NvU32 i; NvU32 i;
NvU64 last_stamp = 0; NvU64 last_stamp = 0;
// TODO: Bug 3988992: [UVM][HCC] RFE - Support encrypted semaphore for secure CE channels
// This test is waived when Confidential Computing is enabled because it
// assumes that CPU can directly read the result of a semaphore timestamp
// operation. Instead the operation needs to be follower up by an encrypt
// -decrypt trip to be accessible to CPU. This will be cleaner and simpler
// once encrypted semaphores are available.
if (uvm_conf_computing_mode_enabled(gpu))
return NV_OK;
for (i = 0; i < 10; ++i) { for (i = 0; i < 10; ++i) {
status = uvm_push_begin(gpu->channel_manager, UVM_CHANNEL_TYPE_GPU_INTERNAL, &push, "Releasing a timestamp"); status = uvm_push_begin(gpu->channel_manager, UVM_CHANNEL_TYPE_GPU_INTERNAL, &push, "Releasing a timestamp");
if (status != NV_OK) if (status != NV_OK)

View File

@@ -449,21 +449,68 @@ static uvm_pushbuffer_chunk_t *gpfifo_to_chunk(uvm_pushbuffer_t *pushbuffer, uvm
return chunk; return chunk;
} }
void uvm_pushbuffer_mark_completed(uvm_pushbuffer_t *pushbuffer, uvm_gpfifo_entry_t *gpfifo) static void decrypt_push(uvm_channel_t *channel, uvm_gpfifo_entry_t *gpfifo)
{
NV_STATUS status;
NvU32 auth_tag_offset;
void *auth_tag_cpu_va;
void *push_protected_cpu_va;
void *push_unprotected_cpu_va;
NvU32 pushbuffer_offset = gpfifo->pushbuffer_offset;
NvU32 push_info_index = gpfifo->push_info - channel->push_infos;
uvm_pushbuffer_t *pushbuffer = channel->pool->manager->pushbuffer;
uvm_push_crypto_bundle_t *crypto_bundle = channel->conf_computing.push_crypto_bundles + push_info_index;
if (channel->conf_computing.push_crypto_bundles == NULL)
return;
// When the crypto bundle is used, the push size cannot be zero
if (crypto_bundle->push_size == 0)
return;
UVM_ASSERT(!uvm_channel_is_wlc(channel));
UVM_ASSERT(!uvm_channel_is_lcic(channel));
push_protected_cpu_va = (char *)get_base_cpu_va(pushbuffer) + pushbuffer_offset;
push_unprotected_cpu_va = (char *)uvm_rm_mem_get_cpu_va(pushbuffer->memory_unprotected_sysmem) + pushbuffer_offset;
auth_tag_offset = push_info_index * UVM_CONF_COMPUTING_AUTH_TAG_SIZE;
auth_tag_cpu_va = (char *)uvm_rm_mem_get_cpu_va(channel->conf_computing.push_crypto_bundle_auth_tags) +
auth_tag_offset;
status = uvm_conf_computing_cpu_decrypt(channel,
push_protected_cpu_va,
push_unprotected_cpu_va,
&crypto_bundle->iv,
crypto_bundle->push_size,
auth_tag_cpu_va);
// A decryption failure here is not fatal because it does not
// prevent UVM from running fine in the future and cannot be used
// maliciously to leak information or otherwise derail UVM from its
// regular duties.
UVM_ASSERT_MSG_RELEASE(status == NV_OK, "Pushbuffer decryption failure: %s\n", nvstatusToString(status));
// Avoid reusing the bundle across multiple pushes
crypto_bundle->push_size = 0;
}
void uvm_pushbuffer_mark_completed(uvm_channel_t *channel, uvm_gpfifo_entry_t *gpfifo)
{ {
uvm_pushbuffer_chunk_t *chunk; uvm_pushbuffer_chunk_t *chunk;
uvm_push_info_t *push_info = gpfifo->push_info;
bool need_to_update_chunk = false; bool need_to_update_chunk = false;
uvm_push_info_t *push_info = gpfifo->push_info;
uvm_pushbuffer_t *pushbuffer = channel->pool->manager->pushbuffer;
UVM_ASSERT(gpfifo->type == UVM_GPFIFO_ENTRY_TYPE_NORMAL); UVM_ASSERT(gpfifo->type == UVM_GPFIFO_ENTRY_TYPE_NORMAL);
chunk = gpfifo_to_chunk(pushbuffer, gpfifo); chunk = gpfifo_to_chunk(pushbuffer, gpfifo);
if (push_info->on_complete != NULL) if (push_info->on_complete != NULL) {
decrypt_push(channel, gpfifo);
push_info->on_complete(push_info->on_complete_data); push_info->on_complete(push_info->on_complete_data);
push_info->on_complete = NULL;
push_info->on_complete = NULL; push_info->on_complete_data = NULL;
push_info->on_complete_data = NULL; }
uvm_spin_lock(&pushbuffer->lock); uvm_spin_lock(&pushbuffer->lock);

View File

@@ -258,7 +258,7 @@ NV_STATUS uvm_pushbuffer_begin_push(uvm_pushbuffer_t *pushbuffer, uvm_push_t *pu
// Complete a pending push // Complete a pending push
// Updates the chunk state the pending push used // Updates the chunk state the pending push used
void uvm_pushbuffer_mark_completed(uvm_pushbuffer_t *pushbuffer, uvm_gpfifo_entry_t *gpfifo); void uvm_pushbuffer_mark_completed(uvm_channel_t *channel, uvm_gpfifo_entry_t *gpfifo);
// Get the GPU VA for an ongoing push // Get the GPU VA for an ongoing push
NvU64 uvm_pushbuffer_get_gpu_va_for_push(uvm_pushbuffer_t *pushbuffer, uvm_push_t *push); NvU64 uvm_pushbuffer_get_gpu_va_for_push(uvm_pushbuffer_t *pushbuffer, uvm_push_t *push);

View File

@@ -275,13 +275,15 @@ static NV_STATUS alloc_and_init_mem(uvm_gpu_t *gpu, uvm_mem_t **mem, size_t size
TEST_NV_CHECK_GOTO(ce_memset_gpu(gpu, *mem, size, 0xdead), err); TEST_NV_CHECK_GOTO(ce_memset_gpu(gpu, *mem, size, 0xdead), err);
} }
else { else {
if (type == MEM_ALLOC_TYPE_SYSMEM_DMA) if (type == MEM_ALLOC_TYPE_SYSMEM_DMA) {
TEST_NV_CHECK_RET(uvm_mem_alloc_sysmem_dma(size, gpu, NULL, mem)); TEST_NV_CHECK_RET(uvm_mem_alloc_sysmem_dma(size, gpu, NULL, mem));
else TEST_NV_CHECK_GOTO(uvm_mem_map_gpu_kernel(*mem, gpu), err);
}
else {
TEST_NV_CHECK_RET(uvm_mem_alloc_sysmem(size, NULL, mem)); TEST_NV_CHECK_RET(uvm_mem_alloc_sysmem(size, NULL, mem));
}
TEST_NV_CHECK_GOTO(uvm_mem_map_cpu_kernel(*mem), err); TEST_NV_CHECK_GOTO(uvm_mem_map_cpu_kernel(*mem), err);
TEST_NV_CHECK_GOTO(uvm_mem_map_gpu_kernel(*mem, gpu), err);
write_range_cpu(*mem, size, 0xdeaddead); write_range_cpu(*mem, size, 0xdeaddead);
} }
@@ -443,7 +445,6 @@ static NV_STATUS test_cpu_to_gpu_roundtrip(uvm_gpu_t *gpu, size_t copy_size, siz
cpu_encrypt(push.channel, src_cipher, src_plain, auth_tag_mem, size, copy_size); cpu_encrypt(push.channel, src_cipher, src_plain, auth_tag_mem, size, copy_size);
gpu_decrypt(&push, dst_plain, src_cipher, auth_tag_mem, size, copy_size); gpu_decrypt(&push, dst_plain, src_cipher, auth_tag_mem, size, copy_size);
// Wait for SEC2 before launching the CE part. // Wait for SEC2 before launching the CE part.
// SEC2 is only allowed to release semaphores in unprotected sysmem, // SEC2 is only allowed to release semaphores in unprotected sysmem,
// and CE can only acquire semaphores in protected vidmem. // and CE can only acquire semaphores in protected vidmem.

View File

@@ -2083,12 +2083,6 @@ static uvm_processor_id_t block_page_get_closest_resident_in_mask(uvm_va_block_t
return id; return id;
} }
// HMM va_blocks don't know if a page is CPU resident until either
// migrate_vma_setup() or hmm_range_fault() is called. If a page isn't
// resident anywhere, assume it is CPU resident.
if (uvm_va_block_is_hmm(va_block))
return UVM_ID_CPU;
return UVM_ID_INVALID; return UVM_ID_INVALID;
} }
@@ -2888,7 +2882,7 @@ static uvm_va_block_region_t block_phys_contig_region(uvm_va_block_t *block,
{ {
if (UVM_ID_IS_CPU(resident_id)) { if (UVM_ID_IS_CPU(resident_id)) {
uvm_cpu_chunk_t *chunk = uvm_cpu_chunk_get_chunk_for_page(block, page_index); uvm_cpu_chunk_t *chunk = uvm_cpu_chunk_get_chunk_for_page(block, page_index);
return uvm_va_block_region(page_index, page_index + uvm_cpu_chunk_num_pages(chunk)); return uvm_cpu_chunk_block_region(block, chunk, page_index);
} }
else { else {
uvm_chunk_size_t chunk_size; uvm_chunk_size_t chunk_size;

View File

@@ -25,7 +25,8 @@
#include "uvm_global.h" #include "uvm_global.h"
#include "uvm_gpu.h" #include "uvm_gpu.h"
#include "uvm_hal.h" #include "uvm_hal.h"
#include "uvm_push.h" #include "uvm_conf_computing.h"
#include "nv_uvm_types.h"
#include "hwref/volta/gv100/dev_fault.h" #include "hwref/volta/gv100/dev_fault.h"
#include "hwref/volta/gv100/dev_fb.h" #include "hwref/volta/gv100/dev_fb.h"
#include "clc369.h" #include "clc369.h"
@@ -246,6 +247,20 @@ static NvU32 *get_fault_buffer_entry(uvm_parent_gpu_t *parent_gpu, NvU32 index)
return fault_entry; return fault_entry;
} }
// See uvm_pascal_fault_buffer.c::get_fault_buffer_entry_metadata
static UvmFaultMetadataPacket *get_fault_buffer_entry_metadata(uvm_parent_gpu_t *parent_gpu, NvU32 index)
{
UvmFaultMetadataPacket *fault_entry_metadata;
UVM_ASSERT(index < parent_gpu->fault_buffer_info.replayable.max_faults);
UVM_ASSERT(!uvm_parent_gpu_replayable_fault_buffer_is_uvm_owned(parent_gpu));
fault_entry_metadata = parent_gpu->fault_buffer_info.rm_info.replayable.bufferMetadata;
UVM_ASSERT(fault_entry_metadata != NULL);
return fault_entry_metadata + index;
}
static void parse_fault_entry_common(uvm_parent_gpu_t *parent_gpu, static void parse_fault_entry_common(uvm_parent_gpu_t *parent_gpu,
NvU32 *fault_entry, NvU32 *fault_entry,
uvm_fault_buffer_entry_t *buffer_entry) uvm_fault_buffer_entry_t *buffer_entry)
@@ -323,24 +338,47 @@ static void parse_fault_entry_common(uvm_parent_gpu_t *parent_gpu,
UVM_ASSERT_MSG(replayable_fault_enabled, "Fault with REPLAYABLE_FAULT_EN bit unset\n"); UVM_ASSERT_MSG(replayable_fault_enabled, "Fault with REPLAYABLE_FAULT_EN bit unset\n");
} }
void uvm_hal_volta_fault_buffer_parse_entry(uvm_parent_gpu_t *parent_gpu, NV_STATUS uvm_hal_volta_fault_buffer_parse_replayable_entry(uvm_parent_gpu_t *parent_gpu,
NvU32 index, NvU32 index,
uvm_fault_buffer_entry_t *buffer_entry) uvm_fault_buffer_entry_t *buffer_entry)
{ {
fault_buffer_entry_c369_t entry;
NvU32 *fault_entry; NvU32 *fault_entry;
BUILD_BUG_ON(NVC369_BUF_SIZE > UVM_GPU_MMU_MAX_FAULT_PACKET_SIZE);
BUILD_BUG_ON(sizeof(entry) > UVM_GPU_MMU_MAX_FAULT_PACKET_SIZE);
// Valid bit must be set before this function is called // Valid bit must be set before this function is called
UVM_ASSERT(parent_gpu->fault_buffer_hal->entry_is_valid(parent_gpu, index)); UVM_ASSERT(parent_gpu->fault_buffer_hal->entry_is_valid(parent_gpu, index));
fault_entry = get_fault_buffer_entry(parent_gpu, index); fault_entry = get_fault_buffer_entry(parent_gpu, index);
// When Confidential Computing is enabled, faults are encrypted by RM, so
// they need to be decrypted before they can be parsed
if (!uvm_parent_gpu_replayable_fault_buffer_is_uvm_owned(parent_gpu)) {
NV_STATUS status;
UvmFaultMetadataPacket *fault_entry_metadata = get_fault_buffer_entry_metadata(parent_gpu, index);
status = uvm_conf_computing_fault_decrypt(parent_gpu,
&entry,
fault_entry,
fault_entry_metadata->authTag,
fault_entry_metadata->valid);
if (status != NV_OK) {
uvm_global_set_fatal_error(status);
return status;
}
fault_entry = (NvU32 *) &entry;
}
parse_fault_entry_common(parent_gpu, fault_entry, buffer_entry); parse_fault_entry_common(parent_gpu, fault_entry, buffer_entry);
UVM_ASSERT(buffer_entry->is_replayable); UVM_ASSERT(buffer_entry->is_replayable);
// Automatically clear valid bit for the entry in the fault buffer // Automatically clear valid bit for the entry in the fault buffer
parent_gpu->fault_buffer_hal->entry_clear_valid(parent_gpu, index); parent_gpu->fault_buffer_hal->entry_clear_valid(parent_gpu, index);
return NV_OK;
} }
void uvm_hal_volta_fault_buffer_parse_non_replayable_entry(uvm_parent_gpu_t *parent_gpu, void uvm_hal_volta_fault_buffer_parse_non_replayable_entry(uvm_parent_gpu_t *parent_gpu,

View File

@@ -939,6 +939,12 @@ nvswitch_os_get_os_version
NvU32 *pBuildNum NvU32 *pBuildNum
); );
NvlStatus
nvswitch_os_get_pid
(
NvU32 *pPid
);
void void
nvswitch_lib_smbpbi_log_sxid nvswitch_lib_smbpbi_log_sxid
( (

View File

@@ -0,0 +1,211 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_AEAD_H
#define CRYPTLIB_AEAD_H
/*=====================================================================================
* Authenticated Encryption with Associated data (AEAD) Cryptography Primitives
*=====================================================================================
*/
#if LIBSPDM_AEAD_GCM_SUPPORT
/**
* Performs AEAD AES-GCM authenticated encryption on a data buffer and additional authenticated
* data.
*
* iv_size must be 12, otherwise false is returned.
* key_size must be 16 or 32, otherwise false is returned.
* tag_size must be 12, 13, 14, 15, 16, otherwise false is returned.
*
* @param[in] key Pointer to the encryption key.
* @param[in] key_size Size of the encryption key in bytes.
* @param[in] iv Pointer to the IV value.
* @param[in] iv_size Size of the IV value in bytes.
* @param[in] a_data Pointer to the additional authenticated data.
* @param[in] a_data_size Size of the additional authenticated data in bytes.
* @param[in] data_in Pointer to the input data buffer to be encrypted.
* @param[in] data_in_size Size of the input data buffer in bytes.
* @param[out] tag_out Pointer to a buffer that receives the authentication tag output.
* @param[in] tag_size Size of the authentication tag in bytes.
* @param[out] data_out Pointer to a buffer that receives the encryption output.
* @param[out] data_out_size Size of the output data buffer in bytes.
*
* @retval true AEAD AES-GCM authenticated encryption succeeded.
* @retval false AEAD AES-GCM authenticated encryption failed.
**/
extern bool libspdm_aead_aes_gcm_encrypt(const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
uint8_t *tag_out, size_t tag_size,
uint8_t *data_out, size_t *data_out_size);
/**
* Performs AEAD AES-GCM authenticated decryption on a data buffer and additional authenticated
* data.
*
* iv_size must be 12, otherwise false is returned.
* key_size must be 16 or 32, otherwise false is returned.
* tag_size must be 12, 13, 14, 15, 16, otherwise false is returned.
*
* If data verification fails, false is returned.
*
* @param[in] key Pointer to the encryption key.
* @param[in] key_size Size of the encryption key in bytes.
* @param[in] iv Pointer to the IV value.
* @param[in] iv_size Size of the IV value in bytes.
* @param[in] a_data Pointer to the additional authenticated data.
* @param[in] a_data_size Size of the additional authenticated data in bytes.
* @param[in] data_in Pointer to the input data buffer to be decrypted.
* @param[in] data_in_size Size of the input data buffer in bytes.
* @param[in] tag Pointer to a buffer that contains the authentication tag.
* @param[in] tag_size Size of the authentication tag in bytes.
* @param[out] data_out Pointer to a buffer that receives the decryption output.
* @param[out] data_out_size Size of the output data buffer in bytes.
*
* @retval true AEAD AES-GCM authenticated decryption succeeded.
* @retval false AEAD AES-GCM authenticated decryption failed.
**/
extern bool libspdm_aead_aes_gcm_decrypt(const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
const uint8_t *tag, size_t tag_size,
uint8_t *data_out, size_t *data_out_size);
#endif /* LIBSPDM_AEAD_GCM_SUPPORT */
#if LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT
/**
* Performs AEAD ChaCha20Poly1305 authenticated encryption on a data buffer and additional
* authenticated data.
*
* iv_size must be 12, otherwise false is returned.
* key_size must be 32, otherwise false is returned.
* tag_size must be 16, otherwise false is returned.
*
* @param[in] key Pointer to the encryption key.
* @param[in] key_size Size of the encryption key in bytes.
* @param[in] iv Pointer to the IV value.
* @param[in] iv_size Size of the IV value in bytes.
* @param[in] a_data Pointer to the additional authenticated data.
* @param[in] a_data_size Size of the additional authenticated data in bytes.
* @param[in] data_in Pointer to the input data buffer to be encrypted.
* @param[in] data_in_size Size of the input data buffer in bytes.
* @param[out] tag_out Pointer to a buffer that receives the authentication tag output.
* @param[in] tag_size Size of the authentication tag in bytes.
* @param[out] data_out Pointer to a buffer that receives the encryption output.
* @param[out] data_out_size Size of the output data buffer in bytes.
*
* @retval true AEAD ChaCha20Poly1305 authenticated encryption succeeded.
* @retval false AEAD ChaCha20Poly1305 authenticated encryption failed.
**/
extern bool libspdm_aead_chacha20_poly1305_encrypt(
const uint8_t *key, size_t key_size, const uint8_t *iv,
size_t iv_size, const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size, uint8_t *tag_out,
size_t tag_size, uint8_t *data_out, size_t *data_out_size);
/**
* Performs AEAD ChaCha20Poly1305 authenticated decryption on a data buffer and additional authenticated data (AAD).
*
* iv_size must be 12, otherwise false is returned.
* key_size must be 32, otherwise false is returned.
* tag_size must be 16, otherwise false is returned.
*
* If data verification fails, false is returned.
*
* @param[in] key Pointer to the encryption key.
* @param[in] key_size Size of the encryption key in bytes.
* @param[in] iv Pointer to the IV value.
* @param[in] iv_size Size of the IV value in bytes.
* @param[in] a_data Pointer to the additional authenticated data.
* @param[in] a_data_size Size of the additional authenticated data in bytes.
* @param[in] data_in Pointer to the input data buffer to be decrypted.
* @param[in] data_in_size Size of the input data buffer in bytes.
* @param[in] tag Pointer to a buffer that contains the authentication tag.
* @param[in] tag_size Size of the authentication tag in bytes.
* @param[out] data_out Pointer to a buffer that receives the decryption output.
* @param[out] data_out_size Size of the output data buffer in bytes.
*
* @retval true AEAD ChaCha20Poly1305 authenticated decryption succeeded.
* @retval false AEAD ChaCha20Poly1305 authenticated decryption failed.
*
**/
extern bool libspdm_aead_chacha20_poly1305_decrypt(
const uint8_t *key, size_t key_size, const uint8_t *iv,
size_t iv_size, const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size, const uint8_t *tag,
size_t tag_size, uint8_t *data_out, size_t *data_out_size);
#endif /* LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT */
#if LIBSPDM_AEAD_SM4_SUPPORT
/**
* Performs AEAD SM4-GCM authenticated encryption on a data buffer and additional authenticated
* data.
*
* iv_size must be 12, otherwise false is returned.
* key_size must be 16, otherwise false is returned.
* tag_size must be 16, otherwise false is returned.
*
* @param[in] key Pointer to the encryption key.
* @param[in] key_size Size of the encryption key in bytes.
* @param[in] iv Pointer to the IV value.
* @param[in] iv_size Size of the IV value in bytes.
* @param[in] a_data Pointer to the additional authenticated data.
* @param[in] a_data_size Size of the additional authenticated data in bytes.
* @param[in] data_in Pointer to the input data buffer to be encrypted.
* @param[in] data_in_size Size of the input data buffer in bytes.
* @param[out] tag_out Pointer to a buffer that receives the authentication tag output.
* @param[in] tag_size Size of the authentication tag in bytes.
* @param[out] data_out Pointer to a buffer that receives the encryption output.
* @param[out] data_out_size Size of the output data buffer in bytes.
*
* @retval true AEAD SM4-GCM authenticated encryption succeeded.
* @retval false AEAD SM4-GCM authenticated encryption failed.
**/
extern bool libspdm_aead_sm4_gcm_encrypt(const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
uint8_t *tag_out, size_t tag_size,
uint8_t *data_out, size_t *data_out_size);
/**
* Performs AEAD SM4-GCM authenticated decryption on a data buffer and additional authenticated
* data.
*
* iv_size must be 12, otherwise false is returned.
* key_size must be 16, otherwise false is returned.
* tag_size must be 16, otherwise false is returned.
*
* If data verification fails, false is returned.
*
* @param[in] key Pointer to the encryption key.
* @param[in] key_size Size of the encryption key in bytes.
* @param[in] iv Pointer to the IV value.
* @param[in] iv_size Size of the IV value in bytes.
* @param[in] a_data Pointer to the additional authenticated data.
* @param[in] a_data_size Size of the additional authenticated data in bytes.
* @param[in] data_in Pointer to the input data buffer to be decrypted.
* @param[in] data_in_size Size of the input data buffer in bytes.
* @param[in] tag Pointer to a buffer that contains the authentication tag.
* @param[in] tag_size Size of the authentication tag in bytes.
* @param[out] data_out Pointer to a buffer that receives the decryption output.
* @param[out] data_out_size Size of the output data buffer in bytes.
*
* @retval true AEAD SM4-GCM authenticated decryption succeeded.
* @retval false AEAD SM4-GCM authenticated decryption failed.
**/
extern bool libspdm_aead_sm4_gcm_decrypt(const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
const uint8_t *tag, size_t tag_size,
uint8_t *data_out, size_t *data_out_size);
#endif /* LIBSPDM_AEAD_SM4_SUPPORT */
#endif /* CRYPTLIB_AEAD_H */

View File

@@ -0,0 +1,416 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_CERT_H
#define CRYPTLIB_CERT_H
/**
* Retrieve the tag and length of the tag.
*
* @param ptr The position in the ASN.1 data.
* @param end End of data.
* @param length The variable that will receive the length.
* @param tag The expected tag.
*
* @retval true Get tag successful.
* @retval false Failed to get tag or tag not match.
**/
extern bool libspdm_asn1_get_tag(uint8_t **ptr, const uint8_t *end, size_t *length, uint32_t tag);
/**
* Retrieve the subject bytes from one X.509 certificate.
*
* If cert is NULL, then return false.
* If subject_size is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] cert_subject Pointer to the retrieved certificate subject bytes.
* @param[in, out] subject_size The size in bytes of the cert_subject buffer on input,
* and the size of buffer returned cert_subject on output.
*
* @retval true The certificate subject retrieved successfully.
* @retval false Invalid certificate, or the subject_size is too small for the result.
* The subject_size will be updated with the required size.
* @retval false This interface is not supported.
**/
extern bool libspdm_x509_get_subject_name(const uint8_t *cert, size_t cert_size,
uint8_t *cert_subject,
size_t *subject_size);
/**
* Retrieve the version from one X.509 certificate.
*
* If cert is NULL, then return false.
* If cert_size is 0, then return false.
* If this interface is not supported, then return false.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] version Pointer to the retrieved version integer.
*
* @retval true
* @retval false
**/
extern bool libspdm_x509_get_version(const uint8_t *cert, size_t cert_size, size_t *version);
/**
* Retrieve the serialNumber from one X.509 certificate.
*
* If cert is NULL, then return false.
* If cert_size is 0, then return false.
* If this interface is not supported, then return false.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] serial_number Pointer to the retrieved certificate serial_number bytes.
* @param[in, out] serial_number_size The size in bytes of the serial_number buffer on input,
* and the size of buffer returned serial_number on output.
*
* @retval true
* @retval false
**/
extern bool libspdm_x509_get_serial_number(const uint8_t *cert, size_t cert_size,
uint8_t *serial_number,
size_t *serial_number_size);
/**
* Retrieve the issuer bytes from one X.509 certificate.
*
* If cert is NULL, then return false.
* If issuer_size is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] cert_issuer Pointer to the retrieved certificate subject bytes.
* @param[in, out] issuer_size The size in bytes of the cert_issuer buffer on input,
* and the size of buffer returned cert_issuer on output.
*
* @retval true The certificate issuer retrieved successfully.
* @retval false Invalid certificate, or the issuer_size is too small for the result.
* The issuer_size will be updated with the required size.
* @retval false This interface is not supported.
**/
extern bool libspdm_x509_get_issuer_name(const uint8_t *cert, size_t cert_size,
uint8_t *cert_issuer,
size_t *issuer_size);
/**
* Retrieve Extension data from one X.509 certificate.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[in] oid Object identifier buffer
* @param[in] oid_size Object identifier buffer size
* @param[out] extension_data Extension bytes.
* @param[in, out] extension_data_size Extension bytes size.
*
* @retval true
* @retval false
**/
extern bool libspdm_x509_get_extension_data(const uint8_t *cert, size_t cert_size,
const uint8_t *oid, size_t oid_size,
uint8_t *extension_data,
size_t *extension_data_size);
/**
* Retrieve the Validity from one X.509 certificate
*
* If cert is NULL, then return false.
* If CertIssuerSize is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] from notBefore Pointer to date_time object.
* @param[in,out] from_size notBefore date_time object size.
* @param[out] to notAfter Pointer to date_time object.
* @param[in,out] to_size notAfter date_time object size.
*
* Note: libspdm_x509_compare_date_time to compare date_time oject
* x509SetDateTime to get a date_time object from a date_time_str
*
* @retval true The certificate Validity retrieved successfully.
* @retval false Invalid certificate, or Validity retrieve failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size,
uint8_t *from, size_t *from_size, uint8_t *to,
size_t *to_size);
/**
* Format a date_time object into DataTime buffer
*
* If date_time_str is NULL, then return false.
* If date_time_size is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] date_time_str date_time string like YYYYMMDDhhmmssZ
* Ref: https://www.w3.org/TR/NOTE-datetime
* Z stand for UTC time
* @param[out] date_time Pointer to a date_time object.
* @param[in,out] date_time_size date_time object buffer size.
*
* @retval true
* @retval false
**/
extern bool libspdm_x509_set_date_time(const char *date_time_str, void *date_time,
size_t *date_time_size);
/**
* Compare date_time1 object and date_time2 object.
*
* If date_time1 is NULL, then return -2.
* If date_time2 is NULL, then return -2.
* If date_time1 == date_time2, then return 0
* If date_time1 > date_time2, then return 1
* If date_time1 < date_time2, then return -1
*
* @param[in] date_time1 Pointer to a date_time Ojbect
* @param[in] date_time2 Pointer to a date_time Object
*
* @retval 0 If date_time1 == date_time2
* @retval 1 If date_time1 > date_time2
* @retval -1 If date_time1 < date_time2
**/
extern int32_t libspdm_x509_compare_date_time(const void *date_time1, const void *date_time2);
/**
* Retrieve the key usage from one X.509 certificate.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] usage Key usage (LIBSPDM_CRYPTO_X509_KU_*)
*
* @retval true The certificate key usage retrieved successfully.
* @retval false Invalid certificate, or usage is NULL
* @retval false This interface is not supported.
**/
extern bool libspdm_x509_get_key_usage(const uint8_t *cert, size_t cert_size, size_t *usage);
/**
* Retrieve the Extended key usage from one X.509 certificate.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] usage Key usage bytes.
* @param[in, out] usage_size Key usage buffer sizs in bytes.
*
* @retval true
* @retval false
**/
extern bool libspdm_x509_get_extended_key_usage(const uint8_t *cert,
size_t cert_size, uint8_t *usage,
size_t *usage_size);
/**
* Retrieve the basic constraints from one X.509 certificate.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] basic_constraints Basic constraints bytes.
* @param[in, out] basic_constraints_size Basic constraints buffer sizs in bytes.
*
* @retval true
* @retval false
**/
extern bool libspdm_x509_get_extended_basic_constraints(const uint8_t *cert,
size_t cert_size,
uint8_t *basic_constraints,
size_t *basic_constraints_size);
/**
* Verify one X509 certificate was issued by the trusted CA.
*
* If cert is NULL, then return false.
* If ca_cert is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate to be verified.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[in] ca_cert Pointer to the DER-encoded trusted CA certificate.
* @param[in] ca_cert_size Size of the CA Certificate in bytes.
*
* @retval true The certificate was issued by the trusted CA.
* @retval false Invalid certificate or the certificate was not issued by the given
* trusted CA.
* @retval false This interface is not supported.
*
**/
extern bool libspdm_x509_verify_cert(const uint8_t *cert, size_t cert_size,
const uint8_t *ca_cert, size_t ca_cert_size);
/**
* Verify one X509 certificate was issued by the trusted CA.
*
* @param[in] cert_chain One or more ASN.1 DER-encoded X.509 certificates
* where the first certificate is signed by the Root
* Certificate or is the Root Cerificate itself. and
* subsequent cerificate is signed by the preceding
* cerificate.
* @param[in] cert_chain_length Total length of the certificate chain, in bytes.
*
* @param[in] root_cert Trusted Root Certificate buffer.
*
* @param[in] root_cert_length Trusted Root Certificate buffer length.
*
* @retval true All cerificates were issued by the first certificate in X509Certchain.
* @retval false Invalid certificate or the certificate was not issued by the given
* trusted CA.
**/
extern bool libspdm_x509_verify_cert_chain(const uint8_t *root_cert, size_t root_cert_length,
const uint8_t *cert_chain,
size_t cert_chain_length);
/**
* Get one X509 certificate from cert_chain.
*
* @param[in] cert_chain One or more ASN.1 DER-encoded X.509 certificates
* where the first certificate is signed by the Root
* Certificate or is the Root Cerificate itself. and
* subsequent cerificate is signed by the preceding
* cerificate.
* @param[in] cert_chain_length Total length of the certificate chain, in bytes.
*
* @param[in] cert_index Index of certificate. If index is -1 indecate the
* last certificate in cert_chain.
*
* @param[out] cert The certificate at the index of cert_chain.
* @param[out] cert_length The length certificate at the index of cert_chain.
*
* @retval true Success.
* @retval false Failed to get certificate from certificate chain.
**/
extern bool libspdm_x509_get_cert_from_cert_chain(const uint8_t *cert_chain,
size_t cert_chain_length,
const int32_t cert_index, const uint8_t **cert,
size_t *cert_length);
#if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
/**
* Retrieve the RSA public key from one DER-encoded X509 certificate.
*
* If cert is NULL, then return false.
* If rsa_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] rsa_context Pointer to new-generated RSA context which contain the retrieved
* RSA public key component. Use libspdm_rsa_free() function to free the
* resource.
*
* @retval true RSA public key was retrieved successfully.
* @retval false Fail to retrieve RSA public key from X509 certificate.
* @retval false This interface is not supported.
**/
extern bool libspdm_rsa_get_public_key_from_x509(const uint8_t *cert, size_t cert_size,
void **rsa_context);
#endif /* (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT) */
#if LIBSPDM_ECDSA_SUPPORT
/**
* Retrieve the EC public key from one DER-encoded X509 certificate.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] ec_context Pointer to new-generated EC DSA context which contain the retrieved
* EC public key component. Use libspdm_ec_free() function to free the
* resource.
*
* If cert is NULL, then return false.
* If ec_context is NULL, then return false.
*
* @retval true EC public key was retrieved successfully.
* @retval false Fail to retrieve EC public key from X509 certificate.
*
**/
extern bool libspdm_ec_get_public_key_from_x509(const uint8_t *cert, size_t cert_size,
void **ec_context);
#endif /* LIBSPDM_ECDSA_SUPPORT */
#if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
/**
* Retrieve the Ed public key from one DER-encoded X509 certificate.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] ecd_context Pointer to new-generated Ed DSA context which contain the retrieved
* Ed public key component. Use libspdm_ecd_free() function to free the
* resource.
*
* If cert is NULL, then return false.
* If ecd_context is NULL, then return false.
*
* @retval true Ed public key was retrieved successfully.
* @retval false Fail to retrieve Ed public key from X509 certificate.
*
**/
extern bool libspdm_ecd_get_public_key_from_x509(const uint8_t *cert, size_t cert_size,
void **ecd_context);
#endif /* (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT) */
#if LIBSPDM_SM2_DSA_SUPPORT
/**
* Retrieve the sm2 public key from one DER-encoded X509 certificate.
*
* @param[in] cert Pointer to the DER-encoded X509 certificate.
* @param[in] cert_size Size of the X509 certificate in bytes.
* @param[out] sm2_context Pointer to new-generated sm2 context which contain the retrieved
* sm2 public key component. Use sm2_free() function to free the
* resource.
*
* If cert is NULL, then return false.
* If sm2_context is NULL, then return false.
*
* @retval true sm2 public key was retrieved successfully.
* @retval false Fail to retrieve sm2 public key from X509 certificate.
*
**/
extern bool libspdm_sm2_get_public_key_from_x509(const uint8_t *cert, size_t cert_size,
void **sm2_context);
#endif /* LIBSPDM_SM2_DSA_SUPPORT */
#if LIBSPDM_ENABLE_CAPABILITY_GET_CSR_CAP
/**
* Generate a CSR.
*
* @param[in] hash_nid hash algo for sign
* @param[in] asym_nid asym algo for sign
*
* @param[in] requester_info requester info to gen CSR
* @param[in] requester_info_length The len of requester info
*
* @param[in] context Pointer to asymmetric context
* @param[in] subject_name Subject name: should be break with ',' in the middle
* example: "C=AA,CN=BB"
*
* Subject names should contain a comma-separated list of OID types and values:
* The valid OID type name is in:
* {"CN", "commonName", "C", "countryName", "O", "organizationName","L",
* "OU", "organizationalUnitName", "ST", "stateOrProvinceName", "emailAddress",
* "serialNumber", "postalAddress", "postalCode", "dnQualifier", "title",
* "SN","givenName","GN", "initials", "pseudonym", "generationQualifier", "domainComponent", "DC"}.
* Note: The object of C and countryName should be CSR Supported Country Codes
*
* @param[in] csr_len For input, csr_len is the size of store CSR buffer.
* For output, csr_len is CSR len for DER format
* @param[in] csr_pointer For input, csr_pointer is buffer address to store CSR.
* For output, csr_pointer is address for stored CSR.
* The csr_pointer address will be changed.
*
* @retval true Success.
* @retval false Failed to gen CSR.
**/
extern bool libspdm_gen_x509_csr(size_t hash_nid, size_t asym_nid,
uint8_t *requester_info, size_t requester_info_length,
void *context, char *subject_name,
size_t *csr_len, uint8_t **csr_pointer);
#endif /* LIBSPDM_ENABLE_CAPABILITY_GET_CSR_CAP */
#endif /* CRYPTLIB_CERT_H */

View File

@@ -0,0 +1,98 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_DH_H
#define CRYPTLIB_DH_H
/*=====================================================================================
* Diffie-Hellman Key Exchange Primitives
*=====================================================================================
*/
#if LIBSPDM_FFDHE_SUPPORT
/**
* Allocates and initializes one Diffie-Hellman context for subsequent use with the NID.
*
* @param nid cipher NID
*
* @return Pointer to the Diffie-Hellman context that has been initialized.
* If the allocations fails, libspdm_dh_new_by_nid() returns NULL.
* If the interface is not supported, libspdm_dh_new_by_nid() returns NULL.
**/
extern void *libspdm_dh_new_by_nid(size_t nid);
/**
* Release the specified DH context.
*
* @param[in] dh_context Pointer to the DH context to be released.
**/
void libspdm_dh_free(void *dh_context);
/**
* Generates DH public key.
*
* This function generates random secret exponent, and computes the public key, which is
* returned via parameter public_key and public_key_size. DH context is updated accordingly.
* If the public_key buffer is too small to hold the public key, false is returned and
* public_key_size is set to the required buffer size to obtain the public key.
*
* If dh_context is NULL, then return false.
* If public_key_size is NULL, then return false.
* If public_key_size is large enough but public_key is NULL, then return false.
* If this interface is not supported, then return false.
*
* For FFDHE2048, the public_size is 256.
* For FFDHE3072, the public_size is 384.
* For FFDHE4096, the public_size is 512.
*
* @param[in, out] dh_context Pointer to the DH context.
* @param[out] public_key Pointer to the buffer to receive generated public key.
* @param[in, out] public_key_size On input, the size of public_key buffer in bytes.
* On output, the size of data returned in public_key buffer in
* bytes.
*
* @retval true DH public key generation succeeded.
* @retval false DH public key generation failed.
* @retval false public_key_size is not large enough.
* @retval false This interface is not supported.
**/
extern bool libspdm_dh_generate_key(void *dh_context, uint8_t *public_key, size_t *public_key_size);
/**
* Computes exchanged common key.
*
* Given peer's public key, this function computes the exchanged common key, based on its own
* context including value of prime modulus and random secret exponent.
*
* If dh_context is NULL, then return false.
* If peer_public_key is NULL, then return false.
* If key_size is NULL, then return false.
* If key is NULL, then return false.
* If key_size is not large enough, then return false.
* If this interface is not supported, then return false.
*
* For FFDHE2048, the peer_public_size and key_size is 256.
* For FFDHE3072, the peer_public_size and key_size is 384.
* For FFDHE4096, the peer_public_size and key_size is 512.
*
* @param[in, out] dh_context Pointer to the DH context.
* @param[in] peer_public_key Pointer to the peer's public key.
* @param[in] peer_public_key_size size of peer's public key in bytes.
* @param[out] key Pointer to the buffer to receive generated key.
* @param[in, out] key_size On input, the size of key buffer in bytes.
* On output, the size of data returned in key buffer in
* bytes.
*
* @retval true DH exchanged key generation succeeded.
* @retval false DH exchanged key generation failed.
* @retval false key_size is not large enough.
* @retval false This interface is not supported.
**/
extern bool libspdm_dh_compute_key(void *dh_context, const uint8_t *peer_public_key,
size_t peer_public_key_size, uint8_t *key,
size_t *key_size);
#endif /* LIBSPDM_FFDHE_SUPPORT */
#endif /* CRYPTLIB_DH_H */

View File

@@ -0,0 +1,162 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_EC_H
#define CRYPTLIB_EC_H
/*=====================================================================================
* Elliptic Curve Primitives
*=====================================================================================*/
#if (LIBSPDM_ECDHE_SUPPORT) || (LIBSPDM_ECDSA_SUPPORT)
/**
* Allocates and Initializes one Elliptic Curve context for subsequent use with the NID.
*
* @param nid cipher NID
*
* @return Pointer to the Elliptic Curve context that has been initialized.
* If the allocations fails, libspdm_ec_new_by_nid() returns NULL.
**/
extern void *libspdm_ec_new_by_nid(size_t nid);
/**
* Release the specified EC context.
*
* @param[in] ec_context Pointer to the EC context to be released.
**/
extern void libspdm_ec_free(void *ec_context);
#endif /* (LIBSPDM_ECDHE_SUPPORT) || (LIBSPDM_ECDSA_SUPPORT) */
#if LIBSPDM_ECDHE_SUPPORT
/**
* Generates EC key and returns EC public key (X, Y).
*
* This function generates random secret, and computes the public key (X, Y), which is
* returned via parameter public, public_size.
* X is the first half of public with size being public_size / 2,
* Y is the second half of public with size being public_size / 2.
* EC context is updated accordingly.
* If the public buffer is too small to hold the public X, Y, false is returned and
* public_size is set to the required buffer size to obtain the public X, Y.
*
* For P-256, the public_size is 64. first 32-byte is X, second 32-byte is Y.
* For P-384, the public_size is 96. first 48-byte is X, second 48-byte is Y.
* For P-521, the public_size is 132. first 66-byte is X, second 66-byte is Y.
*
* If ec_context is NULL, then return false.
* If public_size is NULL, then return false.
* If public_size is large enough but public is NULL, then return false.
*
* @param[in, out] ec_context Pointer to the EC context.
* @param[out] public Pointer to the buffer to receive generated public X,Y.
* @param[in, out] public_size On input, the size of public buffer in bytes.
* On output, the size of data returned in public buffer in bytes.
*
* @retval true EC public X,Y generation succeeded.
* @retval false EC public X,Y generation failed.
* @retval false public_size is not large enough.
**/
extern bool libspdm_ec_generate_key(void *ec_context, uint8_t *public_key, size_t *public_key_size);
/**
* Computes exchanged common key.
*
* Given peer's public key (X, Y), this function computes the exchanged common key,
* based on its own context including value of curve parameter and random secret.
* X is the first half of peer_public with size being peer_public_size / 2,
* Y is the second half of peer_public with size being peer_public_size / 2.
*
* If ec_context is NULL, then return false.
* If peer_public is NULL, then return false.
* If peer_public_size is 0, then return false.
* If key is NULL, then return false.
* If key_size is not large enough, then return false.
*
* For P-256, the peer_public_size is 64. first 32-byte is X, second 32-byte is Y.
* The key_size is 32.
* For P-384, the peer_public_size is 96. first 48-byte is X, second 48-byte is Y.
* The key_size is 48.
* For P-521, the peer_public_size is 132. first 66-byte is X, second 66-byte is Y.
* The key_size is 66.
*
* @param[in, out] ec_context Pointer to the EC context.
* @param[in] peer_public Pointer to the peer's public X,Y.
* @param[in] peer_public_size Size of peer's public X,Y in bytes.
* @param[out] key Pointer to the buffer to receive generated key.
* @param[in, out] key_size On input, the size of key buffer in bytes.
* On output, the size of data returned in key buffer in bytes.
*
* @retval true EC exchanged key generation succeeded.
* @retval false EC exchanged key generation failed.
* @retval false key_size is not large enough.
**/
extern bool libspdm_ec_compute_key(void *ec_context, const uint8_t *peer_public,
size_t peer_public_size, uint8_t *key,
size_t *key_size);
#endif /* LIBSPDM_ECDHE_SUPPORT */
#if LIBSPDM_ECDSA_SUPPORT
/**
* Carries out the EC-DSA signature.
*
* This function carries out the EC-DSA signature.
* If the signature buffer is too small to hold the contents of signature, false
* is returned and sig_size is set to the required buffer size to obtain the signature.
*
* If ec_context is NULL, then return false.
* If message_hash is NULL, then return false.
* If hash_size need match the hash_nid. hash_nid could be SHA256, SHA384, SHA512, SHA3_256,
* SHA3_384, SHA3_512.
* If sig_size is large enough but signature is NULL, then return false.
*
* For P-256, the sig_size is 64. first 32-byte is R, second 32-byte is S.
* For P-384, the sig_size is 96. first 48-byte is R, second 48-byte is S.
* For P-521, the sig_size is 132. first 66-byte is R, second 66-byte is S.
*
* @param[in] ec_context Pointer to EC context for signature generation.
* @param[in] hash_nid hash NID
* @param[in] message_hash Pointer to octet message hash to be signed.
* @param[in] hash_size Size of the message hash in bytes.
* @param[out] signature Pointer to buffer to receive EC-DSA signature.
* @param[in, out] sig_size On input, the size of signature buffer in bytes.
* On output, the size of data returned in signature buffer in bytes.
*
* @retval true signature successfully generated in EC-DSA.
* @retval false signature generation failed.
* @retval false sig_size is too small.
**/
extern bool libspdm_ecdsa_sign(void *ec_context, size_t hash_nid,
const uint8_t *message_hash, size_t hash_size,
uint8_t *signature, size_t *sig_size);
/**
* Verifies the EC-DSA signature.
*
* If ec_context is NULL, then return false.
* If message_hash is NULL, then return false.
* If signature is NULL, then return false.
* If hash_size need match the hash_nid. hash_nid could be SHA256, SHA384, SHA512, SHA3_256,
* SHA3_384, SHA3_512.
*
* For P-256, the sig_size is 64. first 32-byte is R, second 32-byte is S.
* For P-384, the sig_size is 96. first 48-byte is R, second 48-byte is S.
* For P-521, the sig_size is 132. first 66-byte is R, second 66-byte is S.
*
* @param[in] ec_context Pointer to EC context for signature verification.
* @param[in] hash_nid hash NID
* @param[in] message_hash Pointer to octet message hash to be checked.
* @param[in] hash_size Size of the message hash in bytes.
* @param[in] signature Pointer to EC-DSA signature to be verified.
* @param[in] sig_size Size of signature in bytes.
*
* @retval true Valid signature encoded in EC-DSA.
* @retval false Invalid signature or invalid EC context.
**/
extern bool libspdm_ecdsa_verify(void *ec_context, size_t hash_nid,
const uint8_t *message_hash, size_t hash_size,
const uint8_t *signature, size_t sig_size);
#endif /* LIBSPDM_ECDSA_SUPPORT */
#endif /* CRYPTLIB_EC_H */

View File

@@ -0,0 +1,100 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_ECD_H
#define CRYPTLIB_ECD_H
/*=====================================================================================
* Edwards-Curve Primitives
*=====================================================================================*/
#if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
/**
* Allocates and Initializes one Edwards-Curve context for subsequent use with the NID.
*
* @param nid cipher NID
*
* @return Pointer to the Edwards-Curve context that has been initialized.
* If the allocations fails, libspdm_ecd_new_by_nid() returns NULL.
**/
extern void *libspdm_ecd_new_by_nid(size_t nid);
/**
* Release the specified Ed context.
*
* @param[in] ecd_context Pointer to the Ed context to be released.
**/
extern void libspdm_ecd_free(void *ecd_context);
/**
* Carries out the Ed-DSA signature.
*
* This function carries out the Ed-DSA signature.
* If the signature buffer is too small to hold the contents of signature, false
* is returned and sig_size is set to the required buffer size to obtain the signature.
*
* If ecd_context is NULL, then return false.
* If message is NULL, then return false.
* hash_nid must be NULL.
* If sig_size is large enough but signature is NULL, then return false.
*
* For ed25519, context must be NULL and context_size must be 0.
* For ed448, context must be maximum of 255 octets.
*
* For ed25519, the sig_size is 64. first 32-byte is R, second 32-byte is S.
* For ed448, the sig_size is 114. first 57-byte is R, second 57-byte is S.
*
* @param[in] ecd_context Pointer to Ed context for signature generation.
* @param[in] hash_nid hash NID
* @param[in] context The EDDSA signing context.
* @param[in] context_size Size of EDDSA signing context.
* @param[in] message Pointer to octet message to be signed (before hash).
* @param[in] size size of the message in bytes.
* @param[out] signature Pointer to buffer to receive Ed-DSA signature.
* @param[in, out] sig_size On input, the size of signature buffer in bytes.
* On output, the size of data returned in signature buffer in bytes.
*
* @retval true signature successfully generated in Ed-DSA.
* @retval false signature generation failed.
* @retval false sig_size is too small.
**/
extern bool libspdm_eddsa_sign(const void *ecd_context, size_t hash_nid,
const uint8_t *context, size_t context_size,
const uint8_t *message, size_t size, uint8_t *signature,
size_t *sig_size);
/**
* Verifies the Ed-DSA signature.
*
* If ecd_context is NULL, then return false.
* If message is NULL, then return false.
* If signature is NULL, then return false.
* hash_nid must be NULL.
*
* For ed25519, context must be NULL and context_size must be 0.
* For ed448, context must be maximum of 255 octets.
*
* For ed25519, the sig_size is 64. first 32-byte is R, second 32-byte is S.
* For ed448, the sig_size is 114. first 57-byte is R, second 57-byte is S.
*
* @param[in] ecd_context Pointer to Ed context for signature verification.
* @param[in] hash_nid hash NID
* @param[in] context The EDDSA signing context.
* @param[in] context_size Size of EDDSA signing context.
* @param[in] message Pointer to octet message to be checked (before hash).
* @param[in] size Size of the message in bytes.
* @param[in] signature Pointer to Ed-DSA signature to be verified.
* @param[in] sig_size Size of signature in bytes.
*
* @retval true Valid signature encoded in Ed-DSA.
* @retval false Invalid signature or invalid Ed context.
**/
extern bool libspdm_eddsa_verify(const void *ecd_context, size_t hash_nid,
const uint8_t *context, size_t context_size,
const uint8_t *message, size_t size,
const uint8_t *signature, size_t sig_size);
#endif /* (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT) */
#endif /* CRYPTLIB_ECD_H */

View File

@@ -0,0 +1,772 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_HASH_H
#define CRYPTLIB_HASH_H
/* SHA-256 digest size in bytes. */
#define LIBSPDM_SHA256_DIGEST_SIZE 32
/* SHA-384 digest size in bytes. */
#define LIBSPDM_SHA384_DIGEST_SIZE 48
/* SHA-512 digest size in bytes. */
#define LIBSPDM_SHA512_DIGEST_SIZE 64
/* SHA3-256 digest size in bytes. */
#define LIBSPDM_SHA3_256_DIGEST_SIZE 32
/* SHA3-384 digest size in bytes. */
#define LIBSPDM_SHA3_384_DIGEST_SIZE 48
/* SHA3-512 digest size in bytes. */
#define LIBSPDM_SHA3_512_DIGEST_SIZE 64
/* SM3_256 digest size in bytes. */
#define LIBSPDM_SM3_256_DIGEST_SIZE 32
/*=====================================================================================
* One-way cryptographic hash SHA2 primitives.
*=====================================================================================
*/
#if LIBSPDM_SHA256_SUPPORT
/**
* Allocates and initializes one HASH_CTX context for subsequent SHA-256 use.
*
* @return Pointer to the HASH_CTX context that has been initialized.
* If the allocations fails, sha256_new() returns NULL. *
**/
extern void *libspdm_sha256_new(void);
/**
* Release the specified HASH_CTX context.
*
* @param[in] sha256_context Pointer to the HASH_CTX context to be released.
**/
extern void libspdm_sha256_free(void *sha256_context);
/**
* Initializes user-supplied memory pointed to by sha256_context as SHA-256 hash context for
* subsequent use.
*
* If sha256_context is NULL, then return false.
*
* @param[out] sha256_context Pointer to SHA-256 context being initialized.
*
* @retval true SHA-256 context initialization succeeded.
* @retval false SHA-256 context initialization failed.
**/
extern bool libspdm_sha256_init(void *sha256_context);
/**
* Makes a copy of an existing SHA-256 context.
*
* If sha256_context is NULL, then return false.
* If new_sha256_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] sha256_context Pointer to SHA-256 context being copied.
* @param[out] new_sha256_context Pointer to new SHA-256 context.
*
* @retval true SHA-256 context copy succeeded.
* @retval false SHA-256 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha256_duplicate(const void *sha256_context, void *new_sha256_context);
/**
* Digests the input data and updates SHA-256 context.
*
* This function performs SHA-256 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* SHA-256 context should be already correctly initialized by libspdm_sha256_init(), and must not
* have been finalized by libspdm_sha256_final(). Behavior with invalid context is undefined.
*
* If sha256_context is NULL, then return false.
*
* @param[in, out] sha256_context Pointer to the SHA-256 context.
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true SHA-256 data digest succeeded.
* @retval false SHA-256 data digest failed.
**/
extern bool libspdm_sha256_update(void *sha256_context, const void *data, size_t data_size);
/**
* Completes computation of the SHA-256 digest value.
*
* This function completes SHA-256 hash computation and populates the digest value into
* the specified memory. After this function has been called, the SHA-256 context cannot
* be used again. SHA-256 context should be already correctly initialized by libspdm_sha256_init(),
* and must not have been finalized by libspdm_sha256_final(). Behavior with invalid SHA-256 context
* is undefined.
*
* If sha256_context is NULL, then return false.
* If hash_value is NULL, then return false.
*
* @param[in, out] sha256_context Pointer to the SHA-256 context.
* @param[out] hash_value Pointer to a buffer that receives the SHA-256 digest
* value (32 bytes).
*
* @retval true SHA-256 digest computation succeeded.
* @retval false SHA-256 digest computation failed.
**/
extern bool libspdm_sha256_final(void *sha256_context, uint8_t *hash_value);
/**
* Computes the SHA-256 message digest of an input data buffer.
*
* This function performs the SHA-256 message digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
* @param[out] hash_value Pointer to a buffer that receives the SHA-256 digest value (32 bytes).
*
* @retval true SHA-256 digest computation succeeded.
* @retval false SHA-256 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha256_hash_all(const void *data, size_t data_size, uint8_t *hash_value);
#endif /* LIBSPDM_SHA256_SUPPORT */
#if LIBSPDM_SHA384_SUPPORT
/**
* Allocates and initializes one HASH_CTX context for subsequent SHA-384 use.
*
* @return Pointer to the HASH_CTX context that has been initialized.
* If the allocations fails, libspdm_sha384_new() returns NULL.
**/
extern void *libspdm_sha384_new(void);
/**
* Release the specified HASH_CTX context.
*
* @param[in] sha384_context Pointer to the HASH_CTX context to be released.
**/
extern void libspdm_sha384_free(void *sha384_context);
/**
* Initializes user-supplied memory pointed to by sha384_context as SHA-384 hash context for
* subsequent use.
*
* If sha384_context is NULL, then return false.
*
* @param[out] sha384_context Pointer to SHA-384 context being initialized.
*
* @retval true SHA-384 context initialization succeeded.
* @retval false SHA-384 context initialization failed.
**/
extern bool libspdm_sha384_init(void *sha384_context);
/**
* Makes a copy of an existing SHA-384 context.
*
* If sha384_context is NULL, then return false.
* If new_sha384_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] sha384_context Pointer to SHA-384 context being copied.
* @param[out] new_sha384_context Pointer to new SHA-384 context.
*
* @retval true SHA-384 context copy succeeded.
* @retval false SHA-384 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha384_duplicate(const void *sha384_context, void *new_sha384_context);
/**
* Digests the input data and updates SHA-384 context.
*
* This function performs SHA-384 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* SHA-384 context should be already correctly initialized by libspdm_sha384_init(), and must not
* have been finalized by libspdm_sha384_final(). Behavior with invalid context is undefined.
*
* If sha384_context is NULL, then return false.
*
* @param[in, out] sha384_context Pointer to the SHA-384 context.
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true SHA-384 data digest succeeded.
* @retval false SHA-384 data digest failed.
**/
extern bool libspdm_sha384_update(void *sha384_context, const void *data, size_t data_size);
/**
* Completes computation of the SHA-384 digest value.
*
* This function completes SHA-384 hash computation and populates the digest value into
* the specified memory. After this function has been called, the SHA-384 context cannot
* be used again. SHA-384 context should be already correctly initialized by libspdm_sha384_init(),
* and must not have been finalized by libspdm_sha384_final(). Behavior with invalid SHA-384 context
* is undefined.
*
* If sha384_context is NULL, then return false.
* If hash_value is NULL, then return false.
*
* @param[in, out] sha384_context Pointer to the SHA-384 context.
* @param[out] hash_value Pointer to a buffer that receives the SHA-384 digest
* value (48 bytes).
*
* @retval true SHA-384 digest computation succeeded.
* @retval false SHA-384 digest computation failed.
**/
extern bool libspdm_sha384_final(void *sha384_context, uint8_t *hash_value);
/**
* Computes the SHA-384 message digest of an input data buffer.
*
* This function performs the SHA-384 message digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
* @param[out] hash_value Pointer to a buffer that receives the SHA-384 digest value (48 bytes).
*
* @retval true SHA-384 digest computation succeeded.
* @retval false SHA-384 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha384_hash_all(const void *data, size_t data_size, uint8_t *hash_value);
#endif /* LIBSPDM_SHA384_SUPPORT */
#if LIBSPDM_SHA512_SUPPORT
/**
* Allocates and initializes one HASH_CTX context for subsequent SHA-512 use.
*
* @return Pointer to the HASH_CTX context that has been initialized.
* If the allocations fails, libspdm_sha512_new() returns NULL.
**/
extern void *libspdm_sha512_new(void);
/**
* Release the specified HASH_CTX context.
*
* @param[in] sha512_context Pointer to the HASH_CTX context to be released.
**/
extern void libspdm_sha512_free(void *sha512_context);
/**
* Initializes user-supplied memory pointed by sha512_context as SHA-512 hash context for
* subsequent use.
*
* If sha512_context is NULL, then return false.
*
* @param[out] sha512_context Pointer to SHA-512 context being initialized.
*
* @retval true SHA-512 context initialization succeeded.
* @retval false SHA-512 context initialization failed.
**/
extern bool libspdm_sha512_init(void *sha512_context);
/**
* Makes a copy of an existing SHA-512 context.
*
* If sha512_context is NULL, then return false.
* If new_sha512_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] sha512_context Pointer to SHA-512 context being copied.
* @param[out] new_sha512_context Pointer to new SHA-512 context.
*
* @retval true SHA-512 context copy succeeded.
* @retval false SHA-512 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha512_duplicate(const void *sha512_context, void *new_sha512_context);
/**
* Digests the input data and updates SHA-512 context.
*
* This function performs SHA-512 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* SHA-512 context should be already correctly initialized by libspdm_sha512_init(), and must not
* have been finalized by libspdm_sha512_final(). Behavior with invalid context is undefined.
*
* If sha512_context is NULL, then return false.
*
* @param[in, out] sha512_context Pointer to the SHA-512 context.
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true SHA-512 data digest succeeded.
* @retval false SHA-512 data digest failed.
**/
extern bool libspdm_sha512_update(void *sha512_context, const void *data, size_t data_size);
/**
* Completes computation of the SHA-512 digest value.
*
* This function completes SHA-512 hash computation and populates the digest value into
* the specified memory. After this function has been called, the SHA-512 context cannot
* be used again. SHA-512 context should be already correctly initialized by libspdm_sha512_init(),
* and must not have been finalized by libspdm_sha512_final(). Behavior with invalid SHA-512 context
* is undefined.
*
* If sha512_context is NULL, then return false.
* If hash_value is NULL, then return false.
*
* @param[in, out] sha512_context Pointer to the SHA-512 context.
* @param[out] hash_value Pointer to a buffer that receives the SHA-512 digest
* value (64 bytes).
*
* @retval true SHA-512 digest computation succeeded.
* @retval false SHA-512 digest computation failed.
**/
extern bool libspdm_sha512_final(void *sha512_context, uint8_t *hash_value);
/**
* Computes the SHA-512 message digest of an input data buffer.
*
* This function performs the SHA-512 message digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
* @param[out] hash_value Pointer to a buffer that receives the SHA-512 digest value (64 bytes).
*
* @retval true SHA-512 digest computation succeeded.
* @retval false SHA-512 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha512_hash_all(const void *data, size_t data_size, uint8_t *hash_value);
#endif /* LIBSPDM_SHA512_SUPPORT */
/*=====================================================================================
* One-way cryptographic hash SHA3 primitives.
*=====================================================================================
*/
#if LIBSPDM_SHA3_256_SUPPORT
/**
* Allocates and initializes one HASH_CTX context for subsequent SHA3-256 use.
*
* @return Pointer to the HASH_CTX context that has been initialized.
* If the allocations fails, libspdm_sha3_256_new() returns NULL.
**/
extern void *libspdm_sha3_256_new(void);
/**
* Release the specified HASH_CTX context.
*
* @param[in] sha3_256_context Pointer to the HASH_CTX context to be released.
**/
extern void libspdm_sha3_256_free(void *sha3_256_context);
/**
* Initializes user-supplied memory pointed by sha3_256_context as SHA3-256 hash context for
* subsequent use.
*
* If sha3_256_context is NULL, then return false.
*
* @param[out] sha3_256_context Pointer to SHA3-256 context being initialized.
*
* @retval true SHA3-256 context initialization succeeded.
* @retval false SHA3-256 context initialization failed.
**/
extern bool libspdm_sha3_256_init(void *sha3_256_context);
/**
* Makes a copy of an existing SHA3-256 context.
*
* If sha3_256_context is NULL, then return false.
* If new_sha3_256_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] sha3_256_context Pointer to SHA3-256 context being copied.
* @param[out] new_sha3_256_context Pointer to new SHA3-256 context.
*
* @retval true SHA3-256 context copy succeeded.
* @retval false SHA3-256 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha3_256_duplicate(const void *sha3_256_context, void *new_sha3_256_context);
/**
* Digests the input data and updates SHA3-256 context.
*
* This function performs SHA3-256 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* SHA3-256 context should be already correctly initialized by libspdm_sha3_256_init(), and must not
* have been finalized by libspdm_sha3_256_final(). Behavior with invalid context is undefined.
*
* If sha3_256_context is NULL, then return false.
*
* @param[in, out] sha3_256_context Pointer to the SHA3-256 context.
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size size of data buffer in bytes.
*
* @retval true SHA3-256 data digest succeeded.
* @retval false SHA3-256 data digest failed.
**/
extern bool libspdm_sha3_256_update(void *sha3_256_context, const void *data, size_t data_size);
/**
* Completes computation of the SHA3-256 digest value.
*
* This function completes SHA3-256 hash computation and populates the digest value into
* the specified memory. After this function has been called, the SHA3-512 context cannot
* be used again. SHA3-256 context should be already correctly initialized by
* libspdm_sha3_256_init(), and must not have been finalized by libspdm_sha3_256_final().
* Behavior with invalid SHA3-256 context is undefined.
*
* If sha3_256_context is NULL, then return false.
* If hash_value is NULL, then return false.
*
* @param[in, out] sha3_256_context Pointer to the SHA3-256 context.
* @param[out] hash_value Pointer to a buffer that receives the SHA3-256 digest
* value (32 bytes).
*
* @retval true SHA3-256 digest computation succeeded.
* @retval false SHA3-256 digest computation failed.
**/
extern bool libspdm_sha3_256_final(void *sha3_256_context, uint8_t *hash_value);
/**
* Computes the SHA3-256 message digest of an input data buffer.
*
* This function performs the SHA3-256 message digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
* @param[out] hash_value Pointer to a buffer that receives the SHA3-256 digest value (32 bytes).
*
* @retval true SHA3-256 digest computation succeeded.
* @retval false SHA3-256 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha3_256_hash_all(const void *data, size_t data_size, uint8_t *hash_value);
#endif /* LIBSPDM_SHA3_256_SUPPORT */
#if LIBSPDM_SHA3_384_SUPPORT
/**
* Allocates and initializes one HASH_CTX context for subsequent SHA3-384 use.
*
* @return Pointer to the HASH_CTX context that has been initialized.
* If the allocations fails, libspdm_sha3_384_new() returns NULL.
**/
extern void *libspdm_sha3_384_new(void);
/**
* Release the specified HASH_CTX context.
*
* @param[in] sha3_384_context Pointer to the HASH_CTX context to be released.
**/
extern void libspdm_sha3_384_free(void *sha3_384_context);
/**
* Initializes user-supplied memory pointed by sha3_384_context as SHA3-384 hash context for
* subsequent use.
*
* If sha3_384_context is NULL, then return false.
*
* @param[out] sha3_384_context Pointer to SHA3-384 context being initialized.
*
* @retval true SHA3-384 context initialization succeeded.
* @retval false SHA3-384 context initialization failed.
**/
extern bool libspdm_sha3_384_init(void *sha3_384_context);
/**
* Makes a copy of an existing SHA3-384 context.
*
* If sha3_384_context is NULL, then return false.
* If new_sha3_384_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] sha3_384_context Pointer to SHA3-384 context being copied.
* @param[out] new_sha3_384_context Pointer to new SHA3-384 context.
*
* @retval true SHA3-384 context copy succeeded.
* @retval false SHA3-384 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha3_384_duplicate(const void *sha3_384_context, void *new_sha3_384_context);
/**
* Digests the input data and updates SHA3-384 context.
*
* This function performs SHA3-384 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* SHA3-384 context should be already correctly initialized by libspdm_sha3_384_init(), and must not
* have been finalized by libspdm_sha3_384_final(). Behavior with invalid context is undefined.
*
* If sha3_384_context is NULL, then return false.
*
* @param[in, out] sha3_384_context Pointer to the SHA3-384 context.
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true SHA3-384 data digest succeeded.
* @retval false SHA3-384 data digest failed.
**/
extern bool libspdm_sha3_384_update(void *sha3_384_context, const void *data, size_t data_size);
/**
* Completes computation of the SHA3-384 digest value.
*
* This function completes SHA3-384 hash computation and populates the digest value into
* the specified memory. After this function has been called, the SHA3-384 context cannot
* be used again. SHA3-384 context should be already correctly initialized by
* libspdm_sha3_384_init(), and must not have been finalized by libspdm_sha3_384_final().
* Behavior with invalid SHA3-384 context is undefined.
*
* If sha3_384_context is NULL, then return false.
* If hash_value is NULL, then return false.
*
* @param[in, out] sha3_384_context Pointer to the SHA3-384 context.
* @param[out] hash_value Pointer to a buffer that receives the SHA3-384 digest
* value (48 bytes).
*
* @retval true SHA3-384 digest computation succeeded.
* @retval false SHA3-384 digest computation failed.
*
**/
extern bool libspdm_sha3_384_final(void *sha3_384_context, uint8_t *hash_value);
/**
* Computes the SHA3-384 message digest of an input data buffer.
*
* This function performs the SHA3-384 message digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
* @param[out] hash_value Pointer to a buffer that receives the SHA3-384 digest value (48 bytes).
*
* @retval true SHA3-384 digest computation succeeded.
* @retval false SHA3-384 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha3_384_hash_all(const void *data, size_t data_size, uint8_t *hash_value);
#endif /* LIBSPDM_SHA3_384_SUPPORT */
#if LIBSPDM_SHA3_512_SUPPORT
/**
* Allocates and initializes one HASH_CTX context for subsequent SHA3-512 use.
*
* @return Pointer to the HASH_CTX context that has been initialized.
* If the allocations fails, libspdm_sha3_512_new() returns NULL.
**/
extern void *libspdm_sha3_512_new(void);
/**
* Release the specified HASH_CTX context.
*
* @param[in] sha3_512_context Pointer to the HASH_CTX context to be released.
**/
extern void libspdm_sha3_512_free(void *sha3_512_context);
/**
* Initializes user-supplied memory pointed by sha3_512_context as SHA3-512 hash context for
* subsequent use.
*
* If sha3_512_context is NULL, then return false.
*
* @param[out] sha3_512_context Pointer to SHA3-512 context being initialized.
*
* @retval true SHA3-512 context initialization succeeded.
* @retval false SHA3-512 context initialization failed.
**/
extern bool libspdm_sha3_512_init(void *sha3_512_context);
/**
* Makes a copy of an existing SHA3-512 context.
*
* If sha3_512_context is NULL, then return false.
* If new_sha3_512_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] sha3_512_context Pointer to SHA3-512 context being copied.
* @param[out] new_sha3_512_context Pointer to new SHA3-512 context.
*
* @retval true SHA3-512 context copy succeeded.
* @retval false SHA3-512 context copy failed.
* @retval false This interface is not supported.
*
**/
extern bool libspdm_sha3_512_duplicate(const void *sha3_512_context, void *new_sha3_512_context);
/**
* Digests the input data and updates SHA3-512 context.
*
* This function performs SHA3-512 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* SHA3-512 context should be already correctly initialized by libspdm_sha3_512_init(), and must not
* have been finalized by libspdm_sha3_512_final(). Behavior with invalid context is undefined.
*
* If sha3_512_context is NULL, then return false.
*
* @param[in, out] sha3_512_context Pointer to the SHA3-512 context.
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true SHA3-512 data digest succeeded.
* @retval false SHA3-512 data digest failed.
**/
extern bool libspdm_sha3_512_update(void *sha3_512_context, const void *data, size_t data_size);
/**
* Completes computation of the SHA3-512 digest value.
*
* This function completes SHA3-512 hash computation and populates the digest value into
* the specified memory. After this function has been called, the SHA3-512 context cannot
* be used again. SHA3-512 context should be already correctly initialized by
* libspdm_sha3_512_init(), and must not have been finalized by libspdm_sha3_512_final().
* Behavior with invalid SHA3-512 context is undefined.
*
* If sha3_512_context is NULL, then return false.
* If hash_value is NULL, then return false.
*
* @param[in, out] sha3_512_context Pointer to the SHA3-512 context.
* @param[out] hash_value Pointer to a buffer that receives the SHA3-512 digest
* value (64 bytes).
*
* @retval true SHA3-512 digest computation succeeded.
* @retval false SHA3-512 digest computation failed.
**/
extern bool libspdm_sha3_512_final(void *sha3_512_context, uint8_t *hash_value);
/**
* Computes the SHA3-512 message digest of an input data buffer.
*
* This function performs the SHA3-512 message digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
* @param[out] hash_value Pointer to a buffer that receives the SHA3-512 digest value (64 bytes).
*
* @retval true SHA3-512 digest computation succeeded.
* @retval false SHA3-512 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sha3_512_hash_all(const void *data, size_t data_size, uint8_t *hash_value);
#endif /* LIBSPDM_SHA3_512_SUPPORT */
/*=====================================================================================
* One-Way Cryptographic hash SM3 Primitives
*=====================================================================================
*/
#if LIBSPDM_SM3_256_SUPPORT
/**
* Allocates and initializes one HASH_CTX context for subsequent SM3-256 use.
*
* @return Pointer to the HASH_CTX context that has been initialized.
* If the allocations fails, libspdm_sm3_256_new() returns NULL.
**/
extern void *libspdm_sm3_256_new(void);
/**
* Release the specified HASH_CTX context.
*
* @param[in] sm3_context Pointer to the HASH_CTX context to be released.
**/
extern void libspdm_sm3_256_free(void *sm3_context);
/**
* Initializes user-supplied memory pointed by sm3_context as SM3 hash context for
* subsequent use.
*
* If sm3_context is NULL, then return false.
*
* @param[out] sm3_context Pointer to SM3 context being initialized.
*
* @retval true SM3 context initialization succeeded.
* @retval false SM3 context initialization failed.
**/
extern bool libspdm_sm3_256_init(void *sm3_context);
/**
* Makes a copy of an existing SM3 context.
*
* If sm3_context is NULL, then return false.
* If new_sm3_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] sm3_context Pointer to SM3 context being copied.
* @param[out] new_sm3_context Pointer to new SM3 context.
*
* @retval true SM3 context copy succeeded.
* @retval false SM3 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sm3_256_duplicate(const void *sm3_context, void *new_sm3_context);
/**
* Digests the input data and updates SM3 context.
*
* This function performs SM3 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* SM3 context should be already correctly initialized by sm3_init(), and should not be finalized
* by sm3_final(). Behavior with invalid context is undefined.
*
* If sm3_context is NULL, then return false.
*
* @param[in, out] sm3_context Pointer to the SM3 context.
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true SM3 data digest succeeded.
* @retval false SM3 data digest failed.
**/
extern bool libspdm_sm3_256_update(void *sm3_context, const void *data, size_t data_size);
/**
* Completes computation of the SM3 digest value.
*
* This function completes SM3 hash computation and retrieves the digest value into
* the specified memory. After this function has been called, the SM3 context cannot
* be used again. SM3 context should be already correctly initialized by sm3_init(), and should not
* be finalized by sm3_final(). Behavior with invalid SM3 context is undefined.
*
* If sm3_context is NULL, then return false.
* If hash_value is NULL, then return false.
*
* @param[in, out] sm3_context Pointer to the SM3 context.
* @param[out] hash_value Pointer to a buffer that receives the SM3 digest value (32 bytes).
*
* @retval true SM3 digest computation succeeded.
* @retval false SM3 digest computation failed.
**/
extern bool libspdm_sm3_256_final(void *sm3_context, uint8_t *hash_value);
/**
* Computes the SM3 message digest of an input data buffer.
*
* This function performs the SM3 message digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be hashed.
* @param[in] data_size Size of data buffer in bytes.
* @param[out] hash_value Pointer to a buffer that receives the SM3 digest value (32 bytes).
*
* @retval true SM3 digest computation succeeded.
* @retval false SM3 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_sm3_256_hash_all(const void *data, size_t data_size, uint8_t *hash_value);
#endif /* LIBSPDM_SM3_256_SUPPORT */
#endif /* CRYPTLIB_HASH_H */

View File

@@ -0,0 +1,266 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_HKDF_H
#define CRYPTLIB_HKDF_H
/*=====================================================================================
* Key Derivation Function Primitives
*=====================================================================================*/
#if LIBSPDM_SHA256_SUPPORT
/**
* Derive SHA-256 HMAC-based Extract key Derivation Function (HKDF).
*
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[in] salt Pointer to the salt value.
* @param[in] salt_size Salt size in bytes.
* @param[out] prk_out Pointer to buffer to receive prk value.
* @param[in] prk_out_size Size of prk bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha256_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size);
/**
* Derive SHA256 HMAC-based Expand key Derivation Function (HKDF).
*
* @param[in] prk Pointer to the user-supplied key.
* @param[in] prk_size Key size in bytes.
* @param[in] info Pointer to the application specific info.
* @param[in] info_size Info size in bytes.
* @param[out] out Pointer to buffer to receive hkdf value.
* @param[in] out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha256_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size);
#endif /* LIBSPDM_SHA256_SUPPORT */
#if LIBSPDM_SHA384_SUPPORT
/**
* Derive SHA384 HMAC-based Extract key Derivation Function (HKDF).
*
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[in] salt Pointer to the salt value.
* @param[in] salt_size Salt size in bytes.
* @param[out] prk_out Pointer to buffer to receive hkdf value.
* @param[in] prk_out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha384_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size);
/**
* Derive SHA384 HMAC-based Expand key Derivation Function (HKDF).
*
* @param[in] prk Pointer to the user-supplied key.
* @param[in] prk_size Key size in bytes.
* @param[in] info Pointer to the application specific info.
* @param[in] info_size Info size in bytes.
* @param[out] out Pointer to buffer to receive hkdf value.
* @param[in] out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha384_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size);
#endif /* LIBSPDM_SHA384_SUPPORT */
#if LIBSPDM_SHA512_SUPPORT
/**
* Derive SHA512 HMAC-based Extract key Derivation Function (HKDF).
*
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[in] salt Pointer to the salt value.
* @param[in] salt_size Salt size in bytes.
* @param[out] prk_out Pointer to buffer to receive hkdf value.
* @param[in] prk_out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha512_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size);
/**
* Derive SHA512 HMAC-based Expand key Derivation Function (HKDF).
*
* @param[in] prk Pointer to the user-supplied key.
* @param[in] prk_size Key size in bytes.
* @param[in] info Pointer to the application specific info.
* @param[in] info_size Info size in bytes.
* @param[out] out Pointer to buffer to receive hkdf value.
* @param[in] out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha512_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size);
#endif /* LIBSPDM_SHA512_SUPPORT */
#if LIBSPDM_SHA3_256_SUPPORT
/**
* Derive SHA3_256 HMAC-based Extract key Derivation Function (HKDF).
*
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[in] salt Pointer to the salt value.
* @param[in] salt_size Salt size in bytes.
* @param[out] prk_out Pointer to buffer to receive hkdf value.
* @param[in] prk_out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha3_256_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size);
/**
* Derive SHA3_256 HMAC-based Expand key Derivation Function (HKDF).
*
* @param[in] prk Pointer to the user-supplied key.
* @param[in] prk_size Key size in bytes.
* @param[in] info Pointer to the application specific info.
* @param[in] info_size Info size in bytes.
* @param[out] out Pointer to buffer to receive hkdf value.
* @param[in] out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha3_256_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size);
#endif /* LIBSPDM_SHA3_256_SUPPORT */
#if LIBSPDM_SHA3_384_SUPPORT
/**
* Derive SHA3_384 HMAC-based Extract key Derivation Function (HKDF).
*
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[in] salt Pointer to the salt value.
* @param[in] salt_size Salt size in bytes.
* @param[out] prk_out Pointer to buffer to receive hkdf value.
* @param[in] prk_out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha3_384_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size);
/**
* Derive SHA3_384 HMAC-based Expand key Derivation Function (HKDF).
*
* @param[in] prk Pointer to the user-supplied key.
* @param[in] prk_size Key size in bytes.
* @param[in] info Pointer to the application specific info.
* @param[in] info_size Info size in bytes.
* @param[out] out Pointer to buffer to receive hkdf value.
* @param[in] out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha3_384_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size);
#endif /* LIBSPDM_SHA3_384_SUPPORT */
#if LIBSPDM_SHA3_512_SUPPORT
/**
* Derive SHA3_512 HMAC-based Extract key Derivation Function (HKDF).
*
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[in] salt Pointer to the salt value.
* @param[in] salt_size Salt size in bytes.
* @param[out] prk_out Pointer to buffer to receive hkdf value.
* @param[in] prk_out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha3_512_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size);
/**
* Derive SHA3_512 HMAC-based Expand key Derivation Function (HKDF).
*
* @param[in] prk Pointer to the user-supplied key.
* @param[in] prk_size Key size in bytes.
* @param[in] info Pointer to the application specific info.
* @param[in] info_size Info size in bytes.
* @param[out] out Pointer to buffer to receive hkdf value.
* @param[in] out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sha3_512_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size);
#endif /* LIBSPDM_SHA3_512_SUPPORT */
#if LIBSPDM_SM3_256_SUPPORT
/**
* Derive SM3_256 HMAC-based Extract key Derivation Function (HKDF).
*
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[in] salt Pointer to the salt value.
* @param[in] salt_size Salt size in bytes.
* @param[out] prk_out Pointer to buffer to receive hkdf value.
* @param[in] prk_out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sm3_256_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size);
/**
* Derive SM3_256 HMAC-based Expand key Derivation Function (HKDF).
*
* @param[in] prk Pointer to the user-supplied key.
* @param[in] prk_size Key size in bytes.
* @param[in] info Pointer to the application specific info.
* @param[in] info_size Info size in bytes.
* @param[out] out Pointer to buffer to receive hkdf value.
* @param[in] out_size Size of hkdf bytes to generate.
*
* @retval true Hkdf generated successfully.
* @retval false Hkdf generation failed.
**/
extern bool libspdm_hkdf_sm3_256_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size);
#endif /* LIBSPDM_SM3_256_SUPPORT */
#endif /* CRYPTLIB_HKDF_H */

View File

@@ -0,0 +1,833 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_MAC_H
#define CRYPTLIB_MAC_H
/*=====================================================================================
* Message Authentication Code (MAC) Primitives
*=====================================================================================
*/
#if LIBSPDM_SHA256_SUPPORT
/**
* Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA256 use.
*
* @return Pointer to the HMAC_CTX context that has been initialized.
* If the allocations fails, libspdm_hmac_sha256_new() returns NULL.
**/
extern void *libspdm_hmac_sha256_new(void);
/**
* Release the specified HMAC_CTX context.
*
* @param[in] hmac_sha256_ctx Pointer to the HMAC_CTX context to be released.
**/
extern void libspdm_hmac_sha256_free(void *hmac_sha256_ctx);
/**
* Set user-supplied key for subsequent use. It must be done before any
* calling to libspdm_hmac_sha256_update().
*
* If hmac_sha256_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[out] hmac_sha256_ctx Pointer to HMAC-SHA256 context.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
*
* @retval true The key is set successfully.
* @retval false The key is set unsuccessfully.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha256_set_key(void *hmac_sha256_ctx, const uint8_t *key, size_t key_size);
/**
* Makes a copy of an existing HMAC-SHA256 context.
*
* If hmac_sha256_ctx is NULL, then return false.
* If new_hmac_sha256_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] hmac_sha256_ctx Pointer to HMAC-SHA256 context being copied.
* @param[out] new_hmac_sha256_ctx Pointer to new HMAC-SHA256 context.
*
* @retval true HMAC-SHA256 context copy succeeded.
* @retval false HMAC-SHA256 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha256_duplicate(const void *hmac_sha256_ctx, void *new_hmac_sha256_ctx);
/**
* Digests the input data and updates HMAC-SHA256 context.
*
* This function performs HMAC-SHA256 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* HMAC-SHA256 context should be initialized by libspdm_hmac_sha256_new(), and should not be
* finalized by libspdm_hmac_sha256_final(). Behavior with invalid context is undefined.
*
* If hmac_sha256_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha256_ctx Pointer to the HMAC-SHA256 context.
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true HMAC-SHA256 data digest succeeded.
* @retval false HMAC-SHA256 data digest failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha256_update(void *hmac_sha256_ctx, const void *data, size_t data_size);
/**
* Completes computation of the HMAC-SHA256 digest value.
*
* This function completes HMAC-SHA256 hash computation and retrieves the digest value into
* the specified memory. After this function has been called, the HMAC-SHA256 context cannot
* be used again. HMAC-SHA256 context should be initialized by libspdm_hmac_sha256_new(), and should
* not be finalized by libspdm_hmac_sha256_final(). Behavior with invalid HMAC-SHA256 context is
* undefined.
*
* If hmac_sha256_ctx is NULL, then return false.
* If hmac_value is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha256_ctx Pointer to the HMAC-SHA256 context.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA256 digest
* value (32 bytes).
*
* @retval true HMAC-SHA256 digest computation succeeded.
* @retval false HMAC-SHA256 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha256_final(void *hmac_sha256_ctx, uint8_t *hmac_value);
/**
* Computes the HMAC-SHA256 digest of a input data buffer.
*
* This function performs the HMAC-SHA256 digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA256 digest
* value (32 bytes).
*
* @retval true HMAC-SHA256 digest computation succeeded.
* @retval false HMAC-SHA256 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha256_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value);
#endif /* LIBSPDM_SHA256_SUPPORT */
#if LIBSPDM_SHA384_SUPPORT
/**
* Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA384 use.
*
* @return Pointer to the HMAC_CTX context that has been initialized.
* If the allocations fails, libspdm_hmac_sha384_new() returns NULL.
**/
extern void *libspdm_hmac_sha384_new(void);
/**
* Release the specified HMAC_CTX context.
*
* @param[in] hmac_sha384_ctx Pointer to the HMAC_CTX context to be released.
**/
extern void libspdm_hmac_sha384_free(void *hmac_sha384_ctx);
/**
* Set user-supplied key for subsequent use. It must be done before any
* calling to libspdm_hmac_sha384_update().
*
* If hmac_sha384_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[out] hmac_sha384_ctx Pointer to HMAC-SHA384 context.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size key size in bytes.
*
* @retval true The key is set successfully.
* @retval false The key is set unsuccessfully.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha384_set_key(void *hmac_sha384_ctx, const uint8_t *key, size_t key_size);
/**
* Makes a copy of an existing HMAC-SHA384 context.
*
* If hmac_sha384_ctx is NULL, then return false.
* If new_hmac_sha384_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] hmac_sha384_ctx Pointer to HMAC-SHA384 context being copied.
* @param[out] new_hmac_sha384_ctx Pointer to new HMAC-SHA384 context.
*
* @retval true HMAC-SHA384 context copy succeeded.
* @retval false HMAC-SHA384 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha384_duplicate(const void *hmac_sha384_ctx, void *new_hmac_sha384_ctx);
/**
* Digests the input data and updates HMAC-SHA384 context.
*
* This function performs HMAC-SHA384 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* HMAC-SHA384 context should be initialized by libspdm_hmac_sha384_new(), and should not be
* finalized by libspdm_hmac_sha384_final(). Behavior with invalid context is undefined.
*
* If hmac_sha384_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha384_ctx Pointer to the HMAC-SHA384 context.
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true HMAC-SHA384 data digest succeeded.
* @retval false HMAC-SHA384 data digest failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha384_update(void *hmac_sha384_ctx, const void *data, size_t data_size);
/**
* Completes computation of the HMAC-SHA384 digest value.
*
* This function completes HMAC-SHA384 hash computation and retrieves the digest value into
* the specified memory. After this function has been called, the HMAC-SHA384 context cannot
* be used again. HMAC-SHA384 context should be initialized by libspdm_hmac_sha384_new(), and should
* not be finalized by libspdm_hmac_sha384_final(). Behavior with invalid HMAC-SHA384 context is
* undefined.
*
* If hmac_sha384_ctx is NULL, then return false.
* If hmac_value is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha384_ctx Pointer to the HMAC-SHA384 context.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA384 digest
* value (48 bytes).
*
* @retval true HMAC-SHA384 digest computation succeeded.
* @retval false HMAC-SHA384 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha384_final(void *hmac_sha384_ctx, uint8_t *hmac_value);
/**
* Computes the HMAC-SHA384 digest of a input data buffer.
*
* This function performs the HMAC-SHA384 digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA384 digest
* value (48 bytes).
*
* @retval true HMAC-SHA384 digest computation succeeded.
* @retval false HMAC-SHA384 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha384_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value);
#endif /* LIBSPDM_SHA384_SUPPORT */
#if LIBSPDM_SHA512_SUPPORT
/**
* Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA512 use.
*
* @return Pointer to the HMAC_CTX context that has been initialized.
* If the allocations fails, libspdm_hmac_sha512_new() returns NULL.
**/
extern void *libspdm_hmac_sha512_new(void);
/**
* Release the specified HMAC_CTX context.
*
* @param[in] hmac_sha512_ctx Pointer to the HMAC_CTX context to be released.
**/
extern void libspdm_hmac_sha512_free(void *hmac_sha512_ctx);
/**
* Set user-supplied key for subsequent use. It must be done before any
* calling to libspdm_hmac_sha512_update().
*
* If hmac_sha512_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[out] hmac_sha512_ctx Pointer to HMAC-SHA512 context.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
*
* @retval true The key is set successfully.
* @retval false The key is set unsuccessfully.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha512_set_key(void *hmac_sha512_ctx, const uint8_t *key, size_t key_size);
/**
* Makes a copy of an existing HMAC-SHA512 context.
*
* If hmac_sha512_ctx is NULL, then return false.
* If new_hmac_sha512_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] hmac_sha512_ctx Pointer to HMAC-SHA512 context being copied.
* @param[out] new_hmac_sha512_ctx Pointer to new HMAC-SHA512 context.
*
* @retval true HMAC-SHA512 context copy succeeded.
* @retval false HMAC-SHA512 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha512_duplicate(const void *hmac_sha512_ctx, void *new_hmac_sha512_ctx);
/**
* Digests the input data and updates HMAC-SHA512 context.
*
* This function performs HMAC-SHA512 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* HMAC-SHA512 context should be initialized by libspdm_hmac_sha512_new(), and should not be
* finalized by libspdm_hmac_sha512_final(). Behavior with invalid context is undefined.
*
* If hmac_sha512_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha512_ctx Pointer to the HMAC-SHA512 context.
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true HMAC-SHA512 data digest succeeded.
* @retval false HMAC-SHA512 data digest failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha512_update(void *hmac_sha512_ctx, const void *data, size_t data_size);
/**
* Completes computation of the HMAC-SHA512 digest value.
*
* This function completes HMAC-SHA512 hash computation and retrieves the digest value into
* the specified memory. After this function has been called, the HMAC-SHA512 context cannot
* be used again. HMAC-SHA512 context should be initialized by libspdm_hmac_sha512_new(), and should
* not be finalized by libspdm_hmac_sha512_final(). Behavior with invalid HMAC-SHA512 context is
* undefined.
*
* If hmac_sha512_ctx is NULL, then return false.
* If hmac_value is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha512_ctx Pointer to the HMAC-SHA512 context.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA512 digest
* value (64 bytes).
*
* @retval true HMAC-SHA512 digest computation succeeded.
* @retval false HMAC-SHA512 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha512_final(void *hmac_sha512_ctx, uint8_t *hmac_value);
/**
* Computes the HMAC-SHA512 digest of a input data buffer.
*
* This function performs the HMAC-SHA512 digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA512 digest
* value (64 bytes).
*
* @retval true HMAC-SHA512 digest computation succeeded.
* @retval false HMAC-SHA512 digest computation failed.
* @retval false This interface is not supported.
*
**/
extern bool libspdm_hmac_sha512_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value);
#endif /* LIBSPDM_SHA512_SUPPORT */
#if LIBSPDM_SHA3_256_SUPPORT
/**
* Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA3-256 use.
*
* @return Pointer to the HMAC_CTX context that has been initialized.
* If the allocations fails, libspdm_hmac_sha3_256_new() returns NULL.
**/
extern void *libspdm_hmac_sha3_256_new(void);
/**
* Release the specified HMAC_CTX context.
*
* @param[in] hmac_sha3_256_ctx Pointer to the HMAC_CTX context to be released.
**/
extern void libspdm_hmac_sha3_256_free(void *hmac_sha3_256_ctx);
/**
* Set user-supplied key for subsequent use. It must be done before any
* calling to libspdm_hmac_sha3_256_update().
*
* If hmac_sha3_256_ctx is NULL, then return false.
*
* @param[out] hmac_sha3_256_ctx Pointer to HMAC-SHA3-256 context.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
*
* @retval true The key is set successfully.
* @retval false The key is set unsuccessfully.
**/
extern bool libspdm_hmac_sha3_256_set_key(void *hmac_sha3_256_ctx,
const uint8_t *key,
size_t key_size);
/**
* Makes a copy of an existing HMAC-SHA3-256 context.
*
* If hmac_sha3_256_ctx is NULL, then return false.
* If new_hmac_sha3_256_ctx is NULL, then return false.
*
* @param[in] hmac_sha3_256_ctx Pointer to HMAC-SHA3-256 context being copied.
* @param[out] new_hmac_sha3_256_ctx Pointer to new HMAC-SHA3-256 context.
*
* @retval true HMAC-SHA3-256 context copy succeeded.
* @retval false HMAC-SHA3-256 context copy failed.
**/
extern bool libspdm_hmac_sha3_256_duplicate(const void *hmac_sha3_256_ctx,
void *new_hmac_sha3_256_ctx);
/**
* Digests the input data and updates HMAC-SHA3-256 context.
*
* This function performs HMAC-SHA3-256 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* HMAC-SHA3-256 context should be initialized by libspdm_hmac_sha3_256_new(), and should not be
* finalized by libspdm_hmac_sha3_256_final(). Behavior with invalid context is undefined.
*
* If hmac_sha3_256_ctx is NULL, then return false.
*
* @param[in, out] hmac_sha3_256_ctx Pointer to the HMAC-SHA3-256 context.
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true HMAC-SHA3-256 data digest succeeded.
* @retval false HMAC-SHA3-256 data digest failed.
**/
extern bool libspdm_hmac_sha3_256_update(void *hmac_sha3_256_ctx,
const void *data, size_t data_size);
/**
* Completes computation of the HMAC-SHA3-256 digest value.
*
* This function completes HMAC-SHA3-256 hash computation and retrieves the digest value into
* the specified memory. After this function has been called, the HMAC-SHA3-256 context cannot
* be used again. HMAC-SHA3-256 context should be initialized by libspdm_hmac_sha3_256_new(), and
* should not be finalized by libspdm_hmac_sha3_256_final(). Behavior with invalid HMAC-SHA3-256
* context is undefined.
*
* If hmac_sha3_256_ctx is NULL, then return false.
* If hmac_value is NULL, then return false.
*
* @param[in, out] hmac_sha3_256_ctx Pointer to the HMAC-SHA3-256 context.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA3-256 digest
* value (32 bytes).
*
* @retval true HMAC-SHA3-256 digest computation succeeded.
* @retval false HMAC-SHA3-256 digest computation failed.
**/
extern bool libspdm_hmac_sha3_256_final(void *hmac_sha3_256_ctx, uint8_t *hmac_value);
/**
* Computes the HMAC-SHA3-256 digest of a input data buffer.
*
* This function performs the HMAC-SHA3-256 digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA3-256 digest
* value (32 bytes).
*
* @retval true HMAC-SHA3-256 digest computation succeeded.
* @retval false HMAC-SHA3-256 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_256_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value);
#endif /* LIBSPDM_SHA3_256_SUPPORT */
#if LIBSPDM_SHA3_384_SUPPORT
/**
* Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA3-384 use.
*
* @return Pointer to the HMAC_CTX context that has been initialized.
* If the allocations fails, libspdm_hmac_sha3_384_new() returns NULL.
**/
extern void *libspdm_hmac_sha3_384_new(void);
/**
* Release the specified HMAC_CTX context.
*
* @param[in] hmac_sha3_384_ctx Pointer to the HMAC_CTX context to be released.
**/
extern void libspdm_hmac_sha3_384_free(void *hmac_sha3_384_ctx);
/**
* Set user-supplied key for subsequent use. It must be done before any
* calling to libspdm_hmac_sha3_384_update().
*
* If hmac_sha3_384_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[out] hmac_sha3_384_ctx Pointer to HMAC-SHA3-384 context.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
*
* @retval true The key is set successfully.
* @retval false The key is set unsuccessfully.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_384_set_key(void *hmac_sha3_384_ctx,
const uint8_t *key,
size_t key_size);
/**
* Makes a copy of an existing HMAC-SHA3-384 context.
*
* If hmac_sha3_384_ctx is NULL, then return false.
* If new_hmac_sha3_384_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] hmac_sha3_384_ctx Pointer to HMAC-SHA3-384 context being copied.
* @param[out] new_hmac_sha3_384_ctx Pointer to new HMAC-SHA3-384 context.
*
* @retval true HMAC-SHA3-384 context copy succeeded.
* @retval false HMAC-SHA3-384 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_384_duplicate(const void *hmac_sha3_384_ctx,
void *new_hmac_sha3_384_ctx);
/**
* Digests the input data and updates HMAC-SHA3-384 context.
*
* This function performs HMAC-SHA3-384 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* HMAC-SHA3-384 context should be initialized by libspdm_hmac_sha3_384_new(), and should not be
* finalized by libspdm_hmac_sha3_384_final(). Behavior with invalid context is undefined.
*
* If hmac_sha3_384_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha3_384_ctx Pointer to the HMAC-SHA3-384 context.
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true HMAC-SHA3-384 data digest succeeded.
* @retval false HMAC-SHA3-384 data digest failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_384_update(void *hmac_sha3_384_ctx, const void *data,
size_t data_size);
/**
* Completes computation of the HMAC-SHA3-384 digest value.
*
* This function completes HMAC-SHA3-384 hash computation and retrieves the digest value into
* the specified memory. After this function has been called, the HMAC-SHA3-384 context cannot
* be used again. HMAC-SHA3-384 context should be initialized by libspdm_hmac_sha3_384_new(), and
* should not be finalized by libspdm_hmac_sha3_384_final(). Behavior with invalid HMAC-SHA3-384
* context is undefined.
*
* If hmac_sha3_384_ctx is NULL, then return false.
* If hmac_value is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha3_384_ctx Pointer to the HMAC-SHA3-384 context.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA3-384 digest
* value (48 bytes).
*
* @retval true HMAC-SHA3-384 digest computation succeeded.
* @retval false HMAC-SHA3-384 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_384_final(void *hmac_sha3_384_ctx, uint8_t *hmac_value);
/**
* Computes the HMAC-SHA3-384 digest of a input data buffer.
*
* This function performs the HMAC-SHA3-384 digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA3-384 digest
* value (48 bytes).
*
* @retval true HMAC-SHA3-384 digest computation succeeded.
* @retval false HMAC-SHA3-384 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_384_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value);
#endif /* LIBSPDM_SHA3_384_SUPPORT */
#if LIBSPDM_SHA3_512_SUPPORT
/**
* Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA3-512 use.
*
* @return Pointer to the HMAC_CTX context that has been initialized.
* If the allocations fails, libspdm_hmac_sha3_512_new() returns NULL.
**/
extern void *libspdm_hmac_sha3_512_new(void);
/**
* Release the specified HMAC_CTX context.
*
* @param[in] hmac_sha3_512_ctx Pointer to the HMAC_CTX context to be released.
**/
extern void libspdm_hmac_sha3_512_free(void *hmac_sha3_512_ctx);
/**
* Set user-supplied key for subsequent use. It must be done before any
* calling to libspdm_hmac_sha3_512_update().
*
* If hmac_sha3_512_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[out] hmac_sha3_512_ctx Pointer to HMAC-SHA3-512 context.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
*
* @retval true The key is set successfully.
* @retval false The key is set unsuccessfully.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_512_set_key(void *hmac_sha3_512_ctx,
const uint8_t *key,
size_t key_size);
/**
* Makes a copy of an existing HMAC-SHA3-512 context.
*
* If hmac_sha3_512_ctx is NULL, then return false.
* If new_hmac_sha3_512_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] hmac_sha3_512_ctx Pointer to HMAC-SHA3-512 context being copied.
* @param[out] new_hmac_sha3_512_ctx Pointer to new HMAC-SHA3-512 context.
*
* @retval true HMAC-SHA3-512 context copy succeeded.
* @retval false HMAC-SHA3-512 context copy failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_512_duplicate(const void *hmac_sha3_512_ctx,
void *new_hmac_sha3_512_ctx);
/**
* Digests the input data and updates HMAC-SHA3-512 context.
*
* This function performs HMAC-SHA3-512 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* HMAC-SHA3-512 context should be initialized by libspdm_hmac_sha3_512_new(), and should not be
* finalized by libspdm_hmac_sha3_512_final(). Behavior with invalid context is undefined.
*
* If hmac_sha3_512_ctx is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha3_512_ctx Pointer to the HMAC-SHA3-512 context.
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true HMAC-SHA3-512 data digest succeeded.
* @retval false HMAC-SHA3-512 data digest failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_512_update(void *hmac_sha3_512_ctx,
const void *data, size_t data_size);
/**
* Completes computation of the HMAC-SHA3-512 digest value.
*
* This function completes HMAC-SHA3-512 hash computation and retrieves the digest value into
* the specified memory. After this function has been called, the HMAC-SHA3-512 context cannot
* be used again. HMAC-SHA3-512 context should be initialized by libspdm_hmac_sha3_512_new(), and
* should not be finalized by libspdm_hmac_sha3_512_final(). Behavior with invalid HMAC-SHA3-512
* context is undefined.
*
* If hmac_sha3_512_ctx is NULL, then return false.
* If hmac_value is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] hmac_sha3_512_ctx Pointer to the HMAC-SHA3-512 context.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA3-512 digest
* value (64 bytes).
*
* @retval true HMAC-SHA3-512 digest computation succeeded.
* @retval false HMAC-SHA3-512 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_512_final(void *hmac_sha3_512_ctx, uint8_t *hmac_value);
/**
* Computes the HMAC-SHA3-512 digest of a input data buffer.
*
* This function performs the HMAC-SHA3-512 digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SHA3-512 digest
* value (64 bytes).
*
* @retval true HMAC-SHA3-512 digest computation succeeded.
* @retval false HMAC-SHA3-512 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sha3_512_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value);
#endif /* LIBSPDM_SHA3_512_SUPPORT */
#if LIBSPDM_SM3_256_SUPPORT
/**
* Allocates and initializes one HMAC_CTX context for subsequent HMAC-SM3-256 use.
*
* @return Pointer to the HMAC_CTX context that has been initialized.
* If the allocations fails, libspdm_hmac_sm3_256_new() returns NULL.
**/
extern void *libspdm_hmac_sm3_256_new(void);
/**
* Release the specified HMAC_CTX context.
*
* @param[in] hmac_sm3_256_ctx Pointer to the HMAC_CTX context to be released.
**/
extern void libspdm_hmac_sm3_256_free(void *hmac_sm3_256_ctx);
/**
* Set user-supplied key for subsequent use. It must be done before any
* calling to libspdm_hmac_sm3_256_update().
*
* If hmac_sm3_256_ctx is NULL, then return false.
*
* @param[out] hmac_sm3_256_ctx Pointer to HMAC-SM3-256 context.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
*
* @retval true The key is set successfully.
* @retval false The key is set unsuccessfully.
**/
extern bool libspdm_hmac_sm3_256_set_key(void *hmac_sm3_256_ctx,
const uint8_t *key, size_t key_size);
/**
* Makes a copy of an existing HMAC-SM3-256 context.
*
* If hmac_sm3_256_ctx is NULL, then return false.
* If new_hmac_sm3_256_ctx is NULL, then return false.
*
* @param[in] hmac_sm3_256_ctx Pointer to HMAC-SM3-256 context being copied.
* @param[out] new_hmac_sm3_256_ctx Pointer to new HMAC-SM3-256 context.
*
* @retval true HMAC-SM3-256 context copy succeeded.
* @retval false HMAC-SM3-256 context copy failed.
**/
extern bool libspdm_hmac_sm3_256_duplicate(const void *hmac_sm3_256_ctx,
void *new_hmac_sm3_256_ctx);
/**
* Digests the input data and updates HMAC-SM3-256 context.
*
* This function performs HMAC-SM3-256 digest on a data buffer of the specified size.
* It can be called multiple times to compute the digest of long or discontinuous data streams.
* HMAC-SM3-256 context should be initialized by libspdm_hmac_sm3_256_new(), and should not be
* finalized by libspdm_hmac_sm3_256_final(). Behavior with invalid context is undefined.
*
* If hmac_sm3_256_ctx is NULL, then return false.
*
* @param[in, out] hmac_sm3_256_ctx Pointer to the HMAC-SM3-256 context.
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
*
* @retval true HMAC-SM3-256 data digest succeeded.
* @retval false HMAC-SM3-256 data digest failed.
**/
extern bool libspdm_hmac_sm3_256_update(void *hmac_sm3_256_ctx, const void *data, size_t data_size);
/**
* Completes computation of the HMAC-SM3-256 digest value.
*
* This function completes HMAC-SM3-256 hash computation and retrieves the digest value into
* the specified memory. After this function has been called, the HMAC-SM3-256 context cannot
* be used again. HMAC-SM3-256 context should be initialized by libspdm_hmac_sm3_256_new(), and
* should not be finalized by libspdm_hmac_sm3_256_final(). Behavior with invalid HMAC-SM3-256
* context is undefined.
*
* If hmac_sm3_256_ctx is NULL, then return false.
* If hmac_value is NULL, then return false.
*
* @param[in, out] hmac_sm3_256_ctx Pointer to the HMAC-SM3-256 context.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SM3-256 digest
* value (32 bytes).
*
* @retval true HMAC-SM3-256 digest computation succeeded.
* @retval false HMAC-SM3-256 digest computation failed.
**/
extern bool libspdm_hmac_sm3_256_final(void *hmac_sm3_256_ctx, uint8_t *hmac_value);
/**
* Computes the HMAC-SM3-256 digest of a input data buffer.
*
* This function performs the HMAC-SM3-256 digest of a given data buffer, and places
* the digest value into the specified memory.
*
* If this interface is not supported, then return false.
*
* @param[in] data Pointer to the buffer containing the data to be digested.
* @param[in] data_size Size of data buffer in bytes.
* @param[in] key Pointer to the user-supplied key.
* @param[in] key_size Key size in bytes.
* @param[out] hmac_value Pointer to a buffer that receives the HMAC-SM3-256 digest
* value (32 bytes).
*
* @retval true HMAC-SM3-256 digest computation succeeded.
* @retval false HMAC-SM3-256 digest computation failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_hmac_sm3_256_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value);
#endif /* LIBSPDM_SM3_256_SUPPORT */
#endif /* CRYPTLIB_MAC_H */

View File

@@ -0,0 +1,30 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_RNG_H
#define CRYPTLIB_RNG_H
/*=====================================================================================
* Random Number Generation Primitive
*=====================================================================================*/
/**
* Generates a random byte stream of the specified size. If initialization, testing, or seeding of
* the (pseudo)random number generator is required it should be done before this function is called.
*
* If output is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[out] output Pointer to buffer to receive random value.
* @param[in] size Size of random bytes to generate.
*
* @retval true Random byte stream generated successfully.
* @retval false Generation of random byte stream failed.
* @retval false This interface is not supported.
**/
extern bool libspdm_random_bytes(uint8_t *output, size_t size);
#endif /* CRYPTLIB_RNG_H */

View File

@@ -0,0 +1,264 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_RSA_H
#define CRYPTLIB_RSA_H
/*=====================================================================================
* RSA Cryptography Primitives
*=====================================================================================
*/
#if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
/* RSA key Tags Definition used in libspdm_rsa_set_key() function for key component
* identification.
*/
typedef enum {
LIBSPDM_RSA_KEY_N, /*< RSA public Modulus (N)*/
LIBSPDM_RSA_KEY_E, /*< RSA public exponent (e)*/
LIBSPDM_RSA_KEY_D, /*< RSA Private exponent (d)*/
LIBSPDM_RSA_KEY_P, /*< RSA secret prime factor of Modulus (p)*/
LIBSPDM_RSA_KEY_Q, /*< RSA secret prime factor of Modules (q)*/
LIBSPDM_RSA_KEY_DP, /*< p's CRT exponent (== d mod (p - 1))*/
LIBSPDM_RSA_KEY_DQ, /*< q's CRT exponent (== d mod (q - 1))*/
LIBSPDM_RSA_KEY_Q_INV /*< The CRT coefficient (== 1/q mod p)*/
} libspdm_rsa_key_tag_t;
/**
* Allocates and initializes one RSA context for subsequent use.
*
* @return Pointer to the RSA context that has been initialized.
* If the allocations fails, libspdm_rsa_new() returns NULL.
**/
extern void *libspdm_rsa_new(void);
/**
* Release the specified RSA context.
*
* If rsa_context is NULL, then return false.
*
* @param[in] rsa_context Pointer to the RSA context to be released.
**/
extern void libspdm_rsa_free(void *rsa_context);
/**
* Sets the tag-designated key component into the established RSA context.
*
* This function sets the tag-designated RSA key component into the established
* RSA context from the user-specified non-negative integer (octet string format
* represented in RSA PKCS#1).
* If big_number is NULL, then the specified key component in RSA context is cleared.
* If rsa_context is NULL, then return false.
*
* @param[in, out] rsa_context Pointer to RSA context being set.
* @param[in] key_tag tag of RSA key component being set.
* @param[in] big_number Pointer to octet integer buffer.
* If NULL, then the specified key component in RSA
* context is cleared.
* @param[in] bn_size Size of big number buffer in bytes.
* If big_number is NULL, then it is ignored.
*
* @retval true RSA key component was set successfully.
* @retval false Invalid RSA key component tag.
**/
extern bool libspdm_rsa_set_key(void *rsa_context, const libspdm_rsa_key_tag_t key_tag,
const uint8_t *big_number, size_t bn_size);
/**
* Gets the tag-designated RSA key component from the established RSA context.
*
* This function retrieves the tag-designated RSA key component from the
* established RSA context as a non-negative integer (octet string format
* represented in RSA PKCS#1).
* If specified key component has not been set or has been cleared, then returned
* bn_size is set to 0.
* If the big_number buffer is too small to hold the contents of the key, false
* is returned and bn_size is set to the required buffer size to obtain the key.
*
* If rsa_context is NULL, then return false.
* If bn_size is NULL, then return false.
* If bn_size is large enough but big_number is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] rsa_context Pointer to RSA context being set.
* @param[in] key_tag Tag of RSA key component being set.
* @param[out] big_number Pointer to octet integer buffer.
* @param[in, out] bn_size On input, the size of big number buffer in bytes.
* On output, the size of data returned in big number buffer in bytes.
*
* @retval true RSA key component was retrieved successfully.
* @retval false Invalid RSA key component tag.
* @retval false bn_size is too small.
* @retval false This interface is not supported.
**/
extern bool libspdm_rsa_get_key(void *rsa_context, const libspdm_rsa_key_tag_t key_tag,
uint8_t *big_number, size_t *bn_size);
/**
* Generates RSA key components.
*
* This function generates RSA key components. It takes RSA public exponent E and
* length in bits of RSA modulus N as input, and generates all key components.
* If public_exponent is NULL, the default RSA public exponent (0x10001) will be used.
*
* If rsa_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in, out] rsa_context Pointer to RSA context being set.
* @param[in] modulus_length Length of RSA modulus N in bits.
* @param[in] public_exponent Pointer to RSA public exponent.
* @param[in] public_exponent_size Size of RSA public exponent buffer in bytes.
*
* @retval true RSA key component was generated successfully.
* @retval false Invalid RSA key component tag.
* @retval false This interface is not supported.
**/
extern bool libspdm_rsa_generate_key(void *rsa_context, size_t modulus_length,
const uint8_t *public_exponent,
size_t public_exponent_size);
/**
* Validates key components of RSA context.
* NOTE: This function performs integrity checks on all the RSA key material, so
* the RSA key structure must contain all the private key data.
*
* This function validates key components of RSA context in following aspects:
* - Whether p is a prime
* - Whether q is a prime
* - Whether n = p * q
* - Whether d*e = 1 mod lcm(p-1,q-1)
*
* If rsa_context is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] rsa_context Pointer to RSA context to check.
*
* @retval true RSA key components are valid.
* @retval false RSA key components are not valid.
* @retval false This interface is not supported.
**/
extern bool libspdm_rsa_check_key(void *rsa_context);
#endif /* (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT) */
#if LIBSPDM_RSA_SSA_SUPPORT
/**
* Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.
*
* This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme
* defined in RSA PKCS#1. If the signature buffer is too small to hold the contents of signature,
* false is returned and sig_size is set to the required buffer size to obtain the signature.
*
* If rsa_context is NULL, then return false.
* If message_hash is NULL, then return false.
* If hash_size need match the hash_nid. hash_nid could be SHA256, SHA384, SHA512, SHA3_256,
* SHA3_384, SHA3_512.
* If sig_size is large enough but signature is NULL, then return false.
* If this interface is not supported, then return false.
*
* @param[in] rsa_context Pointer to RSA context for signature generation.
* @param[in] hash_nid hash NID
* @param[in] message_hash Pointer to octet message hash to be signed.
* @param[in] hash_size Size of the message hash in bytes.
* @param[out] signature Pointer to buffer to receive RSA PKCS1-v1_5 signature.
* @param[in, out] sig_size On input, the size of signature buffer in bytes.
* On output, the size of data returned in signature buffer in bytes.
*
* @retval true signature successfully generated in PKCS1-v1_5.
* @retval false signature generation failed.
* @retval false sig_size is too small.
* @retval false This interface is not supported.
**/
extern bool libspdm_rsa_pkcs1_sign_with_nid(void *rsa_context, size_t hash_nid,
const uint8_t *message_hash,
size_t hash_size, uint8_t *signature,
size_t *sig_size);
/**
* Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in RSA PKCS#1.
*
* If rsa_context is NULL, then return false.
* If message_hash is NULL, then return false.
* If signature is NULL, then return false.
* If hash_size need match the hash_nid. hash_nid could be SHA256, SHA384, SHA512, SHA3_256,
* SHA3_384, SHA3_512.
*
* @param[in] rsa_context Pointer to RSA context for signature verification.
* @param[in] hash_nid hash NID
* @param[in] message_hash Pointer to octet message hash to be checked.
* @param[in] hash_size Size of the message hash in bytes.
* @param[in] signature Pointer to RSA PKCS1-v1_5 signature to be verified.
* @param[in] sig_size Size of signature in bytes.
*
* @retval true Valid signature encoded in PKCS1-v1_5.
* @retval false Invalid signature or invalid RSA context.
**/
extern bool libspdm_rsa_pkcs1_verify_with_nid(void *rsa_context, size_t hash_nid,
const uint8_t *message_hash,
size_t hash_size, const uint8_t *signature,
size_t sig_size);
#endif /* LIBSPDM_RSA_SSA_SUPPORT */
#if LIBSPDM_RSA_PSS_SUPPORT
/**
* Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
*
* This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined
* in RSA PKCS#1 v2.2.
*
* The salt length is same as digest length.
*
* If the signature buffer is too small to hold the contents of signature, false
* is returned and sig_size is set to the required buffer size to obtain the signature.
*
* If rsa_context is NULL, then return false.
* If message_hash is NULL, then return false.
* If hash_size need match the hash_nid. nid could be SHA256, SHA384, SHA512, SHA3_256, SHA3_384,
* SHA3_512.
* If sig_size is large enough but signature is NULL, then return false.
*
* @param[in] rsa_context Pointer to RSA context for signature generation.
* @param[in] hash_nid hash NID
* @param[in] message_hash Pointer to octet message hash to be signed.
* @param[in] hash_size Size of the message hash in bytes.
* @param[out] signature Pointer to buffer to receive RSA-SSA PSS signature.
* @param[in, out] sig_size On input, the size of signature buffer in bytes.
* On output, the size of data returned in signature buffer in bytes.
*
* @retval true signature successfully generated in RSA-SSA PSS.
* @retval false signature generation failed.
* @retval false sig_size is too small.
**/
extern bool libspdm_rsa_pss_sign(void *rsa_context, size_t hash_nid,
const uint8_t *message_hash, size_t hash_size,
uint8_t *signature, size_t *sig_size);
/**
* Verifies the RSA-SSA signature with EMSA-PSS encoding scheme defined in
* RSA PKCS#1 v2.2.
*
* The salt length is same as digest length.
*
* If rsa_context is NULL, then return false.
* If message_hash is NULL, then return false.
* If signature is NULL, then return false.
* If hash_size need match the hash_nid. nid could be SHA256, SHA384, SHA512, SHA3_256, SHA3_384,
* SHA3_512.
*
* @param[in] rsa_context Pointer to RSA context for signature verification.
* @param[in] hash_nid hash NID
* @param[in] message_hash Pointer to octet message hash to be checked.
* @param[in] hash_size Size of the message hash in bytes.
* @param[in] signature Pointer to RSA-SSA PSS signature to be verified.
* @param[in] sig_size Size of signature in bytes.
*
* @retval true Valid signature encoded in RSA-SSA PSS.
* @retval false Invalid signature or invalid RSA context.
**/
extern bool libspdm_rsa_pss_verify(void *rsa_context, size_t hash_nid,
const uint8_t *message_hash, size_t hash_size,
const uint8_t *signature, size_t sig_size);
#endif /* LIBSPDM_RSA_PSS_SUPPORT */
#endif /* CRYPTLIB_RSA_H */

View File

@@ -0,0 +1,194 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef CRYPTLIB_SM2_H
#define CRYPTLIB_SM2_H
/*=====================================================================================
* Shang-Mi2 Primitives
*=====================================================================================*/
#if LIBSPDM_SM2_DSA_SUPPORT
/**
* Allocates and Initializes one Shang-Mi2 context for subsequent use.
*
* @param nid cipher NID
*
* @return Pointer to the Shang-Mi2 context that has been initialized.
* If the allocations fails, sm2_new_by_nid() returns NULL.
**/
extern void *libspdm_sm2_dsa_new_by_nid(size_t nid);
/**
* Release the specified sm2 context.
*
* @param[in] sm2_context Pointer to the sm2 context to be released.
**/
extern void libspdm_sm2_dsa_free(void *sm2_context);
/**
* Carries out the SM2 signature, based upon GB/T 32918.2-2016: SM2 - Part2.
*
* This function carries out the SM2 signature.
* If the signature buffer is too small to hold the contents of signature, false
* is returned and sig_size is set to the required buffer size to obtain the signature.
*
* If sm2_context is NULL, then return false.
* If message is NULL, then return false.
* hash_nid must be SM3_256.
* If sig_size is large enough but signature is NULL, then return false.
*
* The id_a_size must be smaller than 2^16-1.
* The sig_size is 64. first 32-byte is R, second 32-byte is S.
*
* @param[in] sm2_context Pointer to sm2 context for signature generation.
* @param[in] hash_nid hash NID
* @param[in] id_a The ID-A of the signing context.
* @param[in] id_a_size Size of ID-A signing context.
* @param[in] message Pointer to octet message to be signed (before hash).
* @param[in] size Size of the message in bytes.
* @param[out] signature Pointer to buffer to receive SM2 signature.
* @param[in, out] sig_size On input, the size of signature buffer in bytes.
* On output, the size of data returned in signature buffer in bytes.
*
* @retval true signature successfully generated in SM2.
* @retval false signature generation failed.
* @retval false sig_size is too small.
**/
extern bool libspdm_sm2_dsa_sign(const void *sm2_context, size_t hash_nid,
const uint8_t *id_a, size_t id_a_size,
const uint8_t *message, size_t size,
uint8_t *signature, size_t *sig_size);
/**
* Verifies the SM2 signature, based upon GB/T 32918.2-2016: SM2 - Part2.
*
* If sm2_context is NULL, then return false.
* If message is NULL, then return false.
* If signature is NULL, then return false.
* hash_nid must be SM3_256.
*
* The id_a_size must be smaller than 2^16-1.
* The sig_size is 64. first 32-byte is R, second 32-byte is S.
*
* @param[in] sm2_context Pointer to SM2 context for signature verification.
* @param[in] hash_nid hash NID
* @param[in] id_a The ID-A of the signing context.
* @param[in] id_a_size Size of ID-A signing context.
* @param[in] message Pointer to octet message to be checked (before hash).
* @param[in] size Size of the message in bytes.
* @param[in] signature Pointer to SM2 signature to be verified.
* @param[in] sig_size Size of signature in bytes.
*
* @retval true Valid signature encoded in SM2.
* @retval false Invalid signature or invalid sm2 context.
*
**/
extern bool libspdm_sm2_dsa_verify(const void *sm2_context, size_t hash_nid,
const uint8_t *id_a, size_t id_a_size,
const uint8_t *message, size_t size,
const uint8_t *signature, size_t sig_size);
#endif /* LIBSPDM_SM2_DSA_SUPPORT */
#if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
/**
* Allocates and Initializes one Shang-Mi2 context for subsequent use.
*
* @param nid cipher NID
*
* @return Pointer to the Shang-Mi2 context that has been initialized.
* If the allocations fails, sm2_new_by_nid() returns NULL.
**/
extern void *libspdm_sm2_key_exchange_new_by_nid(size_t nid);
/**
* Release the specified sm2 context.
*
* @param[in] sm2_context Pointer to the sm2 context to be released.
*
**/
extern void libspdm_sm2_key_exchange_free(void *sm2_context);
/**
* Initialize the specified sm2 context.
*
* @param[in] sm2_context Pointer to the sm2 context to be released.
* @param[in] hash_nid hash NID, only SM3 is valid.
* @param[in] id_a The ID-A of the key exchange context.
* @param[in] id_a_size Size of ID-A key exchange context.
* @param[in] id_b The ID-B of the key exchange context.
* @param[in] id_b_size Size of ID-B key exchange context.
* @param[in] is_initiator If the caller is initiator.
*
* @retval true sm2 context is initialized.
* @retval false sm2 context is not initialized.
**/
extern bool libspdm_sm2_key_exchange_init(const void *sm2_context, size_t hash_nid,
const uint8_t *id_a, size_t id_a_size,
const uint8_t *id_b, size_t id_b_size,
bool is_initiator);
/**
* Generates sm2 key and returns sm2 public key (X, Y), based upon GB/T 32918.3-2016: SM2 - Part3.
*
* This function generates random secret, and computes the public key (X, Y), which is
* returned via parameter public, public_size.
* X is the first half of public with size being public_size / 2,
* Y is the second half of public with size being public_size / 2.
* sm2 context is updated accordingly.
* If the public buffer is too small to hold the public X, Y, false is returned and
* public_size is set to the required buffer size to obtain the public X, Y.
*
* The public_size is 64. first 32-byte is X, second 32-byte is Y.
*
* If sm2_context is NULL, then return false.
* If public_size is NULL, then return false.
* If public_size is large enough but public is NULL, then return false.
*
* @param[in, out] sm2_context Pointer to the sm2 context.
* @param[out] public_data Pointer to the buffer to receive generated public X,Y.
* @param[in, out] public_size On input, the size of public buffer in bytes.
* On output, the size of data returned in public buffer in bytes.
*
* @retval true sm2 public X,Y generation succeeded.
* @retval false sm2 public X,Y generation failed.
* @retval false public_size is not large enough.
**/
extern bool libspdm_sm2_key_exchange_generate_key(void *sm2_context, uint8_t *public_data,
size_t *public_size);
/**
* Computes exchanged common key, based upon GB/T 32918.3-2016: SM2 - Part3.
*
* Given peer's public key (X, Y), this function computes the exchanged common key,
* based on its own context including value of curve parameter and random secret.
* X is the first half of peer_public with size being peer_public_size / 2,
* Y is the second half of peer_public with size being peer_public_size / 2.
*
* If sm2_context is NULL, then return false.
* If peer_public is NULL, then return false.
* If peer_public_size is 0, then return false.
* If key is NULL, then return false.
*
* The id_a_size and id_b_size must be smaller than 2^16-1.
* The peer_public_size is 64. first 32-byte is X, second 32-byte is Y.
* The key_size must be smaller than 2^32-1, limited by KDF function.
*
* @param[in, out] sm2_context Pointer to the sm2 context.
* @param[in] peer_public Pointer to the peer's public X,Y.
* @param[in] peer_public_size Size of peer's public X,Y in bytes.
* @param[out] key Pointer to the buffer to receive generated key.
* @param[in] key_size On input, the size of key buffer in bytes.
*
* @retval true sm2 exchanged key generation succeeded.
* @retval false sm2 exchanged key generation failed.
**/
extern bool libspdm_sm2_key_exchange_compute_key(void *sm2_context,
const uint8_t *peer_public,
size_t peer_public_size, uint8_t *key,
size_t *key_size);
#endif /* LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT */
#endif /* CRYPTLIB_SM2_H */

View File

@@ -0,0 +1,71 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef LIBSPDM_LIB_CONFIG_H
#define LIBSPDM_LIB_CONFIG_H
#ifndef LIBSPDM_CONFIG
#include "library/spdm_lib_config.h"
#else
#include LIBSPDM_CONFIG
#endif
#if defined(LIBSPDM_ENABLE_SET_CERTIFICATE_CAP) && \
!defined(LIBSPDM_ENABLE_CAPABILITY_SET_CERTIFICATE_CAP)
#ifdef _MSC_VER
#pragma message("LIBSPDM_ENABLE_SET_CERTIFICATE_CAP is deprecated. Use " \
"LIBSPDM_ENABLE_CAPABILITY_SET_CERTIFICATE_CAP instead. This warning will be removed in a " \
"future release.")
#else
#warning LIBSPDM_ENABLE_SET_CERTIFICATE_CAP is deprecated. Use \
LIBSPDM_ENABLE_CAPABILITY_SET_CERTIFICATE_CAP instead. This warning will be removed in a \
future release.
#endif /* _MSC_VER */
#endif /* defined(LIBSPDM_ENABLE_SET_CERTIFICATE_CAP) */
#if defined(LIBSPDM_ENABLE_CHUNK_CAP) && !defined(LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP)
#ifdef _MSC_VER
#pragma message("LIBSPDM_ENABLE_CHUNK_CAP is deprecated. Use LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP " \
"instead. This warning will be removed in a future release.")
#else
#warning LIBSPDM_ENABLE_CHUNK_CAP is deprecated. Use LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP \
instead. This warning will be removed in a future release.
#endif /* _MSC_VER */
#endif /* defined(LIBSPDM_ENABLE_CHUNK_CAP) */
#if defined(MDEPKG_NDEBUG) && !defined(LIBSPDM_DEBUG_ENABLE)
#ifdef _MSC_VER
#pragma message("MDEPKG_NDEBUG is deprecated. Use LIBSPDM_DEBUG_ENABLE " \
"instead. This warning will be removed in a future release.")
#else
#warning MDEPKG_NDEBUG is deprecated. Use LIBSPDM_DEBUG_ENABLE \
instead. This warning will be removed in a future release.
#endif /* _MSC_VER */
#endif /* defined(MDEPKG_NDEBUG) */
#if defined(LIBSPDM_DEBUG_ENABLE)
#undef LIBSPDM_DEBUG_ASSERT_ENABLE
#undef LIBSPDM_DEBUG_PRINT_ENABLE
#undef LIBSPDM_DEBUG_BLOCK_ENABLE
#define LIBSPDM_DEBUG_ASSERT_ENABLE (LIBSPDM_DEBUG_ENABLE)
#define LIBSPDM_DEBUG_PRINT_ENABLE (LIBSPDM_DEBUG_ENABLE)
#define LIBSPDM_DEBUG_BLOCK_ENABLE (LIBSPDM_DEBUG_ENABLE)
#elif defined(MDEPKG_NDEBUG)
#undef LIBSPDM_DEBUG_ASSERT_ENABLE
#undef LIBSPDM_DEBUG_PRINT_ENABLE
#undef LIBSPDM_DEBUG_BLOCK_ENABLE
#define LIBSPDM_DEBUG_ASSERT_ENABLE 0
#define LIBSPDM_DEBUG_PRINT_ENABLE 0
#define LIBSPDM_DEBUG_BLOCK_ENABLE 0
#endif /* defined(LIBSPDM_DEBUG_ENABLE) */
#if LIBSPDM_CHECK_MACRO
#include "internal/libspdm_macro_check.h"
#endif /* LIBSPDM_CHECK_MACRO */
#endif /* LIBSPDM_LIB_CONFIG_H */

View File

@@ -0,0 +1,154 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef __INTERNAL_CRYPT_LIB_H__
#define __INTERNAL_CRYPT_LIB_H__
/*
* This code uses Linux Kernel Crypto API extensively. Web page written by
* Stephan Mueller and Marek Vasut is a good starting reference on how linux
* kernel provides crypto api.
*/
#include "conftest.h"
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/limits.h>
#include <linux/random.h>
#include <linux/string.h>
// Check if ECDH/ECDSA are there, on some platforms they might not be...
#ifndef AUTOCONF_INCLUDED
#if defined(NV_GENERATED_AUTOCONF_H_PRESENT)
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#endif
#endif
#if \
(defined(CONFIG_CRYPTO_AEAD) || defined(CONFIG_CRYPTO_AEAD_MODULE)) && \
(defined(CONFIG_CRYPTO_AKCIPHER) || defined(CONFIG_CRYPTO_AKCIPHER_MODULE)) && \
(defined(CONFIG_CRYPTO_SKCIPHER) || defined(CONFIG_CRYPTO_SKCIPHER_MODULE)) && \
(defined(CONFIG_CRYPTO_HASH) || defined(CONFIG_CRYPTO_HASH_MODULE)) && \
(defined(CONFIG_CRYPTO_HMAC) || defined(CONFIG_CRYPTO_HMAC_MODULE)) && \
(defined(CONFIG_CRYPTO_ECDH) || defined(CONFIG_CRYPTO_ECDH_MODULE)) && \
(defined(CONFIG_CRYPTO_ECDSA) || defined(CONFIG_CRYPTO_ECDSA_MODULE)) && \
(defined(CONFIG_X509_CERTIFICATE_PARSER) || defined(CONFIG_X509_CERTIFICATE_PARSER_MODULE))
#define NV_CONFIG_CRYPTO_PRESENT 1
#endif
/*
* It is possible that we don't have access to all the functions we have. This
* could be either because we are running non-gpl kernel, because kernel is too
* old or even just user disabled. If we should use LKCA, include headers, else
* define stubs to return errors.
*/
#if defined(NV_CRYPTO_PRESENT) && defined (NV_CONFIG_CRYPTO_PRESENT)
#define USE_LKCA 1
#endif
#ifdef USE_LKCA
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <crypto/aead.h>
#include <crypto/algapi.h>
#include <crypto/hash.h>
#include <crypto/sm3.h>
// HASH_MAX_DIGESTSIZE is available since 4.20.
// This value is accurate as of 6.1
#ifndef HASH_MAX_DIGESTSIZE
#define HASH_MAX_DIGESTSIZE 64
#endif
#else
// Just stub everything out
struct shash_desc;
struct crypto_shash;
#define crypto_shash_setkey(...) -ENOMEM
#define crypto_shash_init(...) -ENOMEM
#define crypto_shash_update(...) -ENOMEM
#define crypto_shash_update(...) -ENOMEM
#define crypto_shash_final(...) -ENOMEM
#endif
#define CHAR_BIT 8U
#undef SIZE_MAX
#define SIZE_MAX 8
#include "library/cryptlib.h"
#define LIBSPDM_ASSERT(...)
struct lkca_aead_ctx;
int lkca_aead_alloc(struct lkca_aead_ctx **ctx, char const *alg);
void lkca_aead_free(struct lkca_aead_ctx *ctx);
int lkca_aead_ex(struct lkca_aead_ctx *ctx,
const uint8_t *key, size_t key_size,
uint8_t *iv, size_t iv_size,
const uint8_t *data_in, size_t data_in_size,
uint8_t *tag, size_t tag_size,
uint8_t *data_out, size_t *data_out_size,
bool enc);
int libspdm_aead(const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
const uint8_t *tag, size_t tag_size,
uint8_t *data_out, size_t *data_out_size,
bool enc, char const *alg);
void *lkca_hash_new(const char* alg_name);
void lkca_hash_free(struct shash_desc *ctx);
bool lkca_hash_duplicate(struct shash_desc *dst, struct shash_desc const *src);
bool lkca_hash_all(const char* alg_name, const void *data,
size_t data_size, uint8_t *hash_value);
bool lkca_hmac_duplicate(struct shash_desc *dst, struct shash_desc const *src);
bool lkca_hmac_set_key(struct shash_desc *ctx, const uint8_t *key, size_t key_size);
bool lkca_hmac_all(const char* alg_name, const uint8_t *key, size_t key_size,
const uint8_t *data, size_t data_size, uint8_t *hash_value);
bool lkca_hkdf_extract_and_expand(const char *alg_name,
const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size);
bool lkca_hkdf_expand(const char *alg_name,
const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size);
bool lkca_ecdsa_set_priv_key(void *context, uint8_t *key, size_t key_size);
bool lkca_ec_set_pub_key(void *ec_context, const uint8_t *public_key,
size_t public_key_size);
bool lkca_ec_get_pub_key(void *ec_context, uint8_t *public_key,
size_t *public_key_size);
bool lkca_ec_generate_key(void *ec_context, uint8_t *public_data,
size_t *public_size);
bool lkca_ec_compute_key(void *ec_context, const uint8_t *peer_public,
size_t peer_public_size, uint8_t *key,
size_t *key_size);
bool lkca_ecdsa_verify(void *ec_context, size_t hash_nid,
const uint8_t *message_hash, size_t hash_size,
const uint8_t *signature, size_t sig_size);
#endif

View File

@@ -0,0 +1,109 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
/** @file
* Defines base cryptographic library APIs.
* The Base Cryptographic Library provides implementations of basic cryptography
* primitives (hash Serials, HMAC, AES, RSA, Diffie-Hellman, Elliptic Curve, etc) for security
* functionality enabling.
**/
#ifndef CRYPTLIB_H
#define CRYPTLIB_H
#include "internal/libspdm_lib_config.h"
#define LIBSPDM_CRYPTO_NID_NULL 0x0000
/* Hash */
#define LIBSPDM_CRYPTO_NID_SHA256 0x0001
#define LIBSPDM_CRYPTO_NID_SHA384 0x0002
#define LIBSPDM_CRYPTO_NID_SHA512 0x0003
#define LIBSPDM_CRYPTO_NID_SHA3_256 0x0004
#define LIBSPDM_CRYPTO_NID_SHA3_384 0x0005
#define LIBSPDM_CRYPTO_NID_SHA3_512 0x0006
#define LIBSPDM_CRYPTO_NID_SM3_256 0x0007
/* Signing */
#define LIBSPDM_CRYPTO_NID_RSASSA2048 0x0101
#define LIBSPDM_CRYPTO_NID_RSASSA3072 0x0102
#define LIBSPDM_CRYPTO_NID_RSASSA4096 0x0103
#define LIBSPDM_CRYPTO_NID_RSAPSS2048 0x0104
#define LIBSPDM_CRYPTO_NID_RSAPSS3072 0x0105
#define LIBSPDM_CRYPTO_NID_RSAPSS4096 0x0106
#define LIBSPDM_CRYPTO_NID_ECDSA_NIST_P256 0x0107
#define LIBSPDM_CRYPTO_NID_ECDSA_NIST_P384 0x0108
#define LIBSPDM_CRYPTO_NID_ECDSA_NIST_P521 0x0109
#define LIBSPDM_CRYPTO_NID_SM2_DSA_P256 0x010A
#define LIBSPDM_CRYPTO_NID_EDDSA_ED25519 0x010B
#define LIBSPDM_CRYPTO_NID_EDDSA_ED448 0x010C
/* Key Exchange */
#define LIBSPDM_CRYPTO_NID_FFDHE2048 0x0201
#define LIBSPDM_CRYPTO_NID_FFDHE3072 0x0202
#define LIBSPDM_CRYPTO_NID_FFDHE4096 0x0203
#define LIBSPDM_CRYPTO_NID_SECP256R1 0x0204
#define LIBSPDM_CRYPTO_NID_SECP384R1 0x0205
#define LIBSPDM_CRYPTO_NID_SECP521R1 0x0206
#define LIBSPDM_CRYPTO_NID_SM2_KEY_EXCHANGE_P256 0x0207
#define LIBSPDM_CRYPTO_NID_CURVE_X25519 0x0208
#define LIBSPDM_CRYPTO_NID_CURVE_X448 0x0209
/* AEAD */
#define LIBSPDM_CRYPTO_NID_AES_128_GCM 0x0301
#define LIBSPDM_CRYPTO_NID_AES_256_GCM 0x0302
#define LIBSPDM_CRYPTO_NID_CHACHA20_POLY1305 0x0303
#define LIBSPDM_CRYPTO_NID_SM4_128_GCM 0x0304
/* X.509 v3 key usage extension flags. */
#define LIBSPDM_CRYPTO_X509_KU_DIGITAL_SIGNATURE 0x80 /* bit 0 */
#define LIBSPDM_CRYPTO_X509_KU_NON_REPUDIATION 0x40 /* bit 1 */
#define LIBSPDM_CRYPTO_X509_KU_KEY_ENCIPHERMENT 0x20 /* bit 2 */
#define LIBSPDM_CRYPTO_X509_KU_DATA_ENCIPHERMENT 0x10 /* bit 3 */
#define LIBSPDM_CRYPTO_X509_KU_KEY_AGREEMENT 0x08 /* bit 4 */
#define LIBSPDM_CRYPTO_X509_KU_KEY_CERT_SIGN 0x04 /* bit 5 */
#define LIBSPDM_CRYPTO_X509_KU_CRL_SIGN 0x02 /* bit 6 */
#define LIBSPDM_CRYPTO_X509_KU_ENCIPHER_ONLY 0x01 /* bit 7 */
#define LIBSPDM_CRYPTO_X509_KU_DECIPHER_ONLY 0x8000 /* bit 8 */
/* These constants comply with the DER encoded ASN.1 type tags. */
#define LIBSPDM_CRYPTO_ASN1_BOOLEAN 0x01
#define LIBSPDM_CRYPTO_ASN1_INTEGER 0x02
#define LIBSPDM_CRYPTO_ASN1_BIT_STRING 0x03
#define LIBSPDM_CRYPTO_ASN1_OCTET_STRING 0x04
#define LIBSPDM_CRYPTO_ASN1_NULL 0x05
#define LIBSPDM_CRYPTO_ASN1_OID 0x06
#define LIBSPDM_CRYPTO_ASN1_UTF8_STRING 0x0C
#define LIBSPDM_CRYPTO_ASN1_SEQUENCE 0x10
#define LIBSPDM_CRYPTO_ASN1_SET 0x11
#define LIBSPDM_CRYPTO_ASN1_PRINTABLE_STRING 0x13
#define LIBSPDM_CRYPTO_ASN1_T61_STRING 0x14
#define LIBSPDM_CRYPTO_ASN1_IA5_STRING 0x16
#define LIBSPDM_CRYPTO_ASN1_UTC_TIME 0x17
#define LIBSPDM_CRYPTO_ASN1_GENERALIZED_TIME 0x18
#define LIBSPDM_CRYPTO_ASN1_UNIVERSAL_STRING 0x1C
#define LIBSPDM_CRYPTO_ASN1_BMP_STRING 0x1E
#define LIBSPDM_CRYPTO_ASN1_PRIMITIVE 0x00
#define LIBSPDM_CRYPTO_ASN1_CONSTRUCTED 0x20
#define LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC 0x80
#define LIBSPDM_CRYPTO_ASN1_TAG_CLASS_MASK 0xC0
#define LIBSPDM_CRYPTO_ASN1_TAG_PC_MASK 0x20
#define LIBSPDM_CRYPTO_ASN1_TAG_VALUE_MASK 0x1F
#include "hal/library/cryptlib/cryptlib_hash.h"
#include "hal/library/cryptlib/cryptlib_mac.h"
#include "hal/library/cryptlib/cryptlib_aead.h"
#include "hal/library/cryptlib/cryptlib_cert.h"
#include "hal/library/cryptlib/cryptlib_hkdf.h"
#include "hal/library/cryptlib/cryptlib_rsa.h"
#include "hal/library/cryptlib/cryptlib_ec.h"
#include "hal/library/cryptlib/cryptlib_dh.h"
#include "hal/library/cryptlib/cryptlib_ecd.h"
#include "hal/library/cryptlib/cryptlib_sm2.h"
#include "hal/library/cryptlib/cryptlib_rng.h"
#endif /* CRYPTLIB_H */

View File

@@ -0,0 +1,415 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/
#ifndef SPDM_LIB_CONFIG_H
#define SPDM_LIB_CONFIG_H
/* Enables assertions and debug printing. When `LIBSPDM_DEBUG_ENABLE` is defined it overrides or
* sets the values of `LIBSPDM_DEBUG_PRINT_ENABLE`, `LIBSPDM_DEBUG_ASSERT_ENABLE`, and
* `LIBSPDM_BLOCK_ENABLE` to the value of `LIBSPDM_DEBUG_ENABLE`.
*
* Note that if this file is used with CMake and `DTARGET=Release` is defined, then all debugging
* is disabled.
*/
#ifndef LIBSPDM_DEBUG_ENABLE
#define LIBSPDM_DEBUG_ENABLE 1
#endif
/* The SPDM specification allows a Responder to return up to 256 version entries in the `VERSION`
* response to the Requester, including duplicate entries. For a Requester this value specifies the
* maximum number of entries that libspdm will tolerate in a `VERSION` response before returning an
* error. A similiar macro, `SPDM_MAX_VERSION_COUNT`, exists for the Responder. However this macro
* is not meant to be configured by the Integrator.
*/
#ifndef LIBSPDM_MAX_VERSION_COUNT
#define LIBSPDM_MAX_VERSION_COUNT 5
#endif
/* This value specifies the maximum size, in bytes, of the `PSK_EXCHANGE.RequesterContext` and,
* if supported by the Responder, `PSK_EXCHANGE_RSP.ResponderContext` fields. The fields are
* typically random or monotonically increasing numbers.
*/
#ifndef LIBSPDM_PSK_CONTEXT_LENGTH
#define LIBSPDM_PSK_CONTEXT_LENGTH LIBSPDM_MAX_HASH_SIZE
#endif
/* This value specifies the maximum size, in bytes, of the `PSK_EXCHANGE.PSKHint` field.*/
#ifndef LIBSPDM_PSK_MAX_HINT_LENGTH
#define LIBSPDM_PSK_MAX_HINT_LENGTH 16
#endif
/* libspdm allows an Integrator to specify multiple root certificates as trust anchors when
* verifying certificate chains from an endpoint. This value specifies the maximum number of root
* certificates that libspdm can support.
*/
#ifndef LIBSPDM_MAX_ROOT_CERT_SUPPORT
#define LIBSPDM_MAX_ROOT_CERT_SUPPORT 10
#endif
/* If the Responder supports it a Requester is allowed to establish multiple secure sessions with
* the Responder. This value specifies the maximum number of sessions libspdm can support.
*/
#ifndef LIBSPDM_MAX_SESSION_COUNT
#define LIBSPDM_MAX_SESSION_COUNT 4
#endif
/* This value specifies the maximum size, in bytes, of a certificate chain that can be stored in a
* libspdm context.
*/
#ifndef LIBSPDM_MAX_CERT_CHAIN_SIZE
#define LIBSPDM_MAX_CERT_CHAIN_SIZE 0x1000
#endif
#ifndef LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE
#define LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE 0x1000
#endif
/* Partial certificates can be retrieved from a Requester or Responder and through multiple messages
* the complete certificate chain can be constructed. This value specifies the maximum size,
* in bytes, of a partial certificate that can be sent or received.
*/
#ifndef LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
#define LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN 1024
#endif
#ifndef LIBSPDM_MAX_MESSAGE_BUFFER_SIZE
#define LIBSPDM_MAX_MESSAGE_BUFFER_SIZE 0x1200
#endif
#ifndef LIBSPDM_MAX_MESSAGE_SMALL_BUFFER_SIZE
#define LIBSPDM_MAX_MESSAGE_SMALL_BUFFER_SIZE 0x100 /* to hold message_a before negotiate*/
#endif
#ifndef LIBSPDM_MAX_MESSAGE_MEDIUM_BUFFER_SIZE
#define LIBSPDM_MAX_MESSAGE_MEDIUM_BUFFER_SIZE 0x300 /* to hold message_k before finished_key is ready*/
#endif
/* If the Responder replies with a Busy `ERROR` response to a request then the Requester is free to
* retry sending the request. This value specifies the maximum number of times libspdm will retry
* sending the request before returning an error. If its value is 0 then libspdm will not send any
* retry requests.
*/
#ifndef LIBSPDM_MAX_REQUEST_RETRY_TIMES
#define LIBSPDM_MAX_REQUEST_RETRY_TIMES 3
#endif
#ifndef LIBSPDM_MAX_SESSION_STATE_CALLBACK_NUM
#define LIBSPDM_MAX_SESSION_STATE_CALLBACK_NUM 4
#endif
#ifndef LIBSPDM_MAX_CONNECTION_STATE_CALLBACK_NUM
#define LIBSPDM_MAX_CONNECTION_STATE_CALLBACK_NUM 4
#endif
#ifndef LIBSPDM_MAX_KEY_UPDATE_CALLBACK_NUM
#define LIBSPDM_MAX_KEY_UPDATE_CALLBACK_NUM 4
#endif
#ifndef LIBSPDM_MAX_CSR_SIZE
#define LIBSPDM_MAX_CSR_SIZE 0x1000
#endif
/* To ensure integrity in communication between the Requester and the Responder libspdm calculates
* cryptographic digests and signatures over multiple requests and responses. This value specifies
* whether libspdm will use a running calculation over the transcript, where requests and responses
* are discarded as they are cryptographically consumed, or whether libspdm will buffer the entire
* transcript before calculating the digest or signature.
*/
#ifndef LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
#define LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT 0
#endif
/* Cryptography Configuration
* In each category, at least one should be selected.
* NOTE: Not all combination can be supported. E.g. Don't mix NIST algo with SMx.*/
#ifndef LIBSPDM_RSA_SSA_SUPPORT
#define LIBSPDM_RSA_SSA_SUPPORT 1
#endif
#ifndef LIBSPDM_RSA_PSS_SUPPORT
#define LIBSPDM_RSA_PSS_SUPPORT 1
#endif
#ifndef LIBSPDM_ECDSA_SUPPORT
#define LIBSPDM_ECDSA_SUPPORT 1
#endif
#ifndef LIBSPDM_SM2_DSA_SUPPORT
#define LIBSPDM_SM2_DSA_SUPPORT 1
#endif
#ifndef LIBSPDM_EDDSA_ED25519_SUPPORT
#define LIBSPDM_EDDSA_ED25519_SUPPORT 1
#endif
#ifndef LIBSPDM_EDDSA_ED448_SUPPORT
#define LIBSPDM_EDDSA_ED448_SUPPORT 1
#endif
#ifndef LIBSPDM_FFDHE_SUPPORT
#define LIBSPDM_FFDHE_SUPPORT 1
#endif
#ifndef LIBSPDM_ECDHE_SUPPORT
#define LIBSPDM_ECDHE_SUPPORT 1
#endif
#ifndef LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
#define LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT 1
#endif
#ifndef LIBSPDM_AEAD_GCM_SUPPORT
#define LIBSPDM_AEAD_GCM_SUPPORT 1
#endif
#ifndef LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT
#define LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT 1
#endif
#ifndef LIBSPDM_AEAD_SM4_SUPPORT
#define LIBSPDM_AEAD_SM4_SUPPORT 1
#endif
#ifndef LIBSPDM_SHA256_SUPPORT
#define LIBSPDM_SHA256_SUPPORT 1
#endif
#ifndef LIBSPDM_SHA384_SUPPORT
#define LIBSPDM_SHA384_SUPPORT 1
#endif
#ifndef LIBSPDM_SHA512_SUPPORT
#define LIBSPDM_SHA512_SUPPORT 1
#endif
#ifndef LIBSPDM_SHA3_256_SUPPORT
#define LIBSPDM_SHA3_256_SUPPORT 1
#endif
#ifndef LIBSPDM_SHA3_384_SUPPORT
#define LIBSPDM_SHA3_384_SUPPORT 1
#endif
#ifndef LIBSPDM_SHA3_512_SUPPORT
#define LIBSPDM_SHA3_512_SUPPORT 1
#endif
#ifndef LIBSPDM_SM3_256_SUPPORT
#define LIBSPDM_SM3_256_SUPPORT 1
#endif
/* Code space optimization for Optional request/response messages.*/
/* Consumers of libspdm may wish to not fully implement all of the optional
* SPDM request/response messages. Therefore we have provided these
* SPDM_ENABLE_CAPABILITY_***_CAP compile time switches as an optimization
* disable the code (#if 0) related to said optional capability, thereby
* reducing the code space used in the image.*/
/* A single switch may enable/disable a single capability or group of related
* capabilities.*/
/* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP - Enable/Disable single CERT capability.
* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP - Enable/Disable single CHAL capability.
* LIBSPDM_ENABLE_CAPABILTIY_MEAS_CAP - Enable/Disables multiple MEAS capabilities:
* (MEAS_CAP_NO_SIG, MEAS_CAP_SIG, MEAS_FRESH_CAP)*/
/* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP - Enable/Disable single Key Exchange capability.
* LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP - Enable/Disable PSK_EX and PSK_FINISH.*/
/* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP - Enable/Disable mutual authentication.
* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP - Enable/Disable encapsulated message.*/
/* LIBSPDM_ENABLE_CAPABILITY_GET_CSR_CAP - Enable/Disable get csr capability.
* LIBSPDM_ENABLE_CAPABILITY_SET_CERTIFICATE_CAP - Enable/Disable set certificate capability. */
#ifndef LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
#define LIBSPDM_ENABLE_CAPABILITY_CERT_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
#define LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
#define LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
#define LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP
#define LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP
#define LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
#define LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
#define LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_GET_CSR_CAP
#define LIBSPDM_ENABLE_CAPABILITY_GET_CSR_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_SET_CERTIFICATE_CAP
#define LIBSPDM_ENABLE_CAPABILITY_SET_CERTIFICATE_CAP 1
#endif
#ifndef LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
#define LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP 1
#endif
/*
* MinDataTransferSize = 42
*
* H = HashLen = HmacLen = [32, 64]
* S = SigLen = [64, 512]
* D = ExchangeDataLen = [64, 512]
* R = RequesterContextLen >= 32
* R = ResponderContextLen >= 0
* O = OpaqueDataLen <= 1024
*
* Max Chunk No = 1, if (message size <= 42)
* Max Chunk No = [(message size + 4) / 30] roundup, if (message size > 42)
*
* +==========================+==========================================+=========+
* | Command | Size |MaxChunk |
* +==========================+==========================================+=========+
* | GET_VERSION | 4 | 1 |
* | VERSION {1.0, 1.1, 1.2} | 6 + 2 * 3 = 12 | 1 |
* +--------------------------+------------------------------------------+---------+
* | GET_CAPABILITIES 1.2 | 20 | 1 |
* | CAPABILITIES 1.2 | 20 | 1 |
* +--------------------------+------------------------------------------+---------+
* | ERROR | 4 | 1 |
* | ERROR(ResponseTooLarge) | 4 + 4 = 8 | 1 |
* | ERROR(LargeResponse) | 4 + 1 = 5 | 1 |
* | ERROR(ResponseNotReady) | 4 + 4 = 8 | 1 |
* +--------------------------+------------------------------------------+---------+
* | CHUNK_SEND header | 12 + L0 (0 or 4) | 1 |
* | CHUNK_RESPONSE header | 12 + L0 (0 or 4) | 1 |
* +==========================+==========================================+=========+
* | NEGOTIATE_ALGORITHMS 1.2 | 32 + 4 * 4 = 48 | 2 |
* | ALGORITHMS 1.2 | 36 + 4 * 4 = 52 | 2 |
* +--------------------------+------------------------------------------+---------+
* | GET_DIGESTS 1.2 | 4 | 1 |
* | DIGESTS 1.2 | 4 + H * SlotNum = [36, 516] | [1, 18] |
* +--------------------------+------------------------------------------+---------+
* | GET_CERTIFICATE 1.2 | 8 | 1 |
* | CERTIFICATE 1.2 | 8 + PortionLen | [1, ] |
* +--------------------------+------------------------------------------+---------+
* | CHALLENGE 1.2 | 40 | 1 |
* | CHALLENGE_AUTH 1.2 | 38 + H * 2 + S [+ O] = [166, 678] | [6, 23] |
* +--------------------------+------------------------------------------+---------+
* | GET_MEASUREMENTS 1.2 | 5 + Nounce (0 or 32) | 1 |
* | MEASUREMENTS 1.2 | 42 + MeasRecLen (+ S) [+ O] = [106, 554] | [4, 19] |
* +--------------------------+------------------------------------------+---------+
* | KEY_EXCHANGE 1.2 | 42 + D [+ O] = [106, 554] | [4, 19] |
* | KEY_EXCHANGE_RSP 1.2 | 42 + D + H + S (+ H) [+ O] = [234, 1194] | [8, 40] |
* +--------------------------+------------------------------------------+---------+
* | FINISH 1.2 | 4 (+ S) + H = [100, 580] | [4, 20] |
* | FINISH_RSP 1.2 | 4 (+ H) = [36, 69] | [1, 3] |
* +--------------------------+------------------------------------------+---------+
* | PSK_EXCHANGE 1.2 | 12 [+ PSKHint] + R [+ O] = 44 | 2 |
* | PSK_EXCHANGE_RSP 1.2 | 12 + R + H (+ H) [+ O] = [108, 172] | [4, 6] |
* +--------------------------+------------------------------------------+---------+
* | PSK_FINISH 1.2 | 4 + H = [36, 68] | [1, 3] |
* | PSK_FINISH_RSP 1.2 | 4 | 1 |
* +--------------------------+------------------------------------------+---------+
* | GET_CSR 1.2 | 8 + RequesterInfoLen [+ O] | [1, ] |
* | CSR 1.2 | 8 + CSRLength | [1, ] |
* +--------------------------+------------------------------------------+---------+
* | SET_CERTIFICATE 1.2 | 4 + CertChainLen | [1, ] |
* | SET_CERTIFICATE_RSP 1.2 | 4 | 1 |
* +==========================+==========================================+=========+
*/
/* Maximum size of a large SPDM message.
* If chunk is unsupported, it must be same as LIBSPDM_DATA_TRANSFER_SIZE.
* If chunk is supported, it must be larger than LIBSPDM_DATA_TRANSFER_SIZE.
* It matches MaxSPDMmsgSize in SPDM specification. */
#ifndef LIBSPDM_MAX_SPDM_MSG_SIZE
#define LIBSPDM_MAX_SPDM_MSG_SIZE LIBSPDM_MAX_MESSAGE_BUFFER_SIZE
#endif
/* Maximum size of a single SPDM message.
* It matches DataTransferSize in SPDM specification. */
#ifndef LIBSPDM_DATA_TRANSFER_SIZE
#define LIBSPDM_DATA_TRANSFER_SIZE LIBSPDM_MAX_MESSAGE_BUFFER_SIZE
#endif
/* Required sender/receive buffer in device io.
* NOTE: This is transport specific. Below configuration is just an example.
* +-------+--------+---------------------------+------+--+------+---+--------+-----+
* | TYPE |TransHdr| EncryptionHeader |AppHdr| |Random|MAC|AlignPad|FINAL|
* | | |SessionId|SeqNum|Len|AppLen| | | | | | |
* +-------+--------+---------------------------+------+ +------+---+--------+-----+
* | MCTP | 1 | 4 | 2 | 2 | 2 | 1 | | 32 | 12| 0 | 56 |
* |PCI_DOE| 8 | 4 | 0 | 2 | 2 | 0 | | 0 | 12| 3 | 31 |
* +-------+--------+---------------------------+------+--+------+---+--------+-----+
*/
#ifndef LIBSPDM_TRANSPORT_ADDITIONAL_SIZE
#define LIBSPDM_TRANSPORT_ADDITIONAL_SIZE 64
#endif
#ifndef LIBSPDM_SENDER_RECEIVE_BUFFER_SIZE
#define LIBSPDM_SENDER_RECEIVE_BUFFER_SIZE (LIBSPDM_DATA_TRANSFER_SIZE + \
LIBSPDM_TRANSPORT_ADDITIONAL_SIZE)
#endif
/* Required scratch buffer size for libspdm internal usage.
* It may be used to hold the encrypted/decrypted message and/or last sent/received message.
* It may be used to hold the large request/response and intermediate send/receive buffer
* in case of chunking.
*
* If chunking is not supported, it may be just LIBSPDM_SENDER_RECEIVE_BUFFER_SIZE.
* If chunking is supported, it should be at least below.
*
* +---------------+--------------+--------------------------+------------------------------+
* |SECURE_MESSAGE |LARGE_MESSAGE | SENDER_RECEIVER | LARGE_SENDER_RECEIVER |
* +---------------+--------------+--------------------------+------------------------------+
* |<-Secure msg ->|<-Large msg ->|<-Snd/Rcv buf for chunk ->|<-Snd/Rcv buf for large msg ->|
*
* The value is NOT configurable.
* The value MAY be changed in different libspdm version.
* It is exposed here, just in case the libspdm consumer wants to configure the setting at build time.
*/
#if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
/* first section */
#define LIBSPDM_SCRATCH_BUFFER_SECURE_MESSAGE_OFFSET 0
#define LIBSPDM_SCRATCH_BUFFER_SECURE_MESSAGE_CAPACITY (LIBSPDM_MAX_SPDM_MSG_SIZE)
/* second section */
#define LIBSPDM_SCRATCH_BUFFER_LARGE_MESSAGE_OFFSET (LIBSPDM_SCRATCH_BUFFER_SECURE_MESSAGE_CAPACITY)
#define LIBSPDM_SCRATCH_BUFFER_LARGE_MESSAGE_CAPACITY (LIBSPDM_MAX_SPDM_MSG_SIZE)
/* third section */
#define LIBSPDM_SCRATCH_BUFFER_SENDER_RECEIVER_OFFSET \
(LIBSPDM_SCRATCH_BUFFER_SECURE_MESSAGE_CAPACITY + \
LIBSPDM_SCRATCH_BUFFER_LARGE_MESSAGE_CAPACITY)
#define LIBSPDM_SCRATCH_BUFFER_SENDER_RECEIVER_CAPACITY (LIBSPDM_MAX_SPDM_MSG_SIZE)
/* fourth section */
#define LIBSPDM_SCRATCH_BUFFER_LARGE_SENDER_RECEIVER_OFFSET \
(LIBSPDM_SCRATCH_BUFFER_SECURE_MESSAGE_CAPACITY + \
LIBSPDM_SCRATCH_BUFFER_LARGE_MESSAGE_CAPACITY + \
LIBSPDM_SCRATCH_BUFFER_SENDER_RECEIVER_CAPACITY)
#define LIBSPDM_SCRATCH_BUFFER_LARGE_SENDER_RECEIVER_CAPACITY (LIBSPDM_MAX_SPDM_MSG_SIZE)
#define LIBSPDM_SCRATCH_BUFFER_SIZE (LIBSPDM_SCRATCH_BUFFER_SECURE_MESSAGE_CAPACITY + \
LIBSPDM_SCRATCH_BUFFER_LARGE_MESSAGE_CAPACITY + \
LIBSPDM_SCRATCH_BUFFER_SENDER_RECEIVER_CAPACITY + \
LIBSPDM_SCRATCH_BUFFER_LARGE_SENDER_RECEIVER_CAPACITY \
)
#else
#define LIBSPDM_SCRATCH_BUFFER_SIZE (LIBSPDM_SENDER_RECEIVE_BUFFER_SIZE)
#endif
/* Enable message logging.
* See https://github.com/DMTF/libspdm/blob/main/doc/user_guide.md#message-logging
* for more information */
#ifndef LIBSPDM_ENABLE_MSG_LOG
#define LIBSPDM_ENABLE_MSG_LOG 1
#endif
/* Enable macro checking during compilation. */
#ifndef LIBSPDM_CHECK_MACRO
#define LIBSPDM_CHECK_MACRO 0
#endif
#endif /* SPDM_LIB_CONFIG_H */

View File

@@ -0,0 +1,470 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "internal_crypt_lib.h"
#include "nvspdm_cryptlib_extensions.h"
#ifdef USE_LKCA
#define BUFFER_SIZE (2 * 1024 * 1024)
#define AUTH_TAG_SIZE 16
struct lkca_aead_ctx
{
struct crypto_aead *aead;
struct aead_request *req;
char *a_data_buffer;
char *in_buffer;
char *out_buffer;
char tag[AUTH_TAG_SIZE];
};
#endif
int libspdm_aead_prealloc(void **context, char const *alg)
{
#ifndef USE_LKCA
return -ENODEV;
#else
struct lkca_aead_ctx *ctx;
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
if (ctx == NULL) {
return -ENOMEM;
}
memset(ctx, 0, sizeof(*ctx));
ctx->aead = crypto_alloc_aead(alg, CRYPTO_ALG_TYPE_AEAD, 0);
if (IS_ERR(ctx->aead)) {
pr_notice("could not allocate AEAD algorithm\n");
kfree(ctx);
return -ENODEV;
}
ctx->req = aead_request_alloc(ctx->aead, GFP_KERNEL);
if (ctx->req == NULL) {
pr_info("could not allocate skcipher request\n");
crypto_free_aead(ctx->aead);
kfree(ctx);
return -ENOMEM;
}
ctx->a_data_buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
if (ctx->a_data_buffer == NULL) {
aead_request_free(ctx->req);
crypto_free_aead(ctx->aead);
kfree(ctx);
return -ENOMEM;
}
ctx->in_buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
if (ctx->in_buffer == NULL) {
kfree(ctx->a_data_buffer);
aead_request_free(ctx->req);
crypto_free_aead(ctx->aead);
kfree(ctx);
return -ENOMEM;
}
ctx->out_buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
if (ctx->out_buffer == NULL) {
kfree(ctx->a_data_buffer);
kfree(ctx->in_buffer);
aead_request_free(ctx->req);
crypto_free_aead(ctx->aead);
kfree(ctx);
return -ENOMEM;
}
*context = ctx;
return 0;
#endif
}
void libspdm_aead_free(void *context)
{
#ifdef USE_LKCA
struct lkca_aead_ctx *ctx = context;
crypto_free_aead(ctx->aead);
aead_request_free(ctx->req);
kfree(ctx->a_data_buffer);
kfree(ctx->in_buffer);
kfree(ctx->out_buffer);
kfree(ctx);
#endif
}
#define SG_AEAD_AAD 0
#define SG_AEAD_TEXT 1
#define SG_AEAD_SIG 2
// Number of fields in AEAD scatterlist
#define SG_AEAD_LEN 3
#ifdef USE_LKCA
// This function doesn't do any allocs, it uses temp buffers instead
static int lkca_aead_internal(struct crypto_aead *aead,
struct aead_request *req,
const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
struct scatterlist sg_in[],
struct scatterlist sg_out[],
size_t a_data_size,
size_t data_in_size,
size_t *data_out_size,
size_t tag_size,
bool enc)
{
DECLARE_CRYPTO_WAIT(wait);
int rc = 0;
if (crypto_aead_setkey(aead, key, key_size)) {
pr_info("key could not be set\n");
return -EINVAL;
}
if (crypto_aead_ivsize(aead) != iv_size) {
pr_info("iv could not be set\n");
return -EINVAL;
}
aead_request_set_ad(req, a_data_size);
aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done, &wait);
if (enc) {
aead_request_set_crypt(req, sg_in, sg_out, data_in_size, (u8 *) iv);
rc = crypto_wait_req(crypto_aead_encrypt(req), &wait);
} else {
aead_request_set_crypt(req, sg_in, sg_out, data_in_size + tag_size, (u8 *) iv);
rc = crypto_wait_req(crypto_aead_decrypt(req), &wait);
}
if (rc != 0) {
pr_info("Encryption FAILED\n");
}
*data_out_size = data_in_size;
return rc;
}
#endif
int libspdm_aead_prealloced(void *context,
const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
uint8_t *tag, size_t tag_size,
uint8_t *data_out, size_t *data_out_size,
bool enc)
{
#ifndef USE_LKCA
return -ENODEV;
#else
int rc = 0;
struct scatterlist sg_in[SG_AEAD_LEN];
struct scatterlist sg_out[SG_AEAD_LEN];
struct lkca_aead_ctx *ctx = context;
sg_init_table(sg_in, SG_AEAD_LEN);
sg_init_table(sg_out, SG_AEAD_LEN);
if (!virt_addr_valid(a_data)) {
if (a_data_size > BUFFER_SIZE) {
return -ENOMEM;
}
sg_set_buf(&sg_in[SG_AEAD_AAD], ctx->a_data_buffer, a_data_size);
sg_set_buf(&sg_out[SG_AEAD_AAD], ctx->a_data_buffer, a_data_size);
memcpy(ctx->a_data_buffer, a_data, a_data_size);
} else {
sg_set_buf(&sg_in[SG_AEAD_AAD], a_data, a_data_size);
sg_set_buf(&sg_out[SG_AEAD_AAD], a_data, a_data_size);
}
if (!virt_addr_valid(data_in)) {
if (data_in_size > BUFFER_SIZE) {
return -ENOMEM;
}
sg_set_buf(&sg_in[SG_AEAD_TEXT], ctx->in_buffer, data_in_size);
memcpy(ctx->in_buffer, data_in, data_in_size);
} else {
sg_set_buf(&sg_in[SG_AEAD_TEXT], data_in, data_in_size);
}
if (!virt_addr_valid(data_out)) {
if (data_in_size > BUFFER_SIZE) {
return -ENOMEM;
}
sg_set_buf(&sg_out[SG_AEAD_TEXT], ctx->out_buffer, data_in_size);
} else {
sg_set_buf(&sg_out[SG_AEAD_TEXT], data_out, data_in_size);
}
// Tag is small enough that memcpy is cheaper than checking if page is virtual
if(tag_size > AUTH_TAG_SIZE) {
return -ENOMEM;
}
sg_set_buf(&sg_in[SG_AEAD_SIG], ctx->tag, tag_size);
sg_set_buf(&sg_out[SG_AEAD_SIG], ctx->tag, tag_size);
if(!enc)
memcpy(ctx->tag, tag, tag_size);
rc = lkca_aead_internal(ctx->aead, ctx->req, key, key_size, iv, iv_size,
sg_in, sg_out, a_data_size, data_in_size,
data_out_size, tag_size, enc);
if (enc) {
memcpy(tag, ctx->tag, tag_size);
}
if (!virt_addr_valid(data_out)) {
memcpy(data_out, ctx->out_buffer, data_in_size);
}
return rc;
#endif
}
int libspdm_aead(const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
const uint8_t *tag, size_t tag_size,
uint8_t *data_out, size_t *data_out_size,
bool enc, char const *alg)
{
#ifndef USE_LKCA
return -ENODEV;
#else
struct crypto_aead *aead = NULL;
struct aead_request *req = NULL;
struct scatterlist sg_in[SG_AEAD_LEN];
struct scatterlist sg_out[SG_AEAD_LEN];
uint8_t *a_data_shadow = NULL;
uint8_t *data_in_shadow = NULL;
uint8_t *data_out_shadow = NULL;
uint8_t *tag_shadow = NULL;
int rc = 0;
aead = crypto_alloc_aead(alg, CRYPTO_ALG_TYPE_AEAD, 0);
if (IS_ERR(aead)) {
pr_notice("could not allocate AEAD algorithm\n");
return -ENODEV;
}
req = aead_request_alloc(aead, GFP_KERNEL);
if (req == NULL) {
pr_info("could not allocate skcipher request\n");
rc = -ENOMEM;
goto out;
}
sg_init_table(sg_in, SG_AEAD_LEN);
sg_init_table(sg_out, SG_AEAD_LEN);
if (!virt_addr_valid(a_data)) {
a_data_shadow = kmalloc(a_data_size, GFP_KERNEL);
if (a_data_shadow == NULL) {
rc = -ENOMEM;
goto out;
}
sg_set_buf(&sg_in[SG_AEAD_AAD], a_data_shadow, a_data_size);
sg_set_buf(&sg_out[SG_AEAD_AAD], a_data_shadow, a_data_size);
memcpy(a_data_shadow, a_data, a_data_size);
} else {
sg_set_buf(&sg_in[SG_AEAD_AAD], a_data, a_data_size);
sg_set_buf(&sg_out[SG_AEAD_AAD], a_data, a_data_size);
}
if (!virt_addr_valid(data_in)) {
data_in_shadow = kmalloc(data_in_size, GFP_KERNEL);
if (data_in_shadow == NULL) {
rc = -ENOMEM;
goto out;
}
sg_set_buf(&sg_in[SG_AEAD_TEXT], data_in_shadow, data_in_size);
memcpy(data_in_shadow, data_in, data_in_size);
} else {
sg_set_buf(&sg_in[SG_AEAD_TEXT], data_in, data_in_size);
}
if (!virt_addr_valid(data_out)) {
data_out_shadow = kmalloc(data_in_size, GFP_KERNEL);
if (data_out_shadow == NULL) {
rc = -ENOMEM;
goto out;
}
sg_set_buf(&sg_out[SG_AEAD_TEXT], data_out_shadow, data_in_size);
} else {
sg_set_buf(&sg_out[SG_AEAD_TEXT], data_out, data_in_size);
}
if (!virt_addr_valid(tag)) {
tag_shadow = kmalloc(tag_size, GFP_KERNEL);
if (tag_shadow == NULL) {
rc = -ENOMEM;
goto out;
}
sg_set_buf(&sg_in[SG_AEAD_SIG], tag_shadow, tag_size);
sg_set_buf(&sg_out[SG_AEAD_SIG], tag_shadow, tag_size);
if(!enc)
memcpy(tag_shadow, tag, tag_size);
} else {
sg_set_buf(&sg_in[SG_AEAD_SIG], tag, tag_size);
sg_set_buf(&sg_out[SG_AEAD_SIG], tag, tag_size);
}
rc = lkca_aead_internal(aead, req, key, key_size, iv, iv_size,
sg_in, sg_out, a_data_size, data_in_size,
data_out_size, tag_size, enc);
if (enc && (tag_shadow != NULL))
memcpy((uint8_t *) tag, tag_shadow, tag_size);
if (data_out_shadow != NULL)
memcpy(data_out, data_out_shadow, data_in_size);
out:
if (a_data_shadow != NULL)
kfree(a_data_shadow);
if (data_in_shadow != NULL)
kfree(data_in_shadow);
if (data_out != NULL)
kfree(data_out_shadow);
if (tag != NULL)
kfree(tag_shadow);
if (aead != NULL)
crypto_free_aead(aead);
if (req != NULL)
aead_request_free(req);
return rc;
#endif
}
// Wrapper to make look like libspdm
bool libspdm_aead_gcm_prealloc(void **context)
{
return libspdm_aead_prealloc(context, "gcm(aes)") == 0;
}
bool libspdm_aead_aes_gcm_encrypt_prealloc(void *context,
const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
uint8_t *tag_out, size_t tag_size,
uint8_t *data_out, size_t *data_out_size)
{
int32_t ret;
if (data_in_size > INT_MAX) {
return false;
}
if (a_data_size > INT_MAX) {
return false;
}
if (iv_size != 12) {
return false;
}
switch (key_size) {
case 16:
case 24:
case 32:
break;
default:
return false;
}
if ((tag_size < 12) || (tag_size > 16)) {
return false;
}
if (data_out_size != NULL) {
if ((*data_out_size > INT_MAX) ||
(*data_out_size < data_in_size)) {
return false;
}
}
ret = libspdm_aead_prealloced(context, key, key_size, iv, iv_size,
a_data, a_data_size, data_in, data_in_size,
tag_out, tag_size, data_out, data_out_size, true);
*data_out_size = data_in_size;
return ret == 0;
}
bool libspdm_aead_aes_gcm_decrypt_prealloc(void *context,
const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
const uint8_t *tag, size_t tag_size,
uint8_t *data_out, size_t *data_out_size)
{
int ret;
if (data_in_size > INT_MAX) {
return false;
}
if (a_data_size > INT_MAX) {
return false;
}
if (iv_size != 12) {
return false;
}
switch (key_size) {
case 16:
case 24:
case 32:
break;
default:
return false;
}
if ((tag_size < 12) || (tag_size > 16)) {
return false;
}
if (data_out_size != NULL) {
if ((*data_out_size > INT_MAX) ||
(*data_out_size < data_in_size)) {
return false;
}
}
ret = libspdm_aead_prealloced(context, key, key_size, iv, iv_size,
a_data, a_data_size, data_in, data_in_size,
(uint8_t *) tag, tag_size, data_out, data_out_size, false);
*data_out_size = data_in_size;
return ret == 0;
}

View File

@@ -0,0 +1,117 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Prototypes and checks taken from DMTF: Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
*/
#include "internal_crypt_lib.h"
bool libspdm_aead_aes_gcm_encrypt(const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
uint8_t *tag_out, size_t tag_size,
uint8_t *data_out, size_t *data_out_size)
{
int32_t ret;
if (data_in_size > INT_MAX) {
return false;
}
if (a_data_size > INT_MAX) {
return false;
}
if (iv_size != 12) {
return false;
}
switch (key_size) {
case 16:
case 24:
case 32:
break;
default:
return false;
}
if ((tag_size < 12) || (tag_size > 16)) {
return false;
}
if (data_out_size != NULL) {
if ((*data_out_size > INT_MAX) ||
(*data_out_size < data_in_size)) {
return false;
}
}
ret = libspdm_aead(key, key_size, iv, iv_size, a_data, a_data_size,
data_in, data_in_size, tag_out, tag_size,
data_out, data_out_size, true, "gcm(aes)");
*data_out_size = data_in_size;
return ret == 0;
}
bool libspdm_aead_aes_gcm_decrypt(const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
const uint8_t *tag, size_t tag_size,
uint8_t *data_out, size_t *data_out_size)
{
int ret;
if (data_in_size > INT_MAX) {
return false;
}
if (a_data_size > INT_MAX) {
return false;
}
if (iv_size != 12) {
return false;
}
switch (key_size) {
case 16:
case 24:
case 32:
break;
default:
return false;
}
if ((tag_size < 12) || (tag_size > 16)) {
return false;
}
if (data_out_size != NULL) {
if ((*data_out_size > INT_MAX) ||
(*data_out_size < data_in_size)) {
return false;
}
}
ret = libspdm_aead(key, key_size, iv, iv_size, a_data, a_data_size,
data_in, data_in_size, tag, tag_size,
data_out, data_out_size, false, "gcm(aes)");
*data_out_size = data_in_size;
return ret == 0;
}

View File

@@ -0,0 +1,172 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Comments, prototypes and checks taken from DMTF: Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
*/
#include "internal_crypt_lib.h"
static bool lkca_ecdsa_sign(void *ec_context,
const uint8_t *message_hash, size_t hash_size,
uint8_t *signature, size_t *sig_size)
{
return false;
}
bool libspdm_ec_set_pub_key(void *ec_context, const uint8_t *public_key,
size_t public_key_size)
{
if (ec_context == NULL || public_key == NULL) {
return false;
}
return lkca_ec_set_pub_key(ec_context, public_key, public_key_size);
}
bool libspdm_ec_get_pub_key(void *ec_context, uint8_t *public_key,
size_t *public_key_size)
{
if (ec_context == NULL || public_key_size == NULL) {
return false;
}
if (public_key == NULL && *public_key_size != 0) {
return false;
}
return lkca_ec_get_pub_key(ec_context, public_key, public_key_size);
}
bool libspdm_ec_check_key(const void *ec_context)
{
/* TBD*/
return true;
}
bool libspdm_ec_generate_key(void *ec_context, uint8_t *public_data,
size_t *public_size)
{
if (ec_context == NULL || public_size == NULL) {
return false;
}
if (public_data == NULL && *public_size != 0) {
return false;
}
return lkca_ec_generate_key(ec_context, public_data, public_size);
}
bool libspdm_ec_compute_key(void *ec_context, const uint8_t *peer_public,
size_t peer_public_size, uint8_t *key,
size_t *key_size)
{
if (ec_context == NULL || peer_public == NULL || key_size == NULL ||
key == NULL) {
return false;
}
if (peer_public_size > INT_MAX) {
return false;
}
return lkca_ec_compute_key(ec_context, peer_public, peer_public_size, key,
key_size);
}
bool libspdm_ecdsa_sign(void *ec_context, size_t hash_nid,
const uint8_t *message_hash, size_t hash_size,
uint8_t *signature, size_t *sig_size)
{
if (ec_context == NULL || message_hash == NULL) {
return false;
}
if (signature == NULL) {
return false;
}
switch (hash_nid) {
case LIBSPDM_CRYPTO_NID_SHA256:
if (hash_size != LIBSPDM_SHA256_DIGEST_SIZE) {
return false;
}
break;
case LIBSPDM_CRYPTO_NID_SHA384:
if (hash_size != LIBSPDM_SHA384_DIGEST_SIZE) {
return false;
}
break;
case LIBSPDM_CRYPTO_NID_SHA512:
if (hash_size != LIBSPDM_SHA512_DIGEST_SIZE) {
return false;
}
break;
default:
return false;
}
return lkca_ecdsa_sign(ec_context, message_hash, hash_size, signature, sig_size);
}
bool libspdm_ecdsa_verify(void *ec_context, size_t hash_nid,
const uint8_t *message_hash, size_t hash_size,
const uint8_t *signature, size_t sig_size)
{
if (ec_context == NULL || message_hash == NULL || signature == NULL) {
return false;
}
if (sig_size > INT_MAX || sig_size == 0) {
return false;
}
switch (hash_nid) {
case LIBSPDM_CRYPTO_NID_SHA256:
if (hash_size != LIBSPDM_SHA256_DIGEST_SIZE) {
return false;
}
break;
case LIBSPDM_CRYPTO_NID_SHA384:
if (hash_size != LIBSPDM_SHA384_DIGEST_SIZE) {
return false;
}
break;
case LIBSPDM_CRYPTO_NID_SHA512:
if (hash_size != LIBSPDM_SHA512_DIGEST_SIZE) {
return false;
}
break;
default:
return false;
}
return lkca_ecdsa_verify(ec_context, hash_nid, message_hash, hash_size,
signature, sig_size);
}

View File

@@ -0,0 +1,326 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "internal_crypt_lib.h"
#ifdef USE_LKCA
#include <linux/module.h>
MODULE_SOFTDEP("pre: ecdh_generic,ecdsa_generic");
#include <crypto/akcipher.h>
#include <crypto/ecdh.h>
#include <crypto/internal/ecc.h>
struct ecc_ctx {
unsigned int curve_id;
u64 priv_key[ECC_MAX_DIGITS]; // In big endian
struct {
// ecdsa wants byte preceding pub_key to be set to '4'
u64 pub_key_prefix;
u64 pub_key[2 * ECC_MAX_DIGITS];
};
bool pub_key_set;
bool priv_key_set;
char const *name;
int size;
};
#endif
void *libspdm_ec_new_by_nid(size_t nid)
{
#ifndef USE_LKCA
return NULL;
#else
struct ecc_ctx *ctx;
if ((nid != LIBSPDM_CRYPTO_NID_SECP256R1) && (nid != LIBSPDM_CRYPTO_NID_SECP384R1)){
return NULL;
}
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
return NULL;
}
if (nid == LIBSPDM_CRYPTO_NID_SECP256R1) {
ctx->curve_id = ECC_CURVE_NIST_P256;
ctx->size = 64;
ctx->name = "ecdsa-nist-p256";
} else {
ctx->curve_id = ECC_CURVE_NIST_P384;
ctx->size = 96;
ctx->name = "ecdsa-nist-p384";
}
ctx->pub_key_set = false;
ctx->priv_key_set = false;
return ctx;
#endif
}
void libspdm_ec_free(void *ec_context)
{
#ifdef USE_LKCA
kfree(ec_context);
#endif
}
bool lkca_ecdsa_set_priv_key(void *context, uint8_t *key, size_t key_size)
{
#ifndef USE_LKCA
return false;
#else
struct ecc_ctx *ctx = context;
unsigned int ndigits = ctx->size / 16;
if (key_size != (ctx->size / 2)) {
return false;
}
memcpy(ctx->priv_key, key, key_size);
// XXX: if this fails, do we want to retry generating new key?
if(ecc_make_pub_key(ctx->curve_id, ndigits, ctx->priv_key, ctx->pub_key)) {
return false;
}
ctx->pub_key_set = true;
ctx->priv_key_set = true;
return true;
#endif
}
bool lkca_ec_set_pub_key(void *ec_context, const uint8_t *public_key,
size_t public_key_size)
{
#ifndef USE_LKCA
return false;
#else
struct ecc_ctx *ctx = ec_context;
struct ecc_point pub_key;
unsigned int ndigits;
if (public_key_size != ctx->size) {
return false;
}
// We can reuse pub_key for now
ndigits = ctx->size / 16;
pub_key = ECC_POINT_INIT(ctx->pub_key, ctx->pub_key + ndigits, ndigits);
ecc_swap_digits(public_key, ctx->pub_key, ndigits);
ecc_swap_digits(((u64 *)public_key) + ndigits, ctx->pub_key + ndigits, ndigits);
if(ecc_is_pubkey_valid_full(ecc_get_curve(ctx->curve_id), &pub_key)) {
return false;
}
memcpy(ctx->pub_key, public_key, public_key_size);
ctx->pub_key_set = true;
return true;
#endif
}
bool lkca_ec_get_pub_key(void *ec_context, uint8_t *public_key,
size_t *public_key_size)
{
#ifndef USE_LKCA
return false;
#else
struct ecc_ctx *ctx = ec_context;
if (*public_key_size < ctx->size) {
*public_key_size = ctx->size;
return false;
}
*public_key_size = ctx->size;
memcpy(public_key, ctx->pub_key, ctx->size);
return true;
#endif
}
bool lkca_ec_generate_key(void *ec_context, uint8_t *public_data,
size_t *public_size)
{
#ifndef USE_LKCA
return false;
#else
struct ecc_ctx *ctx = ec_context;
unsigned int ndigits = ctx->size / 16;
if(ecc_gen_privkey(ctx->curve_id, ndigits, ctx->priv_key)) {
return false;
}
// XXX: if this fails, do we want to retry generating new key?
if(ecc_make_pub_key(ctx->curve_id, ndigits, ctx->priv_key, ctx->pub_key)) {
return false;
}
memcpy(public_data, ctx->pub_key, ctx->size);
*public_size = ctx->size;
ctx->priv_key_set = true;
ctx->pub_key_set = true;
return true;
#endif
}
bool lkca_ec_compute_key(void *ec_context, const uint8_t *peer_public,
size_t peer_public_size, uint8_t *key,
size_t *key_size)
{
#ifndef USE_LKCA
return false;
#else
struct ecc_ctx *ctx = ec_context;
if (peer_public_size != ctx->size) {
return false;
}
if (!ctx->priv_key_set) {
return false;
}
if ((ctx->size / 2) > *key_size) {
return false;
}
if (crypto_ecdh_shared_secret(ctx->curve_id, ctx->size / 16,
(const u64 *) ctx->priv_key,
(const u64 *) peer_public,
(u64 *) key)) {
return false;
}
*key_size = ctx->size / 2;
return true;
#endif
}
bool lkca_ecdsa_verify(void *ec_context, size_t hash_nid,
const uint8_t *message_hash, size_t hash_size,
const uint8_t *signature, size_t sig_size)
{
#ifndef USE_LKCA
return false;
#else
struct ecc_ctx *ctx = ec_context;
// Roundabout way
u64 ber_max_len = 3 + 2 * (4 + (ECC_MAX_BYTES));
u64 ber_len = 0;
u8 *ber = NULL;
u8 *pub_key;
struct akcipher_request *req = NULL;
struct crypto_akcipher *tfm = NULL;
struct scatterlist sg;
DECLARE_CRYPTO_WAIT(wait);
int err;
if (sig_size != ctx->size) {
return false;
}
if(ctx->pub_key_set == false){
return false;
}
tfm = crypto_alloc_akcipher(ctx->name, CRYPTO_ALG_TYPE_AKCIPHER, 0);
if (IS_ERR(tfm)) {
pr_info("ALLOC FAILED\n");
return false;
}
pub_key = (u8 *) ctx->pub_key;
pub_key--; // Go back into byte of pub_key_prefix
*pub_key = 4; // And set it to 4 to placate kernel
if ((err = crypto_akcipher_set_pub_key(tfm, pub_key, ctx->size + 1)) != 0) {
pr_info("SET PUB KEY FAILED: %d\n", -err);
goto failTfm;
}
req = akcipher_request_alloc(tfm, GFP_KERNEL);
if (IS_ERR(req)) {
pr_info("REQUEST ALLOC FAILED\n");
goto failTfm;
}
// We concatenate signature and hash and ship it to kernel
ber = kmalloc(ber_max_len + hash_size, GFP_KERNEL);
if (ber == NULL) {
goto failReq;
}
// XXX: NOTE THIS WILL WORK ONLY FOR 256 AND 384 bits. For larger keys
// length field will be longer than 1 byte and I haven't taken care of that!
// Signature
ber[ber_len++] = 0x30;
ber[ber_len++] = 2 * (2 + ctx->size / 2);
ber[ber_len++] = 0x02;
if (signature[0] > 127) {
ber[ber_len++] = ctx->size / 2 + 1;
ber[1]++;
ber[ber_len++] = 0;
} else {
ber[ber_len++] = ctx->size / 2;
}
memcpy(ber + ber_len, signature, sig_size / 2);
ber_len += sig_size / 2;
ber[ber_len++] = 0x02;
if (signature[sig_size / 2] > 127) {
ber[ber_len++] = ctx->size / 2 + 1;
ber[1]++;
ber[ber_len++] = 0;
} else {
ber[ber_len++] = ctx->size / 2;
}
memcpy(ber + ber_len, signature + sig_size / 2, sig_size / 2);
ber_len += sig_size / 2;
// Just append hash, for scatterlists it can't be on stack anyway
memcpy(ber + ber_len, message_hash, hash_size);
sg_init_one(&sg, ber, ber_len + hash_size);
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done, &wait);
akcipher_request_set_crypt(req, &sg, NULL, ber_len, hash_size);
err = crypto_wait_req(crypto_akcipher_verify(req), &wait);
if (err != 0){
pr_info("Verify FAILED %d\n", -err);
}
kfree(ber);
failReq:
akcipher_request_free(req);
failTfm:
crypto_free_akcipher(tfm);
return err == 0;
#endif
}

View File

@@ -0,0 +1,158 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "internal_crypt_lib.h"
// RFC 5869 has some very non-intuitive points, reading it is advised
static bool lkca_hkdf_expand_only(struct crypto_shash *alg,
const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size)
{
#ifndef USE_LKCA
return false;
#else
int ret;
int i;
uint8_t ctr = 1;
uint8_t tmp[HASH_MAX_DIGESTSIZE];
SHASH_DESC_ON_STACK(desc, alg);
desc->tfm = alg;
ret = crypto_shash_setkey(desc->tfm, prk, prk_size);
if (ret != 0) {
pr_info("key size mismatch %ld\n", prk_size);
return false;
}
for (i = 0, ctr = 1; i < out_size; i += prk_size, ctr++) {
ret = crypto_shash_init(desc);
if (ret) {
return false;
}
if (i != 0) {
ret = crypto_shash_update(desc, out + i - prk_size, prk_size);
if (ret) {
return false;
}
}
if (info_size > 0) {
ret = crypto_shash_update(desc, info, info_size);
if (ret) {
return false;
}
}
ret = crypto_shash_update(desc, &ctr, 1);
if (ret)
return false;
if ((out_size - i) < prk_size) {
ret = crypto_shash_final(desc, tmp);
if (ret) {
return false;
}
memcpy(out + i, tmp, out_size - i);
memzero_explicit(tmp, sizeof(tmp));
} else {
ret = crypto_shash_final(desc, out + i);
if (ret) {
return false;
}
}
}
return true;
#endif
}
bool lkca_hkdf_extract_and_expand(const char *alg_name,
const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size)
{
#ifndef USE_LKCA
return false;
#else
int ret = 0;
struct crypto_shash *alg;
uint8_t prk[HASH_MAX_DIGESTSIZE];
if (key == NULL || salt == NULL || info == NULL || out == NULL ||
key_size > sizeof(prk) || salt_size > INT_MAX || info_size > INT_MAX ||
out_size > (sizeof(prk) * 255)) {
return false;
}
alg = crypto_alloc_shash(alg_name, 0, 0);
if (IS_ERR(alg)) {
return false;
}
ret = crypto_shash_setkey(alg, salt, salt_size);
if (ret != 0) {
goto out;
}
ret = crypto_shash_tfm_digest(alg, key, key_size, prk);
if (ret != 0) {
goto out;
}
ret = !lkca_hkdf_expand_only(alg, prk, crypto_shash_digestsize(alg), info, info_size, out, out_size);
out:
crypto_free_shash(alg);
return ret == 0;
#endif
}
bool lkca_hkdf_expand(const char *alg_name,
const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size)
{
#ifndef USE_LKCA
return false;
#else
bool ret = false;
struct crypto_shash *alg;
if (prk == NULL || info == NULL || out == NULL || prk_size > (512 / 8) ||
info_size > INT_MAX || (out_size > (prk_size * 255))) {
return false;
}
alg = crypto_alloc_shash(alg_name, 0, 0);
if (IS_ERR(alg)) {
return false;
}
ret = lkca_hkdf_expand_only(alg, prk, prk_size, info, info_size, out, out_size);
crypto_free_shash(alg);
return ret;
#endif
}

View File

@@ -0,0 +1,111 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Prototypes and checks taken from DMTF: Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
*/
#include "internal_crypt_lib.h"
bool libspdm_hkdf_sha256_extract_and_expand(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size)
{
return lkca_hkdf_extract_and_expand("hmac(sha256)", key, key_size,
salt, salt_size, info, info_size,
out, out_size);
}
bool libspdm_hkdf_sha256_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size)
{
if (prk_out_size != (256 / 8))
return false;
return libspdm_hmac_sha256_all(key, key_size, salt, salt_size, prk_out);
}
bool libspdm_hkdf_sha256_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size)
{
return lkca_hkdf_expand("hmac(sha256)", prk, prk_size, info, info_size,
out, out_size);
}
bool libspdm_hkdf_sha384_extract_and_expand(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size)
{
return lkca_hkdf_extract_and_expand("hmac(sha384)", key, key_size,
salt, salt_size, info, info_size,
out, out_size);
}
bool libspdm_hkdf_sha384_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size)
{
if (prk_out_size != (384 / 8))
return false;
return libspdm_hmac_sha384_all(key, key_size, salt, salt_size, prk_out);
}
bool libspdm_hkdf_sha384_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size)
{
return lkca_hkdf_expand("hmac(sha384)", prk, prk_size, info, info_size,
out, out_size);
}
bool libspdm_hkdf_sha512_extract_and_expand(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size)
{
return lkca_hkdf_extract_and_expand("hmac(sha512)", key, key_size,
salt, salt_size, info, info_size, out,
out_size);
}
bool libspdm_hkdf_sha512_extract(const uint8_t *key, size_t key_size,
const uint8_t *salt, size_t salt_size,
uint8_t *prk_out, size_t prk_out_size)
{
if (prk_out_size != (512 / 8))
return false;
return libspdm_hmac_sha512_all(key, key_size, salt, salt_size, prk_out);
}
bool libspdm_hkdf_sha512_expand(const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size,
uint8_t *out, size_t out_size)
{
return lkca_hkdf_expand("hmac(sha512)", prk, prk_size, info, info_size,
out, out_size);
}

View File

@@ -0,0 +1,282 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Prototypes and checks taken from DMTF: Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
*/
#include "internal_crypt_lib.h"
void *libspdm_hmac_sha256_new(void)
{
return lkca_hash_new("hmac(sha256)");
}
void libspdm_hmac_sha256_free(void *hmac_sha256_ctx)
{
lkca_hash_free(hmac_sha256_ctx);
}
bool libspdm_hmac_sha256_set_key(void *hmac_sha256_ctx, const uint8_t *key,
size_t key_size)
{
if (hmac_sha256_ctx == NULL)
return false;
return lkca_hmac_set_key(hmac_sha256_ctx, key, key_size);
}
bool libspdm_hmac_sha256_duplicate(const void *hmac_sha256_ctx,
void *new_hmac_sha256_ctx)
{
if (hmac_sha256_ctx == NULL || new_hmac_sha256_ctx == NULL) {
return false;
}
return lkca_hmac_duplicate(new_hmac_sha256_ctx, hmac_sha256_ctx);
}
bool libspdm_hmac_sha256_update(void *hmac_sha256_ctx, const void *data,
size_t data_size)
{
int32_t ret;
if (hmac_sha256_ctx == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
ret = crypto_shash_update(hmac_sha256_ctx, data, data_size);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_hmac_sha256_final(void *hmac_sha256_ctx, uint8_t *hmac_value)
{
int32_t ret;
if (hmac_sha256_ctx == NULL || hmac_value == NULL) {
return false;
}
ret = crypto_shash_final(hmac_sha256_ctx, hmac_value);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_hmac_sha256_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value)
{
if (hmac_value == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
return lkca_hmac_all("hmac(sha256)", key, key_size, data, data_size, hmac_value);
}
void *libspdm_hmac_sha384_new(void)
{
return lkca_hash_new("hmac(sha384)");
}
void libspdm_hmac_sha384_free(void *hmac_sha384_ctx)
{
lkca_hash_free(hmac_sha384_ctx);
}
bool libspdm_hmac_sha384_set_key(void *hmac_sha384_ctx, const uint8_t *key,
size_t key_size)
{
if (hmac_sha384_ctx == NULL)
return false;
return lkca_hmac_set_key(hmac_sha384_ctx, key, key_size);
}
bool libspdm_hmac_sha384_duplicate(const void *hmac_sha384_ctx,
void *new_hmac_sha384_ctx)
{
if (hmac_sha384_ctx == NULL || new_hmac_sha384_ctx == NULL) {
return false;
}
return lkca_hmac_duplicate(new_hmac_sha384_ctx, hmac_sha384_ctx);
}
bool libspdm_hmac_sha384_update(void *hmac_sha384_ctx, const void *data,
size_t data_size)
{
int32_t ret;
if (hmac_sha384_ctx == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
ret = crypto_shash_update(hmac_sha384_ctx, data, data_size);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_hmac_sha384_final(void *hmac_sha384_ctx, uint8_t *hmac_value)
{
int32_t ret;
if (hmac_sha384_ctx == NULL || hmac_value == NULL) {
return false;
}
ret = crypto_shash_final(hmac_sha384_ctx, hmac_value);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_hmac_sha384_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value)
{
if (hmac_value == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
return lkca_hmac_all("hmac(sha384)", key, key_size, data, data_size, hmac_value);
}
void *libspdm_hmac_sha512_new(void)
{
return lkca_hash_new("hmac(sha512)");
}
void libspdm_hmac_sha512_free(void *hmac_sha512_ctx)
{
lkca_hash_free(hmac_sha512_ctx);
}
bool libspdm_hmac_sha512_set_key(void *hmac_sha512_ctx, const uint8_t *key,
size_t key_size)
{
if (hmac_sha512_ctx == NULL)
return false;
return lkca_hmac_set_key(hmac_sha512_ctx, key, key_size);
}
bool libspdm_hmac_sha512_duplicate(const void *hmac_sha512_ctx,
void *new_hmac_sha512_ctx)
{
if (new_hmac_sha512_ctx == NULL || new_hmac_sha512_ctx == NULL) {
return false;
}
return lkca_hmac_duplicate(new_hmac_sha512_ctx, hmac_sha512_ctx);
}
bool libspdm_hmac_sha512_update(void *hmac_sha512_ctx, const void *data,
size_t data_size)
{
int32_t ret;
if (hmac_sha512_ctx == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
ret = crypto_shash_update(hmac_sha512_ctx, data, data_size);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_hmac_sha512_final(void *hmac_sha512_ctx, uint8_t *hmac_value)
{
int32_t ret;
if (hmac_sha512_ctx == NULL || hmac_value == NULL) {
return false;
}
ret = crypto_shash_final(hmac_sha512_ctx, hmac_value);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_hmac_sha512_all(const void *data, size_t data_size,
const uint8_t *key, size_t key_size,
uint8_t *hmac_value)
{
if (hmac_value == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
return lkca_hmac_all("hmac(sha512)", key, key_size, data, data_size, hmac_value);
}

View File

@@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "internal_crypt_lib.h"
// This is non-gpl symbol and not part of LKCA so no need to stub it out
bool libspdm_random_bytes(uint8_t *output, size_t size)
{
get_random_bytes(output, size);
return true;
}
// This is specifically allowed by spdm
bool libspdm_random_seed(const uint8_t *seed, size_t seed_size)
{
return true;
}

View File

@@ -0,0 +1,264 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Comments, prototypes and checks taken from DMTF: Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
*/
#include "internal_crypt_lib.h"
void *libspdm_sha256_new(void)
{
return lkca_hash_new("sha256");
}
void libspdm_sha256_free(void *sha256_ctx)
{
lkca_hash_free(sha256_ctx);
}
bool libspdm_sha256_init(void *sha256_context)
{
return crypto_shash_init(sha256_context) == 0;
}
bool libspdm_sha256_duplicate(const void *sha256_context,
void *new_sha256_context)
{
if (sha256_context == NULL || new_sha256_context == NULL) {
return false;
}
return lkca_hash_duplicate(new_sha256_context, sha256_context);
}
bool libspdm_sha256_update(void *sha256_context, const void *data,
size_t data_size)
{
int32_t ret;
if (sha256_context == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
ret = crypto_shash_update(sha256_context, data, data_size);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_sha256_final(void *sha256_context, uint8_t *hash_value)
{
int32_t ret;
if (sha256_context == NULL || hash_value == NULL) {
return false;
}
ret = crypto_shash_final(sha256_context, hash_value);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_sha256_hash_all(const void *data, size_t data_size,
uint8_t *hash_value)
{
if (hash_value == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
return lkca_hash_all("sha256", data, data_size, hash_value);
}
void *libspdm_sha384_new(void)
{
return lkca_hash_new("sha384");
}
void libspdm_sha384_free(void *sha384_ctx)
{
lkca_hash_free(sha384_ctx);
}
bool libspdm_sha384_init(void *sha384_context)
{
return crypto_shash_init(sha384_context) == 0;
}
bool libspdm_sha384_duplicate(const void *sha384_context,
void *new_sha384_context)
{
if (sha384_context == NULL || new_sha384_context == NULL) {
return false;
}
return lkca_hash_duplicate(new_sha384_context, sha384_context);
}
bool libspdm_sha384_update(void *sha384_context, const void *data,
size_t data_size)
{
int32_t ret;
if (sha384_context == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
ret = crypto_shash_update(sha384_context, data, data_size);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_sha384_final(void *sha384_context, uint8_t *hash_value)
{
int32_t ret;
if (sha384_context == NULL || hash_value == NULL) {
return false;
}
ret = crypto_shash_final(sha384_context, hash_value);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_sha384_hash_all(const void *data, size_t data_size,
uint8_t *hash_value)
{
if (hash_value == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
return lkca_hash_all("sha384", data, data_size, hash_value);
}
void *libspdm_sha512_new(void)
{
return lkca_hash_new("sha512");
}
void libspdm_sha512_free(void *sha512_ctx)
{
lkca_hash_free(sha512_ctx);
}
bool libspdm_sha512_init(void *sha512_context)
{
return crypto_shash_init(sha512_context) == 0;
}
bool libspdm_sha512_duplicate(const void *sha512_context,
void *new_sha512_context)
{
if (sha512_context == NULL || new_sha512_context == NULL) {
return false;
}
return lkca_hash_duplicate(new_sha512_context, sha512_context);
}
bool libspdm_sha512_update(void *sha512_context, const void *data,
size_t data_size)
{
int32_t ret;
if (sha512_context == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
ret = crypto_shash_update(sha512_context, data, data_size);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_sha512_final(void *sha512_context, uint8_t *hash_value)
{
int32_t ret;
if (sha512_context == NULL || hash_value == NULL) {
return false;
}
ret = crypto_shash_final(sha512_context, hash_value);
if (ret != 0) {
return false;
}
return true;
}
bool libspdm_sha512_hash_all(const void *data, size_t data_size,
uint8_t *hash_value)
{
if (hash_value == NULL) {
return false;
}
if (data == NULL && data_size != 0) {
return false;
}
if (data_size > INT_MAX) {
return false;
}
return lkca_hash_all("sha512", data, data_size, hash_value);
}

View File

@@ -0,0 +1,160 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "internal_crypt_lib.h"
void *lkca_hash_new(const char* alg_name)
{
#ifndef USE_LKCA
return false;
#else
//XXX: can we reuse crypto_shash part and just allocate desc
struct crypto_shash *alg;
struct shash_desc *desc;
alg = crypto_alloc_shash(alg_name, 0, 0);
if (IS_ERR(alg)) {
printk (KERN_INFO "Failed to alloc %s\n", alg_name);
return NULL;
}
desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(alg), GFP_KERNEL);
if (desc == NULL){
printk (KERN_INFO "Kernel out of mem\n");
crypto_free_shash(alg);
return NULL;
}
desc->tfm = alg;
return desc;
#endif
}
void lkca_hash_free(struct shash_desc *ctx)
{
#ifndef USE_LKCA
#else
crypto_free_shash(ctx->tfm);
kfree(ctx);
#endif
}
bool lkca_hash_duplicate(struct shash_desc *dst, struct shash_desc const *src)
{
#ifndef USE_LKCA
return false;
#else
SHASH_DESC_ON_STACK(tmp, src);
if (crypto_shash_export((struct shash_desc *) src, tmp)) {
return false;
}
if (crypto_shash_import(dst, tmp)) {
return false;
}
return true;
#endif
}
bool lkca_hmac_duplicate(struct shash_desc *dst, struct shash_desc const *src)
{
#ifndef USE_LKCA
return false;
#else
// in LKCA hmac export doesn't export ipad/opad, so we need to WAR it
struct crypto_shash *src_tfm = src->tfm;
struct crypto_shash *dst_tfm = dst->tfm;
char *src_ipad = crypto_tfm_ctx_aligned(&src_tfm->base);
char *dst_ipad = crypto_tfm_ctx_aligned(&dst_tfm->base);
int ss = crypto_shash_statesize(dst_tfm);
memcpy(dst_ipad, src_ipad, crypto_shash_blocksize(src->tfm));
memcpy(dst_ipad + ss, src_ipad + ss, crypto_shash_blocksize(src->tfm));
crypto_shash_clear_flags(dst->tfm, CRYPTO_TFM_NEED_KEY);
return lkca_hash_duplicate(dst, src);
#endif
}
bool lkca_hash_all(const char* alg_name, const void *data,
size_t data_size, uint8_t *hash_value)
{
#ifndef USE_LKCA
return false;
#else
int ret;
struct crypto_shash *alg;
alg = crypto_alloc_shash(alg_name, 0, 0);
if (IS_ERR(alg)) {
return false;
}
ret = crypto_shash_tfm_digest(alg, data, data_size, hash_value);
crypto_free_shash(alg);
return (ret == 0);
#endif
}
bool lkca_hmac_set_key(struct shash_desc *desc, const uint8_t *key, size_t key_size)
{
#ifndef USE_LKCA
return false;
#else
int ret;
ret = crypto_shash_setkey(desc->tfm, key, key_size);
if (ret == 0) {
ret = crypto_shash_init(desc);
}
return ret == 0;
#endif
}
bool lkca_hmac_all(const char* alg_name, const uint8_t *key, size_t key_size,
const uint8_t *data, size_t data_size, uint8_t *hash_value)
{
#ifndef USE_LKCA
return false;
#else
int ret;
struct crypto_shash *alg;
alg = crypto_alloc_shash(alg_name, 0, 0);
if (IS_ERR(alg)) {
return false;
}
ret = crypto_shash_setkey(alg, key, key_size);
if (ret == 0){
ret = crypto_shash_tfm_digest(alg, data, data_size, hash_value);
}
crypto_free_shash(alg);
return (ret == 0);
#endif
}

View File

@@ -0,0 +1,456 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* libspdm_x509_verify_cert_chain, libspdm_x509_get_cert_from_cert_chain, check
* and prototypes taken from DMTF: Copyright 2021-2022 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
*/
#include "internal_crypt_lib.h"
#ifdef USE_LKCA
#include <crypto/public_key.h>
#include <keys/asymmetric-type.h>
#endif
bool libspdm_x509_construct_certificate(const uint8_t *cert, size_t cert_size,
uint8_t **single_x509_cert)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_construct_certificate_stack(uint8_t **x509_stack, ...)
{
LIBSPDM_ASSERT(false);
return false;
}
void libspdm_x509_free(void *x509_cert)
{
LIBSPDM_ASSERT(false);
}
void libspdm_x509_stack_free(void *x509_stack)
{
LIBSPDM_ASSERT(false);
}
static bool lkca_asn1_get_tag(uint8_t const *ptr, uint8_t const *end,
size_t *length, uint32_t tag)
{
uint64_t max_len = end - ptr;
// Chain must be less than 1 GB
if ((max_len < 2) || (max_len > (1024 * 1024 * 1024))) {
return false;
}
// We only deal with universal and application tags
if (ptr[0] != tag) {
return false;
}
if (ptr[1] < 0x80) {
*length = ptr[1] + 2;
} else if (ptr[1] == 0x81) {
if (max_len < 3) {
return false;
}
*length = ptr[2] + 3;
} else if (ptr[1] == 0x82) {
if (max_len < 4) {
return false;
}
*length = (ptr[2] << 8) + ptr[3] + 4;
} else {
// In theory it could be bigger than 64KB
return false;
}
if (*length > max_len) {
return false;
}
return true;
}
bool libspdm_asn1_get_tag(uint8_t **ptr, const uint8_t *end, size_t *length,
uint32_t tag)
{
return lkca_asn1_get_tag(*ptr, end, length, tag);
}
bool libspdm_x509_get_subject_name(const uint8_t *cert, size_t cert_size,
uint8_t *cert_subject,
size_t *subject_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_common_name(const uint8_t *cert, size_t cert_size,
char *common_name,
size_t *common_name_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool
libspdm_x509_get_organization_name(const uint8_t *cert, size_t cert_size,
char *name_buffer,
size_t *name_buffer_size)
{
LIBSPDM_ASSERT(false);
return false;
}
#if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
bool libspdm_rsa_get_public_key_from_x509(const uint8_t *cert, size_t cert_size,
void **rsa_context)
{
LIBSPDM_ASSERT(false);
return false;
}
#endif /* (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT) */
bool libspdm_ec_get_public_key_from_x509(const uint8_t *cert, size_t cert_size,
void **ec_context)
{
#ifdef USE_LKCA
bool ret = false;
uint32_t key_size = 0;
struct key_preparsed_payload lkca_cert;
struct public_key *pub;
lkca_cert.data = cert;
lkca_cert.datalen = cert_size;
if (cert == NULL) {
return false;
}
if(key_type_asymmetric.preparse(&lkca_cert)) {
return false;
}
pub = lkca_cert.payload.data[asym_crypto];
// -1 is since lkca prepends '4' to public keys...
key_size = pub->keylen - 1;
if (key_size == (2 * 256 / 8)) {
*ec_context = libspdm_ec_new_by_nid(LIBSPDM_CRYPTO_NID_SECP256R1);
} else if (key_size == (2 * 384 / 8)) {
*ec_context = libspdm_ec_new_by_nid(LIBSPDM_CRYPTO_NID_SECP384R1);
} else {
goto err;
}
if (*ec_context == NULL) {
goto err;
}
// Again skip '4' in key to be in line with spdm protocol. We will add it
// back in ecda_verify
if (!lkca_ec_set_pub_key(*ec_context, (char *) pub->key + 1, key_size)) {
libspdm_ec_free(*ec_context);
goto err;
}
ret = true;
err:
key_type_asymmetric.free_preparse(&lkca_cert);
return ret;
#else
return false;
#endif
}
bool libspdm_ecd_get_public_key_from_x509(const uint8_t *cert, size_t cert_size,
void **ecd_context)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_sm2_get_public_key_from_x509(const uint8_t *cert, size_t cert_size,
void **sm2_context)
{
LIBSPDM_ASSERT(false);
return false;
}
static int lkca_x509_verify_cert(const uint8_t *cert, size_t cert_size,
const uint8_t *ca_cert, size_t ca_cert_size)
{
#ifdef USE_LKCA
int ret;
struct key_preparsed_payload lkca_cert;
struct key_preparsed_payload lkca_ca_cert;
lkca_cert.data = cert;
lkca_cert.datalen = cert_size;
lkca_ca_cert.data = ca_cert;
lkca_ca_cert.datalen = ca_cert_size;
ret = key_type_asymmetric.preparse(&lkca_cert);
if (ret) {
return ret;
}
ret = key_type_asymmetric.preparse(&lkca_ca_cert);
if (ret) {
key_type_asymmetric.free_preparse(&lkca_cert);
return ret;
}
ret = public_key_verify_signature(lkca_ca_cert.payload.data[asym_crypto],
lkca_cert.payload.data[asym_auth]);
key_type_asymmetric.free_preparse(&lkca_cert);
key_type_asymmetric.free_preparse(&lkca_ca_cert);
return ret;
#else
return false;
#endif
}
bool libspdm_x509_verify_cert(const uint8_t *cert, size_t cert_size,
const uint8_t *ca_cert, size_t ca_cert_size)
{
return lkca_x509_verify_cert(cert, cert_size, ca_cert, ca_cert_size) == 0;
}
bool libspdm_x509_verify_cert_chain(const uint8_t *root_cert, size_t root_cert_length,
const uint8_t *cert_chain, size_t cert_chain_length)
{
size_t preceding_cert_len;
const uint8_t *preceding_cert;
size_t current_cert_len;
const uint8_t *current_cert;
bool verify_flag;
int ret;
verify_flag = false;
preceding_cert = root_cert;
preceding_cert_len = root_cert_length;
current_cert = cert_chain;
/* Get Current certificate from certificates buffer and Verify with preceding cert*/
do {
if (!lkca_asn1_get_tag(
current_cert, cert_chain + cert_chain_length, &current_cert_len,
LIBSPDM_CRYPTO_ASN1_CONSTRUCTED | LIBSPDM_CRYPTO_ASN1_SEQUENCE)) {
break;
}
ret = lkca_x509_verify_cert(current_cert, current_cert_len,
preceding_cert, preceding_cert_len);
if (ret != 0) {
verify_flag = false;
break;
} else {
verify_flag = true;
}
preceding_cert = current_cert;
preceding_cert_len = current_cert_len;
current_cert = current_cert + current_cert_len;
} while (true);
return verify_flag;
}
bool libspdm_x509_get_cert_from_cert_chain(const uint8_t *cert_chain,
size_t cert_chain_length,
const int32_t cert_index, const uint8_t **cert,
size_t *cert_length)
{
size_t asn1_len;
int32_t current_index;
size_t current_cert_len;
const uint8_t *current_cert;
current_cert_len = 0;
/* Check input parameters.*/
if ((cert_chain == NULL) || (cert == NULL) || (cert_index < -1) ||
(cert_length == NULL)) {
return false;
}
current_cert = cert_chain;
current_index = -1;
/* Traverse the certificate chain*/
while (true) {
/* Get asn1 tag len*/
if (!lkca_asn1_get_tag(
current_cert, cert_chain + cert_chain_length, &asn1_len,
LIBSPDM_CRYPTO_ASN1_CONSTRUCTED | LIBSPDM_CRYPTO_ASN1_SEQUENCE)) {
break;
}
current_cert_len = asn1_len;
current_index++;
if (current_index == cert_index) {
*cert = current_cert;
*cert_length = current_cert_len;
return true;
}
current_cert = current_cert + current_cert_len;
}
/* If cert_index is -1, Return the last certificate*/
if (cert_index == -1 && current_index >= 0) {
*cert = current_cert - current_cert_len;
*cert_length = current_cert_len;
return true;
}
return false;
}
bool libspdm_x509_get_tbs_cert(const uint8_t *cert, size_t cert_size,
uint8_t **tbs_cert, size_t *tbs_cert_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_version(const uint8_t *cert, size_t cert_size,
size_t *version)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_serial_number(const uint8_t *cert, size_t cert_size,
uint8_t *serial_number,
size_t *serial_number_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_issuer_name(const uint8_t *cert, size_t cert_size,
uint8_t *cert_issuer,
size_t *issuer_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool
libspdm_x509_get_issuer_common_name(const uint8_t *cert, size_t cert_size,
char *common_name,
size_t *common_name_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool
libspdm_x509_get_issuer_orgnization_name(const uint8_t *cert, size_t cert_size,
char *name_buffer,
size_t *name_buffer_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_signature_algorithm(const uint8_t *cert,
size_t cert_size, uint8_t *oid,
size_t *oid_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_extension_data(const uint8_t *cert, size_t cert_size,
const uint8_t *oid, size_t oid_size,
uint8_t *extension_data,
size_t *extension_data_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_validity(const uint8_t *cert, size_t cert_size,
uint8_t *from, size_t *from_size, uint8_t *to,
size_t *to_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_key_usage(const uint8_t *cert, size_t cert_size,
size_t *usage)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_extended_key_usage(const uint8_t *cert,
size_t cert_size, uint8_t *usage,
size_t *usage_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_get_extended_basic_constraints(const uint8_t *cert,
size_t cert_size,
uint8_t *basic_constraints,
size_t *basic_constraints_size)
{
LIBSPDM_ASSERT(false);
return false;
}
bool libspdm_x509_set_date_time(char const *date_time_str, void *date_time, size_t *date_time_size)
{
LIBSPDM_ASSERT(false);
return false;
}
int32_t libspdm_x509_compare_date_time(const void *date_time1, const void *date_time2)
{
LIBSPDM_ASSERT(false);
return -3;
}
bool libspdm_gen_x509_csr(size_t hash_nid, size_t asym_nid,
uint8_t *requester_info, size_t requester_info_length,
void *context, char *subject_name,
size_t *csr_len, uint8_t **csr_pointer)
{
LIBSPDM_ASSERT(false);
return false;
}

View File

@@ -2691,3 +2691,17 @@ nvswitch_os_get_supported_register_events_params
*os_descriptor = NV_FALSE; *os_descriptor = NV_FALSE;
return NVL_SUCCESS; return NVL_SUCCESS;
} }
NvlStatus
nvswitch_os_get_pid
(
NvU32 *pPid
)
{
if (pPid != NULL)
{
*pPid = task_pid_nr(current);
}
return NVL_SUCCESS;
}

View File

@@ -126,6 +126,19 @@ static void nvUvmFreeSafeStack(nvidia_stack_t *sp)
nv_kmem_cache_free_stack(sp); nv_kmem_cache_free_stack(sp);
} }
static NV_STATUS nvUvmDestroyFaultInfoAndStacks(nvidia_stack_t *sp,
uvmGpuDeviceHandle device,
UvmGpuFaultInfo *pFaultInfo)
{
nv_kmem_cache_free_stack(pFaultInfo->replayable.cslCtx.nvidia_stack);
nv_kmem_cache_free_stack(pFaultInfo->nonReplayable.isr_bh_sp);
nv_kmem_cache_free_stack(pFaultInfo->nonReplayable.isr_sp);
return rm_gpu_ops_destroy_fault_info(sp,
(gpuDeviceHandle)device,
pFaultInfo);
}
NV_STATUS nvUvmInterfaceRegisterGpu(const NvProcessorUuid *gpuUuid, UvmGpuPlatformInfo *gpuInfo) NV_STATUS nvUvmInterfaceRegisterGpu(const NvProcessorUuid *gpuUuid, UvmGpuPlatformInfo *gpuInfo)
{ {
nvidia_stack_t *sp = NULL; nvidia_stack_t *sp = NULL;
@@ -855,6 +868,7 @@ NV_STATUS nvUvmInterfaceInitFaultInfo(uvmGpuDeviceHandle device,
{ {
nvidia_stack_t *sp = NULL; nvidia_stack_t *sp = NULL;
NV_STATUS status; NV_STATUS status;
int err;
if (nv_kmem_cache_alloc_stack(&sp) != 0) if (nv_kmem_cache_alloc_stack(&sp) != 0)
{ {
@@ -864,36 +878,48 @@ NV_STATUS nvUvmInterfaceInitFaultInfo(uvmGpuDeviceHandle device,
status = rm_gpu_ops_init_fault_info(sp, status = rm_gpu_ops_init_fault_info(sp,
(gpuDeviceHandle)device, (gpuDeviceHandle)device,
pFaultInfo); pFaultInfo);
if (status != NV_OK)
{
goto done;
}
// Preallocate a stack for functions called from ISR top half // Preallocate a stack for functions called from ISR top half
pFaultInfo->nonReplayable.isr_sp = NULL; pFaultInfo->nonReplayable.isr_sp = NULL;
pFaultInfo->nonReplayable.isr_bh_sp = NULL; pFaultInfo->nonReplayable.isr_bh_sp = NULL;
if (status == NV_OK) pFaultInfo->replayable.cslCtx.nvidia_stack = NULL;
// NOTE: nv_kmem_cache_alloc_stack does not allocate a stack on PPC.
// Therefore, the pointer can be NULL on success. Always use the
// returned error code to determine if the operation was successful.
err = nv_kmem_cache_alloc_stack((nvidia_stack_t **)&pFaultInfo->nonReplayable.isr_sp);
if (err)
{ {
// NOTE: nv_kmem_cache_alloc_stack does not allocate a stack on PPC. goto error;
// Therefore, the pointer can be NULL on success. Always use the
// returned error code to determine if the operation was successful.
int err = nv_kmem_cache_alloc_stack((nvidia_stack_t **)&pFaultInfo->nonReplayable.isr_sp);
if (!err)
{
err = nv_kmem_cache_alloc_stack((nvidia_stack_t **)&pFaultInfo->nonReplayable.isr_bh_sp);
if (err)
{
nv_kmem_cache_free_stack(pFaultInfo->nonReplayable.isr_sp);
pFaultInfo->nonReplayable.isr_sp = NULL;
}
}
if (err)
{
rm_gpu_ops_destroy_fault_info(sp,
(gpuDeviceHandle)device,
pFaultInfo);
status = NV_ERR_NO_MEMORY;
}
} }
err = nv_kmem_cache_alloc_stack((nvidia_stack_t **)&pFaultInfo->nonReplayable.isr_bh_sp);
if (err)
{
goto error;
}
// The cslCtx.ctx pointer is not NULL only when ConfidentialComputing is enabled.
if (pFaultInfo->replayable.cslCtx.ctx != NULL)
{
err = nv_kmem_cache_alloc_stack((nvidia_stack_t **)&pFaultInfo->replayable.cslCtx.nvidia_stack);
if (err)
{
goto error;
}
}
goto done;
error:
nvUvmDestroyFaultInfoAndStacks(sp,
device,
pFaultInfo);
status = NV_ERR_NO_MEMORY;
done:
nv_kmem_cache_free_stack(sp); nv_kmem_cache_free_stack(sp);
return status; return status;
} }
@@ -949,23 +975,9 @@ NV_STATUS nvUvmInterfaceDestroyFaultInfo(uvmGpuDeviceHandle device,
nvidia_stack_t *sp = nvUvmGetSafeStack(); nvidia_stack_t *sp = nvUvmGetSafeStack();
NV_STATUS status; NV_STATUS status;
// Free the preallocated stack for functions called from ISR status = nvUvmDestroyFaultInfoAndStacks(sp,
if (pFaultInfo->nonReplayable.isr_sp != NULL) device,
{ pFaultInfo);
nv_kmem_cache_free_stack((nvidia_stack_t *)pFaultInfo->nonReplayable.isr_sp);
pFaultInfo->nonReplayable.isr_sp = NULL;
}
if (pFaultInfo->nonReplayable.isr_bh_sp != NULL)
{
nv_kmem_cache_free_stack((nvidia_stack_t *)pFaultInfo->nonReplayable.isr_bh_sp);
pFaultInfo->nonReplayable.isr_bh_sp = NULL;
}
status = rm_gpu_ops_destroy_fault_info(sp,
(gpuDeviceHandle)device,
pFaultInfo);
nvUvmFreeSafeStack(sp); nvUvmFreeSafeStack(sp);
return status; return status;
} }

View File

@@ -32,6 +32,17 @@ NVIDIA_SOURCES += nvidia/nv-msi.c
NVIDIA_SOURCES += nvidia/nv-caps.c NVIDIA_SOURCES += nvidia/nv-caps.c
NVIDIA_SOURCES += nvidia/nv-frontend.c NVIDIA_SOURCES += nvidia/nv-frontend.c
NVIDIA_SOURCES += nvidia/nv_uvm_interface.c NVIDIA_SOURCES += nvidia/nv_uvm_interface.c
NVIDIA_SOURCES += nvidia/libspdm_aead.c
NVIDIA_SOURCES += nvidia/libspdm_ecc.c
NVIDIA_SOURCES += nvidia/libspdm_hkdf.c
NVIDIA_SOURCES += nvidia/libspdm_rand.c
NVIDIA_SOURCES += nvidia/libspdm_shash.c
NVIDIA_SOURCES += nvidia/libspdm_aead_aes_gcm.c
NVIDIA_SOURCES += nvidia/libspdm_sha.c
NVIDIA_SOURCES += nvidia/libspdm_hmac_sha.c
NVIDIA_SOURCES += nvidia/libspdm_hkdf_sha.c
NVIDIA_SOURCES += nvidia/libspdm_ec.c
NVIDIA_SOURCES += nvidia/libspdm_x509.c
NVIDIA_SOURCES += nvidia/nvlink_linux.c NVIDIA_SOURCES += nvidia/nvlink_linux.c
NVIDIA_SOURCES += nvidia/nvlink_caps.c NVIDIA_SOURCES += nvidia/nvlink_caps.c
NVIDIA_SOURCES += nvidia/linux_nvswitch.c NVIDIA_SOURCES += nvidia/linux_nvswitch.c

View File

@@ -222,6 +222,8 @@ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_set_init
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_clear_init_cb NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_clear_init_cb
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_alloc_mem_from_gscco NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_alloc_mem_from_gscco
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_free_gscco_mem NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_free_gscco_mem
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_memory_block_size_bytes
NV_CONFTEST_SYMBOL_COMPILE_TESTS += crypto
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_ops NV_CONFTEST_TYPE_COMPILE_TESTS += dma_ops
NV_CONFTEST_TYPE_COMPILE_TESTS += swiotlb_dma_ops NV_CONFTEST_TYPE_COMPILE_TESTS += swiotlb_dma_ops

View File

@@ -46,6 +46,11 @@ NvlStatus nvlink_lib_unload(void);
*/ */
NvlStatus nvlink_lib_ioctl_ctrl(nvlink_ioctrl_params *ctrl_params); NvlStatus nvlink_lib_ioctl_ctrl(nvlink_ioctrl_params *ctrl_params);
/*
* Gets number of devices with type deviceType
*/
NvlStatus nvlink_lib_return_device_count_by_type(NvU32 deviceType, NvU32 *numDevices);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: Copyright (c) 2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
@@ -30,6 +30,9 @@ extern "C" {
#include "nvlink_common.h" #include "nvlink_common.h"
#define TOP_LEVEL_LOCKING_DISABLED 1
#define PER_LINK_LOCKING_DISABLED 1
#define NVLINK_FREE(x) nvlink_free((void *)x) #define NVLINK_FREE(x) nvlink_free((void *)x)
// Memory management functions // Memory management functions

View File

@@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
bool libspdm_aead_gcm_prealloc(void **context);
void libspdm_aead_free(void *context);
bool libspdm_aead_aes_gcm_encrypt_prealloc(void *context,
const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
uint8_t *tag_out, size_t tag_size,
uint8_t *data_out, size_t *data_out_size);
bool libspdm_aead_aes_gcm_decrypt_prealloc(void *context,
const uint8_t *key, size_t key_size,
const uint8_t *iv, size_t iv_size,
const uint8_t *a_data, size_t a_data_size,
const uint8_t *data_in, size_t data_in_size,
const uint8_t *tag, size_t tag_size,
uint8_t *data_out, size_t *data_out_size);

View File

@@ -1787,6 +1787,10 @@ NV_STATUS NV_API_CALL os_numa_memblock_size
NvU64 *memblock_size NvU64 *memblock_size
) )
{ {
#if NV_IS_EXPORT_SYMBOL_PRESENT_memory_block_size_bytes
*memblock_size = memory_block_size_bytes();
return NV_OK;
#endif
if (nv_ctl_device.numa_memblock_size == 0) if (nv_ctl_device.numa_memblock_size == 0)
return NV_ERR_INVALID_STATE; return NV_ERR_INVALID_STATE;
*memblock_size = nv_ctl_device.numa_memblock_size; *memblock_size = nv_ctl_device.numa_memblock_size;
@@ -2118,6 +2122,53 @@ void NV_API_CALL os_nv_cap_close_fd
nv_cap_close_fd(fd); nv_cap_close_fd(fd);
} }
typedef struct os_numa_gpu_mem_hotplug_notifier_s
{
NvU64 start_pa;
NvU64 size;
nv_pci_info_t pci_info;
struct notifier_block memory_notifier;
} os_numa_gpu_mem_hotplug_notifier_t;
static int os_numa_verify_gpu_memory_zone(struct notifier_block *nb,
unsigned long action, void *data)
{
os_numa_gpu_mem_hotplug_notifier_t *notifier = container_of(nb,
os_numa_gpu_mem_hotplug_notifier_t,
memory_notifier);
struct memory_notify *mhp = data;
NvU64 start_pa = PFN_PHYS(mhp->start_pfn);
NvU64 size = PFN_PHYS(mhp->nr_pages);
if (action == MEM_GOING_ONLINE)
{
// Check if onlining memory falls in the GPU memory range
if ((start_pa >= notifier->start_pa) &&
(start_pa + size) <= (notifier->start_pa + notifier->size))
{
/*
* Verify GPU memory NUMA node has memory only in ZONE_MOVABLE before
* onlining the memory so that incorrect auto online setting doesn't
* cause the memory onlined in a zone where kernel allocations
* could happen, resulting in GPU memory hot unpluggable and requiring
* system reboot.
*/
if (page_zonenum((pfn_to_page(mhp->start_pfn))) != ZONE_MOVABLE)
{
nv_printf(NV_DBG_ERRORS, "NVRM: Failing GPU memory onlining as the onlining zone "
"is not movable. pa: 0x%llx size: 0x%llx\n"
"NVRM: The NVIDIA GPU %04x:%02x:%02x.%x installed in the system\n"
"NVRM: requires auto onlining mode online_movable enabled in\n"
"NVRM: /sys/devices/system/memory/auto_online_blocks\n",
start_pa, size, notifier->pci_info.domain, notifier->pci_info.bus,
notifier->pci_info.slot, notifier->pci_info.function);
return NOTIFY_BAD;
}
}
}
return NOTIFY_OK;
}
NV_STATUS NV_API_CALL os_numa_add_gpu_memory NV_STATUS NV_API_CALL os_numa_add_gpu_memory
( (
void *handle, void *handle,
@@ -2129,8 +2180,16 @@ NV_STATUS NV_API_CALL os_numa_add_gpu_memory
#if defined(NV_ADD_MEMORY_DRIVER_MANAGED_PRESENT) #if defined(NV_ADD_MEMORY_DRIVER_MANAGED_PRESENT)
int node = 0; int node = 0;
nv_linux_state_t *nvl = pci_get_drvdata(handle); nv_linux_state_t *nvl = pci_get_drvdata(handle);
nv_state_t *nv = NV_STATE_PTR(nvl);
NvU64 base = offset + nvl->coherent_link_info.gpu_mem_pa; NvU64 base = offset + nvl->coherent_link_info.gpu_mem_pa;
int ret; int ret;
os_numa_gpu_mem_hotplug_notifier_t notifier =
{
.start_pa = base,
.size = size,
.pci_info = nv->pci_info,
.memory_notifier.notifier_call = os_numa_verify_gpu_memory_zone,
};
if (nodeId == NULL) if (nodeId == NULL)
{ {
@@ -2149,21 +2208,31 @@ NV_STATUS NV_API_CALL os_numa_add_gpu_memory
NV_ATOMIC_SET(nvl->numa_info.status, NV_IOCTL_NUMA_STATUS_ONLINE_IN_PROGRESS); NV_ATOMIC_SET(nvl->numa_info.status, NV_IOCTL_NUMA_STATUS_ONLINE_IN_PROGRESS);
ret = register_memory_notifier(&notifier.memory_notifier);
if (ret)
{
nv_printf(NV_DBG_ERRORS, "NVRM: Memory hotplug notifier registration failed\n");
goto failed;
}
#ifdef NV_ADD_MEMORY_DRIVER_MANAGED_HAS_MHP_FLAGS_ARG #ifdef NV_ADD_MEMORY_DRIVER_MANAGED_HAS_MHP_FLAGS_ARG
ret = add_memory_driver_managed(node, base, size, "System RAM (NVIDIA)", MHP_NONE); ret = add_memory_driver_managed(node, base, size, "System RAM (NVIDIA)", MHP_NONE);
#else #else
ret = add_memory_driver_managed(node, base, size, "System RAM (NVIDIA)"); ret = add_memory_driver_managed(node, base, size, "System RAM (NVIDIA)");
#endif #endif
unregister_memory_notifier(&notifier.memory_notifier);
if (ret == 0) if (ret == 0)
{ {
struct zone *zone = &NODE_DATA(node)->node_zones[ZONE_MOVABLE]; struct zone *zone = &NODE_DATA(node)->node_zones[ZONE_MOVABLE];
NvU64 start_pfn = base >> PAGE_SHIFT; NvU64 start_pfn = base >> PAGE_SHIFT;
NvU64 end_pfn = (base + size) >> PAGE_SHIFT; NvU64 end_pfn = (base + size) >> PAGE_SHIFT;
/* Verify the full GPU memory range passed on is onlined */
if (zone->zone_start_pfn != start_pfn || if (zone->zone_start_pfn != start_pfn ||
zone_end_pfn(zone) != end_pfn) zone_end_pfn(zone) != end_pfn)
{ {
nv_printf(NV_DBG_ERRORS, "GPU memory zone movable auto onlining failed!\n"); nv_printf(NV_DBG_ERRORS, "NVRM: GPU memory zone movable auto onlining failed!\n");
#ifdef NV_OFFLINE_AND_REMOVE_MEMORY_PRESENT #ifdef NV_OFFLINE_AND_REMOVE_MEMORY_PRESENT
#ifdef NV_REMOVE_MEMORY_HAS_NID_ARG #ifdef NV_REMOVE_MEMORY_HAS_NID_ARG
if (offline_and_remove_memory(node, base, size) != 0) if (offline_and_remove_memory(node, base, size) != 0)
@@ -2171,7 +2240,7 @@ NV_STATUS NV_API_CALL os_numa_add_gpu_memory
if (offline_and_remove_memory(base, size) != 0) if (offline_and_remove_memory(base, size) != 0)
#endif #endif
{ {
nv_printf(NV_DBG_ERRORS, "offline_and_remove_memory failed\n"); nv_printf(NV_DBG_ERRORS, "NVRM: offline_and_remove_memory failed\n");
} }
#endif #endif
goto failed; goto failed;

View File

@@ -1068,6 +1068,12 @@ bool DeviceImpl::getSDPExtnForColorimetrySupported()
} }
} }
if (!targetDevice)
{
DP_ASSERT(0 && "targetDevice is invalid for SDP_EXT COLORIMETRY");
return false;
}
// Send remote DPCD for devices behind the branch // Send remote DPCD for devices behind the branch
if ((AuxBus::success == targetDevice->getDpcdData(NV_DPCD_TRAINING_AUX_RD_INTERVAL, if ((AuxBus::success == targetDevice->getDpcdData(NV_DPCD_TRAINING_AUX_RD_INTERVAL,
&byte, sizeof byte, &size, &nakReason)) && &byte, sizeof byte, &size, &nakReason)) &&
@@ -2476,7 +2482,7 @@ bool DeviceImpl::getPCONCaps(PCONCaps *pPCONCaps)
break; break;
} }
DP_LOG((" DP2HDMI PCON caps - Max TMDS Clk: %u LinkBWGbps: %u MaxBpc: %u", DP_LOG((" DP2HDMI PCON caps - Max TMDS Clk: %u LinkBWGbps: %u MaxBpc: %u",
pPCONCaps->maxTmdsClkRate, pPCONCaps->maxHdmiLinkBandwidthGbps, pPCONCaps->maxBpc)); pPCONCaps->maxTmdsClkRate, pPCONCaps->maxHdmiLinkBandwidthGbps, pPCONCaps->maxBpc));
} }
} }

View File

@@ -36,25 +36,25 @@
// and then checked back in. You cannot make changes to these sections without // and then checked back in. You cannot make changes to these sections without
// corresponding changes to the buildmeister script // corresponding changes to the buildmeister script
#ifndef NV_BUILD_BRANCH #ifndef NV_BUILD_BRANCH
#define NV_BUILD_BRANCH r536_08 #define NV_BUILD_BRANCH r536_62
#endif #endif
#ifndef NV_PUBLIC_BRANCH #ifndef NV_PUBLIC_BRANCH
#define NV_PUBLIC_BRANCH r536_08 #define NV_PUBLIC_BRANCH r536_62
#endif #endif
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) #if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS)
#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r535/r536_08-145" #define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r535/r536_62-214"
#define NV_BUILD_CHANGELIST_NUM (32940552) #define NV_BUILD_CHANGELIST_NUM (33069717)
#define NV_BUILD_TYPE "Official" #define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "rel/gpu_drv/r535/r536_08-145" #define NV_BUILD_NAME "rel/gpu_drv/r535/r536_62-214"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (32940552) #define NV_LAST_OFFICIAL_CHANGELIST_NUM (33069717)
#else /* Windows builds */ #else /* Windows builds */
#define NV_BUILD_BRANCH_VERSION "r536_08-4" #define NV_BUILD_BRANCH_VERSION "r536_62-3"
#define NV_BUILD_CHANGELIST_NUM (32940552) #define NV_BUILD_CHANGELIST_NUM (33061144)
#define NV_BUILD_TYPE "Official" #define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "536.19" #define NV_BUILD_NAME "536.67"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (32940552) #define NV_LAST_OFFICIAL_CHANGELIST_NUM (33061144)
#define NV_BUILD_BRANCH_BASE_VERSION R535 #define NV_BUILD_BRANCH_BASE_VERSION R535
#endif #endif
// End buildmeister python edited section // End buildmeister python edited section

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: Copyright (c) 2009 - 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-FileCopyrightText: Copyright (c) 2009 - 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
@@ -443,6 +443,7 @@ static const PNPVendorId PNPVendorIds[] =
{ "SAN", _VENDOR_NAME_ENTRY("Sanyo Electric Co.,Ltd.") }, { "SAN", _VENDOR_NAME_ENTRY("Sanyo Electric Co.,Ltd.") },
{ "SCC", _VENDOR_NAME_ENTRY("SORD") }, { "SCC", _VENDOR_NAME_ENTRY("SORD") },
{ "SCD", _VENDOR_NAME_ENTRY("Sanyo") }, { "SCD", _VENDOR_NAME_ENTRY("Sanyo") },
{ "SDC", _VENDOR_NAME_ENTRY("Samsung Display Corp.") },
{ "SDI", _VENDOR_NAME_ENTRY("Samtron/Sigma Designs") }, { "SDI", _VENDOR_NAME_ENTRY("Samtron/Sigma Designs") },
{ "SDT", _VENDOR_NAME_ENTRY("Siemens AG") }, { "SDT", _VENDOR_NAME_ENTRY("Siemens AG") },
{ "SEA", _VENDOR_NAME_ENTRY("Segate") }, { "SEA", _VENDOR_NAME_ENTRY("Segate") },

View File

@@ -4,7 +4,7 @@
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \ #if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \
(defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1) (defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1)
#define NV_VERSION_STRING "535.54.03" #define NV_VERSION_STRING "535.86.05"
#else #else

View File

@@ -112,23 +112,12 @@ struct _NVLOG_BUFFER
#endif // NVOS_IS_UNIX #endif // NVOS_IS_UNIX
//
// Due to this file's peculiar location, NvPort may or may not be includable // Due to this file's peculiar location, NvPort may or may not be includable
// This hack will go away when NvLog is moved into common/shared
//
#if NVOS_IS_MACINTOSH
#if !PORT_IS_KERNEL_BUILD
typedef struct PORT_SPINLOCK PORT_SPINLOCK; typedef struct PORT_SPINLOCK PORT_SPINLOCK;
typedef struct PORT_MUTEX PORT_MUTEX; typedef struct PORT_MUTEX PORT_MUTEX;
#else typedef struct PORT_RWLOCK PORT_RWLOCK;
#include "nvport/nvport.h"
#endif
#elif !defined(PORT_IS_KERNEL_BUILD) #if PORT_IS_KERNEL_BUILD
typedef struct PORT_SPINLOCK PORT_SPINLOCK;
typedef struct PORT_MUTEX PORT_MUTEX;
#else
#include "nvport/nvport.h" #include "nvport/nvport.h"
#endif #endif
@@ -149,6 +138,8 @@ typedef struct _NVLOG_LOGGER
PORT_SPINLOCK* mainLock; PORT_SPINLOCK* mainLock;
/** Lock for creating/deleting pBuffers and accessing them from RmCtrls */ /** Lock for creating/deleting pBuffers and accessing them from RmCtrls */
PORT_MUTEX* buffersLock; PORT_MUTEX* buffersLock;
/** Lock for registering/deregistering flush callbacks */
PORT_RWLOCK *flushCbsLock;
} NVLOG_LOGGER; } NVLOG_LOGGER;
extern NVLOG_LOGGER NvLogLogger; extern NVLOG_LOGGER NvLogLogger;

View File

@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -1,685 +0,0 @@
/**
* \file aes.h
*
* \brief This file contains AES definitions and functions.
*
* The Advanced Encryption Standard (AES) specifies a FIPS-approved
* cryptographic algorithm that can be used to protect electronic
* data.
*
* The AES algorithm is a symmetric block cipher that can
* encrypt and decrypt information. For more information, see
* <em>FIPS Publication 197: Advanced Encryption Standard</em> and
* <em>ISO/IEC 18033-2:2006: Information technology -- Security
* techniques -- Encryption algorithms -- Part 2: Asymmetric
* ciphers</em>.
*
* The AES-XTS block mode is standardized by NIST SP 800-38E
* <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
* and described in detail by IEEE P1619
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_AES_H
#define MBEDTLS_AES_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
/* padlock.c and aesni.c rely on these values! */
#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */
#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */
/* Error codes in range 0x0020-0x0022 */
#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
/* Error codes in range 0x0021-0x0025 */
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */
/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */
#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */
/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_AES_ALT)
// Regular implementation
//
/**
* \brief The AES context-type definition.
*/
typedef struct mbedtls_aes_context
{
int nr; /*!< The number of rounds. */
uint32_t *rk; /*!< AES round keys. */
uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
hold 32 extra Bytes, which can be used for
one of the following purposes:
<ul><li>Alignment if VIA padlock is
used.</li>
<li>Simplifying key expansion in the 256-bit
case by generating an extra round key.
</li></ul> */
}
mbedtls_aes_context;
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief The AES XTS context-type definition.
*/
typedef struct mbedtls_aes_xts_context
{
mbedtls_aes_context crypt; /*!< The AES context to use for AES block
encryption or decryption. */
mbedtls_aes_context tweak; /*!< The AES context used for tweak
computation. */
} mbedtls_aes_xts_context;
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#else /* MBEDTLS_AES_ALT */
#include "aes_alt.h"
#endif /* MBEDTLS_AES_ALT */
/**
* \brief This function initializes the specified AES context.
*
* It must be the first API called before using
* the context.
*
* \param ctx The AES context to initialize. This must not be \c NULL.
*/
void mbedtls_aes_init( mbedtls_aes_context *ctx );
/**
* \brief This function releases and clears the specified AES context.
*
* \param ctx The AES context to clear.
* If this is \c NULL, this function does nothing.
* Otherwise, the context must have been at least initialized.
*/
void mbedtls_aes_free( mbedtls_aes_context *ctx );
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief This function initializes the specified AES XTS context.
*
* It must be the first API called before using
* the context.
*
* \param ctx The AES XTS context to initialize. This must not be \c NULL.
*/
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
/**
* \brief This function releases and clears the specified AES XTS context.
*
* \param ctx The AES XTS context to clear.
* If this is \c NULL, this function does nothing.
* Otherwise, the context must have been at least initialized.
*/
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/**
* \brief This function sets the encryption key.
*
* \param ctx The AES context to which the key should be bound.
* It must be initialized.
* \param key The encryption key.
* This must be a readable buffer of size \p keybits bits.
* \param keybits The size of data passed in bits. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief This function sets the decryption key.
*
* \param ctx The AES context to which the key should be bound.
* It must be initialized.
* \param key The decryption key.
* This must be a readable buffer of size \p keybits bits.
* \param keybits The size of data passed. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief This function prepares an XTS context for encryption and
* sets the encryption key.
*
* \param ctx The AES XTS context to which the key should be bound.
* It must be initialized.
* \param key The encryption key. This is comprised of the XTS key1
* concatenated with the XTS key2.
* This must be a readable buffer of size \p keybits bits.
* \param keybits The size of \p key passed in bits. Valid options are:
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function prepares an XTS context for decryption and
* sets the decryption key.
*
* \param ctx The AES XTS context to which the key should be bound.
* It must be initialized.
* \param key The decryption key. This is comprised of the XTS key1
* concatenated with the XTS key2.
* This must be a readable buffer of size \p keybits bits.
* \param keybits The size of \p key passed in bits. Valid options are:
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/**
* \brief This function performs an AES single-block encryption or
* decryption operation.
*
* It performs the operation defined in the \p mode parameter
* (encrypt or decrypt), on the input data buffer defined in
* the \p input parameter.
*
* mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or
* mbedtls_aes_setkey_dec() must be called before the first
* call to this API with the same context.
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param input The buffer holding the input data.
* It must be readable and at least \c 16 Bytes long.
* \param output The buffer where the output data will be written.
* It must be writeable and at least \c 16 Bytes long.
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief This function performs an AES-CBC encryption or decryption operation
* on full blocks.
*
* It performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer defined in
* the \p input parameter.
*
* It can be called as many times as needed, until all the input
* data is processed. mbedtls_aes_init(), and either
* mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
* before the first call to this API with the same context.
*
* \note This function operates on full blocks, that is, the input size
* must be a multiple of the AES block size of \c 16 Bytes.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the same function again on the next
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If you need to retain the contents of the IV, you should
* either save it manually or use the cipher module instead.
*
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of the input data in Bytes. This must be a
* multiple of the block size (\c 16 Bytes).
* \param iv Initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
* on failure.
*/
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief This function performs an AES-XTS encryption or decryption
* operation for an entire XTS data unit.
*
* AES-XTS encrypts or decrypts blocks based on their location as
* defined by a data unit number. The data unit number must be
* provided by \p data_unit.
*
* NIST SP 800-38E limits the maximum size of a data unit to 2^20
* AES blocks. If the data unit is larger than this, this function
* returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
*
* \param ctx The AES XTS context to use for AES XTS operations.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of a data unit in Bytes. This can be any
* length between 16 bytes and 2^24 bytes inclusive
* (between 1 and 2^20 block cipher blocks).
* \param data_unit The address of the data unit encoded as an array of 16
* bytes in little-endian format. For disk encryption, this
* is typically the index of the block device sector that
* contains the data.
* \param input The buffer holding the input data (which is an entire
* data unit). This function reads \p length Bytes from \p
* input.
* \param output The buffer holding the output data (which is an entire
* data unit). This function writes \p length Bytes to \p
* output.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
* smaller than an AES block in size (16 Bytes) or if \p
* length is larger than 2^20 blocks (16 MiB).
*/
int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
int mode,
size_t length,
const unsigned char data_unit[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief This function performs an AES-CFB128 encryption or decryption
* operation.
*
* It performs the operation defined in the \p mode
* parameter (encrypt or decrypt), on the input data buffer
* defined in the \p input parameter.
*
* For CFB, you must set up the context with mbedtls_aes_setkey_enc(),
* regardless of whether you are performing an encryption or decryption
* operation, that is, regardless of the \p mode parameter. This is
* because CFB mode uses the same key schedule for encryption and
* decryption.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the same function again on the next
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If you need to retain the contents of the
* IV, you must either save it manually or use the cipher
* module instead.
*
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of the input data in Bytes.
* \param iv_off The offset in IV (updated after use).
* It must point to a valid \c size_t.
* \param iv The initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief This function performs an AES-CFB8 encryption or decryption
* operation.
*
* It performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer defined
* in the \p input parameter.
*
* Due to the nature of CFB, you must use the same key schedule for
* both encryption and decryption operations. Therefore, you must
* use the context initialized with mbedtls_aes_setkey_enc() for
* both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the same function again on the next
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT
* \param length The length of the input data.
* \param iv The initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/**
* \brief This function performs an AES-OFB (Output Feedback Mode)
* encryption or decryption operation.
*
* For OFB, you must set up the context with
* mbedtls_aes_setkey_enc(), regardless of whether you are
* performing an encryption or decryption operation. This is
* because OFB mode uses the same key schedule for encryption and
* decryption.
*
* The OFB operation is identical for encryption or decryption,
* therefore no operation mode needs to be specified.
*
* \note Upon exit, the content of iv, the Initialisation Vector, is
* updated so that you can call the same function again on the next
* block(s) of data and get the same result as if it was encrypted
* in one call. This allows a "streaming" usage, by initialising
* iv_off to 0 before the first call, and preserving its value
* between calls.
*
* For non-streaming use, the iv should be initialised on each call
* to a unique value, and iv_off set to 0 on each call.
*
* If you need to retain the contents of the initialisation vector,
* you must either save it manually or use the cipher module
* instead.
*
* \warning For the OFB mode, the initialisation vector must be unique
* every encryption operation. Reuse of an initialisation vector
* will compromise security.
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param length The length of the input data.
* \param iv_off The offset in IV (updated after use).
* It must point to a valid \c size_t.
* \param iv The initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief This function performs an AES-CTR encryption or decryption
* operation.
*
* This function performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer
* defined in the \p input parameter.
*
* Due to the nature of CTR, you must use the same key schedule
* for both encryption and decryption operations. Therefore, you
* must use the context initialized with mbedtls_aes_setkey_enc()
* for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
*
* \warning You must never reuse a nonce value with the same key. Doing so
* would void the encryption for the two messages encrypted with
* the same nonce and key.
*
* There are two common strategies for managing nonces with CTR:
*
* 1. You can handle everything as a single message processed over
* successive calls to this function. In that case, you want to
* set \p nonce_counter and \p nc_off to 0 for the first call, and
* then preserve the values of \p nonce_counter, \p nc_off and \p
* stream_block across calls to this function as they will be
* updated by this function.
*
* With this strategy, you must not encrypt more than 2**128
* blocks of data with the same key.
*
* 2. You can encrypt separate messages by dividing the \p
* nonce_counter buffer in two areas: the first one used for a
* per-message nonce, handled by yourself, and the second one
* updated by this function internally.
*
* For example, you might reserve the first 12 bytes for the
* per-message nonce, and the last 4 bytes for internal use. In that
* case, before calling this function on a new message you need to
* set the first 12 bytes of \p nonce_counter to your chosen nonce
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
* stream_block to be ignored). That way, you can encrypt at most
* 2**96 messages of up to 2**32 blocks each with the same key.
*
* The per-message nonce (or information sufficient to reconstruct
* it) needs to be communicated with the ciphertext and must be unique.
* The recommended way to ensure uniqueness is to use a message
* counter. An alternative is to generate random nonces, but this
* limits the number of messages that can be securely encrypted:
* for example, with 96-bit random nonces, you should not encrypt
* more than 2**32 messages with the same key.
*
* Note that for both stategies, sizes are measured in blocks and
* that an AES block is 16 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
* content must not be written to insecure storage and should be
* securely discarded as soon as it's no longer needed.
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param length The length of the input data.
* \param nc_off The offset in the current \p stream_block, for
* resuming within the current cipher stream. The
* offset pointer should be 0 at the start of a stream.
* It must point to a valid \c size_t.
* \param nonce_counter The 128-bit nonce and counter.
* It must be a readable-writeable buffer of \c 16 Bytes.
* \param stream_block The saved stream block for resuming. This is
* overwritten by the function.
* It must be a readable-writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
/**
* \brief Internal AES block encryption function. This is only
* exposed to allow overriding it using
* \c MBEDTLS_AES_ENCRYPT_ALT.
*
* \param ctx The AES context to use for encryption.
* \param input The plaintext block.
* \param output The output (ciphertext) block.
*
* \return \c 0 on success.
*/
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Internal AES block decryption function. This is only
* exposed to allow overriding it using see
* \c MBEDTLS_AES_DECRYPT_ALT.
*
* \param ctx The AES context to use for decryption.
* \param input The ciphertext block.
* \param output The output (plaintext) block.
*
* \return \c 0 on success.
*/
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Deprecated internal AES block encryption function
* without return value.
*
* \deprecated Superseded by mbedtls_internal_aes_encrypt()
*
* \param ctx The AES context to use for encryption.
* \param input Plaintext block.
* \param output Output (ciphertext) block.
*/
MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Deprecated internal AES block decryption function
* without return value.
*
* \deprecated Superseded by mbedtls_internal_aes_decrypt()
*
* \param ctx The AES context to use for decryption.
* \param input Ciphertext block.
* \param output Output (plaintext) block.
*/
MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_aes_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* aes.h */

View File

@@ -1,368 +0,0 @@
/**
* \file asn1.h
*
* \brief Generic ASN.1 parsing
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_ASN1_H
#define MBEDTLS_ASN1_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_BIGNUM_C)
#include "bignum.h"
#endif
/**
* \addtogroup asn1_module
* \{
*/
/**
* \name ASN1 Error codes
* These error codes are OR'ed to X509 error codes for
* higher error granularity.
* ASN1 is a standard to specify data structures.
* \{
*/
#define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
/* \} name */
/**
* \name DER constants
* These constants comply with the DER encoded ASN.1 type tags.
* DER encoding uses hexadecimal representation.
* An example DER sequence is:\n
* - 0x02 -- tag indicating INTEGER
* - 0x01 -- length in octets
* - 0x05 -- value
* Such sequences are typically read into \c ::mbedtls_x509_buf.
* \{
*/
#define MBEDTLS_ASN1_BOOLEAN 0x01
#define MBEDTLS_ASN1_INTEGER 0x02
#define MBEDTLS_ASN1_BIT_STRING 0x03
#define MBEDTLS_ASN1_OCTET_STRING 0x04
#define MBEDTLS_ASN1_NULL 0x05
#define MBEDTLS_ASN1_OID 0x06
#define MBEDTLS_ASN1_UTF8_STRING 0x0C
#define MBEDTLS_ASN1_SEQUENCE 0x10
#define MBEDTLS_ASN1_SET 0x11
#define MBEDTLS_ASN1_PRINTABLE_STRING 0x13
#define MBEDTLS_ASN1_T61_STRING 0x14
#define MBEDTLS_ASN1_IA5_STRING 0x16
#define MBEDTLS_ASN1_UTC_TIME 0x17
#define MBEDTLS_ASN1_GENERALIZED_TIME 0x18
#define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C
#define MBEDTLS_ASN1_BMP_STRING 0x1E
#define MBEDTLS_ASN1_PRIMITIVE 0x00
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
/*
* Bit masks for each of the components of an ASN.1 tag as specified in
* ITU X.690 (08/2015), section 8.1 "General rules for encoding",
* paragraph 8.1.2.2:
*
* Bit 8 7 6 5 1
* +-------+-----+------------+
* | Class | P/C | Tag number |
* +-------+-----+------------+
*/
#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0
#define MBEDTLS_ASN1_TAG_PC_MASK 0x20
#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F
/* \} name */
/* \} addtogroup asn1_module */
/** Returns the size of the binary string, without the trailing \\0 */
#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1)
/**
* Compares an mbedtls_asn1_buf structure to a reference OID.
*
* Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a
* 'unsigned char *oid' here!
*/
#define MBEDTLS_OID_CMP(oid_str, oid_buf) \
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
#ifdef __cplusplus
extern "C" {
#endif
/**
* \name Functions to parse ASN.1 data structures
* \{
*/
/**
* Type-length-value structure that allows for ASN1 using DER.
*/
typedef struct mbedtls_asn1_buf
{
int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
size_t len; /**< ASN1 length, in octets. */
unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
}
mbedtls_asn1_buf;
/**
* Container for ASN1 bit strings.
*/
typedef struct mbedtls_asn1_bitstring
{
size_t len; /**< ASN1 length, in octets. */
unsigned char unused_bits; /**< Number of unused bits at the end of the string */
unsigned char *p; /**< Raw ASN1 data for the bit string */
}
mbedtls_asn1_bitstring;
/**
* Container for a sequence of ASN.1 items
*/
typedef struct mbedtls_asn1_sequence
{
mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */
}
mbedtls_asn1_sequence;
/**
* Container for a sequence or list of 'named' ASN.1 data items
*/
typedef struct mbedtls_asn1_named_data
{
mbedtls_asn1_buf oid; /**< The object identifier. */
mbedtls_asn1_buf val; /**< The named value. */
struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */
unsigned char next_merged; /**< Merge next item into the current one? */
}
mbedtls_asn1_named_data;
/**
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len The variable that will receive the value
*
* \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching
* end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is
* unparseable.
*/
int mbedtls_asn1_get_len( unsigned char **p,
const unsigned char *end,
size_t *len );
/**
* \brief Get the tag and length of the tag. Check for the requested tag.
* Updates the pointer to immediately behind the tag and length.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len The variable that will receive the length
* \param tag The expected tag
*
* \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did
* not match requested tag, or another specific ASN.1 error code.
*/
int mbedtls_asn1_get_tag( unsigned char **p,
const unsigned char *end,
size_t *len, int tag );
/**
* \brief Retrieve a boolean ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param val The variable that will receive the value
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val );
/**
* \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param val The variable that will receive the value
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_int( unsigned char **p,
const unsigned char *end,
int *val );
/**
* \brief Retrieve a bitstring ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param bs The variable that will receive the value
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
mbedtls_asn1_bitstring *bs);
/**
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
* value.
* Updates the pointer to the beginning of the bit/octet string.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len Length of the actual bit/octect string in bytes
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
size_t *len );
/**
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
* Updated the pointer to immediately behind the full sequence tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param cur First variable in the chain to fill
* \param tag Type of sequence
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_sequence_of( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_sequence *cur,
int tag);
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Retrieve a MPI value from an integer ASN.1 tag.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param X The MPI that will receive the value
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
int mbedtls_asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence.
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param alg The buffer to receive the OID
* \param params The buffer to receive the params (if any)
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
int mbedtls_asn1_get_alg( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params );
/**
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
* params.
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param alg The buffer to receive the OID
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
int mbedtls_asn1_get_alg_null( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg );
/**
* \brief Find a specific named_data entry in a sequence or list based on
* the OID.
*
* \param list The list to seek through
* \param oid The OID to look for
* \param len Size of the OID
*
* \return NULL if not found, or a pointer to the existing entry.
*/
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
const char *oid, size_t len );
/**
* \brief Free a mbedtls_asn1_named_data entry
*
* \param entry The named data entry to free
*/
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
/**
* \brief Free all entries in a mbedtls_asn1_named_data list
* Head will be set to NULL
*
* \param head Pointer to the head of the list of named data entries to free
*/
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
#ifdef __cplusplus
}
#endif
#endif /* asn1.h */

View File

@@ -1,339 +0,0 @@
/**
* \file asn1write.h
*
* \brief ASN.1 buffer writing functionality
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_ASN1_WRITE_H
#define MBEDTLS_ASN1_WRITE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "asn1.h"
#define MBEDTLS_ASN1_CHK_ADD(g, f) \
do \
{ \
if( ( ret = (f) ) < 0 ) \
return( ret ); \
else \
(g) += ret; \
} while( 0 )
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Write a length field in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param len The length value to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start,
size_t len );
/**
* \brief Write an ASN.1 tag in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param tag The tag to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start,
unsigned char tag );
/**
* \brief Write raw buffer data.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param buf The data buffer to write.
* \param size The length of the data buffer.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size );
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER)
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param X The MPI to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start,
const mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
* \brief Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start );
/**
* \brief Write an OID tag (#MBEDTLS_ASN1_OID) and data
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param oid The OID to write.
* \param oid_len The length of the OID.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len );
/**
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param oid The OID of the algorithm to write.
* \param oid_len The length of the algorithm's OID.
* \param par_len The length of the parameters, which must be already written.
* If 0, NULL parameters are added
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_algorithm_identifier( unsigned char **p,
unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len );
/**
* \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param boolean The boolean value to write, either \c 0 or \c 1.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start,
int boolean );
/**
* \brief Write an int tag (#MBEDTLS_ASN1_INTEGER) and value
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param val The integer value to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val );
/**
* \brief Write a string in ASN.1 format using a specific
* string encoding tag.
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param tag The string encoding tag to write, e.g.
* #MBEDTLS_ASN1_UTF8_STRING.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start,
int tag, const char *text,
size_t text_len );
/**
* \brief Write a string in ASN.1 format using the PrintableString
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_printable_string( unsigned char **p,
unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a UTF8 string in ASN.1 format using the UTF8String
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a string in ASN.1 format using the IA5String
* string encoding tag (#MBEDTLS_ASN1_IA5_STRING).
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and
* value in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param buf The bitstring to write.
* \param bits The total number of bits in the bitstring.
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits );
/**
* \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING)
* and value in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param buf The buffer holding the data to write.
* \param size The length of the data buffer \p buf.
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size );
/**
* \brief Create or find a specific named_data entry for writing in a
* sequence or list based on the OID. If not already in there,
* a new entry is added to the head of the list.
* Warning: Destructive behaviour for the val data!
*
* \param list The pointer to the location of the head of the list to seek
* through (will be updated in case of a new entry).
* \param oid The OID to look for.
* \param oid_len The size of the OID.
* \param val The data to store (can be \c NULL if you want to fill
* it by hand).
* \param val_len The minimum length of the data buffer needed.
*
* \return A pointer to the new / existing entry on success.
* \return \c NULL if if there was a memory allocation error.
*/
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list,
const char *oid, size_t oid_len,
const unsigned char *val,
size_t val_len );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_ASN1_WRITE_H */

View File

@@ -1,108 +0,0 @@
/**
* \file base64.h
*
* \brief RFC 1521 base64 encoding/decoding
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_BASE64_H
#define MBEDTLS_BASE64_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Encode a buffer into base64 format
*
* \param dst destination buffer
* \param dlen size of the destination buffer
* \param olen number of bytes written
* \param src source buffer
* \param slen amount of data to be encoded
*
* \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL.
* *olen is always updated to reflect the amount
* of data that has (or would have) been written.
* If that length cannot be represented, then no data is
* written to the buffer and *olen is set to the maximum
* length representable as a size_t.
*
* \note Call this function with dlen = 0 to obtain the
* required buffer size in *olen
*/
int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
/**
* \brief Decode a base64-formatted buffer
*
* \param dst destination buffer (can be NULL for checking size)
* \param dlen size of the destination buffer
* \param olen number of bytes written
* \param src source buffer
* \param slen amount of data to be decoded
*
* \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or
* MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is
* not correct. *olen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dst = NULL or dlen = 0 to obtain
* the required buffer size in *olen
*/
int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_base64_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* base64.h */

View File

@@ -1,987 +0,0 @@
/**
* \file bignum.h
*
* \brief Multi-precision integer library
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_BIGNUM_H
#define MBEDTLS_BIGNUM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
#endif
#define MBEDTLS_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */
#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */
#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */
#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */
#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */
#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
#define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */
#define MBEDTLS_MPI_CHK(f) \
do \
{ \
if( ( ret = (f) ) != 0 ) \
goto cleanup; \
} while( 0 )
/*
* Maximum size MPIs are allowed to grow to in number of limbs.
*/
#define MBEDTLS_MPI_MAX_LIMBS 10000
#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
/*
* Maximum window size used for modular exponentiation. Default: 6
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
* for the sliding window calculation. (So 64 by default)
*
* Reduction in size, reduces speed.
*/
#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)
/*
* Maximum size of MPIs allowed in bits and bytes for user-MPIs.
* ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
*
* Note: Calculations can temporarily result in larger MPIs. So the number
* of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher.
*/
#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
#endif /* !MBEDTLS_MPI_MAX_SIZE */
#define MBEDTLS_MPI_MAX_BITS ( 8 * MBEDTLS_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */
/*
* When reading from files with mbedtls_mpi_read_file() and writing to files with
* mbedtls_mpi_write_file() the buffer should have space
* for a (short) label, the MPI (in the provided radix), the newline
* characters and the '\0'.
*
* By default we assume at least a 10 char label, a minimum radix of 10
* (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
* Autosized at compile time for at least a 10 char label, a minimum radix
* of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size.
*
* This used to be statically sized to 1250 for a maximum of 4096 bit
* numbers (1234 decimal chars).
*
* Calculate using the formula:
* MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) +
* LabelSize + 6
*/
#define MBEDTLS_MPI_MAX_BITS_SCALE100 ( 100 * MBEDTLS_MPI_MAX_BITS )
#define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332
#define MBEDTLS_MPI_RW_BUFFER_SIZE ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
/*
* Define the base integer type, architecture-wise.
*
* 32 or 64-bit integer types can be forced regardless of the underlying
* architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64
* respectively and undefining MBEDTLS_HAVE_ASM.
*
* Double-width integers (e.g. 128-bit in 64-bit architectures) can be
* disabled by defining MBEDTLS_NO_UDBL_DIVISION.
*/
#if !defined(MBEDTLS_HAVE_INT32)
#if defined(__GNUC__) && ( \
defined(__amd64__) || defined(__x86_64__) || \
defined(__ppc64__) || defined(__powerpc64__) || \
defined(__ia64__) || defined(__alpha__) || \
( defined(__sparc__) && defined(__arch64__) ) || \
defined(__s390x__) || defined(__mips64) )
#if !defined(MBEDTLS_HAVE_INT64)
#define MBEDTLS_HAVE_INT64
#endif /* MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#if !defined(MBEDTLS_NO_UDBL_DIVISION)
/* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI)));
#define MBEDTLS_HAVE_UDBL
#endif /* !MBEDTLS_NO_UDBL_DIVISION */
#elif defined(__ARMCC_VERSION) && defined(__aarch64__)
/*
* __ARMCC_VERSION is defined for both armcc and armclang and
* __aarch64__ is only defined by armclang when compiling 64-bit code
*/
#if !defined(MBEDTLS_HAVE_INT64)
#define MBEDTLS_HAVE_INT64
#endif /* !MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#if !defined(MBEDTLS_NO_UDBL_DIVISION)
/* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef __uint128_t mbedtls_t_udbl;
#define MBEDTLS_HAVE_UDBL
#endif /* !MBEDTLS_NO_UDBL_DIVISION */
#elif defined(MBEDTLS_HAVE_INT64)
/* Force 64-bit integers with unknown compiler */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#endif
#endif /* !MBEDTLS_HAVE_INT32 */
#if !defined(MBEDTLS_HAVE_INT64)
/* Default to 32-bit compilation */
#if !defined(MBEDTLS_HAVE_INT32)
#define MBEDTLS_HAVE_INT32
#endif /* !MBEDTLS_HAVE_INT32 */
typedef int32_t mbedtls_mpi_sint;
typedef uint32_t mbedtls_mpi_uint;
#if !defined(MBEDTLS_NO_UDBL_DIVISION)
typedef uint64_t mbedtls_t_udbl;
#define MBEDTLS_HAVE_UDBL
#endif /* !MBEDTLS_NO_UDBL_DIVISION */
#endif /* !MBEDTLS_HAVE_INT64 */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MPI structure
*/
typedef struct mbedtls_mpi
{
int s; /*!< Sign: -1 if the mpi is negative, 1 otherwise */
size_t n; /*!< total # of limbs */
mbedtls_mpi_uint *p; /*!< pointer to limbs */
}
mbedtls_mpi;
/**
* \brief Initialize an MPI context.
*
* This makes the MPI ready to be set or freed,
* but does not define a value for the MPI.
*
* \param X The MPI context to initialize. This must not be \c NULL.
*/
void mbedtls_mpi_init( mbedtls_mpi *X );
/**
* \brief This function frees the components of an MPI context.
*
* \param X The MPI context to be cleared. This may be \c NULL,
* in which case this function is a no-op. If it is
* not \c NULL, it must point to an initialized MPI.
*/
void mbedtls_mpi_free( mbedtls_mpi *X );
/**
* \brief Enlarge an MPI to the specified number of limbs.
*
* \note This function does nothing if the MPI is
* already large enough.
*
* \param X The MPI to grow. It must be initialized.
* \param nblimbs The target number of limbs.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs );
/**
* \brief This function resizes an MPI downwards, keeping at least the
* specified number of limbs.
*
* If \c X is smaller than \c nblimbs, it is resized up
* instead.
*
* \param X The MPI to shrink. This must point to an initialized MPI.
* \param nblimbs The minimum number of limbs to keep.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
* (this can only happen when resizing up).
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs );
/**
* \brief Make a copy of an MPI.
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param Y The source MPI. This must point to an initialized MPI.
*
* \note The limb-buffer in the destination MPI is enlarged
* if necessary to hold the value in the source MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Swap the contents of two MPIs.
*
* \param X The first MPI. It must be initialized.
* \param Y The second MPI. It must be initialized.
*/
void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y );
/**
* \brief Perform a safe conditional copy of MPI which doesn't
* reveal whether the condition was true or not.
*
* \param X The MPI to conditionally assign to. This must point
* to an initialized MPI.
* \param Y The MPI to be assigned from. This must point to an
* initialized MPI.
* \param assign The condition deciding whether to perform the
* assignment or not. Possible values:
* * \c 1: Perform the assignment `X = Y`.
* * \c 0: Keep the original value of \p X.
*
* \note This function is equivalent to
* `if( assign ) mbedtls_mpi_copy( X, Y );`
* except that it avoids leaking any information about whether
* the assignment was done or not (the above code may leak
* information through branch prediction and/or memory access
* patterns analysis).
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign );
/**
* \brief Perform a safe conditional swap which doesn't
* reveal whether the condition was true or not.
*
* \param X The first MPI. This must be initialized.
* \param Y The second MPI. This must be initialized.
* \param assign The condition deciding whether to perform
* the swap or not. Possible values:
* * \c 1: Swap the values of \p X and \p Y.
* * \c 0: Keep the original values of \p X and \p Y.
*
* \note This function is equivalent to
* if( assign ) mbedtls_mpi_swap( X, Y );
* except that it avoids leaking any information about whether
* the assignment was done or not (the above code may leak
* information through branch prediction and/or memory access
* patterns analysis).
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
* \return Another negative error code on other kinds of failure.
*
*/
int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign );
/**
* \brief Store integer value in MPI.
*
* \param X The MPI to set. This must be initialized.
* \param z The value to use.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z );
/**
* \brief Get a specific bit from an MPI.
*
* \param X The MPI to query. This must be initialized.
* \param pos Zero-based index of the bit to query.
*
* \return \c 0 or \c 1 on success, depending on whether bit \c pos
* of \c X is unset or set.
* \return A negative error code on failure.
*/
int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos );
/**
* \brief Modify a specific bit in an MPI.
*
* \note This function will grow the target MPI if necessary to set a
* bit to \c 1 in a not yet existing limb. It will not grow if
* the bit should be set to \c 0.
*
* \param X The MPI to modify. This must be initialized.
* \param pos Zero-based index of the bit to modify.
* \param val The desired value of bit \c pos: \c 0 or \c 1.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val );
/**
* \brief Return the number of bits of value \c 0 before the
* least significant bit of value \c 1.
*
* \note This is the same as the zero-based index of
* the least significant bit of value \c 1.
*
* \param X The MPI to query.
*
* \return The number of bits of value \c 0 before the least significant
* bit of value \c 1 in \p X.
*/
size_t mbedtls_mpi_lsb( const mbedtls_mpi *X );
/**
* \brief Return the number of bits up to and including the most
* significant bit of value \c 1.
*
* * \note This is same as the one-based index of the most
* significant bit of value \c 1.
*
* \param X The MPI to query. This must point to an initialized MPI.
*
* \return The number of bits up to and including the most
* significant bit of value \c 1.
*/
size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X );
/**
* \brief Return the total size of an MPI value in bytes.
*
* \param X The MPI to use. This must point to an initialized MPI.
*
* \note The value returned by this function may be less than
* the number of bytes used to store \p X internally.
* This happens if and only if there are trailing bytes
* of value zero.
*
* \return The least number of bytes capable of storing
* the absolute value of \p X.
*/
size_t mbedtls_mpi_size( const mbedtls_mpi *X );
/**
* \brief Import an MPI from an ASCII string.
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param radix The numeric base of the input string.
* \param s Null-terminated string buffer.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s );
/**
* \brief Export an MPI to an ASCII string.
*
* \param X The source MPI. This must point to an initialized MPI.
* \param radix The numeric base of the output string.
* \param buf The buffer to write the string to. This must be writable
* buffer of length \p buflen Bytes.
* \param buflen The available size in Bytes of \p buf.
* \param olen The address at which to store the length of the string
* written, including the final \c NULL byte. This must
* not be \c NULL.
*
* \note You can call this function with `buflen == 0` to obtain the
* minimum required buffer size in `*olen`.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf
* is too small to hold the value of \p X in the desired base.
* In this case, `*olen` is nonetheless updated to contain the
* size of \p buf required for a successful call.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
char *buf, size_t buflen, size_t *olen );
#if defined(MBEDTLS_FS_IO)
/**
* \brief Read an MPI from a line in an opened file.
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param radix The numeric base of the string representation used
* in the source line.
* \param fin The input file handle to use. This must not be \c NULL.
*
* \note On success, this function advances the file stream
* to the end of the current line or to EOF.
*
* The function returns \c 0 on an empty line.
*
* Leading whitespaces are ignored, as is a
* '0x' prefix for radix \c 16.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer
* is too small.
* \return Another negative error code on failure.
*/
int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin );
/**
* \brief Export an MPI into an opened file.
*
* \param p A string prefix to emit prior to the MPI data.
* For example, this might be a label, or "0x" when
* printing in base \c 16. This may be \c NULL if no prefix
* is needed.
* \param X The source MPI. This must point to an initialized MPI.
* \param radix The numeric base to be used in the emitted string.
* \param fout The output file handle. This may be \c NULL, in which case
* the output is written to \c stdout.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X,
int radix, FILE *fout );
#endif /* MBEDTLS_FS_IO */
/**
* \brief Import an MPI from unsigned big endian binary data.
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param buf The input buffer. This must be a readable buffer of length
* \p buflen Bytes.
* \param buflen The length of the input buffer \p p in Bytes.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf,
size_t buflen );
/**
* \brief Export an MPI into unsigned big endian binary data
* of fixed size.
*
* \param X The source MPI. This must point to an initialized MPI.
* \param buf The output buffer. This must be a writable buffer of length
* \p buflen Bytes.
* \param buflen The size of the output buffer \p buf in Bytes.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
* large enough to hold the value of \p X.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf,
size_t buflen );
/**
* \brief Perform a left-shift on an MPI: X <<= count
*
* \param X The MPI to shift. This must point to an initialized MPI.
* \param count The number of bits to shift by.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count );
/**
* \brief Perform a right-shift on an MPI: X >>= count
*
* \param X The MPI to shift. This must point to an initialized MPI.
* \param count The number of bits to shift by.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count );
/**
* \brief Compare the absolute values of two MPIs.
*
* \param X The left-hand MPI. This must point to an initialized MPI.
* \param Y The right-hand MPI. This must point to an initialized MPI.
*
* \return \c 1 if `|X|` is greater than `|Y|`.
* \return \c -1 if `|X|` is lesser than `|Y|`.
* \return \c 0 if `|X|` is equal to `|Y|`.
*/
int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Compare two MPIs.
*
* \param X The left-hand MPI. This must point to an initialized MPI.
* \param Y The right-hand MPI. This must point to an initialized MPI.
*
* \return \c 1 if \p X is greater than \p Y.
* \return \c -1 if \p X is lesser than \p Y.
* \return \c 0 if \p X is equal to \p Y.
*/
int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Check if an MPI is less than the other in constant time.
*
* \param X The left-hand MPI. This must point to an initialized MPI
* with the same allocated length as Y.
* \param Y The right-hand MPI. This must point to an initialized MPI
* with the same allocated length as X.
* \param ret The result of the comparison:
* \c 1 if \p X is less than \p Y.
* \c 0 if \p X is greater than or equal to \p Y.
*
* \return 0 on success.
* \return MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of
* the two input MPIs is not the same.
*/
int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
unsigned *ret );
/**
* \brief Compare an MPI with an integer.
*
* \param X The left-hand MPI. This must point to an initialized MPI.
* \param z The integer value to compare \p X to.
*
* \return \c 1 if \p X is greater than \p z.
* \return \c -1 if \p X is lesser than \p z.
* \return \c 0 if \p X is equal to \p z.
*/
int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z );
/**
* \brief Perform an unsigned addition of MPIs: X = |A| + |B|
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The first summand. This must point to an initialized MPI.
* \param B The second summand. This must point to an initialized MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *B );
/**
* \brief Perform an unsigned subtraction of MPIs: X = |A| - |B|
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The minuend. This must point to an initialized MPI.
* \param B The subtrahend. This must point to an initialized MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A.
* \return Another negative error code on different kinds of failure.
*
*/
int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *B );
/**
* \brief Perform a signed addition of MPIs: X = A + B
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The first summand. This must point to an initialized MPI.
* \param B The second summand. This must point to an initialized MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *B );
/**
* \brief Perform a signed subtraction of MPIs: X = A - B
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The minuend. This must point to an initialized MPI.
* \param B The subtrahend. This must point to an initialized MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *B );
/**
* \brief Perform a signed addition of an MPI and an integer: X = A + b
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The first summand. This must point to an initialized MPI.
* \param b The second summand.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A,
mbedtls_mpi_sint b );
/**
* \brief Perform a signed subtraction of an MPI and an integer:
* X = A - b
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The minuend. This must point to an initialized MPI.
* \param b The subtrahend.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A,
mbedtls_mpi_sint b );
/**
* \brief Perform a multiplication of two MPIs: X = A * B
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The first factor. This must point to an initialized MPI.
* \param B The second factor. This must point to an initialized MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*
*/
int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *B );
/**
* \brief Perform a multiplication of an MPI with an unsigned integer:
* X = A * b
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The first factor. This must point to an initialized MPI.
* \param b The second factor.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*
*/
int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A,
mbedtls_mpi_uint b );
/**
* \brief Perform a division with remainder of two MPIs:
* A = Q * B + R
*
* \param Q The destination MPI for the quotient.
* This may be \c NULL if the value of the
* quotient is not needed.
* \param R The destination MPI for the remainder value.
* This may be \c NULL if the value of the
* remainder is not needed.
* \param A The dividend. This must point to an initialized MPi.
* \param B The divisor. This must point to an initialized MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
const mbedtls_mpi *B );
/**
* \brief Perform a division with remainder of an MPI by an integer:
* A = Q * b + R
*
* \param Q The destination MPI for the quotient.
* This may be \c NULL if the value of the
* quotient is not needed.
* \param R The destination MPI for the remainder value.
* This may be \c NULL if the value of the
* remainder is not needed.
* \param A The dividend. This must point to an initialized MPi.
* \param b The divisor.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
mbedtls_mpi_sint b );
/**
* \brief Perform a modular reduction. R = A mod B
*
* \param R The destination MPI for the residue value.
* This must point to an initialized MPI.
* \param A The MPI to compute the residue of.
* This must point to an initialized MPI.
* \param B The base of the modular reduction.
* This must point to an initialized MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero.
* \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative.
* \return Another negative error code on different kinds of failure.
*
*/
int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A,
const mbedtls_mpi *B );
/**
* \brief Perform a modular reduction with respect to an integer.
* r = A mod b
*
* \param r The address at which to store the residue.
* This must not be \c NULL.
* \param A The MPI to compute the residue of.
* This must point to an initialized MPi.
* \param b The integer base of the modular reduction.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero.
* \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A,
mbedtls_mpi_sint b );
/**
* \brief Perform a sliding-window exponentiation: X = A^E mod N
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The base of the exponentiation.
* This must point to an initialized MPI.
* \param E The exponent MPI. This must point to an initialized MPI.
* \param N The base for the modular reduction. This must point to an
* initialized MPI.
* \param _RR A helper MPI depending solely on \p N which can be used to
* speed-up multiple modular exponentiations for the same value
* of \p N. This may be \c NULL. If it is not \c NULL, it must
* point to an initialized MPI. If it hasn't been used after
* the call to mbedtls_mpi_init(), this function will compute
* the helper value and store it in \p _RR for reuse on
* subsequent calls to this function. Otherwise, the function
* will assume that \p _RR holds the helper value set by a
* previous call to mbedtls_mpi_exp_mod(), and reuse it.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or
* even, or if \c E is negative.
* \return Another negative error code on different kinds of failures.
*
*/
int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *_RR );
/**
* \brief Fill an MPI with a number of random bytes.
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param size The number of random bytes to generate.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context argument.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on failure.
*
* \note The bytes obtained from the RNG are interpreted
* as a big-endian representation of an MPI; this can
* be relevant in applications like deterministic ECDSA.
*/
int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Compute the greatest common divisor: G = gcd(A, B)
*
* \param G The destination MPI. This must point to an initialized MPI.
* \param A The first operand. This must point to an initialized MPI.
* \param B The second operand. This must point to an initialized MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A,
const mbedtls_mpi *B );
/**
* \brief Compute the modular inverse: X = A^-1 mod N
*
* \param X The destination MPI. This must point to an initialized MPI.
* \param A The MPI to calculate the modular inverse of. This must point
* to an initialized MPI.
* \param N The base of the modular inversion. This must point to an
* initialized MPI.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than
* or equal to one.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse
* with respect to \p N.
*/
int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *N );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Perform a Miller-Rabin primality test with error
* probability of 2<sup>-80</sup>.
*
* \deprecated Superseded by mbedtls_mpi_is_prime_ext() which allows
* specifying the number of Miller-Rabin rounds.
*
* \param X The MPI to check for primality.
* This must point to an initialized MPI.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng.
* This may be \c NULL if \p f_rng doesn't use a
* context parameter.
*
* \return \c 0 if successful, i.e. \p X is probably prime.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime.
* \return Another negative error code on other kinds of failure.
*/
MBEDTLS_DEPRECATED int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Miller-Rabin primality test.
*
* \warning If \p X is potentially generated by an adversary, for example
* when validating cryptographic parameters that you didn't
* generate yourself and that are supposed to be prime, then
* \p rounds should be at least the half of the security
* strength of the cryptographic algorithm. On the other hand,
* if \p X is chosen uniformly or non-adversially (as is the
* case when mbedtls_mpi_gen_prime calls this function), then
* \p rounds can be much lower.
*
* \param X The MPI to check for primality.
* This must point to an initialized MPI.
* \param rounds The number of bases to perform the Miller-Rabin primality
* test for. The probability of returning 0 on a composite is
* at most 2<sup>-2*\p rounds</sup>.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng.
* This may be \c NULL if \p f_rng doesn't use
* a context parameter.
*
* \return \c 0 if successful, i.e. \p X is probably prime.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Flags for mbedtls_mpi_gen_prime()
*
* Each of these flags is a constraint on the result X returned by
* mbedtls_mpi_gen_prime().
*/
typedef enum {
MBEDTLS_MPI_GEN_PRIME_FLAG_DH = 0x0001, /**< (X-1)/2 is prime too */
MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR = 0x0002, /**< lower error rate from 2<sup>-80</sup> to 2<sup>-128</sup> */
} mbedtls_mpi_gen_prime_flag_t;
/**
* \brief Generate a prime number.
*
* \param X The destination MPI to store the generated prime in.
* This must point to an initialized MPi.
* \param nbits The required size of the destination MPI in bits.
* This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS.
* \param flags A mask of flags of type #mbedtls_mpi_gen_prime_flag_t.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng.
* This may be \c NULL if \p f_rng doesn't use
* a context parameter.
*
* \return \c 0 if successful, in which case \p X holds a
* probably prime number.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between
* \c 3 and #MBEDTLS_MPI_MAX_BITS.
*/
int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_mpi_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* bignum.h */

View File

@@ -1,899 +0,0 @@
/**
* \file bn_mul.h
*
* \brief Multi-precision integer library
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
/*
* Multiply source vector [s] with b, add result
* to destination vector [d] and set carry c.
*
* Currently supports:
*
* . IA-32 (386+) . AMD64 / EM64T
* . IA-32 (SSE2) . Motorola 68000
* . PowerPC, 32-bit . MicroBlaze
* . PowerPC, 64-bit . TriCore
* . SPARC v8 . ARM v3+
* . Alpha . MIPS32
* . C, longlong . C, generic
*/
#ifndef MBEDTLS_BN_MUL_H
#define MBEDTLS_BN_MUL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "bignum.h"
/*
* Conversion macros for embedded constants:
* build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
*/
#if defined(MBEDTLS_HAVE_INT32)
#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ) \
( (mbedtls_mpi_uint) (a) << 0 ) | \
( (mbedtls_mpi_uint) (b) << 8 ) | \
( (mbedtls_mpi_uint) (c) << 16 ) | \
( (mbedtls_mpi_uint) (d) << 24 )
#define MBEDTLS_BYTES_TO_T_UINT_2( a, b ) \
MBEDTLS_BYTES_TO_T_UINT_4( a, b, 0, 0 )
#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ), \
MBEDTLS_BYTES_TO_T_UINT_4( e, f, g, h )
#else /* 64-bits */
#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
( (mbedtls_mpi_uint) (a) << 0 ) | \
( (mbedtls_mpi_uint) (b) << 8 ) | \
( (mbedtls_mpi_uint) (c) << 16 ) | \
( (mbedtls_mpi_uint) (d) << 24 ) | \
( (mbedtls_mpi_uint) (e) << 32 ) | \
( (mbedtls_mpi_uint) (f) << 40 ) | \
( (mbedtls_mpi_uint) (g) << 48 ) | \
( (mbedtls_mpi_uint) (h) << 56 )
#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ) \
MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
#define MBEDTLS_BYTES_TO_T_UINT_2( a, b ) \
MBEDTLS_BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
#endif /* bits in mbedtls_mpi_uint */
#if defined(MBEDTLS_HAVE_ASM)
#ifndef asm
#define asm __asm
#endif
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
#if defined(__GNUC__) && \
( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
/*
* Disable use of the i386 assembly code below if option -O0, to disable all
* compiler optimisations, is passed, detected with __OPTIMIZE__
* This is done as the number of registers used in the assembly code doesn't
* work with the -O0 option.
*/
#if defined(__i386__) && defined(__OPTIMIZE__)
#define MULADDC_INIT \
asm( \
"movl %%ebx, %0 \n\t" \
"movl %5, %%esi \n\t" \
"movl %6, %%edi \n\t" \
"movl %7, %%ecx \n\t" \
"movl %8, %%ebx \n\t"
#define MULADDC_CORE \
"lodsl \n\t" \
"mull %%ebx \n\t" \
"addl %%ecx, %%eax \n\t" \
"adcl $0, %%edx \n\t" \
"addl (%%edi), %%eax \n\t" \
"adcl $0, %%edx \n\t" \
"movl %%edx, %%ecx \n\t" \
"stosl \n\t"
#if defined(MBEDTLS_HAVE_SSE2)
#define MULADDC_HUIT \
"movd %%ecx, %%mm1 \n\t" \
"movd %%ebx, %%mm0 \n\t" \
"movd (%%edi), %%mm3 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd (%%esi), %%mm2 \n\t" \
"pmuludq %%mm0, %%mm2 \n\t" \
"movd 4(%%esi), %%mm4 \n\t" \
"pmuludq %%mm0, %%mm4 \n\t" \
"movd 8(%%esi), %%mm6 \n\t" \
"pmuludq %%mm0, %%mm6 \n\t" \
"movd 12(%%esi), %%mm7 \n\t" \
"pmuludq %%mm0, %%mm7 \n\t" \
"paddq %%mm2, %%mm1 \n\t" \
"movd 4(%%edi), %%mm3 \n\t" \
"paddq %%mm4, %%mm3 \n\t" \
"movd 8(%%edi), %%mm5 \n\t" \
"paddq %%mm6, %%mm5 \n\t" \
"movd 12(%%edi), %%mm4 \n\t" \
"paddq %%mm4, %%mm7 \n\t" \
"movd %%mm1, (%%edi) \n\t" \
"movd 16(%%esi), %%mm2 \n\t" \
"pmuludq %%mm0, %%mm2 \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd 20(%%esi), %%mm4 \n\t" \
"pmuludq %%mm0, %%mm4 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd 24(%%esi), %%mm6 \n\t" \
"pmuludq %%mm0, %%mm6 \n\t" \
"movd %%mm1, 4(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd 28(%%esi), %%mm3 \n\t" \
"pmuludq %%mm0, %%mm3 \n\t" \
"paddq %%mm5, %%mm1 \n\t" \
"movd 16(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm2 \n\t" \
"movd %%mm1, 8(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm7, %%mm1 \n\t" \
"movd 20(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm4 \n\t" \
"movd %%mm1, 12(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm2, %%mm1 \n\t" \
"movd 24(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm6 \n\t" \
"movd %%mm1, 16(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm4, %%mm1 \n\t" \
"movd 28(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm3 \n\t" \
"movd %%mm1, 20(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm6, %%mm1 \n\t" \
"movd %%mm1, 24(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd %%mm1, 28(%%edi) \n\t" \
"addl $32, %%edi \n\t" \
"addl $32, %%esi \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd %%mm1, %%ecx \n\t"
#define MULADDC_STOP \
"emms \n\t" \
"movl %4, %%ebx \n\t" \
"movl %%ecx, %1 \n\t" \
"movl %%edi, %2 \n\t" \
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ebx", "ecx", "edx", "esi", "edi" \
);
#else
#define MULADDC_STOP \
"movl %4, %%ebx \n\t" \
"movl %%ecx, %1 \n\t" \
"movl %%edi, %2 \n\t" \
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ebx", "ecx", "edx", "esi", "edi" \
);
#endif /* SSE2 */
#endif /* i386 */
#if defined(__amd64__) || defined (__x86_64__)
#define MULADDC_INIT \
asm( \
"xorq %%r8, %%r8\n"
#define MULADDC_CORE \
"movq (%%rsi), %%rax\n" \
"mulq %%rbx\n" \
"addq $8, %%rsi\n" \
"addq %%rcx, %%rax\n" \
"movq %%r8, %%rcx\n" \
"adcq $0, %%rdx\n" \
"nop \n" \
"addq %%rax, (%%rdi)\n" \
"adcq %%rdx, %%rcx\n" \
"addq $8, %%rdi\n"
#define MULADDC_STOP \
: "+c" (c), "+D" (d), "+S" (s) \
: "b" (b) \
: "rax", "rdx", "r8" \
);
#endif /* AMD64 */
#if defined(__mc68020__) || defined(__mcpu32__)
#define MULADDC_INIT \
asm( \
"movl %3, %%a2 \n\t" \
"movl %4, %%a3 \n\t" \
"movl %5, %%d3 \n\t" \
"movl %6, %%d2 \n\t" \
"moveq #0, %%d0 \n\t"
#define MULADDC_CORE \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"moveq #0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"addxl %%d4, %%d3 \n\t"
#define MULADDC_STOP \
"movl %%d3, %0 \n\t" \
"movl %%a3, %1 \n\t" \
"movl %%a2, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "d0", "d1", "d2", "d3", "d4", "a2", "a3" \
);
#define MULADDC_HUIT \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"addxl %%d0, %%d3 \n\t"
#endif /* MC68000 */
#if defined(__powerpc64__) || defined(__ppc64__)
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( \
"ld r3, %3 \n\t" \
"ld r4, %4 \n\t" \
"ld r5, %5 \n\t" \
"ld r6, %6 \n\t" \
"addi r3, r3, -8 \n\t" \
"addi r4, r4, -8 \n\t" \
"addic r5, r5, 0 \n\t"
#define MULADDC_CORE \
"ldu r7, 8(r3) \n\t" \
"mulld r8, r7, r6 \n\t" \
"mulhdu r9, r7, r6 \n\t" \
"adde r8, r8, r5 \n\t" \
"ld r7, 8(r4) \n\t" \
"addze r5, r9 \n\t" \
"addc r8, r8, r7 \n\t" \
"stdu r8, 8(r4) \n\t"
#define MULADDC_STOP \
"addze r5, r5 \n\t" \
"addi r4, r4, 8 \n\t" \
"addi r3, r3, 8 \n\t" \
"std r5, %0 \n\t" \
"std r4, %1 \n\t" \
"std r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#else /* __MACH__ && __APPLE__ */
#define MULADDC_INIT \
asm( \
"ld %%r3, %3 \n\t" \
"ld %%r4, %4 \n\t" \
"ld %%r5, %5 \n\t" \
"ld %%r6, %6 \n\t" \
"addi %%r3, %%r3, -8 \n\t" \
"addi %%r4, %%r4, -8 \n\t" \
"addic %%r5, %%r5, 0 \n\t"
#define MULADDC_CORE \
"ldu %%r7, 8(%%r3) \n\t" \
"mulld %%r8, %%r7, %%r6 \n\t" \
"mulhdu %%r9, %%r7, %%r6 \n\t" \
"adde %%r8, %%r8, %%r5 \n\t" \
"ld %%r7, 8(%%r4) \n\t" \
"addze %%r5, %%r9 \n\t" \
"addc %%r8, %%r8, %%r7 \n\t" \
"stdu %%r8, 8(%%r4) \n\t"
#define MULADDC_STOP \
"addze %%r5, %%r5 \n\t" \
"addi %%r4, %%r4, 8 \n\t" \
"addi %%r3, %%r3, 8 \n\t" \
"std %%r5, %0 \n\t" \
"std %%r4, %1 \n\t" \
"std %%r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#endif /* __MACH__ && __APPLE__ */
#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( \
"lwz r3, %3 \n\t" \
"lwz r4, %4 \n\t" \
"lwz r5, %5 \n\t" \
"lwz r6, %6 \n\t" \
"addi r3, r3, -4 \n\t" \
"addi r4, r4, -4 \n\t" \
"addic r5, r5, 0 \n\t"
#define MULADDC_CORE \
"lwzu r7, 4(r3) \n\t" \
"mullw r8, r7, r6 \n\t" \
"mulhwu r9, r7, r6 \n\t" \
"adde r8, r8, r5 \n\t" \
"lwz r7, 4(r4) \n\t" \
"addze r5, r9 \n\t" \
"addc r8, r8, r7 \n\t" \
"stwu r8, 4(r4) \n\t"
#define MULADDC_STOP \
"addze r5, r5 \n\t" \
"addi r4, r4, 4 \n\t" \
"addi r3, r3, 4 \n\t" \
"stw r5, %0 \n\t" \
"stw r4, %1 \n\t" \
"stw r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#else /* __MACH__ && __APPLE__ */
#define MULADDC_INIT \
asm( \
"lwz %%r3, %3 \n\t" \
"lwz %%r4, %4 \n\t" \
"lwz %%r5, %5 \n\t" \
"lwz %%r6, %6 \n\t" \
"addi %%r3, %%r3, -4 \n\t" \
"addi %%r4, %%r4, -4 \n\t" \
"addic %%r5, %%r5, 0 \n\t"
#define MULADDC_CORE \
"lwzu %%r7, 4(%%r3) \n\t" \
"mullw %%r8, %%r7, %%r6 \n\t" \
"mulhwu %%r9, %%r7, %%r6 \n\t" \
"adde %%r8, %%r8, %%r5 \n\t" \
"lwz %%r7, 4(%%r4) \n\t" \
"addze %%r5, %%r9 \n\t" \
"addc %%r8, %%r8, %%r7 \n\t" \
"stwu %%r8, 4(%%r4) \n\t"
#define MULADDC_STOP \
"addze %%r5, %%r5 \n\t" \
"addi %%r4, %%r4, 4 \n\t" \
"addi %%r3, %%r3, 4 \n\t" \
"stw %%r5, %0 \n\t" \
"stw %%r4, %1 \n\t" \
"stw %%r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#endif /* __MACH__ && __APPLE__ */
#endif /* PPC32 */
/*
* The Sparc(64) assembly is reported to be broken.
* Disable it for now, until we're able to fix it.
*/
#if defined(__microblaze__) || defined(microblaze)
#define MULADDC_INIT \
asm( \
"lwi r3, %3 \n\t" \
"lwi r4, %4 \n\t" \
"lwi r5, %5 \n\t" \
"lwi r6, %6 \n\t" \
"andi r7, r6, 0xffff \n\t" \
"bsrli r6, r6, 16 \n\t"
#define MULADDC_CORE \
"lhui r8, r3, 0 \n\t" \
"addi r3, r3, 2 \n\t" \
"lhui r9, r3, 0 \n\t" \
"addi r3, r3, 2 \n\t" \
"mul r10, r9, r6 \n\t" \
"mul r11, r8, r7 \n\t" \
"mul r12, r9, r7 \n\t" \
"mul r13, r8, r6 \n\t" \
"bsrli r8, r10, 16 \n\t" \
"bsrli r9, r11, 16 \n\t" \
"add r13, r13, r8 \n\t" \
"add r13, r13, r9 \n\t" \
"bslli r10, r10, 16 \n\t" \
"bslli r11, r11, 16 \n\t" \
"add r12, r12, r10 \n\t" \
"addc r13, r13, r0 \n\t" \
"add r12, r12, r11 \n\t" \
"addc r13, r13, r0 \n\t" \
"lwi r10, r4, 0 \n\t" \
"add r12, r12, r10 \n\t" \
"addc r13, r13, r0 \n\t" \
"add r12, r12, r5 \n\t" \
"addc r5, r13, r0 \n\t" \
"swi r12, r4, 0 \n\t" \
"addi r4, r4, 4 \n\t"
#define MULADDC_STOP \
"swi r5, %0 \n\t" \
"swi r4, %1 \n\t" \
"swi r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", \
"r9", "r10", "r11", "r12", "r13" \
);
#endif /* MicroBlaze */
#if defined(__tricore__)
#define MULADDC_INIT \
asm( \
"ld.a %%a2, %3 \n\t" \
"ld.a %%a3, %4 \n\t" \
"ld.w %%d4, %5 \n\t" \
"ld.w %%d1, %6 \n\t" \
"xor %%d5, %%d5 \n\t"
#define MULADDC_CORE \
"ld.w %%d0, [%%a2+] \n\t" \
"madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \
"ld.w %%d0, [%%a3] \n\t" \
"addx %%d2, %%d2, %%d0 \n\t" \
"addc %%d3, %%d3, 0 \n\t" \
"mov %%d4, %%d3 \n\t" \
"st.w [%%a3+], %%d2 \n\t"
#define MULADDC_STOP \
"st.w %0, %%d4 \n\t" \
"st.a %1, %%a3 \n\t" \
"st.a %2, %%a2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "d0", "d1", "e2", "d4", "a2", "a3" \
);
#endif /* TriCore */
/*
* Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about
* our use of r7 below, unless -fomit-frame-pointer is passed.
*
* On the other hand, -fomit-frame-pointer is implied by any -Ox options with
* x !=0, which we can detect using __OPTIMIZE__ (which is also defined by
* clang and armcc5 under the same conditions).
*
* So, only use the optimized assembly below for optimized build, which avoids
* the build error and is pretty reasonable anyway.
*/
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
#define MULADDC_CANNOT_USE_R7
#endif
#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7)
#if defined(__thumb__) && !defined(__thumb2__)
#define MULADDC_INIT \
asm( \
"ldr r0, %3 \n\t" \
"ldr r1, %4 \n\t" \
"ldr r2, %5 \n\t" \
"ldr r3, %6 \n\t" \
"lsr r7, r3, #16 \n\t" \
"mov r9, r7 \n\t" \
"lsl r7, r3, #16 \n\t" \
"lsr r7, r7, #16 \n\t" \
"mov r8, r7 \n\t"
#define MULADDC_CORE \
"ldmia r0!, {r6} \n\t" \
"lsr r7, r6, #16 \n\t" \
"lsl r6, r6, #16 \n\t" \
"lsr r6, r6, #16 \n\t" \
"mov r4, r8 \n\t" \
"mul r4, r6 \n\t" \
"mov r3, r9 \n\t" \
"mul r6, r3 \n\t" \
"mov r5, r9 \n\t" \
"mul r5, r7 \n\t" \
"mov r3, r8 \n\t" \
"mul r7, r3 \n\t" \
"lsr r3, r6, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"lsr r3, r7, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"add r4, r4, r2 \n\t" \
"mov r2, #0 \n\t" \
"adc r5, r2 \n\t" \
"lsl r3, r6, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
"lsl r3, r7, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
"ldr r3, [r1] \n\t" \
"add r4, r4, r3 \n\t" \
"adc r2, r5 \n\t" \
"stmia r1!, {r4} \n\t"
#define MULADDC_STOP \
"str r2, %0 \n\t" \
"str r1, %1 \n\t" \
"str r0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "r8", "r9", "cc" \
);
#elif (__ARM_ARCH >= 6) && \
defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
#define MULADDC_INIT \
asm(
#define MULADDC_CORE \
"ldr r0, [%0], #4 \n\t" \
"ldr r1, [%1] \n\t" \
"umaal r1, %2, %3, r0 \n\t" \
"str r1, [%1], #4 \n\t"
#define MULADDC_STOP \
: "=r" (s), "=r" (d), "=r" (c) \
: "r" (b), "0" (s), "1" (d), "2" (c) \
: "r0", "r1", "memory" \
);
#else
#define MULADDC_INIT \
asm( \
"ldr r0, %3 \n\t" \
"ldr r1, %4 \n\t" \
"ldr r2, %5 \n\t" \
"ldr r3, %6 \n\t"
#define MULADDC_CORE \
"ldr r4, [r0], #4 \n\t" \
"mov r5, #0 \n\t" \
"ldr r6, [r1] \n\t" \
"umlal r2, r5, r3, r4 \n\t" \
"adds r7, r6, r2 \n\t" \
"adc r2, r5, #0 \n\t" \
"str r7, [r1], #4 \n\t"
#define MULADDC_STOP \
"str r2, %0 \n\t" \
"str r1, %1 \n\t" \
"str r0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "cc" \
);
#endif /* Thumb */
#endif /* ARMv3 */
#if defined(__alpha__)
#define MULADDC_INIT \
asm( \
"ldq $1, %3 \n\t" \
"ldq $2, %4 \n\t" \
"ldq $3, %5 \n\t" \
"ldq $4, %6 \n\t"
#define MULADDC_CORE \
"ldq $6, 0($1) \n\t" \
"addq $1, 8, $1 \n\t" \
"mulq $6, $4, $7 \n\t" \
"umulh $6, $4, $6 \n\t" \
"addq $7, $3, $7 \n\t" \
"cmpult $7, $3, $3 \n\t" \
"ldq $5, 0($2) \n\t" \
"addq $7, $5, $7 \n\t" \
"cmpult $7, $5, $5 \n\t" \
"stq $7, 0($2) \n\t" \
"addq $2, 8, $2 \n\t" \
"addq $6, $3, $3 \n\t" \
"addq $5, $3, $3 \n\t"
#define MULADDC_STOP \
"stq $3, %0 \n\t" \
"stq $2, %1 \n\t" \
"stq $1, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "$1", "$2", "$3", "$4", "$5", "$6", "$7" \
);
#endif /* Alpha */
#if defined(__mips__) && !defined(__mips64)
#define MULADDC_INIT \
asm( \
"lw $10, %3 \n\t" \
"lw $11, %4 \n\t" \
"lw $12, %5 \n\t" \
"lw $13, %6 \n\t"
#define MULADDC_CORE \
"lw $14, 0($10) \n\t" \
"multu $13, $14 \n\t" \
"addi $10, $10, 4 \n\t" \
"mflo $14 \n\t" \
"mfhi $9 \n\t" \
"addu $14, $12, $14 \n\t" \
"lw $15, 0($11) \n\t" \
"sltu $12, $14, $12 \n\t" \
"addu $15, $14, $15 \n\t" \
"sltu $14, $15, $14 \n\t" \
"addu $12, $12, $9 \n\t" \
"sw $15, 0($11) \n\t" \
"addu $12, $12, $14 \n\t" \
"addi $11, $11, 4 \n\t"
#define MULADDC_STOP \
"sw $12, %0 \n\t" \
"sw $11, %1 \n\t" \
"sw $10, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "$9", "$10", "$11", "$12", "$13", "$14", "$15", "lo", "hi" \
);
#endif /* MIPS */
#endif /* GNUC */
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
#define MULADDC_INIT \
__asm mov esi, s \
__asm mov edi, d \
__asm mov ecx, c \
__asm mov ebx, b
#define MULADDC_CORE \
__asm lodsd \
__asm mul ebx \
__asm add eax, ecx \
__asm adc edx, 0 \
__asm add eax, [edi] \
__asm adc edx, 0 \
__asm mov ecx, edx \
__asm stosd
#if defined(MBEDTLS_HAVE_SSE2)
#define EMIT __asm _emit
#define MULADDC_HUIT \
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x7E EMIT 0xC9
#define MULADDC_STOP \
EMIT 0x0F EMIT 0x77 \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#else
#define MULADDC_STOP \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#endif /* SSE2 */
#endif /* MSVC */
#endif /* MBEDTLS_HAVE_ASM */
#if !defined(MULADDC_CORE)
#if defined(MBEDTLS_HAVE_UDBL)
#define MULADDC_INIT \
{ \
mbedtls_t_udbl r; \
mbedtls_mpi_uint r0, r1;
#define MULADDC_CORE \
r = *(s++) * (mbedtls_t_udbl) b; \
r0 = (mbedtls_mpi_uint) r; \
r1 = (mbedtls_mpi_uint)( r >> biL ); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#else
#define MULADDC_INIT \
{ \
mbedtls_mpi_uint s0, s1, b0, b1; \
mbedtls_mpi_uint r0, r1, rx, ry; \
b0 = ( b << biH ) >> biH; \
b1 = ( b >> biH );
#define MULADDC_CORE \
s0 = ( *s << biH ) >> biH; \
s1 = ( *s >> biH ); s++; \
rx = s0 * b1; r0 = s0 * b0; \
ry = s1 * b0; r1 = s1 * b1; \
r1 += ( rx >> biH ); \
r1 += ( ry >> biH ); \
rx <<= biH; ry <<= biH; \
r0 += rx; r1 += (r0 < rx); \
r0 += ry; r1 += (r0 < ry); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#endif /* C (generic) */
#endif /* C (longlong) */
#endif /* bn_mul.h */

View File

@@ -1,262 +0,0 @@
/**
* \file certs.h
*
* \brief Sample certificates and DHM parameters for testing
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_CERTS_H
#define MBEDTLS_CERTS_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* List of all PEM-encoded CA certificates, terminated by NULL;
* PEM encoded if MBEDTLS_PEM_PARSE_C is enabled, DER encoded
* otherwise. */
extern const char * mbedtls_test_cas[];
extern const size_t mbedtls_test_cas_len[];
/* List of all DER-encoded CA certificates, terminated by NULL */
extern const unsigned char * mbedtls_test_cas_der[];
extern const size_t mbedtls_test_cas_der_len[];
#if defined(MBEDTLS_PEM_PARSE_C)
/* Concatenation of all CA certificates in PEM format if available */
extern const char mbedtls_test_cas_pem[];
extern const size_t mbedtls_test_cas_pem_len;
#endif /* MBEDTLS_PEM_PARSE_C */
/*
* CA test certificates
*/
extern const char mbedtls_test_ca_crt_ec_pem[];
extern const char mbedtls_test_ca_key_ec_pem[];
extern const char mbedtls_test_ca_pwd_ec_pem[];
extern const char mbedtls_test_ca_key_rsa_pem[];
extern const char mbedtls_test_ca_pwd_rsa_pem[];
extern const char mbedtls_test_ca_crt_rsa_sha1_pem[];
extern const char mbedtls_test_ca_crt_rsa_sha256_pem[];
extern const unsigned char mbedtls_test_ca_crt_ec_der[];
extern const unsigned char mbedtls_test_ca_key_ec_der[];
extern const unsigned char mbedtls_test_ca_key_rsa_der[];
extern const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[];
extern const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[];
extern const size_t mbedtls_test_ca_crt_ec_pem_len;
extern const size_t mbedtls_test_ca_key_ec_pem_len;
extern const size_t mbedtls_test_ca_pwd_ec_pem_len;
extern const size_t mbedtls_test_ca_key_rsa_pem_len;
extern const size_t mbedtls_test_ca_pwd_rsa_pem_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len;
extern const size_t mbedtls_test_ca_crt_ec_der_len;
extern const size_t mbedtls_test_ca_key_ec_der_len;
extern const size_t mbedtls_test_ca_pwd_ec_der_len;
extern const size_t mbedtls_test_ca_key_rsa_der_len;
extern const size_t mbedtls_test_ca_pwd_rsa_der_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha1_der_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha256_der_len;
/* Config-dependent dispatch between PEM and DER encoding
* (PEM if enabled, otherwise DER) */
extern const char mbedtls_test_ca_crt_ec[];
extern const char mbedtls_test_ca_key_ec[];
extern const char mbedtls_test_ca_pwd_ec[];
extern const char mbedtls_test_ca_key_rsa[];
extern const char mbedtls_test_ca_pwd_rsa[];
extern const char mbedtls_test_ca_crt_rsa_sha1[];
extern const char mbedtls_test_ca_crt_rsa_sha256[];
extern const size_t mbedtls_test_ca_crt_ec_len;
extern const size_t mbedtls_test_ca_key_ec_len;
extern const size_t mbedtls_test_ca_pwd_ec_len;
extern const size_t mbedtls_test_ca_key_rsa_len;
extern const size_t mbedtls_test_ca_pwd_rsa_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha1_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha256_len;
/* Config-dependent dispatch between SHA-1 and SHA-256
* (SHA-256 if enabled, otherwise SHA-1) */
extern const char mbedtls_test_ca_crt_rsa[];
extern const size_t mbedtls_test_ca_crt_rsa_len;
/* Config-dependent dispatch between EC and RSA
* (RSA if enabled, otherwise EC) */
extern const char * mbedtls_test_ca_crt;
extern const char * mbedtls_test_ca_key;
extern const char * mbedtls_test_ca_pwd;
extern const size_t mbedtls_test_ca_crt_len;
extern const size_t mbedtls_test_ca_key_len;
extern const size_t mbedtls_test_ca_pwd_len;
/*
* Server test certificates
*/
extern const char mbedtls_test_srv_crt_ec_pem[];
extern const char mbedtls_test_srv_key_ec_pem[];
extern const char mbedtls_test_srv_pwd_ec_pem[];
extern const char mbedtls_test_srv_key_rsa_pem[];
extern const char mbedtls_test_srv_pwd_rsa_pem[];
extern const char mbedtls_test_srv_crt_rsa_sha1_pem[];
extern const char mbedtls_test_srv_crt_rsa_sha256_pem[];
extern const unsigned char mbedtls_test_srv_crt_ec_der[];
extern const unsigned char mbedtls_test_srv_key_ec_der[];
extern const unsigned char mbedtls_test_srv_key_rsa_der[];
extern const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[];
extern const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[];
extern const size_t mbedtls_test_srv_crt_ec_pem_len;
extern const size_t mbedtls_test_srv_key_ec_pem_len;
extern const size_t mbedtls_test_srv_pwd_ec_pem_len;
extern const size_t mbedtls_test_srv_key_rsa_pem_len;
extern const size_t mbedtls_test_srv_pwd_rsa_pem_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len;
extern const size_t mbedtls_test_srv_crt_ec_der_len;
extern const size_t mbedtls_test_srv_key_ec_der_len;
extern const size_t mbedtls_test_srv_pwd_ec_der_len;
extern const size_t mbedtls_test_srv_key_rsa_der_len;
extern const size_t mbedtls_test_srv_pwd_rsa_der_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha1_der_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha256_der_len;
/* Config-dependent dispatch between PEM and DER encoding
* (PEM if enabled, otherwise DER) */
extern const char mbedtls_test_srv_crt_ec[];
extern const char mbedtls_test_srv_key_ec[];
extern const char mbedtls_test_srv_pwd_ec[];
extern const char mbedtls_test_srv_key_rsa[];
extern const char mbedtls_test_srv_pwd_rsa[];
extern const char mbedtls_test_srv_crt_rsa_sha1[];
extern const char mbedtls_test_srv_crt_rsa_sha256[];
extern const size_t mbedtls_test_srv_crt_ec_len;
extern const size_t mbedtls_test_srv_key_ec_len;
extern const size_t mbedtls_test_srv_pwd_ec_len;
extern const size_t mbedtls_test_srv_key_rsa_len;
extern const size_t mbedtls_test_srv_pwd_rsa_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha1_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha256_len;
/* Config-dependent dispatch between SHA-1 and SHA-256
* (SHA-256 if enabled, otherwise SHA-1) */
extern const char mbedtls_test_srv_crt_rsa[];
extern const size_t mbedtls_test_srv_crt_rsa_len;
/* Config-dependent dispatch between EC and RSA
* (RSA if enabled, otherwise EC) */
extern const char * mbedtls_test_srv_crt;
extern const char * mbedtls_test_srv_key;
extern const char * mbedtls_test_srv_pwd;
extern const size_t mbedtls_test_srv_crt_len;
extern const size_t mbedtls_test_srv_key_len;
extern const size_t mbedtls_test_srv_pwd_len;
/*
* Client test certificates
*/
extern const char mbedtls_test_cli_crt_ec_pem[];
extern const char mbedtls_test_cli_key_ec_pem[];
extern const char mbedtls_test_cli_pwd_ec_pem[];
extern const char mbedtls_test_cli_key_rsa_pem[];
extern const char mbedtls_test_cli_pwd_rsa_pem[];
extern const char mbedtls_test_cli_crt_rsa_pem[];
extern const unsigned char mbedtls_test_cli_crt_ec_der[];
extern const unsigned char mbedtls_test_cli_key_ec_der[];
extern const unsigned char mbedtls_test_cli_key_rsa_der[];
extern const unsigned char mbedtls_test_cli_crt_rsa_der[];
extern const size_t mbedtls_test_cli_crt_ec_pem_len;
extern const size_t mbedtls_test_cli_key_ec_pem_len;
extern const size_t mbedtls_test_cli_pwd_ec_pem_len;
extern const size_t mbedtls_test_cli_key_rsa_pem_len;
extern const size_t mbedtls_test_cli_pwd_rsa_pem_len;
extern const size_t mbedtls_test_cli_crt_rsa_pem_len;
extern const size_t mbedtls_test_cli_crt_ec_der_len;
extern const size_t mbedtls_test_cli_key_ec_der_len;
extern const size_t mbedtls_test_cli_key_rsa_der_len;
extern const size_t mbedtls_test_cli_crt_rsa_der_len;
/* Config-dependent dispatch between PEM and DER encoding
* (PEM if enabled, otherwise DER) */
extern const char mbedtls_test_cli_crt_ec[];
extern const char mbedtls_test_cli_key_ec[];
extern const char mbedtls_test_cli_pwd_ec[];
extern const char mbedtls_test_cli_key_rsa[];
extern const char mbedtls_test_cli_pwd_rsa[];
extern const char mbedtls_test_cli_crt_rsa[];
extern const size_t mbedtls_test_cli_crt_ec_len;
extern const size_t mbedtls_test_cli_key_ec_len;
extern const size_t mbedtls_test_cli_pwd_ec_len;
extern const size_t mbedtls_test_cli_key_rsa_len;
extern const size_t mbedtls_test_cli_pwd_rsa_len;
extern const size_t mbedtls_test_cli_crt_rsa_len;
/* Config-dependent dispatch between EC and RSA
* (RSA if enabled, otherwise EC) */
extern const char * mbedtls_test_cli_crt;
extern const char * mbedtls_test_cli_key;
extern const char * mbedtls_test_cli_pwd;
extern const size_t mbedtls_test_cli_crt_len;
extern const size_t mbedtls_test_cli_key_len;
extern const size_t mbedtls_test_cli_pwd_len;
#ifdef __cplusplus
}
#endif
#endif /* certs.h */

View File

@@ -1,746 +0,0 @@
/**
* \file check_config.h
*
* \brief Consistency checks for configuration options
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
/*
* It is recommended to include this file from your config.h
* in order to catch dependency issues early.
*/
#ifndef MBEDTLS_CHECK_CONFIG_H
#define MBEDTLS_CHECK_CONFIG_H
/*
* We assume CHAR_BIT is 8 in many places. In practice, this is true on our
* target platforms, so not an issue, but let's just be extra sure.
*/
#include <limits.h>
#if CHAR_BIT != 8
#error "mbed TLS requires a platform with 8-bit chars"
#endif
#if defined(TARGET_LIKE_MBED) && \
( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) )
#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
#endif
#if defined(MBEDTLS_DEPRECATED_WARNING) && \
!defined(__GNUC__) && !defined(__clang__)
#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang"
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME)
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
#endif
#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C)
#error "MBEDTLS_DHM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDTLS_SSL_TRUNCATED_HMAC)
#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CMAC_C) && \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C)
#error "MBEDTLS_CMAC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_NIST_KW_C) && \
( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) )
#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_C) && \
( !defined(MBEDTLS_ECP_C) || \
!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_ASN1_WRITE_C) )
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECJPAKE_C) && \
( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) )
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \
defined(MBEDTLS_ECDSA_SIGN_ALT) || \
defined(MBEDTLS_ECDSA_VERIFY_ALT) || \
defined(MBEDTLS_ECDSA_GENKEY_ALT) || \
defined(MBEDTLS_ECP_INTERNAL_ALT) || \
defined(MBEDTLS_ECP_ALT) )
#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \
!defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) )
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_C) && !( \
defined(MBEDTLS_ECP_ALT) || \
defined(MBEDTLS_CTR_DRBG_C) || \
defined(MBEDTLS_HMAC_DRBG_C) || \
defined(MBEDTLS_SHA512_C) || \
defined(MBEDTLS_SHA256_C) || \
defined(MBEDTLS_ECP_NO_INTERNAL_RNG))
#error "MBEDTLS_ECP_C requires a DRBG or SHA-2 module unless MBEDTLS_ECP_NO_INTERNAL_RNG is defined or an alternative implementation is used"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA256_C))
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \
defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \
&& defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C)
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define MBEDTLS_HAS_MEMSAN
#endif
#endif
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN)
#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer"
#endif
#undef MBEDTLS_HAS_MEMSAN
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
defined(MBEDTLS_HAVEGE_C) )
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too"
#endif
#if defined(MBEDTLS_GCM_C) && ( \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HKDF_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C)
#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
!defined(MBEDTLS_ECDH_C)
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites"
#endif
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_C) && \
( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) )
#error "MBEDTLS_PK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\
defined(MBEDTLS_PLATFORM_EXIT_ALT) )
#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
defined(MBEDTLS_PLATFORM_TIME_ALT) )
#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
defined(MBEDTLS_PLATFORM_TIME_ALT) )
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\
defined(MBEDTLS_PLATFORM_FPRINTF_ALT) )
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
defined(MBEDTLS_PLATFORM_STD_FREE)
#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
defined(MBEDTLS_PLATFORM_STD_CALLOC)
#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO)
#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is"
#endif
#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\
defined(MBEDTLS_PLATFORM_PRINTF_ALT) )
#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\
defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) )
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\
!defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\
!defined(MBEDTLS_PLATFORM_EXIT_ALT)
#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\
( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\
!defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\
!defined(MBEDTLS_PLATFORM_PRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\
!defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) )
#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\
!defined(MBEDTLS_ENTROPY_NV_SEED)
#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) )
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled"
#endif
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) )
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \
!defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \
!(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) )
#error "One or more versions of the TLS protocol are enabled " \
"but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx"
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C)
#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \
!defined(MBEDTLS_MD_C) )
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C)
#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2))
#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \
!defined(MBEDTLS_SSL_PROTO_TLS1_1)))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS)
#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
!defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \
!defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1)
#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
!defined(MBEDTLS_X509_CRT_PARSE_C)
#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_THREADING_PTHREAD)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif
#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif
#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_C defined, single threading implementation required"
#endif
#undef MBEDTLS_THREADING_IMPL
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_PK_PARSE_C) )
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \
!defined(MBEDTLS_PK_WRITE_C) )
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C)
#error "MBEDTLS_CERTS_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64)
#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously"
#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */
#if ( defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64) ) && \
defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously"
#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
* #if defined(MBEDTLS_xxx_C) that results in empty translation units.
*/
typedef int mbedtls_iso_c_forbids_empty_translation_units;
#endif /* MBEDTLS_CHECK_CONFIG_H */

View File

@@ -1,882 +0,0 @@
/**
* \file cipher.h
*
* \brief This file contains an abstraction interface for use with the cipher
* primitives provided by the library. It provides a common interface to all of
* the available cipher operations.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_CIPHER_H
#define MBEDTLS_CIPHER_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include "platform_util.h"
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#define MBEDTLS_CIPHER_MODE_AEAD
#endif
#if defined(MBEDTLS_CIPHER_MODE_CBC)
#define MBEDTLS_CIPHER_MODE_WITH_PADDING
#endif
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
defined(MBEDTLS_CHACHA20_C)
#define MBEDTLS_CIPHER_MODE_STREAM
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */
#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */
#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */
/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */
#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */
#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Supported cipher types.
*
* \warning RC4 and DES are considered weak ciphers and their use
* constitutes a security risk. Arm recommends considering stronger
* ciphers instead.
*/
typedef enum {
MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */
MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */
MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */
MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */
MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */
MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */
MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */
MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */
MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */
MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */
} mbedtls_cipher_id_t;
/**
* \brief Supported {cipher type, cipher mode} pairs.
*
* \warning RC4 and DES are considered weak ciphers and their use
* constitutes a security risk. Arm recommends considering stronger
* ciphers instead.
*/
typedef enum {
MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */
MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */
MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */
MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */
MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */
MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */
MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */
MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */
MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */
MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */
MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */
MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */
MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */
MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */
MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */
MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */
MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */
MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */
MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */
MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */
MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */
MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */
MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */
MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */
MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */
MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */
MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */
MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */
MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */
MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */
MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */
MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */
MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */
MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */
MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */
MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */
MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */
MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */
MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */
MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */
MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */
MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */
MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */
MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */
MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */
MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */
MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */
MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */
MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */
MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */
MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */
MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */
MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */
MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */
MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */
MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */
MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */
MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */
MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */
} mbedtls_cipher_type_t;
/** Supported cipher modes. */
typedef enum {
MBEDTLS_MODE_NONE = 0, /**< None. */
MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */
MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */
MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */
MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */
MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */
MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */
MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */
MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */
MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */
MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */
} mbedtls_cipher_mode_t;
/** Supported cipher padding types. */
typedef enum {
MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */
MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */
MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */
MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */
MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */
} mbedtls_cipher_padding_t;
/** Type of operation. */
typedef enum {
MBEDTLS_OPERATION_NONE = -1,
MBEDTLS_DECRYPT = 0,
MBEDTLS_ENCRYPT,
} mbedtls_operation_t;
enum {
/** Undefined key length. */
MBEDTLS_KEY_LENGTH_NONE = 0,
/** Key length, in bits (including parity), for DES keys. */
MBEDTLS_KEY_LENGTH_DES = 64,
/** Key length in bits, including parity, for DES in two-key EDE. */
MBEDTLS_KEY_LENGTH_DES_EDE = 128,
/** Key length in bits, including parity, for DES in three-key EDE. */
MBEDTLS_KEY_LENGTH_DES_EDE3 = 192,
};
/** Maximum length of any IV, in Bytes. */
#define MBEDTLS_MAX_IV_LENGTH 16
/** Maximum block size of any cipher, in Bytes. */
#define MBEDTLS_MAX_BLOCK_LENGTH 16
/**
* Base cipher information (opaque struct).
*/
typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t;
/**
* CMAC context (opaque struct).
*/
typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
/**
* Cipher information. Allows calling cipher functions
* in a generic way.
*/
typedef struct mbedtls_cipher_info_t
{
/** Full cipher identifier. For example,
* MBEDTLS_CIPHER_AES_256_CBC.
*/
mbedtls_cipher_type_t type;
/** The cipher mode. For example, MBEDTLS_MODE_CBC. */
mbedtls_cipher_mode_t mode;
/** The cipher key length, in bits. This is the
* default length for variable sized ciphers.
* Includes parity bits for ciphers like DES.
*/
unsigned int key_bitlen;
/** Name of the cipher. */
const char * name;
/** IV or nonce size, in Bytes.
* For ciphers that accept variable IV sizes,
* this is the recommended size.
*/
unsigned int iv_size;
/** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
* MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
* cipher supports variable IV or variable key sizes, respectively.
*/
int flags;
/** The block size, in Bytes. */
unsigned int block_size;
/** Struct for base cipher information and functions. */
const mbedtls_cipher_base_t *base;
} mbedtls_cipher_info_t;
/**
* Generic cipher context.
*/
typedef struct mbedtls_cipher_context_t
{
/** Information about the associated cipher. */
const mbedtls_cipher_info_t *cipher_info;
/** Key length to use. */
int key_bitlen;
/** Operation that the key of the context has been
* initialized for.
*/
mbedtls_operation_t operation;
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/** Padding functions to use, if relevant for
* the specific cipher mode.
*/
void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
#endif
/** Buffer for input that has not been processed yet. */
unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
/** Number of Bytes that have not been processed yet. */
size_t unprocessed_len;
/** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number
* for XTS-mode. */
unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
/** IV size in Bytes, for ciphers with variable-length IVs. */
size_t iv_size;
/** The cipher-specific context. */
void *cipher_ctx;
#if defined(MBEDTLS_CMAC_C)
/** CMAC-specific context. */
mbedtls_cmac_context_t *cmac_ctx;
#endif
} mbedtls_cipher_context_t;
/**
* \brief This function retrieves the list of ciphers supported by the generic
* cipher module.
*
* \return A statically-allocated array of ciphers. The last entry
* is zero.
*/
const int *mbedtls_cipher_list( void );
/**
* \brief This function retrieves the cipher-information
* structure associated with the given cipher name.
*
* \param cipher_name Name of the cipher to search for. This must not be
* \c NULL.
*
* \return The cipher information structure associated with the
* given \p cipher_name.
* \return \c NULL if the associated cipher information is not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
/**
* \brief This function retrieves the cipher-information
* structure associated with the given cipher type.
*
* \param cipher_type Type of the cipher to search for.
*
* \return The cipher information structure associated with the
* given \p cipher_type.
* \return \c NULL if the associated cipher information is not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
/**
* \brief This function retrieves the cipher-information
* structure associated with the given cipher ID,
* key size and mode.
*
* \param cipher_id The ID of the cipher to search for. For example,
* #MBEDTLS_CIPHER_ID_AES.
* \param key_bitlen The length of the key in bits.
* \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC.
*
* \return The cipher information structure associated with the
* given \p cipher_id.
* \return \c NULL if the associated cipher information is not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
int key_bitlen,
const mbedtls_cipher_mode_t mode );
/**
* \brief This function initializes a \p cipher_context as NONE.
*
* \param ctx The context to be initialized. This must not be \c NULL.
*/
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
/**
* \brief This function frees and clears the cipher-specific
* context of \p ctx. Freeing \p ctx itself remains the
* responsibility of the caller.
*
* \param ctx The context to be freed. If this is \c NULL, the
* function has no effect, otherwise this must point to an
* initialized context.
*/
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
/**
* \brief This function initializes and fills the cipher-context
* structure with the appropriate values. It also clears
* the structure.
*
* \param ctx The context to initialize. This must be initialized.
* \param cipher_info The cipher to use.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
* cipher-specific context fails.
*
* \internal Currently, the function also clears the structure.
* In future versions, the caller will be required to call
* mbedtls_cipher_init() on the structure first.
*/
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
const mbedtls_cipher_info_t *cipher_info );
/**
* \brief This function returns the block size of the given cipher.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The block size of the underlying cipher.
* \return \c 0 if \p ctx has not been initialized.
*/
static inline unsigned int mbedtls_cipher_get_block_size(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
if( ctx->cipher_info == NULL )
return 0;
return ctx->cipher_info->block_size;
}
/**
* \brief This function returns the mode of operation for
* the cipher. For example, MBEDTLS_MODE_CBC.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The mode of operation.
* \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
*/
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE );
if( ctx->cipher_info == NULL )
return MBEDTLS_MODE_NONE;
return ctx->cipher_info->mode;
}
/**
* \brief This function returns the size of the IV or nonce
* of the cipher, in Bytes.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The recommended IV size if no IV has been set.
* \return \c 0 for ciphers not using an IV or a nonce.
* \return The actual size if an IV has been set.
*/
static inline int mbedtls_cipher_get_iv_size(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
if( ctx->cipher_info == NULL )
return 0;
if( ctx->iv_size != 0 )
return (int) ctx->iv_size;
return (int) ctx->cipher_info->iv_size;
}
/**
* \brief This function returns the type of the given cipher.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The type of the cipher.
* \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
*/
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_CIPHER_NONE );
if( ctx->cipher_info == NULL )
return MBEDTLS_CIPHER_NONE;
return ctx->cipher_info->type;
}
/**
* \brief This function returns the name of the given cipher
* as a string.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The name of the cipher.
* \return NULL if \p ctx has not been not initialized.
*/
static inline const char *mbedtls_cipher_get_name(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
if( ctx->cipher_info == NULL )
return 0;
return ctx->cipher_info->name;
}
/**
* \brief This function returns the key length of the cipher.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The key length of the cipher in bits.
* \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
* initialized.
*/
static inline int mbedtls_cipher_get_key_bitlen(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_KEY_LENGTH_NONE );
if( ctx->cipher_info == NULL )
return MBEDTLS_KEY_LENGTH_NONE;
return (int) ctx->cipher_info->key_bitlen;
}
/**
* \brief This function returns the operation of the given cipher.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
* \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
*/
static inline mbedtls_operation_t mbedtls_cipher_get_operation(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_OPERATION_NONE );
if( ctx->cipher_info == NULL )
return MBEDTLS_OPERATION_NONE;
return ctx->operation;
}
/**
* \brief This function sets the key to use with the given context.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
* \param key The key to use. This must be a readable buffer of at
* least \p key_bitlen Bits.
* \param key_bitlen The key length to use, in Bits.
* \param operation The operation that the key will be used for:
* #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
const unsigned char *key,
int key_bitlen,
const mbedtls_operation_t operation );
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/**
* \brief This function sets the padding mode, for cipher modes
* that use padding.
*
* The default passing mode is PKCS7 padding.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
* \param mode The padding mode.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
* if the selected padding mode is not supported.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
* does not support padding.
*/
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
mbedtls_cipher_padding_t mode );
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
/**
* \brief This function sets the initialization vector (IV)
* or nonce.
*
* \note Some ciphers do not use IVs nor nonce. For these
* ciphers, this function has no effect.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
* must be a readable buffer of at least \p iv_len Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size IV.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
*/
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
const unsigned char *iv,
size_t iv_len );
/**
* \brief This function resets the cipher state.
*
* \param ctx The generic cipher context. This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
*/
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/**
* \brief This function adds additional data for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called exactly once, after
* mbedtls_cipher_reset().
*
* \param ctx The generic cipher context. This must be initialized.
* \param ad The additional data to use. This must be a readable
* buffer of at least \p ad_len Bytes.
* \param ad_len the Length of \p ad Bytes.
*
* \return \c 0 on success.
* \return A specific error code on failure.
*/
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len );
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
/**
* \brief The generic cipher update function. It encrypts or
* decrypts using the given cipher context. Writes as
* many block-sized blocks of data as possible to output.
* Any data that cannot be written immediately is either
* added to the next block, or flushed when
* mbedtls_cipher_finish() is called.
* Exception: For MBEDTLS_MODE_ECB, expects a single block
* in size. For example, 16 Bytes for AES.
*
* \note If the underlying cipher is used in GCM mode, all calls
* to this function, except for the last one before
* mbedtls_cipher_finish(), must have \p ilen as a
* multiple of the block size of the cipher.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data.
* \param output The buffer for the output data. This must be able to
* hold at least `ilen + block_size`. This must not be the
* same buffer as \p input.
* \param olen The length of the output data, to be updated with the
* actual number of Bytes written. This must not be
* \c NULL.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
* unsupported mode for a cipher.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
size_t ilen, unsigned char *output, size_t *olen );
/**
* \brief The generic cipher finalization function. If data still
* needs to be flushed from an incomplete block, the data
* contained in it is padded to the size of
* the last block, and written to the \p output buffer.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param output The buffer to write data to. This needs to be a writable
* buffer of at least \p block_size Bytes.
* \param olen The length of the data written to the \p output buffer.
* This may not be \c NULL.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
* expecting a full block but not receiving one.
* \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/**
* \brief This function writes a tag for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called after mbedtls_cipher_finish().
*
* \param ctx The generic cipher context. This must be initialized,
* bound to a key, and have just completed a cipher
* operation through mbedtls_cipher_finish() the tag for
* which should be written.
* \param tag The buffer to write the tag to. This must be a writable
* buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to write.
*
* \return \c 0 on success.
* \return A specific error code on failure.
*/
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
unsigned char *tag, size_t tag_len );
/**
* \brief This function checks the tag for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called after mbedtls_cipher_finish().
*
* \param ctx The generic cipher context. This must be initialized.
* \param tag The buffer holding the tag. This must be a readable
* buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to check.
*
* \return \c 0 on success.
* \return A specific error code on failure.
*/
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len );
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
/**
* \brief The generic all-in-one encryption/decryption function,
* for all ciphers except AEAD constructs.
*
* \param ctx The generic cipher context. This must be initialized.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* This must be a readable buffer of at least \p iv_len
* Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size
* IV.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data in Bytes.
* \param output The buffer for the output data. This must be able to
* hold at least `ilen + block_size`. This must not be the
* same buffer as \p input.
* \param olen The length of the output data, to be updated with the
* actual number of Bytes written. This must not be
* \c NULL.
*
* \note Some ciphers do not use IVs nor nonce. For these
* ciphers, use \p iv = NULL and \p iv_len = 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
* expecting a full block but not receiving one.
* \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
/**
* \brief The generic autenticated encryption (AEAD) function.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* This must be a readable buffer of at least \p iv_len
* Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size IV.
* \param ad The additional data to authenticate. This must be a
* readable buffer of at least \p ad_len Bytes.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data.
* \param output The buffer for the output data. This must be able to
* hold at least \p ilen Bytes.
* \param olen The length of the output data, to be updated with the
* actual number of Bytes written. This must not be
* \c NULL.
* \param tag The buffer for the authentication tag. This must be a
* writable buffer of at least \p tag_len Bytes.
* \param tag_len The desired length of the authentication tag.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
unsigned char *tag, size_t tag_len );
/**
* \brief The generic autenticated decryption (AEAD) function.
*
* \note If the data is not authentic, then the output buffer
* is zeroed out to prevent the unauthentic plaintext being
* used, making this interface safer.
*
* \param ctx The generic cipher context. This must be initialized and
* and bound to a key.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* This must be a readable buffer of at least \p iv_len
* Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size IV.
* \param ad The additional data to be authenticated. This must be a
* readable buffer of at least \p ad_len Bytes.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data.
* \param output The buffer for the output data.
* This must be able to hold at least \p ilen Bytes.
* \param olen The length of the output data, to be updated with the
* actual number of Bytes written. This must not be
* \c NULL.
* \param tag The buffer holding the authentication tag. This must be
* a readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication tag.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
const unsigned char *tag, size_t tag_len );
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CIPHER_H */

View File

@@ -1,135 +0,0 @@
/**
* \file cipher_internal.h
*
* \brief Cipher wrappers.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_CIPHER_WRAP_H
#define MBEDTLS_CIPHER_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "cipher.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Base cipher information. The non-mode specific functions and values.
*/
struct mbedtls_cipher_base_t
{
/** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
mbedtls_cipher_id_t cipher;
/** Encrypt using ECB */
int (*ecb_func)( void *ctx, mbedtls_operation_t mode,
const unsigned char *input, unsigned char *output );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/** Encrypt using CBC */
int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length,
unsigned char *iv, const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/** Encrypt using CFB (Full length) */
int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
unsigned char *iv, const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/** Encrypt using OFB (Full length) */
int (*ofb_func)( void *ctx, size_t length, size_t *iv_off,
unsigned char *iv,
const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/** Encrypt using CTR */
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/** Encrypt or decrypt using XTS. */
int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length,
const unsigned char data_unit[16],
const unsigned char *input, unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
/** Encrypt using STREAM */
int (*stream_func)( void *ctx, size_t length,
const unsigned char *input, unsigned char *output );
#endif
/** Set key for encryption purposes */
int (*setkey_enc_func)( void *ctx, const unsigned char *key,
unsigned int key_bitlen );
/** Set key for decryption purposes */
int (*setkey_dec_func)( void *ctx, const unsigned char *key,
unsigned int key_bitlen);
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** Free the given context */
void (*ctx_free_func)( void *ctx );
};
typedef struct
{
mbedtls_cipher_type_t type;
const mbedtls_cipher_info_t *info;
} mbedtls_cipher_definition_t;
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
extern int mbedtls_cipher_supported[];
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CIPHER_WRAP_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,569 +0,0 @@
/**
* \file ctr_drbg.h
*
* \brief This file contains definitions and functions for the
* CTR_DRBG pseudorandom generator.
*
* CTR_DRBG is a standardized way of building a PRNG from a block-cipher
* in counter mode operation, as defined in <em>NIST SP 800-90A:
* Recommendation for Random Number Generation Using Deterministic Random
* Bit Generators</em>.
*
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
* (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
* as the underlying block cipher, with a derivation function.
* The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy.
* See the documentation of mbedtls_ctr_drbg_seed() for more details.
*
* Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2,
* here are the security strengths achieved in typical configuration:
* - 256 bits under the default configuration of the library, with AES-256
* and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more.
* - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set
* to 32 or more, and the DRBG is initialized with an explicit
* nonce in the \c custom parameter to mbedtls_ctr_drbg_seed().
* - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
* between 24 and 47 and the DRBG is not initialized with an explicit
* nonce (see mbedtls_ctr_drbg_seed()).
* - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
* and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is
* always the case unless it is explicitly set to a different value
* in config.h).
*
* Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to:
* - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time.
* This is the default configuration of the library.
* - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time.
* - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time.
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_CTR_DRBG_H
#define MBEDTLS_CTR_DRBG_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "aes.h"
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#endif
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< The requested random buffer length is too big. */
#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< The input (entropy + additional data) is too large. */
#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read or write error in file. */
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
#define MBEDTLS_CTR_DRBG_KEYSIZE 16
/**< The key size in bytes used by the cipher.
*
* Compile-time choice: 16 bytes (128 bits)
* because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled.
*/
#else
#define MBEDTLS_CTR_DRBG_KEYSIZE 32
/**< The key size in bytes used by the cipher.
*
* Compile-time choice: 32 bytes (256 bits)
* because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled.
*/
#endif
#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
#define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them using the compiler command
* line.
* \{
*/
/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN
*
* \brief The amount of entropy used per seed by default, in bytes.
*/
#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
/** This is 48 bytes because the entropy module uses SHA-512
* (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled).
*/
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48
#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
/** This is 32 bytes because the entropy module uses SHA-256
* (the SHA512 module is disabled or
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled).
*/
#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
/** \warning To achieve a 256-bit security strength, you must pass a nonce
* to mbedtls_ctr_drbg_seed().
*/
#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32
#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000
/**< The interval before reseed is performed by default. */
#endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_INPUT 256
/**< The maximum number of additional input Bytes. */
#endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST)
#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024
/**< The maximum number of requested Bytes per call. */
#endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384
/**< The maximum size of seed or reseed buffer in bytes. */
#endif
/* \} name SECTION: Module settings */
#define MBEDTLS_CTR_DRBG_PR_OFF 0
/**< Prediction resistance is disabled. */
#define MBEDTLS_CTR_DRBG_PR_ON 1
/**< Prediction resistance is enabled. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The CTR_DRBG context structure.
*/
typedef struct mbedtls_ctr_drbg_context
{
unsigned char counter[16]; /*!< The counter (V). */
int reseed_counter; /*!< The reseed counter. */
int prediction_resistance; /*!< This determines whether prediction
resistance is enabled, that is
whether to systematically reseed before
each random generation. */
size_t entropy_len; /*!< The amount of entropy grabbed on each
seed or reseed operation. */
int reseed_interval; /*!< The reseed interval. */
mbedtls_aes_context aes_ctx; /*!< The AES context. */
/*
* Callbacks (Entropy)
*/
int (*f_entropy)(void *, unsigned char *, size_t);
/*!< The entropy callback function. */
void *p_entropy; /*!< The context for the entropy function. */
#if defined(MBEDTLS_THREADING_C)
/* Invariant: the mutex is initialized if and only if f_entropy != NULL.
* This means that the mutex is initialized during the initial seeding
* in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free().
*
* Note that this invariant may change without notice. Do not rely on it
* and do not access the mutex directly in application code.
*/
mbedtls_threading_mutex_t mutex;
#endif
}
mbedtls_ctr_drbg_context;
/**
* \brief This function initializes the CTR_DRBG context,
* and prepares it for mbedtls_ctr_drbg_seed()
* or mbedtls_ctr_drbg_free().
*
* \note The reseed interval is
* #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default.
* You can override it by calling
* mbedtls_ctr_drbg_set_reseed_interval().
*
* \param ctx The CTR_DRBG context to initialize.
*/
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
/**
* \brief This function seeds and sets up the CTR_DRBG
* entropy source for future reseeds.
*
* A typical choice for the \p f_entropy and \p p_entropy parameters is
* to use the entropy module:
* - \p f_entropy is mbedtls_entropy_func();
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
* with mbedtls_entropy_init() (which registers the platform's default
* entropy sources).
*
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
*
* You can provide a personalization string in addition to the
* entropy source, to make this instantiation as unique as possible.
*
* \note The _seed_material_ value passed to the derivation
* function in the CTR_DRBG Instantiate Process
* described in NIST SP 800-90A §10.2.1.3.2
* is the concatenation of the string obtained from
* calling \p f_entropy and the \p custom string.
* The origin of the nonce depends on the value of
* the entropy length relative to the security strength.
* - If the entropy length is at least 1.5 times the
* security strength then the nonce is taken from the
* string obtained with \p f_entropy.
* - If the entropy length is less than the security
* strength, then the nonce is taken from \p custom.
* In this case, for compliance with SP 800-90A,
* you must pass a unique value of \p custom at
* each invocation. See SP 800-90A §8.6.7 for more
* details.
*/
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than
* #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the
* maximum security strength permitted by CTR_DRBG,
* you must pass a value of \p custom that is a nonce:
* this value must never be repeated in subsequent
* runs of the same application or on a different
* device.
*/
#endif
#if defined(MBEDTLS_THREADING_C)
/**
* \note When Mbed TLS is built with threading support,
* after this function returns successfully,
* it is safe to call mbedtls_ctr_drbg_random()
* from multiple threads. Other operations, including
* reseeding, are not thread-safe.
*/
#endif /* MBEDTLS_THREADING_C */
/**
* \param ctx The CTR_DRBG context to seed.
* It must have been initialized with
* mbedtls_ctr_drbg_init().
* After a successful call to mbedtls_ctr_drbg_seed(),
* you may not call mbedtls_ctr_drbg_seed() again on
* the same context unless you call
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
* again first.
* After a failed call to mbedtls_ctr_drbg_seed(),
* you must call mbedtls_ctr_drbg_free().
* \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the
* length of the buffer.
* \p f_entropy is always called with a buffer size
* equal to the entropy length.
* \param p_entropy The entropy context to pass to \p f_entropy.
* \param custom The personalization string.
* This can be \c NULL, in which case the personalization
* string is empty regardless of the value of \p len.
* \param len The length of the personalization string.
* This must be at most
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
* - #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
*/
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len );
/**
* \brief This function resets CTR_DRBG context to the state immediately
* after initial call of mbedtls_ctr_drbg_init().
*
* \param ctx The CTR_DRBG context to clear.
*/
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
/**
* \brief This function turns prediction resistance on or off.
* The default value is off.
*
* \note If enabled, entropy is gathered at the beginning of
* every call to mbedtls_ctr_drbg_random_with_add()
* or mbedtls_ctr_drbg_random().
* Only use this if your entropy source has sufficient
* throughput.
*
* \param ctx The CTR_DRBG context.
* \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF.
*/
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
int resistance );
/**
* \brief This function sets the amount of entropy grabbed on each
* seed or reseed.
*
* The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
*
* \note The security strength of CTR_DRBG is bounded by the
* entropy length. Thus:
* - When using AES-256
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled,
* which is the default),
* \p len must be at least 32 (in bytes)
* to achieve a 256-bit strength.
* - When using AES-128
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled)
* \p len must be at least 16 (in bytes)
* to achieve a 128-bit strength.
*
* \param ctx The CTR_DRBG context.
* \param len The amount of entropy to grab, in bytes.
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
*/
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
size_t len );
/**
* \brief This function sets the reseed interval.
*
* The reseed interval is the number of calls to mbedtls_ctr_drbg_random()
* or mbedtls_ctr_drbg_random_with_add() after which the entropy function
* is called again.
*
* The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
*
* \param ctx The CTR_DRBG context.
* \param interval The reseed interval.
*/
void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
int interval );
/**
* \brief This function reseeds the CTR_DRBG context, that is
* extracts data from the entropy source.
*
* \note This function is not thread-safe. It is not safe
* to call this function if another thread might be
* concurrently obtaining random numbers from the same
* context or updating or reseeding the same context.
*
* \param ctx The CTR_DRBG context.
* \param additional Additional data to add to the state. Can be \c NULL.
* \param len The length of the additional data.
* This must be less than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \c entropy_len is the entropy length
* configured for the context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
*/
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t len );
/**
* \brief This function updates the state of the CTR_DRBG context.
*
* \note This function is not thread-safe. It is not safe
* to call this function if another thread might be
* concurrently obtaining random numbers from the same
* context or updating or reseeding the same context.
*
* \param ctx The CTR_DRBG context.
* \param additional The data to update the state with. This must not be
* \c NULL unless \p add_len is \c 0.
* \param add_len Length of \p additional in bytes. This must be at
* most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
* \p add_len is more than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
* \return An error from the underlying AES cipher on failure.
*/
int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional,
size_t add_len );
/**
* \brief This function updates a CTR_DRBG instance with additional
* data and uses it to generate random data.
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
* \note This function is not thread-safe. It is not safe
* to call this function if another thread might be
* concurrently obtaining random numbers from the same
* context or updating or reseeding the same context.
*
* \param p_rng The CTR_DRBG context. This must be a pointer to a
* #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill.
* \param output_len The length of the buffer in bytes.
* \param additional Additional data to update. Can be \c NULL, in which
* case the additional data is empty regardless of
* the value of \p add_len.
* \param add_len The length of the additional data
* if \p additional is not \c NULL.
* This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT
* and less than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \c entropy_len is the entropy length
* configured for the context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
*/
int mbedtls_ctr_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len,
const unsigned char *additional, size_t add_len );
/**
* \brief This function uses CTR_DRBG to generate random data.
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*/
#if defined(MBEDTLS_THREADING_C)
/**
* \note When Mbed TLS is built with threading support,
* it is safe to call mbedtls_ctr_drbg_random()
* from multiple threads. Other operations, including
* reseeding, are not thread-safe.
*/
#endif /* MBEDTLS_THREADING_C */
/**
* \param p_rng The CTR_DRBG context. This must be a pointer to a
* #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill.
* \param output_len The length of the buffer in bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
*/
int mbedtls_ctr_drbg_random( void *p_rng,
unsigned char *output, size_t output_len );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function updates the state of the CTR_DRBG context.
*
* \deprecated Superseded by mbedtls_ctr_drbg_update_ret()
* in 2.16.0.
*
* \note If \p add_len is greater than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
* The remaining Bytes are silently discarded.
*
* \param ctx The CTR_DRBG context.
* \param additional The data to update the state with.
* \param add_len Length of \p additional data.
*/
MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional,
size_t add_len );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_FS_IO)
/**
* \brief This function writes a seed file.
*
* \param ctx The CTR_DRBG context.
* \param path The name of the file.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed
* failure.
*/
int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
/**
* \brief This function reads and updates a seed file. The seed
* is added to this instance.
*
* \param ctx The CTR_DRBG context.
* \param path The name of the file.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
* reseed failure.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing
* seed file is too large.
*/
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The CTR_DRBG checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_ctr_drbg_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
/* Internal functions (do not call directly) */
int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *,
int (*)(void *, unsigned char *, size_t), void *,
const unsigned char *, size_t, size_t );
#ifdef __cplusplus
}
#endif
#endif /* ctr_drbg.h */

View File

@@ -1,365 +0,0 @@
/**
* \file des.h
*
* \brief DES block cipher
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_DES_H
#define MBEDTLS_DES_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#define MBEDTLS_DES_ENCRYPT 1
#define MBEDTLS_DES_DECRYPT 0
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
/* MBEDTLS_ERR_DES_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED -0x0033 /**< DES hardware accelerator failed. */
#define MBEDTLS_DES_KEY_SIZE 8
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_DES_ALT)
// Regular implementation
//
/**
* \brief DES context structure
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
typedef struct mbedtls_des_context
{
uint32_t sk[32]; /*!< DES subkeys */
}
mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct mbedtls_des3_context
{
uint32_t sk[96]; /*!< 3DES subkeys */
}
mbedtls_des3_context;
#else /* MBEDTLS_DES_ALT */
#include "des_alt.h"
#endif /* MBEDTLS_DES_ALT */
/**
* \brief Initialize DES context
*
* \param ctx DES context to be initialized
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
void mbedtls_des_init( mbedtls_des_context *ctx );
/**
* \brief Clear DES context
*
* \param ctx DES context to be cleared
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
void mbedtls_des_free( mbedtls_des_context *ctx );
/**
* \brief Initialize Triple-DES context
*
* \param ctx DES3 context to be initialized
*/
void mbedtls_des3_init( mbedtls_des3_context *ctx );
/**
* \brief Clear Triple-DES context
*
* \param ctx DES3 context to be cleared
*/
void mbedtls_des3_free( mbedtls_des3_context *ctx );
/**
* \brief Set key parity on the given key to odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key parity on the given key is odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*
* \return 0 is parity was ok, 1 if parity was not correct.
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key is not a weak or semi-weak DES key
*
* \param key 8-byte secret key
*
* \return 0 if no weak key was found, 1 if a weak key was identified.
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, encryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, decryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Triple-DES key schedule (112-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (112-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (168-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief Triple-DES key schedule (168-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief DES-ECB block encryption/decryption
*
* \param ctx DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief 3DES-ECB block encryption/decryption
*
* \param ctx 3DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief 3DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx 3DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
*/
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief Internal function for key expansion.
* (Only exposed to allow overriding it,
* see MBEDTLS_DES_SETKEY_ALT)
*
* \param SK Round keys
* \param key Base key
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
void mbedtls_des_setkey( uint32_t SK[32],
const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_des_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* des.h */

View File

@@ -1,450 +0,0 @@
/**
* \file ecdh.h
*
* \brief This file contains ECDH definitions and functions.
*
* The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous
* key agreement protocol allowing two parties to establish a shared
* secret over an insecure channel. Each party must have an
* elliptic-curve publicprivate key pair.
*
* For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for
* Pair-Wise Key Establishment Schemes Using Discrete Logarithm
* Cryptography</em>.
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_ECDH_H
#define MBEDTLS_ECDH_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ecp.h"
/*
* Use a backward compatible ECDH context.
*
* This flag is always enabled for now and future versions might add a
* configuration option that conditionally undefines this flag.
* The configuration option in question may have a different name.
*
* Features undefining this flag, must have a warning in their description in
* config.h stating that the feature breaks backward compatibility.
*/
#define MBEDTLS_ECDH_LEGACY_CONTEXT
#ifdef __cplusplus
extern "C" {
#endif
/**
* Defines the source of the imported EC key.
*/
typedef enum
{
MBEDTLS_ECDH_OURS, /**< Our key. */
MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */
} mbedtls_ecdh_side;
#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
/**
* Defines the ECDH implementation used.
*
* Later versions of the library may add new variants, therefore users should
* not make any assumptions about them.
*/
typedef enum
{
MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */
MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */
} mbedtls_ecdh_variant;
/**
* The context used by the default ECDH implementation.
*
* Later versions might change the structure of this context, therefore users
* should not make any assumptions about the structure of
* mbedtls_ecdh_context_mbed.
*/
typedef struct mbedtls_ecdh_context_mbed
{
mbedtls_ecp_group grp; /*!< The elliptic curve used. */
mbedtls_mpi d; /*!< The private key. */
mbedtls_ecp_point Q; /*!< The public key. */
mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */
mbedtls_mpi z; /*!< The shared secret. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
#endif
} mbedtls_ecdh_context_mbed;
#endif
/**
*
* \warning Performing multiple operations concurrently on the same
* ECDSA context is not supported; objects of this type
* should not be shared between multiple threads.
* \brief The ECDH context structure.
*/
typedef struct mbedtls_ecdh_context
{
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
mbedtls_ecp_group grp; /*!< The elliptic curve used. */
mbedtls_mpi d; /*!< The private key. */
mbedtls_ecp_point Q; /*!< The public key. */
mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */
mbedtls_mpi z; /*!< The shared secret. */
int point_format; /*!< The format of point export in TLS messages. */
mbedtls_ecp_point Vi; /*!< The blinding value. */
mbedtls_ecp_point Vf; /*!< The unblinding value. */
mbedtls_mpi _d; /*!< The previous \p d. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
int restart_enabled; /*!< The flag for restartable mode. */
mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
#endif /* MBEDTLS_ECP_RESTARTABLE */
#else
uint8_t point_format; /*!< The format of point export in TLS messages
as defined in RFC 4492. */
mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */
mbedtls_ecdh_variant var; /*!< The ECDH implementation/structure used. */
union
{
mbedtls_ecdh_context_mbed mbed_ecdh;
} ctx; /*!< Implementation-specific context. The
context in use is specified by the \c var
field. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
uint8_t restart_enabled; /*!< The flag for restartable mode. Functions of
an alternative implementation not supporting
restartable mode must return
MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error
if this flag is set. */
#endif /* MBEDTLS_ECP_RESTARTABLE */
#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
}
mbedtls_ecdh_context;
/**
* \brief This function generates an ECDH keypair on an elliptic
* curve.
*
* This function performs the first of two core computations
* implemented during the ECDH key exchange. The second core
* computation is performed by mbedtls_ecdh_compute_shared().
*
* \see ecp.h
*
* \param grp The ECP group to use. This must be initialized and have
* domain parameters loaded, for example through
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
* \param d The destination MPI (private key).
* This must be initialized.
* \param Q The destination point (public key).
* This must be initialized.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return Another \c MBEDTLS_ERR_ECP_XXX or
* \c MBEDTLS_MPI_XXX error code on failure.
*/
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function computes the shared secret.
*
* This function performs the second of two core computations
* implemented during the ECDH key exchange. The first core
* computation is performed by mbedtls_ecdh_gen_public().
*
* \see ecp.h
*
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against side-channel attacks.
* For more information, see mbedtls_ecp_mul().
*
* \param grp The ECP group to use. This must be initialized and have
* domain parameters loaded, for example through
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
* \param z The destination MPI (shared secret).
* This must be initialized.
* \param Q The public key from another party.
* This must be initialized.
* \param d Our secret exponent (private key).
* This must be initialized.
* \param f_rng The RNG function. This may be \c NULL if randomization
* of intermediate results during the ECP computations is
* not needed (discouraged). See the documentation of
* mbedtls_ecp_mul() for more.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't need a
* context argument.
*
* \return \c 0 on success.
* \return Another \c MBEDTLS_ERR_ECP_XXX or
* \c MBEDTLS_MPI_XXX error code on failure.
*/
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function initializes an ECDH context.
*
* \param ctx The ECDH context to initialize. This must not be \c NULL.
*/
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
/**
* \brief This function sets up the ECDH context with the information
* given.
*
* This function should be called after mbedtls_ecdh_init() but
* before mbedtls_ecdh_make_params(). There is no need to call
* this function before mbedtls_ecdh_read_params().
*
* This is the first function used by a TLS server for ECDHE
* ciphersuites.
*
* \param ctx The ECDH context to set up. This must be initialized.
* \param grp_id The group id of the group to set up the context for.
*
* \return \c 0 on success.
*/
int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx,
mbedtls_ecp_group_id grp_id );
/**
* \brief This function frees a context.
*
* \param ctx The context to free. This may be \c NULL, in which
* case this function does nothing. If it is not \c NULL,
* it must point to an initialized ECDH context.
*/
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
/**
* \brief This function generates an EC key pair and exports its
* in the format used in a TLS ServerKeyExchange handshake
* message.
*
* This is the second function used by a TLS server for ECDHE
* ciphersuites. (It is called after mbedtls_ecdh_setup().)
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, for example via mbedtls_ecdh_setup().
* \param olen The address at which to store the number of Bytes written.
* \param buf The destination buffer. This must be a writable buffer of
* length \p blen Bytes.
* \param blen The length of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function parses the ECDHE parameters in a
* TLS ServerKeyExchange handshake message.
*
* \note In a TLS handshake, this is the how the client
* sets up its ECDHE context from the server's public
* ECDHE key material.
*
* \see ecp.h
*
* \param ctx The ECDHE context to use. This must be initialized.
* \param buf On input, \c *buf must be the start of the input buffer.
* On output, \c *buf is updated to point to the end of the
* data that has been read. On success, this is the first byte
* past the end of the ServerKeyExchange parameters.
* On error, this is the point at which an error has been
* detected, which is usually not useful except to debug
* failures.
* \param end The end of the input buffer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
const unsigned char **buf,
const unsigned char *end );
/**
* \brief This function sets up an ECDH context from an EC key.
*
* It is used by clients and servers in place of the
* ServerKeyEchange for static ECDH, and imports ECDH
* parameters from the EC key information of a certificate.
*
* \see ecp.h
*
* \param ctx The ECDH context to set up. This must be initialized.
* \param key The EC key to use. This must be initialized.
* \param side Defines the source of the key. Possible values are:
* - #MBEDTLS_ECDH_OURS: The key is ours.
* - #MBEDTLS_ECDH_THEIRS: The key is that of the peer.
*
* \return \c 0 on success.
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side );
/**
* \brief This function generates a public key and exports it
* as a TLS ClientKeyExchange payload.
*
* This is the second function used by a TLS client for ECDH(E)
* ciphersuites.
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, the latter usually by
* mbedtls_ecdh_read_params().
* \param olen The address at which to store the number of Bytes written.
* This must not be \c NULL.
* \param buf The destination buffer. This must be a writable buffer
* of length \p blen Bytes.
* \param blen The size of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function parses and processes the ECDHE payload of a
* TLS ClientKeyExchange message.
*
* This is the third function used by a TLS server for ECDH(E)
* ciphersuites. (It is called after mbedtls_ecdh_setup() and
* mbedtls_ecdh_make_params().)
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, for example via mbedtls_ecdh_setup().
* \param buf The pointer to the ClientKeyExchange payload. This must
* be a readable buffer of length \p blen Bytes.
* \param blen The length of the input buffer \p buf in Bytes.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
const unsigned char *buf, size_t blen );
/**
* \brief This function derives and exports the shared secret.
*
* This is the last function used by both TLS client
* and servers.
*
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against side-channel attacks.
* For more information, see mbedtls_ecp_mul().
*
* \see ecp.h
* \param ctx The ECDH context to use. This must be initialized
* and have its own private key generated and the peer's
* public key imported.
* \param olen The address at which to store the total number of
* Bytes written on success. This must not be \c NULL.
* \param buf The buffer to write the generated shared key to. This
* must be a writable buffer of size \p blen Bytes.
* \param blen The length of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function, for blinding purposes. This may
* b \c NULL if blinding isn't needed.
* \param p_rng The RNG context. This may be \c NULL if \p f_rng
* doesn't need a context argument.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief This function enables restartable EC computations for this
* context. (Default: disabled.)
*
* \see \c mbedtls_ecp_set_max_ops()
*
* \note It is not possible to safely disable restartable
* computations once enabled, except by free-ing the context,
* which cancels possible in-progress operations.
*
* \param ctx The ECDH context to use. This must be initialized.
*/
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
#ifdef __cplusplus
}
#endif
#endif /* ecdh.h */

View File

@@ -1,614 +0,0 @@
/**
* \file ecdsa.h
*
* \brief This file contains ECDSA definitions and functions.
*
* The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in
* <em>Standards for Efficient Cryptography Group (SECG):
* SEC1 Elliptic Curve Cryptography</em>.
* The use of ECDSA for TLS is defined in <em>RFC-4492: Elliptic Curve
* Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
*
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_ECDSA_H
#define MBEDTLS_ECDSA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ecp.h"
#include "md.h"
/*
* RFC-4492 page 20:
*
* Ecdsa-Sig-Value ::= SEQUENCE {
* r INTEGER,
* s INTEGER
* }
*
* Size is at most
* 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
* twice that + 1 (tag) + 2 (len) for the sequence
* (assuming ECP_MAX_BYTES is less than 126 for r and s,
* and less than 124 (total len <= 255) for the sequence)
*/
#if MBEDTLS_ECP_MAX_BYTES > 124
#error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN"
#endif
/** The maximal size of an ECDSA signature in Bytes. */
#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The ECDSA context structure.
*
* \warning Performing multiple operations concurrently on the same
* ECDSA context is not supported; objects of this type
* should not be shared between multiple threads.
*/
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Internal restart context for ecdsa_verify()
*
* \note Opaque struct, defined in ecdsa.c
*/
typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx;
/**
* \brief Internal restart context for ecdsa_sign()
*
* \note Opaque struct, defined in ecdsa.c
*/
typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx;
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/**
* \brief Internal restart context for ecdsa_sign_det()
*
* \note Opaque struct, defined in ecdsa.c
*/
typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx;
#endif
/**
* \brief General context for resuming ECDSA operations
*/
typedef struct
{
mbedtls_ecp_restart_ctx ecp; /*!< base context for ECP restart and
shared administrative info */
mbedtls_ecdsa_restart_ver_ctx *ver; /*!< ecdsa_verify() sub-context */
mbedtls_ecdsa_restart_sig_ctx *sig; /*!< ecdsa_sign() sub-context */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
mbedtls_ecdsa_restart_det_ctx *det; /*!< ecdsa_sign_det() sub-context */
#endif
} mbedtls_ecdsa_restart_ctx;
#else /* MBEDTLS_ECP_RESTARTABLE */
/* Now we can declare functions that take a pointer to that */
typedef void mbedtls_ecdsa_restart_ctx;
#endif /* MBEDTLS_ECP_RESTARTABLE */
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message.
*
* \note The deterministic version implemented in
* mbedtls_ecdsa_sign_det() is usually preferred.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated
* as defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized.
* \param buf The content to be signed. This is usually the hash of
* the original data to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param f_rng The RNG function. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX
* or \c MBEDTLS_MPI_XXX error code on failure.
*/
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message, deterministic version.
*
* For more information, see <em>RFC-6979: Deterministic
* Usage of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \warning Since the output of the internal RNG is always the same for
* the same key and message, this limits the efficiency of
* blinding and leaks information through side channels. For
* secure behavior use mbedtls_ecdsa_sign_det_ext() instead.
*
* (Optimally the blinding is a random value that is different
* on every execution. In this case the blinding is still
* random from the attackers perspective, but is the same on
* each execution. This means that this blinding does not
* prevent attackers from recovering secrets by combining
* several measurement traces, but may prevent some attacks
* that exploit relationships between secret data.)
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized
* and setup, for example through mbedtls_ecp_gen_privkey().
* \param buf The hashed content to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param md_alg The hash algorithm used to hash the original data.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*/
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg );
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message, deterministic version.
*
* For more information, see <em>RFC-6979: Deterministic
* Usage of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized
* and setup, for example through mbedtls_ecp_gen_privkey().
* \param buf The hashed content to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param md_alg The hash algorithm used to hash the original data.
* \param f_rng_blind The RNG function used for blinding. This must not be
* \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*/
int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg,
int (*f_rng_blind)(void *, unsigned char *,
size_t),
void *p_rng_blind );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
* \brief This function verifies the ECDSA signature of a
* previously-hashed message.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.4, step 3.
*
* \see ecp.h
*
* \param grp The ECP group to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param buf The hashed content that was signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param Q The public key to use for verification. This must be
* initialized and setup.
* \param r The first integer of the signature.
* This must be initialized.
* \param s The second integer of the signature.
* This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
* is invalid.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure for any other reason.
*/
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
const mbedtls_mpi *s);
/**
* \brief This function computes the ECDSA signature and writes it
* to a buffer, serialized as defined in <em>RFC-4492:
* Elliptic Curve Cryptography (ECC) Cipher Suites for
* Transport Layer Security (TLS)</em>.
*
* \warning It is not thread-safe to use the same context in
* multiple threads.
*
* \note The deterministic version is used if
* #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more
* information, see <em>RFC-6979: Deterministic Usage
* of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is unused and may be set to \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function computes the ECDSA signature and writes it
* to a buffer, in a restartable way.
*
* \see \c mbedtls_ecdsa_write_signature()
*
* \note This function is like \c mbedtls_ecdsa_write_signature()
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is unused and may be set to \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
* restarting. If it is not \c NULL, it must point to an
* initialized restart context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
mbedtls_ecdsa_restart_ctx *rs_ctx );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function computes an ECDSA signature and writes
* it to a buffer, serialized as defined in <em>RFC-4492:
* Elliptic Curve Cryptography (ECC) Cipher Suites for
* Transport Layer Security (TLS)</em>.
*
* The deterministic version is defined in <em>RFC-6979:
* Deterministic Usage of the Digital Signature Algorithm (DSA)
* and Elliptic Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \warning It is not thread-safe to use the same context in
* multiple threads.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in
* Mbed TLS version 2.0 and later.
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param md_alg The message digest that was used to hash the message.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
* \brief This function reads and verifies an ECDSA signature.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.4, step 3.
*
* \see ecp.h
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes.
* \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
* \param slen The size of \p sig in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
* \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
* signature in \p sig, but its length is less than \p siglen.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
* error code on failure for any other reason.
*/
int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen );
/**
* \brief This function reads and verifies an ECDSA signature,
* in a restartable way.
*
* \see \c mbedtls_ecdsa_read_signature()
*
* \note This function is like \c mbedtls_ecdsa_read_signature()
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes.
* \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
* \param slen The size of \p sig in Bytes.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
* restarting. If it is not \c NULL, it must point to an
* initialized restart context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
* \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
* signature in \p sig, but its length is less than \p siglen.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
* error code on failure for any other reason.
*/
int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen,
mbedtls_ecdsa_restart_ctx *rs_ctx );
/**
* \brief This function generates an ECDSA keypair on the given curve.
*
* \see ecp.h
*
* \param ctx The ECDSA context to store the keypair in.
* This must be initialized.
* \param gid The elliptic curve to use. One of the various
* \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
*/
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief This function sets up an ECDSA context from an EC key pair.
*
* \see ecp.h
*
* \param ctx The ECDSA context to setup. This must be initialized.
* \param key The EC key to use. This must be initialized and hold
* a private-public key pair or a public key. In the former
* case, the ECDSA context may be used for signature creation
* and verification after this call. In the latter case, it
* may be used for signature verification.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
*/
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx,
const mbedtls_ecp_keypair *key );
/**
* \brief This function initializes an ECDSA context.
*
* \param ctx The ECDSA context to initialize.
* This must not be \c NULL.
*/
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
/**
* \brief This function frees an ECDSA context.
*
* \param ctx The ECDSA context to free. This may be \c NULL,
* in which case this function does nothing. If it
* is not \c NULL, it must be initialized.
*/
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context.
*
* \param ctx The restart context to initialize.
* This must not be \c NULL.
*/
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx );
/**
* \brief Free the components of a restart context.
*
* \param ctx The restart context to free. This may be \c NULL,
* in which case this function does nothing. If it
* is not \c NULL, it must be initialized.
*/
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
#ifdef __cplusplus
}
#endif
#endif /* ecdsa.h */

File diff suppressed because it is too large Load Diff

View File

@@ -1,309 +0,0 @@
/**
* \file ecp_internal.h
*
* \brief Function declarations for alternative implementation of elliptic curve
* point arithmetic.
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
/*
* References:
*
* [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records.
* <https://cr.yp.to/ecdh/curve25519-20060209.pdf>
*
* [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
* for elliptic curve cryptosystems. In : Cryptographic Hardware and
* Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
* <https://link.springer.com/chapter/10.1007/3-540-48059-5_25>
*
* [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
* render ECC resistant against Side Channel Attacks. IACR Cryptology
* ePrint Archive, 2004, vol. 2004, p. 342.
* <https://eprint.iacr.org/2004/342.pdf>
*
* [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters.
* <https://www.secg.org/sec2-v2.pdf>
*
* [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic
* Curve Cryptography.
*
* [6] Digital Signature Standard (DSS), FIPS 186-4.
* <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf>
*
* [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
* Security (TLS), RFC 4492.
* <https://tools.ietf.org/search/rfc4492>
*
* [8] <https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html>
*
* [9] COHEN, Henri. A Course in Computational Algebraic Number Theory.
* Springer Science & Business Media, 1 Aug 2000
*/
#ifndef MBEDTLS_ECP_INTERNAL_H
#define MBEDTLS_ECP_INTERNAL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
/**
* \brief Indicate if the Elliptic Curve Point module extension can
* handle the group.
*
* \param grp The pointer to the elliptic curve group that will be the
* basis of the cryptographic computations.
*
* \return Non-zero if successful.
*/
unsigned char mbedtls_internal_ecp_grp_capable( const mbedtls_ecp_group *grp );
/**
* \brief Initialise the Elliptic Curve Point module extension.
*
* If mbedtls_internal_ecp_grp_capable returns true for a
* group, this function has to be able to initialise the
* module for it.
*
* This module can be a driver to a crypto hardware
* accelerator, for which this could be an initialise function.
*
* \param grp The pointer to the group the module needs to be
* initialised for.
*
* \return 0 if successful.
*/
int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp );
/**
* \brief Frees and deallocates the Elliptic Curve Point module
* extension.
*
* \param grp The pointer to the group the module was initialised for.
*/
void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp );
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
/**
* \brief Randomize jacobian coordinates:
* (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l.
*
* \param grp Pointer to the group representing the curve.
*
* \param pt The point on the curve to be randomised, given with Jacobian
* coordinates.
*
* \param f_rng A function pointer to the random number generator.
*
* \param p_rng A pointer to the random number generator state.
*
* \return 0 if successful.
*/
int mbedtls_internal_ecp_randomize_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#endif
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
/**
* \brief Addition: R = P + Q, mixed affine-Jacobian coordinates.
*
* The coordinates of Q must be normalized (= affine),
* but those of P don't need to. R is not normalized.
*
* This function is used only as a subrutine of
* ecp_mul_comb().
*
* Special cases: (1) P or Q is zero, (2) R is zero,
* (3) P == Q.
* None of these cases can happen as intermediate step in
* ecp_mul_comb():
* - at each step, P, Q and R are multiples of the base
* point, the factor being less than its order, so none of
* them is zero;
* - Q is an odd multiple of the base point, P an even
* multiple, due to the choice of precomputed points in the
* modified comb method.
* So branches for these cases do not leak secret information.
*
* We accept Q->Z being unset (saving memory in tables) as
* meaning 1.
*
* Cost in field operations if done by [5] 3.22:
* 1A := 8M + 3S
*
* \param grp Pointer to the group representing the curve.
*
* \param R Pointer to a point structure to hold the result.
*
* \param P Pointer to the first summand, given with Jacobian
* coordinates
*
* \param Q Pointer to the second summand, given with affine
* coordinates.
*
* \return 0 if successful.
*/
int mbedtls_internal_ecp_add_mixed( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *R, const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q );
#endif
/**
* \brief Point doubling R = 2 P, Jacobian coordinates.
*
* Cost: 1D := 3M + 4S (A == 0)
* 4M + 4S (A == -3)
* 3M + 6S + 1a otherwise
* when the implementation is based on the "dbl-1998-cmo-2"
* doubling formulas in [8] and standard optimizations are
* applied when curve parameter A is one of { 0, -3 }.
*
* \param grp Pointer to the group representing the curve.
*
* \param R Pointer to a point structure to hold the result.
*
* \param P Pointer to the point that has to be doubled, given with
* Jacobian coordinates.
*
* \return 0 if successful.
*/
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
int mbedtls_internal_ecp_double_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *R, const mbedtls_ecp_point *P );
#endif
/**
* \brief Normalize jacobian coordinates of an array of (pointers to)
* points.
*
* Using Montgomery's trick to perform only one inversion mod P
* the cost is:
* 1N(t) := 1I + (6t - 3)M + 1S
* (See for example Algorithm 10.3.4. in [9])
*
* This function is used only as a subrutine of
* ecp_mul_comb().
*
* Warning: fails (returning an error) if one of the points is
* zero!
* This should never happen, see choice of w in ecp_mul_comb().
*
* \param grp Pointer to the group representing the curve.
*
* \param T Array of pointers to the points to normalise.
*
* \param t_len Number of elements in the array.
*
* \return 0 if successful,
* an error if one of the points is zero.
*/
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
int mbedtls_internal_ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *T[], size_t t_len );
#endif
/**
* \brief Normalize jacobian coordinates so that Z == 0 || Z == 1.
*
* Cost in field operations if done by [5] 3.2.1:
* 1N := 1I + 3M + 1S
*
* \param grp Pointer to the group representing the curve.
*
* \param pt pointer to the point to be normalised. This is an
* input/output parameter.
*
* \return 0 if successful.
*/
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
int mbedtls_internal_ecp_normalize_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *pt );
#endif
#endif /* ECP_SHORTWEIERSTRASS */
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
int mbedtls_internal_ecp_double_add_mxz( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *R, mbedtls_ecp_point *S, const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d );
#endif
/**
* \brief Randomize projective x/z coordinates:
* (X, Z) -> (l X, l Z) for random l
*
* \param grp pointer to the group representing the curve
*
* \param P the point on the curve to be randomised given with
* projective coordinates. This is an input/output parameter.
*
* \param f_rng a function pointer to the random number generator
*
* \param p_rng a pointer to the random number generator state
*
* \return 0 if successful
*/
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
int mbedtls_internal_ecp_randomize_mxz( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#endif
/**
* \brief Normalize Montgomery x/z coordinates: X = X/Z, Z = 1.
*
* \param grp pointer to the group representing the curve
*
* \param P pointer to the point to be normalised. This is an
* input/output parameter.
*
* \return 0 if successful
*/
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
int mbedtls_internal_ecp_normalize_mxz( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *P );
#endif
#endif /* ECP_MONTGOMERY */
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
#endif /* ecp_internal.h */

View File

@@ -1,301 +0,0 @@
/**
* \file entropy.h
*
* \brief Entropy accumulator implementation
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_ENTROPY_H
#define MBEDTLS_ENTROPY_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
#include "sha512.h"
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
#else
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
#include "sha256.h"
#endif
#endif
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
#include "havege.h"
#endif
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */
#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */
#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */
#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D /**< No strong sources have been added to poll. */
#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F /**< Read/write error in file. */
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES)
#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
#endif
#if !defined(MBEDTLS_ENTROPY_MAX_GATHER)
#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
#endif
/* \} name SECTION: Module settings */
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
#else
#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */
#endif
#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */
#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES
#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */
#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Entropy poll callback pointer
*
* \param data Callback-specific data pointer
* \param output Data to fill
* \param len Maximum size to provide
* \param olen The actual amount of bytes put into the buffer (Can be 0)
*
* \return 0 if no critical failures occurred,
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise
*/
typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len,
size_t *olen);
/**
* \brief Entropy source state
*/
typedef struct mbedtls_entropy_source_state
{
mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */
void * p_source; /**< The callback data pointer */
size_t size; /**< Amount received in bytes */
size_t threshold; /**< Minimum bytes required before release */
int strong; /**< Is the source strong? */
}
mbedtls_entropy_source_state;
/**
* \brief Entropy context structure
*/
typedef struct mbedtls_entropy_context
{
int accumulator_started; /* 0 after init.
* 1 after the first update.
* -1 after free. */
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_context accumulator;
#else
mbedtls_sha256_context accumulator;
#endif
int source_count; /* Number of entries used in source. */
mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES];
#if defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_state havege_data;
#endif
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex; /*!< mutex */
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
int initial_entropy_run;
#endif
}
mbedtls_entropy_context;
/**
* \brief Initialize the context
*
* \param ctx Entropy context to initialize
*/
void mbedtls_entropy_init( mbedtls_entropy_context *ctx );
/**
* \brief Free the data in the context
*
* \param ctx Entropy context to free
*/
void mbedtls_entropy_free( mbedtls_entropy_context *ctx );
/**
* \brief Adds an entropy source to poll
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
* \param f_source Entropy function
* \param p_source Function data
* \param threshold Minimum required from source before entropy is released
* ( with mbedtls_entropy_func() ) (in bytes)
* \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or
* MBEDTLS_ENTROPY_SOURCE_WEAK.
* At least one strong source needs to be added.
* Weaker sources (such as the cycle counter) can be used as
* a complement.
*
* \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES
*/
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
mbedtls_entropy_f_source_ptr f_source, void *p_source,
size_t threshold, int strong );
/**
* \brief Trigger an extra gather poll for the accumulator
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
*
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx );
/**
* \brief Retrieve entropy from the accumulator
* (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE)
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param data Entropy context
* \param output Buffer to fill
* \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE
*
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len );
/**
* \brief Add data to the accumulator manually
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
* \param data Data to add
* \param len Length of data
*
* \return 0 if successful
*/
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
const unsigned char *data, size_t len );
#if defined(MBEDTLS_ENTROPY_NV_SEED)
/**
* \brief Trigger an update of the seed file in NV by using the
* current entropy pool.
*
* \param ctx Entropy context
*
* \return 0 if successful
*/
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx );
#endif /* MBEDTLS_ENTROPY_NV_SEED */
#if defined(MBEDTLS_FS_IO)
/**
* \brief Write a seed file
*
* \param ctx Entropy context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path );
/**
* \brief Read and update a seed file. Seed is added to this
* instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are
* read from the seed file. The rest is ignored.
*
* \param ctx Entropy context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error,
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* This module self-test also calls the entropy self-test,
* mbedtls_entropy_source_self_test();
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_entropy_self_test( int verbose );
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
/**
* \brief Checkup routine
*
* Verifies the integrity of the hardware entropy source
* provided by the function 'mbedtls_hardware_poll()'.
*
* Note this is the only hardware entropy source that is known
* at link time, and other entropy sources configured
* dynamically at runtime by the function
* mbedtls_entropy_add_source() will not be tested.
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_entropy_source_self_test( int verbose );
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* entropy.h */

View File

@@ -1,140 +0,0 @@
/**
* \file error.h
*
* \brief Error to string translation
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_ERROR_H
#define MBEDTLS_ERROR_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
/**
* Error code layout.
*
* Currently we try to keep all error codes within the negative space of 16
* bits signed integers to support all platforms (-0x0001 - -0x7FFF). In
* addition we'd like to give two layers of information on the error if
* possible.
*
* For that purpose the error codes are segmented in the following manner:
*
* 16 bit error code bit-segmentation
*
* 1 bit - Unused (sign bit)
* 3 bits - High level module ID
* 5 bits - Module-dependent error code
* 7 bits - Low level module errors
*
* For historical reasons, low-level error codes are divided in even and odd,
* even codes were assigned first, and -1 is reserved for other errors.
*
* Low-level module errors (0x0002-0x007E, 0x0003-0x007F)
*
* Module Nr Codes assigned
* MPI 7 0x0002-0x0010
* GCM 3 0x0012-0x0014 0x0013-0x0013
* BLOWFISH 3 0x0016-0x0018 0x0017-0x0017
* THREADING 3 0x001A-0x001E
* AES 5 0x0020-0x0022 0x0021-0x0025
* CAMELLIA 3 0x0024-0x0026 0x0027-0x0027
* XTEA 2 0x0028-0x0028 0x0029-0x0029
* BASE64 2 0x002A-0x002C
* OID 1 0x002E-0x002E 0x000B-0x000B
* PADLOCK 1 0x0030-0x0030
* DES 2 0x0032-0x0032 0x0033-0x0033
* CTR_DBRG 4 0x0034-0x003A
* ENTROPY 3 0x003C-0x0040 0x003D-0x003F
* NET 13 0x0042-0x0052 0x0043-0x0049
* ARIA 4 0x0058-0x005E
* ASN1 7 0x0060-0x006C
* CMAC 1 0x007A-0x007A
* PBKDF2 1 0x007C-0x007C
* HMAC_DRBG 4 0x0003-0x0009
* CCM 3 0x000D-0x0011
* ARC4 1 0x0019-0x0019
* MD2 1 0x002B-0x002B
* MD4 1 0x002D-0x002D
* MD5 1 0x002F-0x002F
* RIPEMD160 1 0x0031-0x0031
* SHA1 1 0x0035-0x0035 0x0073-0x0073
* SHA256 1 0x0037-0x0037 0x0074-0x0074
* SHA512 1 0x0039-0x0039 0x0075-0x0075
* CHACHA20 3 0x0051-0x0055
* POLY1305 3 0x0057-0x005B
* CHACHAPOLY 2 0x0054-0x0056
* PLATFORM 1 0x0070-0x0072
*
* High-level module nr (3 bits - 0x0...-0x7...)
* Name ID Nr of Errors
* PEM 1 9
* PKCS#12 1 4 (Started from top)
* X509 2 20
* PKCS5 2 4 (Started from top)
* DHM 3 11
* PK 3 15 (Started from top)
* RSA 4 11
* ECP 4 10 (Started from top)
* MD 5 5
* HKDF 5 1 (Started from top)
* SSL 5 1 (Started from 0x5E80)
* CIPHER 6 8
* SSL 6 23 (Started from top)
* SSL 7 32
*
* Module dependent error code (5 bits 0x.00.-0x.F8.)
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Translate a mbed TLS error code into a string representation,
* Result is truncated if necessary and always includes a terminating
* null byte.
*
* \param errnum error code
* \param buffer buffer to place representation in
* \param buflen length of the buffer
*/
void mbedtls_strerror( int errnum, char *buffer, size_t buflen );
#ifdef __cplusplus
}
#endif
#endif /* error.h */

View File

@@ -1,336 +0,0 @@
/**
* \file gcm.h
*
* \brief This file contains GCM definitions and functions.
*
* The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
* in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
* (GCM), Natl. Inst. Stand. Technol.</em>
*
* For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
* Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
*
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_GCM_H
#define MBEDTLS_GCM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "cipher.h"
#include <stdint.h>
#define MBEDTLS_GCM_ENCRYPT 1
#define MBEDTLS_GCM_DECRYPT 0
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_GCM_ALT)
/**
* \brief The GCM context structure.
*/
typedef struct mbedtls_gcm_context
{
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
uint64_t HL[16]; /*!< Precalculated HTable low. */
uint64_t HH[16]; /*!< Precalculated HTable high. */
uint64_t len; /*!< The total length of the encrypted data. */
uint64_t add_len; /*!< The total length of the additional data. */
unsigned char base_ectr[16]; /*!< The first ECTR for tag. */
unsigned char y[16]; /*!< The Y working value. */
unsigned char buf[16]; /*!< The buf working value. */
int mode; /*!< The operation to perform:
#MBEDTLS_GCM_ENCRYPT or
#MBEDTLS_GCM_DECRYPT. */
}
mbedtls_gcm_context;
#else /* !MBEDTLS_GCM_ALT */
#include "gcm_alt.h"
#endif /* !MBEDTLS_GCM_ALT */
/**
* \brief This function initializes the specified GCM context,
* to make references valid, and prepares the context
* for mbedtls_gcm_setkey() or mbedtls_gcm_free().
*
* The function does not bind the GCM context to a particular
* cipher, nor set the key. For this purpose, use
* mbedtls_gcm_setkey().
*
* \param ctx The GCM context to initialize. This must not be \c NULL.
*/
void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
/**
* \brief This function associates a GCM context with a
* cipher algorithm and a key.
*
* \param ctx The GCM context. This must be initialized.
* \param cipher The 128-bit block cipher to use.
* \param key The encryption key. This must be a readable buffer of at
* least \p keybits bits.
* \param keybits The key size in bits. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success.
* \return A cipher-specific error code on failure.
*/
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function performs GCM encryption or decryption of a buffer.
*
* \note For encryption, the output buffer can be the same as the
* input buffer. For decryption, the output buffer cannot be
* the same as input buffer. If the buffers overlap, the output
* buffer must trail at least 8 Bytes behind the input buffer.
*
* \warning When this function performs a decryption, it outputs the
* authentication tag and does not verify that the data is
* authentic. You should use this function to perform encryption
* only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
*
* \param ctx The GCM context to use for encryption or decryption. This
* must be initialized.
* \param mode The operation to perform:
* - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
* The ciphertext is written to \p output and the
* authentication tag is written to \p tag.
* - #MBEDTLS_GCM_DECRYPT to perform decryption.
* The plaintext is written to \p output and the
* authentication tag is written to \p tag.
* Note that this mode is not recommended, because it does
* not verify the authenticity of the data. For this reason,
* you should use mbedtls_gcm_auth_decrypt() instead of
* calling this function in decryption mode.
* \param length The length of the input data, which is equal to the length
* of the output data.
* \param iv The initialization vector. This must be a readable buffer of
* at least \p iv_len Bytes.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data. This must be of at
* least that size in Bytes.
* \param add_len The length of the additional data.
* \param input The buffer holding the input data. If \p length is greater
* than zero, this must be a readable buffer of at least that
* size in Bytes.
* \param output The buffer for holding the output data. If \p length is greater
* than zero, this must be a writable buffer of at least that
* size in Bytes.
* \param tag_len The length of the tag to generate.
* \param tag The buffer for holding the tag. This must be a writable
* buffer of at least \p tag_len Bytes.
*
* \return \c 0 if the encryption or decryption was performed
* successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
* this does not indicate that the data is authentic.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
* not valid or a cipher-specific error code if the encryption
* or decryption failed.
*/
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
int mode,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *input,
unsigned char *output,
size_t tag_len,
unsigned char *tag );
/**
* \brief This function performs a GCM authenticated decryption of a
* buffer.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
*
* \param ctx The GCM context. This must be initialized.
* \param length The length of the ciphertext to decrypt, which is also
* the length of the decrypted plaintext.
* \param iv The initialization vector. This must be a readable buffer
* of at least \p iv_len Bytes.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data. This must be of at
* least that size in Bytes.
* \param add_len The length of the additional data.
* \param tag The buffer holding the tag to verify. This must be a
* readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to verify.
* \param input The buffer holding the ciphertext. If \p length is greater
* than zero, this must be a readable buffer of at least that
* size.
* \param output The buffer for holding the decrypted plaintext. If \p length
* is greater than zero, this must be a writable buffer of at
* least that size.
*
* \return \c 0 if successful and authenticated.
* \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
* not valid or a cipher-specific error code if the decryption
* failed.
*/
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *tag,
size_t tag_len,
const unsigned char *input,
unsigned char *output );
/**
* \brief This function starts a GCM encryption or decryption
* operation.
*
* \param ctx The GCM context. This must be initialized.
* \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
* #MBEDTLS_GCM_DECRYPT.
* \param iv The initialization vector. This must be a readable buffer of
* at least \p iv_len Bytes.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data, or \c NULL
* if \p add_len is \c 0.
* \param add_len The length of the additional data. If \c 0,
* \p add may be \c NULL.
*
* \return \c 0 on success.
*/
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
int mode,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len );
/**
* \brief This function feeds an input buffer into an ongoing GCM
* encryption or decryption operation.
*
* ` The function expects input to be a multiple of 16
* Bytes. Only the last call before calling
* mbedtls_gcm_finish() can be less than 16 Bytes.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
*
* \param ctx The GCM context. This must be initialized.
* \param length The length of the input data. This must be a multiple of
* 16 except in the last call before mbedtls_gcm_finish().
* \param input The buffer holding the input data. If \p length is greater
* than zero, this must be a readable buffer of at least that
* size in Bytes.
* \param output The buffer for holding the output data. If \p length is
* greater than zero, this must be a writable buffer of at
* least that size in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/
int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
size_t length,
const unsigned char *input,
unsigned char *output );
/**
* \brief This function finishes the GCM operation and generates
* the authentication tag.
*
* It wraps up the GCM stream, and generates the
* tag. The tag can have a maximum length of 16 Bytes.
*
* \param ctx The GCM context. This must be initialized.
* \param tag The buffer for holding the tag. This must be a writable
* buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to generate. This must be at least
* four.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
unsigned char *tag,
size_t tag_len );
/**
* \brief This function clears a GCM context and the underlying
* cipher sub-context.
*
* \param ctx The GCM context to clear. If this is \c NULL, the call has
* no effect. Otherwise, this must be initialized.
*/
void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The GCM checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_gcm_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* gcm.h */

View File

@@ -1,151 +0,0 @@
/**
* \file hkdf.h
*
* \brief This file contains the HKDF interface.
*
* The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is
* specified by RFC 5869.
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_HKDF_H
#define MBEDTLS_HKDF_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "md.h"
/**
* \name HKDF Error codes
* \{
*/
#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */
/* \} name */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief This is the HMAC-based Extract-and-Expand Key Derivation Function
* (HKDF).
*
* \param md A hash function; md.size denotes the length of the hash
* function output in bytes.
* \param salt An optional salt value (a non-secret random value);
* if the salt is not provided, a string of all zeros of
* md.size length is used as the salt.
* \param salt_len The length in bytes of the optional \p salt.
* \param ikm The input keying material.
* \param ikm_len The length in bytes of \p ikm.
* \param info An optional context and application specific information
* string. This can be a zero-length string.
* \param info_len The length of \p info in bytes.
* \param okm The output keying material of \p okm_len bytes.
* \param okm_len The length of the output keying material in bytes. This
* must be less than or equal to 255 * md.size bytes.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
* MD layer.
*/
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len );
/**
* \brief Take the input keying material \p ikm and extract from it a
* fixed-length pseudorandom key \p prk.
*
* \warning This function should only be used if the security of it has been
* studied and established in that particular context (eg. TLS 1.3
* key schedule). For standard HKDF security guarantees use
* \c mbedtls_hkdf instead.
*
* \param md A hash function; md.size denotes the length of the
* hash function output in bytes.
* \param salt An optional salt value (a non-secret random value);
* if the salt is not provided, a string of all zeros
* of md.size length is used as the salt.
* \param salt_len The length in bytes of the optional \p salt.
* \param ikm The input keying material.
* \param ikm_len The length in bytes of \p ikm.
* \param[out] prk A pseudorandom key of at least md.size bytes.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
* MD layer.
*/
int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
const unsigned char *salt, size_t salt_len,
const unsigned char *ikm, size_t ikm_len,
unsigned char *prk );
/**
* \brief Expand the supplied \p prk into several additional pseudorandom
* keys, which is the output of the HKDF.
*
* \warning This function should only be used if the security of it has been
* studied and established in that particular context (eg. TLS 1.3
* key schedule). For standard HKDF security guarantees use
* \c mbedtls_hkdf instead.
*
* \param md A hash function; md.size denotes the length of the hash
* function output in bytes.
* \param prk A pseudorandom key of at least md.size bytes. \p prk is
* usually the output from the HKDF extract step.
* \param prk_len The length in bytes of \p prk.
* \param info An optional context and application specific information
* string. This can be a zero-length string.
* \param info_len The length of \p info in bytes.
* \param okm The output keying material of \p okm_len bytes.
* \param okm_len The length of the output keying material in bytes. This
* must be less than or equal to 255 * md.size bytes.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
* MD layer.
*/
int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
size_t prk_len, const unsigned char *info,
size_t info_len, unsigned char *okm, size_t okm_len );
#ifdef __cplusplus
}
#endif
#endif /* hkdf.h */

View File

@@ -1,480 +0,0 @@
/**
* \file md.h
*
* \brief This file contains the generic message-digest wrapper.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_MD_H
#define MBEDTLS_MD_H
#include <stddef.h>
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Supported message digests.
*
* \warning MD2, MD4, MD5 and SHA-1 are considered weak message digests and
* their use constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
typedef enum {
MBEDTLS_MD_NONE=0, /**< None. */
MBEDTLS_MD_MD2, /**< The MD2 message digest. */
MBEDTLS_MD_MD4, /**< The MD4 message digest. */
MBEDTLS_MD_MD5, /**< The MD5 message digest. */
MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */
MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */
MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */
MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */
MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */
MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
} mbedtls_md_type_t;
#if defined(MBEDTLS_SHA512_C)
#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */
#else
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
#endif
/**
* Opaque struct defined in md_internal.h.
*/
typedef struct mbedtls_md_info_t mbedtls_md_info_t;
/**
* The generic message-digest context.
*/
typedef struct mbedtls_md_context_t
{
/** Information about the associated message digest. */
const mbedtls_md_info_t *md_info;
/** The digest-specific context. */
void *md_ctx;
/** The HMAC part of the context. */
void *hmac_ctx;
} mbedtls_md_context_t;
/**
* \brief This function returns the list of digests supported by the
* generic digest module.
*
* \note The list starts with the strongest available hashes.
*
* \return A statically allocated array of digests. Each element
* in the returned list is an integer belonging to the
* message-digest enumeration #mbedtls_md_type_t.
* The last entry is 0.
*/
const int *mbedtls_md_list( void );
/**
* \brief This function returns the message-digest information
* associated with the given digest name.
*
* \param md_name The name of the digest to search for.
*
* \return The message-digest information associated with \p md_name.
* \return NULL if the associated message-digest information is not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
/**
* \brief This function returns the message-digest information
* associated with the given digest type.
*
* \param md_type The type of digest to search for.
*
* \return The message-digest information associated with \p md_type.
* \return NULL if the associated message-digest information is not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
/**
* \brief This function initializes a message-digest context without
* binding it to a particular message-digest algorithm.
*
* This function should always be called first. It prepares the
* context for mbedtls_md_setup() for binding it to a
* message-digest algorithm.
*/
void mbedtls_md_init( mbedtls_md_context_t *ctx );
/**
* \brief This function clears the internal structure of \p ctx and
* frees any embedded internal structure, but does not free
* \p ctx itself.
*
* If you have called mbedtls_md_setup() on \p ctx, you must
* call mbedtls_md_free() when you are no longer using the
* context.
* Calling this function if you have previously
* called mbedtls_md_init() and nothing else is optional.
* You must not call this function if you have not called
* mbedtls_md_init().
*/
void mbedtls_md_free( mbedtls_md_context_t *ctx );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function selects the message digest algorithm to use,
* and allocates internal structures.
*
* It should be called after mbedtls_md_init() or mbedtls_md_free().
* Makes it necessary to call mbedtls_md_free() later.
*
* \deprecated Superseded by mbedtls_md_setup() in 2.0.0
*
* \param ctx The context to set up.
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
*/
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief This function selects the message digest algorithm to use,
* and allocates internal structures.
*
* It should be called after mbedtls_md_init() or
* mbedtls_md_free(). Makes it necessary to call
* mbedtls_md_free() later.
*
* \param ctx The context to set up.
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory),
* or non-zero: HMAC is used with this context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
*/
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
/**
* \brief This function clones the state of an message-digest
* context.
*
* \note You must call mbedtls_md_setup() on \c dst before calling
* this function.
*
* \note The two contexts must have the same type,
* for example, both are SHA-256.
*
* \warning This function clones the message-digest state, not the
* HMAC state.
*
* \param dst The destination context.
* \param src The context to be cloned.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
*/
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src );
/**
* \brief This function extracts the message-digest size from the
* message-digest information structure.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return The size of the message-digest output in Bytes.
*/
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info );
/**
* \brief This function extracts the message-digest type from the
* message-digest information structure.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return The type of the message digest.
*/
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info );
/**
* \brief This function extracts the message-digest name from the
* message-digest information structure.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return The name of the message digest.
*/
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
/**
* \brief This function starts a message-digest computation.
*
* You must call this function after setting up the context
* with mbedtls_md_setup(), and before passing data with
* mbedtls_md_update().
*
* \param ctx The generic message-digest context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_starts( mbedtls_md_context_t *ctx );
/**
* \brief This function feeds an input buffer into an ongoing
* message-digest computation.
*
* You must call mbedtls_md_starts() before calling this
* function. You may call this function multiple times.
* Afterwards, call mbedtls_md_finish().
*
* \param ctx The generic message-digest context.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
/**
* \brief This function finishes the digest operation,
* and writes the result to the output buffer.
*
* Call this function after a call to mbedtls_md_starts(),
* followed by any number of calls to mbedtls_md_update().
* Afterwards, you may either clear the context with
* mbedtls_md_free(), or call mbedtls_md_starts() to reuse
* the context for another digest operation with the same
* algorithm.
*
* \param ctx The generic message-digest context.
* \param output The buffer for the generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
/**
* \brief This function calculates the message-digest of a buffer,
* with respect to a configurable message-digest algorithm
* in a single call.
*
* The result is calculated as
* Output = message_digest(input buffer).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param input The buffer holding the data.
* \param ilen The length of the input data.
* \param output The generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output );
#if defined(MBEDTLS_FS_IO)
/**
* \brief This function calculates the message-digest checksum
* result of the contents of the provided file.
*
* The result is calculated as
* Output = message_digest(file contents).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param path The input file name.
* \param output The generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
* the file pointed by \p path.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
*/
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
unsigned char *output );
#endif /* MBEDTLS_FS_IO */
/**
* \brief This function sets the HMAC key and prepares to
* authenticate a new message.
*
* Call this function after mbedtls_md_setup(), to use
* the MD context for an HMAC calculation, then call
* mbedtls_md_hmac_update() to provide the input data, and
* mbedtls_md_hmac_finish() to get the HMAC value.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC key in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
size_t keylen );
/**
* \brief This function feeds an input buffer into an ongoing HMAC
* computation.
*
* Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset()
* before calling this function.
* You may call this function multiple times to pass the
* input piecewise.
* Afterwards, call mbedtls_md_hmac_finish().
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief This function finishes the HMAC operation, and writes
* the result to the output buffer.
*
* Call this function after mbedtls_md_hmac_starts() and
* mbedtls_md_hmac_update() to get the HMAC value. Afterwards
* you may either call mbedtls_md_free() to clear the context,
* or call mbedtls_md_hmac_reset() to reuse the context with
* the same HMAC key.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param output The generic HMAC checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
/**
* \brief This function prepares to authenticate a new message with
* the same key as the previous HMAC operation.
*
* You may call this function after mbedtls_md_hmac_finish().
* Afterwards call mbedtls_md_hmac_update() to pass the new
* input.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
/**
* \brief This function calculates the full generic HMAC
* on the input buffer with the provided key.
*
* The function allocates the context, performs the
* calculation, and frees the context.
*
* The HMAC result is calculated as
* output = generic HMAC(hmac key, input buffer).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC secret key in Bytes.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
* \param output The generic HMAC result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
/* Internal use */
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_MD_H */

View File

@@ -1,321 +0,0 @@
/**
* \file md5.h
*
* \brief MD5 message digest algorithm (hash function)
*
* \warning MD5 is considered a weak message digest and its use constitutes a
* security risk. We recommend considering stronger message
* digests instead.
*/
//
// Copyright The Mbed TLS Contributors
// NVIDIA_EDIT: This version of MbedTLS is dual-licensed - NVIDIA
// receives it under the GPL-2.0 license - these headers are updated
// accordingly.
//
// SPDX-License-Identifier: GPL-2.0
//
// This file is provided under the GNU General Public License v2.0.
//
// **********
// GNU General Public License v2.0:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// **********
//
#ifndef MBEDTLS_MD5_H
#define MBEDTLS_MD5_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
/* MBEDTLS_ERR_MD5_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED -0x002F /**< MD5 hardware accelerator failed */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_MD5_ALT)
// Regular implementation
//
/**
* \brief MD5 context structure
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
typedef struct mbedtls_md5_context
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
}
mbedtls_md5_context;
#else /* MBEDTLS_MD5_ALT */
#include "md5_alt.h"
#endif /* MBEDTLS_MD5_ALT */
/**
* \brief Initialize MD5 context
*
* \param ctx MD5 context to be initialized
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md5_init( mbedtls_md5_context *ctx );
/**
* \brief Clear MD5 context
*
* \param ctx MD5 context to be cleared
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md5_free( mbedtls_md5_context *ctx );
/**
* \brief Clone (the state of) an MD5 context
*
* \param dst The destination context
* \param src The context to be cloned
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md5_clone( mbedtls_md5_context *dst,
const mbedtls_md5_context *src );
/**
* \brief MD5 context setup
*
* \param ctx context to be initialized
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD5 final digest
*
* \param ctx MD5 context
* \param output MD5 checksum result
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
unsigned char output[16] );
/**
* \brief MD5 process data block (internal use only)
*
* \param ctx MD5 context
* \param data buffer holding one block of data
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief MD5 context setup
*
* \deprecated Superseded by mbedtls_md5_starts_ret() in 2.7.0
*
* \param ctx context to be initialized
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_starts( mbedtls_md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \deprecated Superseded by mbedtls_md5_update_ret() in 2.7.0
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_update( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD5 final digest
*
* \deprecated Superseded by mbedtls_md5_finish_ret() in 2.7.0
*
* \param ctx MD5 context
* \param output MD5 checksum result
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_finish( mbedtls_md5_context *ctx,
unsigned char output[16] );
/**
* \brief MD5 process data block (internal use only)
*
* \deprecated Superseded by mbedtls_internal_md5_process() in 2.7.0
*
* \param ctx MD5 context
* \param data buffer holding one block of data
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Output = MD5( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Output = MD5( input buffer )
*
* \deprecated Superseded by mbedtls_md5_ret() in 2.7.0
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_md5.h */

Some files were not shown because too many files have changed in this diff Show More