~ubuntu-branches/ubuntu/natty/9base/natty

« back to all changes in this revision

Viewing changes to lib9/sec/sha1.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2010-06-04 17:22:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20100604172203-ei85j0da495sr8ut
Tags: 1:6-1
* Adding Kai as co-maintainer.
* Merging upstream version 6.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "os.h"
 
2
#include <libsec.h>
 
3
 
 
4
static void encode(uchar*, u32int*, ulong);
 
5
 
 
6
extern void _sha1block(uchar*, ulong, u32int*);
 
7
 
 
8
/*
 
9
 *  we require len to be a multiple of 64 for all but
 
10
 *  the last call.  There must be room in the input buffer
 
11
 *  to pad.
 
12
 */
 
13
SHA1state*
 
14
sha1(uchar *p, ulong len, uchar *digest, SHA1state *s)
 
15
{
 
16
        uchar buf[128];
 
17
        u32int x[16];
 
18
        int i;
 
19
        uchar *e;
 
20
 
 
21
        if(s == nil){
 
22
                s = malloc(sizeof(*s));
 
23
                if(s == nil)
 
24
                        return nil;
 
25
                memset(s, 0, sizeof(*s));
 
26
                s->malloced = 1;
 
27
        }
 
28
 
 
29
        if(s->seeded == 0){
 
30
                /* seed the state, these constants would look nicer big-endian */
 
31
                s->state[0] = 0x67452301;
 
32
                s->state[1] = 0xefcdab89;
 
33
                s->state[2] = 0x98badcfe;
 
34
                s->state[3] = 0x10325476;
 
35
                s->state[4] = 0xc3d2e1f0;
 
36
                s->seeded = 1;
 
37
        }
 
38
 
 
39
        /* fill out the partial 64 byte block from previous calls */
 
40
        if(s->blen){
 
41
                i = 64 - s->blen;
 
42
                if(len < i)
 
43
                        i = len;
 
44
                memmove(s->buf + s->blen, p, i);
 
45
                len -= i;
 
46
                s->blen += i;
 
47
                p += i;
 
48
                if(s->blen == 64){
 
49
                        _sha1block(s->buf, s->blen, s->state);
 
50
                        s->len += s->blen;
 
51
                        s->blen = 0;
 
52
                }
 
53
        }
 
54
 
 
55
        /* do 64 byte blocks */
 
56
        i = len & ~0x3f;
 
57
        if(i){
 
58
                _sha1block(p, i, s->state);
 
59
                s->len += i;
 
60
                len -= i;
 
61
                p += i;
 
62
        }
 
63
 
 
64
        /* save the left overs if not last call */
 
65
        if(digest == 0){
 
66
                if(len){
 
67
                        memmove(s->buf, p, len);
 
68
                        s->blen += len;
 
69
                }
 
70
                return s;
 
71
        }
 
72
 
 
73
        /*
 
74
         *  this is the last time through, pad what's left with 0x80,
 
75
         *  0's, and the input count to create a multiple of 64 bytes
 
76
         */
 
77
        if(s->blen){
 
78
                p = s->buf;
 
79
                len = s->blen;
 
80
        } else {
 
81
                memmove(buf, p, len);
 
82
                p = buf;
 
83
        }
 
84
        s->len += len;
 
85
        e = p + len;
 
86
        if(len < 56)
 
87
                i = 56 - len;
 
88
        else
 
89
                i = 120 - len;
 
90
        memset(e, 0, i);
 
91
        *e = 0x80;
 
92
        len += i;
 
93
 
 
94
        /* append the count */
 
95
        x[0] = s->len>>29;
 
96
        x[1] = s->len<<3;
 
97
        encode(p+len, x, 8);
 
98
 
 
99
        /* digest the last part */
 
100
        _sha1block(p, len+8, s->state);
 
101
        s->len += len+8;
 
102
 
 
103
        /* return result and free state */
 
104
        encode(digest, s->state, SHA1dlen);
 
105
        if(s->malloced == 1)
 
106
                free(s);
 
107
        return nil;
 
108
}
 
109
 
 
110
/*
 
111
 *      encodes input (ulong) into output (uchar). Assumes len is
 
112
 *      a multiple of 4.
 
113
 */
 
114
static void
 
115
encode(uchar *output, u32int *input, ulong len)
 
116
{
 
117
        u32int x;
 
118
        uchar *e;
 
119
 
 
120
        for(e = output + len; output < e;) {
 
121
                x = *input++;
 
122
                *output++ = x >> 24;
 
123
                *output++ = x >> 16;
 
124
                *output++ = x >> 8;
 
125
                *output++ = x;
 
126
        }
 
127
}