| @@ -0,0 +1,90 @@ | ||
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | ||
| <head> | ||
| <meta http-equiv="Content-Type" content="text/xhtml;charset=iso-8859-1" /> | ||
| <meta http-equiv="Content-Style-Type" content="text/css" /> | ||
| <meta http-equiv="Content-Language" content="en" /> | ||
| <link rel="stylesheet" href="doxygen.css"> | ||
| <title>TreeView</title> | ||
| <script type="text/javascript"> | ||
| <!-- // Hide script from old browsers | ||
|
|
||
| function toggleFolder(id, imageNode) | ||
| { | ||
| var folder = document.getElementById(id); | ||
| var l = imageNode.src.length; | ||
| if (imageNode.src.substring(l-20,l)=="ftv2folderclosed.png" || | ||
| imageNode.src.substring(l-18,l)=="ftv2folderopen.png") | ||
| { | ||
| imageNode = imageNode.previousSibling; | ||
| l = imageNode.src.length; | ||
| } | ||
| if (folder == null) | ||
| { | ||
| } | ||
| else if (folder.style.display == "block") | ||
| { | ||
| if (imageNode != null) | ||
| { | ||
| imageNode.nextSibling.src = "ftv2folderclosed.png"; | ||
| if (imageNode.src.substring(l-13,l) == "ftv2mnode.png") | ||
| { | ||
| imageNode.src = "ftv2pnode.png"; | ||
| } | ||
| else if (imageNode.src.substring(l-17,l) == "ftv2mlastnode.png") | ||
| { | ||
| imageNode.src = "ftv2plastnode.png"; | ||
| } | ||
| } | ||
| folder.style.display = "none"; | ||
| } | ||
| else | ||
| { | ||
| if (imageNode != null) | ||
| { | ||
| imageNode.nextSibling.src = "ftv2folderopen.png"; | ||
| if (imageNode.src.substring(l-13,l) == "ftv2pnode.png") | ||
| { | ||
| imageNode.src = "ftv2mnode.png"; | ||
| } | ||
| else if (imageNode.src.substring(l-17,l) == "ftv2plastnode.png") | ||
| { | ||
| imageNode.src = "ftv2mlastnode.png"; | ||
| } | ||
| } | ||
| folder.style.display = "block"; | ||
| } | ||
| } | ||
|
|
||
| // End script hiding --> | ||
| </script> | ||
| </head> | ||
|
|
||
| <body class="ftvtree"> | ||
| <div class="directory"> | ||
| <h3>Synopsys DWC Portability and Common Library for UWB</h3> | ||
| <div style="display: block;"> | ||
| <p><img src="ftv2node.png" alt="o" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="main.html" target="basefrm">DWC Portability and Common Library</a></p> | ||
| <p><img src="ftv2pnode.png" alt="o" width=16 height=22 onclick="toggleFolder('folder1', this)"/><img src="ftv2folderclosed.png" alt="+" width=24 height=22 onclick="toggleFolder('folder1', this)"/><a class="el" href="files.html" target="basefrm">File List</a></p> | ||
| <div id="folder1"> | ||
| <p><img src="ftv2vertline.png" alt="|" width=16 height=22 /><img src="ftv2node.png" alt="o" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="dwc__cc_8h.html" target="basefrm">dwc_cc.h</a></p> | ||
| <p><img src="ftv2vertline.png" alt="|" width=16 height=22 /><img src="ftv2node.png" alt="o" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="dwc__crypto_8c.html" target="basefrm">dwc_crypto.c</a></p> | ||
| <p><img src="ftv2vertline.png" alt="|" width=16 height=22 /><img src="ftv2node.png" alt="o" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="dwc__crypto_8h.html" target="basefrm">dwc_crypto.h</a></p> | ||
| <p><img src="ftv2vertline.png" alt="|" width=16 height=22 /><img src="ftv2node.png" alt="o" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="dwc__dh_8h.html" target="basefrm">dwc_dh.h</a></p> | ||
| <p><img src="ftv2vertline.png" alt="|" width=16 height=22 /><img src="ftv2node.png" alt="o" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="dwc__list_8h.html" target="basefrm">dwc_list.h</a></p> | ||
| <p><img src="ftv2vertline.png" alt="|" width=16 height=22 /><img src="ftv2node.png" alt="o" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="dwc__modpow_8h.html" target="basefrm">dwc_modpow.h</a></p> | ||
| <p><img src="ftv2vertline.png" alt="|" width=16 height=22 /><img src="ftv2node.png" alt="o" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="dwc__notifier_8h.html" target="basefrm">dwc_notifier.h</a></p> | ||
| <p><img src="ftv2vertline.png" alt="|" width=16 height=22 /><img src="ftv2lastnode.png" alt="\" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="dwc__os_8h.html" target="basefrm">dwc_os.h</a></p> | ||
| </div> | ||
| <p><img src="ftv2pnode.png" alt="o" width=16 height=22 onclick="toggleFolder('folder2', this)"/><img src="ftv2folderclosed.png" alt="+" width=24 height=22 onclick="toggleFolder('folder2', this)"/><a class="el" href="dirs.html" target="basefrm">Directories</a></p> | ||
| <div id="folder2"> | ||
| <p><img src="ftv2vertline.png" alt="|" width=16 height=22 /><img src="ftv2lastnode.png" alt="\" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="dir_c13d72e45af28cdc461a5f284d3d36fc.html" target="basefrm">dwc_common_port</a></p> | ||
| </div> | ||
| <p><img src="ftv2node.png" alt="o" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="globals.html" target="basefrm">Globals</a></p> | ||
| <p><img src="ftv2plastnode.png" alt="\" width=16 height=22 onclick="toggleFolder('folder3', this)"/><img src="ftv2folderclosed.png" alt="+" width=24 height=22 onclick="toggleFolder('folder3', this)"/><a class="el" href="pages.html" target="basefrm">Related Pages</a></p> | ||
| <div id="folder3"> | ||
| <p><img src="ftv2blank.png" alt=" " width=16 height=22 /><img src="ftv2lastnode.png" alt="\" width=16 height=22 /><img src="ftv2doc.png" alt="*" width=24 height=22 /><a class="el" href="todo.html" target="basefrm">Todo List</a></p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> |
| @@ -0,0 +1,209 @@ | ||
| /* ========================================================================= | ||
| * $File: //dwh/usb_iip/dev/software/dwc_common_port/dwc_cc.h $ | ||
| * $Revision: #1 $ | ||
| * $Date: 2008/12/21 $ | ||
| * $Change: 1156609 $ | ||
| * | ||
| * Synopsys Portability Library Software and documentation | ||
| * (hereinafter, "Software") is an Unsupported proprietary work of | ||
| * Synopsys, Inc. unless otherwise expressly agreed to in writing | ||
| * between Synopsys and you. | ||
| * | ||
| * The Software IS NOT an item of Licensed Software or Licensed Product | ||
| * under any End User Software License Agreement or Agreement for | ||
| * Licensed Product with Synopsys or any supplement thereto. You are | ||
| * permitted to use and redistribute this Software in source and binary | ||
| * forms, with or without modification, provided that redistributions | ||
| * of source code must retain this notice. You may not view, use, | ||
| * disclose, copy or distribute this file or any information contained | ||
| * herein except pursuant to this license grant from Synopsys. If you | ||
| * do not agree with this notice, including the disclaimer below, then | ||
| * you are not authorized to use the Software. | ||
| * | ||
| * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
| * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL | ||
| * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | ||
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
| * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
| * DAMAGE. | ||
| * ========================================================================= */ | ||
| #ifndef _DWC_CC_H_ | ||
| #define _DWC_CC_H_ | ||
|
|
||
| /** @file | ||
| * | ||
| * This file defines the Context Context library. | ||
| * | ||
| * The main data structure is dwc_cc_if_t which is returned by either the | ||
| * dwc_cc_if_alloc function or returned by the module to the user via a provided | ||
| * function. The data structure is opaque and should only be manipulated via the | ||
| * functions provied in this API. | ||
| * | ||
| * It manages a list of connection contexts and operations can be performed to | ||
| * add, remove, query, search, and change, those contexts. Additionally, | ||
| * a dwc_notifier_t object can be requested from the manager so that | ||
| * the user can be notified whenever the context list has changed. | ||
| */ | ||
|
|
||
| #include "dwc_os.h" | ||
| #include "dwc_list.h" | ||
| #include "dwc_notifier.h" | ||
|
|
||
|
|
||
| /* Notifications */ | ||
| #define DWC_CC_LIST_CHANGED_NOTIFICATION "DWC_CC_LIST_CHANGED_NOTIFICATION" | ||
|
|
||
| struct dwc_cc_if; | ||
| typedef struct dwc_cc_if dwc_cc_if_t; | ||
|
|
||
|
|
||
| /** @name Connection Context Operations */ | ||
| /** @{ */ | ||
|
|
||
| /** This function allocates memory for a dwc_cc_if_t structure, initializes | ||
| * fields to default values, and returns a pointer to the structure or NULL on | ||
| * error. */ | ||
| extern dwc_cc_if_t *dwc_cc_if_alloc(dwc_notifier_t *notifier, unsigned is_host); | ||
|
|
||
| /** Frees the memory for the specified CC structure allocated from | ||
| * dwc_cc_if_alloc(). */ | ||
| extern void dwc_cc_if_free(dwc_cc_if_t *cc_if); | ||
|
|
||
| /** Removes all contexts from the connection context list */ | ||
| extern void dwc_cc_clear(dwc_cc_if_t *cc_if); | ||
|
|
||
| /** Adds a connection context (CHID, CK, CDID, Name) to the connection context list. | ||
| * If a CHID already exists, the CK and name are overwritten. Statistics are | ||
| * not overwritten. | ||
| * | ||
| * @param cc_if The cc_if structure. | ||
| * @param chid A pointer to the 16-byte CHID. This value will be copied. | ||
| * @param ck A pointer to the 16-byte CK. This value will be copied. | ||
| * @param cdid A pointer to the 16-byte CDID. This value will be copied. | ||
| * @param name An optional host friendly name as defined in the association model | ||
| * spec. Must be a UTF16-LE unicode string. Can be NULL to indicated no name. | ||
| * @param length The length othe unicode string. | ||
| * @return A unique identifier used to refer to this context that is valid for | ||
| * as long as this context is still in the list. */ | ||
| extern int32_t dwc_cc_add(dwc_cc_if_t *cc_if, uint8_t *chid, uint8_t *cdid, uint8_t *ck, uint8_t *name, uint8_t length); | ||
|
|
||
| /** Changes the CHID, CK, CDID, or Name values of a connection context in the | ||
| * list, preserving any accumulated statistics. This would typically be called | ||
| * if the host decideds to change the context with a SET_CONNECTION request. | ||
| * | ||
| * @param cc_if The cc_if structure. | ||
| * @param id The identifier of the connection context. | ||
| * @param chid A pointer to the 16-byte CHID. This value will be copied. NULL | ||
| * indicates no change. | ||
| * @param cdid A pointer to the 16-byte CDID. This value will be copied. NULL | ||
| * indicates no change. | ||
| * @param ck A pointer to the 16-byte CK. This value will be copied. NULL | ||
| * indicates no change. | ||
| * @param name Host friendly name UTF16-LE. NULL indicates no change. | ||
| * @param length Length of name. */ | ||
| extern void dwc_cc_change(dwc_cc_if_t *cc_if, int32_t id, uint8_t *chid, uint8_t *cdid, uint8_t *ck, uint8_t *name, uint8_t length); | ||
|
|
||
| /** Remove the specified connection context. | ||
| * @param cc_if The cc_if structure. | ||
| * @param id The identifier of the connection context to remove. */ | ||
| extern void dwc_cc_remove(dwc_cc_if_t *cc_if, int32_t id); | ||
|
|
||
| /** Get a binary block of data for the connection context list and attributes. | ||
| * This data can be used by the OS specific driver to save the connection | ||
| * context list into non-volatile memory. | ||
| * | ||
| * @param cc_if The cc_if structure. | ||
| * @param length Return the length of the data buffer. | ||
| * @return A pointer to the data buffer. The memory for this buffer should be freed with DWC_FREE() after use. */ | ||
| extern uint8_t *dwc_cc_data_for_save(dwc_cc_if_t *cc_if, unsigned int *length); | ||
|
|
||
| /** Restore the connection context list from the binary data that was previously | ||
| * returned from a call to dwc_cc_data_for_save. This can be used by the OS specific | ||
| * driver to load a connection context list from non-volatile memory. | ||
| * | ||
| * @param cc_if The cc_if structure. | ||
| * @param data The data bytes as returned from dwc_cc_data_for_save. | ||
| * @param length The length of the data. */ | ||
| extern void dwc_cc_restore_from_data(dwc_cc_if_t *cc_if, uint8_t *data, unsigned int length); | ||
|
|
||
| /** Find the connection context from the specified CHID. | ||
| * | ||
| * @param cc_if The cc_if structure. | ||
| * @param chid A pointer to the CHID data. | ||
| * @return A non-zero identifier of the connection context if the CHID matches. | ||
| * Otherwise returns 0. */ | ||
| extern uint32_t dwc_cc_match_chid(dwc_cc_if_t *cc_if, uint8_t *chid); | ||
|
|
||
| /** Find the connection context from the specified CDID. | ||
| * | ||
| * @param cc_if The cc_if structure. | ||
| * @param cdid A pointer to the CDID data. | ||
| * @return A non-zero identifier of the connection context if the CHID matches. | ||
| * Otherwise returns 0. */ | ||
| extern uint32_t dwc_cc_match_cdid(dwc_cc_if_t *cc_if, uint8_t *cdid); | ||
|
|
||
| /** Retrieve the CK from the specified connection context. | ||
| * | ||
| * @param cc_if The cc_if structure. | ||
| * @param id The identifier of the connection context. | ||
| * @return A pointer to the CK data. The memory does not need to be freed. */ | ||
| extern uint8_t *dwc_cc_ck(dwc_cc_if_t *cc_if, int32_t id); | ||
|
|
||
| /** Retrieve the CHID from the specified connection context. | ||
| * | ||
| * @param cc_if The cc_if structure. | ||
| * @param id The identifier of the connection context. | ||
| * @return A pointer to the CHID data. The memory does not need to be freed. */ | ||
| extern uint8_t *dwc_cc_chid(dwc_cc_if_t *cc_if, int32_t id); | ||
|
|
||
| /** Retrieve the CDID from the specified connection context. | ||
| * | ||
| * @param cc_if The cc_if structure. | ||
| * @param id The identifier of the connection context. | ||
| * @return A pointer to the CDID data. The memory does not need to be freed. */ | ||
| extern uint8_t *dwc_cc_cdid(dwc_cc_if_t *cc_if, int32_t id); | ||
|
|
||
| extern uint8_t *dwc_cc_name(dwc_cc_if_t *cc_if, int32_t id, uint8_t *length); | ||
|
|
||
| /** Checks a buffer for non-zero. | ||
| * @param id A pointer to a 16 byte buffer. | ||
| * @return true if the 16 byte value is non-zero. */ | ||
| static inline unsigned dwc_assoc_is_not_zero_id(uint8_t *id) { | ||
| int i; | ||
| for (i=0; i<16; i++) { | ||
| if (id[i]) return 1; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| /** Checks a buffer for zero. | ||
| * @param id A pointer to a 16 byte buffer. | ||
| * @return true if the 16 byte value is zero. */ | ||
| static inline unsigned dwc_assoc_is_zero_id(uint8_t *id) { | ||
| return !dwc_assoc_is_not_zero_id(id); | ||
| } | ||
|
|
||
| /** Prints an ASCII representation for the 16-byte chid, cdid, or ck, into | ||
| * buffer. */ | ||
| static inline int dwc_print_id_string(char *buffer, uint8_t *id) { | ||
| char *ptr = buffer; | ||
| int i; | ||
| for (i=0; i<16; i++) { | ||
| ptr += DWC_SPRINTF(ptr, "%02x", id[i]); | ||
| if (i < 15) { | ||
| ptr += DWC_SPRINTF(ptr, " "); | ||
| } | ||
| } | ||
| return ptr - buffer; | ||
| } | ||
|
|
||
| /** @} */ | ||
|
|
||
| #endif /* _DWC_CC_H_ */ | ||
|
|
| @@ -0,0 +1,306 @@ | ||
| /* ========================================================================= | ||
| * $File: //dwh/usb_iip/dev/software/dwc_common_port/dwc_crypto.c $ | ||
| * $Revision: #1 $ | ||
| * $Date: 2008/12/21 $ | ||
| * $Change: 1156609 $ | ||
| * | ||
| * Synopsys Portability Library Software and documentation | ||
| * (hereinafter, "Software") is an Unsupported proprietary work of | ||
| * Synopsys, Inc. unless otherwise expressly agreed to in writing | ||
| * between Synopsys and you. | ||
| * | ||
| * The Software IS NOT an item of Licensed Software or Licensed Product | ||
| * under any End User Software License Agreement or Agreement for | ||
| * Licensed Product with Synopsys or any supplement thereto. You are | ||
| * permitted to use and redistribute this Software in source and binary | ||
| * forms, with or without modification, provided that redistributions | ||
| * of source code must retain this notice. You may not view, use, | ||
| * disclose, copy or distribute this file or any information contained | ||
| * herein except pursuant to this license grant from Synopsys. If you | ||
| * do not agree with this notice, including the disclaimer below, then | ||
| * you are not authorized to use the Software. | ||
| * | ||
| * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
| * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL | ||
| * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | ||
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
| * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
| * DAMAGE. | ||
| * ========================================================================= */ | ||
|
|
||
| /** @file | ||
| * This file contains the WUSB cryptographic routines. | ||
| */ | ||
|
|
||
| #include "dwc_crypto.h" | ||
| #include "usb.h" | ||
|
|
||
| #ifdef DEBUG | ||
| static inline void dump_bytes(char *name, uint8_t *bytes, int len) | ||
| { | ||
| int i; | ||
| DWC_PRINTF("%s: ", name); | ||
| for (i=0; i<len; i++) { | ||
| DWC_PRINTF("%02x ", bytes[i]); | ||
| } | ||
| DWC_PRINTF("\n"); | ||
| } | ||
| #else | ||
| #define dump_bytes(x...) | ||
| #endif | ||
|
|
||
| /* Display a block */ | ||
| void show_block(const u8 *blk, const char *prefix, const char *suffix, int a) | ||
| { | ||
| #ifdef DEBUG_CRYPTO | ||
| int i, blksize = 16; | ||
|
|
||
| DWC_DEBUG("%s", prefix); | ||
|
|
||
| if (suffix == NULL) { | ||
| suffix = "\n"; | ||
| blksize = a; | ||
| } | ||
|
|
||
| for (i = 0; i < blksize; i++) | ||
| DWC_PRINT("%02x%s", *blk++, ((i & 3) == 3) ? " " : " "); | ||
| DWC_PRINT(suffix); | ||
|
|
||
| #endif | ||
| } | ||
|
|
||
| /** | ||
| * Encrypts an array of bytes using the AES encryption engine. | ||
| * If <code>dst</code> == <code>src</code>, then the bytes will be encrypted | ||
| * in-place. | ||
| * | ||
| * @return 0 on success, negative error code on error. | ||
| */ | ||
| int dwc_wusb_aes_encrypt(u8 *src, u8 *key, u8 *dst) | ||
| { | ||
| u8 block_t[16]; | ||
| DWC_MEMSET(block_t, 0, 16); | ||
|
|
||
| return DWC_AES_CBC(src, 16, key, 16, block_t, dst); | ||
| } | ||
|
|
||
| /** | ||
| * The CCM-MAC-FUNCTION described in section 6.5 of the WUSB spec. | ||
| * This function takes a data string and returns the encrypted CBC | ||
| * Counter-mode MIC. | ||
| * | ||
| * @param key The 128-bit symmetric key. | ||
| * @param nonce The CCM nonce. | ||
| * @param label The unique 14-byte ASCII text label. | ||
| * @param bytes The byte array to be encrypted. | ||
| * @param len Length of the byte array. | ||
| * @param result Byte array to receive the 8-byte encrypted MIC. | ||
| */ | ||
| void dwc_wusb_cmf(u8 *key, u8 *nonce, | ||
| char *label, u8 *bytes, int len, u8 *result) | ||
| { | ||
| u8 block_m[16]; | ||
| u8 block_x[16]; | ||
| u8 block_t[8]; | ||
| int idx, blkNum; | ||
| u16 la = (u16)(len + 14); | ||
|
|
||
| /* Set the AES-128 key */ | ||
| //dwc_aes_setkey(tfm, key, 16); | ||
|
|
||
| /* Fill block B0 from flags = 0x59, N, and l(m) = 0 */ | ||
| block_m[0] = 0x59; | ||
| for (idx = 0; idx < 13; idx++) | ||
| block_m[idx + 1] = nonce[idx]; | ||
| block_m[14] = 0; | ||
| block_m[15] = 0; | ||
|
|
||
| /* Produce the CBC IV */ | ||
| dwc_wusb_aes_encrypt(block_m, key, block_x); | ||
| show_block(block_m, "CBC IV in: ", "\n", 0); | ||
| show_block(block_x, "CBC IV out:", "\n", 0); | ||
|
|
||
| /* Fill block B1 from l(a) = Blen + 14, and A */ | ||
| block_x[0] ^= (u8)(la >> 8); | ||
| block_x[1] ^= (u8)la; | ||
| for (idx = 0; idx < 14; idx++) | ||
| block_x[idx + 2] ^= label[idx]; | ||
| show_block(block_x, "After xor: ", "b1\n", 16); | ||
|
|
||
| dwc_wusb_aes_encrypt(block_x, key, block_x); | ||
| show_block(block_x, "After AES: ", "b1\n", 16); | ||
|
|
||
| idx = 0; | ||
| blkNum = 0; | ||
|
|
||
| /* Fill remaining blocks with B */ | ||
| while (len-- > 0) { | ||
| block_x[idx] ^= *bytes++; | ||
| if (++idx >= 16) { | ||
| idx = 0; | ||
| show_block(block_x, "After xor: ", "\n", blkNum); | ||
| dwc_wusb_aes_encrypt(block_x, key, block_x); | ||
| show_block(block_x, "After AES: ", "\n", blkNum); | ||
| blkNum++; | ||
| } | ||
| } | ||
|
|
||
| /* Handle partial last block */ | ||
| if (idx > 0) { | ||
| show_block(block_x, "After xor: ", "\n", blkNum); | ||
| dwc_wusb_aes_encrypt(block_x, key, block_x); | ||
| show_block(block_x, "After AES: ", "\n", blkNum); | ||
| } | ||
|
|
||
| /* Save the MIC tag */ | ||
| DWC_MEMCPY(block_t, block_x, 8); | ||
| show_block(block_t, "MIC tag : ", NULL, 8); | ||
|
|
||
| /* Fill block A0 from flags = 0x01, N, and counter = 0 */ | ||
| block_m[0] = 0x01; | ||
| block_m[14] = 0; | ||
| block_m[15] = 0; | ||
|
|
||
| /* Encrypt the counter */ | ||
| dwc_wusb_aes_encrypt(block_m, key, block_x); | ||
| show_block(block_x, "CTR[MIC] : ", NULL, 8); | ||
|
|
||
| /* XOR with MIC tag */ | ||
| for (idx = 0; idx < 8; idx++) { | ||
| block_t[idx] ^= block_x[idx]; | ||
| } | ||
|
|
||
| /* Return result to caller */ | ||
| DWC_MEMCPY(result, block_t, 8); | ||
| show_block(result, "CCM-MIC : ", NULL, 8); | ||
|
|
||
| } | ||
|
|
||
| /** | ||
| * The PRF function described in section 6.5 of the WUSB spec. This function | ||
| * concatenates MIC values returned from dwc_cmf() to create a value of | ||
| * the requested length. | ||
| * | ||
| * @param prf_len Length of the PRF function in bits (64, 128, or 256). | ||
| * @param key, nonce, label, bytes, len Same as for dwc_cmf(). | ||
| * @param result Byte array to receive the result. | ||
| */ | ||
| void dwc_wusb_prf(int prf_len, u8 *key, | ||
| u8 *nonce, char *label, u8 *bytes, int len, u8 *result) | ||
| { | ||
| int i; | ||
|
|
||
| nonce[0] = 0; | ||
| for (i = 0; i < prf_len >> 6; i++, nonce[0]++) { | ||
| dwc_wusb_cmf(key, nonce, label, bytes, len, result); | ||
| result += 8; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Fills in CCM Nonce per the WUSB spec. | ||
| * | ||
| * @param[in] haddr Host address. | ||
| * @param[in] daddr Device address. | ||
| * @param[in] tkid Session Key(PTK) identifier. | ||
| * @param[out] nonce Pointer to where the CCM Nonce output is to be written. | ||
| */ | ||
| void dwc_wusb_fill_ccm_nonce(uint16_t haddr, uint16_t daddr, uint8_t *tkid, | ||
| uint8_t *nonce) | ||
| { | ||
|
|
||
| DWC_DEBUG("%s %x %x\n", __func__, daddr, haddr); | ||
|
|
||
| DWC_MEMSET(&nonce[0], 0, 16); | ||
|
|
||
| DWC_MEMCPY(&nonce[6], tkid, 3); | ||
| nonce[9] = daddr & 0xFF; | ||
| nonce[10] = (daddr >> 8) & 0xFF; | ||
| nonce[11] = haddr & 0xFF; | ||
| nonce[12] = (haddr >> 8) & 0xFF; | ||
|
|
||
| dump_bytes("CCM nonce", nonce, 16); | ||
| } | ||
|
|
||
| /** | ||
| * Generates a 16-byte cryptographic-grade random number for the Host/Device | ||
| * Nonce. | ||
| */ | ||
| void dwc_wusb_gen_nonce(uint16_t addr, uint8_t *nonce) | ||
| { | ||
| uint8_t inonce[16]; | ||
| uint32_t temp[4]; | ||
|
|
||
| /* Fill in the Nonce */ | ||
| DWC_MEMSET(&inonce[0], 0, sizeof(inonce)); | ||
| inonce[9] = addr & 0xFF; | ||
| inonce[10] = (addr >> 8) & 0xFF; | ||
| inonce[11] = inonce[9]; | ||
| inonce[12] = inonce[10]; | ||
|
|
||
| /* Collect "randomness samples" */ | ||
| DWC_RANDOM_BYTES((uint8_t *)temp, 16); | ||
|
|
||
| dwc_wusb_prf_128((uint8_t *)temp, nonce, | ||
| "Random Numbers", (uint8_t *)temp, sizeof(temp), | ||
| nonce); | ||
| } | ||
|
|
||
| /** | ||
| * Generates the Session Key (PTK) and Key Confirmation Key (KCK) per the | ||
| * WUSB spec. | ||
| * | ||
| * @param[in] ccm_nonce Pointer to CCM Nonce. | ||
| * @param[in] mk Master Key to derive the session from | ||
| * @param[in] hnonce Pointer to Host Nonce. | ||
| * @param[in] dnonce Pointer to Device Nonce. | ||
| * @param[out] kck Pointer to where the KCK output is to be written. | ||
| * @param[out] ptk Pointer to where the PTK output is to be written. | ||
| */ | ||
| void dwc_wusb_gen_key(uint8_t *ccm_nonce, uint8_t *mk, uint8_t *hnonce, | ||
| uint8_t *dnonce, uint8_t *kck, uint8_t *ptk) | ||
| { | ||
| uint8_t idata[32]; | ||
| uint8_t odata[32]; | ||
|
|
||
| dump_bytes("ck", mk, 16); | ||
| dump_bytes("hnonce", hnonce, 16); | ||
| dump_bytes("dnonce", dnonce, 16); | ||
|
|
||
| /* The data is the HNonce and DNonce concatenated */ | ||
| DWC_MEMCPY(&idata[0], hnonce, 16); | ||
| DWC_MEMCPY(&idata[16], dnonce, 16); | ||
|
|
||
| dwc_wusb_prf_256(mk, ccm_nonce, "Pair-wise keys", idata, 32, odata); | ||
|
|
||
| /* Low 16 bytes of the result is the KCK, high 16 is the PTK */ | ||
| DWC_MEMCPY(kck, &odata[0], 16); | ||
| DWC_MEMCPY(ptk, &odata[16], 16); | ||
|
|
||
| dump_bytes("kck", kck, 16); | ||
| dump_bytes("ptk", ptk, 16); | ||
| } | ||
|
|
||
| /** | ||
| * Generates the Message Integrity Code over the Handshake data per the | ||
| * WUSB spec. | ||
| * | ||
| * @param ccm_nonce Pointer to CCM Nonce. | ||
| * @param kck Pointer to Key Confirmation Key. | ||
| * @param data Pointer to Handshake data to be checked. | ||
| * @param mic Pointer to where the MIC output is to be written. | ||
| */ | ||
| void dwc_wusb_gen_mic(uint8_t *ccm_nonce, uint8_t *kck, | ||
| uint8_t *data, uint8_t *mic) | ||
| { | ||
|
|
||
| dwc_wusb_prf_64(kck, ccm_nonce, "out-of-bandMIC", | ||
| data, WUSB_HANDSHAKE_LEN_FOR_MIC, mic); | ||
| } | ||
|
|
| @@ -0,0 +1,103 @@ | ||
| /* ========================================================================= | ||
| * $File: //dwh/usb_iip/dev/software/dwc_common_port/dwc_crypto.h $ | ||
| * $Revision: #1 $ | ||
| * $Date: 2008/12/21 $ | ||
| * $Change: 1156609 $ | ||
| * | ||
| * Synopsys Portability Library Software and documentation | ||
| * (hereinafter, "Software") is an Unsupported proprietary work of | ||
| * Synopsys, Inc. unless otherwise expressly agreed to in writing | ||
| * between Synopsys and you. | ||
| * | ||
| * The Software IS NOT an item of Licensed Software or Licensed Product | ||
| * under any End User Software License Agreement or Agreement for | ||
| * Licensed Product with Synopsys or any supplement thereto. You are | ||
| * permitted to use and redistribute this Software in source and binary | ||
| * forms, with or without modification, provided that redistributions | ||
| * of source code must retain this notice. You may not view, use, | ||
| * disclose, copy or distribute this file or any information contained | ||
| * herein except pursuant to this license grant from Synopsys. If you | ||
| * do not agree with this notice, including the disclaimer below, then | ||
| * you are not authorized to use the Software. | ||
| * | ||
| * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
| * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL | ||
| * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | ||
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
| * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
| * DAMAGE. | ||
| * ========================================================================= */ | ||
|
|
||
| #ifndef _DWC_CRYPTO_H_ | ||
| #define _DWC_CRYPTO_H_ | ||
|
|
||
| /** @file | ||
| * | ||
| * This file contains declarations for the WUSB Cryptographic routines as | ||
| * defined in the WUSB spec. They are only to be used internally by the DWC UWB | ||
| * modules. | ||
| */ | ||
|
|
||
| #include "dwc_os.h" | ||
|
|
||
| int dwc_wusb_aes_encrypt(u8 *src, u8 *key, u8 *dst); | ||
|
|
||
| void dwc_wusb_cmf(u8 *key, u8 *nonce, | ||
| char *label, u8 *bytes, int len, u8 *result); | ||
| void dwc_wusb_prf(int prf_len, u8 *key, | ||
| u8 *nonce, char *label, u8 *bytes, int len, u8 *result); | ||
|
|
||
| /** | ||
| * The PRF-64 function described in section 6.5 of the WUSB spec. | ||
| * | ||
| * @param key, nonce, label, bytes, len, result Same as for dwc_prf(). | ||
| */ | ||
| static inline void dwc_wusb_prf_64(u8 *key, u8 *nonce, | ||
| char *label, u8 *bytes, int len, u8 *result) | ||
| { | ||
| dwc_wusb_prf(64, key, nonce, label, bytes, len, result); | ||
| } | ||
|
|
||
| /** | ||
| * The PRF-128 function described in section 6.5 of the WUSB spec. | ||
| * | ||
| * @param key, nonce, label, bytes, len, result Same as for dwc_prf(). | ||
| */ | ||
| static inline void dwc_wusb_prf_128(u8 *key, u8 *nonce, | ||
| char *label, u8 *bytes, int len, u8 *result) | ||
| { | ||
| dwc_wusb_prf(128, key, nonce, label, bytes, len, result); | ||
| } | ||
|
|
||
| /** | ||
| * The PRF-256 function described in section 6.5 of the WUSB spec. | ||
| * | ||
| * @param key, nonce, label, bytes, len, result Same as for dwc_prf(). | ||
| */ | ||
| static inline void dwc_wusb_prf_256(u8 *key, u8 *nonce, | ||
| char *label, u8 *bytes, int len, u8 *result) | ||
| { | ||
| dwc_wusb_prf(256, key, nonce, label, bytes, len, result); | ||
| } | ||
|
|
||
|
|
||
| void dwc_wusb_fill_ccm_nonce(uint16_t haddr, uint16_t daddr, uint8_t *tkid, | ||
| uint8_t *nonce); | ||
| void dwc_wusb_gen_nonce(uint16_t addr, | ||
| uint8_t *nonce); | ||
|
|
||
| void dwc_wusb_gen_key(uint8_t *ccm_nonce, uint8_t *mk, | ||
| uint8_t *hnonce, uint8_t *dnonce, | ||
| uint8_t *kck, uint8_t *ptk); | ||
|
|
||
|
|
||
| void dwc_wusb_gen_mic(uint8_t *ccm_nonce, uint8_t | ||
| *kck, uint8_t *data, uint8_t *mic); | ||
|
|
||
| #endif /* _DWC_CRYPTO_H_ */ |
| @@ -0,0 +1,286 @@ | ||
| /* ========================================================================= | ||
| * $File: //dwh/usb_iip/dev/software/dwc_common_port/dwc_dh.c $ | ||
| * $Revision: #1 $ | ||
| * $Date: 2008/12/21 $ | ||
| * $Change: 1156609 $ | ||
| * | ||
| * Synopsys Portability Library Software and documentation | ||
| * (hereinafter, "Software") is an Unsupported proprietary work of | ||
| * Synopsys, Inc. unless otherwise expressly agreed to in writing | ||
| * between Synopsys and you. | ||
| * | ||
| * The Software IS NOT an item of Licensed Software or Licensed Product | ||
| * under any End User Software License Agreement or Agreement for | ||
| * Licensed Product with Synopsys or any supplement thereto. You are | ||
| * permitted to use and redistribute this Software in source and binary | ||
| * forms, with or without modification, provided that redistributions | ||
| * of source code must retain this notice. You may not view, use, | ||
| * disclose, copy or distribute this file or any information contained | ||
| * herein except pursuant to this license grant from Synopsys. If you | ||
| * do not agree with this notice, including the disclaimer below, then | ||
| * you are not authorized to use the Software. | ||
| * | ||
| * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
| * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL | ||
| * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | ||
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
| * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
| * DAMAGE. | ||
| * ========================================================================= */ | ||
| #ifndef CONFIG_MACH_IPMATE | ||
| #include "dwc_dh.h" | ||
| #include "dwc_modpow.h" | ||
|
|
||
| #ifdef DEBUG | ||
| /* This function prints out a buffer in the format described in the Association | ||
| * Model specification. */ | ||
| static void dh_dump(char *str, void *_num, int len) | ||
| { | ||
| uint8_t *num = _num; | ||
| int i; | ||
| DWC_PRINTF("%s\n", str); | ||
| for (i = 0; i < len; i ++) { | ||
| DWC_PRINTF("%02x", num[i]); | ||
| if (((i + 1) % 2) == 0) DWC_PRINTF(" "); | ||
| if (((i + 1) % 26) == 0) DWC_PRINTF("\n"); | ||
| } | ||
|
|
||
| DWC_PRINTF("\n"); | ||
| } | ||
| #else | ||
| #define dh_dump(_x...) do {; } while(0) | ||
| #endif | ||
|
|
||
| /* Constant g value */ | ||
| static __u32 dh_g[] = { | ||
| 0x02000000, | ||
| }; | ||
|
|
||
| /* Constant p value */ | ||
| static __u32 dh_p[] = { | ||
| 0xFFFFFFFF, 0xFFFFFFFF, 0xA2DA0FC9, 0x34C26821, 0x8B62C6C4, 0xD11CDC80, 0x084E0229, 0x74CC678A, | ||
| 0xA6BE0B02, 0x229B133B, 0x79084A51, 0xDD04348E, 0xB31995EF, 0x1B433ACD, 0x6D0A2B30, 0x37145FF2, | ||
| 0x6D35E14F, 0x45C2516D, 0x76B585E4, 0xC67E5E62, 0xE9424CF4, 0x6BED37A6, 0xB65CFF0B, 0xEDB706F4, | ||
| 0xFB6B38EE, 0xA59F895A, 0x11249FAE, 0xE61F4B7C, 0x51662849, 0x3D5BE4EC, 0xB87C00C2, 0x05BF63A1, | ||
| 0x3648DA98, 0x9AD3551C, 0xA83F1669, 0x5FCF24FD, 0x235D6583, 0x96ADA3DC, 0x56F3621C, 0xBB528520, | ||
| 0x0729D59E, 0x6D969670, 0x4E350C67, 0x0498BC4A, 0x086C74F1, 0x7C2118CA, 0x465E9032, 0x3BCE362E, | ||
| 0x2C779EE3, 0x03860E18, 0xA283279B, 0x8FA207EC, 0xF05DC5B5, 0xC9524C6F, 0xF6CB2BDE, 0x18175895, | ||
| 0x7C499539, 0xE56A95EA, 0x1826D215, 0x1005FA98, 0x5A8E7215, 0x2DC4AA8A, 0x0D1733AD, 0x337A5004, | ||
| 0xAB2155A8, 0x64BA1CDF, 0x0485FBEC, 0x0AEFDB58, 0x5771EA8A, 0x7D0C065D, 0x850F97B3, 0xC7E4E1A6, | ||
| 0x8CAEF5AB, 0xD73309DB, 0xE0948C1E, 0x9D61254A, 0x26D2E3CE, 0x6BEED21A, 0x06FA2FF1, 0x64088AD9, | ||
| 0x730276D8, 0x646AC83E, 0x182B1F52, 0x0C207B17, 0x5717E1BB, 0x6C5D617A, 0xC0880977, 0xE246D9BA, | ||
| 0xA04FE208, 0x31ABE574, 0xFC5BDB43, 0x8E10FDE0, 0x20D1824B, 0xCAD23AA9, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| }; | ||
|
|
||
| static void dh_swap_bytes(void *_in, void *_out, uint32_t len) | ||
| { | ||
| uint8_t *in = _in; | ||
| uint8_t *out = _out; | ||
| int i; | ||
| for (i=0; i<len; i++) { | ||
| out[i] = in[len-1-i]; | ||
| } | ||
| } | ||
|
|
||
| /* Computes the modular exponentiation (num^exp % mod). num, exp, and mod are | ||
| * big endian numbers of size len, in bytes. Each len value must be a multiple | ||
| * of 4. */ | ||
| int dwc_dh_modpow(void *num, uint32_t num_len, | ||
| void *exp, uint32_t exp_len, | ||
| void *mod, uint32_t mod_len, | ||
| void *out) | ||
| { | ||
| /* modpow() takes little endian numbers. AM uses big-endian. This | ||
| * function swaps bytes of numbers before passing onto modpow. */ | ||
|
|
||
| int retval = 0; | ||
| uint32_t *result; | ||
|
|
||
| uint32_t *bignum_num = DWC_ALLOC(num_len + 4); | ||
| uint32_t *bignum_exp = DWC_ALLOC(exp_len + 4); | ||
| uint32_t *bignum_mod = DWC_ALLOC(mod_len + 4); | ||
|
|
||
| dh_swap_bytes(num, &bignum_num[1], num_len); | ||
| bignum_num[0] = num_len / 4; | ||
|
|
||
| dh_swap_bytes(exp, &bignum_exp[1], exp_len); | ||
| bignum_exp[0] = exp_len / 4; | ||
|
|
||
| dh_swap_bytes(mod, &bignum_mod[1], mod_len); | ||
| bignum_mod[0] = mod_len / 4; | ||
|
|
||
| result = dwc_modpow(bignum_num, bignum_exp, bignum_mod); | ||
| if (!result) { | ||
| retval = -1; | ||
| goto dh_modpow_nomem; | ||
| } | ||
|
|
||
| dh_swap_bytes(&result[1], out, result[0] * 4); | ||
| DWC_FREE(result); | ||
|
|
||
| dh_modpow_nomem: | ||
| DWC_FREE(bignum_num); | ||
| DWC_FREE(bignum_exp); | ||
| DWC_FREE(bignum_mod); | ||
| return retval; | ||
| } | ||
|
|
||
|
|
||
| int dwc_dh_pk(uint8_t nd, uint8_t *exp, uint8_t *pk, uint8_t *hash) | ||
| { | ||
| int retval; | ||
| uint8_t m3[385]; | ||
|
|
||
| #ifndef DH_TEST_VECTORS | ||
| DWC_RANDOM_BYTES(exp, 32); | ||
| #endif | ||
|
|
||
| /* Compute the pkd */ | ||
| if ((retval = dwc_dh_modpow(dh_g, 4, | ||
| exp, 32, | ||
| dh_p, 384, pk))) { | ||
| return retval; | ||
| } | ||
|
|
||
| m3[384] = nd; | ||
| DWC_MEMCPY(&m3[0], pk, 384); | ||
| DWC_SHA256(m3, 385, hash); | ||
|
|
||
| dh_dump("PK", pk, 384); | ||
| dh_dump("SHA-256(M3)", hash, 32); | ||
| return 0; | ||
| } | ||
|
|
||
| int dwc_dh_derive_keys(uint8_t nd, uint8_t *pkh, uint8_t *pkd, | ||
| uint8_t *exp, int is_host, | ||
| char *dd, uint8_t *ck, uint8_t *kdk) | ||
| { | ||
| int retval; | ||
| uint8_t mv[784]; | ||
| uint8_t sha_result[32]; | ||
| uint8_t dhkey[384]; | ||
| uint8_t shared_secret[384]; | ||
| char *message; | ||
| uint32_t vd; | ||
|
|
||
| uint8_t *pk; | ||
|
|
||
| if (is_host) { | ||
| pk = pkd; | ||
| } | ||
| else { | ||
| pk = pkh; | ||
| } | ||
|
|
||
| if ((retval = dwc_dh_modpow(pk, 384, | ||
| exp, 32, | ||
| dh_p, 384, shared_secret))) { | ||
| return retval; | ||
| } | ||
| dh_dump("Shared Secret", shared_secret, 384); | ||
|
|
||
| DWC_SHA256(shared_secret, 384, dhkey); | ||
| dh_dump("DHKEY", dhkey, 384); | ||
|
|
||
| DWC_MEMCPY(&mv[0], pkd, 384); | ||
| DWC_MEMCPY(&mv[384], pkh, 384); | ||
| DWC_MEMCPY(&mv[768], "displayed digest", 16); | ||
| dh_dump("MV", mv, 784); | ||
|
|
||
| DWC_SHA256(mv, 784, sha_result); | ||
| dh_dump("SHA-256(MV)", sha_result, 32); | ||
| dh_dump("First 32-bits of SHA-256(MV)", sha_result, 4); | ||
|
|
||
| dh_swap_bytes(sha_result, &vd, 4); | ||
| #ifdef DEBUG | ||
| DWC_PRINTF("Vd (decimal) = %d\n", vd); | ||
| #endif | ||
|
|
||
| switch (nd) { | ||
| case 2: | ||
| vd = vd % 100; | ||
| DWC_SPRINTF(dd, "%02d", vd); | ||
| break; | ||
| case 3: | ||
| vd = vd % 1000; | ||
| DWC_SPRINTF(dd, "%03d", vd); | ||
| break; | ||
| case 4: | ||
| vd = vd % 10000; | ||
| DWC_SPRINTF(dd, "%04d", vd); | ||
| break; | ||
| } | ||
| #ifdef DEBUG | ||
| DWC_PRINTF("Display Digits: %s\n", dd); | ||
| #endif | ||
|
|
||
| message = "connection key"; | ||
| DWC_HMAC_SHA256(message, DWC_STRLEN(message), dhkey, 32, sha_result); | ||
| dh_dump("HMAC(SHA-256, DHKey, connection key)", sha_result, 32); | ||
| DWC_MEMCPY(ck, sha_result, 16); | ||
|
|
||
| message = "key derivation key"; | ||
| DWC_HMAC_SHA256(message, DWC_STRLEN(message), dhkey, 32, sha_result); | ||
| dh_dump("HMAC(SHA-256, DHKey, key derivation key)", sha_result, 32); | ||
| DWC_MEMCPY(kdk, sha_result, 32); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
|
|
||
| #ifdef DH_TEST_VECTORS | ||
|
|
||
| static __u8 dh_a[] = { | ||
| 0x44, 0x00, 0x51, 0xd6, | ||
| 0xf0, 0xb5, 0x5e, 0xa9, | ||
| 0x67, 0xab, 0x31, 0xc6, | ||
| 0x8a, 0x8b, 0x5e, 0x37, | ||
| 0xd9, 0x10, 0xda, 0xe0, | ||
| 0xe2, 0xd4, 0x59, 0xa4, | ||
| 0x86, 0x45, 0x9c, 0xaa, | ||
| 0xdf, 0x36, 0x75, 0x16, | ||
| }; | ||
|
|
||
| static __u8 dh_b[] = { | ||
| 0x5d, 0xae, 0xc7, 0x86, | ||
| 0x79, 0x80, 0xa3, 0x24, | ||
| 0x8c, 0xe3, 0x57, 0x8f, | ||
| 0xc7, 0x5f, 0x1b, 0x0f, | ||
| 0x2d, 0xf8, 0x9d, 0x30, | ||
| 0x6f, 0xa4, 0x52, 0xcd, | ||
| 0xe0, 0x7a, 0x04, 0x8a, | ||
| 0xde, 0xd9, 0x26, 0x56, | ||
| }; | ||
|
|
||
| void dwc_run_dh_test_vectors(void) | ||
| { | ||
| uint8_t pkd[384]; | ||
| uint8_t pkh[384]; | ||
| uint8_t hashd[32]; | ||
| uint8_t hashh[32]; | ||
| uint8_t ck[16]; | ||
| uint8_t kdk[32]; | ||
| char dd[5]; | ||
|
|
||
| DWC_PRINTF("\n\n\nDH_TEST_VECTORS\n\n"); | ||
|
|
||
| /* compute the PKd and SHA-256(PKd || Nd) */ | ||
| DWC_PRINTF("Computing PKd\n"); | ||
| dwc_dh_pk(2, dh_a, pkd, hashd); | ||
|
|
||
| /* compute the PKd and SHA-256(PKh || Nd) */ | ||
| DWC_PRINTF("Computing PKh\n"); | ||
| dwc_dh_pk(2, dh_b, pkh, hashh); | ||
|
|
||
| /* compute the dhkey */ | ||
| dwc_dh_derive_keys(2, pkh, pkd, dh_a, 0, dd, ck, kdk); | ||
| } | ||
| #endif /* DH_TEST_VECTORS */ | ||
|
|
||
| #endif /* CONFIG_IPMATE_MACH */ |
| @@ -0,0 +1,98 @@ | ||
| /* ========================================================================= | ||
| * $File: //dwh/usb_iip/dev/software/dwc_common_port/dwc_dh.h $ | ||
| * $Revision: #1 $ | ||
| * $Date: 2008/12/21 $ | ||
| * $Change: 1156609 $ | ||
| * | ||
| * Synopsys Portability Library Software and documentation | ||
| * (hereinafter, "Software") is an Unsupported proprietary work of | ||
| * Synopsys, Inc. unless otherwise expressly agreed to in writing | ||
| * between Synopsys and you. | ||
| * | ||
| * The Software IS NOT an item of Licensed Software or Licensed Product | ||
| * under any End User Software License Agreement or Agreement for | ||
| * Licensed Product with Synopsys or any supplement thereto. You are | ||
| * permitted to use and redistribute this Software in source and binary | ||
| * forms, with or without modification, provided that redistributions | ||
| * of source code must retain this notice. You may not view, use, | ||
| * disclose, copy or distribute this file or any information contained | ||
| * herein except pursuant to this license grant from Synopsys. If you | ||
| * do not agree with this notice, including the disclaimer below, then | ||
| * you are not authorized to use the Software. | ||
| * | ||
| * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" | ||
| * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL | ||
| * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | ||
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
| * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
| * DAMAGE. | ||
| * ========================================================================= */ | ||
| #ifndef _DWC_DH_H_ | ||
| #define _DWC_DH_H_ | ||
|
|
||
| #include "dwc_os.h" | ||
|
|
||
| /** @file | ||
| * | ||
| * This file defines the common functions on device and host for performing | ||
| * numeric association as defined in the WUSB spec. They are only to be | ||
| * used internally by the DWC UWB modules. */ | ||
|
|
||
| extern int dwc_dh_sha256(uint8_t *message, uint32_t len, uint8_t *out); | ||
| extern int dwc_dh_hmac_sha256(uint8_t *message, uint32_t messagelen, | ||
| uint8_t *key, uint32_t keylen, | ||
| uint8_t *out); | ||
| extern int dwc_dh_modpow(void *num, uint32_t num_len, | ||
| void *exp, uint32_t exp_len, | ||
| void *mod, uint32_t mod_len, | ||
| void *out); | ||
|
|
||
| /** Computes PKD or PKH, and SHA-256(PKd || Nd) | ||
| * | ||
| * PK = g^exp mod p. | ||
| * | ||
| * Input: | ||
| * Nd = Number of digits on the device. | ||
| * | ||
| * Output: | ||
| * exp = A 32-byte buffer to be filled with a randomly generated number. | ||
| * used as either A or B. | ||
| * pk = A 384-byte buffer to be filled with the PKH or PKD. | ||
| * hash = A 32-byte buffer to be filled with SHA-256(PK || ND). | ||
| */ | ||
| extern int dwc_dh_pk(uint8_t nd, uint8_t *exp, uint8_t *pkd, uint8_t *hash); | ||
|
|
||
| /** Computes the DHKEY, and VD. | ||
| * | ||
| * If called from host, then it will comput DHKEY=PKD^exp % p. | ||
| * If called from device, then it will comput DHKEY=PKH^exp % p. | ||
| * | ||
| * Input: | ||
| * pkd = The PKD value. | ||
| * pkh = The PKH value. | ||
| * exp = The A value (if device) or B value (if host) generated in dwc_wudev_dh_pk. | ||
| * is_host = Set to non zero if a WUSB host is calling this function. | ||
| * | ||
| * Output: | ||
| * dd = A pointer to an buffer to be set to the displayed digits string to be shown | ||
| * to the user. This buffer should be at 5 bytes long to hold 4 digits plus a | ||
| * null termination character. This buffer can be used directly for display. | ||
| * ck = A 16-byte buffer to be filled with the CK. | ||
| * kdk = A 32-byte buffer to be filled with the KDK. | ||
| */ | ||
| extern int dwc_dh_derive_keys(uint8_t nd, uint8_t *pkh, uint8_t *pkd, | ||
| uint8_t *exp, int is_host, | ||
| char *dd, uint8_t *ck, uint8_t *kdk); | ||
|
|
||
| #ifdef DH_TEST_VECTORS | ||
| extern void dwc_run_dh_test_vectors(void); | ||
| #endif | ||
|
|
||
| #endif /* _DWC_DH_H_ */ |
| @@ -0,0 +1,172 @@ | ||
| #include "dwc_os.h" | ||
| #include "dwc_list.h" | ||
|
|
||
| /* Memory Debugging */ | ||
| #ifdef DEBUG_MEMORY | ||
|
|
||
| struct allocation | ||
| { | ||
| void *addr; | ||
| char *func; | ||
| int line; | ||
| uint32_t size; | ||
| int dma; | ||
| DWC_CIRCLEQ_ENTRY(allocation) entry; | ||
| }; | ||
|
|
||
| DWC_CIRCLEQ_HEAD(allocation_queue, allocation); | ||
|
|
||
| struct allocation_manager | ||
| { | ||
| struct allocation_queue allocations; | ||
|
|
||
| /* statistics */ | ||
| int num; | ||
| int num_freed; | ||
| int num_active; | ||
| uint32_t total; | ||
| uint32_t current; | ||
| uint32_t max; | ||
| }; | ||
|
|
||
|
|
||
| static struct allocation_manager *manager = NULL; | ||
|
|
||
| static void add_allocation(uint32_t size, char const* func, int line, void *addr, int dma) | ||
| { | ||
| struct allocation *a = __DWC_ALLOC_ATOMIC(sizeof(*a)); | ||
| a->func = __DWC_ALLOC_ATOMIC(DWC_STRLEN(func)+1); | ||
| DWC_MEMCPY(a->func, func, DWC_STRLEN(func)+1); | ||
| a->line = line; | ||
| a->size = size; | ||
| a->addr = addr; | ||
| a->dma = dma; | ||
| DWC_CIRCLEQ_INSERT_TAIL(&manager->allocations, a, entry); | ||
|
|
||
| /* Update stats */ | ||
| manager->num ++; | ||
| manager->num_active ++; | ||
| manager->total += size; | ||
| manager->current += size; | ||
| if (manager->max < manager->current) { | ||
| manager->max = manager->current; | ||
| } | ||
| } | ||
|
|
||
| static struct allocation *find_allocation(void *addr) | ||
| { | ||
| struct allocation *a; | ||
| DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) { | ||
| if (a->addr == addr) { | ||
| return a; | ||
| } | ||
| } | ||
| return NULL; | ||
| } | ||
|
|
||
| static void free_allocation(void *addr, char const* func, int line) | ||
| { | ||
| struct allocation *a = find_allocation(addr); | ||
| if (!a && func && (line >= 0)) { | ||
| DWC_ASSERT(0, "Free of address %p that was never allocated or already freed %s:%d", addr, func, line); | ||
| return; | ||
| } | ||
| DWC_CIRCLEQ_REMOVE(&manager->allocations, a, entry); | ||
|
|
||
| manager->num_active --; | ||
| manager->num_freed ++; | ||
| manager->current -= a->size; | ||
| __DWC_FREE(a->func); | ||
| __DWC_FREE(a); | ||
| } | ||
|
|
||
| void dwc_memory_debug_start(void) | ||
| { | ||
| DWC_ASSERT(manager == NULL, "Memory debugging has already started\n"); | ||
| if (manager == NULL) { | ||
| manager = __DWC_ALLOC(sizeof(*manager)); | ||
| } | ||
|
|
||
| DWC_CIRCLEQ_INIT(&manager->allocations); | ||
| manager->num = 0; | ||
| manager->num_freed = 0; | ||
| manager->num_active = 0; | ||
| manager->total = 0; | ||
| manager->current = 0; | ||
| manager->max = 0; | ||
| } | ||
|
|
||
| void dwc_memory_debug_stop(void) | ||
| { | ||
| struct allocation *a; | ||
| dwc_memory_debug_report(); | ||
|
|
||
| DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) { | ||
| DWC_ERROR("Memory leaked from %s:%d\n", a->func, a->line); | ||
| free_allocation(a->addr, NULL, -1); | ||
| } | ||
|
|
||
| __DWC_FREE(manager); | ||
| } | ||
|
|
||
| void dwc_memory_debug_report(void) | ||
| { | ||
| struct allocation *a; | ||
| DWC_PRINTF("\n\n\n----------------- Memory Debugging Report -----------------\n\n"); | ||
| DWC_PRINTF("Num Allocations = %d\n", manager->num); | ||
| DWC_PRINTF("Freed = %d\n", manager->num_freed); | ||
| DWC_PRINTF("Active = %d\n", manager->num_active); | ||
| DWC_PRINTF("Current Memory Used = %d\n", manager->current); | ||
| DWC_PRINTF("Total Memory Used = %d\n", manager->total); | ||
| DWC_PRINTF("Maximum Memory Used at Once = %d\n", manager->max); | ||
| DWC_PRINTF("Unfreed allocations:\n"); | ||
|
|
||
| DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) { | ||
| DWC_PRINTF(" addr=%p, size=%d from %s:%d, DMA=%d\n", a->addr, a->size, a->func, a->line, a->dma); | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
| /* The replacement functions */ | ||
| void *dwc_alloc_debug(uint32_t size, char const* func, int line) | ||
| { | ||
| void *addr = __DWC_ALLOC(size); | ||
| add_allocation(size, func, line, addr, 0); | ||
| return addr; | ||
| } | ||
|
|
||
| void *dwc_alloc_atomic_debug(uint32_t size, char const* func, int line) | ||
| { | ||
| void *addr = __DWC_ALLOC_ATOMIC(size); | ||
| add_allocation(size, func, line, addr, 0); | ||
| return addr; | ||
| } | ||
|
|
||
| void dwc_free_debug(void *addr, char const* func, int line) | ||
| { | ||
| free_allocation(addr, func, line); | ||
| __DWC_FREE(addr); | ||
| } | ||
|
|
||
| void *dwc_dma_alloc_debug(uint32_t size, dwc_dma_t *dma_addr, char const *func, int line) | ||
| { | ||
| void *addr = __DWC_DMA_ALLOC(size, dma_addr); | ||
| add_allocation(size, func, line, addr, 1); | ||
| return addr; | ||
| } | ||
|
|
||
| void *dwc_dma_alloc_atomic_debug(uint32_t size, dwc_dma_t *dma_addr, char const *func, int line) | ||
| { | ||
| void *addr = __DWC_DMA_ALLOC_ATOMIC(size, dma_addr); | ||
| add_allocation(size, func, line, addr, 1); | ||
| return addr; | ||
| } | ||
|
|
||
| void dwc_dma_free_debug(uint32_t size, void *virt_addr, dwc_dma_t dma_addr, char const *func, int line) | ||
| { | ||
| free_allocation(virt_addr, func, line); | ||
| __DWC_DMA_FREE(size, virt_addr, dma_addr); | ||
| } | ||
|
|
||
| #endif /* DEBUG_MEMORY */ |
| @@ -0,0 +1,26 @@ | ||
| /* | ||
| * dwc_modpow.h | ||
| * See dwc_modpow.c for license and changes | ||
| */ | ||
| #ifndef _DWC_MODPOW_H | ||
| #define _DWC_MODPOW_H | ||
|
|
||
| #include "dwc_os.h" | ||
|
|
||
| /** @file | ||
| * | ||
| * This file defines the module exponentiation function which is only used | ||
| * internally by the DWC UWB modules for calculation of PKs during numeric | ||
| * association. The routine is taken from the PUTTY, an open source terminal | ||
| * emulator. The PUTTY License is preserved in the dwc_modpow.c file. | ||
| * | ||
| */ | ||
|
|
||
| typedef uint32_t BignumInt; | ||
| typedef uint64_t BignumDblInt; | ||
| typedef BignumInt *Bignum; | ||
|
|
||
| /* Compute modular exponentiaion */ | ||
| extern Bignum dwc_modpow(Bignum base_in, Bignum exp, Bignum mod); | ||
|
|
||
| #endif /* _LINUX_BIGNUM_H */ |
| @@ -0,0 +1,256 @@ | ||
| #include "dwc_notifier.h" | ||
| #include "dwc_list.h" | ||
|
|
||
| typedef struct dwc_observer | ||
| { | ||
| void *observer; | ||
| dwc_notifier_callback_t callback; | ||
| void *data; | ||
| char *notification; | ||
| DWC_CIRCLEQ_ENTRY(dwc_observer) list_entry; | ||
| } observer_t; | ||
|
|
||
| DWC_CIRCLEQ_HEAD(observer_queue, dwc_observer); | ||
|
|
||
| typedef struct dwc_notifier | ||
| { | ||
| void *object; | ||
| struct observer_queue observers; | ||
| DWC_CIRCLEQ_ENTRY(dwc_notifier) list_entry; | ||
| } notifier_t; | ||
|
|
||
| DWC_CIRCLEQ_HEAD(notifier_queue, dwc_notifier); | ||
|
|
||
| typedef struct manager | ||
| { | ||
| dwc_workq_t *wq; | ||
| dwc_mutex_t *mutex; | ||
| struct notifier_queue notifiers; | ||
| } manager_t; | ||
|
|
||
| static manager_t *manager = NULL; | ||
|
|
||
| static void create_manager(void) | ||
| { | ||
| manager = DWC_ALLOC(sizeof(manager_t)); | ||
| DWC_CIRCLEQ_INIT(&manager->notifiers); | ||
| manager->wq = DWC_WORKQ_ALLOC("DWC Notification WorkQ"); | ||
| } | ||
|
|
||
| static void free_manager(void) | ||
| { | ||
| DWC_WORKQ_FREE(manager->wq); | ||
| /* All notifiers must have unregistered themselves before this module | ||
| * can be removed. Hitting this assertion indicates a programmer | ||
| * error. */ | ||
| DWC_ASSERT(DWC_CIRCLEQ_EMPTY(&manager->notifiers), "Notification manager being freed before all notifiers have been removed"); | ||
| DWC_FREE(manager); | ||
| } | ||
|
|
||
| #ifdef DEBUG | ||
| static void dump_manager(void) | ||
| { | ||
| notifier_t *n; | ||
| observer_t *o; | ||
| DWC_ASSERT(manager, "Notification manager not found"); | ||
| DWC_DEBUG("List of all notifiers and observers:"); | ||
| DWC_CIRCLEQ_FOREACH(n, &manager->notifiers, list_entry) { | ||
| DWC_DEBUG("Notifier %p has observers:", n->object); | ||
| DWC_CIRCLEQ_FOREACH(o, &n->observers, list_entry) { | ||
| DWC_DEBUG(" %p watching %s", o->observer, o->notification); | ||
| } | ||
| } | ||
| } | ||
| #else | ||
| #define dump_manager(...) | ||
| #endif | ||
|
|
||
| static observer_t *alloc_observer(void *observer, char *notification, dwc_notifier_callback_t callback, void *data) | ||
| { | ||
| observer_t *new_observer = DWC_ALLOC(sizeof(observer_t)); | ||
| DWC_CIRCLEQ_INIT_ENTRY(new_observer, list_entry); | ||
| new_observer->observer = observer; | ||
| new_observer->notification = notification; | ||
| new_observer->callback = callback; | ||
| new_observer->data = data; | ||
| return new_observer; | ||
| } | ||
|
|
||
| static void free_observer(observer_t *observer) | ||
| { | ||
| DWC_FREE(observer); | ||
| } | ||
|
|
||
| static notifier_t *alloc_notifier(void *object) | ||
| { | ||
| notifier_t *notifier; | ||
|
|
||
| if (!object) { | ||
| return NULL; | ||
| } | ||
|
|
||
| notifier = DWC_ALLOC(sizeof(notifier_t)); | ||
| DWC_CIRCLEQ_INIT(¬ifier->observers); | ||
| DWC_CIRCLEQ_INIT_ENTRY(notifier, list_entry); | ||
|
|
||
| notifier->object = object; | ||
| return notifier; | ||
| } | ||
|
|
||
| static void free_notifier(notifier_t *notifier) | ||
| { | ||
| observer_t *observer; | ||
| DWC_CIRCLEQ_FOREACH(observer, ¬ifier->observers, list_entry) { | ||
| free_observer(observer); | ||
| } | ||
| DWC_FREE(notifier); | ||
| } | ||
|
|
||
| static notifier_t *find_notifier(void *object) | ||
| { | ||
| notifier_t *notifier; | ||
| if (!object) { | ||
| return NULL; | ||
| } | ||
| DWC_ASSERT(manager, "Notification manager not found"); | ||
| DWC_CIRCLEQ_FOREACH(notifier, &manager->notifiers, list_entry) { | ||
| if (notifier->object == object) { | ||
| return notifier; | ||
| } | ||
| } | ||
| return NULL; | ||
| } | ||
|
|
||
| void dwc_alloc_notification_manager(void) | ||
| { | ||
| create_manager(); | ||
| } | ||
|
|
||
| void dwc_free_notification_manager(void) | ||
| { | ||
| free_manager(); | ||
| } | ||
|
|
||
| dwc_notifier_t *dwc_register_notifier(void *object) | ||
| { | ||
| notifier_t *notifier = find_notifier(object); | ||
| DWC_ASSERT(manager, "Notification manager not found"); | ||
| if (notifier) { | ||
| DWC_ERROR("Notifier %p is already registered", object); | ||
| return NULL; | ||
| } | ||
|
|
||
| notifier = alloc_notifier(object); | ||
| DWC_CIRCLEQ_INSERT_TAIL(&manager->notifiers, notifier, list_entry); | ||
|
|
||
|
|
||
| DWC_INFO("Notifier %p registered", object); | ||
| dump_manager(); | ||
|
|
||
| return notifier; | ||
| } | ||
|
|
||
| void dwc_unregister_notifier(dwc_notifier_t *notifier) | ||
| { | ||
| DWC_ASSERT(manager, "Notification manager not found"); | ||
| if (!DWC_CIRCLEQ_EMPTY(¬ifier->observers)) { | ||
| observer_t *o; | ||
| DWC_ERROR("Notifier %p has active observers when removing", notifier->object); | ||
| DWC_CIRCLEQ_FOREACH(o, ¬ifier->observers, list_entry) { | ||
| DWC_DEBUG(" %p watching %s", o->observer, o->notification); | ||
| } | ||
| DWC_ASSERT(DWC_CIRCLEQ_EMPTY(¬ifier->observers), "Notifier %p has active observers when removing", notifier); | ||
| } | ||
|
|
||
| DWC_CIRCLEQ_REMOVE_INIT(&manager->notifiers, notifier, list_entry); | ||
| free_notifier(notifier); | ||
|
|
||
| DWC_INFO("Notifier unregistered"); | ||
| dump_manager(); | ||
| } | ||
|
|
||
| /* Add an observer to observe the notifier for a particular state, event, or notification. */ | ||
| int dwc_add_observer(void *observer, void *object, char *notification, dwc_notifier_callback_t callback, void *data) | ||
| { | ||
| notifier_t *notifier = find_notifier(object); | ||
| observer_t *new_observer; | ||
| if (!notifier) { | ||
| DWC_ERROR("Notifier %p is not found when adding observer", object); | ||
| return -1; | ||
| } | ||
|
|
||
| new_observer = alloc_observer(observer, notification, callback, data); | ||
|
|
||
| DWC_CIRCLEQ_INSERT_TAIL(¬ifier->observers, new_observer, list_entry); | ||
|
|
||
| DWC_INFO("Added observer %p to notifier %p observing notification %s, callback=%p, data=%p", | ||
| observer, object, notification, callback, data); | ||
|
|
||
| dump_manager(); | ||
| return 0; | ||
| } | ||
|
|
||
| int dwc_remove_observer(void *observer) | ||
| { | ||
| notifier_t *n; | ||
| DWC_ASSERT(manager, "Notification manager not found"); | ||
| DWC_CIRCLEQ_FOREACH(n, &manager->notifiers, list_entry) { | ||
| observer_t *o; | ||
| observer_t *o2; | ||
| DWC_CIRCLEQ_FOREACH_SAFE(o, o2, &n->observers, list_entry) { | ||
| if (o->observer == observer) { | ||
| DWC_CIRCLEQ_REMOVE_INIT(&n->observers, o, list_entry); | ||
| DWC_INFO("Removing observer %p from notifier %p watching notification %s:", | ||
| o->observer, n->object, o->notification); | ||
| free_observer(o); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| dump_manager(); | ||
| return 0; | ||
| } | ||
|
|
||
| typedef struct callback_data | ||
| { | ||
| dwc_notifier_callback_t cb; | ||
| void *observer; | ||
| void *data; | ||
| void *object; | ||
| void *notification; | ||
| void *notification_data; | ||
| } cb_data_t; | ||
|
|
||
| static void cb_task(void *data) | ||
| { | ||
| cb_data_t *cb = (cb_data_t *)data; | ||
| cb->cb(cb->object, cb->notification, cb->observer, cb->notification_data, cb->data); | ||
| DWC_FREE(cb); | ||
| } | ||
|
|
||
| void dwc_notify(dwc_notifier_t *notifier, char *notification, void *notification_data) | ||
| { | ||
| observer_t *o; | ||
| DWC_ASSERT(manager, "Notification manager not found"); | ||
| DWC_CIRCLEQ_FOREACH(o, ¬ifier->observers, list_entry) { | ||
| int len = DWC_STRLEN(notification); | ||
| if (DWC_STRLEN(o->notification) != len) { | ||
| continue; | ||
| } | ||
|
|
||
| if (DWC_STRNCMP(o->notification, notification, len) == 0) { | ||
| cb_data_t *cb_data = DWC_ALLOC(sizeof(cb_data_t)); | ||
| cb_data->cb = o->callback; | ||
| cb_data->observer = o->observer; | ||
| cb_data->data = o->data; | ||
| cb_data->object = notifier->object; | ||
| cb_data->notification = notification; | ||
| cb_data->notification_data = notification_data; | ||
| DWC_DEBUG("Observer found %p for notification %s", o->observer, notification); | ||
| DWC_WORKQ_SCHEDULE(manager->wq, cb_task, cb_data, | ||
| "Notify callback from %p for Notification %s, to observer %p", | ||
| cb_data->object, notification, cb_data->observer); | ||
| } | ||
| } | ||
| } | ||
|
|
| @@ -0,0 +1,112 @@ | ||
|
|
||
| #ifndef __DWC_NOTIFIER_H__ | ||
| #define __DWC_NOTIFIER_H__ | ||
|
|
||
| #include "dwc_os.h" | ||
|
|
||
| /** @file | ||
| * | ||
| * A simple implementation of the Observer pattern. Any "module" can | ||
| * register as an observer or notifier. The notion of "module" is abstract and | ||
| * can mean anything used to identify either an observer or notifier. Usually | ||
| * it will be a pointer to a data structure which contains some state, ie an | ||
| * object. | ||
| * | ||
| * Before any notifiers can be added, the global notification manager must be | ||
| * brought up with dwc_alloc_notification_manager(). | ||
| * dwc_free_notification_manager() will bring it down and free all resources. | ||
| * These would typically be called upon module load and unload. The | ||
| * notification manager is a single global instance that handles all registered | ||
| * observable modules and observers so this should be done only once. | ||
| * | ||
| * A module can be observable by using Notifications to publicize some general | ||
| * information about it's state or operation. It does not care who listens, or | ||
| * even if anyone listens, or what they do with the information. The observable | ||
| * modules do not need to know any information about it's observers or their | ||
| * interface, or their state or data. | ||
| * | ||
| * Any module can register to emit Notifications. It should publish a list of | ||
| * notifications that it can emit and their behavior, such as when they will get | ||
| * triggered, and what information will be provided to the observer. Then it | ||
| * should register itself as an observable module. See dwc_register_notifier(). | ||
| * | ||
| * Any module can observe any observable, registered module, provided it has a | ||
| * handle to the other module and knows what notifications to observe. See | ||
| * dwc_add_observer(). | ||
| * | ||
| * A function of type dwc_notifier_callback_t is called whenever a notification | ||
| * is triggered with one or more observers observing it. This function is | ||
| * called in it's own process so it may sleep or block if needed. It is | ||
| * guaranteed to be called sometime after the notification has occurred and will | ||
| * be called once per each time the notification is triggered. It will NOT be | ||
| * called in the same process context used to trigger the notification. | ||
| * | ||
| * @section Limitiations | ||
| * | ||
| * Keep in mind that Notifications that can be triggered in rapid sucession may | ||
| * schedule too many processes too handle. Be aware of this limitation when | ||
| * designing to use notifications, and only add notifications for appropriate | ||
| * observable information. | ||
| * | ||
| * Also Notification callbacks are not synchronous. If you need to synchronize | ||
| * the behavior between module/observer you must use other means. And perhaps | ||
| * that will mean Notifications are not the proper solution. | ||
| */ | ||
|
|
||
| struct dwc_notifier; | ||
| typedef struct dwc_notifier dwc_notifier_t; | ||
|
|
||
| /** The callback function must be of this type. | ||
| * | ||
| * @param object This is the object that is being observed. | ||
| * @param notification This is the notification that was triggered. | ||
| * @param observer This is the observer | ||
| * @param notification_data This is notification-specific data that the notifier | ||
| * has included in this notification. The value of this should be published in | ||
| * the documentation of the observable module with the notifications. | ||
| * @param user_data This is any custom data that the observer provided when | ||
| * adding itself as an observer to the notification. */ | ||
| typedef void (*dwc_notifier_callback_t)(void *object, char *notification, void *observer, void *notification_data, void *user_data); | ||
|
|
||
| /** Brings up the notification manager. */ | ||
| extern void dwc_alloc_notification_manager(void); | ||
| /** Brings down the notification manager. */ | ||
| extern void dwc_free_notification_manager(void); | ||
|
|
||
| /** This function register an observable module. A dwc_notifier_t object is | ||
| * returned to the observable module. This is an opaque object that is used by | ||
| * the observable module to trigger notifications. This object should only be | ||
| * accessible to functions that are authorized to trigger notifications for this | ||
| * module. Observers do not need this object. */ | ||
| extern dwc_notifier_t *dwc_register_notifier(void *object); | ||
|
|
||
| /** This function unregister an observable module. All observers have to be | ||
| * removed prior to unregistration. */ | ||
| extern void dwc_unregister_notifier(dwc_notifier_t *notifier); | ||
|
|
||
| /** Add a module as an observer to the observable module. The observable module | ||
| * needs to have previously registered with the notification manager. | ||
| * | ||
| * @param observer The observer module | ||
| * @param object The module to observe | ||
| * @param notification The notification to observe | ||
| * @param callback The callback function to call | ||
| * @param user_data Any additional user data to pass into the callback function */ | ||
| extern int dwc_add_observer(void *observer, void *object, char *notification, dwc_notifier_callback_t callback, void *user_data); | ||
|
|
||
| /** Removes the specified observer from all notifications that it is currently | ||
| * observing. */ | ||
| extern int dwc_remove_observer(void *observer); | ||
|
|
||
| /** This function triggers a Notification. It should be called by the | ||
| * observable module, or any module or library which the observable module | ||
| * allows to trigger notification on it's behalf. Such as the dwc_cc_t. | ||
| * | ||
| * dwc_notify is a non-blocking function. Callbacks are scheduled called in | ||
| * their own process context for each trigger. Callbacks can be blocking. | ||
| * dwc_notify can be called from interrupt context if needed. | ||
| * | ||
| */ | ||
| void dwc_notify(dwc_notifier_t *notifier, char *notification, void *notification_data); | ||
|
|
||
| #endif /* __DWC_NOTIFIER_H__ */ |
| @@ -0,0 +1,78 @@ | ||
| # | ||
| # Makefile for DWC_otg Highspeed USB controller driver | ||
| # | ||
|
|
||
| ifneq ($(KERNELRELEASE),) | ||
|
|
||
| ifeq ($(BUS_INTERFACE),) | ||
| # BUS_INTERFACE = -DLM_INTERFACE | ||
| BUS_INTERFACE = -DPLATFORM_INTERFACE=1 | ||
| endif | ||
|
|
||
| CPPFLAGS += -DDEBUG | ||
|
|
||
| # Use one of the following flags to compile the software in host-only or | ||
| # device-only mode. | ||
| #CPPFLAGS += -DDWC_HOST_ONLY | ||
| #CPPFLAGS += -DDWC_DEVICE_ONLY | ||
|
|
||
| CPPFLAGS += -Dlinux -DDWC_HS_ELECT_TST | ||
| #CGG: CPPFLAGS += -DDWC_EN_ISOC | ||
| CPPFLAGS += -I$(obj)/../dwc_common_port | ||
| #CPPFLAGS += -I$(PORTLIB) | ||
| CPPFLAGS += -DDWC_LINUX | ||
| CPPFLAGS += $(CFI) | ||
| CPPFLAGS += $(BUS_INTERFACE) | ||
|
|
||
| obj-$(CONFIG_USB_DWCOTG) += dwc_otg.o | ||
|
|
||
| dwc_otg-objs := dwc_otg_driver.o dwc_otg_attr.o | ||
| dwc_otg-objs += dwc_otg_cil.o dwc_otg_cil_intr.o | ||
| dwc_otg-objs += dwc_otg_pcd_linux.o dwc_otg_pcd.o dwc_otg_pcd_intr.o | ||
| dwc_otg-objs += dwc_otg_hcd.o dwc_otg_hcd_linux.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o dwc_otg_hcd_ddma.o | ||
| ifneq ($(CFI),) | ||
| dwc_otg-objs += dwc_otg_cfi.o | ||
| endif | ||
|
|
||
| kernrelwd := $(subst ., ,$(KERNELRELEASE)) | ||
| kernrel3 := $(word 1,$(kernrelwd)).$(word 2,$(kernrelwd)).$(word 3,$(kernrelwd)) | ||
|
|
||
| ifneq ($(kernrel3),2.6.20) | ||
| EXTRA_CFLAGS += $(CPPFLAGS) | ||
| endif | ||
|
|
||
| else | ||
|
|
||
| PWD := $(shell pwd) | ||
| PORTLIB := $(PWD)/../dwc_common_port | ||
|
|
||
| # Command paths | ||
| CTAGS := $(CTAGS) | ||
| DOXYGEN := $(DOXYGEN) | ||
|
|
||
| default: portlib | ||
| $(MAKE) -C$(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules | ||
|
|
||
| install: default | ||
| ifneq ($(INSTALL_MOD_PATH),) | ||
| $(MAKE) -C$(KDIR) M=$(PORTLIB) modules_install | ||
| $(MAKE) -C$(KDIR) M=$(PWD) modules_install | ||
| else | ||
| @echo "No install path defined" | ||
| endif | ||
|
|
||
| portlib: | ||
| $(MAKE) -C$(KDIR) M=$(PORTLIB) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules | ||
| cp $(PORTLIB)/Module.symvers $(PWD)/ | ||
|
|
||
| docs: $(wildcard *.[hc]) doc/doxygen.cfg | ||
| $(DOXYGEN) doc/doxygen.cfg | ||
|
|
||
| tags: $(wildcard *.[hc]) | ||
| $(CTAGS) -e $(wildcard *.[hc]) $(wildcard linux/*.[hc]) $(wildcard $(KDIR)/include/linux/usb*.h) | ||
|
|
||
|
|
||
| clean: | ||
| rm -rf *.o *.ko .*cmd *.mod.c .tmp_versions | ||
|
|
||
| endif |
| @@ -0,0 +1,224 @@ | ||
| # Doxyfile 1.3.9.1 | ||
|
|
||
| #--------------------------------------------------------------------------- | ||
| # Project related configuration options | ||
| #--------------------------------------------------------------------------- | ||
| PROJECT_NAME = "DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver" | ||
| PROJECT_NUMBER = v2.90a | ||
| OUTPUT_DIRECTORY = ./doc/ | ||
| CREATE_SUBDIRS = NO | ||
| OUTPUT_LANGUAGE = English | ||
| BRIEF_MEMBER_DESC = YES | ||
| REPEAT_BRIEF = YES | ||
| ABBREVIATE_BRIEF = "The $name class" \ | ||
| "The $name widget" \ | ||
| "The $name file" \ | ||
| is \ | ||
| provides \ | ||
| specifies \ | ||
| contains \ | ||
| represents \ | ||
| a \ | ||
| an \ | ||
| the | ||
| ALWAYS_DETAILED_SEC = NO | ||
| INLINE_INHERITED_MEMB = NO | ||
| FULL_PATH_NAMES = NO | ||
| STRIP_FROM_PATH = | ||
| STRIP_FROM_INC_PATH = | ||
| SHORT_NAMES = NO | ||
| JAVADOC_AUTOBRIEF = YES | ||
| MULTILINE_CPP_IS_BRIEF = NO | ||
| INHERIT_DOCS = YES | ||
| DISTRIBUTE_GROUP_DOC = NO | ||
| TAB_SIZE = 8 | ||
| ALIASES = | ||
| OPTIMIZE_OUTPUT_FOR_C = YES | ||
| OPTIMIZE_OUTPUT_JAVA = NO | ||
| SUBGROUPING = YES | ||
| #--------------------------------------------------------------------------- | ||
| # Build related configuration options | ||
| #--------------------------------------------------------------------------- | ||
| EXTRACT_ALL = NO | ||
| EXTRACT_PRIVATE = YES | ||
| EXTRACT_STATIC = YES | ||
| EXTRACT_LOCAL_CLASSES = YES | ||
| EXTRACT_LOCAL_METHODS = NO | ||
| HIDE_UNDOC_MEMBERS = NO | ||
| HIDE_UNDOC_CLASSES = NO | ||
| HIDE_FRIEND_COMPOUNDS = NO | ||
| HIDE_IN_BODY_DOCS = NO | ||
| INTERNAL_DOCS = NO | ||
| CASE_SENSE_NAMES = NO | ||
| HIDE_SCOPE_NAMES = NO | ||
| SHOW_INCLUDE_FILES = YES | ||
| INLINE_INFO = YES | ||
| SORT_MEMBER_DOCS = NO | ||
| SORT_BRIEF_DOCS = NO | ||
| SORT_BY_SCOPE_NAME = NO | ||
| GENERATE_TODOLIST = YES | ||
| GENERATE_TESTLIST = YES | ||
| GENERATE_BUGLIST = YES | ||
| GENERATE_DEPRECATEDLIST= YES | ||
| ENABLED_SECTIONS = | ||
| MAX_INITIALIZER_LINES = 30 | ||
| SHOW_USED_FILES = YES | ||
| SHOW_DIRECTORIES = YES | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to warning and progress messages | ||
| #--------------------------------------------------------------------------- | ||
| QUIET = YES | ||
| WARNINGS = YES | ||
| WARN_IF_UNDOCUMENTED = NO | ||
| WARN_IF_DOC_ERROR = YES | ||
| WARN_FORMAT = "$file:$line: $text" | ||
| WARN_LOGFILE = | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to the input files | ||
| #--------------------------------------------------------------------------- | ||
| INPUT = . | ||
| FILE_PATTERNS = *.c \ | ||
| *.h \ | ||
| ./linux/*.c \ | ||
| ./linux/*.h | ||
| RECURSIVE = NO | ||
| EXCLUDE = ./test/ \ | ||
| ./dwc_otg/.AppleDouble/ | ||
| EXCLUDE_SYMLINKS = YES | ||
| EXCLUDE_PATTERNS = *.mod.* | ||
| EXAMPLE_PATH = | ||
| EXAMPLE_PATTERNS = * | ||
| EXAMPLE_RECURSIVE = NO | ||
| IMAGE_PATH = | ||
| INPUT_FILTER = | ||
| FILTER_PATTERNS = | ||
| FILTER_SOURCE_FILES = NO | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to source browsing | ||
| #--------------------------------------------------------------------------- | ||
| SOURCE_BROWSER = YES | ||
| INLINE_SOURCES = NO | ||
| STRIP_CODE_COMMENTS = YES | ||
| REFERENCED_BY_RELATION = NO | ||
| REFERENCES_RELATION = NO | ||
| VERBATIM_HEADERS = NO | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to the alphabetical class index | ||
| #--------------------------------------------------------------------------- | ||
| ALPHABETICAL_INDEX = NO | ||
| COLS_IN_ALPHA_INDEX = 5 | ||
| IGNORE_PREFIX = | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to the HTML output | ||
| #--------------------------------------------------------------------------- | ||
| GENERATE_HTML = YES | ||
| HTML_OUTPUT = html | ||
| HTML_FILE_EXTENSION = .html | ||
| HTML_HEADER = | ||
| HTML_FOOTER = | ||
| HTML_STYLESHEET = | ||
| HTML_ALIGN_MEMBERS = YES | ||
| GENERATE_HTMLHELP = NO | ||
| CHM_FILE = | ||
| HHC_LOCATION = | ||
| GENERATE_CHI = NO | ||
| BINARY_TOC = NO | ||
| TOC_EXPAND = NO | ||
| DISABLE_INDEX = NO | ||
| ENUM_VALUES_PER_LINE = 4 | ||
| GENERATE_TREEVIEW = YES | ||
| TREEVIEW_WIDTH = 250 | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to the LaTeX output | ||
| #--------------------------------------------------------------------------- | ||
| GENERATE_LATEX = NO | ||
| LATEX_OUTPUT = latex | ||
| LATEX_CMD_NAME = latex | ||
| MAKEINDEX_CMD_NAME = makeindex | ||
| COMPACT_LATEX = NO | ||
| PAPER_TYPE = a4wide | ||
| EXTRA_PACKAGES = | ||
| LATEX_HEADER = | ||
| PDF_HYPERLINKS = NO | ||
| USE_PDFLATEX = NO | ||
| LATEX_BATCHMODE = NO | ||
| LATEX_HIDE_INDICES = NO | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to the RTF output | ||
| #--------------------------------------------------------------------------- | ||
| GENERATE_RTF = NO | ||
| RTF_OUTPUT = rtf | ||
| COMPACT_RTF = NO | ||
| RTF_HYPERLINKS = NO | ||
| RTF_STYLESHEET_FILE = | ||
| RTF_EXTENSIONS_FILE = | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to the man page output | ||
| #--------------------------------------------------------------------------- | ||
| GENERATE_MAN = NO | ||
| MAN_OUTPUT = man | ||
| MAN_EXTENSION = .3 | ||
| MAN_LINKS = NO | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to the XML output | ||
| #--------------------------------------------------------------------------- | ||
| GENERATE_XML = NO | ||
| XML_OUTPUT = xml | ||
| XML_SCHEMA = | ||
| XML_DTD = | ||
| XML_PROGRAMLISTING = YES | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options for the AutoGen Definitions output | ||
| #--------------------------------------------------------------------------- | ||
| GENERATE_AUTOGEN_DEF = NO | ||
| #--------------------------------------------------------------------------- | ||
| # configuration options related to the Perl module output | ||
| #--------------------------------------------------------------------------- | ||
| GENERATE_PERLMOD = NO | ||
| PERLMOD_LATEX = NO | ||
| PERLMOD_PRETTY = YES | ||
| PERLMOD_MAKEVAR_PREFIX = | ||
| #--------------------------------------------------------------------------- | ||
| # Configuration options related to the preprocessor | ||
| #--------------------------------------------------------------------------- | ||
| ENABLE_PREPROCESSING = YES | ||
| MACRO_EXPANSION = YES | ||
| EXPAND_ONLY_PREDEF = YES | ||
| SEARCH_INCLUDES = YES | ||
| INCLUDE_PATH = | ||
| INCLUDE_FILE_PATTERNS = | ||
| PREDEFINED = DEVICE_ATTR DWC_EN_ISOC | ||
| EXPAND_AS_DEFINED = DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW DWC_OTG_DEVICE_ATTR_BITFIELD_STORE DWC_OTG_DEVICE_ATTR_BITFIELD_RW DWC_OTG_DEVICE_ATTR_BITFIELD_RO DWC_OTG_DEVICE_ATTR_REG_SHOW DWC_OTG_DEVICE_ATTR_REG_STORE DWC_OTG_DEVICE_ATTR_REG32_RW DWC_OTG_DEVICE_ATTR_REG32_RO DWC_EN_ISOC | ||
| SKIP_FUNCTION_MACROS = NO | ||
| #--------------------------------------------------------------------------- | ||
| # Configuration::additions related to external references | ||
| #--------------------------------------------------------------------------- | ||
| TAGFILES = | ||
| GENERATE_TAGFILE = | ||
| ALLEXTERNALS = NO | ||
| EXTERNAL_GROUPS = YES | ||
| PERL_PATH = /usr/bin/perl | ||
| #--------------------------------------------------------------------------- | ||
| # Configuration options related to the dot tool | ||
| #--------------------------------------------------------------------------- | ||
| CLASS_DIAGRAMS = YES | ||
| HIDE_UNDOC_RELATIONS = YES | ||
| HAVE_DOT = NO | ||
| CLASS_GRAPH = YES | ||
| COLLABORATION_GRAPH = YES | ||
| UML_LOOK = NO | ||
| TEMPLATE_RELATIONS = NO | ||
| INCLUDE_GRAPH = YES | ||
| INCLUDED_BY_GRAPH = YES | ||
| CALL_GRAPH = NO | ||
| GRAPHICAL_HIERARCHY = YES | ||
| DOT_IMAGE_FORMAT = png | ||
| DOT_PATH = | ||
| DOTFILE_DIRS = | ||
| MAX_DOT_GRAPH_DEPTH = 1000 | ||
| GENERATE_LEGEND = YES | ||
| DOT_CLEANUP = YES | ||
| #--------------------------------------------------------------------------- | ||
| # Configuration::additions related to the search engine | ||
| #--------------------------------------------------------------------------- | ||
| SEARCHENGINE = NO |
| @@ -0,0 +1,358 @@ | ||
| BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { | ||
| font-family: Geneva, Arial, Helvetica, sans-serif; | ||
| } | ||
| BODY,TD { | ||
| font-size: 90%; | ||
| } | ||
| H1 { | ||
| text-align: center; | ||
| font-size: 160%; | ||
| } | ||
| H2 { | ||
| font-size: 120%; | ||
| } | ||
| H3 { | ||
| font-size: 100%; | ||
| } | ||
| CAPTION { font-weight: bold } | ||
| DIV.qindex { | ||
| width: 100%; | ||
| background-color: #e8eef2; | ||
| border: 1px solid #84b0c7; | ||
| text-align: center; | ||
| margin: 2px; | ||
| padding: 2px; | ||
| line-height: 140%; | ||
| } | ||
| DIV.nav { | ||
| width: 100%; | ||
| background-color: #e8eef2; | ||
| border: 1px solid #84b0c7; | ||
| text-align: center; | ||
| margin: 2px; | ||
| padding: 2px; | ||
| line-height: 140%; | ||
| } | ||
| DIV.navtab { | ||
| background-color: #e8eef2; | ||
| border: 1px solid #84b0c7; | ||
| text-align: center; | ||
| margin: 2px; | ||
| margin-right: 15px; | ||
| padding: 2px; | ||
| } | ||
| TD.navtab { | ||
| font-size: 70%; | ||
| } | ||
| A.qindex { | ||
| text-decoration: none; | ||
| font-weight: bold; | ||
| color: #1A419D; | ||
| } | ||
| A.qindex:visited { | ||
| text-decoration: none; | ||
| font-weight: bold; | ||
| color: #1A419D | ||
| } | ||
| A.qindex:hover { | ||
| text-decoration: none; | ||
| background-color: #ddddff; | ||
| } | ||
| A.qindexHL { | ||
| text-decoration: none; | ||
| font-weight: bold; | ||
| background-color: #6666cc; | ||
| color: #ffffff; | ||
| border: 1px double #9295C2; | ||
| } | ||
| A.qindexHL:hover { | ||
| text-decoration: none; | ||
| background-color: #6666cc; | ||
| color: #ffffff; | ||
| } | ||
| A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } | ||
| A.el { text-decoration: none; font-weight: bold } | ||
| A.elRef { font-weight: bold } | ||
| A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} | ||
| A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} | ||
| A.codeRef:link { font-weight: normal; color: #0000FF} | ||
| A.codeRef:visited { font-weight: normal; color: #0000FF} | ||
| A:hover { text-decoration: none; background-color: #f2f2ff } | ||
| DL.el { margin-left: -1cm } | ||
| .fragment { | ||
| font-family: monospace, fixed; | ||
| font-size: 95%; | ||
| } | ||
| PRE.fragment { | ||
| border: 1px solid #CCCCCC; | ||
| background-color: #f5f5f5; | ||
| margin-top: 4px; | ||
| margin-bottom: 4px; | ||
| margin-left: 2px; | ||
| margin-right: 8px; | ||
| padding-left: 6px; | ||
| padding-right: 6px; | ||
| padding-top: 4px; | ||
| padding-bottom: 4px; | ||
| } | ||
| DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } | ||
|
|
||
| DIV.groupHeader { | ||
| margin-left: 16px; | ||
| margin-top: 12px; | ||
| margin-bottom: 6px; | ||
| font-weight: bold; | ||
| } | ||
| DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } | ||
| BODY { | ||
| background: white; | ||
| color: black; | ||
| margin-right: 20px; | ||
| margin-left: 20px; | ||
| } | ||
| TD.indexkey { | ||
| background-color: #e8eef2; | ||
| font-weight: bold; | ||
| padding-right : 10px; | ||
| padding-top : 2px; | ||
| padding-left : 10px; | ||
| padding-bottom : 2px; | ||
| margin-left : 0px; | ||
| margin-right : 0px; | ||
| margin-top : 2px; | ||
| margin-bottom : 2px; | ||
| border: 1px solid #CCCCCC; | ||
| } | ||
| TD.indexvalue { | ||
| background-color: #e8eef2; | ||
| font-style: italic; | ||
| padding-right : 10px; | ||
| padding-top : 2px; | ||
| padding-left : 10px; | ||
| padding-bottom : 2px; | ||
| margin-left : 0px; | ||
| margin-right : 0px; | ||
| margin-top : 2px; | ||
| margin-bottom : 2px; | ||
| border: 1px solid #CCCCCC; | ||
| } | ||
| TR.memlist { | ||
| background-color: #f0f0f0; | ||
| } | ||
| P.formulaDsp { text-align: center; } | ||
| IMG.formulaDsp { } | ||
| IMG.formulaInl { vertical-align: middle; } | ||
| SPAN.keyword { color: #008000 } | ||
| SPAN.keywordtype { color: #604020 } | ||
| SPAN.keywordflow { color: #e08000 } | ||
| SPAN.comment { color: #800000 } | ||
| SPAN.preprocessor { color: #806020 } | ||
| SPAN.stringliteral { color: #002080 } | ||
| SPAN.charliteral { color: #008080 } | ||
| .mdescLeft { | ||
| padding: 0px 8px 4px 8px; | ||
| font-size: 80%; | ||
| font-style: italic; | ||
| background-color: #FAFAFA; | ||
| border-top: 1px none #E0E0E0; | ||
| border-right: 1px none #E0E0E0; | ||
| border-bottom: 1px none #E0E0E0; | ||
| border-left: 1px none #E0E0E0; | ||
| margin: 0px; | ||
| } | ||
| .mdescRight { | ||
| padding: 0px 8px 4px 8px; | ||
| font-size: 80%; | ||
| font-style: italic; | ||
| background-color: #FAFAFA; | ||
| border-top: 1px none #E0E0E0; | ||
| border-right: 1px none #E0E0E0; | ||
| border-bottom: 1px none #E0E0E0; | ||
| border-left: 1px none #E0E0E0; | ||
| margin: 0px; | ||
| } | ||
| .memItemLeft { | ||
| padding: 1px 0px 0px 8px; | ||
| margin: 4px; | ||
| border-top-width: 1px; | ||
| border-right-width: 1px; | ||
| border-bottom-width: 1px; | ||
| border-left-width: 1px; | ||
| border-top-color: #E0E0E0; | ||
| border-right-color: #E0E0E0; | ||
| border-bottom-color: #E0E0E0; | ||
| border-left-color: #E0E0E0; | ||
| border-top-style: solid; | ||
| border-right-style: none; | ||
| border-bottom-style: none; | ||
| border-left-style: none; | ||
| background-color: #FAFAFA; | ||
| font-size: 80%; | ||
| } | ||
| .memItemRight { | ||
| padding: 1px 8px 0px 8px; | ||
| margin: 4px; | ||
| border-top-width: 1px; | ||
| border-right-width: 1px; | ||
| border-bottom-width: 1px; | ||
| border-left-width: 1px; | ||
| border-top-color: #E0E0E0; | ||
| border-right-color: #E0E0E0; | ||
| border-bottom-color: #E0E0E0; | ||
| border-left-color: #E0E0E0; | ||
| border-top-style: solid; | ||
| border-right-style: none; | ||
| border-bottom-style: none; | ||
| border-left-style: none; | ||
| background-color: #FAFAFA; | ||
| font-size: 80%; | ||
| } | ||
| .memTemplItemLeft { | ||
| padding: 1px 0px 0px 8px; | ||
| margin: 4px; | ||
| border-top-width: 1px; | ||
| border-right-width: 1px; | ||
| border-bottom-width: 1px; | ||
| border-left-width: 1px; | ||
| border-top-color: #E0E0E0; | ||
| border-right-color: #E0E0E0; | ||
| border-bottom-color: #E0E0E0; | ||
| border-left-color: #E0E0E0; | ||
| border-top-style: none; | ||
| border-right-style: none; | ||
| border-bottom-style: none; | ||
| border-left-style: none; | ||
| background-color: #FAFAFA; | ||
| font-size: 80%; | ||
| } | ||
| .memTemplItemRight { | ||
| padding: 1px 8px 0px 8px; | ||
| margin: 4px; | ||
| border-top-width: 1px; | ||
| border-right-width: 1px; | ||
| border-bottom-width: 1px; | ||
| border-left-width: 1px; | ||
| border-top-color: #E0E0E0; | ||
| border-right-color: #E0E0E0; | ||
| border-bottom-color: #E0E0E0; | ||
| border-left-color: #E0E0E0; | ||
| border-top-style: none; | ||
| border-right-style: none; | ||
| border-bottom-style: none; | ||
| border-left-style: none; | ||
| background-color: #FAFAFA; | ||
| font-size: 80%; | ||
| } | ||
| .memTemplParams { | ||
| padding: 1px 0px 0px 8px; | ||
| margin: 4px; | ||
| border-top-width: 1px; | ||
| border-right-width: 1px; | ||
| border-bottom-width: 1px; | ||
| border-left-width: 1px; | ||
| border-top-color: #E0E0E0; | ||
| border-right-color: #E0E0E0; | ||
| border-bottom-color: #E0E0E0; | ||
| border-left-color: #E0E0E0; | ||
| border-top-style: solid; | ||
| border-right-style: none; | ||
| border-bottom-style: none; | ||
| border-left-style: none; | ||
| color: #606060; | ||
| background-color: #FAFAFA; | ||
| font-size: 80%; | ||
| } | ||
| .search { color: #003399; | ||
| font-weight: bold; | ||
| } | ||
| FORM.search { | ||
| margin-bottom: 0px; | ||
| margin-top: 0px; | ||
| } | ||
| INPUT.search { font-size: 75%; | ||
| color: #000080; | ||
| font-weight: normal; | ||
| background-color: #e8eef2; | ||
| } | ||
| TD.tiny { font-size: 75%; | ||
| } | ||
| a { | ||
| color: #1A41A8; | ||
| } | ||
| a:visited { | ||
| color: #2A3798; | ||
| } | ||
| .dirtab { padding: 4px; | ||
| border-collapse: collapse; | ||
| border: 1px solid #84b0c7; | ||
| } | ||
| TH.dirtab { background: #e8eef2; | ||
| font-weight: bold; | ||
| } | ||
| HR { height: 1px; | ||
| border: none; | ||
| border-top: 1px solid black; | ||
| } | ||
|
|
||
| /* Style for detailed member documentation */ | ||
| .memtemplate { | ||
| font-size: 80%; | ||
| color: #606060; | ||
| font-weight: normal; | ||
| } | ||
| .memnav { | ||
| background-color: #e8eef2; | ||
| border: 1px solid #84b0c7; | ||
| text-align: center; | ||
| margin: 2px; | ||
| margin-right: 15px; | ||
| padding: 2px; | ||
| } | ||
| .memitem { | ||
| padding: 4px; | ||
| background-color: #eef3f5; | ||
| border-width: 1px; | ||
| border-style: solid; | ||
| border-color: #dedeee; | ||
| -moz-border-radius: 8px 8px 8px 8px; | ||
| } | ||
| .memname { | ||
| white-space: nowrap; | ||
| font-weight: bold; | ||
| } | ||
| .memdoc{ | ||
| padding-left: 10px; | ||
| } | ||
| .memproto { | ||
| background-color: #d5e1e8; | ||
| width: 100%; | ||
| border-width: 1px; | ||
| border-style: solid; | ||
| border-color: #84b0c7; | ||
| font-weight: bold; | ||
| -moz-border-radius: 8px 8px 8px 8px; | ||
| } | ||
| .paramkey { | ||
| text-align: right; | ||
| } | ||
| .paramtype { | ||
| white-space: nowrap; | ||
| } | ||
| .paramname { | ||
| color: #602020; | ||
| font-style: italic; | ||
| } | ||
| /* End Styling for detailed member documentation */ | ||
|
|
||
| /* for the tree view */ | ||
| .ftvtree { | ||
| font-family: sans-serif; | ||
| margin:0.5em; | ||
| } | ||
| .directory { font-size: 9pt; font-weight: bold; } | ||
| .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } | ||
| .directory > h3 { margin-top: 0; } | ||
| .directory p { margin: 0px; white-space: nowrap; } | ||
| .directory div { display: none; margin: 0px; } | ||
| .directory img { vertical-align: -30%; } | ||
|
|