1/* Copyright (c) 2011 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 * Tests for vboot_audio
6 */
7
8#include <stddef.h>
9#include <stdint.h>
10#include <stdio.h>
11#include <stdlib.h>
12
13#include "crc32.h"
14#include "gbb_header.h"
15#include "host_common.h"
16#include "load_kernel_fw.h"
17#include "rollback_index.h"
18#include "test_common.h"
19#include "vboot_audio.h"
20#include "vboot_audio_private.h"
21#include "vboot_common.h"
22#include "vboot_display.h"
23#include "vboot_nvstorage.h"
24#include "vboot_struct.h"
25
26
27/* Builtin notes */
28extern VbDevMusicNote default_notes_[], short_notes_[];
29extern uint32_t default_count_, short_count_;
30
31/* Mock data */
32static VbCommonParams cparams;
33static GoogleBinaryBlockHeader gbb;
34static VbDevMusicNote good_notes[] = { {100, 100},
35                                       {100, 0},
36                                       {200, 200},
37                                       {100, 0},
38                                       {300, 300},
39                                       {100, 0},
40                                       {400, 400},
41                                       {30000, 0} };
42static VbDevMusic good_header =
43{ .sig = { '$', 'S', 'N', 'D' },
44  .count = sizeof(good_notes) / sizeof(VbDevMusicNote),
45};
46
47static uint8_t notebuf[sizeof(good_header) +
48                       sizeof(good_notes) - sizeof(VbDevMusicNote)];
49
50static VbDevMusic *use_hdr;
51static VbDevMusicNote *use_notes;
52static uint32_t use_size;
53
54/* Set correct checksum for custom notes */
55void FixChecksum(VbDevMusic *hdr) {
56  hdr->checksum = Crc32(&(hdr->count), sizeof(hdr->count) +
57                        hdr->count * sizeof(hdr->notes[0]));
58}
59
60/* Reset mock data (for use before each test) */
61static void ResetMocks(void) {
62  VBDEBUG(("ResetMocks()\n"));
63  Memset(&cparams, 0, sizeof(cparams));
64  cparams.gbb_data = &gbb;
65  cparams.gbb = &gbb;
66  Memset(&gbb, 0, sizeof(gbb));
67  gbb.major_version = GBB_MAJOR_VER;
68  gbb.minor_version = GBB_MINOR_VER;
69  gbb.flags = 0;
70  use_hdr = (VbDevMusic *)notebuf;
71  use_notes = use_hdr->notes;
72  Memcpy(use_hdr, &good_header, sizeof(good_header));
73  Memcpy(use_notes, good_notes, sizeof(good_notes));
74  FixChecksum(use_hdr);
75  use_size = sizeof(notebuf);
76}
77
78/* Compare two sets of notes */
79static int NotesMatch(VbDevMusicNote *a, VbDevMusicNote *b, uint32_t count) {
80  int i;
81  if (!a || !b)
82    return 0;
83
84  for ( i=0; i<count; i++) {
85    if ( a[i].msec != b[i].msec || a[i].frequency != b[i].frequency)
86      return 0;
87  }
88
89  return count;
90}
91
92
93
94
95/****************************************************************************/
96/* Mocked verification functions */
97
98void *VbExGetMusicPtr(void) {
99  return use_hdr;
100}
101
102uint32_t VbExMaxMusicSize(void) {
103  return use_size;
104}
105
106
107/****************************************************************************/
108
109static void VbAudioTest(void) {
110  VbAudioContext* a = 0;
111
112  /* default is okay */
113  ResetMocks();
114  use_hdr = 0;
115  a = VbAudioOpen(&cparams);
116  TEST_TRUE(a->music_notes ==  default_notes_ &&
117            a->note_count == default_count_,
118            "VbAudioTest( default )");
119  VbAudioClose(a);
120
121  /* short is okay */
122  ResetMocks();
123  use_hdr = 0;
124  gbb.flags = 0x00000001;
125  a = VbAudioOpen(&cparams);
126  TEST_TRUE(a->music_notes == short_notes_ &&
127            a->note_count == short_count_,
128            "VbAudioTest( short )");
129  VbAudioClose(a);
130
131  /* good custom is okay */
132  ResetMocks();
133  a = VbAudioOpen(&cparams);
134  TEST_TRUE(NotesMatch(a->music_notes, good_notes, good_header.count) &&
135            a->note_count == good_header.count,
136            "VbAudioTest( custom good )");
137  VbAudioClose(a);
138
139  /* good custom is rejected when short flag is set */
140  ResetMocks();
141  gbb.flags = 0x00000001;
142  a = VbAudioOpen(&cparams);
143  TEST_TRUE(a->music_notes == short_notes_ &&
144            a->note_count == short_count_,
145            "VbAudioTest( short has priority )");
146  VbAudioClose(a);
147
148  /* too short gets extended */
149  ResetMocks();
150  use_hdr->count--;
151  FixChecksum(use_hdr);
152  a = VbAudioOpen(&cparams);
153  TEST_TRUE(NotesMatch(a->music_notes, use_notes, use_hdr->count) &&
154            a->note_count == use_hdr->count + 1 &&
155            a->music_notes[use_hdr->count].msec == 28700 &&
156            a->music_notes[use_hdr->count].frequency == 0,
157            "VbAudioTest( too short )");
158  VbAudioClose(a);
159
160  /* too quiet is rejected */
161  ResetMocks();
162  use_notes[6].msec = 10;
163  FixChecksum(use_hdr);
164  a = VbAudioOpen(&cparams);
165  TEST_TRUE(a->music_notes == default_notes_ &&
166            a->note_count == default_count_,
167            "VbAudioTest( too quiet )");
168  VbAudioClose(a);
169
170  /* inaudible is rejected */
171  ResetMocks();
172  use_notes[0].frequency = 99;
173  use_notes[2].frequency = 2001;
174  FixChecksum(use_hdr);
175  a = VbAudioOpen(&cparams);
176  TEST_TRUE(a->music_notes == default_notes_ &&
177            a->note_count == default_count_,
178            "VbAudioTest( inaudible )");
179  VbAudioClose(a);
180
181  /* bad signature is rejected */
182  ResetMocks();
183  use_hdr->sig[0] = 'C';
184  a = VbAudioOpen(&cparams);
185  TEST_TRUE(a->music_notes == default_notes_ &&
186            a->note_count == default_count_,
187            "VbAudioTest( bad signature )");
188  VbAudioClose(a);
189
190  /* count == 0 is rejected */
191  ResetMocks();
192  use_hdr->count = 0;
193  a = VbAudioOpen(&cparams);
194  TEST_TRUE(a->music_notes == default_notes_ &&
195            a->note_count == default_count_,
196            "VbAudioTest( count == 0 )");
197  VbAudioClose(a);
198
199  /* too big is rejected */
200  ResetMocks();
201  use_hdr->count = 999;
202  a = VbAudioOpen(&cparams);
203  TEST_TRUE(a->music_notes == default_notes_ &&
204            a->note_count == default_count_,
205            "VbAudioTest( count too big )");
206  VbAudioClose(a);
207
208  /* bad checksum is rejected */
209  ResetMocks();
210  use_hdr->checksum++;
211  a = VbAudioOpen(&cparams);
212  TEST_TRUE(a->music_notes == default_notes_ &&
213            a->note_count == default_count_,
214            "VbAudioTest( count too big )");
215  VbAudioClose(a);
216}
217
218
219int main(int argc, char* argv[]) {
220  int error_code = 0;
221
222  VbAudioTest();
223
224  if (!gTestSuccess)
225    error_code = 255;
226
227  if (vboot_api_stub_check_memory())
228    error_code = 255;
229
230  return error_code;
231}
232