1*ef3aeadcSPatrick Venture /* 2*ef3aeadcSPatrick Venture * Copyright 2018 Google Inc. 3*ef3aeadcSPatrick Venture * 4*ef3aeadcSPatrick Venture * Licensed under the Apache License, Version 2.0 (the "License"); 5*ef3aeadcSPatrick Venture * you may not use this file except in compliance with the License. 6*ef3aeadcSPatrick Venture * You may obtain a copy of the License at 7*ef3aeadcSPatrick Venture * 8*ef3aeadcSPatrick Venture * http://www.apache.org/licenses/LICENSE-2.0 9*ef3aeadcSPatrick Venture * 10*ef3aeadcSPatrick Venture * Unless required by applicable law or agreed to in writing, software 11*ef3aeadcSPatrick Venture * distributed under the License is distributed on an "AS IS" BASIS, 12*ef3aeadcSPatrick Venture * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*ef3aeadcSPatrick Venture * See the License for the specific language governing permissions and 14*ef3aeadcSPatrick Venture * limitations under the License. 15*ef3aeadcSPatrick Venture */ 16*ef3aeadcSPatrick Venture 17*ef3aeadcSPatrick Venture #include "process.hpp" 18*ef3aeadcSPatrick Venture 19*ef3aeadcSPatrick Venture #include "ipmi.hpp" 20*ef3aeadcSPatrick Venture 21*ef3aeadcSPatrick Venture #include <cstring> 22*ef3aeadcSPatrick Venture #include <vector> 23*ef3aeadcSPatrick Venture 24*ef3aeadcSPatrick Venture namespace blobs 25*ef3aeadcSPatrick Venture { 26*ef3aeadcSPatrick Venture 27*ef3aeadcSPatrick Venture /* Used by all commands with data. */ 28*ef3aeadcSPatrick Venture struct BmcRx 29*ef3aeadcSPatrick Venture { 30*ef3aeadcSPatrick Venture uint8_t cmd; 31*ef3aeadcSPatrick Venture uint16_t crc; 32*ef3aeadcSPatrick Venture uint8_t data; /* one byte minimum of data. */ 33*ef3aeadcSPatrick Venture } __attribute__((packed)); 34*ef3aeadcSPatrick Venture 35*ef3aeadcSPatrick Venture IpmiBlobHandler validateBlobCommand(CrcInterface* crc, const uint8_t* reqBuf, 36*ef3aeadcSPatrick Venture uint8_t* replyCmdBuf, size_t* dataLen) 37*ef3aeadcSPatrick Venture { 38*ef3aeadcSPatrick Venture IpmiBlobHandler cmd; 39*ef3aeadcSPatrick Venture size_t requestLength = (*dataLen); 40*ef3aeadcSPatrick Venture /* We know dataLen is at least 1 already */ 41*ef3aeadcSPatrick Venture auto command = static_cast<BlobOEMCommands>(reqBuf[0]); 42*ef3aeadcSPatrick Venture 43*ef3aeadcSPatrick Venture /* Validate it's at least well-formed. */ 44*ef3aeadcSPatrick Venture if (!validateRequestLength(command, requestLength)) 45*ef3aeadcSPatrick Venture { 46*ef3aeadcSPatrick Venture return nullptr; 47*ef3aeadcSPatrick Venture } 48*ef3aeadcSPatrick Venture 49*ef3aeadcSPatrick Venture /* If there is a payload. */ 50*ef3aeadcSPatrick Venture if (requestLength > sizeof(uint8_t)) 51*ef3aeadcSPatrick Venture { 52*ef3aeadcSPatrick Venture /* Verify the request includes: command, crc16, data */ 53*ef3aeadcSPatrick Venture if (requestLength < sizeof(struct BmcRx)) 54*ef3aeadcSPatrick Venture { 55*ef3aeadcSPatrick Venture return nullptr; 56*ef3aeadcSPatrick Venture } 57*ef3aeadcSPatrick Venture 58*ef3aeadcSPatrick Venture /* We don't include the command byte at offset 0 as part of the crc 59*ef3aeadcSPatrick Venture * payload area or the crc bytes at the beginning. 60*ef3aeadcSPatrick Venture */ 61*ef3aeadcSPatrick Venture size_t requestBodyLen = requestLength - 3; 62*ef3aeadcSPatrick Venture 63*ef3aeadcSPatrick Venture /* We start after the command byte. */ 64*ef3aeadcSPatrick Venture std::vector<uint8_t> bytes(requestBodyLen); 65*ef3aeadcSPatrick Venture 66*ef3aeadcSPatrick Venture /* It likely has a well-formed payload. */ 67*ef3aeadcSPatrick Venture struct BmcRx request; 68*ef3aeadcSPatrick Venture std::memcpy(&request, reqBuf, sizeof(request)); 69*ef3aeadcSPatrick Venture uint16_t crcValue = request.crc; 70*ef3aeadcSPatrick Venture 71*ef3aeadcSPatrick Venture /* Set the in-place CRC to zero. */ 72*ef3aeadcSPatrick Venture std::memcpy(bytes.data(), &reqBuf[3], requestBodyLen); 73*ef3aeadcSPatrick Venture 74*ef3aeadcSPatrick Venture crc->clear(); 75*ef3aeadcSPatrick Venture crc->compute(bytes.data(), bytes.size()); 76*ef3aeadcSPatrick Venture 77*ef3aeadcSPatrick Venture /* Crc expected but didn't match. */ 78*ef3aeadcSPatrick Venture if (crcValue != crc->get()) 79*ef3aeadcSPatrick Venture { 80*ef3aeadcSPatrick Venture return nullptr; 81*ef3aeadcSPatrick Venture } 82*ef3aeadcSPatrick Venture } 83*ef3aeadcSPatrick Venture 84*ef3aeadcSPatrick Venture /* Grab the corresponding handler for the command (could do map or array 85*ef3aeadcSPatrick Venture * of function pointer lookup). 86*ef3aeadcSPatrick Venture */ 87*ef3aeadcSPatrick Venture switch (command) 88*ef3aeadcSPatrick Venture { 89*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobGetCount: 90*ef3aeadcSPatrick Venture cmd = getBlobCount; 91*ef3aeadcSPatrick Venture break; 92*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobEnumerate: 93*ef3aeadcSPatrick Venture cmd = enumerateBlob; 94*ef3aeadcSPatrick Venture break; 95*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobOpen: 96*ef3aeadcSPatrick Venture cmd = openBlob; 97*ef3aeadcSPatrick Venture break; 98*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobRead: 99*ef3aeadcSPatrick Venture cmd = readBlob; 100*ef3aeadcSPatrick Venture break; 101*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobWrite: 102*ef3aeadcSPatrick Venture cmd = writeBlob; 103*ef3aeadcSPatrick Venture break; 104*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobCommit: 105*ef3aeadcSPatrick Venture cmd = commitBlob; 106*ef3aeadcSPatrick Venture break; 107*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobClose: 108*ef3aeadcSPatrick Venture cmd = closeBlob; 109*ef3aeadcSPatrick Venture break; 110*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobDelete: 111*ef3aeadcSPatrick Venture cmd = deleteBlob; 112*ef3aeadcSPatrick Venture break; 113*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobStat: 114*ef3aeadcSPatrick Venture cmd = statBlob; 115*ef3aeadcSPatrick Venture break; 116*ef3aeadcSPatrick Venture case BlobOEMCommands::bmcBlobSessionStat: 117*ef3aeadcSPatrick Venture cmd = sessionStatBlob; 118*ef3aeadcSPatrick Venture break; 119*ef3aeadcSPatrick Venture default: 120*ef3aeadcSPatrick Venture return nullptr; 121*ef3aeadcSPatrick Venture } 122*ef3aeadcSPatrick Venture 123*ef3aeadcSPatrick Venture return cmd; 124*ef3aeadcSPatrick Venture } 125*ef3aeadcSPatrick Venture 126*ef3aeadcSPatrick Venture ipmi_ret_t processBlobCommand(IpmiBlobHandler cmd, ManagerInterface* mgr, 127*ef3aeadcSPatrick Venture CrcInterface* crc, const uint8_t* reqBuf, 128*ef3aeadcSPatrick Venture uint8_t* replyCmdBuf, size_t* dataLen) 129*ef3aeadcSPatrick Venture { 130*ef3aeadcSPatrick Venture ipmi_ret_t result = cmd(mgr, reqBuf, replyCmdBuf, dataLen); 131*ef3aeadcSPatrick Venture if (result != IPMI_CC_OK) 132*ef3aeadcSPatrick Venture { 133*ef3aeadcSPatrick Venture return result; 134*ef3aeadcSPatrick Venture } 135*ef3aeadcSPatrick Venture 136*ef3aeadcSPatrick Venture size_t replyLength = (*dataLen); 137*ef3aeadcSPatrick Venture 138*ef3aeadcSPatrick Venture /* The command, whatever it was, returned success. */ 139*ef3aeadcSPatrick Venture if (replyLength == 0) 140*ef3aeadcSPatrick Venture { 141*ef3aeadcSPatrick Venture return result; 142*ef3aeadcSPatrick Venture } 143*ef3aeadcSPatrick Venture 144*ef3aeadcSPatrick Venture /* The response, if it has one byte, has three, to include the crc16. */ 145*ef3aeadcSPatrick Venture if (replyLength < (sizeof(uint16_t) + 1)) 146*ef3aeadcSPatrick Venture { 147*ef3aeadcSPatrick Venture return IPMI_CC_INVALID; 148*ef3aeadcSPatrick Venture } 149*ef3aeadcSPatrick Venture 150*ef3aeadcSPatrick Venture /* The command, whatever it was, replied, so let's set the CRC. */ 151*ef3aeadcSPatrick Venture crc->clear(); 152*ef3aeadcSPatrick Venture replyCmdBuf[0] = 0x00; 153*ef3aeadcSPatrick Venture replyCmdBuf[1] = 0x00; 154*ef3aeadcSPatrick Venture crc->compute(replyCmdBuf, replyLength); 155*ef3aeadcSPatrick Venture 156*ef3aeadcSPatrick Venture /* Copy the CRC into place. */ 157*ef3aeadcSPatrick Venture uint16_t crcValue = crc->get(); 158*ef3aeadcSPatrick Venture std::memcpy(replyCmdBuf, &crcValue, sizeof(crcValue)); 159*ef3aeadcSPatrick Venture 160*ef3aeadcSPatrick Venture return result; 161*ef3aeadcSPatrick Venture } 162*ef3aeadcSPatrick Venture } // namespace blobs 163