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