Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2597e754 authored by Wonsik Kim's avatar Wonsik Kim Committed by Android (Google) Code Review
Browse files

Merge "Partial revert of commit ccb7ac6b"

parents 4b0dec26 1cac425d
Loading
Loading
Loading
Loading
+134 −6
Original line number Original line Diff line number Diff line
@@ -1750,22 +1750,150 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
        return;
        return;
    }
    }


    NativeCryptoInfo cryptoInfo{env, cryptoInfoObj};
    jint numSubSamples =
        env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID);

    jintArray numBytesOfClearDataObj =
        (jintArray)env->GetObjectField(
                cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID);

    jintArray numBytesOfEncryptedDataObj =
        (jintArray)env->GetObjectField(
                cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID);

    jbyteArray keyObj =
        (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID);

    jbyteArray ivObj =
        (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID);

    jint jmode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
    enum CryptoPlugin::Mode mode;
    if (jmode == gCryptoModes.Unencrypted) {
        mode = CryptoPlugin::kMode_Unencrypted;
    } else if (jmode == gCryptoModes.AesCtr) {
        mode = CryptoPlugin::kMode_AES_CTR;
    } else if (jmode == gCryptoModes.AesCbc) {
        mode = CryptoPlugin::kMode_AES_CBC;
    }  else {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    jobject patternObj = env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID);

    CryptoPlugin::Pattern pattern;
    if (patternObj == NULL) {
        pattern.mEncryptBlocks = 0;
        pattern.mSkipBlocks = 0;
    } else {
        pattern.mEncryptBlocks = env->GetIntField(patternObj, gFields.patternEncryptBlocksID);
        pattern.mSkipBlocks = env->GetIntField(patternObj, gFields.patternSkipBlocksID);
    }

    status_t err = OK;

    CryptoPlugin::SubSample *subSamples = NULL;
    jbyte *key = NULL;
    jbyte *iv = NULL;

    if (numSubSamples <= 0) {
        err = -EINVAL;
    } else if (numBytesOfClearDataObj == NULL
            && numBytesOfEncryptedDataObj == NULL) {
        err = -EINVAL;
    } else if (numBytesOfEncryptedDataObj != NULL
            && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) {
        err = -ERANGE;
    } else if (numBytesOfClearDataObj != NULL
            && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) {
        err = -ERANGE;
    // subSamples array may silently overflow if number of samples are too large.  Use
    // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms
    } else if ( CC_UNLIKELY(numSubSamples >= (signed)(INT32_MAX / sizeof(*subSamples))) ) {
        err = -EINVAL;
    } else {
        jboolean isCopy;

        jint *numBytesOfClearData =
            (numBytesOfClearDataObj == NULL)
                ? NULL
                : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy);

        jint *numBytesOfEncryptedData =
            (numBytesOfEncryptedDataObj == NULL)
                ? NULL
                : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy);

        subSamples = new CryptoPlugin::SubSample[numSubSamples];

        for (jint i = 0; i < numSubSamples; ++i) {
            subSamples[i].mNumBytesOfClearData =
                (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i];

            subSamples[i].mNumBytesOfEncryptedData =
                (numBytesOfEncryptedData == NULL)
                    ? 0 : numBytesOfEncryptedData[i];
        }

        if (numBytesOfEncryptedData != NULL) {
            env->ReleaseIntArrayElements(
                    numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0);
            numBytesOfEncryptedData = NULL;
        }

        if (numBytesOfClearData != NULL) {
            env->ReleaseIntArrayElements(
                    numBytesOfClearDataObj, numBytesOfClearData, 0);
            numBytesOfClearData = NULL;
        }
    }

    if (err == OK && keyObj != NULL) {
        if (env->GetArrayLength(keyObj) != 16) {
            err = -EINVAL;
        } else {
            jboolean isCopy;
            key = env->GetByteArrayElements(keyObj, &isCopy);
        }
    }

    if (err == OK && ivObj != NULL) {
        if (env->GetArrayLength(ivObj) != 16) {
            err = -EINVAL;
        } else {
            jboolean isCopy;
            iv = env->GetByteArrayElements(ivObj, &isCopy);
        }
    }

    AString errorDetailMsg;
    AString errorDetailMsg;


    status_t err = cryptoInfo.mErr;
    if (err == OK) {
    if (err == OK) {
        err = codec->queueSecureInputBuffer(
        err = codec->queueSecureInputBuffer(
                index, offset,
                index, offset,
                cryptoInfo.mSubSamples, cryptoInfo.mNumSubSamples,
                subSamples, numSubSamples,
                (const uint8_t *)cryptoInfo.mKey, (const uint8_t *)cryptoInfo.mIv,
                (const uint8_t *)key, (const uint8_t *)iv,
                cryptoInfo.mMode,
                mode,
                cryptoInfo.mPattern,
                pattern,
                timestampUs,
                timestampUs,
                flags,
                flags,
                &errorDetailMsg);
                &errorDetailMsg);
    }
    }


    if (iv != NULL) {
        env->ReleaseByteArrayElements(ivObj, iv, 0);
        iv = NULL;
    }

    if (key != NULL) {
        env->ReleaseByteArrayElements(keyObj, key, 0);
        key = NULL;
    }

    delete[] subSamples;
    subSamples = NULL;

    throwExceptionAsNecessary(
    throwExceptionAsNecessary(
            env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
            env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
}
}