xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cbc.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 /*
9  * Copyright (c) 1990 Dennis Ferguson.  All rights reserved.
10  *
11  * Commercial use is permitted only if products which are derived from
12  * or include this software are made available for purchase and/or use
13  * in Canada.  Otherwise, redistribution and use in source and binary
14  * forms are permitted.
15  */
16 
17 /*
18  * des_cbc_encrypt.c - an implementation of the DES cipher function in cbc mode
19  */
20 #include <des_int.h>
21 
22 /*
23  * des_cbc_encrypt - {en,de}crypt a stream in CBC mode
24  */
25 
26 #ifndef _KERNEL
27 int
28 mit_des_cbc_encrypt(context, in, out, length, key, ivec, encrypt)
29 	krb5_context context;
30 	const mit_des_cblock FAR *in;
31 	mit_des_cblock FAR *out;
32 	long length;
33 	krb5_keyblock *key;
34 	mit_des_cblock ivec;
35 	int encrypt;
36 {
37     krb5_error_code ret = KRB5_PROG_ETYPE_NOSUPP;
38 /* EXPORT DELETE START */
39     KRB5_MECH_TO_PKCS algos;
40     CK_MECHANISM mechanism;
41     CK_RV rv;
42     /* For the Key Object */
43 
44     ret = 0;
45     if ((rv = get_algo(key->enctype, &algos)) != CKR_OK) {
46         KRB5_LOG0(KRB5_ERR, "failure to get algo id in function "
47             "mit_des_cbc_encrypt.");
48         ret = PKCS_ERR;
49         goto cleanup;
50     }
51 
52     rv = init_key_uef(krb_ctx_hSession(context), key);
53     if (rv != CKR_OK) {
54         KRB5_LOG(KRB5_ERR, "init_key_uef failed in "
55 		"mit_des_cbc_encrypt: rv = 0x%x", rv);
56         ret = PKCS_ERR;
57         goto cleanup;
58     }
59 
60     mechanism.mechanism = algos.enc_algo;
61     mechanism.pParameter = ivec;
62     if (ivec != NULL)
63     	mechanism.ulParameterLen = MIT_DES_BLOCK_LENGTH;
64     else
65 	mechanism.ulParameterLen = 0;
66 
67     if (encrypt)
68         rv = C_EncryptInit(krb_ctx_hSession(context), &mechanism, key->hKey);
69     else
70         rv = C_DecryptInit(krb_ctx_hSession(context), &mechanism, key->hKey);
71 
72     if (rv != CKR_OK) {
73         KRB5_LOG(KRB5_ERR, "C_EncryptInit/C_DecryptInit failed in "
74 		"mit_des_cbc_encrypt: rv = 0x%x", rv);
75         ret = PKCS_ERR;
76         goto cleanup;
77     }
78 
79     if (encrypt)
80 	rv = C_Encrypt(krb_ctx_hSession(context), (CK_BYTE_PTR)in,
81 	    (CK_ULONG)length, (CK_BYTE_PTR)out,
82 	    (CK_ULONG_PTR)&length);
83     else
84 	rv = C_Decrypt(krb_ctx_hSession(context), (CK_BYTE_PTR)in,
85 	    (CK_ULONG)length, (CK_BYTE_PTR)out,
86 	    (CK_ULONG_PTR)&length);
87 
88     if (rv != CKR_OK) {
89             KRB5_LOG(KRB5_ERR,
90 		"C_Encrypt/C_Decrypt failed in mit_des_cbc_encrypt: "
91                 "rv = 0x%x", rv);
92             ret = PKCS_ERR;
93     }
94 cleanup:
95 
96 final_cleanup:
97     if (ret)
98         (void) memset(out, 0, length);
99 
100 /* EXPORT DELETE END */
101     KRB5_LOG(KRB5_INFO, "mit_des_cbc_encrypt() end retval=%d", ret);
102 
103     return(ret);
104 }
105 #else
106 
107 /*
108  * This routine performs DES cipher-block-chaining operation, either
109  * encrypting from cleartext to ciphertext, if encrypt != 0 or
110  * decrypting from ciphertext to cleartext, if encrypt == 0.
111  *
112  * The key schedule is passed as an arg, as well as the cleartext or
113  * ciphertext.  The cleartext and ciphertext should be in host order.
114  *
115  * NOTE-- the output is ALWAYS an multiple of 8 bytes long.  If not
116  * enough space was provided, your program will get trashed.
117  *
118  * For encryption, the cleartext string is null padded, at the end, to
119  * an integral multiple of eight bytes.
120  *
121  * For decryption, the ciphertext will be used in integral multiples
122  * of 8 bytes, but only the first "length" bytes returned into the
123  * cleartext.
124  */
125 
126 /* ARGSUSED */
127 int
128 mit_des_cbc_encrypt(krb5_context context,
129 	const mit_des_cblock FAR *in,
130 	mit_des_cblock FAR *out,
131 	long length, krb5_keyblock *key,
132 	mit_des_cblock ivec, int encrypt)
133 {
134 	int ret = KRB5_PROG_ETYPE_NOSUPP;
135 /* EXPORT DELETE START */
136 	krb5_data ivdata;
137 	ret = 0;
138 
139 	KRB5_LOG(KRB5_INFO, "mit_des_cbc_encrypt() start encrypt=%d", encrypt);
140 
141 	ivdata.data = (char *)ivec;
142 	ivdata.length = sizeof(mit_des_cblock);
143 
144 	ret = k5_ef_crypto((const char *)in,
145 			(char *)out, length, key, &ivdata, encrypt);
146 
147 /* EXPORT DELETE END */
148 	KRB5_LOG(KRB5_INFO, "mit_des_cbc_encrypt() end retval=%d", ret);
149 	return(ret);
150 }
151 #endif /* !_KERNEL */
152