1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/kdb/decrypt_key.c */
3 /*
4 * Copyright 1990,1991,2023 by the Massachusetts Institute of Technology.
5 * All Rights Reserved.
6 *
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
11 *
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
25 */
26 /*
27 * Copyright (C) 1998 by the FundsXpress, INC.
28 *
29 * All rights reserved.
30 *
31 * Export of this software from the United States of America may require
32 * a specific license from the United States Government. It is the
33 * responsibility of any person or organization contemplating export to
34 * obtain such a license before exporting.
35 *
36 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
37 * distribute this software and its documentation for any purpose and
38 * without fee is hereby granted, provided that the above copyright
39 * notice appear in all copies and that both that copyright notice and
40 * this permission notice appear in supporting documentation, and that
41 * the name of FundsXpress. not be used in advertising or publicity pertaining
42 * to distribution of the software without specific, written prior
43 * permission. FundsXpress makes no representations about the suitability of
44 * this software for any purpose. It is provided "as is" without express
45 * or implied warranty.
46 *
47 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
48 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
49 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
50 */
51
52 #include "k5-int.h"
53 #include "kdb.h"
54
55 /* Decrypt key_data, putting the result into dbkey_out and (if not null)
56 * keysalt_out. */
57 krb5_error_code
krb5_dbe_def_decrypt_key_data(krb5_context context,const krb5_keyblock * mkey,const krb5_key_data * kd,krb5_keyblock * dbkey_out,krb5_keysalt * keysalt_out)58 krb5_dbe_def_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
59 const krb5_key_data *kd,
60 krb5_keyblock *dbkey_out,
61 krb5_keysalt *keysalt_out)
62 {
63 krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
64 int16_t keylen;
65 krb5_enc_data cipher;
66 krb5_data plain = empty_data();
67 krb5_keyblock kb = { 0 };
68 krb5_keysalt salt = { 0 };
69
70 memset(dbkey_out, 0, sizeof(*dbkey_out));
71 if (keysalt_out != NULL)
72 memset(keysalt_out, 0, sizeof(*keysalt_out));
73
74 if (mkey == NULL)
75 return KRB5_KDB_BADSTORED_MKEY;
76
77 if (kd->key_data_contents[0] == NULL || kd->key_data_length[0] < 2)
78 return KRB5_KDB_INVALIDKEYSIZE;
79
80 keylen = load_16_le(kd->key_data_contents[0]);
81 if (keylen < 0)
82 return KRB5_KDB_INVALIDKEYSIZE;
83
84 cipher.enctype = ENCTYPE_UNKNOWN;
85 cipher.ciphertext = make_data(kd->key_data_contents[0] + 2,
86 kd->key_data_length[0] - 2);
87 ret = alloc_data(&plain, kd->key_data_length[0] - 2);
88 if (ret)
89 goto cleanup;
90
91 ret = krb5_c_decrypt(context, mkey, 0, 0, &cipher, &plain);
92 if (ret)
93 goto cleanup;
94
95 /* Make sure the plaintext has at least as many bytes as the true key
96 * length (it may have more due to padding). */
97 if ((unsigned int)keylen > plain.length) {
98 ret = KRB5_CRYPTO_INTERNAL;
99 if (ret)
100 goto cleanup;
101 }
102
103 kb.magic = KV5M_KEYBLOCK;
104 kb.enctype = kd->key_data_type[0];
105 kb.length = keylen;
106 kb.contents = (uint8_t *)plain.data;
107 plain = empty_data();
108
109 /* Decode salt data. */
110 if (keysalt_out != NULL) {
111 if (kd->key_data_ver == 2) {
112 salt.type = kd->key_data_type[1];
113 salt.data.length = kd->key_data_length[1];
114 if (kd->key_data_length[1] > 0) {
115 ret = alloc_data(&salt.data, kd->key_data_length[1]);
116 if (ret)
117 goto cleanup;
118 memcpy(salt.data.data, kd->key_data_contents[1],
119 salt.data.length);
120 }
121 } else {
122 salt.type = KRB5_KDB_SALTTYPE_NORMAL;
123 }
124 }
125
126 *dbkey_out = kb;
127 if (keysalt_out != NULL)
128 *keysalt_out = salt;
129 memset(&kb, 0, sizeof(kb));
130 memset(&salt, 0, sizeof(salt));
131
132 cleanup:
133 zapfree(plain.data, plain.length);
134 krb5_free_keyblock_contents(context, &kb);
135 free(salt.data.data);
136 return ret;
137 }
138