コード例 #1
0
static int checkInfoElement(tAuthRsnFsm *fsm,
                            tAniEapolKeyAvailEventData *data)
{
    tAniEapolRsnKeyDesc *desc;
    v_U8_t *ieStaBytes;
    int ieStaLen;

    desc = (tAniEapolRsnKeyDesc *) data->keyDesc;
    if( desc )
    {
        ieStaLen = aniAsfPacketGetBytes(fsm->staCtx->ieSta, &ieStaBytes);
        if( !ANI_IS_STATUS_SUCCESS( ieStaLen ) )
        {
            return ieStaLen;
        }

        if ((desc->keyDataLen != ieStaLen) ||
            ( !vos_mem_compare(desc->keyData, ieStaBytes, ieStaLen-2) )) 
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                         "Auth STA sent inconsistent RSN IE!\n");
            return ANI_E_FAILED;
        }
        // Copy RSN IE
        //vos_mem_copy(fsm->advertizedRsnIe, desc->keyData, ieStaLen);
        vos_mem_copy(fsm->advertizedRsnIe, ieStaBytes, ieStaLen);

        return ANI_OK;
    }
    else
    {
        return ANI_E_NULL_VALUE;
    }

}
static int checkInfoElement(tSuppRsnFsm *fsm,
                            tAniEapolKeyAvailEventData *data)
{
    tAniEapolRsnKeyDesc *desc;
    v_U8_t *ieApBytes;
    int ieApLen;

    desc = (tAniEapolRsnKeyDesc *) data->keyDesc;
    if( NULL == desc )
    {
        return ANI_E_NULL_VALUE;
    }

    ieApLen = aniAsfPacketGetBytes(fsm->suppCtx->ieAp, &ieApBytes);
    if( ANI_IS_STATUS_SUCCESS( ieApLen ) )
    {

        if ((desc->keyDataLen != ieApLen) ||
            ( vos_mem_compare(desc->keyData, ieApBytes, ieApLen) )) 
        {
            // TODO: Send a fault here
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, 
                         "Supp AP sent inconsistent RSN IE!\n" );
            return ANI_E_FAILED;
        }
    }

    return ANI_OK;
}
コード例 #3
0
/*
    \brief bapRsnSendEapolFrame
    To push an eapol frame to TL. 

    \param pAniPkt - a ready eapol frame that is prepared in tAniPacket format
*/
VOS_STATUS bapRsnSendEapolFrame( v_PVOID_t pvosGCtx, tAniPacket *pAniPkt )
{
    VOS_STATUS status;
    vos_pkt_t *pPacket = NULL;
    v_U8_t *pData, *pSrc;
    int pktLen = aniAsfPacketGetBytes( pAniPkt, &pSrc );

    if( pktLen <= 0 )
    {
        return VOS_STATUS_E_EMPTY;
    }
    status = bapRsnAcquirePacket( &pPacket, &pData, pktLen );
    if( VOS_IS_STATUS_SUCCESS( status ) && ( NULL != pPacket ))
    {
        vos_mem_copy( pData, pSrc, pktLen );
        //Send the packet, need to check whether we have an outstanding packet first.
        status = bapRsnTxFrame( pvosGCtx, pPacket );
        if( !VOS_IS_STATUS_SUCCESS( status ) )
        {
            vos_pkt_return_packet( pPacket );
        }
    }

    return ( status );
}
コード例 #4
0
static int
checkRsnKeyMic(v_U32_t cryptHandle,
               tAniPacket *eapolFrame,
               tAniEapolRsnKeyDesc *rsnDesc,
               v_U8_t *micKey,
               v_U32_t micKeyLen)
{
    int retVal = ANI_ERROR;
    int len;

    v_U8_t *ptr = NULL;
    v_U8_t *micPos = NULL;

    v_U8_t result[VOS_DIGEST_SHA1_SIZE]; // Larger of the two
    v_U8_t incomingMic[ANI_EAPOL_KEY_RSN_MIC_SIZE];

    if (!rsnDesc->info.micFlag)
    {
        VOS_ASSERT( 0 );
        return ANI_E_ILLEGAL_ARG;
    }

    len = aniAsfPacketGetBytes(eapolFrame, &ptr);
    if( ANI_IS_STATUS_SUCCESS( len ) )
    {
        micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET;

        // Skip to the EAPOL version field for MIC computation
        ptr += EAPOL_VERSION_POS;
        len -= EAPOL_VERSION_POS;

        // Copy existing MIC to temporary location and zero it out
        vos_mem_copy( incomingMic, micPos, ANI_EAPOL_KEY_RSN_MIC_SIZE );
        vos_mem_zero( micPos, ANI_EAPOL_KEY_RSN_MIC_SIZE );

        if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES)
        {
            if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) )
            {
                retVal = ANI_OK;
            }
        }
        else {
            VOS_ASSERT( 0 );
            retVal = ANI_E_ILLEGAL_ARG;
        }

        if (retVal == ANI_OK)
        {
            if ( !vos_mem_compare(incomingMic, result, ANI_EAPOL_KEY_RSN_MIC_SIZE))
            {
                retVal = ANI_E_MIC_FAILED;
            }
        }
    }

    return retVal;
}
コード例 #5
0
int
aagPtkPrf(v_U32_t cryptHandle,
          v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE],
          v_U32_t prfLen,
          tAniPacket *pmk, 
          tAniMacAddr authAddr,
          tAniMacAddr suppAddr,
          v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE],
          v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE])
{
    v_U8_t *lowMac;
    v_U8_t *highMac;
    v_U8_t *lowNonce;
    v_U8_t *highNonce;

    v_U8_t *keyBytes;
    int keyLen;

    v_U8_t text[AAG_PTK_PRF_TEXT_LEN];

    
    if (vos_mem_compare2(authAddr, suppAddr, sizeof(tAniMacAddr)) < 0) {
        lowMac = authAddr;
        highMac = suppAddr;
    } else {
        lowMac = suppAddr;
        highMac = authAddr;
    }

    if (vos_mem_compare2(aNonce, sNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE) < 0) {
        lowNonce = aNonce;
        highNonce = sNonce;
    } else {
        lowNonce = sNonce;
        highNonce = aNonce;
    }

    vos_mem_copy(text + AAG_PTK_PRF_LM_POS, lowMac, sizeof(tAniMacAddr));
    vos_mem_copy(text + AAG_PTK_PRF_HM_POS, highMac, sizeof(tAniMacAddr));
    vos_mem_copy(text + AAG_PTK_PRF_LN_POS, lowNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE);
    vos_mem_copy(text + AAG_PTK_PRF_HN_POS, highNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE);

    keyLen = aniAsfPacketGetBytes(pmk, &keyBytes);
    if( !ANI_IS_STATUS_SUCCESS( keyLen ) )
    {
        return keyLen;
    }

    return aagPrf(cryptHandle,
                  result, 
                  keyBytes, keyLen, 
                  (v_U8_t *)AAG_PTK_PRF_CONST, AAG_PTK_PRF_CONST_LEN,
                  text, sizeof(text),
                  prfLen);
}
コード例 #6
0
int 
aniEapolParse(tAniPacket *packet,
              v_U8_t **dstMac, 
              v_U8_t **srcMac, 
              v_U8_t **type)
{
    v_U16_t frameType;
    v_U8_t *ptr;
    int retVal;
    int tmp;

    if (aniAsfPacketGetLen(packet) < EAPOL_BODY_POS)
        return ANI_E_ILLEGAL_ARG;

    retVal = aniAsfPacketGetBytes(packet, &ptr);
    if( !ANI_IS_STATUS_SUCCESS( retVal ) )
    {
        return retVal;
    }

    VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO,
            "Supp parsing EAPOL packet of len %d: \n",
                retVal);

    frameType = (ptr[ETHER_PROTO_POS] << 8) + ptr[ETHER_PROTO_POS+1];


    if (frameType != ANI_ETH_P_EAPOL)
        return ANI_E_ILLEGAL_ARG;

    *dstMac = ptr + DST_MAC_POS;
    *srcMac = ptr + SRC_MAC_POS;

    
    

    *type = ptr + ANI_EAPOL_TYPE_POS;
    retVal = (ptr[EAPOL_BODY_LEN_POS] << 8) + ptr[EAPOL_BODY_LEN_POS + 1];
 
    tmp = aniAsfPacketGetLen(packet) - EAPOL_RX_HEADER_SIZE;
    if (retVal > tmp) 
    {
        retVal = ANI_E_ILLEGAL_ARG;
    } 
    else {
        if (retVal < tmp) 
        {
            retVal = aniAsfPacketTruncateFromRear(packet, tmp - retVal);
        }
    }

    return retVal;
}
コード例 #7
0
/**
 * aniEapolParseKey
 *
 * Parses and verifies a complete EAPOL-Key frame. The key descriptor
 * type is returned and so is a newly allocated key descriptor structure
 * that is appropriate for the type.
 *
 * NOTE: This is a non-destructive read. That is, the packet headers
 * will be unchanged at the end of this read operation. This is so
 * that a followup MIC check may be done on the complete packet. If
 * the packet parsing fails, the packet headers are not guaranteed to
 * be unchanged.
 *
 * @param packet the packet to read from. Note that the frame is not
 * expected to contain any additional padding at the end other than
 * the exact number of key bytes. (The aniEapolParse function will
 * ensure this.)
 * @param descType is set to the key descriptor type
 * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or
 * ANI_EAPOL_KEY_DESC_TYPE_RSN).
 * @param keyDescData is set to a newly allocated key descriptor
 * corresponding to the above descType. The signature field is
 * verified. The key bytes will be returned encrypted. It is the
 * responsibility of the caller to free this structure and the data
 * contained therein.
 *
 * @return ANI_OK if the operation succeeds
 */
int
aniEapolParseKey(tAniPacket *packet,
                 int *descType,
                 void **keyDescData)
{
    int retVal;
    v_U8_t *bytes;
    v_U32_t eapolFrameLen;

    if (packet == NULL)
        return ANI_E_NULL_VALUE;

    do
    {
        eapolFrameLen = aniAsfPacketGetLen(packet);

        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "Supp parsing EAPOL-Key frame of len %d\n",
                      eapolFrameLen);

        retVal = aniAsfPacketTruncateFromFront(packet, EAPOL_RX_HEADER_SIZE);
        if( !ANI_IS_STATUS_SUCCESS(retVal) ) break;

        retVal = aniAsfPacketGetBytes(packet, &bytes);
        if( !ANI_IS_STATUS_SUCCESS(retVal) ) break;

        if (*bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN ||
                   *bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW)
        {
            tAniEapolRsnKeyDesc *rsnDesc = NULL;

            //*descType = ANI_EAPOL_KEY_DESC_TYPE_RSN;
            *descType = (*bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW ?
                 ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW :  ANI_EAPOL_KEY_DESC_TYPE_RSN) ;
            retVal = parseRsnKeyDesc(packet, &rsnDesc);
            if( !ANI_IS_STATUS_SUCCESS(retVal) ) break;
            *keyDescData = rsnDesc;
        }
        else
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                "Supp received unknown EAPOL-Key descriptor: %d\n",
                        *bytes);
            retVal = ANI_E_ILLEGAL_ARG;
            break;
        }

        aniAsfPacketMoveLeft(packet, eapolFrameLen);
    }while( 0 );

    return retVal;
}
コード例 #8
0
/**
 * aniAsfPacketGetN
 *
 * Returns N bytes from the packet and moves the head of the packet
 * beyond those bytes.
 *
 * @param packet the packet to read from
 * @param n the number of bytes to read
 * @param bytesPtr is set to the start of the octets
 *
 * @return ANI_OK if the operation succeeds; ANI_E_SHORT_PACKET if the
 * packet does not have n bytes.
 */
int
aniAsfPacketGetN(tAniPacket *packet, int n, v_U8_t **bytesPtr)
{
    int retVal;
    v_U8_t *bytes = NULL;

    if (packet == NULL)
        return ANI_E_NULL_VALUE;

    retVal = aniAsfPacketGetBytes(packet, &bytes);
    if (retVal < n)
        return ANI_E_SHORT_PACKET;

    aniAsfPacketTruncateFromFront(packet, n);

    *bytesPtr = bytes;

    return ANI_OK;
}
コード例 #9
0
static int
writeRsnKeyMic(v_U32_t cryptHandle,
               tAniPacket *eapolFrame,
               tAniEapolRsnKeyDesc *rsnDesc,
               v_U8_t *micKey,
               v_U32_t micKeyLen)
{
    int retVal = ANI_OK;
    int len;

    v_U8_t *ptr = NULL;
    v_U8_t *micPos = NULL;
    v_U8_t result[VOS_DIGEST_SHA1_SIZE]; // Larger of the two

    // Sanity check the arguments and return if no MIC generation is
    // needed
    if (micKey != NULL)
    {
        if (micKeyLen == 0 || !rsnDesc->info.micFlag)
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                "Supp MIC key provided but micKeyLen or micFlag is not set!\n");
            VOS_ASSERT( 0 );
            return ANI_E_ILLEGAL_ARG;
        }
    }
    else {
        if (rsnDesc->info.micFlag)
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                "Supp micFlag is set but MIC key not provided!\n");
            VOS_ASSERT( 0 );
            return ANI_E_ILLEGAL_ARG;
        }
        // Normal condition where MIC is not desired by the caller
        return ANI_OK;
    }

    len = aniAsfPacketGetBytes(eapolFrame, &ptr);
    if( !ANI_IS_STATUS_SUCCESS( len ) )
    {
        return len;
    }

    micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET + SNAP_HEADER_SIZE;

    // Clear the MIC field in the packet before the MIC computation
    vos_mem_zero( micPos, VOS_DIGEST_MD5_SIZE);

    // Skip to the EAPOL version field for MIC computation
    ptr += EAPOL_VERSION_POS + SNAP_HEADER_SIZE;
    len -= (EAPOL_VERSION_POS + SNAP_HEADER_SIZE);

    if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES)
    {
        if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) )
        {
            retVal = ANI_OK;
        }
        else
        {
            retVal = ANI_ERROR;
        }
    }
    else {
        VOS_ASSERT( 0 );
        retVal = ANI_E_ILLEGAL_ARG;
    }

    if (retVal == ANI_OK)
    {
        // Copy only 16B which is the smaller of the two and the same as
        // ANI_EAPOL_KEY_RSN_MIC_SIZE
        vos_mem_copy(micPos, result, VOS_DIGEST_MD5_SIZE);
    }

    return retVal;
}
コード例 #10
0
/**
 * aniEapolParse
 *
 * FUNCTION:
 * Parses an EAPoL frame to the first level of headers (no EAP
 * headers are parsed).
 *
 * NOTE: This is a non-destructive read, that is the
 * headers are not stripped off the packet. However, any additional
 * data at  the end of the packet, beyond what the EAPoL headers encode
 * will be stripped off.
 *
 * @param packet the packet containing the EAPoL frame to parse
 * @param dstMac a pointer to set to the location of the destination
 * MAC address
 * @param srcMac a pointer to set to the location of the source
 * MAC address
 * @param type a pointer to set to the location of the EAPOL type
 * field.
 *
 * @return the non-negative length of the EAPOL payload if the operation
 * succeeds
 */
int
aniEapolParse(tAniPacket *packet,
              v_U8_t **dstMac,
              v_U8_t **srcMac,
              v_U8_t **type)
{
    v_U16_t frameType;
    v_U8_t *ptr;
    int retVal;
    int tmp;

    if (aniAsfPacketGetLen(packet) < EAPOL_BODY_POS)
        return ANI_E_ILLEGAL_ARG;

    retVal = aniAsfPacketGetBytes(packet, &ptr);
    if( !ANI_IS_STATUS_SUCCESS( retVal ) )
    {
        return retVal;
    }

    VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO,
            "Supp parsing EAPOL packet of len %d: \n",
                retVal);

    frameType = (ptr[ETHER_PROTO_POS] << 8) + ptr[ETHER_PROTO_POS+1];

    /*
     * Validate the EAPOL-FRAME
     */

    if (frameType != ANI_ETH_P_EAPOL)
        return ANI_E_ILLEGAL_ARG;

    *dstMac = ptr + DST_MAC_POS;
    *srcMac = ptr + SRC_MAC_POS;

    //    if (ptr[EAPOL_VERSION_POS] != EAPOL_VERSION_1)
    //        return ANI_E_ILLEGAL_ARG;

    *type = ptr + ANI_EAPOL_TYPE_POS;
    retVal = (ptr[EAPOL_BODY_LEN_POS] << 8) + ptr[EAPOL_BODY_LEN_POS + 1];

    /*
     * Validate the length of the body. Allow for longer
     * packets than encoded, but encoding should not be larger than
     * packet.
     * Note: EAPOL body len does not include headers
     */
    tmp = aniAsfPacketGetLen(packet) - EAPOL_RX_HEADER_SIZE;
    if (retVal > tmp)
    {
        retVal = ANI_E_ILLEGAL_ARG;
    }
    else {
        if (retVal < tmp)
        {
            retVal = aniAsfPacketTruncateFromRear(packet, tmp - retVal);
        }
    }

    return retVal;
}
コード例 #11
0
static int
gotoStatePtkInitNegoTx(tAuthRsnFsm *fsm)
{
    tAniEapolRsnKeyDesc txDesc;
    v_BOOL_t retransmit = eANI_BOOLEAN_FALSE;
    v_U8_t *rsnWpaIe = NULL;
    int rsnWpaIeLen;
    static tAniPacket *keyData;
    // The longest length...the extra 8 bytes account for RSN key data
    // encapsulation
    v_U8_t paddedGroupKeyEncaps[1024];
    int padLen = 0;
    v_U8_t *groupKeyBytes;
    int groupKeyLen;
    v_U8_t *wrappedKey = NULL;
    // Variables used for RC4 GTK wrap
    //v_U8_t keyIv[ANI_EAPOL_KEY_RSN_IV_SIZE];
    //v_U32_t keyIvLsb;
    int retVal = 0;

    //invalidate this
    fsm->msg4TimeOut = VOS_FALSE;
    fsm->currentState = PTK_INIT_NEGO_TX ;

    if (keyData == NULL) 
    {
        // Allocate the packet the first time around that you enter
        retVal = aniAsfPacketAllocateExplicit(&keyData, 1024, 10);
        if( !ANI_IS_STATUS_SUCCESS( retVal ) )
        {
            return retVal;
        }
    } 
    else {
        // Just empty out the packet
        aniAsfPacketEmptyExplicit(keyData, 10);
    }

    do
    {
        // Create a new EAPOL frame if we don't have one to retransmit
        //if (aniAsfPacketGetLen(fsm->lastEapol) == 0) 
#if 0
        if( fsm->lastEapol )
         {
             aniAsfPacketFree( fsm->lastEapol );
             fsm->lastEapol = NULL;

             retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol,
                                          RSN_MAX_PACKET_SIZE,
                                          EAPOL_TX_HEADER_SIZE );
#endif     
             aniAsfPacketEmptyExplicit(fsm->lastEapol, 
                              EAPOL_TX_HEADER_SIZE);
      //  }

        if (1) 
        {

            vos_mem_zero( &txDesc, sizeof(txDesc) );

            // The Key Information bits...
            if (fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) 
            {
                txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES;
            } 
            else {
                txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_RC4;
            }
            txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.installFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.ackFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.micFlag = eANI_BOOLEAN_TRUE;

            txDesc.keyLen = aagGetKeyMaterialLen(fsm->staCtx->pwCipherType);
            aniSsmReplayCtrNext(fsm->staCtx->localReplayCtr, txDesc.replayCounter);
            vos_mem_copy(txDesc.keyNonce, fsm->aNonce, sizeof(txDesc.keyNonce));

            // Add the RSN IE (but not any WPA IE)
            rsnWpaIeLen = getRsnIeFromAdvertizedIes(fsm, &rsnWpaIe);

            if( !ANI_IS_STATUS_SUCCESS( rsnWpaIeLen) ) break;

            retVal = aniAsfPacketAppendBuffer(keyData, rsnWpaIe, rsnWpaIeLen);
            if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;

            // Add the RSN group key encapsulation
            retVal = aagAppendGroupKeyForRsn ( keyData );

            if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break;

            groupKeyLen = aniAsfPacketGetBytes(keyData, &groupKeyBytes);
            if( !ANI_IS_STATUS_SUCCESS( groupKeyLen ) ) 
            {
                retVal = ANI_E_FAILED;
                break;
            }

            txDesc.info.secureFlag = eANI_BOOLEAN_TRUE;
            txDesc.info.encKeyDataFlag = eANI_BOOLEAN_TRUE;

            if ( fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES ) 
            {
                /*
                 * Use the AES key wrap algorithm if either one of the pairwise
                 * key or the group key is an AES key.
                 *
                 * If the key being sent is not a multiple of
                 * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then pad it with
                 * zeroes. e.g., if we are sending a WEP key of 5 or 13
                 * bytes.
                 */
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                           "AES Key Wrap invoked. groupKeyLen = %d", groupKeyLen);

                padLen = groupKeyLen % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
                if (padLen != 0) {
                    padLen = ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE - padLen;
            
                    VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                               "Before AES Key Wrap: padLen = %d", padLen);

                    if (groupKeyLen + padLen > sizeof(paddedGroupKeyEncaps)) {
#if 0
                        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                                   "Cannot encode group key encapsulation of len %d and cipher type %s "
                                   "to send to %s %s (aid %d, radio %d, user %s)",
                                   groupKeyLen,
                                   aniSsmIntGetCipherStr(AAG_GROUP_CIPHER(fsm->ctx->radioId)),
                                   (fsm->ctx->bpIndicator ? "BP" : "STA"),
                                   aniAsfHexStr(fsm->ctx->suppMac, sizeof(tAniMacAddr)),
                                   fsm->ctx->aid,
                                   fsm->ctx->radioId,
                                   aagGetStaUserId(fsm->ctx));
#endif
                         retVal = ANI_E_FAILED;
                    }
                    // OK, after you compute the pad length, you need to 
                    // add the padding  - 0xdd followed by 0x00's
                    addPad( groupKeyBytes , groupKeyLen , padLen );
                    // add the padding length
                    groupKeyLen += padLen;
                    // IMMEDIATELY adjust the packet size to reflect the pad 
                    aniAsfPacketMoveRight(keyData, padLen); 
                    if( !ANI_IS_STATUS_SUCCESS( retVal) ) break;
                }
            
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                           "Before AES Key Wrap: padded groupKeyLen = %d", groupKeyLen);

                retVal = aniSsmAesKeyWrap(fsm->cryptHandle, groupKeyBytes, groupKeyLen,
                                          fsm->staCtx->ptk + ANI_EAPOL_KEY_RSN_MIC_SIZE,
                                          ANI_EAPOL_KEY_RSN_ENC_KEY_SIZE,
                                          &wrappedKey);
                if( !ANI_IS_STATUS_SUCCESS( retVal) ) break;
                // This doesn't work...
                //groupKeyBytes = wrappedKey;
                //groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
                // ...here is the right way to do it
                // Add the length of the prepended IV A[0]
                if (NULL == wrappedKey)
                {
                    break;
                }
                groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE;
                memcpy( groupKeyBytes, wrappedKey, groupKeyLen);
                // Free the array used to hold the wrapped key
                if (wrappedKey) vos_mem_free( wrappedKey);
                // IMMEDIATELY adjust the packet size to reflect the IV 
                aniAsfPacketMoveRight(keyData, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE);
            } 
            else {
            
                VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                    "Auth RC4 Key Wrap invoked. groupKeyLen = %d", groupKeyLen);
            }
            txDesc.keyDataLen = aniAsfPacketGetBytes(keyData, &txDesc.keyData);

            retVal = aniEapolWriteKey(fsm->cryptHandle,
                                      fsm->lastEapol,
                                      fsm->staCtx->suppMac,
                                      fsm->staCtx->authMac,
                                      ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW,
                                      &txDesc,
                                      fsm->staCtx->ptk,
                                      CSR_AES_KEY_LEN);
            if( !ANI_IS_STATUS_SUCCESS( retVal) ) break;
        } 
        else {
            retransmit = eANI_BOOLEAN_TRUE;
        }

        if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) )
        {
            retVal = ANI_OK;
        }
        else
        {
            //we fail to send the eapol frame disconnect
            bapAuthDisconnect( fsm->ctx );
            retVal = ANI_ERROR;
        }

    }while( 0 );

    return retVal;
}

static int
gotoStatePtkInitDone(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data)
{
    int retVal;
    tAniEapolRsnKeyDesc *rxDesc;
    tCsrRoamSetKey setKeyInfo;

    fsm->currentState = PTK_INIT_DONE;

    rxDesc = data->keyDesc;

    vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) );
    setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES;
    setKeyInfo.keyDirection = eSIR_TX_RX;
    vos_mem_copy( setKeyInfo.peerMac, fsm->staCtx->suppMac, sizeof( tAniMacAddr ) );
    setKeyInfo.paeRole = 0; //this is a supplicant
    setKeyInfo.keyId = 0;   //always
    setKeyInfo.keyLength = CSR_AES_KEY_LEN; 
    vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->staCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN );
    //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one.
    if( VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) )
    {
        //Done
        aniAsfPacketEmptyExplicit(fsm->lastEapol, EAPOL_TX_HEADER_SIZE);
        retVal = ANI_OK;
    }
    else
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Auth: gotoStatePtkInitDone fail to set key\n" );
        retVal = ANI_ERROR;
    }

    return retVal;
}
コード例 #12
0
int
aagAppendGroupKeyForRsn(tAniPacket *packet)
{
#if 0
    tAniPacket *groupKey = NULL;
#else
    tANI_U8 groupKey[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                          0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15};
#endif
    tANI_U8 *groupKeyBytes = NULL;
    tANI_U8 *lenPtr = NULL;
    tANI_U8 *endPtr = NULL;
    int groupKeyLen;
    int retVal;

#if 0
    groupKey = AAG_GROUP_KEY(radioId);
    if (groupKey == NULL) {
        ANI_AAG_LOG_E("Group key is not yet set on radio %d, id %d!",
                      radioId, AAG_GROUP_KEY_ID(radioId));
        assert(0 && "Group key is still NULL!");
        return ANI_E_FAILED;
    }

    groupKeyLen = aniAsfPacketGetBytes(groupKey, &groupKeyBytes);
    CHECK_NO_ERROR(groupKeyLen);

    if (aagConfig.logLevel >= LOG_INFO) {
        ANI_AAG_LOG_D("Will encapsulate group key bytes %s",
                      aniAsfHexStr(groupKeyBytes, groupKeyLen));
    }
#else
    groupKeyBytes = groupKey;

    groupKeyLen = STATIC_WEP_KEY_LEN;
#endif

    /*
     * Add the key data encapsulation needed for RSN/WPA2
     */

    // The IE ID
    retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID);
    //CHECK_NO_ERROR(retVal);

    // Obtain the position for the length
    aniAsfPacketGetBytesFromTail(packet, &lenPtr);

    // Write out a dummy length - we'll fill this in later. It will be 
    // 6 bytes more than the length of the GTK
    retVal = aniAsfPacketAppend8(packet, 0);
    //CHECK_NO_ERROR(retVal);

    // Copy the RSN OUI
    retVal = aniAsfPacketAppendBuffer(packet, aniSsmIeRsnOui, sizeof(aniSsmIeRsnOui));
    //CHECK_NO_ERROR(retVal);

    // Indicate that the key type is group key
    retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID);
    //CHECK_NO_ERROR(retVal);
 
    // Copy the key-id to the first two bits of the next byte
    // Copy the Tx bit the third bit of the same byte
    // (Here, I assume the Group Key is to be used for both STA Tx and Rx)
    retVal = aniAsfPacketAppend8(
            packet,
            GROUP_KEY_ID );
            //AAG_GROUP_KEY_ID(radioId) );
    //CHECK_NO_ERROR(retVal);

    retVal = aniAsfPacketMoveRight(packet, 1); // Reserved bits (1 byte)
    //CHECK_NO_ERROR(retVal);

    // Copy the real key bytes
    retVal = aniAsfPacketAppendBuffer(packet, groupKeyBytes, groupKeyLen);
    //CHECK_NO_ERROR(retVal);
    
    // Calculate and enter the length of the entire encoding
    aniAsfPacketGetBytesFromTail(packet, &endPtr);
    *lenPtr = endPtr - (lenPtr + 1) ; // subtract one to avoid tail

    return retVal;
}
コード例 #13
0
static int
writeRsnKeyMic(v_U32_t cryptHandle,
               tAniPacket *eapolFrame, 
               tAniEapolRsnKeyDesc *rsnDesc,
               v_U8_t *micKey, 
               v_U32_t micKeyLen)
{
    int retVal = ANI_OK;
    int len;

    v_U8_t *ptr = NULL;
    v_U8_t *micPos = NULL;
    v_U8_t result[VOS_DIGEST_SHA1_SIZE]; 

    
    
    if (micKey != NULL) 
    {
        if (micKeyLen == 0 || !rsnDesc->info.micFlag) 
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                "Supp MIC key provided but micKeyLen or micFlag is not set!\n");
            VOS_ASSERT( 0 );
            return ANI_E_ILLEGAL_ARG;
        }
    } 
    else {
        if (rsnDesc->info.micFlag) 
        {
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                "Supp micFlag is set but MIC key not provided!\n");
            VOS_ASSERT( 0 );
            return ANI_E_ILLEGAL_ARG;
        }
        
        return ANI_OK;
    }

    len = aniAsfPacketGetBytes(eapolFrame, &ptr);
    if( !ANI_IS_STATUS_SUCCESS( len ) )
    {
        return len;
    }

    micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET + SNAP_HEADER_SIZE;

    
    vos_mem_zero( micPos, VOS_DIGEST_MD5_SIZE);

    
    ptr += EAPOL_VERSION_POS + SNAP_HEADER_SIZE;
    len -= (EAPOL_VERSION_POS + SNAP_HEADER_SIZE);

    if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES) 
    {
        if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) )
        {
            retVal = ANI_OK;
        }
        else
        {
            retVal = ANI_ERROR;
        }
    } 
    else {
        VOS_ASSERT( 0 );
        retVal = ANI_E_ILLEGAL_ARG;
    }

    if (retVal == ANI_OK) 
    {
        
        
        vos_mem_copy(micPos, result, VOS_DIGEST_MD5_SIZE);
    }

    return retVal;
}