117398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull/* 217398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * Copyright (C) 2017 The Android Open Source Project 317398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * 417398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * Licensed under the Apache License, Version 2.0 (the "License"); 517398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * you may not use this file except in compliance with the License. 617398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * You may obtain a copy of the License at 717398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * 817398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * http://www.apache.org/licenses/LICENSE-2.0 917398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * 1017398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * Unless required by applicable law or agreed to in writing, software 1117398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * distributed under the License is distributed on an "AS IS" BASIS, 1217398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1317398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * See the License for the specific language governing permissions and 1417398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull * limitations under the License. 1517398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull */ 1617398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull 1714ddec9715217258408b569da961e866a6a1665aAndrew Scull#include <apdu/apdu.h> 1817398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull 1917398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull#include <limits> 2017398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull 2117398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scullnamespace android { 2217398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull 2317398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew ScullCommandApdu::CommandApdu(const uint8_t cla, const uint8_t ins, const uint8_t p1, const uint8_t p2, 2417398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull const size_t lc, const size_t le) { 2517398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull constexpr size_t headerSize = 4; 2617398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull constexpr size_t shortLcMax = std::numeric_limits<uint8_t>::max(); 2717398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull constexpr size_t shortLeMax = std::numeric_limits<uint8_t>::max() + 1; 2817398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull //constexpr size_t extendedLcMax = std::numeric_limits<uint16_t>::max(); 2917398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull constexpr size_t extendedLeMax = std::numeric_limits<uint16_t>::max() + 1; 3017398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull 3117398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull const bool extended = lc > shortLcMax || le > shortLeMax; 3217398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull const bool hasLc = lc > 0; 3317398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull const bool hasLe = le > 0; 3417398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull const size_t lcSize = hasLc ? (extended ? 3 : 1) : 0; 3517398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull const size_t leSize = hasLe ? (extended ? (hasLc ? 2 : 3) : 1) : 0; 3617398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull const size_t commandSize = headerSize + lcSize + lc + leSize; 3717398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull mCommand.resize(commandSize, 0); 3817398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull 3917398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull // All cases have the header 4017398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull auto it = mCommand.begin(); 4117398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = cla; 4217398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = ins; 4317398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = p1; 4417398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = p2; 4517398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull 4617398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull // Cases 3 & 4 send data 4717398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull if (hasLc) { 4817398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull if (extended) { 4917398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = 0; 5017398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = 0xff & (lc >> 8); 5117398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull } 5217398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = 0xff & lc; 5317398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull mDataBegin = it; 5417398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull it += lc; 5517398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull mDataEnd = it; 5617398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull } else { 5717398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull mDataBegin = mDataEnd = mCommand.end(); 5817398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull } 5917398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull 6017398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull // Cases 2 & 4 expect data back 6117398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull if (hasLe) { 6217398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull if (extended) { 6317398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull if (!hasLc) { 6417398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = 0; 6517398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull } 6617398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull const bool isLeMax = le == extendedLeMax; 6717398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = (isLeMax ? 0 : 0xff & (le >> 8)); 6817398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = (isLeMax ? 0 : 0xff & le); 6917398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull } else { 7017398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull *it++ = (le == shortLeMax ? 0 : 0xff & le); 7117398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull } 7217398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull } 7317398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull} 7417398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull 7517398427e40008fbae3e3053eb7a6f47b16c6ef0Andrew Scull} // namespace android 76