64
65 typedef struct QOP_entry {
66 int export_level; /* Not currentlyt used */
67 verifier_t verifier; /* Verifier entry to use for integrity */
68 } QOP_entry;
69
70 /*
71 * Return the length produced by using cipher entry c given the supplied len
72 */
73 static unsigned int
74 cipher_pad(cipher_t c, unsigned int len)
75 {
76 unsigned int pad;
77
78 pad = c ? c->pad : 1;
79
80 return (((len + pad - 1)/pad)*pad);
81 }
82
83
84 /* EXPORT DELETE START */
85
86 /*
87 * Des [en/de]crypt buffer, buf of length, len for each key provided using
88 * an CBC initialization vector ivec.
89 * If the mode is encrypt we will use the following pattern if the number
90 * of keys is odd
91 * encrypt(buf, k[0]), decrypt(buf, k[1]), encrypt(buf, k[2])
92 * decrypt(buf, k[4]) ... encrypt(buf, k[keynum - 1])
93 * If we have an even number of keys and additional encryption will be
94 * done with the first key, i.e., ecrypt(buf, k[0]);
95 * In each [en/de]cription above we will used the passed in CBC initialization
96 * vector. The new initialization vector will be the vector return from the
97 * last encryption.
98 *
99 * In the decryption case we reverse the proccess. Note in this case
100 * the return ivec will be from the first decryption.
101 */
102
103 static int
104 __desN_crypt(des_block keys[], int keynum, char *buf, unsigned int len,
105 unsigned int mode, char *ivec)
131 m = (m == DES_ENCRYPT ? DES_DECRYPT : DES_ENCRYPT);
132
133 if ((mode & DES_DECRYPT) || i != keynum - 1 || i%2)
134 memcpy(ivec, svec.c, sizeof (des_block));
135 }
136
137 /*
138 * If we have an even number of keys then do an extra round of
139 * [en/de]cryption with the first key.
140 */
141 if (keynum % 2 == 0)
142 stat = cbc_crypt(keys[0].c, buf, len, mode, ivec);
143
144 /* If were decrypting ivec is set from first decryption */
145 if (mode & DES_DECRYPT)
146 memcpy(ivec, dvec.c, sizeof (des_block));
147
148 return (stat);
149 }
150
151 /* EXPORT DELETE END */
152
153
154 /*
155 * DesN crypt packaged for use as a cipher entry
156 */
157 static OM_uint32
158 __dh_desN_crypt(gss_buffer_t buf, dh_key_set_t keys, cipher_mode_t cipher_mode)
159 {
160 int stat = DESERR_BADPARAM;
161 /* EXPORT DELETE START */
162 int encrypt_flag = (cipher_mode == ENCIPHER);
163 unsigned mode = (encrypt_flag ? DES_ENCRYPT : DES_DECRYPT) | DES_HW;
164 des_block ivec;
165
166 if (keys->dh_key_set_len < 1)
167 return (DH_BADARG_FAILURE);
168
169 /*
170 * We all ways start of with ivec set to zeros. There is no
171 * good way to maintain ivecs since packets could be out of sequence
172 * duplicated or worst of all lost. Under these conditions the
173 * higher level protocol would have to some how resync the ivecs
174 * on both sides and start again. Theres no mechanism for this in
175 * GSS.
176 */
177 memset(&ivec, 0, sizeof (ivec));
178
179 /* Do the encryption/decryption */
180 stat = __desN_crypt(keys->dh_key_set_val, keys->dh_key_set_len,
181 (char *)buf->value, buf->length, mode, ivec.c);
182 /* EXPORT DELETE END */
183
184 if (DES_FAILED(stat))
185 return (DH_CIPHER_FAILURE);
186
187 return (DH_SUCCESS);
188 }
189
190 /*
191 * Package up plain des cbc crypt for use as a cipher entry.
192 */
193 static OM_uint32
194 __dh_des_crypt(gss_buffer_t buf, dh_key_set_t keys, cipher_mode_t cipher_mode)
195 {
196 int stat = DESERR_BADPARAM;
197 /* EXPORT DELETE START */
198 int encrypt_flag = (cipher_mode == ENCIPHER);
199 unsigned mode = (encrypt_flag ? DES_ENCRYPT : DES_DECRYPT) | DES_HW;
200 des_block ivec;
201
202 if (keys->dh_key_set_len < 1)
203 return (DH_BADARG_FAILURE);
204
205 /* Set the ivec to zeros and then cbc crypt the result */
206 memset(&ivec, 0, sizeof (ivec));
207 stat = cbc_crypt(keys->dh_key_set_val[0].c, (char *)buf->value,
208 buf->length, mode, ivec.c);
209 /* EXPORT DELETE END */
210
211 if (DES_FAILED(stat))
212 return (DH_CIPHER_FAILURE);
213
214 return (DH_SUCCESS);
215 }
216
217 /*
218 * MD5_verifier: This is a verifier routine suitable for use in a
219 * verifier entry. It calculates the MD5 check sum over an optional
220 * msg and a token. It signs it using the supplied cipher_proc and stores
221 * the result in signature.
222 *
223 * Note signature should already be allocated and be large enough to
224 * hold the signature after its been encrypted. If keys is null, then
225 * we will just return the unencrypted check sum.
226 */
227 static OM_uint32
228 MD5_verifier(gss_buffer_t tok, /* The buffer to sign */
229 gss_buffer_t msg, /* Optional buffer to include */
|
64
65 typedef struct QOP_entry {
66 int export_level; /* Not currentlyt used */
67 verifier_t verifier; /* Verifier entry to use for integrity */
68 } QOP_entry;
69
70 /*
71 * Return the length produced by using cipher entry c given the supplied len
72 */
73 static unsigned int
74 cipher_pad(cipher_t c, unsigned int len)
75 {
76 unsigned int pad;
77
78 pad = c ? c->pad : 1;
79
80 return (((len + pad - 1)/pad)*pad);
81 }
82
83
84 /*
85 * Des [en/de]crypt buffer, buf of length, len for each key provided using
86 * an CBC initialization vector ivec.
87 * If the mode is encrypt we will use the following pattern if the number
88 * of keys is odd
89 * encrypt(buf, k[0]), decrypt(buf, k[1]), encrypt(buf, k[2])
90 * decrypt(buf, k[4]) ... encrypt(buf, k[keynum - 1])
91 * If we have an even number of keys and additional encryption will be
92 * done with the first key, i.e., ecrypt(buf, k[0]);
93 * In each [en/de]cription above we will used the passed in CBC initialization
94 * vector. The new initialization vector will be the vector return from the
95 * last encryption.
96 *
97 * In the decryption case we reverse the proccess. Note in this case
98 * the return ivec will be from the first decryption.
99 */
100
101 static int
102 __desN_crypt(des_block keys[], int keynum, char *buf, unsigned int len,
103 unsigned int mode, char *ivec)
129 m = (m == DES_ENCRYPT ? DES_DECRYPT : DES_ENCRYPT);
130
131 if ((mode & DES_DECRYPT) || i != keynum - 1 || i%2)
132 memcpy(ivec, svec.c, sizeof (des_block));
133 }
134
135 /*
136 * If we have an even number of keys then do an extra round of
137 * [en/de]cryption with the first key.
138 */
139 if (keynum % 2 == 0)
140 stat = cbc_crypt(keys[0].c, buf, len, mode, ivec);
141
142 /* If were decrypting ivec is set from first decryption */
143 if (mode & DES_DECRYPT)
144 memcpy(ivec, dvec.c, sizeof (des_block));
145
146 return (stat);
147 }
148
149
150 /*
151 * DesN crypt packaged for use as a cipher entry
152 */
153 static OM_uint32
154 __dh_desN_crypt(gss_buffer_t buf, dh_key_set_t keys, cipher_mode_t cipher_mode)
155 {
156 int stat = DESERR_BADPARAM;
157 int encrypt_flag = (cipher_mode == ENCIPHER);
158 unsigned mode = (encrypt_flag ? DES_ENCRYPT : DES_DECRYPT) | DES_HW;
159 des_block ivec;
160
161 if (keys->dh_key_set_len < 1)
162 return (DH_BADARG_FAILURE);
163
164 /*
165 * We all ways start of with ivec set to zeros. There is no
166 * good way to maintain ivecs since packets could be out of sequence
167 * duplicated or worst of all lost. Under these conditions the
168 * higher level protocol would have to some how resync the ivecs
169 * on both sides and start again. Theres no mechanism for this in
170 * GSS.
171 */
172 memset(&ivec, 0, sizeof (ivec));
173
174 /* Do the encryption/decryption */
175 stat = __desN_crypt(keys->dh_key_set_val, keys->dh_key_set_len,
176 (char *)buf->value, buf->length, mode, ivec.c);
177
178 if (DES_FAILED(stat))
179 return (DH_CIPHER_FAILURE);
180
181 return (DH_SUCCESS);
182 }
183
184 /*
185 * Package up plain des cbc crypt for use as a cipher entry.
186 */
187 static OM_uint32
188 __dh_des_crypt(gss_buffer_t buf, dh_key_set_t keys, cipher_mode_t cipher_mode)
189 {
190 int stat = DESERR_BADPARAM;
191 int encrypt_flag = (cipher_mode == ENCIPHER);
192 unsigned mode = (encrypt_flag ? DES_ENCRYPT : DES_DECRYPT) | DES_HW;
193 des_block ivec;
194
195 if (keys->dh_key_set_len < 1)
196 return (DH_BADARG_FAILURE);
197
198 /* Set the ivec to zeros and then cbc crypt the result */
199 memset(&ivec, 0, sizeof (ivec));
200 stat = cbc_crypt(keys->dh_key_set_val[0].c, (char *)buf->value,
201 buf->length, mode, ivec.c);
202
203 if (DES_FAILED(stat))
204 return (DH_CIPHER_FAILURE);
205
206 return (DH_SUCCESS);
207 }
208
209 /*
210 * MD5_verifier: This is a verifier routine suitable for use in a
211 * verifier entry. It calculates the MD5 check sum over an optional
212 * msg and a token. It signs it using the supplied cipher_proc and stores
213 * the result in signature.
214 *
215 * Note signature should already be allocated and be large enough to
216 * hold the signature after its been encrypted. If keys is null, then
217 * we will just return the unencrypted check sum.
218 */
219 static OM_uint32
220 MD5_verifier(gss_buffer_t tok, /* The buffer to sign */
221 gss_buffer_t msg, /* Optional buffer to include */
|