1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 #pragma ident	"%Z%%M%	%I%	%E% SMI"
6 
7 /*
8  * Copyright 1995 by Richard P. Basch.  All Rights Reserved.
9  * Copyright 1995 by Lehman Brothers, Inc.  All Rights Reserved.
10  *
11  * Export of this software from the United States of America may
12  *   require a specific license from the United States Government.
13  *   It is the responsibility of any person or organization contemplating
14  *   export to obtain such a license before exporting.
15  *
16  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
17  * distribute this software and its documentation for any purpose and
18  * without fee is hereby granted, provided that the above copyright
19  * notice appear in all copies and that both that copyright notice and
20  * this permission notice appear in supporting documentation, and that
21  * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
22  * in advertising or publicity pertaining to distribution of the software
23  * without specific, written prior permission.  Richard P. Basch,
24  * Lehman Brothers and M.I.T. make no representations about the suitability
25  * of this software for any purpose.  It is provided "as is" without
26  * express or implied warranty.
27  */
28 
29 #include <des_int.h>
30 
31 /*
32  * Triple-DES CBC encryption mode.
33  */
34 #ifndef _KERNEL
35 int
36 mit_des3_cbc_encrypt(context, in, out, length, key, ivec, encrypt)
37 	krb5_context context;
38 	const mit_des_cblock *in;
39 	mit_des_cblock *out;
40 	long length;
41 	krb5_keyblock *key;
42 	mit_des_cblock ivec;
43 	int encrypt;
44 {
45     int ret = KRB5_PROG_ETYPE_NOSUPP;
46 /* EXPORT DELETE START */
47     KRB5_MECH_TO_PKCS algos;
48     CK_MECHANISM mechanism;
49     CK_RV rv;
50     /* For the Key Object */
51     ret = 0;
52 
53     if ((rv = get_algo(key->enctype, &algos)) != CKR_OK) {
54         KRB5_LOG0(KRB5_ERR, "failure to get algo id in function "
55             "mit_des3_cbc_encrypt.");
56         ret = PKCS_ERR;
57         goto cleanup;
58     }
59 
60     rv = init_key_uef(krb_ctx_hSession(context), key);
61     if (rv != CKR_OK) {
62         KRB5_LOG(KRB5_ERR, "init_key_uef failed in "
63             "mit_des3_cbc_encrypt: rv = 0x%0x", rv);
64         ret = PKCS_ERR;
65         goto cleanup;
66     }
67 
68     mechanism.mechanism = algos.enc_algo;
69     mechanism.pParameter = ivec;
70     if (ivec != NULL)
71     	mechanism.ulParameterLen = sizeof(mit_des_cblock);
72     else
73 	mechanism.ulParameterLen = 0;
74 
75     if (encrypt)
76         rv = C_EncryptInit(krb_ctx_hSession(context), &mechanism, key->hKey);
77     else
78         rv = C_DecryptInit(krb_ctx_hSession(context), &mechanism, key->hKey);
79 
80     if (rv != CKR_OK) {
81         KRB5_LOG(KRB5_ERR, "C_EncryptInit/C_DecryptInit failed in "
82 		"mit_des3_cbc_encrypt: rv = 0x%x", rv);
83         ret = PKCS_ERR;
84         goto cleanup;
85     }
86 
87     if (encrypt)
88         rv = C_Encrypt(krb_ctx_hSession(context), (CK_BYTE_PTR)in,
89             (CK_ULONG)length, (CK_BYTE_PTR)out,
90             (CK_ULONG_PTR)&length);
91     else
92         rv = C_Decrypt(krb_ctx_hSession(context), (CK_BYTE_PTR)in,
93             (CK_ULONG)length, (CK_BYTE_PTR)out,
94             (CK_ULONG_PTR)&length);
95 
96     if (rv != CKR_OK) {
97             KRB5_LOG(KRB5_ERR,
98                 "C_Encrypt/C_Decrypt failed in mit_des3_cbc_encrypt: "
99                 "rv = 0x%x", rv);
100             ret = PKCS_ERR;
101     }
102 cleanup:
103 
104 final_cleanup:
105     if (ret)
106         (void) memset(out, 0, length);
107 
108 /* EXPORT DELETE END */
109     KRB5_LOG(KRB5_INFO, "mit_des3_cbc_encrypt() end ret=%d\n", ret);
110     return(ret);
111 }
112 
113 #else
114 #include <sys/crypto/api.h>
115 
116 /* ARGSUSED */
117 int
118 mit_des3_cbc_encrypt(krb5_context context,
119 	const mit_des_cblock *in,
120 	mit_des_cblock *out,
121         long length, krb5_keyblock *key,
122         mit_des_cblock ivec, int encrypt)
123 {
124 	int ret = KRB5_PROG_ETYPE_NOSUPP;
125 /* EXPORT DELETE START */
126 	krb5_data ivdata;
127 
128         KRB5_LOG(KRB5_INFO, "mit_des3_cbc_encrypt() start encrypt=%d", encrypt);
129 
130 	ivdata.data = (char *)ivec;
131 	ivdata.length = sizeof(mit_des_cblock);
132 
133         ret = k5_ef_crypto((const char *)in, (char *)out,
134 			length, key, &ivdata, encrypt);
135 
136 /* EXPORT DELETE END */
137         KRB5_LOG(KRB5_INFO, "mit_des3_cbc_encrypt() end retval=%d", ret);
138         return(ret);
139 }
140 #endif /* !_KERNEL */
141