xref: /aosp_15_r20/external/libcups/cups/hash.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Hashing function for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2015-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  *
6*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
7*5e7646d2SAndroid Build Coastguard Worker  * information.
8*5e7646d2SAndroid Build Coastguard Worker  */
9*5e7646d2SAndroid Build Coastguard Worker 
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker  */
13*5e7646d2SAndroid Build Coastguard Worker 
14*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
15*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
16*5e7646d2SAndroid Build Coastguard Worker #  include <CommonCrypto/CommonDigest.h>
17*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_GNUTLS)
18*5e7646d2SAndroid Build Coastguard Worker #  include <gnutls/crypto.h>
19*5e7646d2SAndroid Build Coastguard Worker #  include "md5-internal.h"
20*5e7646d2SAndroid Build Coastguard Worker #else
21*5e7646d2SAndroid Build Coastguard Worker #  include "md5-internal.h"
22*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
23*5e7646d2SAndroid Build Coastguard Worker 
24*5e7646d2SAndroid Build Coastguard Worker 
25*5e7646d2SAndroid Build Coastguard Worker /*
26*5e7646d2SAndroid Build Coastguard Worker  * 'cupsHashData()' - Perform a hash function on the given data.
27*5e7646d2SAndroid Build Coastguard Worker  *
28*5e7646d2SAndroid Build Coastguard Worker  * The "algorithm" argument can be any of the registered, non-deprecated IPP
29*5e7646d2SAndroid Build Coastguard Worker  * hash algorithms for the "job-password-encryption" attribute, including
30*5e7646d2SAndroid Build Coastguard Worker  * "sha" for SHA-1, "sha-256" for SHA2-256, etc.
31*5e7646d2SAndroid Build Coastguard Worker  *
32*5e7646d2SAndroid Build Coastguard Worker  * The "hash" argument points to a buffer of "hashsize" bytes and should be at
33*5e7646d2SAndroid Build Coastguard Worker  * least 64 bytes in length for all of the supported algorithms.
34*5e7646d2SAndroid Build Coastguard Worker  *
35*5e7646d2SAndroid Build Coastguard Worker  * The returned hash is binary data.
36*5e7646d2SAndroid Build Coastguard Worker  *
37*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 2.2/macOS 10.12@
38*5e7646d2SAndroid Build Coastguard Worker  */
39*5e7646d2SAndroid Build Coastguard Worker 
40*5e7646d2SAndroid Build Coastguard Worker ssize_t					/* O - Size of hash or -1 on error */
cupsHashData(const char * algorithm,const void * data,size_t datalen,unsigned char * hash,size_t hashsize)41*5e7646d2SAndroid Build Coastguard Worker cupsHashData(const char    *algorithm,	/* I - Algorithm name */
42*5e7646d2SAndroid Build Coastguard Worker              const void    *data,	/* I - Data to hash */
43*5e7646d2SAndroid Build Coastguard Worker              size_t        datalen,	/* I - Length of data to hash */
44*5e7646d2SAndroid Build Coastguard Worker              unsigned char *hash,	/* I - Hash buffer */
45*5e7646d2SAndroid Build Coastguard Worker              size_t        hashsize)	/* I - Size of hash buffer */
46*5e7646d2SAndroid Build Coastguard Worker {
47*5e7646d2SAndroid Build Coastguard Worker   if (!algorithm || !data || datalen == 0 || !hash || hashsize == 0)
48*5e7646d2SAndroid Build Coastguard Worker   {
49*5e7646d2SAndroid Build Coastguard Worker     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad arguments to function"), 1);
50*5e7646d2SAndroid Build Coastguard Worker     return (-1);
51*5e7646d2SAndroid Build Coastguard Worker   }
52*5e7646d2SAndroid Build Coastguard Worker 
53*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
54*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(algorithm, "md5"))
55*5e7646d2SAndroid Build Coastguard Worker   {
56*5e7646d2SAndroid Build Coastguard Worker    /*
57*5e7646d2SAndroid Build Coastguard Worker     * MD5 (deprecated but widely used...)
58*5e7646d2SAndroid Build Coastguard Worker     */
59*5e7646d2SAndroid Build Coastguard Worker 
60*5e7646d2SAndroid Build Coastguard Worker     CC_MD5_CTX	ctx;			/* MD5 context */
61*5e7646d2SAndroid Build Coastguard Worker 
62*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < CC_MD5_DIGEST_LENGTH)
63*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
64*5e7646d2SAndroid Build Coastguard Worker 
65*5e7646d2SAndroid Build Coastguard Worker     CC_MD5_Init(&ctx);
66*5e7646d2SAndroid Build Coastguard Worker     CC_MD5_Update(&ctx, data, (CC_LONG)datalen);
67*5e7646d2SAndroid Build Coastguard Worker     CC_MD5_Final(hash, &ctx);
68*5e7646d2SAndroid Build Coastguard Worker 
69*5e7646d2SAndroid Build Coastguard Worker     return (CC_MD5_DIGEST_LENGTH);
70*5e7646d2SAndroid Build Coastguard Worker   }
71*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha"))
72*5e7646d2SAndroid Build Coastguard Worker   {
73*5e7646d2SAndroid Build Coastguard Worker    /*
74*5e7646d2SAndroid Build Coastguard Worker     * SHA-1...
75*5e7646d2SAndroid Build Coastguard Worker     */
76*5e7646d2SAndroid Build Coastguard Worker 
77*5e7646d2SAndroid Build Coastguard Worker     CC_SHA1_CTX	ctx;			/* SHA-1 context */
78*5e7646d2SAndroid Build Coastguard Worker 
79*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < CC_SHA1_DIGEST_LENGTH)
80*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
81*5e7646d2SAndroid Build Coastguard Worker 
82*5e7646d2SAndroid Build Coastguard Worker     CC_SHA1_Init(&ctx);
83*5e7646d2SAndroid Build Coastguard Worker     CC_SHA1_Update(&ctx, data, (CC_LONG)datalen);
84*5e7646d2SAndroid Build Coastguard Worker     CC_SHA1_Final(hash, &ctx);
85*5e7646d2SAndroid Build Coastguard Worker 
86*5e7646d2SAndroid Build Coastguard Worker     return (CC_SHA1_DIGEST_LENGTH);
87*5e7646d2SAndroid Build Coastguard Worker   }
88*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-224"))
89*5e7646d2SAndroid Build Coastguard Worker   {
90*5e7646d2SAndroid Build Coastguard Worker     CC_SHA256_CTX	ctx;		/* SHA-224 context */
91*5e7646d2SAndroid Build Coastguard Worker 
92*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < CC_SHA224_DIGEST_LENGTH)
93*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
94*5e7646d2SAndroid Build Coastguard Worker 
95*5e7646d2SAndroid Build Coastguard Worker     CC_SHA224_Init(&ctx);
96*5e7646d2SAndroid Build Coastguard Worker     CC_SHA224_Update(&ctx, data, (CC_LONG)datalen);
97*5e7646d2SAndroid Build Coastguard Worker     CC_SHA224_Final(hash, &ctx);
98*5e7646d2SAndroid Build Coastguard Worker 
99*5e7646d2SAndroid Build Coastguard Worker     return (CC_SHA224_DIGEST_LENGTH);
100*5e7646d2SAndroid Build Coastguard Worker   }
101*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-256"))
102*5e7646d2SAndroid Build Coastguard Worker   {
103*5e7646d2SAndroid Build Coastguard Worker     CC_SHA256_CTX	ctx;		/* SHA-256 context */
104*5e7646d2SAndroid Build Coastguard Worker 
105*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < CC_SHA256_DIGEST_LENGTH)
106*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
107*5e7646d2SAndroid Build Coastguard Worker 
108*5e7646d2SAndroid Build Coastguard Worker     CC_SHA256_Init(&ctx);
109*5e7646d2SAndroid Build Coastguard Worker     CC_SHA256_Update(&ctx, data, (CC_LONG)datalen);
110*5e7646d2SAndroid Build Coastguard Worker     CC_SHA256_Final(hash, &ctx);
111*5e7646d2SAndroid Build Coastguard Worker 
112*5e7646d2SAndroid Build Coastguard Worker     return (CC_SHA256_DIGEST_LENGTH);
113*5e7646d2SAndroid Build Coastguard Worker   }
114*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-384"))
115*5e7646d2SAndroid Build Coastguard Worker   {
116*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_CTX	ctx;		/* SHA-384 context */
117*5e7646d2SAndroid Build Coastguard Worker 
118*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < CC_SHA384_DIGEST_LENGTH)
119*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
120*5e7646d2SAndroid Build Coastguard Worker 
121*5e7646d2SAndroid Build Coastguard Worker     CC_SHA384_Init(&ctx);
122*5e7646d2SAndroid Build Coastguard Worker     CC_SHA384_Update(&ctx, data, (CC_LONG)datalen);
123*5e7646d2SAndroid Build Coastguard Worker     CC_SHA384_Final(hash, &ctx);
124*5e7646d2SAndroid Build Coastguard Worker 
125*5e7646d2SAndroid Build Coastguard Worker     return (CC_SHA384_DIGEST_LENGTH);
126*5e7646d2SAndroid Build Coastguard Worker   }
127*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-512"))
128*5e7646d2SAndroid Build Coastguard Worker   {
129*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_CTX	ctx;		/* SHA-512 context */
130*5e7646d2SAndroid Build Coastguard Worker 
131*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < CC_SHA512_DIGEST_LENGTH)
132*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
133*5e7646d2SAndroid Build Coastguard Worker 
134*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_Init(&ctx);
135*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_Update(&ctx, data, (CC_LONG)datalen);
136*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_Final(hash, &ctx);
137*5e7646d2SAndroid Build Coastguard Worker 
138*5e7646d2SAndroid Build Coastguard Worker     return (CC_SHA512_DIGEST_LENGTH);
139*5e7646d2SAndroid Build Coastguard Worker   }
140*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-512_224"))
141*5e7646d2SAndroid Build Coastguard Worker   {
142*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_CTX	ctx;		/* SHA-512 context */
143*5e7646d2SAndroid Build Coastguard Worker     unsigned char	temp[CC_SHA512_DIGEST_LENGTH];
144*5e7646d2SAndroid Build Coastguard Worker                                         /* SHA-512 hash */
145*5e7646d2SAndroid Build Coastguard Worker 
146*5e7646d2SAndroid Build Coastguard Worker    /*
147*5e7646d2SAndroid Build Coastguard Worker     * SHA2-512 truncated to 224 bits (28 bytes)...
148*5e7646d2SAndroid Build Coastguard Worker     */
149*5e7646d2SAndroid Build Coastguard Worker 
150*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < CC_SHA224_DIGEST_LENGTH)
151*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
152*5e7646d2SAndroid Build Coastguard Worker 
153*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_Init(&ctx);
154*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_Update(&ctx, data, (CC_LONG)datalen);
155*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_Final(temp, &ctx);
156*5e7646d2SAndroid Build Coastguard Worker 
157*5e7646d2SAndroid Build Coastguard Worker     memcpy(hash, temp, CC_SHA224_DIGEST_LENGTH);
158*5e7646d2SAndroid Build Coastguard Worker 
159*5e7646d2SAndroid Build Coastguard Worker     return (CC_SHA224_DIGEST_LENGTH);
160*5e7646d2SAndroid Build Coastguard Worker   }
161*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-512_256"))
162*5e7646d2SAndroid Build Coastguard Worker   {
163*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_CTX	ctx;		/* SHA-512 context */
164*5e7646d2SAndroid Build Coastguard Worker     unsigned char	temp[CC_SHA512_DIGEST_LENGTH];
165*5e7646d2SAndroid Build Coastguard Worker                                         /* SHA-512 hash */
166*5e7646d2SAndroid Build Coastguard Worker 
167*5e7646d2SAndroid Build Coastguard Worker    /*
168*5e7646d2SAndroid Build Coastguard Worker     * SHA2-512 truncated to 256 bits (32 bytes)...
169*5e7646d2SAndroid Build Coastguard Worker     */
170*5e7646d2SAndroid Build Coastguard Worker 
171*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < CC_SHA256_DIGEST_LENGTH)
172*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
173*5e7646d2SAndroid Build Coastguard Worker 
174*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_Init(&ctx);
175*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_Update(&ctx, data, (CC_LONG)datalen);
176*5e7646d2SAndroid Build Coastguard Worker     CC_SHA512_Final(temp, &ctx);
177*5e7646d2SAndroid Build Coastguard Worker 
178*5e7646d2SAndroid Build Coastguard Worker     memcpy(hash, temp, CC_SHA256_DIGEST_LENGTH);
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker     return (CC_SHA256_DIGEST_LENGTH);
181*5e7646d2SAndroid Build Coastguard Worker   }
182*5e7646d2SAndroid Build Coastguard Worker 
183*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_GNUTLS)
184*5e7646d2SAndroid Build Coastguard Worker   gnutls_digest_algorithm_t alg = GNUTLS_DIG_UNKNOWN;
185*5e7646d2SAndroid Build Coastguard Worker 					/* Algorithm */
186*5e7646d2SAndroid Build Coastguard Worker   unsigned char	temp[64];		/* Temporary hash buffer */
187*5e7646d2SAndroid Build Coastguard Worker   size_t	tempsize = 0;		/* Truncate to this size? */
188*5e7646d2SAndroid Build Coastguard Worker 
189*5e7646d2SAndroid Build Coastguard Worker 
190*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(algorithm, "md5"))
191*5e7646d2SAndroid Build Coastguard Worker   {
192*5e7646d2SAndroid Build Coastguard Worker    /*
193*5e7646d2SAndroid Build Coastguard Worker     * Some versions of GNU TLS disable MD5 without warning...
194*5e7646d2SAndroid Build Coastguard Worker     */
195*5e7646d2SAndroid Build Coastguard Worker 
196*5e7646d2SAndroid Build Coastguard Worker     _cups_md5_state_t	state;		/* MD5 state info */
197*5e7646d2SAndroid Build Coastguard Worker 
198*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < 16)
199*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
200*5e7646d2SAndroid Build Coastguard Worker 
201*5e7646d2SAndroid Build Coastguard Worker     _cupsMD5Init(&state);
202*5e7646d2SAndroid Build Coastguard Worker     _cupsMD5Append(&state, data, (int)datalen);
203*5e7646d2SAndroid Build Coastguard Worker     _cupsMD5Finish(&state, hash);
204*5e7646d2SAndroid Build Coastguard Worker 
205*5e7646d2SAndroid Build Coastguard Worker     return (16);
206*5e7646d2SAndroid Build Coastguard Worker   }
207*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha"))
208*5e7646d2SAndroid Build Coastguard Worker     alg = GNUTLS_DIG_SHA1;
209*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-224"))
210*5e7646d2SAndroid Build Coastguard Worker     alg = GNUTLS_DIG_SHA224;
211*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-256"))
212*5e7646d2SAndroid Build Coastguard Worker     alg = GNUTLS_DIG_SHA256;
213*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-384"))
214*5e7646d2SAndroid Build Coastguard Worker     alg = GNUTLS_DIG_SHA384;
215*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-512"))
216*5e7646d2SAndroid Build Coastguard Worker     alg = GNUTLS_DIG_SHA512;
217*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-512_224"))
218*5e7646d2SAndroid Build Coastguard Worker   {
219*5e7646d2SAndroid Build Coastguard Worker     alg      = GNUTLS_DIG_SHA512;
220*5e7646d2SAndroid Build Coastguard Worker     tempsize = 28;
221*5e7646d2SAndroid Build Coastguard Worker   }
222*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(algorithm, "sha2-512_256"))
223*5e7646d2SAndroid Build Coastguard Worker   {
224*5e7646d2SAndroid Build Coastguard Worker     alg      = GNUTLS_DIG_SHA512;
225*5e7646d2SAndroid Build Coastguard Worker     tempsize = 32;
226*5e7646d2SAndroid Build Coastguard Worker   }
227*5e7646d2SAndroid Build Coastguard Worker 
228*5e7646d2SAndroid Build Coastguard Worker   if (alg != GNUTLS_DIG_UNKNOWN)
229*5e7646d2SAndroid Build Coastguard Worker   {
230*5e7646d2SAndroid Build Coastguard Worker     if (tempsize > 0)
231*5e7646d2SAndroid Build Coastguard Worker     {
232*5e7646d2SAndroid Build Coastguard Worker      /*
233*5e7646d2SAndroid Build Coastguard Worker       * Truncate result to tempsize bytes...
234*5e7646d2SAndroid Build Coastguard Worker       */
235*5e7646d2SAndroid Build Coastguard Worker 
236*5e7646d2SAndroid Build Coastguard Worker       if (hashsize < tempsize)
237*5e7646d2SAndroid Build Coastguard Worker         goto too_small;
238*5e7646d2SAndroid Build Coastguard Worker 
239*5e7646d2SAndroid Build Coastguard Worker       gnutls_hash_fast(alg, data, datalen, temp);
240*5e7646d2SAndroid Build Coastguard Worker       memcpy(hash, temp, tempsize);
241*5e7646d2SAndroid Build Coastguard Worker 
242*5e7646d2SAndroid Build Coastguard Worker       return ((ssize_t)tempsize);
243*5e7646d2SAndroid Build Coastguard Worker     }
244*5e7646d2SAndroid Build Coastguard Worker 
245*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < gnutls_hash_get_len(alg))
246*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
247*5e7646d2SAndroid Build Coastguard Worker 
248*5e7646d2SAndroid Build Coastguard Worker     gnutls_hash_fast(alg, data, datalen, hash);
249*5e7646d2SAndroid Build Coastguard Worker 
250*5e7646d2SAndroid Build Coastguard Worker     return ((ssize_t)gnutls_hash_get_len(alg));
251*5e7646d2SAndroid Build Coastguard Worker   }
252*5e7646d2SAndroid Build Coastguard Worker 
253*5e7646d2SAndroid Build Coastguard Worker #else
254*5e7646d2SAndroid Build Coastguard Worker  /*
255*5e7646d2SAndroid Build Coastguard Worker   * No hash support beyond MD5 without CommonCrypto or GNU TLS...
256*5e7646d2SAndroid Build Coastguard Worker   */
257*5e7646d2SAndroid Build Coastguard Worker 
258*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(algorithm, "md5"))
259*5e7646d2SAndroid Build Coastguard Worker   {
260*5e7646d2SAndroid Build Coastguard Worker     _cups_md5_state_t	state;		/* MD5 state info */
261*5e7646d2SAndroid Build Coastguard Worker 
262*5e7646d2SAndroid Build Coastguard Worker     if (hashsize < 16)
263*5e7646d2SAndroid Build Coastguard Worker       goto too_small;
264*5e7646d2SAndroid Build Coastguard Worker 
265*5e7646d2SAndroid Build Coastguard Worker     _cupsMD5Init(&state);
266*5e7646d2SAndroid Build Coastguard Worker     _cupsMD5Append(&state, data, datalen);
267*5e7646d2SAndroid Build Coastguard Worker     _cupsMD5Finish(&state, hash);
268*5e7646d2SAndroid Build Coastguard Worker 
269*5e7646d2SAndroid Build Coastguard Worker     return (16);
270*5e7646d2SAndroid Build Coastguard Worker   }
271*5e7646d2SAndroid Build Coastguard Worker   else if (hashsize < 64)
272*5e7646d2SAndroid Build Coastguard Worker     goto too_small;
273*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
274*5e7646d2SAndroid Build Coastguard Worker 
275*5e7646d2SAndroid Build Coastguard Worker  /*
276*5e7646d2SAndroid Build Coastguard Worker   * Unknown hash algorithm...
277*5e7646d2SAndroid Build Coastguard Worker   */
278*5e7646d2SAndroid Build Coastguard Worker 
279*5e7646d2SAndroid Build Coastguard Worker   _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown hash algorithm."), 1);
280*5e7646d2SAndroid Build Coastguard Worker 
281*5e7646d2SAndroid Build Coastguard Worker   return (-1);
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker  /*
284*5e7646d2SAndroid Build Coastguard Worker   * We get here if the buffer is too small.
285*5e7646d2SAndroid Build Coastguard Worker   */
286*5e7646d2SAndroid Build Coastguard Worker 
287*5e7646d2SAndroid Build Coastguard Worker   too_small:
288*5e7646d2SAndroid Build Coastguard Worker 
289*5e7646d2SAndroid Build Coastguard Worker   _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Hash buffer too small."), 1);
290*5e7646d2SAndroid Build Coastguard Worker   return (-1);
291*5e7646d2SAndroid Build Coastguard Worker }
292*5e7646d2SAndroid Build Coastguard Worker 
293*5e7646d2SAndroid Build Coastguard Worker 
294*5e7646d2SAndroid Build Coastguard Worker /*
295*5e7646d2SAndroid Build Coastguard Worker  * 'cupsHashString()' - Format a hash value as a hexadecimal string.
296*5e7646d2SAndroid Build Coastguard Worker  *
297*5e7646d2SAndroid Build Coastguard Worker  * The passed buffer must be at least 2 * hashsize + 1 characters in length.
298*5e7646d2SAndroid Build Coastguard Worker  *
299*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 2.2.7@
300*5e7646d2SAndroid Build Coastguard Worker  */
301*5e7646d2SAndroid Build Coastguard Worker 
302*5e7646d2SAndroid Build Coastguard Worker const char *				/* O - Formatted string */
cupsHashString(const unsigned char * hash,size_t hashsize,char * buffer,size_t bufsize)303*5e7646d2SAndroid Build Coastguard Worker cupsHashString(
304*5e7646d2SAndroid Build Coastguard Worker     const unsigned char *hash,		/* I - Hash */
305*5e7646d2SAndroid Build Coastguard Worker     size_t              hashsize,	/* I - Size of hash */
306*5e7646d2SAndroid Build Coastguard Worker     char                *buffer,	/* I - String buffer */
307*5e7646d2SAndroid Build Coastguard Worker     size_t		bufsize)	/* I - Size of string buffer */
308*5e7646d2SAndroid Build Coastguard Worker {
309*5e7646d2SAndroid Build Coastguard Worker   char		*bufptr = buffer;	/* Pointer into buffer */
310*5e7646d2SAndroid Build Coastguard Worker   static const char *hex = "0123456789abcdef";
311*5e7646d2SAndroid Build Coastguard Worker 					/* Hex characters (lowercase!) */
312*5e7646d2SAndroid Build Coastguard Worker 
313*5e7646d2SAndroid Build Coastguard Worker 
314*5e7646d2SAndroid Build Coastguard Worker  /*
315*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
316*5e7646d2SAndroid Build Coastguard Worker   */
317*5e7646d2SAndroid Build Coastguard Worker 
318*5e7646d2SAndroid Build Coastguard Worker   if (!hash || hashsize < 1 || !buffer || bufsize < (2 * hashsize + 1))
319*5e7646d2SAndroid Build Coastguard Worker   {
320*5e7646d2SAndroid Build Coastguard Worker     if (buffer)
321*5e7646d2SAndroid Build Coastguard Worker       *buffer = '\0';
322*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
323*5e7646d2SAndroid Build Coastguard Worker   }
324*5e7646d2SAndroid Build Coastguard Worker 
325*5e7646d2SAndroid Build Coastguard Worker  /*
326*5e7646d2SAndroid Build Coastguard Worker   * Loop until we've converted the whole hash...
327*5e7646d2SAndroid Build Coastguard Worker   */
328*5e7646d2SAndroid Build Coastguard Worker 
329*5e7646d2SAndroid Build Coastguard Worker   while (hashsize > 0)
330*5e7646d2SAndroid Build Coastguard Worker   {
331*5e7646d2SAndroid Build Coastguard Worker     *bufptr++ = hex[*hash >> 4];
332*5e7646d2SAndroid Build Coastguard Worker     *bufptr++ = hex[*hash & 15];
333*5e7646d2SAndroid Build Coastguard Worker 
334*5e7646d2SAndroid Build Coastguard Worker     hash ++;
335*5e7646d2SAndroid Build Coastguard Worker     hashsize --;
336*5e7646d2SAndroid Build Coastguard Worker   }
337*5e7646d2SAndroid Build Coastguard Worker 
338*5e7646d2SAndroid Build Coastguard Worker   *bufptr = '\0';
339*5e7646d2SAndroid Build Coastguard Worker 
340*5e7646d2SAndroid Build Coastguard Worker   return (buffer);
341*5e7646d2SAndroid Build Coastguard Worker }
342