sha2_mod.c revision d2b323064c1e0b7131b3f784139d57c317e9b625
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A * The sha2 module is created with two modlinkages: 2N/A * - a modlmisc that allows consumers to directly call the entry points 2N/A * SHA2Init, SHA2Update, and SHA2Final. 2N/A * - a modlcrypto that allows the module to register with the Kernel 2N/A * Cryptographic Framework (KCF) as a software provider for the SHA2 2N/A "SHA2 Message-Digest Algorithm" 2N/A "SHA2 Kernel SW Provider" 2N/A * CSPI information (entry points, provider info, etc.) 2N/A * Context for SHA2 mechanism. 2N/A * Context for SHA2 HMAC and HMAC GENERAL mechanisms. 2N/A * Macros to access the SHA2 or SHA2-HMAC contexts from a context passed 2N/A * by KCF to one of the entry points. 2N/A/* to extract the digest length passed as mechanism parameter */ 2N/A * Mechanism info structure passed to KCF during registration. 2N/A /* SHA256-HMAC GENERAL */ 2N/A /* SHA384-HMAC GENERAL */ 2N/A /* SHA512-HMAC GENERAL */ 2N/A "SHA2 Software Provider",
2N/A * Register with KCF. If the registration fails, log an 2N/A * error but do not uninstall the module, since the functionality 2N/A "crypto_register_provider() failed (0x%x)",
ret);
2N/A * KCF software provider control entry points. 2N/A * KCF software provider digest entry points. 2N/A * Allocate and initialize SHA2 context. 2N/A * Helper SHA2 digest update function for uio data. /* we support only kernel buffer */ * Jump to the first iovec containing data to be * The caller specified an offset that is larger than the * total size of the buffers it provided. * Now do the digesting on the iovecs. * The end of the specified iovec's was reached but * the length requested could not be processed, i.e. * The caller requested to digest more data than it provided. * Helper SHA2 digest final function for uio data. * digest_len is the length of the desired digest. If digest_len * is smaller than the default SHA2 digest length, the caller * must pass a scratch buffer, digest_scratch, which must * be at least the algorithm's digest length bytes. /* we support only kernel buffer */ * Jump to the first iovec containing ptr to the digest to * The caller specified an offset that is * larger than the total size of the buffers * The computed SHA2 digest will fit in the current * The caller requested a short digest. Digest * into a scratch buffer and return to * the user only what was requested. * The computed digest will be crossing one or more iovec's. * This is bad performance-wise but we need to support it. * Allocate a small scratch buffer on the stack and * copy it piece meal to the specified digest iovec's. * The end of the specified iovec's was reached but * the length requested could not be processed, i.e. * The caller requested to digest more data than it * Helper SHA2 digest update for mblk's. * Jump to the first mblk_t containing data to be digested. * The caller specified an offset that is larger than the * total size of the buffers it provided. * Now do the digesting on the mblk chain. * The end of the mblk was reached but the length requested * could not be processed, i.e. The caller requested * to digest more data than it provided. * Helper SHA2 digest final for mblk's. * digest_len is the length of the desired digest. If digest_len * is smaller than the default SHA2 digest length, the caller * must pass a scratch buffer, digest_scratch, which must * be at least the algorithm's digest length bytes. * Jump to the first mblk_t that will be used to store the digest. * The caller specified an offset that is larger than the * total size of the buffers it provided. * The computed SHA2 digest will fit in the current mblk. * Do the SHA2Final() in-place. * The caller requested a short digest. Digest * into a scratch buffer and return to * the user only what was requested. * The computed digest will be crossing one or more mblk's. * This is bad performance-wise but we need to support it. * Allocate a small scratch buffer on the stack and * copy it piece meal to the specified digest iovec's. * The end of the specified mblk was reached but * the length requested could not be processed, i.e. * The caller requested to digest more data than it * We need to just return the length needed to store the output. * We should not destroy the context for the following cases. * Do the SHA2 update on the specified input data. /* the update failed, free context and bail */ * Do a SHA2 final, must be done separately since the digest * type can be different than the input data type. /* all done, free context and return */ * Do the SHA2 update on the specified input data. * We need to just return the length needed to store the output. * We should not destroy the context for the following cases. /* all done, free context and return */ * Do the SHA updates on the specified input data. /* the update failed, bail */ * Do a SHA2 final, must be done separately since the digest * type can be different than the input data type. * KCF software provider mac entry points. * SHA2 HMAC is: SHA2(key XOR opad, SHA2(key XOR ipad, text)) * The initialization routine initializes what we denote * as the inner and outer contexts by doing * - for inner context: SHA2(key XOR ipad) * - for outer context: SHA2(key XOR opad) * Each subsequent SHA2 HMAC update will result in an * update of the inner context with the specified data. * The SHA2 HMAC final will do a SHA2 final operation on the * inner context, and the resulting digest will be used * as the data for an update on the outer context. Last * but not least, a SHA2 final on the outer context will * be performed to obtain the SHA2 HMAC digest to return * Initialize a SHA2-HMAC context. /* Determine the block size */ /* XOR key with ipad (0x36) and opad (0x5c) */ ipad[i] ^=
0x3636363636363636;
opad[i] ^=
0x5c5c5c5c5c5c5c5c;
/* perform SHA2 on ipad */ /* perform SHA2 on opad */ * Set the digest length and block size to values approriate to the /* reuse context template */ /* no context template, compute context */ * Hash the passed-in key to get a smaller key. * The inner context is used since it hasn't been * Get the mechanism parameters, if applicable. * Do a SHA2 update of the inner context using the specified /* Set the digest lengths to values approriate to the mechanism */ * We need to just return the length needed to store the output. * We should not destroy the context for the following cases. * Do a SHA2 final on the inner context. * Do a SHA2 update on the outer context, feeding the inner * Do a SHA2 final on the outer context, storing the computing * digest in the users buffer. * The caller requested a short digest. Digest * into a scratch buffer and return to * the user only what was requested. * Set the digest length and block size to values approriate to the /* Add support for key by attributes (RFE 4706552) */ /* reuse context template */ /* no context template, initialize context */ * Hash the passed-in key to get a smaller key. * The inner context is used since it hasn't been /* get the mechanism parameters, if applicable */ /* do a SHA2 update of the inner context using the specified data */ /* the update failed, free context and bail */ * Do a SHA2 final on the inner context. * Do an SHA2 update on the outer context, feeding the inner * Make sure that SHA384 is handled special because * it cannot feed a 60-byte inner hash to the outer * Do a SHA2 final on the outer context, storing the computed * digest in the users buffer. * The caller requested a short digest. Digest * into a scratch buffer and return to * the user only what was requested. * Set the digest length and block size to values approriate to the /* Add support for key by attributes (RFE 4706552) */ /* reuse context template */ /* no context template, initialize context */ * Hash the passed-in key to get a smaller key. * The inner context is used since it hasn't been /* get the mechanism parameters, if applicable */ /* do a SHA2 update of the inner context using the specified data */ /* the update failed, free context and bail */ /* do a SHA2 final on the inner context */ * Do an SHA2 update on the outer context, feeding the inner * Do a SHA2 final on the outer context, storing the computed * digest in the users buffer. * Compare the computed digest against the expected digest passed /* we support only kernel buffer */ /* jump to the first iovec containing the expected digest */ * The caller specified an offset that is * larger than the total size of the buffers /* do the comparison of computed digest vs specified one */ /* jump to the first mblk_t containing the expected digest */ * The caller specified an offset that is larger than * the total size of the buffers it provided. * KCF software provider context management entry points. * Set the digest length and block size to values approriate to the /* Add support for key by attributes (RFE 4706552) */ * Allocate and initialize SHA2 context. * Hash the passed-in key to get a smaller key. * The inner context is used since it hasn't been * We have to free either SHA2 or SHA2-HMAC contexts, which * have different lengths. * Note: Below is dependent on the mechanism ordering.