xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cbc.c (revision 505d05c73a6e56769f263d4803b22eddd168ee24)
1 /*
2  * Copyright 2005 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 /* SUNW14resync - sparcv9 cc complained about lack of object init */
27 /* = all zero */
28 const mit_des_cblock mit_des_zeroblock = {0, 0, 0, 0, 0, 0, 0, 0};
29 
30 #undef mit_des_cbc_encrypt
31 
32 #ifndef _KERNEL
33 int
34 mit_des_cbc_encrypt(context, in, out, length, key, ivec, encrypt)
35 	krb5_context context;
36 	const mit_des_cblock  *in;
37 	mit_des_cblock  *out;
38 	long length;
39 	krb5_keyblock *key;
40 	mit_des_cblock ivec;
41 	int encrypt;
42 {
43     krb5_error_code ret = KRB5_PROG_ETYPE_NOSUPP;
44 /* EXPORT DELETE START */
45     KRB5_MECH_TO_PKCS algos;
46     CK_MECHANISM mechanism;
47     CK_RV rv;
48     /* For the Key Object */
49 
50     ret = 0;
51     if ((rv = get_algo(key->enctype, &algos)) != CKR_OK) {
52         KRB5_LOG0(KRB5_ERR, "failure to get algo id in function "
53             "mit_des_cbc_encrypt.");
54         ret = PKCS_ERR;
55         goto cleanup;
56     }
57 
58     rv = init_key_uef(krb_ctx_hSession(context), key);
59     if (rv != CKR_OK) {
60         KRB5_LOG(KRB5_ERR, "init_key_uef failed in "
61 		"mit_des_cbc_encrypt: rv = 0x%x", rv);
62         ret = PKCS_ERR;
63         goto cleanup;
64     }
65 
66     mechanism.mechanism = algos.enc_algo;
67     mechanism.pParameter = ivec;
68     if (ivec != NULL)
69     	mechanism.ulParameterLen = MIT_DES_BLOCK_LENGTH;
70     else
71 	mechanism.ulParameterLen = 0;
72 
73     if (encrypt)
74         rv = C_EncryptInit(krb_ctx_hSession(context), &mechanism, key->hKey);
75     else
76         rv = C_DecryptInit(krb_ctx_hSession(context), &mechanism, key->hKey);
77 
78     if (rv != CKR_OK) {
79         KRB5_LOG(KRB5_ERR, "C_EncryptInit/C_DecryptInit failed in "
80 		"mit_des_cbc_encrypt: rv = 0x%x", rv);
81         ret = PKCS_ERR;
82         goto cleanup;
83     }
84 
85     if (encrypt)
86 	rv = C_Encrypt(krb_ctx_hSession(context), (CK_BYTE_PTR)in,
87 	    (CK_ULONG)length, (CK_BYTE_PTR)out,
88 	    (CK_ULONG_PTR)&length);
89     else
90 	rv = C_Decrypt(krb_ctx_hSession(context), (CK_BYTE_PTR)in,
91 	    (CK_ULONG)length, (CK_BYTE_PTR)out,
92 	    (CK_ULONG_PTR)&length);
93 
94     if (rv != CKR_OK) {
95             KRB5_LOG(KRB5_ERR,
96 		"C_Encrypt/C_Decrypt failed in mit_des_cbc_encrypt: "
97                 "rv = 0x%x", rv);
98             ret = PKCS_ERR;
99     }
100 cleanup:
101 
102 final_cleanup:
103     if (ret)
104         (void) memset(out, 0, length);
105 
106 /* EXPORT DELETE END */
107     KRB5_LOG(KRB5_INFO, "mit_des_cbc_encrypt() end retval=%d", ret);
108 
109     return(ret);
110 }
111 #else
112 
113 /*
114  * This routine performs DES cipher-block-chaining operation, either
115  * encrypting from cleartext to ciphertext, if encrypt != 0 or
116  * decrypting from ciphertext to cleartext, if encrypt == 0.
117  *
118  * The key schedule is passed as an arg, as well as the cleartext or
119  * ciphertext.  The cleartext and ciphertext should be in host order.
120  *
121  * NOTE-- the output is ALWAYS an multiple of 8 bytes long.  If not
122  * enough space was provided, your program will get trashed.
123  *
124  * For encryption, the cleartext string is null padded, at the end, to
125  * an integral multiple of eight bytes.
126  *
127  * For decryption, the ciphertext will be used in integral multiples
128  * of 8 bytes, but only the first "length" bytes returned into the
129  * cleartext.
130  */
131 
132 /* ARGSUSED */
133 int
134 mit_des_cbc_encrypt(krb5_context context,
135 	const mit_des_cblock *in,
136 	mit_des_cblock *out,
137 	long length, krb5_keyblock *key,
138 	mit_des_cblock ivec, int encrypt)
139 {
140 	int ret = KRB5_PROG_ETYPE_NOSUPP;
141 /* EXPORT DELETE START */
142 	krb5_data ivdata;
143 	ret = 0;
144 
145 	KRB5_LOG(KRB5_INFO, "mit_des_cbc_encrypt() start encrypt=%d", encrypt);
146 
147 	ivdata.data = (char *)ivec;
148 	ivdata.length = sizeof(mit_des_cblock);
149 
150 	ret = k5_ef_crypto((const char *)in,
151 			(char *)out, length, key, &ivdata, encrypt);
152 
153 /* EXPORT DELETE END */
154 	KRB5_LOG(KRB5_INFO, "mit_des_cbc_encrypt() end retval=%d", ret);
155 	return(ret);
156 }
157 #endif /* !_KERNEL */
158