1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright © 2009 Michael Sparmann
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "config.h"
#include "system.h"
#include "s5l87xx.h"
#include "clocking-s5l8702.h"
#include "crypto-s5l8702.h"
void hwkeyaes(enum hwkeyaes_direction direction, uint32_t keyidx, void* data, uint32_t size)
{
int i;
clockgate_enable(CLOCKGATE_AES, true);
for (i = 0; i < 4; i++) AESIV[i] = 0;
AESUNKREG0 = 1;
AESUNKREG0 = 0;
AESCONTROL = 1;
AESUNKREG1 = 0;
AESTYPE = keyidx;
AESTYPE2 = ~AESTYPE;
AESUNKREG2 = 0;
AESKEYLEN = direction == HWKEYAES_ENCRYPT ? 9 : 8;
AESOUTSIZE = size;
AESOUTADDR = data;
AESINSIZE = size;
AESINADDR = data;
AESAUXSIZE = size;
AESAUXADDR = data;
AESSIZE3 = size;
commit_discard_dcache();
AESGO = 1;
while (!(AESSTATUS & 0xf));
clockgate_enable(CLOCKGATE_AES, false);
}
void sha1(void* data, uint32_t size, void* hash)
{
int i, space;
bool done = false;
uint32_t tmp32[16];
uint8_t* tmp8 = (uint8_t*)tmp32;
uint32_t* databuf = (uint32_t*)data;
uint32_t* hashbuf = (uint32_t*)hash;
clockgate_enable(CLOCKGATE_SHA, true);
SHA1RESET = 1;
while (SHA1CONFIG & 1);
SHA1RESET = 0;
SHA1CONFIG = 0;
while (!done)
{
space = ((uint32_t)databuf) - ((uint32_t)data) - size + 64;
if (space > 0)
{
for (i = 0; i < 16; i++) tmp32[i] = 0;
if (space <= 64)
{
for (i = 0; i < 64 - space; i++)
tmp8[i] = ((uint8_t*)databuf)[i];
tmp8[64 - space] = 0x80;
}
if (space >= 8)
{
tmp8[0x3b] = (size >> 29) & 0xff;
tmp8[0x3c] = (size >> 21) & 0xff;
tmp8[0x3d] = (size >> 13) & 0xff;
tmp8[0x3e] = (size >> 5) & 0xff;
tmp8[0x3f] = (size << 3) & 0xff;
done = true;
}
for (i = 0; i < 16; i++) SHA1DATAIN[i] = tmp32[i];
}
else
for (i = 0; i < 16; i++) SHA1DATAIN[i] = *databuf++;
SHA1CONFIG |= 2;
while (SHA1CONFIG & 1);
SHA1CONFIG |= 8;
}
for (i = 0; i < 5; i++) *hashbuf++ = SHA1RESULT[i];
clockgate_enable(CLOCKGATE_SHA, false);
}
|