xref: /freebsd/crypto/krb5/src/lib/crypto/krb/enc_raw.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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