2 * Copyright (c) 1997 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Kungliga Tekniska
20 * Högskolan and its contributors.
22 * 4. Neither the name of the Institute nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 #include <krb5_locl.h>
48 reverse (unsigned char *s
)
50 static const unsigned char tbl
[] = {
71 #define REVONE(str, i, j) \
72 do { tmp = str[i]; str[i] = str[j]; str[j] = tmp;} while(0)
81 q = (tbl[q & 0x0F] << 4) | (tbl[q >> 4])
96 * A = A xor B. A & B is 8 bytes.
100 xor (des_cblock
*key
, unsigned char *b
)
102 unsigned char *a
= (unsigned char*)key
;
118 init (unsigned char *a
, unsigned char *b
)
131 DES_string_to_key(const unsigned char *str
, size_t len
, des_cblock
*key
)
134 des_key_schedule sched
;
136 memset (key
, 0, sizeof(des_cblock
));
139 for (i
= 0; i
< len
; i
+= 8) {
140 unsigned char tmp
[8];
142 init (tmp
, (unsigned char*)&str
[i
]);
152 des_set_odd_parity (key
);
153 des_set_key (key
, sched
);
154 des_cbc_cksum ((des_cblock
*)str
, key
, len
, sched
, key
);
155 des_set_odd_parity (key
);
156 if (des_is_weak_key (key
))
157 xor (key
, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
173 rr13(unsigned char *buf
, size_t len
)
175 unsigned char *tmp
= malloc(len
);
177 for(i
= 0; i
< len
; i
++){
178 int x
= (buf
[i
] << 8) | buf
[(i
+ 1) % len
];
180 tmp
[(i
+ 2) % len
] = x
& 0xff;
182 memcpy(buf
, tmp
, len
);
187 add1(unsigned char *a
, unsigned char *b
, size_t len
)
191 for(i
= len
- 1; i
>= 0; i
--){
196 for(i
= len
- 1; carry
&& i
>= 0; i
--){
197 int x
= a
[i
] + carry
;
204 fold(const unsigned char *str
, size_t len
, unsigned char *out
)
207 unsigned char key
[24];
210 int lcm
= size
* len
/ gcd(size
, len
);
211 unsigned char *tmp
= malloc(lcm
);
212 unsigned char *buf
= malloc(len
);
213 memcpy(buf
, str
, len
);
214 for(; num
< lcm
; num
+= len
){
215 memcpy(tmp
+ num
, buf
, len
);
219 memset(key
, 0, sizeof(key
));
220 for(i
= 0; i
< lcm
; i
+= size
)
221 add1(key
, tmp
+ i
, size
);
223 memcpy(out
, key
, size
);
227 DES3_string_to_key(const unsigned char *str
, size_t len
, des_cblock
*keys
)
229 unsigned char tmp
[24];
231 des_key_schedule s
[3];
235 for(i
= 0; i
< 3; i
++){
236 memcpy(keys
+ i
, tmp
+ 8 * i
, 8);
237 des_set_odd_parity(keys
+ i
);
238 if(des_is_weak_key(keys
+ i
))
239 xor(keys
+ i
, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
240 des_set_key(keys
+ i
, s
[i
]);
242 memset(&ivec
, 0, sizeof(ivec
));
243 des_ede3_cbc_encrypt((void*)tmp
, (void*)tmp
, sizeof(tmp
),
244 s
[0], s
[1], s
[2], &ivec
, 1);
245 memset(s
, 0, sizeof(s
));
246 for(i
= 0; i
< 3; i
++){
247 memcpy(keys
+ i
, tmp
+ 8 * i
, 8);
248 des_set_odd_parity(keys
+ i
);
249 if(des_is_weak_key(keys
+ i
))
250 xor(keys
+ i
, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
252 memset(tmp
, 0, sizeof(tmp
));
256 static krb5_error_code
257 string_to_key_internal (const unsigned char *str
,
264 unsigned char *s
, *p
;
267 len
= str_len
+ salt
->length
;
269 len
= (len
+ 7) / 8 * 8;
271 p
= s
= malloc (len
);
275 strncpy ((char *)p
, (char *)str
, str_len
);
277 memcpy (p
, salt
->data
, salt
->length
);
282 DES_string_to_key(s
, len
, &tmpkey
);
283 ret
= krb5_data_copy(&key
->keyvalue
, tmpkey
, sizeof(des_cblock
));
284 memset(&tmpkey
, 0, sizeof(tmpkey
));
289 DES3_string_to_key(s
, len
, keys
);
290 ret
= krb5_data_copy(&key
->keyvalue
, keys
, sizeof(keys
));
291 memset(keys
, 0, sizeof(keys
));
295 ret
= KRB5_PROG_KEYTYPE_NOSUPP
;
302 key
->keytype
= ktype
;
307 krb5_string_to_key (const char *str
,
312 return string_to_key_internal ((const unsigned char *)str
,
313 strlen(str
), salt
, ktype
, key
);
317 krb5_string_to_key_data (krb5_data
*str
,
322 return string_to_key_internal (str
->data
, str
->length
, salt
, ktype
, key
);
326 krb5_get_salt (krb5_principal princ
,
334 len
= strlen(princ
->realm
);
335 for (i
= 0; i
< princ
->name
.name_string
.len
; ++i
)
336 len
+= strlen(princ
->name
.name_string
.val
[i
]);
337 err
= krb5_data_alloc (salt
, len
);
341 strncpy (p
, princ
->realm
, strlen(princ
->realm
));
342 p
+= strlen(princ
->realm
);
343 for (i
= 0; i
< princ
->name
.name_string
.len
; ++i
) {
345 princ
->name
.name_string
.val
[i
],
346 strlen(princ
->name
.name_string
.val
[i
]));
347 p
+= strlen(princ
->name
.name_string
.val
[i
]);