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