1/*
2 * Copyright (c) 1997 - 2008 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 the Institute nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34/* Functions which are used by both single and triple DES enctypes */
35
36#include "krb5_locl.h"
37
38/*
39 * A = A xor B. A & B are 8 bytes.
40 */
41
42void
43_krb5_xor (unsigned char *key, const unsigned char *b)
44{
45    unsigned char *a = (unsigned char*)key;
46    a[0] ^= b[0];
47    a[1] ^= b[1];
48    a[2] ^= b[2];
49    a[3] ^= b[3];
50    a[4] ^= b[4];
51    a[5] ^= b[5];
52    a[6] ^= b[6];
53    a[7] ^= b[7];
54}
55
56#if defined(DES3_OLD_ENCTYPE) || defined(HEIM_WEAK_CRYPTO)
57krb5_error_code
58_krb5_des_checksum(krb5_context context,
59		   CCDigestAlg alg,
60		   struct _krb5_key_data *key,
61		   const void *data,
62		   size_t len,
63		   Checksum *cksum)
64{
65    struct _krb5_evp_schedule *ctx = key->schedule->data;
66    CCDigestRef m;
67    unsigned char ivec[8];
68    unsigned char *p = cksum->checksum.data;
69
70    krb5_generate_random_block(p, 8);
71
72    m = CCDigestCreate(alg);
73    if (m == NULL) {
74	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
75	return ENOMEM;
76    }
77
78    CCDigestUpdate(m, p, 8);
79    CCDigestUpdate(m, data, len);
80    CCDigestFinal(m, p + 8);
81    CCDigestDestroy(m);
82    memset (&ivec, 0, sizeof(ivec));
83    EVP_CipherInit_ex(&ctx->ectx, NULL, NULL, NULL, (void *)ivec, -1);
84    EVP_Cipher(&ctx->ectx, p, p, 24);
85
86    return 0;
87}
88
89krb5_error_code
90_krb5_des_verify(krb5_context context,
91		 CCDigestAlg alg,
92		 struct _krb5_key_data *key,
93		 const void *data,
94		 size_t len,
95		 Checksum *C)
96{
97    struct _krb5_evp_schedule *ctx = key->schedule->data;
98    CCDigestRef m;
99    unsigned char tmp[24];
100    unsigned char res[16];
101    unsigned char ivec[8];
102    krb5_error_code ret = 0;
103
104    m = CCDigestCreate(alg);
105    if (m == NULL) {
106	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
107	return ENOMEM;
108    }
109
110    memset(ivec, 0, sizeof(ivec));
111    EVP_CipherInit_ex(&ctx->dctx, NULL, NULL, NULL, (void *)ivec, -1);
112    EVP_Cipher(&ctx->dctx, tmp, C->checksum.data, 24);
113
114    CCDigestUpdate(m, tmp, 8); /* confounder */
115    CCDigestUpdate(m, data, len);
116    CCDigestFinal(m, res);
117    CCDigestDestroy(m);
118    if(ct_memcmp(res, tmp + 8, sizeof(res)) != 0) {
119	krb5_clear_error_message (context);
120	ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
121    }
122    memset(tmp, 0, sizeof(tmp));
123    memset(res, 0, sizeof(res));
124    return ret;
125}
126
127#endif
128
129static krb5_error_code
130RSA_MD5_checksum(krb5_context context,
131		 struct _krb5_key_data *key,
132		 const void *data,
133		 size_t len,
134		 unsigned usage,
135		 Checksum *C)
136{
137    if (CCDigest(kCCDigestMD5, data, len, C->checksum.data) != 0)
138	krb5_abortx(context, "md5 checksum failed");
139    return 0;
140}
141
142struct _krb5_checksum_type _krb5_checksum_rsa_md5 = {
143    CKSUMTYPE_RSA_MD5,
144    "rsa-md5",
145    64,
146    16,
147    F_CPROOF,
148    RSA_MD5_checksum,
149    NULL
150};
151