Software APIs
hardened_memory.h
Go to the documentation of this file.
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_HARDENED_MEMORY_H_
6#define OPENTITAN_SW_DEVICE_LIB_BASE_HARDENED_MEMORY_H_
7
8/**
9 * @file
10 * @brief Hardened memory operations for constant power buffer manipulation.
11 */
12
13#include <stddef.h>
14#include <stdint.h>
15
18#include "sw/device/lib/crypto/impl/status.h"
19
20#ifdef __cplusplus
21extern "C" {
22#endif // __cplusplus
23
24/**
25 * Expects some external implementation of randomness to be linked.
26 *
27 * @return A fresh random word.
28 */
29extern uint32_t hardened_memshred_random_word(void);
30
31/**
32 * Copies 32-bit words between non-overlapping regions.
33 *
34 * Unlike `memcpy()`, this function has important differences:
35 * - It is significantly slower, since it mitigates power-analysis attacks.
36 * - It performs operations on 32-bit words, rather than bytes.
37 * - It returns void.
38 *
39 * Input pointers *MUST* be 32-bit aligned, although they do not need to
40 * actually point to memory declared as `uint32_t` per the C aliasing rules.
41 * Internally, this function is careful to not dereference its operands
42 * directly, and instead uses dedicated load/store intrinsics.
43 *
44 * @param dest The destination of the copy.
45 * @param src The source of the copy.
46 * @param word_len The number of words to copy.
47 * @return OK or error.
48 */
49status_t hardened_memcpy(uint32_t *OT_RESTRICT dest,
50 const uint32_t *OT_RESTRICT src, size_t word_len);
51
52/**
53 * Fills a 32-bit aligned region of memory with random data.
54 *
55 * Unlike `memset()`, this function has important differences:
56 * - It is significantly slower, since it mitigates power-analysis attacks.
57 * - It performs operations on 32-bit words, rather than bytes.
58 * - A fill value cannot be specified.
59 * - It returns void.
60 *
61 * Input pointers *MUST* be 32-bit aligned, although they do not need to
62 * actually point to memory declared as `uint32_t` per the C aliasing rules.
63 * Internally, this function is careful to not dereference its operands
64 * directly, and instead uses dedicated load/store intrinsics.
65 *
66 * @param dest The destination of the set.
67 * @param word_len The number of words to write.
68 * @return OK or error.
69 */
70status_t hardened_memshred(uint32_t *dest, size_t word_len);
71
72/**
73 * Compare two potentially-overlapping 32-bit aligned regions of memory for
74 * equality.
75 *
76 * Unlike `memcmp()`, this function has important differences:
77 * - It is significantly slower, since it mitigates power-analysis attacks.
78 * - It performs operations on 32-bit words, rather than bytes.
79 * - It only computes equality, not lexicographic ordering, which would be even
80 * slower.
81 * - It returns a `hardened_bool_t`.
82 * - It is constant-time.
83 *
84 * Input pointers *MUST* be 32-bit aligned, although they do not need to
85 * actually point to memory declared as `uint32_t` per the C aliasing rules.
86 * Internally, this function is careful to not dereference its operands
87 * directly, and instead uses dedicated load/store intrinsics.
88 *
89 * @param lhs The first buffer to compare.
90 * @param rhs The second buffer to compare.
91 * @param word_len The number of words to compare.
92 */
93hardened_bool_t hardened_memeq(const uint32_t *lhs, const uint32_t *rhs,
94 size_t word_len);
95
96/**
97 * Constant time memeq implementation that can also handle non 32-bit aligned
98 * buffers.
99 *
100 * Important: not hardened against SCA leakage, only guarantees constant time
101 * execution.
102 *
103 * @param lhs The first buffer to compare.
104 * @param rhs The second buffer to compare.
105 * @param word_len The number of bytes to compare.
106 */
107hardened_bool_t consttime_memeq_byte(const void *lhs, const void *rhs,
108 size_t len);
109
110/**
111 * Combines two word buffers with XOR and store the result in the dest. buffer.
112 *
113 * Performs dest = ((rand ^ x) ^ y) ^ rand
114 *
115 * Callers should ensure the entropy complex is up before calling this
116 * function. The implementation uses random-order hardening primitives for
117 * side-channel defense. Moreover, calles should ensure that the dest. buffer
118 * is different from the source buffers.
119 *
120 * @param x Pointer to the first operand.
121 * @param y Pointer to the second operand.
122 * @param word_len Length in words of each operand.
123 * @param dest[out] Pointer to the output buffer.
124 * @return OK or error.
125 */
126status_t hardened_xor(const uint32_t *OT_RESTRICT x,
127 const uint32_t *OT_RESTRICT y, size_t word_len,
128 uint32_t *OT_RESTRICT dest);
129
130/**
131 * Combines two word buffers with XOR in-place.
132 *
133 * Callers should ensure the entropy complex is up before calling this
134 * function. The implementation uses random-order hardening primitives for
135 * side-channel defense.
136 *
137 * @param[in,out] x Pointer to the first operand (modified in-place).
138 * @param y Pointer to the second operand.
139 * @param word_len Length in words of each operand.
140 * @return OK or error.
141 */
143 const uint32_t *OT_RESTRICT y, size_t word_len);
144
145#ifdef __cplusplus
146} // extern "C"
147#endif // __cplusplus
148
149#endif // OPENTITAN_SW_DEVICE_LIB_BASE_HARDENED_MEMORY_H_