9e75d0c3afee4d28c83e0a6641d36e820357e5b9
[akaros.git] / kern / lib / crypto / 2common.c
1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  *
5  * Common functions between firmware and kernel verified boot.
6  * (Firmware portion)
7  */
8
9 #include "2sysincludes.h"
10 #include "2common.h"
11 #include "2rsa.h"
12 #include "2sha.h"
13
14 int vb2_safe_memcmp(const void *s1, const void *s2, size_t size)
15 {
16         const unsigned char *us1 = s1;
17         const unsigned char *us2 = s2;
18         int result = 0;
19
20         if (0 == size)
21                 return 0;
22
23         /*
24          * Code snippet without data-dependent branch due to Nate Lawson
25          * (nate@root.org) of Root Labs.
26          */
27         while (size--)
28                 result |= *us1++ ^ *us2++;
29
30         return result != 0;
31 }
32
33 int vb2_align(uint8_t **ptr, uint32_t *size, uint32_t align, uint32_t want_size)
34 {
35         uintptr_t p = (uintptr_t)*ptr;
36         uintptr_t offs = p & (align - 1);
37
38         if (offs) {
39                 offs = align - offs;
40
41                 if (*size < offs)
42                         return VB2_ERROR_ALIGN_BIGGER_THAN_SIZE;
43
44                 *ptr += offs;
45                 *size -= offs;
46         }
47
48         if (*size < want_size)
49                 return VB2_ERROR_ALIGN_SIZE;
50
51         return VB2_SUCCESS;
52 }
53
54 void vb2_workbuf_init(struct vb2_workbuf *wb, uint8_t *buf, uint32_t size)
55 {
56         wb->buf = buf;
57         wb->size = size;
58
59         /* Align the buffer so allocations will be aligned */
60         if (vb2_align(&wb->buf, &wb->size, VB2_WORKBUF_ALIGN, 0))
61                 wb->size = 0;
62 }
63
64 /**
65  * Round up a number to a multiple of VB2_WORKBUF_ALIGN
66  *
67  * @param v             Number to round up
68  * @return The number, rounded up.
69  */
70 static __inline uint32_t wb_round_up(uint32_t v)
71 {
72         return (v + VB2_WORKBUF_ALIGN - 1) & ~(VB2_WORKBUF_ALIGN - 1);
73 }
74
75 void *vb2_workbuf_alloc(struct vb2_workbuf *wb, uint32_t size)
76 {
77         uint8_t *ptr = wb->buf;
78
79         /* Round up size to work buffer alignment */
80         size = wb_round_up(size);
81
82         if (size > wb->size)
83                 return NULL;
84
85         wb->buf += size;
86         wb->size -= size;
87
88         return ptr;
89 }
90
91 void *vb2_workbuf_realloc(struct vb2_workbuf *wb,
92                           uint32_t oldsize,
93                           uint32_t newsize)
94 {
95         /*
96          * Just free and allocate to update the size.  No need to move/copy
97          * memory, since the new pointer is guaranteed to be the same as the
98          * old one.  The new allocation can fail, if the new size is too big.
99          */
100         vb2_workbuf_free(wb, oldsize);
101         return vb2_workbuf_alloc(wb, newsize);
102 }
103
104 void vb2_workbuf_free(struct vb2_workbuf *wb, uint32_t size)
105 {
106         /* Round up size to work buffer alignment */
107         size = wb_round_up(size);
108
109         wb->buf -= size;
110         wb->size += size;
111 }
112
113 ptrdiff_t vb2_offset_of(const void *base, const void *ptr)
114 {
115         return (uintptr_t)ptr - (uintptr_t)base;
116 }