xref: /freebsd/crypto/krb5/src/lib/crypto/krb/crypto_length.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/crypto/krb/crypto_length.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 #include "crypto_int.h"
28 
29 krb5_error_code KRB5_CALLCONV
krb5_c_crypto_length(krb5_context context,krb5_enctype enctype,krb5_cryptotype type,unsigned int * size)30 krb5_c_crypto_length(krb5_context context, krb5_enctype enctype,
31                      krb5_cryptotype type, unsigned int *size)
32 {
33     const struct krb5_keytypes *ktp;
34 
35     ktp = find_enctype(enctype);
36     if (ktp == NULL)
37         return KRB5_BAD_ENCTYPE;
38 
39     switch (type) {
40     case KRB5_CRYPTO_TYPE_EMPTY:
41     case KRB5_CRYPTO_TYPE_SIGN_ONLY:
42         *size = 0;
43         break;
44     case KRB5_CRYPTO_TYPE_DATA:
45         *size = (unsigned int)~0; /* match Heimdal */
46         break;
47     case KRB5_CRYPTO_TYPE_HEADER:
48     case KRB5_CRYPTO_TYPE_PADDING:
49     case KRB5_CRYPTO_TYPE_TRAILER:
50     case KRB5_CRYPTO_TYPE_CHECKSUM:
51         *size = ktp->crypto_length(ktp, type);
52         break;
53     default:
54         return EINVAL;
55     }
56 
57     return 0;
58 }
59 
60 krb5_error_code KRB5_CALLCONV
krb5_c_padding_length(krb5_context context,krb5_enctype enctype,size_t data_length,unsigned int * pad_length)61 krb5_c_padding_length(krb5_context context, krb5_enctype enctype,
62                       size_t data_length, unsigned int *pad_length)
63 {
64     const struct krb5_keytypes *ktp;
65 
66     ktp = find_enctype(enctype);
67     if (ktp == NULL)
68         return KRB5_BAD_ENCTYPE;
69 
70     *pad_length = krb5int_c_padding_length(ktp, data_length);
71     return 0;
72 }
73 
74 krb5_error_code KRB5_CALLCONV
krb5_c_crypto_length_iov(krb5_context context,krb5_enctype enctype,krb5_crypto_iov * data,size_t num_data)75 krb5_c_crypto_length_iov(krb5_context context, krb5_enctype enctype,
76                          krb5_crypto_iov *data, size_t num_data)
77 {
78     size_t i;
79     const struct krb5_keytypes *ktp;
80     unsigned int data_length = 0, pad_length;
81     krb5_crypto_iov *padding = NULL;
82 
83     /*
84      * XXX need to rejig internal interface so we can accurately
85      * report variable header lengths.
86      */
87 
88     ktp = find_enctype(enctype);
89     if (ktp == NULL)
90         return KRB5_BAD_ENCTYPE;
91 
92     for (i = 0; i < num_data; i++) {
93         krb5_crypto_iov *iov = &data[i];
94 
95         switch (iov->flags) {
96         case KRB5_CRYPTO_TYPE_DATA:
97             data_length += iov->data.length;
98             break;
99         case KRB5_CRYPTO_TYPE_PADDING:
100             if (padding != NULL)
101                 return EINVAL;
102 
103             padding = iov;
104             break;
105         case KRB5_CRYPTO_TYPE_HEADER:
106         case KRB5_CRYPTO_TYPE_TRAILER:
107         case KRB5_CRYPTO_TYPE_CHECKSUM:
108             iov->data.length = ktp->crypto_length(ktp, iov->flags);
109             break;
110         case KRB5_CRYPTO_TYPE_EMPTY:
111         case KRB5_CRYPTO_TYPE_SIGN_ONLY:
112         default:
113             break;
114         }
115     }
116 
117     pad_length = krb5int_c_padding_length(ktp, data_length);
118     if (pad_length != 0 && padding == NULL)
119         return EINVAL;
120 
121     if (padding != NULL)
122         padding->data.length = pad_length;
123 
124     return 0;
125 }
126