xref: /freebsd/crypto/krb5/src/lib/kdb/encrypt_key.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/kdb/encrypt_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 /*
56  * Encrypt dbkey for storage in the database, putting the result into
57  * key_data_out.
58  */
59 krb5_error_code
krb5_dbe_def_encrypt_key_data(krb5_context context,const krb5_keyblock * mkey,const krb5_keyblock * dbkey,const krb5_keysalt * keysalt,int keyver,krb5_key_data * key_data_out)60 krb5_dbe_def_encrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
61                               const krb5_keyblock *dbkey,
62                               const krb5_keysalt *keysalt, int keyver,
63                               krb5_key_data *key_data_out)
64 {
65     krb5_error_code ret;
66     size_t clen;
67     krb5_data plain;
68     krb5_enc_data cipher;
69     krb5_key_data kd = { 0 };
70 
71     memset(key_data_out, 0, sizeof(*key_data_out));
72 
73     kd.key_data_ver = 1;
74     kd.key_data_kvno = keyver;
75 
76     ret = krb5_c_encrypt_length(context, mkey->enctype, dbkey->length, &clen);
77     if (ret)
78         goto cleanup;
79 
80     /* The first element of the type/length/contents fields is the key
81      * type/length/contents. */
82     kd.key_data_type[0] = dbkey->enctype;
83     kd.key_data_length[0] = 2 + clen;
84     kd.key_data_contents[0] = k5alloc(kd.key_data_length[0], &ret);
85     if (kd.key_data_contents[0] == NULL)
86         goto cleanup;
87     store_16_le(dbkey->length, kd.key_data_contents[0]);
88 
89     plain = make_data(dbkey->contents, dbkey->length);
90     cipher.ciphertext = make_data(kd.key_data_contents[0] + 2, clen);
91     ret = krb5_c_encrypt(context, mkey, 0, 0, &plain, &cipher);
92     if (ret)
93         goto cleanup;
94 
95     /* The second element of each array is the salt, if necessary. */
96     if (keysalt != NULL && keysalt->type > 0) {
97         kd.key_data_ver++;
98         kd.key_data_type[1] = keysalt->type;
99         kd.key_data_length[1] = keysalt->data.length;
100         if (keysalt->data.length > 0) {
101             kd.key_data_contents[1] = k5memdup(keysalt->data.data,
102                                                keysalt->data.length, &ret);
103             if (kd.key_data_contents[1] == NULL)
104                 goto cleanup;
105         }
106     }
107 
108     *key_data_out = kd;
109     memset(&kd, 0, sizeof(kd));
110 
111 cleanup:
112     krb5_dbe_free_key_data_contents(context, &kd);
113     return ret;
114 }
115