Branch data Line data Source code
1 : : #include "test_libsha512_utils.h"
2 : :
3 : : /* Largest byte-aligned bit count; relies on SHA512_MAX_BIT_COUNT == UINT64_MAX */
4 : : #define SHA512_TEST_MAX_BYTE_ALIGNED_BITS (UINT64_MAX & ~(uint64_t)7U)
5 : :
6 : : /**
7 : : * @brief Check that the public API rejects missing pointers
8 : : * @details NULL arguments are caller mistakes. The SHA-512 functions should
9 : : * report them as ordinary failures instead of touching memory through them
10 : : *
11 : : * @return SUCCESS when each NULL argument is rejected cleanly
12 : : */
13 : 1 : static Return test_libsha512_0003_1(void)
14 : : {
15 : 1 : INITTEST;
16 : :
17 : : static const unsigned char sample_bytes[] = {0x61};
18 : 1 : SHA512_Context context = {0};
19 : :
20 : : /* Build a minimal valid byte buffer and digest destination. The NULL checks
21 : : below should fail because of the tested argument, not because setup is bad */
22 : 1 : m_create(unsigned char,input);
23 : 1 : m_create(unsigned char,digest);
24 : :
25 : 1 : ASSERT(SUCCESS == m_copy_buffer(input,sizeof(sample_bytes),sample_bytes));
26 : 1 : ASSERT(SUCCESS == m_resize(digest,SHA512_DIGEST_LENGTH,ZERO_NEW_MEMORY));
27 : :
28 : : /* Extract raw pointers only after libmem has prepared the descriptors */
29 : 1 : const unsigned char *input_data = m_data_ro(unsigned char,input);
30 : 1 : unsigned char *digest_data = m_data(unsigned char,digest);
31 : :
32 : : /* Every public SHA-512 entry point should reject NULL storage clearly and
33 : : leave the caller with a named error code */
34 : 1 : ASSERT(input_data != NULL);
35 : 1 : ASSERT(digest_data != NULL);
36 : 1 : ASSERT(CRYPT_INVALID_ARG == sha512_init(NULL));
37 : 1 : ASSERT(CRYPT_OK == sha512_init(&context));
38 : 1 : ASSERT(CRYPT_INVALID_ARG == sha512_update(NULL,input_data,input->length));
39 : 1 : ASSERT(CRYPT_INVALID_ARG == sha512_update(&context,NULL,input->length));
40 : 1 : ASSERT(CRYPT_INVALID_ARG == sha512_final(NULL,digest_data));
41 : 1 : ASSERT(CRYPT_INVALID_ARG == sha512_final(&context,NULL));
42 : :
43 : : /* Mandatory cleanup uses call() so descriptors are freed even after a failed
44 : : assertion inside this negative-path test */
45 : 1 : call(m_del(input));
46 : 1 : call(m_del(digest));
47 : :
48 : 1 : RETURN_STATUS;
49 : : }
50 : :
51 : : /**
52 : : * @brief Check that a damaged buffered-byte count is rejected
53 : : * @details A context with a full internal buffer should never be handed back to
54 : : * update or finalization. Rejecting it keeps the API from looping forever or
55 : : * writing past the valid SHA-512 block area
56 : : *
57 : : * @return SUCCESS when damaged buffer state is rejected
58 : : */
59 : 1 : static Return test_libsha512_0003_2(void)
60 : : {
61 : 1 : INITTEST;
62 : :
63 : : static const unsigned char sample_bytes[] = {0x61};
64 : 1 : SHA512_Context context = {0};
65 : :
66 : : /* Prepare ordinary input and output buffers first. The only damaged value in
67 : : this scenario should be the context's buffered-byte counter */
68 : 1 : m_create(unsigned char,input);
69 : 1 : m_create(unsigned char,digest);
70 : :
71 : 1 : ASSERT(SUCCESS == m_copy_buffer(input,sizeof(sample_bytes),sample_bytes));
72 : 1 : ASSERT(SUCCESS == m_resize(digest,SHA512_DIGEST_LENGTH,ZERO_NEW_MEMORY));
73 : :
74 : : /* Convert libmem descriptors to raw pointers after their sizes are known */
75 : 1 : const unsigned char *input_data = m_data_ro(unsigned char,input);
76 : 1 : unsigned char *digest_data = m_data(unsigned char,digest);
77 : :
78 : : /* Start from a real initialized context, then simulate a corrupted caller
79 : : state that claims the internal buffer is already full */
80 : 1 : ASSERT(input_data != NULL);
81 : 1 : ASSERT(digest_data != NULL);
82 : 1 : ASSERT(CRYPT_OK == sha512_init(&context));
83 : :
84 : 1 : context.curlen = sizeof(context.buf);
85 : 1 : ASSERT(CRYPT_INVALID_ARG == sha512_update(&context,input_data,input->length));
86 : 1 : ASSERT(CRYPT_INVALID_ARG == sha512_final(&context,digest_data));
87 : :
88 : : /* Free local descriptors regardless of which invalid-state assertion fails */
89 : 1 : call(m_del(input));
90 : 1 : call(m_del(digest));
91 : :
92 : 1 : RETURN_STATUS;
93 : : }
94 : :
95 : : /**
96 : : * @brief Check that the message length counter cannot wrap
97 : : * @details This implementation stores the SHA-512 message length in a 64-bit
98 : : * bit counter. When a context is already at the largest byte-aligned value, one
99 : : * more byte must be rejected before the counter can overflow
100 : : *
101 : : * @return SUCCESS when update and finalization both report CRYPT_HASH_OVERFLOW
102 : : */
103 : 1 : static Return test_libsha512_0003_3(void)
104 : : {
105 : 1 : INITTEST;
106 : :
107 : : static const unsigned char sample_bytes[] = {0x61};
108 : 1 : SHA512_Context context = {0};
109 : :
110 : : /* Build one extra byte of input and a digest buffer. Both are valid, so the
111 : : expected failure can only come from the length counter limit */
112 : 1 : m_create(unsigned char,input);
113 : 1 : m_create(unsigned char,digest);
114 : :
115 : 1 : ASSERT(SUCCESS == m_copy_buffer(input,sizeof(sample_bytes),sample_bytes));
116 : 1 : ASSERT(SUCCESS == m_resize(digest,SHA512_DIGEST_LENGTH,ZERO_NEW_MEMORY));
117 : :
118 : : /* Work with raw pointers after libmem has finished allocating storage */
119 : 1 : const unsigned char *input_data = m_data_ro(unsigned char,input);
120 : 1 : unsigned char *digest_data = m_data(unsigned char,digest);
121 : :
122 : 1 : ASSERT(input_data != NULL);
123 : 1 : ASSERT(digest_data != NULL);
124 : :
125 : : /* Updating a context already at the byte-aligned maximum must refuse the
126 : : next byte before the bit counter can wrap */
127 : 1 : ASSERT(CRYPT_OK == sha512_init(&context));
128 : 1 : context.length = SHA512_TEST_MAX_BYTE_ALIGNED_BITS;
129 : 1 : ASSERT(CRYPT_HASH_OVERFLOW == sha512_update(&context,input_data,input->length));
130 : :
131 : : /* Finalization also adds buffered bytes to the counter, so it must detect the
132 : : same overflow risk before writing a digest */
133 : 1 : ASSERT(CRYPT_OK == sha512_init(&context));
134 : 1 : context.length = SHA512_TEST_MAX_BYTE_ALIGNED_BITS;
135 : 1 : context.curlen = 1U;
136 : 1 : ASSERT(CRYPT_HASH_OVERFLOW == sha512_final(&context,digest_data));
137 : :
138 : : /* Cleanup is intentionally unconditional from the test's point of view */
139 : 1 : call(m_del(input));
140 : 1 : call(m_del(digest));
141 : :
142 : 1 : RETURN_STATUS;
143 : : }
144 : :
145 : : /**
146 : : * @brief Check that libsha512 fails safely on invalid API use
147 : : * @details These cases cover practical misuse and corrupted state: missing
148 : : * pointers, impossible buffered-byte counts, and messages too long for the
149 : : * library's 64-bit length counter
150 : : *
151 : : * @return SUCCESS when every invalid case is reported as an error
152 : : */
153 : 1 : Return test_libsha512_0003(void)
154 : : {
155 : 1 : INITTEST;
156 : :
157 : : /* Keep invalid-use checks split by user story: missing storage, damaged
158 : : context state, and input that is too large to represent safely */
159 : 1 : TEST(test_libsha512_0003_1,"Missing SHA-512 pointers return CRYPT_INVALID_ARG");
160 : 1 : TEST(test_libsha512_0003_2,"A damaged SHA-512 buffer length is rejected before hashing continues");
161 : 1 : TEST(test_libsha512_0003_3,"SHA-512 length overflow returns CRYPT_HASH_OVERFLOW before wraparound");
162 : :
163 : 1 : RETURN_STATUS;
164 : : }
|