~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/heimdal/lib/krb5/n-fold.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1999 Kungliga Tekniska Högskolan
 
3
 * (Royal Institute of Technology, Stockholm, Sweden).
 
4
 * All rights reserved.
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions
 
8
 * are met:
 
9
 *
 
10
 * 1. Redistributions of source code must retain the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer.
 
12
 *
 
13
 * 2. Redistributions in binary form must reproduce the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer in the
 
15
 *    documentation and/or other materials provided with the distribution.
 
16
 *
 
17
 * 3. Neither the name of KTH nor the names of its contributors may be
 
18
 *    used to endorse or promote products derived from this software without
 
19
 *    specific prior written permission.
 
20
 *
 
21
 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 
22
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
24
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
 
25
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
26
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
27
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 
28
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
29
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
30
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
31
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
 
32
 
 
33
#include "krb5_locl.h"
 
34
 
 
35
RCSID("$Id$");
 
36
 
 
37
static krb5_error_code
 
38
rr13(unsigned char *buf, size_t len)
 
39
{
 
40
    unsigned char *tmp;
 
41
    int bytes = (len + 7) / 8;
 
42
    int i;
 
43
    if(len == 0)
 
44
        return 0;
 
45
    {
 
46
        const int bits = 13 % len;
 
47
        const int lbit = len % 8;
 
48
 
 
49
        tmp = malloc(bytes);
 
50
        if (tmp == NULL)
 
51
            return ENOMEM;
 
52
        memcpy(tmp, buf, bytes);
 
53
        if(lbit) {
 
54
            /* pad final byte with inital bits */
 
55
            tmp[bytes - 1] &= 0xff << (8 - lbit);
 
56
            for(i = lbit; i < 8; i += len)
 
57
                tmp[bytes - 1] |= buf[0] >> i;
 
58
        }
 
59
        for(i = 0; i < bytes; i++) {
 
60
            int bb;
 
61
            int b1, s1, b2, s2;
 
62
            /* calculate first bit position of this byte */
 
63
            bb = 8 * i - bits;
 
64
            while(bb < 0)
 
65
                bb += len;
 
66
            /* byte offset and shift count */
 
67
            b1 = bb / 8;
 
68
            s1 = bb % 8;
 
69
        
 
70
            if(bb + 8 > bytes * 8)
 
71
                /* watch for wraparound */
 
72
                s2 = (len + 8 - s1) % 8;
 
73
            else
 
74
                s2 = 8 - s1;
 
75
            b2 = (b1 + 1) % bytes;
 
76
            buf[i] = (tmp[b1] << s1) | (tmp[b2] >> s2);
 
77
        }
 
78
        free(tmp);
 
79
    }
 
80
    return 0;
 
81
}
 
82
 
 
83
/* Add `b' to `a', both being one's complement numbers. */
 
84
static void
 
85
add1(unsigned char *a, unsigned char *b, size_t len)
 
86
{
 
87
    int i;
 
88
    int carry = 0;
 
89
    for(i = len - 1; i >= 0; i--){
 
90
        int x = a[i] + b[i] + carry;
 
91
        carry = x > 0xff;
 
92
        a[i] = x & 0xff;
 
93
    }
 
94
    for(i = len - 1; carry && i >= 0; i--){
 
95
        int x = a[i] + carry;
 
96
        carry = x > 0xff;
 
97
        a[i] = x & 0xff;
 
98
    }
 
99
}
 
100
 
 
101
krb5_error_code KRB5_LIB_FUNCTION
 
102
_krb5_n_fold(const void *str, size_t len, void *key, size_t size)
 
103
{
 
104
    /* if len < size we need at most N * len bytes, ie < 2 * size;
 
105
       if len > size we need at most 2 * len */
 
106
    krb5_error_code ret = 0;
 
107
    size_t maxlen = 2 * max(size, len);
 
108
    size_t l = 0;
 
109
    unsigned char *tmp = malloc(maxlen);
 
110
    unsigned char *buf = malloc(len);
 
111
 
 
112
    if (tmp == NULL || buf == NULL)
 
113
        return ENOMEM;
 
114
 
 
115
    memcpy(buf, str, len);
 
116
    memset(key, 0, size);
 
117
    do {
 
118
        memcpy(tmp + l, buf, len);
 
119
        l += len;
 
120
        ret = rr13(buf, len * 8);
 
121
        if (ret)
 
122
            goto out;
 
123
        while(l >= size) {
 
124
            add1(key, tmp, size);
 
125
            l -= size;
 
126
            if(l == 0)
 
127
                break;
 
128
            memmove(tmp, tmp + size, l);
 
129
        }
 
130
    } while(l != 0);
 
131
out:
 
132
    memset(buf, 0, len);
 
133
    free(buf);
 
134
    memset(tmp, 0, maxlen);
 
135
    free(tmp);
 
136
    return ret;
 
137
}