blob: 82c8b33168abffac960690f11e43a4e40aeb4a7a [file] [log] [blame]
Juan Castillo9c25a402015-01-13 12:21:04 +00001/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* Authentication module based on PolarSSL */
32
33#include <stddef.h>
34
35#include <assert.h>
36#include <auth.h>
37#include <debug.h>
38#include <platform.h>
39#include <platform_def.h>
40#include <platform_oid.h>
41
42#include <polarssl/memory_buffer_alloc.h>
43#include <polarssl/oid.h>
44#include <polarssl/platform.h>
45#include <polarssl/sha256.h>
46#include <polarssl/x509_crt.h>
47
48/*
49 * At each authentication stage, the module is responsible for extracting and
50 * storing those elements (keys, hashes, etc.) that will be needed later on
51 * during the Trusted Boot process.
52 */
53
Juan Castilloac402932015-03-05 14:30:00 +000054/* Maximum OID string length ("a.b.c.d.e.f ...") */
55#define MAX_OID_STR_LEN 64
Juan Castillo9c25a402015-01-13 12:21:04 +000056
57/*
58 * An 8 KB stack has been proven to be enough for the current Trusted Boot
59 * process
60 */
61#define POLARSSL_HEAP_SIZE (8*1024)
62static unsigned char heap[POLARSSL_HEAP_SIZE];
63
64/*
65 * RSA public keys:
66 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
67 * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
68 * + 1 + 1 + 9 (rsa oid)
69 * + 1 + 1 (params null)
70 * subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
71 * RSAPublicKey ::= SEQUENCE { 1 + 3
72 * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
73 * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
74 * }
75 *
76 * POLARSSL_MPI_MAX_SIZE is set to 256 bytes (RSA-2048 bit keys) in the
77 * configuration file
78 */
79#define RSA_PUB_DER_MAX_BYTES 38 + 2 * POLARSSL_MPI_MAX_SIZE
80
81/*
Juan Castilloac402932015-03-05 14:30:00 +000082 * SHA256:
83 * DigestInfo ::= SEQUENCE { 1 + 1
84 * digestAlgorithm AlgorithmIdentifier, + 1 + 1 (sequence)
85 * + 1 + 1 + 9 (sha256 oid)
86 * + 1 + 1 (params null)
87 * digest OCTET STRING + 1 + 1 + 32 (sha256)
88 * }
89 */
90#define SHA256_BYTES 32
91#define SHA256_DER_BYTES (19 + SHA256_BYTES)
92
93/*
Juan Castillo9c25a402015-01-13 12:21:04 +000094 * Buffer for storing public keys extracted from certificates while they are
95 * verified
96 */
97static unsigned char pk_buf[RSA_PUB_DER_MAX_BYTES];
98
99/* We use this variable to parse and authenticate the certificates */
100static x509_crt cert;
101
102/* BL specific variables */
103#if IMAGE_BL1
Juan Castilloac402932015-03-05 14:30:00 +0000104static unsigned char sha_bl2[SHA256_DER_BYTES];
Juan Castillo9c25a402015-01-13 12:21:04 +0000105#elif IMAGE_BL2
106/* Buffers to store the hash of BL3-x images */
Juan Castilloac402932015-03-05 14:30:00 +0000107static unsigned char sha_bl30[SHA256_DER_BYTES];
108static unsigned char sha_bl31[SHA256_DER_BYTES];
109static unsigned char sha_bl32[SHA256_DER_BYTES];
110static unsigned char sha_bl33[SHA256_DER_BYTES];
Juan Castillo9c25a402015-01-13 12:21:04 +0000111/* Buffers to store the Trusted and Non-Trusted world public keys */
112static unsigned char tz_world_pk[RSA_PUB_DER_MAX_BYTES];
113static unsigned char ntz_world_pk[RSA_PUB_DER_MAX_BYTES];
114static size_t tz_world_pk_len, ntz_world_pk_len;
115/* Buffer to store the BL3-x public keys */
116static unsigned char content_pk[RSA_PUB_DER_MAX_BYTES];
117static size_t content_pk_len;
118#endif
119
120
121static int x509_get_crt_ext_data(const unsigned char **ext_data,
122 size_t *ext_len,
123 x509_crt *crt,
124 const char *oid)
125{
Juan Castilloac402932015-03-05 14:30:00 +0000126 int ret, oid_len;
Juan Castillo9c25a402015-01-13 12:21:04 +0000127 size_t len;
128 unsigned char *end_ext_data, *end_ext_octet;
129 unsigned char *p;
130 const unsigned char *end;
Juan Castilloac402932015-03-05 14:30:00 +0000131 char oid_str[MAX_OID_STR_LEN];
Juan Castillo9c25a402015-01-13 12:21:04 +0000132
133 p = crt->v3_ext.p;
134 end = crt->v3_ext.p + crt->v3_ext.len;
135
136 ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
137 if (ret != 0)
138 return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
139
140 if (end != p + len)
141 return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
142 POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
143
144 while (p < end) {
145 /*
146 * Extension ::= SEQUENCE {
147 * extnID OBJECT IDENTIFIER,
148 * critical BOOLEAN DEFAULT FALSE,
149 * extnValue OCTET STRING }
150 */
151 x509_buf extn_oid = {0, 0, NULL};
152 int is_critical = 0; /* DEFAULT FALSE */
153
154 ret = asn1_get_tag(&p, end, &len,
155 ASN1_CONSTRUCTED | ASN1_SEQUENCE);
156 if (ret != 0)
157 return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
158
159 end_ext_data = p + len;
160
161 /* Get extension ID */
162 extn_oid.tag = *p;
163
164 ret = asn1_get_tag(&p, end, &extn_oid.len, ASN1_OID);
165 if (ret != 0)
166 return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
167
168 extn_oid.p = p;
169 p += extn_oid.len;
170
171 if ((end - p) < 1)
172 return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
173 POLARSSL_ERR_ASN1_OUT_OF_DATA;
174
175 /* Get optional critical */
176 ret = asn1_get_bool(&p, end_ext_data, &is_critical);
177 if (ret != 0 && (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG))
178 return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
179
180 /* Data should be octet string type */
181 ret = asn1_get_tag(&p, end_ext_data, &len, ASN1_OCTET_STRING);
182 if (ret != 0)
183 return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
184
185 end_ext_octet = p + len;
186
187 if (end_ext_octet != end_ext_data)
188 return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
189 POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
190
191 /* Detect requested extension */
Juan Castilloac402932015-03-05 14:30:00 +0000192 oid_len = oid_get_numeric_string(oid_str,
193 MAX_OID_STR_LEN, &extn_oid);
194 if (oid_len == POLARSSL_ERR_OID_BUF_TOO_SMALL)
195 return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
196 POLARSSL_ERR_ASN1_BUF_TOO_SMALL;
197 if ((oid_len == strlen(oid_str)) && !strcmp(oid, oid_str)) {
Juan Castillo9c25a402015-01-13 12:21:04 +0000198 *ext_data = p;
199 *ext_len = len;
200 return 0;
201 }
202
203 /* Next */
204 p = end_ext_octet;
205 }
206
207 if (p != end)
208 return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
209 POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
210
211 return POLARSSL_ERR_X509_UNKNOWN_OID;
212}
213
214#if IMAGE_BL1
215/*
216 * Parse and verify the BL2 certificate
217 *
218 * This function verifies the integrity of the BL2 certificate, checks that it
219 * has been signed with the ROT key and extracts the BL2 hash stored in the
220 * certificate so it can be matched later against the calculated hash.
221 *
222 * Return: 0 = success, Otherwise = error
223 */
224static int check_bl2_cert(unsigned char *buf, size_t len)
225{
226 const unsigned char *p;
227 size_t sz;
228 int err, flags;
229
230 x509_crt_init(&cert);
231
232 /* Parse the BL2 certificate */
233 err = x509_crt_parse(&cert, buf, len);
234 if (err) {
235 ERROR("BL2 certificate parse error %d.\n", err);
236 goto error;
237 }
238
239 /* Check that it has been signed with the ROT key */
240 err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
241 if (err < 0) {
242 ERROR("Error loading ROT key in DER format %d.\n", err);
243 goto error;
244 }
245
246 sz = (size_t)err;
247 p = pk_buf + sizeof(pk_buf) - sz;
248
249 err = plat_match_rotpk(p, sz);
250 if (err) {
251 ERROR("ROT and BL2 certificate key mismatch\n");
252 goto error;
253 }
254
255 /* Verify certificate */
256 err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
257 if (err) {
258 ERROR("BL2 certificate verification error %d. Flags: 0x%x.\n",
259 err, flags);
260 goto error;
261 }
262
263 /* Extract BL2 image hash from certificate */
264 err = x509_get_crt_ext_data(&p, &sz, &cert, BL2_HASH_OID);
265 if (err) {
266 ERROR("Cannot read BL2 hash from certificate\n");
267 goto error;
268 }
269
Juan Castilloac402932015-03-05 14:30:00 +0000270 assert(sz == SHA256_DER_BYTES);
271 memcpy(sha_bl2, p, SHA256_DER_BYTES);
Juan Castillo9c25a402015-01-13 12:21:04 +0000272
273error:
274 x509_crt_free(&cert);
275
276 return err;
277}
278#endif /* IMAGE_BL1 */
279
280#if IMAGE_BL2
281static int check_trusted_key_cert(unsigned char *buf, size_t len)
282{
283 const unsigned char *p;
284 size_t sz;
285 int err, flags;
286
287 x509_crt_init(&cert);
288
289 /* Parse the Trusted Key certificate */
290 err = x509_crt_parse(&cert, buf, len);
291 if (err) {
292 ERROR("Trusted Key certificate parse error %d.\n", err);
293 goto error;
294 }
295
296 /* Verify Trusted Key certificate */
297 err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
298 if (err) {
299 ERROR("Trusted Key certificate verification error %d. Flags: "
300 "0x%x.\n", err, flags);
301 goto error;
302 }
303
304 /* Check that it has been signed with the ROT key */
305 err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
306 if (err < 0) {
307 ERROR("Error loading ROT key in DER format %d.\n", err);
308 goto error;
309 }
310
311 sz = (size_t)err;
312 p = pk_buf + sizeof(pk_buf) - sz;
313
314 if (plat_match_rotpk(p, sz)) {
315 ERROR("ROT and Trusted Key certificate key mismatch\n");
316 goto error;
317 }
318
319 /* Extract Trusted World key from extensions */
320 err = x509_get_crt_ext_data(&p, &tz_world_pk_len,
321 &cert, TZ_WORLD_PK_OID);
322 if (err) {
323 ERROR("Cannot read Trusted World key\n");
324 goto error;
325 }
326
327 assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES);
328 memcpy(tz_world_pk, p, tz_world_pk_len);
329
330 /* Extract Non-Trusted World key from extensions */
331 err = x509_get_crt_ext_data(&p, &ntz_world_pk_len,
332 &cert, NTZ_WORLD_PK_OID);
333 if (err) {
334 ERROR("Cannot read Non-Trusted World key\n");
335 goto error;
336 }
337
338 assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES);
339 memcpy(ntz_world_pk, p, ntz_world_pk_len);
340
341error:
342 x509_crt_free(&cert);
343
344 return err;
345}
346
347static int check_bl3x_key_cert(const unsigned char *buf, size_t len,
348 const unsigned char *i_key, size_t i_key_len,
349 unsigned char *s_key, size_t *s_key_len,
350 const char *key_oid)
351{
352 const unsigned char *p;
353 size_t sz;
354 int err, flags;
355
356 x509_crt_init(&cert);
357
358 /* Parse key certificate */
359 err = x509_crt_parse(&cert, buf, len);
360 if (err) {
361 ERROR("Key certificate parse error %d.\n", err);
362 goto error;
363 }
364
365 /* Verify certificate */
366 err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
367 if (err) {
368 ERROR("Key certificate verification error %d. Flags: "
369 "0x%x.\n", err, flags);
370 goto error;
371 }
372
373 /* Check that the certificate has been signed by the issuer */
374 err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
375 if (err < 0) {
376 ERROR("Error loading key in DER format %d.\n", err);
377 goto error;
378 }
379
380 sz = (size_t)err;
381 p = pk_buf + sizeof(pk_buf) - sz;
382 if ((sz != i_key_len) || memcmp(p, i_key, sz)) {
383 ERROR("Key certificate not signed with issuer key\n");
384 err = 1;
385 goto error;
386 }
387
388 /* Get the content certificate key */
389 err = x509_get_crt_ext_data(&p, &sz, &cert, key_oid);
390 if (err) {
391 ERROR("Extension %s not found in Key certificate\n", key_oid);
392 goto error;
393 }
394
395 assert(sz <= RSA_PUB_DER_MAX_BYTES);
396 memcpy(s_key, p, sz);
397 *s_key_len = sz;
398
399error:
400 x509_crt_free(&cert);
401
402 return err;
403}
404
405static int check_bl3x_cert(unsigned char *buf, size_t len,
406 const unsigned char *i_key, size_t i_key_len,
407 const char *hash_oid, unsigned char *sha)
408{
409 const unsigned char *p;
410 size_t sz;
411 int err, flags;
412
413 x509_crt_init(&cert);
414
415 /* Parse BL31 content certificate */
416 err = x509_crt_parse(&cert, buf, len);
417 if (err) {
418 ERROR("Content certificate parse error %d.\n", err);
419 goto error;
420 }
421
422 /* Verify certificate */
423 err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
424 if (err) {
425 ERROR("Content certificate verification error %d. Flags: "
426 "0x%x.\n", err, flags);
427 goto error;
428 }
429
430 /* Check that content certificate has been signed with the content
431 * certificate key corresponding to this image */
432 sz = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
433 p = pk_buf + sizeof(pk_buf) - sz;
434
435 if ((sz != i_key_len) || memcmp(p, i_key, sz)) {
436 ERROR("Content certificate not signed with content "
437 "certificate key\n");
438 err = 1;
439 goto error;
440 }
441
442 /* Extract image hash from certificate */
443 err = x509_get_crt_ext_data(&p, &sz, &cert, hash_oid);
444 if (err) {
445 ERROR("Cannot read hash from certificate\n");
446 goto error;
447 }
448
Juan Castilloac402932015-03-05 14:30:00 +0000449 assert(sz == SHA256_DER_BYTES);
450 memcpy(sha, p, SHA256_DER_BYTES);
Juan Castillo9c25a402015-01-13 12:21:04 +0000451
452error:
453 x509_crt_free(&cert);
454
455 return err;
456}
457#endif /* IMAGE_BL2 */
458
459/*
460 * Calculate the hash of the image and check it against the hash extracted
461 * previously from the certificate
462 *
463 * Parameters:
464 * buf: buffer where image is loaded
465 * len: size of the image
466 * sha: matching hash (extracted from the image certificate)
467 *
468 * Return: 0 = match, Otherwise = mismatch
469 */
470static int check_bl_img(unsigned char *buf, size_t len,
471 const unsigned char *sha)
472{
Juan Castilloac402932015-03-05 14:30:00 +0000473 asn1_buf md_oid, params;
474 md_type_t md_alg;
475 int err;
476 unsigned char *p = NULL;
477 const unsigned char *end = NULL;
478 size_t sz;
479 unsigned char img_sha[SHA256_BYTES];
480
481 /*
482 * Extract the image hash from the ASN.1 structure:
483 *
484 * DigestInfo ::= SEQUENCE {
485 * digestAlgorithm AlgorithmIdentifier,
486 * digest OCTET STRING
487 * }
488 */
489
490 p = (unsigned char *)sha;
491 end = sha + SHA256_DER_BYTES;
492 err = asn1_get_tag(&p, end, &sz, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
493 if (err != 0) {
494 ERROR("Malformed image hash extension\n");
495 goto error;
496 }
497
498 err = asn1_get_alg(&p, end, &md_oid, &params);
499 if (err != 0) {
500 ERROR("Malformed image hash algorithm\n");
501 goto error;
502 }
503
504 err = oid_get_md_alg(&md_oid, &md_alg);
505 if (err != 0) {
506 ERROR("Unknown image hash algorithm\n");
507 goto error;
508 }
509
510 /* Only SHA256 is supported */
511 if (md_alg != POLARSSL_MD_SHA256) {
512 ERROR("Only SHA256 is supported as image hash algorithm\n");
513 err = 1;
514 goto error;
515 }
516
517 /* Get the hash */
518 err = asn1_get_tag(&p, end, &sz, ASN1_OCTET_STRING);
519 if (err != 0) {
520 ERROR("Image hash not found in extension\n");
521 goto error;
522 }
Juan Castillo9c25a402015-01-13 12:21:04 +0000523
524 /* Calculate the hash of the image */
525 sha256(buf, len, img_sha, 0);
526
527 /* Match the hash with the one extracted from the certificate */
Juan Castilloac402932015-03-05 14:30:00 +0000528 if (memcmp(img_sha, p, SHA256_BYTES)) {
Juan Castillo9c25a402015-01-13 12:21:04 +0000529 ERROR("Image hash mismatch\n");
530 return 1;
531 }
532
Juan Castilloac402932015-03-05 14:30:00 +0000533error:
534 return err;
Juan Castillo9c25a402015-01-13 12:21:04 +0000535}
536
537/*
538 * Object verification function
539 *
540 * The id parameter will indicate the expected format of the object
541 * (certificate, image, etc).
542 *
543 * Return: 0 = success, Otherwise = error
544 */
545static int polarssl_mod_verify(unsigned int id, uintptr_t obj, size_t len)
546{
547 int ret;
548
549 switch (id) {
550#if IMAGE_BL1
551 case AUTH_BL2_IMG_CERT:
552 ret = check_bl2_cert((unsigned char *)obj, len);
553 break;
554 case AUTH_BL2_IMG:
555 ret = check_bl_img((unsigned char *)obj, len, sha_bl2);
556 break;
557#endif /* IMAGE_BL1 */
558
559#if IMAGE_BL2
560 case AUTH_TRUSTED_KEY_CERT:
561 ret = check_trusted_key_cert((unsigned char *)obj, len);
562 break;
563 case AUTH_BL30_KEY_CERT:
564 ret = check_bl3x_key_cert((unsigned char *)obj, len,
565 tz_world_pk, tz_world_pk_len,
566 content_pk, &content_pk_len,
567 BL30_CONTENT_CERT_PK_OID);
568 break;
569 case AUTH_BL31_KEY_CERT:
570 ret = check_bl3x_key_cert((unsigned char *)obj, len,
571 tz_world_pk, tz_world_pk_len,
572 content_pk, &content_pk_len,
573 BL31_CONTENT_CERT_PK_OID);
574 break;
575 case AUTH_BL32_KEY_CERT:
576 ret = check_bl3x_key_cert((unsigned char *)obj, len,
577 tz_world_pk, tz_world_pk_len,
578 content_pk, &content_pk_len,
579 BL32_CONTENT_CERT_PK_OID);
580 break;
581 case AUTH_BL33_KEY_CERT:
582 ret = check_bl3x_key_cert((unsigned char *)obj, len,
583 ntz_world_pk, ntz_world_pk_len,
584 content_pk, &content_pk_len,
585 BL33_CONTENT_CERT_PK_OID);
586 break;
587 case AUTH_BL30_IMG_CERT:
588 ret = check_bl3x_cert((unsigned char *)obj, len,
589 content_pk, content_pk_len,
590 BL30_HASH_OID, sha_bl30);
591 break;
592 case AUTH_BL31_IMG_CERT:
593 ret = check_bl3x_cert((unsigned char *)obj, len,
594 content_pk, content_pk_len,
595 BL31_HASH_OID, sha_bl31);
596 break;
597 case AUTH_BL32_IMG_CERT:
598 ret = check_bl3x_cert((unsigned char *)obj, len,
599 content_pk, content_pk_len,
600 BL32_HASH_OID, sha_bl32);
601 break;
602 case AUTH_BL33_IMG_CERT:
603 ret = check_bl3x_cert((unsigned char *)obj, len,
604 content_pk, content_pk_len,
605 BL33_HASH_OID, sha_bl33);
606 break;
607 case AUTH_BL30_IMG:
608 ret = check_bl_img((unsigned char *)obj, len, sha_bl30);
609 break;
610 case AUTH_BL31_IMG:
611 ret = check_bl_img((unsigned char *)obj, len, sha_bl31);
612 break;
613 case AUTH_BL32_IMG:
614 ret = check_bl_img((unsigned char *)obj, len, sha_bl32);
615 break;
616 case AUTH_BL33_IMG:
617 ret = check_bl_img((unsigned char *)obj, len, sha_bl33);
618 break;
619#endif /* IMAGE_BL2 */
620 default:
621 ret = -1;
622 break;
623 }
624
625 return ret;
626}
627
628/*
629 * Module initialization function
630 *
631 * Return: 0 = success, Otherwise = error
632 */
633static int polarssl_mod_init(void)
634{
635 /* Initialize the PolarSSL heap */
636 return memory_buffer_alloc_init(heap, POLARSSL_HEAP_SIZE);
637}
638
639const auth_mod_t auth_mod = {
640 .name = "PolarSSL",
641 .init = polarssl_mod_init,
642 .verify = polarssl_mod_verify
643};