Exemplo n.º 1
0
 uint8_t* TPMT_HA_logMarshal(const TPMT_HA* val, uint8_t* i_logBuf)
 {
     uint16_t* field16 = (uint16_t*)i_logBuf;
     *field16 = htole16(val->algorithmId);
     i_logBuf += sizeof(uint16_t);
     memcpy(i_logBuf, &(val->digest),
            getDigestSize((TPM_Alg_Id)val->algorithmId));
     i_logBuf += getDigestSize((TPM_Alg_Id)val->algorithmId);
     return i_logBuf;
 }
Exemplo n.º 2
0
 uint8_t* TPMT_HA_marshal(const TPMT_HA* val,
                          uint8_t* o_tpmBuf,
                          size_t i_tpmBufSize,
                          size_t * io_cmdSize)
 {
     o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
                             &(val->algorithmId), sizeof(val->algorithmId));
     if (getDigestSize((TPM_Alg_Id)val->algorithmId) == 0)
     {
         return NULL;
     }
     o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
                             &(val->digest),
                             getDigestSize((TPM_Alg_Id)val->algorithmId));
     return o_tpmBuf;
 }
Exemplo n.º 3
0
    const uint8_t* TPMT_HA_logUnmarshal(TPMT_HA* val,
                                        const uint8_t* i_tpmBuf, bool* o_err)
    {
        size_t size = 0;
        uint16_t* field16 = NULL;

        do {
            *o_err = false;

            // algorithmId
            size = sizeof(val->algorithmId);
            field16 = (uint16_t*)i_tpmBuf;
            val->algorithmId = le16toh(*field16);
            // Ensure a valid count
            if (val->algorithmId >= TPM_ALG_INVALID_ID)
            {
                *o_err = true;
                i_tpmBuf = NULL;
                TRACFCOMP(g_trac_trustedboot,"ERROR> TPMT_HA:logUnmarshal()"
                          " invalid algorithmId %d",
                          val->algorithmId);
                break;
            }
            i_tpmBuf += size;

            // digest
            size = getDigestSize((TPM_Alg_Id)val->algorithmId);
            // Ensure a valid count
            if (size >= TPM_ALG_INVALID_SIZE)
            {
                *o_err = true;
                i_tpmBuf = NULL;
                TRACFCOMP(g_trac_trustedboot,"ERROR> TPMT_HA:logUnmarshal() "
                          "invalid algorithm size of %d for algorithm id %d",
                          (int)size, val->algorithmId);
                break;
            }

            memcpy(&(val->digest), i_tpmBuf, size);
            i_tpmBuf += size;
        } while(0);

        return i_tpmBuf;
    }
Exemplo n.º 4
0
// Final process, place digest in hash
void HASHwithTransform::Final(byte* hash)
{
    word32    blockSz  = getBlockSize();
    word32    digestSz = getDigestSize();
    word32    padSz    = getPadSize();
    ByteOrder order    = getByteOrder();

    AddLength(buffLen_);                        // before adding pads
    HashLengthType preLoLen = GetBitCountLo();
    HashLengthType preHiLen = GetBitCountHi();
    byte*     local         = reinterpret_cast<byte*>(buffer_);

    local[buffLen_++] = 0x80;  // add 1

    // pad with zeros
    if (buffLen_ > padSz) {
        memset(&local[buffLen_], 0, blockSz - buffLen_);
        buffLen_ += blockSz - buffLen_;

        ByteReverseIf(local, local, blockSz, order);
        Transform();
        buffLen_ = 0;
    }
    memset(&local[buffLen_], 0, padSz - buffLen_);
   
    ByteReverseIf(local, local, blockSz, order);
    
    memcpy(&local[padSz],   order ? &preHiLen : &preLoLen, sizeof(preLoLen));
    memcpy(&local[padSz+4], order ? &preLoLen : &preHiLen, sizeof(preLoLen));

    Transform();
    ByteReverseIf(digest_, digest_, digestSz, order);
    memcpy(hash, digest_, digestSz);

    Init();  // reset state
}
Exemplo n.º 5
0
 bool TPMT_HA::operator==(const TPMT_HA& i_rhs) const
 {
     size_t digestSize = getDigestSize((TPM_Alg_Id)algorithmId);
     return (algorithmId == i_rhs.algorithmId) &&
         (memcmp(&(digest), &(i_rhs.digest), digestSize) == 0);
 }
Exemplo n.º 6
0
 size_t TPMT_HA_marshalSize(const TPMT_HA* val)
 {
     return (sizeof(val->algorithmId) +
             getDigestSize((TPM_Alg_Id)(val->algorithmId)));
 }
Exemplo n.º 7
0
/* prepares binary version of this message, returns number of bytes used
**/
int TMsg::storeSelf(char * buffer)
{
    char *start = buffer;
    int tmp = this->TransID;

    enum DigestTypes UsedDigestType;
    
    if (Bulk) {

        int tmpSize = this->MsgSize;
        Log(Debug) <<"MsgSize - DHCP "<<this->MsgSize<< LogEnd;
        buffer[1]=tmpSize%256; tmpSize/=256;
        buffer[0]=tmpSize%256; tmpSize/=256;

        buffer[2]=(char)MsgType;
        buffer[5] = tmp%256;  tmp = tmp/256;
        buffer[4] = tmp%256;  tmp = tmp/256;
        buffer[3] = tmp%256;  tmp = tmp/256;
        buffer+=6;

    } else {

        *(buffer++) = (char)MsgType;

        /* ugly 3-byte version of htons/htonl */
        buffer[2] = tmp%256;  tmp = tmp/256;
        buffer[1] = tmp%256;  tmp = tmp/256;
        buffer[0] = tmp%256;  tmp = tmp/256;
        buffer+=3;
    }

    TOptList::iterator option;
    for (option=Options.begin(); option!=Options.end(); ++option) {
        (*option)->storeSelf(buffer);
	buffer += (*option)->getSize();
    }

#ifndef MOD_DISABLE_AUTH
    // for AAAAUTH use only HMAC-SHA1
    if (getOption(OPTION_AAAAUTH))
            UsedDigestType = DIGEST_HMAC_SHA1;
    else
            UsedDigestType = DigestType;

    if (AuthInfoKey && AuthInfoPtr && (getOption(OPTION_AUTH) || getOption(OPTION_AAAAUTH)) && UsedDigestType != DIGEST_NONE) {
            Log(Debug) << "Auth: Used digest type is " << getDigestName(UsedDigestType) << LogEnd;
            switch (UsedDigestType) {
                    case DIGEST_PLAIN:
                        memcpy(AuthInfoPtr, "This is 32-byte plain testkey...", getDigestSize(UsedDigestType));
                        break;
                    case DIGEST_HMAC_MD5:
                        hmac_md5(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr);
                        break;
                    case DIGEST_HMAC_SHA1:
                        hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 1);
                        break;
                    case DIGEST_HMAC_SHA224:
                        hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 224);
                        break;
                    case DIGEST_HMAC_SHA256:
                        hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 256);
                        break;
                    case DIGEST_HMAC_SHA384:
                        hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 384);
                        break;
                    case DIGEST_HMAC_SHA512:
                        hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 512);
                        break;
                    default:
                        break;
            }
            PrintHex("Auth: Sending digest: ", AuthInfoPtr, getDigestSize(UsedDigestType));
    }
#endif

    return buffer-start;
}
Exemplo n.º 8
0
bool TMsg::validateAuthInfo(char *buf, int bufSize,
                            AuthProtocols proto,
                            const DigestTypesLst& acceptedDigestTypes) {
    bool is_ok = false;
    bool dt_in_list = false;

    switch (proto) {
    case AUTH_PROTO_NOT_SUPPORTED:
    case AUTH_PROTO_NONE:
        return true;
    case AUTH_PROTO_DELAYED: {
        SPtr<TOptAuthentication> auth = (Ptr*)getOption(OPTION_AUTH);
        if (!auth) {
            Log(Warning) << "AUTH: Mandatory AUTH option missing in delayed auth."
                         << LogEnd;
            return false;
        }
        if (auth->getProto() != AUTH_PROTO_DELAYED) {
            Log(Warning) << "AUTH: Bad protocol in auth: expected 2(delayed auth), but got "
                         << int(auth->getProto()) << ", key ignored." << LogEnd;
            return false;
        }
        if (auth->getAlgorithm() != 1) {
            Log(Warning) << "AUTH: Bad algorithm in auth option: expected 1 (HMAC-MD5), but got "
                         << int(auth->getAlgorithm()) << ", key ignored." << LogEnd;
            return false;
        }
        if (MsgType == SOLICIT_MSG) {
            if (auth->getSize() != TOptAuthentication::OPT_AUTH_FIXED_SIZE + TOpt::OPTION6_HDR_LEN) {
                Log(Warning) << "AUTH: Received non-empty delayed-auth option in SOLICIT,"
                             << " expected empty." << LogEnd;
                return false;
            } else {
                return true; // delayed auth in Solicit should come in empty
            }
        }

        if (SPI_ == 0) {
            Log(Warning) << "AUTH: Received invalid SPI = 0." << LogEnd;
            return false;
        }

        if (!loadAuthKey()) {
            Log(Warning) << "AUTH: Failed to load delayed auth key with key id="
                         << std::hex << getSPI() << std::dec << LogEnd;
            return false;
        }

        // Ok, let's do validation
        char *rcvdAuthInfo = new char[RECONFIGURE_DIGEST_SIZE];
        char *goodAuthInfo = new char[RECONFIGURE_DIGEST_SIZE];

        memmove(rcvdAuthInfo, AuthDigestPtr_, DELAYED_AUTH_DIGEST_SIZE);
        memset(AuthDigestPtr_, 0, DELAYED_AUTH_DIGEST_SIZE);

        hmac_md5(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo);

        Log(Debug) << "Auth: Checking delayed-auth (HMAC-MD5) digest:" << LogEnd;
        PrintHex("Auth:received digest: ", (uint8_t*)rcvdAuthInfo, DELAYED_AUTH_DIGEST_SIZE);
        PrintHex("Auth:  proper digest: ", (uint8_t*)goodAuthInfo, DELAYED_AUTH_DIGEST_SIZE);

        if (0 == memcmp(goodAuthInfo, rcvdAuthInfo, DELAYED_AUTH_DIGEST_SIZE))
            is_ok = true;

        delete [] rcvdAuthInfo;
        delete [] goodAuthInfo;

        return is_ok;
    }
    case AUTH_PROTO_RECONFIGURE_KEY: {
        if (MsgType != RECONFIGURE_MSG)
            return true;
        SPtr<TOptAuthentication> auth = (Ptr*)getOption(OPTION_AUTH);
        if (!auth) {
            Log(Warning) << "AUTH: Mandatory AUTH option missing in RECONFIGURE." << LogEnd;
            return false;
        }
        if (auth->getProto() != AUTH_PROTO_RECONFIGURE_KEY) {
            Log(Warning) << "AUTH: Bad protocol in auth: expected 3(reconfigure-key), but got "
                         << int(auth->getProto()) << ", key ignored." << LogEnd;
            return false;
        }
        if (auth->getAlgorithm() != 1) {
            Log(Warning) << "AUTH: Bad algorithm in auth option: expected 1, but got "
                         << int(auth->getAlgorithm()) << ", key ignored." << LogEnd;
            return false;
        }
        if (auth->getRDM() != AUTH_REPLAY_NONE) {
            Log(Warning) << "AUTH: Bad replay detection method (RDM) value: expected 0,"
                         << ", but got " << auth->getRDM() << LogEnd;
            // This is small issue enough, so we can continue.
        }
        if (AuthKey_.size() != RECONFIGURE_KEY_SIZE) {
            Log(Error) << "AUTH: Failed to verify incoming RECONFIGURE message due to "
                       << "reconfigure-key issue: expected size " << RECONFIGURE_KEY_SIZE
                       << ", but got " << AuthKey_.size() << ", message dropped." << LogEnd;
            return false;
        }
        if (!AuthDigestPtr_) {
            Log(Error) << "AUTH: Failed to verify incoming RECONFIGURE message: "
                       << "AuthDigestPtr_ not set, message dropped." << LogEnd;
            return false;
        }

        char *rcvdAuthInfo = new char[RECONFIGURE_DIGEST_SIZE];
        char *goodAuthInfo = new char[RECONFIGURE_DIGEST_SIZE];

        memmove(rcvdAuthInfo, AuthDigestPtr_, RECONFIGURE_DIGEST_SIZE);
        memset(AuthDigestPtr_, 0, RECONFIGURE_DIGEST_SIZE);

        hmac_md5(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo);

        Log(Debug) << "Auth: Checking reconfigure-key" << LogEnd;
        PrintHex("Auth:received digest: ", (uint8_t*)rcvdAuthInfo, RECONFIGURE_DIGEST_SIZE);
        PrintHex("Auth:  proper digest: ", (uint8_t*)goodAuthInfo, RECONFIGURE_DIGEST_SIZE);

        if (0 == memcmp(goodAuthInfo, rcvdAuthInfo, RECONFIGURE_DIGEST_SIZE))
            is_ok = true;

        delete [] rcvdAuthInfo;
        delete [] goodAuthInfo;

        return is_ok;
    }
    case AUTH_PROTO_DIBBLER:
        break;
    }
    
    //empty list means that any digest type is accepted
    if (acceptedDigestTypes.empty()) {
        dt_in_list = true;
    } else {
        // check if the digest is allowed AUTH list
        for (unsigned i = 0; i < acceptedDigestTypes.size(); ++i) {
            if (acceptedDigestTypes[i] == DigestType_) {
                dt_in_list = true;
                break;
            }
        }
    }

    if (dt_in_list == false) {
        if (DigestType_ == DIGEST_NONE)
            Log(Warning) << "Authentication option is required." << LogEnd;
        else
            Log(Warning) << "Authentication method " << getDigestName(DigestType_)
                       << " not accepted." << LogEnd;
        return false;
    }

    if (DigestType_ == DIGEST_NONE) {
            is_ok = true;
    } else if (AuthDigestPtr_) {
#ifndef MOD_DISABLE_AUTH

        if (AuthKey_.empty() && !loadAuthKey()) {
            Log(Debug) << "Auth: Failed to load key with SPI=" << SPI_ << LogEnd;
            return false;
        }

        unsigned AuthInfoLen = getDigestSize(DigestType_);
        char *rcvdAuthInfo = new char[AuthInfoLen];
        char *goodAuthInfo = new char[AuthInfoLen];

        memmove(rcvdAuthInfo, AuthDigestPtr_, AuthInfoLen);
        memset(AuthDigestPtr_, 0, AuthInfoLen);

        switch (DigestType_) {
                case DIGEST_PLAIN:
                    /// @todo: load plain text from a file
                    memcpy(goodAuthInfo, "This is 32-byte plain testkey...", 32);
                    break;
                case DIGEST_HMAC_MD5:
                    hmac_md5(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo);
                    break;
                case DIGEST_HMAC_SHA1:
                    hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 1);
                    break;
                case DIGEST_HMAC_SHA224:
                    hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 224);
                    break;
                case DIGEST_HMAC_SHA256:
                    hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 256);
                    break;
                case DIGEST_HMAC_SHA384:
                    hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 384);
                    break;
                case DIGEST_HMAC_SHA512:
                    hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 512);
                    break;
                default:
                    break;
        }
        if (0 == memcmp(goodAuthInfo, rcvdAuthInfo, AuthInfoLen))
            is_ok = true;

        Log(Debug) << "Auth:Checking using digest method: "
                   << getDigestName(DigestType_) << LogEnd;
        PrintHex("Auth:received digest: ", (uint8_t*)rcvdAuthInfo, AuthInfoLen);
        PrintHex("Auth:  proper digest: ", (uint8_t*)goodAuthInfo, AuthInfoLen);

        delete [] rcvdAuthInfo;
        delete [] goodAuthInfo;

        if (is_ok)
            Log(Info) << "Auth: Digest correct." << LogEnd;
        else {
            Log(Warning) << "Auth: Digest incorrect." << LogEnd;
	}
#endif
    } else {
        Log(Error) << "Auth: Digest mode set to " << DigestType_
                   << ", but AUTH option not set." << LogEnd;
        return false;
    }
    
    return is_ok;
}
Exemplo n.º 9
0
void TMsg::calculateDigests(char* buffer, size_t len) {

    SPtr<TOptAuthentication> auth = (Ptr*)getOption(OPTION_AUTH);
    if (!auth)
        return;

    switch (auth->getProto()) {
    default: {
        Log(Error) << "AUTH: protocol " << auth->getProto() << " not supported yet." << LogEnd;
        return;
    }
    case AUTH_PROTO_DELAYED: {
        if (AuthKey_.empty()) {
            if (MsgType == SOLICIT_MSG) {
                return; // That's alright, no auth info in SOLICIT
            }
            Log(Error) << "AUTH: Can't sign delayed-auth option, key empty." << LogEnd;
            return;
        }
        if (auth->getAuthDataPtr()) {
            hmac_md5(buffer, len, (char*) &AuthKey_[0], AuthKey_.size() ,auth->getAuthDataPtr());
        }
        return;
    }
    case AUTH_PROTO_RECONFIGURE_KEY: {
        if (AuthKey_.size() != RECONFIGURE_KEY_SIZE) {
            Log(Error) << "AUTH: Invalid size of reconfigure-key: expected " <<
                RECONFIGURE_KEY_SIZE << ", actual size " << AuthKey_.size() << LogEnd;
            return;
        }
        if (auth->getAuthDataPtr()) {
            hmac_md5(buffer, len, (char*) &AuthKey_[0], AuthKey_.size() ,auth->getAuthDataPtr());
        }
        return;
    }
    case AUTH_PROTO_NOT_SUPPORTED:
    case AUTH_PROTO_NONE: {
        // don't calculate anything
        return;
    }
    case AUTH_PROTO_DIBBLER: {
        DigestTypes UsedDigestType;

	// for AAAAUTH use only HMAC-SHA1
        UsedDigestType = DigestType_;

        if (getSPI() && !loadAuthKey()) {
            return;
        }
        
        if (getSPI() && !AuthKey_.empty() && UsedDigestType != DIGEST_NONE) {
            Log(Debug) << "Auth: Used digest type is " << getDigestName(UsedDigestType) << LogEnd;
            switch (UsedDigestType) {
            case DIGEST_PLAIN:
                memcpy(AuthDigestPtr_, "This is 32-byte plain testkey...", getDigestSize(UsedDigestType));
                break;
            case DIGEST_HMAC_MD5:
                hmac_md5(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_);
                break;
            case DIGEST_HMAC_SHA1:
                hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 1);
                break;
            case DIGEST_HMAC_SHA224:
                hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 224);
                break;
            case DIGEST_HMAC_SHA256:
                hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 256);
                break;
            case DIGEST_HMAC_SHA384:
                hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 384);
                break;
            case DIGEST_HMAC_SHA512:
                hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 512);
                break;
            default:
                break;
            }
            PrintHex(std::string("Auth: Sending digest ") + getDigestName(UsedDigestType) +" : ",
				 (uint8_t*)AuthDigestPtr_, getDigestSize(UsedDigestType));
        }
    }
    }

}