• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "lmots.h"
3#include "mbedtls/lms.h"
4
5#if defined(MBEDTLS_TEST_HOOKS)
6int check_lmots_private_key_for_leak(unsigned char * sig)
7{
8    size_t idx;
9
10    for( idx = MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(MBEDTLS_LMOTS_SHA256_N32_W8);
11         idx < MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8);
12         idx++ )
13    {
14        TEST_EQUAL( sig[idx], 0x7E );
15    }
16
17    return( 0 );
18
19exit:
20    return( -1 );
21}
22#endif /* defined(MBEDTLS_TEST_HOOKS) */
23
24/* END_HEADER */
25
26/* BEGIN_DEPENDENCIES
27 * depends_on:MBEDTLS_LMS_C
28 * END_DEPENDENCIES
29 */
30
31/* BEGIN_CASE depends_on:MBEDTLS_LMS_PRIVATE */
32void lmots_sign_verify_test ( data_t *msg, data_t *key_id, int leaf_id,
33                              data_t *seed )
34{
35    mbedtls_lmots_public_t pub_ctx;
36    mbedtls_lmots_private_t priv_ctx;
37    unsigned char sig[MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8)];
38
39    mbedtls_lmots_public_init( &pub_ctx );
40    mbedtls_lmots_private_init( &priv_ctx );
41
42    TEST_EQUAL( mbedtls_lmots_generate_private_key(&priv_ctx, MBEDTLS_LMOTS_SHA256_N32_W8,
43                key_id->x, leaf_id, seed->x, seed->len ), 0 );
44    TEST_EQUAL( mbedtls_lmots_calculate_public_key(&pub_ctx, &priv_ctx), 0 );
45    TEST_EQUAL( mbedtls_lmots_sign(&priv_ctx, &mbedtls_test_rnd_std_rand, NULL,
46                msg->x, msg->len, sig, sizeof(sig), NULL ), 0 );
47    TEST_EQUAL( mbedtls_lmots_verify(&pub_ctx, msg->x, msg->len, sig, sizeof(sig)), 0 );
48
49exit:
50    mbedtls_lmots_public_free( &pub_ctx );
51    mbedtls_lmots_private_free( &priv_ctx );
52}
53/* END_CASE */
54
55/* BEGIN_CASE depends_on:MBEDTLS_LMS_PRIVATE */
56void lmots_sign_verify_null_msg_test ( data_t *key_id, int leaf_id, data_t *seed )
57{
58    mbedtls_lmots_public_t pub_ctx;
59    mbedtls_lmots_private_t priv_ctx;
60    unsigned char sig[MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8)];
61
62    mbedtls_lmots_public_init( &pub_ctx );
63    mbedtls_lmots_private_init( &priv_ctx );
64
65    TEST_EQUAL( mbedtls_lmots_generate_private_key(&priv_ctx, MBEDTLS_LMOTS_SHA256_N32_W8,
66                key_id->x, leaf_id, seed->x, seed->len ), 0 );
67    TEST_EQUAL( mbedtls_lmots_calculate_public_key(&pub_ctx, &priv_ctx), 0 );
68    TEST_EQUAL( mbedtls_lmots_sign(&priv_ctx, &mbedtls_test_rnd_std_rand, NULL,
69                NULL, 0, sig, sizeof(sig), NULL ), 0 );
70    TEST_EQUAL( mbedtls_lmots_verify(&pub_ctx, NULL, 0, sig, sizeof(sig)), 0 );
71
72exit:
73    mbedtls_lmots_public_free( &pub_ctx );
74    mbedtls_lmots_private_free( &priv_ctx );
75}
76/* END_CASE */
77
78/* BEGIN_CASE */
79void lmots_verify_test ( data_t *msg, data_t *sig, data_t *pub_key,
80                         int expected_rc )
81{
82    mbedtls_lmots_public_t ctx;
83    unsigned int size;
84    unsigned char *tmp_sig = NULL;
85
86    mbedtls_lmots_public_init( &ctx );
87
88    TEST_EQUAL(mbedtls_lmots_import_public_key( &ctx, pub_key->x, pub_key->len ), 0);
89
90    TEST_EQUAL(mbedtls_lmots_verify( &ctx, msg->x, msg->len, sig->x, sig->len ), expected_rc);
91
92    /* Test negative cases if the input data is valid */
93    if( expected_rc == 0 )
94    {
95        if( msg->len >= 1 )
96        {
97            /* Altering first message byte must cause verification failure */
98            msg->x[0] ^= 1;
99            TEST_EQUAL(mbedtls_lmots_verify( &ctx, msg->x, msg->len, sig->x, sig->len ),
100                       MBEDTLS_ERR_LMS_VERIFY_FAILED);
101            msg->x[0] ^= 1;
102
103            /* Altering last message byte must cause verification failure */
104            msg->x[msg->len - 1] ^= 1;
105            TEST_EQUAL(mbedtls_lmots_verify( &ctx, msg->x, msg->len, sig->x, sig->len ),
106                       MBEDTLS_ERR_LMS_VERIFY_FAILED);
107            msg->x[msg->len - 1] ^= 1;
108        }
109
110        /* Altering first signature byte must cause verification failure */
111        sig->x[0] ^= 1;
112        TEST_EQUAL(mbedtls_lmots_verify( &ctx, msg->x, msg->len, sig->x, sig->len ),
113                   MBEDTLS_ERR_LMS_VERIFY_FAILED);
114        sig->x[0] ^= 1;
115
116        /* Altering last signature byte must cause verification failure */
117        sig->x[sig->len - 1] ^= 1;
118        TEST_EQUAL(mbedtls_lmots_verify( &ctx, msg->x, msg->len, sig->x, sig->len ),
119                   MBEDTLS_ERR_LMS_VERIFY_FAILED);
120        sig->x[sig->len - 1] ^= 1;
121
122        /* Signatures of all sizes must not verify, whether shorter or longer */
123        for( size = 0; size < sig->len; size++ ) {
124            if( size == sig->len )
125                continue;
126
127            ASSERT_ALLOC( tmp_sig, size );
128            if( tmp_sig != NULL )
129                memcpy( tmp_sig, sig->x, MIN(size, sig->len) );
130
131            TEST_EQUAL(mbedtls_lmots_verify( &ctx, msg->x, msg->len, tmp_sig, size ),
132                       MBEDTLS_ERR_LMS_VERIFY_FAILED);
133            mbedtls_free( tmp_sig );
134            tmp_sig = NULL;
135        }
136    }
137
138exit:
139    mbedtls_free( tmp_sig );
140    mbedtls_lmots_public_free( &ctx );
141}
142/* END_CASE */
143
144/* BEGIN_CASE */
145void lmots_import_export_test (  data_t * pub_key, int expected_import_rc )
146{
147    mbedtls_lmots_public_t ctx;
148    unsigned char *exported_pub_key = NULL;
149    size_t exported_pub_key_buf_size;
150    size_t exported_pub_key_size;
151
152    mbedtls_lmots_public_init( &ctx );
153    TEST_EQUAL( mbedtls_lmots_import_public_key( &ctx, pub_key->x, pub_key->len ),
154                expected_import_rc );
155
156    if( expected_import_rc == 0 )
157    {
158        exported_pub_key_buf_size = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(MBEDTLS_LMOTS_SHA256_N32_W8);
159        ASSERT_ALLOC( exported_pub_key, exported_pub_key_buf_size );
160
161        TEST_EQUAL( mbedtls_lmots_export_public_key( &ctx, exported_pub_key,
162                                                   exported_pub_key_buf_size,
163                                                   &exported_pub_key_size ), 0 );
164
165        TEST_EQUAL( exported_pub_key_size,
166                    MBEDTLS_LMOTS_PUBLIC_KEY_LEN(MBEDTLS_LMOTS_SHA256_N32_W8) );
167        ASSERT_COMPARE( pub_key->x, pub_key->len,
168                        exported_pub_key, exported_pub_key_size );
169        mbedtls_free(exported_pub_key);
170        exported_pub_key = NULL;
171
172        /* Export into too-small buffer should fail */
173        exported_pub_key_buf_size = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(MBEDTLS_LMOTS_SHA256_N32_W8) - 1;
174        ASSERT_ALLOC( exported_pub_key, exported_pub_key_buf_size);
175        TEST_EQUAL( mbedtls_lmots_export_public_key( &ctx, exported_pub_key,
176                                                   exported_pub_key_buf_size, NULL ),
177                    MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL );
178        mbedtls_free(exported_pub_key);
179        exported_pub_key = NULL;
180
181        /* Export into too-large buffer should succeed */
182        exported_pub_key_buf_size = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(MBEDTLS_LMOTS_SHA256_N32_W8) + 1;
183        ASSERT_ALLOC( exported_pub_key, exported_pub_key_buf_size);
184        TEST_EQUAL( mbedtls_lmots_export_public_key( &ctx, exported_pub_key,
185                                                   exported_pub_key_buf_size,
186                                                   &exported_pub_key_size ),
187                    0 );
188        ASSERT_COMPARE( pub_key->x, pub_key->len,
189                        exported_pub_key, exported_pub_key_size );
190        mbedtls_free(exported_pub_key);
191        exported_pub_key = NULL;
192    }
193
194exit:
195    mbedtls_lmots_public_free( &ctx );
196    mbedtls_free( exported_pub_key );
197}
198/* END_CASE */
199
200/* BEGIN_CASE depends_on:MBEDTLS_LMS_PRIVATE */
201void lmots_reuse_test ( data_t *msg, data_t *key_id, int leaf_id, data_t *seed )
202{
203    mbedtls_lmots_private_t ctx;
204    unsigned char sig[MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8)];
205
206    mbedtls_lmots_private_init( &ctx );
207    TEST_EQUAL( mbedtls_lmots_generate_private_key(&ctx, MBEDTLS_LMOTS_SHA256_N32_W8,
208                                                   key_id->x, leaf_id, seed->x,
209                                                   seed->len ), 0 );
210    TEST_EQUAL( mbedtls_lmots_sign(&ctx, mbedtls_test_rnd_std_rand, NULL,
211                                   msg->x, msg->len, sig, sizeof( sig ), NULL ), 0 );
212
213    /* Running another sign operation should fail, since the key should now have
214     * been erased.
215     */
216    TEST_EQUAL( mbedtls_lmots_sign(&ctx, mbedtls_test_rnd_std_rand, NULL,
217                                   msg->x, msg->len, sig, sizeof( sig ), NULL ), MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
218
219exit:
220    mbedtls_lmots_private_free( &ctx );
221}
222/* END_CASE */
223
224/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_LMS_PRIVATE */
225void lmots_signature_leak_test ( data_t *msg, data_t *key_id, int leaf_id,
226                                 data_t *seed )
227{
228    mbedtls_lmots_private_t ctx;
229    unsigned char sig[MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8)];
230
231    mbedtls_lmots_sign_private_key_invalidated_hook = &check_lmots_private_key_for_leak;
232
233    /* Fill with recognisable pattern */
234    memset( sig, 0x7E, sizeof( sig ) );
235
236    mbedtls_lmots_private_init( &ctx );
237    TEST_EQUAL( mbedtls_lmots_generate_private_key(&ctx, MBEDTLS_LMOTS_SHA256_N32_W8,
238                                                   key_id->x, leaf_id, seed->x,
239                                                   seed->len ), 0 );
240    TEST_EQUAL( mbedtls_lmots_sign(&ctx, mbedtls_test_rnd_std_rand, NULL,
241                                   msg->x, msg->len, sig, sizeof( sig ), NULL ), 0 );
242
243exit:
244    mbedtls_lmots_private_free( &ctx );
245    mbedtls_lmots_sign_private_key_invalidated_hook = NULL;
246}
247/* END_CASE */
248