Line data Source code
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 : static void
36 50303348 : rr13(uint8_t *dst1, uint8_t *dst2, uint8_t *src, size_t len)
37 : {
38 50303348 : int bytes = (len + 7) / 8;
39 1630576 : int i;
40 50303348 : const int bits = 13 % len;
41 :
42 279730052 : for (i = 0; i < bytes; i++) {
43 7313824 : int bb;
44 7313824 : int b1, s1, b2, s2;
45 : /* calculate first bit position of this byte */
46 229426704 : bb = 8 * i - bits;
47 330033400 : while(bb < 0)
48 100606696 : bb += len;
49 : /* byte offset and shift count */
50 229426704 : b1 = bb / 8;
51 229426704 : s1 = bb % 8;
52 :
53 229426704 : if (bb + 8 > bytes * 8)
54 : /* watch for wraparound */
55 50303348 : s2 = (len + 8 - s1) % 8;
56 : else
57 179123356 : s2 = 8 - s1;
58 229426704 : b2 = (b1 + 1) % bytes;
59 229426704 : dst1[i] = (src[b1] << s1) | (src[b2] >> s2);
60 229426704 : dst2[i] = dst1[i];
61 : }
62 :
63 50303348 : return;
64 : }
65 :
66 : /*
67 : * Add `b' to `a', both being one's complement numbers.
68 : * This function assumes that inputs *a, *b are aligned
69 : * to 4 bytes.
70 : */
71 : static void
72 14339169 : add1(uint8_t *a, uint8_t *b, size_t len)
73 : {
74 457114 : int i;
75 14339169 : int carry = 0;
76 457114 : uint32_t x;
77 457114 : uint32_t left, right;
78 :
79 14339169 : for (i = len - 1; (i+1) % 4; i--) {
80 0 : x = a[i] + b[i] + carry;
81 0 : carry = x > 0xff;
82 0 : a[i] = x & 0xff;
83 : }
84 :
85 71695845 : for (i = len / 4 - 1; i >= 0; i--) {
86 57356676 : left = ntohl(((uint32_t *)a)[i]);
87 57356676 : right = ntohl(((uint32_t *)b)[i]);
88 57356676 : x = left + right + carry;
89 57356676 : carry = x < left || x < right;
90 57356676 : ((uint32_t *)a)[i] = x;
91 : }
92 :
93 14339169 : for (i = len - 1; (i+1) % 4; i--) {
94 0 : x = a[i] + carry;
95 0 : carry = x > 0xff;
96 0 : a[i] = x & 0xff;
97 : }
98 :
99 15354658 : for (i = len / 4 - 1; carry && i >= 0; i--) {
100 1015489 : left = ((uint32_t *)a)[i];
101 1015489 : x = left + carry;
102 1015489 : carry = x < left;
103 1015489 : ((uint32_t *)a)[i] = x;
104 : }
105 :
106 71695845 : for (i = len / 4 - 1; i >=0; i--)
107 57356676 : ((uint32_t *)a)[i] = htonl(((uint32_t *)a)[i]);
108 14339169 : }
109 :
110 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
111 3219701 : _krb5_n_fold(const void *str, size_t len, void *key, size_t size)
112 : {
113 : /* if len < size we need at most N * len bytes, ie < 2 * size;
114 : if len > size we need at most 2 * len */
115 3219701 : size_t maxlen = 2 * max(size, len);
116 3219701 : size_t l = 0;
117 103346 : uint8_t *tmp;
118 103346 : uint8_t *tmpbuf;
119 103346 : uint8_t *buf1;
120 103346 : uint8_t *buf2;
121 :
122 3219701 : tmp = malloc(maxlen + 2 * len);
123 3219701 : if (tmp == NULL)
124 0 : return ENOMEM;
125 :
126 3219701 : buf1 = tmp + maxlen;
127 3219701 : buf2 = tmp + maxlen + len;
128 :
129 3219701 : memset(key, 0, size);
130 3219701 : memcpy(buf1, str, len);
131 3219701 : memcpy(tmp, buf1, len);
132 1630576 : do {
133 50303348 : l += len;
134 61069048 : while(l >= size) {
135 14339169 : add1(key, tmp, size);
136 14339169 : l -= size;
137 14339169 : if(l == 0)
138 3116355 : break;
139 12750044 : memmove(tmp, tmp + size, l);
140 : }
141 50303348 : rr13(tmp + l, buf2, buf1, len * 8);
142 50303348 : tmpbuf = buf1;
143 50303348 : buf1 = buf2;
144 50303348 : buf2 = tmpbuf;
145 50303348 : } while(l != 0);
146 :
147 3219701 : memset(tmp, 0, maxlen + 2 * len);
148 3219701 : free(tmp);
149 3219701 : return 0;
150 : }
|