1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/crypto/krb/enc_raw.c */
3 /*
4 * Copyright 2008 by the Massachusetts Institute of Technology.
5 * All Rights Reserved.
6 *
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
11 *
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
25 */
26
27
28 #include "crypto_int.h"
29
30 unsigned int
krb5int_raw_crypto_length(const struct krb5_keytypes * ktp,krb5_cryptotype type)31 krb5int_raw_crypto_length(const struct krb5_keytypes *ktp,
32 krb5_cryptotype type)
33 {
34 switch (type) {
35 case KRB5_CRYPTO_TYPE_PADDING:
36 return ktp->enc->block_size;
37 default:
38 return 0;
39 }
40 }
41
42 krb5_error_code
krb5int_raw_encrypt(const struct krb5_keytypes * ktp,krb5_key key,krb5_keyusage usage,const krb5_data * ivec,krb5_crypto_iov * data,size_t num_data)43 krb5int_raw_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
44 krb5_keyusage usage, const krb5_data *ivec,
45 krb5_crypto_iov *data, size_t num_data)
46 {
47 krb5_crypto_iov *padding;
48 size_t i;
49 unsigned int blocksize, plainlen = 0, padsize = 0;
50
51 blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING);
52
53 for (i = 0; i < num_data; i++) {
54 krb5_crypto_iov *iov = &data[i];
55
56 if (iov->flags == KRB5_CRYPTO_TYPE_DATA)
57 plainlen += iov->data.length;
58 }
59
60 if (blocksize != 0) {
61 /* Check that the input data is correctly padded */
62 if (plainlen % blocksize)
63 padsize = blocksize - (plainlen % blocksize);
64 }
65
66 padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
67 if (padsize && (padding == NULL || padding->data.length < padsize))
68 return KRB5_BAD_MSIZE;
69
70 if (padding != NULL) {
71 memset(padding->data.data, 0, padsize);
72 padding->data.length = padsize;
73 }
74
75 return ktp->enc->encrypt(key, ivec, data, num_data);
76 }
77
78 krb5_error_code
krb5int_raw_decrypt(const struct krb5_keytypes * ktp,krb5_key key,krb5_keyusage usage,const krb5_data * ivec,krb5_crypto_iov * data,size_t num_data)79 krb5int_raw_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
80 krb5_keyusage usage, const krb5_data *ivec,
81 krb5_crypto_iov *data, size_t num_data)
82 {
83 size_t i;
84 unsigned int blocksize = 0; /* enc block size, not confounder len */
85 unsigned int cipherlen = 0;
86
87 /* E(Confounder | Plaintext | Pad) | Checksum */
88
89 blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING);
90
91 for (i = 0; i < num_data; i++) {
92 const krb5_crypto_iov *iov = &data[i];
93
94 if (ENCRYPT_DATA_IOV(iov))
95 cipherlen += iov->data.length;
96 }
97
98 if (blocksize == 0) {
99 /* Check for correct input length in CTS mode */
100 if (ktp->enc->block_size != 0 && cipherlen < ktp->enc->block_size)
101 return KRB5_BAD_MSIZE;
102 } else {
103 /* Check that the input data is correctly padded */
104 if (cipherlen % blocksize != 0)
105 return KRB5_BAD_MSIZE;
106 }
107
108 return ktp->enc->decrypt(key, ivec, data, num_data);
109 }
110